Creating the Pop Piano Jukebox Part 2: How?

In a prior blog post, I described WHY I created PopPianoJukebox.com (aka “PPJ”). For the techies out there, and to reinforce my own learning, I wanted to describe some of HOW I built it. I'll try to keep it readable but the inclusion of software software developer “geek speak” is inescapable here. :-)

When I first conceived the Pop Piano Jukebox, more than 20 years ago after a Starbucks gig in San Francisco, there were many unknowns:

  • Could I build the software myself? I had never built a web app.
  • Would audiences engage and enjoy browsing a long list to pick from?
  • Could I maintain enough material at my fingertips to keep the audience entertained and myself interested?
  • Would the flow and energy of a set be compromised by chasing votes?

It took two decades (and retiring from corporate life) to carve out the time to finish the app and build my repertoire. Now after 12 months and a dozen PPJ shows, I've learned a ton about software, music, audiences, and myself. It's been incredibly empowering at each show to find "I wish PPJ did that thing" and then go build that thing before the next show.

How I Built It

In early 2017 I found myself between jobs and figured it was time to put together a prototype if I was at all serious about this idea. I had done a lot of "thought design" but had no code to show for it. After some brief looking around (aka "Googling how to build a web site with Python"), I chose Django 4 as my development platform. It included robust database integration, built-in Admin pages, and HTML templates with CSS (aka "minimal JavaScript") that I felt I could deliver, as I had never done JS before. I grabbed a tutorial and started modifying it to incorporate my ideas. I relied on Bootstrap to facilitate mobile-friendly responsive web pages. I'm sure today's expert web devs would scoff as they push out pixel perfect pages with JS and the latest style libraries, but Bootstrap was a) fit for purpose and b) approachable for someone not steeped in web dev.

Two Modes: Audience or Admin

When I log into the site, I get more pages and features, but audience members or anyone who lands on the site in casual browsing see a simplified view.

Audience Mode

Since the site is available 24/7, I needed it to function both as a marketing AND audience landing page on gig day. That led to a simple landing page with three distinct calls to action when not logged in.

  1. Contact me (mailto: link)
  2. Get on the mailing list (cross link to ddr.band)
  3. Open the Jukebox

From the Jukebox page you see the list of events including today's gig, if there is one, and future shows, as a nudge to consider coming back again! Selecting the event (almost always today's gig) shows you the Jukebox page:


I'm especially proud of this "jukebox" visual design, down to the typewriter font and pink shading. I wanted to recreate the feel of those tabletop jukebox controllers featured in diners in the 1900s:

Image: akamaidivers.com via pinterest.com

Those magenta boxes are drawn via CSS borders:

.song-pane {
border: 4px;
border-style: solid;
border-color: mediumvioletred;
color: black;
padding-top: 3px;
padding-bottom: 3px;
}

.song-pane-even {
background-color: rgb(230, 185, 208);
}

.song-pane-odd {
background-color: white;
margin-top: -4px;
margin-bottom: -4px;
}

.artist-pane {
border: 2px;
border-style: solid;
border-color: mediumvioletred;
background-color: white;
font-weight: normal;
color: black;
padding-top: 2px;
text-align: center;
font-size: 12px;
}

.artist-pane-line {
border-top: 2px solid mediumvioletred;
position: relative;
top: 11px;
}

It took a fair bit of experimentation, but the design has held up through many iterations and other changes. It accommodates long song titles well, and I think it looks great! The "Filters..." panel is less elegant. In particular, I haven't yet implemented sticky filters, so if you filter by "uptempo" songs and then pick a song, the list returns to its unfiltered state. There is always more to learn!

Admin Mode

I hadn't anticipated how vital the site would be for my own rehearsal and set list management activities. Almost immediately, though, I adapted the "Performance" view I use during a show into a "Rehearsal" view, showing me the set of songs I've selected for each upcoming show. The kicker? I want to track the date I last played each song, so whether at rehearsal or in performance, tapping the song title marks the "last played" field in the database with today's date. Then, it's a simple matter of sorting Rehearsal view by date played, oldest to newest:

Here you can see the song name and Spotify logo, which is a link to open the track on Spotify for playback reference. Tapping the song name (e.g. Stand By Me) jumps right to the Django admin page for the song to edit its lyrics, tempo, or other details. I use the "Key" data to remind me the musical key in which I like to play the song. Over the years I've played many songs in different keys depending on the band context, so this helps ensure I start in the right place!

All of this adds up to an incredibly helpful database-backed repertoire management system I use every day. I can add songs as work-in-progress, hiding them from inclusion in an event while still leaving them easy to rehearse. My most recent additions to Admin mode include a "Review" page to see what happened at an event in the past (number of users, requests, play sequences, etc.) and a “Reference” section where I can find charts for new songs easily. The former is a huge boon to remembering what went well and where I might need more work before the next show. The latter makes finding the chords for Toto's Africa or roughly 500 other songs quick and easy!

Couldn't You Build This With AI Today?

Almost certainly prompting my way to something similar would be possible albeit a whole new learning curve for me. For now, I'm confident and content that I know what the code is doing, and I can generally make it do what I want with minimal disruption.

I would consider rewriting ("vibe" coding or otherwise) if I were able to update the platform to JavaScript (e.g. VueJS with FastAPI or similar) so that the UI could be more slick like a modern single-page application. Database-driven reactive page elements would be especially powerful. Perhaps that will happen, but with shows to hustle and more songs to learn, the app I have is making me happy and serving my purposes right now.

For the Technically Curious (Cue the Geek Speak)

Today's PPJ platform is built on:

  • Django 4 with HTMX
  • Bootstrap 5
  • PostgreSQL 15 (with psycopg2 for Python integration)
  • 14 HTML templates and less than 1700 lines of Python code
  • JavaScript has crept in over the years to implement popup dialogs, seamless page scrolling, and more.
  • Azure App Service on Python 3.12
  • Azure Database for PostgreSQL flexible server
  • Azure hosting costs $30 to $50 monthly depending on scale (I scale up instances to meet user demand at a show)

I'm thrilled to have been able to conceive, build, and deliver something entirely "on my own" (that is, with generous web searching and some ChatGPT tips). In my professional career, I certainly worked on larger and more impactful software projects, but none were more fulfilling than PopPianoJukebox.com.

Carousel Photo: Levi Bastion Cross

Leave a comment