diff --git a/nixos/doc/manual/release-notes/rl-2411.section.md b/nixos/doc/manual/release-notes/rl-2411.section.md index 3c6f0ff26fb8..69f5e27fe712 100644 --- a/nixos/doc/manual/release-notes/rl-2411.section.md +++ b/nixos/doc/manual/release-notes/rl-2411.section.md @@ -95,6 +95,8 @@ - [FlareSolverr](https://github.com/FlareSolverr/FlareSolverr), a proxy server to bypass Cloudflare protection. Available as [services.flaresolverr](#opt-services.flaresolverr.enable). +- [Whisparr](https://wiki.servarr.com/en/whisparr), an adult movie collection manager for Usenet and BitTorrent users. Available as [services.whisparr](#opt-services.whisparr.enable). + - [Gancio](https://gancio.org/), a shared agenda for local communities. Available as [services.gancio](#opt-services.gancio.enable). - [Goatcounter](https://www.goatcounter.com/), an easy web analytics platform with no tracking of personal data. Available as [services.goatcounter](options.html#opt-services.goatcounter.enable). diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix index 814ee77c0119..d1347766420a 100644 --- a/nixos/modules/misc/ids.nix +++ b/nixos/modules/misc/ids.nix @@ -355,6 +355,7 @@ in rstudio-server = 324; localtimed = 325; automatic-timezoned = 326; + whisparr = 328; # When adding a uid, make sure it doesn't match an existing gid. # @@ -683,6 +684,7 @@ in localtimed = 325; automatic-timezoned = 326; uinput = 327; + whisparr = 328; # When adding a gid, make sure it doesn't match an existing # uid. Users and groups with the same name should have equal diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index e84bbb6c6aab..d3963d6114cc 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -886,6 +886,7 @@ ./services/misc/wastebin.nix ./services/misc/weechat.nix ./services/misc/workout-tracker.nix + ./services/misc/whisparr.nix ./services/misc/xmrig.nix ./services/misc/zoneminder.nix ./services/misc/zookeeper.nix diff --git a/nixos/modules/services/misc/whisparr.nix b/nixos/modules/services/misc/whisparr.nix new file mode 100644 index 000000000000..8594a682ec9f --- /dev/null +++ b/nixos/modules/services/misc/whisparr.nix @@ -0,0 +1,73 @@ +{ + config, + pkgs, + lib, + ... +}: + +let + cfg = config.services.whisparr; +in +{ + options = { + services.whisparr = { + enable = lib.mkEnableOption "Whisparr"; + + package = lib.mkPackageOption pkgs "whisparr" { }; + + dataDir = lib.mkOption { + type = lib.types.path; + default = "/var/lib/whisparr/.config/Whisparr"; + description = "The directory where Whisparr stores its data files."; + }; + + openFirewall = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Open ports in the firewall for the Whisparr web interface."; + }; + + user = lib.mkOption { + type = lib.types.str; + default = "whisparr"; + description = "User account under which Whisparr runs."; + }; + + group = lib.mkOption { + type = lib.types.str; + default = "whisparr"; + description = "Group under which Whisparr runs."; + }; + }; + }; + + config = lib.mkIf cfg.enable { + systemd.tmpfiles.rules = [ "d '${cfg.dataDir}' 0700 ${cfg.user} ${cfg.group} - -" ]; + + systemd.services.whisparr = { + description = "Whisparr"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + + serviceConfig = { + Type = "simple"; + User = cfg.user; + Group = cfg.group; + ExecStart = "${lib.getExe cfg.package} -nobrowser -data='${cfg.dataDir}'"; + Restart = "on-failure"; + }; + }; + + networking.firewall = lib.mkIf cfg.openFirewall { allowedTCPPorts = [ 6969 ]; }; + + users.users = lib.mkIf (cfg.user == "whisparr") { + whisparr = { + group = cfg.group; + home = cfg.dataDir; + uid = config.ids.uids.whisparr; + }; + }; + + users.groups = lib.mkIf (cfg.group == "whisparr") { whisparr.gid = config.ids.gids.whisparr; }; + }; +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 0c5236143c37..74d98935e54d 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -1148,6 +1148,7 @@ in { watchdogd = handleTest ./watchdogd.nix {}; webhook = runTest ./webhook.nix; weblate = handleTest ./web-apps/weblate.nix {}; + whisparr = handleTest ./whisparr.nix {}; wiki-js = handleTest ./wiki-js.nix {}; wine = handleTest ./wine.nix {}; wireguard = handleTest ./wireguard {}; diff --git a/nixos/tests/whisparr.nix b/nixos/tests/whisparr.nix new file mode 100644 index 000000000000..3d528a21c6e2 --- /dev/null +++ b/nixos/tests/whisparr.nix @@ -0,0 +1,19 @@ +import ./make-test-python.nix ( + { lib, ... }: + { + name = "whisparr"; + meta.maintainers = [ lib.maintainers.paveloom ]; + + nodes.machine = + { pkgs, ... }: + { + services.whisparr.enable = true; + }; + + testScript = '' + machine.wait_for_unit("whisparr.service") + machine.wait_for_open_port(6969) + machine.succeed("curl --fail http://localhost:6969/") + ''; + } +) diff --git a/pkgs/by-name/wh/whisparr/package.nix b/pkgs/by-name/wh/whisparr/package.nix new file mode 100644 index 000000000000..b2db8c9e0f45 --- /dev/null +++ b/pkgs/by-name/wh/whisparr/package.nix @@ -0,0 +1,96 @@ +{ + lib, + stdenv, + + curl, + dotnet-runtime, + fetchurl, + icu, + libmediainfo, + makeWrapper, + mono, + openssl, + sqlite, + zlib, + + nixosTests, +}: + +let + os = if stdenv.hostPlatform.isDarwin then "osx" else "linux"; + system = stdenv.hostPlatform.system; + arch = + { + aarch64-darwin = "arm64"; + aarch64-linux = "arm64"; + x86_64-darwin = "x64"; + x86_64-linux = "x64"; + } + ."${system}" or (throw "Unsupported system: ${system}"); + hash = + { + arm64-linux-hash = "sha256-s0j3ZYqS0fp8yLxPXP25BvLzLt7Uisl2c+94saMWEMw="; + arm64-osx-hash = "sha256-vHUtrMHJ1g7ltGuf765/IVDAWfanSUGRQbVnzsuTgrQ="; + x64-linux-hash = "sha256-mYLDQxAS6WV8CWzG1gSjPl37SJaVoLV21Meh1cRk45w="; + x64-osx-hash = "sha256-YNUb5eOc0iMOjZ9vbYLodFp5jlqk1OcOyRi10REyVX4="; + } + ."${arch}-${os}-hash"; +in +stdenv.mkDerivation rec { + pname = "whisparr"; + version = "2.0.0.548"; + + src = fetchurl { + name = "${pname}-${arch}-${os}-${version}.tar.gz"; + url = "https://whisparr.servarr.com/v1/update/nightly/updatefile?runtime=netcore&version=${version}&arch=${arch}&os=${os}"; + inherit hash; + }; + + nativeBuildInputs = [ makeWrapper ]; + + runtimeLibs = lib.makeLibraryPath [ + curl + icu + libmediainfo + mono + openssl + sqlite + zlib + ]; + + installPhase = '' + runHook preInstall + + rm -rf "Whisparr.Update" + + mkdir -p $out/{bin,share/${pname}-${version}} + cp -r * $out/share/${pname}-${version}/ + + makeWrapper "${dotnet-runtime}/bin/dotnet" $out/bin/Whisparr \ + --add-flags "$out/share/${pname}-${version}/Whisparr.dll" \ + --prefix LD_LIBRARY_PATH : ${runtimeLibs} + + runHook postInstall + ''; + + passthru = { + updateScript = ./update.sh; + tests.smoke-test = nixosTests.whisparr; + }; + + meta = { + description = "Adult movie collection manager for Usenet and BitTorrent users"; + homepage = "https://wiki.servarr.com/en/whisparr"; + changelog = "https://whisparr.servarr.com/v1/update/nightly/changes"; + license = lib.licenses.gpl3Only; + platforms = [ + "aarch64-darwin" + "aarch64-linux" + "x86_64-darwin" + "x86_64-linux" + ]; + sourceProvenance = [ lib.sourceTypes.binaryNativeCode ]; + mainProgram = "Whisparr"; + maintainers = [ lib.maintainers.paveloom ]; + }; +} diff --git a/pkgs/by-name/wh/whisparr/update.sh b/pkgs/by-name/wh/whisparr/update.sh new file mode 100755 index 000000000000..6e9b69e65a02 --- /dev/null +++ b/pkgs/by-name/wh/whisparr/update.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env nix-shell +#!nix-shell -i bash -p curl gnused jq nix-prefetch +#shellcheck shell=bash + +set -e + +dirname="$(dirname "$0")" + +updateVersion() { + version=$1 + echo "Updating the version..." + sed -i "s#version = \"[0-9.]*\"#version = \"$version\"#" "$dirname/package.nix" +} + +updateHash() +{ + version=$1 + arch=$2 + os=$3 + + system="${arch}-${os}" + hashKey="${system}-hash" + + echo "Updating the hash for the \`${system}\` system..." + url="https://whisparr.servarr.com/v1/update/nightly/updatefile?runtime=netcore&version=${version}&arch=${arch}&os=${os}" + hash=$(nix-prefetch-url --type sha256 --name "whisparr-$system-$version.tar.gz" "$url") + sriHash="$(nix hash to-sri --type sha256 "$hash")" + + sed -i "s#$hashKey = \"[a-zA-Z0-9\/+-=]*\"#$hashKey = \"$sriHash\"#" "$dirname/package.nix" +} + +echo "Checking for updates of Whisparr..." + +currentVersion=$(nix eval --raw -f "$dirname"/../../../.. whisparr.version) +echo "Current version: \`$currentVersion\`." + +echo "Fetching the latest version..." +latestVersion=$( + curl -s "https://whisparr.servarr.com/v1/update/nightly/changes?runtime=netcore&os=linux" | + jq -r .[0].version +) + +if [[ "$currentVersion" == "$latestVersion" ]]; then + echo "Whisparr is up-to-date." + exit 0 +else + echo "New version is available: \`$latestVersion\`." +fi + +updateHash "$latestVersion" arm64 linux +updateHash "$latestVersion" arm64 osx +updateHash "$latestVersion" x64 linux +updateHash "$latestVersion" x64 osx + +updateVersion "$latestVersion"