diff --git a/Config.py b/Config.py index a33c8f6..280c134 100644 --- a/Config.py +++ b/Config.py @@ -31,3 +31,4 @@ configuration = loadCFG(CFG_PATH) dirParser, JellyfinConfig = loadParser(configuration) DBPath = configuration["Main"]["DBPath"] +tmpDir = configuration["Main"]["TMPDir"] diff --git a/QBitAPI.py b/QBitAPI.py index 40a96af..280cb0e 100644 --- a/QBitAPI.py +++ b/QBitAPI.py @@ -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}%" diff --git a/Torrent.py b/Torrent.py index f406e66..a403d44 100644 --- a/Torrent.py +++ b/Torrent.py @@ -1,15 +1,19 @@ # -*- 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): + def __init__(self, url: str, path: str): self.url = url + self.path = path if not (self.validate()): raise ValueError @@ -41,6 +45,10 @@ class MagnetLink(Torrent): 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 diff --git a/config.json b/config.json index c750aa7..327a2d0 100644 --- a/config.json +++ b/config.json @@ -1,11 +1,12 @@ { "Main": { "DirParser": "Jellyfin", - "DBPath": "/etc/qbitbot/botdb.db" + "DBPath": "/etc/qbitbot/botdb.db", + "TMPDir": "/tmp/qbitbot" }, "JellyfinConfig": { "ServerURL": "https://yourdomain.com", "APIKey": "youaractualjellyfintoken" } -} \ No newline at end of file +}