diff options
Diffstat (limited to 'module')
| -rw-r--r-- | module/gui/AccountEdit.py | 13 | ||||
| -rw-r--r-- | module/gui/Accounts.py | 49 | ||||
| -rw-r--r-- | module/gui/CaptchaDock.py | 8 | ||||
| -rw-r--r-- | module/gui/Collector.py | 70 | ||||
| -rw-r--r-- | module/gui/Queue.py | 59 | ||||
| -rw-r--r-- | module/gui/connector.py | 53 | 
6 files changed, 231 insertions, 21 deletions
| 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) | 
