SF.net SVN: fclient: [59] trunk/fclient/fclient_widgets/download_widget.py
Status: Pre-Alpha
Brought to you by:
jurner
From: <jU...@us...> - 2007-11-08 11:13:49
|
Revision: 59 http://fclient.svn.sourceforge.net/fclient/?rev=59&view=rev Author: jUrner Date: 2007-11-08 03:13:54 -0800 (Thu, 08 Nov 2007) Log Message: ----------- continued working on downloads widget Modified Paths: -------------- trunk/fclient/fclient_widgets/download_widget.py Modified: trunk/fclient/fclient_widgets/download_widget.py =================================================================== --- trunk/fclient/fclient_widgets/download_widget.py 2007-11-08 11:12:56 UTC (rev 58) +++ trunk/fclient/fclient_widgets/download_widget.py 2007-11-08 11:13:54 UTC (rev 59) @@ -19,7 +19,7 @@ from fclient_lib.pyex import namespace, numbers -#from fclient_lib.qt4ex import settingsbase +from fclient_lib.qt4ex import settingsbase from fclient_lib.qt4ex.ctrls import progressbarwrap from fclient_lib.qt4ex.ctrls import treewidgetwrap @@ -36,7 +36,33 @@ #***************************************************************************** # #***************************************************************************** +class UserSettings(settingsbase.SettingsBase): + """Settings for the download widget""" + + #TODO: impl dynamic setting of key for multiple widgets per app + KEY_SETTINGS = 'DownloadsWidgetUser' + SETTINGS = ( + ('ColorProgressBarRequestInfo', ['toString', 'cyan']), + ('ColorProgressBgRequestInfo', ['toString', 'white']), + ('ColorProgressBarRequestInfoComplete', ['toString', 'darkCyan']), + ('ColorProgressBgRequestInfoComplete', ['toString', 'white']), + ('ColorProgressBarDownloading', ['toString', 'blue']), + ('ColorProgressBgDownloading', ['toString', 'white']), + ('ColorProgressBarDownloadComplete', ['toString', 'green']), + ('ColorProgressBgDownloadComplete', ['toString', 'white']), + ('ColorProgressBarError', ['toString', 'red']), + ('ColorProgressBgError', ['toString', 'white']), + ('ColorProgressBarStopped', ['toString', 'gray']), + ('ColorProgressBarStopped', ['toString', 'white']), + + ('ClearCompletedDownloads', ['toBool', False]), + ) + +#***************************************************************************** +# +#***************************************************************************** class DownloadItem(QtGui.QTreeWidgetItem): + """Tree item""" # default indices IndexName = 0 @@ -57,81 +83,138 @@ StatusRequestInfoComplete = 0x4 StatusDownloading = 0x8 StatusDownloadComplete = 0x10 + + StatusStopped = 0x1000 + StatusError = 0x20000 - StatusError = 0x10000 - StatusMaskBusy = StatusRequestInfo | StatusDownloading + - - - def __init__(self, parent, requestIdentifier, uri): + """ + @param parent: parent of the item + @param requestIdentifier: (str) request identifier + @param uri: (str) uri to download + """ + QtGui.QTreeWidgetItem.__init__(self, parent) + self._requestError = None self._requestIdentifier = requestIdentifier self._requestStatus = self.StatusNone self._requestInitTime = time.time() self._uri = uri - + + def setRequestError(self, event, params): + """If an error occures, sets info about the error + @param event: event that triggered the error + @param params: params passed along with the event + """ + self._requestError = (event, params) + + def requestError(self): + """Return information about the last error encountered or None""" + return self._requestError + def setRequestIdentifier(self, identifier): + """Sets the request identifier of the item + @param requestIdentifier: (str) request identifier + """ self._requestIdentifier = identifier def requestIdentifier(self): + """Returns the request identifier of the item""" return self._requestIdentifier def requestInitTime(self): + """Returns the time the request was initialized + @return: (float) time + """ return self._requestInitTime def setRequestMimeType(self, mimeType): + """Sets the mime type of the item + @param mimeType: (str) mime type + """ self.setText(self.IndexMimeType, mimeType) def requestMimeType(self): + """Returns the mime type of the item""" return self.text(self.IndexMimeType) def setRequestName(self, name): + """Sets the request name of the item + @param name: (str) name + """ self.setText(self.IndexName, name) def requestName(self): + """Returns the request name of the item + """ return self.text(self.IndexName) def setRequestPriority(self, priority): + """Sets the request priority of the item + @param prority: (FcpClient.Priority) + """ self.setText(self.IndexPriority, priority) def requestPriority(self): + """Returns the request priority of the item""" return self.text(self.IndexPriority) def setProgressWidget(self, tree, widget): + """Associates a progress widget to the item + @param tree: (QTreeWidget) + @param widget: (QProgressBar) + """ tree.setItemWidget(self, self.IndexProgress, widget) def progressWidget(self, tree): + """Returns the progress widget associated to the item""" return tree.itemWidget(self, self.IndexProgress) def setRequestStatus(self, status, text=''): + """Sets the request status of the item + @param status: one of the Status* consts + @param text: status text to display + """ self._requestStatus = status self.setText(self.IndexStatus, text) def requestStatus(self): + """Returns the request status of the item + @return: (int) one of the Status* consts + """ return self._requestStatus def setRequestSize(self, size): + """Sets the request size of the item + @param size: (str) size + """ self.setText(self.IndexSize, size) def requestSize(self): + """Returns the request size of the item""" return self.text(self.IndexSize) def setRequestUri(self, uri): + """Sets the request uri of the item + @param uri: (str) uri + """ self._uri = uri def requestUri(self): + """Returns the request uri of the item""" return self._uri #***************************************************************************** # #***************************************************************************** class DownloadWidgetStrings(QtCore.QObject): - - + """Strings for the download widget""" + def __init__(self, parent): QtCore.QObject.__init__(self, parent) @@ -155,6 +238,7 @@ DownloadItem.StatusDownloading: self.trUtf8('Loading'), DownloadItem.StatusDownloadComplete: self.trUtf8('Complete'), + DownloadItem.StatusStopped: self.trUtf8('Stopped'), DownloadItem.StatusError: self.trUtf8('Error'), } @@ -202,6 +286,8 @@ self._maxSimultaniousDownloads = maxSimultaniousDownloads #TODO: move to settings self._strings = None + self._userSettings = UserSettings() + # setup tree self.setSelectionMode(self.ContiguousSelection) header = self.header() @@ -212,7 +298,7 @@ self.connect( self, QtCore.SIGNAL('customContextMenuRequested(const QPoint&)'), - self.handleContextMenu + self.handleCustomContextMenu ) @@ -227,14 +313,14 @@ def showEvent(self, event): if not self._isCreated: self._isCreated = True - self._fcpClient = self._cfg.fcpClientManager.newClient(self._connectionName, self.handleClientConnected) + self._fcpClient = self._cfg.fcpClientManager.newClient(self._connectionName, self.handleFcpClientConnected) ############################################################# ## ## handlers for Qt events ## ############################################################# - def handleContextMenu(self): + def handleCustomContextMenu(self): pass @@ -244,16 +330,19 @@ ## handlers for Fcp events ## ############################################################# - def handleClientConnected(self, event, params): + def handleFcpClientConnected(self, event, params): """ """ self._fcpEvents = ( - (self._fcpClient.events.Idle, self.handleClientIdle), - (self._fcpClient.events.ClientDisconnected, self.handleClientDisconnected), + (self._fcpClient.events.Idle, self.handleFcpClientIdle), + (self._fcpClient.events.ClientDisconnected, self.handleFcpClientDisconnected), - (self._fcpClient.events.TestDDAComplete, self.handleTestDDAComplete), - (self._fcpClient.events.ClientGetInfo, self.handleClientGetInfo), - (self._fcpClient.events.ClientGetInfoProgress, self.handleClientGetInfoProgress), + (self._fcpClient.events.TestDDAComplete, self.handleFcpClientTestDDAComplete), + (self._fcpClient.events.ClientRequestInfo, self.handleFcpClientRequestInfo), + (self._fcpClient.events.ClientRequestInfoProgress, self.handleFcpClientRequestInfoProgress), + + (self._fcpClient.events.GetFailed, self.handleFcpClientGetFailed), + (self._fcpClient.events.ProtocolError, self.handleFcpClientProtocolError), ) # take care not to connect twice for event, observer in self._fcpEvents: @@ -265,9 +354,32 @@ self._fcpClient.testDDA(directory, wantWriteDirectory=True) - - def handleClientIdle(self, event, msg): + def handleFcpClientDisconnected(self, event, params): + """ + """ + + #TODO: how to provide extra information to the user? + def handleFcpClientGetFailed(self, event, params): + identifier = params['Identifier'] + item = self._downloads['Downloads'].get(identifier, None) + if item is not None: + del self._downloads['Downloads'][identifier] + progress = item.progressWidget(self) + status = DownloadItem.StatusError + + progress.setRange(0, 1) + progress.setValue(1) + progress.setColors( + colorBar=self._userSettings['ColorProgressBarError'], + colorBg=self._userSettings['ColorProgressBgError'] + ) + item.setRequestStatus(status, self._strings.itemStatus[status]) + item.setRequestError(event, params) + + + def handleFcpClientIdle(self, event, params): + # check if there are sownloads queued n = 0 while self._downloads['DownloadQueue'] and n < self._maxQueuedItemsPerHop: @@ -287,6 +399,9 @@ # check how many downloads are currently running + + #TODO: bit sloppy coding here. We know how max downloads to start, + # so should be not too hard to keep the lists short items = { DownloadItem.StatusPending: [], DownloadItem.StatusRequestInfoComplete: [], @@ -329,46 +444,33 @@ item = pendingItems.pop(0) progress = progressbarwrap.ProgressBarEx(self) uri = item.requestUri() - - + progress.setRange(0, 0) progress.setValue(0) + progress.setColors( + colorBar=self._userSettings['ColorProgressBarRequestInfo'], + colorBg=self._userSettings['ColorProgressBgRequestInfo'] + ) item.setProgressWidget(self, progress) - identifier = self._fcpClient.clientGetInfo(uri) + identifier = self._fcpClient.clientRequestInfo(uri) self._downloads['Downloads'][identifier] = item - - def handleClientDisconnected(self, event, params): - """ - """ - def handleTestDDAComplete(self, event, params): - """ - """ - directory = params['Directory'] - readAllowed = params.get('WriteDirectoryAllowed') - writeAllowed = params.get('WriteDirectoryAllowed') + def handleFcpClientProtocolError(self, event, params): + identifier = params.get('Identifier', None) + if identifier is None: + #TDO: handle error + pass + else: + item = self._downloads['Downloads'].get(identifier, None) + if item is not None: + self.handleFcpClientGetFailed(event, params) + - # check if there are items to be donloaded for the directory - downloads = self._downloads['DownloadDirectories'].get(directory, None) - if downloads is not None: - del self._downloads['DownloadDirectories'][directory] # ??? - - 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 - + def handleFcpClientRequestInfo(self, event, params): - def handleClientGetInfo(self, event, params): - identifier = params['Identifier'] item = self._downloads['Downloads'].get(identifier, None) if item is not None: @@ -384,13 +486,18 @@ else: dataLength = numbers.format_num_bytes(dataLength) + progress = item.progressWidget(self) + progress.setColors( + colorBar=self._userSettings['ColorProgressBarRequestInfoComplete'], + colorBg=self._userSettings['ColorProgressBgRequestInfoComplete'] + ) + item.setRequestStatus(status, self._strings.itemStatus[status]) item.setRequestMimeType(mimeType) item.setRequestSize(dataLength) - - - def handleClientGetInfoProgress(self, event, params): + + def handleFcpClientRequestInfoProgress(self, event, params): identifier = params['Identifier'] item = self._downloads['Downloads'].get(identifier, None) @@ -403,6 +510,29 @@ progress.setRange(0, required) progress.setValue(succeeded) + + def handleFcpClientTestDDAComplete(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 = self._downloads['DownloadDirectories'].get(directory, None) + if downloads is not None: + del self._downloads['DownloadDirectories'][directory] # ??? + + 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 @@ -434,7 +564,7 @@ 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''' +CHK@[I AM INVALID] Jg~F~~WbKu8AlBgmwkonWGQNzZFUholE2CkGnyt23kk,Gj7JtnR97EIRvabG8m6Xp1dUAqiP6qD4J5FJRN9waMQ,AAIC--8/should-error.test''' TestUris = TestUris.split('\n') This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |