|
|
@@ -4,11 +4,55 @@ import logging |
|
|
|
from jinja2 import Environment, FileSystemLoader, select_autoescape |
|
|
|
from deluge_client import DelugeRPCClient |
|
|
|
from urllib.parse import urlparse |
|
|
|
from pprint import pprint |
|
|
|
from threading import Thread |
|
|
|
from time import sleep |
|
|
|
from queue import Queue |
|
|
|
from dataclasses import dataclass, field |
|
|
|
|
|
|
|
|
|
|
|
APPROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "../")) |
|
|
|
|
|
|
|
|
|
|
|
@dataclass |
|
|
|
class Cache: |
|
|
|
torrents: dict = field(default_factory=dict) |
|
|
|
|
|
|
|
|
|
|
|
class ClientCache(object): |
|
|
|
def __init__(self, client): |
|
|
|
self.client = client |
|
|
|
self.data = Cache() |
|
|
|
self.q = Queue() |
|
|
|
|
|
|
|
self.background_t = Thread(target=self.background, daemon=True) |
|
|
|
self.background_t.start() |
|
|
|
|
|
|
|
self.timer_t = Thread(target=self.timer, daemon=True) |
|
|
|
self.timer_t.start() |
|
|
|
|
|
|
|
def refresh(self): |
|
|
|
self.q.put(None) |
|
|
|
|
|
|
|
def background(self): |
|
|
|
while True: |
|
|
|
self.q.get() # block until we need to do something |
|
|
|
logging.info("performing background tasks...") |
|
|
|
|
|
|
|
self.data.torrents = self.client.core.get_torrents_status({"label": "sickrage"}, |
|
|
|
['name', 'label', 'save_path', 'is_seed', |
|
|
|
'is_finished', 'progress']) |
|
|
|
|
|
|
|
self.q.task_done() |
|
|
|
logging.info("background tasks complete") |
|
|
|
|
|
|
|
def timer(self): |
|
|
|
while True: |
|
|
|
self.refresh() |
|
|
|
logging.info("sleeping...") |
|
|
|
sleep(300) # TODO configurable task interval |
|
|
|
|
|
|
|
|
|
|
|
class MediaWeb(object): |
|
|
|
def __init__(self, rpc, templater, uioptions): |
|
|
|
self.tpl = templater |
|
|
@@ -25,17 +69,21 @@ class MediaWeb(object): |
|
|
|
return {} |
|
|
|
|
|
|
|
@cherrypy.expose |
|
|
|
def index(self): |
|
|
|
torrents = self.rpc.core.get_torrents_status({"label": "sickrage"}, ['name', 'label', 'save_path', 'is_seed', 'is_finished', 'progress']) |
|
|
|
return self.render("index.html", torrents=torrents) |
|
|
|
def index(self, action=None): |
|
|
|
if action: |
|
|
|
if action == "update": |
|
|
|
self.rpc.refresh() |
|
|
|
raise cherrypy.HTTPRedirect("/") |
|
|
|
return self.render("index.html", torrents=self.rpc.data.torrents) |
|
|
|
|
|
|
|
@cherrypy.expose |
|
|
|
def move(self, thash, dest=None, otherdest=None): |
|
|
|
torrent = self.rpc.core.get_torrent_status(thash, []) # TODO reduce to needed fields |
|
|
|
torrent = self.rpc.client.core.get_torrent_status(thash, []) # TODO reduce to needed fields |
|
|
|
|
|
|
|
if cherrypy.request.method == "POST" and (dest or otherdest): |
|
|
|
target = otherdest or dest |
|
|
|
self.rpc.core.move_storage([thash], target) |
|
|
|
self.rpc.client.core.move_storage([thash], target) |
|
|
|
self.rpc.refresh() |
|
|
|
raise cherrypy.HTTPRedirect("/") |
|
|
|
|
|
|
|
return self.render("moveform.html", torrent=torrent) |
|
|
@@ -83,7 +131,9 @@ def main(): |
|
|
|
assert uri.scheme == "deluge" |
|
|
|
rpc = DelugeRPCClient(uri.hostname, uri.port if uri.port else 58846, uri.username, uri.password, decode_utf8=True) |
|
|
|
|
|
|
|
web = MediaWeb(rpc, tpl, uioptions) |
|
|
|
rpc_cache = ClientCache(rpc) |
|
|
|
|
|
|
|
web = MediaWeb(rpc_cache, tpl, uioptions) |
|
|
|
cherrypy.tree.mount(web, '/', {'/': {'tools.auth_basic.on': True, |
|
|
|
'tools.auth_basic.realm': 'mediaweb', |
|
|
|
'tools.auth_basic.checkpassword': validate_password, }}) |
|
|
|