Thomas shares makes

2022-02-03

Podcast downloading with Python and systemd

pimped terminal screenshot

My favorite radio show airs on Sunday afternoon, and often can't listen to it live. Fortunately the radio station offers a podcast feed so I can catch up and listen to old shows. I set up a systemd user timer (cronjob) on my Linux computer that runs getpodcast to download updates.

Getpodcast configuration

Getpodcast is pretty effective python module, you can create a small python script that contains some simple configuration details and if needed a post-download hook.

pip3 install getpodcast

In this example I added a post-download trigger that adds the new file to a m3u playlist, but you can also use os.system to trigger a command that adds the file to a music player queue.

#! /usr/bin/env python3
# podcast_task.py

import getpodcast
import pathlib

def add_to_playlist(*args, **kwargs):
    """ Add new files to a playlist """
    newfilename = pathlib.Path(kwargs["newfilename"])
    with open("new.m3u", 'a', encoding='utf-8') as playlist:
        playlist.write(f"{newfilename}\n")

opt = getpodcast.options(
    #date_from='2021-01-01',
    root_dir='.',
    hooks='validated=add_to_playlist'
    )

podcasts = {
    "Slacker Station": "https://www.omnycontent.com/d/playlist/c292b3ac-094e-4616-a956-a99800ed54e9/c2b3611e-0597-4e7e-aabb-ac36008131d7/97e83ee0-349f-4444-b17f-ac360081f03e/podcast.rss",
    "De M Show": "https://www.omnycontent.com/d/playlist/c292b3ac-094e-4616-a956-a99800ed54e9/28068cad-eb0d-46a1-8b77-abdd00f622c4/bbb709cc-4190-48af-aa70-ac2800e1dfdb/podcast.rss"
}

getpodcast.getpodcast(podcasts, opt)

After verifying the the script does what it is supposed to do in the command shell, it's time to automate it and run it as a systemd service.

Systemd configuration

Systemd is typically used to manage system wide services, but it can also be used for more personal stuff that runs under the local user account.

To do just that, we can create ~/.config/systemd/user and put some files there.

Systemd normally only activates these user jobs when the user is logged in. Since I'm using this on a headless server, I need to enable lingering on the account:

loginctl enable-linger username

Two configuration files are needed, a service that describes what to do, and a timer that triggers the service.

# ~/.config/systemd/user/mypodcaster.service
[Unit]
Description=run getpodcast script
Wants=mypodcaster.timer

[Service]
Type=oneshot
ExecStart=/home/thomas/podcasts/podcast_task.py --run
WorkingDirectory=/home/thomas/podcasts

[Install]
WantedBy=multi-user.target
# ~/.config/systemd/user/mypodcaster.timer
[Unit]
Description=Run podcast service one a day
Requires=mypodcaster.service

[Timer]
Unit=mypodcaster.service
OnCalendar=*-*-* 02:00:00

[Install]
WantedBy=timers.target

To have systemd pick up the newly created configuration, we need to trigger daemon-reload:

systemctl --user daemon-reload

Final check

It's a good idea to check the systemd service before leaving it to the timer:

thomas@elektra:~$ journalctl --user -f -u mypodcaster &
thomas@elektra:~$ systemctl --user start mypodcaster

You can view the output later on using journalctl:

thomas@elektra:~$ journalctl --user  -u mypodcaster|tail
Feb 03 20:10:13 elektra getpodcasts.py[1801309]:   File:  ./De M Show/2020/2020.08.31 De M-show met Marcel Vanthilt (288 16u).mp3:
Feb 03 20:10:13 elektra getpodcasts.py[1801309]:   Status:
Feb 03 20:10:13 elektra getpodcasts.py[1801309]:          Downloading ...
Feb 03 20:10:13 elektra getpodcasts.py[1801309]:          Download complete
Feb 03 20:10:13 elektra getpodcasts.py[1801309]:          File validated
Feb 03 20:10:13 elektra systemd[801650]: mypodcaster.service: Succeeded.
Feb 03 20:10:13 elektra systemd[801650]: Finished run getpodcast script.
Feb 04 02:00:06 elektra systemd[801650]: Starting run getpodcast script...
Feb 04 02:18:06 elektra systemd[801650]: mypodcaster.service: Succeeded.
Feb 04 02:18:06 elektra systemd[801650]: Finished run getpodcast script.

Enjoy listening...


Liked something? Worked on something similar? Let me know what you think on Mastodon!
You can use your Mastodon account to reply to this post.

Reply to post

You can respond to this post with an account on the Fediverse or Mastodon. Since Mastodon is decentralized, you can use your existing account or create your account on a server of your choice.

Copy and paste this URL into the search field of your favourite Fediverse app or the web interface of your Mastodon server.

Learn how @carlschwan wrote the code that loads Mastodon posts into this webpage here.

Follow me on Mastodon!