Giulio De Pasquale ea37aee1f9 fix: navidrome
2025-07-10 16:09:31 +01:00

171 lines
4.2 KiB
Nix

{ config, lib, pkgs, ... }:
let
inherit (lib) mkIf;
cfg = config.pepe.services.navidrome;
beetsConfigTemplate = pkgs.writeText "beets.conf.template" ''
directory: ${cfg.musicFolder}
plugins: embedart fetchart scrub lastgenre chroma
import:
write: yes
move: yes
incremental: yes
from_scratch: yes
group_albums: yes
log: ${cfg.musicFolder}/beets.log
original_date: yes
discogs:
user_token: "__DISCOGS_TOKEN__"
paths:
default: $albumartist/$album ($original_year)/$track - $title
singleton: $artist/singles/$title
match:
strong_rec_thresh: 0.20
musicbrainz:
extra_tags: [year]
lastfm:
user: peperunas
api_key: "__LASTFM_KEY__"
embedart:
auto: yes
fetchart:
auto: yes
lastfmkey: "__LASTFM_KEY__"
enforce_ratio: 0.5%
scrub:
auto: yes
lastgenre:
auto: yes
count: 5
min_weight: 10
prefer_specific: yes
force: yes
chroma:
auto: yes
'';
preStartBeetsDecrypt = ''
set -eu
sed \
-e "s|__DISCOGS_TOKEN__|$(cat ${config.age.secrets.discogs.path})|g" \
-e "s|__LASTFM_KEY__|$(cat ${config.age.secrets.lastfmKey.path})|g" \
${beetsConfigTemplate} > /run/beets.conf
'';
navidromeWrapped = pkgs.writeShellScriptBin "navidrome-wrapped" ''
set -eu
${preStartNavidromeDecrypt}
exec ${cfg.package}/bin/navidrome "$@"
'';
preStartNavidromeDecrypt = ''
set -eu
# export ND_LASTFM_APIKEY=$(cat ${config.age.secrets.lastfmKey.path})
# export ND_LASTFM_SECRET=$(cat ${config.age.secrets.lastfmSecret.path})
# export ND_SPOTIFY_ID=$(cat ${config.age.secrets.spotifyID.path})
# export ND_SPOTIFY_SECRET=$(cat ${config.age.secrets.spotifySecret.path})
'';
in
{
options.pepe.services.navidrome = with lib; {
enable = mkEnableOption "Enable navidrome";
enableBeets = mkEnableOption "Enable beets";
package = mkPackageOption pkgs "navidrome" { };
beetsPackage = mkPackageOption pkgs "beets" { };
domain = mkOption {
type = types.str;
default = null;
};
musicFolder = mkOption {
type = types.str;
default = "/media/Music";
description = "Path to the music library";
};
settings = mkOption {
type = types.attrs;
default = { };
description = "Additional settings for Navidrome";
};
};
config = mkIf cfg.enable {
services.navidrome = {
enable = true;
package = navidromeWrapped;
settings = {
MusicFolder = cfg.musicFolder;
LastFM.enable = true;
EnableGravatar = true;
LogLevel = "WARN";
} // cfg.settings;
};
pepe.core.vhost.hosts.${cfg.domain} = {
locations."/" = {
port = config.services.navidrome.settings.Port;
allowLAN = true;
allowVPN = true;
allowWAN = true;
};
};
age.secrets = {
discogs = mkIf cfg.enableBeets {
file = ../../../secrets/discogs.age;
};
lastfmKey = {
file = ../../../secrets/lastfm-key.age;
};
lastfmSecret = {
file = ../../../secrets/lastfm-key.age;
};
spotifyID = {
file = ../../../secrets/spotify-id.age;
};
spotifySecret = {
file = ../../../secrets/spotify-secret.age;
};
};
systemd.services = {
"navidrome".preStart = preStartNavidromeDecrypt;
} // mkIf cfg.enableBeets {
"beets-update" = {
enable = true;
preStart = preStartBeetsDecrypt;
before = [ "beets-import.service" ];
serviceConfig = {
Type = "oneshot";
ExecStart = "${cfg.beetsPackage}/bin/beet -c /run/beets.conf update";
};
};
"beets-import" = {
enable = true;
path = [ pkgs.imagemagick ];
requires = [ "beets-update.service" ];
after = [ "beets-update.service" ];
serviceConfig = {
Type = "oneshot";
ExecStart = "${cfg.beetsPackage}/bin/beet -c /run/beets.conf import --flat -q ${cfg.musicFolder}";
};
startAt = "weekly";
};
};
pepe.core.media.groupMembers = mkIf config.pepe.core.media.enable [ "navidrome" ];
};
}