summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar mkaay <mkaay@mkaay.de> 2011-02-12 18:04:24 +0100
committerGravatar mkaay <mkaay@mkaay.de> 2011-02-12 18:04:24 +0100
commit5a6bcc04e4a0b0088b7ca08c2a782fbc1212d674 (patch)
treecdbdda06598c0f2dd85273b2f32642e1ab1a5405
parentFileserveCom: Fixes download check (diff)
downloadpyload-5a6bcc04e4a0b0088b7ca08c2a782fbc1212d674.tar.xz
GUI refactoring (now Thrift powered), closes #233
please test!
-rw-r--r--module/database/FileDatabase.py3
-rw-r--r--module/gui/Accounts.py30
-rw-r--r--module/gui/Collector.py124
-rw-r--r--module/gui/ConnectionManager.py1
-rw-r--r--module/gui/MainWindow.py21
-rw-r--r--module/gui/Overview.py13
-rw-r--r--module/gui/Queue.py47
-rw-r--r--module/gui/SettingsWidget.py100
-rw-r--r--module/gui/connector.py276
-rw-r--r--module/remote/thriftbackend/Handler.py46
-rw-r--r--module/remote/thriftbackend/pyload.thrift28
-rwxr-xr-xmodule/remote/thriftbackend/thriftgen/pyload/Pyload-remote21
-rw-r--r--module/remote/thriftbackend/thriftgen/pyload/Pyload.py221
-rw-r--r--module/remote/thriftbackend/thriftgen/pyload/ttypes.py76
-rwxr-xr-xpyLoadCore.py20
-rwxr-xr-xpyLoadGui.py133
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()