forked from openlp/openlp
Better handle failed downloads
This commit is contained in:
parent
121f0908a1
commit
6d2b1d958e
@ -60,6 +60,35 @@ def init_db(url, auto_flush=True, auto_commit=False, base=None):
|
||||
return session, metadata
|
||||
|
||||
|
||||
def get_db_path(plugin_name, db_file_name=None):
|
||||
"""
|
||||
Create a path to a database from the plugin name and database name
|
||||
|
||||
:param plugin_name: Name of plugin
|
||||
:param db_file_name: File name of database
|
||||
:return: The path to the database as type str
|
||||
"""
|
||||
if db_file_name is None:
|
||||
return 'sqlite:///%s/%s.sqlite' % (AppLocation.get_section_data_path(plugin_name), plugin_name)
|
||||
else:
|
||||
return 'sqlite:///%s/%s' % (AppLocation.get_section_data_path(plugin_name), db_file_name)
|
||||
|
||||
|
||||
def handle_db_error(plugin_name, db_file_name):
|
||||
"""
|
||||
Log and report to the user that a database cannot be loaded
|
||||
|
||||
:param plugin_name: Name of plugin
|
||||
:param db_file_name: File name of database
|
||||
:return: None
|
||||
"""
|
||||
db_path = get_db_path(plugin_name, db_file_name)
|
||||
log.exception('Error loading database: %s', db_path)
|
||||
critical_error_message_box(translate('OpenLP.Manager', 'Database Error'),
|
||||
translate('OpenLP.Manager', 'OpenLP cannot load your database.\n\nDatabase: %s')
|
||||
% db_path)
|
||||
|
||||
|
||||
def init_url(plugin_name, db_file_name=None):
|
||||
"""
|
||||
Return the database URL.
|
||||
@ -69,13 +98,9 @@ def init_url(plugin_name, db_file_name=None):
|
||||
"""
|
||||
settings = Settings()
|
||||
settings.beginGroup(plugin_name)
|
||||
db_url = ''
|
||||
db_type = settings.value('db type')
|
||||
if db_type == 'sqlite':
|
||||
if db_file_name is None:
|
||||
db_url = 'sqlite:///%s/%s.sqlite' % (AppLocation.get_section_data_path(plugin_name), plugin_name)
|
||||
else:
|
||||
db_url = 'sqlite:///%s/%s' % (AppLocation.get_section_data_path(plugin_name), db_file_name)
|
||||
db_url = get_db_path(plugin_name, db_file_name)
|
||||
else:
|
||||
db_url = '%s://%s:%s@%s/%s' % (db_type, urlquote(settings.value('db username')),
|
||||
urlquote(settings.value('db password')),
|
||||
@ -212,7 +237,7 @@ class Manager(object):
|
||||
try:
|
||||
db_ver, up_ver = upgrade_db(self.db_url, upgrade_mod)
|
||||
except (SQLAlchemyError, DBAPIError):
|
||||
log.exception('Error loading database: %s', self.db_url)
|
||||
handle_db_error(plugin_name, db_file_name)
|
||||
return
|
||||
if db_ver > up_ver:
|
||||
critical_error_message_box(
|
||||
@ -225,10 +250,7 @@ class Manager(object):
|
||||
try:
|
||||
self.session = init_schema(self.db_url)
|
||||
except (SQLAlchemyError, DBAPIError):
|
||||
log.exception('Error loading database: %s', self.db_url)
|
||||
critical_error_message_box(translate('OpenLP.Manager', 'Database Error'),
|
||||
translate('OpenLP.Manager', 'OpenLP cannot load your database.\n\nDatabase: %s')
|
||||
% self.db_url)
|
||||
handle_db_error(plugin_name, db_file_name)
|
||||
|
||||
def save_object(self, object_instance, commit=True):
|
||||
"""
|
||||
@ -362,6 +384,8 @@ class Manager(object):
|
||||
:param object_class: The type of objects to return.
|
||||
:param filter_clause: The filter governing selection of objects to return. Defaults to None.
|
||||
"""
|
||||
if not self.session:
|
||||
return
|
||||
query = self.session.query(object_class)
|
||||
if filter_clause is not None:
|
||||
query = query.filter(filter_clause)
|
||||
|
@ -22,6 +22,7 @@
|
||||
"""
|
||||
This module contains the first time wizard.
|
||||
"""
|
||||
import hashlib
|
||||
import logging
|
||||
import os
|
||||
import time
|
||||
@ -221,8 +222,9 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
self.application.process_events()
|
||||
title = self.config.get('songs_%s' % song, 'title')
|
||||
filename = self.config.get('songs_%s' % song, 'filename')
|
||||
sha256 = self.config.get('songs_%s' % song, 'sha256', fallback=None)
|
||||
item = QtGui.QListWidgetItem(title, self.songs_list_widget)
|
||||
item.setData(QtCore.Qt.UserRole, filename)
|
||||
item.setData(QtCore.Qt.UserRole, (filename, sha256))
|
||||
item.setCheckState(QtCore.Qt.Unchecked)
|
||||
item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable)
|
||||
bible_languages = self.config.get('bibles', 'languages')
|
||||
@ -372,7 +374,7 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
Settings().setValue('core/has run wizard', True)
|
||||
self.close()
|
||||
|
||||
def url_get_file(self, url, f_path):
|
||||
def url_get_file(self, url, f_path, sha256=None):
|
||||
""""
|
||||
Download a file given a URL. The file is retrieved in chunks, giving the ability to cancel the download at any
|
||||
point. Returns False on download error.
|
||||
@ -396,7 +398,11 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
block_count += 1
|
||||
self._download_progress(block_count, block_size)
|
||||
filename.close()
|
||||
except ConnectionError:
|
||||
if sha256 and hashlib.sha256(open(f_path, 'rb').read()).hexdigest() != sha256:
|
||||
log.error('sha256 sums did not match for file: {}'.format(f_path))
|
||||
os.remove(f_path)
|
||||
return False
|
||||
except urllib.error.URLError:
|
||||
trace_error_handler(log)
|
||||
filename.close()
|
||||
os.remove(f_path)
|
||||
@ -436,7 +442,7 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
site = urllib.request.urlopen(url, timeout=CONNECTION_TIMEOUT)
|
||||
meta = site.info()
|
||||
return int(meta.get("Content-Length"))
|
||||
except ConnectionException:
|
||||
except urllib.error.URLError:
|
||||
if retries > CONNECTION_RETRIES:
|
||||
raise
|
||||
else:
|
||||
@ -478,7 +484,7 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
self.application.process_events()
|
||||
item = self.songs_list_widget.item(i)
|
||||
if item.checkState() == QtCore.Qt.Checked:
|
||||
filename = item.data(QtCore.Qt.UserRole)
|
||||
filename, _ = item.data(QtCore.Qt.UserRole)
|
||||
size = self._get_file_size('%s%s' % (self.songs_url, filename))
|
||||
self.max_progress += size
|
||||
# Loop through the Bibles list and increase for each selected item
|
||||
@ -499,7 +505,7 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
filename = item.data(QtCore.Qt.UserRole)
|
||||
size = self._get_file_size('%s%s' % (self.themes_url, filename))
|
||||
self.max_progress += size
|
||||
except ConnectionError:
|
||||
except urllib.error.URLError:
|
||||
trace_error_handler(log)
|
||||
critical_error_message_box(translate('OpenLP.FirstTimeWizard', 'Download Error'),
|
||||
translate('OpenLP.FirstTimeWizard', 'There was a connection problem during '
|
||||
@ -595,11 +601,11 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
for i in range(self.songs_list_widget.count()):
|
||||
item = self.songs_list_widget.item(i)
|
||||
if item.checkState() == QtCore.Qt.Checked:
|
||||
filename = item.data(QtCore.Qt.UserRole)
|
||||
filename, sha256 = item.data(QtCore.Qt.UserRole)
|
||||
self._increment_progress_bar(self.downloading % filename, 0)
|
||||
self.previous_size = 0
|
||||
destination = os.path.join(songs_destination, str(filename))
|
||||
if not self.url_get_file('%s%s' % (self.songs_url, filename), destination):
|
||||
if not self.url_get_file('%s%s' % (self.songs_url, filename), destination, sha256):
|
||||
return False
|
||||
# Download Bibles
|
||||
bibles_iterator = QtGui.QTreeWidgetItemIterator(self.bibles_tree_widget)
|
||||
|
@ -144,8 +144,9 @@ class BibleDB(QtCore.QObject, Manager, RegistryProperties):
|
||||
if 'file' in kwargs:
|
||||
self.file = kwargs['file']
|
||||
Manager.__init__(self, 'bibles', init_schema, self.file, upgrade)
|
||||
if 'file' in kwargs:
|
||||
self.get_name()
|
||||
if self.session:
|
||||
if 'file' in kwargs:
|
||||
self.get_name()
|
||||
if 'path' in kwargs:
|
||||
self.path = kwargs['path']
|
||||
self.wizard = None
|
||||
|
@ -121,6 +121,8 @@ class BibleManager(RegistryProperties):
|
||||
self.old_bible_databases = []
|
||||
for filename in files:
|
||||
bible = BibleDB(self.parent, path=self.path, file=filename)
|
||||
if not bible.session:
|
||||
continue
|
||||
name = bible.get_name()
|
||||
# Remove corrupted files.
|
||||
if name is None:
|
||||
|
Loading…
Reference in New Issue
Block a user