cleanup category handling
This commit is contained in:
49
module.nix
49
module.nix
@@ -112,7 +112,13 @@ let
|
||||
syncCategories = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.int;
|
||||
default = [ ];
|
||||
description = "List of sync category IDs for the application.";
|
||||
description = ''
|
||||
List of Newznab category IDs to sync for this application.
|
||||
When empty (default), categories are auto-detected at runtime
|
||||
by querying Prowlarr's indexer/categories API endpoint and
|
||||
collecting all IDs under the parent category matching the
|
||||
implementation type (e.g. Sonarr -> TV, Radarr -> Movies).
|
||||
'';
|
||||
example = [
|
||||
5000
|
||||
5010
|
||||
@@ -291,6 +297,44 @@ let
|
||||
};
|
||||
};
|
||||
|
||||
# Map Servarr implementation names to their Newznab parent category names.
|
||||
# Used to auto-detect syncCategories from the Prowlarr API when not explicitly set.
|
||||
implementationCategoryMap = {
|
||||
Sonarr = "TV";
|
||||
Radarr = "Movies";
|
||||
Lidarr = "Audio";
|
||||
Readarr = "Books";
|
||||
Whisparr = "XXX";
|
||||
};
|
||||
|
||||
# Emit shell code that sets SYNC_CATEGORIES to a JSON array of category IDs.
|
||||
# When the user provides explicit IDs, use those. Otherwise, query the Prowlarr
|
||||
# /indexer/categories endpoint and collect the parent + all subcategory IDs for
|
||||
# the implementation's Newznab category.
|
||||
mkResolveSyncCategories =
|
||||
app:
|
||||
let
|
||||
hasExplicit = app.syncCategories != [ ];
|
||||
categoryName = implementationCategoryMap.${app.implementation} or null;
|
||||
in
|
||||
if hasExplicit then
|
||||
"SYNC_CATEGORIES=${lib.escapeShellArg (builtins.toJSON app.syncCategories)}"
|
||||
else if categoryName != null then
|
||||
''
|
||||
echo "Auto-detecting sync categories for ${app.implementation}..."
|
||||
ALL_CATEGORIES=$(${curl} -sf "$BASE_URL/indexer/categories" -H "X-Api-Key: $API_KEY")
|
||||
SYNC_CATEGORIES=$(echo "$ALL_CATEGORIES" | ${jq} --arg name ${lib.escapeShellArg categoryName} \
|
||||
'[.[] | select(.name == $name) | .id, .subCategories[].id]')
|
||||
if [ "$SYNC_CATEGORIES" = "[]" ] || [ -z "$SYNC_CATEGORIES" ]; then
|
||||
echo "Warning: could not auto-detect categories for '${categoryName}', using empty list" >&2
|
||||
SYNC_CATEGORIES='[]'
|
||||
else
|
||||
echo "Resolved sync categories: $SYNC_CATEGORIES"
|
||||
fi
|
||||
''
|
||||
else
|
||||
"SYNC_CATEGORIES='[]' ";
|
||||
|
||||
curl = "${pkgs.curl}/bin/curl";
|
||||
jq = "${pkgs.jq}/bin/jq";
|
||||
grep = "${pkgs.gnugrep}/bin/grep";
|
||||
@@ -353,6 +397,7 @@ let
|
||||
echo "Synced app '${app.name}' already exists, skipping"
|
||||
else
|
||||
echo "Adding synced app '${app.name}'..."
|
||||
${mkResolveSyncCategories app}
|
||||
PAYLOAD=$(${jq} -n \
|
||||
--arg name ${lib.escapeShellArg app.name} \
|
||||
--arg implementation ${lib.escapeShellArg app.implementation} \
|
||||
@@ -361,7 +406,7 @@ let
|
||||
--arg prowlarrUrl ${lib.escapeShellArg app.prowlarrUrl} \
|
||||
--arg baseUrl ${lib.escapeShellArg app.baseUrl} \
|
||||
--arg apiKey "$TARGET_API_KEY" \
|
||||
--argjson syncCategories ${builtins.toJSON app.syncCategories} \
|
||||
--argjson syncCategories "$SYNC_CATEGORIES" \
|
||||
'{
|
||||
name: $name,
|
||||
implementation: $implementation,
|
||||
|
||||
@@ -182,16 +182,7 @@ pkgs.testers.runNixOSTest {
|
||||
prowlarrUrl = "http://localhost:9696";
|
||||
baseUrl = "http://localhost:8989";
|
||||
apiKeyFrom = "/var/lib/sonarr/.config/NzbDrone/config.xml";
|
||||
syncCategories = [
|
||||
5000
|
||||
5010
|
||||
5020
|
||||
5030
|
||||
5040
|
||||
5045
|
||||
5050
|
||||
5090
|
||||
];
|
||||
# syncCategories omitted — auto-detected from Prowlarr API
|
||||
serviceName = "sonarr";
|
||||
}
|
||||
{
|
||||
@@ -201,18 +192,7 @@ pkgs.testers.runNixOSTest {
|
||||
prowlarrUrl = "http://localhost:9696";
|
||||
baseUrl = "http://localhost:7878";
|
||||
apiKeyFrom = "/var/lib/radarr/.config/Radarr/config.xml";
|
||||
syncCategories = [
|
||||
2000
|
||||
2010
|
||||
2020
|
||||
2030
|
||||
2040
|
||||
2045
|
||||
2050
|
||||
2060
|
||||
2070
|
||||
2080
|
||||
];
|
||||
# syncCategories omitted — auto-detected from Prowlarr API
|
||||
serviceName = "radarr";
|
||||
}
|
||||
];
|
||||
@@ -325,6 +305,34 @@ pkgs.testers.runNixOSTest {
|
||||
"jq -e '.[] | select(.name == \"Radarr\")'"
|
||||
)
|
||||
|
||||
# Verify auto-detected syncCategories are non-empty for Sonarr (TV: 5xxx)
|
||||
machine.succeed(
|
||||
"API_KEY=$(grep -oP '(?<=<ApiKey>)[^<]+' /var/lib/prowlarr/config.xml) && "
|
||||
"curl -sf http://localhost:9696/api/v1/applications -H \"X-Api-Key: $API_KEY\" | "
|
||||
"jq -e '.[] | select(.name == \"Sonarr\") | .fields[] | select(.name == \"syncCategories\") | .value | length > 0'"
|
||||
)
|
||||
|
||||
# Verify auto-detected syncCategories contain parent TV category (5000)
|
||||
machine.succeed(
|
||||
"API_KEY=$(grep -oP '(?<=<ApiKey>)[^<]+' /var/lib/prowlarr/config.xml) && "
|
||||
"curl -sf http://localhost:9696/api/v1/applications -H \"X-Api-Key: $API_KEY\" | "
|
||||
"jq -e '.[] | select(.name == \"Sonarr\") | .fields[] | select(.name == \"syncCategories\") | .value | map(select(. == 5000)) | length > 0'"
|
||||
)
|
||||
|
||||
# Verify auto-detected syncCategories are non-empty for Radarr (Movies: 2xxx)
|
||||
machine.succeed(
|
||||
"API_KEY=$(grep -oP '(?<=<ApiKey>)[^<]+' /var/lib/prowlarr/config.xml) && "
|
||||
"curl -sf http://localhost:9696/api/v1/applications -H \"X-Api-Key: $API_KEY\" | "
|
||||
"jq -e '.[] | select(.name == \"Radarr\") | .fields[] | select(.name == \"syncCategories\") | .value | length > 0'"
|
||||
)
|
||||
|
||||
# Verify auto-detected syncCategories contain parent Movies category (2000)
|
||||
machine.succeed(
|
||||
"API_KEY=$(grep -oP '(?<=<ApiKey>)[^<]+' /var/lib/prowlarr/config.xml) && "
|
||||
"curl -sf http://localhost:9696/api/v1/applications -H \"X-Api-Key: $API_KEY\" | "
|
||||
"jq -e '.[] | select(.name == \"Radarr\") | .fields[] | select(.name == \"syncCategories\") | .value | map(select(. == 2000)) | length > 0'"
|
||||
)
|
||||
|
||||
# Idempotency test: restart init services and verify no duplicate entries
|
||||
machine.succeed("systemctl restart sonarr-init.service")
|
||||
machine.succeed("systemctl restart radarr-init.service")
|
||||
|
||||
Reference in New Issue
Block a user