Browse All Episodes of The Imp And Skizz Podcast
The Imp and Skizz podcast is one of my favourite ways to pass the time whilst driving or doing routine tasks around the house. ImpulseSV and Skizzleman are both content creators, which I discovered through Hermitcraft. I’ve recently started learning Python’s Django framework. I decided to combine my love of this podcast with my learning by creating a small project that helps people easily navigate all podcast episodes released across different streaming platforms.
Goals & Features
- Display all episodes of the podcast.
- Link to the different streaming platforms:
- YouTube
- Spotify
- Apple Music/Podcasts
- Search podcasts by name.
- Automatically populate data via APIs.
- To direct users to a third-party streaming service and not serve the content directly.
Tech Stack
- Back end:
- Front end:
- Cloudflare
One of my main goals in this project was to allow for users to be able to navigate all of the episodes in a way that is fast and useful, whilst ensuring that listeners must still go to the streaming platforms to watch/listen to the episodes. This ensures that no views or engagement are taken away from these platforms so as to not negatively affect the original creators.
The Back End
I used Django as it allowed me to create an API to handle the application data with very little boilerplate code. This meant I could have an admin interface with correctly configured database models and migrations with very little bloat.
The Django API
You can see an example of the data the API provides by visiting the API’s main route: https://api.impandskizzpodcast.com/api/v2/podcasts
As you can see, this returns a list of all of the podcasts, including their:
- Title
- Episode number
- Youtube ID
- Spotify URL
- Apple Music URL
- Release date
- Preview URL
- Duration
You’ll notice that this uses an ID for YouTube, but URLs for Spotify and Apple Music. I decided to use YouTube’s thumbnails on the website. To do this, you take the ID of the video and generate an image URL as follows: https://img.youtube.com/vi/{YOUTUBE_ID}/hqdefault.jpg
. To then link to the video itself, you can generate a URL with: https://www.youtube.com/watch?v={YOUTUBE_ID}
. Instead of merely storing a URL for each in the database, it makes more sense to generate the URLs from the ID and save repetition.
The preview URL is a nice feature provided by the Spotify API. In the data Spotify provide, they give you this URL which links to a 60-ish-second audio snippet of the episode. Embedding this in a playable element is very simple, so it made sense to include it as an interactive feature for users who are perhaps deciding which episode to listen to or watch.
Fetching New Podcast Episodes
To ensure the website is always as up-to-date as possible, I wrote a few scripts that run a schedule to fetch the latest podcast episodes. These scripts include custom API clients to interact with the YouTube and Spotify APIs (as of writing this post, I haven’t written a client for Apple Music just yet).
These scripts run via CRON jobs, triggering them to start at 15:00 every day. Each script fetches the latest couple of podcasts. The YouTube client will create a new record in the database if the podcast episode isn’t yet stored. The Spotify client will then use the upload date to marry up the data and add the Spotify details. These are the two required data sources for all functions to exist on the podcast listing on the website. That is the reason they were prioritised.
Dockerising Django
I host all of my websites using Plesk on a Linux bare-metal server. Unfortunately, as of building this project, Plesk doesn’t have native Python support. It does, however, have excellent Docker support as it is Linux. To deploy the Django API without polluting the server’s OS with packages unsupported by Plesk, Docker just made sense.
To deploy this in a container, I created a Docker image that can run Django applications and also enable CRON scheduling. I then used Github actions to have a new image built every time I generated a release within Github. This image is available to then be fetched via Plesk’s admin interface to update the container to the latest version.
The Front End
I decided to use NUXT, a framework which uses Vue JS in a ‘batteries included’ approach. I’ve used Vue for a few projects with work, but have always used it for small applications embedded on pages. I’d never built a full front end with only Vue. By utilising NUXT, I could easily have routing, server-side rendering and single-page-application (SPA) fluidity, all whilst enjoying the ease of developing interactive pages with Vue components. Needless to say, I’m slightly obsessed now!
When the page loads, it fetches the data from the API back end and then uses that to generate the page. A card is created for each podcast episode and is populated with the appropriate data. On the top of the page, there is a search bar which checks the input against the titles of the episodes and a button to re-order the results. Whenever these filters are used, the URL is updated to include a query string to reflect it. These query strings allow filtered results to be shared via the URL. When the page loads, if the query strings are present, it’ll apply them as needed.
I explained how this works from a data perspective above, but using YouTube and Spotify has allowed me to display thumbnail images and preview audio elements on each card. This adds a lot of appeal to the site visually and practically.
Search Engine Optimisation
As NUXT allows for server-side rendering, the website can be viewed by search engine scrapers. This means the content is viewable without JavaScript, and Google can ‘see’ the page’s content to understand it properly.
The page also includes the core meta-information required for SEO and social sharing; title, description, og:image, and more. This means that if the website is viewed in the right format on Google or shared via social media, it shows a specific image and content to showcase what the site’s about at a glance.
The Future
This was intended to be a quick project for my personal development. With this in mind, the project has been a huge success. I’ve learned a great deal and have also built something that I’m proud of and can reflect on as a ‘thank you’ to the creators of this podcast who have brought me many hours of entertainment.
I don’t have any immediate plans to expand this idea any further. The only exception is that I hope to soon implement an Apple Music client to fetch the podcast URLs for that platform.