Skip to content

A tiny podcast client written in GNU Make with sprinkles of Ruby

Notifications You must be signed in to change notification settings

gromnitsky/gmakepod

Repository files navigation

gmakepod

A tiny podcast client written in GNU Make with sprinkles of Ruby.

Why?

Why not? Besides because we can, this are the features you get when using Make for something it wasn't intended for:

  • download in parallel;
  • yt-dlp integration;
  • filter by subs name, enclosure type or url;
  • auto-convert ogg/m4a to mp3 or vice-versa;
  • sort in reverse, so you may fetch the 1st 2 episodes, instead of the last 2, for example;
  • 'catch up' w/ feeds w/o downloading anything.

Despite the number of src files, the client itself is rather small:

$ f='*rb *mk gmakepod'; join -j2 <(wc -l $f) <(du -bhc $f) | column -t -NFILE,LINES,SIZE
FILE                  LINES  SIZE
enclosures-print.rb   13     444
ini-parse.rb          6      174
u.rb                  19     548
enclosures-reject.mk  5      212
feed-parse.mk         24     893
generate.mk           56     1.3K
u.mk                  13     646
gmakepod              57     1.3K
total                 193    5.4K

Install

Requires GNU Make 4+, Ruby 2.7+, curl.

$ git clone --recurse-submodules https://github.com/gromnitsky/gmakepod.git
$ cd gmakepod
$ bundle

Then create a symlink to gmakepod somewhere in PATH.

Setup

Chose an 'umbrella' dir for your podcasts, e.g., ~/podcasts; create a file named podcasts.ini in that dir:

[BBC In Our Time]
url = http://downloads.bbc.co.uk/podcasts/radio4/iot/rss.xml

[Dave Winer]
url = http://scripting.com/rss.xml
convert-to = .mp3

An optional convert-to prop tells gmakepod that it'll need to convert each enclosure (from that feed only) to mp3 (the dot is important). Other valid props here are e, reverse, filter.type & filter.url. Type gmakepod help to read what they mean.

Now, cd to ~/podcasts & type gmakepod. It should download the last 2 enclosures tops from each feed.

$ tree --noreport media
media/
├── BBC_In_Our_Time
│   ├── p02q5q4c.mp3
│   └── p02q5phk.mp3
└── Dave_Winer
    └── denverPostAndBerkeleyside.mp3

If you run gmakepod again it says 'make[1]: *** No targets. Stop.' because it refuses to process already processed enclosures.

For parallel downloads, pass j=N param.

yt-dlp

tl;dr: to get audio from the Computer History Museum playlist:

[CHM Oral History]
url = https://apps.sigwait.org/youtube-dl-feeds/https://www.youtube.com/playlist?list=PLQsxaNhYv8daKdGi7s85ubzbWdTB36-_q
curl = yt-dlp -o $@ -x --audio-format mp3 --add-metadata --no-part

This will fetch a specially augmented youtube feed & run yt-dlp for each enclosure.

Youtube provides several types of atom feeds, but they all lack enclosures in them. apps.sigwait.org/youtube-dl-feeds server injects enclosure links to youtube videos. (It doesn't log anything, have no state, the source is available here; you can run your own server if you trust no one.)

We cannot put real enclosure links into the feed, for the only way to get a format of the audio/video, contained behind a youtube url, is to replicate a yt-dlp job.

convert-to prop is not applicable here.

How does it work?

gmakepod target desc
.feeds parse .ini to extract feeds names & urls
.enclosures fetch & parse each feed to extract enclosures urls
.files generate a proper output file name for each url
.files.new check if we have already downloaded a url in the past, filter out
.download.mk generate a makefile, where we list all the rules for all the enclosures
run run the makefile

xxx->mp3 conversions require ffmpeg (tested /w 4.1.4) & gawk.

kumamon

License

MIT.

About

A tiny podcast client written in GNU Make with sprinkles of Ruby

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published