Skip to content

Commit f84ba9f

Browse files
committed
convert configureApiService to bash scripting
1 parent f3fb1d2 commit f84ba9f

1 file changed

Lines changed: 122 additions & 151 deletions

File tree

modules/sabnzbd/configureApiService.nix

Lines changed: 122 additions & 151 deletions
Original file line numberDiff line numberDiff line change
@@ -3,145 +3,7 @@
33
lib,
44
cfg,
55
}:
6-
with lib; let
7-
configureScript =
8-
pkgs.writers.writePython3Bin "sabnzbd-configure-api" {
9-
libraries = with pkgs.python3Packages; [requests];
10-
} ''
11-
import requests
12-
import time
13-
import sys
14-
import os
15-
import json
16-
17-
# Read API key from environment or file
18-
API_KEY = os.environ.get("SABNZBD_API_KEY", "")
19-
BASE_URL = os.environ.get("SABNZBD_BASE_URL", "")
20-
21-
22-
def api_call(mode, **params):
23-
"""Make an API call to SABnzbd"""
24-
params.update({"mode": mode, "apikey": API_KEY, "output": "json"})
25-
try:
26-
response = requests.get(BASE_URL, params=params, timeout=10)
27-
response.raise_for_status()
28-
return response.json()
29-
except Exception as e:
30-
print(f"API call failed for mode={mode}: {e}", file=sys.stderr)
31-
return None
32-
33-
34-
def wait_for_sabnzbd():
35-
"""Wait for SABnzbd to be ready"""
36-
print("Waiting for SABnzbd to be ready...")
37-
for i in range(60):
38-
try:
39-
result = api_call("version")
40-
if result and "version" in result:
41-
print(f"SABnzbd is ready (version: {result['version']})")
42-
return True
43-
except Exception:
44-
pass
45-
time.sleep(1)
46-
print("SABnzbd did not become ready in time", file=sys.stderr)
47-
return False
48-
49-
50-
def set_config(section, keyword, value):
51-
"""Set a configuration value"""
52-
result = api_call("set_config", section=section, keyword=keyword,
53-
value=value)
54-
if result:
55-
print(f"Set {section}.{keyword} = {value}")
56-
return True
57-
return False
58-
59-
60-
def configure_misc_settings():
61-
"""Configure misc settings via API"""
62-
print("Configuring misc settings...")
63-
settings_json = os.environ.get("SETTINGS_JSON", "{}")
64-
settings = json.loads(settings_json)
65-
66-
for key, value in settings.items():
67-
# Convert booleans to 0/1
68-
if isinstance(value, bool):
69-
value = 1 if value else 0
70-
set_config("misc", key, str(value))
71-
72-
73-
def configure_servers():
74-
"""Configure SABnzbd servers via API"""
75-
print("Configuring servers...")
76-
servers_json = os.environ.get("SERVERS_JSON", "[]")
77-
servers = json.loads(servers_json)
78-
79-
for server in servers:
80-
name = server["name"]
81-
# Read secrets from environment if they're placeholders
82-
username = server["username"]
83-
password = server["password"]
84-
85-
if username.startswith("$"):
86-
username = os.environ.get(username[1:], username)
87-
if password.startswith("$"):
88-
password = os.environ.get(password[1:], password)
89-
90-
params = {
91-
"section": "servers",
92-
"name": name,
93-
"host": server["host"],
94-
"port": server["port"],
95-
"username": username,
96-
"password": password,
97-
"connections": server["connections"],
98-
"ssl": 1 if server["ssl"] else 0,
99-
"priority": server["priority"],
100-
"optional": 1 if server["optional"] else 0,
101-
"retention": server["retention"],
102-
"enable": 1 if server["enable"] else 0,
103-
}
104-
105-
result = api_call("set_config", **params)
106-
if result:
107-
print(f"Configured server: {name}")
108-
109-
110-
def configure_categories():
111-
"""Configure SABnzbd categories via API"""
112-
print("Configuring categories...")
113-
categories_json = os.environ.get("CATEGORIES_JSON", "[]")
114-
categories = json.loads(categories_json)
115-
116-
for category in categories:
117-
name = category["name"]
118-
params = {
119-
"section": "categories",
120-
"name": name,
121-
"dir": category["dir"],
122-
"priority": category["priority"],
123-
"pp": category["pp"],
124-
"script": category["script"],
125-
}
126-
127-
result = api_call("set_config", **params)
128-
if result:
129-
print(f"Configured category: {name}")
130-
131-
132-
if __name__ == "__main__":
133-
if not wait_for_sabnzbd():
134-
sys.exit(1)
135-
136-
configure_misc_settings()
137-
configure_servers()
138-
configure_categories()
139-
140-
print("SABnzbd configuration completed successfully")
141-
'';
142-
in {
143-
script = configureScript;
144-
6+
with lib; {
1457
serviceConfig = {
1468
description = "Configure SABnzbd via API";
1479
after = ["sabnzbd.service"];
@@ -154,27 +16,136 @@ in {
15416
};
15517

15618
script = ''
157-
# Export API key
19+
set -eu
20+
21+
# Read API key from file
15822
${optionalString (cfg.apiKeyPath != null) ''
159-
export SABNZBD_API_KEY=$(${pkgs.coreutils}/bin/cat ${cfg.apiKeyPath})
23+
API_KEY=$(cat ${cfg.apiKeyPath})
24+
''}
25+
${optionalString (cfg.apiKeyPath == null) ''
26+
API_KEY=""
16027
''}
16128
162-
# Export base URL
163-
export SABNZBD_BASE_URL="http://${cfg.settings.host}:${toString cfg.settings.port}${cfg.settings.url_base}/api"
164-
165-
# Export configuration as JSON
166-
export SETTINGS_JSON='${builtins.toJSON (filterAttrs (n: v: n != "servers" && n != "categories") cfg.settings)}'
167-
export SERVERS_JSON='${builtins.toJSON cfg.settings.servers}'
168-
export CATEGORIES_JSON='${builtins.toJSON cfg.settings.categories}'
29+
BASE_URL="http://${cfg.settings.host}:${toString cfg.settings.port}${cfg.settings.url_base}/api"
16930
17031
# Export environment secrets
17132
${concatMapStringsSep "\n" (secret: ''
172-
export ${secret.env}=$(${pkgs.coreutils}/bin/cat ${secret.path})
33+
export ${secret.env}=$(cat ${secret.path})
17334
'')
17435
cfg.environmentSecrets}
17536
176-
# Run configuration script
177-
${configureScript}/bin/sabnzbd-configure-api
37+
# Function to make API calls
38+
api_call() {
39+
local mode="$1"
40+
shift
41+
local params="mode=$mode&apikey=$API_KEY&output=json"
42+
43+
while [[ $# -gt 0 ]]; do
44+
params="$params&$1"
45+
shift
46+
done
47+
48+
${pkgs.curl}/bin/curl -s -f -m 10 "$BASE_URL?$params" 2>&1 || return 1
49+
}
50+
51+
# Wait for SABnzbd to be ready
52+
echo "Waiting for SABnzbd API to be available..."
53+
for i in {1..60}; do
54+
if result=$(api_call "version" 2>/dev/null); then
55+
if version=$(echo "$result" | ${pkgs.jq}/bin/jq -r '.version // empty' 2>/dev/null); then
56+
if [[ -n "$version" ]]; then
57+
echo "SABnzbd is ready (version: $version)"
58+
break
59+
fi
60+
fi
61+
fi
62+
if [[ $i -eq 60 ]]; then
63+
echo "SABnzbd did not become ready in time" >&2
64+
exit 1
65+
fi
66+
sleep 1
67+
done
68+
69+
# Configure misc settings
70+
echo "Configuring misc settings..."
71+
SETTINGS_JSON='${builtins.toJSON (filterAttrs (n: v: n != "servers" && n != "categories") cfg.settings)}'
72+
73+
echo "$SETTINGS_JSON" | ${pkgs.jq}/bin/jq -r 'to_entries[] | "\(.key)=\(.value)"' | while IFS='=' read -r key value; do
74+
# Convert booleans to 0/1
75+
if [[ "$value" == "true" ]]; then
76+
value="1"
77+
elif [[ "$value" == "false" ]]; then
78+
value="0"
79+
fi
80+
81+
encoded_value=$(echo -n "$value" | ${pkgs.jq}/bin/jq -sRr @uri)
82+
if api_call "set_config" "section=misc" "keyword=$key" "value=$encoded_value" >/dev/null 2>&1; then
83+
echo "Set misc.$key = $value"
84+
fi
85+
done
86+
87+
# Configure servers
88+
echo "Configuring servers..."
89+
SERVERS_JSON='${builtins.toJSON cfg.settings.servers}'
90+
91+
echo "$SERVERS_JSON" | ${pkgs.jq}/bin/jq -c '.[]' | while IFS= read -r server; do
92+
# Extract name for logging and env var substitution
93+
name=$(echo "$server" | ${pkgs.jq}/bin/jq -r '.name')
94+
username=$(echo "$server" | ${pkgs.jq}/bin/jq -r '.username')
95+
password=$(echo "$server" | ${pkgs.jq}/bin/jq -r '.password')
96+
97+
# Handle environment variable substitution
98+
if [[ "$username" =~ ^\$ ]]; then
99+
var_name="''${username:1}"
100+
username="''${!var_name}"
101+
fi
102+
if [[ "$password" =~ ^\$ ]]; then
103+
var_name="''${password:1}"
104+
password="''${!var_name}"
105+
fi
106+
107+
# Build parameters using jq, converting booleans to 0/1 and URL encoding
108+
params=$(echo "$server" | ${pkgs.jq}/bin/jq -r \
109+
--arg username "$username" \
110+
--arg password "$password" \
111+
'
112+
. + {username: $username, password: $password}
113+
| to_entries
114+
| map(
115+
if .value == true then .value = "1"
116+
elif .value == false then .value = "0"
117+
else .
118+
end
119+
)
120+
| map("\(.key)=\(.value | tostring | @uri)")
121+
| join("&")
122+
')
123+
124+
if api_call "set_config" "section=servers" "$params" >/dev/null 2>&1; then
125+
echo "Configured server: $name"
126+
fi
127+
done
128+
129+
# Configure categories
130+
echo "Configuring categories..."
131+
CATEGORIES_JSON='${builtins.toJSON cfg.settings.categories}'
132+
133+
echo "$CATEGORIES_JSON" | ${pkgs.jq}/bin/jq -c '.[]' | while IFS= read -r category; do
134+
name=$(echo "$category" | ${pkgs.jq}/bin/jq -r '.name')
135+
136+
# Build parameters using jq, URL encoding values
137+
params=$(echo "$category" | ${pkgs.jq}/bin/jq -r '
138+
to_entries
139+
| map("\(.key)=\(.value | tostring | @uri)")
140+
| join("&")
141+
')
142+
143+
if api_call "set_config" "section=categories" "$params" >/dev/null 2>&1; then
144+
echo "Configured category: $name"
145+
fi
146+
done
147+
148+
echo "SABnzbd configuration completed successfully"
178149
'';
179150
};
180151
}

0 commit comments

Comments
 (0)