diff --git a/data/example-config.py b/data/example-config.py index 84909908..8e628821 100644 --- a/data/example-config.py +++ b/data/example-config.py @@ -214,7 +214,6 @@ "password": "password", "api_key": 'get_it_by_running_/api/ login command from https://retroflix.club/api/doc', "announce_url": "get from upload page", - # "tag": "RetroFlix, nd", "anon": True }, "RF": { @@ -254,6 +253,10 @@ "announce_url": "https://shareisland.org/announce/customannounceurl", # "anon" : "False" }, + "SPD": { + "api_key": "SPEEDAPP API KEY", + "announce_url": "https://ramjet.speedapp.io//announce", + }, "TIK": { "useAPI": False, # Set to True if using TIK "api_key": "", @@ -261,6 +264,11 @@ "anon": False, "modq": True, }, + "TVC": { + "api_key": "TVC API Key", + "announce_url": "https://tvchaosuk.com/announce/", + "anon": "False" + }, "PSS": { "api_key": "PSS api key", "announce_url": "https://privatesilverscreen.cc/announce/customannounceurl", diff --git a/src/trackers/SPD.py b/src/trackers/SPD.py new file mode 100644 index 00000000..b5893da1 --- /dev/null +++ b/src/trackers/SPD.py @@ -0,0 +1,153 @@ +# -*- coding: utf-8 -*- +# import discord +import asyncio +from torf import Torrent +import requests +from src.console import console +from pprint import pprint +import base64 +import shutil +import os +import traceback + +from src.trackers.COMMON import COMMON + + +# from pprint import pprint + +class SPD(): + + def __init__(self, config): + self.url = "https://speedapp.io" + self.config = config + self.tracker = 'SPD' + self.source_flag = 'speedapp.io' + self.search_url = 'https://speedapp.io/api/torrent' + self.upload_url = 'https://speedapp.io/api/upload' + self.forum_link = 'https://speedapp.io/support/wiki/rules' + self.banned_groups = [''] + pass + + async def upload(self, meta, disctype): + common = COMMON(config=self.config) + await common.edit_torrent(meta, self.tracker, self.source_flag) + type_id = "" + if meta['anime']: + type_id = '3' + elif meta['category'] == 'TV': + if meta['tv_pack']: + type_id = '41' + elif meta['sd'] and not meta['tv_pack']: + type_id = '45' + # must be hd + else: + type_id = '43' + else: + if meta['type'] != "DISC" and meta['resolution'] == "2160p": + type_id = '61' + else: + type_id = { + 'DISC': '17', + 'REMUX': '8', + 'WEBDL': '8', + 'WEBRIP': '8', + 'HDTV': '8', + 'SD': '10', + 'ENCODE': '8' + }.get(type, '0') + + if meta['bdinfo'] is not None: + mi_dump = None + bd_dump = open(f"{meta['base_dir']}/tmp/{meta['uuid']}/BD_SUMMARY_00.txt", 'r', encoding='utf-8').read() + else: + mi_dump = open(f"{meta['base_dir']}/tmp/{meta['uuid']}/MEDIAINFO_CLEANPATH.txt", 'r', encoding='utf-8').read() + bd_dump = None + screenshots = [] + if len(meta['image_list']) != 0: + for image in meta['image_list']: + screenshots.append(image['raw_url']) + data = { + 'name': meta['name'].replace("'", '').replace(': ', '.').replace(':', '.').replace(' ', '.').replace(' ', '.').replace('DD+', 'DDP'), + 'screenshots': screenshots, + 'release_info': f"[center][url={self.forum_link}]Please seed[/url][/center]", + 'media_info': mi_dump, + 'bd_info': bd_dump, + 'type': type_id, + 'url': f"https://www.imdb.com/title/tt{meta['imdb_id']}", + 'shortDescription': meta['genres'], + 'keywords': meta['keywords'], + 'releaseInfo': self.forum_link + } + with open(f"{meta['base_dir']}/tmp/{meta['uuid']}/[{self.tracker}]{meta['clean_name']}.torrent", 'rb') as binary_file: + binary_file_data = binary_file.read() + base64_encoded_data = base64.b64encode(binary_file_data) + base64_message = base64_encoded_data.decode('utf-8') + data['file'] = base64_message + + headers = {'Authorization': 'Bearer ' + self.config['TRACKERS'][self.tracker]['api_key'].strip()} + + if meta['debug'] is False: + response = requests.request("POST", url=self.upload_url, json=data, headers=headers) + try: + print(response.json()) + # response = {'status': True, 'error': False, 'downloadUrl': '/api/torrent/383435/download', 'torrent': {'id': 383435, 'name': 'name-with-full-stops', 'slug': 'name-with-dashs', 'category_id': 3}} + # downloading the torrent from site as it adds a tonne of different trackers and the source is different all the time. + try: + # torrent may not dl and may not provide error if machine is under load or network connection usage high. + with requests.get(url=self.url + response.json()['downloadUrl'], stream=True, headers=headers) as r: + # replacing L4g/torf created torrent so it will be added to the client. + with open(f"{meta['base_dir']}/tmp/{meta['uuid']}/[{self.tracker}]{meta['clean_name']}.torrent", + 'wb') as f: + shutil.copyfileobj(r.raw, f) + # adding as comment link to torrent + if os.path.exists(f"{meta['base_dir']}/tmp/{meta['uuid']}/[{self.tracker}]{meta['clean_name']}.torrent"): + new_torrent = Torrent.read(f"{meta['base_dir']}/tmp/{meta['uuid']}/[{self.tracker}]{meta['clean_name']}.torrent") + new_torrent.metainfo['comment'] = f"{self.url}/browse/{response.json()['torrent']['id']}" + Torrent.copy(new_torrent).write(f"{meta['base_dir']}/tmp/{meta['uuid']}/[{self.tracker}]{meta['clean_name']}.torrent", overwrite=True) + except Exception: + console.print(traceback.print_exc()) + console.print("[red]Unable to Download torrent, try manually") + except Exception: + console.print(traceback.print_exc()) + console.print("[yellow]Unable to Download torrent, try manually") + return + else: + console.print("[cyan]Request Data:") + pprint(data) + + async def get_cat_id(self, category_name): + category_id = { + 'MOVIE': '1', + 'TV': '2', + 'FANRES': '3' + }.get(category_name, '0') + return category_id + + async def search_existing(self, meta, disctype): + dupes = [] + console.print("[yellow]Searching for existing torrents on site...") + headers = { + 'accept': 'application/json', + 'Authorization': self.config['TRACKERS'][self.tracker]['api_key'].strip(), + } + + params = { + 'includingDead': '1' + } + + if meta['imdb_id'] != "0": + params['imdbId'] = meta['imdb_id'] if str(meta['imdb_id']).startswith("tt") else "tt" + meta['imdb_id'] + else: + params['search'] = meta['title'].replace(':', '').replace("'", '').replace(",", '') + + try: + response = requests.get(url=self.search_url, params=params, headers=headers) + response = response.json() + for each in response: + result = [each][0]['name'] + dupes.append(result) + except Exception: + console.print('[bold red]Unable to search for existing torrents on site. Either the site is down or your API key is incorrect') + await asyncio.sleep(5) + + return dupes diff --git a/upload.py b/upload.py index 0c73bb37..300b77ea 100644 --- a/upload.py +++ b/upload.py @@ -43,6 +43,7 @@ from src.trackers.TVC import TVC from src.trackers.PSS import PSS from src.trackers.ULCX import ULCX +from src.trackers.SPD import SPD import json from pathlib import Path import asyncio @@ -238,13 +239,13 @@ async def do_the_thing(base_dir): common = COMMON(config=config) api_trackers = ['BLU', 'AITHER', 'STC', 'R4E', 'STT', 'RF', 'ACM', 'LCD', 'HUNO', 'LT', 'JPTV', 'TDC', 'OE', 'OTW', 'FNP', 'CBR', 'UTP', 'AL', 'SHRI', 'LST', 'TIK', 'PSS', 'ULCX', 'BHD'] - other_api_trackers = ['SN', 'NBL', 'ANT', 'BHDTV', 'RTF', 'TL', 'TVC'] + other_api_trackers = ['SN', 'NBL', 'ANT', 'BHDTV', 'RTF', 'TL', 'TVC', 'SPD'] http_trackers = ['HDB', 'TTG', 'FL', 'PTER', 'HDT', 'MTV'] tracker_class_map = { 'BLU': BLU, 'BHD': BHD, 'AITHER': AITHER, 'STC': STC, 'R4E': R4E, 'THR': THR, 'STT': STT, 'HP': HP, 'PTP': PTP, 'RF': RF, 'SN': SN, 'TIK': TIK, 'TVC': TVC, 'ACM': ACM, 'HDB': HDB, 'LCD': LCD, 'TTG': TTG, 'LST': LST, 'HUNO': HUNO, 'FL': FL, 'LT': LT, 'NBL': NBL, 'ANT': ANT, 'PTER': PTER, 'JPTV': JPTV, 'TL': TL, 'TDC': TDC, 'HDT': HDT, 'MTV': MTV, 'OE': OE, 'BHDTV': BHDTV, 'RTF': RTF, 'OTW': OTW, 'FNP': FNP, 'CBR': CBR, 'UTP': UTP, 'AL': AL, - 'SHRI': SHRI, 'PSS': PSS, 'ULCX': ULCX} + 'SHRI': SHRI, 'PSS': PSS, 'ULCX': ULCX, 'SPD': SPD} tracker_capabilities = { 'LST': {'mod_q': True, 'draft': True},