pyradio: add module
This commit is contained in:
parent
fdafcac367
commit
2a08ab21ab
8 changed files with 193 additions and 0 deletions
9
modules/misc/news/2026/01/2026-01-19_03-12-38.nix
Normal file
9
modules/misc/news/2026/01/2026-01-19_03-12-38.nix
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
time = "2026-01-19T03:12:38+00:00";
|
||||||
|
condition = true;
|
||||||
|
message = ''
|
||||||
|
A new module `programs.pyradio` is available.
|
||||||
|
|
||||||
|
A curses based internet radio player.
|
||||||
|
'';
|
||||||
|
}
|
||||||
122
modules/programs/pyradio.nix
Normal file
122
modules/programs/pyradio.nix
Normal file
|
|
@ -0,0 +1,122 @@
|
||||||
|
{
|
||||||
|
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 <https://github.com/coderholic/pyradio/blob/master/pyradio/config>
|
||||||
|
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.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
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.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
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: "${escapeCSV station.name},${escapeCSV station.url}"
|
||||||
|
) stations;
|
||||||
|
in
|
||||||
|
"${body}\n";
|
||||||
|
in
|
||||||
|
stationsToCSV cfg.stations;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
11
tests/modules/programs/pyradio/basic-configuration.nix
Normal file
11
tests/modules/programs/pyradio/basic-configuration.nix
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
programs.pyradio = {
|
||||||
|
enable = true;
|
||||||
|
settings.enable_clock = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
nmt.script = ''
|
||||||
|
assertFileExists "home-files/.config/pyradio/config"
|
||||||
|
assertFileContent "home-files/.config/pyradio/config" ${./expected-config}
|
||||||
|
'';
|
||||||
|
}
|
||||||
28
tests/modules/programs/pyradio/custom-stations.nix
Normal file
28
tests/modules/programs/pyradio/custom-stations.nix
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
programs.pyradio = {
|
||||||
|
enable = true;
|
||||||
|
stations = [
|
||||||
|
{
|
||||||
|
name = "DEF CON Radio (SomaFM)";
|
||||||
|
url = "https://somafm.com/defcon256.pls";
|
||||||
|
}
|
||||||
|
# The stations below test the csv escaping functionality.
|
||||||
|
{
|
||||||
|
name = "DEF CON Radio, SomaFM";
|
||||||
|
url = "https://somafm.com/defcon256.pls";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "DEF CON Radio on \"SomaFM\"";
|
||||||
|
url = "https://somafm.com/defcon256.pls";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = ''DEF CON Radio on "SomaFM"'';
|
||||||
|
url = "https://somafm.com/defcon256.pls";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
nmt.script = ''
|
||||||
|
assertFileContent "home-files/.config/pyradio/stations.csv" ${./expected-stations.csv}
|
||||||
|
'';
|
||||||
|
}
|
||||||
5
tests/modules/programs/pyradio/default.nix
Normal file
5
tests/modules/programs/pyradio/default.nix
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
pyradio-basic-configuration = ./basic-configuration.nix;
|
||||||
|
pyradio-custom-stations = ./custom-stations.nix;
|
||||||
|
pyradio-empty-settings = ./empty-settings.nix;
|
||||||
|
}
|
||||||
11
tests/modules/programs/pyradio/empty-settings.nix
Normal file
11
tests/modules/programs/pyradio/empty-settings.nix
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
programs.pyradio = {
|
||||||
|
enable = true;
|
||||||
|
settings = { };
|
||||||
|
};
|
||||||
|
|
||||||
|
nmt.script = ''
|
||||||
|
assertPathNotExists "home-files/.config/pyradio/config"
|
||||||
|
assertPathNotExists "home-files/.config/pyradio/stations.csv"
|
||||||
|
'';
|
||||||
|
}
|
||||||
3
tests/modules/programs/pyradio/expected-config
Normal file
3
tests/modules/programs/pyradio/expected-config
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
# Generated by Home Manager.
|
||||||
|
|
||||||
|
enable_clock=true
|
||||||
4
tests/modules/programs/pyradio/expected-stations.csv
Normal file
4
tests/modules/programs/pyradio/expected-stations.csv
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
DEF CON Radio (SomaFM),https://somafm.com/defcon256.pls
|
||||||
|
"DEF CON Radio, SomaFM",https://somafm.com/defcon256.pls
|
||||||
|
"DEF CON Radio on ""SomaFM""",https://somafm.com/defcon256.pls
|
||||||
|
"DEF CON Radio on ""SomaFM""",https://somafm.com/defcon256.pls
|
||||||
|
Loading…
Add table
Add a link
Reference in a new issue