Compare commits
No commits in common. "f9681e35f4455eaacce83dd9f9c5bbb532bf0a93" and "7e17c716101c521f8cd78c565eee96635bd25e2c" have entirely different histories.
f9681e35f4
...
7e17c71610
|
@ -31,4 +31,3 @@ configuration = loadCFG(CFG_PATH)
|
||||||
|
|
||||||
dirParser, JellyfinConfig = loadParser(configuration)
|
dirParser, JellyfinConfig = loadParser(configuration)
|
||||||
DBPath = configuration["Main"]["DBPath"]
|
DBPath = configuration["Main"]["DBPath"]
|
||||||
tmpDir = configuration["Main"]["TMPDir"]
|
|
||||||
|
|
66
QBitAPI.py
66
QBitAPI.py
|
@ -1,67 +1 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- 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}%"
|
|
||||||
|
|
11
TYPES.py
11
TYPES.py
|
@ -7,11 +7,6 @@ class DirParserTypes(Enum):
|
||||||
|
|
||||||
|
|
||||||
class LogTypes(Enum):
|
class LogTypes(Enum):
|
||||||
LOG = "LOG"
|
LOG = "Log"
|
||||||
ERROR = "ERROR"
|
ERROR = "Error"
|
||||||
WARN = "WARNING"
|
WARN = "Warning"
|
||||||
|
|
||||||
|
|
||||||
class TorrentTypes(Enum):
|
|
||||||
MAGNET = "Magnet Link"
|
|
||||||
FILE = "Torrent File"
|
|
||||||
|
|
58
Torrent.py
58
Torrent.py
|
@ -1,58 +0,0 @@
|
||||||
# -*- 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
|
|
|
@ -1,8 +1,7 @@
|
||||||
{
|
{
|
||||||
"Main": {
|
"Main": {
|
||||||
"DirParser": "Jellyfin",
|
"DirParser": "Jellyfin",
|
||||||
"DBPath": "/etc/qbitbot/botdb.db",
|
"DBPath": "/etc/qbitbot/botdb.db"
|
||||||
"TMPDir": "/tmp/qbitbot"
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"JellyfinConfig": {
|
"JellyfinConfig": {
|
||||||
|
|
Reference in New Issue