Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
34b6e36787 |
@@ -226,6 +226,58 @@ def t_manual_scan(a):
|
||||
return get("/api/v1/manualimport", path=a["path"], platform=a.get("platform"))
|
||||
|
||||
|
||||
def t_indexer_schema(_):
|
||||
return get("/api/v1/indexer/schema")
|
||||
|
||||
|
||||
def _secret_from(body, field, literal, env_name):
|
||||
"""Set a credential field, optionally resolved from the server's own env.
|
||||
|
||||
Passing a key by *reference* means the value never enters the transcript: the
|
||||
gateway already exposes Prowlarr's and SABnzbd's keys to this process, so the
|
||||
caller names the variable instead of quoting the secret.
|
||||
"""
|
||||
if env_name:
|
||||
value = os.environ.get(env_name, "")
|
||||
if not value:
|
||||
raise ToolError(f"{env_name} is not set in this server's environment")
|
||||
body[field] = value
|
||||
elif literal:
|
||||
body[field] = literal
|
||||
|
||||
|
||||
def t_indexer_save(a):
|
||||
kind = (a.get("type") or "").strip()
|
||||
if not kind:
|
||||
raise ToolError("type is required (see indexer_schema), e.g. 'prowlarr'")
|
||||
body = dict(a.get("extra") or {})
|
||||
body["type"] = kind
|
||||
for field in ("name", "url", "enable", "id"):
|
||||
if a.get(field) not in (None, ""):
|
||||
body[field] = a[field]
|
||||
_secret_from(body, "api_key", a.get("api_key"), a.get("api_key_env"))
|
||||
return post("/api/v1/indexer", body)
|
||||
|
||||
|
||||
def t_client_schema(_):
|
||||
return get("/api/v1/downloadclient/schema")
|
||||
|
||||
|
||||
def t_client_save(a):
|
||||
kind = (a.get("type") or "").strip()
|
||||
if not kind:
|
||||
raise ToolError("type is required (see download_client_schema), e.g. 'qbittorrent'")
|
||||
body = dict(a.get("extra") or {})
|
||||
body["type"] = kind
|
||||
for field in ("name", "host", "port", "use_ssl", "url_base", "username",
|
||||
"category", "id"):
|
||||
if a.get(field) not in (None, ""):
|
||||
body[field] = a[field]
|
||||
_secret_from(body, "password", a.get("password"), a.get("password_env"))
|
||||
_secret_from(body, "api_key", a.get("api_key"), a.get("api_key_env"))
|
||||
return post("/api/v1/downloadclient", body)
|
||||
|
||||
|
||||
def _obj(props, required=None):
|
||||
return {
|
||||
"type": "object",
|
||||
@@ -410,6 +462,64 @@ TOOLS = [
|
||||
"write": False,
|
||||
"fn": t_manual_scan,
|
||||
},
|
||||
{
|
||||
"name": "indexer_schema",
|
||||
"description": "Every indexer type ROMarr supports, with the fields each one needs — read this before indexer_save.",
|
||||
"schema": _obj({}),
|
||||
"write": False,
|
||||
"fn": t_indexer_schema,
|
||||
},
|
||||
{
|
||||
"name": "indexer_save",
|
||||
"description": "Create or update an indexer. Prefer api_key_env over api_key: the server resolves the variable from its own environment, so the secret never appears in the call.",
|
||||
"schema": _obj(
|
||||
{
|
||||
"type": {"type": "string", "description": "Indexer type, e.g. 'prowlarr', 'torznab', 'newznab'."},
|
||||
"name": {"type": "string"},
|
||||
"url": {"type": "string", "description": "Base URL, e.g. http://127.0.0.1:9696 for Prowlarr."},
|
||||
"api_key": {"type": "string", "description": "Inline key. Avoid: prefer api_key_env."},
|
||||
"api_key_env": {"type": "string", "description": "Name of an env var holding the key, e.g. 'PROWLARR_API_KEY'."},
|
||||
"enable": {"type": "boolean"},
|
||||
"id": {"type": "string", "description": "Existing indexer id to update."},
|
||||
"extra": {"type": "object", "description": "Any other fields the type needs, verbatim."},
|
||||
},
|
||||
["type"],
|
||||
),
|
||||
"write": True,
|
||||
"fn": t_indexer_save,
|
||||
},
|
||||
{
|
||||
"name": "download_client_schema",
|
||||
"description": "Every download client type ROMarr supports, with its fields and default port.",
|
||||
"schema": _obj({}),
|
||||
"write": False,
|
||||
"fn": t_client_schema,
|
||||
},
|
||||
{
|
||||
"name": "download_client_save",
|
||||
"description": "Create or update a torrent/usenet download client. Credentials may be passed by reference (password_env / api_key_env) instead of inline.",
|
||||
"schema": _obj(
|
||||
{
|
||||
"type": {"type": "string", "description": "Client type, e.g. 'qbittorrent', 'sabnzbd', 'transmission'."},
|
||||
"name": {"type": "string"},
|
||||
"host": {"type": "string"},
|
||||
"port": {"type": "integer"},
|
||||
"use_ssl": {"type": "boolean"},
|
||||
"url_base": {"type": "string"},
|
||||
"username": {"type": "string"},
|
||||
"password": {"type": "string", "description": "Inline. Avoid: prefer password_env."},
|
||||
"password_env": {"type": "string"},
|
||||
"api_key": {"type": "string", "description": "Inline. Avoid: prefer api_key_env."},
|
||||
"api_key_env": {"type": "string", "description": "e.g. 'SABNZBD_API_KEY'."},
|
||||
"category": {"type": "string"},
|
||||
"id": {"type": "string", "description": "Existing client id to update."},
|
||||
"extra": {"type": "object", "description": "Any other fields the type needs, verbatim."},
|
||||
},
|
||||
["type"],
|
||||
),
|
||||
"write": True,
|
||||
"fn": t_client_save,
|
||||
},
|
||||
]
|
||||
|
||||
BY_NAME = {t["name"]: t for t in TOOLS}
|
||||
|
||||
Reference in new issue
Block a user