Install Importarr from repository checkout

This commit is contained in:
2026-07-29 13:06:00 +02:00
parent 577ea97d46
commit 0f7fc6f032
9 changed files with 171 additions and 26 deletions
+11 -4
View File
@@ -28,7 +28,7 @@ class Settings(BaseModel):
def from_env(cls) -> "Settings":
return cls(
sab_url=os.getenv("IMPORTARR_SAB_URL", cls.model_fields["sab_url"].default),
sab_api_key=os.getenv("IMPORTARR_SAB_API_KEY"),
sab_api_key=_env_secret("IMPORTARR_SAB_API_KEY"),
sab_category=os.getenv("IMPORTARR_SAB_CATEGORY", "manual"),
download_root=Path(os.getenv("IMPORTARR_DOWNLOAD_ROOT", "/data/downloads/manual")),
movies_root=Path(os.getenv("IMPORTARR_MOVIES_ROOT", "/data/movies")),
@@ -36,10 +36,10 @@ class Settings(BaseModel):
state_path=Path(os.getenv("IMPORTARR_STATE_PATH", "/config/importarr.db")),
log_level=os.getenv("IMPORTARR_LOG_LEVEL", "info"),
radarr_url=os.getenv("IMPORTARR_RADARR_URL"),
radarr_api_key=os.getenv("IMPORTARR_RADARR_API_KEY"),
radarr_api_key=_env_secret("IMPORTARR_RADARR_API_KEY"),
sonarr_url=os.getenv("IMPORTARR_SONARR_URL"),
sonarr_api_key=os.getenv("IMPORTARR_SONARR_API_KEY"),
auth_token=os.getenv("IMPORTARR_AUTH_TOKEN"),
sonarr_api_key=_env_secret("IMPORTARR_SONARR_API_KEY"),
auth_token=_env_secret("IMPORTARR_AUTH_TOKEN"),
bind_host=os.getenv("IMPORTARR_BIND_HOST", "127.0.0.1"),
bind_port=int(os.getenv("IMPORTARR_BIND_PORT", "8765")),
poll_seconds=int(os.getenv("IMPORTARR_POLL_SECONDS", "60")),
@@ -54,3 +54,10 @@ class Settings(BaseModel):
if resolved != root and root not in resolved.parents:
raise ValueError("path must resolve under IMPORTARR_DOWNLOAD_ROOT")
return resolved
def _env_secret(name: str) -> str | None:
file_value = os.getenv(f"{name}_FILE")
if file_value:
return Path(file_value).read_text(encoding="utf-8").strip()
return os.getenv(name)
+14 -3
View File
@@ -97,18 +97,29 @@ def history() -> list[dict[str, object]]:
@app.get("/api/jobs")
async def jobs() -> dict[str, object]:
return await preview()
@app.get("/api/preview")
async def preview() -> dict[str, object]:
client = SabnzbdClient(settings.sab_url, settings.sab_api_key)
try:
active = await client.active_nzo_ids()
data = await client.history()
except Exception as exc: # do not leak keys in URL/params
return {"sab_status": "error", "error": exc.__class__.__name__, "jobs": manual_batch_jobs()}
jobs = manual_batch_jobs()
return {"sab_status": "error", "error": exc.__class__.__name__, "jobs": jobs, "would_import": len(jobs)}
slots = data.get("history", {}).get("slots", [])
rows = []
for item in slots:
readiness = classify_history_item(item, active, settings.sab_category, settings.download_root)
rows.append({"name": item.get("name"), "state": readiness.state, "reason": readiness.reason, "storage": str(readiness.storage) if readiness.storage else None})
return {"sab_status": "ok", "jobs": rows + manual_batch_jobs()}
if readiness.ready and readiness.storage:
for video in scan_videos(readiness.storage):
rows.append({"name": video.path.name, "state": "ready", "relative_path": str(video.relative_path), "storage": str(readiness.storage), "size": video.size})
else:
rows.append({"name": item.get("name"), "state": readiness.state, "reason": readiness.reason, "storage": str(readiness.storage) if readiness.storage else None})
jobs = rows + manual_batch_jobs()
return {"sab_status": "ok", "jobs": jobs, "would_import": sum(1 for row in jobs if row["state"] in {"ready", "manual_batch"})}
def manual_batch_jobs() -> list[dict[str, object]]: