Merge branch 'master' of gitlab.com:openlp/openlp

This commit is contained in:
Tim 2019-12-18 17:13:10 +00:00
commit 49f30e497c
No known key found for this signature in database
GPG Key ID: 3D454289AF831A6D
26 changed files with 318 additions and 166 deletions

109
openlp/core/common/enum.py Normal file
View File

@ -0,0 +1,109 @@
# -*- coding: utf-8 -*-
##########################################################################
# OpenLP - Open Source Lyrics Projection #
# ---------------------------------------------------------------------- #
# Copyright (c) 2008-2019 OpenLP Developers #
# ---------------------------------------------------------------------- #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
##########################################################################
"""
The :mod:`enumm` module provides enumm functions.
"""
from enum import IntEnum, unique
@unique
class AlertLocation(IntEnum):
"""
This is an enumeration class which controls where Alerts are placed on the screen.
``Top``
Place the text at the top of the screen.
``Middle``
Place the text in the middle of the screen.
``Bottom``
Place the text at the bottom of the screen.
"""
Top = 0
Middle = 1
Bottom = 2
@unique
class BibleSearch(IntEnum):
"""
Enumeration class for the different search types for the "Search" tab.
"""
Reference = 1
Text = 2
Combined = 3
@unique
class CustomSearch(IntEnum):
"""
An enumeration for custom search methods.
"""
Titles = 1
Themes = 2
@unique
class DisplayStyle(IntEnum):
"""
An enumeration for bible text bracket display styles.
"""
NoBrackets = 0
Round = 1
Curly = 2
Square = 3
@unique
class LayoutStyle(IntEnum):
"""
An enumeration for bible screen layout styles.
"""
VersePerSlide = 0
VersePerLine = 1
Continuous = 2
@unique
class LanguageSelection(IntEnum):
"""
An enumeration for bible bookname language. And standard strings for use throughout the bibles plugin.
"""
Bible = 0
Application = 1
English = 2
@unique
class SongSearch(IntEnum):
"""
An enumeration for song search methods.
"""
Entire = 1
Titles = 2
Lyrics = 3
Authors = 4
Topics = 5
Books = 6
Themes = 7
Copyright = 8
CCLInumber = 9

View File

@ -0,0 +1,49 @@
# -*- coding: utf-8 -*-
##########################################################################
# OpenLP - Open Source Lyrics Projection #
# ---------------------------------------------------------------------- #
# Copyright (c) 2008-2019 OpenLP Developers #
# ---------------------------------------------------------------------- #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
##########################################################################
"""
The :mod:`~openlp.core.display.window` module contains the display window
"""
import logging
import time
from openlp.core.common.registry import Registry
log = logging.getLogger(__name__)
def wait_for(check_func, error_message='Timed out waiting for completion', timeout=10):
"""
Wait until web engine page loaded
:return boolean: True on success, False on timeout
"""
# Timeout in 10 seconds
end_time = time.time() + timeout
app = Registry().get('application')
success = True
while not check_func():
now = time.time()
if now > end_time:
log.error(error_message)
success = False
break
time.sleep(0.001)
app.process_events()
return success

View File

@ -383,6 +383,7 @@ var Display = {
init: function (doTransitions=false) {
Display._doTransitions = doTransitions;
Reveal.initialize(Display._revealConfig);
displayWatcher.setInitialised(true);
},
/**
* Reinitialise Reveal
@ -1134,4 +1135,5 @@ var Display = {
};
new QWebChannel(qt.webChannelTransport, function (channel) {
window.mediaWatcher = channel.objects.mediaWatcher;
window.displayWatcher = channel.objects.displayWatcher;
});

View File

@ -36,6 +36,7 @@ from openlp.core.common.i18n import translate
from openlp.core.common.mixins import LogMixin
from openlp.core.common.registry import Registry, RegistryBase
from openlp.core.common.settings import Settings
from openlp.core.common.utils import wait_for
from openlp.core.display.screens import ScreenList
from openlp.core.display.window import DisplayWindow
from openlp.core.lib import ItemCapabilities
@ -486,35 +487,6 @@ class ThemePreviewRenderer(LogMixin, DisplayWindow):
footer_html = 'Dummy footer text'
return footer_html
def wait_till_loaded(self):
"""
Wait until web engine page loaded
:return boolean: True on success, False on timeout
"""
# Timeout in 10 seconds
end_time = time.time() + 10
app = Registry().get('application')
success = True
while not self._is_initialised:
if time.time() > end_time:
log.error('Timed out waiting for web engine page to load')
success = False
break
time.sleep(0.1)
app.process_events()
return success
def _wait_and_process(self, delay):
"""
Wait while allowing things to process
:param delay: The amount of time in seconds to delay, can be a float
"""
end_time = time.time() + delay
app = Registry().get('application')
while time.time() < end_time:
app.process_events()
def generate_preview(self, theme_data, force_page=False, generate_screenshot=True):
"""
Generate a preview of a theme.
@ -535,7 +507,8 @@ class ThemePreviewRenderer(LogMixin, DisplayWindow):
verses['verse'] = 'V1'
verses['footer'] = self.generate_footer()
self.load_verses([verses], is_sync=True)
self._wait_and_process(1)
# Wait for a second
wait_for(lambda: False, timeout=1)
self.force_page = False
if generate_screenshot:
return self.grab()
@ -550,8 +523,7 @@ class ThemePreviewRenderer(LogMixin, DisplayWindow):
:param item: The :class:`~openlp.core.lib.serviceitem.ServiceItem` item object.
"""
while not self._is_initialised:
QtWidgets.QApplication.instance().processEvents()
wait_for(lambda: self._is_initialised)
self.log_debug('format slide')
if item:
# Set theme for preview
@ -771,8 +743,10 @@ class ThemePreviewRenderer(LogMixin, DisplayWindow):
:param text: The text to check. It may contain HTML tags.
"""
self.clear_slides()
self.log_debug('_text_fits_on_slide: 1\n{text}'.format(text=text))
self.run_javascript('Display.addTextSlide("v1", "{text}", "Dummy Footer");'
.format(text=text.replace('"', '\\"')), is_sync=True)
self.log_debug('_text_fits_on_slide: 2')
does_text_fits = self.run_javascript('Display.doesContentFit();', is_sync=True)
return does_text_fits

View File

@ -25,18 +25,18 @@ import json
import logging
import os
import copy
import time
from PyQt5 import QtCore, QtWebChannel, QtWidgets
from openlp.core.common.i18n import translate
from openlp.core.common.path import path_to_str
from openlp.core.common.settings import Settings
from openlp.core.common.registry import Registry
from openlp.core.common.applocation import AppLocation
from openlp.core.ui import HideMode
from openlp.core.display.screens import ScreenList
from openlp.core.common.i18n import translate
from openlp.core.common.mixins import RegistryProperties
from openlp.core.common.path import path_to_str
from openlp.core.common.registry import Registry
from openlp.core.common.settings import Settings
from openlp.core.common.utils import wait_for
from openlp.core.display.screens import ScreenList
from openlp.core.ui import HideMode
log = logging.getLogger(__name__)
@ -102,6 +102,21 @@ class MediaWatcher(QtCore.QObject):
self.muted.emit(is_muted)
class DisplayWatcher(QtCore.QObject):
"""
This facilitates communication from the Display object in the browser back to the Python
"""
initialised = QtCore.pyqtSignal(bool)
@QtCore.pyqtSlot(bool)
def setInitialised(self, is_initialised):
"""
This method is called from the JS in the browser to set the _is_initialised attribute
"""
log.info('Display is initialised: {init}'.format(init=is_initialised))
self.initialised.emit(is_initialised)
class DisplayWindow(QtWidgets.QWidget, RegistryProperties):
"""
This is a window to show the output
@ -137,10 +152,13 @@ class DisplayWindow(QtWidgets.QWidget, RegistryProperties):
self.checkerboard_path = display_base_path / 'checkerboard.png'
self.openlp_splash_screen_path = display_base_path / 'openlp-splash-screen.png'
self.set_url(QtCore.QUrl.fromLocalFile(path_to_str(self.display_path)))
self.media_watcher = MediaWatcher(self)
self.channel = QtWebChannel.QWebChannel(self)
self.media_watcher = MediaWatcher(self)
self.channel.registerObject('mediaWatcher', self.media_watcher)
self.display_watcher = DisplayWatcher(self)
self.channel.registerObject('displayWatcher', self.display_watcher)
self.webview.page().setWebChannel(self.channel)
self.display_watcher.initialised.connect(self.on_initialised)
self.is_display = False
self.scale = 1
self.hide_mode = None
@ -155,6 +173,16 @@ class DisplayWindow(QtWidgets.QWidget, RegistryProperties):
if len(ScreenList()) > 1 or Settings().value('core/display on monitor'):
self.show()
@property
def is_initialised(self):
return self._is_initialised
def on_initialised(self, is_initialised):
"""
Update the initialised status
"""
self._is_initialised = is_initialised
def update_from_screen(self, screen):
"""
Update the number and the geometry from the screen.
@ -208,7 +236,7 @@ class DisplayWindow(QtWidgets.QWidget, RegistryProperties):
"""
js_is_display = str(self.is_display).lower()
self.run_javascript('Display.init({do_transitions});'.format(do_transitions=js_is_display))
self._is_initialised = True
wait_for(lambda: self._is_initialised)
if self.scale != 1:
self.set_scale(self.scale)
if self._can_show_startup_screen:
@ -222,14 +250,8 @@ class DisplayWindow(QtWidgets.QWidget, RegistryProperties):
:param is_sync: Run the script synchronously. Defaults to False
"""
log.debug(script)
# Wait for other scripts to finish
end_time = time.time() + 10
while not self.__script_done:
if time.time() > end_time:
log.error('Timed out waiting for preivous javascript script to finish')
break
time.sleep(0.1)
self.application.process_events()
# Wait for previous scripts to finish
wait_for(lambda: self.__script_done)
if not is_sync:
self.webview.page().runJavaScript(script)
else:
@ -244,14 +266,9 @@ class DisplayWindow(QtWidgets.QWidget, RegistryProperties):
self.__script_result = result
self.webview.page().runJavaScript(script, handle_result)
end_time = time.time() + 10
while not self.__script_done:
if time.time() > end_time:
self.__script_done = True
log.error('Timed out waiting for javascript script to finish')
break
time.sleep(0.001)
self.application.process_events()
# Wait for script to finish
if not wait_for(lambda: self.__script_done):
self.__script_done = True
return self.__script_result
def go_to_slide(self, verse):

View File

@ -43,24 +43,6 @@ class HideMode(object):
Screen = 3
class AlertLocation(object):
"""
This is an enumeration class which controls where Alerts are placed on the screen.
``Top``
Place the text at the top of the screen.
``Middle``
Place the text in the middle of the screen.
``Bottom``
Place the text at the bottom of the screen.
"""
Top = 0
Middle = 1
Bottom = 2
class DisplayControllerType(object):
"""
This is an enumeration class which says where a display controller originated from.

View File

@ -37,6 +37,7 @@ from openlp.core.common.mixins import LogMixin, RegistryProperties
from openlp.core.common.path import create_paths
from openlp.core.common.registry import Registry, RegistryBase
from openlp.core.common.settings import Settings
from openlp.core.common.utils import wait_for
from openlp.core.lib import build_icon, check_item_selected, create_thumb, get_text_file_string, validate_thumb
from openlp.core.lib.exceptions import ValidationError
from openlp.core.lib.theme import Theme
@ -165,7 +166,6 @@ class ThemeManager(QtWidgets.QWidget, RegistryBase, Ui_ThemeManager, LogMixin, R
self.setup_ui(self)
self.global_theme = Settings().value(self.settings_section + '/global theme')
self.build_theme_path()
self.upgrade_themes() # TODO: Can be removed when upgrade path from OpenLP 2.4 no longer needed
def bootstrap_post_set_up(self):
"""
@ -175,8 +175,14 @@ class ThemeManager(QtWidgets.QWidget, RegistryBase, Ui_ThemeManager, LogMixin, R
self.theme_form = ThemeForm(self)
self.theme_form.path = self.theme_path
self.file_rename_form = FileRenameForm()
Registry().register_function('theme_update_global', self.change_global_from_tab)
def bootstrap_completion(self):
"""
process the bootstrap completion request
"""
self.upgrade_themes() # TODO: Can be removed when upgrade path from OpenLP 2.4 no longer needed
self.load_themes()
Registry().register_function('theme_update_global', self.change_global_from_tab)
def upgrade_themes(self):
"""
@ -184,6 +190,8 @@ class ThemeManager(QtWidgets.QWidget, RegistryBase, Ui_ThemeManager, LogMixin, R
:rtype: None
"""
# Wait for 2 seconds to allow some other things to start processing first
wait_for(lambda: False, timeout=1)
xml_file_paths = AppLocation.get_section_data_path('themes').glob('*/*.xml')
for xml_file_path in xml_file_paths:
theme_data = get_text_file_string(xml_file_path)
@ -722,7 +730,6 @@ class ThemeManager(QtWidgets.QWidget, RegistryBase, Ui_ThemeManager, LogMixin, R
theme_name_list = theme_name_list or self.get_theme_names()
self.progress_form.theme_list = theme_name_list
self.progress_form.show()
self.progress_form.theme_display.wait_till_loaded()
for theme_name in theme_name_list:
theme_data = self._get_theme_data(theme_name)
preview_pixmap = self.progress_form.get_preview(theme_name, theme_data)

View File

@ -23,12 +23,13 @@ The theme regeneration progress dialog
"""
from PyQt5 import QtWidgets
from openlp.core.common.mixins import RegistryProperties, LogMixin
from openlp.core.common.utils import wait_for
from openlp.core.display.screens import ScreenList
from openlp.core.ui.themeprogressdialog import UiThemeProgressDialog
from openlp.core.common.mixins import RegistryProperties
class ThemeProgressForm(QtWidgets.QDialog, UiThemeProgressDialog, RegistryProperties):
class ThemeProgressForm(QtWidgets.QDialog, UiThemeProgressDialog, RegistryProperties, LogMixin):
"""
The theme regeneration progress dialog
"""
@ -38,9 +39,9 @@ class ThemeProgressForm(QtWidgets.QDialog, UiThemeProgressDialog, RegistryProper
self._theme_list = []
def show(self):
self.progress_bar.setValue(0)
self.progress_bar.setMinimum(0)
self.progress_bar.setMaximum(0)
self.progress_bar.setValue(0)
try:
screens = ScreenList()
self.ratio = screens.current.display_geometry.width() / screens.current.display_geometry.height()
@ -52,6 +53,7 @@ class ThemeProgressForm(QtWidgets.QDialog, UiThemeProgressDialog, RegistryProper
def get_preview(self, theme_name, theme_data):
self.label.setText(theme_name)
self.progress_bar.setValue(self.progress_bar.value() + 1)
wait_for(lambda: self.theme_display.is_initialised)
self.theme_display.set_scale(float(self.theme_display.width()) / self.renderer.width())
return self.theme_display.generate_preview(theme_data, generate_screenshot=True)

View File

@ -26,13 +26,13 @@ from PyQt5 import QtGui
from openlp.core.state import State
from openlp.core.api.http import register_endpoint
from openlp.core.common.actions import ActionList
from openlp.core.common.enum import AlertLocation
from openlp.core.common.i18n import UiStrings, translate
from openlp.core.common.settings import Settings
from openlp.core.lib.db import Manager
from openlp.core.lib.plugin import Plugin, StringContent
from openlp.core.lib.theme import VerticalType
from openlp.core.lib.ui import create_action
from openlp.core.ui import AlertLocation
from openlp.core.ui.icons import UiIcons
from openlp.plugins.alerts.endpoint import api_alerts_endpoint, alerts_endpoint
from openlp.plugins.alerts.forms.alertform import AlertForm

View File

@ -24,15 +24,15 @@ import logging
from openlp.core.state import State
from openlp.core.api.http import register_endpoint
from openlp.core.common.actions import ActionList
from openlp.core.common.enum import BibleSearch, LayoutStyle, DisplayStyle, LanguageSelection
from openlp.core.common.i18n import UiStrings, translate
from openlp.core.ui.icons import UiIcons
from openlp.core.lib.plugin import Plugin, StringContent
from openlp.core.lib.ui import create_action
from openlp.plugins.bibles.endpoint import api_bibles_endpoint, bibles_endpoint
from openlp.plugins.bibles.lib import LayoutStyle, DisplayStyle, LanguageSelection
from openlp.plugins.bibles.lib.biblestab import BiblesTab
from openlp.plugins.bibles.lib.manager import BibleManager
from openlp.plugins.bibles.lib.mediaitem import BibleMediaItem, BibleSearch
from openlp.plugins.bibles.lib.mediaitem import BibleMediaItem
log = logging.getLogger(__name__)

View File

@ -21,10 +21,11 @@
from PyQt5 import QtCore, QtWidgets
from openlp.core.common.enum import LanguageSelection
from openlp.core.common.i18n import translate
from openlp.core.lib.ui import create_button_box
from openlp.core.ui.icons import UiIcons
from openlp.plugins.bibles.lib import BibleStrings, LanguageSelection
from openlp.plugins.bibles.lib import BibleStrings
from openlp.plugins.bibles.lib.db import BiblesResourcesDB

View File

@ -36,34 +36,6 @@ REFERENCE_MATCHES = {}
REFERENCE_SEPARATORS = {}
class LayoutStyle(object):
"""
An enumeration for bible screen layout styles.
"""
VersePerSlide = 0
VersePerLine = 1
Continuous = 2
class DisplayStyle(object):
"""
An enumeration for bible text bracket display styles.
"""
NoBrackets = 0
Round = 1
Curly = 2
Square = 3
class LanguageSelection(object):
"""
An enumeration for bible bookname language. And standard strings for use throughout the bibles plugin.
"""
Bible = 0
Application = 1
English = 2
class BibleStrings(metaclass=Singleton):
"""
Provide standard strings for objects to use.

View File

@ -23,13 +23,13 @@ import logging
from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.common.enum import DisplayStyle, LanguageSelection, LayoutStyle
from openlp.core.common.i18n import UiStrings, translate
from openlp.core.common.registry import Registry
from openlp.core.common.settings import Settings
from openlp.core.lib.settingstab import SettingsTab
from openlp.core.lib.ui import find_and_set_in_combo_box
from openlp.plugins.bibles.lib import DisplayStyle, LanguageSelection, LayoutStyle, get_reference_separator, \
update_reference_separators
from openlp.plugins.bibles.lib import get_reference_separator, update_reference_separators
log = logging.getLogger(__name__)

View File

@ -33,11 +33,12 @@ from sqlalchemy.orm import class_mapper, mapper, relation
from sqlalchemy.orm.exc import UnmappedClassError
from openlp.core.common import clean_filename
from openlp.core.common.enum import LanguageSelection
from openlp.core.common.applocation import AppLocation
from openlp.core.common.i18n import translate
from openlp.core.lib.db import BaseModel, Manager, init_db
from openlp.core.lib.ui import critical_error_message_box
from openlp.plugins.bibles.lib import BibleStrings, LanguageSelection, upgrade
from openlp.plugins.bibles.lib import BibleStrings, upgrade
log = logging.getLogger(__name__)
@ -307,7 +308,8 @@ class BibleDB(Manager):
:rtype: list[int]
"""
log.debug('get_book_ref_id_by_localised_name("{book}", "{lang}")'.format(book=book, lang=language_selection))
from openlp.plugins.bibles.lib import LanguageSelection, BibleStrings
from openlp.core.common.enum import LanguageSelection
from openlp.plugins.bibles.lib import BibleStrings
book_names = BibleStrings().BookNames
# escape reserved characters
for character in RESERVED_CHARACTERS:

View File

@ -22,11 +22,12 @@ import logging
from pathlib import Path
from openlp.core.common import delete_file
from openlp.core.common.enum import LanguageSelection
from openlp.core.common.applocation import AppLocation
from openlp.core.common.i18n import UiStrings, translate
from openlp.core.common.mixins import LogMixin, RegistryProperties
from openlp.core.common.settings import Settings
from openlp.plugins.bibles.lib import LanguageSelection, parse_reference
from openlp.plugins.bibles.lib import parse_reference
from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta
from .importers.csvbible import CSVBible

View File

@ -25,6 +25,7 @@ from enum import IntEnum, unique
from PyQt5 import QtCore, QtWidgets
from openlp.core.common.enum import BibleSearch, DisplayStyle, LayoutStyle
from openlp.core.common.i18n import UiStrings, get_locale_key, translate
from openlp.core.common.registry import Registry
from openlp.core.common.settings import Settings
@ -37,8 +38,7 @@ from openlp.core.ui.icons import UiIcons
from openlp.core.widgets.edits import SearchEdit
from openlp.plugins.bibles.forms.bibleimportform import BibleImportForm
from openlp.plugins.bibles.forms.editbibleform import EditBibleForm
from openlp.plugins.bibles.lib import DisplayStyle, LayoutStyle, get_reference_match, \
get_reference_separator
from openlp.plugins.bibles.lib import get_reference_match, get_reference_separator
from openlp.plugins.bibles.lib.versereferencelist import VerseReferenceList
log = logging.getLogger(__name__)
@ -53,16 +53,6 @@ def get_reference_separators():
'list': get_reference_separator('sep_l_display')}
@unique
class BibleSearch(IntEnum):
"""
Enumeration class for the different search types for the "Search" tab.
"""
Reference = 1
Text = 2
Combined = 3
@unique
class ResultsTab(IntEnum):
"""

View File

@ -27,6 +27,7 @@ import logging
from openlp.core.state import State
from openlp.core.api.http import register_endpoint
from openlp.core.common.enum import CustomSearch
from openlp.core.common.i18n import translate
from openlp.core.lib import build_icon
from openlp.core.lib.db import Manager
@ -34,7 +35,7 @@ from openlp.core.lib.plugin import Plugin, StringContent
from openlp.core.ui.icons import UiIcons
from openlp.plugins.custom.endpoint import api_custom_endpoint, custom_endpoint
from openlp.plugins.custom.lib.db import CustomSlide, init_schema
from openlp.plugins.custom.lib.mediaitem import CustomMediaItem, CustomSearch
from openlp.plugins.custom.lib.mediaitem import CustomMediaItem
from openlp.plugins.custom.lib.customtab import CustomTab

View File

@ -24,6 +24,7 @@ import logging
from PyQt5 import QtCore, QtWidgets
from sqlalchemy.sql import and_, func, or_
from openlp.core.common.enum import CustomSearch
from openlp.core.common.i18n import UiStrings, translate
from openlp.core.common.registry import Registry
from openlp.core.common.settings import Settings
@ -41,14 +42,6 @@ from openlp.plugins.custom.lib.db import CustomSlide
log = logging.getLogger(__name__)
class CustomSearch(object):
"""
An enumeration for custom search methods.
"""
Titles = 1
Themes = 2
class CustomMediaItem(MediaManagerItem):
"""
This is the custom media manager item for Custom Slides.

View File

@ -228,8 +228,7 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
:param media: The media
:param target_group:
"""
# TODO needs to be fixed as no idea why this fails
# media.sort(key=lambda file_path: get_natural_key(file_path.name))
media.sort(key=lambda file_path: get_natural_key(os.path.split(str(file_path))[1]))
file_name = translate('MediaPlugin.MediaItem', 'Live Stream')
item_name = QtWidgets.QListWidgetItem(file_name)
item_name.setIcon(UiIcons().video)
@ -281,13 +280,13 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
:return: The media list
"""
media_file_paths = Settings().value(self.settings_section + '/media files')
media_file_paths.sort(key=lambda file_path: get_natural_key(file_path.name))
media_file_paths.sort(key=lambda file_path: get_natural_key(os.path.split(str(file_path))[1]))
if media_type == MediaType.Audio:
extension = AUDIO_EXT
else:
extension = VIDEO_EXT
extension = [x[1:] for x in extension]
media = [x for x in media_file_paths if x.suffix in extension]
media = [x for x in media_file_paths if os.path.splitext(x)[1] in extension]
return media
def search(self, string, show_error):

View File

@ -28,6 +28,7 @@ from sqlalchemy.sql import and_, or_
from openlp.core.state import State
from openlp.core.common.applocation import AppLocation
from openlp.core.common.enum import SongSearch
from openlp.core.common.i18n import UiStrings, get_natural_key, translate
from openlp.core.common.path import create_paths
from openlp.core.common.registry import Registry
@ -51,21 +52,6 @@ from openlp.plugins.songs.lib.ui import SongStrings
log = logging.getLogger(__name__)
class SongSearch(object):
"""
An enumeration for song search methods.
"""
Entire = 1
Titles = 2
Lyrics = 3
Authors = 4
Topics = 5
Books = 6
Themes = 7
Copyright = 8
CCLInumber = 9
class SongMediaItem(MediaManagerItem):
"""
This is the custom media manager item for Songs.

View File

@ -33,6 +33,7 @@ from PyQt5 import QtCore, QtWidgets
from openlp.core.state import State
from openlp.core.api.http import register_endpoint
from openlp.core.common.actions import ActionList
from openlp.core.common.enum import SongSearch
from openlp.core.common.i18n import UiStrings, translate
from openlp.core.common.registry import Registry
from openlp.core.lib import build_icon
@ -48,7 +49,7 @@ from openlp.plugins.songs.lib import clean_song, upgrade
from openlp.plugins.songs.lib.db import Song, init_schema
from openlp.plugins.songs.lib.importer import SongFormat
from openlp.plugins.songs.lib.importers.openlp import OpenLPSongImport
from openlp.plugins.songs.lib.mediaitem import SongMediaItem, SongSearch
from openlp.plugins.songs.lib.mediaitem import SongMediaItem
from openlp.plugins.songs.lib.songstab import SongsTab

View File

@ -58,7 +58,6 @@ class TestThemeManager(TestCase, TestMixin):
# GIVEN: A new a call to initialise
self.theme_manager.setup_ui = MagicMock()
self.theme_manager.build_theme_path = MagicMock()
self.theme_manager.upgrade_themes = MagicMock()
Settings().setValue('themes/global theme', 'my_theme')
# WHEN: the initialisation is run
@ -68,7 +67,6 @@ class TestThemeManager(TestCase, TestMixin):
self.theme_manager.setup_ui.assert_called_once_with(self.theme_manager)
assert self.theme_manager.global_theme == 'my_theme'
self.theme_manager.build_theme_path.assert_called_once_with()
self.theme_manager.upgrade_themes.assert_called_once_with()
@patch('openlp.core.ui.thememanager.create_paths')
@patch('openlp.core.ui.thememanager.AppLocation.get_section_data_path')
@ -110,7 +108,6 @@ class TestThemeManager(TestCase, TestMixin):
Test the functions of bootstrap_post_setup are called.
"""
# GIVEN:
self.theme_manager.load_themes = MagicMock()
self.theme_manager.theme_path = MagicMock()
# WHEN:
@ -118,4 +115,21 @@ class TestThemeManager(TestCase, TestMixin):
self.theme_manager.bootstrap_post_set_up()
# THEN:
assert 1 == self.theme_manager.load_themes.call_count, "load_themes should have been called once"
assert self.theme_manager.progress_form is not None
assert self.theme_manager.theme_form is not None
assert self.theme_manager.file_rename_form is not None
def test_bootstrap_completion(self):
"""
Test the functions of bootstrap_post_setup are called.
"""
# GIVEN:
self.theme_manager.load_themes = MagicMock()
self.theme_manager.upgrade_themes = MagicMock()
# WHEN:
self.theme_manager.bootstrap_completion()
# THEN:
self.theme_manager.upgrade_themes.assert_called_once()
self.theme_manager.load_themes.assert_called_once()

View File

@ -24,9 +24,9 @@ Functional tests to test the Bible Manager class and related methods.
from unittest import TestCase
from unittest.mock import MagicMock, patch
from openlp.core.common.enum import LanguageSelection
from openlp.core.common.registry import Registry
from openlp.core.common.settings import Settings
from openlp.plugins.bibles.lib import LanguageSelection
from openlp.plugins.bibles.lib.manager import BibleManager
from tests.helpers.testmixin import TestMixin
from tests.utils.constants import TEST_RESOURCES_PATH

View File

@ -24,9 +24,10 @@ This module contains tests for the lib submodule of the Bibles plugin.
from unittest import TestCase
from unittest.mock import MagicMock, patch
from openlp.core.common.enum import LanguageSelection
from openlp.core.common.registry import Registry
from openlp.core.common.settings import Settings
from openlp.plugins.bibles.lib import LanguageSelection, parse_reference
from openlp.plugins.bibles.lib import parse_reference
from openlp.plugins.bibles.lib.manager import BibleManager
from tests.helpers.testmixin import TestMixin
from tests.utils.constants import TEST_RESOURCES_PATH

View File

@ -1,5 +1,10 @@
// This is a mock QWebChannel
var qt = {webChannelTransport: 1};
var displayWatcher = {
setInitialised: function (is_initialised) {
// do nothing
}
}
var QWebChannel = function (transport, callback) {
callback({objects: {mediaWatcher: {}}});
callback({objects: {mediaWatcher: {}, displayWatcher: displayWatcher}});
};

View File

@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
##########################################################################
# OpenLP - Open Source Lyrics Projection #
# ---------------------------------------------------------------------- #
# Copyright (c) 2008-2019 OpenLP Developers #
# ---------------------------------------------------------------------- #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
##########################################################################
"""
Interface tests to test the themeManager class and related methods.
"""
from unittest.mock import MagicMock
from openlp.core.common.registry import Registry
from openlp.core.common.utils import wait_for
def test_wait_for(registry):
"""
Test the wait_for function
"""
# GIVEN: Mocked app and Registry
mock_app = MagicMock()
Registry().register('application', mock_app)
mock_func = MagicMock()
mock_func.side_effect = [False, True]
# WHEN: wait_for is run
wait_for(mock_func)
# THEN: the functions got called
assert mock_func.call_count == 2