No project description provided
Project description
Spodcat
This is the backend part of my podcast platform. It's designed to go along with the frontend part. It's built on Django REST Framework with a JSON:API implementation, but more on that later. The admin interface is just the regular Django admin with some minor tweakage. My own specific implementation is available in this repo and is also live here.
It's mainly made for my own specific purposes. Lately I have been making some effort to generalise stuff, in order to facilitate some potential wider use. But there's probably lots more that needs to be done to that end.
Spodcat configuration
Spodcat is configured using a SPODCAT dict in your Django settings module. These are the available settings:
FRONTEND_ROOT_URL
Mainly used for RSS feed generation and some places in the admin. Default: http://localhost:4200/.
BACKEND_HOST
Used (along with BACKEND_ROOT, see below) for generating RSS feed URLs which are sent to the frontend, as well as some stuff in the admin. Default: http://localhost:8000/.
BACKEND_ROOT
Set this is your backend installation is not at the URL root. Default: empty string.
USE_INTERNAL_AUDIO_REDIRECT
If True, the episode API responses and RSS feeds will use the internal view spodcat:episode-audio (resolving to something like https://example.com/episodes/<episode-id>/audio/) for episode URLs instead of linking directly to whatever episode.audio_file.url returns. This view will then save a PodcastEpisodeAudioRequestLog entry (provided the spodcat.logs app is installed) and return a 302 (temporary) redirect to episode.audio_file.url.
Possible use cases for this:
- Your storage provider cannot reliably provide permanent, canonical episode URLs for some reason
- You want to save
PodcastEpisodeAudioRequestLoglogs but your storage provider doesn't let you access request logs
Note that the spodcat:episode-audio view has no way to log partial episode downloads, and will log every request as if it's for the entire audio file.
USE_INTERNAL_AUDIO_PROXY
Like USE_INTERNAL_AUDIO_REDIRECT but more involved and with many potential downsides. Basically, when set to True it will make the spodcat:episode-audio view act as a full on proxy instead of just redirecting, i.e. it will fetch the audio file contents from your storage provider and serve them directly. You probably only want to use this if you store episode audio locally on the backend server, or if you really want to be able to log partial episode downloads but your storage provider doesn't let you access request logs. With remote storage backends, it will probably add a bunch of overhead and generally make things a little worse for everyone.
Takes priority over USE_INTERNAL_AUDIO_REDIRECT if True.
FILEFIELDS
Contains settings for various FileFields on different models, and govern where uploaded files will be stored and by which storage engine.
SPODCAT = {
"FILEFIELDS": {
"__FILEFIELD_CONSTANT__": {
"UPLOAD_TO": Callable[[Model, str], str] | str,
"STORAGE": Storage | Callable[[], Storage] | str,
},
},
}
I.e. the UPLOAD_TO values represent FileField.upload_to callables or paths to them, and STORAGE represent the storage parameter of the same FileField (with the addition that they can also be strings, in which case the storage with this key in django.core.files.storage.storages will be used).
Here are the available values for __FILEFIELD_CONSTANT__ and the model types and default values for their UPLOAD_TO settings:
EPISODE_AUDIO_FILE: Model isEpisode. Default:f"{instance.podcast.slug}/episodes/{filename}"EPISODE_CHAPTER_IMAGE: Model isAbstractEpisodeChapter. Default:f"{instance.episode.podcast.slug}/images/episodes/{instance.episode.slug}/chapters/{filename}"EPISODE_IMAGE: Model isEpisode. Default:f"{instance.podcast.slug}/images/episodes/{instance.slug}/{filename}"EPISODE_IMAGE_THUMBNAIL: Same as aboveFONTFACE_FILE: Model isFontFace. Default:f"fonts/{filename}"PODCAST_BANNER: Model isPodcast. Default:f"{instance.slug}/images/{filename}"PODCAST_COVER: Same as abovePODCAST_COVER_THUMBNAIL: Same as abovePODCAST_FAVICON: Same as abovePODCAST_LINK_ICON: Model isPodcastLink. Default:f"{instance.podcast.slug}/images/links/{filename}"SEASON_IMAGE: Model isSeason. Default:f"{instance.podcast.slug}/images/season/{instance.number}/{filename}"SEASON_IMAGE_THUMBNAIL: Same as above
Footnote: The reason for adding the STORAGE settings was that I did my file hosting with Azure, but that didn't work with CSS fonts since I couldn't control the Access-Control-Allow-Origin header. So I did this:
MEDIA_ROOT = os.environ.get("MEDIA_ROOT", BASE_DIR / "media")
MEDIA_URL = "/media/"
STORAGES = {
"default": {"BACKEND": "storages.backends.azure_storage.AzureStorage"},
"staticfiles": {"BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage"},
"local": {"BACKEND": "django.core.files.storage.FileSystemStorage"},
}
SPODCAT = {
"FILEFIELDS": {
"FONTFACE_FILE": {"STORAGE": "local"},
},
...
}
... and then just had my web server reply to MEDIA_URL request by serving the files in MEDIA_ROOT.
Other Django settings
This is a bare minimum of apps you need to include in your project:
INSTALLED_APPS = [
"django.contrib.auth",
"django.contrib.contenttypes",
"spodcat",
]
However, this will only be able to run the API. It will not allow you to use the admin or the Django REST Framework browsable API. This is probably more like what you want:
INSTALLED_APPS = [
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions", # needed for admin
"django.contrib.messages", # needed for admin
"django.contrib.staticfiles", # needed for admin and REST browsable API
"rest_framework", # needed for REST browsable API
"rest_framework_json_api", # needed for REST browsable API
"django_filters", # needed for REST browsable API
"martor", # needed for admin
"spodcat",
"spodcat.logs",
"spodcat.contrib.admin",
]
Here, spodcat.contrib.admin is used instead of django.contrib.admin. It adds some nice stuff like a couple of charts and a notice on the admin index page about comments awaiting approval.
If you somehow don't want to log any page, episode audio, and RSS requests, you can leave out spodcat.logs.
URLs
This root URL conf is perfectly adequate:
from django.urls import include, path
urlpatterns = [
path("", include("spodcat.urls")),
path("admin/", include("spodcat.contrib.admin.urls")),
]
(You don't need to include django.contrib.admin.site.urls if you use spodcat.contrib.admin.urls.)
Used software
- Django
- Django REST Framework
- Django REST Framework JSON:API
- django-polymorphic
- country_list (for making country codes more human readable in admin)
- python-feedgen (for generating RSS feeds)
- Feedparser (for importing external RSS feeds)
- Maxmind GeoIP2 Python API (getting geo data for remote IPs, for logging purposes)
- iso639-lang (getting possible language choices for podcasts)
- klaatu-django (my own collection of useful bits & bobs)
- Markdownify (convert HTML to Markdown when importing RSS feeds)
- Martor (Markdown editor for admin)
- Pillow (for automatic image thumbnail generation)
- Pydub (to generate dBFS arrays for audio visualization in frontend)
- Dateutil (for generating statistics graphs in admin)
- Python Slugify (generating slugs for podcast episodes/posts)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file spodcat_backend-0.8.0rc2.tar.gz.
File metadata
- Download URL: spodcat_backend-0.8.0rc2.tar.gz
- Upload date:
- Size: 35.4 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7246ea137435e7313a31370423e16a9263816e8774994dc8ecd0897a883c5744
|
|
| MD5 |
fa8663241d9607380b3af0cd9f6c99a7
|
|
| BLAKE2b-256 |
e5c558410e17a2cdd3b19990f8224c8fe9d1742f0b657f48474cf3a3d00b57b1
|
File details
Details for the file spodcat_backend-0.8.0rc2-py3-none-any.whl.
File metadata
- Download URL: spodcat_backend-0.8.0rc2-py3-none-any.whl
- Upload date:
- Size: 35.7 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7d529784f1b4d3ad8509382a56469b4137c0f0096c8858a20dbcc357d51e4f1b
|
|
| MD5 |
22505a9de2ff9a29c6ce18d224236fce
|
|
| BLAKE2b-256 |
848d666722a9db0b530af9153d22bf99f58b14ea1a9625bb1ed37e957061aefb
|