From a55fdbf0c8538f83cd1546ae7fb16a6221ac50e1 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Wed, 10 Jun 2020 20:10:56 +0000 Subject: [PATCH] Update API definition resolves #295 --- openlp/core/api/versions/v2/plugins.py | 6 +- openlp/core/common/registry.py | 2 +- openlp/core/ui/mainwindow.py | 4 -- openlp/core/ui/media/mediacontroller.py | 16 +++-- openlp/core/ui/media/remote.py | 64 ++++++------------- openlp/core/ui/slidecontroller.py | 37 ++++------- openlp/plugins/media/lib/mediaitem.py | 15 ++++- openlp/plugins/presentations/lib/mediaitem.py | 2 + .../openlp_core/ui/test_slidecontroller.py | 4 +- .../openlp_plugins/media/test_mediaitem.py | 12 ++++ 10 files changed, 75 insertions(+), 87 deletions(-) diff --git a/openlp/core/api/versions/v2/plugins.py b/openlp/core/api/versions/v2/plugins.py index 237fa838d..60ba42b92 100644 --- a/openlp/core/api/versions/v2/plugins.py +++ b/openlp/core/api/versions/v2/plugins.py @@ -57,7 +57,7 @@ def add(plugin_name, id): @plugins.route('//search') @login_required def search_view(plugin): - log.debug(f'{plugin}/search search called') + log.debug(f'{plugin}/search called') text = request.args.get('text', '') result = search(plugin, text) return jsonify(result) @@ -66,7 +66,7 @@ def search_view(plugin): @plugins.route('//add', methods=['POST']) @login_required def add_view(plugin): - log.debug(f'{plugin}/add search called') + log.debug(f'{plugin}/add called') data = request.json if not data: abort(400) @@ -78,7 +78,7 @@ def add_view(plugin): @plugins.route('//live', methods=['POST']) @login_required def live_view(plugin): - log.debug(f'{plugin}/live search called') + log.debug(f'{plugin}/live called') data = request.json if not data: abort(400) diff --git a/openlp/core/common/registry.py b/openlp/core/common/registry.py index 1ff479eba..a6777102c 100644 --- a/openlp/core/common/registry.py +++ b/openlp/core/common/registry.py @@ -120,11 +120,11 @@ class Registry(metaclass=Singleton): :param args: Parameters to be passed to the function. :param kwargs: Parameters to be passed to the function. """ + log.debug(f'Running function {event}') results = [] if event in self.functions_list: for function in self.functions_list[event]: try: - log.debug('Running function {} for {}'.format(function, event)) result = function(*args, **kwargs) if result is not None: results.append(result) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 7acb05794..9100bedfe 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -573,8 +573,6 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, LogMixin, RegistryPropert """ process the bootstrap post setup request """ - # self.preview_controller.panel.setVisible(self.settings.value('user interface/preview panel')) - # self.live_controller.panel.setVisible(self.settings.value('user interface/live panel')) self.load_settings() self.restore_current_media_manager_item() Registry().execute('theme_update_global') @@ -637,8 +635,6 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, LogMixin, RegistryPropert Show the main form, as well as the display form """ QtWidgets.QWidget.show(self) - # if self.live_controller.display.isVisible(): - # self.live_controller.display.setFocus() self.activateWindow() # We have -disable-web-security added by our code. # If a file is passed in we will have that as well so count of 2 diff --git a/openlp/core/ui/media/mediacontroller.py b/openlp/core/ui/media/mediacontroller.py index 7b37d619d..4c6671e3e 100644 --- a/openlp/core/ui/media/mediacontroller.py +++ b/openlp/core/ui/media/mediacontroller.py @@ -411,13 +411,13 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties): :param msg: First element is the controller which should be used :param status: """ - self.media_play(msg[0], status) + return self.media_play(msg[0], status) def on_media_play(self): """ Responds to the request to play a loaded video from the web. """ - self.media_play(Registry().get('live_controller'), False) + return self.media_play(Registry().get('live_controller'), False) def media_play(self, controller, first_time=True): """ @@ -495,13 +495,13 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties): :param msg: First element is the controller which should be used """ - self.media_pause(msg[0]) + return self.media_pause(msg[0]) def on_media_pause(self): """ Responds to the request to pause a loaded video from the web. """ - self.media_pause(Registry().get('live_controller')) + return self.media_pause(Registry().get('live_controller')) def media_pause(self, controller): """ @@ -515,6 +515,8 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties): controller.mediabar.actions['playbackStop'].setDisabled(False) controller.mediabar.actions['playbackPause'].setVisible(False) controller.media_info.is_playing = False + return True + return False def media_loop_msg(self, msg): """ @@ -540,13 +542,13 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties): :param msg: First element is the controller which should be used """ - self.media_stop(msg[0]) + return self.media_stop(msg[0]) def on_media_stop(self): """ Responds to the request to stop a loaded video from the web. """ - self.media_stop(Registry().get('live_controller')) + return self.media_stop(Registry().get('live_controller')) def media_stop(self, controller): """ @@ -570,6 +572,8 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties): controller.media_timer = 0 display = self._define_display(controller) display.show_display() + return True + return False def media_volume_msg(self, msg): """ diff --git a/openlp/core/ui/media/remote.py b/openlp/core/ui/media/remote.py index 8bad4796f..cfc1990e5 100644 --- a/openlp/core/ui/media/remote.py +++ b/openlp/core/ui/media/remote.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- -# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4 ############################################################################### # OpenLP - Open Source Lyrics Projection # @@ -20,79 +19,58 @@ # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### """ -The :mod:`~openlp.core.api.endpoint` module contains various API endpoints +The :mod:`~openlp.core.ui.media` module contains various API endpoints """ import logging -from flask import abort, jsonify, Blueprint +from flask import abort, Blueprint from openlp.core.api import app -from openlp.core.api.lib import login_required, old_auth +from openlp.core.api.lib import login_required from openlp.core.common.registry import Registry log = logging.getLogger(__name__) -v1_media = Blueprint('v1-media-controller', __name__) v2_media = Blueprint('v2-media-controller', __name__) @v2_media.route('/play', methods=['POST']) @login_required def media_play(): - media = Registry().get('media_controller') + log.debug('media_play') live = Registry().get('live_controller') - try: - status = media.media_play(live, True) - except Exception: - # The current item probably isn't a media item + if live.service_item.name != 'media': abort(400) + status = live.mediacontroller_live_play.emit() if status: - return '', 204 + return '', 202 abort(400) @v2_media.route('/pause', methods=['POST']) @login_required def media_pause(): - media = Registry().get('media_controller') + log.debug('media_pause') live = Registry().get('live_controller') - media.media_pause(live) - return '', 204 + if live.service_item.name != 'media': + abort(400) + status = live.mediacontroller_live_pause.emit() + if status: + return '', 202 + abort(400) @v2_media.route('/stop', methods=['POST']) @login_required def media_stop(): - Registry().get('live_controller').mediacontroller_live_stop.emit() - return '', 204 - - -# -------------- DEPRECATED ------------------------ -@v1_media.route('/play') -@old_auth -def v1_media_play(): - media = Registry().get('media_controller') + log.debug('media_stop') live = Registry().get('live_controller') - status = media.media_play(live, False) - return jsonify({'success': status}) - - -@v1_media.route('/pause') -@old_auth -def v1_media_pause(): - media = Registry().get('media_controller') - live = Registry().get('live_controller') - status = media.media_pause(live) - return jsonify({'success': status}) - - -@v1_media.route('/stop') -@old_auth -def v1_media_stop(): - Registry().get('live_controller').mediacontroller_live_stop.emit() - return '' -# -------------- END OF DEPRECATED ------------------------ + if live.service_item.name != 'media': + abort(400) + status = live.mediacontroller_live_stop.emit() + if status: + return '', 202 + abort(400) def register_views(): app.register_blueprint(v2_media, url_prefix='/api/v2/media/') - app.register_blueprint(v1_media, url_prefix='/api/media/') diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 9800a2b0c..8ff7197af 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -287,42 +287,26 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties): icon=UiIcons().live_presentation, checked=False, can_shortcuts=True, category=self.category, triggers=self.on_show_display) - self.theme_screen = create_action(self, 'setThemeScreen', + self.theme_screen = create_action(self, 'themeScreen', text=translate('OpenLP.SlideController', 'Show Theme'), icon=UiIcons().live_theme, - checked=False, can_shortcuts=False, category=self.category, + checked=False, can_shortcuts=True, category=self.category, triggers=self.on_theme_display) - self.blank_screen = create_action(self, 'setBlankScreen', + self.blank_screen = create_action(self, 'blankScreen', text=translate('OpenLP.SlideController', 'Show Black'), icon=UiIcons().live_black, - checked=False, can_shortcuts=False, category=self.category, + checked=False, can_shortcuts=True, category=self.category, triggers=self.on_blank_display) - self.desktop_screen = create_action(self, 'setDesktopScreen', + self.desktop_screen = create_action(self, 'desktopScreen', text=translate('OpenLP.SlideController', 'Show Desktop'), icon=UiIcons().live_desktop, - checked=False, can_shortcuts=False, category=self.category, + checked=False, can_shortcuts=True, category=self.category, triggers=self.on_hide_display) self.hide_menu.setDefaultAction(self.show_screen) self.hide_menu.menu().addAction(self.show_screen) self.hide_menu.menu().addAction(self.theme_screen) self.hide_menu.menu().addAction(self.blank_screen) self.hide_menu.menu().addAction(self.desktop_screen) - # Add togglable actions for keyboard shortcuts - self.controller.addAction(create_action(self, 'desktopScreen', - can_shortcuts=True, - context=QtCore.Qt.WidgetWithChildrenShortcut, - category=self.category, - triggers=self.on_toggle_desktop)) - self.controller.addAction(create_action(self, 'themeScreen', - can_shortcuts=True, - context=QtCore.Qt.WidgetWithChildrenShortcut, - category=self.category, - triggers=self.on_toggle_theme)) - self.controller.addAction(create_action(self, 'blankScreen', - can_shortcuts=True, - context=QtCore.Qt.WidgetWithChildrenShortcut, - category=self.category, - triggers=self.on_toggle_blank)) # Wide menu of display control buttons. self.show_screen_button = QtWidgets.QToolButton(self.toolbar) self.show_screen_button.setObjectName('show_screen_button') @@ -922,7 +906,7 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties): self.selected_row = 0 # take a copy not a link to the servicemanager copy. self.service_item = copy.copy(service_item) - if self.service_item.is_command(): + if self.service_item.is_command() and not self.service_item.is_media(): Registry().execute( '{text}_start'.format(text=self.service_item.name.lower()), [self.service_item, self.is_live, self.get_hide_mode(), slide_no]) @@ -967,7 +951,7 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties): self.preview_display.load_images(self.service_item.slides) for display in self.displays: display.load_images(self.service_item.slides) - for slide_index, slide in enumerate(self.service_item.slides): + for _, _ in enumerate(self.service_item.slides): row += 1 self.slide_list[str(row)] = row - 1 self.preview_widget.replace_service_item(self.service_item, width, slide_no) @@ -987,7 +971,10 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties): # close the previous, so make sure we don't close the new one. if old_item.is_command() and not self.service_item.is_command() or \ old_item.is_command() and not old_item.is_media() and self.service_item.is_media(): - Registry().execute('{name}_stop'.format(name=old_item.name.lower()), [old_item, self.is_live]) + if old_item.is_media(): + self.on_media_close() + else: + Registry().execute('{name}_stop'.format(name=old_item.name.lower()), [old_item, self.is_live]) if old_item.is_media() and not self.service_item.is_media(): self.on_media_close() if self.is_live: diff --git a/openlp/plugins/media/lib/mediaitem.py b/openlp/plugins/media/lib/mediaitem.py index 63e4d70aa..39b9db3b7 100644 --- a/openlp/plugins/media/lib/mediaitem.py +++ b/openlp/plugins/media/lib/mediaitem.py @@ -314,12 +314,21 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties): :param show_error: Should the error be shown (True) :return: The search result. """ + from pathlib import Path results = [] string = string.lower() for file_path in self.settings.value('media/media files'): - file_name = file_path.name - if file_name.lower().find(string) > -1: - results.append([str(file_path), file_name]) + if isinstance(file_path, Path): + file_name = file_path.name + if file_name.lower().find(string) > -1: + results.append([str(file_path), file_name]) + else: + if file_path.lower().find(string) > -1: + if file_path.startswith('device'): + (name, _, _) = parse_stream_path(file_path) + results.append([str(file_path), name]) + else: + results.append([str(file_path), file_path]) return results def on_load_optical(self): diff --git a/openlp/plugins/presentations/lib/mediaitem.py b/openlp/plugins/presentations/lib/mediaitem.py index 17ab2b592..b3499db7f 100644 --- a/openlp/plugins/presentations/lib/mediaitem.py +++ b/openlp/plugins/presentations/lib/mediaitem.py @@ -160,6 +160,8 @@ class PresentationMediaItem(MediaManagerItem): existing files, and when the user adds new files via the media manager. :param list[pathlib.Path] file_paths: List of file paths to add to the media manager. + :param list[pathlib.Path] target_group: Group to load. + :param boolean initial_load: Is this the initial load of the list at start up """ current_paths = self.get_file_list() titles = [file_path.name for file_path in current_paths] diff --git a/tests/functional/openlp_core/ui/test_slidecontroller.py b/tests/functional/openlp_core/ui/test_slidecontroller.py index e46424b11..a5938061a 100644 --- a/tests/functional/openlp_core/ui/test_slidecontroller.py +++ b/tests/functional/openlp_core/ui/test_slidecontroller.py @@ -739,8 +739,8 @@ def test_process_item(mocked_execute, registry): slide_controller._process_item(mocked_media_item, 0) # THEN: Registry.execute should have been called to stop the presentation - assert 2 == mocked_execute.call_count, 'Execute should have been called 2 times' - assert 'mocked_presentation_item_stop' == mocked_execute.call_args_list[1][0][0], \ + assert 1 == mocked_execute.call_count, 'Execute should have been called 2 times' + assert 'mocked_presentation_item_stop' == mocked_execute.call_args_list[0][0][0], \ 'The presentation should have been stopped.' diff --git a/tests/functional/openlp_plugins/media/test_mediaitem.py b/tests/functional/openlp_plugins/media/test_mediaitem.py index 51d7bb673..6f935caec 100644 --- a/tests/functional/openlp_plugins/media/test_mediaitem.py +++ b/tests/functional/openlp_plugins/media/test_mediaitem.py @@ -55,6 +55,18 @@ def test_search_found(media_item): assert result == [['test.mp4', 'test.mp4']], 'The result file contain the file name' +def test_search_found_mixed(media_item): + """ + Media Remote Search Successful find with Paths and Strings + """ + # GIVEN: The Mediaitem set up a list of media + media_item.settings.setValue('media/media files', [Path('test.mp3'), 'test.mp4']) + # WHEN: Retrieving the test file + result = media_item.search('test.mp4', False) + # THEN: a file should be found + assert result == [['test.mp4', 'test.mp4']], 'The result file contain the file name' + + def test_search_not_found(media_item): """ Media Remote Search not find