155 lines
4.4 KiB
Python
155 lines
4.4 KiB
Python
|
|
#!/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 <meta type="tag"> 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())
|