from bs4 import BeautifulSoup from dotenv import load_dotenv import requests from typing import List, TypeAlias from dataclasses import dataclass import os import re import pickle import urllib.parse @dataclass class Torrent: name: str link: str season_ep: str season: str load_dotenv() cookies = { "cf_clereance": os.getenv('CF_CLEREANCE') or "", "pass": os.getenv("PASS") or "", "uid": os.getenv("UID") or "" } def search_series(serie_name: str) -> List[Torrent] | None: try: torrents = [] page=1 valid = True while valid: valid = False base_url = "https://iptorrents.com/" search_url = f"{base_url}t?q={urllib.parse.quote(serie_name)};p={page}" response = requests.get(search_url, cookies=cookies) response.raise_for_status() serie_name = serie_name.replace(' ', '.') expr = re.compile(f"{serie_name}.*((S[0-9]+)E[0-9]+).*(1080p).*", re.I) soup = BeautifulSoup(response.content, 'html.parser') results = soup.find_all('a', {'class': 'tTipWrap'}) for result in results: link = result['href'] m = expr.search(link) if link.endswith('.torrent') and m is not None: torrents.append(Torrent(serie_name, link, m.group(1), season=m.group(2))) valid = True if valid: page += 1 return torrents except Exception as e: print(f"ERROR: {e}") return None OK: TypeAlias = int def download_torrent(url: str, file_name: str) -> OK | None: try: read = requests.get(url, cookies=cookies) with open(file_name, 'wb') as f: for chunk in read.iter_content(chunk_size=512): if chunk: f.write(chunk) return 1 except Exception as e: print("ERROR: {e}") return None def main() -> None: if os.path.exists("downloaded.bin"): with open("downloaded.bin", "rb") as f: downloaded: List[Torrent] = pickle.load(f) else: downloaded = list() serie_name = input("Name serie: ") torrents = search_series(serie_name) if torrents is None: exit(downloaded) return season = "" if len(torrents) <= 0: print("torrent not found") exit(downloaded) return seasons = set() for to in torrents: seasons.add(to.season) for idx, s in enumerate(seasons): print(f"{idx + 1}, {s}") choice = int(input("What season? ")) if 0 <= (choice -1 ) <= len(seasons): season = list(seasons)[choice -1] print(f"Selected season: {season}") for torrent in torrents: if torrent.link.find(season) >=0: name = os.path.basename(torrent.link) got = list(filter(lambda x: (x.name in torrent.name and x.season_ep in torrent.season_ep), downloaded)) if len(got) == 0: downloaded.append(torrent) print(f"Downloading {torrent.season} - {torrent.season_ep}") if download_torrent(f"https://iptorrents.com/t/{torrent.link}", name) is None: print(f"Failed to download {torrent.link}") else: print("Escolha invalida") exit(downloaded) def exit(downloaded: List[Torrent]): with open("downloaded.bin", 'wb') as f: pickle.dump(downloaded, f, protocol=pickle.HIGHEST_PROTOCOL) if __name__ == '__main__': main()