Number of fixes, including:

* Fix to creation and saving of services
* SongBeamer encoding detection
* OSX plugin, media and presentation controller discovery and import fixes
* Make the ftw thread work in its own thread, rather than the main thread


lp:~phill-ridout/openlp/fixes-V (revision 2801)
https://ci.openlp.io/job/Branch-01-Pull/2351/                          [WAITING]
[RUNNING]
[SUCCESS]
https://ci.openlp.io/job/Branch-02-Functional-Tests/2252/              [WAITING]
[RUNNING]
[SUCC...

bzr-revno: 2798
This commit is contained in:
Phill 2017-12-21 20:23:26 +00:00 committed by Tim Bentley
commit 2db71e57c0
7 changed files with 63 additions and 5 deletions

View File

@ -80,6 +80,7 @@ def extension_loader(glob_pattern, excluded_files=[]):
extension_path = extension_path.relative_to(app_dir)
if extension_path.name in excluded_files:
continue
log.debug('Attempting to import %s', extension_path)
module_name = path_to_module(extension_path)
try:
importlib.import_module(module_name)

View File

@ -71,7 +71,7 @@ class PluginManager(RegistryBase, LogMixin, RegistryProperties):
"""
Scan a directory for objects inheriting from the ``Plugin`` class.
"""
glob_pattern = os.path.join('plugins', '*', '*plugin.py')
glob_pattern = os.path.join('plugins', '*', '[!.]*plugin.py')
extension_loader(glob_pattern)
plugin_classes = Plugin.__subclasses__()
plugin_objects = []

View File

@ -181,7 +181,8 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
"""
log.debug('_check_available_media_players')
controller_dir = os.path.join('core', 'ui', 'media')
glob_pattern = os.path.join(controller_dir, '*player.py')
# Find all files that do not begin with '.' (lp:#1738047) and end with player.py
glob_pattern = os.path.join(controller_dir, '[!.]*player.py')
extension_loader(glob_pattern, ['mediaplayer.py'])
player_classes = MediaPlayer.__subclasses__()
for player_class in player_classes:

View File

@ -370,7 +370,7 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
:rtype: None
"""
self._service_path = file_path
self.main_window.set_service_modified(self.is_modified(), file_path.name)
self.set_modified(self.is_modified())
Settings().setValue('servicemanager/last file', file_path)
if file_path and file_path.suffix == '.oszl':
self._save_lite = True

View File

@ -336,6 +336,7 @@ class BibleImportForm(OpenLPWizard):
self.sword_layout.addWidget(self.sword_tab_widget)
self.sword_disabled_label = QtWidgets.QLabel(self.sword_widget)
self.sword_disabled_label.setObjectName('SwordDisabledLabel')
self.sword_disabled_label.setWordWrap(True)
self.sword_layout.addWidget(self.sword_disabled_label)
self.select_stack.addWidget(self.sword_widget)
self.wordproject_widget = QtWidgets.QWidget(self.select_page)

View File

@ -129,7 +129,8 @@ class PresentationPlugin(Plugin):
"""
log.debug('check_pre_conditions')
controller_dir = os.path.join('plugins', 'presentations', 'lib')
glob_pattern = os.path.join(controller_dir, '*controller.py')
# Find all files that do not begin with '.' (lp:#1738047) and end with controller.py
glob_pattern = os.path.join(controller_dir, '[!.]*controller.py')
extension_loader(glob_pattern, ['presentationcontroller.py'])
controller_classes = PresentationController.__subclasses__()
for controller_class in controller_classes:

View File

@ -23,7 +23,7 @@
Functional tests to test the Impress class and related methods.
"""
from unittest import TestCase
from unittest.mock import MagicMock
from unittest.mock import MagicMock, patch
import shutil
from tempfile import mkdtemp
@ -72,6 +72,60 @@ class TestImpressController(TestCase, TestMixin):
self.assertEqual('Impress', controller.name,
'The name of the presentation controller should be correct')
@patch('openlp.plugins.presentations.lib.impresscontroller.log')
def test_check_available(self, mocked_log):
"""
Test `ImpressController.check_available` on Windows
"""
# GIVEN: An instance of :class:`ImpressController`
controller = ImpressController(plugin=self.mock_plugin)
# WHEN: `check_available` is called on Windows and `get_com_servicemanager` returns None
with patch('openlp.plugins.presentations.lib.impresscontroller.is_win', return_value=True), \
patch.object(controller, 'get_com_servicemanager', return_value=None) as mocked_get_com_servicemanager:
result = controller.check_available()
# THEN: `check_available` should return False
assert mocked_get_com_servicemanager.called is True
assert result is False
@patch('openlp.plugins.presentations.lib.impresscontroller.log')
def test_check_available1(self, mocked_log):
"""
Test `ImpressController.check_available` on Windows
"""
# GIVEN: An instance of :class:`ImpressController`
controller = ImpressController(plugin=self.mock_plugin)
# WHEN: `check_available` is called on Windows and `get_com_servicemanager` returns an object
mocked_com_object = MagicMock()
with patch('openlp.plugins.presentations.lib.impresscontroller.is_win', return_value=True), \
patch.object(controller, 'get_com_servicemanager', return_value=mocked_com_object) \
as mocked_get_com_servicemanager:
result = controller.check_available()
# THEN: `check_available` should return True
assert mocked_get_com_servicemanager.called is True
assert result is True
@patch('openlp.plugins.presentations.lib.impresscontroller.log')
@patch('openlp.plugins.presentations.lib.impresscontroller.is_win', return_value=False)
def test_check_available2(self, mocked_is_win, mocked_log):
"""
Test `ImpressController.check_available` when not on Windows
"""
# GIVEN: An instance of :class:`ImpressController`
controller = ImpressController(plugin=self.mock_plugin)
# WHEN: `check_available` is called on Windows and `uno_available` is True
with patch('openlp.plugins.presentations.lib.impresscontroller.uno_available', True), \
patch.object(controller, 'get_com_servicemanager') as mocked_get_com_servicemanager:
result = controller.check_available()
# THEN: `check_available` should return True
assert mocked_get_com_servicemanager.called is False
assert result is True
class TestImpressDocument(TestCase):
"""