{ config, lib, pkgs, ... }: let inherit (lib) mkIf mkEnableOption mkPackageOption mkOption ; cfg = config.programs.pyradio; in { meta.maintainers = with lib.maintainers; [ magicquark ]; options.programs.pyradio = { enable = mkEnableOption "pyradio"; package = mkPackageOption pkgs "pyradio" { nullable = true; }; settings = mkOption { type = with lib.types; attrsOf (oneOf [ str int bool ]); default = { }; example = { enable_clock = true; enable_notifications = 0; player = "mpv"; theme = "dark_16_colors"; time_format = 0; use_transparency = true; }; description = '' Options to add to the PyRadio {file}`config` file. See for available options. ''; }; stations = mkOption { type = with lib.types; listOf (submodule { options = { name = mkOption { type = str; description = "Display name of the radio station."; }; url = mkOption { type = str; description = "Stream URL of the radio station."; }; buffering = mkOption { type = nullOr (submodule { options = { seconds = mkOption { type = ints.positive; description = "Number of seconds to buffer the stream."; }; bitrate = mkOption { type = ints.positive; default = 128; description = "Bitrate of the stream in kbps (modify only if using MPlayer)."; }; }; }); description = "Buffering configuration to apply to the station."; default = null; }; encoding = mkOption { type = str; default = ""; description = "Encoding of the station's metadata block."; }; forceHttp = mkOption { type = bool; default = false; description = "If enabled, the connection is forced to use http (note when false it can either use http or https)."; }; iconUrl = mkOption { type = str; default = ""; description = "URL of an icon to be shown in desktop notifications."; }; profile = mkOption { type = str; default = ""; description = "Name of the profile to use when using mpv or mplayer."; }; volume = mkOption { type = ints.between 0 130; default = 50; description = "Volume to use for the station."; }; }; }); default = [ ]; example = [ { name = "DEF CON Radio (SomaFM)"; url = "https://somafm.com/defcon256.pls"; } { name = "Intense Radio - We Love Dance!"; url = "https://secure.live-streams.nl/flac.ogg"; } ]; description = '' Radio stations to add to the {file}`stations.csv` file. If empty, {file}`stations.csv` defaults to the built-in playlist. To add a group, add a station with the url set to "-" and the name set to the name of the group. Its order in the list will be where it appears in `pyradio`. ''; }; }; config = mkIf cfg.enable { home.packages = mkIf (cfg.package != null) [ cfg.package ]; xdg.configFile."pyradio/config" = mkIf (cfg.settings != { }) { text = let renderedSettings = lib.generators.toINIWithGlobalSection { } { globalSection = cfg.settings; }; in lib.removeSuffix "\n\n" '' # Generated by Home Manager. ${renderedSettings} ''; }; xdg.configFile."pyradio/stations.csv" = mkIf (cfg.stations != [ ]) { text = let escapeCSV = s: if lib.hasInfix "," s || lib.hasInfix "\"" s then "\"${lib.replaceStrings [ "\"" ] [ "\"\"" ] s}\"" else s; stationsToCSV = stations: let body = lib.concatMapStringsSep "\n" ( station: lib.concatStringsSep "," [ (escapeCSV station.name) (escapeCSV station.url) station.encoding (escapeCSV station.iconUrl) (escapeCSV station.profile) (lib.optionalString ( station.buffering != null ) "${toString station.buffering.seconds}@${toString station.buffering.bitrate}") (if station.forceHttp then "1" else "0") (toString station.volume) ] ) stations; in "${body}\n"; in stationsToCSV cfg.stations; }; }; }