summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar RaNaN <Mast3rRaNaN@hotmail.de> 2011-07-12 23:42:11 +0200
committerGravatar RaNaN <Mast3rRaNaN@hotmail.de> 2011-07-12 23:42:11 +0200
commitc52ee8392501ee916d85fd9da75aa08a8f014493 (patch)
tree1cd802f64a1ffe0173473fd1f044e014bee59fff
parentchanged version strings (diff)
downloadpyload-c52ee8392501ee916d85fd9da75aa08a8f014493.tar.xz
removed server_methods, please test everything entirely
-rw-r--r--module/Api.py49
-rw-r--r--module/PluginThread.py2
-rw-r--r--module/ThreadManager.py4
-rw-r--r--module/common/APIExerciser.py114
-rw-r--r--module/plugins/Crypter.py4
-rw-r--r--module/plugins/hooks/Ev0InFetcher.py2
-rw-r--r--module/plugins/hooks/HotFolder.py4
-rw-r--r--module/plugins/hooks/IRCInterface.py3
-rw-r--r--module/plugins/hooks/UpdateManager.py2
-rw-r--r--module/plugins/hoster/BasePlugin.py2
-rw-r--r--module/remote/XMLRPCBackend.py2
-rw-r--r--module/remote/thriftbackend/Handler.py568
-rw-r--r--module/remote/thriftbackend/pyload.thrift6
-rwxr-xr-xmodule/remote/thriftbackend/thriftgen/pyload/Pyload-remote14
-rw-r--r--module/remote/thriftbackend/thriftgen/pyload/Pyload.py75
-rw-r--r--module/web/json_app.py114
-rw-r--r--module/web/media/default/js/funktions.js4
-rw-r--r--module/web/pyload_app.py119
-rw-r--r--module/web/templates/default/base.html4
-rw-r--r--module/web/templates/default/collector.html8
-rw-r--r--module/web/templates/default/home.html27
-rw-r--r--module/web/templates/default/info.html11
-rw-r--r--module/web/templates/default/package_ui.js1
-rw-r--r--module/web/templates/default/queue.html8
-rw-r--r--module/web/templates/default/settings.html10
-rw-r--r--module/web/templates/default/settings_item.html84
-rw-r--r--module/web/utils.py6
-rw-r--r--module/web/webinterface.py5
-rwxr-xr-xpyLoadCore.py347
-rwxr-xr-xpyLoadGui.py2
30 files changed, 334 insertions, 1267 deletions
diff --git a/module/Api.py b/module/Api.py
index 975b43709..5328fb617 100644
--- a/module/Api.py
+++ b/module/Api.py
@@ -49,11 +49,9 @@ class Api(Iface):
return f
def _convertConfigFormat(self, c):
- sections = []
+ sections = {}
for sectionName, sub in c.iteritems():
- section = ConfigSection()
- section.name = sectionName
- section.description = sub["desc"]
+ section = ConfigSection(sectionName, sub["desc"])
items = []
for key, data in sub.iteritems():
if key == "desc":
@@ -65,10 +63,10 @@ class Api(Iface):
item.type = data["type"]
items.append(item)
section.items = items
- sections.append(section)
+ sections[sectionName] = section
return sections
- def getConfigValue(self, category, option, section):
+ def getConfigValue(self, category, option, section="core"):
"""Retrieve config value.
:param category: name of category, or plugin
@@ -81,7 +79,7 @@ class Api(Iface):
elif section == "plugin":
return self.core.config.getPlugin(category, option)
- def setConfigValue(self, category, option, value, section):
+ def setConfigValue(self, category, option, value, section="core"):
"""Set new config value.
:param category:
@@ -105,6 +103,13 @@ class Api(Iface):
"""
return self._convertConfigFormat(self.core.config.config)
+ def getConfigDict(self):
+ """Retrieves complete config in dict format, not for RPC.
+
+ :return: dict
+ """
+ return self.core.config.config
+
def getPluginConfig(self):
"""Retrieves complete config for all plugins.
@@ -112,6 +117,14 @@ class Api(Iface):
"""
return self._convertConfigFormat(self.core.config.plugin)
+ def getPluginConfigDict(self):
+ """Plugin config as dict, not for RPC.
+
+ :return: dict
+ """
+ return self.core.config.plugin
+
+
def pauseServer(self):
"""Pause server: Tt wont start any new downloads, but nothing gets aborted."""
self.core.threadManager.pause = True
@@ -167,7 +180,7 @@ class Api(Iface):
"""Untested"""
self.core.do_restart = True
- def getLog(self, offset):
+ def getLog(self, offset=0):
"""Returns most recent log entries.
:param offset: line offset
@@ -639,14 +652,14 @@ class Api(Iface):
:return: list
"""
- return self.core.accountManager.getAccountInfos(False, False).keys()
+ return self.core.accountManager.accounts.keys()
- def updateAccounts(self, data):
+ def updateAccount(self, plugin, account, password=None, options={}):
"""Changes pw/options for specific account.
:param data: `AccountData`
"""
- self.core.accountManager.updateAccount(data.type, data.login, data.password, data.options)
+ self.core.accountManager.updateAccount(plugin, account, password, options)
def removeAccount(self, plugin, account):
"""Remove account from pyload.
@@ -689,6 +702,10 @@ class Api(Iface):
return self.checkAuth(username, password)
+ def getAllUserData(self):
+ """returns all known user and info"""
+ return self.core.db.getAllUserData()
+
def getServices(self):
""" A dict of available services, these can be defined by hook plugins.
@@ -749,4 +766,12 @@ class Api(Iface):
if info.has_key(plugin):
return info[plugin]
else:
- return {} \ No newline at end of file
+ return {}
+
+ def changePassword(self, user, oldpw, newpw):
+ """ changes password for specific user """
+ return self.core.db.changePassword(user, oldpw, newpw)
+
+ def setUserPermission(self, user, permission, role):
+ self.core.db.setPermission(user, permission)
+ self.core.db.setRole(user, role) \ No newline at end of file
diff --git a/module/PluginThread.py b/module/PluginThread.py
index 228ba4e6a..ff5014f63 100644
--- a/module/PluginThread.py
+++ b/module/PluginThread.py
@@ -46,7 +46,7 @@ class PluginThread(Thread):
def writeDebugReport(self, pyfile):
- dump = "pyLoad %s Debug Report of %s \n\nTRACEBACK:\n %s \n\nFRAMESTACK:\n" % (self.m.core.server_methods.get_server_version(), pyfile.pluginname, format_exc())
+ dump = "pyLoad %s Debug Report of %s \n\nTRACEBACK:\n %s \n\nFRAMESTACK:\n" % (self.m.core.api.getServerVersion(), pyfile.pluginname, format_exc())
tb = exc_info()[2]
stack = []
diff --git a/module/ThreadManager.py b/module/ThreadManager.py
index adf17ee8c..a0025879c 100644
--- a/module/ThreadManager.py
+++ b/module/ThreadManager.py
@@ -114,7 +114,7 @@ class ThreadManager:
def tryReconnect(self):
"""checks if reconnect needed"""
- if not (self.core.config["reconnect"]["activated"] and self.core.server_methods.is_time_reconnect()):
+ if not (self.core.config["reconnect"]["activated"] and self.core.api.isTimeReconnect()):
return False
active = [x.active.plugin.wantReconnect and x.active.plugin.waiting for x in self.threads if x.active]
@@ -209,7 +209,7 @@ class ThreadManager:
def assignJob(self):
"""assing a job to a thread if possible"""
- if self.pause or not self.core.server_methods.is_time_download(): return
+ if self.pause or not self.core.api.isTimeDownload(): return
#if self.downloaded > 20:
# if not self.cleanPyCurl(): return
diff --git a/module/common/APIExerciser.py b/module/common/APIExerciser.py
index f645f12df..b9e67d824 100644
--- a/module/common/APIExerciser.py
+++ b/module/common/APIExerciser.py
@@ -24,16 +24,19 @@ def createURLs():
AVOID = (0,3,8)
class APIExerciser(Thread):
- """ tests api randomly """
-
- def __init__(self, core):
+ def __init__(self, core, thrift=False):
Thread.__init__(self)
self.setDaemon(True)
self.core = core
- self.methods = core.server_methods
self.count = 0 #number of methods
self.time = time()
+ if thrift:
+ self.api = ThriftClient()
+ self.api.login("user", "pw")
+ else:
+ self.api = core.api
+
self.start()
def run(self):
@@ -60,89 +63,8 @@ class APIExerciser(Thread):
#sleep(random() / 500)
def testAPI(self):
- m = ["status_downloads", "status_server", "add_package", "get_package_data", "get_file_data", "del_links",
- "del_packages",
- "get_queue", "get_collector", "get_queue_info", "get_collector_info", "is_captcha_waiting"]
-
- method = choice(m)
- #print "Testing:", method
-
- if hasattr(self, method):
- res = getattr(self, method)()
- else:
- res = getattr(self.methods, method)()
-
- self.count += 1
-
- #print res
-
- def add_package(self):
- name = "".join(sample(string.ascii_letters, 10))
- urls = createURLs()
-
- self.methods.add_package(name, urls, 1)
-
-
- def del_links(self):
- info = self.methods.get_queue()
- if not info: return
-
- pid = choice(info.keys())
- pack = info[pid]
- links = pack["links"]
- #filter links which are not queued, finished or failed
- fids = filter(lambda x: links[x]["status"] not in AVOID, links.keys())
-
- if len(fids):
- fids = sample(fids, randint(1, max(len(fids) / 2, 1)))
- self.methods.del_links(fids)
-
-
- def del_packages(self):
- info = self.methods.get_queue_info()
- if not info: return
-
- pids = info.keys()
- if len(pids):
- pids = sample(pids, randint(1, max(len(pids) / 2, 1)))
- filtered = []
-
- for p in pids:
- info = self.methods.get_package_data(p)
- append = True
- for link in info["links"].itervalues():
- if link["status"] not in AVOID:
- append = False
- break
-
- if append: filtered.append(p)
-
- self.methods.del_packages(filtered)
-
- def get_file_data(self):
- info = self.methods.get_queue()
- if info:
- p = info[choice(info.keys())]
- if p["links"]:
- self.methods.get_file_data(choice(p["links"].keys()))
-
- def get_package_data(self):
- info = self.methods.get_queue_info()
- if info:
- self.methods.get_package_data(choice(info.keys()))
-
-
-class ThriftExerciser(APIExerciser):
- def __init__(self, core):
- self.thrift = ThriftClient()
- self.thrift.login("user", "pw")
-
- APIExerciser.__init__(self, core)
-
- def testAPI(self):
m = ["statusDownloads", "statusServer", "addPackage", "getPackageData", "getFileData", "deleteFiles",
- "deletePackages",
- "getQueue", "getCollector", "getQueueData", "getCollectorData", "isCaptchaWaiting"]
+ "deletePackages", "getQueue", "getCollector", "getQueueData", "getCollectorData", "isCaptchaWaiting"]
method = choice(m)
#print "Testing:", method
@@ -150,7 +72,7 @@ class ThriftExerciser(APIExerciser):
if hasattr(self, method):
res = getattr(self, method)()
else:
- res = getattr(self.thrift, method)()
+ res = getattr(self.api, method)()
self.count += 1
@@ -160,11 +82,11 @@ class ThriftExerciser(APIExerciser):
name = "".join(sample(string.ascii_letters, 10))
urls = createURLs()
- self.thrift.addPackage(name, urls, 0)
+ self.api.addPackage(name, urls, 0)
def deleteFiles(self):
- info = self.thrift.getQueueData()
+ info = self.api.getQueueData()
if not info: return
pack = choice(info)
@@ -172,26 +94,26 @@ class ThriftExerciser(APIExerciser):
if len(fids):
fids = [f.fid for f in sample(fids, randint(1, max(len(fids) / 2, 1)))]
- self.thrift.deleteFiles(fids)
+ self.api.deleteFiles(fids)
def deletePackages(self):
- info = self.thrift.getQueue()
+ info = self.api.getQueue()
if not info: return
pids = [p.pid for p in info]
if len(pids):
pids = sample(pids, randint(1, max(len(pids) / 2, 1)))
- self.thrift.deletePackages(pids)
+ self.api.deletePackages(pids)
def getFileData(self):
- info = self.thrift.getQueueData()
+ info = self.api.getQueueData()
if info:
p = choice(info)
if p.links:
- self.thrift.getFileData(choice(p.links).fid)
+ self.api.getFileData(choice(p.links).fid)
def getPackageData(self):
- info = self.thrift.getQueue()
+ info = self.api.getQueue()
if info:
- self.thrift.getPackageData(choice(info).pid) \ No newline at end of file
+ self.api.getPackageData(choice(info).pid) \ No newline at end of file
diff --git a/module/plugins/Crypter.py b/module/plugins/Crypter.py
index 7ba739dc4..9c56eb91b 100644
--- a/module/plugins/Crypter.py
+++ b/module/plugins/Crypter.py
@@ -64,8 +64,8 @@ class Crypter(Plugin):
links = [x.decode("utf-8") for x in pack[1]]
- pid = self.core.server_methods.add_package(pack[0], links, self.pyfile.package().queue)
+ pid = self.core.api.addPackage(pack[0], links, self.pyfile.package().queue)
if self.pyfile.package().password:
- self.core.server_methods.set_package_data(pid, {"password": self.pyfile.package().password})
+ self.core.api.setPackageData(pid, {"password": self.pyfile.package().password})
diff --git a/module/plugins/hooks/Ev0InFetcher.py b/module/plugins/hooks/Ev0InFetcher.py
index f573d28a3..5eb4e09c1 100644
--- a/module/plugins/hooks/Ev0InFetcher.py
+++ b/module/plugins/hooks/Ev0InFetcher.py
@@ -75,7 +75,7 @@ class Ev0InFetcher(Hook, PluginStorage):
links = self.filterLinks(item['description'].split("<br />"))
packagename = item['title'].encode("utf-8")
self.core.log.info("Ev0InFetcher: new episode '%s' (matched '%s')" % (packagename, show))
- self.core.server_methods.add_package(packagename, links, queue=(1 if self.getConfig("queue") else 0))
+ self.core.api.addPackage(packagename, links, queue=(1 if self.getConfig("queue") else 0))
self.setStorage("show_%s_lastfound" % show, int(mktime(item.date_parsed)))
found = True
if not found:
diff --git a/module/plugins/hooks/HotFolder.py b/module/plugins/hooks/HotFolder.py
index 1e320b87c..ee1031ad5 100644
--- a/module/plugins/hooks/HotFolder.py
+++ b/module/plugins/hooks/HotFolder.py
@@ -68,7 +68,7 @@ class HotFolder(Hook):
f.write(content)
f.close()
- self.core.server_methods.add_package(f.name, [f.name], 1)
+ self.core.api.addPackage(f.name, [f.name], 1)
for f in listdir(self.getConfig("folder")):
path = join(self.getConfig("folder"), f)
@@ -80,6 +80,6 @@ class HotFolder(Hook):
move(path, newpath)
self.log.info(_("Added %s from HotFolder") % f)
- self.core.server_methods.add_package(f, [newpath], 1)
+ self.core.api.addPackage(f, [newpath], 1)
\ No newline at end of file
diff --git a/module/plugins/hooks/IRCInterface.py b/module/plugins/hooks/IRCInterface.py
index 8be84f863..ae0a51385 100644
--- a/module/plugins/hooks/IRCInterface.py
+++ b/module/plugins/hooks/IRCInterface.py
@@ -53,7 +53,8 @@ class IRCInterface(Thread, Hook):
Thread.__init__(self)
Hook.__init__(self, core, manager)
self.setDaemon(True)
- self.sm = core.server_methods
+ #self.sm = core.server_methods
+ self.api = core.api #todo, only use api
def coreReady(self):
self.new_package = {}
diff --git a/module/plugins/hooks/UpdateManager.py b/module/plugins/hooks/UpdateManager.py
index 10f50d1f0..dc8eafbb8 100644
--- a/module/plugins/hooks/UpdateManager.py
+++ b/module/plugins/hooks/UpdateManager.py
@@ -65,7 +65,7 @@ class UpdateManager(Hook):
"""checks if an update is available"""
try:
- version_check = getURL("http://get.pyload.org/check/%s/" % self.core.server_methods.get_server_version())
+ version_check = getURL("http://get.pyload.org/check/%s/" % self.core.api.getServerVersion())
if version_check == "":
return False
else:
diff --git a/module/plugins/hoster/BasePlugin.py b/module/plugins/hoster/BasePlugin.py
index 49bab50f1..4b55f0357 100644
--- a/module/plugins/hoster/BasePlugin.py
+++ b/module/plugins/hoster/BasePlugin.py
@@ -33,7 +33,7 @@ class BasePlugin(Hoster):
# self.decryptCaptcha("http://localhost:9000/captcha")
#
# if pyfile.url == "79":
-# self.core.server_methods.add_package("test", [str(i) for i in range(80)], 1)
+# self.core.api.addPackage("test", [str(i) for i in range(80)], 1)
#
# return
if pyfile.url.startswith("http"):
diff --git a/module/remote/XMLRPCBackend.py b/module/remote/XMLRPCBackend.py
index 50b37f17b..003dc29ea 100644
--- a/module/remote/XMLRPCBackend.py
+++ b/module/remote/XMLRPCBackend.py
@@ -34,7 +34,7 @@ class XMLRPCBackend(BackendBase):
else:
self.server = Server.AuthXMLRPCServer(server_addr, self.checkAuth)
- self.server.register_instance(self.core.server_methods)
+ self.server.register_instance(self.core.api)
def serve(self):
self.server.serve_forever()
diff --git a/module/remote/thriftbackend/Handler.py b/module/remote/thriftbackend/Handler.py
deleted file mode 100644
index 998ace06b..000000000
--- a/module/remote/thriftbackend/Handler.py
+++ /dev/null
@@ -1,568 +0,0 @@
-# -*- coding: utf-8 -*-
-
-from thriftgen.pyload.ttypes import *
-from thriftgen.pyload.Pyload import Iface
-
-from module.PyFile import PyFile
-from module.utils import freeSpace
-
-from base64 import standard_b64encode
-
-class Handler(Iface):
- def __init__(self, backend):
- self.backend = backend
- self.core = backend.core
- self.serverMethods = self.core.server_methods
-
-
- def _convertPyFile(self, p):
- f = FileData(p["id"], p["url"], p["name"], p["plugin"], p["size"],
- p["format_size"], p["status"], p["statusmsg"],
- p["package"], p["error"], p["order"], p["progress"])
- return f
-
- def _convertConfigFormat(self, c):
- sections = []
- for sectionName, sub in c.iteritems():
- section = ConfigSection()
- section.name = sectionName
- section.description = sub["desc"]
- items = []
- for key, data in sub.iteritems():
- if key == "desc":
- continue
- item = ConfigItem()
- item.name = key
- item.description = data["desc"]
- item.value = str(data["value"]) if type(data["value"]) != basestring else data["value"]
- item.type = data["type"]
- items.append(item)
- section.items = items
- sections.append(section)
- return sections
-
- #general
- def getConfigValue(self, category, option, section):
- """
- Parameters:
- - category
- - option
- - section
- """
- self.serverMethods.get_conf_val(category, option, section)
-
- def setConfigValue(self, category, option, value, section):
- """
- Parameters:
- - category
- - option
- - value
- - section
- """
- pass
-
- def getConfig(self):
- c = self.serverMethods.get_config()
- return self._convertConfigFormat(c)
-
- def getPluginConfig(self):
- c = self.serverMethods.get_plugin_config()
- return self._convertConfigFormat(c)
-
- def pauseServer(self):
- self.serverMethods.pause_server()
-
- def unpauseServer(self):
- self.serverMethods.unpause_server()
-
- def togglePause(self):
- return self.serverMethods.toggle_pause()
-
- def toggleReconnect(self):
- return self.serverMethods.toggle_reconnect()
-
- def statusServer(self):
- status = self.serverMethods.status_server()
- serverStatus = ServerStatus()
- serverStatus.pause = status["pause"]
- serverStatus.active = status["activ"]
- serverStatus.queue = status["queue"]
- serverStatus.total = status["total"]
- serverStatus.speed = 0
- for pyfile in [x.active for x in self.core.threadManager.threads if x.active and x.active != "quit"]:
- serverStatus.speed += pyfile.getSpeed() #bytes/s
- serverStatus.download = status["download"]
- serverStatus.reconnect = status["reconnect"]
- return serverStatus
-
- def freeSpace(self):
- return freeSpace(self.core.config["general"]["download_folder"])
-
- def getServerVersion(self):
- return self.serverMethods.get_server_version()
-
- def kill(self):
- self.serverMethods.kill()
-
- def restart(self):
- self.serverMethods.restart()
-
- def getLog(self, offset):
- """
- Parameters:
- - offset
- """
- log = self.serverMethods.get_log(offset)
- return log or []
-
- def checkURL(self, urls):
- """
- Parameters:
- - urls
- """
- checked = {}
- for u, p in self.core.pluginManager.parseUrls(urls):
- if p == "BasePlugin":
- checked[u] = ""
- else:
- checked[u] = p
- return checked
-
- def isTimeDownload(self):
- return self.serverMethods.is_time_download()
-
- def isTimeReconnect(self):
- return self.serverMethods.is_time_reconnect()
-
- #downloads
- def statusDownloads(self):
- data = []
- for pyfile in [x.active for x in self.core.threadManager.threads + self.core.threadManager.localThreads if
- x.active and x.active != "quit"]:
- if not isinstance(pyfile, PyFile):
- continue
- status = DownloadInfo()
- status.fid = pyfile.id
- status.name = pyfile.name
- status.speed = pyfile.getSpeed() #bytes
- status.eta = pyfile.getETA()
- status.format_eta = pyfile.formatETA()
- status.bleft = pyfile.getBytesLeft()
- status.size = pyfile.getSize()
- status.format_size = pyfile.formatSize()
- status.percent = pyfile.getPercent()
- status.status = pyfile.status
- status.statusmsg = pyfile.m.statusMsg[pyfile.status]
- status.format_wait = pyfile.formatWait()
- status.wait_until = pyfile.waitUntil
- status.packageName = pyfile.package().name
- status.packageID = pyfile.package().id
- status.plugin = pyfile.pluginname
- data.append(status)
- return data
-
- def addPackage(self, name, links, dest):
- """
- Parameters:
- - name
- - links
- - dest
- """
- return self.serverMethods.add_package(name, links, 0 if dest == Destination.Collector else 1)
-
- def getPackageData(self, pid):
- """
- Parameters:
- - pid
- """
- pdata = PackageData()
- rawData = self.serverMethods.get_package_data(pid)
-
- if not rawData:
- raise PackageDoesNotExists(pid)
-
- pdata.pid = rawData["id"]
- pdata.name = rawData["name"]
- pdata.folder = rawData["folder"]
- pdata.site = rawData["site"]
- pdata.password = rawData["password"]
- pdata.dest = rawData["queue"]
- pdata.order = rawData["order"]
- pdata.priority = rawData["priority"]
- pdata.links = []
- for id, pyfile in rawData["links"].iteritems():
- pdata.links.append(self._convertPyFile(pyfile))
-
- return pdata
-
- def getFileData(self, fid):
- """
- Parameters:
- - fid
- """
- rawData = self.serverMethods.get_file_data(fid)
- if rawData:
- rawData = rawData.values()[0]
- else:
- raise FileDoesNotExists(fid)
-
- fdata = self._convertPyFile(rawData)
- return fdata
-
- def deleteFiles(self, fids):
- """
- Parameters:
- - fids
- """
- self.serverMethods.del_links(fids)
-
- def deletePackages(self, pids):
- """
- Parameters:
- - pids
- """
- self.serverMethods.del_packages(pids)
-
- def getQueue(self):
- packs = self.serverMethods.get_queue()
- ret = []
- for pid, pack in packs.iteritems():
- pdata = PackageInfo()
- pdata.pid = pack["id"]
- pdata.name = pack["name"]
- pdata.folder = pack["folder"]
- pdata.site = pack["site"]
- pdata.password = pack["password"]
- pdata.dest = pack["queue"]
- pdata.order = pack["order"]
- pdata.priority = pack["priority"]
- pdata.links = [int(x) for x in pack["links"].keys()]
- ret.append(pdata)
- return ret
-
- def getQueueData(self):
- packs = self.serverMethods.get_queue()
- ret = []
- for pid, pack in packs.iteritems():
- pdata = PackageData()
- pdata.pid = pack["id"]
- pdata.name = pack["name"]
- pdata.folder = pack["folder"]
- pdata.site = pack["site"]
- pdata.password = pack["password"]
- pdata.dest = pack["queue"]
- pdata.order = pack["order"]
- pdata.priority = pack["priority"]
- pdata.links = [self._convertPyFile(x) for x in pack["links"].values()]
- ret.append(pdata)
- return ret
-
- def getCollector(self):
- packs = self.serverMethods.get_collector()
- ret = []
- for pid, pack in packs.iteritems():
- pdata = PackageInfo()
- pdata.pid = pack["id"]
- pdata.name = pack["name"]
- pdata.folder = pack["folder"]
- pdata.site = pack["site"]
- pdata.password = pack["password"]
- pdata.dest = pack["queue"]
- pdata.order = pack["order"]
- pdata.priority = pack["priority"]
- pdata.links = [int(x) for x in pack["links"].keys()]
- ret.append(pdata)
- return ret
-
- def getCollectorData(self):
- packs = self.serverMethods.get_collector()
- ret = []
- for pid, pack in packs.iteritems():
- pdata = PackageData()
- pdata.pid = pack["id"]
- pdata.name = pack["name"]
- pdata.folder = pack["folder"]
- pdata.site = pack["site"]
- pdata.password = pack["password"]
- pdata.dest = pack["queue"]
- pdata.order = pack["order"]
- pdata.priority = pack["priority"]
- pdata.links = [self._convertPyFile(x) for x in pack["links"].values()]
- ret.append(pdata)
- return ret
-
- def addFiles(self, pid, links):
- """
- Parameters:
- - pid
- - links
- """
- self.serverMethods.add_files(pid, links)
-
- def pushToQueue(self, pid):
- """
- Parameters:
- - pid
- """
- self.serverMethods.push_package_to_queue(pid)
-
- def pullFromQueue(self, pid):
- """
- Parameters:
- - pid
- """
- self.serverMethods.pull_out_package(pid)
-
- def restartPackage(self, pid):
- """
- Parameters:
- - pid
- """
- self.serverMethods.restart_package(pid)
-
- def restartFile(self, fid):
- """
- Parameters:
- - fid
- """
- self.serverMethods.restart_file(fid)
-
- def recheckPackage(self, pid):
- """
- Parameters:
- - pid
- """
- self.serverMethods.recheck_package(pid)
-
- def stopAllDownloads(self):
- self.serverMethods.stop_downloads()
-
- def stopDownloads(self, fids):
- """
- Parameters:
- - fids
- """
- self.serverMethods.abort_files(fids)
-
- def setPackageName(self, pid, name):
- """
- Parameters:
- - pid
- - name
- """
- self.serverMethods.set_package_name(pid, name)
-
- def movePackage(self, destination, pid):
- """
- Parameters:
- - destination
- - pid
- """
- self.serverMethods.move_package(destination, pid)
-
- def uploadContainer(self, filename, data):
- """
- Parameters:
- - filename
- - data
- """
- self.serverMethods.upload_container(filename, data)
-
- def setPriority(self, pid, priority):
- """
- Parameters:
- - pid
- - priority
- """
- self.serverMethods.set_priority(pid, priority)
-
- def orderPackage(self, pid, position):
- """
- Parameters:
- - pid
- - position
- """
- self.serverMethods.order_package(pid, position)
-
- def orderFile(self, fid, position):
- """
- Parameters:
- - fid
- - position
- """
- self.serverMethods.order_file(fid, position)
-
- def setPackageData(self, pid, data):
- """
- Parameters:
- - pid
- - data
- """
- self.serverMethods.set_package_data(pid, data)
-
- def deleteFinished(self):
- self.serverMethods.delete_finished()
-
- def restartFailed(self):
- self.serverMethods.restart_failed()
-
- def getPackageOrder(self, destination):
- """
- Parameters:
- - destination
- """
- order = {}
- if destination == Destination.Queue:
- packs = self.serverMethods.get_queue()
- else:
- packs = self.serverMethods.get_collector()
- for pid in packs:
- pack = self.serverMethods.get_package_data(pid)
- while pack["order"] in order.keys(): #just in case
- pack["order"] += 1
- order[pack["order"]] = pack["id"]
- return order
-
- def getFileOrder(self, pid):
- """
- Parameters:
- - pid
- """
- rawData = self.serverMethods.get_package_data(pid)
- order = {}
- for id, pyfile in rawData["links"].iteritems():
- while pyfile["order"] in order.keys(): #just in case
- pyfile["order"] += 1
- order[pyfile["order"]] = pyfile["id"]
- return order
-
- #captcha
- def isCaptchaWaiting(self):
- return self.serverMethods.is_captcha_waiting()
-
- def getCaptchaTask(self, exclusive):
- """
- Parameters:
- - exclusive
- """
- tid, data, type, result = self.serverMethods.get_captcha_task(exclusive)
- t = CaptchaTask(int(tid), standard_b64encode(data), type, result)
- return t
-
- def getCaptchaTaskStatus(self, tid):
- """
- Parameters:
- - tid
- """
- return self.serverMethods.get_task_status(tid)
-
- def setCaptchaResult(self, tid, result):
- """
- Parameters:
- - tid
- - result
- """
- self.serverMethods.set_captcha_result(tid, result)
-
- #events
- def getEvents(self, uuid):
- events = self.serverMethods.get_events(uuid)
- newEvents = []
- def convDest(d):
- return Destination.Queue if d == "queue" else Destination.Collector
- for e in events:
- event = Event()
- event.event = e[0]
- if e[0] in ("update", "remove", "insert"):
- event.id = e[3]
- event.type = ElementType.Package if e[2] == "pack" else ElementType.File
- event.destination = convDest(e[1])
- elif e[0] == "order":
- if e[1]:
- event.id = e[1]
- event.type = ElementType.Package if e[2] == "pack" else ElementType.File
- event.destination = convDest(e[3])
- elif e[0] == "reload":
- event.destination = convDest(e[1])
- newEvents.append(event)
- return newEvents
-
- #accounts
- def getAccounts(self, refresh):
- """
- Parameters:
- - refresh
- """
- accs = self.serverMethods.get_accounts(False, refresh)
- accounts = []
- for group in accs.values():
- for acc in group:
- account = AccountInfo()
- account.validuntil = acc["validuntil"]
- account.login = acc["login"]
- account.options = acc["options"]
- account.valid = acc["valid"]
- account.trafficleft = acc["trafficleft"]
- account.maxtraffic = acc["maxtraffic"]
- account.premium = acc["premium"]
- account.type = acc["type"]
- accounts.append(account)
- return accounts
-
- def getAccountTypes(self):
- return self.serverMethods.get_accounts().keys()
-
- def updateAccounts(self, data):
- """
- Parameters:
- - data
- """
- self.serverMethods.update_account(data.type, data.login, data.password, data.options)
-
- def removeAccount(self, plugin, account):
- """
- Parameters:
- - plugin
- - account
- """
- self.serverMethods.remove_account(plugin, account)
-
- #auth
- def login(self, username, password, remoteip=None):
- """
- Parameters:
- - username
- - password
- """
- return self.backend.checkAuth(username, password, remoteip)
-
- def getUserData(self, username, password):
- return self.serverMethods.checkAuth(username, password)
-
-
- def getServices(self):
- data = {}
- for plugin, funcs in self.core.hookManager.methods.iteritems():
- data[plugin] = funcs
-
- return data
-
- def hasService(self, plugin, func):
- cont = self.core.hookManager.methods
- return cont.has_key(plugin) and cont[plugin].has_key(func)
-
- def call(self, info):
- plugin = info.plugin
- func = info.func
- args = info.arguments
- parse = info.parseArguments
-
- if not self.hasService(plugin, func):
- raise ServiceDoesNotExists(plugin, func)
-
- try:
- ret = self.core.hookManager.callRPC(plugin, func, args, parse)
- return str(ret)
- except Exception, e:
- raise ServiceException(e.message)
- \ No newline at end of file
diff --git a/module/remote/thriftbackend/pyload.thrift b/module/remote/thriftbackend/pyload.thrift
index 45d7f5eeb..32fe69d13 100644
--- a/module/remote/thriftbackend/pyload.thrift
+++ b/module/remote/thriftbackend/pyload.thrift
@@ -187,8 +187,8 @@ service Pyload {
//config
string getConfigValue(1: string category, 2: string option, 3: string section),
void setConfigValue(1: string category, 2: string option, 3: string value, 4: string section),
- list<ConfigSection> getConfig(),
- list<ConfigSection> getPluginConfig(),
+ map<string, ConfigSection> getConfig(),
+ map<string, ConfigSection> getPluginConfig(),
// server status
void pauseServer(),
@@ -259,7 +259,7 @@ service Pyload {
//accounts
list<AccountInfo> getAccounts(1: bool refresh),
list<string> getAccountTypes()
- void updateAccounts(1: AccountData data),
+ void updateAccount(1: PluginName plugin, 2: string account, 3: string password, 4: map<string, string> options),
void removeAccount(1: PluginName plugin, 2: string account),
//auth
diff --git a/module/remote/thriftbackend/thriftgen/pyload/Pyload-remote b/module/remote/thriftbackend/thriftgen/pyload/Pyload-remote
index 0e454c816..2b055321b 100755
--- a/module/remote/thriftbackend/thriftgen/pyload/Pyload-remote
+++ b/module/remote/thriftbackend/thriftgen/pyload/Pyload-remote
@@ -80,7 +80,7 @@ if len(sys.argv) <= 1 or sys.argv[1] == '--help':
print ' getEvents(string uuid)'
print ' getAccounts(bool refresh)'
print ' getAccountTypes()'
- print ' void updateAccounts(AccountData data)'
+ print ' void updateAccount(PluginName plugin, string account, string password, options)'
print ' void removeAccount(PluginName plugin, string account)'
print ' bool login(string username, string password)'
print ' UserData getUserData(string username, string password)'
@@ -88,7 +88,7 @@ if len(sys.argv) <= 1 or sys.argv[1] == '--help':
print ' bool hasService(PluginName plugin, string func)'
print ' string call(ServiceCall info)'
print ' getAllInfo()'
- print ' getInfoByPlugin(string plugin)'
+ print ' getInfoByPlugin(PluginName plugin)'
print ''
sys.exit(0)
@@ -481,11 +481,11 @@ elif cmd == 'getAccountTypes':
sys.exit(1)
pp.pprint(client.getAccountTypes())
-elif cmd == 'updateAccounts':
- if len(args) != 1:
- print 'updateAccounts requires 1 args'
+elif cmd == 'updateAccount':
+ if len(args) != 4:
+ print 'updateAccount requires 4 args'
sys.exit(1)
- pp.pprint(client.updateAccounts(eval(args[0]),))
+ pp.pprint(client.updateAccount(eval(args[0]),args[1],args[2],eval(args[3]),))
elif cmd == 'removeAccount':
if len(args) != 2:
@@ -533,7 +533,7 @@ elif cmd == 'getInfoByPlugin':
if len(args) != 1:
print 'getInfoByPlugin requires 1 args'
sys.exit(1)
- pp.pprint(client.getInfoByPlugin(args[0],))
+ pp.pprint(client.getInfoByPlugin(eval(args[0]),))
else:
print 'Unrecognized method %s' % cmd
diff --git a/module/remote/thriftbackend/thriftgen/pyload/Pyload.py b/module/remote/thriftbackend/thriftgen/pyload/Pyload.py
index ec850b70c..de3611b6d 100644
--- a/module/remote/thriftbackend/thriftgen/pyload/Pyload.py
+++ b/module/remote/thriftbackend/thriftgen/pyload/Pyload.py
@@ -336,10 +336,13 @@ class Iface(object):
def getAccountTypes(self, ):
pass
- def updateAccounts(self, data):
+ def updateAccount(self, plugin, account, password, options):
"""
Parameters:
- - data
+ - plugin
+ - account
+ - password
+ - options
"""
pass
@@ -1988,30 +1991,36 @@ class Client(Iface):
return result.success
raise TApplicationException(TApplicationException.MISSING_RESULT, "getAccountTypes failed: unknown result");
- def updateAccounts(self, data):
+ def updateAccount(self, plugin, account, password, options):
"""
Parameters:
- - data
+ - plugin
+ - account
+ - password
+ - options
"""
- self.send_updateAccounts(data)
- self.recv_updateAccounts()
+ self.send_updateAccount(plugin, account, password, options)
+ self.recv_updateAccount()
- def send_updateAccounts(self, data):
- self._oprot.writeMessageBegin('updateAccounts', TMessageType.CALL, self._seqid)
- args = updateAccounts_args()
- args.data = data
+ def send_updateAccount(self, plugin, account, password, options):
+ self._oprot.writeMessageBegin('updateAccount', TMessageType.CALL, self._seqid)
+ args = updateAccount_args()
+ args.plugin = plugin
+ args.account = account
+ args.password = password
+ args.options = options
args.write(self._oprot)
self._oprot.writeMessageEnd()
self._oprot.trans.flush()
- def recv_updateAccounts(self, ):
+ def recv_updateAccount(self, ):
(fname, mtype, rseqid) = self._iprot.readMessageBegin()
if mtype == TMessageType.EXCEPTION:
x = TApplicationException()
x.read(self._iprot)
self._iprot.readMessageEnd()
raise x
- result = updateAccounts_result()
+ result = updateAccount_result()
result.read(self._iprot)
self._iprot.readMessageEnd()
return
@@ -2318,7 +2327,7 @@ class Processor(Iface, TProcessor):
self._processMap["getEvents"] = Processor.process_getEvents
self._processMap["getAccounts"] = Processor.process_getAccounts
self._processMap["getAccountTypes"] = Processor.process_getAccountTypes
- self._processMap["updateAccounts"] = Processor.process_updateAccounts
+ self._processMap["updateAccount"] = Processor.process_updateAccount
self._processMap["removeAccount"] = Processor.process_removeAccount
self._processMap["login"] = Processor.process_login
self._processMap["getUserData"] = Processor.process_getUserData
@@ -2982,13 +2991,13 @@ class Processor(Iface, TProcessor):
oprot.writeMessageEnd()
oprot.trans.flush()
- def process_updateAccounts(self, seqid, iprot, oprot):
- args = updateAccounts_args()
+ def process_updateAccount(self, seqid, iprot, oprot):
+ args = updateAccount_args()
args.read(iprot)
iprot.readMessageEnd()
- result = updateAccounts_result()
- self._handler.updateAccounts(args.data)
- oprot.writeMessageBegin("updateAccounts", TMessageType.REPLY, seqid)
+ result = updateAccount_result()
+ self._handler.updateAccount(args.plugin, args.account, args.password, args.options)
+ oprot.writeMessageBegin("updateAccount", TMessageType.REPLY, seqid)
result.write(oprot)
oprot.writeMessageEnd()
oprot.trans.flush()
@@ -3194,7 +3203,7 @@ class getConfig_result(TBase):
]
thrift_spec = (
- (0, TType.LIST, 'success', (TType.STRUCT,(ConfigSection, ConfigSection.thrift_spec)), None, ), # 0
+ (0, TType.MAP, 'success', (TType.STRING,None,TType.STRUCT,(ConfigSection, ConfigSection.thrift_spec)), None, ), # 0
)
def __init__(self, success=None,):
@@ -3221,7 +3230,7 @@ class getPluginConfig_result(TBase):
]
thrift_spec = (
- (0, TType.LIST, 'success', (TType.STRUCT,(ConfigSection, ConfigSection.thrift_spec)), None, ), # 0
+ (0, TType.MAP, 'success', (TType.STRING,None,TType.STRUCT,(ConfigSection, ConfigSection.thrift_spec)), None, ), # 0
)
def __init__(self, success=None,):
@@ -4829,26 +4838,38 @@ class getAccountTypes_result(TBase):
self.success = success
-class updateAccounts_args(TBase):
+class updateAccount_args(TBase):
"""
Attributes:
- - data
+ - plugin
+ - account
+ - password
+ - options
"""
__slots__ = [
- 'data',
+ 'plugin',
+ 'account',
+ 'password',
+ 'options',
]
thrift_spec = (
None, # 0
- (1, TType.STRUCT, 'data', (AccountData, AccountData.thrift_spec), None, ), # 1
+ (1, TType.STRING, 'plugin', None, None, ), # 1
+ (2, TType.STRING, 'account', None, None, ), # 2
+ (3, TType.STRING, 'password', None, None, ), # 3
+ (4, TType.MAP, 'options', (TType.STRING,None,TType.STRING,None), None, ), # 4
)
- def __init__(self, data=None,):
- self.data = data
+ def __init__(self, plugin=None, account=None, password=None, options=None,):
+ self.plugin = plugin
+ self.account = account
+ self.password = password
+ self.options = options
-class updateAccounts_result(TBase):
+class updateAccount_result(TBase):
__slots__ = [
]
diff --git a/module/web/json_app.py b/module/web/json_app.py
index d35ca1ad7..bc95b5ffd 100644
--- a/module/web/json_app.py
+++ b/module/web/json_app.py
@@ -1,22 +1,21 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-import base64
-from os.path import join, exists
+import os
+import os.path
+from os.path import join
from traceback import print_exc
+import shutil
from shutil import copyfileobj
from bottle import route, request, HTTPError, validate
from webinterface import PYLOAD
-from utils import login_required, render_to_response
+from utils import login_required, render_to_response, toDict
-from module.utils import decode
+from module.utils import decode, formatSize
-import os
-import shutil
-import os.path
def format_time(seconds):
seconds = int(seconds)
@@ -35,8 +34,8 @@ def get_sort_key(item):
@login_required('see_downloads')
def status():
try:
- status = PYLOAD.status_server()
- status['captcha'] = PYLOAD.is_captcha_waiting()
+ status = toDict(PYLOAD.statusServer())
+ status['captcha'] = PYLOAD.isCaptchaWaiting()
return status
except:
return HTTPError()
@@ -47,17 +46,17 @@ def status():
@login_required('see_downloads')
def links():
try:
- links = PYLOAD.status_downloads()
+ links = [toDict(x) for x in PYLOAD.statusDownloads()]
ids = []
for link in links:
- ids.append(link['id'])
+ ids.append(link['fid'])
if link['status'] == 12:
- link['info'] = "%s @ %s kb/s" % (link['format_eta'], round(link['speed'], 2))
+ link['info'] = "%s @ %s/s" % (link['format_eta'], formatSize(link['speed']))
elif link['status'] == 5:
link['percent'] = 0
link['size'] = 0
- link['kbleft'] = 0
+ link['bleft'] = 0
link['info'] = _("waiting %s") % link['format_wait']
else:
link['info'] = ""
@@ -65,14 +64,16 @@ def links():
data = {'links': links, 'ids': ids}
return data
except Exception, e:
+ print_exc()
return HTTPError()
@route("/json/queue")
@login_required('see_downloads')
def queue():
+ print "/json/queue"
try:
- return PYLOAD.get_queue()
+ return PYLOAD.getQueue()
except:
return HTTPError()
@@ -82,7 +83,7 @@ def queue():
@login_required('status')
def pause():
try:
- return PYLOAD.pause_server()
+ return PYLOAD.pauseServer()
except:
return HTTPError()
@@ -92,7 +93,7 @@ def pause():
@login_required('status')
def unpause():
try:
- return PYLOAD.unpause_server()
+ return PYLOAD.unpauseServer()
except:
return HTTPError()
@@ -102,7 +103,7 @@ def unpause():
@login_required('status')
def cancel():
try:
- return PYLOAD.stop_downloads()
+ return PYLOAD.stopDownloads()
except:
return HTTPError()
@@ -110,8 +111,9 @@ def cancel():
@route("/json/packages")
@login_required('see_downloads')
def packages():
+ print "/json/packages"
try:
- data = PYLOAD.get_queue()
+ data = PYLOAD.getQueue()
for package in data:
package['links'] = []
@@ -129,9 +131,10 @@ def packages():
@login_required('see_downloads')
def package(id):
try:
- data = PYLOAD.get_package_data(id)
+ data = toDict(PYLOAD.getPackageData(id))
+ data["links"] = [toDict(x) for x in data["links"]]
- for pyfile in data["links"].itervalues():
+ for pyfile in data["links"]:
if pyfile["status"] == 0:
pyfile["icon"] = "status_finished.png"
elif pyfile["status"] in (2, 3):
@@ -149,12 +152,13 @@ def package(id):
else:
pyfile["icon"] = "status_downloading.png"
- tmp = data["links"].values()
+ tmp = data["links"]
tmp.sort(key=get_sort_key)
data["links"] = tmp
return data
except:
+ print_exc()
return HTTPError()
@@ -163,7 +167,7 @@ def package(id):
def package_order(ids):
try:
pid, pos = ids.split("|")
- PYLOAD.order_package(int(pid), int(pos))
+ PYLOAD.orderPackage(int(pid), int(pos))
return {"response": "success"}
except:
return HTTPError()
@@ -173,8 +177,9 @@ def package_order(ids):
@validate(id=int)
@login_required('see_downloads')
def link(id):
+ print "/json/link/%d" % id
try:
- data = PYLOAD.get_file_info(id)
+ data = toDict(PYLOAD.getFileData(id))
return data
except:
return HTTPError()
@@ -185,7 +190,7 @@ def link(id):
@login_required('delete')
def remove_link(id):
try:
- PYLOAD.del_links([id])
+ PYLOAD.deleteFiles([id])
return {"response": "success"}
except Exception, e:
return HTTPError()
@@ -196,7 +201,7 @@ def remove_link(id):
@login_required('add')
def restart_link(id):
try:
- PYLOAD.restart_file(id)
+ PYLOAD.restartFile(id)
return {"response": "success"}
except Exception:
return HTTPError()
@@ -207,7 +212,7 @@ def restart_link(id):
@login_required('delete')
def abort_link(id):
try:
- PYLOAD.stop_download("link", id)
+ PYLOAD.stopDownload("link", id)
return {"response": "success"}
except:
return HTTPError()
@@ -218,7 +223,7 @@ def abort_link(id):
def link_order(ids):
try:
pid, pos = ids.split("|")
- PYLOAD.order_file(int(pid), int(pos))
+ PYLOAD.orderFile(int(pid), int(pos))
return {"response": "success"}
except:
return HTTPError()
@@ -240,7 +245,7 @@ def add_package():
if not name or name == "New Package":
name = f.name
- fpath = join(PYLOAD.get_conf_val("general", "download_folder"), "tmp_" + f.filename)
+ fpath = join(PYLOAD.getConfigValue("general", "download_folder"), "tmp_" + f.filename)
destination = open(fpath, 'wb')
copyfileobj(f.file, destination)
destination.close()
@@ -253,11 +258,11 @@ def add_package():
links = map(lambda x: x.strip(), links)
links = filter(lambda x: x != "", links)
- pack = PYLOAD.add_package(name, links, queue)
+ pack = PYLOAD.addPackage(name, links, queue)
if pw:
pw = pw.decode("utf8", "ignore")
data = {"password": pw}
- PYLOAD.set_package_data(pack, data)
+ PYLOAD.setPackageData(pack, data)
@route("/json/remove_package/:id")
@@ -265,7 +270,7 @@ def add_package():
@login_required('delete')
def remove_package(id):
try:
- PYLOAD.del_packages([id])
+ PYLOAD.deletePackages([id])
return {"response": "success"}
except Exception, e:
return HTTPError()
@@ -276,7 +281,7 @@ def remove_package(id):
@login_required('add')
def restart_package(id):
try:
- PYLOAD.restart_package(id)
+ PYLOAD.restartPackage(id)
return {"response": "success"}
except Exception:
print_exc()
@@ -288,7 +293,7 @@ def restart_package(id):
@login_required('add')
def move_package(dest, id):
try:
- PYLOAD.move_package(dest, id)
+ PYLOAD.movePackage(dest, id)
return {"response": "success"}
except:
return HTTPError()
@@ -304,7 +309,7 @@ def edit_package():
"priority": request.forms.get("pack_prio"),
"password": request.forms.get("pack_pws").decode("utf8", "ignore")}
- PYLOAD.set_package_data(id, data)
+ PYLOAD.setPackageData(id, data)
return {"response": "success"}
except:
@@ -317,17 +322,16 @@ def edit_package():
def set_captcha():
if request.environ.get('REQUEST_METHOD', "GET") == "POST":
try:
- PYLOAD.set_captcha_result(request.forms["cap_id"], request.forms["cap_result"])
+ PYLOAD.setCaptchaResult(request.forms["cap_id"], request.forms["cap_result"])
except:
pass
- id, binary, format, result_type = PYLOAD.get_captcha_task()
+ task = PYLOAD.getCaptchaTask()
if id:
- binary = base64.standard_b64encode(str(binary))
- src = "data:image/%s;base64,%s" % (format, binary)
+ src = "data:image/%s;base64,%s" % (task.type, task.data)
- return {'captcha': True, 'id': id, 'src': src, 'result_type' : result_type}
+ return {'captcha': True, 'id': task.tid, 'src': src, 'result_type' : task.resultType}
else:
return {'captcha': False}
@@ -335,13 +339,13 @@ def set_captcha():
@route("/json/delete_finished")
@login_required('delete')
def delete_finished():
- return {"del": PYLOAD.delete_finished()}
+ return {"del": PYLOAD.deleteFinished()}
@route("/json/restart_failed")
@login_required('delete')
def restart_failed():
- restart = PYLOAD.restart_failed()
+ restart = PYLOAD.restartFailed()
if restart: return restart
return {"response": "success"}
@@ -352,17 +356,15 @@ def restart_failed():
def load_config(category, section):
conf = None
if category == "general":
- conf = PYLOAD.get_config()
+ conf = PYLOAD.getConfig()
elif category == "plugin":
- conf = PYLOAD.get_plugin_config()
-
- for key, option in conf[section].iteritems():
- if key == "desc": continue
+ conf = PYLOAD.getPluginConfig()
- if ";" in option["type"]:
- option["list"] = option["type"].split(";")
+ for option in conf[section].items:
+ if ";" in option.type:
+ option.type = option.type.split(";")
- option["value"] = decode(option["value"])
+ option.value = decode(option.value)
return render_to_response("settings_item.html", {"skey": section, "section": conf[section]})
@@ -378,7 +380,7 @@ def save_config(category):
if category == "general": category = "core"
- PYLOAD.set_conf_val(section, option, decode(value), category)
+ PYLOAD.setConfigValue(section, option, decode(value), category)
@route("/json/add_account", method="POST")
@@ -388,7 +390,7 @@ def add_account():
password = request.POST["account_password"]
type = request.POST["account_type"]
- PYLOAD.update_account(type, login, password)
+ PYLOAD.updateAccount(type, login, password)
@route("/json/update_accounts", method="POST")
@@ -406,14 +408,14 @@ def update_accounts():
if (plugin, user) in deleted: continue
if action == "password":
- PYLOAD.update_account(plugin, user, value)
+ PYLOAD.updateAccount(plugin, user, value)
elif action == "time" and "-" in value:
- PYLOAD.update_account(plugin, user, options={"time": [value]})
+ PYLOAD.updateAccount(plugin, user, options={"time": [value]})
elif action == "limitdl" and value.isdigit():
- PYLOAD.update_account(plugin, user, options={"limitDL": [value]})
+ PYLOAD.updateAccount(plugin, user, options={"limitDL": [value]})
elif action == "delete":
deleted.append((plugin,user))
- PYLOAD.remove_account(plugin, user)
+ PYLOAD.removeAccount(plugin, user)
@route("/json/change_password", method="POST")
def change_password():
@@ -422,7 +424,7 @@ def change_password():
oldpw = request.POST["login_current_password"]
newpw = request.POST["login_new_password"]
- if not PYLOAD.change_password(user, oldpw, newpw):
+ if not PYLOAD.changePassword(user, oldpw, newpw):
print "Wrong password"
return HTTPError()
diff --git a/module/web/media/default/js/funktions.js b/module/web/media/default/js/funktions.js
index 8d9d332b3..529b7056b 100644
--- a/module/web/media/default/js/funktions.js
+++ b/module/web/media/default/js/funktions.js
@@ -1,6 +1,6 @@
// JavaScript Document
-function HumanFileSize(size) {
- var filesizename = new Array("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB");
+function humanFileSize(size) {
+ var filesizename = new Array("B", "KiB", "MiB", "GiB", "TiB", "PiB");
var loga = Math.log(size) / Math.log(1024);
var i = Math.floor(loga);
var a = Math.pow(1024, i);
diff --git a/module/web/pyload_app.py b/module/web/pyload_app.py
index 3bd314a40..0131e888f 100644
--- a/module/web/pyload_app.py
+++ b/module/web/pyload_app.py
@@ -16,9 +16,8 @@
@author: RaNaN
"""
-from copy import deepcopy
from datetime import datetime
-from operator import itemgetter
+from operator import itemgetter, attrgetter
import time
import os
@@ -26,14 +25,15 @@ import sys
from os import listdir
from os.path import isdir, isfile, join, abspath
from sys import getfilesystemencoding
-from hashlib import sha1
from urllib import unquote
from bottle import route, static_file, request, response, redirect, HTTPError, error
from webinterface import PYLOAD, PYLOAD_DIR, PROJECT_DIR, SETUP
-from utils import render_to_response, parse_permissions, parse_userdata, login_required, get_permission, set_permission
+from utils import render_to_response, parse_permissions, parse_userdata, \
+ login_required, get_permission, set_permission, toDict
+
from filters import relpath, unquotepath
from module.utils import formatSize, decode, fs_decode, freeSpace
@@ -46,10 +46,10 @@ def pre_processor():
perms = parse_permissions(s)
status = {}
if user["is_authenticated"]:
- status = PYLOAD.status_server()
+ status = PYLOAD.statusServer()
captcha = False
if user["is_authenticated"]:
- captcha = PYLOAD.is_captcha_waiting()
+ captcha = PYLOAD.isCaptchaWaiting()
return {"user": user,
'status': status,
'captcha': captcha,
@@ -57,10 +57,6 @@ def pre_processor():
'url': request.url}
-def get_sort_key(item):
- return item[1]["order"]
-
-
def base(messages):
return render_to_response('base.html', {'messages': messages}, [pre_processor])
@@ -79,7 +75,7 @@ def error500(error):
@route('/media/:path#.+#')
def server_static(path):
response.headers['Expires'] = time.strftime("%a, %d %b %Y %H:%M:%S GMT",
- time.gmtime(time.time() + 60 * 60 * 24 * 7))
+ time.gmtime(time.time() + 60 * 60 * 24 * 2))
response.headers['Cache-control'] = "public"
return static_file(path, root=join(PROJECT_DIR, "media"))
@@ -136,7 +132,7 @@ def logout():
@login_required("see_downloads")
def home():
try:
- res = PYLOAD.status_downloads()
+ res = [toDict(x) for x in PYLOAD.statusDownloads()]
except:
s = request.environ.get('beaker.session')
s.delete()
@@ -152,29 +148,27 @@ def home():
@route("/queue")
@login_required("see_downloads")
def queue():
- queue = PYLOAD.get_queue_info()
+ queue = PYLOAD.getQueue()
- data = zip(queue.keys(), queue.values())
- data.sort(key=get_sort_key)
+ queue.sort(key=attrgetter("order"))
- return render_to_response('queue.html', {'content': data}, [pre_processor])
+ return render_to_response('queue.html', {'content': queue}, [pre_processor])
@route("/collector")
@login_required('see_downloads')
def collector():
- queue = PYLOAD.get_collector_info()
+ queue = PYLOAD.getCollector()
- data = zip(queue.keys(), queue.values())
- data.sort(key=get_sort_key)
+ queue.sort(key=attrgetter("order"))
- return render_to_response('collector.html', {'content': data}, [pre_processor])
+ return render_to_response('collector.html', {'content': queue}, [pre_processor])
@route("/downloads")
@login_required('download')
def downloads():
- root = PYLOAD.get_conf_val("general", "download_folder")
+ root = PYLOAD.getConfigValue("general", "download_folder")
if not isdir(root):
return base([_('Download directory not found.')])
@@ -213,7 +207,7 @@ def get_download(path):
path = unquote(path)
#@TODO some files can not be downloaded
- root = PYLOAD.get_conf_val("general", "download_folder")
+ root = PYLOAD.getConfigValue("general", "download_folder")
path = path.replace("..", "")
try:
@@ -227,7 +221,7 @@ def get_download(path):
#@route("/filemanager")
#@login_required('filemanager')
def filemanager():
- root = PYLOAD.get_conf_val("general", "download_folder")
+ root = PYLOAD.getConfigValue("general", "download_folder")
if not isdir(root):
return base([_('Download directory not found.')])
@@ -283,48 +277,49 @@ def folder():
@route("/settings")
@login_required('settings')
def config():
- conf = PYLOAD.get_config()
- plugin = PYLOAD.get_plugin_config()
+ conf = PYLOAD.getConfig()
+ plugin = PYLOAD.getPluginConfig()
conf_menu = []
plugin_menu = []
for entry in sorted(conf.keys()):
- conf_menu.append((entry, conf[entry]["desc"]))
+ conf_menu.append((entry, conf[entry].description))
for entry in sorted(plugin.keys()):
- plugin_menu.append((entry, plugin[entry]["desc"]))
-
- accs = deepcopy(PYLOAD.get_accounts(False, False))
- for accounts in accs.itervalues():
- for data in accounts:
- if data["trafficleft"] == -1:
- data["trafficleft"] = _("unlimited")
- elif not data["trafficleft"]:
- data["trafficleft"] = _("not available")
- else:
- data["trafficleft"] = formatSize(data["trafficleft"] * 1024)
+ plugin_menu.append((entry, plugin[entry].description))
- if data["validuntil"] == -1:
- data["validuntil"] = _("unlimited")
- elif not data["validuntil"]:
- data["validuntil"] = _("not available")
- else:
- t = time.localtime(data["validuntil"])
- data["validuntil"] = time.strftime("%d.%m.%Y", t)
+ accs = PYLOAD.getAccounts(False)
- if data["options"].has_key("time"):
- try:
- data["time"] = data["options"]["time"][0]
- except:
- data["time"] = "0:00-0:00"
- if data["options"].has_key("limitDL"):
- data["limitdl"] = data["options"]["limitDL"][0]
- else:
- data["limitdl"] = "0"
+ for data in accs:
+ if data.trafficleft == -1:
+ data.trafficleft = _("unlimited")
+ elif not data.trafficleft:
+ data.trafficleft = _("not available")
+ else:
+ data.trafficleft = formatSize(data.trafficleft * 1024)
+
+ if data.validuntil == -1:
+ data.validuntil = _("unlimited")
+ elif not data.validuntil :
+ data.validuntil = _("not available")
+ else:
+ t = time.localtime(data.validuntil)
+ data.validuntil = time.strftime("%d.%m.%Y", t)
+
+ if data.options.has_key("time"):
+ try:
+ data.options["time"] = data.options["time"][0]
+ except:
+ data.options["time"] = "0:00-0:00"
+
+ if data.options.has_key("limitDL"):
+ data.options["limitdl"] = data.options["limitDL"][0]
+ else:
+ data.options["limitdl"] = "0"
return render_to_response('settings.html',
- {'conf': {'plugin': plugin_menu, 'general': conf_menu, 'accs': accs}},
+ {'conf': {'plugin': plugin_menu, 'general': conf_menu, 'accs': accs}, 'types': PYLOAD.getAccountTypes()},
[pre_processor])
@@ -448,8 +443,8 @@ def logs(item=-1):
reversed = s.get('reversed', False)
warning = ""
- conf = PYLOAD.get_config()
- if not conf['log']['file_log']['value']:
+ conf = PYLOAD.getConfigValue("log","file_log")
+ if not conf:
warning = "Warning: File log is disabled, see settings page."
perpage_p = ((20, 20), (34, 34), (40, 40), (100, 100), (0, 'all'))
@@ -476,7 +471,7 @@ def logs(item=-1):
except:
pass
- log = PYLOAD.get_log()
+ log = PYLOAD.getLog()
if not perpage:
item = 0
@@ -527,7 +522,7 @@ def logs(item=-1):
@route("/admin", method="POST")
@login_required("is_admin")
def admin():
- user = PYLOAD.get_user_data()
+ user = PYLOAD.getAllUserData()
for data in user.itervalues():
data["perms"] = {}
get_permission(data["perms"], data["permission"])
@@ -580,7 +575,7 @@ def admin():
user[name]["permission"] = set_permission(user[name]["perms"])
- PYLOAD.set_user_permission(name, user[name]["permission"], user[name]["role"])
+ PYLOAD.setUserPermission(name, user[name]["permission"], user[name]["role"])
return render_to_response("admin.html", {"users": user}, [pre_processor])
@@ -595,7 +590,7 @@ def setup():
@route("/info")
def info():
- conf = PYLOAD.get_config()
+ conf = PYLOAD.getConfigDict()
if hasattr(os, "uname"):
extra = os.uname()
@@ -604,10 +599,10 @@ def info():
data = {"python": sys.version,
"os": " ".join((os.name, sys.platform) + extra),
- "version": PYLOAD.get_server_version(),
+ "version": PYLOAD.getServerVersion(),
"folder": abspath(PYLOAD_DIR), "config": abspath(""),
"download": abspath(conf["general"]["download_folder"]["value"]),
- "freespace": formatSize(freeSpace(conf["general"]["download_folder"]["value"])),
+ "freespace": formatSize(PYLOAD.freeSpace()),
"remote": conf["remote"]["port"]["value"],
"webif": conf["webinterface"]["port"]["value"],
"language": conf["general"]["language"]["value"]}
diff --git a/module/web/templates/default/base.html b/module/web/templates/default/base.html
index 6eb71f737..13538cf08 100644
--- a/module/web/templates/default/base.html
+++ b/module/web/templates/default/base.html
@@ -86,7 +86,7 @@ document.addEvent("domready", function(){
function LoadJsonToContent(data)
{
$("speed").set('text', Math.round(data.speed*100)/100);
- $("aktiv").set('text', data.activ);
+ $("aktiv").set('text', data.active);
$("aktiv_from").set('text', data.queue);
$("aktiv_total").set('text', data.total);
@@ -257,7 +257,7 @@ function AddBox(){
<li><span class="time">{{_("Download:")}}</span><a id="time" style=" background-color: {% if status.download %}#8ffc25{% else %} #fc6e26{% endif %}; padding-left: 0cm; padding-right: 0.1cm; "> {% if status.download %}{{_("on")}}{% else %}{{_("off")}}{% endif %}</a></li>
<li><span class="reconnect">{{_("Reconnect:")}}</span><a id="reconnect" style=" background-color: {% if status.reconnect %}#8ffc25{% else %} #fc6e26{% endif %}; padding-left: 0cm; padding-right: 0.1cm; "> {% if status.reconnect %}{{_("on")}}{% else %}{{_("off")}}{% endif %}</a></li>
<li><a class="action backlink">{{_("Speed:")}} <b id="speed">{{ status.speed }}</b> kb/s</a></li>
- <li><a class="action cog">{{_("Active:")}} <b id="aktiv">{{ status.activ }}</b> / <b id="aktiv_from">{{ status.queue }}</b> / <b id="aktiv_total">{{ status.total }}</b></a></li>
+ <li><a class="action cog">{{_("Active:")}} <b id="aktiv">{{ status.active }}</b> / <b id="aktiv_from">{{ status.queue }}</b> / <b id="aktiv_total">{{ status.total }}</b></a></li>
<li><a href="" class="action revisions" accesskey="o" rel="nofollow">{{_("Reload page")}}</a></li>
</ul>
{% endif %}
diff --git a/module/web/templates/default/collector.html b/module/web/templates/default/collector.html
index 2683d8ee5..20221b899 100644
--- a/module/web/templates/default/collector.html
+++ b/module/web/templates/default/collector.html
@@ -24,9 +24,9 @@ document.addEvent("domready", function(){
{% block content %}
<ul id="package-list" style="list-style: none; padding-left: 0; margin-top: -10px;">
-{% for id, package in content %}
+{% for package in content %}
<li>
-<div id="package_{{id}}" class="package">
+<div id="package_{{package.pid}}" class="package">
<div class="order" style="display: none;">{{ package.order }}</div>
<div class="packagename" style="cursor: pointer;">
@@ -43,9 +43,9 @@ document.addEvent("domready", function(){
<img title="{{_("Move Package to Queue")}}" style="margin-left: -10px; cursor: pointer" height="12px" src="/media/default/img/package_go.png" />
</span>
</div>
- <div id="children_{{id}}" style="display: none;" class="children">
+ <div id="children_{{package.pid}}" style="display: none;" class="children">
<span class="child_secrow">{{_("Folder:")}} <span class="folder">{{package.folder}}</span> | {{_("Password:")}} <span class="password">{{package.password}}</span> | {{_("Priority:")}} <span class="prio">{{package.priority}}</span></span>
- <ul id="sort_children_{{id}}" style="list-style: none; padding-left: 0">
+ <ul id="sort_children_{{package.pid}}" style="list-style: none; padding-left: 0">
</ul>
</div>
</div>
diff --git a/module/web/templates/default/home.html b/module/web/templates/default/home.html
index 1239d381d..0efb1bcf8 100644
--- a/module/web/templates/default/home.html
+++ b/module/web/templates/default/home.html
@@ -48,7 +48,7 @@ var EntryManager = new Class({
try{
this.ids = this.entries.map(function(item){
- return item.id
+ return item.fid
});
this.ids.filter(function(id){
@@ -56,21 +56,21 @@ var EntryManager = new Class({
},data).each(function(id){
var index = this.ids.indexOf(id);
this.entries[index].remove();
- this.entries = this.entries.filter(function(item){return item.id != this},id);
+ this.entries = this.entries.filter(function(item){return item.fid != this},id);
this.ids = this.ids.erase(id)
}, this);
data.links.each(function(link, i){
- if (this.ids.contains(link.id)){
+ if (this.ids.contains(link.fid)){
- var index = this.ids.indexOf(link.id);
+ var index = this.ids.indexOf(link.fid);
this.entries[index].update(link)
}else{
- var entry = new LinkEntry(link.id);
+ var entry = new LinkEntry(link.fid);
entry.insert(link);
this.entries.push(entry);
- this.ids.push(link.id);
+ this.ids.push(link.fid);
this.container.adopt(entry.elements.tr,entry.elements.pgbTr);
entry.fade.start('opacity', 1);
entry.fadeBar.start('opacity', 1);
@@ -86,7 +86,8 @@ var EntryManager = new Class({
var LinkEntry = new Class({
initialize: function(id){
- this.id = id
+ this.fid = id;
+ this.id = id;
},
parse: function(){
this.elements = {
@@ -94,7 +95,7 @@ var LinkEntry = new Class({
name: $("link_{id}_name".substitute({id: this.id})),
status: $("link_{id}_status".substitute({id: this.id})),
info: $("link_{id}_info".substitute({id: this.id})),
- bleft: $("link_{id}_kbleft".substitute({id: this.id})),
+ bleft: $("link_{id}_bleft".substitute({id: this.id})),
percent: $("link_{id}_percent".substitute({id: this.id})),
remove: $("link_{id}_remove".substitute({id: this.id})),
pgbTr: $("link_{id}_pgb_tr".substitute({id: this.id})),
@@ -122,10 +123,10 @@ var LinkEntry = new Class({
'html': item.info
}),
bleft: new Element('td', {
- 'html': HumanFileSize(item.size)
+ 'html': humanFileSize(item.size)
}),
percent: new Element('span', {
- 'html': item.percent+ '% / '+ HumanFileSize(item.size-item.bleft)
+ 'html': item.percent+ '% / '+ humanFileSize(item.size-item.bleft)
}),
remove: new Element('img',{
'src': 'media/default/img/control_cancel.png',
@@ -173,7 +174,7 @@ var LinkEntry = new Class({
this.elements.status.set('text', item.statusmsg);
this.elements.info.set('text', item.info);
this.elements.bleft.set('text', item.format_size);
- this.elements.percent.set('text', item.percent+ '% / '+ HumanFileSize(item.size-item.bleft));
+ this.elements.percent.set('text', item.percent+ '% / '+ humanFileSize(item.size-item.bleft));
if(!operafix)
{
this.bar.start({
@@ -247,9 +248,9 @@ var LinkEntry = new Class({
<td id="link_{{ link.id }}_name">{{ link.name }}</td>
<td id="link_{{ link.id }}_status">{{ link.status }}</td>
<td id="link_{{ link.id }}_info">{{ link.info }}</td>
- <td id="link_{{ link.id }}_kbleft">{{ link.format_size }}</td>
+ <td id="link_{{ link.id }}_bleft">{{ link.format_size }}</td>
<td>
- <span id="link_{{ link.id }}_percent">{{ link.percent }}% /{{ link.kbleft }}</span>
+ <span id="link_{{ link.id }}_percent">{{ link.percent }}% /{{ link.bleft }}</span>
<img id="link_{{ link.id }}_remove" style="vertical-align: middle; margin-right: -20px; margin-left: 5px; margin-top: -2px; cursor:pointer;" src="media/default/img/control_cancel.png"/>
</td>
</tr>
diff --git a/module/web/templates/default/info.html b/module/web/templates/default/info.html
index 14f5a734f..77ae57376 100644
--- a/module/web/templates/default/info.html
+++ b/module/web/templates/default/info.html
@@ -21,9 +21,14 @@
<h3>{{ _("Support") }}</h3>
<ul>
- <li style="font-weight:bold;"><a href="http://pyload.org/wiki" target="_blank">Wiki</a></li>
- <li style="font-weight:bold;"><a href="http://forum.pyload.org/" target="_blank">Forum</a></li>
- <li style="font-weight:bold;"><a href="http://pyload.org/irc/" target="_blank">Chat</a></li>
+ <li style="font-weight:bold;">
+ <a href="http://pyload.org/wiki" target="_blank">Wiki</a>
+ &nbsp;&nbsp;|&nbsp;&nbsp;
+ <a href="http://forum.pyload.org/" target="_blank">Forum</a>
+ &nbsp;&nbsp;|&nbsp;&nbsp;
+ <a href="http://pyload.org/irc/" target="_blank">Chat</a>
+ </li>
+ <li style="font-weight:bold;"><a href="http://docs.pyload.org" target="_blank">Documentation</a></li>
<li style="font-weight:bold;"><a href="https://bitbucket.org/spoob/pyload/overview" target="_blank">Development</a></li>
<li style="font-weight:bold;"><a href="https://bitbucket.org/spoob/pyload/issues?status=new&status=open" target="_blank">Issue Tracker</a></li>
diff --git a/module/web/templates/default/package_ui.js b/module/web/templates/default/package_ui.js
index cee29dfd8..0b938910a 100644
--- a/module/web/templates/default/package_ui.js
+++ b/module/web/templates/default/package_ui.js
@@ -204,6 +204,7 @@ var Package = new Class({
var ul = $("sort_children_{id}".substitute({"id": this.id}));
ul.erase("html");
data.links.each(function(link) {
+ link.id = link.fid;
var li = new Element("li", {
"style": {
"margin-left": 0
diff --git a/module/web/templates/default/queue.html b/module/web/templates/default/queue.html
index 104369c11..b9ec525a1 100644
--- a/module/web/templates/default/queue.html
+++ b/module/web/templates/default/queue.html
@@ -25,9 +25,9 @@ document.addEvent("domready", function(){
<ul id="package-list" style="list-style: none; padding-left: 0; margin-top: -10px;">
-{% for id, package in content %}
+{% for package in content %}
<li>
-<div id="package_{{id}}" class="package">
+<div id="package_{{package.pid}}" class="package">
<div class="order" style="display: none;">{{ package.order }}</div>
<div class="packagename" style="cursor: pointer;">
@@ -44,9 +44,9 @@ document.addEvent("domready", function(){
<img title="{{_("Move Package to Collector")}}" style="margin-left: -10px; cursor: pointer" height="12px" src="/media/default/img/package_go.png" />
</span>
</div>
- <div id="children_{{id}}" style="display: none;" class="children">
+ <div id="children_{{package.pid}}" style="display: none;" class="children">
<span class="child_secrow">{{_("Folder:")}} <span class="folder">{{package.folder}}</span> | {{_("Password:")}} <span class="password">{{package.password}}</span> | {{_("Priority:")}} <span class="prio">{{package.priority}}</span></span>
- <ul id="sort_children_{{id}}" style="list-style: none; padding-left: 0">
+ <ul id="sort_children_{{package.pid}}" style="list-style: none; padding-left: 0">
</ul>
</div>
</div>
diff --git a/module/web/templates/default/settings.html b/module/web/templates/default/settings.html
index a74fe4261..d5484f06e 100644
--- a/module/web/templates/default/settings.html
+++ b/module/web/templates/default/settings.html
@@ -131,10 +131,9 @@
</tr>
</thead>
- {% for plugin, accounts in conf.accs.iteritems() %}
-
- {% for account in accounts %}
+ {% for account in conf.accs %}
+ {% set plugin = account.type %}
<tr>
<td>
<span style="padding:5px">{{ plugin }}</span>
@@ -193,11 +192,9 @@
value="True"/>
</td>
</tr>
- {% endfor %}
{% endfor %}
</table>
-
<button id="account_submit" type="submit" class="styled_button">{{_("Submit")}}</button>
<button id="account_add" style="margin-left: 0" type="submit" class="styled_button">{{_("Add")}}</button>
</form>
@@ -223,12 +220,11 @@
<span class="small">{{_("Choose the hoster for your account.")}}</span>
</label>
<select name=account_type id="account_type">
- {% for type in conf.accs.iterkeys()|sort %}
+ {% for type in types|sort %}
<option value="{{ type }}">{{ type }}</option>
{% endfor %}
</select>
-
<button id="account_add_button" type="submit">{{_("Add")}}</button>
<button id="account_reset" style="margin-left: 0" type="reset">{{_("Reset")}}</button>
<div class="spacer"></div>
diff --git a/module/web/templates/default/settings_item.html b/module/web/templates/default/settings_item.html
index 593050bd2..92223557d 100644
--- a/module/web/templates/default/settings_item.html
+++ b/module/web/templates/default/settings_item.html
@@ -1,45 +1,45 @@
<table class="settable">
- {% for okey, option in section.iteritems() %}
- {% if okey != "desc" %}
- <tr>
- <td><label for="{{skey}}|{{okey}}"
- style="color:#424242;">{{ option.desc }}:</label></td>
- <td>
- {% if option.type == "bool" %}
- <select id="{{skey}}|{{okey}}" name="{{skey}}|{{okey}}">
- <option {% if option.value %} selected="selected"
- {% endif %}value="True">{{ _("on") }}</option>
- <option {% if not option.value %} selected="selected"
- {% endif %}value="False">{{ _("off") }}</option>
- </select>
- {% elif ";" in option.type %}
- <select id="{{skey}}|{{okey}}" name="{{skey}}|{{okey}}">
- {% for entry in option.list %}
- <option {% if option.value == entry %}
- selected="selected" {% endif %}>{{ entry }}</option>
- {% endfor %}
- </select>
- {% elif option.type == "folder" %}
- <input name="{{skey}}|{{okey}}" type="text"
- id="{{skey}}|{{okey}}" value="{{option.value}}"/>
- <input name="browsebutton" type="button"
- onclick="ifield = document.getElementById('{{skey}}|{{okey}}'); pathchooser = window.open('{% if option.value %}{{ "/pathchooser/" + option.value|quotepath }}{% else %}{{ pathroot }}{% endif %}', 'pathchooser', 'scrollbars=yes,toolbar=no,menubar=no,statusbar=no,width=650,height=300'); pathchooser.ifield = ifield; window.ifield = ifield;"
- value="{{_("Browse")}}"/>
- {% elif option.type == "file" %}
- <input name="{{skey}}|{{okey}}" type="text"
- id="{{skey}}|{{okey}}" value="{{option.value}}"/>
- <input name="browsebutton" type="button"
- onclick="ifield = document.getElementById('{{skey}}|{{okey}}'); filechooser = window.open('{% if option.value %}{{ "/filechooser/" + option.value|quotepath }}{% else %}{{ fileroot }}{% endif %}', 'filechooser', 'scrollbars=yes,toolbar=no,menubar=no,statusbar=no,width=650,height=300'); filechooser.ifield = ifield; window.ifield = ifield;"
- value="{{_("Browse")}}"/>
- {% elif option.type == "password" %}
- <input id="{{skey}}|{{okey}}" name="{{skey}}|{{okey}}"
- type="password" value="{{option.value}}"/>
- {% else %}
- <input id="{{skey}}|{{okey}}" name="{{skey}}|{{okey}}"
- type="text" value="{{option.value}}"/>
- {% endif %}
- </td>
- </tr>
- {% endif %}
+ {% set skey = section.name %}
+ {% for option in section.items %}
+ {% set okey = option.name %}
+ <tr>
+ <td><label for="{{skey}}|{{okey}}"
+ style="color:#424242;">{{ option.description }}:</label></td>
+ <td>
+ {% if option.type == "bool" %}
+ <select id="{{skey}}|{{okey}}" name="{{skey}}|{{okey}}">
+ <option {% if option.value %} selected="selected"
+ {% endif %}value="True">{{ _("on") }}</option>
+ <option {% if not option.value %} selected="selected"
+ {% endif %}value="False">{{ _("off") }}</option>
+ </select>
+ {% elif option.type|type == "<type 'list'>" %}
+ <select id="{{skey}}|{{okey}}" name="{{skey}}|{{okey}}">
+ {% for entry in option.type %}
+ <option {% if option.value == entry %}
+ selected="selected" {% endif %}>{{ entry }}</option>
+ {% endfor %}
+ </select>
+ {% elif option.type == "folder" %}
+ <input name="{{skey}}|{{okey}}" type="text"
+ id="{{skey}}|{{okey}}" value="{{option.value}}"/>
+ <input name="browsebutton" type="button"
+ onclick="ifield = document.getElementById('{{skey}}|{{okey}}'); pathchooser = window.open('{% if option.value %}{{ "/pathchooser/" + option.value|quotepath }}{% else %}{{ pathroot }}{% endif %}', 'pathchooser', 'scrollbars=yes,toolbar=no,menubar=no,statusbar=no,width=650,height=300'); pathchooser.ifield = ifield; window.ifield = ifield;"
+ value="{{_("Browse")}}"/>
+ {% elif option.type == "file" %}
+ <input name="{{skey}}|{{okey}}" type="text"
+ id="{{skey}}|{{okey}}" value="{{option.value}}"/>
+ <input name="browsebutton" type="button"
+ onclick="ifield = document.getElementById('{{skey}}|{{okey}}'); filechooser = window.open('{% if option.value %}{{ "/filechooser/" + option.value|quotepath }}{% else %}{{ fileroot }}{% endif %}', 'filechooser', 'scrollbars=yes,toolbar=no,menubar=no,statusbar=no,width=650,height=300'); filechooser.ifield = ifield; window.ifield = ifield;"
+ value="{{_("Browse")}}"/>
+ {% elif option.type == "password" %}
+ <input id="{{skey}}|{{okey}}" name="{{skey}}|{{okey}}"
+ type="password" value="{{option.value}}"/>
+ {% else %}
+ <input id="{{skey}}|{{okey}}" name="{{skey}}|{{okey}}"
+ type="text" value="{{option.value}}"/>
+ {% endif %}
+ </td>
+ </tr>
{% endfor %}
</table> \ No newline at end of file
diff --git a/module/web/utils.py b/module/web/utils.py
index 81baa4fd2..1455c3c01 100644
--- a/module/web/utils.py
+++ b/module/web/utils.py
@@ -109,6 +109,12 @@ def login_required(perm=None):
return _dec
+def toDict(obj):
+ ret = {}
+ for att in obj.__slots__:
+ ret[att] = getattr(obj, att)
+ return ret
+
class CherryPyWSGI(ServerAdapter):
def run(self, handler):
diff --git a/module/web/webinterface.py b/module/web/webinterface.py
index 69e67f9e4..e54c8b137 100644
--- a/module/web/webinterface.py
+++ b/module/web/webinterface.py
@@ -49,7 +49,7 @@ if not ServerThread.core:
else:
raise Exception("Could not access pyLoad Core")
else:
- PYLOAD = ServerThread.core.server_methods
+ PYLOAD = ServerThread.core.api
config = ServerThread.core.config
from module.common.JsEngine import JsEngine
@@ -72,7 +72,7 @@ loader = PrefixLoader({
})
env = Environment(loader=loader, extensions=['jinja2.ext.i18n'], trim_blocks=True, auto_reload=False, bytecode_cache=bcc)
-from filters import quotepath, path_make_relative, path_make_absolute, truncate,date
+from filters import quotepath, path_make_relative, path_make_absolute, truncate, date
env.filters["quotepath"] = quotepath
env.filters["truncate"] = truncate
@@ -80,6 +80,7 @@ env.filters["date"] = date
env.filters["path_make_relative"] = path_make_relative
env.filters["path_make_absolute"] = path_make_absolute
env.filters["decode"] = decode
+env.filters["type"] = lambda x: str(type(x))
translation = gettext.translation("django", join(PYLOAD_DIR, "locale"),
diff --git a/pyLoadCore.py b/pyLoadCore.py
index b0196c3c5..3e0979b57 100755
--- a/pyLoadCore.py
+++ b/pyLoadCore.py
@@ -49,7 +49,6 @@ from module.PullEvents import PullManager
from module.network.RequestFactory import RequestFactory
from module.ThreadManager import ThreadManager
from module.web.ServerThread import WebServer
-from module.PyFile import PyFile
from module.Scheduler import Scheduler
from module.common.JsEngine import JsEngine
from module.remote.RemoteManager import RemoteManager
@@ -337,8 +336,6 @@ class Core(object):
self.lastClientConnected = 0
from module.Api import Api
-
- self.server_methods = ServerMethods(self)
self.api = Api(self)
self.scheduler = Scheduler(self)
@@ -354,7 +351,7 @@ class Core(object):
self.js = JsEngine()
- self.log.info(_("Downloadtime: %s") % self.server_methods.is_time_download())
+ self.log.info(_("Downloadtime: %s") % self.api.isTimeDownload())
if rpc:
self.remoteManager.startBackends()
@@ -375,14 +372,14 @@ class Core(object):
if exists(link_file):
f = open(link_file, "rb")
if f.read().strip():
- self.server_methods.add_package("links.txt", [link_file], 1)
+ self.api.addPackage("links.txt", [link_file], 1)
f.close()
link_file = "links.txt"
if exists(link_file):
f = open(link_file, "rb")
if f.read().strip():
- self.server_methods.add_package("links.txt", [link_file], 1)
+ self.api.addPackage("links.txt", [link_file], 1)
f.close()
#self.scheduler.addJob(0, self.accountManager.getAccountInfos)
@@ -550,344 +547,6 @@ class Core(object):
def path(self, * args):
return join(pypath, * args)
-
-#TODO: replace with api class
-class ServerMethods():
- """ deprecated"""
-
- def __init__(self, core):
- self.core = core
-
- def _dispatch(self, method, params):
- f = getattr(self, method)
- try:
- return f(*params)
- except:
- print_exc()
- raise
-
- def status_downloads(self):
- """ gives status about all files currently processed """
- downloads = []
- for pyfile in [x.active for x in self.core.threadManager.threads + self.core.threadManager.localThreads if
- x.active and x.active != "quit"]:
- if not isinstance(pyfile, PyFile) or not hasattr(pyfile, "plugin"):
- continue
- download = {'id': pyfile.id,
- 'name': pyfile.name,
- 'speed': pyfile.getSpeed() / 1024,
- 'eta': pyfile.getETA(),
- 'format_eta': pyfile.formatETA(),
- 'kbleft': pyfile.getBytesLeft(),
- 'bleft': pyfile.getBytesLeft(),
- 'size': pyfile.getSize(),
- 'format_size': pyfile.formatSize(),
- 'percent': pyfile.getPercent(),
- 'status': pyfile.status,
- 'statusmsg': pyfile.m.statusMsg[pyfile.status],
- 'format_wait': pyfile.formatWait(),
- 'wait_until': pyfile.waitUntil,
- 'package': pyfile.package().name}
- downloads.append(download)
- return downloads
-
- def get_conf_val(self, cat, var, sec="core"):
- """ get config value """
- if sec == "core":
- return self.core.config[cat][var]
- elif sec == "plugin":
- return self.core.config.getPlugin(cat, var)
-
- def set_conf_val(self, cat, opt, val, sec="core"):
- """ set config value """
- if sec == "core":
- opt = str(opt)
- self.core.config[str(cat)][opt] = val
-
- if opt in ("limit_speed", "max_speed"): #not so nice to update the limit
- self.core.requestFactory.updateBucket()
-
- elif sec == "plugin":
- self.core.config.setPlugin(cat, opt, val)
-
- def get_config(self):
- """ gets complete config """
- return self.core.config.config
-
- def get_plugin_config(self):
- """ gets complete plugin config """
- return self.core.config.plugin
-
- def pause_server(self):
- self.core.threadManager.pause = True
-
- def unpause_server(self):
- self.core.threadManager.pause = False
-
- def toggle_pause(self):
- self.core.threadManager.pause ^= True
- return self.core.threadManager.pause
-
- def toggle_reconnect(self):
- self.core.config["reconnect"]["activated"] ^= True
- return self.core.config["reconnect"]["activated"]
-
- def status_server(self):
- """ dict with current server status """
- status = {'pause': self.core.threadManager.pause,
- 'activ': len(self.core.threadManager.processingIds()),
- 'queue': self.core.files.getQueueCount(),
- 'total': self.core.files.getFileCount(),
- 'speed': 0}
-
- for pyfile in [x.active for x in self.core.threadManager.threads if x.active and x.active != "quit"]:
- status['speed'] += pyfile.getSpeed()/1024
-
- status['download'] = not self.core.threadManager.pause and self.is_time_download()
- status['reconnect'] = self.core.config['reconnect']['activated'] and self.is_time_reconnect()
-
- return status
-
- def free_space(self):
- return freeSpace(self.core.config["general"]["download_folder"]) / 1024 / 1024 #mb
-
- def get_server_version(self):
- return CURRENT_VERSION
-
- def add_package(self, name, links, queue=0):
- #0 is collector
- if self.core.config['general']['folder_per_package']:
- folder = name
- else:
- folder = ""
-
- folder = folder.replace("http://","").replace(":","").replace("/","_").replace("\\","_")
-
- pid = self.core.files.addPackage(name, folder, queue)
-
- self.core.files.addLinks(links, pid)
-
- self.core.log.info(_("Added package %(name)s containing %(count)d links") % {"name": name, "count": len(links)})
-
- self.core.files.save()
-
- return pid
-
-
- def get_package_data(self, id):
- return self.core.files.getPackageData(int(id))
-
- def get_file_data(self, id):
- info = self.core.files.getFileData(int(id))
- if not info:
- return None
- info = {str(info.keys()[0]): info[info.keys()[0]]}
- return info
-
- def del_links(self, ids):
- for id in ids:
- self.core.files.deleteLink(int(id))
-
- self.core.files.save()
-
- def del_packages(self, ids):
- for id in ids:
- self.core.files.deletePackage(int(id))
-
- self.core.files.save()
-
- def kill(self):
- self.core.do_kill = True
- return True
-
- def restart(self):
- self.core.do_restart = True
-
- def get_queue(self):
- return self.core.files.getCompleteData(1)
-
- def get_collector(self):
- return self.core.files.getCompleteData(0)
-
- def get_queue_info(self):
- return self.core.files.getInfoData(1)
-
- def get_collector_info(self):
- return self.core.files.getInfoData(0)
-
- def add_files(self, pid, links):
- pid = int(pid)
- self.core.files.addLinks(links, pid)
-
- self.core.log.info(_("Added %(count)d links to package #%(package)d ") % {"count": len(links), "package": pid})
- self.core.files.save()
-
- return pid
-
- def push_package_to_queue(self, id):
- self.core.files.setPackageLocation(id, 1)
-
- def restart_package(self, packid):
- self.core.files.restartPackage(int(packid))
-
- def recheck_package(self, packid):
- self.core.files.reCheckPackage(int(packid))
-
- def restart_file(self, fileid):
- self.core.files.restartFile(int(fileid))
-
- def upload_container(self, filename, content):
- th = open(join(self.core.config["general"]["download_folder"], "tmp_" + filename), "wb")
- th.write(str(content))
- th.close()
-
- self.add_package(th.name, [th.name], 1)
-
- def get_log(self, offset=0):
- filename = join(self.core.config['log']['log_folder'], 'log.txt')
- try:
- fh = open(filename, "r")
- lines = fh.readlines()
- fh.close()
- if offset >= len(lines):
- return None
- return lines[offset:]
- except:
- return ('No log available', )
-
- def stop_downloads(self):
- pyfiles = self.core.files.cache.values()
-
- for pyfile in pyfiles:
- pyfile.abortDownload()
-
- def abort_files(self, fids):
- pyfiles = self.core.files.cache.values()
-
- for pyfile in pyfiles:
- if pyfile.id in fids:
- pyfile.abortDownload()
-
- def stop_download(self, type, id):
- if self.core.files.cache.has_key(id):
- self.core.files.cache[id].abortDownload()
-
-
- def set_package_name(self, pid, name):
- pack = self.core.files.getPackage(pid)
- pack.name = name
- pack.sync()
-
- def pull_out_package(self, pid):
- """put package back to collector"""
- self.core.files.setPackageLocation(pid, 0)
-
- def move_package(self, dest, pid):
- if dest not in (0,1): return
- self.core.files.setPackageLocation(pid, dest)
-
- def is_captcha_waiting(self):
- self.core.lastClientConnected = time()
- task = self.core.captchaManager.getTask()
- return not task is None
-
- def get_captcha_task(self, exclusive=False):
- """ returns tid, data, type, resulttype """
- self.core.lastClientConnected = time()
- task = self.core.captchaManager.getTask()
- if task:
- task.setWatingForUser(exclusive=exclusive)
- captcha_info = task.getCaptcha()
- return (task.id,) + captcha_info
- else:
- return None, None, None, None
-
- def get_task_status(self, tid):
- self.core.lastClientConnected = time()
- t = self.core.captchaManager.getTaskByID(tid)
- return t.getStatus() if t else ""
-
- def set_captcha_result(self, tid, result):
- self.core.lastClientConnected = time()
- task = self.core.captchaManager.getTaskByID(tid)
- if task:
- task.setResult(result)
- self.core.captchaManager.removeTask(task)
- return True
- else:
- return False
-
- def get_events(self, uuid):
- return self.core.pullManager.getEvents(uuid)
-
- def get_accounts(self, force=False, refresh=True):
- return self.core.accountManager.getAccountInfos(force, refresh)
-
- def update_account(self, plugin, account, password=None, options={}):
- """ create and update account """
- self.core.accountManager.updateAccount(plugin, account, password, options)
-
- def remove_account(self, plugin, account):
- self.core.accountManager.removeAccount(plugin, account)
-
- def set_priority(self, id, priority):
- p = self.core.files.getPackage(id)
- p.setPriority(priority)
-
- def order_package(self, id, pos):
- self.core.files.reorderPackage(id, pos)
-
- def order_file(self, id, pos):
- self.core.files.reorderFile(id, pos)
-
- def set_package_data(self, id, data):
- p = self.core.files.getPackage(id)
- if not p: return
-
- for key, value in data.iteritems():
- if key == "id": continue
- setattr(p, key, value)
-
- p.sync()
- self.core.files.save()
-
- def checkURLs(self, urls):
- support = self.core.pluginManager.parseUrls(urls)
- return [(u, p) if not p == "BasePlugin" else (u, None) for u, p in support]
-
- def is_time_download(self):
- start = self.core.config['downloadTime']['start'].split(":")
- end = self.core.config['downloadTime']['end'].split(":")
- return compare_time(start, end)
-
- def is_time_reconnect(self):
- start = self.core.config['reconnect']['startTime'].split(":")
- end = self.core.config['reconnect']['endTime'].split(":")
- return compare_time(start, end) and self.core.config["reconnect"]["activated"]
-
- def delete_finished(self):
- """ delete all finished links + packages, returns deleted packages """
- deleted = self.core.files.deleteFinishedLinks()
- return deleted
-
- def restart_failed(self):
- """ restart all failed links """
- self.core.files.restartFailed()
-
- def checkAuth(self, username, password):
- return self.core.db.checkAuth(username, password)
-
- def get_user_data(self):
- return self.core.db.getAllUserData()
-
- def set_user_permission(self, user, permission, role):
- self.core.db.setPermission(user, permission)
- self.core.db.setRole(user, role)
-
- def change_password(self, user, oldpw, newpw):
- return self.core.db.changePassword(user, oldpw, newpw)
-
-
def deamon():
try:
pid = os.fork()
diff --git a/pyLoadGui.py b/pyLoadGui.py
index 87b501ee2..33326c416 100755
--- a/pyLoadGui.py
+++ b/pyLoadGui.py
@@ -694,7 +694,7 @@ class main(QObject):
def quitInternal(self):
if self.core:
- self.core.server_methods.kill()
+ self.core.api.kill()
for i in range(10):
if self.core.shuttedDown:
break