diff options
-rw-r--r-- | module/database/FileDatabase.py | 3 | ||||
-rw-r--r-- | module/gui/Accounts.py | 30 | ||||
-rw-r--r-- | module/gui/Collector.py | 124 | ||||
-rw-r--r-- | module/gui/ConnectionManager.py | 1 | ||||
-rw-r--r-- | module/gui/MainWindow.py | 21 | ||||
-rw-r--r-- | module/gui/Overview.py | 13 | ||||
-rw-r--r-- | module/gui/Queue.py | 47 | ||||
-rw-r--r-- | module/gui/SettingsWidget.py | 100 | ||||
-rw-r--r-- | module/gui/connector.py | 276 | ||||
-rw-r--r-- | module/remote/thriftbackend/Handler.py | 46 | ||||
-rw-r--r-- | module/remote/thriftbackend/pyload.thrift | 28 | ||||
-rwxr-xr-x | module/remote/thriftbackend/thriftgen/pyload/Pyload-remote | 21 | ||||
-rw-r--r-- | module/remote/thriftbackend/thriftgen/pyload/Pyload.py | 221 | ||||
-rw-r--r-- | module/remote/thriftbackend/thriftgen/pyload/ttypes.py | 76 | ||||
-rwxr-xr-x | pyLoadCore.py | 20 | ||||
-rwxr-xr-x | pyLoadGui.py | 133 |
16 files changed, 617 insertions, 543 deletions
diff --git a/module/database/FileDatabase.py b/module/database/FileDatabase.py index 46f23855e..66dfd3c6c 100644 --- a/module/database/FileDatabase.py +++ b/module/database/FileDatabase.py @@ -697,7 +697,8 @@ class FileMethods(): 'error': r[5], 'plugin': r[6], 'package': r[7], - 'order': r[8] + 'order': r[8], + 'progress': 100 if r[4] in (0, 4) else 0 } return data diff --git a/module/gui/Accounts.py b/module/gui/Accounts.py index a4a047920..62971f3ed 100644 --- a/module/gui/Accounts.py +++ b/module/gui/Accounts.py @@ -31,11 +31,7 @@ class AccountModel(QAbstractItemModel): self.mutex = QMutex() def reloadData(self, force=False): - data = self.connector.proxy.get_accounts(force, False) - - accounts = [] - for li in data.values(): - accounts += li + accounts = self.connector.proxy.getAccounts(False) if self._data == accounts: return @@ -58,15 +54,15 @@ class AccountModel(QAbstractItemModel): return QVariant() if role == Qt.DisplayRole: if index.column() == 0: - return QVariant(self.toData(index)["type"]) + return QVariant(self.toData(index).type) elif index.column() == 1: - return QVariant(self.toData(index)["login"]) + return QVariant(self.toData(index).login) elif index.column() == 2: - if not self.toData(index)["valid"]: + if not self.toData(index).valid: return QVariant(_("not valid")) - if not self.toData(index)["validuntil"]: + if not self.toData(index).validuntil: return QVariant(_("n/a")) - until = int(self.toData(index)["validuntil"]) + until = int(self.toData(index).validuntil) if until > 0: fmtime = strftime(_("%a, %d %b %Y %H:%M"), gmtime(until)) return QVariant(fmtime) @@ -155,22 +151,22 @@ class AccountDelegate(QItemDelegate): data = self.model.toData(index) opts = QStyleOptionProgressBarV2() opts.minimum = 0 - if data["trafficleft"]: - if data["trafficleft"] == -1 or data["trafficleft"] is None: + if data.trafficleft: + if data.trafficleft == -1 or data.trafficleft is None: opts.maximum = opts.progress = 1 else: - opts.maximum = opts.progress = data["trafficleft"] - if data["maxtraffic"]: - opts.maximum = data["maxtraffic"] + opts.maximum = opts.progress = data.trafficleft + if data.maxtraffic: + opts.maximum = data.maxtraffic opts.rect = option.rect opts.rect.setRight(option.rect.right()-1) opts.rect.setHeight(option.rect.height()-1) opts.textVisible = True opts.textAlignment = Qt.AlignCenter - if data["trafficleft"] and data["trafficleft"] == -1: + if data.trafficleft and data.trafficleft == -1: opts.text = QString(_("unlimited")) - elif data["trafficleft"] is None: + elif data.trafficleft is None: opts.text = QString(_("n/a")) else: opts.text = QString.number(round(float(opts.progress)/1024/1024, 2)) + " GB" diff --git a/module/gui/Collector.py b/module/gui/Collector.py index 87d433566..0711a811e 100644 --- a/module/gui/Collector.py +++ b/module/gui/Collector.py @@ -19,6 +19,8 @@ from PyQt4.QtCore import * from PyQt4.QtGui import * +from module.remote.thriftbackend.thriftgen.pyload.ttypes import * + statusMap = { "finished": 0, "offline": 1, @@ -72,90 +74,84 @@ class CollectorModel(QAbstractItemModel): def addEvent(self, event): locker = QMutexLocker(self.mutex) - if event[0] == "reload": + if event.event == "reload": self.fullReload() - elif event[0] == "remove": + elif event.event == "remove": self.removeEvent(event) - elif event[0] == "insert": + elif event.event == "insert": self.insertEvent(event) - elif event[0] == "update": + elif event.event == "update": self.updateEvent(event) def fullReload(self): self._data = [] - packs = self.connector.getPackageCollector() - self.beginInsertRows(QModelIndex(), 0, len(packs)) - for pid, data in packs.items(): - package = Package(pid, data) + order = self.connector.getPackageOrder(Destination.Collector) + self.beginInsertRows(QModelIndex(), 0, len(order.values())) + for position, pid in order.iteritems(): + pack = self.connector.getPackageData(pid) + package = Package(pack) self._data.append(package) self._data = sorted(self._data, key=lambda p: p.data["order"]) self.endInsertRows() def removeEvent(self, event): - if event[2] == "file": + if event.type == ElementType.File: for p, package in enumerate(self._data): for k, child in enumerate(package.children): - if child.id == int(event[3]): + if child.id == event.id: self.beginRemoveRows(self.index(p, 0), k, k) del package.children[k] self.endRemoveRows() break else: for k, package in enumerate(self._data): - if package.id == int(event[3]): + if package.id == event.id: self.beginRemoveRows(QModelIndex(), k, k) del self._data[k] self.endRemoveRows() break def insertEvent(self, event): - if event[2] == "file": - info = self.connector.proxy.get_file_data(int(event[3])) - fid = info.keys()[0] - info = info.values()[0] + if event.type == ElementType.File: + info = self.connector.getFileData(event.id) for k, package in enumerate(self._data): - if package.id == int(info["package"]): - if package.getChild(fid): - del event[4] + if package.id == info.package: + if package.getChild(info.fid): self.updateEvent(event) break - self.beginInsertRows(self.index(k, 0), info["order"], info["order"]) - package.addChild(fid, info, info["order"]) + self.beginInsertRows(self.index(k, 0), info.order, info.order) + package.addChild(info) self.endInsertRows() break else: - data = self.connector.proxy.get_package_data(event[3]) - package = Package(event[3], data) - self.beginInsertRows(QModelIndex(), data["order"], data["order"]) - self._data.insert(data["order"], package) + data = self.connector.getPackageData(event.id) + package = Package(data) + self.beginInsertRows(QModelIndex(), data.order, data.order) + self._data.insert(data.order, package) self.endInsertRows() def updateEvent(self, event): - if event[2] == "file": - info = self.connector.proxy.get_file_data(int(event[3])) + if event.type == ElementType.File: + info = self.connector.proxy.getFileData(event.id) if not info: return - fid = info.keys()[0] - info = info.values()[0] for p, package in enumerate(self._data): - if package.id == int(info["package"]): + if package.id == info.package: for k, child in enumerate(package.children): - if child.id == int(event[3]): - child.data.update(info) - if not info["status"] == 12: + if child.id == event.id: + child.update(info) + if not info.status == 12: child.data["downloading"] = None self.emit(SIGNAL("dataChanged(const QModelIndex &, const QModelIndex &)"), self.index(k, 0, self.index(p, 0)), self.index(k, self.cols, self.index(p, self.cols))) break else: - data = self.connector.proxy.get_package_data(int(event[3])) + data = self.connector.getPackageData(event.id) if not data: return - pid = event[3] - del data["links"] for p, package in enumerate(self._data): - if package.id == int(pid): - package.data = data + if package.id == event.id: + package.update(data) self.emit(SIGNAL("dataChanged(const QModelIndex &, const QModelIndex &)"), self.index(p, 0), self.index(p, self.cols)) break @@ -265,19 +261,27 @@ class CollectorModel(QAbstractItemModel): return True class Package(object): - def __init__(self, pid, data): - self.id = int(pid) + def __init__(self, pack): + self.id = pack.pid self.children = [] - for fid, fdata in data["links"].items(): - self.addChild(int(fid), fdata) - del data["links"] - self.data = data + for f in pack.links: + self.addChild(f) + self.data = {} + self.update(pack) - def addChild(self, fid, data, pos=None): - if pos is None: - self.children.insert(data["order"], Link(fid, data, self)) - else: - self.children.insert(pos, Link(fid, data, self)) + def update(self, pack): + data = { + "name": pack.name, + "folder": pack.folder, + "site": pack.site, + "password": pack.password, + "order": pack.order, + "priority": pack.priority, + } + self.data.update(data) + + def addChild(self, f): + self.children.insert(f.order, Link(f, self)) self.children = sorted(self.children, key=lambda l: l.data["order"]) def getChild(self, fid): @@ -298,11 +302,27 @@ class Package(object): del self.children[k] class Link(object): - def __init__(self, fid, data, pack): - self.data = data - self.data["downloading"] = None - self.id = int(fid) + def __init__(self, f, pack): + self.data = {"downloading": None} + self.update(f) + self.id = f.fid self.package = pack + + def update(self, f): + data = { + "url": f.url, + "name": f.name, + "plugin": f.plugin, + "size": f.size, + "forrmat_size": f.format_size, + "status": f.status, + "statusmsg": f.statusmsg, + "package": f.package, + "error": f.error, + "order": f.order, + "progress": f.progress + } + self.data.update(data) class CollectorView(QTreeView): def __init__(self, connector): diff --git a/module/gui/ConnectionManager.py b/module/gui/ConnectionManager.py index 92c1540d7..c101a7add 100644 --- a/module/gui/ConnectionManager.py +++ b/module/gui/ConnectionManager.py @@ -61,6 +61,7 @@ class ConnectionManager(QWidget): form.setAlignment(Qt.AlignRight) checkbox = QCheckBox() + checkbox.setDisabled(True) form.addRow(_("Use internal Core:"), checkbox) boxLayout.addLayout(form) diff --git a/module/gui/MainWindow.py b/module/gui/MainWindow.py index b5ec345cb..ff54e8d76 100644 --- a/module/gui/MainWindow.py +++ b/module/gui/MainWindow.py @@ -32,6 +32,8 @@ from module.gui.Overview import OverviewView from module.gui.Accounts import AccountView from module.gui.AccountEdit import AccountEdit +from module.remote.thriftbackend.thriftgen.pyload.ttypes import * + class MainWindow(QMainWindow): def __init__(self, connector): """ @@ -411,7 +413,7 @@ class MainWindow(QMainWindow): for index in smodel.selectedRows(0): item = index.internalPointer() if isinstance(item, Package): - self.connector.proxy.add_files(item.id, links) + self.connector.proxy.addFiles(item.id, links) break def slotShowAddContainer(self): @@ -652,13 +654,17 @@ class MainWindow(QMainWindow): def save(data): if data["password"]: self.accountEdit.close() - self.connector.proxy.update_account(data["acctype"], data["login"], data["password"]) + a = AccountData() + a.type = data["acctype"] + a.login = data["login"] + a.password = data["password"] + self.connector.updateAccounts(a) self.accountEdit.connect(self.accountEdit, SIGNAL("done"), save) self.accountEdit.show() def slotEditAccount(self): - types = self.connector.proxy.get_accounts(False, False).keys() + types = self.connector.getAccountTypes() data = self.tabs["accounts"]["view"].selectedIndexes() if len(data) < 1: @@ -670,7 +676,12 @@ class MainWindow(QMainWindow): def save(data): self.accountEdit.close() - self.connector.proxy.update_account(data["acctype"], data["login"], data["password"] if data["password"] else None) + a = AccountData() + a.type = data["acctype"] + a.login = data["login"] + if data["password"]: + a.password = data["password"] + self.connector.updateAccounts(a) self.accountEdit.connect(self.accountEdit, SIGNAL("done"), save) self.accountEdit.show() @@ -682,7 +693,7 @@ class MainWindow(QMainWindow): data = data[0].internalPointer() - self.connector.proxy.remove_account(data["type"], data["login"]) + self.connector.removeAccount(data["type"], data["login"]) def slotAccountContextMenu(self, pos): globalPos = self.tabs["accounts"]["view"].mapToGlobal(pos) diff --git a/module/gui/Overview.py b/module/gui/Overview.py index 1ac790515..ad63bf9fd 100644 --- a/module/gui/Overview.py +++ b/module/gui/Overview.py @@ -21,6 +21,15 @@ from PyQt4.QtGui import * from time import sleep, time +def formatSpeed(speed): + speed = int(speed) + steps = 0 + sizes = ["B/s", "KiB/s", "MiB/s", "GiB/s"] + while speed > 1000: + speed /= 1024.0 + steps += 1 + return "%i %s" % (speed, sizes[steps]) + class OverviewModel(QAbstractListModel): PackageName = 10 Progress = 11 @@ -76,7 +85,7 @@ class OverviewModel(QAbstractListModel): maxsize, currentsize = maxSize(p) speed = self.queue.getSpeed(p) if speed: - eta = (maxsize - (maxsize * (progress/100.0)))/1024/speed + eta = (maxsize - (maxsize * (progress/100.0)))/speed else: eta = 0 if not speed and not progress: @@ -152,7 +161,7 @@ class OverviewDelegate(QItemDelegate): elif not status == _("Downloading"): speedline = QString(status) else: - speedline = QString(formatEta(eta) + " " + _("Speed: %s kb/s") % speed) + speedline = QString(formatEta(eta) + " " + _("Speed: %s") % formatSpeed(speed)) def formatSize(size): from math import ceil diff --git a/module/gui/Queue.py b/module/gui/Queue.py index d2541f024..5acbf2eb3 100644 --- a/module/gui/Queue.py +++ b/module/gui/Queue.py @@ -19,6 +19,8 @@ from PyQt4.QtCore import * from PyQt4.QtGui import * +from module.remote.thriftbackend.thriftgen.pyload.ttypes import * + from time import sleep, time from module.gui.Collector import CollectorModel, Package, Link, CollectorView, statusMap, statusMapReverse @@ -35,6 +37,15 @@ def formatSize(size): return "%.2f %s" % (size, sizes[steps]) +def formatSpeed(speed): + speed = int(speed) + steps = 0 + sizes = ["B/s", "KiB/s", "MiB/s", "GiB/s"] + while speed > 1000: + speed /= 1024.0 + steps += 1 + return "%i %s" % (speed, sizes[steps]) + class QueueModel(CollectorModel): def __init__(self, view, connector): CollectorModel.__init__(self, view, connector) @@ -66,10 +77,11 @@ class QueueModel(CollectorModel): def fullReload(self): self._data = [] - packs = self.connector.getPackageQueue() - self.beginInsertRows(QModelIndex(), 0, len(packs)) - for pid, data in packs.items(): - package = Package(pid, data) + order = self.connector.getPackageOrder(Destination.Queue) + self.beginInsertRows(QModelIndex(), 0, len(order.values())) + for position, pid in order.iteritems(): + pack = self.connector.getPackageData(pid) + package = Package(pack) self._data.append(package) self._data = sorted(self._data, key=lambda p: p.data["order"]) self.endInsertRows() @@ -94,16 +106,29 @@ class QueueModel(CollectorModel): def update(self): locker = QMutexLocker(self.mutex) - downloading = self.connector.getDownloadQueue() - if downloading is None: + downloading = self.connector.statusDownloads() + if not downloading: return for p, pack in enumerate(self._data): for d in downloading: - child = pack.getChild(d["id"]) + child = pack.getChild(d.id) if child: - child.data["downloading"] = d - #child.data["progress"] = child.data["downloading"]["percent"] - k = pack.getChildKey(d["id"]) + dd = { + "name": d.name, + "speed": d.speed, + "eta": d.eta, + "format_eta": d.format_eta, + "bleft": d.bleft, + "size": d.size, + "format_size": d.format_size, + "percent": d.percent, + "status": d.status, + "statusmsg": d.statusmsg, + "format_wait": d.format_wait, + "wait_until": d.wait_until + } + child.data["downloading"] = dd + k = pack.getChildKey(d.id) self.emit(SIGNAL("dataChanged(const QModelIndex &, const QModelIndex &)"), self.index(k, 0, self.index(p, 0)), self.index(k, self.cols, self.index(p, self.cols))) self.updateCount() @@ -222,7 +247,7 @@ class QueueModel(CollectorModel): if speed is None or status == 7 or status == 10 or status == 5: return QVariant(self.translateStatus(statusMapReverse[status])) else: - return QVariant("%s (%s KiB/s)" % (self.translateStatus(statusMapReverse[status]), speed)) + return QVariant("%s (%s)" % (self.translateStatus(statusMapReverse[status]), formatSpeed(speed))) elif index.column() == 3: item = index.internalPointer() if isinstance(item, Package): diff --git a/module/gui/SettingsWidget.py b/module/gui/SettingsWidget.py index cdb5fba93..7218cc570 100644 --- a/module/gui/SettingsWidget.py +++ b/module/gui/SettingsWidget.py @@ -20,6 +20,8 @@ from PyQt4.QtCore import * from PyQt4.QtGui import * from sip import delete +from module.remote.thriftbackend.thriftgen.pyload.ttypes import * + class SettingsWidget(QWidget): def __init__(self): QWidget.__init__(self) @@ -35,8 +37,8 @@ class SettingsWidget(QWidget): def loadConfig(self): if self.sections and self.psections: - self.data = self.connector.proxy.get_config() - self.pdata = self.connector.proxy.get_plugin_config() + self.data = self.connector.getConfig() + self.pdata = self.connector.getPluginConfig() self.reloadSection(self.sections, self.data) self.reloadSection(self.psections, self.pdata) @@ -75,13 +77,13 @@ class SettingsWidget(QWidget): layout.addWidget(tab) - self.data = self.connector.proxy.get_config() - self.pdata = self.connector.proxy.get_plugin_config() - for k, section in self.data.items(): + self.data = self.connector.getConfig() + self.pdata = self.connector.getPluginConfig() + for k, section in enumerate(self.data): s = Section(section, general) self.sections[k] = s - for k, section in self.pdata.items(): + for k, section in enumerate(self.pdata): s = Section(section, plugins, "plugin") self.psections[k] = s @@ -104,59 +106,59 @@ class SettingsWidget(QWidget): def reloadSection(self, sections, pdata): - for k, section in pdata.iteritems(): + for k, section in enumerate(pdata): if sections.has_key(k): widget = sections[k] - for option,data in section.iteritems(): - if widget.inputs.has_key(option): - i = widget.inputs[option] - - if data["type"] == "int": - i.setValue(int(data["value"])) - elif not data["type"].find(";") == -1: - i.setCurrentIndex(i.findText(data["value"])) - elif data["type"] == "bool": - if data["value"]: + for item in section.items: + if widget.inputs.has_key(item.name): + i = widget.inputs[item.name] + + if item.type == "int": + i.setValue(int(item.value)) + elif not item.type.find(";") == -1: + i.setCurrentIndex(i.findText(item.value)) + elif item.type == "bool": + if (True if item.value.lower() in ("1","true", "on", "an","yes") else False): i.setCurrentIndex(0) else: i.setCurrentIndex(1) else: - i.setText(data["value"]) + i.setText(item.value) def saveConfig(self): - self.data = self.connector.proxy.get_config() - self.pdata = self.connector.proxy.get_plugin_config() + self.data = self.connector.getConfig() + self.pdata = self.connector.getPluginConfig() self.saveSection(self.sections, self.data) self.saveSection(self.psections, self.pdata, "plugin") def saveSection(self, sections, pdata, sec="core"): - for k, section in pdata.iteritems(): + for k, section in enumerate(pdata): if sections.has_key(k): widget = sections[k] - for option,data in section.iteritems(): - if widget.inputs.has_key(option): - i = widget.inputs[option] - - if data["type"] == "int": - if i.value() != data["value"]: - self.connector.proxy.set_conf_val(k, option, i.value(), sec) - elif not data["type"].find(";") == -1: - if i.currentText() != data["value"]: - self.connector.proxy.set_conf_val(k, option, i.currentText(), sec) - elif data["type"] == "bool": - if (data["value"] ^ (not i.currentIndex())): - self.connector.proxy.set_conf_val(k, option, not i.currentIndex(), sec) + for item in section.items: + if widget.inputs.has_key(item.name): + i = widget.inputs[item.name] + + if item.type == "int": + if i.value() != int(item.value): + self.connector.setConfigValue(k, option, i.value(), sec) + elif not item.type.find(";") == -1: + if i.currentText() != item.value: + self.connector.setConfigValue(k, option, i.currentText(), sec) + elif item.type == "bool": + if ((True if item.value.lower() in ("1","true", "on", "an","yes") else False) ^ (not i.currentIndex())): + self.connector.setConfigValue(k, option, not i.currentIndex(), sec) else: - if i.text() != data["value"]: - self.connector.proxy.set_conf_val(k, option, str(i.text()), sec) + if i.text() != item.value: + self.connector.setConfigValue(k, option, str(i.text()), sec) class Section(QGroupBox): def __init__(self, data, parent, ctype="core"): self.data = data - QGroupBox.__init__(self, data["desc"], parent) + QGroupBox.__init__(self, data.description, parent) self.labels = {} self.inputs = {} self.ctype = ctype @@ -172,30 +174,28 @@ class Section(QGroupBox): sa.setWidget(sw) sa.setFrameShape(sa.NoFrame) - parent.addTab(sa, data["desc"]) + parent.addTab(sa, data.description) - for k, option in self.data.iteritems(): - if k == "desc": - continue - if option["type"] == "int": + for option in self.data.items: + if option.type == "int": i = QSpinBox(self) i.setMaximum(999999) - i.setValue(int(option["value"])) - elif not option["type"].find(";") == -1: - choices = option["type"].split(";") + i.setValue(int(option.value)) + elif not option.type.find(";") == -1: + choices = option.type.split(";") i = QComboBox(self) i.addItems(choices) - i.setCurrentIndex(i.findText(option["value"])) - elif option["type"] == "bool": + i.setCurrentIndex(i.findText(option.value)) + elif option.type == "bool": i = QComboBox(self) i.addItem(_("Yes"), QVariant(True)) i.addItem(_("No"), QVariant(False)) - if option["value"]: + if (True if option.value.lower() in ("1","true", "on", "an","yes") else False): i.setCurrentIndex(0) else: i.setCurrentIndex(1) else: i = QLineEdit(self) - i.setText(option["value"]) - layout.addRow(option["desc"], i) + i.setText(option.value) + layout.addRow(option.description, i) layout.setFieldGrowthPolicy(QFormLayout.AllNonFixedFieldsGrow) diff --git a/module/gui/connector.py b/module/gui/connector.py index 907475726..a9cb0610c 100644 --- a/module/gui/connector.py +++ b/module/gui/connector.py @@ -24,269 +24,77 @@ from uuid import uuid4 as uuid from PyQt4.QtCore import * from PyQt4.QtGui import * -from xmlrpclib import ServerProxy import socket -class Connector(QThread): +from module.remote.thriftbackend.thriftgen.pyload import Pyload +from module.remote.thriftbackend.thriftgen.pyload.ttypes import * +from module.remote.thriftbackend.Socket import Socket +from module.remote.thriftbackend.Protocol import Protocol + +from thrift import Thrift +from thrift.transport import TTransport + +class Connector(QObject): def __init__(self): - QThread.__init__(self) + QObject.__init__(self) self.mutex = QMutex() - self.addr = None - self.errorQueue = [] self.connectionID = None + self.host = None + self.port = None + self.user = None + self.password = None + self.ssl = None self.running = True self.proxy = self.Dummy() - def setAddr(self, addr): - """ - set new address - """ - self.mutex.lock() - self.addr = addr - self.mutex.unlock() + def setConnectionData(self, host, port, user, password, ssl=False): + self.host = host + self.port = port + self.user = user + self.password = password + self.ssl = ssl def connectProxy(self): - if isinstance(self.addr, tuple): - while not hasattr(self.addr[1], "server_methods"): - sleep(1) - - self.proxy = self.addr[1].server_methods - else: - self.proxy = DispatchRPC(self.mutex, ServerProxy(self.addr, allow_none=True, verbose=False)) + transport = Socket(self.host, self.port, self.ssl) + transport = TTransport.TBufferedTransport(transport) + protocol = Protocol(transport) + client = Pyload.Client(protocol) - self.connect(self.proxy, SIGNAL("proxy_error"), self._proxyError) - self.connect(self.proxy, SIGNAL("connectionLost"), self, SIGNAL("connectionLost")) + transport.open() - try: - server_version = self.proxy.get_server_version() - self.connectionID = uuid().hex - except: + if not client.login(self.user, self.password): + self.emit(SIGNAL("error_box"), "bad login credentials") return False - if not server_version: - return False - elif not server_version == SERVER_VERSION: + + self.proxy = DispatchRPC(self.mutex, client) + self.connect(self.proxy, SIGNAL("proxy_error"), self._proxyError) + self.connect(self.proxy, SIGNAL("connectionLost"), self, SIGNAL("connectionLost")) + + server_version = self.proxy.getServerVersion() + self.connectionID = uuid().hex + + if not server_version == SERVER_VERSION: self.emit(SIGNAL("error_box"), "server is version %s client accepts version %s" % (server_version, SERVER_VERSION)) return False + return True - def canConnect(self): - return self.connectProxy() - def _proxyError(self, func, e): """ formats proxy error msg """ msg = "proxy error in '%s':\n%s" % (func, e) - self.errorQueue.append(msg) + print msg + self.emit(SIGNAL("error_box"), msg) - def getError(self): - self.mutex.lock() - if len(self.errorQueue) > 0: - err = self.errorQueue.pop() - print err - self.emit(SIGNAL("error_box"), err) - self.mutex.unlock() - - def stop(self): - """ - stop thread - """ - self.running = False - - def run(self): - """ - start thread - (called from thread.start()) - """ - self.canConnect() - while self.running: - sleep(1) - self.getError() + def __getattr__(self, attr): + return getattr(self.proxy, attr) class Dummy(object): def __getattr__(self, attr): def dummy(*args, **kwargs): return None return dummy - - def getPackageCollector(self): - """ - grab packages from collector and return the data - """ - return self.proxy.get_collector() - - def getLinkInfo(self, id): - """ - grab file info for the given id and return it - """ - w = self.proxy.get_file_data - w.error = False - info = w(id) - if not info: return None - info["downloading"] = None - return info - - def getPackageInfo(self, id): - """ - grab package info for the given id and return it - """ - w = self.proxy.get_package_data - w.error = False - return w(id) - - def getPackageQueue(self): - """ - grab queue return the data - """ - return self.proxy.get_queue() - - def getPackageFiles(self, id): - """ - grab package files and return ids - """ - return self.proxy.get_package_files(id) - - def getDownloadQueue(self): - """ - grab files that are currently downloading and return info - """ - return self.proxy.status_downloads() - - def getServerStatus(self): - """ - return server status - """ - return self.proxy.status_server() - - def addURLs(self, links): - """ - add links to collector - """ - self.proxy.add_urls(links) - - def togglePause(self): - """ - toogle pause - """ - return self.proxy.toggle_pause() - - def setPause(self, pause): - """ - set pause - """ - if pause: - self.proxy.pause_server() - else: - self.proxy.unpause_server() - - def newPackage(self, name): - """ - create a new package and return id - """ - return self.proxy.new_package(name) - - def addFileToPackage(self, fileid, packid): - """ - add a file from collector to package - """ - self.proxy.move_file_2_package(fileid, packid) - - def pushPackageToQueue(self, packid): - """ - push a package to queue - """ - self.proxy.push_package_2_queue(packid) - - def restartPackage(self, packid): - """ - restart a package - """ - self.proxy.restart_package(packid) - - def restartFile(self, fileid): - """ - restart a file - """ - self.proxy.restart_file(fileid) - - def removePackage(self, packid): - """ - remove a package - """ - self.proxy.del_packages([packid,]) - - def removeFile(self, fileid): - """ - remove a file - """ - self.proxy.del_links([fileid,]) - - def uploadContainer(self, filename, type, content): - """ - upload a container - """ - self.proxy.upload_container(filename, type, content) - - def getLog(self, offset): - """ - get log - """ - return self.proxy.get_log(offset) - - def stopAllDownloads(self): - """ - get log - """ - self.proxy.pause_server() - self.proxy.stop_downloads() - - def updateAvailable(self): - """ - update available - """ - return self.proxy.update_available() - - def setPackageName(self, pid, name): - """ - set new package name - """ - return self.proxy.set_package_name(pid, name) - - def pullOutPackage(self, pid): - """ - pull out package - """ - return self.proxy.pull_out_package(pid) - - def captchaWaiting(self): - """ - is the a captcha waiting? - """ - return self.proxy.is_captcha_waiting() - - def getCaptcha(self): - """ - get captcha - """ - return self.proxy.get_captcha_task() - - def setCaptchaResult(self, cid, result): - """ - get captcha - """ - return self.proxy.set_captcha_result(cid, result) - - def getCaptchaStatus(self, cid): - """ - get captcha status - """ - return self.proxy.get_task_status(cid) - - def getEvents(self): - """ - get events - """ - return self.proxy.get_events(self.connectionID) class DispatchRPC(QObject): def __init__(self, mutex, server): diff --git a/module/remote/thriftbackend/Handler.py b/module/remote/thriftbackend/Handler.py index da77b8ed2..6eb2a8bc6 100644 --- a/module/remote/thriftbackend/Handler.py +++ b/module/remote/thriftbackend/Handler.py @@ -15,7 +15,7 @@ class Handler(Iface): 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["package"], p["error"], p["order"], p["progress"]) return f def _convertConfigFormat(self, c): @@ -23,14 +23,14 @@ class Handler(Iface): for sectionName, sub in c.iteritems(): section = ConfigSection() section.name = sectionName - section.decription = sub["desc"] + section.description = sub["desc"] items = [] for key, data in sub.iteritems(): if key == "desc": continue item = ConfigItem() item.name = key - item.decription = data["desc"] + item.description = data["desc"] item.value = str(data["value"]) item.type = data["type"] items.append(item) @@ -82,13 +82,15 @@ class Handler(Iface): serverStatus.active = status["activ"] serverStatus.queue = status["queue"] serverStatus.total = status["total"] - serverStatus.speed = status["speed"] + 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 self.serverMethods.free_space() + return self.core.freeSpace() #bytes def getServerVersion(self): return self.serverMethods.get_server_version() @@ -104,7 +106,8 @@ class Handler(Iface): Parameters: - offset """ - return list(self.serverMethods.restart(offset)) + log = self.serverMethods.get_log(offset) + return log or [] def checkURL(self, urls): """ @@ -135,7 +138,7 @@ class Handler(Iface): status = DownloadInfo() status.id = pyfile.id status.name = pyfile.name - status.speed = pyfile.getSpeed() / 1024 + status.speed = pyfile.getSpeed() #bytes status.eta = pyfile.getETA() status.format_eta = pyfile.formatETA() status.kbleft = pyfile.getBytesLeft() #holded for backward comp. @@ -187,9 +190,8 @@ class Handler(Iface): Parameters: - fid """ - rawData = self.serverMethods.get_file_data(fid) + rawData = self.serverMethods.get_file_data(fid).values()[0] fdata = self._convertPyFile(rawData) - fdata.progress = rawData["progress"] return fdata def deleteFiles(self, fids): @@ -369,6 +371,8 @@ class Handler(Iface): packs = self.serverMethods.get_collector() for pid in packs: pack = self.serverMethods.get_package_data(pid) + while pack["order"] in order.keys(): + pack["order"] += 1 order[pack["order"]] = pack["id"] return order @@ -412,26 +416,35 @@ class Handler(Iface): self.serverMethods.set_captcha_result(tid, result) #events - def getEvents(self): - events = self.serverMethods.get_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 = e[1] + 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 = e[3] + event.destination = convDest(e[3]) + elif e[0] == "reload": + event.destination = convDest(e[1]) newEvents.append(event) return newEvents #accounts - def getAccounts(self): - accs = self.serverMethods.get_accounts() + def getAccounts(self, refresh): + """ + Parameters: + - refresh + """ + accs = self.serverMethods.get_accounts(False, refresh) accounts = [] for group in accs.values(): for acc in group: @@ -446,6 +459,9 @@ class Handler(Iface): account.type = acc["type"] accounts.append(account) return accounts + + def getAccountTypes(self): + return self.serverMethods.get_accounts().keys() def updateAccounts(self, data): """ diff --git a/module/remote/thriftbackend/pyload.thrift b/module/remote/thriftbackend/pyload.thrift index aaa843808..3cbd62d7a 100644 --- a/module/remote/thriftbackend/pyload.thrift +++ b/module/remote/thriftbackend/pyload.thrift @@ -36,19 +36,18 @@ enum ElementType { struct DownloadInfo { 1: FileID id, 2: string name, - 3: i32 speed, + 3: i64 speed, 4: i32 eta, 5: string format_eta, - 6: i64 kbleft, - 7: i64 bleft, - 8: i64 size, - 9: string format_size, - 10: Progress percent, - 11: DownloadStatus status, - 12: string statusmsg, - 13: string format_wait, - 14: i64 wait_until, - 15: PackageID packageID, + 6: i64 bleft, + 7: i64 size, + 8: string format_size, + 9: Progress percent, + 10: DownloadStatus status, + 11: string statusmsg, + 12: string format_wait, + 13: i64 wait_until, + 14: PackageID packageID, } struct ServerStatus { @@ -86,7 +85,7 @@ struct FileData { 9: PackageID package, 10: string error, 11: i16 order, - 12: optional Progress progress + 12: Progress progress } struct PackageData { @@ -207,10 +206,11 @@ service Pyload { void setCaptchaResult(1: TaskID tid, 2: string result), //events - list<Event> getEvents() + list<Event> getEvents(1: string uuid) //accounts - list<AccountInfo> getAccounts(), + list<AccountInfo> getAccounts(1: bool refresh), + list<string> getAccountTypes() void updateAccounts(1: AccountData data), void removeAccount(1: string plugin, 2: string account) diff --git a/module/remote/thriftbackend/thriftgen/pyload/Pyload-remote b/module/remote/thriftbackend/thriftgen/pyload/Pyload-remote index bf52facff..f8e047e49 100755 --- a/module/remote/thriftbackend/thriftgen/pyload/Pyload-remote +++ b/module/remote/thriftbackend/thriftgen/pyload/Pyload-remote @@ -68,8 +68,9 @@ if len(sys.argv) <= 1 or sys.argv[1] == '--help': print ' CaptchaTask getCaptchaTask(bool exclusive)' print ' string getCaptchaTaskStatus(TaskID tid)' print ' void setCaptchaResult(TaskID tid, string result)' - print ' getEvents()' - print ' getAccounts()' + print ' getEvents(string uuid)' + print ' getAccounts(bool refresh)' + print ' getAccountTypes()' print ' void updateAccounts(AccountData data)' print ' void removeAccount(string plugin, string account)' print ' bool login(string username, string password)' @@ -407,16 +408,22 @@ elif cmd == 'setCaptchaResult': pp.pprint(client.setCaptchaResult(eval(args[0]),args[1],)) elif cmd == 'getEvents': - if len(args) != 0: - print 'getEvents requires 0 args' + if len(args) != 1: + print 'getEvents requires 1 args' sys.exit(1) - pp.pprint(client.getEvents()) + pp.pprint(client.getEvents(args[0],)) elif cmd == 'getAccounts': + if len(args) != 1: + print 'getAccounts requires 1 args' + sys.exit(1) + pp.pprint(client.getAccounts(eval(args[0]),)) + +elif cmd == 'getAccountTypes': if len(args) != 0: - print 'getAccounts requires 0 args' + print 'getAccountTypes requires 0 args' sys.exit(1) - pp.pprint(client.getAccounts()) + pp.pprint(client.getAccountTypes()) elif cmd == 'updateAccounts': if len(args) != 1: diff --git a/module/remote/thriftbackend/thriftgen/pyload/Pyload.py b/module/remote/thriftbackend/thriftgen/pyload/Pyload.py index 51d76d46c..19e972559 100644 --- a/module/remote/thriftbackend/thriftgen/pyload/Pyload.py +++ b/module/remote/thriftbackend/thriftgen/pyload/Pyload.py @@ -285,10 +285,21 @@ class Iface: """ pass - def getEvents(self, ): + def getEvents(self, uuid): + """ + Parameters: + - uuid + """ + pass + + def getAccounts(self, refresh): + """ + Parameters: + - refresh + """ pass - def getAccounts(self, ): + def getAccountTypes(self, ): pass def updateAccounts(self, data): @@ -1622,13 +1633,18 @@ class Client(Iface): self._iprot.readMessageEnd() return - def getEvents(self, ): - self.send_getEvents() + def getEvents(self, uuid): + """ + Parameters: + - uuid + """ + self.send_getEvents(uuid) return self.recv_getEvents() - def send_getEvents(self, ): + def send_getEvents(self, uuid): self._oprot.writeMessageBegin('getEvents', TMessageType.CALL, self._seqid) args = getEvents_args() + args.uuid = uuid args.write(self._oprot) self._oprot.writeMessageEnd() self._oprot.trans.flush() @@ -1647,13 +1663,18 @@ class Client(Iface): return result.success raise TApplicationException(TApplicationException.MISSING_RESULT, "getEvents failed: unknown result"); - def getAccounts(self, ): - self.send_getAccounts() + def getAccounts(self, refresh): + """ + Parameters: + - refresh + """ + self.send_getAccounts(refresh) return self.recv_getAccounts() - def send_getAccounts(self, ): + def send_getAccounts(self, refresh): self._oprot.writeMessageBegin('getAccounts', TMessageType.CALL, self._seqid) args = getAccounts_args() + args.refresh = refresh args.write(self._oprot) self._oprot.writeMessageEnd() self._oprot.trans.flush() @@ -1672,6 +1693,31 @@ class Client(Iface): return result.success raise TApplicationException(TApplicationException.MISSING_RESULT, "getAccounts failed: unknown result"); + def getAccountTypes(self, ): + self.send_getAccountTypes() + return self.recv_getAccountTypes() + + def send_getAccountTypes(self, ): + self._oprot.writeMessageBegin('getAccountTypes', TMessageType.CALL, self._seqid) + args = getAccountTypes_args() + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_getAccountTypes(self, ): + (fname, mtype, rseqid) = self._iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(self._iprot) + self._iprot.readMessageEnd() + raise x + result = getAccountTypes_result() + result.read(self._iprot) + self._iprot.readMessageEnd() + if result.success != None: + return result.success + raise TApplicationException(TApplicationException.MISSING_RESULT, "getAccountTypes failed: unknown result"); + def updateAccounts(self, data): """ Parameters: @@ -1841,6 +1887,7 @@ class Processor(Iface, TProcessor): self._processMap["setCaptchaResult"] = Processor.process_setCaptchaResult 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["removeAccount"] = Processor.process_removeAccount self._processMap["login"] = Processor.process_login @@ -2383,7 +2430,7 @@ class Processor(Iface, TProcessor): args.read(iprot) iprot.readMessageEnd() result = getEvents_result() - result.success = self._handler.getEvents() + result.success = self._handler.getEvents(args.uuid) oprot.writeMessageBegin("getEvents", TMessageType.REPLY, seqid) result.write(oprot) oprot.writeMessageEnd() @@ -2394,12 +2441,23 @@ class Processor(Iface, TProcessor): args.read(iprot) iprot.readMessageEnd() result = getAccounts_result() - result.success = self._handler.getAccounts() + result.success = self._handler.getAccounts(args.refresh) oprot.writeMessageBegin("getAccounts", TMessageType.REPLY, seqid) result.write(oprot) oprot.writeMessageEnd() oprot.trans.flush() + def process_getAccountTypes(self, seqid, iprot, oprot): + args = getAccountTypes_args() + args.read(iprot) + iprot.readMessageEnd() + result = getAccountTypes_result() + result.success = self._handler.getAccountTypes() + oprot.writeMessageBegin("getAccountTypes", TMessageType.REPLY, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + def process_updateAccounts(self, seqid, iprot, oprot): args = updateAccounts_args() args.read(iprot) @@ -7517,10 +7575,19 @@ class setCaptchaResult_result: return not (self == other) class getEvents_args: + """ + Attributes: + - uuid + """ thrift_spec = ( + None, # 0 + (1, TType.STRING, 'uuid', None, None, ), # 1 ) + def __init__(self, uuid=None,): + self.uuid = uuid + def read(self, iprot): if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None: fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec)) @@ -7530,6 +7597,11 @@ class getEvents_args: (fname, ftype, fid) = iprot.readFieldBegin() if ftype == TType.STOP: break + if fid == 1: + if ftype == TType.STRING: + self.uuid = iprot.readString(); + else: + iprot.skip(ftype) else: iprot.skip(ftype) iprot.readFieldEnd() @@ -7540,6 +7612,10 @@ class getEvents_args: oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec))) return oprot.writeStructBegin('getEvents_args') + if self.uuid != None: + oprot.writeFieldBegin('uuid', TType.STRING, 1) + oprot.writeString(self.uuid) + oprot.writeFieldEnd() oprot.writeFieldStop() oprot.writeStructEnd() def validate(self): @@ -7625,10 +7701,19 @@ class getEvents_result: return not (self == other) class getAccounts_args: + """ + Attributes: + - refresh + """ thrift_spec = ( + None, # 0 + (1, TType.BOOL, 'refresh', None, None, ), # 1 ) + def __init__(self, refresh=None,): + self.refresh = refresh + def read(self, iprot): if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None: fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec)) @@ -7638,6 +7723,11 @@ class getAccounts_args: (fname, ftype, fid) = iprot.readFieldBegin() if ftype == TType.STOP: break + if fid == 1: + if ftype == TType.BOOL: + self.refresh = iprot.readBool(); + else: + iprot.skip(ftype) else: iprot.skip(ftype) iprot.readFieldEnd() @@ -7648,6 +7738,10 @@ class getAccounts_args: oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec))) return oprot.writeStructBegin('getAccounts_args') + if self.refresh != None: + oprot.writeFieldBegin('refresh', TType.BOOL, 1) + oprot.writeBool(self.refresh) + oprot.writeFieldEnd() oprot.writeFieldStop() oprot.writeStructEnd() def validate(self): @@ -7732,6 +7826,113 @@ class getAccounts_result: def __ne__(self, other): return not (self == other) +class getAccountTypes_args: + + thrift_spec = ( + ) + + def read(self, iprot): + if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None: + fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None: + oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('getAccountTypes_args') + oprot.writeFieldStop() + oprot.writeStructEnd() + def validate(self): + return + + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.iteritems()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + +class getAccountTypes_result: + """ + Attributes: + - success + """ + + thrift_spec = ( + (0, TType.LIST, 'success', (TType.STRING,None), None, ), # 0 + ) + + def __init__(self, success=None,): + self.success = success + + def read(self, iprot): + if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None: + fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.LIST: + self.success = [] + (_etype176, _size173) = iprot.readListBegin() + for _i177 in xrange(_size173): + _elem178 = iprot.readString(); + self.success.append(_elem178) + iprot.readListEnd() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None: + oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('getAccountTypes_result') + if self.success != None: + oprot.writeFieldBegin('success', TType.LIST, 0) + oprot.writeListBegin(TType.STRING, len(self.success)) + for iter179 in self.success: + oprot.writeString(iter179) + oprot.writeListEnd() + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + def validate(self): + return + + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.iteritems()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + class updateAccounts_args: """ Attributes: diff --git a/module/remote/thriftbackend/thriftgen/pyload/ttypes.py b/module/remote/thriftbackend/thriftgen/pyload/ttypes.py index 2b51e1467..10964d127 100644 --- a/module/remote/thriftbackend/thriftgen/pyload/ttypes.py +++ b/module/remote/thriftbackend/thriftgen/pyload/ttypes.py @@ -104,7 +104,6 @@ class DownloadInfo: - speed - eta - format_eta - - kbleft - bleft - size - format_size @@ -120,28 +119,26 @@ class DownloadInfo: None, # 0 (1, TType.I32, 'id', None, None, ), # 1 (2, TType.STRING, 'name', None, None, ), # 2 - (3, TType.I32, 'speed', None, None, ), # 3 + (3, TType.I64, 'speed', None, None, ), # 3 (4, TType.I32, 'eta', None, None, ), # 4 (5, TType.STRING, 'format_eta', None, None, ), # 5 - (6, TType.I64, 'kbleft', None, None, ), # 6 - (7, TType.I64, 'bleft', None, None, ), # 7 - (8, TType.I64, 'size', None, None, ), # 8 - (9, TType.STRING, 'format_size', None, None, ), # 9 - (10, TType.BYTE, 'percent', None, None, ), # 10 - (11, TType.I32, 'status', None, None, ), # 11 - (12, TType.STRING, 'statusmsg', None, None, ), # 12 - (13, TType.STRING, 'format_wait', None, None, ), # 13 - (14, TType.I64, 'wait_until', None, None, ), # 14 - (15, TType.I32, 'packageID', None, None, ), # 15 + (6, TType.I64, 'bleft', None, None, ), # 6 + (7, TType.I64, 'size', None, None, ), # 7 + (8, TType.STRING, 'format_size', None, None, ), # 8 + (9, TType.BYTE, 'percent', None, None, ), # 9 + (10, TType.I32, 'status', None, None, ), # 10 + (11, TType.STRING, 'statusmsg', None, None, ), # 11 + (12, TType.STRING, 'format_wait', None, None, ), # 12 + (13, TType.I64, 'wait_until', None, None, ), # 13 + (14, TType.I32, 'packageID', None, None, ), # 14 ) - def __init__(self, id=None, name=None, speed=None, eta=None, format_eta=None, kbleft=None, bleft=None, size=None, format_size=None, percent=None, status=None, statusmsg=None, format_wait=None, wait_until=None, packageID=None,): + def __init__(self, id=None, name=None, speed=None, eta=None, format_eta=None, bleft=None, size=None, format_size=None, percent=None, status=None, statusmsg=None, format_wait=None, wait_until=None, packageID=None,): self.id = id self.name = name self.speed = speed self.eta = eta self.format_eta = format_eta - self.kbleft = kbleft self.bleft = bleft self.size = size self.format_size = format_size @@ -172,8 +169,8 @@ class DownloadInfo: else: iprot.skip(ftype) elif fid == 3: - if ftype == TType.I32: - self.speed = iprot.readI32(); + if ftype == TType.I64: + self.speed = iprot.readI64(); else: iprot.skip(ftype) elif fid == 4: @@ -188,50 +185,45 @@ class DownloadInfo: iprot.skip(ftype) elif fid == 6: if ftype == TType.I64: - self.kbleft = iprot.readI64(); - else: - iprot.skip(ftype) - elif fid == 7: - if ftype == TType.I64: self.bleft = iprot.readI64(); else: iprot.skip(ftype) - elif fid == 8: + elif fid == 7: if ftype == TType.I64: self.size = iprot.readI64(); else: iprot.skip(ftype) - elif fid == 9: + elif fid == 8: if ftype == TType.STRING: self.format_size = iprot.readString(); else: iprot.skip(ftype) - elif fid == 10: + elif fid == 9: if ftype == TType.BYTE: self.percent = iprot.readByte(); else: iprot.skip(ftype) - elif fid == 11: + elif fid == 10: if ftype == TType.I32: self.status = iprot.readI32(); else: iprot.skip(ftype) - elif fid == 12: + elif fid == 11: if ftype == TType.STRING: self.statusmsg = iprot.readString(); else: iprot.skip(ftype) - elif fid == 13: + elif fid == 12: if ftype == TType.STRING: self.format_wait = iprot.readString(); else: iprot.skip(ftype) - elif fid == 14: + elif fid == 13: if ftype == TType.I64: self.wait_until = iprot.readI64(); else: iprot.skip(ftype) - elif fid == 15: + elif fid == 14: if ftype == TType.I32: self.packageID = iprot.readI32(); else: @@ -255,8 +247,8 @@ class DownloadInfo: oprot.writeString(self.name) oprot.writeFieldEnd() if self.speed != None: - oprot.writeFieldBegin('speed', TType.I32, 3) - oprot.writeI32(self.speed) + oprot.writeFieldBegin('speed', TType.I64, 3) + oprot.writeI64(self.speed) oprot.writeFieldEnd() if self.eta != None: oprot.writeFieldBegin('eta', TType.I32, 4) @@ -266,44 +258,40 @@ class DownloadInfo: oprot.writeFieldBegin('format_eta', TType.STRING, 5) oprot.writeString(self.format_eta) oprot.writeFieldEnd() - if self.kbleft != None: - oprot.writeFieldBegin('kbleft', TType.I64, 6) - oprot.writeI64(self.kbleft) - oprot.writeFieldEnd() if self.bleft != None: - oprot.writeFieldBegin('bleft', TType.I64, 7) + oprot.writeFieldBegin('bleft', TType.I64, 6) oprot.writeI64(self.bleft) oprot.writeFieldEnd() if self.size != None: - oprot.writeFieldBegin('size', TType.I64, 8) + oprot.writeFieldBegin('size', TType.I64, 7) oprot.writeI64(self.size) oprot.writeFieldEnd() if self.format_size != None: - oprot.writeFieldBegin('format_size', TType.STRING, 9) + oprot.writeFieldBegin('format_size', TType.STRING, 8) oprot.writeString(self.format_size) oprot.writeFieldEnd() if self.percent != None: - oprot.writeFieldBegin('percent', TType.BYTE, 10) + oprot.writeFieldBegin('percent', TType.BYTE, 9) oprot.writeByte(self.percent) oprot.writeFieldEnd() if self.status != None: - oprot.writeFieldBegin('status', TType.I32, 11) + oprot.writeFieldBegin('status', TType.I32, 10) oprot.writeI32(self.status) oprot.writeFieldEnd() if self.statusmsg != None: - oprot.writeFieldBegin('statusmsg', TType.STRING, 12) + oprot.writeFieldBegin('statusmsg', TType.STRING, 11) oprot.writeString(self.statusmsg) oprot.writeFieldEnd() if self.format_wait != None: - oprot.writeFieldBegin('format_wait', TType.STRING, 13) + oprot.writeFieldBegin('format_wait', TType.STRING, 12) oprot.writeString(self.format_wait) oprot.writeFieldEnd() if self.wait_until != None: - oprot.writeFieldBegin('wait_until', TType.I64, 14) + oprot.writeFieldBegin('wait_until', TType.I64, 13) oprot.writeI64(self.wait_until) oprot.writeFieldEnd() if self.packageID != None: - oprot.writeFieldBegin('packageID', TType.I32, 15) + oprot.writeFieldBegin('packageID', TType.I32, 14) oprot.writeI32(self.packageID) oprot.writeFieldEnd() oprot.writeFieldStop() diff --git a/pyLoadCore.py b/pyLoadCore.py index 48568edf6..fd48748ba 100755 --- a/pyLoadCore.py +++ b/pyLoadCore.py @@ -347,10 +347,16 @@ class Core(object): #linkFile = self.config['general']['link_file'] freeSpace = self.freeSpace() - if freeSpace > 5 * 1024: - self.log.info(_("Free space: %sGB") % (freeSpace / 1024)) - else: - self.log.info(_("Free space: %sMB") % freeSpace) + def formatSize(size): + """formats size of bytes""" + size = int(size) + steps = 0 + sizes = ["B", "KiB", "MiB", "GiB", "TiB"] + while size > 1000: + size /= 1024.0 + steps += 1 + return "%.2f %s" % (size, sizes[steps]) + self.log.info(_("Free space: %s") % formatSize(freeSpace)) self.threadManager.pause = False #self.threadManager.start() @@ -533,12 +539,12 @@ class Core(object): free_bytes = ctypes.c_ulonglong(0) ctypes.windll.kernel32.GetDiskFreeSpaceExW(ctypes.c_wchar_p(folder), None, None, ctypes.pointer(free_bytes)) - return free_bytes.value / 1024 / 1024 #megabyte + return free_bytes.value else: from os import statvfs s = statvfs(folder) - return s.f_bsize * s.f_bavail / 1024 / 1024 #megabyte + return s.f_bsize * s.f_bavail #################################### @@ -643,7 +649,7 @@ class ServerMethods(): return status def free_space(self): - return self.core.freeSpace() + return self.core.freeSpace() / 1024 / 1024 #mb def get_server_version(self): return CURRENT_VERSION diff --git a/pyLoadGui.py b/pyLoadGui.py index f730ec145..e1a680df5 100755 --- a/pyLoadGui.py +++ b/pyLoadGui.py @@ -28,7 +28,6 @@ from PyQt4.QtGui import * import re import gettext -from xmlrpclib import Binary from os.path import abspath from os.path import join from os.path import basename @@ -36,7 +35,7 @@ from os.path import commonprefix from module import InitHomeDir from module.gui.ConnectionManager import * -from module.gui.connector import Connector +from module.gui.Connector import Connector from module.gui.MainWindow import * from module.gui.Queue import * from module.gui.Overview import * @@ -44,6 +43,8 @@ from module.gui.Collector import * from module.gui.XMLParser import * from module.gui.CoreConfigParser import ConfigParser +from module.remote.thriftbackend.thriftgen.pyload.ttypes import * + try: import pynotify except ImportError: @@ -109,7 +110,7 @@ class main(QObject): default = self.refreshConnections() self.connData = None self.captchaProcessing = False - self.serverStatus = {"pause":True, "speed":0, "freespace":0} + self.serverStatus = {"freespace":0} self.core = None # pyLoadCore if started self.connectionLost = False @@ -134,12 +135,9 @@ class main(QObject): """ start all refresh threads and show main window """ - if not self.connector.canConnect(): + if not self.connector.connectProxy(): self.init() - return - self.connector.start() self.connect(self.connector, SIGNAL("connectionLost"), self.slotConnectionLost) - sleep(1) self.restoreMainWindow() self.mainWindow.show() self.initQueue() @@ -161,11 +159,9 @@ class main(QObject): self.disconnect(self.clipboard, SIGNAL('dataChanged()'), self.slotClipboardChange) self.disconnect(self.connector, SIGNAL("connectionLost"), self.slotConnectionLost) self.mainloop.stop() - self.connector.stop() self.mainWindow.saveWindow() self.mainWindow.hide() self.queue.stop() - self.connector.wait() def connectSignals(self): """ @@ -223,7 +219,7 @@ class main(QObject): display a nice error box """ msgb = QMessageBox(QMessageBox.Warning, "Error", msg) - msgb.exec_() + #msgb.show() def initPackageCollector(self): """ @@ -303,17 +299,14 @@ class main(QObject): """ refresh server status and overall speed in the status bar """ - s = self.connector.getServerStatus() - if s is None: - return - self.serverStatus.update(s) - if self.serverStatus["pause"]: + s = self.connector.statusServer() + if s.pause: self.mainWindow.status.setText(_("paused")) else: self.mainWindow.status.setText(_("running")) - self.mainWindow.speed.setText(formatSpeed(self.serverStatus["speed"]*1024)) - self.mainWindow.space.setText(formatSize(self.serverStatus["freespace"]*1024*1024)) - self.mainWindow.actions["toggle_status"].setChecked(not self.serverStatus["pause"]) + self.mainWindow.speed.setText(formatSpeed(s.speed)) + self.mainWindow.space.setText(formatSize(self.serverStatus["freespace"])) + self.mainWindow.actions["toggle_status"].setChecked(not s.pause) def refreshLog(self): """ @@ -438,26 +431,16 @@ class main(QObject): coreparser = ConfigParser(self.configdir) if not coreparser.config: - data["port"] = 7227 - data["user"] = "anonymous" - data["password"] = "anonymous" - data["host"] = "127.0.0.1" - data["ssl"] = False + self.connector.setConnectionData("127.0.0.1", 7228, "anonymous", "anonymous", False) else: - data["port"] = coreparser.get("remote","port") - data["user"] = "anonymous" - data["password"] = "anonymous" - data["host"] = "127.0.0.1" - data["ssl"] = coreparser.get("ssl","activated") - - data["ssl"] = "s" if data["ssl"] else "" - server_url = "http%(ssl)s://%(user)s:%(password)s@%(host)s:%(port)s/" % data - self.connector.setAddr(str(server_url)) + #coreparser.get("remote","port") + self.connector.setConnectionData("127.0.0.1", 7228, "anonymous", "anonymous", coreparser.get("ssl","activated")) elif data["type"] == "remote": - data["ssl"] = "s" if data["ssl"] else "" - server_url = "http%(ssl)s://%(user)s:%(password)s@%(host)s:%(port)s/" % data - self.connector.setAddr(str(server_url)) + if data["port"] == 7227: + print "xmlrpc port selected, autocorrecting" + data["port"] = 7228 + self.connector.setConnectionData(data["host"], data["port"], data["user"], data["password"], data["ssl"]) elif data["type"] == "internal": from pyLoadCore import Core @@ -469,7 +452,7 @@ class main(QObject): config = CoreConfig() #create so at least default config exists self.core = Core() thread.start_new_thread(self.core.start, (False,False)) - self.connector.setAddr(("core", self.core)) + self.connector.setConnectionData("127.0.0.1", 7228, "anonymous", "anonymous", config.get("ssl","activated")) self.startMain() self.notification.showMessage(_("connected to %s") % data["host"]) @@ -490,23 +473,27 @@ class main(QObject): """ toolbar start/pause slot """ - self.connector.setPause(not status) + if status: + self.connector.unpauseServer() + else: + self.connector.pauseServer() def slotAddPackage(self, name, links, password=None): """ emitted from main window add package to the collector """ - pack = self.connector.proxy.add_package(name, links) + pack = self.connector.addPackage(name, links) if password: data = {"password": password} - self.connector.proxy.set_package_data(pack, data) + self.connector.setPackageData(pack, data) - def slotAddFileToPackage(self, pid, fid): + def slotAddFileToPackage(self, pid, fid): #deprecated? """ emitted from collector view after a drop action """ - self.connector.addFileToPackage(fid, pid) + #self.connector.addFileToPackage(fid, pid) + pass def slotAddContainer(self, path): """ @@ -518,7 +505,7 @@ class main(QObject): fh = open(path, "r") content = fh.read() fh.close() - self.connector.proxy.upload_container(filename, Binary(content)) + self.connector.uploadContainer(filename, content) def slotSaveMainWindow(self, state, geo): """ @@ -560,7 +547,7 @@ class main(QObject): emitted from main window push the collector package to queue """ - self.connector.proxy.push_package_to_queue(id) + self.connector.pushToQueue(id) def slotRestartDownload(self, id, isPack): """ @@ -577,7 +564,7 @@ class main(QObject): emitted from main window refresh download status """ - self.connector.proxy.recheck_package(id) + self.connector.recheckPackage(id) def slotRemoveDownload(self, id, isPack): """ @@ -585,9 +572,9 @@ class main(QObject): remove download """ if isPack: - self.connector.removePackage(id) + self.connector.deletePackages([id]) else: - self.connector.removeFile(id) + self.connector.deleteFiles([id]) def slotAbortDownload(self, id, isPack): """ @@ -595,10 +582,10 @@ class main(QObject): remove download """ if isPack: - data = self.connector.proxy.get_package_data(id) - self.connector.proxy.abort_files(data["links"].keys()) + data = self.connector.getFileOrder(id) #less data to transmit + self.connector.stopDownloads(data.values()) else: - self.connector.proxy.abort_files([id]) + self.connector.stopDownloads([id]) def slotStopAllDownloads(self): """ @@ -645,57 +632,55 @@ class main(QObject): """ pull package out of the queue """ - self.connector.proxy.pull_out_package(pid) + self.connector.pullFromQueue(pid) def slotSetPriority(self, pid, level): """ set package priority """ - self.connector.proxy.set_priority(pid, level) + self.connector.setPriority(pid, level) def checkCaptcha(self): - if self.connector.captchaWaiting() and self.mainWindow.captchaDock.isFree(): - cid, img, imgType = self.connector.getCaptcha() + if self.connector.isCaptchaWaiting() and self.mainWindow.captchaDock.isFree(): + t = self.connector.getCaptchaTask() self.mainWindow.show() self.mainWindow.raise_() self.mainWindow.activateWindow() - self.mainWindow.captchaDock.emit(SIGNAL("setTask"), cid, str(img), imgType) + self.mainWindow.captchaDock.emit(SIGNAL("setTask"), t.tid, t.data, t.type) elif not self.mainWindow.captchaDock.isFree(): - status = self.connector.getCaptchaStatus(self.mainWindow.captchaDock.currentID) + status = self.connector.getCaptchaTaskStatus(self.mainWindow.captchaDock.currentID) if not (status == "user" or status == "shared-user"): self.mainWindow.captchaDock.hide() self.mainWindow.captchaDock.processing = False self.mainWindow.captchaDock.currentID = None def slotCaptchaDone(self, cid, result): - self.connector.setCaptchaResult(str(cid), str(result)) + self.connector.setCaptchaResult(cid, str(result)) def pullEvents(self): - events = self.connector.getEvents() - if events is None: + events = self.connector.getEvents(self.connector.connectionID) + if not events: return for event in events: - if event[0] == "account": + if event.event == "account": self.mainWindow.emit(SIGNAL("reloadAccounts"), False) - elif event[0] == "config": + elif event.event == "config": pass - elif event[1] == "queue": + elif event.destination == Destination.Queue: self.queue.addEvent(event) try: - if event[0] == "update" and event[2] == "file": - info = self.connector.getLinkInfo(event[3]) - if info.has_key(str(event[3])): - info = info[str(event[3])] - if info["statusmsg"] == "finished": - self.emit(SIGNAL("showMessage"), _("Finished downloading of '%s'") % info["name"]) - elif info["statusmsg"] == "failed": - self.emit(SIGNAL("showMessage"), _("Failed downloading '%s'!") % info["name"]) - if event[0] == "insert" and event[2] == "file": + if event.event == "update" and event.type == ElementType.File: + info = self.connector.getFileData(event.id) + if info.statusmsg == "finished": + self.emit(SIGNAL("showMessage"), _("Finished downloading of '%s'") % info.name) + elif info.statusmsg == "failed": + self.emit(SIGNAL("showMessage"), _("Failed downloading '%s'!") % info.name) + if event.event == "insert" and event.type == ElementType.File: info = self.connector.getLinkInfo(event[3]) - self.emit(SIGNAL("showMessage"), _("Added '%s' to queue") % info["name"]) + self.emit(SIGNAL("showMessage"), _("Added '%s' to queue") % info.name) except: print "can't send notification" - elif event[1] == "collector": + elif event.destination == Destination.Collector: self.packageCollector.addEvent(event) def slotReloadAccounts(self, force=False): @@ -718,7 +703,7 @@ class main(QObject): if not self.connectionLost: self.connectionLost = True m = QMessageBox(QMessageBox.Critical, _("Connection lost"), _("Lost connection to the core!"), QMessageBox.Ok) - m.exec_() + #m.show() self.slotQuit() class Loop(): @@ -739,7 +724,7 @@ class main(QObject): self.parent.refreshServerStatus() if self.lastSpaceCheck + 5 < time(): self.lastSpaceCheck = time() - self.parent.serverStatus["freespace"] = self.parent.connector.proxy.free_space() + self.parent.serverStatus["freespace"] = self.parent.connector.freeSpace() self.parent.refreshLog() self.parent.checkCaptcha() self.parent.pullEvents() |