mopidy: add module

This is adapted from the `services.mopidy` NixOS module. The
difference is the setting can be configured with Nix language, taking
advantage of generators from nixpkgs. The module is also suited more
for user-specific configuration, removing the `extraConfigFiles` and
`dataDir` option.
This commit is contained in:
Gabriel Arazas 2022-01-21 21:22:52 +08:00 committed by Robert Helgesson
parent 32a7da69dc
commit cb9f03d519
No known key found for this signature in database
GPG Key ID: 36BDAA14C2797E89
9 changed files with 204 additions and 0 deletions

3
.github/CODEOWNERS vendored
View File

@ -346,6 +346,9 @@
/modules/services/mbsync.nix @pjones
/modules/services/mopidy.nix @foo-dogsquared
/tests/modules/services/mopidy @foo-dogsquared
/modules/services/mpdris2.nix @pjones
/modules/services/mpd-discord-rpc.nix @Kranzes

View File

@ -55,6 +55,12 @@
github = "chisui";
githubId = 4526429;
};
foo-dogsquared = {
name = "Gabriel Arazas";
email = "foo.dogsquared@gmail.com";
github = "foo-dogsquared";
githubId = 34962634;
};
olmokramer = {
name = "Olmo Kramer";
email = "olmokramer@users.noreply.github.com";

View File

@ -2471,6 +2471,14 @@ in
A new module is available: 'programs.tealdeer'.
'';
}
{
time = "2022-05-18T22:09:45+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'services.mopidy'.
'';
}
];
};
}

View File

@ -212,6 +212,7 @@ let
./services/lorri.nix
./services/mako.nix
./services/mbsync.nix
./services/mopidy.nix
./services/mpd.nix
./services/mpdris2.nix
./services/mpd-discord-rpc.nix

136
modules/services/mopidy.nix Normal file
View File

@ -0,0 +1,136 @@
{ config, options, lib, pkgs, ... }:
with lib;
let
cfg = config.services.mopidy;
# The configuration format of Mopidy. It seems to use configparser with
# some quirky handling of its types. You can see how they're handled in
# `mopidy/config/types.py` from the source code.
toMopidyConf = generators.toINI {
mkKeyValue = generators.mkKeyValueDefault {
mkValueString = v:
if isList v then
"\n " + concatStringsSep "\n " v
else
generators.mkValueStringDefault { } v;
} " = ";
};
mopidyEnv = pkgs.buildEnv {
name = "mopidy-with-extensions-${pkgs.mopidy.version}";
paths = closePropagation cfg.extensionPackages;
pathsToLink = [ "/${pkgs.mopidyPackages.python.sitePackages}" ];
buildInputs = [ pkgs.makeWrapper ];
postBuild = ''
makeWrapper ${pkgs.mopidy}/bin/mopidy $out/bin/mopidy \
--prefix PYTHONPATH : $out/${pkgs.mopidyPackages.python.sitePackages}
'';
};
# Nix-representable format for Mopidy config.
mopidyConfFormat = { }: {
type = with types;
let
valueType = nullOr (oneOf [ bool float int str (listOf valueType) ])
// {
description = "Mopidy config value";
};
in attrsOf (attrsOf valueType);
generate = name: value: pkgs.writeText name (toMopidyConf value);
};
settingsFormat = mopidyConfFormat { };
in {
meta.maintainers = [ hm.maintainers.foo-dogsquared ];
options.services.mopidy = {
enable = mkEnableOption "Mopidy music player daemon";
extensionPackages = mkOption {
type = with types; listOf package;
default = [ ];
example = literalExpression
"with pkgs; [ mopidy-spotify mopidy-mpd mopidy-mpris ]";
description = ''
Mopidy extensions that should be loaded by the service.
'';
};
settings = mkOption {
type = settingsFormat.type;
default = { };
example = literalExpression ''
{
file = {
media_dirs = [
"$XDG_MUSIC_DIR|Music"
"~/library|Library"
];
follow_symlinks = true;
excluded_file_extensions = [
".html"
".zip"
".jpg"
".jpeg"
".png"
];
};
# Please don't put your mopidy-spotify configuration in the public. :)
# Think of your Spotify Premium subscription!
spotify = {
client_id = "CLIENT_ID";
client_secret = "CLIENT_SECRET";
};
}
'';
description = ''
Configuration written to
<filename>$XDG_CONFIG_HOME/mopidy/mopidy.conf</filename>.
</para><para>
See <link xlink:href="https://docs.mopidy.com/en/latest/config/"/> for
more details.
'';
};
};
config = mkIf cfg.enable {
assertions =
[ (hm.assertions.assertPlatform "services.mopidy" pkgs platforms.linux) ];
xdg.configFile."mopidy/mopidy.conf".source =
settingsFormat.generate "mopidy-${config.home.username}" cfg.settings;
systemd.user.services.mopidy = {
Unit = {
Description = "mopidy music player daemon";
Documentation = [ "https://mopidy.com/" ];
After = [ "network.target" "sound.target" ];
};
Service = { ExecStart = "${mopidyEnv}/bin/mopidy"; };
Install.WantedBy = [ "default.target" ];
};
systemd.user.services.mopidy-scan = {
Unit = {
Description = "mopidy local files scanner";
Documentation = [ "https://mopidy.com/" ];
After = [ "network.target" "sound.target" ];
};
Service = {
ExecStart = "${mopidyEnv}/bin/mopidy local scan";
Type = "oneshot";
};
Install.WantedBy = [ "default.target" ];
};
};
}

View File

@ -153,6 +153,7 @@ import nmt {
./modules/services/home-manager-auto-upgrade
./modules/services/kanshi
./modules/services/lieer
./modules/services/mopidy
./modules/services/mpd
./modules/services/pantalaimon
./modules/services/pbgopy

View File

@ -0,0 +1,10 @@
[file]
enabled = true
media_dirs =
$XDG_MUSIC_DIR|Music
~/Downloads|Downloads
[spotify]
client_id = TOTALLY_NOT_A_FAKE_CLIENT_ID
client_secret = YOU_CAN_USE_ME_FOR_YOUR_SPOTIFY_PREMIUM_SUBSCRIPTION
enabled = true

View File

@ -0,0 +1,38 @@
{ config, pkgs, ... }:
{
services.mopidy = {
enable = true;
settings = {
file = {
enabled = true;
media_dirs = [ "$XDG_MUSIC_DIR|Music" "~/Downloads|Downloads" ];
};
spotify = {
enabled = true;
client_id = "TOTALLY_NOT_A_FAKE_CLIENT_ID";
client_secret = "YOU_CAN_USE_ME_FOR_YOUR_SPOTIFY_PREMIUM_SUBSCRIPTION";
};
};
};
test.stubs.mopidy = {
version = "0";
outPath = null;
buildScript = ''
mkdir -p $out/bin
touch $out/bin/mopidy
chmod +x $out/bin/mopidy
'';
};
nmt.script = ''
assertFileExists home-files/.config/systemd/user/mopidy.service
assertFileExists home-files/.config/systemd/user/mopidy-scan.service
assertFileExists home-files/.config/mopidy/mopidy.conf
assertFileContent home-files/.config/mopidy/mopidy.conf \
${./basic-configuration.conf}
'';
}

View File

@ -0,0 +1 @@
{ mopidy-basic-configuration = ./basic-configuration.nix; }