예제 #1
0
 def find_qm_files():
     """
     Find all available language files in this OpenLP install
     """
     log.debug("Translation files: %s", AppLocation.get_directory(AppLocation.LanguageDir))
     trans_dir = QtCore.QDir(AppLocation.get_directory(AppLocation.LanguageDir))
     file_names = trans_dir.entryList(["*.qm"], QtCore.QDir.Files, QtCore.QDir.Name)
     # Remove qm files from the list which start with "qt_".
     file_names = [file_ for file_ in file_names if not file_.startswith("qt_")]
     return list(map(trans_dir.filePath, file_names))
예제 #2
0
 def find_qm_files():
     """
     Find all available language files in this OpenLP install
     """
     log.debug('Translation files: %s', AppLocation.get_directory(AppLocation.LanguageDir))
     trans_dir = QtCore.QDir(AppLocation.get_directory(AppLocation.LanguageDir))
     file_names = trans_dir.entryList(['*.qm'], QtCore.QDir.Files, QtCore.QDir.Name)
     # Remove qm files from the list which start with "qt_".
     file_names = [file_ for file_ in file_names if not file_.startswith('qt_')]
     return list(map(trans_dir.filePath, file_names))
예제 #3
0
    def check_installed(self):
        """
        Check the viewer is installed.

        :return: True if program to open PDF-files was found, otherwise False.
        """
        log.debug('check_installed Pdf')
        self.mudrawbin = ''
        self.mutoolbin = ''
        self.gsbin = ''
        self.also_supports = []
        # Use the user defined program if given
        if Settings().value('presentations/enable_pdf_program'):
            pdf_program = Settings().value('presentations/pdf_program')
            program_type = self.process_check_binary(pdf_program)
            if program_type == 'gs':
                self.gsbin = pdf_program
            elif program_type == 'mudraw':
                self.mudrawbin = pdf_program
            elif program_type == 'mutool':
                self.mutoolbin = pdf_program
        else:
            # Fallback to autodetection
            application_path = AppLocation.get_directory(AppLocation.AppDir)
            if is_win():
                # for windows we only accept mudraw.exe or mutool.exe in the base folder
                application_path = AppLocation.get_directory(AppLocation.AppDir)
                if os.path.isfile(os.path.join(application_path, 'mudraw.exe')):
                    self.mudrawbin = os.path.join(application_path, 'mudraw.exe')
                elif os.path.isfile(os.path.join(application_path, 'mutool.exe')):
                    self.mutoolbin = os.path.join(application_path, 'mutool.exe')
            else:
                DEVNULL = open(os.devnull, 'wb')
                # First try to find mudraw
                self.mudrawbin = which('mudraw')
                # if mudraw isn't installed, try mutool
                if not self.mudrawbin:
                    self.mutoolbin = which('mutool')
                    # Check we got a working mutool
                    if not self.mutoolbin or self.process_check_binary(self.mutoolbin) != 'mutool':
                        self.gsbin = which('gs')
                # Last option: check if mudraw or mutool is placed in OpenLP base folder
                if not self.mudrawbin and not self.mutoolbin and not self.gsbin:
                    application_path = AppLocation.get_directory(AppLocation.AppDir)
                    if os.path.isfile(os.path.join(application_path, 'mudraw')):
                        self.mudrawbin = os.path.join(application_path, 'mudraw')
                    elif os.path.isfile(os.path.join(application_path, 'mutool')):
                        self.mutoolbin = os.path.join(application_path, 'mutool')
        if self.mudrawbin or self.mutoolbin:
            self.also_supports = ['xps', 'oxps']
            return True
        elif self.gsbin:
            return True
        else:
            return False
예제 #4
0
 def check_pre_conditions(self):
     """
     Check to see if we have any presentation software available. If not do not install the plugin.
     """
     log.debug('check_pre_conditions')
     controller_dir = os.path.join(
         AppLocation.get_directory(AppLocation.PluginsDir), 'presentations',
         'lib')
     for filename in os.listdir(controller_dir):
         if filename.endswith(
                 'controller.py'
         ) and not filename == 'presentationcontroller.py':
             path = os.path.join(controller_dir, filename)
             if os.path.isfile(path):
                 module_name = 'openlp.plugins.presentations.lib.' + os.path.splitext(
                     filename)[0]
                 log.debug('Importing controller %s', module_name)
                 try:
                     __import__(module_name, globals(), locals(), [])
                 except ImportError:
                     log.warning('Failed to import %s on path %s',
                                 module_name, path)
     controller_classes = PresentationController.__subclasses__()
     for controller_class in controller_classes:
         controller = controller_class(self)
         self.register_controllers(controller)
     return bool(self.controllers)
예제 #5
0
 def on_data_directory_default_button_clicked(self):
     """
     Re-set the data directory location to the 'default' location.
     """
     new_data_path = AppLocation.get_directory(AppLocation.DataDir)
     if self.current_data_path.lower() != new_data_path.lower():
         # Make sure they want to change the data location back to the
         # default.
         answer = QtWidgets.QMessageBox.question(self, translate('OpenLP.AdvancedTab', 'Reset Data Directory'),
                                                 translate('OpenLP.AdvancedTab', 'Are you sure you want to change '
                                                                                 'the location of the OpenLP data '
                                                                                 'directory to the default location?'
                                                                                 '\n\nThis location will be used '
                                                                                 'after OpenLP is closed.'),
                                                 QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes |
                                                                                       QtWidgets.QMessageBox.No),
                                                 QtWidgets.QMessageBox.No)
         if answer != QtWidgets.QMessageBox.Yes:
             return
         self.check_data_overwrite(new_data_path)
         # Save the new location.
         self.main_window.set_new_data_path(new_data_path)
         self.new_data_directory_edit.setText(os.path.abspath(new_data_path))
         self.data_directory_cancel_button.show()
     else:
         # We cancel the change in case user changed their mind.
         self.on_data_directory_cancel_button_clicked()
예제 #6
0
 def load(self):
     """
     Load the configuration and update the server configuration if necessary
     """
     self.is_secure = Settings().value(self.settings_section + '/https enabled')
     self.port_spin_box.setValue(Settings().value(self.settings_section + '/port'))
     self.https_port_spin_box.setValue(Settings().value(self.settings_section + '/https port'))
     self.address_edit.setText(Settings().value(self.settings_section + '/ip address'))
     self.twelve_hour = Settings().value(self.settings_section + '/twelve hour')
     self.twelve_hour_check_box.setChecked(self.twelve_hour)
     self.thumbnails = Settings().value(self.settings_section + '/thumbnails')
     self.thumbnails_check_box.setChecked(self.thumbnails)
     local_data = AppLocation.get_directory(AppLocation.DataDir)
     if not os.path.exists(os.path.join(local_data, 'remotes', 'openlp.crt')) or \
             not os.path.exists(os.path.join(local_data, 'remotes', 'openlp.key')):
         self.https_settings_group_box.setChecked(False)
         self.https_settings_group_box.setEnabled(False)
         self.https_error_label.setVisible(True)
     else:
         self.https_settings_group_box.setChecked(Settings().value(self.settings_section + '/https enabled'))
         self.https_settings_group_box.setEnabled(True)
         self.https_error_label.setVisible(False)
     self.user_login_group_box.setChecked(Settings().value(self.settings_section + '/authentication enabled'))
     self.user_id.setText(Settings().value(self.settings_section + '/user id'))
     self.password.setText(Settings().value(self.settings_section + '/password'))
     self.set_urls()
     self.https_changed()
예제 #7
0
 def bootstrap_initialise(self):
     """
     Check to see if we have any media Player's available.
     """
     log.debug('_check_available_media_players')
     controller_dir = os.path.join(AppLocation.get_directory(AppLocation.AppDir), 'core', 'ui', 'media')
     for filename in os.listdir(controller_dir):
         if filename.endswith('player.py') and not filename == 'mediaplayer.py':
             path = os.path.join(controller_dir, filename)
             if os.path.isfile(path):
                 module_name = 'openlp.core.ui.media.' + os.path.splitext(filename)[0]
                 log.debug('Importing controller %s', module_name)
                 try:
                     __import__(module_name, globals(), locals(), [])
                 # On some platforms importing vlc.py might cause
                 # also OSError exceptions. (e.g. Mac OS X)
                 except (ImportError, OSError):
                     log.warning('Failed to import %s on path %s', module_name, path)
     player_classes = MediaPlayer.__subclasses__()
     for player_class in player_classes:
         player = player_class(self)
         self.register_players(player)
     if not self.media_players:
         return False
     saved_players, overridden_player = get_media_players()
     invalid_media_players = \
         [media_player for media_player in saved_players if media_player not in self.media_players or
             not self.media_players[media_player].check_available()]
     if invalid_media_players:
         for invalidPlayer in invalid_media_players:
             saved_players.remove(invalidPlayer)
         set_media_players(saved_players, overridden_player)
     self._set_active_players()
     self._generate_extensions_lists()
     return True
예제 #8
0
 def initialise(self):
     """
     Initialise the router stack and any other variables.
     """
     auth_code = "%s:%s" % (Settings().value('remotes/user id'), Settings().value('remotes/password'))
     try:
         self.auth = base64.b64encode(auth_code)
     except TypeError:
         self.auth = base64.b64encode(auth_code.encode()).decode()
     self.routes = [
         ('^/$', {'function': self.serve_file, 'secure': False}),
         ('^/(stage)$', {'function': self.serve_file, 'secure': False}),
         ('^/(main)$', {'function': self.serve_file, 'secure': False}),
         ('^/(music)$', {'function': self.serve_file, 'secure': False}),
         (r'^/files/(.*)$', {'function': self.serve_file, 'secure': False}),
         (r'^/(\w+)/thumbnails([^/]+)?/(.*)$', {'function': self.serve_thumbnail, 'secure': False}),
         (r'^/api/poll$', {'function': self.poll, 'secure': False}),
         (r'^/main/poll$', {'function': self.main_poll, 'secure': False}),
         (r'^/main/image$', {'function': self.main_image, 'secure': False}),
         (r'^/api/controller/(live|preview)/text$', {'function': self.controller_text, 'secure': False}),
         (r'^/api/controller/(live|preview)/(.*)$', {'function': self.controller, 'secure': True}),
         (r'^/api/service/list$', {'function': self.service_list, 'secure': False}),
         (r'^/api/service/(.*)$', {'function': self.service, 'secure': True}),
         (r'^/api/display/(hide|show|blank|theme|desktop)$', {'function': self.display, 'secure': True}),
         (r'^/api/alert$', {'function': self.alert, 'secure': True}),
         (r'^/api/plugin/(search)$', {'function': self.plugin_info, 'secure': False}),
         (r'^/api/(.*)/search$', {'function': self.search, 'secure': False}),
         (r'^/api/(.*)/live$', {'function': self.go_live, 'secure': True}),
         (r'^/api/(.*)/add$', {'function': self.add_to_service, 'secure': True}),
         (r'^/silas/(.*)$', {'function': self.process_chord_view, 'secure': False})
     ]
     self.settings_section = 'remotes'
     self.translate()
     self.html_dir = os.path.join(AppLocation.get_directory(AppLocation.PluginsDir), 'remotes', 'html')
예제 #9
0
 def on_data_directory_default_button_clicked(self):
     """
     Re-set the data directory location to the 'default' location.
     """
     new_data_path = AppLocation.get_directory(AppLocation.DataDir)
     if self.current_data_path.lower() != new_data_path.lower():
         # Make sure they want to change the data location back to the
         # default.
         answer = QtWidgets.QMessageBox.question(self, translate('OpenLP.AdvancedTab', 'Reset Data Directory'),
                                                 translate('OpenLP.AdvancedTab', 'Are you sure you want to change '
                                                                                 'the location of the OpenLP data '
                                                                                 'directory to the default location?'
                                                                                 '\n\nThis location will be used '
                                                                                 'after OpenLP is closed.'),
                                                 QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes |
                                                                                       QtWidgets.QMessageBox.No),
                                                 QtWidgets.QMessageBox.No)
         if answer != QtWidgets.QMessageBox.Yes:
             return
         self.check_data_overwrite(new_data_path)
         # Save the new location.
         self.main_window.set_new_data_path(new_data_path)
         self.new_data_directory_edit.setText(os.path.abspath(new_data_path))
         self.data_directory_cancel_button.show()
     else:
         # We cancel the change in case user changed their mind.
         self.on_data_directory_cancel_button_clicked()
예제 #10
0
 def get_cursor():
     """
     Return the cursor object. Instantiate one if it doesn't exist yet.
     """
     if BiblesResourcesDB.cursor is None:
         file_path = os.path.join(AppLocation.get_directory(AppLocation.PluginsDir),
                                  'bibles', 'resources', 'bibles_resources.sqlite')
         conn = sqlite3.connect(file_path)
         BiblesResourcesDB.cursor = conn.cursor()
     return BiblesResourcesDB.cursor
예제 #11
0
 def __init__(self):
     """
     Initialise the theme object.
     """
     # basic theme object with defaults
     json_dir = os.path.join(AppLocation.get_directory(AppLocation.AppDir), 'core', 'lib', 'json')
     json_file = os.path.join(json_dir, 'theme.json')
     jsn = get_text_file_string(json_file)
     jsn = json.loads(jsn)
     self.expand_json(jsn)
예제 #12
0
파일: db.py 프로젝트: imkernel/openlp
 def get_cursor():
     """
     Return the cursor object. Instantiate one if it doesn't exist yet.
     """
     if BiblesResourcesDB.cursor is None:
         file_path = os.path.join(AppLocation.get_directory(AppLocation.PluginsDir),
                                  'bibles', 'resources', 'bibles_resources.sqlite')
         conn = sqlite3.connect(file_path)
         BiblesResourcesDB.cursor = conn.cursor()
     return BiblesResourcesDB.cursor
예제 #13
0
 def __init__(self, parent=None):
     """
     The constructor for the plugin manager. Passes the controllers on to
     the plugins for them to interact with via their ServiceItems.
     """
     super(PluginManager, self).__init__(parent)
     self.log_info('Plugin manager Initialising')
     self.base_path = os.path.abspath(AppLocation.get_directory(AppLocation.PluginsDir))
     self.log_debug('Base path %s ' % self.base_path)
     self.plugins = []
     self.log_info('Plugin manager Initialised')
예제 #14
0
 def __init__(self):
     """
     Initialise the theme object.
     """
     # basic theme object with defaults
     json_dir = os.path.join(AppLocation.get_directory(AppLocation.AppDir), 'core', 'lib', 'json')
     json_file = os.path.join(json_dir, 'theme.json')
     jsn = get_text_file_string(json_file)
     jsn = json.loads(jsn)
     self.expand_json(jsn)
     self.background_filename = None
예제 #15
0
 def __init__(self, parent=None):
     """
     The constructor for the plugin manager. Passes the controllers on to
     the plugins for them to interact with via their ServiceItems.
     """
     super(PluginManager, self).__init__(parent)
     self.log_info('Plugin manager Initialising')
     self.base_path = os.path.abspath(
         AppLocation.get_directory(AppLocation.PluginsDir))
     self.log_debug('Base path {path}'.format(path=self.base_path))
     self.plugins = []
     self.log_info('Plugin manager Initialised')
예제 #16
0
 def start_process(self):
     """
     Loads the PPTVIEWLIB library.
     """
     if self.process:
         return
     log.debug('start PPTView')
     dll_path = os.path.join(AppLocation.get_directory(AppLocation.AppDir),
                             'plugins', 'presentations', 'lib', 'pptviewlib', 'pptviewlib.dll')
     self.process = cdll.LoadLibrary(dll_path)
     if log.isEnabledFor(logging.DEBUG):
         self.process.SetDebug(1)
예제 #17
0
 def check_pre_conditions(self):
     """
     Check it we have a valid environment.
     :return: true or false
     """
     log.debug('check_installed Mediainfo')
     # Try to find mediainfo in the path
     exists = process_check_binary('mediainfo')
     # If mediainfo is not in the path, try to find it in the application folder
     if not exists:
         exists = process_check_binary(os.path.join(AppLocation.get_directory(AppLocation.AppDir), 'mediainfo'))
     return exists
예제 #18
0
 def start_process(self):
     """
     Loads the PPTVIEWLIB library.
     """
     if self.process:
         return
     log.debug('start PPTView')
     dll_path = os.path.join(
         AppLocation.get_directory(AppLocation.AppDir), 'plugins',
         'presentations', 'lib', 'pptviewlib', 'pptviewlib.dll')
     self.process = cdll.LoadLibrary(dll_path)
     if log.isEnabledFor(logging.DEBUG):
         self.process.SetDebug(1)
예제 #19
0
 def __init__(self, address, handler):
     """
     Initialise the secure handlers for the SSL server if required.s
     """
     BaseServer.__init__(self, address, handler)
     local_data = AppLocation.get_directory(AppLocation.DataDir)
     self.socket = ssl.SSLSocket(
         sock=socket.socket(self.address_family, self.socket_type),
         certfile=os.path.join(local_data, 'remotes', 'openlp.crt'),
         keyfile=os.path.join(local_data, 'remotes', 'openlp.key'),
         server_side=True)
     self.server_bind()
     self.server_activate()
예제 #20
0
    def get_directory_for_app_dir_test(self):
        """
        Test the AppLocation.get_directory() method for AppLocation.AppDir
        """
        # GIVEN: A mocked out _get_frozen_path function
        with patch('openlp.core.common.applocation.get_frozen_path') as mocked_get_frozen_path:
            mocked_get_frozen_path.return_value = os.path.join('app', 'dir')

            # WHEN: We call AppLocation.get_directory
            directory = AppLocation.get_directory(AppLocation.AppDir)

            # THEN: check that the correct directory is returned
            self.assertEqual(os.path.join('app', 'dir'), directory, 'Directory should be "app/dir"')
예제 #21
0
 def __init__(self, address, handler):
     """
     Initialise the secure handlers for the SSL server if required.s
     """
     BaseServer.__init__(self, address, handler)
     local_data = AppLocation.get_directory(AppLocation.DataDir)
     self.socket = ssl.SSLSocket(
         sock=socket.socket(self.address_family, self.socket_type),
         certfile=os.path.join(local_data, 'remotes', 'openlp.crt'),
         keyfile=os.path.join(local_data, 'remotes', 'openlp.key'),
         server_side=True)
     self.server_bind()
     self.server_activate()
예제 #22
0
 def check_pre_conditions(self):
     """
     Check it we have a valid environment.
     :return: true or false
     """
     log.debug('check_installed Mediainfo')
     # Try to find mediainfo in the path
     exists = process_check_binary('mediainfo')
     # If mediainfo is not in the path, try to find it in the application folder
     if not exists:
         exists = process_check_binary(
             os.path.join(AppLocation.get_directory(AppLocation.AppDir),
                          'mediainfo'))
     return exists
예제 #23
0
    def gs_get_resolution(self, size):
        """
        Only used when using ghostscript
        Ghostscript can't scale automatically while keeping aspect like mupdf, so we need
        to get the ratio between the screen size and the PDF to scale

        :param size: Size struct containing the screen size.
        :return: The resolution dpi to be used.
        """
        # Use a postscript script to get size of the pdf. It is assumed that all pages have same size
        gs_resolution_script = AppLocation.get_directory(
            AppLocation.PluginsDir
        ) + '/presentations/lib/ghostscript_get_resolution.ps'
        # Run the script on the pdf to get the size
        runlog = []
        try:
            runlog = check_output([
                self.controller.gsbin, '-dNOPAUSE', '-dNODISPLAY', '-dBATCH',
                '-sFile=' + self.file_path, gs_resolution_script
            ],
                                  startupinfo=self.startupinfo)
        except CalledProcessError as e:
            log.debug(' '.join(e.cmd))
            log.debug(e.output)
        # Extract the pdf resolution from output, the format is " Size: x: <width>, y: <height>"
        width = 0.0
        height = 0.0
        for line in runlog.splitlines():
            try:
                width = float(
                    re.search(r'.*Size: x: (\d+\.?\d*), y: \d+.*',
                              line.decode()).group(1))
                height = float(
                    re.search(r'.*Size: x: \d+\.?\d*, y: (\d+\.?\d*).*',
                              line.decode()).group(1))
                break
            except AttributeError:
                continue
        # Calculate the ratio from pdf to screen
        if width > 0 and height > 0:
            width_ratio = size.width() / width
            height_ratio = size.height() / height
            # return the resolution that should be used. 72 is default.
            if width_ratio > height_ratio:
                return int(height_ratio * 72)
            else:
                return int(width_ratio * 72)
        else:
            return 72
예제 #24
0
    def test_get_directory_for_app_dir(self):
        """
        Test the AppLocation.get_directory() method for AppLocation.AppDir
        """
        # GIVEN: A mocked out _get_frozen_path function
        with patch('openlp.core.common.applocation.get_frozen_path'
                   ) as mocked_get_frozen_path:
            mocked_get_frozen_path.return_value = os.path.join('app', 'dir')

            # WHEN: We call AppLocation.get_directory
            directory = AppLocation.get_directory(AppLocation.AppDir)

            # THEN: check that the correct directory is returned
            self.assertEqual(os.path.join('app', 'dir'), directory,
                             'Directory should be "app/dir"')
예제 #25
0
    def get_translator(language):
        """
        Set up a translator to use in this instance of OpenLP

        :param language: The language to load into the translator
        """
        if LanguageManager.auto_language:
            language = QtCore.QLocale.system().name()
        lang_path = AppLocation.get_directory(AppLocation.LanguageDir)
        app_translator = QtCore.QTranslator()
        app_translator.load(language, lang_path)
        # A translator for buttons and other default strings provided by Qt.
        if not is_win() and not is_macosx():
            lang_path = QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.TranslationsPath)
        default_translator = QtCore.QTranslator()
        default_translator.load('qt_%s' % language, lang_path)
        return app_translator, default_translator
예제 #26
0
    def get_translator(language):
        """
        Set up a translator to use in this instance of OpenLP

        :param language: The language to load into the translator
        """
        if LanguageManager.auto_language:
            language = QtCore.QLocale.system().name()
        lang_path = AppLocation.get_directory(AppLocation.LanguageDir)
        app_translator = QtCore.QTranslator()
        app_translator.load(language, lang_path)
        # A translator for buttons and other default strings provided by Qt.
        if not is_win() and not is_macosx():
            lang_path = QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.TranslationsPath)
        default_translator = QtCore.QTranslator()
        default_translator.load("qt_%s" % language, lang_path)
        return app_translator, default_translator
예제 #27
0
 def get_cursor():
     """
     Return the cursor object. Instantiate one if it doesn't exist yet.
     If necessary loads up the database and creates the tables if the database doesn't exist.
     """
     if AlternativeBookNamesDB.cursor is None:
         file_path = os.path.join(
             AppLocation.get_directory(AppLocation.DataDir), 'bibles', 'alternative_book_names.sqlite')
         if not os.path.exists(file_path):
             # create new DB, create table alternative_book_names
             AlternativeBookNamesDB.conn = sqlite3.connect(file_path)
             AlternativeBookNamesDB.conn.execute(
                 'CREATE TABLE alternative_book_names(id INTEGER NOT NULL, '
                 'book_reference_id INTEGER, language_id INTEGER, name VARCHAR(50), PRIMARY KEY (id))')
         else:
             # use existing DB
             AlternativeBookNamesDB.conn = sqlite3.connect(file_path)
         AlternativeBookNamesDB.cursor = AlternativeBookNamesDB.conn.cursor()
     return AlternativeBookNamesDB.cursor
예제 #28
0
파일: db.py 프로젝트: imkernel/openlp
 def get_cursor():
     """
     Return the cursor object. Instantiate one if it doesn't exist yet.
     If necessary loads up the database and creates the tables if the database doesn't exist.
     """
     if AlternativeBookNamesDB.cursor is None:
         file_path = os.path.join(
             AppLocation.get_directory(AppLocation.DataDir), 'bibles', 'alternative_book_names.sqlite')
         if not os.path.exists(file_path):
             # create new DB, create table alternative_book_names
             AlternativeBookNamesDB.conn = sqlite3.connect(file_path)
             AlternativeBookNamesDB.conn.execute(
                 'CREATE TABLE alternative_book_names(id INTEGER NOT NULL, '
                 'book_reference_id INTEGER, language_id INTEGER, name VARCHAR(50), PRIMARY KEY (id))')
         else:
             # use existing DB
             AlternativeBookNamesDB.conn = sqlite3.connect(file_path)
         AlternativeBookNamesDB.cursor = AlternativeBookNamesDB.conn.cursor()
     return AlternativeBookNamesDB.cursor
예제 #29
0
    def gs_get_resolution(self, size):
        """
        Only used when using ghostscript
        Ghostscript can't scale automatically while keeping aspect like mupdf, so we need
        to get the ratio between the screen size and the PDF to scale

        :param size: Size struct containing the screen size.
        :return: The resolution dpi to be used.
        """
        # Use a postscript script to get size of the pdf. It is assumed that all pages have same size
        gs_resolution_script = AppLocation.get_directory(
            AppLocation.PluginsDir) + '/presentations/lib/ghostscript_get_resolution.ps'
        # Run the script on the pdf to get the size
        runlog = []
        try:
            runlog = check_output([self.controller.gsbin, '-dNOPAUSE', '-dNODISPLAY', '-dBATCH',
                                   '-sFile=' + self.file_path, gs_resolution_script],
                                  startupinfo=self.startupinfo)
        except CalledProcessError as e:
            log.debug(' '.join(e.cmd))
            log.debug(e.output)
        # Extract the pdf resolution from output, the format is " Size: x: <width>, y: <height>"
        width = 0.0
        height = 0.0
        for line in runlog.splitlines():
            try:
                width = float(re.search(r'.*Size: x: (\d+\.?\d*), y: \d+.*', line.decode()).group(1))
                height = float(re.search(r'.*Size: x: \d+\.?\d*, y: (\d+\.?\d*).*', line.decode()).group(1))
                break
            except AttributeError:
                continue
        # Calculate the ratio from pdf to screen
        if width > 0 and height > 0:
            width_ratio = size.width() / width
            height_ratio = size.height() / height
            # return the resolution that should be used. 72 is default.
            if width_ratio > height_ratio:
                return int(height_ratio * 72)
            else:
                return int(width_ratio * 72)
        else:
            return 72
예제 #30
0
    def get_directory_for_plugins_dir_test(self):
        """
        Test the AppLocation.get_directory() method for AppLocation.PluginsDir
        """
        # GIVEN: _get_frozen_path, abspath, split and sys are mocked out
        with patch('openlp.core.common.applocation.get_frozen_path') as mocked_get_frozen_path, \
                patch('openlp.core.common.applocation.os.path.abspath') as mocked_abspath, \
                patch('openlp.core.common.applocation.os.path.split') as mocked_split, \
                patch('openlp.core.common.applocation.sys') as mocked_sys:
            mocked_abspath.return_value = os.path.join('plugins', 'dir')
            mocked_split.return_value = ['openlp']
            mocked_get_frozen_path.return_value = os.path.join('plugins', 'dir')
            mocked_sys.frozen = 1
            mocked_sys.argv = ['openlp']

            # WHEN: We call AppLocation.get_directory
            directory = AppLocation.get_directory(AppLocation.PluginsDir)

            # THEN: The correct directory should be returned
            self.assertEqual(os.path.join('plugins', 'dir'), directory, 'Directory should be "plugins/dir"')
예제 #31
0
 def check_pre_conditions(self):
     """
     Check to see if we have any presentation software available. If not do not install the plugin.
     """
     log.debug('check_pre_conditions')
     controller_dir = os.path.join(AppLocation.get_directory(AppLocation.PluginsDir), 'presentations', 'lib')
     for filename in os.listdir(controller_dir):
         if filename.endswith('controller.py') and filename != 'presentationcontroller.py':
             path = os.path.join(controller_dir, filename)
             if os.path.isfile(path):
                 module_name = 'openlp.plugins.presentations.lib.' + os.path.splitext(filename)[0]
                 log.debug('Importing controller {name}'.format(name=module_name))
                 try:
                     __import__(module_name, globals(), locals(), [])
                 except ImportError:
                     log.warning('Failed to import {name} on path {path}'.format(name=module_name, path=path))
     controller_classes = PresentationController.__subclasses__()
     for controller_class in controller_classes:
         controller = controller_class(self)
         self.register_controllers(controller)
     return bool(self.controllers)
예제 #32
0
 def check_pre_conditions(self):
     """
     Check to see if we have any presentation software available. If not do not install the plugin.
     """
     log.debug("check_pre_conditions")
     controller_dir = os.path.join(AppLocation.get_directory(AppLocation.PluginsDir), "presentations", "lib")
     for filename in os.listdir(controller_dir):
         if filename.endswith("controller.py") and not filename == "presentationcontroller.py":
             path = os.path.join(controller_dir, filename)
             if os.path.isfile(path):
                 module_name = "openlp.plugins.presentations.lib." + os.path.splitext(filename)[0]
                 log.debug("Importing controller %s", module_name)
                 try:
                     __import__(module_name, globals(), locals(), [])
                 except ImportError:
                     log.warning("Failed to import %s on path %s", module_name, path)
     controller_classes = PresentationController.__subclasses__()
     for controller_class in controller_classes:
         controller = controller_class(self)
         self.register_controllers(controller)
     return bool(self.controllers)
예제 #33
0
 def bootstrap_initialise(self):
     """
     Check to see if we have any media Player's available.
     """
     log.debug('_check_available_media_players')
     controller_dir = os.path.join(
         AppLocation.get_directory(AppLocation.AppDir), 'core', 'ui',
         'media')
     for filename in os.listdir(controller_dir):
         if filename.endswith(
                 'player.py') and not filename == 'mediaplayer.py':
             path = os.path.join(controller_dir, filename)
             if os.path.isfile(path):
                 module_name = 'openlp.core.ui.media.' + os.path.splitext(
                     filename)[0]
                 log.debug('Importing controller %s', module_name)
                 try:
                     __import__(module_name, globals(), locals(), [])
                 # On some platforms importing vlc.py might cause
                 # also OSError exceptions. (e.g. Mac OS X)
                 except (ImportError, OSError):
                     log.warning('Failed to import %s on path %s',
                                 module_name, path)
     player_classes = MediaPlayer.__subclasses__()
     for player_class in player_classes:
         player = player_class(self)
         self.register_players(player)
     if not self.media_players:
         return False
     saved_players, overridden_player = get_media_players()
     invalid_media_players = \
         [media_player for media_player in saved_players if media_player not in self.media_players or
             not self.media_players[media_player].check_available()]
     if invalid_media_players:
         for invalidPlayer in invalid_media_players:
             saved_players.remove(invalidPlayer)
         set_media_players(saved_players, overridden_player)
     self._set_active_players()
     self._generate_extensions_lists()
     return True
예제 #34
0
    def test_get_directory_for_plugins_dir(self):
        """
        Test the AppLocation.get_directory() method for AppLocation.PluginsDir
        """
        # GIVEN: _get_frozen_path, abspath, split and sys are mocked out
        with patch('openlp.core.common.applocation.get_frozen_path') as mocked_get_frozen_path, \
                patch('openlp.core.common.applocation.os.path.abspath') as mocked_abspath, \
                patch('openlp.core.common.applocation.os.path.split') as mocked_split, \
                patch('openlp.core.common.applocation.sys') as mocked_sys:
            mocked_abspath.return_value = os.path.join('plugins', 'dir')
            mocked_split.return_value = ['openlp']
            mocked_get_frozen_path.return_value = os.path.join(
                'plugins', 'dir')
            mocked_sys.frozen = 1
            mocked_sys.argv = ['openlp']

            # WHEN: We call AppLocation.get_directory
            directory = AppLocation.get_directory(AppLocation.PluginsDir)

            # THEN: The correct directory should be returned
            self.assertEqual(os.path.join('plugins', 'dir'), directory,
                             'Directory should be "plugins/dir"')
예제 #35
0
 def load(self):
     """
     Load the configuration and update the server configuration if necessary
     """
     self.is_secure = Settings().value(self.settings_section +
                                       '/https enabled')
     self.port_spin_box.setValue(Settings().value(self.settings_section +
                                                  '/port'))
     self.https_port_spin_box.setValue(
         Settings().value(self.settings_section + '/https port'))
     self.address_edit.setText(Settings().value(self.settings_section +
                                                '/ip address'))
     self.twelve_hour = Settings().value(self.settings_section +
                                         '/twelve hour')
     self.twelve_hour_check_box.setChecked(self.twelve_hour)
     self.thumbnails = Settings().value(self.settings_section +
                                        '/thumbnails')
     self.thumbnails_check_box.setChecked(self.thumbnails)
     local_data = AppLocation.get_directory(AppLocation.DataDir)
     if not os.path.exists(os.path.join(local_data, 'remotes', 'openlp.crt')) or \
             not os.path.exists(os.path.join(local_data, 'remotes', 'openlp.key')):
         self.https_settings_group_box.setChecked(False)
         self.https_settings_group_box.setEnabled(False)
         self.https_error_label.setVisible(True)
     else:
         self.https_settings_group_box.setChecked(
             Settings().value(self.settings_section + '/https enabled'))
         self.https_settings_group_box.setEnabled(True)
         self.https_error_label.setVisible(False)
     self.user_login_group_box.setChecked(
         Settings().value(self.settings_section +
                          '/authentication enabled'))
     self.user_id.setText(Settings().value(self.settings_section +
                                           '/user id'))
     self.password.setText(Settings().value(self.settings_section +
                                            '/password'))
     self.set_urls()
     self.https_changed()
예제 #36
0
def get_application_version():
    """
    Returns the application version of the running instance of OpenLP::

        {'full': '1.9.4-bzr1249', 'version': '1.9.4', 'build': 'bzr1249'}
    """
    global APPLICATION_VERSION
    if APPLICATION_VERSION:
        return APPLICATION_VERSION
    if '--dev-version' in sys.argv or '-d' in sys.argv:
        # NOTE: The following code is a duplicate of the code in setup.py. Any fix applied here should also be applied
        # there.

        # Get the revision of this tree.
        bzr = Popen(('bzr', 'revno'), stdout=PIPE)
        tree_revision, error = bzr.communicate()
        tree_revision = tree_revision.decode()
        code = bzr.wait()
        if code != 0:
            raise Exception('Error running bzr log')

        # Get all tags.
        bzr = Popen(('bzr', 'tags'), stdout=PIPE)
        output, error = bzr.communicate()
        code = bzr.wait()
        if code != 0:
            raise Exception('Error running bzr tags')
        tags = list(map(bytes.decode, output.splitlines()))
        if not tags:
            tag_version = '0.0.0'
            tag_revision = '0'
        else:
            # Remove any tag that has "?" as revision number. A "?" as revision number indicates, that this tag is from
            # another series.
            tags = [tag for tag in tags if tag.split()[-1].strip() != '?']
            # Get the last tag and split it in a revision and tag name.
            tag_version, tag_revision = tags[-1].split()
        # If they are equal, then this tree is tarball with the source for the release. We do not want the revision
        # number in the full version.
        if tree_revision == tag_revision:
            full_version = tag_version.strip()
        else:
            full_version = '{tag}-bzr{tree}'.format(tag=tag_version.strip(), tree=tree_revision.strip())
    else:
        # We're not running the development version, let's use the file.
        file_path = AppLocation.get_directory(AppLocation.VersionDir)
        file_path = os.path.join(file_path, '.version')
        version_file = None
        try:
            version_file = open(file_path, 'r')
            full_version = str(version_file.read()).rstrip()
        except IOError:
            log.exception('Error in version file.')
            full_version = '0.0.0-bzr000'
        finally:
            if version_file:
                version_file.close()
    bits = full_version.split('-')
    APPLICATION_VERSION = {
        'full': full_version,
        'version': bits[0],
        'build': bits[1] if len(bits) > 1 else None
    }
    if APPLICATION_VERSION['build']:
        log.info('Openlp version {version} build {build}'.format(version=APPLICATION_VERSION['version'],
                                                                 build=APPLICATION_VERSION['build']))
    else:
        log.info('Openlp version {version}'.format(version=APPLICATION_VERSION['version']))
    return APPLICATION_VERSION
예제 #37
0
def get_application_version():
    """
    Returns the application version of the running instance of OpenLP::

        {'full': '1.9.4-bzr1249', 'version': '1.9.4', 'build': 'bzr1249'}
    """
    global APPLICATION_VERSION
    if APPLICATION_VERSION:
        return APPLICATION_VERSION
    if '--dev-version' in sys.argv or '-d' in sys.argv:
        # NOTE: The following code is a duplicate of the code in setup.py. Any fix applied here should also be applied
        # there.

        # Get the revision of this tree.
        bzr = Popen(('bzr', 'revno'), stdout=PIPE)
        tree_revision, error = bzr.communicate()
        tree_revision = tree_revision.decode()
        code = bzr.wait()
        if code != 0:
            raise Exception('Error running bzr log')

        # Get all tags.
        bzr = Popen(('bzr', 'tags'), stdout=PIPE)
        output, error = bzr.communicate()
        code = bzr.wait()
        if code != 0:
            raise Exception('Error running bzr tags')
        tags = list(map(bytes.decode, output.splitlines()))
        if not tags:
            tag_version = '0.0.0'
            tag_revision = '0'
        else:
            # Remove any tag that has "?" as revision number. A "?" as revision number indicates, that this tag is from
            # another series.
            tags = [tag for tag in tags if tag.split()[-1].strip() != '?']
            # Get the last tag and split it in a revision and tag name.
            tag_version, tag_revision = tags[-1].split()
        # If they are equal, then this tree is tarball with the source for the release. We do not want the revision
        # number in the full version.
        if tree_revision == tag_revision:
            full_version = tag_version.strip()
        else:
            full_version = '{tag}-bzr{tree}'.format(tag=tag_version.strip(),
                                                    tree=tree_revision.strip())
    else:
        # We're not running the development version, let's use the file.
        file_path = AppLocation.get_directory(AppLocation.VersionDir)
        file_path = os.path.join(file_path, '.version')
        version_file = None
        try:
            version_file = open(file_path, 'r')
            full_version = str(version_file.read()).rstrip()
        except IOError:
            log.exception('Error in version file.')
            full_version = '0.0.0-bzr000'
        finally:
            if version_file:
                version_file.close()
    bits = full_version.split('-')
    APPLICATION_VERSION = {
        'full': full_version,
        'version': bits[0],
        'build': bits[1] if len(bits) > 1 else None
    }
    if APPLICATION_VERSION['build']:
        log.info('Openlp version {version} build {build}'.format(
            version=APPLICATION_VERSION['version'],
            build=APPLICATION_VERSION['build']))
    else:
        log.info('Openlp version {version}'.format(
            version=APPLICATION_VERSION['version']))
    return APPLICATION_VERSION
예제 #38
0
    def check_installed(self):
        """
        Check the viewer is installed.

        :return: True if program to open PDF-files was found, otherwise False.
        """
        log.debug('check_installed Pdf')
        self.mudrawbin = ''
        self.mutoolbin = ''
        self.gsbin = ''
        self.also_supports = []
        # Use the user defined program if given
        if Settings().value('presentations/enable_pdf_program'):
            pdf_program = Settings().value('presentations/pdf_program')
            program_type = self.process_check_binary(pdf_program)
            if program_type == 'gs':
                self.gsbin = pdf_program
            elif program_type == 'mudraw':
                self.mudrawbin = pdf_program
            elif program_type == 'mutool':
                self.mutoolbin = pdf_program
        else:
            # Fallback to autodetection
            application_path = AppLocation.get_directory(AppLocation.AppDir)
            if is_win():
                # for windows we only accept mudraw.exe or mutool.exe in the base folder
                application_path = AppLocation.get_directory(
                    AppLocation.AppDir)
                if os.path.isfile(os.path.join(application_path,
                                               'mudraw.exe')):
                    self.mudrawbin = os.path.join(application_path,
                                                  'mudraw.exe')
                elif os.path.isfile(
                        os.path.join(application_path, 'mutool.exe')):
                    self.mutoolbin = os.path.join(application_path,
                                                  'mutool.exe')
            else:
                DEVNULL = open(os.devnull, 'wb')
                # First try to find mudraw
                self.mudrawbin = which('mudraw')
                # if mudraw isn't installed, try mutool
                if not self.mudrawbin:
                    self.mutoolbin = which('mutool')
                    # Check we got a working mutool
                    if not self.mutoolbin or self.process_check_binary(
                            self.mutoolbin) != 'mutool':
                        self.gsbin = which('gs')
                # Last option: check if mudraw or mutool is placed in OpenLP base folder
                if not self.mudrawbin and not self.mutoolbin and not self.gsbin:
                    application_path = AppLocation.get_directory(
                        AppLocation.AppDir)
                    if os.path.isfile(os.path.join(application_path,
                                                   'mudraw')):
                        self.mudrawbin = os.path.join(application_path,
                                                      'mudraw')
                    elif os.path.isfile(
                            os.path.join(application_path, 'mutool')):
                        self.mutoolbin = os.path.join(application_path,
                                                      'mutool')
        if self.mudrawbin or self.mutoolbin:
            self.also_supports = ['xps', 'oxps']
            return True
        elif self.gsbin:
            return True
        else:
            return False
예제 #39
0
def get_application_version():
    """
    Returns the application version of the running instance of OpenLP::

        {'full': '1.9.4-bzr1249', 'version': '1.9.4', 'build': 'bzr1249'}
    """
    global APPLICATION_VERSION
    if APPLICATION_VERSION:
        return APPLICATION_VERSION
    if "--dev-version" in sys.argv or "-d" in sys.argv:
        # NOTE: The following code is a duplicate of the code in setup.py. Any fix applied here should also be applied
        # there.

        # Get the revision of this tree.
        bzr = Popen(("bzr", "revno"), stdout=PIPE)
        tree_revision, error = bzr.communicate()
        tree_revision = tree_revision.decode()
        code = bzr.wait()
        if code != 0:
            raise Exception("Error running bzr log")

        # Get all tags.
        bzr = Popen(("bzr", "tags"), stdout=PIPE)
        output, error = bzr.communicate()
        code = bzr.wait()
        if code != 0:
            raise Exception("Error running bzr tags")
        tags = list(map(bytes.decode, output.splitlines()))
        if not tags:
            tag_version = "0.0.0"
            tag_revision = "0"
        else:
            # Remove any tag that has "?" as revision number. A "?" as revision number indicates, that this tag is from
            # another series.
            tags = [tag for tag in tags if tag.split()[-1].strip() != "?"]
            # Get the last tag and split it in a revision and tag name.
            tag_version, tag_revision = tags[-1].split()
        # If they are equal, then this tree is tarball with the source for the release. We do not want the revision
        # number in the full version.
        if tree_revision == tag_revision:
            full_version = tag_version.decode("utf-8")
        else:
            full_version = "%s-bzr%s" % (tag_version.decode("utf-8"), tree_revision.decode("utf-8"))
    else:
        # We're not running the development version, let's use the file.
        file_path = AppLocation.get_directory(AppLocation.VersionDir)
        file_path = os.path.join(file_path, ".version")
        version_file = None
        try:
            version_file = open(file_path, "r")
            full_version = str(version_file.read()).rstrip()
        except IOError:
            log.exception("Error in version file.")
            full_version = "0.0.0-bzr000"
        finally:
            if version_file:
                version_file.close()
    bits = full_version.split("-")
    APPLICATION_VERSION = {"full": full_version, "version": bits[0], "build": bits[1] if len(bits) > 1 else None}
    if APPLICATION_VERSION["build"]:
        log.info("Openlp version %s build %s", APPLICATION_VERSION["version"], APPLICATION_VERSION["build"])
    else:
        log.info("Openlp version %s" % APPLICATION_VERSION["version"])
    return APPLICATION_VERSION
예제 #40
0
def main(args=None):
    """
    The main function which parses command line options and then runs

    :param args: Some args
    """
    (options, args) = parse_options(args)
    qt_args = []
    if options.loglevel.lower() in ['d', 'debug']:
        log.setLevel(logging.DEBUG)
    elif options.loglevel.lower() in ['w', 'warning']:
        log.setLevel(logging.WARNING)
    else:
        log.setLevel(logging.INFO)
    if options.style:
        qt_args.extend(['-style', options.style])
    # Throw the rest of the arguments at Qt, just in case.
    qt_args.extend(args)
    # Bug #1018855: Set the WM_CLASS property in X11
    if not is_win() and not is_macosx():
        qt_args.append('OpenLP')
    # Initialise the resources
    qInitResources()
    # Now create and actually run the application.
    application = OpenLP(qt_args)
    application.setOrganizationName('OpenLP')
    application.setOrganizationDomain('openlp.org')
    if options.portable:
        application.setApplicationName('OpenLPPortable')
        Settings.setDefaultFormat(Settings.IniFormat)
        # Get location OpenLPPortable.ini
        application_path = AppLocation.get_directory(AppLocation.AppDir)
        set_up_logging(os.path.abspath(os.path.join(application_path, '..', '..', 'Other')))
        log.info('Running portable')
        portable_settings_file = os.path.abspath(os.path.join(application_path, '..', '..', 'Data', 'OpenLP.ini'))
        # Make this our settings file
        log.info('INI file: %s', portable_settings_file)
        Settings.set_filename(portable_settings_file)
        portable_settings = Settings()
        # Set our data path
        data_path = os.path.abspath(os.path.join(application_path, '..', '..', 'Data',))
        log.info('Data path: %s', data_path)
        # Point to our data path
        portable_settings.setValue('advanced/data path', data_path)
        portable_settings.setValue('advanced/is portable', True)
        portable_settings.sync()
    else:
        application.setApplicationName('OpenLP')
        set_up_logging(AppLocation.get_directory(AppLocation.CacheDir))
    Registry.create()
    Registry().register('application', application)
    application.setApplicationVersion(get_application_version()['version'])
    # Instance check
    if application.is_already_running():
        sys.exit()
    # Remove/convert obsolete settings.
    Settings().remove_obsolete_settings()
    # First time checks in settings
    if not Settings().value('core/has run wizard'):
        if not FirstTimeLanguageForm().exec_():
            # if cancel then stop processing
            sys.exit()
    # i18n Set Language
    language = LanguageManager.get_language()
    application_translator, default_translator = LanguageManager.get_translator(language)
    if not application_translator.isEmpty():
        application.installTranslator(application_translator)
    if not default_translator.isEmpty():
        application.installTranslator(default_translator)
    else:
        log.debug('Could not find default_translator.')
    if not options.no_error_form:
        sys.excepthook = application.hook_exception
    sys.exit(application.run(qt_args))
예제 #41
0
 def initialise(self):
     """
     Initialise the router stack and any other variables.
     """
     auth_code = "%s:%s" % (Settings().value('remotes/user id'),
                            Settings().value('remotes/password'))
     try:
         self.auth = base64.b64encode(auth_code)
     except TypeError:
         self.auth = base64.b64encode(auth_code.encode()).decode()
     self.routes = [('^/$', {
         'function': self.serve_file,
         'secure': False
     }), ('^/(stage)$', {
         'function': self.serve_file,
         'secure': False
     }), ('^/(stage)/(.*)$', {
         'function': self.stages,
         'secure': False
     }), ('^/(main)$', {
         'function': self.serve_file,
         'secure': False
     }), (r'^/files/(.*)$', {
         'function': self.serve_file,
         'secure': False
     }),
                    (r'^/(\w+)/thumbnails([^/]+)?/(.*)$', {
                        'function': self.serve_thumbnail,
                        'secure': False
                    }),
                    (r'^/api/poll$', {
                        'function': self.poll,
                        'secure': False
                    }),
                    (r'^/main/poll$', {
                        'function': self.main_poll,
                        'secure': False
                    }),
                    (r'^/main/image$', {
                        'function': self.main_image,
                        'secure': False
                    }),
                    (r'^/api/controller/(live|preview)/text$', {
                        'function': self.controller_text,
                        'secure': False
                    }),
                    (r'^/api/controller/(live|preview)/(.*)$', {
                        'function': self.controller,
                        'secure': True
                    }),
                    (r'^/api/service/list$', {
                        'function': self.service_list,
                        'secure': False
                    }),
                    (r'^/api/service/(.*)$', {
                        'function': self.service,
                        'secure': True
                    }),
                    (r'^/api/display/(hide|show|blank|theme|desktop)$', {
                        'function': self.display,
                        'secure': True
                    }),
                    (r'^/api/alert$', {
                        'function': self.alert,
                        'secure': True
                    }),
                    (r'^/api/plugin/(search)$', {
                        'function': self.plugin_info,
                        'secure': False
                    }),
                    (r'^/api/(.*)/search$', {
                        'function': self.search,
                        'secure': False
                    }),
                    (r'^/api/(.*)/live$', {
                        'function': self.go_live,
                        'secure': True
                    }),
                    (r'^/api/(.*)/add$', {
                        'function': self.add_to_service,
                        'secure': True
                    })]
     self.settings_section = 'remotes'
     self.translate()
     self.html_dir = os.path.join(
         AppLocation.get_directory(AppLocation.PluginsDir), 'remotes',
         'html')
     self.config_dir = os.path.join(AppLocation.get_data_path(), 'stages')
예제 #42
0
def main(args=None):
    """
    The main function which parses command line options and then runs

    :param args: Some args
    """
    args = parse_options(args)
    qt_args = []
    if args and args.loglevel.lower() in ['d', 'debug']:
        log.setLevel(logging.DEBUG)
    elif args and args.loglevel.lower() in ['w', 'warning']:
        log.setLevel(logging.WARNING)
    else:
        log.setLevel(logging.INFO)
    if args and args.style:
        qt_args.extend(['-style', args.style])
    # Throw the rest of the arguments at Qt, just in case.
    qt_args.extend(args.rargs)
    # Bug #1018855: Set the WM_CLASS property in X11
    if not is_win() and not is_macosx():
        qt_args.append('OpenLP')
    # Initialise the resources
    qInitResources()
    # Now create and actually run the application.
    application = OpenLP(qt_args)
    application.setOrganizationName('OpenLP')
    application.setOrganizationDomain('openlp.org')
    application.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps, True)
    application.setAttribute(QtCore.Qt.AA_DontCreateNativeWidgetSiblings, True)
    if args and args.portable:
        application.setApplicationName('OpenLPPortable')
        Settings.setDefaultFormat(Settings.IniFormat)
        # Get location OpenLPPortable.ini
        application_path = AppLocation.get_directory(AppLocation.AppDir)
        set_up_logging(
            os.path.abspath(os.path.join(application_path, '..', '..',
                                         'Other')))
        log.info('Running portable')
        portable_settings_file = os.path.abspath(
            os.path.join(application_path, '..', '..', 'Data', 'OpenLP.ini'))
        # Make this our settings file
        log.info('INI file: %s', portable_settings_file)
        Settings.set_filename(portable_settings_file)
        portable_settings = Settings()
        # Set our data path
        data_path = os.path.abspath(
            os.path.join(
                application_path,
                '..',
                '..',
                'Data',
            ))
        log.info('Data path: %s', data_path)
        # Point to our data path
        portable_settings.setValue('advanced/data path', data_path)
        portable_settings.setValue('advanced/is portable', True)
        portable_settings.sync()
    else:
        application.setApplicationName('OpenLP')
        set_up_logging(AppLocation.get_directory(AppLocation.CacheDir))
    Registry.create()
    Registry().register('application', application)
    application.setApplicationVersion(get_application_version()['version'])
    # Check if an instance of OpenLP is already running. Quit if there is a running instance and the user only wants one
    if application.is_already_running():
        sys.exit()
    # If the custom data path is missing and the user wants to restore the data path, quit OpenLP.
    if application.is_data_path_missing():
        application.shared_memory.detach()
        sys.exit()
    # Remove/convert obsolete settings.
    Settings().remove_obsolete_settings()
    # First time checks in settings
    if not Settings().value('core/has run wizard'):
        if not FirstTimeLanguageForm().exec():
            # if cancel then stop processing
            sys.exit()
    # i18n Set Language
    language = LanguageManager.get_language()
    translators = LanguageManager.get_translator(language)
    for translator in translators:
        if not translator.isEmpty():
            application.installTranslator(translator)
    if not translators:
        log.debug('Could not find translators.')
    if args and not args.no_error_form:
        sys.excepthook = application.hook_exception
    sys.exit(application.run(qt_args))