#!/usr/bin/env python3 import os import sys import urllib.error import urllib.parse import urllib.request import xml.etree.ElementTree as ET # NZBGet Exit Codes POSTPROCESS_SUCCESS = 93 POSTPROCESS_ERROR = 94 POSTPROCESS_NONE = 95 # Configuration API API_BASE_URL = "https://unfr.pw/api_verif_hs.php" def log_info(msg): print(f"[INFO] {msg}") def log_warn(msg): print(f"[WARNING] {msg}") def log_error(msg): print(f"[ERROR] {msg}") def extract_info(nzb_path): log_info(f"Lecture NZB: {nzb_path}") with open(nzb_path, "rb") as f: xml_data = f.read() root = ET.fromstring(xml_data) title = None randomid = None ns = {"nzb": "http://www.newzbin.com/DTD/2003/nzb"} meta_nodes = root.findall(".//nzb:head/nzb:meta", ns) if not meta_nodes: meta_nodes = root.findall(".//head/meta") for meta in meta_nodes: meta_type = (meta.get("type") or "").strip().lower() meta_value = (meta.text or "").strip() if not meta_value: continue if meta_type == "title": title = meta_value elif meta_type == "tag": randomid = meta_value return title, randomid def call_markhs(api_key, randomid, extra_info=""): params = {"apikey": api_key, "action": "markhs", "randomid": randomid} if extra_info: params["extra_info"] = extra_info nzbget_version = os.environ.get("NZBOP_VERSION", "unknown") user_agent = f"nzbget/{nzbget_version}" query = urllib.parse.urlencode(params, quote_via=urllib.parse.quote) url = f"{API_BASE_URL}?{query}" log_url = url.replace(api_key, "***") # Décodage de l'URL uniquement pour l'affichage dans les logs log_info(f"Appel API: {urllib.parse.unquote(log_url)}") try: req = urllib.request.Request( url, method="GET", headers={ "User-Agent": user_agent, "Accept": "*/*", "Connection": "close", }, ) with urllib.request.urlopen(req, timeout=30) as resp: body = resp.read().decode("utf-8", errors="replace") log_info(f"Reponse 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 reseau: {e.reason}") except Exception as e: log_error(f"Erreur inattendue: {e}") return False def main(): if "NZBOP_EXTENSIONS" not in os.environ: print("[ERROR] Ce script necessite au moins NZBGet v18.0") return POSTPROCESS_ERROR print("[INFO] Script démarré - python " + str(sys.version_info)) sys.stdout.flush() # Check nzbget.conf options required_options = ( "NZBPO_UNFRAPIKEY", ) for optname in required_options: if optname not in os.environ: print( "[ERROR] Option %s est manquante dans la configuration du script. Veuillez vérifier" % optname[6:] ) return POSTPROCESS_ERROR nzb_status = os.environ.get("NZBPP_STATUS", "") nzb_path = os.environ.get("NZBPP_QUEUEDFILE", "") api_key = os.environ.get("NZBPO_UNFRAPIKEY") log_info(f"NZBStatus: {nzb_status}") log_info(f"NZBPath: {nzb_path}") if nzb_status not in ("FAILURE/PAR", "FAILURE/HEALTH"): log_info("NZBStatus non concerné, rien à signaler.") return POSTPROCESS_NONE if not (nzb_path and os.path.isfile(nzb_path)): log_error("Impossible de trouver le fichier NZB dans NZBPP_QUEUEDFILE.") return POSTPROCESS_ERROR try: title, randomid = extract_info(nzb_path) except Exception as e: log_error(f"Erreur parsing NZB: {e}") return POSTPROCESS_ERROR if title: log_info(f"Title: {title}") if not randomid: log_info('Aucune balise trouvée dans le NZB.') return POSTPROCESS_NONE log_info(f"Random ID: {randomid}") extra_info = f"NZBGet: Echec verification/reparation PAR | job={title}" ok = call_markhs(api_key, randomid, extra_info) if ok: log_info("Release marquée HS avec succes.") return POSTPROCESS_SUCCESS else: log_warn("Impossible de marquer la release HS.") return POSTPROCESS_ERROR if __name__ == "__main__": sys.exit(main())