Ajouter markhs.py
This commit is contained in:
169
markhs.py
Normal file
169
markhs.py
Normal file
@@ -0,0 +1,169 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
SABnzbd Post-Processing Script — UNFR Mark HS
|
||||
=====================================================
|
||||
En cas d'échec de vérification/réparation (statut 1),
|
||||
parse le NZB original (gzippé) pour extraire le randomid
|
||||
depuis <meta type="tag"> et appelle l'API UNFR markhs.
|
||||
|
||||
Installation :
|
||||
1. Éditez la variable API_KEY ci-dessous avec votre clé UNFR.
|
||||
2. Copiez ce script dans le dossier "scripts" de SABnzbd.
|
||||
3. Rendez le script exécutable (chmod +x sabnzbd_markhs.py) si vous êtes sous Linux/macOS.
|
||||
4. Dans SABnzbd → Config → Dossiers → Dossier des scripts, assurez-vous que le dossier est correct.
|
||||
5. Assignez ce script à la catégorie voulue (ou en post-processing par défaut).
|
||||
|
||||
Variables d'environnement SABnzbd utilisées :
|
||||
SAB_ORIG_NZB_GZ = Chemin vers le NZB original compressé (.nzb.gz)
|
||||
|
||||
Arguments positionnels SABnzbd :
|
||||
7 = Statut post-processing (1 = échec vérification/réparation)
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import gzip
|
||||
import xml.etree.ElementTree as ET
|
||||
import urllib.request
|
||||
import urllib.parse
|
||||
import urllib.error
|
||||
|
||||
# ──────────────────────────────────────────────
|
||||
# CONFIGURATION UNFR
|
||||
# ──────────────────────────────────────────────
|
||||
# Remplacez "METTRE_VOTRE_CLE_ICI" par votre clé API UNFR
|
||||
API_KEY = "METTRE_VOTRE_CLE_ICI"
|
||||
|
||||
API_BASE_URL = "https://unfr.pw/api_verif_hs.php"
|
||||
# ──────────────────────────────────────────────
|
||||
|
||||
def log_info(msg):
|
||||
"""Affiche un message d'information visible dans les logs SABnzbd."""
|
||||
print(f"[INFO] {msg}", flush=True)
|
||||
|
||||
def log_error(msg):
|
||||
"""Affiche un message d'erreur visible dans les logs SABnzbd."""
|
||||
print(f"[ERROR] {msg}", flush=True)
|
||||
|
||||
def extract_randomid(nzb_gz_path):
|
||||
"""
|
||||
Décompresse le NZB gzippé, parse le XML et retourne
|
||||
la valeur de <meta type="tag">...</meta>.
|
||||
"""
|
||||
log_info(f"Lecture NZB : {nzb_gz_path}")
|
||||
|
||||
with gzip.open(nzb_gz_path, "rb") as f:
|
||||
xml_data = f.read()
|
||||
|
||||
root = ET.fromstring(xml_data)
|
||||
|
||||
# Le namespace NZB standard
|
||||
ns = {"nzb": "http://www.newzbin.com/DTD/2003/nzb"}
|
||||
|
||||
# Cherche <meta type="tag">value</meta> avec namespace
|
||||
for meta in root.findall(".//nzb:head/nzb:meta", ns):
|
||||
if meta.get("type") == "tag" and meta.text:
|
||||
return meta.text.strip()
|
||||
|
||||
# Fallback sans namespace (certains NZB n'en ont pas)
|
||||
for meta in root.findall(".//head/meta"):
|
||||
if meta.get("type") == "tag" and meta.text:
|
||||
return meta.text.strip()
|
||||
|
||||
# Dernier fallback : chercher partout
|
||||
for meta in root.iter():
|
||||
tag_local = meta.tag.split("}")[-1] if "}" in meta.tag else meta.tag
|
||||
if tag_local == "meta" and meta.get("type") == "tag" and meta.text:
|
||||
return meta.text.strip()
|
||||
|
||||
return None
|
||||
|
||||
def call_markhs(randomid, extra_info=""):
|
||||
"""Appelle l'API UNFR pour marquer la release HS."""
|
||||
params = {
|
||||
"apikey": API_KEY,
|
||||
"action": "markhs",
|
||||
"randomid": randomid,
|
||||
}
|
||||
if extra_info:
|
||||
params["extra_info"] = extra_info
|
||||
|
||||
query = urllib.parse.urlencode(params, quote_via=urllib.parse.quote)
|
||||
url = f"{API_BASE_URL}?{query}"
|
||||
|
||||
# Masquage de la clé API et décodage pour un affichage propre dans les logs
|
||||
log_url = url.replace(API_KEY, "***")
|
||||
log_info(f"Appel API : {urllib.parse.unquote(log_url)}")
|
||||
|
||||
try:
|
||||
req = urllib.request.Request(url, method="GET")
|
||||
with urllib.request.urlopen(req, timeout=30) as resp:
|
||||
body = resp.read().decode("utf-8", errors="replace")
|
||||
log_info(f"Réponse API ({resp.status}) : {body[:500]}")
|
||||
return resp.status == 200
|
||||
except urllib.error.HTTPError as e:
|
||||
body = e.read().decode("utf-8", errors="replace")
|
||||
log_error(f"Erreur HTTP {e.code} : {e.reason} | body={body[:500]}")
|
||||
except urllib.error.URLError as e:
|
||||
log_error(f"Erreur réseau : {e.reason}")
|
||||
except Exception as e:
|
||||
log_error(f"Erreur inattendue : {e}")
|
||||
|
||||
return False
|
||||
|
||||
def main():
|
||||
log_info(f"Script démarré - python {sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}")
|
||||
|
||||
if len(sys.argv) < 8:
|
||||
log_error("Pas assez d'arguments — ce script doit être lancé par SABnzbd lors du post-processing.")
|
||||
sys.exit(0)
|
||||
|
||||
clean_name = sys.argv[3]
|
||||
category = sys.argv[5]
|
||||
status = sys.argv[7]
|
||||
|
||||
log_info(f"Job : {clean_name}")
|
||||
log_info(f"Catégorie : {category}")
|
||||
log_info(f"Statut : {status}")
|
||||
|
||||
# ── Seul le statut 1 (échec vérification/réparation) nous intéresse ──
|
||||
if status != "1":
|
||||
log_info("Statut non concerné (téléchargement réussi) — rien à signaler.")
|
||||
sys.exit(0)
|
||||
|
||||
if API_KEY == "METTRE_VOTRE_CLE_ICI" or not API_KEY:
|
||||
log_error("L'API Key n'a pas été configurée dans le script. Veuillez éditer sabnzbd_markhs.py.")
|
||||
sys.exit(0)
|
||||
|
||||
# ── Récupérer le chemin du NZB gzippé ──
|
||||
nzb_gz_path = os.environ.get("SAB_ORIG_NZB_GZ", "")
|
||||
if not nzb_gz_path or not os.path.isfile(nzb_gz_path):
|
||||
log_error(f"SAB_ORIG_NZB_GZ introuvable ou invalide ({nzb_gz_path})")
|
||||
sys.exit(0)
|
||||
|
||||
# ── Extraire le randomid depuis <meta type="tag"> ──
|
||||
try:
|
||||
randomid = extract_randomid(nzb_gz_path)
|
||||
except Exception as e:
|
||||
log_error(f"Erreur lors du parsing du fichier NZB : {e}")
|
||||
sys.exit(0)
|
||||
|
||||
if not randomid:
|
||||
log_info("Aucune balise <meta type=\"tag\"> trouvée dans le NZB. Abandon.")
|
||||
sys.exit(0)
|
||||
|
||||
log_info(f"Random ID : {randomid}")
|
||||
|
||||
# ── Appel API ──
|
||||
extra_info = f"SABnzbd: Echec verification / reparation | job={clean_name}"
|
||||
success = call_markhs(randomid, extra_info)
|
||||
|
||||
if success:
|
||||
log_info("Release marquée HS avec succès sur UNFR.")
|
||||
else:
|
||||
log_error("Impossible de marquer la release HS sur UNFR.")
|
||||
|
||||
sys.exit(0)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user