From 83c163d9bf4fa90aea14f3ae0d5f64143e225ab3 Mon Sep 17 00:00:00 2001 From: Adair-GA Date: Sat, 3 Jun 2023 18:45:04 +0200 Subject: [PATCH] first commit --- .gitignore | 5 +++ app.py | 84 +++++++++++++++++++++++++++++++++++++++++++++++ db_conn.py | 81 +++++++++++++++++++++++++++++++++++++++++++++ requirements.txt | Bin 0 -> 404 bytes torrent.py | 29 ++++++++++++++++ 5 files changed, 199 insertions(+) create mode 100644 .gitignore create mode 100644 app.py create mode 100644 db_conn.py create mode 100644 requirements.txt create mode 100644 torrent.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0891304 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +venv/ +__pycache__/ +.vscode/ + +rarbg_db.sqlite diff --git a/app.py b/app.py new file mode 100644 index 0000000..9d6091b --- /dev/null +++ b/app.py @@ -0,0 +1,84 @@ +from fastapi import FastAPI, Request, Depends +import db_conn +from torrent import Torrent + +app = FastAPI() +DB_FILE = "rarbg_db.sqlite" + +async def get_db(): + """Return a database connection for use as a dependency. + This connection has the Row row factory automatically attached.""" + db = db_conn.RarbgDatabase() + await db.connect(DB_FILE) + + try: + yield db + finally: + await db.close() + +@app.get("/pubapi_v2.php") +async def req(request: Request, db: db_conn.RarbgDatabase = Depends(get_db)): + request_dict = dict(request.query_params.items()) + + if "get_token" in request_dict: + return {"token": "1234567890"} + + if "mode" in request_dict: + if request_dict["mode"] == "search": + return await search(db, request_dict) + elif request_dict["mode"] == "list": + return await list_cat(db, request_dict) + +def get_categories(request_dict: dict): + cats = request_dict.get("category", None) + if cats is not None: + cats = cats.split(";") + cats = [int(cat) for cat in cats] + return cats + +async def search(db: db_conn.RarbgDatabase, request_dict: dict): + list_of_categories = get_categories(request_dict) + limit = request_dict.get("limit", 100) + imdb = request_dict.get("search_imdb", None) + search_string = request_dict.get("search_string", None) + res = await db.search(list_of_categories, limit, imdb, search_string) + return build_response(res, True) + + +async def list_cat(db: db_conn.RarbgDatabase, request_dict, limit: int = 100): + categories = get_categories(request_dict) + if categories is None: + raise ValueError("No categories provided") + + res = await db.list_from_categories(categories, limit) + return build_response(res, True) + +def build_response(torrents: list[Torrent], extended: bool = False): + res = {"torrent_results": []} + if not extended: + for t in torrents: + res["torrent_results"].append({ + "filename": t.title, + "category": "Not Available", + "download": "magnet:?xt=urn:btih:" + t.hash_code, + }) + else: + for t in torrents: + res["torrent_results"].append({ + "title": t.title, + "category": "Not Available", + "download": t.build_magnet_link(), + "seeders":10, + "leechers":10, + "size":t.size, + "pubdate": t.time +" +0000", + "episode_info":{ + "imdb":t.imdb, + "tvrage": None, + "tvdb":None, + "themoviedb":None + }, + "ranked":1, + "info_page":"https://torrentapi.org/" + }) + return res diff --git a/db_conn.py b/db_conn.py new file mode 100644 index 0000000..4c68ff9 --- /dev/null +++ b/db_conn.py @@ -0,0 +1,81 @@ +import aiosqlite +import torrent + + +CATEGORIES = { + 35: 'ebooks', + 27: 'games_pc_iso', + 28: 'games_pc_rip', + 40: 'games_ps3', + 53: 'games_ps4', + 32: 'games_xbox', + 14: 'movies_xvid', + 42: 'movies_bd_full', + 46: 'movies_bd_remux', + 17: 'movies_x264', + 44: 'movies_x264', + 47: 'movies_x264_3d', + 50: 'movies_x264_4k', + 45: 'movies_x264_720p', + 54: 'movies_x265', + 51: 'movies_x265_4k', + 52: 'movies_x265_4k_hdr', + 48: 'movies_xvid_720p', + 25: 'music_flac', + 23: 'music_mp3', + 41: 'tv', + 18: 'tv_sd', + 49: 'tv_uhd', + 4: 'xxx', +} + +class RarbgDatabase: + conn: aiosqlite.Connection + + def __init__(self): + self.conn = None + + async def close(self): + await self.conn.close() + + async def connect(self, db_path: str): + self.conn = await aiosqlite.connect(db_path) + self.conn.row_factory = torrent.torrent_row_factory + + async def list_from_categories(self, list_of_categories: list[int], limit: int = 100) -> list[torrent.Torrent]: + """_summary_ + + Args: + list_of_categories (list[int]): _description_ + limit (int, optional): _description_. Defaults to 100. + + Returns: + list[tuple]: (title, hash, time, size, imdb) + """ + cats = [CATEGORIES[cat] for cat in list_of_categories] + cur = await self.conn.execute("SELECT title, hash, dt, size, imdb FROM items WHERE cat IN (" + "?,"*(len(list_of_categories)-1) + "?) ORDER BY id DESC LIMIT (?)", (*cats, limit)) + return list(await cur.fetchall()) + + async def search(self, list_of_categories: list[int]= None, limit: int = 100, imdb: str = None, search_string: str = None) -> list[torrent.Torrent]: + sql = "SELECT title, hash, dt, size, imdb FROM items WHERE " + categ = None + if list_of_categories is not None: + categ = [CATEGORIES[cat] for cat in list_of_categories] + sql += "cat IN (" + "?,"*(len(list_of_categories)-1) + "?) AND " + if imdb is not None: + sql += "imdb = ? AND " + if search_string is not None: + sql += "title LIKE ? " + + if sql.endswith("AND "): + sql = sql[:-4] + + sql += "ORDER BY id DESC LIMIT (?)" + + + params = (*categ, imdb, search_string, limit) + params = tuple([param for param in params if param is not None]) + + cur = await self.conn.execute(sql, params) + + return list(await cur.fetchall()) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..4e0fbeca39d9bdcc6ff6be4adc0fe78c02da7e01 GIT binary patch literal 404 zcmYk2+YW*-5JczM#9uKK@%G@i7=kyVq5>NIdG+izHKZveJF~Mh`~8%vbycUk&iwV- zY0b$rQP7HSrm;pU)#&X^L#Naif2{J(N+<7Jdgla=^;Kw}xh)D8ZqhDb&7HBQ+A+7( z4gG|#G=q^lPAPYlzD x%F$7a_Z=$3t>lB`J(J9Jqk}duU(RgEW2*L=a?F}G^3W61_R_*gd2_O+**_TJItc&( literal 0 HcmV?d00001 diff --git a/torrent.py b/torrent.py new file mode 100644 index 0000000..cefd202 --- /dev/null +++ b/torrent.py @@ -0,0 +1,29 @@ +import dataclasses +import urllib.parse + +trackers = ["http://tracker.trackerfix.com:80/announce", + "udp://9.rarbg.me:2740", + "udp://9.rarbg.to:2780", + "udp://tracker.fatkhoala.org:13720", + "udp://tracker.tallpenguin.org:15730"] + + + + +@dataclasses.dataclass +class Torrent: + title: str + hash_code: str + time: str + size: str + imdb: str | None + + def build_magnet_link(self): + res = "magnet:?xt=urn:btih:" + self.hash_code + "&dn=" + self.title + for tracker in trackers: + res += "&tr=" + urllib.parse.quote(tracker) + return res + + +def torrent_row_factory(_cursor, row): + return Torrent(*row) \ No newline at end of file