From c50326a33f1a90b00325273af8710700bbac67d2 Mon Sep 17 00:00:00 2001 From: mkaay Date: Mon, 14 Feb 2011 17:05:11 +0100 Subject: fixes, docstring update for gui --- module/gui/AccountEdit.py | 13 +++++++++ module/gui/Accounts.py | 49 +++++++++++++++++++++++++++++---- module/gui/CaptchaDock.py | 8 ++++++ module/gui/Collector.py | 70 +++++++++++++++++++++++++++++++++++++++++++++++ module/gui/Queue.py | 59 +++++++++++++++++++++++++++++++++++++++ module/gui/connector.py | 53 +++++++++++++++++++++++++---------- 6 files changed, 231 insertions(+), 21 deletions(-) (limited to 'module/gui') diff --git a/module/gui/AccountEdit.py b/module/gui/AccountEdit.py index cc213b0d5..b22cfc49f 100644 --- a/module/gui/AccountEdit.py +++ b/module/gui/AccountEdit.py @@ -22,6 +22,10 @@ from PyQt4.QtGui import * from os.path import join class AccountEdit(QWidget): + """ + account editor widget + """ + def __init__(self): QMainWindow.__init__(self) @@ -62,6 +66,9 @@ class AccountEdit(QWidget): self.connect(save, SIGNAL("clicked()"), self.slotSave) def slotSave(self): + """ + save entered data + """ data = {"login": str(self.login.text()), "acctype": str(self.acctype.currentText()), "password": False} if self.changePw.isChecked(): data["password"] = str(self.password.text()) @@ -69,6 +76,9 @@ class AccountEdit(QWidget): @staticmethod def newAccount(types): + """ + create empty editor instance + """ w = AccountEdit() w.setWindowTitle(_("Create account")) @@ -81,6 +91,9 @@ class AccountEdit(QWidget): @staticmethod def editAccount(types, base): + """ + create editor instance with given data + """ w = AccountEdit() w.acctype.addItems(types) diff --git a/module/gui/Accounts.py b/module/gui/Accounts.py index 62971f3ed..8db04dfa9 100644 --- a/module/gui/Accounts.py +++ b/module/gui/Accounts.py @@ -22,6 +22,10 @@ from PyQt4.QtGui import * from time import strftime, gmtime class AccountModel(QAbstractItemModel): + """ + model for account view + """ + def __init__(self, view, connector): QAbstractItemModel.__init__(self) self.connector = connector @@ -31,6 +35,9 @@ class AccountModel(QAbstractItemModel): self.mutex = QMutex() def reloadData(self, force=False): + """ + reload account list + """ accounts = self.connector.proxy.getAccounts(False) if self._data == accounts: @@ -47,9 +54,15 @@ class AccountModel(QAbstractItemModel): self.endInsertRows() def toData(self, index): + """ + return index pointer + """ return index.internalPointer() def data(self, index, role=Qt.DisplayRole): + """ + return cell data + """ if not index.isValid(): return QVariant() if role == Qt.DisplayRole: @@ -74,6 +87,9 @@ class AccountModel(QAbstractItemModel): return QVariant() def index(self, row, column, parent=QModelIndex()): + """ + create index with data pointer + """ if parent == QModelIndex() and len(self._data) > row: pointer = self._data[row] index = self.createIndex(row, column, pointer) @@ -85,9 +101,15 @@ class AccountModel(QAbstractItemModel): return index def parent(self, index): + """ + no parents, everything on top level + """ return QModelIndex() def rowCount(self, parent=QModelIndex()): + """ + account count + """ if parent == QModelIndex(): return len(self._data) return 0 @@ -96,6 +118,9 @@ class AccountModel(QAbstractItemModel): return self.cols def hasChildren(self, parent=QModelIndex()): + """ + everything on top level + """ if parent == QModelIndex(): return True else: @@ -105,6 +130,9 @@ class AccountModel(QAbstractItemModel): return False def headerData(self, section, orientation, role=Qt.DisplayRole): + """ + returns column heading + """ if orientation == Qt.Horizontal and role == Qt.DisplayRole: if section == 0: return QVariant(_("Type")) @@ -117,14 +145,16 @@ class AccountModel(QAbstractItemModel): return QVariant() def flags(self, index): - return Qt.ItemIsSelectable | Qt.ItemIsEditable | Qt.ItemIsEnabled - - #def setData(self, index, value, role=Qt.EditRole): - # if index.column() == 0 and self.parent(index) == QModelIndex() and role == Qt.EditRole: - # self.connector.setPackageName(index.internalPointer().id, str(value.toString())) - # return True + """ + cell flags + """ + return Qt.ItemIsSelectable | Qt.ItemIsEnabled class AccountView(QTreeView): + """ + view component for accounts + """ + def __init__(self, connector): QTreeView.__init__(self) self.setModel(AccountModel(self, connector)) @@ -140,11 +170,18 @@ class AccountView(QTreeView): self.setItemDelegateForColumn(3, self.delegate) class AccountDelegate(QItemDelegate): + """ + used to display a progressbar for the traffic in the traffic cell + """ + def __init__(self, parent, model): QItemDelegate.__init__(self, parent) self.model = model def paint(self, painter, option, index): + """ + paint the progressbar + """ if not index.isValid(): return if index.column() == 3: diff --git a/module/gui/CaptchaDock.py b/module/gui/CaptchaDock.py index ad61ae4f5..b88cb53ca 100644 --- a/module/gui/CaptchaDock.py +++ b/module/gui/CaptchaDock.py @@ -21,6 +21,10 @@ from PyQt4.QtCore import * from PyQt4.QtGui import * class CaptchaDock(QDockWidget): + """ + dock widget for captcha input + """ + def __init__(self): QDockWidget.__init__(self, _("Captcha")) self.setObjectName("Captcha Dock") @@ -45,6 +49,10 @@ class CaptchaDock(QDockWidget): self.show() class CaptchaDockWidget(QWidget): + """ + widget for the input widgets + """ + def __init__(self, dock): QWidget.__init__(self) self.dock = dock diff --git a/module/gui/Collector.py b/module/gui/Collector.py index 39310a45d..75f693323 100644 --- a/module/gui/Collector.py +++ b/module/gui/Collector.py @@ -54,6 +54,10 @@ def formatSize(size): return "%.2f %s" % (size, sizes[steps]) class CollectorModel(QAbstractItemModel): + """ + model for the collector view + """ + def __init__(self, view, connector): QAbstractItemModel.__init__(self) self.connector = connector @@ -82,9 +86,15 @@ class CollectorModel(QAbstractItemModel): } def translateStatus(self, string): + """ + used to convert to locale specific status + """ return translatedStatusMap[string] def addEvent(self, event): + """ + called from main loop, pass events to the correct methods + """ locker = QMutexLocker(self.mutex) if event.event == "reload": self.fullReload() @@ -96,6 +106,9 @@ class CollectorModel(QAbstractItemModel): self.updateEvent(event) def fullReload(self): + """ + reload whole model, used at startup to load initial data + """ self._data = [] order = self.connector.getPackageOrder(Destination.Collector) self.beginInsertRows(QModelIndex(), 0, len(order.values())) @@ -107,6 +120,9 @@ class CollectorModel(QAbstractItemModel): self.endInsertRows() def removeEvent(self, event): + """ + remove an element from model + """ if event.type == ElementType.File: for p, package in enumerate(self._data): for k, child in enumerate(package.children): @@ -124,6 +140,9 @@ class CollectorModel(QAbstractItemModel): break def insertEvent(self, event): + """ + inserts a new element in the model + """ if event.type == ElementType.File: info = self.connector.getFileData(event.id) @@ -144,6 +163,9 @@ class CollectorModel(QAbstractItemModel): self.endInsertRows() def updateEvent(self, event): + """ + update an element in the model + """ if event.type == ElementType.File: info = self.connector.proxy.getFileData(event.id) if not info: @@ -168,6 +190,9 @@ class CollectorModel(QAbstractItemModel): break def data(self, index, role=Qt.DisplayRole): + """ + return cell data + """ if not index.isValid(): return QVariant() if role == Qt.DisplayRole: @@ -208,6 +233,9 @@ class CollectorModel(QAbstractItemModel): return QVariant() def index(self, row, column, parent=QModelIndex()): + """ + creates a cell index with pointer to the data + """ if parent == QModelIndex() and len(self._data) > row: pointer = self._data[row] index = self.createIndex(row, column, pointer) @@ -222,6 +250,10 @@ class CollectorModel(QAbstractItemModel): return index def parent(self, index): + """ + return index of parent element + only valid for links + """ if index == QModelIndex(): return QModelIndex() if index.isValid(): @@ -233,6 +265,9 @@ class CollectorModel(QAbstractItemModel): return QModelIndex() def rowCount(self, parent=QModelIndex()): + """ + returns row count for the element + """ if parent == QModelIndex(): #return package count return len(self._data) @@ -262,6 +297,9 @@ class CollectorModel(QAbstractItemModel): return False def headerData(self, section, orientation, role=Qt.DisplayRole): + """ + returns column heading + """ if orientation == Qt.Horizontal and role == Qt.DisplayRole: if section == 0: return QVariant(_("Name")) @@ -274,16 +312,26 @@ class CollectorModel(QAbstractItemModel): return QVariant() def flags(self, index): + """ + cell flags + """ if index.column() == 0 and self.parent(index) == QModelIndex(): return Qt.ItemIsSelectable | Qt.ItemIsEditable | Qt.ItemIsEnabled return Qt.ItemIsSelectable | Qt.ItemIsEnabled def setData(self, index, value, role=Qt.EditRole): + """ + called if package name editing is finished, sets new name + """ if index.column() == 0 and self.parent(index) == QModelIndex() and role == Qt.EditRole: self.connector.setPackageName(index.internalPointer().id, str(value.toString())) return True class Package(object): + """ + package object in the model + """ + def __init__(self, pack): self.id = pack.pid self.children = [] @@ -293,6 +341,9 @@ class Package(object): self.update(pack) def update(self, pack): + """ + update data dict from thift object + """ data = { "name": pack.name, "folder": pack.folder, @@ -304,22 +355,34 @@ class Package(object): self.data.update(data) def addChild(self, f): + """ + add child (Link) to package + """ self.children.insert(f.order, Link(f, self)) self.children = sorted(self.children, key=lambda l: l.data["order"]) def getChild(self, fid): + """ + get child from package + """ for child in self.children: if child.id == int(fid): return child return None def getChildKey(self, fid): + """ + get child index + """ for k, child in enumerate(self.children): if child.id == int(fid): return k return None def removeChild(self, fid): + """ + remove child + """ for k, child in enumerate(self.children): if child.id == int(fid): del self.children[k] @@ -332,6 +395,9 @@ class Link(object): self.package = pack def update(self, f): + """ + update data dict from thift object + """ data = { "url": f.url, "name": f.name, @@ -348,6 +414,10 @@ class Link(object): self.data.update(data) class CollectorView(QTreeView): + """ + view component for collector + """ + def __init__(self, connector): QTreeView.__init__(self) self.setModel(CollectorModel(self, connector)) diff --git a/module/gui/Queue.py b/module/gui/Queue.py index 94025c867..17717795e 100644 --- a/module/gui/Queue.py +++ b/module/gui/Queue.py @@ -35,6 +35,10 @@ def formatSpeed(speed): return "%.2f %s" % (speed, sizes[steps]) class QueueModel(CollectorModel): + """ + model for the queue view, inherits from CollectorModel + """ + def __init__(self, view, connector): CollectorModel.__init__(self, view, connector) self.cols = 7 @@ -44,6 +48,11 @@ class QueueModel(CollectorModel): self.connect(self.updater, SIGNAL("update()"), self.update) class QueueUpdater(QObject): + """ + timer which emits signal for a download status reload + @TODO: make intervall configurable + """ + def __init__(self, interval): QObject.__init__(self) @@ -64,6 +73,9 @@ class QueueModel(CollectorModel): self.updater.stop() def fullReload(self): + """ + reimplements CollectorModel.fullReload, because we want the Queue data + """ self._data = [] order = self.connector.getPackageOrder(Destination.Queue) self.beginInsertRows(QModelIndex(), 0, len(order.values())) @@ -76,18 +88,31 @@ class QueueModel(CollectorModel): self.updateCount() def insertEvent(self, event): + """ + wrap CollectorModel.insertEvent to update the element count + """ CollectorModel.insertEvent(self, event) self.updateCount() def removeEvent(self, event): + """ + wrap CollectorModel.removeEvent to update the element count + """ CollectorModel.removeEvent(self, event) self.updateCount() def updateEvent(self, event): + """ + wrap CollectorModel.updateEvent to update the element count + """ CollectorModel.updateEvent(self, event) self.updateCount() def updateCount(self): + """ + calculate package- and filecount for statusbar, + ugly?: Overview connects to this signal for updating + """ packageCount = len(self._data) fileCount = 0 for p in self._data: @@ -97,6 +122,9 @@ class QueueModel(CollectorModel): self.mutex.lock() def update(self): + """ + update slot for download status updating + """ locker = QMutexLocker(self.mutex) downloading = self.connector.statusDownloads() if not downloading: @@ -125,6 +153,9 @@ class QueueModel(CollectorModel): self.updateCount() def headerData(self, section, orientation, role=Qt.DisplayRole): + """ + returns column heading + """ if orientation == Qt.Horizontal and role == Qt.DisplayRole: if section == 0: return QVariant(_("Name")) @@ -143,6 +174,9 @@ class QueueModel(CollectorModel): return QVariant() def getWaitingProgress(self, item): + """ + returns time to wait, caches startingtime to provide progress + """ locker = QMutexLocker(self.mutex) if isinstance(item, Link): if item.data["status"] == 5 and item.data["downloading"]: @@ -165,6 +199,11 @@ class QueueModel(CollectorModel): return None def getProgress(self, item, locked=True): + """ + return download progress, locks by default + since it's used in already locked calls, + it provides an option to not lock + """ if locked: locker = QMutexLocker(self.mutex) if isinstance(item, Link): @@ -188,6 +227,9 @@ class QueueModel(CollectorModel): return 0 def getSpeed(self, item): + """ + calculate download speed + """ if isinstance(item, Link): if item.data["downloading"]: return int(item.data["downloading"]["speed"]) @@ -210,6 +252,9 @@ class QueueModel(CollectorModel): return None def data(self, index, role=Qt.DisplayRole): + """ + return cell data + """ if not index.isValid(): return QVariant() if role == Qt.DisplayRole: @@ -289,11 +334,18 @@ class QueueModel(CollectorModel): return QVariant() def flags(self, index): + """ + cell flags + """ if index.column() == 0 and self.parent(index) == QModelIndex(): return Qt.ItemIsSelectable | Qt.ItemIsEditable | Qt.ItemIsEnabled return Qt.ItemIsSelectable | Qt.ItemIsEnabled class QueueView(CollectorView): + """ + view component for queue + """ + def __init__(self, connector): CollectorView.__init__(self, connector) self.setModel(QueueModel(self, connector)) @@ -311,11 +363,18 @@ class QueueView(CollectorView): self.setItemDelegateForColumn(6, self.delegate) class QueueProgressBarDelegate(QItemDelegate): + """ + used to display a progressbar in the progress cell + """ + def __init__(self, parent, queue): QItemDelegate.__init__(self, parent) self.queue = queue def paint(self, painter, option, index): + """ + paint the progressbar + """ if not index.isValid(): return if index.column() == 6: diff --git a/module/gui/connector.py b/module/gui/connector.py index 5acfdfc8b..c594ae5e1 100644 --- a/module/gui/connector.py +++ b/module/gui/connector.py @@ -30,6 +30,10 @@ from module.remote.thriftbackend.ThriftClient import ThriftClient, WrongLogin, N from thrift.Thrift import TException class Connector(QObject): + """ + manages the connection to the pyload core via thrift + """ + def __init__(self): QObject.__init__(self) self.mutex = QMutex() @@ -43,6 +47,9 @@ class Connector(QObject): self.proxy = self.Dummy() def setConnectionData(self, host, port, user, password, ssl=False): + """ + set connection data for connection attempt, called from slotConnect + """ self.host = host self.port = port self.user = user @@ -50,6 +57,13 @@ class Connector(QObject): self.ssl = ssl def connectProxy(self): + """ + initialize thrift rpc client, + check for ssl, check auth, + setup dispatcher, + connect error signals, + check server version + """ try: client = ThriftClient(self.host, self.port, self.user, self.password) except WrongLogin: @@ -63,67 +77,76 @@ class Connector(QObject): return False 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)) + self.emit(SIGNAL("errorBox"), "server is version %s client accepts version %s" % (server_version, SERVER_VERSION)) return False return True - def _proxyError(self, func, e): + def __getattr__(self, attr): """ - formats proxy error msg + redirect rpc calls to dispatcher """ - msg = "proxy error in '%s':\n%s" % (func, e) - print msg - self.emit(SIGNAL("error_box"), msg) - - def __getattr__(self, attr): return getattr(self.proxy, attr) class Dummy(object): + """ + dummy rpc proxy, to prevent errors + """ def __getattr__(self, attr): def dummy(*args, **kwargs): return None return dummy class DispatchRPC(QObject): + """ + wraps the thrift client, to catch critical exceptions (connection lost) + adds thread safety + """ + def __init__(self, mutex, server): QObject.__init__(self) self.mutex = mutex self.server = server def __getattr__(self, attr): + """ + redirect and wrap call in Wrapper instance, locks dispatcher + """ self.mutex.lock() self.fname = attr f = self.Wrapper(getattr(self.server, attr), self.mutex, self) return f class Wrapper(object): + """ + represents a rpc call + """ + def __init__(self, f, mutex, dispatcher): self.f = f self.mutex = mutex self.dispatcher = dispatcher def __call__(self, *args, **kwargs): + """ + instance is called, rpc is executed + exceptions are processed + finally dispatcher is unlocked + """ lost = False - error = False try: return self.f(*args, **kwargs) - except socket.error: + except socket.error: #necessary? lost = True except TException: lost = True - except Exception, e: - err = e finally: self.mutex.unlock() if lost: self.dispatcher.emit(SIGNAL("connectionLost")) - if error: - self.dispatcher.emit(SIGNAL("proxy_error"), self.dispatcher.fname, error) -- cgit v1.2.3