SF.net SVN: fclient: [51] trunk/fclient/fclient_widgets/download_widget.py
Status: Pre-Alpha
Brought to you by:
jurner
|
From: <jU...@us...> - 2007-11-06 12:39:15
|
Revision: 51
http://fclient.svn.sourceforge.net/fclient/?rev=51&view=rev
Author: jUrner
Date: 2007-11-06 04:39:13 -0800 (Tue, 06 Nov 2007)
Log Message:
-----------
started implementing a download widget
Added Paths:
-----------
trunk/fclient/fclient_widgets/download_widget.py
Added: trunk/fclient/fclient_widgets/download_widget.py
===================================================================
--- trunk/fclient/fclient_widgets/download_widget.py (rev 0)
+++ trunk/fclient/fclient_widgets/download_widget.py 2007-11-06 12:39:13 UTC (rev 51)
@@ -0,0 +1,358 @@
+"""Sketch for a download widget
+
+"""
+
+
+import os, sys
+
+#--> rel import hack
+def parentdir(n, fpath):
+ fpath = os.path.abspath(fpath)
+ for i in xrange(n):
+ fpath = os.path.dirname(fpath)
+ return fpath
+sys.path.insert(0, parentdir(2, __file__))
+
+import config
+from fclient_lib import fcp
+#from fclient_dlgs import frdx_viewer
+from fclient_lib.pyex import namespace, numbers
+#from fclient_lib.qt4ex import settingsbase
+#from fclient_lib.qt4ex.ctrls import progressbarwrap
+
+sys.path.pop(0)
+del parentdir
+#<-- rel import hack
+
+
+import thread
+from PyQt4 import QtCore, QtGui
+#*****************************************************************************
+#
+#*****************************************************************************
+class DownloadItem(QtGui.QTreeWidgetItem):
+
+ # default indices
+ IndexName = 0
+ IndexStatus = 1
+ IndexProgress = 2
+ IndexSize = 3
+ IndexMimeType = 4
+ IndexPriority = 5
+
+ ######################
+ IndexLastProgress = 6
+ IndexDuration = 7
+
+
+ def __init__(self, parent, requestIdentifier, uri):
+ QtGui.QTreeWidgetItem.__init__(self, parent)
+
+ self._requestIdentifier = requestIdentifier
+ self._uri = uri
+
+
+ def setRequestIdentifier(self, identifier):
+ self._requestIdentifier = identifier
+
+ def requestIdentifier(self):
+ return self._requestIdentifier
+
+ def setRequestMimeType(self, mimeType):
+ self.setText(self.IndexMimeType, mimeType)
+
+ def requestMimeType(self):
+ return self.text(self.IndexMimeType)
+
+ def setRequestName(self, name):
+ self.setText(self.IndexName, name)
+
+ def requestName(self):
+ return self.text(self.IndexName)
+
+ def setRequestPriority(self, priority):
+ self.setText(self.IndexPriority, priority)
+
+ def requestPriority(self):
+ return self.text(self.IndexPriority)
+
+ def setProgressWidget(self, tree, widget):
+ tree.setItemWidget(self, self.IndexProgress, widget)
+
+ def progressWidget(self, tree):
+ return tree.itemWidget(self, self.IndexProgress)
+
+ def setRequestStatus(self, status):
+ self.setText(self.IndexStatus, status)
+
+ def requestStatus(self):
+ return self.text(self.IndexStatus)
+
+ def setRequestSize(self, size):
+ self.setText(self.IndexSize, size)
+
+ def requestSize(self):
+ return self.text(self.IndexSize)
+
+ def setRequestUri(self, uri):
+ self._uri = uri
+
+ def requestUri(self):
+ return self._uri
+
+#*****************************************************************************
+#
+#*****************************************************************************
+class DownloadWidgetStrings(QtCore.QObject):
+
+
+ def __init__(self, parent):
+ QtCore.QObject.__init__(self, parent)
+
+
+ self.headerSections = [
+ (DownloadItem.IndexName, self.trUtf8('Name')),
+ (DownloadItem.IndexStatus, self.trUtf8('Status')),
+ (DownloadItem.IndexProgress, self.trUtf8('Progress')),
+ (DownloadItem.IndexSize, self.trUtf8('Size')),
+ (DownloadItem.IndexMimeType, self.trUtf8('Content')),
+ (DownloadItem.IndexPriority, self.trUtf8('Priority')),
+ (DownloadItem.IndexLastProgress, self.trUtf8('Last Progress')),
+ (DownloadItem.IndexDuration, self.trUtf8('Duration')),
+ ]
+ self.headerSections.sort()
+
+
+#****************************************************************************
+#
+#****************************************************************************
+class DownloadWidget(QtGui.QTreeWidget):
+
+ def __init__(self,
+ parent,
+ connectionName='',
+ directory=None,
+ uris=None,
+ maxQueuedItemsPerHop=200,
+ maxSimultaniousDownloads=2,
+ cfg=None
+ ):
+ """
+ @param parent: (QWidget) parent or None
+ @param directory: (str) directory to sownload items to or None to use default directory
+ @param connectionName: name of the connection to the node
+ @param maxQueuedItemsPerHop: maximum number of items that can be e added in one hop
+ @param maxSimultaniousDownloads: maximim number of simultaneous downloads
+ @param cfg: (configConfig) instance or None
+ """
+
+ QtGui.QTreeWidget.__init__(self, parent)
+
+ self._connectionName = connectionName
+ self._cfg = cfg if cfg is not None else config.Config(self)
+ self._directory = directory if directory is not None else self._cfg.defaultDownloadDir
+ self._downloads = {
+ 'Downloads': {}, # identifier --> item / items currently downloading
+ 'DownloadQueue': [], # (parent-item, uri) / items scheduled for download
+ 'DownloadDirectories': {}, # directory --> (parentItem, uris) / directories scheduled for testDDA
+ }
+ self._fcpClient = None
+ self._isCreated = False
+ self._lock = thread.allocate_lock()
+ self._maxQueuedItemsPerHop = maxQueuedItemsPerHop #TODO: move to settings
+ self._maxSimultaniousDownloads = maxSimultaniousDownloads #TODO: move to settings
+ self._strings = DownloadWidgetStrings(self)
+
+ # timer to add scheduled downloads (add maxQueuedItemsPerHop / hop to avoid flooding of the tree)
+ self._timer = QtCore.QTimer(self)
+ self._timer.setInterval(300) # arbitrary delay
+ self.connect(
+ self._timer,
+ QtCore.SIGNAL('timeout()'),
+ self.addQueuedItems
+ )
+
+ # setup tree
+ self.setHeaderLabels([i[1] for i in self._strings.headerSections])
+ #self.setColumnCount(len(self._strings.HeaderSections))
+ self.setSelectionMode(self.ContiguousSelection)
+
+ header = self.header()
+ header.setResizeMode(header.ResizeToContents)
+ header.setStretchLastSection(True)
+
+ self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
+ self.connect(
+ self,
+ QtCore.SIGNAL('customContextMenuRequested(const QPoint&)'),
+ self.handleContextMenu
+ )
+
+ # schedule initial uris
+ if uris is not None:
+ self._downloads['DownloadDirectories'][self._directory] = (self, uris)
+
+
+ def showEvent(self, event):
+ if not self._isCreated:
+ self._isCreated = True
+ self._fcpClient = self._cfg.fcpClientManager.newClient(self._connectionName, self.handleClientConnected)
+
+ #############################################################
+ ##
+ ## handlers for Qt events
+ ##
+ #############################################################
+ def handleContextMenu(self):
+ pass
+
+
+
+ #############################################################
+ ##
+ ## handlers for Fcp events
+ ##
+ #############################################################
+ def handleClientConnected(self, event, params):
+ """
+ """
+ self._fcpEvents = (
+ (self._fcpClient.events.ClientDisconnected, self.handleClientDisconnected),
+
+ (self._fcpClient.events.TestDDAComplete, self.handleTestDDAComplete),
+ )
+ # take care not to connect twice
+ for event, observer in self._fcpEvents:
+ if not observer in event:
+ event += observer
+
+ # register directories
+ for directory in self._downloads['DownloadDirectories']:
+ self._fcpClient.testDDA(directory, wantWriteDirectory=True)
+
+
+ def handleClientDisconnected(self, event, params):
+ """
+ """
+
+ def handleTestDDAComplete(self, event, params):
+ """
+ """
+ directory = params['Directory']
+ readAllowed = params.get('WriteDirectoryAllowed')
+ writeAllowed = params.get('WriteDirectoryAllowed')
+
+ # check if there are items to be donloaded for the directory
+ downloads = None
+ self._lock.acquire(True)
+ try:
+ downloads = self._downloads['DownloadDirectories'].get(directory, None)
+ if downloads is not None:
+ del self._downloads['DownloadDirectories'][directory] # ???
+ finally:
+ self._lock.release()
+
+ if downloads:
+ if writeAllowed == self._fcpClient.FcpTrue:
+ parent, uris = downloads
+ for uri in uris:
+ self.download(uri, parent=parent)
+
+ else:
+ pass
+ #TODO: write access denied, error
+
+ #######################################################
+ ##
+ ## methods
+ ##
+ #######################################################
+ def addQueuedItems(self):
+
+ self._timer.stop()
+
+ self._lock.acquire(True)
+ try:
+ n = 0
+ while self._downloads['DownloadQueue'] and n < self._maxQueuedItemsPerHop:
+ n += 1
+
+ parent, uri = self._downloads['DownloadQueue'].pop(0)
+ item = DownloadItem(parent, '', uri)
+ fcpUri = self._fcpClient.FcpUri(uri)
+ fileName = fcpUri.fileName()
+ fileName = namespace.unquote_uri(fileName)
+
+ item.setRequestName(fileName)
+
+ #... more here
+
+ if self._downloads['DownloadQueue']:
+ self._timer.start()
+
+ finally:
+ self._lock.release()
+
+
+ def download(self, uri, parent=None):
+ self._lock.acquire(True)
+ try:
+ self._downloads['DownloadQueue'].append( (parent, uri) )
+ finally:
+ self._lock.release()
+
+ if not self._timer.isActive():
+ self._timer.start()
+
+
+ def retranslate(self):
+ pass
+
+#***************************************************************************************************
+#
+#***************************************************************************************************
+if __name__ == '__main__':
+ import sys
+
+ TestUris = '''CHK@sdNenKGj5mupxaSwo44jcW8dsX7vYTLww~BsRPtur0k,ZNRm9reMjtKEl9e-xFByKXbW6q4f6OQyfg~l9GRSAes,AAIC--8/snow_002%20%281%29.jpg
+CHK@q4~2soHTd9SOINIoXmg~dn7LNUAOYzN1tHNHT3j4c9E,gcVRtoglEhgqN-DJolXPqJ4yX1f~1gBGh89HNWlFMWQ,AAIC--8/snow_002%20%2810%29.jpg
+CHK@6tw-vrINDoNgSY9pTq-88n2sOAhREv1iFc3T0E18xHk,NxJxo9d7spLHCqGsMyY26XtXpUACPKTJq9v~WxVp3ic,AAIC--8/snow_002%20%2811%29.jpg
+CHK@nOb-ZM4h1SNpoG3E0xcOPnNDydSf~y2DON~R80exAtU,2o6smJYijaftLzMz4iva24T1geEAnDFn~bIMKFkzU30,AAIC--8/snow_002%20%2812%29.jpg
+CHK@XWyYvxoirEKiLWhnSVdKffSHT~nnKWsVZ5tJRKiFxBk,mK9-g5AeCvcNue1wYHRhc1Hdj3-yn77Vyu9Tq7XXJTM,AAIC--8/snow_002%20%2813%29.jpg
+CHK@AbQOZRSJcgXnKOI16D2hF8qkjxp3cl1u72bkL2KS29E,jjQlvojCkJJgzI2WgWj5rMsmUd935zjGChiV-j937X0,AAIC--8/snow_002%20%2814%29.jpg
+CHK@1ZW0fOpB7RmUFqSO2TtAOyfFm1uJ6~JcWuPESiYwtc4,aCDkI~JCr3Mb8s7rPBgmalPqzQEFdovlF~DgDRkGWuE,AAIC--8/snow_002%20%2815%29.jpg
+CHK@a8jHCl0TkwVAcTdYOezd-FtIWTLIFhjrWeHXVcSjRPk,4rIwDZE~-Gp~B5tjDSAcSpn~tLgMmnMUFeikXP4f7y0,AAIC--8/snow_002%20%2816%29.jpg
+CHK@Jg~F~~WbKu8AlBgmwkonWGQNzZFUholE2CkGnyt23kk,Gj7JtnR97EIRvabG8m6Xp1dUAqiP6qD4J5FJRN9waMQ,AAIC--8/snow_002%20%2836%29.jpg'''
+ TestUris = TestUris.split('\n')
+
+
+
+ app = QtGui.QApplication(sys.argv)
+ w = QtGui.QMainWindow()
+ peers = DownloadWidget(None,
+ connectionName='TestDownloadWidget',
+ uris=TestUris
+
+ )
+ w.setCentralWidget(peers)
+
+ #m = w.menuBar()
+ #m1 = m.addMenu('Peers')
+ #peers.populateMenu(m1)
+
+ w.show()
+ res = app.exec_()
+ sys.exit(res)
+
+
+
+
+
+
+
+
+
+
+
+
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|