Fixes and Updates

This commit is contained in:
Tim Bentley 2020-10-19 07:18:26 +00:00 committed by Tomas Groth
parent 0fc95c22b2
commit 1c4ae35c9c
9 changed files with 109 additions and 46 deletions

View File

@ -31,9 +31,9 @@ controller_views = Blueprint('controller', __name__)
log = logging.getLogger(__name__)
@controller_views.route('/live-item')
def controller_text_api():
log.debug('controller-v2-live-item')
@controller_views.route('/live-items')
def controller_live_items():
log.debug('controller-v2-live-items')
live_controller = Registry().get('live_controller')
current_item = live_controller.service_item
live_item = {}
@ -43,6 +43,17 @@ def controller_text_api():
return jsonify(live_item)
@controller_views.route('/live-item')
def controller_live_item():
log.debug('controller-v2-live-item')
live_controller = Registry().get('live_controller')
current_item = live_controller.service_item
live_item = {}
if current_item:
live_item = current_item.to_dict(True, live_controller.selected_row)
return jsonify(live_item)
@controller_views.route('/show', methods=['POST'])
@login_required
def controller_set():

View File

@ -870,10 +870,13 @@ class ServiceItem(RegistryProperties):
return os.path.dirname(self.slides[0]['thumbnail'])
return None
def to_dict(self):
def to_dict(self, active=False, item_no=0):
"""
Convert the service item into a dictionary
Images and thumbnails are put in dict as data uri strings.
:param boolean active: Do I filter list for only the active item
:param int item_no: the index of the active item
"""
data_dict = {
'title': self.title,
@ -890,45 +893,48 @@ class ServiceItem(RegistryProperties):
'slides': []
}
for index, frame in enumerate(self.get_frames()):
item = {
'tag': index + 1,
'title': self.title,
'selected': False
}
if self.is_text():
if frame['verse']:
item['tag'] = str(frame['verse'])
item['text'] = frame['text']
item['html'] = self.rendered_slides[index]['text']
item['chords'] = self.rendered_slides[index]['chords']
item['footer'] = self.rendered_slides[index]['footer']
elif self.is_image() and not frame.get('image', '') and \
Registry().get('settings_thread').value('api/thumbnails'):
thumbnail_path = os.path.join('images', 'thumbnails', frame['title'])
full_thumbnail_path = AppLocation.get_data_path() / thumbnail_path
if not full_thumbnail_path.exists():
create_thumb(Path(self.get_frame_path(index)), full_thumbnail_path, False)
item['img'] = image_to_data_uri(full_thumbnail_path)
item['text'] = str(frame['title'])
item['html'] = str(frame['title'])
if active and index is not item_no:
continue
else:
# presentations and other things
if self.is_capable(ItemCapabilities.HasDisplayTitle):
item['title'] = str(frame['display_title'])
if self.is_capable(ItemCapabilities.HasNotes):
item['slide_notes'] = str(frame['notes'])
if self.is_capable(ItemCapabilities.HasThumbnails) and \
item = {
'tag': index + 1,
'title': self.title,
'selected': False
}
if self.is_text():
if frame['verse']:
item['tag'] = str(frame['verse'])
item['text'] = frame['text']
item['html'] = self.rendered_slides[index]['text']
item['chords'] = self.rendered_slides[index]['chords']
item['footer'] = self.rendered_slides[index]['footer']
elif self.is_image() and not frame.get('image', '') and \
Registry().get('settings_thread').value('api/thumbnails'):
# If the file is under our app directory tree send the portion after the match
data_path = str(AppLocation.get_data_path())
try:
relative_file = frame['image'].relative_to(data_path)
except ValueError:
log.warning('Service item "{title}" is missing a thumbnail or has an invalid thumbnail path'
.format(title=self.title))
else:
item['img'] = image_to_data_uri(AppLocation.get_data_path() / relative_file)
item['text'] = str(frame['title'])
item['html'] = str(frame['title'])
data_dict['slides'].append(item)
thumbnail_path = os.path.join('images', 'thumbnails', frame['title'])
full_thumbnail_path = AppLocation.get_data_path() / thumbnail_path
if not full_thumbnail_path.exists():
create_thumb(Path(self.get_frame_path(index)), full_thumbnail_path, False)
item['img'] = image_to_data_uri(full_thumbnail_path)
item['text'] = str(frame['title'])
item['html'] = str(frame['title'])
else:
# presentations and other things
if self.is_capable(ItemCapabilities.HasDisplayTitle):
item['title'] = str(frame['display_title'])
if self.is_capable(ItemCapabilities.HasNotes):
item['slide_notes'] = str(frame['notes'])
if self.is_capable(ItemCapabilities.HasThumbnails) and \
Registry().get('settings_thread').value('api/thumbnails'):
# If the file is under our app directory tree send the portion after the match
data_path = str(AppLocation.get_data_path())
try:
relative_file = frame['image'].relative_to(data_path)
except ValueError:
log.warning('Service item "{title}" is missing a thumbnail or has an invalid thumbnail path'
.format(title=self.title))
else:
item['img'] = image_to_data_uri(AppLocation.get_data_path() / relative_file)
item['text'] = str(frame['title'])
item['html'] = str(frame['title'])
data_dict['slides'].append(item)
return data_dict

View File

@ -246,7 +246,11 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
self.presentation_check_box.setChecked(
self.plugin_manager.get_plugin_by_name('presentations').is_active())
self.image_check_box.setChecked(self.plugin_manager.get_plugin_by_name('images').is_active())
self.media_check_box.setChecked(self.plugin_manager.get_plugin_by_name('media').is_active())
# temp fix for #677 when we have an error
try:
self.media_check_box.setChecked(self.plugin_manager.get_plugin_by_name('media').is_active())
except Exception:
self.media_check_box.setEnabled(False)
self.custom_check_box.setChecked(self.plugin_manager.get_plugin_by_name('custom').is_active())
self.song_usage_check_box.setChecked(self.plugin_manager.get_plugin_by_name('songusage').is_active())
self.alert_check_box.setChecked(self.plugin_manager.get_plugin_by_name('alerts').is_active())

View File

@ -64,6 +64,12 @@ class CustomPlugin(Plugin):
'the same way songs are. This plugin provides greater freedom over the songs plugin.')
return about_text
def check_pre_conditions(self):
"""
Check the plugin can run.
"""
return self.db_manager.session is not None
def uses_theme(self, theme):
"""
Called to find out if the custom plugin is currently using a theme.

View File

@ -63,6 +63,12 @@ class ImagePlugin(Plugin):
'provided by the theme.')
return about_text
def check_pre_conditions(self):
"""
Check the plugin can run.
"""
return self.manager.session is not None
def set_plugin_text_strings(self):
"""
Called to define all translatable texts of the plugin.

View File

@ -64,6 +64,12 @@ class MediaPlugin(Plugin):
"""
pass
def check_pre_conditions(self):
"""
Check the plugin can run and the media controller is available.
"""
return State().is_module_active('mediacontroller')
@staticmethod
def about():
"""

View File

@ -24,7 +24,7 @@ from openlp.core.common.registry import Registry
from pathlib import Path
def test_retrieve_live_item(flask_client, settings):
def test_retrieve_live_items(flask_client, settings):
"""
Test the live-item endpoint with a mocked service item
"""
@ -36,7 +36,7 @@ def test_retrieve_live_item(flask_client, settings):
Registry().register('live_controller', fake_live_controller)
# WHEN: The live-item endpoint is called
res = flask_client.get('/api/v2/controller/live-item').get_json()
res = flask_client.get('/api/v2/controller/live-items').get_json()
# THEN: The correct item data should be returned
assert res == {'slides': [{'selected': True}]}

View File

@ -49,6 +49,8 @@ def test_bootstrap_initialise(settings, state):
Test the PluginManager.bootstrap_initialise() method
"""
# GIVEN: A plugin manager with some mocked out methods
State().add_service('mediacontroller', 0)
State().update_pre_conditions('mediacontroller', True)
manager = PluginManager()
with patch.object(manager, 'hook_settings_tabs') as mocked_hook_settings_tabs, \
@ -474,6 +476,25 @@ def test_get_plugin_by_name_exists(registry, state):
assert result == mocked_plugin, 'The result for get_plugin_by_name should be the mocked plugin'
def test_get_plugin_by_name_disabled(registry, state):
"""
Test running the get_plugin_by_name() method to find a plugin that is disabled
"""
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active
mocked_plugin = MagicMock()
mocked_plugin.name = 'Mocked Plugin'
plugin_manager = PluginManager()
Registry().register('mock_plugin', mocked_plugin)
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Disabled)
State().flush_preconditions()
# WHEN: We run finalise_plugins()
result = plugin_manager.get_plugin_by_name('Mocked Plugin')
# THEN: The is_active() and finalise() methods should have been called
assert result == mocked_plugin, 'The result for get_plugin_by_name should be the mocked plugin'
def test_new_service_created_with_disabled_plugin(registry, state):
"""
Test running the new_service_created() method with a disabled plugin

View File

@ -23,6 +23,7 @@ Test the media plugin
"""
from unittest.mock import patch
from openlp.core.state import State
from openlp.plugins.media.mediaplugin import MediaPlugin
@ -32,6 +33,8 @@ def test_initialise(mock_initialise, state, settings):
Test that the initialise() method overwrites the built-in one, but still calls it
"""
# GIVEN: A media plugin instance
State().add_service('mediacontroller', 0)
State().update_pre_conditions('mediacontroller', True)
media_plugin = MediaPlugin()
# WHEN: initialise() is called