commit 38477bd46b6a49d22fec166ac4ce475e5fe65f44 Author: cousclou Date: Sun Mar 30 00:57:36 2025 +0100 plex_fix diff --git a/qbittorrent_cleanup.py b/qbittorrent_cleanup.py new file mode 100644 index 0000000..d48bb03 --- /dev/null +++ b/qbittorrent_cleanup.py @@ -0,0 +1,121 @@ +import requests +import time +import json +import argparse +import paramiko +from getpass import getpass + +# Configuration +API_URLS = [ + "http://10.94.11.11:8080/api/v2", + "http://10.94.11.12:8080/api/v2" +] +API_USER = "cous" +API_PASS = "johg7chahquah2Boo" +MAX_AGE_HOURS = 5 +MAX_AGE_SECONDS = MAX_AGE_HOURS * 3600 +DOCKER_SERVERS = [ + {"ip": "10.94.11.11", "port": 60797}, + {"ip": "10.94.11.12", "port": 60797} +] +SSH_USER = "admin-cous" +SSH_KEY_PATH = "/home/cous/ed25519.key" +SSH_KEY_PASS = "pdFaPkycxkSBuLKbwyGSLaQPzQvTJmXbd9jdurC5HDIA8W5uBj0PzbYGmOa0hRsV" +DISCORD_WEBHOOK_URL = "https://discord.com/api/webhooks/1285350787786211461/4X0mtNgvvPTHSum96HsE49PjAQrjTYUUWhn0ZjCEx56fOb7NveIfnkmiwCD71yPNvfq_" + +def send_discord_message(content, color): + payload = { + "embeds": [ + { + "description": content, + "color": color + } + ] + } + response = requests.post(DISCORD_WEBHOOK_URL, json=payload) + if response.status_code != 204: + print(f"Erreur lors de l'envoi du message Discord : {response.status_code}") + +def get_torrents(api_url): + response = requests.get(f"{api_url}/torrents/info", auth=(API_USER, API_PASS)) + if response.status_code == 200: + return response.json() + else: + print(f"Erreur lors de la récupération des torrents : {response.status_code}") + print(f"Réponse brute : {response.text}") + return [] + +def check_and_restart_containers(test_mode): + print("Vérification des torrents bloqués pour redémarrage...") + + # Liste des états bloqués, excluant 'stalledUP' + BLOCKED_STATES = ["metaDL", "stalledDL", "error"] + + for server in DOCKER_SERVERS: + ip = server["ip"] + port = server["port"] + api_url = API_URLS[DOCKER_SERVERS.index(server)] + print(f"Vérification des conteneurs sur {ip}...") + + try: + ssh_client = paramiko.SSHClient() + ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + private_key = paramiko.Ed25519Key.from_private_key_file(SSH_KEY_PATH, password=SSH_KEY_PASS) + ssh_client.connect(ip, port=port, username=SSH_USER, pkey=private_key) + + # Récupérer les torrents + torrents = get_torrents(api_url) + blocked_torrents = [] + + for torrent in torrents: + hash = torrent.get('hash', '') + name = torrent.get('name', '') + state = torrent.get('state', '') + + print(f"Torrent: {name}, État: {state}") # Log pour débogage + + if state in BLOCKED_STATES: + blocked_torrents.append({ + "name": name, + "hash": hash, + "state": state + }) + + # Envoi des messages Discord et redémarrage si nécessaire + if blocked_torrents: + # Regrouper les torrents par instance + content = f"**Torrents bloqués détectés sur {ip} :**\n" + for torrent in blocked_torrents: + content += f"**Nom** : {torrent['name']}\n" + content += f"**Hash** : {torrent['hash']}\n" + content += f"**État** : {torrent['state']}\n\n" + + # Envoyer un seul message par instance + send_discord_message(content, color=0xFF0000) # Rouge pour tous les états bloqués + + if not test_mode: + stdin, stdout, stderr = ssh_client.exec_command("sudo docker container restart qbittorrent") + errors = stderr.read().decode().strip() + if errors: + print(f"Erreur lors du redémarrage du conteneur sur {ip} : {errors}") + else: + send_discord_message(f"Le conteneur qbittorrent a été redémarré sur {ip}.", color=0x00FF00) # Vert pour redémarrage + print(f"Commande de redémarrage envoyée au conteneur sur {ip}") + else: + print(f"Aucun torrent bloqué détecté sur {ip}.") + + ssh_client.close() + + except paramiko.AuthenticationException: + print(f"Erreur d'authentification SSH pour {ip}.") + except paramiko.SSHException as e: + print(f"Erreur lors de la connexion SSH pour {ip} : {e}") + except Exception as e: + print(f"Erreur inattendue pour {ip} : {e}") + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Script de gestion des torrents") + parser.add_argument('-test', action='store_true', help="Mode test. Simule l'ajout du tag et la suppression des torrents sans les supprimer réellement.") + args = parser.parse_args() + + check_and_restart_containers(test_mode=args.test)