Skip to content

marcomc/raiplaysound-cli

Repository files navigation

RaiPlaySound CLI

A Python CLI for RaiPlaySound program discovery, season and episode inspection, incremental downloads, Rich-based transfer progress, metadata caching, RSS feed generation, and playlist generation.

Disclaimer: RaiPlaySound CLI is an independent, community-developed project and is not affiliated with, endorsed by, or in any way officially connected with RAI, RaiPlaySound, or the official RaiPlaySound application. "RAI", "RaiPlaySound", radio station names, program names, show titles, and related marks remain the property of their respective owners. This tool references publicly accessible RaiPlaySound web resources only to help users inspect programs and download episodes they already have access to. It is provided as a free, open-source convenience utility for users who prefer a terminal-based workflow.

Table of Contents

Installation

Requirements:

  • Python 3.10+
  • yt-dlp
  • ffmpeg

System dependency example on macOS:

brew install python yt-dlp ffmpeg

Standalone user install:

git clone https://github.com/marcomc/raiplaysound-cli.git
cd raiplaysound-cli
make install

This installs the package into:

  • ~/.local/share/raiplaysound-cli/venv
  • ~/.local/share/raiplaysound-cli/bin/raiplaysound-cli
  • ~/.local/share/raiplaysound-cli/bin/raiplaysound-cli-daily-sync

and creates the user-facing command at:

  • ~/.local/bin/raiplaysound-cli
  • ~/.local/bin/raiplaysound-cli-daily-sync

The installed command is a small Python launcher that loads the package from the local install tree. It does not rely on the exact interpreter path baked into a pip-generated console script, so it keeps working if the underlying Python version changes or the venv is recreated.

Editable development install:

git clone https://github.com/marcomc/raiplaysound-cli.git
cd raiplaysound-cli
make install-dev

make install-dev keeps the command in ~/.local/bin/raiplaysound-cli, but points it at the project-local launcher so source edits take effect immediately.

Run the CLI from the user install:

~/.local/bin/raiplaysound-cli --version

Install and load the optional daily favourites LaunchAgent:

make launchagent-install

This also installs ~/.local/bin/raiplaysound-cli-daily-sync, then schedules it as a user LaunchAgent at 08:00 every day. The companion runs raiplaysound-cli download --favourites, compares the downloaded audio files before and after the run, and sends a plain-text summary email through msmtp when email settings are configured. It refreshes only the daily sync companion and LaunchAgent; it does not rewrite the user-facing ~/.local/bin/raiplaysound-cli command.

The daily sync install and run path follows the Makefile, LaunchAgent plist, and companion command:

flowchart LR
  accTitle: Daily favourites sync
  accDescr: Shows how the optional LaunchAgent is installed, scheduled, tested, and run.
  install["make launchagent-install"] --> companion["Install daily sync companion"]
  companion --> plist["Write user LaunchAgent plist"]
  plist --> load["Load com.raiplaysound-cli.daily-sync"]
  load --> schedule["Run daily at 08:00"]
  schedule --> sync["Download configured favourites"]
  sync --> report["Send or dry-run email summary"]
Loading

Remove the scheduled job:

make launchagent-uninstall

This unloads and removes the LaunchAgent plist. It leaves installed command files in place; use make uninstall when you also want to remove the CLI and daily sync companion.

Test the daily sync manually without sending email:

~/.local/bin/raiplaysound-cli-daily-sync --dry-run-email

Run the same sync for real, including email delivery when configured:

~/.local/bin/raiplaysound-cli-daily-sync

Trigger the loaded LaunchAgent immediately:

launchctl kickstart -k gui/$(id -u)/com.raiplaysound-cli.daily-sync

Follow the daily sync log while it runs:

tail -f ~/Library/Logs/raiplaysound-cli-daily-sync.log

Check the scheduler state:

launchctl print gui/$(id -u)/com.raiplaysound-cli.daily-sync

Print the focused top-level command overview:

~/.local/bin/raiplaysound-cli

Use command-specific help for detailed options:

~/.local/bin/raiplaysound-cli list --help
~/.local/bin/raiplaysound-cli search --help
~/.local/bin/raiplaysound-cli download --help

The subcommand help screens are organized by topic and include short examples, so they are the best place to discover the supported flags in practice.

Or run it directly from the project venv:

.venv/bin/python -m raiplaysound_cli --version

Alternative installs from Git:

pip install "git+https://github.com/marcomc/raiplaysound-cli.git"
pip install --user "git+https://github.com/marcomc/raiplaysound-cli.git"
pipx install "git+https://github.com/marcomc/raiplaysound-cli.git"

Uninstalling:

Install method Uninstall command
make install make uninstall
make install-dev make uninstall-dev
pip install ... pip uninstall raiplaysound-cli
pipx install ... pipx uninstall raiplaysound-cli

Capabilities

  • Accepts either a RaiPlaySound program_slug or full program_url
  • Supports list, search, download, repair, and outputs commands
  • Lists stations, programs, seasons, and episodes
  • Searches stations, programs, locally cached seasons/groupings, and locally cached episode metadata
  • Downloads episodes into ~/Music/RaiPlaySound/<slug>/
  • Repairs existing local filenames from the per-show metadata cache without deleting or re-downloading audio
  • Uses yt-dlp --download-archive for idempotent repeat runs
  • Uses RaiPlaySound episode date_tracking metadata for episode dates, so filenames and generated feeds follow the editorial episode date rather than a later technical publication date when Rai exposes both.
  • Supports audio formats mp3, m4a, aac, ogg, opus, flac, and wav
  • Supports season filtering, episode ID filtering, and episode URL filtering
  • Supports automatic re-download of archive-marked but missing local files
  • Generates Rich-based live per-episode download progress with megabyte size tracking and aggregate transfer speed
  • Caches program catalog metadata and per-show episode metadata
  • Generates optional feed.xml RSS output and playlist.m3u playlist output
  • Downloads each program cover image into the program folder and references it from generated RSS feeds
  • Provides an optional macOS LaunchAgent companion that runs the configured favourites download once a day and emails a compact msmtp summary
  • Keeps a RaiPlayPodcast index.html landing page in the target root with program artwork, descriptions, local episode counts, latest downloaded episode dates, RSS links, and Apple Podcasts app links only for programs that currently have a feed.xml
  • Preserves the existing KEY=VALUE dot-config format at ~/.raiplaysound-cli.conf

Configuration

The CLI reads optional user defaults from:

  • ~/.raiplaysound-cli.conf

Use raiplaysound-cli --config /path/to/config <command> for a one-off run with a different defaults file.

Install the example config:

cp ./.raiplaysound-cli.conf.example ~/.raiplaysound-cli.conf

Example values:

TARGET_BASE="$HOME/Music/RaiPlaySound"
AUDIO_FORMAT="mp3"
JOBS=5
FAVORITES="musicalbox,profili"
GROUP_BY="auto"
STATION_FILTER="radio2"
CATALOG_MAX_AGE_HOURS=2160
EMAIL_TO="you@example.test"
EMAIL_FROM="you+raiplaysound-cli@example.test"
EMAIL_FROM_NAME="raiplaysound-cli"
EMAIL_SUBJECT_PREFIX="[raiplaysound-cli]"
EMAIL_CONFIG="$HOME/.config/msmtp/config"
MSMTP_BIN="msmtp"

Cache-age defaults are intentionally different:

  • METADATA_MAX_AGE_HOURS defaults to 24 for per-show episode metadata
  • CATALOG_MAX_AGE_HOURS defaults to 2160 (90 days) for the full program catalog used by list programs

If you want fresher program listings by default, lower CATALOG_MAX_AGE_HOURS in your config, for example:

CATALOG_MAX_AGE_HOURS=24

Supported config keys:

Config key CLI option Scope
AUDIO_FORMAT --format download
JOBS --jobs download
SEASONS_ARG --season download, list episodes
GROUPS_ARG --group download, list episodes
EPISODES_ARG --episode-ids download
EPISODE_URLS_ARG --episode-urls download
AUTO_REDOWNLOAD_MISSING --missing download
ENABLE_LOG --log download
DEBUG_PIDS --debug-pids download
LOG_PATH_ARG --log[=PATH] download
TARGET_BASE --target-base outputs
RSS_FEED --rss / --no-rss download
RSS_BASE_URL --rss-base-url download, repair, outputs
APPLE_PODCASTS --no-apple-podcasts outputs
PLAYLIST --playlist / --no-playlist download
FORCE_REFRESH_METADATA --refresh-metadata download
CLEAR_METADATA_CACHE --clear-metadata-cache download
METADATA_MAX_AGE_HOURS --metadata-max-age-hours download
FAVORITES --favourites download
HTTP_TIMEOUT_SECONDS n/a network requests
HTTP_RETRIES n/a network requests
HTTP_BACKOFF_SECONDS n/a network requests
FAVORITES_PROGRAM_TIMEOUT_SECONDS n/a download --favourites
FAVORITES_MAX_SECONDS n/a download --favourites
EMAIL_TO n/a daily sync email
EMAIL_FROM n/a daily sync email
EMAIL_FROM_NAME n/a daily sync email
EMAIL_SUBJECT_PREFIX n/a daily sync email
EMAIL_CONFIG n/a daily sync email
MSMTP_BIN n/a daily sync email
DAILY_SYNC_LOG n/a daily sync
DAILY_SYNC_MAX_SECONDS n/a daily sync
DAILY_SYNC_SCAN_TIMEOUT_SECONDS n/a daily sync
GROUP_BY --group-by list programs
PODCASTS_SORTED --sorted list programs
STATION_FILTER --filter list programs
FORCE_REFRESH_CATALOG --refresh-catalog list programs
CATALOG_MAX_AGE_HOURS --catalog-max-age-hours list programs
STATIONS_DETAILED --detailed list stations
SHOW_URLS --show-urls list episodes, search
PAGER --pager list, search
INPUT <program_slug|program_url> download, list seasons, list episodes

FAVORITES accepts a comma-separated list of RaiPlaySound program slugs or full program URLs. Running raiplaysound-cli download --favourites iterates that list in separate child runs, so one failed or timed-out program does not stop the remaining favourites. If you do not pass --season, --group, --episode-ids, or --episode-urls, each favourite downloads only the latest season by default.

HTTP_TIMEOUT_SECONDS, HTTP_RETRIES, and HTTP_BACKOFF_SECONDS apply to RaiPlaySound HTTP requests across CLI commands. HTTP_RETRIES retries transient network failures, HTTP 429, and HTTP 5xx responses with exponential backoff; HTTP 404 is not retried. FAVORITES_PROGRAM_TIMEOUT_SECONDS limits each favourite child run, and FAVORITES_MAX_SECONDS limits the whole favourites run. Set a favourites or daily-sync watchdog timeout to 0 to disable that specific limit.

The daily sync companion uses the same FAVORITES and download defaults. It does not configure msmtp; it only uses the existing EMAIL_CONFIG file. If EMAIL_TO, msmtp, or the msmtp config is missing, the download still runs and the email step is skipped with a note in ~/Library/Logs/raiplaysound-cli-daily-sync.log. Use raiplaysound-cli-daily-sync --config /path/to/config to run the sync from an alternate config file; the companion passes that same config to the child download command. DAILY_SYNC_SCAN_TIMEOUT_SECONDS bounds the before/after file snapshots used to detect new downloads. DAILY_SYNC_MAX_SECONDS is an outer watchdog for the scheduled wrapper; if either guard fires, the companion still sends a failed summary email when email is configured.

FORCE_REFRESH_CATALOG and CATALOG_MAX_AGE_HOURS affect only list programs. They do not change the per-show metadata cache used by download and list episodes.

RSS_BASE_URL must be a direct file-serving base URL. The CLI builds enclosure URLs as:

<RSS_BASE_URL>/<program_slug>/<filename>

Public enclosure filenames are URL-encoded while preserving the filename form stored on disk, so episode titles with accents remain fetchable by podcast clients on servers that expose those files directly.

That means ordinary browser share-page URLs with query strings are not valid RSS enclosure bases.

Usage

Quick Start

raiplaysound-cli list stations
raiplaysound-cli list programs
raiplaysound-cli search lucio dalla
raiplaysound-cli list episodes america7
raiplaysound-cli download america7
raiplaysound-cli download --favourites
raiplaysound-cli repair filenames musicalbox
raiplaysound-cli outputs --index

Common Workflows

Discover stations and programs

raiplaysound-cli list stations
raiplaysound-cli list programs
raiplaysound-cli list programs --filter radio2
raiplaysound-cli list stations --detailed

Example output:

Available RaiPlaySound radio stations (7):
┏━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━┓
┃ Name          ┃ Programs ┃ Slug         ┃ Page ┃
┡━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━┩
│ Rai Radio 1   │      123 │ radio1       │ open │
│ Rai Radio 2   │      107 │ radio2       │ open │
│ Rai Radio 3   │      198 │ radio3       │ open │
└───────────────┴──────────┴──────────────┴──────┘

Next:
  programs for one station: raiplaysound-cli list programs --filter radio2
Programs grouped alphabetically (107):
┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━┓
┃ Name                 ┃ Slug          ┃ Station ┃ Years     ┃ Groupings ┃ Description                  ┃ Page ┃
┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━┩
│ 1 M Next             │ 1mnext        │ radio2  │ 2025      │         — │ —                            │ open │
│ 100 Volte Alberto    │ 100voltealbe… │ radio2  │ 2020-2025 │         — │ —                            │ open │
│ Sordi                │               │         │           │           │                              │      │
│ A qualcuno piace     │ aqualcunopia… │ radio2  │ 2025-2026 │         2 │ Un programma del mattino... │ open │
│ Radio2               │               │         │           │           │                              │      │
└──────────────────────┴───────────────┴─────────┴───────────┴───────────┴──────────────────────────────┴──────┘

Next:
  one station:   raiplaysound-cli list programs --filter radio2
  one program:   raiplaysound-cli list episodes 1mnext
  download one:  raiplaysound-cli download 1mnext

list programs intentionally prints the full table by default so the output is pipe-friendly and easy to capture. For large catalogs, the most practical ways to narrow or browse the output are --filter, --sorted, or the opt-in --pager flag rather than auto-paging by default.

Search cached metadata

raiplaysound-cli search lucio
raiplaysound-cli search burnt sugar --json
raiplaysound-cli search radio2 --show-urls

search always queries live stations and the cached-or-refreshed global program catalog. Season/grouping and episode matches come from local caches that were already populated by earlier list or download runs.

If RaiPlaySound is temporarily unavailable, search still returns any local season/grouping and episode matches it can find from existing caches instead of failing outright. Live station and program sections are left empty in that case, and the cache summary notes the live lookup failure.

That means:

  • station and program matches are available immediately
  • season/grouping matches depend on cached list seasons payloads
  • episode matches depend on local .metadata-cache.tsv files and, when available, cached list episodes payloads

When episode metadata is refreshed through downloads, the per-show .metadata-cache.tsv now also stores a searchable text field derived from the episode JSON payload. That lets search match titles, authors, descriptions, and other metadata strings that Rai exposes for the cached episode.

Inspect seasons and episodes

raiplaysound-cli list seasons america7
raiplaysound-cli list episodes america7
raiplaysound-cli list episodes america7 --show-urls
raiplaysound-cli list seasons america7 --json
raiplaysound-cli list episodes battiti --group speciali

Season listing uses a lightweight discovery path, so list seasons avoids download-side metadata refreshes and is typically faster than episode inspection or download preparation.

Repeated list seasons <program> runs now also use a dedicated list-summary cache under the state directory, separate from download-side metadata, so grouped programs do not need to re-enumerate every grouping on every call.

For programs that use non-season groupings on RaiPlaySound, list seasons also reports those groupings instead of incorrectly collapsing everything into a flat episode list. For example, programs may expose specials, named thematic collections, or year and period buckets instead of numbered seasons.

Grouping discovery is now filter-first: when RaiPlaySound exposes selector filters in the program JSON, the CLI treats those filters as the authoritative group source even if the site uses custom route names such as cicli, clip, or other product-specific paths.

list seasons is also the long-term grouping inspector name for the CLI, even when the discovered program structure uses non-season collections.

When a program exposes real seasons, list seasons <program> --season <n> narrows the output to the requested season. For non-season groupings or flat programs, --season is rejected instead of being silently ignored.

Season selectors can be ordinary season numbers or year-style season keys such as 2025 when RaiPlaySound models seasons that way.

list episodes <program> also aggregates episodes across discovered groupings for grouped programs, instead of only listing the currently selected subpage.

Episode listing now uses a read-only path: it can reuse an existing .metadata-cache.tsv to improve titles and dates, but it does not refresh or rewrite that cache during list episodes.

Repeated list episodes runs also use a list-only cache keyed by the resolved source scope, so repeated calls for the same program or grouping can reuse the previous listing without touching download artifacts.

Those list-only caches are versioned, and stale or incompatible cached payloads are rebuilt automatically instead of being reused indefinitely.

When a program uses non-season groupings, list episodes <program> --group <key> narrows the output to one or more discovered grouping keys or labels. For example:

raiplaysound-cli list episodes battiti --group speciali
raiplaysound-cli list episodes profili --group speciale-lucio-dalla

--group cannot be combined with --season.

list seasons <program> now renders seasons and non-season groupings in a table with:

  • Program
  • Type
  • Name
  • Episodes
  • Selector
  • Published

For grouped programs, the footer now shows compact generic download --group examples instead of repeating one command per discovered grouping.

For flat programs that do not expose real seasons or other groupings, list episodes does not invent a fake S1 column. Those programs are shown as a plain episode list, and JSON output reports the season as null.

download <program> now follows the same grouping-aware discovery path as list episodes, so grouped programs can be downloaded across their discovered collections instead of only the root subpage.

Download startup is also narrower now: episode discovery still happens across the selected program or grouping, but metadata refresh is deferred until after episode filtering. When you use selectors like --group, --episode-ids, or --episode-urls, the CLI refreshes metadata only for the episodes that will actually be downloaded.

During that preparation phase, the CLI now prints explicit startup steps such as source discovery, episode enumeration, metadata refresh, and archive-file checks so long grouped downloads are not silent before transfer starts.

If you prefer a batch workflow, set FAVORITES in ~/.raiplaysound-cli.conf and run:

raiplaysound-cli download --favourites

That iterates each configured favourite program. By default, seasonal programs download only their latest season in this mode, matching the normal single-program default. You can still override the selection for every favourite in the batch with options such as --season all or --group speciali.

Once transfers begin, each per-episode progress row now shows downloaded size in megabytes, for example 5.0/10.0 MB, while the overall row shows aggregate transfer speed.

Download workers are now split into two stages:

  • yt-dlp workers fetch source audio plus sidecar metadata and thumbnails into a hidden per-run workspace
  • a separate ffmpeg queue converts those completed downloads into the final requested audio format and appends the archive entry only after conversion succeeds

That means long local conversion or thumbnail-embedding work no longer blocks the next network download from starting as soon as a download worker becomes free.

The staged conversion path also preserves richer embedded tags for seasonal shows by restoring episode titles plus season and episode numbering from the downloaded sidecar metadata.

When RaiPlaySound exposes both an editorial episode date and a later technical publication date, the CLI uses the editorial date_tracking value from the episode JSON. That date is used for the final audio filename, RSS pubDate, RSS item matching, playlist titles, and missing-file detection.

When --missing is not enabled, the CLI now skips the archive/file existence scan entirely instead of paying that startup cost on every download.

Repair existing filenames

Use repair filenames when local audio files were downloaded with a technical publication date but the metadata cache has the corrected RaiPlaySound date_tracking date.

Preview changes without touching files:

raiplaysound-cli repair filenames musicalbox
raiplaysound-cli repair filenames --favourites

Apply the planned renames:

raiplaysound-cli repair filenames musicalbox --apply
raiplaysound-cli repair filenames --favourites --apply

The repair command matches local audio files to .metadata-cache.tsv by normalized title. If the cache is partial, it can also use an unambiguous DD/MM/YYYY date embedded in the local title, such as Musical Box del 12/04/2026. It changes only the first date segment in the filename and skips ambiguous titles or destination conflicts. When RSS_FEED or PLAYLIST is enabled in configuration, --apply also regenerates feed.xml, playlist.m3u, and the root index.html.

If the metadata cache itself needs to be refreshed first, run:

raiplaysound-cli download PROGRAM_SLUG --clear-metadata-cache --refresh-metadata --rss --playlist

Then run the filename repair in dry-run mode before applying it.

Example output:

Available seasons for america7 (https://www.raiplaysound.it/programmi/america7):
  - Season 1: 71 episodes (published: 2023-2025)
  - Season 2: 17 episodes (published: 2025-2026)
Episodes for america7 (https://www.raiplaysound.it/programmi/america7):
┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┓
┃ Season ┃ Date       ┃ Episode          ┃ ID               ┃ URL              ┃
┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━┩
│ S2     │ 2026-03-13 │ America7 S2E17   │ 692674e0-ceb7-4… │ https://www.rai… │
│        │            │ La prima guerra  │                  │                  │
│        │            │ A.I.             │                  │                  │
│ S2     │ 2026-03-06 │ America7 S2E16   │ 7e2a8652-b220-4… │ https://www.rai… │

Download episodes

raiplaysound-cli download [OPTIONS] <program_slug|program_url>
raiplaysound-cli download musicalbox
raiplaysound-cli download --format mp3 --jobs 5 musicalbox
raiplaysound-cli download --season 1,2 america7
raiplaysound-cli download battiti --group speciali
raiplaysound-cli download --missing america7

Example completion summary:

Completed: done=1, skipped=0, errors=0

Download specific episode selections

raiplaysound-cli download --episode-ids <id1,id2> america7
raiplaysound-cli download --episode-url <episode-url> america7

Generate RSS and playlists

raiplaysound-cli download --rss --playlist musicalbox

The RSS feed is written as feed.xml. RSS is an XML format, and .xml is the most compatible extension for podcast clients and static file hosting.

Every download run also refreshes program-level assets in the show's folder: the program details cache, the local cover image, and the root ~/Music/RaiPlaySound/index.html page. The index page is titled RaiPlayPodcast and lists each program folder with artwork, title, author, description, local episode count, latest local episode date, and an RSS link only when that program folder currently contains feed.xml. When RSS_BASE_URL is configured, each RSS link is paired with an Apple Podcasts link using the pcast:// URL scheme. iOS support for third-party podcast URL schemes is best-effort, so the normal RSS link remains available as a fallback. When cached episode metadata can be matched to a local file, the latest date follows Rai's editorial episode date rather than the file's technical publication date. The generated index uses paths relative to itself, such as program-slug/cover.jpg, for local folder and artwork links. RSS links are shown only for program folders that currently contain feed.xml; when RSS_BASE_URL is configured, those RSS links point to <RSS_BASE_URL>/<program_slug>/feed.xml. The index generator also stores apple-touch-icon.png beside index.html, displays it in the page heading, and references it with Apple touch icon metadata, so iPhone Home Screen bookmarks can use the bundled RaiPlayPodcast-style icon. When the target root already contains older program folders without program metadata or cover art, index generation refreshes those missing assets for each folder.

Regenerate local output files from the files already present on disk, without downloading episodes again. Use --target-base, --rss-base-url, and --no-apple-podcasts to try alternate folders, link hosts, or index link behavior without changing ~/.raiplaysound-cli.conf. Apple Podcasts links are included by default when the index can use absolute RSS URLs; set APPLE_PODCASTS=false in config or pass --no-apple-podcasts to omit them.

raiplaysound-cli outputs --index
raiplaysound-cli outputs --rss --index --rss-base-url http://podcasts.example.test/audio
raiplaysound-cli outputs --all --no-apple-podcasts
raiplaysound-cli outputs --target-base /tmp/RaiPlaySound --all --rss-base-url http://podcasts.example.test/audio

Command forms:

raiplaysound-cli download [OPTIONS] <program_slug|program_url>
raiplaysound-cli list <stations|programs> [OPTIONS]
raiplaysound-cli list <seasons|episodes> [OPTIONS] <program_slug|program_url>
raiplaysound-cli outputs [OPTIONS]

Output folder contents:

File Producer Purpose
*.m4a / *.mp3 / ... yt-dlp Downloaded audio episodes
cover.* CLI Local program artwork
.program-info.json CLI Per-show program title, author, description, and artwork metadata
.download-archive.txt yt-dlp Idempotency archive
.metadata-cache.tsv CLI Per-show metadata cache
feed.xml CLI Optional RSS 2.0 podcast feed
playlist.m3u CLI Optional local playlist
*.log CLI Optional run/debug log

Target root contents:

File Producer Purpose
index.html CLI Static browsable program index for the target root
apple-touch-icon.png CLI Home Screen icon for iPhone bookmarks

Development

Common commands:

make install
make install-dev
make launchagent-install
make launchagent-uninstall
make uninstall
make run
make test
make lint
make lint-docs

Validation currently includes:

  • ruff check src tests
  • mypy src tests
  • black --check src tests
  • python -m py_compile src/raiplaysound_cli/*.py
  • pytest
  • markdownlint

Testing

See docs/TESTING.md for the full validation and regression-test guide for users and AI agents.

Disclaimer

RaiPlaySound CLI is an independent, community-developed project and is not affiliated with, endorsed by, or officially connected with RAI, RaiPlaySound, or the official RaiPlaySound application. "RAI", "RaiPlaySound", radio station names, program names, and related marks remain the property of their respective owners.

About

RaiPlaySound CLI for program discovery, listing, and incremental episode downloads

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors