forked from openlp/openlp
Made the FTW able to handle if the downloaded config file is invalid (part of bug 1222944).
Improved FTW handling of connection issues. Update thememanager widget after theme import. Close song db session after import to unlock file on windows, so they can be deleted. Fix for importing old bible DBs, like KJV Removed old pyinstaller hooks which has been moved to the packaging branch. When bible or song plugin is disabled in FTW don't show download for those plugins in FTW. Fixes bug 1194622. bzr-revno: 2450
This commit is contained in:
commit
46641fecbe
@ -302,7 +302,7 @@ class Renderer(OpenLPMixin, RegistryMixin, RegistryProperties):
|
||||
lines = text.strip('\n').split('\n')
|
||||
pages.extend(self._paginate_slide(lines, line_end))
|
||||
break
|
||||
count =+ 1
|
||||
count += 1
|
||||
else:
|
||||
# Clean up line endings.
|
||||
pages = self._paginate_slide(text.split('\n'), line_end)
|
||||
|
@ -37,14 +37,15 @@ import urllib.request
|
||||
import urllib.parse
|
||||
import urllib.error
|
||||
from tempfile import gettempdir
|
||||
from configparser import ConfigParser
|
||||
from configparser import ConfigParser, MissingSectionHeaderError, NoSectionError, NoOptionError
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.common import Registry, RegistryProperties, AppLocation, Settings, check_directory_exists, \
|
||||
translate, clean_button_text
|
||||
translate, clean_button_text, trace_error_handler
|
||||
from openlp.core.lib import PluginStatus, build_icon
|
||||
from openlp.core.utils import get_web_page
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.core.utils import get_web_page, CONNECTION_RETRIES, CONNECTION_TIMEOUT
|
||||
from .firsttimewizard import UiFirstTimeWizard, FirstTimePage
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@ -89,27 +90,32 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
super(FirstTimeForm, self).__init__(parent)
|
||||
self.setup_ui(self)
|
||||
|
||||
def get_next_page_id(self):
|
||||
"""
|
||||
Returns the id of the next FirstTimePage to go to based on enabled plugins
|
||||
"""
|
||||
# The songs plugin is enabled
|
||||
if FirstTimePage.Welcome < self.currentId() < FirstTimePage.Songs and self.songs_check_box.isChecked():
|
||||
print('Go for songs! %r' % self.songs_check_box.isChecked())
|
||||
return FirstTimePage.Songs
|
||||
# The Bibles plugin is enabled
|
||||
elif FirstTimePage.Welcome < self.currentId() < FirstTimePage.Bibles and self.bible_check_box.isChecked():
|
||||
return FirstTimePage.Bibles
|
||||
elif FirstTimePage.Welcome < self.currentId() < FirstTimePage.Themes:
|
||||
return FirstTimePage.Themes
|
||||
else:
|
||||
return self.currentId() + 1
|
||||
|
||||
def nextId(self):
|
||||
"""
|
||||
Determine the next page in the Wizard to go to.
|
||||
"""
|
||||
self.application.process_events()
|
||||
if self.currentId() == FirstTimePage.Plugins:
|
||||
if self.has_run_wizard:
|
||||
self.songs_check_box.setChecked(self.plugin_manager.get_plugin_by_name('songs').is_active())
|
||||
self.bible_check_box.setChecked(self.plugin_manager.get_plugin_by_name('bibles').is_active())
|
||||
self.presentation_check_box.setChecked(self.plugin_manager.get_plugin_by_name(
|
||||
'presentations').is_active())
|
||||
self.image_check_box.setChecked(self.plugin_manager.get_plugin_by_name('images').is_active())
|
||||
self.media_check_box.setChecked(self.plugin_manager.get_plugin_by_name('media').is_active())
|
||||
self.remote_check_box.setChecked(self.plugin_manager.get_plugin_by_name('remotes').is_active())
|
||||
self.custom_check_box.setChecked(self.plugin_manager.get_plugin_by_name('custom').is_active())
|
||||
self.song_usage_check_box.setChecked(self.plugin_manager.get_plugin_by_name('songusage').is_active())
|
||||
self.alert_check_box.setChecked(self.plugin_manager.get_plugin_by_name('alerts').is_active())
|
||||
if not self.web_access:
|
||||
return FirstTimePage.NoInternet
|
||||
else:
|
||||
return FirstTimePage.Songs
|
||||
return self.get_next_page_id()
|
||||
elif self.currentId() == FirstTimePage.Progress:
|
||||
return -1
|
||||
elif self.currentId() == FirstTimePage.NoInternet:
|
||||
@ -124,7 +130,7 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
self.application.set_normal_cursor()
|
||||
return FirstTimePage.Defaults
|
||||
else:
|
||||
return self.currentId() + 1
|
||||
return self.get_next_page_id()
|
||||
|
||||
def exec_(self):
|
||||
"""
|
||||
@ -141,17 +147,23 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
"""
|
||||
self.screens = screens
|
||||
# check to see if we have web access
|
||||
self.web_access = False
|
||||
self.web = 'http://openlp.org/files/frw/'
|
||||
self.config = ConfigParser()
|
||||
user_agent = 'OpenLP/' + Registry().get('application').applicationVersion()
|
||||
self.web_access = get_web_page('%s%s' % (self.web, 'download.cfg'), header=('User-Agent', user_agent))
|
||||
if self.web_access:
|
||||
files = self.web_access.read()
|
||||
self.config.read_string(files.decode())
|
||||
self.web = self.config.get('general', 'base url')
|
||||
self.songs_url = self.web + self.config.get('songs', 'directory') + '/'
|
||||
self.bibles_url = self.web + self.config.get('bibles', 'directory') + '/'
|
||||
self.themes_url = self.web + self.config.get('themes', 'directory') + '/'
|
||||
web_config = get_web_page('%s%s' % (self.web, 'download.cfg'), header=('User-Agent', user_agent))
|
||||
if web_config:
|
||||
files = web_config.read()
|
||||
try:
|
||||
self.config.read_string(files.decode())
|
||||
self.web = self.config.get('general', 'base url')
|
||||
self.songs_url = self.web + self.config.get('songs', 'directory') + '/'
|
||||
self.bibles_url = self.web + self.config.get('bibles', 'directory') + '/'
|
||||
self.themes_url = self.web + self.config.get('themes', 'directory') + '/'
|
||||
self.web_access = True
|
||||
except (NoSectionError, NoOptionError, MissingSectionHeaderError):
|
||||
log.debug('A problem occured while parsing the downloaded config file')
|
||||
trace_error_handler(log)
|
||||
self.update_screen_list_combo()
|
||||
self.was_download_cancelled = False
|
||||
self.theme_screenshot_thread = None
|
||||
@ -171,6 +183,17 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
self.no_internet_finish_button.setVisible(False)
|
||||
# Check if this is a re-run of the wizard.
|
||||
self.has_run_wizard = Settings().value('core/has run wizard')
|
||||
if self.has_run_wizard:
|
||||
self.songs_check_box.setChecked(self.plugin_manager.get_plugin_by_name('songs').is_active())
|
||||
self.bible_check_box.setChecked(self.plugin_manager.get_plugin_by_name('bibles').is_active())
|
||||
self.presentation_check_box.setChecked(self.plugin_manager.get_plugin_by_name('presentations').is_active())
|
||||
self.image_check_box.setChecked(self.plugin_manager.get_plugin_by_name('images').is_active())
|
||||
self.media_check_box.setChecked(self.plugin_manager.get_plugin_by_name('media').is_active())
|
||||
self.remote_check_box.setChecked(self.plugin_manager.get_plugin_by_name('remotes').is_active())
|
||||
self.custom_check_box.setChecked(self.plugin_manager.get_plugin_by_name('custom').is_active())
|
||||
self.song_usage_check_box.setChecked(self.plugin_manager.get_plugin_by_name('songusage').is_active())
|
||||
self.alert_check_box.setChecked(self.plugin_manager.get_plugin_by_name('alerts').is_active())
|
||||
self.application.set_normal_cursor()
|
||||
# Sort out internet access for downloads
|
||||
if self.web_access:
|
||||
songs = self.config.get('songs', 'languages')
|
||||
@ -200,7 +223,6 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
# Download the theme screenshots.
|
||||
self.theme_screenshot_thread = ThemeScreenshotThread(self)
|
||||
self.theme_screenshot_thread.start()
|
||||
self.application.set_normal_cursor()
|
||||
|
||||
def update_screen_list_combo(self):
|
||||
"""
|
||||
@ -286,24 +308,42 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
def url_get_file(self, url, f_path):
|
||||
""""
|
||||
Download a file given a URL. The file is retrieved in chunks, giving the ability to cancel the download at any
|
||||
point.
|
||||
point. Returns False on download error.
|
||||
|
||||
:param url: URL to download
|
||||
:param f_path: Destination file
|
||||
"""
|
||||
block_count = 0
|
||||
block_size = 4096
|
||||
url_file = urllib.request.urlopen(url)
|
||||
filename = open(f_path, "wb")
|
||||
# Download until finished or canceled.
|
||||
while not self.was_download_cancelled:
|
||||
data = url_file.read(block_size)
|
||||
if not data:
|
||||
break
|
||||
filename.write(data)
|
||||
block_count += 1
|
||||
self._download_progress(block_count, block_size)
|
||||
filename.close()
|
||||
retries = 0
|
||||
while True:
|
||||
try:
|
||||
url_file = urllib.request.urlopen(url, timeout=CONNECTION_TIMEOUT)
|
||||
filename = open(f_path, "wb")
|
||||
# Download until finished or canceled.
|
||||
while not self.was_download_cancelled:
|
||||
data = url_file.read(block_size)
|
||||
if not data:
|
||||
break
|
||||
filename.write(data)
|
||||
block_count += 1
|
||||
self._download_progress(block_count, block_size)
|
||||
filename.close()
|
||||
except ConnectionError:
|
||||
trace_error_handler(log)
|
||||
filename.close()
|
||||
os.remove(f_path)
|
||||
if retries > CONNECTION_RETRIES:
|
||||
return False
|
||||
else:
|
||||
retries += 1
|
||||
time.sleep(0.1)
|
||||
continue
|
||||
break
|
||||
# Delete file if cancelled, it may be a partial file.
|
||||
if self.was_download_cancelled:
|
||||
os.remove(f_path)
|
||||
return True
|
||||
|
||||
def _build_theme_screenshots(self):
|
||||
"""
|
||||
@ -322,9 +362,19 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
|
||||
:param url: The URL of the file we want to download.
|
||||
"""
|
||||
site = urllib.request.urlopen(url)
|
||||
meta = site.info()
|
||||
return int(meta.get("Content-Length"))
|
||||
retries = 0
|
||||
while True:
|
||||
try:
|
||||
site = urllib.request.urlopen(url, timeout=CONNECTION_TIMEOUT)
|
||||
meta = site.info()
|
||||
return int(meta.get("Content-Length"))
|
||||
except ConnectionException:
|
||||
if retries > CONNECTION_RETRIES:
|
||||
raise
|
||||
else:
|
||||
retries += 1
|
||||
time.sleep(0.1)
|
||||
continue
|
||||
|
||||
def _download_progress(self, count, block_size):
|
||||
"""
|
||||
@ -354,32 +404,41 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
self.max_progress = 0
|
||||
self.finish_button.setVisible(False)
|
||||
self.application.process_events()
|
||||
# Loop through the songs list and increase for each selected item
|
||||
for i in range(self.songs_list_widget.count()):
|
||||
self.application.process_events()
|
||||
item = self.songs_list_widget.item(i)
|
||||
if item.checkState() == QtCore.Qt.Checked:
|
||||
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
|
||||
iterator = QtGui.QTreeWidgetItemIterator(self.bibles_tree_widget)
|
||||
while iterator.value():
|
||||
self.application.process_events()
|
||||
item = iterator.value()
|
||||
if item.parent() and item.checkState(0) == QtCore.Qt.Checked:
|
||||
filename = item.data(0, QtCore.Qt.UserRole)
|
||||
size = self._get_file_size('%s%s' % (self.bibles_url, filename))
|
||||
self.max_progress += size
|
||||
iterator += 1
|
||||
# Loop through the themes list and increase for each selected item
|
||||
for i in range(self.themes_list_widget.count()):
|
||||
self.application.process_events()
|
||||
item = self.themes_list_widget.item(i)
|
||||
if item.checkState() == QtCore.Qt.Checked:
|
||||
filename = item.data(QtCore.Qt.UserRole)
|
||||
size = self._get_file_size('%s%s' % (self.themes_url, filename))
|
||||
self.max_progress += size
|
||||
try:
|
||||
# Loop through the songs list and increase for each selected item
|
||||
for i in range(self.songs_list_widget.count()):
|
||||
self.application.process_events()
|
||||
item = self.songs_list_widget.item(i)
|
||||
if item.checkState() == QtCore.Qt.Checked:
|
||||
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
|
||||
iterator = QtGui.QTreeWidgetItemIterator(self.bibles_tree_widget)
|
||||
while iterator.value():
|
||||
self.application.process_events()
|
||||
item = iterator.value()
|
||||
if item.parent() and item.checkState(0) == QtCore.Qt.Checked:
|
||||
filename = item.data(0, QtCore.Qt.UserRole)
|
||||
size = self._get_file_size('%s%s' % (self.bibles_url, filename))
|
||||
self.max_progress += size
|
||||
iterator += 1
|
||||
# Loop through the themes list and increase for each selected item
|
||||
for i in range(self.themes_list_widget.count()):
|
||||
self.application.process_events()
|
||||
item = self.themes_list_widget.item(i)
|
||||
if item.checkState() == QtCore.Qt.Checked:
|
||||
filename = item.data(QtCore.Qt.UserRole)
|
||||
size = self._get_file_size('%s%s' % (self.themes_url, filename))
|
||||
self.max_progress += size
|
||||
except ConnectionError:
|
||||
trace_error_handler(log)
|
||||
critical_error_message_box(translate('OpenLP.FirstTimeWizard', 'Download Error'),
|
||||
translate('OpenLP.FirstTimeWizard', 'There was a connection problem during '
|
||||
'download, so further downloads will be skipped. Try to re-run the '
|
||||
'First Time Wizard later.'))
|
||||
self.max_progress = 0
|
||||
self.web_access = None
|
||||
if self.max_progress:
|
||||
# Add on 2 for plugins status setting plus a "finished" point.
|
||||
self.max_progress += 2
|
||||
@ -443,38 +502,11 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
self._set_plugin_status(self.song_usage_check_box, 'songusage/status')
|
||||
self._set_plugin_status(self.alert_check_box, 'alerts/status')
|
||||
if self.web_access:
|
||||
# Build directories for downloads
|
||||
songs_destination = os.path.join(gettempdir(), 'openlp')
|
||||
bibles_destination = AppLocation.get_section_data_path('bibles')
|
||||
themes_destination = AppLocation.get_section_data_path('themes')
|
||||
# Download songs
|
||||
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)
|
||||
self._increment_progress_bar(self.downloading % filename, 0)
|
||||
self.previous_size = 0
|
||||
destination = os.path.join(songs_destination, str(filename))
|
||||
self.url_get_file('%s%s' % (self.songs_url, filename), destination)
|
||||
# Download Bibles
|
||||
bibles_iterator = QtGui.QTreeWidgetItemIterator(
|
||||
self.bibles_tree_widget)
|
||||
while bibles_iterator.value():
|
||||
item = bibles_iterator.value()
|
||||
if item.parent() and item.checkState(0) == QtCore.Qt.Checked:
|
||||
bible = item.data(0, QtCore.Qt.UserRole)
|
||||
self._increment_progress_bar(self.downloading % bible, 0)
|
||||
self.previous_size = 0
|
||||
self.url_get_file('%s%s' % (self.bibles_url, bible), os.path.join(bibles_destination, bible))
|
||||
bibles_iterator += 1
|
||||
# Download themes
|
||||
for i in range(self.themes_list_widget.count()):
|
||||
item = self.themes_list_widget.item(i)
|
||||
if item.checkState() == QtCore.Qt.Checked:
|
||||
theme = item.data(QtCore.Qt.UserRole)
|
||||
self._increment_progress_bar(self.downloading % theme, 0)
|
||||
self.previous_size = 0
|
||||
self.url_get_file('%s%s' % (self.themes_url, theme), os.path.join(themes_destination, theme))
|
||||
if not self._download_selected():
|
||||
critical_error_message_box(translate('OpenLP.FirstTimeWizard', 'Download Error'),
|
||||
translate('OpenLP.FirstTimeWizard', 'There was a connection problem while '
|
||||
'downloading, so further downloads will be skipped. Try to re-run '
|
||||
'the First Time Wizard later.'))
|
||||
# Set Default Display
|
||||
if self.display_combo_box.currentIndex() != -1:
|
||||
Settings().setValue('core/monitor', self.display_combo_box.currentIndex())
|
||||
@ -483,6 +515,46 @@ class FirstTimeForm(QtGui.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
if self.theme_combo_box.currentIndex() != -1:
|
||||
Settings().setValue('themes/global theme', self.theme_combo_box.currentText())
|
||||
|
||||
def _download_selected(self):
|
||||
"""
|
||||
Download selected songs, bibles and themes. Returns False on download error
|
||||
"""
|
||||
# Build directories for downloads
|
||||
songs_destination = os.path.join(gettempdir(), 'openlp')
|
||||
bibles_destination = AppLocation.get_section_data_path('bibles')
|
||||
themes_destination = AppLocation.get_section_data_path('themes')
|
||||
# Download songs
|
||||
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)
|
||||
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):
|
||||
return False
|
||||
# Download Bibles
|
||||
bibles_iterator = QtGui.QTreeWidgetItemIterator(self.bibles_tree_widget)
|
||||
while bibles_iterator.value():
|
||||
item = bibles_iterator.value()
|
||||
if item.parent() and item.checkState(0) == QtCore.Qt.Checked:
|
||||
bible = item.data(0, QtCore.Qt.UserRole)
|
||||
self._increment_progress_bar(self.downloading % bible, 0)
|
||||
self.previous_size = 0
|
||||
if not self.url_get_file('%s%s' % (self.bibles_url, bible), os.path.join(bibles_destination, bible)):
|
||||
return False
|
||||
bibles_iterator += 1
|
||||
# Download themes
|
||||
for i in range(self.themes_list_widget.count()):
|
||||
item = self.themes_list_widget.item(i)
|
||||
if item.checkState() == QtCore.Qt.Checked:
|
||||
theme = item.data(QtCore.Qt.UserRole)
|
||||
self._increment_progress_bar(self.downloading % theme, 0)
|
||||
self.previous_size = 0
|
||||
if not self.url_get_file('%s%s' % (self.themes_url, theme), os.path.join(themes_destination, theme)):
|
||||
return False
|
||||
return True
|
||||
|
||||
def _set_plugin_status(self, field, tag):
|
||||
"""
|
||||
Set the status of a plugin.
|
||||
|
@ -706,7 +706,10 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow, RegistryProperties):
|
||||
self.active_plugin.toggle_status(PluginStatus.Inactive)
|
||||
# Set global theme and
|
||||
Registry().execute('theme_update_global')
|
||||
# Load the themes from files
|
||||
self.theme_manager_contents.load_first_time_themes()
|
||||
# Update the theme widget
|
||||
self.theme_manager_contents.load_themes()
|
||||
# Check if any Bibles downloaded. If there are, they will be processed.
|
||||
Registry().execute('bibles_load_list', True)
|
||||
self.application.set_normal_cursor()
|
||||
|
@ -35,6 +35,7 @@ import logging
|
||||
import locale
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
from subprocess import Popen, PIPE
|
||||
import sys
|
||||
import urllib.request
|
||||
@ -91,6 +92,8 @@ USER_AGENTS = {
|
||||
'Mozilla/5.0 (X11; NetBSD amd64; rv:18.0) Gecko/20130120 Firefox/18.0'
|
||||
]
|
||||
}
|
||||
CONNECTION_TIMEOUT = 30
|
||||
CONNECTION_RETRIES = 2
|
||||
|
||||
|
||||
class VersionThread(QtCore.QThread):
|
||||
@ -250,10 +253,19 @@ def check_latest_version(current_version):
|
||||
req = urllib.request.Request('http://www.openlp.org/files/version.txt')
|
||||
req.add_header('User-Agent', 'OpenLP/%s' % current_version['full'])
|
||||
remote_version = None
|
||||
try:
|
||||
remote_version = str(urllib.request.urlopen(req, None).read().decode()).strip()
|
||||
except IOError:
|
||||
log.exception('Failed to download the latest OpenLP version file')
|
||||
retries = 0
|
||||
while True:
|
||||
try:
|
||||
remote_version = str(urllib.request.urlopen(req, None,
|
||||
timeout=CONNECTION_TIMEOUT).read().decode()).strip()
|
||||
except ConnectionException:
|
||||
if retries > CONNECTION_RETRIES:
|
||||
log.exception('Failed to download the latest OpenLP version file')
|
||||
else:
|
||||
retries += 1
|
||||
time.sleep(0.1)
|
||||
continue
|
||||
break
|
||||
if remote_version:
|
||||
version_string = remote_version
|
||||
return version_string
|
||||
@ -389,11 +401,19 @@ def get_web_page(url, header=None, update_openlp=False):
|
||||
req.add_header(header[0], header[1])
|
||||
page = None
|
||||
log.debug('Downloading URL = %s' % url)
|
||||
try:
|
||||
page = urllib.request.urlopen(req)
|
||||
log.debug('Downloaded URL = %s' % page.geturl())
|
||||
except urllib.error.URLError:
|
||||
log.exception('The web page could not be downloaded')
|
||||
retries = 0
|
||||
while True:
|
||||
try:
|
||||
page = urllib.request.urlopen(req, timeout=CONNECTION_TIMEOUT)
|
||||
log.debug('Downloaded URL = %s' % page.geturl())
|
||||
except (urllib.error.URLError, ConnectionError):
|
||||
if retries > CONNECTION_RETRIES:
|
||||
log.exception('The web page could not be downloaded')
|
||||
raise
|
||||
else:
|
||||
time.sleep(0.1)
|
||||
continue
|
||||
break
|
||||
if not page:
|
||||
return None
|
||||
if update_openlp:
|
||||
|
@ -159,7 +159,7 @@ class BiblePlugin(Plugin):
|
||||
self.upgrade_wizard = BibleUpgradeForm(self.main_window, self.manager, self)
|
||||
# If the import was not cancelled then reload.
|
||||
if self.upgrade_wizard.exec_():
|
||||
self.media_item.reloadBibles()
|
||||
self.media_item.reload_bibles()
|
||||
|
||||
def on_bible_import_click(self):
|
||||
if self.media_item:
|
||||
|
@ -170,6 +170,9 @@ class BibleDB(QtCore.QObject, Manager, RegistryProperties):
|
||||
Returns the version name of the Bible.
|
||||
"""
|
||||
version_name = self.get_object(BibleMeta, 'name')
|
||||
# Fallback to old way of naming
|
||||
if not version_name:
|
||||
version_name = self.get_object(BibleMeta, 'Version')
|
||||
self.name = version_name.value if version_name else None
|
||||
return self.name
|
||||
|
||||
@ -969,11 +972,15 @@ class OldBibleDB(QtCore.QObject, Manager):
|
||||
"""
|
||||
Returns the version name of the Bible.
|
||||
"""
|
||||
self.name = None
|
||||
version_name = self.run_sql('SELECT value FROM metadata WHERE key = "name"')
|
||||
if version_name:
|
||||
self.name = version_name[0][0]
|
||||
else:
|
||||
self.name = None
|
||||
# Fallback to old way of naming
|
||||
version_name = self.run_sql('SELECT value FROM metadata WHERE key = "Version"')
|
||||
if version_name:
|
||||
self.name = version_name[0][0]
|
||||
return self.name
|
||||
|
||||
def get_metadata(self):
|
||||
|
@ -217,4 +217,5 @@ class OpenLPSongImport(SongImport):
|
||||
self.import_wizard.increment_progress_bar(WizardStrings.ImportingType % new_song.title)
|
||||
if self.stop_import_flag:
|
||||
break
|
||||
self.source_session.close()
|
||||
engine.dispose()
|
||||
|
@ -1,32 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2014 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2014 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
|
||||
# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. #
|
||||
# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, #
|
||||
# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
|
||||
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, #
|
||||
# Frode Woldsund, Martin Zibricky, Patrick Zimmermann #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
# Software Foundation; version 2 of the License. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT #
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
||||
# more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License along #
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
hiddenimports = ['openlp.core.ui.media.phononplayer',
|
||||
'openlp.core.ui.media.vlcplayer',
|
||||
'openlp.core.ui.media.webkitplayer']
|
@ -1,33 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2014 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2014 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
|
||||
# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. #
|
||||
# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, #
|
||||
# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
|
||||
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, #
|
||||
# Frode Woldsund, Martin Zibricky, Patrick Zimmermann #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
# Software Foundation; version 2 of the License. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT #
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
||||
# more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License along #
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
hiddenimports = ['openlp.plugins.presentations.lib.impresscontroller',
|
||||
'openlp.plugins.presentations.lib.powerpointcontroller',
|
||||
'openlp.plugins.presentations.lib.pptviewcontroller',
|
||||
'openlp.plugins.presentations.lib.pdfcontroller']
|
@ -1,38 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2014 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2014 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
|
||||
# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. #
|
||||
# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, #
|
||||
# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
|
||||
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, #
|
||||
# Frode Woldsund, Martin Zibricky, Patrick Zimmermann #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
# Software Foundation; version 2 of the License. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT #
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
||||
# more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License along #
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
hiddenimports = ['plugins.songs.songsplugin',
|
||||
'plugins.bibles.bibleplugin',
|
||||
'plugins.presentations.presentationplugin',
|
||||
'plugins.media.mediaplugin',
|
||||
'plugins.images.imageplugin',
|
||||
'plugins.custom.customplugin',
|
||||
'plugins.songusage.songusageplugin',
|
||||
'plugins.remotes.remoteplugin',
|
||||
'plugins.alerts.alertsplugin']
|
@ -49,6 +49,22 @@ directory = bibles
|
||||
directory = themes
|
||||
"""
|
||||
|
||||
FAKE_BROKEN_CONFIG = b"""
|
||||
[general]
|
||||
base url = http://example.com/frw/
|
||||
[songs]
|
||||
directory = songs
|
||||
[bibles]
|
||||
directory = bibles
|
||||
"""
|
||||
|
||||
FAKE_INVALID_CONFIG = b"""
|
||||
<html>
|
||||
<head><title>This is not a config file</title></head>
|
||||
<body>Some text</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
|
||||
class TestFirstTimeForm(TestCase, TestMixin):
|
||||
|
||||
@ -104,3 +120,33 @@ class TestFirstTimeForm(TestCase, TestMixin):
|
||||
self.assertEqual(expected_songs_url, first_time_form.songs_url, 'The songs URL should be correct')
|
||||
self.assertEqual(expected_bibles_url, first_time_form.bibles_url, 'The bibles URL should be correct')
|
||||
self.assertEqual(expected_themes_url, first_time_form.themes_url, 'The themes URL should be correct')
|
||||
|
||||
def broken_config_test(self):
|
||||
"""
|
||||
Test if we can handle an config file with missing data
|
||||
"""
|
||||
# GIVEN: A mocked get_web_page, a First Time Wizard, an expected screen object, and a mocked broken config file
|
||||
with patch('openlp.core.ui.firsttimeform.get_web_page') as mocked_get_web_page:
|
||||
first_time_form = FirstTimeForm(None)
|
||||
mocked_get_web_page.return_value.read.return_value = FAKE_BROKEN_CONFIG
|
||||
|
||||
# WHEN: The First Time Wizard is initialised
|
||||
first_time_form.initialize(MagicMock())
|
||||
|
||||
# THEN: The First Time Form should not have web access
|
||||
self.assertFalse(first_time_form.web_access, 'There should not be web access with a broken config file')
|
||||
|
||||
def invalid_config_test(self):
|
||||
"""
|
||||
Test if we can handle an config file in invalid format
|
||||
"""
|
||||
# GIVEN: A mocked get_web_page, a First Time Wizard, an expected screen object, and a mocked invalid config file
|
||||
with patch('openlp.core.ui.firsttimeform.get_web_page') as mocked_get_web_page:
|
||||
first_time_form = FirstTimeForm(None)
|
||||
mocked_get_web_page.return_value.read.return_value = FAKE_INVALID_CONFIG
|
||||
|
||||
# WHEN: The First Time Wizard is initialised
|
||||
first_time_form.initialize(MagicMock())
|
||||
|
||||
# THEN: The First Time Form should not have web access
|
||||
self.assertFalse(first_time_form.web_access, 'There should not be web access with an invalid config file')
|
||||
|
@ -335,7 +335,7 @@ class TestUtils(TestCase):
|
||||
self.assertEqual(1, mocked_request_object.add_header.call_count,
|
||||
'There should only be 1 call to add_header')
|
||||
mock_get_user_agent.assert_called_with()
|
||||
mock_urlopen.assert_called_with(mocked_request_object)
|
||||
mock_urlopen.assert_called_with(mocked_request_object, timeout=30)
|
||||
mocked_page_object.geturl.assert_called_with()
|
||||
self.assertEqual(0, MockRegistry.call_count, 'The Registry() object should have never been called')
|
||||
self.assertEqual(mocked_page_object, returned_page, 'The returned page should be the mock object')
|
||||
@ -365,7 +365,7 @@ class TestUtils(TestCase):
|
||||
self.assertEqual(2, mocked_request_object.add_header.call_count,
|
||||
'There should only be 2 calls to add_header')
|
||||
mock_get_user_agent.assert_called_with()
|
||||
mock_urlopen.assert_called_with(mocked_request_object)
|
||||
mock_urlopen.assert_called_with(mocked_request_object, timeout=30)
|
||||
mocked_page_object.geturl.assert_called_with()
|
||||
self.assertEqual(mocked_page_object, returned_page, 'The returned page should be the mock object')
|
||||
|
||||
@ -393,7 +393,7 @@ class TestUtils(TestCase):
|
||||
self.assertEqual(1, mocked_request_object.add_header.call_count,
|
||||
'There should only be 1 call to add_header')
|
||||
self.assertEqual(0, mock_get_user_agent.call_count, '_get_user_agent should not have been called')
|
||||
mock_urlopen.assert_called_with(mocked_request_object)
|
||||
mock_urlopen.assert_called_with(mocked_request_object, timeout=30)
|
||||
mocked_page_object.geturl.assert_called_with()
|
||||
self.assertEqual(mocked_page_object, returned_page, 'The returned page should be the mock object')
|
||||
|
||||
@ -425,7 +425,7 @@ class TestUtils(TestCase):
|
||||
mocked_request_object.add_header.assert_called_with('User-Agent', 'user_agent')
|
||||
self.assertEqual(1, mocked_request_object.add_header.call_count,
|
||||
'There should only be 1 call to add_header')
|
||||
mock_urlopen.assert_called_with(mocked_request_object)
|
||||
mock_urlopen.assert_called_with(mocked_request_object, timeout=30)
|
||||
mocked_page_object.geturl.assert_called_with()
|
||||
mocked_registry_object.get.assert_called_with('application')
|
||||
mocked_application_object.process_events.assert_called_with()
|
||||
|
Loading…
Reference in New Issue
Block a user