kopia lustrzana https://github.com/Adair-GA/rarbg-database-api
first commit
commit
83c163d9bf
|
@ -0,0 +1,5 @@
|
||||||
|
venv/
|
||||||
|
__pycache__/
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
rarbg_db.sqlite
|
|
@ -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
|
|
@ -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())
|
Plik binarny nie jest wyświetlany.
|
@ -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)
|
Ładowanie…
Reference in New Issue