4
1
Fork 1

Compare commits

...

2 Commits

Author SHA1 Message Date
trueold89 f9681e35f4
Add qbittorrent api class 2024-05-09 17:47:57 +03:00
trueold89 e5857715e8
Add Torrent class 2024-05-05 20:10:11 +03:00
5 changed files with 136 additions and 5 deletions

View File

@ -31,3 +31,4 @@ configuration = loadCFG(CFG_PATH)
dirParser, JellyfinConfig = loadParser(configuration)
DBPath = configuration["Main"]["DBPath"]
tmpDir = configuration["Main"]["TMPDir"]

View File

@ -1 +1,67 @@
# -*- coding: utf-8 -*-
from requests import get, post
from requests.cookies import RequestsCookieJar
from Torrent import TorrentFile, MagnetLink, Torrent, TorrentTypes
class Qbit(object):
def __init__(self, username: str, passwd: str, url: str):
self.username = username
self.passwd = passwd
self.baseurl = url
self.cookies = self.__getcookies()
def __getcookies(self) -> RequestsCookieJar:
creds = {
"username": self.username,
"password": self.passwd
}
resp = post(f"{self.baseurl}/api/v2/auth/login", data=creds)
cookies = resp.cookies
if get(f"{self.baseurl}/api/v2/app/version", cookies=cookies).status_code != 200:
raise Exception("Error connecting to QBitTorrentAPI")
return cookies
def getlist(self) -> list:
json = get(f"{self.baseurl}/api/v2/torrents/info?filter=completed,downloading&sort=progress", cookies=self.cookies).json()
output = []
for element in json:
output.append(TorrentElement(element["name"], element["state"], float(element["progress"])))
return output
def __uploadfile(self, torrent: TorrentFile) -> int:
with open(torrent.url, "rb") as torrent_binary:
torrent_file = {"torrents": (torrent.url, torrent_binary, "application/x-bittorrent")}
params = {"savepath": torrent.path}
resp = post(url=f"{self.baseurl}/api/v2/torrents/add", cookies=self.cookies, files=torrent_file, data=params)
return resp.status_code
def __uploadmagnet(self, torrent: MagnetLink) -> int:
params = {
"urls": torrent.url,
"savepath": torrent.path
}
resp = post(url=f"{self.baseurl}/api/v2/torrents/add", cookies=self.cookies, data=params)
return resp.status_code
def upload(self, torrent: Torrent) -> None:
status = None
match torrent.torrent_type:
case TorrentTypes.FILE:
status = self.__uploadfile(torrent)
case TorrentTypes.MAGNET:
status = self.__uploadmagnet(torrent)
if status != 200:
raise Exception("Error downloading torrent")
class TorrentElement(object):
def __init__(self, name: str, state: str, progress: float):
self.name = name
self.state = state
self.progress = round(progress*100, 1)
def __str__(self):
return f"{self.name} | {self.state} | {self.progress}%"

View File

@ -7,6 +7,11 @@ class DirParserTypes(Enum):
class LogTypes(Enum):
LOG = "Log"
ERROR = "Error"
WARN = "Warning"
LOG = "LOG"
ERROR = "ERROR"
WARN = "WARNING"
class TorrentTypes(Enum):
MAGNET = "Magnet Link"
FILE = "Torrent File"

58
Torrent.py Normal file
View File

@ -0,0 +1,58 @@
# -*- coding: utf-8 -*-
from abc import ABCMeta, abstractmethod, abstractproperty
from typing import BinaryIO
from TYPES import TorrentTypes
from os.path import splitext as getext
from re import match
from Config import tmpDir
class Torrent(object):
__metaclass__ = ABCMeta
def __init__(self, url: str, path: str):
self.url = url
self.path = path
if not (self.validate()):
raise ValueError
@property
@abstractmethod
def torrent_type(self) -> TorrentTypes:
pass
@abstractmethod
def validate(self) -> bool:
pass
@property
def value(self) -> str:
return self.value
class MagnetLink(Torrent):
@property
def torrent_type(self) -> TorrentTypes:
return TorrentTypes.MAGNET
def validate(self) -> bool:
pattern = r"^magnet:\?xt=urn:btih:[a-fA-F0-9]{40}.*$"
if match(pattern, self.url):
return True
class TorrentFile(Torrent):
def __init__(self, url: str, path: str):
super().__init__(url, path)
self.url = f"{tmpDir}/{url}"
@property
def torrent_type(self) -> TorrentTypes:
return TorrentTypes.FILE
def validate(self) -> bool:
if getext(self.url)[1].lower() == ".torrent":
return True

View File

@ -1,7 +1,8 @@
{
"Main": {
"DirParser": "Jellyfin",
"DBPath": "/etc/qbitbot/botdb.db"
"DBPath": "/etc/qbitbot/botdb.db",
"TMPDir": "/tmp/qbitbot"
},
"JellyfinConfig": {