示例#1
0
    def __init__(self, plugin=None, name='PresentationController', document_class=PresentationDocument):
        """
        This is the constructor for the presentationcontroller object. This provides an easy way for descendent plugins

        to populate common data. This method *must* be overridden, like so::

            class MyPresentationController(PresentationController):
                def __init__(self, plugin):
                    PresentationController.__init(
                        self, plugin, 'My Presenter App')

        :param plugin:  Defaults to *None*. The presentationplugin object
        :param name: Name of the application, to appear in the application
        :param document_class:
        """
        self.supports = []
        self.also_supports = []
        self.docs = []
        self.plugin = plugin
        self.name = name
        self.document_class = document_class
        self.settings_section = self.plugin.settings_section
        self.available = None
        self.temp_folder = os.path.join(AppLocation.get_section_data_path(self.settings_section), name)
        self.thumbnail_folder = os.path.join(AppLocation.get_section_data_path(self.settings_section), 'thumbnails')
        self.thumbnail_prefix = 'slide'
        check_directory_exists(self.thumbnail_folder)
        check_directory_exists(self.temp_folder)
示例#2
0
 def initialise(self):
     """
     Initialise the router stack and any other variables.
     """
     auth_code = "{user}:{password}".format(user=Settings().value('remotes/user id'),
                                            password=Settings().value('remotes/password'))
     try:
         self.auth = base64.b64encode(auth_code)
     except TypeError:
         self.auth = base64.b64encode(auth_code.encode()).decode()
     self.default_route = {'function': self.serve_file, 'secure': False}
     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'^/(\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')
示例#3
0
 def controller_text(self, var):
     """
     Perform an action on the slide controller.
     """
     log.debug("controller_text var = %s" % var)
     current_item = self.live_controller.service_item
     data = []
     if current_item:
         for index, frame in enumerate(current_item.get_frames()):
             item = {}
             # Handle text (songs, custom, bibles)
             if current_item.is_text():
                 if frame['verseTag']:
                     item['tag'] = str(frame['verseTag'])
                 else:
                     item['tag'] = str(index + 1)
                 item['text'] = str(frame['text'])
                 item['html'] = str(frame['html'])
             # Handle images, unless a custom thumbnail is given or if thumbnails is disabled
             elif current_item.is_image() and not frame.get(
                     'image',
                     '') and Settings().value('remotes/thumbnails'):
                 item['tag'] = str(index + 1)
                 thumbnail_path = os.path.join('images', 'thumbnails',
                                               frame['title'])
                 full_thumbnail_path = os.path.join(
                     AppLocation.get_data_path(), thumbnail_path)
                 # Create thumbnail if it doesn't exists
                 if not os.path.exists(full_thumbnail_path):
                     create_thumb(current_item.get_frame_path(index),
                                  full_thumbnail_path, False)
                 item['img'] = urllib.request.pathname2url(os.path.sep +
                                                           thumbnail_path)
                 item['text'] = str(frame['title'])
                 item['html'] = str(frame['title'])
             else:
                 # Handle presentation etc.
                 item['tag'] = str(index + 1)
                 if current_item.is_capable(
                         ItemCapabilities.HasDisplayTitle):
                     item['title'] = str(frame['display_title'])
                 if current_item.is_capable(ItemCapabilities.HasNotes):
                     item['slide_notes'] = str(frame['notes'])
                 if current_item.is_capable(ItemCapabilities.HasThumbnails) and \
                         Settings().value('remotes/thumbnails'):
                     # If the file is under our app directory tree send the portion after the match
                     data_path = AppLocation.get_data_path()
                     if frame['image'][0:len(data_path)] == data_path:
                         item['img'] = urllib.request.pathname2url(
                             frame['image'][len(data_path):])
                 item['text'] = str(frame['title'])
                 item['html'] = str(frame['title'])
             item['selected'] = (self.live_controller.selected_row == index)
             data.append(item)
     json_data = {'results': {'slides': data}}
     if current_item:
         json_data['results'][
             'item'] = self.live_controller.service_item.unique_identifier
     self.do_json_header()
     return json.dumps(json_data).encode()
    def __init__(self, plugin=None, name='PresentationController', document_class=PresentationDocument):
        """
        This is the constructor for the presentationcontroller object. This provides an easy way for descendent plugins

        to populate common data. This method *must* be overridden, like so::

            class MyPresentationController(PresentationController):
                def __init__(self, plugin):
                    PresentationController.__init(
                        self, plugin, 'My Presenter App')

        :param plugin:  Defaults to *None*. The presentationplugin object
        :param name: Name of the application, to appear in the application
        :param document_class:
        """
        self.supports = []
        self.also_supports = []
        self.docs = []
        self.plugin = plugin
        self.name = name
        self.document_class = document_class
        self.settings_section = self.plugin.settings_section
        self.available = None
        self.temp_folder = os.path.join(AppLocation.get_section_data_path(self.settings_section), name)
        self.thumbnail_folder = os.path.join(AppLocation.get_section_data_path(self.settings_section), 'thumbnails')
        self.thumbnail_prefix = 'slide'
        check_directory_exists(self.thumbnail_folder)
        check_directory_exists(self.temp_folder)
示例#5
0
 def _update_background_audio(self, song, item):
     song.media_files = []
     for i, bga in enumerate(item.background_audio):
         dest_file = os.path.join(
             AppLocation.get_section_data_path(self.plugin.name), 'audio', str(song.id), os.path.split(bga)[1])
         check_directory_exists(os.path.split(dest_file)[0])
         shutil.copyfile(os.path.join(AppLocation.get_section_data_path('servicemanager'), bga), dest_file)
         song.media_files.append(MediaFile.populate(weight=i, file_name=dest_file))
     self.plugin.manager.save_object(song, True)
示例#6
0
 def _update_background_audio(self, song, item):
     song.media_files = []
     for i, bga in enumerate(item.background_audio):
         dest_file = os.path.join(
             AppLocation.get_section_data_path(self.plugin.name), 'audio', str(song.id), os.path.split(bga)[1])
         check_directory_exists(os.path.split(dest_file)[0])
         shutil.copyfile(os.path.join(AppLocation.get_section_data_path('servicemanager'), bga), dest_file)
         song.media_files.append(MediaFile.populate(weight=i, file_name=dest_file))
     self.plugin.manager.save_object(song, True)
示例#7
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))
示例#8
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))
示例#9
0
 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')
     missed_files = []
     # 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, sha256 = item.data(QtCore.Qt.UserRole)
             self._increment_progress_bar(self.downloading % filename, 0)
             self.previous_size = 0
             destination = os.path.join(songs_destination, str(filename))
             if not self.url_get_file('%s%s' % (self.songs_url, filename), destination, sha256):
                 missed_files.append('Song: {}'.format(filename))
     # Download Bibles
     bibles_iterator = QtWidgets.QTreeWidgetItemIterator(self.bibles_tree_widget)
     while bibles_iterator.value():
         item = bibles_iterator.value()
         if item.parent() and item.checkState(0) == QtCore.Qt.Checked:
             bible, sha256 = 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),
                                      sha256):
                 missed_files.append('Bible: {}'.format(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, sha256 = 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),
                                      sha256):
                 missed_files.append('Theme: {}'.format(theme))
     if missed_files:
         file_list = ''
         for entry in missed_files:
             file_list += '{}<br \>'.format(entry)
         msg = QtWidgets.QMessageBox()
         msg.setIcon(QtWidgets.QMessageBox.Warning)
         msg.setWindowTitle(translate('OpenLP.FirstTimeWizard', 'Network Error'))
         msg.setText(translate('OpenLP.FirstTimeWizard', 'Unable to download some files'))
         msg.setInformativeText(translate('OpenLP.FirstTimeWizard',
                                          'The following files were not able to be '
                                          'downloaded:<br \>{}'.format(file_list)))
         msg.setStandardButtons(msg.Ok)
         ans = msg.exec()
     return True
示例#10
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
示例#11
0
 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')
     missed_files = []
     # 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, sha256 = item.data(QtCore.Qt.UserRole)
             self._increment_progress_bar(self.downloading % filename, 0)
             self.previous_size = 0
             destination = os.path.join(songs_destination, str(filename))
             if not self.url_get_file('%s%s' % (self.songs_url, filename), destination, sha256):
                 missed_files.append('Song: {}'.format(filename))
     # 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, sha256 = 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),
                                      sha256):
                 missed_files.append('Bible: {}'.format(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, sha256 = 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),
                                      sha256):
                 missed_files.append('Theme: {}'.format(theme))
     if missed_files:
         file_list = ''
         for entry in missed_files:
             file_list += '{}<br \>'.format(entry)
         msg = QtGui.QMessageBox()
         msg.setIcon(QtGui.QMessageBox.Warning)
         msg.setWindowTitle(translate('OpenLP.FirstTimeWizard', 'Network Error'))
         msg.setText(translate('OpenLP.FirstTimeWizard', 'Unable to download some files'))
         msg.setInformativeText(translate('OpenLP.FirstTimeWizard',
                                          'The following files were not able to be '
                                          'downloaded:<br \>{}'.format(file_list)))
         msg.setStandardButtons(msg.Ok)
         ans = msg.exec_()
     return True
示例#12
0
    def controller_text(self, var):
        """
        Perform an action on the slide controller.

        :param var: variable - not used
        """
        log.debug("controller_text var = {var}".format(var=var))
        current_item = self.live_controller.service_item
        data = []
        if current_item:
            for index, frame in enumerate(current_item.get_frames()):
                item = {}
                # Handle text (songs, custom, bibles)
                if current_item.is_text():
                    if frame['verseTag']:
                        item['tag'] = str(frame['verseTag'])
                    else:
                        item['tag'] = str(index + 1)
                    item['text'] = str(frame['text'])
                    item['html'] = str(frame['html'])
                # Handle images, unless a custom thumbnail is given or if thumbnails is disabled
                elif current_item.is_image() and not frame.get('image', '') and Settings().value('remotes/thumbnails'):
                    item['tag'] = str(index + 1)
                    thumbnail_path = os.path.join('images', 'thumbnails', frame['title'])
                    full_thumbnail_path = os.path.join(AppLocation.get_data_path(), thumbnail_path)
                    # Create thumbnail if it doesn't exists
                    if not os.path.exists(full_thumbnail_path):
                        create_thumb(current_item.get_frame_path(index), full_thumbnail_path, False)
                    item['img'] = urllib.request.pathname2url(os.path.sep + thumbnail_path)
                    item['text'] = str(frame['title'])
                    item['html'] = str(frame['title'])
                else:
                    # Handle presentation etc.
                    item['tag'] = str(index + 1)
                    if current_item.is_capable(ItemCapabilities.HasDisplayTitle):
                        item['title'] = str(frame['display_title'])
                    if current_item.is_capable(ItemCapabilities.HasNotes):
                        item['slide_notes'] = str(frame['notes'])
                    if current_item.is_capable(ItemCapabilities.HasThumbnails) and \
                            Settings().value('remotes/thumbnails'):
                        # If the file is under our app directory tree send the portion after the match
                        data_path = AppLocation.get_data_path()
                        if frame['image'][0:len(data_path)] == data_path:
                            item['img'] = urllib.request.pathname2url(frame['image'][len(data_path):])
                    item['text'] = str(frame['title'])
                    item['html'] = str(frame['title'])
                item['selected'] = (self.live_controller.selected_row == index)
                data.append(item)
        json_data = {'results': {'slides': data}}
        if current_item:
            json_data['results']['item'] = self.live_controller.service_item.unique_identifier
        self.do_json_header()
        return json.dumps(json_data).encode()
示例#13
0
def get_db_path(plugin_name, db_file_name=None):
    """
    Create a path to a database from the plugin name and database name

    :param plugin_name: Name of plugin
    :param db_file_name: File name of database
    :return: The path to the database as type str
    """
    if db_file_name is None:
        return 'sqlite:///%s/%s.sqlite' % (AppLocation.get_section_data_path(plugin_name), plugin_name)
    else:
        return 'sqlite:///%s/%s' % (AppLocation.get_section_data_path(plugin_name), db_file_name)
示例#14
0
def delete_database(plugin_name, db_file_name=None):
    """
    Remove a database file from the system.

    :param plugin_name: The name of the plugin to remove the database for
    :param db_file_name: The database file name. Defaults to None resulting in the plugin_name being used.
    """
    if db_file_name:
        db_file_path = os.path.join(AppLocation.get_section_data_path(plugin_name), db_file_name)
    else:
        db_file_path = os.path.join(AppLocation.get_section_data_path(plugin_name), plugin_name)
    return delete_file(db_file_path)
示例#15
0
文件: db.py 项目: imkernel/openlp
def get_db_path(plugin_name, db_file_name=None):
    """
    Create a path to a database from the plugin name and database name

    :param plugin_name: Name of plugin
    :param db_file_name: File name of database
    :return: The path to the database as type str
    """
    if db_file_name is None:
        return 'sqlite:///{path}/{plugin}.sqlite'.format(path=AppLocation.get_section_data_path(plugin_name),
                                                         plugin=plugin_name)
    else:
        return 'sqlite:///{path}/{name}'.format(path=AppLocation.get_section_data_path(plugin_name),
                                                name=db_file_name)
示例#16
0
文件: db.py 项目: jkunle/paul
def get_db_path(plugin_name, db_file_name=None):
    """
    Create a path to a database from the plugin name and database name

    :param plugin_name: Name of plugin
    :param db_file_name: File name of database
    :return: The path to the database as type str
    """
    if db_file_name is None:
        return 'sqlite:///%s/%s.sqlite' % (
            AppLocation.get_section_data_path(plugin_name), plugin_name)
    else:
        return 'sqlite:///%s/%s' % (
            AppLocation.get_section_data_path(plugin_name), db_file_name)
示例#17
0
文件: db.py 项目: jkunle/paul
def delete_database(plugin_name, db_file_name=None):
    """
    Remove a database file from the system.

    :param plugin_name: The name of the plugin to remove the database for
    :param db_file_name: The database file name. Defaults to None resulting in the plugin_name being used.
    """
    if db_file_name:
        db_file_path = os.path.join(
            AppLocation.get_section_data_path(plugin_name), db_file_name)
    else:
        db_file_path = os.path.join(
            AppLocation.get_section_data_path(plugin_name), plugin_name)
    return delete_file(db_file_path)
示例#18
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()
示例#19
0
 def on_clone_click(self):
     """
     Clone a Song
     """
     log.debug('on_clone_click')
     if check_item_selected(self.list_view, UiStrings().SelectEdit):
         self.edit_item = self.list_view.currentItem()
         item_id = self.edit_item.data(QtCore.Qt.UserRole)
         old_song = self.plugin.manager.get_object(Song, item_id)
         song_xml = self.open_lyrics.song_to_xml(old_song)
         new_song = self.open_lyrics.xml_to_song(song_xml)
         new_song.title = '{title} <{text}>'.format(title=new_song.title,
                                                    text=translate('SongsPlugin.MediaItem',
                                                                   'copy', 'For song cloning'))
         # Copy audio files from the old to the new song
         if len(old_song.media_files) > 0:
             save_path = os.path.join(AppLocation.get_section_data_path(self.plugin.name), 'audio', str(new_song.id))
             check_directory_exists(save_path)
             for media_file in old_song.media_files:
                 new_media_file_name = os.path.join(save_path, os.path.basename(media_file.file_name))
                 shutil.copyfile(media_file.file_name, new_media_file_name)
                 new_media_file = MediaFile()
                 new_media_file.file_name = new_media_file_name
                 new_media_file.type = media_file.type
                 new_media_file.weight = media_file.weight
                 new_song.media_files.append(new_media_file)
         self.plugin.manager.save_object(new_song)
     self.on_song_list_load()
示例#20
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()
示例#21
0
 def on_clone_click(self):
     """
     Clone a Song
     """
     log.debug('on_clone_click')
     if check_item_selected(self.list_view, UiStrings().SelectEdit):
         self.edit_item = self.list_view.currentItem()
         item_id = self.edit_item.data(QtCore.Qt.UserRole)
         old_song = self.plugin.manager.get_object(Song, item_id)
         song_xml = self.open_lyrics.song_to_xml(old_song)
         new_song = self.open_lyrics.xml_to_song(song_xml)
         new_song.title = '%s <%s>' % \
                          (new_song.title, translate('SongsPlugin.MediaItem', 'copy', 'For song cloning'))
         # Copy audio files from the old to the new song
         if len(old_song.media_files) > 0:
             save_path = os.path.join(AppLocation.get_section_data_path(self.plugin.name), 'audio', str(new_song.id))
             check_directory_exists(save_path)
             for media_file in old_song.media_files:
                 new_media_file_name = os.path.join(save_path, os.path.basename(media_file.file_name))
                 shutil.copyfile(media_file.file_name, new_media_file_name)
                 new_media_file = MediaFile()
                 new_media_file.file_name = new_media_file_name
                 new_media_file.type = media_file.type
                 new_media_file.weight = media_file.weight
                 new_song.media_files.append(new_media_file)
         self.plugin.manager.save_object(new_song)
     self.on_song_list_load()
示例#22
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)
示例#23
0
    def add_from_command(self, path, file_name, image, display_title=None, notes=None):
        """
        Add a slide from a command.

        :param path: The title of the slide in the service item.
        :param file_name: The title of the slide in the service item.
        :param image: The command of/for the slide.
        :param display_title: Title to show in gui/webinterface, optional.
        :param notes: Notes to show in the webinteface, optional.
        """
        self.service_item_type = ServiceItemType.Command
        # If the item should have a display title but this frame doesn't have one, we make one up
        if self.is_capable(ItemCapabilities.HasDisplayTitle) and not display_title:
            display_title = translate('OpenLP.ServiceItem',
                                      '[slide {frame:d}]').format(frame=len(self._raw_frames) + 1)
        # Update image path to match servicemanager location if file was loaded from service
        if image and not self.has_original_files and self.name == 'presentations':
            file_location = os.path.join(path, file_name)
            file_location_hash = md5_hash(file_location.encode('utf-8'))
            image = os.path.join(AppLocation.get_section_data_path(self.name), 'thumbnails',
                                 file_location_hash, ntpath.basename(image))
        self._raw_frames.append({'title': file_name, 'image': image, 'path': path,
                                 'display_title': display_title, 'notes': notes})
        if self.is_capable(ItemCapabilities.HasThumbnails):
            self.image_manager.add_image(image, ImageSource.CommandPlugins, '#000000')
        self._new_item()
示例#24
0
 def serve_thumbnail(self, controller_name=None, dimensions=None, file_name=None):
     """
     Serve an image file. If not found return 404.
     """
     log.debug('serve thumbnail %s/thumbnails%s/%s' % (controller_name, dimensions, file_name))
     supported_controllers = ['presentations', 'images']
     # -1 means use the default dimension in ImageManager
     width = -1
     height = -1
     if dimensions:
         match = re.search('(\d+)x(\d+)', dimensions)
         if match:
             # let's make sure that the dimensions are within reason
             width = sorted([10, int(match.group(1)), 1000])[1]
             height = sorted([10, int(match.group(2)), 1000])[1]
     content = ''
     content_type = None
     if controller_name and file_name:
         if controller_name in supported_controllers:
             full_path = urllib.parse.unquote(file_name)
             if '..' not in full_path:  # no hacking please
                 full_path = os.path.normpath(os.path.join(AppLocation.get_section_data_path(controller_name),
                                                           'thumbnails/' + full_path))
                 if os.path.exists(full_path):
                     path, just_file_name = os.path.split(full_path)
                     self.image_manager.add_image(full_path, just_file_name, None, width, height)
                     ext, content_type = self.get_content_type(full_path)
                     image = self.image_manager.get_image(full_path, just_file_name, width, height)
                     content = image_to_byte(image, False)
     if len(content) == 0:
         return self.do_not_found()
     self.send_response(200)
     self.send_header('Content-type', content_type)
     self.end_headers()
     return content
示例#25
0
def get_db_path(plugin_name, db_file_name=None):
    """
    Create a path to a database from the plugin name and database name

    :param plugin_name: Name of plugin
    :param db_file_name: File name of database
    :return: The path to the database as type str
    """
    if db_file_name is None:
        return 'sqlite:///{path}/{plugin}.sqlite'.format(
            path=AppLocation.get_section_data_path(plugin_name),
            plugin=plugin_name)
    else:
        return 'sqlite:///{path}/{name}'.format(
            path=AppLocation.get_section_data_path(plugin_name),
            name=db_file_name)
示例#26
0
 def load_themes(self):
     """
     Loads the theme lists and triggers updates across the whole system using direct calls or core functions and
     events for the plugins.
     The plugins will call back in to get the real list if they want it.
     """
     self.theme_list = []
     self.theme_list_widget.clear()
     files = AppLocation.get_files(self.settings_section, '.png')
     # Sort the themes by its name considering language specific
     files.sort(key=lambda file_name: get_locale_key(str(file_name)))
     # now process the file list of png files
     for name in files:
         # check to see file is in theme root directory
         theme = os.path.join(self.path, name)
         if os.path.exists(theme):
             text_name = os.path.splitext(name)[0]
             if text_name == self.global_theme:
                 name = translate('OpenLP.ThemeManager',
                                  '%s (default)') % text_name
             else:
                 name = text_name
             thumb = os.path.join(self.thumb_path, '%s.png' % text_name)
             item_name = QtWidgets.QListWidgetItem(name)
             if validate_thumb(theme, thumb):
                 icon = build_icon(thumb)
             else:
                 icon = create_thumb(theme, thumb)
             item_name.setIcon(icon)
             item_name.setData(QtCore.Qt.UserRole, text_name)
             self.theme_list_widget.addItem(item_name)
             self.theme_list.append(text_name)
     self._push_themes()
示例#27
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
示例#28
0
 def load_themes(self):
     """
     Loads the theme lists and triggers updates across the whole system using direct calls or core functions and
     events for the plugins.
     The plugins will call back in to get the real list if they want it.
     """
     self.theme_list = []
     self.theme_list_widget.clear()
     files = AppLocation.get_files(self.settings_section, '.png')
     # Sort the themes by its name considering language specific
     files.sort(key=lambda file_name: get_locale_key(str(file_name)))
     # now process the file list of png files
     for name in files:
         # check to see file is in theme root directory
         theme = os.path.join(self.path, name)
         if os.path.exists(theme):
             text_name = os.path.splitext(name)[0]
             if text_name == self.global_theme:
                 name = translate('OpenLP.ThemeManager', '{name} (default)').format(name=text_name)
             else:
                 name = text_name
             thumb = os.path.join(self.thumb_path, '{name}.png'.format(name=text_name))
             item_name = QtWidgets.QListWidgetItem(name)
             if validate_thumb(theme, thumb):
                 icon = build_icon(thumb)
             else:
                 icon = create_thumb(theme, thumb)
             item_name.setIcon(icon)
             item_name.setData(QtCore.Qt.UserRole, text_name)
             self.theme_list_widget.addItem(item_name)
             self.theme_list.append(text_name)
     self._push_themes()
示例#29
0
 def is_data_path_missing(self):
     """
     Check if the data folder path exists.
     """
     data_folder_path = AppLocation.get_data_path()
     if not os.path.exists(data_folder_path):
         log.critical('Database was not found in: ' + data_folder_path)
         status = QtWidgets.QMessageBox.critical(
             None, translate('OpenLP', 'Data Directory Error'),
             translate(
                 'OpenLP', 'OpenLP data folder was not found in:\n\n{path}'
                 '\n\nThe location of the data folder was '
                 'previously changed from the OpenLP\'s '
                 'default location. If the data was stored on '
                 'removable device, that device needs to be '
                 'made available.\n\nYou may reset the data '
                 'location back to the default location, '
                 'or you can try to make the current location '
                 'available.\n\nDo you want to reset to the '
                 'default data location? If not, OpenLP will be '
                 'closed so you can try to fix the the problem.').format(
                     path=data_folder_path),
             QtWidgets.QMessageBox.StandardButtons(
                 QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No),
             QtWidgets.QMessageBox.No)
         if status == QtWidgets.QMessageBox.No:
             # If answer was "No", return "True", it will shutdown OpenLP in def main
             log.info('User requested termination')
             return True
         # If answer was "Yes", remove the custom data path thus resetting the default location.
         Settings().remove('advanced/data path')
         log.info(
             'Database location has been reset to the default settings.')
         return False
示例#30
0
    def backup_on_upgrade(self, has_run_wizard):
        """
        Check if OpenLP has been upgraded, and ask if a backup of data should be made

        :param has_run_wizard: OpenLP has been run before
        """
        data_version = Settings().value('core/application version')
        openlp_version = get_application_version()['version']
        # New installation, no need to create backup
        if not has_run_wizard:
            Settings().setValue('core/application version', openlp_version)
        # If data_version is different from the current version ask if we should backup the data folder
        elif data_version != openlp_version:
            if QtGui.QMessageBox.question(None, translate('OpenLP', 'Backup'),
                                          translate('OpenLP', 'OpenLP has been upgraded, '
                                                              'do you want to create a backup of OpenLPs data folder?'),
                                          QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
                                          QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes:
                # Create copy of data folder
                data_folder_path = AppLocation.get_data_path()
                timestamp = time.strftime("%Y%m%d-%H%M%S")
                data_folder_backup_path = data_folder_path + '-' + timestamp
                try:
                    shutil.copytree(data_folder_path, data_folder_backup_path)
                except OSError:
                    QtGui.QMessageBox.warning(None, translate('OpenLP', 'Backup'),
                                              translate('OpenLP', 'Backup of the data folder failed!'))
                    return
                QtGui.QMessageBox.information(None, translate('OpenLP', 'Backup'),
                                              translate('OpenLP', 'A backup of the data folder has been created at %s')
                                              % data_folder_backup_path)
            # Update the version in the settings
            Settings().setValue('core/application version', openlp_version)
示例#31
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()
示例#32
0
    def test_get_data_path(self):
        """
        Test the AppLocation.get_data_path() method
        """
        with patch('openlp.core.common.applocation.Settings') as mocked_class, \
                patch('openlp.core.common.AppLocation.get_directory') as mocked_get_directory, \
                patch('openlp.core.common.applocation.check_directory_exists') as mocked_check_directory_exists, \
                patch('openlp.core.common.applocation.os') as mocked_os:
            # GIVEN: A mocked out Settings class and a mocked out AppLocation.get_directory()
            mocked_settings = mocked_class.return_value
            mocked_settings.contains.return_value = False
            mocked_get_directory.return_value = os.path.join('test', 'dir')
            mocked_check_directory_exists.return_value = True
            mocked_os.path.normpath.return_value = os.path.join('test', 'dir')

            # WHEN: we call AppLocation.get_data_path()
            data_path = AppLocation.get_data_path()

            # THEN: check that all the correct methods were called, and the result is correct
            mocked_settings.contains.assert_called_with('advanced/data path')
            mocked_get_directory.assert_called_with(AppLocation.DataDir)
            mocked_check_directory_exists.assert_called_with(
                os.path.join('test', 'dir'))
            self.assertEqual(os.path.join('test', 'dir'), data_path,
                             'Result should be "test/dir"')
示例#33
0
 def build_theme_path(self):
     """
     Set up the theme path variables
     """
     self.path = AppLocation.get_section_data_path(self.settings_section)
     check_directory_exists(self.path)
     self.thumb_path = os.path.join(self.path, 'thumbnails')
     check_directory_exists(self.thumb_path)
示例#34
0
 def build_loop_path(self):
     """
     Set up the loop path variables
     """
     self.path = AppLocation.get_section_data_path(self.settings_section)
     check_directory_exists(self.path)
     self.thumb_path = os.path.join(self.path, 'thumbnails')
     check_directory_exists(self.thumb_path)
示例#35
0
 def load(self):
     """
     Load settings from disk.
     """
     settings = Settings()
     settings.beginGroup(self.settings_section)
     # The max recent files value does not have an interface and so never
     # gets actually stored in the settings therefore the default value of
     # 20 will always be used.
     self.recent_spin_box.setMaximum(settings.value('max recent files'))
     self.recent_spin_box.setValue(settings.value('recent file count'))
     self.media_plugin_check_box.setChecked(settings.value('save current plugin'))
     self.double_click_live_check_box.setChecked(settings.value('double click live'))
     self.single_click_preview_check_box.setChecked(settings.value('single click preview'))
     self.single_click_service_preview_check_box.setChecked(settings.value('single click service preview'))
     self.expand_service_item_check_box.setChecked(settings.value('expand service item'))
     slide_max_height_value = settings.value('slide max height')
     for i in range(0, self.slide_max_height_combo_box.count()):
         if self.slide_max_height_combo_box.itemData(i) == slide_max_height_value:
             self.slide_max_height_combo_box.setCurrentIndex(i)
     autoscroll_value = settings.value('autoscrolling')
     for i in range(0, len(self.autoscroll_map)):
         if self.autoscroll_map[i] == autoscroll_value and i < self.autoscroll_combo_box.count():
             self.autoscroll_combo_box.setCurrentIndex(i)
     self.enable_auto_close_check_box.setChecked(settings.value('enable exit confirmation'))
     self.hide_mouse_check_box.setChecked(settings.value('hide mouse'))
     self.service_name_day.setCurrentIndex(settings.value('default service day'))
     self.service_name_time.setTime(QtCore.QTime(settings.value('default service hour'),
                                                 settings.value('default service minute')))
     self.should_update_service_name_example = True
     self.service_name_edit.setText(settings.value('default service name'))
     default_service_enabled = settings.value('default service enabled')
     self.service_name_check_box.setChecked(default_service_enabled)
     self.service_name_check_box_toggled(default_service_enabled)
     self.x11_bypass_check_box.setChecked(settings.value('x11 bypass wm'))
     self.slide_limits = settings.value('slide limits')
     self.is_search_as_you_type_enabled = settings.value('search as type')
     self.search_as_type_check_box.setChecked(self.is_search_as_you_type_enabled)
     # Prevent the dialog displayed by the alternate_rows_check_box to display.
     self.alternate_rows_check_box.blockSignals(True)
     self.alternate_rows_check_box.setChecked(settings.value('alternate rows'))
     self.alternate_rows_check_box.blockSignals(False)
     if self.slide_limits == SlideLimits.End:
         self.end_slide_radio_button.setChecked(True)
     elif self.slide_limits == SlideLimits.Wrap:
         self.wrap_slide_radio_button.setChecked(True)
     else:
         self.next_item_radio_button.setChecked(True)
     settings.endGroup()
     self.data_directory_copy_check_box.hide()
     self.new_data_directory_has_files_label.hide()
     self.data_directory_cancel_button.hide()
     # Since data location can be changed, make sure the path is present.
     self.current_data_path = AppLocation.get_data_path()
     self.data_directory_label.setText(os.path.abspath(self.current_data_path))
     # Don't allow data directory move if running portable.
     if settings.value('advanced/is portable'):
         self.data_directory_group_box.hide()
示例#36
0
 def initialise(self):
     """
     Initialize media item.
     """
     self.list_view.clear()
     self.service_path = os.path.join(AppLocation.get_section_data_path(self.settings_section), 'thumbnails')
     check_directory_exists(self.service_path)
     self.load_list(Settings().value(self.settings_section + '/media files'))
     self.rebuild_players()
示例#37
0
 def load_first_time_themes(self):
     """
     Imports any themes on start up and makes sure there is at least one theme
     """
     self.application.set_busy_cursor()
     files = AppLocation.get_files(self.settings_section, '.otz')
     for theme_file in files:
         theme_file = os.path.join(self.path, theme_file)
         self.unzip_theme(theme_file, self.path)
         delete_file(theme_file)
     files = AppLocation.get_files(self.settings_section, '.png')
     # No themes have been found so create one
     if not files:
         theme = ThemeXML()
         theme.theme_name = UiStrings().Default
         self._write_theme(theme, None, None)
         Settings().setValue(self.settings_section + '/global theme', theme.theme_name)
     self.application.set_normal_cursor()
示例#38
0
    def build_html(self, service_item, image_path=''):
        """
        Store the service_item and build the new HTML from it. Add the HTML to the display

        :param service_item: The Service item to be used
        :param image_path: Where the image resides.
        """
        self.web_loaded = False
        self.initial_fame = None
        self.service_item = service_item
        background = None
        # We have an image override so keep the image till the theme changes.
        if self.override:
            # We have an video override so allow it to be stopped.
            if 'video' in self.override:
                Registry().execute('video_background_replaced')
                self.override = {}
            # We have a different theme.
            elif self.override['theme'] != service_item.theme_data.background_filename:
                Registry().execute('live_theme_changed')
                self.override = {}
            else:
                # replace the background
                background = self.image_manager.get_image_bytes(self.override['image'], ImageSource.ImagePlugin)
        self.set_transparency(self.service_item.theme_data.background_type ==
                              BackgroundType.to_string(BackgroundType.Transparent))
        image_bytes = None
        if self.service_item.theme_data.background_type == 'image':
            if self.service_item.theme_data.background_filename:
                self.service_item.bg_image_bytes = self.image_manager.get_image_bytes(
                    self.service_item.theme_data.background_filename, ImageSource.Theme)
            if image_path:
                image_bytes = self.image_manager.get_image_bytes(image_path, ImageSource.ImagePlugin)
        created_html = build_html(self.service_item, self.screen, self.is_live, background, image_bytes,
                                  plugins=self.plugin_manager.plugins)
        self.web_view.setHtml(created_html)
        if service_item.foot_text:
            self.footer(service_item.foot_text)
        # if was hidden keep it hidden
        if self.hide_mode and self.is_live and not service_item.is_media():
            if Settings().value('core/auto unblank'):
                Registry().execute('slidecontroller_live_unblank')
            else:
                self.hide_display(self.hide_mode)
        if self.service_item.theme_data.background_type == 'video' and self.is_live:
            if self.service_item.theme_data.background_filename:
                service_item = ServiceItem()
                service_item.title = 'webkit'
                service_item.processor = 'webkit'
                path = os.path.join(AppLocation.get_section_data_path('themes'),
                                    self.service_item.theme_data.theme_name)
                service_item.add_from_command(path,
                                              self.service_item.theme_data.background_filename,
                                              ':/media/slidecontroller_multimedia.png')
                self.media_controller.video(DisplayControllerType.Live, service_item, video_behind_text=True)
        self._hide_mouse()
示例#39
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
示例#40
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
示例#41
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)
示例#42
0
 def load_first_time_themes(self):
     """
     Imports any themes on start up and makes sure there is at least one theme
     """
     self.application.set_busy_cursor()
     files = AppLocation.get_files(self.settings_section, '.otz')
     for theme_file in files:
         theme_file = os.path.join(self.path, theme_file)
         self.unzip_theme(theme_file, self.path)
         delete_file(theme_file)
     files = AppLocation.get_files(self.settings_section, '.png')
     # No themes have been found so create one
     if not files:
         theme = ThemeXML()
         theme.theme_name = UiStrings().Default
         self._write_theme(theme, None, None)
         Settings().setValue(self.settings_section + '/global theme',
                             theme.theme_name)
     self.application.set_normal_cursor()
示例#43
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')
示例#44
0
 def initialise(self):
     log.debug('initialise')
     self.list_view.clear()
     self.list_view.setIconSize(QtCore.QSize(88, 50))
     self.list_view.setIndentation(self.list_view.default_indentation)
     self.list_view.allow_internal_dnd = True
     self.service_path = os.path.join(AppLocation.get_section_data_path(self.settings_section), 'thumbnails')
     check_directory_exists(self.service_path)
     # Load images from the database
     self.load_full_list(
         self.manager.get_all_objects(ImageFilenames, order_by_ref=ImageFilenames.filename), initial_load=True)
示例#45
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
示例#46
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)
示例#47
0
 def initialise(self):
     """
     Initialize media item.
     """
     self.list_view.clear()
     self.service_path = os.path.join(
         AppLocation.get_section_data_path(self.settings_section),
         'thumbnails')
     check_directory_exists(self.service_path)
     self.load_list(Settings().value(self.settings_section +
                                     '/media files'))
     self.rebuild_players()
示例#48
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')
示例#49
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
示例#50
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)
示例#51
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()
示例#52
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"')
示例#53
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
示例#54
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
示例#55
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"')
示例#56
0
    def test_get_files_no_section_no_extension(self):
        """
        Test the AppLocation.get_files() method with no parameters passed.
        """
        with patch('openlp.core.common.AppLocation.get_data_path') as mocked_get_data_path, \
                patch('openlp.core.common.applocation.os.listdir') as mocked_listdir:
            # GIVEN: Our mocked modules/methods.
            mocked_get_data_path.return_value = 'test/dir'
            mocked_listdir.return_value = copy.deepcopy(FILE_LIST)

            # When: Get the list of files.
            result = AppLocation.get_files()

            # Then: check if the file lists are identical.
            self.assertListEqual(FILE_LIST, result,
                                 'The file lists should be identical.')
示例#57
0
    def copy_media_file(self, song_id, filename):
        """
        This method copies the media file to the correct location and returns
        the new file location.

        :param song_id:
        :param filename: The file to copy.
        """
        if not hasattr(self, 'save_path'):
            self.save_path = os.path.join(AppLocation.get_section_data_path(self.import_wizard.plugin.name),
                                          'audio', str(song_id))
        check_directory_exists(self.save_path)
        if not filename.startswith(self.save_path):
            old_file, filename = filename, os.path.join(self.save_path, os.path.split(filename)[1])
            shutil.copyfile(old_file, filename)
        return filename
示例#58
0
    def serve_thumbnail(self,
                        controller_name=None,
                        dimensions=None,
                        file_name=None):
        """
        Serve an image file. If not found return 404.

        :param file_name: file name to be served
        :param dimensions: image size
        :param controller_name: controller to be called
        """
        log.debug('serve thumbnail %s/thumbnails%s/%s' %
                  (controller_name, dimensions, file_name))
        supported_controllers = ['presentations', 'images']
        # -1 means use the default dimension in ImageManager
        width = -1
        height = -1
        if dimensions:
            match = re.search('(\d+)x(\d+)', dimensions)
            if match:
                # let's make sure that the dimensions are within reason
                width = sorted([10, int(match.group(1)), 1000])[1]
                height = sorted([10, int(match.group(2)), 1000])[1]
        content = ''
        content_type = None
        if controller_name and file_name:
            if controller_name in supported_controllers:
                full_path = urllib.parse.unquote(file_name)
                if '..' not in full_path:  # no hacking please
                    full_path = os.path.normpath(
                        os.path.join(
                            AppLocation.get_section_data_path(controller_name),
                            'thumbnails/' + full_path))
                    if os.path.exists(full_path):
                        path, just_file_name = os.path.split(full_path)
                        self.image_manager.add_image(full_path, just_file_name,
                                                     None, width, height)
                        ext, content_type = self.get_content_type(full_path)
                        image = self.image_manager.get_image(
                            full_path, just_file_name, width, height)
                        content = image_to_byte(image, False)
        if len(content) == 0:
            return self.do_not_found()
        self.send_response(200)
        self.send_header('Content-type', content_type)
        self.end_headers()
        return content
示例#59
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