diff --git a/.github/labeler.yml b/.github/labeler.yml index de310a412..6c0b20b9e 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -24,6 +24,7 @@ - modules/services/pasystray.nix - modules/services/playerctld.nix - modules/services/pulseeffects.nix + - modules/services/rescrobbled.nix - modules/services/spotifyd.nix - tests/modules/services/mpd/**/* "automation": diff --git a/modules/misc/news/2025/08/2025-08-05_21-18-50.nix b/modules/misc/news/2025/08/2025-08-05_21-18-50.nix new file mode 100644 index 000000000..d0f96289f --- /dev/null +++ b/modules/misc/news/2025/08/2025-08-05_21-18-50.nix @@ -0,0 +1,12 @@ +{ pkgs, ... }: +{ + time = "2025-08-06T04:18:50+00:00"; + condition = pkgs.stdenv.hostPlatform.isLinux; + message = '' + A new service is available: 'services.rescrobbled'. + + Rescrobbled is a music scrobbler daemon. It detects active media players + running on D-Bus using MPRIS automatically updates "now playing" status, and + scrobbles songs to Last.fm or ListenBrainz-compatible services as they play. + ''; +} diff --git a/modules/services/rescrobbled.nix b/modules/services/rescrobbled.nix new file mode 100644 index 000000000..c58bb3bf0 --- /dev/null +++ b/modules/services/rescrobbled.nix @@ -0,0 +1,68 @@ +{ + lib, + pkgs, + config, + ... +}: +let + tomlFormat = pkgs.formats.toml { }; + cfg = config.services.rescrobbled; +in +{ + meta.maintainers = [ lib.maintainers.awwpotato ]; + + options.services.rescrobbled = { + enable = lib.mkEnableOption "rescrobbled, a MPRIS music scrobbler daemon"; + package = lib.mkPackageOption pkgs "rescrobbled" { }; + + settings = lib.mkOption { + inherit (tomlFormat) type; + default = { }; + description = '' + Configuration written to {file}`$XDG_CONFIG_HOME/rescrobbled/config.toml` + See for + the full list of options. + ''; + example = { + lastfm-key = "Last.fm API key"; + lastfm-secret = "Last.fm API secret"; + min-play-time = 0; + player-whitelist = [ "Player MPRIS identity or bus name" ]; + filter-script = "path/to/script"; + use-track-start-timestamp = false; + + listenbrainz = [ + { + url = "Custom API URL"; + token = "User token"; + } + ]; + }; + }; + }; + + config = lib.mkIf cfg.enable { + assertions = [ + (lib.hm.assertions.assertPlatform "services.rescrobbled" pkgs lib.platforms.linux) + ]; + + home.packages = [ cfg.package ]; + + xdg.configFile."rescrobbled/config.toml" = lib.mkIf (cfg.settings != { }) { + source = tomlFormat.generate "rescrobbled-config" cfg.settings; + }; + + systemd.user.services.rescrobbled = { + Unit = { + Description = "An MPRIS scrobbler"; + Documentation = "https://github.com/InputUsername/rescrobbled"; + Wants = [ "network-online.target" ]; + After = [ "network-online.target" ]; + }; + + Service.ExecStart = lib.getExe cfg.package; + + Install.WantedBy = [ "default.target" ]; + }; + }; +} diff --git a/tests/modules/services/rescrobbled/basic-config.nix b/tests/modules/services/rescrobbled/basic-config.nix new file mode 100644 index 000000000..72bbd9109 --- /dev/null +++ b/tests/modules/services/rescrobbled/basic-config.nix @@ -0,0 +1,46 @@ +{ pkgs, ... }: +{ + services.rescrobbled = { + enable = true; + settings = { + lastfm-key = "Last.fm API key"; + lastfm-secret = "Last.fm API secret"; + min-play-time = 0; + player-whitelist = [ "Player MPRIS identity or bus name" ]; + filter-script = "path/to/script"; + use-track-start-timestamp = false; + + listenbrainz = [ + { + url = "Custom API URL"; + token = "User token"; + } + ]; + }; + }; + + nmt.script = '' + assertFileExists home-files/.config/rescrobbled/config.toml + assertFileContent home-files/.config/rescrobbled/config.toml \ + ${pkgs.writeText "settings-expected" '' + filter-script = "path/to/script" + lastfm-key = "Last.fm API key" + lastfm-secret = "Last.fm API secret" + min-play-time = 0 + player-whitelist = ["Player MPRIS identity or bus name"] + use-track-start-timestamp = false + + [[listenbrainz]] + token = "User token" + url = "Custom API URL" + ''} + + service=home-files/.config/systemd/user/rescrobbled.service + + assertFileExists $service + assertFileRegex $service 'Description=An MPRIS scrobbler' + assertFileRegex $service 'Wants=network-online.target' + assertFileRegex $service 'After=network-online.target' + assertFileRegex $service 'WantedBy=default.target' + ''; +} diff --git a/tests/modules/services/rescrobbled/default.nix b/tests/modules/services/rescrobbled/default.nix new file mode 100644 index 000000000..a283f574b --- /dev/null +++ b/tests/modules/services/rescrobbled/default.nix @@ -0,0 +1,4 @@ +{ lib, pkgs, ... }: +lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux { + rescrobbled-basic-config = ./basic-config.nix; +}