import os
import requests
import libtorrent as lt
import time
import random
import concurrent.futures

def telecharger_torrent(url, dossier_destination):
    try:
        # Télécharger le fichier .torrent à partir de l'URL
        response = requests.get(url, stream=True, timeout=30)  # Timeout de 30 secondes pour chaque requête
        response.raise_for_status()  # Vérifier s'il y a une erreur dans la requête

        # Créer un nom de fichier unique basé sur l'URL
        nom_fichier = url.split('/')[-1].split('?')[0] + ".torrent"
        chemin_fichier = os.path.join(dossier_destination, nom_fichier)

        # Si le fichier existe déjà, ajouter un suffixe pour éviter l'écrasement
        if os.path.exists(chemin_fichier):
            base, extension = os.path.splitext(nom_fichier)
            compteur = 1
            while os.path.exists(chemin_fichier):
                chemin_fichier = os.path.join(dossier_destination, f"{base}_{compteur}{extension}")
                compteur += 1

        # Sauvegarder le fichier .torrent
        with open(chemin_fichier, 'wb') as f:
            for chunk in response.iter_content(chunk_size=1024):
                if chunk:
                    f.write(chunk)

        print(f"Fichier .torrent téléchargé: {nom_fichier}")

        # Charger le torrent avec libtorrent pour récupérer les métadonnées
        ses = lt.session()
        info = lt.torrent_info(chemin_fichier)
        nom_torrent = info.name()

        # Renommer le fichier torrent en utilisant le nom du torrent
        chemin_fichier_renomme = os.path.join(dossier_destination, f"{nom_torrent}.torrent")
        
        # Si un fichier avec ce nom existe déjà, ajouter un suffixe
        if os.path.exists(chemin_fichier_renomme):
            base, extension = os.path.splitext(nom_torrent)
            compteur = 1
            while os.path.exists(chemin_fichier_renomme):
                chemin_fichier_renomme = os.path.join(dossier_destination, f"{base}_{compteur}{extension}")
                compteur += 1

        # Renommer le fichier torrent
        os.rename(chemin_fichier, chemin_fichier_renomme)

        print(f"Le torrent a été renommé en : {nom_torrent}")

        return True  # Indiquer que le téléchargement a réussi

    except requests.exceptions.Timeout:
        print(f"Erreur: Timeout lors du téléchargement depuis {url}. Attente avant réessai.")
        time.sleep(random.uniform(5, 10))  # Attendre entre 5 et 10 secondes avant réessayer
        return False  # Indiquer que le téléchargement a échoué (timeout)

    except Exception as e:
        print(f"Erreur lors du téléchargement du torrent depuis {url} : {e}")
        return False  # Indiquer que le téléchargement a échoué pour une autre raison

def lire_urls_depuis_fichier(fichier):
    with open(fichier, 'r') as f:
        return [ligne.strip() for ligne in f.readlines()]

def ecrire_urls_dans_fichier(fichier, urls):
    with open(fichier, 'w') as f:
        f.write("\n".join(urls) + "\n")

def telecharger_torrents_depuis_fichier(fichier_urls, dossier_destination, max_concurrent=3, delay_range=(2, 5)):
    if not os.path.exists(dossier_destination):
        os.makedirs(dossier_destination)

    urls = lire_urls_depuis_fichier(fichier_urls)

    while urls:
        # Traiter les 3 premières URLs
        current_urls = urls[:3]
        urls = urls[3:]  # Supprimer les URLs traitées de la liste

        # Utilisation de ThreadPoolExecutor pour la gestion de la concurrence
        with concurrent.futures.ThreadPoolExecutor(max_workers=max_concurrent) as executor:
            futures = []
            for url in current_urls:
                futures.append(executor.submit(telecharger_torrent, url, dossier_destination))
            
            # Attendre que toutes les tâches soient terminées
            for future in concurrent.futures.as_completed(futures):
                pass

        # Si tous les torrents d'un groupe ont été téléchargés avec succès, les retirer du fichier
        # Retirer les URLs qui ont été traitées avec succès
        successful_urls = [current_urls[i] for i, future in enumerate(futures) if future.result()]
        urls = [url for url in urls if url not in successful_urls]  # Mettre à jour la liste des URLs restantes

        # Mettre à jour le fichier en supprimant les URLs déjà traitées
        ecrire_urls_dans_fichier(fichier_urls, urls)

        # Ajouter une pause entre les groupes de téléchargements
        print(f"Attente avant de continuer avec le prochain lot de 3 torrents...")
        time.sleep(random.uniform(5, 10))  # Pause entre chaque lot de 3 téléchargements

if __name__ == "__main__":
    dossier_destination = "torrents"  # Dossier où les torrents seront sauvegardés
    fichier_urls = "test.txt"  # Fichier contenant les URLs des torrents
    max_concurrent = 3  # Limiter à 3 téléchargements simultanés
    telecharger_torrents_depuis_fichier(fichier_urls, dossier_destination, max_concurrent)
