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:
Tomas Groth 2014-12-07 08:11:59 +00:00 committed by Tim Bentley
commit 46641fecbe
12 changed files with 263 additions and 217 deletions

View File

@ -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)

View File

@ -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.

View File

@ -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()

View File

@ -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:

View File

@ -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:

View File

@ -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):

View File

@ -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()

View File

@ -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']

View File

@ -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']

View File

@ -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']

View File

@ -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')

View 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()