From f230cab40a5caf2295aa849b3d37ea7fa750f0d8 Mon Sep 17 00:00:00 2001 From: PythonCoderAS <13932583+PythonCoderAS@users.noreply.github.com> Date: Fri, 18 Jul 2025 21:53:44 -0400 Subject: [PATCH 1/5] inital --- src/trackers/NYAA.py | 246 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 src/trackers/NYAA.py diff --git a/src/trackers/NYAA.py b/src/trackers/NYAA.py new file mode 100644 index 000000000..6cf75d556 --- /dev/null +++ b/src/trackers/NYAA.py @@ -0,0 +1,246 @@ +# -*- coding: utf-8 -*- +import os +import re +import requests +from src.exceptions import UploadException +from src.console import console +from .COMMON import COMMON +from torf import Torrent +from aiohttp import ClientSession + + +class NYAA(COMMON): + def __init__(self, config): + super().__init__(config) + self.tracker = 'NYAA' + self.source_flag = 'Nyaa.si' + self.base_url = "https://nyaa.si" + self.torrent_url = f"{self.base_url}/view/" + self.announce_url = "http://nyaa.tracker.wf:7777/announce" + self.banned_groups = [""] + + self.session_cookie = self.config['TRACKERS'][self.tracker].get('session_cookie') + self.session = ClientSession(headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36'}, cookies={'session': self.session_cookie} if self.session_cookie else None) + self.signature = "----\n[Created by Audionut's Upload Assistant](https://github.com/Audionut/Upload-Assistant)" + + async def edit_torrent(self, meta, tracker, source_flag, torrent_filename="BASE"): + if os.path.exists(f"{meta['base_dir']}/tmp/{meta['uuid']}/{torrent_filename}.torrent"): + new_torrent = Torrent.read(f"{meta['base_dir']}/tmp/{meta['uuid']}/{torrent_filename}.torrent") + for each in list(new_torrent.metainfo): + if each not in ('announce', 'comment', 'creation date', 'created by', 'encoding', 'info'): + new_torrent.metainfo.pop(each, None) + new_torrent.metainfo['announce'] = self.announce_url + if 'created by' in new_torrent.metainfo and isinstance(new_torrent.metainfo['created by'], str): + created_by = new_torrent.metainfo['created by'] + if "mkbrr" in created_by.lower(): + new_torrent.metainfo['created by'] = f"{created_by} using Audionut's Upload Assistant" + + new_torrent.metainfo['comment'] = '' + new_torrent.private = False + + Torrent.copy(new_torrent).write(f"{meta['base_dir']}/tmp/{meta['uuid']}/[{tracker}].torrent", overwrite=True) + + async def generate_description(self, meta): + nyaa_desc = f"{meta['base_dir']}/tmp/{meta['uuid']}/[{self.tracker}]DESCRIPTION.txt" + + desc_parts = [] + + # Screenshots + images = meta.get('image_list', []) + if images: + screenshots_block = "## Screenshots\n\n" + for image_number, image in enumerate(images, start=1): + img_url = image['img_url'] + web_url = image['web_url'] + screenshots_block += f"[![Screenshot ]({img_url})]({web_url}) " + desc_parts.append(screenshots_block) + + # BDInfo + tech_info = "" + if meta.get('is_disc') == 'BDMV': + bd_summary_file = f"{meta['base_dir']}/tmp/{meta['uuid']}/BD_SUMMARY_00.txt" + if os.path.exists(bd_summary_file): + with open(bd_summary_file, 'r', encoding='utf-8') as f: + tech_info = f.read() + + if tech_info: + desc_parts.append(f"## BD Info\n```\n{tech_info}\n```\n") + + mediainfo_file = f"{meta['base_dir']}/tmp/{meta['uuid']}/MEDIAINFO.txt" + if os.path.exists(mediainfo_file): + with open(mediainfo_file, 'r', encoding='utf-8') as f: + mediainfo_content = f.read() + desc_parts.append(f"## MediaInfo\n```\n{mediainfo_content}\n```\n") + + if self.signature: + desc_parts.append(self.signature) + + final_description = "\n".join(filter(None, desc_parts)) + + with open(nyaa_desc, 'w', encoding='utf-8') as f: + f.write(final_description) + + async def get_category_id(self, meta): + # resolution = meta.get('resolution') + # category = meta.get('category') + # is_disc = meta.get('is_disc') + # tv_pack = meta.get('tv_pack') + # sd = meta.get('sd') + + mediainfo = meta.get("mediainfo", {}) + print(meta) + raise Exception + + if is_disc == 'BDMV': + if resolution == '1080p' and category == 'MOVIE': + return 3 + elif resolution == '2160p' and category == 'MOVIE': + return 38 + elif category == 'TV': + return 14 + if is_disc == 'DVD': + if category == 'MOVIE': + return 1 + elif category == 'TV': + return 11 + if category == 'TV' and tv_pack == 1: + return 12 + if sd == 1: + if category == 'MOVIE': + return 2 + elif category == 'TV': + return 10 + category_map = { + 'MOVIE': {'2160p': 4, '1080p': 6, '1080i': 6, '720p': 5}, + 'TV': {'2160p': 13, '1080p': 9, '1080i': 9, '720p': 8}, + } + if category in category_map: + return category_map[category].get(resolution) + return None + + async def login(self): + if self.session_cookie is None: + console.print(f"[bold red]Login failed on {self.tracker}: No session cookie provided.[/bold red]") + return False + async with self.session.get(f"{self.base_url}/profile", allow_redirects=False) as resp: + if resp.status != 200: + console.print(f"[bold red]Login failed on {self.tracker}: Redirected to homepage (indicates session cookie is invalid).[/bold red]") + return False + else: + return True + + async def search_existing(self, meta, disctype): + if self.session_cookie is None: + console.print(f"[bold red]Login failed on {self.tracker}: No session cookie provided.[/bold red]") + return [] + + search_url = f"{self.api_base_url}/torrents" + search_params = {'searchText': imdb_id} + + try: + response = self.session.get(search_url, params=search_params, cookies=self.auth_cookies, timeout=15) + response.raise_for_status() + + if response.text and response.text != '[]': + results = response.json() + if results and isinstance(results, list): + return results + + except Exception as e: + console.print(f"[bold red]Error searching for IMDb ID '{imdb_id}' on {self.tracker}: {e}[/bold red]") + + return [] + + async def upload(self, meta, disctype): + await self.edit_torrent(meta, self.tracker, self.source_flag) + + cat_id = await self.get_category_id(meta) + + await self.generate_description(meta) + + description_path = f"{meta['base_dir']}/tmp/{meta['uuid']}/[{self.tracker}]DESCRIPTION.txt" + with open(description_path, 'r', encoding='utf-8') as f: + description = f.read() + + imdb = meta.get('imdb_info', {}).get('imdbID', '') + + mi_path = f"{meta['base_dir']}/tmp/{meta['uuid']}/{'BD_SUMMARY_00.txt' if meta.get('is_disc') == 'BDMV' else 'MEDIAINFO.txt'}" + with open(mi_path, 'r', encoding='utf-8') as f: + mediainfo_dump = f.read() + + is_anonymous = "1" if meta['anon'] != 0 or self.config['TRACKERS'][self.tracker].get('anon', False) else "0" + + data = { + 'category': cat_id, + 'imdbId': imdb, + 'nfo': description, + 'mediainfo': mediainfo_dump, + 'reqid': "0", + 'section': "new", + 'frileech': "1", + 'anonymousUpload': is_anonymous, + 'p2p': "0" + } + + torrent_path = f"{meta['base_dir']}/tmp/{meta['uuid']}/[{self.tracker}].torrent" + + try: + is_scene = bool(meta.get('scene_name')) + base_name = meta['scene_name'] if is_scene else meta['uuid'] + + existing_torrents = await self.search_existing(meta, disctype) + needs_unrar_tag = False + + if existing_torrents: + current_release_identifiers = {meta['uuid']} + if is_scene: + current_release_identifiers.add(meta['scene_name']) + + relevant_torrents = [ + t for t in existing_torrents + if t.get('name') in current_release_identifiers + ] + + if relevant_torrents: + unrar_version_exists = any(t.get('unrar', 0) != 0 for t in relevant_torrents) + + if unrar_version_exists: + raise UploadException("An UNRAR duplicate of this specific release already exists on site.") + else: + console.print(f"[bold yellow]Found a RAR version of this release on {self.tracker}. Appending [UNRAR] to filename.[/bold yellow]") + needs_unrar_tag = True + + if needs_unrar_tag: + upload_base_name = meta['scene_name'] if is_scene else meta['uuid'] + upload_filename = f"{upload_base_name} [UNRAR].torrent" + else: + upload_filename = f"{base_name}.torrent" + + with open(torrent_path, 'rb') as torrent_file: + files = {'file': (upload_filename, torrent_file, "application/x-bittorrent")} + upload_url = f"{self.api_base_url}/torrents/upload" + + if meta['debug'] is False: + response = self.session.post(upload_url, data=data, files=files, cookies=self.auth_cookies, timeout=90) + response.raise_for_status() + json_response = response.json() + meta['tracker_status'][self.tracker]['status_message'] = response.json() + + if response.status_code == 200 and json_response.get('id'): + torrent_id = json_response.get('id') + details_url = f"{self.base_url}/torrent/{torrent_id}/" if torrent_id else self.base_url + if torrent_id: + meta['tracker_status'][self.tracker]['torrent_id'] = torrent_id + announce_url = self.config['TRACKERS'][self.tracker].get('announce_url') + await self.add_tracker_torrent(meta, self.tracker, self.source_flag, announce_url, details_url) + else: + raise UploadException(f"{json_response.get('message', 'Unknown API error.')}") + else: + console.print(f"[bold blue]Debug Mode: Upload to {self.tracker} was not sent.[/bold blue]") + console.print("Headers:", self.session.headers) + console.print("Payload (data):", data) + + except UploadException: + raise + except Exception as e: + raise UploadException(f"An unexpected error occurred during upload to {self.tracker}: {e}") From 503529c6cd9f97ca20d1e7295ef89507c48882c4 Mon Sep 17 00:00:00 2001 From: PythonCoderAS <13932583+PythonCoderAS@users.noreply.github.com> Date: Fri, 18 Jul 2025 23:02:00 -0400 Subject: [PATCH 2/5] Finish --- src/languages.py | 28 +++++++- src/trackers/NYAA.py | 163 ++++++++++++++++--------------------------- 2 files changed, 86 insertions(+), 105 deletions(-) diff --git a/src/languages.py b/src/languages.py index d70ad7b47..6aad0a2d7 100644 --- a/src/languages.py +++ b/src/languages.py @@ -220,11 +220,33 @@ async def process_desc_language(meta, desc=None, tracker=None): else: return desc if desc is not None else None +async def has_language(languages, lang_to_check): + """Check if any language in the list matches the given language""" + if isinstance(languages, str): + languages = [languages] + if not languages: + return False + lang_lower = lang_to_check.lower() + return any(lang_lower in lang.lower() for lang in languages) -async def has_english_language(languages): - """Check if any language in the list contains 'english'""" +async def has_language_other_than(languages, lang_to_check): + """Check if any language in the list does not match the given language""" if isinstance(languages, str): languages = [languages] if not languages: return False - return any('english' in lang.lower() for lang in languages) + lang_lower = lang_to_check.lower() + return any(lang_lower not in lang.lower() for lang in languages) + +async def doesnt_have_language(languages, lang_to_check): + """Check if no language in the list matches the given language""" + if isinstance(languages, str): + languages = [languages] + if not languages: + return True + lang_lower = lang_to_check.lower() + return all(lang_lower not in lang.lower() for lang in languages) + +async def has_english_language(languages): + """Check if any language in the list contains 'english'""" + return await has_language(languages, 'english') diff --git a/src/trackers/NYAA.py b/src/trackers/NYAA.py index 6cf75d556..a02464452 100644 --- a/src/trackers/NYAA.py +++ b/src/trackers/NYAA.py @@ -1,9 +1,12 @@ # -*- coding: utf-8 -*- import os import re +from xml.etree import ElementTree + import requests from src.exceptions import UploadException from src.console import console +from src.languages import has_english_language, has_language, has_language_other_than from .COMMON import COMMON from torf import Torrent from aiohttp import ClientSession @@ -88,35 +91,15 @@ async def get_category_id(self, meta): # sd = meta.get('sd') mediainfo = meta.get("mediainfo", {}) - print(meta) - raise Exception - - if is_disc == 'BDMV': - if resolution == '1080p' and category == 'MOVIE': - return 3 - elif resolution == '2160p' and category == 'MOVIE': - return 38 - elif category == 'TV': - return 14 - if is_disc == 'DVD': - if category == 'MOVIE': - return 1 - elif category == 'TV': - return 11 - if category == 'TV' and tv_pack == 1: - return 12 - if sd == 1: - if category == 'MOVIE': - return 2 - elif category == 'TV': - return 10 - category_map = { - 'MOVIE': {'2160p': 4, '1080p': 6, '1080i': 6, '720p': 5}, - 'TV': {'2160p': 13, '1080p': 9, '1080i': 9, '720p': 8}, - } - if category in category_map: - return category_map[category].get(resolution) - return None + has_english_audio_or_sub = await has_english_language(meta.get('audio_languages')) or await has_english_language(meta.get('subtitle_languages')) + has_non_japanese = await has_language_other_than(meta.get('audio_languages'), 'japanese') or await has_language_other_than(meta.get('subtitle_languages'), 'japanese') + + if has_english_audio_or_sub: + return "1_2" + elif has_non_japanese: + return "1_3" + else: + return "1_4" async def login(self): if self.session_cookie is None: @@ -134,23 +117,41 @@ async def search_existing(self, meta, disctype): console.print(f"[bold red]Login failed on {self.tracker}: No session cookie provided.[/bold red]") return [] - search_url = f"{self.api_base_url}/torrents" - search_params = {'searchText': imdb_id} + search_url = f"{self.base_url}/" + search_params = {'q': meta["name"]} try: - response = self.session.get(search_url, params=search_params, cookies=self.auth_cookies, timeout=15) - response.raise_for_status() + async with self.session.get(search_url, params=search_params, timeout=15) as response: + response.raise_for_status() + + if text := await response.text(): + root = ElementTree.fromstring(text) - if response.text and response.text != '[]': - results = response.json() - if results and isinstance(results, list): - return results + # 3. Find all items, accommodating both RSS () and Atom () + # The './/' prefix searches the entire tree for the tag. + items = root.findall('.//item') + root.findall('.//entry') + + titles = [] + for item in items: + # Find the 'title' tag within each item/entry + title_element = item.find('title') + if title_element is not None and title_element.text: + titles.append(title_element.text.strip()) + + return titles except Exception as e: - console.print(f"[bold red]Error searching for IMDb ID '{imdb_id}' on {self.tracker}: {e}[/bold red]") + console.print(f"[bold red]Error searching for '{search_params["q"]}' on {self.tracker}: {e}[/bold red]") return [] + async def add_tracker_torrent(self, meta, tracker, source_flag, new_tracker, comment): + if os.path.exists(f"{meta['base_dir']}/tmp/{meta['uuid']}/[{tracker}].torrent"): + new_torrent = Torrent.read(f"{meta['base_dir']}/tmp/{meta['uuid']}/[{tracker}].torrent") + new_torrent.metainfo['announce'] = new_tracker + new_torrent.metainfo['comment'] = comment + Torrent.copy(new_torrent).write(f"{meta['base_dir']}/tmp/{meta['uuid']}/[{tracker}].torrent", overwrite=True) + async def upload(self, meta, disctype): await self.edit_torrent(meta, self.tracker, self.source_flag) @@ -162,85 +163,43 @@ async def upload(self, meta, disctype): with open(description_path, 'r', encoding='utf-8') as f: description = f.read() - imdb = meta.get('imdb_info', {}).get('imdbID', '') - - mi_path = f"{meta['base_dir']}/tmp/{meta['uuid']}/{'BD_SUMMARY_00.txt' if meta.get('is_disc') == 'BDMV' else 'MEDIAINFO.txt'}" - with open(mi_path, 'r', encoding='utf-8') as f: - mediainfo_dump = f.read() - - is_anonymous = "1" if meta['anon'] != 0 or self.config['TRACKERS'][self.tracker].get('anon', False) else "0" + is_anonymous = meta['anon'] != 0 or self.config['TRACKERS'][self.tracker].get('anon', False) + is_pack = bool(meta.get('tv_pack', 0)) + is_remake = bool(meta.get("repack", "")) data = { + 'display_name': meta['name'], 'category': cat_id, - 'imdbId': imdb, - 'nfo': description, - 'mediainfo': mediainfo_dump, - 'reqid': "0", - 'section': "new", - 'frileech': "1", - 'anonymousUpload': is_anonymous, - 'p2p': "0" + 'information': f"https://myanimelist.net/anime/{meta['mal']}" if meta.get('mal') else '', + description: description, } + if is_anonymous: + data['is_anonymous'] = 'y' + if is_pack: + data['is_complete'] = 'y' + if is_remake: + data['is_remake'] = 'y' + torrent_path = f"{meta['base_dir']}/tmp/{meta['uuid']}/[{self.tracker}].torrent" + upload_filename = f"{meta['name']}.torrent" try: - is_scene = bool(meta.get('scene_name')) - base_name = meta['scene_name'] if is_scene else meta['uuid'] - - existing_torrents = await self.search_existing(meta, disctype) - needs_unrar_tag = False - - if existing_torrents: - current_release_identifiers = {meta['uuid']} - if is_scene: - current_release_identifiers.add(meta['scene_name']) - - relevant_torrents = [ - t for t in existing_torrents - if t.get('name') in current_release_identifiers - ] - - if relevant_torrents: - unrar_version_exists = any(t.get('unrar', 0) != 0 for t in relevant_torrents) - - if unrar_version_exists: - raise UploadException("An UNRAR duplicate of this specific release already exists on site.") - else: - console.print(f"[bold yellow]Found a RAR version of this release on {self.tracker}. Appending [UNRAR] to filename.[/bold yellow]") - needs_unrar_tag = True - - if needs_unrar_tag: - upload_base_name = meta['scene_name'] if is_scene else meta['uuid'] - upload_filename = f"{upload_base_name} [UNRAR].torrent" - else: - upload_filename = f"{base_name}.torrent" - with open(torrent_path, 'rb') as torrent_file: - files = {'file': (upload_filename, torrent_file, "application/x-bittorrent")} - upload_url = f"{self.api_base_url}/torrents/upload" + files = {'torrent_file': (upload_filename, torrent_file, "application/x-bittorrent")} + upload_url = f"{self.base_url}/upload" if meta['debug'] is False: - response = self.session.post(upload_url, data=data, files=files, cookies=self.auth_cookies, timeout=90) - response.raise_for_status() - json_response = response.json() - meta['tracker_status'][self.tracker]['status_message'] = response.json() - - if response.status_code == 200 and json_response.get('id'): - torrent_id = json_response.get('id') - details_url = f"{self.base_url}/torrent/{torrent_id}/" if torrent_id else self.base_url - if torrent_id: - meta['tracker_status'][self.tracker]['torrent_id'] = torrent_id - announce_url = self.config['TRACKERS'][self.tracker].get('announce_url') + async with self.session.post(upload_url, data=data, files=files, timeout=90, allow_redirects=True) as response: + response.raise_for_status() + details_url = response.url + torrent_id = int(re.search(r'/view/(\d+)', str(details_url)).group(1)) + meta['tracker_status'][self.tracker]['torrent_id'] = torrent_id + announce_url = self.announce_url await self.add_tracker_torrent(meta, self.tracker, self.source_flag, announce_url, details_url) - else: - raise UploadException(f"{json_response.get('message', 'Unknown API error.')}") else: console.print(f"[bold blue]Debug Mode: Upload to {self.tracker} was not sent.[/bold blue]") console.print("Headers:", self.session.headers) console.print("Payload (data):", data) - - except UploadException: - raise except Exception as e: raise UploadException(f"An unexpected error occurred during upload to {self.tracker}: {e}") From a797c4f093d50cfc7bc24565320ab7defaa25f01 Mon Sep 17 00:00:00 2001 From: PythonCoderAS <13932583+PythonCoderAS@users.noreply.github.com> Date: Sat, 19 Jul 2025 00:00:36 -0400 Subject: [PATCH 3/5] Finish? --- src/trackers/NYAA.py | 44 +++++++++++++++++++++++++++++++++----------- src/trackersetup.py | 5 +++-- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/src/trackers/NYAA.py b/src/trackers/NYAA.py index a02464452..22a24def4 100644 --- a/src/trackers/NYAA.py +++ b/src/trackers/NYAA.py @@ -6,10 +6,10 @@ import requests from src.exceptions import UploadException from src.console import console -from src.languages import has_english_language, has_language, has_language_other_than +from src.languages import has_english_language, has_language, has_language_other_than, process_desc_language from .COMMON import COMMON from torf import Torrent -from aiohttp import ClientSession +from aiohttp import ClientSession, FormData class NYAA(COMMON): @@ -24,7 +24,7 @@ def __init__(self, config): self.session_cookie = self.config['TRACKERS'][self.tracker].get('session_cookie') self.session = ClientSession(headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36'}, cookies={'session': self.session_cookie} if self.session_cookie else None) - self.signature = "----\n[Created by Audionut's Upload Assistant](https://github.com/Audionut/Upload-Assistant)" + self.signature = "----\n[Created by a modified version of Audionut's Upload Assistant](https://github.com/Audionut/Upload-Assistant)" async def edit_torrent(self, meta, tracker, source_flag, torrent_filename="BASE"): if os.path.exists(f"{meta['base_dir']}/tmp/{meta['uuid']}/{torrent_filename}.torrent"): @@ -66,6 +66,13 @@ async def generate_description(self, meta): with open(bd_summary_file, 'r', encoding='utf-8') as f: tech_info = f.read() + if not meta.get('audio_languages') or not meta.get('subtitle_languages'): + await process_desc_language(meta, desc=None, tracker=self.tracker) + + if meta.get("subtitle_languages", []): + sub_languages = '\n'.join(f"- {lang}" for lang in meta["subtitle_languages"]) + desc_parts.append(f"## Subtitles\n{sub_languages}\n") + if tech_info: desc_parts.append(f"## BD Info\n```\n{tech_info}\n```\n") @@ -73,7 +80,12 @@ async def generate_description(self, meta): if os.path.exists(mediainfo_file): with open(mediainfo_file, 'r', encoding='utf-8') as f: mediainfo_content = f.read() - desc_parts.append(f"## MediaInfo\n```\n{mediainfo_content}\n```\n") + mediainfo_pieces = mediainfo_content.split('\n\n') + kept_pieces = [] + for mediainfo_piece, mediainfo_piece_json in zip(mediainfo_pieces, meta["mediainfo"]["media"]["track"]): + if mediainfo_piece_json["@type"] in ["General", "Video", "Audio"]: + kept_pieces.append(mediainfo_piece) + desc_parts.append(f"## MediaInfo\n```\n{"\n\n".join(kept_pieces)}\n```\n") if self.signature: desc_parts.append(self.signature) @@ -90,7 +102,9 @@ async def get_category_id(self, meta): # tv_pack = meta.get('tv_pack') # sd = meta.get('sd') - mediainfo = meta.get("mediainfo", {}) + if not meta.get('audio_languages') or not meta.get('subtitle_languages'): + await process_desc_language(meta, desc=None, tracker=self.tracker) + has_english_audio_or_sub = await has_english_language(meta.get('audio_languages')) or await has_english_language(meta.get('subtitle_languages')) has_non_japanese = await has_language_other_than(meta.get('audio_languages'), 'japanese') or await has_language_other_than(meta.get('subtitle_languages'), 'japanese') @@ -101,7 +115,7 @@ async def get_category_id(self, meta): else: return "1_4" - async def login(self): + async def validate_credentials(self, meta): if self.session_cookie is None: console.print(f"[bold red]Login failed on {self.tracker}: No session cookie provided.[/bold red]") return False @@ -118,7 +132,7 @@ async def search_existing(self, meta, disctype): return [] search_url = f"{self.base_url}/" - search_params = {'q': meta["name"]} + search_params = {'q': meta["name"], "page": "rss"} try: async with self.session.get(search_url, params=search_params, timeout=15) as response: @@ -171,7 +185,7 @@ async def upload(self, meta, disctype): 'display_name': meta['name'], 'category': cat_id, 'information': f"https://myanimelist.net/anime/{meta['mal']}" if meta.get('mal') else '', - description: description, + "description": description, } if is_anonymous: @@ -186,13 +200,19 @@ async def upload(self, meta, disctype): upload_filename = f"{meta['name']}.torrent" try: with open(torrent_path, 'rb') as torrent_file: - files = {'torrent_file': (upload_filename, torrent_file, "application/x-bittorrent")} + form_data = FormData() + for key, value in data.items(): + form_data.add_field(key, value) + # files = {'torrent_file': (upload_filename, torrent_file, "application/x-bittorrent")} + form_data.add_field("torrent_file", torrent_file, filename=upload_filename) upload_url = f"{self.base_url}/upload" if meta['debug'] is False: - async with self.session.post(upload_url, data=data, files=files, timeout=90, allow_redirects=True) as response: + async with self.session.post(upload_url, data=form_data, timeout=90, allow_redirects=True) as response: + with open(f"{meta['base_dir']}/tmp/{meta['uuid']}/upload_response.html", 'w', encoding='utf-8') as f: + f.write(await response.text()) response.raise_for_status() - details_url = response.url + details_url = str(response.url) torrent_id = int(re.search(r'/view/(\d+)', str(details_url)).group(1)) meta['tracker_status'][self.tracker]['torrent_id'] = torrent_id announce_url = self.announce_url @@ -203,3 +223,5 @@ async def upload(self, meta, disctype): console.print("Payload (data):", data) except Exception as e: raise UploadException(f"An unexpected error occurred during upload to {self.tracker}: {e}") + finally: + await self.session.close() diff --git a/src/trackersetup.py b/src/trackersetup.py index a4940c6ed..5efabceff 100644 --- a/src/trackersetup.py +++ b/src/trackersetup.py @@ -26,6 +26,7 @@ from src.trackers.LT import LT from src.trackers.MTV import MTV from src.trackers.NBL import NBL +from src.trackers.NYAA import NYAA from src.trackers.OE import OE from src.trackers.OTW import OTW from src.trackers.PSS import PSS @@ -468,7 +469,7 @@ async def process_single_tracker(tracker_name): tracker_class_map = { 'ACM': ACM, 'AITHER': AITHER, 'AL': AL, 'ANT': ANT, 'AR': AR, 'ASC': ASC, 'BHD': BHD, 'BHDTV': BHDTV, 'BLU': BLU, 'BT': BT, 'CBR': CBR, 'DC': DC, 'DP': DP, 'FNP': FNP, 'FL': FL, 'FRIKI': FRIKI, 'HDB': HDB, 'HDS': HDS, 'HDT': HDT, 'HHD': HHD, 'HUNO': HUNO, 'ITT': ITT, - 'LCD': LCD, 'LDU': LDU, 'LST': LST, 'LT': LT, 'MTV': MTV, 'NBL': NBL, 'OE': OE, 'OTW': OTW, 'PSS': PSS, 'PT': PT, 'PTP': PTP, 'PTER': PTER, 'PTT': PTT, + 'LCD': LCD, 'LDU': LDU, 'LST': LST, 'LT': LT, 'MTV': MTV, 'NBL': NBL, "NYAA": NYAA, 'OE': OE, 'OTW': OTW, 'PSS': PSS, 'PT': PT, 'PTP': PTP, 'PTER': PTER, 'PTT': PTT, 'R4E': R4E, 'RAS': RAS, 'RF': RF, 'RTF': RTF, 'SAM': SAM, 'SHRI': SHRI, 'SN': SN, 'SP': SP, 'SPD': SPD, 'STC': STC, 'THR': THR, 'TIK': TIK, 'TL': TL, 'TOCA': TOCA, 'TVC': TVC, 'TTG': TTG, 'UHD': UHD, 'ULCX': ULCX, 'UTP': UTP, 'YOINK': YOINK, 'YUS': YUS } @@ -483,5 +484,5 @@ async def process_single_tracker(tracker_name): } http_trackers = { - 'AR', 'ASC', 'BT', 'FL', 'HDB', 'HDS', 'HDT', 'MTV', 'PTER', 'TTG' + 'AR', 'ASC', 'BT', 'FL', 'HDB', 'HDS', 'HDT', 'MTV', 'PTER', 'TTG', "NYAA" } From 369425e55177fcfc9cf0d272f13908c9d6bc361f Mon Sep 17 00:00:00 2001 From: PythonCoderAS <13932583+PythonCoderAS@users.noreply.github.com> Date: Fri, 1 Aug 2025 01:07:42 -0400 Subject: [PATCH 4/5] Rm sig --- src/trackers/NYAA.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/trackers/NYAA.py b/src/trackers/NYAA.py index 22a24def4..6648b11d8 100644 --- a/src/trackers/NYAA.py +++ b/src/trackers/NYAA.py @@ -24,7 +24,7 @@ def __init__(self, config): self.session_cookie = self.config['TRACKERS'][self.tracker].get('session_cookie') self.session = ClientSession(headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36'}, cookies={'session': self.session_cookie} if self.session_cookie else None) - self.signature = "----\n[Created by a modified version of Audionut's Upload Assistant](https://github.com/Audionut/Upload-Assistant)" + self.signature = "" async def edit_torrent(self, meta, tracker, source_flag, torrent_filename="BASE"): if os.path.exists(f"{meta['base_dir']}/tmp/{meta['uuid']}/{torrent_filename}.torrent"): @@ -55,7 +55,7 @@ async def generate_description(self, meta): for image_number, image in enumerate(images, start=1): img_url = image['img_url'] web_url = image['web_url'] - screenshots_block += f"[![Screenshot ]({img_url})]({web_url}) " + screenshots_block += f"[![Screenshot]({img_url})]({web_url}) " desc_parts.append(screenshots_block) # BDInfo From 13f1803cd7da595bd8b73944fefa6b429d76ef6e Mon Sep 17 00:00:00 2001 From: PythonCoderAS <13932583+PythonCoderAS@users.noreply.github.com> Date: Fri, 1 Aug 2025 01:08:19 -0400 Subject: [PATCH 5/5] Add python version --- .python-version | 1 + 1 file changed, 1 insertion(+) create mode 100644 .python-version diff --git a/.python-version b/.python-version new file mode 100644 index 000000000..e4fba2183 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.12