Skip to content

Commit

Permalink
Added cross-seed support, still untested
Browse files Browse the repository at this point in the history
  • Loading branch information
rasmus-kirk committed Mar 1, 2024
1 parent bd37178 commit 2779a07
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 36 deletions.
1 change: 0 additions & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@

packages = {
docs = pkgs.callPackage ./mkDocs.nix {inherit inputs;};
pandoc = pkgs.callPackage ./mkPandoc.nix {inherit inputs;};
};

devshells.default = {
Expand Down
31 changes: 22 additions & 9 deletions nixarr/transmission/cross-seed/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,23 @@
}:
with lib; let
cfg = config.util-nixarr.services.cross-seed;
#settingsFormat = pkgs.formats.json {};
#settingsFile = settingsFormat.generate "settings.json" cfg.settings;
settingsFormat = pkgs.formats.json {};
settingsFile = settingsFormat.generate "settings.json" cfg.settings;
cross-seedPkg = import ../../../pkgs/cross-seed { inherit (pkgs) stdenv lib fetchFromGitHub; };
in {
options = {
util-nixarr.services.cross-seed = {
enable = mkEnableOption "cross-seed";

configFile = mkOption {
type = with types; nullOr path;
default = null;
example = "/var/lib/secrets/cross-seed/settings.js";
description = "cross-seed config file"; # TODO: todo
settings = mkOption {
type = types.attrs;
default = {};
example = ''
{
delay = 10;
}
'';
description = "cross-seed config"; # TODO: todo
};

dataDir = mkOption {
Expand All @@ -27,6 +31,12 @@ in {
description = "cross-seed dataDir"; # TODO: todo
};

credentialsFile = mkOption {
type = types.path;
default = "/run/secrets/cross-seed/credentialsFile.json";
description = "cross-seed dataDir"; # TODO: todo
};

user = mkOption {
type = types.str;
default = "cross-seed";
Expand Down Expand Up @@ -54,9 +64,12 @@ in {
environment.CONFIG_DIR = cfg.dataDir;

serviceConfig = {
# Run as root in case that the cfg.credentialsFile is not readable by cross-seed
ExecStartPre = [("+" + pkgs.writeShellScript "transmission-prestart" ''
mv ${cfg.configFile} ${cfg.dataDir}
'')];
${pkgs.jq}/bin/jq --slurp add ${settingsFile} '${cfg.credentialsFile}' |
install -D -m 600 -o '${cfg.user}' /dev/stdin '${cfg.dataDir}/config.json'
''
)];
Type = "simple";
User = cfg.user;
Group = cfg.group;
Expand Down
125 changes: 99 additions & 26 deletions nixarr/transmission/default.nix
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# TODO: Dir creation and file permissions in nix
{
config,
lib,
Expand All @@ -9,19 +8,41 @@ with lib; let
cfg = config.nixarr.transmission;
nixarr = config.nixarr;
dnsServers = config.lib.vpn.dnsServers;
get-indexers = with builtins; pkgs.writeShellApplication {
name = "get-indexers";
cfg-cross-seed = config.nixarr.transmission.privateTrackers.cross-seed;
transmissionCrossSeedScript = with builtins; pkgs.writeShellApplication {
name = "mk-cross-seed-credentials";

runtimeInputs = with pkgs; [ jq yq ];
runtimeInputs = with pkgs; [ curl ];

text = ''
PROWLARR_API_KEY=$(xq '.Config.ApiKey' "${nixarr.prowlarr.stateDir}/config.xml")
''
+ toJson (
map (x:
''http://localhost:9696/${toString x}/api?apikey="$PROWLARR_API_KEY"''
) cfg.privateTrackers.cross-seed.indexIds
);
curl -XPOST http://localhost:2468/api/webhook?apikey=YOUR_API_KEY --data-urlencode "infoHash=$TR_TORRENT_HASH"
'';
};
mkCrossSeedCredentials = with builtins; pkgs.writeShellApplication {
name = "mk-cross-seed-credentials";

runtimeInputs = with pkgs; [ jq yq ];

text =
"INDEX_LINKS=("
+ strings.concatMapStringsSep " " toString cfg.privateTrackers.cross-seed.indexIds
+ ")"
''
TMP_JSON=$(mktemp)
CRED_FILE="/run/secrets/cross-seed/credentialsFile.json"
PROWLARR_API_KEY=$(xq '.Config.ApiKey' "${nixarr.prowlarr.stateDir}/config.xml")
CRED_DIR=$(dirname "$filePath")
echo '{}' > "$CRED_FILE"
chmod 400 "$CRED_FILE"
chown "${config.util-nixarr.services.cross-seed.user}" "$CRED_FILE"
for i in "''${INDEX_LINKS[@]}"
do
LINK="http://localhost:9696/$i/api?apikey=$PROWLARR_API_KEY"
jq ".torznab += [\"$LINK\"]" "$CRED_FILE" > "$TMP_JSON" && mv "$TMP_JSON" "$CRED_FILE"
done
'';
};
in {
options.nixarr.transmission = {
Expand Down Expand Up @@ -69,19 +90,47 @@ in {
their rules ¯\\_(ツ)_/¯.
'';
};

cross-seed = {
enable = mkOption {
type = types.bool;
default = false;
description = ''
Enable the cross-seed service.
**Required options:** [`nixarr.prowlarr.enable`](#nixarr.prowlarr.enable)
Whether or not to enable the [cross-seed](https://www.cross-seed.org/) service.
'';
};

stateDir = mkOption {
type = types.path;
default = "${nixarr.stateDir}/nixarr/cross-seed";
description = ''
The state directory for Transmission.
'';
};

indexIds = mkOption {
type = with types; listOf int;
default = [];
# TODO: Flesh this out
description = ''
**Required options:** [`nixarr.transmission.privateTrackers.cross-seed.enable`](#nixarr.transmission.privatetrackers.cross-seed.enable)
List of indexer-ids, from prowlarr. These are from the RSS links
for the indexers on Prowlarr.
'';
};

extraSettings = mkOption {
type = types.attrs;
default = {};
description = ''
list of indexers TODO: todo
**Required options:** [`nixarr.transmission.privateTrackers.cross-seed.enable`](#nixarr.transmission.privatetrackers.cross-seed.enable)
Extra settings for the cross-seed
service, see [the cross-seed options
documentation](https://www.cross-seed.org/docs/basics/options)
'';
};
};
Expand Down Expand Up @@ -113,7 +162,7 @@ in {
description = "Transmission web-UI port.";
};

extraConfig = mkOption {
extraSettings = mkOption {
type = types.attrs;
default = {};
description = ''
Expand All @@ -140,9 +189,10 @@ in {
'';
}
{
assertion = cfg.privateTrackers.cross-seed.enable -> nixarr.prowlarr.enable;
assertion = cfg-cross-seed.enable -> nixarr.prowlarr.enable;
message = ''
TODO: todo
The nixarr.privateTrackers.cross-seed.enable option requires the
nixarr.prowlarr.enable option to be set, but it was not.
'';
}
];
Expand All @@ -151,7 +201,34 @@ in {
"d '${cfg.stateDir}' 0700 torrenter root - -"
# This is fixes a bug in nixpks (https://github.com/NixOS/nixpkgs/issues/291883)
"d '${cfg.stateDir}/.config/transmission-daemon' 0700 torrenter root - -"
];
] ++ (
if cfg-cross-seed.enable then
[ "d '${cfg-cross-seed.stateDir}' 0700 cross-seed root - -" ]
else []
);

util-nixarr.cross-seed = mkIf cfg-cross-seed.enable {
enable = true;
dataDir = cfg-cross-seed.stateDir;
#group = "media";
settings = {
torrentDir = "${nixarr.mediaDir}/torrents";
outputDir = "${nixarr.mediaDir}/torrents/cross-seed";
transmissionRpcUrl = "http://transmission:${builtins.toString cfg.uiPort}/transmission/rpc";
rssCadence = "20 minutes";

# Enable infrequent periodic searches
searchCadence = "1 week";
excludeRecentSearch = "1 year";
excludeOlder = "1 year";
} // cfg-cross-seed.extraSettings;
};
# Run as root in case that the cfg.credentialsFile is not readable by cross-seed
systemd.services.cross-seed.serviceConfig = mkIf cfg-cross-seed.enable {
ExecStartPre = [(mkBefore
("+" + (getExe mkCrossSeedCredentials))
)];
};

services.transmission = mkIf (!cfg.vpn.enable) {
enable = true;
Expand Down Expand Up @@ -192,6 +269,9 @@ in {
anti-brute-force-enabled = true;
anti-brute-force-threshold = 10;

script-torrent-done-enabled = true;
script-torrent-done-filename = getExe transmissionCrossSeedScript;

message-level =
if cfg.messageLevel == "none"
then 0
Expand All @@ -209,14 +289,7 @@ in {
then 6
else null;
}
// cfg.extraConfig;
};

services.cross-seed = mkIf cfg.cross-seed.enable {
enable = true;
group = "media";
dataDir = cfg.privateTrackers.cross-seed.dataDir;
configFile = cfg.privateTrackers.cross-seed.configFile;
// cfg.extraSettings;
};

util-nixarr.vpnnamespace = mkIf cfg.vpn.enable {
Expand Down Expand Up @@ -309,7 +382,7 @@ in {
# 0 = None, 1 = Critical, 2 = Error, 3 = Warn, 4 = Info, 5 = Debug, 6 = Trace
message-level = 3;
}
// cfg.extraConfig;
// cfg.extraSettings;
};

environment.systemPackages = with pkgs; [
Expand Down

0 comments on commit 2779a07

Please sign in to comment.