From 2c589f8b0e474ba0da82b9afbcb896190f136c2a Mon Sep 17 00:00:00 2001 From: Stevan Pettit Date: Thu, 8 Sep 2011 09:14:51 -0400 Subject: [PATCH] Added code to allow canceling of file downloads. Fixed aparent hang if no internet connection. --- openlp/core/ui/firsttimeform.py | 117 +++++++++++++++++++----------- openlp/core/ui/firsttimewizard.py | 2 - 2 files changed, 74 insertions(+), 45 deletions(-) diff --git a/openlp/core/ui/firsttimeform.py b/openlp/core/ui/firsttimeform.py index 340a689d2..9046f3e09 100644 --- a/openlp/core/ui/firsttimeform.py +++ b/openlp/core/ui/firsttimeform.py @@ -28,7 +28,7 @@ import io import logging import os -import urllib +import urllib, urllib2 from tempfile import gettempdir from ConfigParser import SafeConfigParser @@ -60,8 +60,11 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): files = self.webAccess.read() self.config.readfp(io.BytesIO(files)) self.updateScreenListCombo() + self.downloadCanceled = False self.downloading = unicode(translate('OpenLP.FirstTimeWizard', 'Downloading %s...')) + QtCore.QObject.connect(self.cancelButton,QtCore.SIGNAL('clicked()'), + self.onCancelButtonClicked) QtCore.QObject.connect(self, QtCore.SIGNAL(u'currentIdChanged(int)'), self.onCurrentIdChanged) QtCore.QObject.connect(Receiver.get_receiver(), @@ -120,7 +123,7 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): title = self.config.get(u'theme_%s' % theme, u'title') filename = self.config.get(u'theme_%s' % theme, u'filename') screenshot = self.config.get(u'theme_%s' % theme, u'screenshot') - urllib.urlretrieve(u'%s/%s' % (self.web, screenshot), + urllib.urlretrieve(u'%s%s' % (self.web, screenshot), os.path.join(gettempdir(), u'openlp', screenshot)) item = QtGui.QListWidgetItem(title, self.themesListWidget) item.setData(QtCore.Qt.UserRole, @@ -152,15 +155,16 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): """ Detects Page changes and updates as approprate. """ - if pageId == FirstTimePage.Defaults: + if pageId == FirstTimePage.Plugins: + # Check if this is a re-run of the wizard. + self.has_run_wizard = QtCore.QSettings().value( + u'general/has run wizard', QtCore.QVariant(False)).toBool() + elif pageId == FirstTimePage.Defaults: self.themeComboBox.clear() for iter in xrange(self.themesListWidget.count()): item = self.themesListWidget.item(iter) if item.checkState() == QtCore.Qt.Checked: self.themeComboBox.addItem(item.text()) - # Check if this is a re-run of the wizard. - self.has_run_wizard = QtCore.QSettings().value( - u'general/has run wizard', QtCore.QVariant(False)).toBool() if self.has_run_wizard: # Add any existing themes to list. for theme in self.parent().themeManagerContents.getThemes(): @@ -192,6 +196,33 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): self.displayComboBox.addItems(self.screens.get_screen_list()) self.displayComboBox.setCurrentIndex(self.displayComboBox.count() - 1) + def onCancelButtonClicked(self): + self.downloadCanceled = True + Receiver.send_message(u'cursor_normal') + + def urlGetFile(self, url, fpath): + """" + Download a file given a URL. The file is retrieved in chunks, giving + the ability to cancel the download at any point. + """ + block_count = 0 + block_size = 4096 + urlfile = urllib2.urlopen(url) + filesize = urlfile.headers["Content-Length"] + filename = open(fpath, "wb") + # Download until finished or canceled. + while not self.downloadCanceled: + data = urlfile.read(block_size) + if not data: + break + filename.write(data) + block_count += 1 + self._downloadProgress(block_count, block_size, filesize) + filename.close() + # Delete file if canceled, it may be a partial file. + if self.downloadCanceled: + os.remove(fpath) + def _getFileSize(self, url): site = urllib.urlopen(url) meta = site.info() @@ -201,7 +232,7 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): increment = (count * block_size) - self.previous_size self._incrementProgressBar(None, increment) self.previous_size = count * block_size - + def _incrementProgressBar(self, status_text, increment=1): """ Update the wizard progress page. @@ -309,42 +340,42 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): self._setPluginStatus(self.customCheckBox, u'custom/status') self._setPluginStatus(self.songUsageCheckBox, u'songusage/status') self._setPluginStatus(self.alertCheckBox, u'alerts/status') - # Build directories for downloads - songs_destination = os.path.join(unicode(gettempdir()), u'openlp') - bibles_destination = AppLocation.get_section_data_path(u'bibles') - themes_destination = AppLocation.get_section_data_path(u'themes') - # Download songs - for i in xrange(self.songsListWidget.count()): - item = self.songsListWidget.item(i) - if item.checkState() == QtCore.Qt.Checked: - filename = item.data(QtCore.Qt.UserRole).toString() - self._incrementProgressBar(self.downloading % filename, 0) - self.previous_size = 0 - destination = os.path.join(songs_destination, unicode(filename)) - urllib.urlretrieve(u'%s%s' % (self.web, filename), destination, - self._downloadProgress) - # Download Bibles - bibles_iterator = QtGui.QTreeWidgetItemIterator(self.biblesTreeWidget) - while bibles_iterator.value(): - item = bibles_iterator.value() - if item.parent() and item.checkState(0) == QtCore.Qt.Checked: - bible = unicode(item.data(0, QtCore.Qt.UserRole).toString()) - self._incrementProgressBar(self.downloading % bible, 0) - self.previous_size = 0 - urllib.urlretrieve(u'%s%s' % (self.web, bible), - os.path.join(bibles_destination, bible), - self._downloadProgress) - bibles_iterator += 1 - # Download themes - for i in xrange(self.themesListWidget.count()): - item = self.themesListWidget.item(i) - if item.checkState() == QtCore.Qt.Checked: - theme = unicode(item.data(QtCore.Qt.UserRole).toString()) - self._incrementProgressBar(self.downloading % theme, 0) - self.previous_size = 0 - urllib.urlretrieve(u'%s%s' % (self.web, theme), - os.path.join(themes_destination, theme), - self._downloadProgress) + if self.webAccess: + # Build directories for downloads + songs_destination = os.path.join(unicode(gettempdir()), u'openlp') + bibles_destination = AppLocation.get_section_data_path(u'bibles') + themes_destination = AppLocation.get_section_data_path(u'themes') + # Download songs + for i in xrange(self.songsListWidget.count()): + item = self.songsListWidget.item(i) + if item.checkState() == QtCore.Qt.Checked: + filename = item.data(QtCore.Qt.UserRole).toString() + self._incrementProgressBar(self.downloading % filename, 0) + self.previous_size = 0 + destination = os.path.join(songs_destination, + unicode(filename)) + self.urlGetFile(u'%s%s' % (self.web, filename), destination) + # Download Bibles + bibles_iterator = QtGui.QTreeWidgetItemIterator( + self.biblesTreeWidget) + while bibles_iterator.value(): + item = bibles_iterator.value() + if item.parent() and item.checkState(0) == QtCore.Qt.Checked: + bible = unicode(item.data(0, QtCore.Qt.UserRole).toString()) + self._incrementProgressBar(self.downloading % bible, 0) + self.previous_size = 0 + self.urlGetFile(u'%s%s' % (self.web, bible), + os.path.join(bibles_destination, bible)) + bibles_iterator += 1 + # Download themes + for i in xrange(self.themesListWidget.count()): + item = self.themesListWidget.item(i) + if item.checkState() == QtCore.Qt.Checked: + theme = unicode(item.data(QtCore.Qt.UserRole).toString()) + self._incrementProgressBar(self.downloading % theme, 0) + self.previous_size = 0 + self.urlGetFile(u'%s%s' % (self.web, theme), + os.path.join(themes_destination, theme)) # Set Default Display if self.displayComboBox.currentIndex() != -1: QtCore.QSettings().setValue(u'General/monitor', diff --git a/openlp/core/ui/firsttimewizard.py b/openlp/core/ui/firsttimewizard.py index 7e94b4595..b989d986a 100644 --- a/openlp/core/ui/firsttimewizard.py +++ b/openlp/core/ui/firsttimewizard.py @@ -189,9 +189,7 @@ class Ui_FirstTimeWizard(object): self.progressBar.setObjectName(u'progressBar') self.progressLayout.addWidget(self.progressBar) FirstTimeWizard.setPage(FirstTimePage.Progress, self.progressPage) - self.retranslateUi(FirstTimeWizard) - QtCore.QMetaObject.connectSlotsByName(FirstTimeWizard) def retranslateUi(self, FirstTimeWizard): FirstTimeWizard.setWindowTitle(translate(