Mise à jour automatique (Gitea + Watchtower) et conteneurisation Docker
- Détection de version via l'API Gitea, application via Watchtower - Router système, UI admin (intégrations), bandeau de mise à jour - Dockerfile multi-étapes, docker-compose, scripts/release.sh - Version centralisée dans app/version.py (pyproject ou OHM_VERSION au build)
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
"""Paramètres persistés en DB (activation des sources, réglages UI…)."""
|
||||
"""Paramètres persistés en DB (activation des sources, santé, réglages UI…)."""
|
||||
import json
|
||||
import logging
|
||||
import secrets
|
||||
from datetime import UTC, datetime
|
||||
|
||||
from app.db import db
|
||||
|
||||
@@ -35,6 +36,48 @@ async def set_source_enabled(name: str, enabled: bool) -> None:
|
||||
await set_setting(f"source:{name}:enabled", enabled)
|
||||
logger.info("Source %s %s", name, "activée" if enabled else "désactivée")
|
||||
|
||||
|
||||
async def get_source_health(name: str) -> dict | None:
|
||||
"""Dernier état de santé connu d'une source (None si jamais testée)."""
|
||||
value = await get_setting(f"source:{name}:health")
|
||||
return value if isinstance(value, dict) else None
|
||||
|
||||
|
||||
async def set_source_health(name: str, healthy: bool, detail: str) -> dict:
|
||||
state = {
|
||||
"healthy": healthy,
|
||||
"detail": detail,
|
||||
"checked_at": datetime.now(UTC).isoformat(),
|
||||
}
|
||||
await set_setting(f"source:{name}:health", state)
|
||||
return state
|
||||
|
||||
|
||||
async def get_source_base_url(name: str) -> str | None:
|
||||
"""URL personnalisée d'une source (None = valeur par défaut du code)."""
|
||||
value = await get_setting(f"source:{name}:base_url")
|
||||
return value if isinstance(value, str) and value else None
|
||||
|
||||
|
||||
async def set_source_base_url(name: str, url: str | None) -> None:
|
||||
"""Persiste l'URL personnalisée (None/'' → retour à la valeur par défaut)."""
|
||||
key = f"source:{name}:base_url"
|
||||
if url:
|
||||
await set_setting(key, url)
|
||||
else:
|
||||
await db.execute("DELETE FROM settings WHERE key = ?", (key,))
|
||||
|
||||
|
||||
async def apply_source_base_urls() -> None:
|
||||
"""Applique les URL personnalisées aux instances de sources (au démarrage)."""
|
||||
from app.scrapers.base import all_sources
|
||||
|
||||
for source in all_sources():
|
||||
override = await get_source_base_url(source.name)
|
||||
if override and override != type(source).base_url:
|
||||
source.base_url = override
|
||||
logger.info("URL personnalisée pour %s : %s", source.name, override)
|
||||
|
||||
# ---------------------------------------------------------------- intégrations *arr
|
||||
|
||||
TORZNAB_APIKEY_KEY = "torznab:apikey"
|
||||
@@ -70,3 +113,24 @@ async def set_sonarr_config(url: str, apikey: str) -> None:
|
||||
await set_setting(SONARR_URL_KEY, url.rstrip("/"))
|
||||
await set_setting(SONARR_APIKEY_KEY, apikey.strip())
|
||||
logger.info("Configuration Sonarr enregistrée (%s)", url)
|
||||
|
||||
# ---------------------------------------------------------------- mise à jour logicielle
|
||||
|
||||
UPDATE_GITEA_URL_KEY = "update:gitea_url"
|
||||
UPDATE_REPO_KEY = "update:repo"
|
||||
UPDATE_TOKEN_KEY = "update:token"
|
||||
|
||||
|
||||
async def get_update_config() -> dict[str, str]:
|
||||
return {
|
||||
"gitea_url": await get_setting(UPDATE_GITEA_URL_KEY, "https://git.lanro.eu"),
|
||||
"repo": await get_setting(UPDATE_REPO_KEY, "Roman/ohm_streaming"),
|
||||
"token": await get_setting(UPDATE_TOKEN_KEY, ""),
|
||||
}
|
||||
|
||||
|
||||
async def set_update_config(gitea_url: str, repo: str, token: str) -> None:
|
||||
await set_setting(UPDATE_GITEA_URL_KEY, gitea_url.rstrip("/"))
|
||||
await set_setting(UPDATE_REPO_KEY, repo.strip().strip("/"))
|
||||
await set_setting(UPDATE_TOKEN_KEY, token.strip())
|
||||
logger.info("Configuration de mise à jour enregistrée (%s)", repo)
|
||||
|
||||
Reference in New Issue
Block a user