forked from openlp/openlp
more state stuff
This commit is contained in:
parent
92492ab0e8
commit
1d4a414240
@ -35,6 +35,7 @@ from traceback import format_exception
|
||||
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
from openlp.core.state import State
|
||||
from openlp.core.common import is_macosx, is_win
|
||||
from openlp.core.common.applocation import AppLocation
|
||||
from openlp.core.loader import loader
|
||||
@ -118,6 +119,7 @@ class OpenLP(QtWidgets.QApplication):
|
||||
self.main_window = MainWindow()
|
||||
Registry().execute('bootstrap_initialise')
|
||||
Registry().execute('bootstrap_post_set_up')
|
||||
State().flush_preconditions()
|
||||
Registry().initialise = False
|
||||
self.main_window.show()
|
||||
if can_show_splash:
|
||||
|
@ -24,11 +24,9 @@ Provide the generic plugin functionality for OpenLP plugins.
|
||||
"""
|
||||
import logging
|
||||
|
||||
from PyQt5 import QtCore
|
||||
|
||||
from openlp.core.common.i18n import UiStrings
|
||||
from openlp.core.common.mixins import RegistryProperties
|
||||
from openlp.core.common.registry import Registry
|
||||
from openlp.core.common.registry import Registry, RegistryBase
|
||||
from openlp.core.common.settings import Settings
|
||||
from openlp.core.version import get_version
|
||||
|
||||
@ -60,7 +58,7 @@ class StringContent(object):
|
||||
VisibleName = 'visible_name'
|
||||
|
||||
|
||||
class Plugin(QtCore.QObject, RegistryProperties):
|
||||
class Plugin(RegistryBase, RegistryProperties):
|
||||
"""
|
||||
Base class for openlp plugins to inherit from.
|
||||
|
||||
|
@ -25,6 +25,7 @@ The :mod:`~openlp.core.commmon.loader` module provides a bootstrap for the commo
|
||||
|
||||
from openlp.core.state import State
|
||||
from openlp.core.ui.media import MediaController
|
||||
from openlp.core.lib.pluginmanager import PluginManager
|
||||
|
||||
|
||||
def loader():
|
||||
@ -34,5 +35,5 @@ def loader():
|
||||
:return: None
|
||||
"""
|
||||
State().load_settings()
|
||||
|
||||
MediaController()
|
||||
PluginManager()
|
||||
|
@ -28,13 +28,27 @@ logging and a plugin framework are contained within the openlp.core module.
|
||||
"""
|
||||
import logging
|
||||
|
||||
from openlp.core.common.mixins import LogMixin
|
||||
from openlp.core.lib.plugin import PluginStatus
|
||||
|
||||
|
||||
log = logging.getLogger()
|
||||
|
||||
|
||||
class State(object):
|
||||
class StateModule(LogMixin):
|
||||
def __init__(self):
|
||||
"""
|
||||
"""
|
||||
super(StateModule, self).__init__()
|
||||
self.name = None
|
||||
self.order = 0
|
||||
self.status = PluginStatus.Inactive
|
||||
self.pass_preconditions = True
|
||||
self.requires = None
|
||||
self.required_by = None
|
||||
|
||||
|
||||
class State(LogMixin):
|
||||
|
||||
__instance__ = None
|
||||
|
||||
@ -44,7 +58,6 @@ class State(object):
|
||||
"""
|
||||
if not cls.__instance__:
|
||||
cls.__instance__ = object.__new__(cls)
|
||||
cls.modules = {}
|
||||
return cls.__instance__
|
||||
|
||||
def load_settings(self):
|
||||
@ -53,12 +66,47 @@ class State(object):
|
||||
def save_settings(self):
|
||||
pass
|
||||
|
||||
def add_service(self, name, order, status, dependance=None):
|
||||
def add_service(self, name, order, status=PluginStatus.Active, requires=None):
|
||||
"""
|
||||
Add a module to the array and lod dependancies. There will only be one item per module
|
||||
:param name: Module name
|
||||
:param order: Order fo display
|
||||
:param status: The active status
|
||||
:param requires: Module name this requires
|
||||
:return:
|
||||
"""
|
||||
if name not in self.modules:
|
||||
self.modules[name] = {'order': order, 'status': status, 'depemdancy': dependance}
|
||||
state = StateModule()
|
||||
state.name = name
|
||||
state.order = order
|
||||
state.status = status
|
||||
state.requires = requires
|
||||
state.required_by = []
|
||||
self.modules[name] = state
|
||||
if requires and requires in self.modules:
|
||||
if requires not in self.modules[requires].required_by:
|
||||
self.modules[requires].required_by.append(name)
|
||||
|
||||
def is_service_active(self, name):
|
||||
return self.modules[name]['status'] == PluginStatus.Active
|
||||
def update_pre_conditions(self, name, status):
|
||||
"""
|
||||
Updates the preconditions state of a module
|
||||
:param name: Module name
|
||||
:param status: Module new status
|
||||
:return:
|
||||
"""
|
||||
self.modules[name].pass_preconditions = status
|
||||
|
||||
def flush_preconditions(self):
|
||||
"""
|
||||
Now all modules are loaded lets update all the preconditions.
|
||||
:return:
|
||||
"""
|
||||
for mods in self.modules:
|
||||
for req in self.modules[mods].required_by:
|
||||
self.modules[mods].pass_preconditions = self.modules[req].pass_preconditions
|
||||
|
||||
def is_module_active(self, name):
|
||||
return self.modules[name].status == PluginStatus.Active
|
||||
|
||||
def check_active_dependency(self, name):
|
||||
pass
|
||||
|
@ -506,7 +506,6 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, LogMixin, RegistryPropert
|
||||
self.formatting_tag_form = FormattingTagForm(self)
|
||||
self.shortcut_form = ShortcutListForm(self)
|
||||
# Set up the path with plugins
|
||||
PluginManager(self)
|
||||
ImageManager()
|
||||
Renderer()
|
||||
# Set up the interface
|
||||
|
@ -25,13 +25,20 @@ related to playing media, such as sliders.
|
||||
"""
|
||||
import datetime
|
||||
import logging
|
||||
import os
|
||||
|
||||
try:
|
||||
import pymediainfo
|
||||
pymediainfo_available = True
|
||||
except ImportError:
|
||||
pymediainfo_available = False
|
||||
|
||||
from subprocess import check_output
|
||||
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
from openlp.core.state import State
|
||||
from openlp.core.api.http import register_endpoint
|
||||
from openlp.core.common import extension_loader
|
||||
from openlp.core.common.i18n import UiStrings, translate
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.common.mixins import LogMixin, RegistryProperties
|
||||
from openlp.core.common.registry import Registry, RegistryBase
|
||||
from openlp.core.common.settings import Settings
|
||||
@ -41,9 +48,7 @@ from openlp.core.ui import DisplayControllerType
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.ui.media import MediaState, MediaInfo, MediaType, parse_optical_path
|
||||
from openlp.core.ui.media.endpoint import media_endpoint
|
||||
from openlp.core.ui.media.mediaplayer import MediaPlayer
|
||||
from openlp.core.ui.media.vlcplayer import VlcPlayer
|
||||
from openlp.core.ui.media.vendor.mediainfoWrapper import MediaInfoWrapper
|
||||
from openlp.core.ui.media.vlcplayer import VlcPlayer, get_vlc
|
||||
from openlp.core.widgets.toolbar import OpenLPToolbar
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@ -62,7 +67,6 @@ class MediaSlider(QtWidgets.QSlider):
|
||||
super(MediaSlider, self).__init__(direction)
|
||||
self.manager = manager
|
||||
self.controller = controller
|
||||
self.no_matching_player = translate('MediaPlugin.MediaItem', 'File %s not supported using player %s')
|
||||
|
||||
def mouseMoveEvent(self, event):
|
||||
"""
|
||||
@ -193,6 +197,9 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
# self.register_players()
|
||||
self.setup()
|
||||
self.media_players = VlcPlayer(self)
|
||||
State().add_service("mediacontroller", 0)
|
||||
if get_vlc() and pymediainfo_available:
|
||||
State().update_pre_conditions("mediacontroller", True)
|
||||
self._generate_extensions_lists()
|
||||
return True
|
||||
|
||||
@ -460,7 +467,14 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
media_info = MediaInfo()
|
||||
media_info.volume = 0
|
||||
media_info.file_info = QtCore.QFileInfo(service_item.get_frame_path())
|
||||
media_data = MediaInfoWrapper.parse(service_item.get_frame_path())
|
||||
filename = service_item.get_frame_path()
|
||||
if pymediainfo.MediaInfo.can_parse():
|
||||
media_data = pymediainfo.MediaInfo.parse(filename)
|
||||
else:
|
||||
xml = check_output(['mediainfo', '-f', '--Output=XML', '--Inform=OLDXML', filename])
|
||||
if not xml.startswith(b'<?xml'):
|
||||
xml = check_output(['mediainfo', '-f', '--Output=XML', filename])
|
||||
media_data = pymediainfo.MediaInfo(xml)
|
||||
# duration returns in milli seconds
|
||||
service_item.set_media_length(media_data.tracks[0].duration)
|
||||
return True
|
||||
|
128
openlp/core/ui/media/vendor/mediainfoWrapper.py
vendored
128
openlp/core/ui/media/vendor/mediainfoWrapper.py
vendored
@ -1,128 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2018 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; version 2 of the License. #
|
||||
# #
|
||||
# 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, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
"""
|
||||
The :mod:`~openlp.core.ui.media.mediainfo` module contains code to run mediainfo on a media file and obtain
|
||||
information related to the rwquested media.
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
from subprocess import check_output
|
||||
|
||||
from bs4 import BeautifulSoup, NavigableString
|
||||
|
||||
ENV_DICT = os.environ
|
||||
|
||||
|
||||
class Track(object):
|
||||
|
||||
def __getattribute__(self, name):
|
||||
try:
|
||||
return object.__getattribute__(self, name)
|
||||
except:
|
||||
pass
|
||||
return None
|
||||
|
||||
def __init__(self, xml_dom_fragment):
|
||||
self.xml_dom_fragment = xml_dom_fragment
|
||||
self.track_type = xml_dom_fragment.attrs['type']
|
||||
for el in self.xml_dom_fragment.children:
|
||||
if not isinstance(el, NavigableString):
|
||||
node_name = el.name.lower().strip().strip('_')
|
||||
if node_name == 'id':
|
||||
node_name = 'track_id'
|
||||
node_value = el.string
|
||||
other_node_name = "other_%s" % node_name
|
||||
if getattr(self, node_name) is None:
|
||||
setattr(self, node_name, node_value)
|
||||
else:
|
||||
if getattr(self, other_node_name) is None:
|
||||
setattr(self, other_node_name, [node_value, ])
|
||||
else:
|
||||
getattr(self, other_node_name).append(node_value)
|
||||
|
||||
for o in [d for d in self.__dict__.keys() if d.startswith('other_')]:
|
||||
try:
|
||||
primary = o.replace('other_', '')
|
||||
setattr(self, primary, int(getattr(self, primary)))
|
||||
except:
|
||||
for v in getattr(self, o):
|
||||
try:
|
||||
current = getattr(self, primary)
|
||||
setattr(self, primary, int(v))
|
||||
getattr(self, o).append(current)
|
||||
break
|
||||
except:
|
||||
pass
|
||||
|
||||
def __repr__(self):
|
||||
return "<Track track_id='{0}', track_type='{1}'>".format(self.track_id, self.track_type)
|
||||
|
||||
def to_data(self):
|
||||
data = {}
|
||||
for k, v in self.__dict__.items():
|
||||
if k != 'xml_dom_fragment':
|
||||
data[k] = v
|
||||
return data
|
||||
|
||||
|
||||
class MediaInfoWrapper(object):
|
||||
|
||||
def __init__(self, xml):
|
||||
self.xml_dom = xml
|
||||
xml_types = (str,) # no unicode type in python3
|
||||
if isinstance(xml, xml_types):
|
||||
self.xml_dom = MediaInfoWrapper.parse_xml_data_into_dom(xml)
|
||||
|
||||
@staticmethod
|
||||
def parse_xml_data_into_dom(xml_data):
|
||||
return BeautifulSoup(xml_data, "xml")
|
||||
|
||||
@staticmethod
|
||||
def parse(filename, environment=ENV_DICT):
|
||||
xml = check_output(['mediainfo', '-f', '--Output=XML', '--Inform=OLDXML', filename])
|
||||
if not xml.startswith(b'<?xml'):
|
||||
xml = check_output(['mediainfo', '-f', '--Output=XML', filename])
|
||||
xml_dom = MediaInfoWrapper.parse_xml_data_into_dom(xml)
|
||||
return MediaInfoWrapper(xml_dom)
|
||||
|
||||
def _populate_tracks(self):
|
||||
if self.xml_dom is None:
|
||||
return
|
||||
for xml_track in self.xml_dom.Mediainfo.File.find_all("track"):
|
||||
self._tracks.append(Track(xml_track))
|
||||
|
||||
@property
|
||||
def tracks(self):
|
||||
if not hasattr(self, "_tracks"):
|
||||
self._tracks = []
|
||||
if len(self._tracks) == 0:
|
||||
self._populate_tracks()
|
||||
return self._tracks
|
||||
|
||||
def to_data(self):
|
||||
data = {'tracks': []}
|
||||
for track in self.tracks:
|
||||
data['tracks'].append(track.to_data())
|
||||
return data
|
||||
|
||||
def to_json(self):
|
||||
return json.dumps(self.to_data())
|
@ -81,7 +81,7 @@ def get_vlc():
|
||||
# Newer versions of VLC on OS X need this. See https://forum.videolan.org/viewtopic.php?t=124521
|
||||
os.environ['VLC_PLUGIN_PATH'] = '/Applications/VLC.app/Contents/MacOS/plugins'
|
||||
# On Windows when frozen in PyInstaller, we need to blank SetDllDirectoryW to allow loading of the VLC dll.
|
||||
# This is due to limitations (by desgin) in PyInstaller. SetDllDirectoryW original value is restored once
|
||||
# This is due to limitations (by design) in PyInstaller. SetDllDirectoryW original value is restored once
|
||||
# VLC has been imported.
|
||||
if is_win():
|
||||
buffer_size = 1024
|
||||
|
@ -339,31 +339,31 @@ class SlideController(DisplayController, LogMixin, RegistryProperties):
|
||||
self.toolbar.add_toolbar_widget(self.song_menu)
|
||||
# Stuff for items with background audio.
|
||||
# FIXME: object name should be changed. But this requires that we migrate the shortcut.
|
||||
self.audio_pause_item = self.toolbar.add_toolbar_action(
|
||||
'audioPauseItem',
|
||||
icon=UiIcons().pause, text=translate('OpenLP.SlideController', 'Pause Audio'),
|
||||
tooltip=translate('OpenLP.SlideController', 'Pause audio.'),
|
||||
checked=False, visible=False, category=self.category, context=QtCore.Qt.WindowShortcut,
|
||||
can_shortcuts=True, triggers=self.set_audio_pause_clicked)
|
||||
self.audio_menu = QtWidgets.QMenu(translate('OpenLP.SlideController', 'Background Audio'), self.toolbar)
|
||||
self.audio_pause_item.setMenu(self.audio_menu)
|
||||
self.audio_pause_item.setParent(self.toolbar)
|
||||
self.toolbar.widgetForAction(self.audio_pause_item).setPopupMode(QtWidgets.QToolButton.MenuButtonPopup)
|
||||
self.next_track_item = create_action(self, 'nextTrackItem', text=UiStrings().NextTrack,
|
||||
icon=UiIcons().arrow_right,
|
||||
tooltip=translate('OpenLP.SlideController',
|
||||
'Go to next audio track.'),
|
||||
category=self.category,
|
||||
can_shortcuts=True,
|
||||
triggers=self.on_next_track_clicked)
|
||||
self.audio_menu.addAction(self.next_track_item)
|
||||
self.track_menu = self.audio_menu.addMenu(translate('OpenLP.SlideController', 'Tracks'))
|
||||
self.audio_time_label = QtWidgets.QLabel(' 00:00 ', self.toolbar)
|
||||
self.audio_time_label.setAlignment(QtCore.Qt.AlignCenter | QtCore.Qt.AlignHCenter)
|
||||
self.audio_time_label.setStyleSheet(AUDIO_TIME_LABEL_STYLESHEET)
|
||||
self.audio_time_label.setObjectName('audio_time_label')
|
||||
self.toolbar.add_toolbar_widget(self.audio_time_label)
|
||||
self.toolbar.set_widget_visible(AUDIO_LIST, False)
|
||||
# self.audio_pause_item = self.toolbar.add_toolbar_action(
|
||||
# 'audioPauseItem',
|
||||
# icon=UiIcons().pause, text=translate('OpenLP.SlideController', 'Pause Audio'),
|
||||
# tooltip=translate('OpenLP.SlideController', 'Pause audio.'),
|
||||
# checked=False, visible=False, category=self.category, context=QtCore.Qt.WindowShortcut,
|
||||
# can_shortcuts=True, triggers=self.set_audio_pause_clicked)
|
||||
# self.audio_menu = QtWidgets.QMenu(translate('OpenLP.SlideController', 'Background Audio'), self.toolbar)
|
||||
# self.audio_pause_item.setMenu(self.audio_menu)
|
||||
# self.audio_pause_item.setParent(self.toolbar)
|
||||
# self.toolbar.widgetForAction(self.audio_pause_item).setPopupMode(QtWidgets.QToolButton.MenuButtonPopup)
|
||||
# self.next_track_item = create_action(self, 'nextTrackItem', text=UiStrings().NextTrack,
|
||||
# icon=UiIcons().arrow_right,
|
||||
# tooltip=translate('OpenLP.SlideController',
|
||||
# 'Go to next audio track.'),
|
||||
# category=self.category,
|
||||
# can_shortcuts=True,
|
||||
# triggers=self.on_next_track_clicked)
|
||||
# self.audio_menu.addAction(self.next_track_item)
|
||||
# self.track_menu = self.audio_menu.addMenu(translate('OpenLP.SlideController', 'Tracks'))
|
||||
# self.audio_time_label = QtWidgets.QLabel(' 00:00 ', self.toolbar)
|
||||
# self.audio_time_label.setAlignment(QtCore.Qt.AlignCenter | QtCore.Qt.AlignHCenter)
|
||||
# self.audio_time_label.setStyleSheet(AUDIO_TIME_LABEL_STYLESHEET)
|
||||
# self.audio_time_label.setObjectName('audio_time_label')
|
||||
# self.toolbar.add_toolbar_widget(self.audio_time_label)
|
||||
# self.toolbar.set_widget_visible(AUDIO_LIST, False)
|
||||
self.toolbar.set_widget_visible('song_menu', False)
|
||||
# Screen preview area
|
||||
self.preview_frame = QtWidgets.QFrame(self.splitter)
|
||||
@ -874,24 +874,25 @@ class SlideController(DisplayController, LogMixin, RegistryProperties):
|
||||
if self.display.audio_player:
|
||||
self.display.audio_player.reset()
|
||||
self.set_audio_items_visibility(False)
|
||||
self.audio_pause_item.setChecked(False)
|
||||
# self.audio_pause_item.setChecked(False)
|
||||
# If the current item has background audio
|
||||
if self.service_item.is_capable(ItemCapabilities.HasBackgroundAudio):
|
||||
self.log_debug('Starting to play...')
|
||||
self.display.audio_player.add_to_playlist(self.service_item.background_audio)
|
||||
self.track_menu.clear()
|
||||
for counter in range(len(self.service_item.background_audio)):
|
||||
action = self.track_menu.addAction(
|
||||
os.path.basename(str(self.service_item.background_audio[counter])))
|
||||
action.setData(counter)
|
||||
action.triggered.connect(self.on_track_triggered)
|
||||
self.display.audio_player.repeat = \
|
||||
Settings().value(self.main_window.general_settings_section + '/audio repeat list')
|
||||
if Settings().value(self.main_window.general_settings_section + '/audio start paused'):
|
||||
self.audio_pause_item.setChecked(True)
|
||||
self.display.audio_player.pause()
|
||||
else:
|
||||
self.display.audio_player.play()
|
||||
self.on_media_start(service_item)
|
||||
#self.log_debug('Starting to play...')
|
||||
#self.display.audio_player.add_to_playlist(self.service_item.background_audio)
|
||||
#self.track_menu.clear()
|
||||
#for counter in range(len(self.service_item.background_audio)):
|
||||
# action = self.track_menu.addAction(
|
||||
# os.path.basename(str(self.service_item.background_audio[counter])))
|
||||
# action.setData(counter)
|
||||
# action.triggered.connect(self.on_track_triggered)
|
||||
#self.display.audio_player.repeat = \
|
||||
# Settings().value(self.main_window.general_settings_section + '/audio repeat list')
|
||||
#if Settings().value(self.main_window.general_settings_section + '/audio start paused'):
|
||||
# self.audio_pause_item.setChecked(True)
|
||||
# self.display.audio_player.pause()
|
||||
#else:
|
||||
# self.display.audio_player.play()
|
||||
self.set_audio_items_visibility(True)
|
||||
row = 0
|
||||
width = self.main_window.control_splitter.sizes()[self.split]
|
||||
|
@ -24,6 +24,7 @@ import logging
|
||||
|
||||
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.i18n import UiStrings, translate
|
||||
@ -146,6 +147,8 @@ class AlertsPlugin(Plugin):
|
||||
self.alert_form = AlertForm(self)
|
||||
register_endpoint(alerts_endpoint)
|
||||
register_endpoint(api_alerts_endpoint)
|
||||
State().add_service(self.name, self.weight)
|
||||
State().update_pre_conditions(self.name, self.check_pre_conditions())
|
||||
|
||||
def add_tools_menu_item(self, tools_menu):
|
||||
"""
|
||||
|
@ -22,11 +22,11 @@
|
||||
|
||||
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.i18n import UiStrings, translate
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.lib import build_icon
|
||||
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
|
||||
@ -81,6 +81,8 @@ class BiblePlugin(Plugin):
|
||||
self.manager = BibleManager(self)
|
||||
register_endpoint(bibles_endpoint)
|
||||
register_endpoint(api_bibles_endpoint)
|
||||
State().add_service(self.name, self.weight)
|
||||
State().update_pre_conditions(self.name, self.check_pre_conditions())
|
||||
|
||||
def initialise(self):
|
||||
"""
|
||||
|
@ -26,6 +26,7 @@ for the Custom Slides plugin.
|
||||
|
||||
import logging
|
||||
|
||||
from openlp.core.state import State
|
||||
from openlp.core.api.http import register_endpoint
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
@ -68,6 +69,8 @@ class CustomPlugin(Plugin):
|
||||
self.icon = build_icon(self.icon_path)
|
||||
register_endpoint(custom_endpoint)
|
||||
register_endpoint(api_custom_endpoint)
|
||||
State().add_service(self.name, self.weight)
|
||||
State().update_pre_conditions(self.name, self.check_pre_conditions())
|
||||
|
||||
@staticmethod
|
||||
def about():
|
||||
|
@ -24,6 +24,7 @@ import logging
|
||||
|
||||
from PyQt5 import QtGui
|
||||
|
||||
from openlp.core.state import State
|
||||
from openlp.core.api.http import register_endpoint
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
@ -59,6 +60,8 @@ class ImagePlugin(Plugin):
|
||||
self.icon = build_icon(self.icon_path)
|
||||
register_endpoint(images_endpoint)
|
||||
register_endpoint(api_images_endpoint)
|
||||
State().add_service(self.name, self.weight)
|
||||
State().update_pre_conditions(self.name, self.check_pre_conditions())
|
||||
|
||||
@staticmethod
|
||||
def about():
|
||||
|
@ -27,6 +27,7 @@ import re
|
||||
|
||||
from PyQt5 import QtCore
|
||||
|
||||
from openlp.core.state import State
|
||||
from openlp.core.api.http import register_endpoint
|
||||
from openlp.core.common import check_binary_exists
|
||||
from openlp.core.common.applocation import AppLocation
|
||||
@ -64,6 +65,8 @@ class MediaPlugin(Plugin):
|
||||
self.dnd_id = 'Media'
|
||||
register_endpoint(media_endpoint)
|
||||
register_endpoint(api_media_endpoint)
|
||||
State().add_service(self.name, self.weight, requires='mediacontroller')
|
||||
State().update_pre_conditions(self.name, self.check_pre_conditions())
|
||||
|
||||
def initialise(self):
|
||||
"""
|
||||
|
@ -28,6 +28,7 @@ import os
|
||||
|
||||
from PyQt5 import QtCore
|
||||
|
||||
from openlp.core.state import State
|
||||
from openlp.core.api.http import register_endpoint
|
||||
from openlp.core.common import extension_loader
|
||||
from openlp.core.common.i18n import translate
|
||||
@ -74,6 +75,8 @@ class PresentationPlugin(Plugin):
|
||||
self.icon = build_icon(self.icon_path)
|
||||
register_endpoint(presentations_endpoint)
|
||||
register_endpoint(api_presentations_endpoint)
|
||||
State().add_service(self.name, self.weight)
|
||||
State().update_pre_conditions(self.name, self.check_pre_conditions())
|
||||
|
||||
def create_settings_tab(self, parent):
|
||||
"""
|
||||
|
@ -634,7 +634,7 @@ class SongMediaItem(MediaManagerItem):
|
||||
if song.media_files:
|
||||
service_item.add_capability(ItemCapabilities.HasBackgroundAudio)
|
||||
service_item.background_audio = [m.file_path for m in song.media_files]
|
||||
item.metadata.append('<em>{label}:</em> {media}'.
|
||||
service_item.metadata.append('<em>{label}:</em> {media}'.
|
||||
format(label=translate('SongsPlugin.MediaItem', 'Media'),
|
||||
media=service_item.background_audio))
|
||||
return True
|
||||
|
@ -31,6 +31,7 @@ from tempfile import gettempdir
|
||||
|
||||
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.i18n import UiStrings, translate
|
||||
@ -99,6 +100,8 @@ class SongsPlugin(Plugin):
|
||||
self.songselect_form = None
|
||||
register_endpoint(songs_endpoint)
|
||||
register_endpoint(api_songs_endpoint)
|
||||
State().add_service(self.name, self.weight)
|
||||
State().update_pre_conditions(self.name, self.check_pre_conditions())
|
||||
|
||||
def check_pre_conditions(self):
|
||||
"""
|
||||
|
@ -25,6 +25,7 @@ from datetime import datetime
|
||||
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
from openlp.core.state import State
|
||||
from openlp.core.common.actions import ActionList
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.common.registry import Registry
|
||||
@ -66,6 +67,8 @@ class SongUsagePlugin(Plugin):
|
||||
self.weight = -4
|
||||
self.icon = UiIcons().song_usage
|
||||
self.song_usage_active = False
|
||||
State().add_service(self.name, self.weight)
|
||||
State().update_pre_conditions(self.name, self.check_pre_conditions())
|
||||
|
||||
def check_pre_conditions(self):
|
||||
"""
|
||||
|
@ -99,7 +99,8 @@ MODULES = [
|
||||
'six',
|
||||
'webob',
|
||||
'requests',
|
||||
'qtawesome'
|
||||
'qtawesome',
|
||||
'pymediainfo'
|
||||
]
|
||||
|
||||
|
||||
|
@ -72,9 +72,24 @@ class TestState(TestCase, TestMixin):
|
||||
# WHEN I add a new service twice
|
||||
State().add_service("test", 1, PluginStatus.Active)
|
||||
State().add_service("test1", 1, PluginStatus.Active, "test")
|
||||
State().add_service("test1", 1, PluginStatus.Active, "test")
|
||||
|
||||
# THEN I have a single saved service
|
||||
# THEN I have a single saved service and one dependancy
|
||||
assert len(State().modules) == 2
|
||||
assert len(State().modules['test'].required_by) == 1
|
||||
|
||||
def test_add_service_multiple_depends(self):
|
||||
# GIVEN a new state
|
||||
State().load_settings()
|
||||
|
||||
# WHEN I add a new service twice
|
||||
State().add_service("test", 1, PluginStatus.Active)
|
||||
State().add_service("test1", 1, PluginStatus.Active, "test")
|
||||
State().add_service("test2", 1, PluginStatus.Active, "test")
|
||||
|
||||
# THEN I have a 3 modules and 2 dependancies
|
||||
assert len(State().modules) == 3
|
||||
assert len(State().modules['test'].required_by) == 2
|
||||
|
||||
def test_active_service(self):
|
||||
# GIVEN a new state
|
||||
@ -84,7 +99,7 @@ class TestState(TestCase, TestMixin):
|
||||
State().add_service("test", 1, PluginStatus.Active)
|
||||
|
||||
# THEN I have a single saved service
|
||||
assert State().is_service_active('test') is True
|
||||
assert State().is_module_active('test') is True
|
||||
|
||||
def test_inactive_service(self):
|
||||
# GIVEN a new state
|
||||
@ -94,4 +109,23 @@ class TestState(TestCase, TestMixin):
|
||||
State().add_service("test", 1, PluginStatus.Inactive)
|
||||
|
||||
# THEN I have a single saved service
|
||||
assert State().is_service_active('test') is False
|
||||
assert State().is_module_active('test') is False
|
||||
|
||||
def test_basic_preconditions(self):
|
||||
# GIVEN a new state
|
||||
State().load_settings()
|
||||
|
||||
# WHEN I add a new services with dependancies and a failed pre condition
|
||||
State().add_service("test", 1, PluginStatus.Inactive)
|
||||
State().add_service("test2", 1, PluginStatus.Inactive)
|
||||
State().add_service("test1", 1, PluginStatus.Inactive, 'test')
|
||||
State().update_pre_conditions('test1', False)
|
||||
|
||||
# THEN correct the state when I flush the preconditions
|
||||
assert State().modules['test'].pass_preconditions == True
|
||||
assert State().modules['test2'].pass_preconditions == True
|
||||
assert State().modules['test1'].pass_preconditions == False
|
||||
State().flush_preconditions()
|
||||
assert State().modules['test'].pass_preconditions == False
|
||||
assert State().modules['test2'].pass_preconditions == True
|
||||
assert State().modules['test1'].pass_preconditions == False
|
||||
|
@ -30,6 +30,12 @@ from openlp.core.ui.media.mediacontroller import MediaController
|
||||
from openlp.core.ui.media.mediaplayer import MediaPlayer
|
||||
from tests.helpers.testmixin import TestMixin
|
||||
|
||||
from tests.utils.constants import RESOURCE_PATH
|
||||
|
||||
|
||||
TEST_PATH = RESOURCE_PATH / 'media'
|
||||
TEST_MEDIA = [['avi_file.avi', 61495], ['mp3_file.mp3', 134426], ['mpg_file.mpg', 9404], ['mp4_file.mp4', 188336]]
|
||||
|
||||
|
||||
class TestMediaController(TestCase, TestMixin):
|
||||
|
||||
@ -254,3 +260,18 @@ class TestMediaController(TestCase, TestMixin):
|
||||
|
||||
# THEN: The underlying method is called
|
||||
mocked_media_seek.assert_called_with(1, 800)
|
||||
|
||||
def test_media_length(self):
|
||||
"""
|
||||
Test the Media Info basic functionality
|
||||
"""
|
||||
for test_data in TEST_MEDIA:
|
||||
# GIVEN: a media file
|
||||
full_path = str(TEST_PATH / test_data[0])
|
||||
media_controller = MediaController()
|
||||
|
||||
# WHEN the media data is retrieved
|
||||
results = media_controller.media_length(full_path)
|
||||
|
||||
# THEN you can determine the run time
|
||||
assert results.tracks[0].duration == test_data[1], 'The correct duration is returned for ' + test_data[0]
|
||||
|
@ -1,21 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2018 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; version 2 of the License. #
|
||||
# #
|
||||
# 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, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
@ -1,21 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2018 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; version 2 of the License. #
|
||||
# #
|
||||
# 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, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
@ -1,48 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2018 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; version 2 of the License. #
|
||||
# #
|
||||
# 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, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
"""
|
||||
Package to test the openlp.core.ui.media package.
|
||||
"""
|
||||
from unittest import TestCase
|
||||
|
||||
from openlp.core.ui.media.vendor.mediainfoWrapper import MediaInfoWrapper
|
||||
from tests.utils.constants import RESOURCE_PATH
|
||||
|
||||
TEST_PATH = RESOURCE_PATH / 'media'
|
||||
TEST_MEDIA = [['avi_file.avi', 61495], ['mp3_file.mp3', 134426], ['mpg_file.mpg', 9404], ['mp4_file.mp4', 188336]]
|
||||
|
||||
|
||||
class TestMediainfoWrapper(TestCase):
|
||||
|
||||
def test_media_length(self):
|
||||
"""
|
||||
Test the Media Info basic functionality
|
||||
"""
|
||||
for test_data in TEST_MEDIA:
|
||||
# GIVEN: a media file
|
||||
full_path = str(TEST_PATH / test_data[0])
|
||||
|
||||
# WHEN the media data is retrieved
|
||||
results = MediaInfoWrapper.parse(full_path)
|
||||
|
||||
# THEN you can determine the run time
|
||||
assert results.tracks[0].duration == test_data[1], 'The correct duration is returned for ' + test_data[0]
|
Loading…
Reference in New Issue
Block a user