← Back to team overview

openlp-core team mailing list archive

Re: [Merge] lp:~tomasgroth/openlp/ftw-issues into lp:openlp

 

See answers to comments below.

Besides the bugreport linked the issues are some I've found on the forum or experienced myself.

Diff comments:

> === modified file 'openlp/core/ui/firsttimeform.py'
> --- openlp/core/ui/firsttimeform.py	2014-11-01 10:38:33 +0000
> +++ openlp/core/ui/firsttimeform.py	2014-11-07 12:10:59 +0000
> @@ -37,13 +37,14 @@
>  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.lib.ui import critical_error_message_box
>  from openlp.core.utils import get_web_page
>  from .firsttimewizard import UiFirstTimeWizard, FirstTimePage
>  
> @@ -130,17 +131,23 @@
>          """
>          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)

If an exception is thrown self.web_access is never set to true, and the FTW will display the text about internet connection problem.

>          self.update_screen_list_combo()
>          self.was_download_cancelled = False
>          self.theme_screenshot_thread = None
> @@ -275,24 +282,34 @@
>      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()
> +        try:
> +            url_file = urllib.request.urlopen(url, timeout=30)
> +            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)
> +            return False
>          # 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):
>          """
> @@ -311,7 +328,7 @@
>  
>          :param url: The URL of the file we want to download.
>          """
> -        site = urllib.request.urlopen(url)
> +        site = urllib.request.urlopen(url, timeout=30)
>          meta = site.info()
>          return int(meta.get("Content-Length"))
>  
> @@ -343,32 +360,41 @@
>          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
> @@ -432,38 +458,11 @@
>          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())
> @@ -472,6 +471,46 @@
>          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.
> 
> === modified file 'openlp/core/ui/mainwindow.py'
> --- openlp/core/ui/mainwindow.py	2014-10-23 22:16:38 +0000
> +++ openlp/core/ui/mainwindow.py	2014-11-07 12:10:59 +0000
> @@ -706,7 +706,10 @@
>                      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()

bootstrap_post_set_up is only called at startup it seems, not is FTW is activated from the menu.

>          # Check if any Bibles downloaded.  If there are, they will be processed.
>          Registry().execute('bibles_load_list', True)
>          self.application.set_normal_cursor()
> 
> === modified file 'openlp/core/utils/__init__.py'
> --- openlp/core/utils/__init__.py	2014-10-22 20:47:47 +0000
> +++ openlp/core/utils/__init__.py	2014-11-07 12:10:59 +0000
> @@ -390,9 +390,9 @@
>      page = None
>      log.debug('Downloading URL = %s' % url)
>      try:
> -        page = urllib.request.urlopen(req)
> +        page = urllib.request.urlopen(req, timeout=30)
>          log.debug('Downloaded URL = %s' % page.geturl())
> -    except urllib.error.URLError:
> +    except (urllib.error.URLError, ConnectionError):
>          log.exception('The web page could not be downloaded')
>      if not page:
>          return None
> 
> === modified file 'openlp/plugins/bibles/bibleplugin.py'
> --- openlp/plugins/bibles/bibleplugin.py	2014-04-12 20:19:22 +0000
> +++ openlp/plugins/bibles/bibleplugin.py	2014-11-07 12:10:59 +0000
> @@ -159,7 +159,7 @@
>              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:
> 
> === modified file 'openlp/plugins/bibles/lib/db.py'
> --- openlp/plugins/bibles/lib/db.py	2014-05-02 06:42:17 +0000
> +++ openlp/plugins/bibles/lib/db.py	2014-11-07 12:10:59 +0000
> @@ -170,6 +170,9 @@
>          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 @@
>          """
>          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):
> 
> === modified file 'openlp/plugins/songs/lib/importers/openlp.py'
> --- openlp/plugins/songs/lib/importers/openlp.py	2014-07-04 09:35:10 +0000
> +++ openlp/plugins/songs/lib/importers/openlp.py	2014-11-07 12:10:59 +0000
> @@ -217,4 +217,5 @@
>                  self.import_wizard.increment_progress_bar(WizardStrings.ImportingType % new_song.title)
>              if self.stop_import_flag:
>                  break
> +        self.source_session.close()
>          engine.dispose()
> 
> === removed directory 'resources/pyinstaller'
> === removed file 'resources/pyinstaller/hook-openlp.core.ui.media.py'
> --- resources/pyinstaller/hook-openlp.core.ui.media.py	2013-12-24 08:56:50 +0000
> +++ resources/pyinstaller/hook-openlp.core.ui.media.py	1970-01-01 00:00:00 +0000
> @@ -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']
> 
> === removed file 'resources/pyinstaller/hook-openlp.plugins.presentations.presentationplugin.py'
> --- resources/pyinstaller/hook-openlp.plugins.presentations.presentationplugin.py	2013-12-29 19:47:54 +0000
> +++ resources/pyinstaller/hook-openlp.plugins.presentations.presentationplugin.py	1970-01-01 00:00:00 +0000
> @@ -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']
> 
> === removed file 'resources/pyinstaller/hook-openlp.py'
> --- resources/pyinstaller/hook-openlp.py	2013-12-24 08:56:50 +0000
> +++ resources/pyinstaller/hook-openlp.py	1970-01-01 00:00:00 +0000
> @@ -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']
> 
> === modified file 'tests/functional/openlp_core_ui/test_firsttimeform.py'
> --- tests/functional/openlp_core_ui/test_firsttimeform.py	2014-10-22 20:43:05 +0000
> +++ tests/functional/openlp_core_ui/test_firsttimeform.py	2014-11-07 12:10:59 +0000
> @@ -49,6 +49,22 @@
>  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 @@
>              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')
> 
> === modified file 'tests/functional/openlp_core_utils/test_utils.py'
> --- tests/functional/openlp_core_utils/test_utils.py	2014-05-02 06:42:17 +0000
> +++ tests/functional/openlp_core_utils/test_utils.py	2014-11-07 12:10:59 +0000
> @@ -335,7 +335,7 @@
>              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 @@
>              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 @@
>              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 @@
>              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()
> 


-- 
https://code.launchpad.net/~tomasgroth/openlp/ftw-issues/+merge/241070
Your team OpenLP Core is subscribed to branch lp:openlp.