Fixes #1325 - Handling of Missing VLC.

This commit is contained in:
Tim Bentley 2023-10-19 23:15:38 +00:00 committed by Raoul Snyman
parent c277ac2b6f
commit 6b31c01ab9
8 changed files with 106 additions and 27 deletions

View File

@ -114,7 +114,7 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties, LogMixin):
def required_icons(self):
"""
This method is called to define the icons for the plugin. It provides a default set and the plugin is able to
override the if required.
override if required.
"""
self.has_import_icon = False
self.has_new_icon = True

View File

@ -897,7 +897,14 @@ class ServiceItem(RegistryProperties):
self.is_valid = False
break
elif self.is_command():
if self.is_capable(ItemCapabilities.IsOptical) and State().check_preconditions('media'):
# Needs Media but no media processing available.
if self.is_capable(ItemCapabilities.RequiresMedia) and not State().check_preconditions('media'):
self.is_valid = False
break
elif self.is_capable(ItemCapabilities.HasBackgroundAudio) and not State().check_preconditions('media'):
self.is_valid = False
break
elif self.is_capable(ItemCapabilities.IsOptical) and State().check_preconditions('media'):
if not os.path.exists(slide['title']):
self.is_valid = False
break

View File

@ -146,7 +146,14 @@ class State(LogMixin, metaclass=Singleton):
mdl[pl] = self.modules[pl]
self.modules = mdl
def is_module_active(self, name) -> bool:
def is_module_active(self, name: str) -> bool:
"""
Checks if a modules is active.
:param name: Module name
:return: Have the preconditions been met.
:rtype: bool
"""
return self.modules[name].status == PluginStatus.Active
def check_preconditions(self, name: str) -> bool:

View File

@ -169,27 +169,32 @@ class FolderLibraryItem(MediaManagerItem):
icon=UiIcons().edit,
triggers=self.on_edit_click)
create_widget_action(self.list_view, separator=True)
create_widget_action(
self.list_view,
'listView{name}{preview}Item'.format(name=self.plugin.name.title(), preview=StringContent.Preview.title()),
text=self.plugin.get_string(StringContent.Preview)['title'],
icon=UiIcons().preview,
can_shortcuts=True,
triggers=self.on_preview_click)
create_widget_action(
self.list_view,
'listView{name}{live}Item'.format(name=self.plugin.name.title(), live=StringContent.Live.title()),
text=self.plugin.get_string(StringContent.Live)['title'],
icon=UiIcons().live,
can_shortcuts=True,
triggers=self.on_live_click)
create_widget_action(
self.list_view,
'listView{name}{service}Item'.format(name=self.plugin.name.title(), service=StringContent.Service.title()),
can_shortcuts=True,
text=self.plugin.get_string(StringContent.Service)['title'],
icon=UiIcons().add,
triggers=self.on_add_click)
if self.can_preview:
create_widget_action(
self.list_view,
'listView{name}{preview}Item'.format(name=self.plugin.name.title(),
preview=StringContent.Preview.title()),
text=self.plugin.get_string(StringContent.Preview)['title'],
icon=UiIcons().preview,
can_shortcuts=True,
triggers=self.on_preview_click)
if self.can_make_live:
create_widget_action(
self.list_view,
'listView{name}{live}Item'.format(name=self.plugin.name.title(), live=StringContent.Live.title()),
text=self.plugin.get_string(StringContent.Live)['title'],
icon=UiIcons().live,
can_shortcuts=True,
triggers=self.on_live_click)
if self.can_add_to_service:
create_widget_action(
self.list_view,
'listView{name}{service}Item'.format(name=self.plugin.name.title(),
service=StringContent.Service.title()),
can_shortcuts=True,
text=self.plugin.get_string(StringContent.Service)['title'],
icon=UiIcons().add,
triggers=self.on_add_click)
if self.add_to_service_item:
create_widget_action(self.list_view, separator=True)
create_widget_action(

View File

@ -158,7 +158,8 @@ class MediaController(QtWidgets.QWidget, RegistryBase, LogMixin, RegistryPropert
except AttributeError:
State().update_pre_conditions('media_live', False)
State().missing_text('media_live', translate(
'OpenLP.MediaController', 'No Displays have been configured, so Live Media has been disabled'))
'OpenLP.MediaController', 'No Displays have been configured, '
'so Live Media has been disabled'))
self.setup_display(self.preview_controller, True)
def _display_controllers(self, controller_type: DisplayControllerType) -> SlideController:

View File

@ -727,7 +727,7 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
self.play_slides_loop.setIcon(UiIcons().loop)
self.play_slides_loop.setText(UiStrings().PlaySlidesInLoop)
if item.is_text():
if (self.settings.value('songs/display songbar') and not self.song_menu.menu().isEmpty()):
if self.settings.value('songs/display songbar') and not self.song_menu.menu().isEmpty():
self.toolbar.set_widget_visible('song_menu', True)
if item.is_capable(ItemCapabilities.CanLoop) and len(item.slides) > 1:
self.toolbar.set_widget_visible(LOOP_LIST)

View File

@ -108,6 +108,10 @@ class MediaMediaItem(FolderLibraryItem):
self.can_add_to_service = False
if State().check_preconditions('media_live'):
self.can_make_live = True
else:
self.can_preview = False
self.can_make_live = False
self.can_add_to_service = False
def initialise(self):
"""

View File

@ -36,6 +36,7 @@ from openlp.core.common.registry import Registry
from openlp.core.lib.formattingtags import FormattingTags
from openlp.core.lib.serviceitem import ItemCapabilities, ServiceItem
from openlp.core.lib.theme import TransitionSpeed
from openlp.core.state import State
from openlp.core.ui.icons import UiIcons
from tests.utils import convert_file_service_item
from tests.utils.constants import RESOURCE_PATH
@ -399,7 +400,6 @@ def test_service_item_load_optical_media_from_service(state_media):
# GIVEN: A new service item and a mocked add icon function
service_item = ServiceItem(None)
service_item.add_icon = MagicMock()
# WHEN: We load a serviceitem with optical media
line = convert_file_service_item(TEST_PATH, 'serviceitem-dvd.osj')
with patch('openlp.core.ui.servicemanager.os.path.exists') as mocked_exists,\
@ -416,6 +416,30 @@ def test_service_item_load_optical_media_from_service(state_media):
assert service_item.media_length == 17.694, 'Media length should be 17.694'
def test_service_item_load_optical_media_from_service_no_vlc(state_media):
"""
Test the Service Item - load an optical media item
"""
# GIVEN: A new service item and a mocked add icon function
service_item = ServiceItem(None)
service_item.add_icon = MagicMock()
State().modules["media"].pass_preconditions = False
# WHEN: We load a serviceitem with optical media
line = convert_file_service_item(TEST_PATH, 'serviceitem-dvd.osj')
with patch('openlp.core.ui.servicemanager.os.path.exists') as mocked_exists,\
patch('openlp.core.lib.serviceitem.sha256_file_hash') as mocked_sha256_file_hash:
mocked_sha256_file_hash.return_value = 'abcd'
mocked_exists.return_value = True
service_item.set_from_service(line)
# THEN: We should get back a valid service item with optical media info
assert service_item.is_valid is False, 'The service item should not be valid'
assert service_item.is_capable(ItemCapabilities.IsOptical) is True, 'The item should be Optical'
assert service_item.start_time == 654.375, 'Start time should be 654.375'
assert service_item.end_time == 672.069, 'End time should be 672.069'
assert service_item.media_length == 17.694, 'Media length should be 17.694'
def test_service_item_load_duplicate_presentation_from_24x_service(state_media, settings):
"""
Test the Service Item - simulate loading the same presentation file from a 2.4.x service file twice
@ -508,6 +532,37 @@ def test_service_item_load_song_and_audio_from_service(mock_sha256_file_hash, st
'The tuple ("/test/abcd.mp3", "abcd") should be in the background_audio list'
@patch('openlp.core.lib.serviceitem.sha256_file_hash')
def test_service_item_load_song_and_audio_from_service_no_vlc(mock_sha256_file_hash, state_media,
settings, service_item_env):
"""
Test the Service Item - adding a song slide from a saved service
"""
# GIVEN: A new service item and a mocked add icon function
service_item = ServiceItem(None)
service_item.add_icon = MagicMock()
FormattingTags.load_tags()
mock_sha256_file_hash.return_value = 'abcd'
State().modules["media"].pass_preconditions = False
# WHEN: We add a custom from a saved service
line = convert_file_service_item(TEST_PATH, 'serviceitem-song-linked-audio.osj')
service_item.set_from_service(line, Path('/test/'))
# THEN: We should get back a valid service item
assert service_item.is_valid is True, 'The new service item should not be valid'
assert len(service_item.display_slides) == 6, 'The service item should have 6 display slides'
assert len(service_item.capabilities) == 7, 'There should be 7 default custom item capabilities'
assert 'Amazing Grace' == service_item.get_display_title(), 'The title should be "Amazing Grace"'
assert CLEANED_VERSE[:-1] == service_item.get_frames()[0]['text'], \
'The returned text matches the input, except the last line feed'
assert 'Amazing Grace! how sweet the s' == service_item.get_frame_title(0), \
'"Amazing Grace! how sweet the s" has been returned as the title'
assert 'Twas grace that taught my hea' == service_item.get_frame_title(1), \
'"Twas grace that taught my hea" has been returned as the title'
assert service_item.background_audio == [], 'The background_audio list is not populated'
@patch('openlp.core.lib.serviceitem.sha256_file_hash')
def test_service_item_to_dict_is_valid_json(mock_sha256_file_hash, state_media, settings, service_item_env):
"""