openlp/openlp/core/lib/serviceitem.py

648 lines
24 KiB
Python
Raw Normal View History

# -*- coding: utf-8 -*-
2012-12-07 21:57:35 +00:00
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
2013-12-24 08:56:50 +00:00
# Copyright (c) 2008-2014 Raoul Snyman #
# Portions copyright (c) 2008-2014 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
2012-11-11 21:16:14 +00:00
# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. #
2012-10-21 13:16:22 +00:00
# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, #
# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, #
# Frode Woldsund, Martin Zibricky, Patrick Zimmermann #
# --------------------------------------------------------------------------- #
# 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 #
###############################################################################
2010-06-10 21:30:50 +00:00
"""
The :mod:`serviceitem` provides the service item functionality including the
type and capability of an item.
"""
2012-05-23 16:53:08 +00:00
2011-02-13 10:37:27 +00:00
import datetime
2014-01-11 17:52:01 +00:00
import html
2009-05-02 11:16:08 +00:00
import logging
import os
2009-11-04 17:48:46 +00:00
import uuid
2009-07-10 13:16:15 +00:00
2013-01-18 23:31:02 +00:00
from PyQt4 import QtGui
2009-07-10 13:16:15 +00:00
2014-03-16 21:25:23 +00:00
from openlp.core.common import RegistryProperties, Settings, translate
2013-12-13 17:44:05 +00:00
from openlp.core.lib import ImageSource, build_icon, clean_tags, expand_tags
2009-07-10 13:16:15 +00:00
2010-02-27 15:31:23 +00:00
log = logging.getLogger(__name__)
2013-02-01 19:58:18 +00:00
class ServiceItemType(object):
2009-09-29 04:58:26 +00:00
"""
Defines the type of service item
"""
Text = 1
Image = 2
Command = 3
2010-04-03 07:10:31 +00:00
class ItemCapabilities(object):
2010-06-10 21:30:50 +00:00
"""
2012-10-20 19:52:04 +00:00
Provides an enumeration of a service item's capabilities
2012-11-22 21:58:16 +00:00
``CanPreview``
The capability to allow the ServiceManager to add to the preview tab when making the previous item live.
2012-11-22 21:58:16 +00:00
``CanEdit``
2013-04-08 16:53:11 +00:00
The capability to allow the ServiceManager to allow the item to be edited
2012-11-22 21:58:16 +00:00
``CanMaintain``
2013-04-08 16:53:11 +00:00
The capability to allow the ServiceManager to allow the item to be reordered.
2012-11-22 21:58:16 +00:00
``RequiresMedia``
2013-03-06 22:23:01 +00:00
Determines is the service_item needs a Media Player
2012-11-22 21:58:16 +00:00
``CanLoop``
The capability to allow the SlideController to allow the loop processing.
2012-11-22 21:58:16 +00:00
``CanAppend``
The capability to allow the ServiceManager to add leaves to the
item
``NoLineBreaks``
The capability to remove lines breaks in the renderer
``OnLoadUpdate``
The capability to update MediaManager when a service Item is loaded.
2012-11-22 21:58:16 +00:00
``AddIfNewItem``
2012-11-24 07:24:30 +00:00
Not Used
2012-11-22 21:58:16 +00:00
``ProvidesOwnDisplay``
The capability to tell the SlideController the service Item has a different display.
2012-11-22 21:58:16 +00:00
``HasDetailedTitleDisplay``
Being Removed and decommissioned.
2012-11-22 21:58:16 +00:00
``HasVariableStartTime``
The capability to tell the ServiceManager that a change to start time is possible.
2012-11-22 21:58:16 +00:00
``CanSoftBreak``
The capability to tell the renderer that Soft Break is allowed
``CanWordSplit``
2012-11-24 07:24:30 +00:00
The capability to tell the renderer that it can split words is
allowed
2012-11-22 21:58:16 +00:00
``HasBackgroundAudio``
2012-11-24 07:24:30 +00:00
That a audio file is present with the text.
2012-11-22 21:58:16 +00:00
``CanAutoStartForLive``
The capability to ignore the do not play if display blank flag.
``CanEditTitle``
2013-07-08 21:26:31 +00:00
The capability to edit the title of the item
2012-11-22 21:58:16 +00:00
``IsOptical``
.Determines is the service_item is based on an optical device
2014-04-20 13:57:12 +00:00
2010-06-10 21:30:50 +00:00
"""
2011-08-28 17:45:13 +00:00
CanPreview = 1
CanEdit = 2
CanMaintain = 3
2010-05-24 22:37:20 +00:00
RequiresMedia = 4
2011-08-28 17:45:13 +00:00
CanLoop = 5
CanAppend = 6
2010-08-03 19:23:05 +00:00
NoLineBreaks = 7
2010-09-30 05:12:06 +00:00
OnLoadUpdate = 8
AddIfNewItem = 9
ProvidesOwnDisplay = 10
2011-08-28 17:45:13 +00:00
HasDetailedTitleDisplay = 11
HasVariableStartTime = 12
CanSoftBreak = 13
CanWordSplit = 14
2011-08-28 17:45:13 +00:00
HasBackgroundAudio = 15
CanAutoStartForLive = 16
CanEditTitle = 17
2014-04-20 13:57:12 +00:00
IsOptical = 18
2010-04-03 07:10:31 +00:00
2011-01-12 19:31:46 +00:00
2014-03-16 21:25:23 +00:00
class ServiceItem(RegistryProperties):
"""
The service item is a base class for the plugins to use to interact with
the service manager, the slide controller, and the projection screen
compositor.
"""
2013-08-31 18:17:38 +00:00
log.info('Service Item created')
2009-11-14 08:40:14 +00:00
def __init__(self, plugin=None):
"""
2009-07-10 13:16:15 +00:00
Set up the service item.
2014-03-17 19:05:55 +00:00
:param plugin: The plugin that this service item belongs to.
"""
2009-11-14 08:40:14 +00:00
if plugin:
self.name = plugin.name
2013-08-31 18:17:38 +00:00
self.title = ''
self.processor = None
2013-08-31 18:17:38 +00:00
self.audit = ''
2009-05-02 11:16:08 +00:00
self.items = []
self.iconic_representation = None
2011-03-04 17:31:23 +00:00
self.raw_footer = []
2013-08-31 18:17:38 +00:00
self.foot_text = ''
2009-05-02 11:16:08 +00:00
self.theme = None
self.service_item_type = None
2009-11-14 09:06:25 +00:00
self._raw_frames = []
self._display_frames = []
2013-01-21 07:34:50 +00:00
self.unique_identifier = 0
2013-08-31 18:17:38 +00:00
self.notes = ''
2010-03-28 15:56:49 +00:00
self.from_plugin = False
2010-04-03 07:10:31 +00:00
self.capabilities = []
2010-05-07 18:29:17 +00:00
self.is_valid = True
2010-06-12 20:22:58 +00:00
self.icon = None
2013-12-26 08:56:53 +00:00
self.theme_data = None
2010-07-25 08:58:08 +00:00
self.main = None
self.footer = None
2010-09-16 21:19:51 +00:00
self.bg_image_bytes = None
2013-08-31 18:17:38 +00:00
self.search_string = ''
self.data_string = ''
self.edit_id = None
self.xml_version = None
2011-02-13 13:11:15 +00:00
self.start_time = 0
2011-03-19 11:50:48 +00:00
self.end_time = 0
2011-02-14 17:54:09 +00:00
self.media_length = 0
self.from_service = False
2013-08-31 18:17:38 +00:00
self.image_border = '#000000'
2011-08-28 17:45:13 +00:00
self.background_audio = []
2011-11-04 20:09:35 +00:00
self.theme_overwritten = False
2011-12-10 08:45:17 +00:00
self.temporary_edit = False
2012-11-14 11:47:15 +00:00
self.auto_play_slides_once = False
self.auto_play_slides_loop = False
self.timed_slide_interval = 0
self.will_auto_start = False
2012-12-08 16:20:52 +00:00
self.has_original_files = True
self._new_item()
2010-04-02 19:02:38 +00:00
2010-08-02 19:08:55 +00:00
def _new_item(self):
2010-08-21 08:24:14 +00:00
"""
2014-03-17 19:05:55 +00:00
Method to set the internal id of the item. This is used to compare service items to see if they are the same.
2010-08-21 08:24:14 +00:00
"""
2013-08-31 18:17:38 +00:00
self.unique_identifier = str(uuid.uuid1())
self.validate_item()
2010-08-02 19:08:55 +00:00
2010-04-03 07:10:31 +00:00
def add_capability(self, capability):
2010-06-10 21:30:50 +00:00
"""
Add an ItemCapability to a ServiceItem
2014-03-17 19:05:55 +00:00
:param capability: The capability to add
2010-06-10 21:30:50 +00:00
"""
2010-04-03 07:10:31 +00:00
self.capabilities.append(capability)
2010-04-02 19:02:38 +00:00
2010-04-03 07:10:31 +00:00
def is_capable(self, capability):
2010-06-10 21:30:50 +00:00
"""
Tell the caller if a ServiceItem has a capability
2014-03-17 19:05:55 +00:00
:param capability: The capability to test for
2010-06-10 21:30:50 +00:00
"""
2010-04-03 07:10:31 +00:00
return capability in self.capabilities
2009-05-02 11:16:08 +00:00
2010-06-12 20:22:58 +00:00
def add_icon(self, icon):
2009-07-10 13:16:15 +00:00
"""
2014-03-17 19:05:55 +00:00
Add an icon to the service item. This is used when displaying the service item in the service manager.
2009-07-10 13:16:15 +00:00
2014-03-17 19:05:55 +00:00
:param icon: A string to an icon in the resources or on disk.
2009-07-10 13:16:15 +00:00
"""
2009-06-08 19:06:42 +00:00
self.icon = icon
self.iconic_representation = build_icon(icon)
2012-05-20 19:11:27 +00:00
def render(self, provides_own_theme_data=False):
"""
2014-03-17 19:05:55 +00:00
The render method is what generates the frames for the screen and obtains the display information from the
renderer. At this point all slides are built for the given display size.
2012-05-23 16:14:03 +00:00
2014-03-17 19:05:55 +00:00
:param provides_own_theme_data: This switch disables the usage of the item's theme. However, this is
2012-05-23 16:55:41 +00:00
disabled by default. If this is used, it has to be taken care, that
the renderer knows the correct theme data. However, this is needed
for the theme manager.
"""
2013-08-31 18:17:38 +00:00
log.debug('Render called')
2009-11-14 09:06:25 +00:00
self._display_frames = []
2010-09-16 21:19:51 +00:00
self.bg_image_bytes = None
2012-05-20 19:11:27 +00:00
if not provides_own_theme_data:
2013-01-22 19:34:15 +00:00
self.renderer.set_item_theme(self.theme)
2013-12-24 08:56:50 +00:00
self.theme_data, self.main, self.footer = self.renderer.pre_render()
if self.service_item_type == ServiceItemType.Text:
2013-08-31 18:17:38 +00:00
log.debug('Formatting slides: %s' % self.title)
2014-01-11 17:52:01 +00:00
# Save rendered pages to this dict. In the case that a slide is used twice we can use the pages saved to
# the dict instead of rendering them again.
previous_pages = {}
2009-11-14 09:06:25 +00:00
for slide in self._raw_frames:
2013-08-31 18:17:38 +00:00
verse_tag = slide['verseTag']
if verse_tag in previous_pages and previous_pages[verse_tag][0] == slide['raw_slide']:
pages = previous_pages[verse_tag][1]
else:
2013-08-31 18:17:38 +00:00
pages = self.renderer.format_slide(slide['raw_slide'], self)
previous_pages[verse_tag] = (slide['raw_slide'], pages)
2011-06-13 08:16:50 +00:00
for page in pages:
2013-08-31 18:17:38 +00:00
page = page.replace('<br>', '{br}')
2014-01-11 17:52:01 +00:00
html_data = expand_tags(html.escape(page.rstrip()))
2011-04-26 17:03:19 +00:00
self._display_frames.append({
2013-08-31 18:17:38 +00:00
'title': clean_tags(page),
'text': clean_tags(page.rstrip()),
2014-01-11 17:52:01 +00:00
'html': html_data.replace('&amp;nbsp;', '&nbsp;'),
2013-08-31 18:17:38 +00:00
'verseTag': verse_tag
2011-04-26 17:03:19 +00:00
})
2012-12-07 21:57:35 +00:00
elif self.service_item_type == ServiceItemType.Image or self.service_item_type == ServiceItemType.Command:
pass
else:
2013-08-31 18:17:38 +00:00
log.error('Invalid value renderer: %s' % self.service_item_type)
2010-08-24 17:12:47 +00:00
self.title = clean_tags(self.title)
2011-03-19 16:06:04 +00:00
# The footer should never be None, but to be compatible with a few
2011-03-19 16:11:52 +00:00
# nightly builds between 1.9.4 and 1.9.5, we have to correct this to
# avoid tracebacks.
2011-03-13 15:01:01 +00:00
if self.raw_footer is None:
self.raw_footer = []
2013-08-31 18:17:38 +00:00
self.foot_text = '<br>'.join([_f for _f in self.raw_footer if _f])
2011-08-20 11:45:06 +00:00
def add_from_image(self, path, title, background=None):
2009-07-10 13:16:15 +00:00
"""
Add an image slide to the service item.
2014-03-17 19:05:55 +00:00
:param path: The directory in which the image file is located.
:param title: A title for the slide in the service item.
:param background:
2009-07-10 13:16:15 +00:00
"""
2011-08-20 11:45:06 +00:00
if background:
self.image_border = background
self.service_item_type = ServiceItemType.Image
2013-08-31 18:17:38 +00:00
self._raw_frames.append({'title': title, 'path': path})
self.image_manager.add_image(path, ImageSource.ImagePlugin, self.image_border)
2010-08-02 19:08:55 +00:00
self._new_item()
2012-06-10 13:39:45 +00:00
def add_from_text(self, raw_slide, verse_tag=None):
2009-07-10 13:16:15 +00:00
"""
Add a text slide to the service item.
2014-03-17 19:05:55 +00:00
:param raw_slide: The raw text of the slide.
:param verse_tag:
2009-07-10 13:16:15 +00:00
"""
2011-05-11 22:32:25 +00:00
if verse_tag:
verse_tag = verse_tag.upper()
self.service_item_type = ServiceItemType.Text
2013-08-31 18:17:38 +00:00
title = raw_slide[:30].split('\n')[0]
self._raw_frames.append({'title': title, 'raw_slide': raw_slide, 'verseTag': verse_tag})
2010-08-02 19:08:55 +00:00
self._new_item()
2009-11-14 08:40:14 +00:00
def add_from_command(self, path, file_name, image):
2009-07-10 13:16:15 +00:00
"""
Add a slide from a command.
2014-03-17 19:05:55 +00:00
:param path: The title of the slide in the service item.
:param file_name: The title of the slide in the service item.
:param image: The command of/for the slide.
2009-07-10 13:16:15 +00:00
"""
self.service_item_type = ServiceItemType.Command
2013-08-31 18:17:38 +00:00
self._raw_frames.append({'title': file_name, 'image': image, 'path': path})
2010-08-02 19:08:55 +00:00
self._new_item()
2009-05-02 11:16:08 +00:00
2012-10-15 16:20:23 +00:00
def get_service_repr(self, lite_save):
"""
2014-03-17 19:05:55 +00:00
This method returns some text which can be saved into the service file to represent this item.
"""
2009-09-19 21:45:50 +00:00
service_header = {
2013-08-31 18:17:38 +00:00
'name': self.name,
'plugin': self.name,
'theme': self.theme,
'title': self.title,
'icon': self.icon,
'footer': self.raw_footer,
'type': self.service_item_type,
'audit': self.audit,
'notes': self.notes,
'from_plugin': self.from_plugin,
'capabilities': self.capabilities,
'search': self.search_string,
'data': self.data_string,
'xml_version': self.xml_version,
'auto_play_slides_once': self.auto_play_slides_once,
'auto_play_slides_loop': self.auto_play_slides_loop,
'timed_slide_interval': self.timed_slide_interval,
'start_time': self.start_time,
'end_time': self.end_time,
'media_length': self.media_length,
'background_audio': self.background_audio,
'theme_overwritten': self.theme_overwritten,
'will_auto_start': self.will_auto_start,
'processor': self.processor
2009-07-10 13:16:15 +00:00
}
2009-09-19 21:45:50 +00:00
service_data = []
if self.service_item_type == ServiceItemType.Text:
service_data = [slide for slide in self._raw_frames]
elif self.service_item_type == ServiceItemType.Image:
2012-10-15 16:20:23 +00:00
if lite_save:
for slide in self._raw_frames:
2013-08-31 18:17:38 +00:00
service_data.append({'title': slide['title'], 'path': slide['path']})
2012-10-15 16:20:23 +00:00
else:
2013-08-31 18:17:38 +00:00
service_data = [slide['title'] for slide in self._raw_frames]
elif self.service_item_type == ServiceItemType.Command:
2009-11-14 09:06:25 +00:00
for slide in self._raw_frames:
2013-08-31 18:17:38 +00:00
service_data.append({'title': slide['title'], 'image': slide['image'], 'path': slide['path']})
return {'header': service_header, 'data': service_data}
2014-03-17 19:05:55 +00:00
def set_from_service(self, service_item, path=None):
"""
2014-03-17 19:05:55 +00:00
This method takes a service item from a saved service file (passed from the ServiceManager) and extracts the
data actually required.
2009-07-10 13:16:15 +00:00
2014-03-17 19:05:55 +00:00
:param service_item: The item to extract data from.
:param path: Defaults to *None*. This is the service manager path for things which have their files saved
with them or None when the saved service is lite and the original file paths need to be preserved.
"""
2013-08-31 18:17:38 +00:00
log.debug('set_from_service called with path %s' % path)
2014-03-17 19:14:22 +00:00
header = service_item['serviceitem']['header']
2013-08-31 18:17:38 +00:00
self.title = header['title']
self.name = header['name']
self.service_item_type = header['type']
self.theme = header['theme']
self.add_icon(header['icon'])
self.raw_footer = header['footer']
self.audit = header['audit']
self.notes = header['notes']
self.from_plugin = header['from_plugin']
self.capabilities = header['capabilities']
2010-09-30 17:07:27 +00:00
# Added later so may not be present in older services.
2013-08-31 18:17:38 +00:00
self.search_string = header.get('search', '')
self.data_string = header.get('data', '')
self.xml_version = header.get('xml_version')
self.start_time = header.get('start_time', 0)
self.end_time = header.get('end_time', 0)
self.media_length = header.get('media_length', 0)
self.auto_play_slides_once = header.get('auto_play_slides_once', False)
self.auto_play_slides_loop = header.get('auto_play_slides_loop', False)
self.timed_slide_interval = header.get('timed_slide_interval', 0)
self.will_auto_start = header.get('will_auto_start', False)
self.processor = header.get('processor', None)
2012-12-07 21:57:35 +00:00
self.has_original_files = True
2014-04-12 20:19:22 +00:00
# TODO: Remove me in 2,3 build phase
if self.is_capable(ItemCapabilities.HasDetailedTitleDisplay):
self.capabilities.remove(ItemCapabilities.HasDetailedTitleDisplay)
self.processor = self.title
self.title = None
2013-08-31 18:17:38 +00:00
if 'background_audio' in header:
self.background_audio = []
2013-08-31 18:17:38 +00:00
for filename in header['background_audio']:
# Give them real file paths
self.background_audio.append(os.path.join(path, filename))
2013-08-31 18:17:38 +00:00
self.theme_overwritten = header.get('theme_overwritten', False)
if self.service_item_type == ServiceItemType.Text:
2014-03-17 19:14:22 +00:00
for slide in service_item['serviceitem']['data']:
2009-11-14 09:06:25 +00:00
self._raw_frames.append(slide)
elif self.service_item_type == ServiceItemType.Image:
2014-03-17 19:14:22 +00:00
settings_section = service_item['serviceitem']['header']['name']
2013-08-31 18:17:38 +00:00
background = QtGui.QColor(Settings().value(settings_section + '/background color'))
2012-10-15 16:20:23 +00:00
if path:
2012-12-07 21:57:35 +00:00
self.has_original_files = False
2014-03-17 19:14:22 +00:00
for text_image in service_item['serviceitem']['data']:
2012-10-15 16:20:23 +00:00
filename = os.path.join(path, text_image)
self.add_from_image(filename, text_image, background)
2012-10-15 16:20:23 +00:00
else:
2014-03-17 19:14:22 +00:00
for text_image in service_item['serviceitem']['data']:
2013-08-31 18:17:38 +00:00
self.add_from_image(text_image['path'], text_image['title'], background)
elif self.service_item_type == ServiceItemType.Command:
2014-03-17 19:14:22 +00:00
for text_image in service_item['serviceitem']['data']:
if not self.title:
2013-08-31 18:17:38 +00:00
self.title = text_image['title']
if self.is_capable(ItemCapabilities.IsOptical):
self.has_original_files = False
self.add_from_command(text_image['path'], text_image['title'], text_image['image'])
elif path:
2012-12-07 21:57:35 +00:00
self.has_original_files = False
2013-08-31 18:17:38 +00:00
self.add_from_command(path, text_image['title'], text_image['image'])
else:
2013-08-31 18:17:38 +00:00
self.add_from_command(text_image['path'], text_image['title'], text_image['image'])
self._new_item()
2009-11-05 17:03:37 +00:00
2011-01-29 07:53:21 +00:00
def get_display_title(self):
2011-01-28 19:46:55 +00:00
"""
Returns the title of the service item.
"""
2014-04-20 13:57:12 +00:00
if self.is_text() or self.is_capable(ItemCapabilities.IsOptical) \
2014-04-20 14:36:56 +00:00
or self.is_capable(ItemCapabilities.CanEditTitle):
2011-01-28 19:46:55 +00:00
return self.title
else:
if len(self._raw_frames) > 1:
2011-01-28 19:46:55 +00:00
return self.title
else:
2013-08-31 18:17:38 +00:00
return self._raw_frames[0]['title']
2011-01-28 19:46:55 +00:00
2009-11-05 17:03:37 +00:00
def merge(self, other):
"""
2013-01-21 07:34:50 +00:00
Updates the unique_identifier with the value from the original one
2014-03-17 19:05:55 +00:00
The unique_identifier is unique for a given service item but this allows one to replace an original version.
2014-03-17 19:05:55 +00:00
:param other: The service item to be merged with
2009-11-05 17:03:37 +00:00
"""
2013-01-21 07:34:50 +00:00
self.unique_identifier = other.unique_identifier
self.notes = other.notes
2011-12-10 08:52:18 +00:00
self.temporary_edit = other.temporary_edit
2011-10-03 16:53:54 +00:00
# Copy theme over if present.
if other.theme is not None:
2011-10-03 16:53:54 +00:00
self.theme = other.theme
self._new_item()
self.render()
2011-09-02 19:04:07 +00:00
if self.is_capable(ItemCapabilities.HasBackgroundAudio):
log.debug(self.background_audio)
2009-11-05 17:03:37 +00:00
def __eq__(self, other):
"""
Confirms the service items are for the same instance
"""
if not other:
return False
2013-01-21 07:34:50 +00:00
return self.unique_identifier == other.unique_identifier
2009-11-05 17:03:37 +00:00
def __ne__(self, other):
"""
Confirms the service items are not for the same instance
"""
2013-01-21 07:34:50 +00:00
return self.unique_identifier != other.unique_identifier
2009-11-05 17:03:37 +00:00
2013-06-30 18:33:41 +00:00
def __hash__(self):
"""
Return the hash for the service item.
"""
return self.unique_identifier
def is_media(self):
2010-06-10 21:30:50 +00:00
"""
Confirms if the ServiceItem is media
"""
2010-04-03 07:10:31 +00:00
return ItemCapabilities.RequiresMedia in self.capabilities
2009-11-11 19:10:38 +00:00
def is_command(self):
2010-06-10 21:30:50 +00:00
"""
Confirms if the ServiceItem is a command
"""
return self.service_item_type == ServiceItemType.Command
2009-11-11 19:10:38 +00:00
def is_image(self):
2010-06-10 21:30:50 +00:00
"""
Confirms if the ServiceItem is an image
"""
return self.service_item_type == ServiceItemType.Image
def uses_file(self):
2010-06-10 21:30:50 +00:00
"""
Confirms if the ServiceItem uses a file
"""
return self.service_item_type == ServiceItemType.Image or \
2014-04-22 20:42:07 +00:00
(self.service_item_type == ServiceItemType.Command and not self.is_capable(ItemCapabilities.IsOptical))
def is_text(self):
2010-06-10 21:30:50 +00:00
"""
Confirms if the ServiceItem is text
"""
return self.service_item_type == ServiceItemType.Text
2009-11-14 08:40:14 +00:00
def set_media_length(self, length):
"""
Stores the media length of the item
2014-03-17 19:05:55 +00:00
:param length: The length of the media item
"""
self.media_length = length
if length > 0:
self.add_capability(ItemCapabilities.HasVariableStartTime)
def get_frames(self):
2010-06-10 21:30:50 +00:00
"""
Returns the frames for the ServiceItem
"""
2009-11-14 09:02:30 +00:00
if self.service_item_type == ServiceItemType.Text:
2009-11-14 09:06:25 +00:00
return self._display_frames
2009-11-14 09:02:30 +00:00
else:
2009-11-14 09:06:25 +00:00
return self._raw_frames
2009-11-14 09:02:30 +00:00
def get_rendered_frame(self, row):
2009-11-14 09:06:25 +00:00
"""
Returns the correct frame for a given list and renders it if required.
2014-03-17 19:05:55 +00:00
:param row: The service item slide to be returned
2009-11-14 09:06:25 +00:00
"""
2009-11-14 09:02:30 +00:00
if self.service_item_type == ServiceItemType.Text:
2013-08-31 18:17:38 +00:00
return self._display_frames[row]['html'].split('\n')[0]
2010-10-24 06:26:07 +00:00
elif self.service_item_type == ServiceItemType.Image:
2013-08-31 18:17:38 +00:00
return self._raw_frames[row]['path']
2010-10-24 06:26:07 +00:00
else:
2013-08-31 18:17:38 +00:00
return self._raw_frames[row]['image']
def get_frame_title(self, row=0):
"""
Returns the title of the raw frame
"""
try:
2013-08-31 18:17:38 +00:00
return self._raw_frames[row]['title']
2011-01-22 12:48:16 +00:00
except IndexError:
2013-08-31 18:17:38 +00:00
return ''
def get_frame_path(self, row=0, frame=None):
2010-03-30 19:01:23 +00:00
"""
2010-10-15 08:35:00 +00:00
Returns the path of the raw frame
2010-03-30 19:01:23 +00:00
"""
if not frame:
try:
frame = self._raw_frames[row]
except IndexError:
2013-08-31 18:17:38 +00:00
return ''
if self.is_image() or self.is_capable(ItemCapabilities.IsOptical):
2013-08-31 18:17:38 +00:00
path_from = frame['path']
else:
2013-08-31 18:17:38 +00:00
path_from = os.path.join(frame['path'], frame['title'])
return path_from
def remove_frame(self, frame):
"""
2012-12-07 21:57:35 +00:00
Remove the specified frame from the item
"""
if frame in self._raw_frames:
self._raw_frames.remove(frame)
2011-02-13 10:37:27 +00:00
def get_media_time(self):
"""
Returns the start and finish time for a media item
"""
start = None
end = None
2011-02-13 13:11:15 +00:00
if self.start_time != 0:
2012-12-28 22:06:43 +00:00
start = translate('OpenLP.ServiceItem', '<strong>Start</strong>: %s') % \
2013-08-31 18:17:38 +00:00
str(datetime.timedelta(seconds=self.start_time))
2011-02-14 17:54:09 +00:00
if self.media_length != 0:
2012-12-28 22:06:43 +00:00
end = translate('OpenLP.ServiceItem', '<strong>Length</strong>: %s') % \
2013-08-31 18:17:38 +00:00
str(datetime.timedelta(seconds=self.media_length))
2011-02-13 10:37:27 +00:00
if not start and not end:
2013-08-31 18:17:38 +00:00
return ''
2011-02-13 10:37:27 +00:00
elif start and not end:
return start
elif not start and end:
return end
else:
2013-08-31 18:17:38 +00:00
return '%s <br>%s' % (start, end)
2011-04-26 17:03:19 +00:00
def update_theme(self, theme):
"""
updates the theme in the service item
2014-03-17 19:05:55 +00:00
:param theme: The new theme to be replaced in the service item
"""
2013-02-01 19:58:18 +00:00
self.theme_overwritten = (theme is None)
self.theme = theme
self._new_item()
self.render()
2011-04-26 17:03:19 +00:00
2012-11-02 18:54:42 +00:00
def remove_invalid_frames(self, invalid_paths=None):
"""
Remove invalid frames, such as ones where the file no longer exists.
"""
if self.uses_file():
for frame in self.get_frames():
if self.get_frame_path(frame=frame) in invalid_paths:
self.remove_frame(frame)
def missing_frames(self):
2012-11-02 18:54:42 +00:00
"""
Returns if there are any frames in the service item
2012-11-02 18:54:42 +00:00
"""
2012-12-08 16:20:52 +00:00
return not bool(self._raw_frames)
def validate_item(self, suffix_list=None):
"""
Validates a service item to make sure it is valid
"""
self.is_valid = True
for frame in self._raw_frames:
2013-08-31 18:17:38 +00:00
if self.is_image() and not os.path.exists(frame['path']):
self.is_valid = False
break
elif self.is_command():
if self.is_capable(ItemCapabilities.IsOptical):
if not os.path.exists(frame['title']):
self.is_valid = False
break
else:
file_name = os.path.join(frame['path'], frame['title'])
if not os.path.exists(file_name):
self.is_valid = False
break
if suffix_list and not self.is_text():
file_suffix = frame['title'].split('.')[-1]
if file_suffix.lower() not in suffix_list:
self.is_valid = False
2014-04-22 20:42:07 +00:00
break