From 9e48362f1d6347817e5f2be7371af272808bdcc8 Mon Sep 17 00:00:00 2001 From: Philip Ridout Date: Sun, 4 Aug 2013 16:30:58 +0100 Subject: [PATCH 1/4] Fixes #1096450 Stripping the leading and trailing spaces at the end rather than begginning (the space means something, see added comments) Semi-colons (;) denotes comments ONLY when it is the first char of the line ie the whole line is a comment Finally fixed an issue when a verse was being added to the verse order multiple times, thus repeating it over and over and .... --- openlp/plugins/songs/lib/opensongimport.py | 40 ++++++++++------------ 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/openlp/plugins/songs/lib/opensongimport.py b/openlp/plugins/songs/lib/opensongimport.py index b636932db..fd4399a88 100644 --- a/openlp/plugins/songs/lib/opensongimport.py +++ b/openlp/plugins/songs/lib/opensongimport.py @@ -45,13 +45,14 @@ class OpenSongImport(SongImport): Import songs exported from OpenSong The format is described loosly on the `OpenSong File Format Specification - `_ page on - the OpenSong web site. However, it doesn't describe the section, - so here's an attempt: + `_ page on the OpenSong web site. However, it + doesn't describe the section, so here's an attempt: - Verses can be expressed in one of 2 ways, either in complete verses, or by - line grouping, i.e. grouping all line 1's of a verse together, all line 2's - of a verse together, and so on. + If the first charachter of a line is a space, then the rest of that line is lyrics. If it is not a space the + following applies. + + Verses can be expressed in one of 2 ways, either in complete verses, or by line grouping, i.e. grouping all line 1's + of a verse together, all line 2's of a verse together, and so on. An example of complete verses:: @@ -78,9 +79,8 @@ class OpenSongImport(SongImport): 2etc... - Either or both forms can be used in one song. The number does not - necessarily appear at the start of the line. Additionally, the [v1] labels - can have either upper or lower case Vs. + Either or both forms can be used in one song. The number does not necessarily appear at the start of the line. + Additionally, the [v1] labels can have either upper or lower case Vs. Other labels can be used also: @@ -92,18 +92,16 @@ class OpenSongImport(SongImport): All verses are imported and tagged appropriately. - Guitar chords can be provided "above" the lyrics (the line is preceeded by - a period "."), and one or more "_" can be used to signify long-drawn-out - words. Chords and "_" are removed by this importer. For example:: + Guitar chords can be provided "above" the lyrics (the line is preceeded by a period "."), and one or more "_" can + be used to signify long-drawn-out words. Chords and "_" are removed by this importer. For example:: . A7 Bm 1 Some____ Words - The tag is used to populate the OpenLP verse display order - field. The Author and Copyright tags are also imported to the appropriate - places. - + The tag is used to populate the OpenLP verse display order field. The Author and Copyright tags are + also imported to the appropriate places. """ + def __init__(self, manager, **kwargs): """ Initialise the class. @@ -169,13 +167,11 @@ class OpenSongImport(SongImport): else: lyrics = u'' for this_line in lyrics.split(u'\n'): - # remove comments - semicolon = this_line.find(u';') - if semicolon >= 0: - this_line = this_line[:semicolon] - this_line = this_line.strip() if not this_line: continue + # skip this line if it is a comment + if this_line.startswith(u';'): + continue # skip guitar chords and page and column breaks if this_line.startswith(u'.') or this_line.startswith(u'---') or this_line.startswith(u'-!!'): continue @@ -204,7 +200,6 @@ class OpenSongImport(SongImport): if this_line[0].isdigit(): verse_num = this_line[0] this_line = this_line[1:].strip() - our_verse_order.append([verse_tag, verse_num, inst]) verses.setdefault(verse_tag, {}) verses[verse_tag].setdefault(verse_num, {}) if inst not in verses[verse_tag][verse_num]: @@ -214,6 +209,7 @@ class OpenSongImport(SongImport): this_line = self.tidyText(this_line) this_line = this_line.replace(u'_', u'') this_line = this_line.replace(u'|', u'\n') + this_line = this_line.strip() verses[verse_tag][verse_num][inst].append(this_line) # done parsing # add verses in original order From c83dbe7f632e7084bc8c9ae28c1832d916950c14 Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Thu, 15 Aug 2013 21:49:51 +0200 Subject: [PATCH 2/4] Fix bug #1212801 where the song edit form did not clear a previously set theme. Fixes: https://launchpad.net/bugs/1212801 --- openlp/plugins/bibles/lib/__init__.py | 13 ++-- openlp/plugins/bibles/lib/http.py | 4 +- openlp/plugins/songs/forms/editsongform.py | 8 +++ .../openlp_plugins/bibles/__init__.py | 3 + .../openlp_plugins/bibles/test_lib.py | 59 +++++++++++++++++++ .../openlp_plugins/songs/__init__.py | 3 + 6 files changed, 83 insertions(+), 7 deletions(-) create mode 100644 tests/functional/openlp_plugins/bibles/__init__.py create mode 100644 tests/functional/openlp_plugins/bibles/test_lib.py diff --git a/openlp/plugins/bibles/lib/__init__.py b/openlp/plugins/bibles/lib/__init__.py index 371632d41..be1d3b35f 100644 --- a/openlp/plugins/bibles/lib/__init__.py +++ b/openlp/plugins/bibles/lib/__init__.py @@ -221,6 +221,7 @@ def update_reference_separators(): u'(?P(?:%(range_regex)s(?:%(sep_l)s(?!\s*$)|(?=\s*$)))+)\s*$' \ % dict(REFERENCE_SEPARATORS.items() + [(u'range_regex', range_regex)]), re.UNICODE) + def get_reference_separator(separator_type): """ Provides separators for parsing and formatting scripture references. @@ -232,6 +233,7 @@ def get_reference_separator(separator_type): update_reference_separators() return REFERENCE_SEPARATORS[separator_type] + def get_reference_match(match_type): """ Provides matches for parsing scripture references strings. @@ -243,6 +245,7 @@ def get_reference_match(match_type): update_reference_separators() return REFERENCE_MATCHES[match_type] + def parse_reference(reference, bible, language_selection, book_ref_id=False): """ This is the next generation über-awesome function that takes a person's typed in string and converts it to a list @@ -402,7 +405,7 @@ class SearchResults(object): """ Encapsulate a set of search results. This is Bible-type independent. """ - def __init__(self, book, chapter, verselist): + def __init__(self, book, chapter, verse_list): """ Create the search result object. @@ -412,19 +415,19 @@ class SearchResults(object): ``chapter`` The chapter of the book. - ``verselist`` + ``verse_list`` The list of verses for this reading. """ self.book = book self.chapter = chapter - self.verselist = verselist + self.verse_list = verse_list - def has_verselist(self): + def has_verse_list(self): """ Returns whether or not the verse list contains verses. """ - return len(self.verselist) > 0 + return len(self.verse_list) > 0 from versereferencelist import VerseReferenceList diff --git a/openlp/plugins/bibles/lib/http.py b/openlp/plugins/bibles/lib/http.py index de48b2617..a8fe8aacc 100644 --- a/openlp/plugins/bibles/lib/http.py +++ b/openlp/plugins/bibles/lib/http.py @@ -618,7 +618,7 @@ class HTTPBible(BibleDB): if BibleDB.get_verse_count(self, book_id, reference[1]) == 0: self.application.set_busy_cursor() search_results = self.get_chapter(book, reference[1]) - if search_results and search_results.has_verselist(): + if search_results and search_results.has_verse_list(): ## We have found a book of the bible lets check to see ## if it was there. By reusing the returned book name ## we get a correct book. For example it is possible @@ -627,7 +627,7 @@ class HTTPBible(BibleDB): self.application.process_events() # Check to see if book/chapter exists. db_book = self.get_book(book_name) - self.create_chapter(db_book.id, search_results.chapter, search_results.verselist) + self.create_chapter(db_book.id, search_results.chapter, search_results.verse_list) self.application.process_events() self.application.set_normal_cursor() self.application.process_events() diff --git a/openlp/plugins/songs/forms/editsongform.py b/openlp/plugins/songs/forms/editsongform.py index 24d0d3024..6c9b68699 100644 --- a/openlp/plugins/songs/forms/editsongform.py +++ b/openlp/plugins/songs/forms/editsongform.py @@ -348,6 +348,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): self.load_topics() self.load_books() self.load_media_files() + self.theme_combo_box.setEditText(u'') self.theme_combo_box.setCurrentIndex(0) # it's a new song to preview is not possible self.preview_button.setVisible(False) @@ -376,8 +377,15 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): if self.song.song_book_id != 0: book_name = self.manager.get_object(Book, self.song.song_book_id) find_and_set_in_combo_box(self.song_book_combo_box, unicode(book_name.name)) + else: + self.song_book_combo_box.setEditText(u'') + self.song_book_combo_box.setCurrentIndex(0) if self.song.theme_name: find_and_set_in_combo_box(self.theme_combo_box, unicode(self.song.theme_name)) + else: + # Clear the theme combo box in case it was previously set (bug #1212801) + self.theme_combo_box.setEditText(u'') + self.theme_combo_box.setCurrentIndex(0) self.copyright_edit.setText(self.song.copyright if self.song.copyright else u'') self.comments_edit.setPlainText(self.song.comments if self.song.comments else u'') self.ccli_number_edit.setText(self.song.ccli_number if self.song.ccli_number else u'') diff --git a/tests/functional/openlp_plugins/bibles/__init__.py b/tests/functional/openlp_plugins/bibles/__init__.py new file mode 100644 index 000000000..c60847dc0 --- /dev/null +++ b/tests/functional/openlp_plugins/bibles/__init__.py @@ -0,0 +1,3 @@ +""" +Tests for the Bibles plugin +""" diff --git a/tests/functional/openlp_plugins/bibles/test_lib.py b/tests/functional/openlp_plugins/bibles/test_lib.py new file mode 100644 index 000000000..b1f945273 --- /dev/null +++ b/tests/functional/openlp_plugins/bibles/test_lib.py @@ -0,0 +1,59 @@ +""" +This module contains tests for the lib submodule of the Bibles plugin. +""" +from unittest import TestCase + +from openlp.plugins.bibles.lib import SearchResults + + +class TestLib(TestCase): + """ + Test the functions in the :mod:`lib` module. + """ + def search_results_creation_test(self): + """ + Test the creation and construction of the SearchResults class + """ + # GIVEN: A book, chapter and a verse list + book = u'Genesis' + chapter = 1 + verse_list = { + 1: u'In the beginning God created the heavens and the earth.', + 2: u'The earth was without form and void, and darkness was over the face of the deep. And the Spirit of ' + u'God was hovering over the face of the waters.' + } + + # WHEN: We create the search results object + search_results = SearchResults(book, chapter, verse_list) + + # THEN: It should have a book, a chapter and a verse list + self.assertIsNotNone(search_results, u'The search_results object should not be None') + self.assertEqual(search_results.book, book, u'The book should be "Genesis"') + self.assertEqual(search_results.chapter, chapter, u'The chapter should be 1') + self.assertDictEqual(search_results.verse_list, verse_list, u'The verse lists should be identical') + + def search_results_has_verse_list_test(self): + """ + Test that a SearchResults object with a valid verse list returns True when checking ``has_verse_list()`` + """ + # GIVEN: A valid SearchResults object with a proper verse list + search_results = SearchResults(u'Genesis', 1, {1: u'In the beginning God created the heavens and the earth.'}) + + # WHEN: We check that the SearchResults object has a verse list + has_verse_list = search_results.has_verse_list() + + # THEN: It should be True + self.assertTrue(has_verse_list, u'The SearchResults object should have a verse list') + + def search_results_has_no_verse_list_test(self): + """ + Test that a SearchResults object with an empty verse list returns False when checking ``has_verse_list()`` + """ + # GIVEN: A valid SearchResults object with an empty verse list + search_results = SearchResults(u'Genesis', 1, {}) + + # WHEN: We check that the SearchResults object has a verse list + has_verse_list = search_results.has_verse_list() + + # THEN: It should be False + self.assertFalse(has_verse_list, u'The SearchResults object should have a verse list') diff --git a/tests/functional/openlp_plugins/songs/__init__.py b/tests/functional/openlp_plugins/songs/__init__.py index e69de29bb..70026715f 100644 --- a/tests/functional/openlp_plugins/songs/__init__.py +++ b/tests/functional/openlp_plugins/songs/__init__.py @@ -0,0 +1,3 @@ +""" +Tests for the Songs plugin +""" From ba111776ed927ff224365a804812ffa6d80537f5 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 25 Aug 2013 19:31:15 +0100 Subject: [PATCH 3/4] Remove pickle from the code now 2.0.2 is in --- openlp/core/ui/formattingtagform.py | 4 +- openlp/core/ui/servicemanager.py | 5 +- .../openlp_core_lib/test_serviceitem.py | 211 +--- .../openlp_core_lib/test_serviceitem_json.py | 261 ----- .../openlp_core_ui/test_listpreviewwidget.py | 20 +- tests/resources/serviceitem_custom_1.osd | 96 -- tests/resources/serviceitem_image_1.osd | 79 -- tests/resources/serviceitem_image_2.osd | 101 -- tests/resources/serviceitem_image_3.osj | 1 + tests/resources/serviceitem_osd2osj.osd | 1037 ----------------- tests/utils/osdinteraction.py | 5 +- 11 files changed, 68 insertions(+), 1752 deletions(-) delete mode 100644 tests/functional/openlp_core_lib/test_serviceitem_json.py delete mode 100644 tests/resources/serviceitem_custom_1.osd delete mode 100644 tests/resources/serviceitem_image_1.osd delete mode 100644 tests/resources/serviceitem_image_2.osd create mode 100644 tests/resources/serviceitem_image_3.osj delete mode 100644 tests/resources/serviceitem_osd2osj.osd diff --git a/openlp/core/ui/formattingtagform.py b/openlp/core/ui/formattingtagform.py index 30ab0902d..dbb649173 100644 --- a/openlp/core/ui/formattingtagform.py +++ b/openlp/core/ui/formattingtagform.py @@ -28,8 +28,8 @@ ############################################################################### """ The :mod:`formattingtagform` provides an Tag Edit facility. The Base set are protected and included each time loaded. -Custom tags can be defined and saved. The Custom Tag arrays are saved in a pickle so QSettings works on them. Base Tags -cannot be changed. +Custom tags can be defined and saved. The Custom Tag arrays are saved in a json string so QSettings works on them. +Base Tags cannot be changed. """ from PyQt4 import QtGui diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 4f5534602..0f22cb25e 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -30,7 +30,6 @@ The service manager sets up, loads, saves and manages services. """ import cgi -import cPickle import logging import os import shutil @@ -706,7 +705,9 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog): if p_file.endswith(u'osj'): items = json.load(file_to) else: - items = cPickle.load(file_to) + critical_error_message_box(message=translate('OpenLP.ServiceManager', + 'File is not in a supported format.\n The use OpenLP 2.0.2 or greater to create file.')) + return file_to.close() self.new_file() self.set_file_name(file_name) diff --git a/tests/functional/openlp_core_lib/test_serviceitem.py b/tests/functional/openlp_core_lib/test_serviceitem.py index fdeb081b3..d96b788d6 100644 --- a/tests/functional/openlp_core_lib/test_serviceitem.py +++ b/tests/functional/openlp_core_lib/test_serviceitem.py @@ -1,14 +1,16 @@ +# -*- coding: utf-8 -*- + """ Package to test the openlp.core.lib package. """ import os +import json +import tempfile from unittest import TestCase from mock import MagicMock, patch from openlp.core.lib import ItemCapabilities, ServiceItem, Registry -from tests.utils.osdinteraction import read_service_from_file -from tests.utils.constants import TEST_RESOURCES_PATH - +from lxml import objectify, etree VERSE = u'The Lord said to {r}Noah{/r}: \n'\ 'There\'s gonna be a {su}floody{/su}, {sb}floody{/sb}\n'\ @@ -19,6 +21,8 @@ VERSE = u'The Lord said to {r}Noah{/r}: \n'\ 'r{/pk}{o}e{/o}{pp}n{/pp} of the Lord\n' FOOTER = [u'Arky Arky (Unknown)', u'Public Domain', u'CCLI 123456'] +TEST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), u'..', u'..', u'resources')) + class TestServiceItem(TestCase): @@ -45,136 +49,17 @@ class TestServiceItem(TestCase): assert service_item.is_valid is True, u'The new service item should be valid' assert service_item.missing_frames() is True, u'There should not be any frames in the service item' - def serviceitem_add_text_test(self): - """ - Test the Service Item - add text test - """ - # GIVEN: A new service item - service_item = ServiceItem(None) - - # WHEN: adding text to a service item - service_item.add_from_text(VERSE) - service_item.raw_footer = FOOTER - - # THEN: We should get back a valid service item - assert service_item.is_valid is True, u'The new service item should be valid' - assert service_item.missing_frames() is False, u'check frames loaded ' - - # WHEN: Render called - assert len(service_item._display_frames) == 0, u'A blank Service Item with no display frames' - service_item.render(True) - - # THEN: We should have a page of output. - assert len(service_item._display_frames) == 1, u'A valid rendered Service Item has 1 display frame' - assert service_item.get_rendered_frame(0) == VERSE.split(u'\n')[0], u'A output has rendered correctly.' - - def serviceitem_add_image_test(self): - """ - Test the Service Item - add image test - """ - # GIVEN: A new service item and a mocked renderer - service_item = ServiceItem(None) - service_item.name = u'test' - - # WHEN: adding image to a service item - test_image = os.path.join(TEST_RESOURCES_PATH, u'church.jpg') - service_item.add_from_image(test_image, u'Image Title') - - # THEN: We should get back a valid service item - assert service_item.is_valid is True, u'The new service item should be valid' - assert len(service_item._display_frames) == 0, u'The service item has no display frames' - - # THEN: We should have a page of output. - assert len(service_item._raw_frames) == 1, u'A valid rendered Service Item has display frames' - assert service_item.get_rendered_frame(0) == test_image - - # WHEN: adding a second image to a service item - service_item.add_from_image(test_image, u'Image1 Title') - - # THEN: We should have an increased page of output. - assert len(service_item._raw_frames) == 2, u'A valid rendered Service Item has display frames' - assert service_item.get_rendered_frame(0) == test_image - assert service_item.get_rendered_frame(0) == service_item.get_rendered_frame(1) - - # WHEN requesting a saved service item - service = service_item.get_service_repr(True) - - # THEN: We should have two parts of the service. - assert len(service) == 2, u'A saved service should have two parts' - assert service[u'header'][u'name'] == u'test', u'A test plugin should have been returned' - assert service[u'data'][0][u'title'] == u'Image Title', u'"Image Title" should be returned as the title' - assert service[u'data'][0][u'path'] == test_image, u'The returned path should match the inputted path' - assert service[u'data'][0][u'title'] != service[u'data'][1][u'title'], \ - u'The individual slide titles should not match' - assert service[u'data'][0][u'path'] == service[u'data'][1][u'path'], u'The file paths should match' - - # WHEN validating a service item - service_item.validate_item([u'jpg']) - - # THEN the service item should be valid - assert service_item.is_valid is True, u'The new service item should be valid' - - # WHEN: adding a second image to a service item - service_item.add_from_image(u'resources/church1.jpg', u'Image1 Title') - - # WHEN validating a service item - service_item.validate_item([u'jpg']) - - # THEN the service item should be valid - assert service_item.is_valid is False, u'The service item should not be valid due to validation changes' - - def serviceitem_add_command_test(self): - """ - Test the Service Item - add command test - """ - # GIVEN: A new service item and a mocked renderer - service_item = ServiceItem(None) - service_item.name = u'test' - - # WHEN: adding image to a service item - test_file = os.path.join(TEST_RESOURCES_PATH, u'church.jpg') - service_item.add_from_command(TEST_RESOURCES_PATH, u'church.jpg', test_file) - - # THEN: We should get back a valid service item - assert service_item.is_valid is True, u'The new service item should be valid' - assert len(service_item._display_frames) == 0, u'The service item should have no display frames ' - - # THEN: We should have a page of output. - assert len(service_item._raw_frames) == 1, u'A valid rendered Service Item should have one raw frame' - assert service_item.get_rendered_frame(0) == test_file, u'The image should match the input' - - # WHEN requesting a saved service item - service = service_item.get_service_repr(True) - - # THEN: We should have two parts of the service. - assert len(service) == 2, u'The saved service should have two parts' - assert service[u'header'][u'name'] == u'test', u'A test plugin should be returned' - assert service[u'data'][0][u'title'] == u'church.jpg', u'The first title name should be "church,jpg"' - assert service[u'data'][0][u'path'] == TEST_RESOURCES_PATH, u'The path should match the input path' - assert service[u'data'][0][u'image'] == test_file, u'The image should match the full path to image' - - # WHEN validating a service item - service_item.validate_item([u'jpg']) - - # THEN the service item should be valid - assert service_item.is_valid is True, u'The service item should be valid' - - # WHEN validating a service item with a different suffix - service_item.validate_item([u'png']) - - # THEN the service item should not be valid - assert service_item.is_valid is False, u'The service item should not be valid' - def serviceitem_load_custom_from_service_test(self): """ Test the Service Item - adding a custom slide from a saved service """ - # GIVEN: A new service item + # GIVEN: A new service item and a mocked add icon function service_item = ServiceItem(None) + service_item.add_icon = MagicMock() # WHEN: adding a custom from a saved Service - service = read_service_from_file(u'serviceitem_custom_1.osd') - service_item.set_from_service(service[0]) + line = self.convert_file_service_item(u'serviceitem_custom_1.osj') + service_item.set_from_service(line) # THEN: We should get back a valid service item assert service_item.is_valid is True, u'The new service item should be valid' @@ -193,17 +78,19 @@ class TestServiceItem(TestCase): """ Test the Service Item - adding an image from a saved service """ - # GIVEN: A new service item + # GIVEN: A new service item and a mocked add icon function image_name = u'image_1.jpg' - test_file = os.path.join(TEST_RESOURCES_PATH, image_name) + test_file = os.path.join(TEST_PATH, image_name) frame_array = {u'path': test_file, u'title': image_name} service_item = ServiceItem(None) + service_item.add_icon = MagicMock() # WHEN: adding an image from a saved Service and mocked exists - service = read_service_from_file(u'serviceitem_image_1.osd') - with patch('os.path.exists'): - service_item.set_from_service(service[0], TEST_RESOURCES_PATH) + line = self.convert_file_service_item(u'serviceitem_image_1.osj') + with patch(u'openlp.core.ui.servicemanager.os.path.exists') as mocked_exists: + mocked_exists.return_value = True + service_item.set_from_service(line, TEST_PATH) # THEN: We should get back a valid service item assert service_item.is_valid is True, u'The new service item should be valid' @@ -226,7 +113,7 @@ class TestServiceItem(TestCase): """ Test the Service Item - adding an image from a saved local service """ - # GIVEN: A new service item + # GIVEN: A new service item and a mocked add icon function image_name1 = u'image_1.jpg' image_name2 = u'image_2.jpg' test_file1 = os.path.join(u'/home/openlp', image_name1) @@ -235,23 +122,36 @@ class TestServiceItem(TestCase): frame_array2 = {u'path': test_file2, u'title': image_name2} service_item = ServiceItem(None) + service_item.add_icon = MagicMock() + + service_item2 = ServiceItem(None) + service_item2.add_icon = MagicMock() # WHEN: adding an image from a saved Service and mocked exists - service = read_service_from_file(u'serviceitem_image_2.osd') - with patch('os.path.exists'): - service_item.set_from_service(service[0]) + line = self.convert_file_service_item(u'serviceitem_image_2.osj') + line2 = self.convert_file_service_item(u'serviceitem_image_2.osj', 1) + + with patch(u'openlp.core.ui.servicemanager.os.path.exists') as mocked_exists: + mocked_exists.return_value = True + service_item2.set_from_service(line2) + service_item.set_from_service(line) + # THEN: We should get back a valid service item - assert service_item.is_valid is True, u'The new service item should be valid' + + # This test is copied from service_item.py, but is changed since to conform to + # new layout of service item. The layout use in serviceitem_image_2.osd is actually invalid now. + assert service_item.is_valid is True, u'The first service item should be valid' + assert service_item2.is_valid is True, u'The second service item should be valid' assert service_item.get_rendered_frame(0) == test_file1, u'The first frame should match the path to the image' - assert service_item.get_rendered_frame(1) == test_file2, u'The Second frame should match the path to the image' + assert service_item2.get_rendered_frame(0) == test_file2, u'The Second frame should match the path to the image' assert service_item.get_frames()[0] == frame_array1, u'The return should match the frame array1' - assert service_item.get_frames()[1] == frame_array2, u'The return should match the frame array2' + assert service_item2.get_frames()[0] == frame_array2, u'The return should match the frame array2' assert service_item.get_frame_path(0) == test_file1, u'The frame path should match the full path to the image' - assert service_item.get_frame_path(1) == test_file2, u'The frame path should match the full path to the image' + assert service_item2.get_frame_path(0) == test_file2, u'The frame path should match the full path to the image' assert service_item.get_frame_title(0) == image_name1, u'The 1st frame title should match the image name' - assert service_item.get_frame_title(1) == image_name2, u'The 2nd frame title should match the image name' - assert service_item.get_display_title().lower() == service_item.name, \ + assert service_item2.get_frame_title(0) == image_name2, u'The 2nd frame title should match the image name' + assert service_item.title.lower() == service_item.name, \ u'The plugin name should match the display title, as there are > 1 Images' assert service_item.is_image() is True, u'This service item should be of an "image" type' assert service_item.is_capable(ItemCapabilities.CanMaintain) is True, \ @@ -263,22 +163,15 @@ class TestServiceItem(TestCase): assert service_item.is_capable(ItemCapabilities.CanAppend) is True, \ u'This service item should be able to have new items added to it' - def serviceitem_migrate_test_20_22(self): - """ - Test the Service Item - migrating a media only service item from 2.0 to 2.2 format - """ - # GIVEN: A new service item and a mocked add icon function - service_item = ServiceItem(None) - service_item.add_icon = MagicMock() + def convert_file_service_item(self, name, row=0): + service_file = os.path.join(TEST_PATH, name) + try: + open_file = open(service_file, u'r') + items = json.load(open_file) + first_line = items[row] + except IOError: + first_line = u'' + finally: + open_file.close() + return first_line - # WHEN: adding an media from a saved Service and mocked exists - line = read_service_from_file(u'migrate_video_20_22.osd') - with patch('os.path.exists'): - service_item.set_from_service(line[0], TEST_RESOURCES_PATH) - - # THEN: We should get back a converted service item - assert service_item.is_valid is True, u'The new service item should be valid' - assert service_item.processor == u'VLC', u'The Processor should have been set' - assert service_item.title is not None, u'The title should be set to a value' - assert service_item.is_capable(ItemCapabilities.HasDetailedTitleDisplay) is False, \ - u'The Capability should have been removed' diff --git a/tests/functional/openlp_core_lib/test_serviceitem_json.py b/tests/functional/openlp_core_lib/test_serviceitem_json.py deleted file mode 100644 index 3e0b74f2c..000000000 --- a/tests/functional/openlp_core_lib/test_serviceitem_json.py +++ /dev/null @@ -1,261 +0,0 @@ -# -*- coding: utf-8 -*- - -""" - Package to test the openlp.core.lib package. -""" -import os -import io -import cPickle -import json -import tempfile -from unittest import TestCase -from mock import MagicMock, patch - -from openlp.core.lib import ItemCapabilities, ServiceItem, Registry -from lxml import objectify, etree - -VERSE = u'The Lord said to {r}Noah{/r}: \n'\ - 'There\'s gonna be a {su}floody{/su}, {sb}floody{/sb}\n'\ - 'The Lord said to {g}Noah{/g}:\n'\ - 'There\'s gonna be a {st}floody{/st}, {it}floody{/it}\n'\ - 'Get those children out of the muddy, muddy \n'\ - '{r}C{/r}{b}h{/b}{bl}i{/bl}{y}l{/y}{g}d{/g}{pk}'\ - 'r{/pk}{o}e{/o}{pp}n{/pp} of the Lord\n' -FOOTER = [u'Arky Arky (Unknown)', u'Public Domain', u'CCLI 123456'] - -TEST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), u'..', u'..', u'resources')) - - -class TestServiceItem(TestCase): - - def setUp(self): - """ - Set up the Registry - """ - Registry.create() - mocked_renderer = MagicMock() - mocked_renderer.format_slide.return_value = [VERSE] - Registry().register(u'renderer', mocked_renderer) - Registry().register(u'image_manager', MagicMock()) - - def serviceitem_basic_test(self): - """ - Test the Service Item - basic test - """ - # GIVEN: A new service item - - # WHEN: A service item is created (without a plugin) - service_item = ServiceItem(None) - - # THEN: We should get back a valid service item - assert service_item.is_valid is True, u'The new service item should be valid' - assert service_item.missing_frames() is True, u'There should not be any frames in the service item' - - def serviceitem_load_custom_from_service_test(self): - """ - Test the Service Item - adding a custom 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() - - # WHEN: adding a custom from a saved Service - line = self.convert_file_service_item(u'serviceitem_custom_1.osj') - service_item.set_from_service(line) - - # THEN: We should get back a valid service item - assert service_item.is_valid is True, u'The new service item should be valid' - assert len(service_item._display_frames) == 0, u'The service item should have no display frames' - assert len(service_item.capabilities) == 5, u'There should be 5 default custom item capabilities' - service_item.render(True) - assert service_item.get_display_title() == u'Test Custom', u'The title should be "Test Custom"' - assert service_item.get_frames()[0][u'text'] == VERSE[:-1], \ - u'The returned text matches the input, except the last line feed' - assert service_item.get_rendered_frame(1) == VERSE.split(u'\n', 1)[0], u'The first line has been returned' - assert service_item.get_frame_title(0) == u'Slide 1', u'"Slide 1" has been returned as the title' - assert service_item.get_frame_title(1) == u'Slide 2', u'"Slide 2" has been returned as the title' - assert service_item.get_frame_title(2) == u'', u'Blank has been returned as the title of slide 3' - - def serviceitem_load_image_from_service_test(self): - """ - Test the Service Item - adding an image from a saved service - """ - # GIVEN: A new service item and a mocked add icon function - image_name = u'image_1.jpg' - test_file = os.path.join(TEST_PATH, image_name) - frame_array = {u'path': test_file, u'title': image_name} - - service_item = ServiceItem(None) - service_item.add_icon = MagicMock() - - # WHEN: adding an image from a saved Service and mocked exists - line = self.convert_file_service_item(u'serviceitem_image_1.osj') - with patch(u'openlp.core.ui.servicemanager.os.path.exists') as mocked_exists: - mocked_exists.return_value = True - service_item.set_from_service(line, TEST_PATH) - - # THEN: We should get back a valid service item - assert service_item.is_valid is True, u'The new service item should be valid' - assert service_item.get_rendered_frame(0) == test_file, u'The first frame should match the path to the image' - assert service_item.get_frames()[0] == frame_array, u'The return should match frame array1' - assert service_item.get_frame_path(0) == test_file, u'The frame path should match the full path to the image' - assert service_item.get_frame_title(0) == image_name, u'The frame title should match the image name' - assert service_item.get_display_title() == image_name, u'The display title should match the first image name' - assert service_item.is_image() is True, u'This service item should be of an "image" type' - assert service_item.is_capable(ItemCapabilities.CanMaintain) is True, \ - u'This service item should be able to be Maintained' - assert service_item.is_capable(ItemCapabilities.CanPreview) is True, \ - u'This service item should be able to be be Previewed' - assert service_item.is_capable(ItemCapabilities.CanLoop) is True, \ - u'This service item should be able to be run in a can be made to Loop' - assert service_item.is_capable(ItemCapabilities.CanAppend) is True, \ - u'This service item should be able to have new items added to it' - - def serviceitem_load_image_from_local_service_test(self): - """ - Test the Service Item - adding an image from a saved local service - """ - # GIVEN: A new service item and a mocked add icon function - image_name1 = u'image_1.jpg' - image_name2 = u'image_2.jpg' - test_file1 = os.path.join(u'/home/openlp', image_name1) - test_file2 = os.path.join(u'/home/openlp', image_name2) - frame_array1 = {u'path': test_file1, u'title': image_name1} - frame_array2 = {u'path': test_file2, u'title': image_name2} - - service_item = ServiceItem(None) - service_item.add_icon = MagicMock() - - service_item2 = ServiceItem(None) - service_item2.add_icon = MagicMock() - - # WHEN: adding an image from a saved Service and mocked exists - line = self.convert_file_service_item(u'serviceitem_image_2.osj') - line2 = self.convert_file_service_item(u'serviceitem_image_2.osj', 1) - - with patch(u'openlp.core.ui.servicemanager.os.path.exists') as mocked_exists: - mocked_exists.return_value = True - service_item2.set_from_service(line2) - service_item.set_from_service(line) - - - # THEN: We should get back a valid service item - - # This test is copied from service_item.py, but is changed since to conform to - # new layout of service item. The layout use in serviceitem_image_2.osd is actually invalid now. - assert service_item.is_valid is True, u'The first service item should be valid' - assert service_item2.is_valid is True, u'The second service item should be valid' - assert service_item.get_rendered_frame(0) == test_file1, u'The first frame should match the path to the image' - assert service_item2.get_rendered_frame(0) == test_file2, u'The Second frame should match the path to the image' - assert service_item.get_frames()[0] == frame_array1, u'The return should match the frame array1' - assert service_item2.get_frames()[0] == frame_array2, u'The return should match the frame array2' - assert service_item.get_frame_path(0) == test_file1, u'The frame path should match the full path to the image' - assert service_item2.get_frame_path(0) == test_file2, u'The frame path should match the full path to the image' - assert service_item.get_frame_title(0) == image_name1, u'The 1st frame title should match the image name' - assert service_item2.get_frame_title(0) == image_name2, u'The 2nd frame title should match the image name' - assert service_item.title.lower() == service_item.name, \ - u'The plugin name should match the display title, as there are > 1 Images' - assert service_item.is_image() is True, u'This service item should be of an "image" type' - assert service_item.is_capable(ItemCapabilities.CanMaintain) is True, \ - u'This service item should be able to be Maintained' - assert service_item.is_capable(ItemCapabilities.CanPreview) is True, \ - u'This service item should be able to be be Previewed' - assert service_item.is_capable(ItemCapabilities.CanLoop) is True, \ - u'This service item should be able to be run in a can be made to Loop' - assert service_item.is_capable(ItemCapabilities.CanAppend) is True, \ - u'This service item should be able to have new items added to it' - - def serviceitem_convert_osd2osj_test(self): - """ - Test the Service Item - load a osd to service_item, convert to json, - load again to service_item and compare the old and new service_item. - """ - # GIVEN: A valid osd (python pickle format) service in file - service_file = os.path.join(TEST_PATH, u'serviceitem_osd2osj.osd') - osd_service_items = [] - try: - open_file = open(service_file, u'r') - osd_service_items = cPickle.load(open_file) - except IOError: - osd_service_items = [] - finally: - open_file.close() - - # WHEN: Dumping loaded osd service to json format, and save to file and reloading to service - json_service_content = json.dumps(osd_service_items) - open_file = None - open_filename = u'' - try: - (open_filep, open_filename) = tempfile.mkstemp() - open_file = open(open_filename, u'w') - open_file.write(json_service_content) - open_file.close() - open_file = open(open_filename, u'r') - json_service_content = open_file.read() - except IOError: - json_service_content = u'' - finally: - open_file.close() - os.remove(open_filename) - osj_service_items = json.loads(json_service_content) - - # THEN: The service loaded from osj (json format) should be the same as the service loaded from the original osd (python pickle format) - - # Loop over every item and compare the osj with osd version - for osd_item, osj_item in zip(osd_service_items, osj_service_items): - # Create service item objects - service_item_osd = ServiceItem() - service_item_osd.add_icon = MagicMock() - - service_item_osj = ServiceItem() - service_item_osj.add_icon = MagicMock() - - with patch(u'openlp.core.ui.servicemanager.os.path.exists') as mocked_exists: - mocked_exists.return_value = True - service_item_osd.set_from_service(osd_item, TEST_PATH) - service_item_osj.set_from_service(osj_item, TEST_PATH) - - # Check that the exported/imported attributes are the same - assert service_item_osj.is_valid is True, u'The osj service item should be valid' - assert service_item_osd.is_valid is True, u'The osd service item should be valid' - assert service_item_osj.name == service_item_osd.name , u'The osd and the osj attribute name should be the same!' - assert service_item_osj.theme == service_item_osd.theme , u'The osd and the osj attribute theme should be the same!' - assert service_item_osj.title == service_item_osd.title , u'The osd and the osj attribute title should be the same!' - assert service_item_osj.icon == service_item_osd.icon , u'The osd and the osj attribute icon should be the same!' - assert service_item_osj.raw_footer == service_item_osd.raw_footer , u'The osd and the osj attribute raw_footer should be the same!' - assert service_item_osj.service_item_type == service_item_osd.service_item_type , u'The osd and the osj attribute service_item_type should be the same!' - assert service_item_osj.audit == service_item_osd.audit , u'The osd and the osj attribute audit should be the same!' - assert service_item_osj.notes == service_item_osd.notes , u'The osd and the osj attribute notes should be the same!' - assert service_item_osj.from_plugin == service_item_osd.from_plugin , u'The osd and the osj attribute from_plugin should be the same!' - assert service_item_osj.capabilities == service_item_osd.capabilities , u'The osd and the osj attribute capabilities should be the same!' - assert service_item_osj.search_string == service_item_osd.search_string , u'The osd and the osj attribute search_string should be the same!' - assert service_item_osj.data_string == service_item_osd.data_string , u'The osd and the osj attribute data_string should be the same!' - # Notice that xml_version from osd needs to be utf-8 decoded, since unicode-characters - # is written as byte-codes by pickle, while json can escape unicode-characters - if service_item_osd.xml_version: - assert service_item_osj.xml_version == service_item_osd.xml_version.decode(u'utf-8') , u'The osd and the osj attribute xml_version should be the same!' - assert service_item_osj.auto_play_slides_once == service_item_osd.auto_play_slides_once , u'The osd and the osj attribute auto_play_slides_once should be the same!' - assert service_item_osj.auto_play_slides_loop == service_item_osd.auto_play_slides_loop , u'The osd and the osj attribute auto_play_slides_loop should be the same!' - assert service_item_osj.timed_slide_interval == service_item_osd.timed_slide_interval , u'The osd and the osj attribute timed_slide_interval should be the same!' - assert service_item_osj.start_time == service_item_osd.start_time , u'The osd and the osj attribute start_time should be the same!' - assert service_item_osj.end_time == service_item_osd.end_time , u'The osd and the osj attribute end_time should be the same!' - assert service_item_osj.media_length == service_item_osd.media_length , u'The osd and the osj attribute media_length should be the same!' - assert service_item_osj.background_audio == service_item_osd.background_audio , u'The osd and the osj attribute background_audio should be the same!' - assert service_item_osj.theme_overwritten == service_item_osd.theme_overwritten , u'The osd and the osj attribute theme_overwritten should be the same!' - assert service_item_osj.will_auto_start == service_item_osd.will_auto_start , u'The osd and the osj attribute will_auto_start should be the same!' - assert service_item_osj.processor == service_item_osd.processor , u'The osd and the osj attribute processor should be the same!' - - - - def convert_file_service_item(self, name, row=0): - service_file = os.path.join(TEST_PATH, name) - try: - open_file = open(service_file, u'r') - items = json.load(open_file) - first_line = items[row] - except IOError: - first_line = u'' - finally: - open_file.close() - return first_line - diff --git a/tests/interfaces/openlp_core_ui/test_listpreviewwidget.py b/tests/interfaces/openlp_core_ui/test_listpreviewwidget.py index 8a25c0b4f..d4d9154da 100644 --- a/tests/interfaces/openlp_core_ui/test_listpreviewwidget.py +++ b/tests/interfaces/openlp_core_ui/test_listpreviewwidget.py @@ -11,6 +11,7 @@ from openlp.core.lib import Registry, ServiceItem from openlp.core.ui import listpreviewwidget from tests.utils.osdinteraction import read_service_from_file + class TestListPreviewWidget(TestCase): def setUp(self): @@ -41,8 +42,7 @@ class TestListPreviewWidget(TestCase): # GIVEN: A new ListPreviewWidget instance. # WHEN: No SlideItem has been added yet. # THEN: The count of items should be zero. - self.assertEqual(self.preview_widget.slide_count(), 0, - u'The slide list should be empty.') + self.assertEqual(self.preview_widget.slide_count(), 0, u'The slide list should be empty.') def initial_slide_number_test(self): """ @@ -51,8 +51,7 @@ class TestListPreviewWidget(TestCase): # GIVEN: A new ListPreviewWidget instance. # WHEN: No SlideItem has been added yet. # THEN: The number of the current item should be -1. - self.assertEqual(self.preview_widget.current_slide_number(), -1, - u'The slide number should be -1.') + self.assertEqual(self.preview_widget.current_slide_number(), -1, u'The slide number should be -1.') def replace_service_item_test(self): """ @@ -60,16 +59,14 @@ class TestListPreviewWidget(TestCase): """ # GIVEN: A ServiceItem with two frames. service_item = ServiceItem(None) - service = read_service_from_file(u'serviceitem_image_2.osd') + service = read_service_from_file(u'serviceitem_image_3.osj') with patch('os.path.exists'): service_item.set_from_service(service[0]) # WHEN: Added to the preview widget. self.preview_widget.replace_service_item(service_item, 1, 1) # THEN: The slide count and number should fit. - self.assertEqual(self.preview_widget.slide_count(), 2, - u'The slide count should be 2.') - self.assertEqual(self.preview_widget.current_slide_number(), 1, - u'The current slide number should be 1.') + self.assertEqual(self.preview_widget.slide_count(), 2, u'The slide count should be 2.') + self.assertEqual(self.preview_widget.current_slide_number(), 1, u'The current slide number should be 1.') def change_slide_test(self): """ @@ -77,12 +74,11 @@ class TestListPreviewWidget(TestCase): """ # GIVEN: A ServiceItem with two frames content. service_item = ServiceItem(None) - service = read_service_from_file(u'serviceitem_image_2.osd') + service = read_service_from_file(u'serviceitem_image_3.osj') with patch('os.path.exists'): service_item.set_from_service(service[0]) # WHEN: Added to the preview widget and switched to the second frame. self.preview_widget.replace_service_item(service_item, 1, 0) self.preview_widget.change_slide(1) # THEN: The current_slide_number should reflect the change. - self.assertEqual(self.preview_widget.current_slide_number(), 1, - u'The current slide number should be 1.') + self.assertEqual(self.preview_widget.current_slide_number(), 1, u'The current slide number should be 1.') diff --git a/tests/resources/serviceitem_custom_1.osd b/tests/resources/serviceitem_custom_1.osd deleted file mode 100644 index 7f75b39f4..000000000 --- a/tests/resources/serviceitem_custom_1.osd +++ /dev/null @@ -1,96 +0,0 @@ -(lp1 -(dp2 -Vserviceitem -p3 -(dp4 -Vheader -p5 -(dp6 -Vfooter -p7 -(lp8 -VTest Custom Credits -p9 -asVaudit -p10 -V -sVsearch -p11 -V -sVwill_auto_start -p12 -I00 -sVname -p13 -Vcustom -p14 -sVplugin -p15 -g14 -sVdata -p16 -V -sVnotes -p17 -V -sVtitle -p18 -VTest Custom -p19 -sVfrom_plugin -p20 -I00 -sVcapabilities -p21 -(lp22 -I2 -aI1 -aI5 -aI13 -aI8 -asVmedia_length -p23 -I0 -sVtheme_overwritten -p24 -I00 -sVtheme -p25 -NsVxml_version -p26 -NsVend_time -p27 -I0 -sVbackground_audio -p28 -(lp29 -sVtype -p30 -I1 -sVstart_time -p31 -I0 -sVicon -p32 -V:/plugins/plugin_custom.png -p33 -ssg16 -(lp34 -(dp35 -VverseTag -p36 -NsVraw_slide -p37 -VSlide 1 -p38 -sVtitle -p39 -g38 -sa(dp40 -g36 -Nsg37 -VSlide 2 -p41 -sg39 -g41 -sassa. \ No newline at end of file diff --git a/tests/resources/serviceitem_image_1.osd b/tests/resources/serviceitem_image_1.osd deleted file mode 100644 index cc0a6a897..000000000 --- a/tests/resources/serviceitem_image_1.osd +++ /dev/null @@ -1,79 +0,0 @@ -(lp1 -(dp2 -Vserviceitem -p3 -(dp4 -Vheader -p5 -(dp6 -Vfooter -p7 -(lp8 -sVaudit -p9 -V -sVsearch -p10 -V -sVwill_auto_start -p11 -I00 -sVname -p12 -Vimages -p13 -sVplugin -p14 -g13 -sVdata -p15 -V -sVnotes -p16 -V -sVtitle -p17 -VImages -p18 -sVfrom_plugin -p19 -I00 -sVcapabilities -p20 -(lp21 -I3 -aI1 -aI5 -aI6 -asVmedia_length -p22 -I0 -sVtheme_overwritten -p23 -I00 -sVtheme -p24 -I-1 -sVxml_version -p25 -NsVend_time -p26 -I0 -sVbackground_audio -p27 -(lp28 -sVtype -p29 -I2 -sVstart_time -p30 -I0 -sVicon -p31 -V:/plugins/plugin_images.png -p32 -ssg15 -(lp33 -Vimage_1.jpg -p34 -assa. \ No newline at end of file diff --git a/tests/resources/serviceitem_image_2.osd b/tests/resources/serviceitem_image_2.osd deleted file mode 100644 index 0556c236a..000000000 --- a/tests/resources/serviceitem_image_2.osd +++ /dev/null @@ -1,101 +0,0 @@ -(lp1 -(dp2 -Vserviceitem -p3 -(dp4 -Vheader -p5 -(dp6 -Vxml_version -p7 -NsVauto_play_slides_loop -p8 -I00 -sVauto_play_slides_once -p9 -I00 -sVwill_auto_start -p10 -I00 -sVtitle -p11 -VImages -p12 -sVcapabilities -p13 -(lp14 -I3 -aI1 -aI5 -aI6 -asVtheme -p15 -I-1 -sVbackground_audio -p16 -(lp17 -sVicon -p18 -V:/plugins/plugin_images.png -p19 -sVtype -p20 -I2 -sVstart_time -p21 -I0 -sVfrom_plugin -p22 -I00 -sVmedia_length -p23 -I0 -sVdata -p24 -V -sVtimed_slide_interval -p25 -I0 -sVaudit -p26 -V -sVsearch -p27 -V -sVname -p28 -Vimages -p29 -sVfooter -p30 -(lp31 -sVnotes -p32 -V -sVplugin -p33 -g29 -sVtheme_overwritten -p34 -I00 -sVend_time -p35 -I0 -ssg24 -(lp36 -(dp37 -Vpath -p38 -V/home/openlp/image_1.jpg -p39 -sg11 -Vimage_1.jpg -p40 -sa(dp41 -g38 -V/home/openlp/image_2.jpg -p42 -sg11 -Vimage_2.jpg -p43 -sassa. \ No newline at end of file diff --git a/tests/resources/serviceitem_image_3.osj b/tests/resources/serviceitem_image_3.osj new file mode 100644 index 000000000..c1d0bc5b7 --- /dev/null +++ b/tests/resources/serviceitem_image_3.osj @@ -0,0 +1 @@ +[{"serviceitem": {"header": {"xml_version": null, "auto_play_slides_loop": false, "auto_play_slides_once": false, "will_auto_start": false, "title": "Images", "capabilities": [3, 1, 5, 6, 3, 1, 5, 6], "theme": -1, "background_audio": [], "icon": ":/plugins/plugin_images.png", "type": 2, "start_time": 0, "from_plugin": false, "media_length": 0, "data": "", "timed_slide_interval": 0, "audit": "", "search": "", "name": "images", "footer": [], "notes": "", "plugin": "images", "theme_overwritten": false, "end_time": 0, "processor": null}, "data": [{"path": "/home/tim/Pictures/Holiday_base/11 November/Holiday - Jon/IMG_7445.JPG", "title": "IMG_7445.JPG"}, {"path": "/home/tim/Pictures/Holiday_base/11 November/Holiday - Jon/IMG_7478.JPG", "title": "IMG_7478.JPG"}]}}] \ No newline at end of file diff --git a/tests/resources/serviceitem_osd2osj.osd b/tests/resources/serviceitem_osd2osj.osd deleted file mode 100644 index 2a09588c4..000000000 --- a/tests/resources/serviceitem_osd2osj.osd +++ /dev/null @@ -1,1037 +0,0 @@ -(lp1 -(dp2 -Vserviceitem -p3 -(dp4 -Vheader -p5 -(dp6 -Vxml_version -p7 -S'\nAmazing GraceJohn NewtonAmazing Grace! how sweet the sound
That saved a wretch like me;
I once was lost, but now am found,
Was blind, but now I see.
\xe2\x80\x99Twas grace that taught my heart to fear,
And grace my fears relieved;
How precious did that grace appear,
The hour I first believed!
Through many dangers, toils and snares
I have already come;
\xe2\x80\x99Tis grace that brought me safe thus far,
And grace will lead me home.
The Lord has promised good to me,
His word my hope secures;
He will my shield and portion be
As long as life endures.
Yes, when this heart and flesh shall fail,
And mortal life shall cease,
I shall possess within the veil
A life of joy and peace.
When we\xe2\x80\x99ve been there a thousand years,
Bright shining as the sun,
We\xe2\x80\x99ve no less days to sing God\xe2\x80\x99s praise
Than when we first begun.
' -p8 -sVauto_play_slides_loop -p9 -I00 -sVauto_play_slides_once -p10 -I00 -sVwill_auto_start -p11 -I00 -sVtitle -p12 -VAmazing Grace -p13 -sVcapabilities -p14 -(lp15 -I2 -aI1 -aI5 -aI8 -aI9 -aI13 -asVtheme -p16 -NsVbackground_audio -p17 -(lp18 -sVicon -p19 -V:/plugins/plugin_songs.png -p20 -sVtype -p21 -I1 -sVstart_time -p22 -I0 -sVfrom_plugin -p23 -I00 -sVmedia_length -p24 -I0 -sVdata -p25 -(dp26 -Vauthors -p27 -VJohn Newton -p28 -sVtitle -p29 -Vamazing grace@ -p30 -ssVtimed_slide_interval -p31 -I0 -sVaudit -p32 -(lp33 -g13 -a(lp34 -g28 -aaV -aV -asVsearch -p35 -V -sVname -p36 -Vsongs -p37 -sVfooter -p38 -(lp39 -g13 -aVJohn Newton -p40 -aV -asVnotes -p41 -V -sVplugin -p42 -g37 -sVtheme_overwritten -p43 -I00 -sVend_time -p44 -I0 -sVprocessor -p45 -Nssg25 -(lp46 -(dp47 -VverseTag -p48 -VV1 -p49 -sVraw_slide -p50 -VAmazing Grace! how sweet the sound\u000aThat saved a wretch like me;\u000aI once was lost, but now am found,\u000aWas blind, but now I see. -p51 -sVtitle -p52 -VAmazing Grace! how sweet the s -p53 -sa(dp54 -g48 -VV2 -p55 -sg50 -V\u2019Twas grace that taught my heart to fear,\u000aAnd grace my fears relieved;\u000aHow precious did that grace appear,\u000aThe hour I first believed! -p56 -sg52 -V\u2019Twas grace that taught my hea -p57 -sa(dp58 -g48 -VV3 -p59 -sg50 -VThrough many dangers, toils and snares\u000aI have already come;\u000a\u2019Tis grace that brought me safe thus far,\u000aAnd grace will lead me home. -p60 -sg52 -VThrough many dangers, toils an -p61 -sa(dp62 -g48 -VV4 -p63 -sg50 -VThe Lord has promised good to me,\u000aHis word my hope secures;\u000aHe will my shield and portion be\u000aAs long as life endures. -p64 -sg52 -VThe Lord has promised good to -p65 -sa(dp66 -g48 -VV5 -p67 -sg50 -VYes, when this heart and flesh shall fail,\u000aAnd mortal life shall cease,\u000aI shall possess within the veil\u000aA life of joy and peace. -p68 -sg52 -VYes, when this heart and flesh -p69 -sa(dp70 -g48 -VV6 -p71 -sg50 -VWhen we\u2019ve been there a thousand years,\u000aBright shining as the sun,\u000aWe\u2019ve no less days to sing God\u2019s praise\u000aThan when we first begun. -p72 -sg52 -VWhen we\u2019ve been there a thousa -p73 -sassa(dp74 -g3 -(dp75 -g5 -(dp76 -g7 -S'\nAs With GladnessW. C. DixAs with gladness men of old
Did the guiding star behold;
As with joy they hailed its light,
Leading onward, beaming bright,
So, most gracious God, may we
Evermore be led by Thee.
As with joyful steps they sped,
Saviour, to Thy lowly bed,
There to bend the knee before
Thee whom heaven and earth adore,
So may we with willing feet
Ever seek Thy mercy-seat.
As they offered gifts most rare
At Thy cradle rude and bare,
So may we with holy joy,
Pure, and free from sin\xe2\x80\x99s alloy,
All our costliest treasures bring,
Christ, to Thee, our heavenly King.
Holy Jesus, every day
Keep us in the narrow way;
And, when earthly things are past,
Bring our ransomed souls at last
Where they need no star to guide,
Where no clouds Thy glory hide.
In the heavenly country bright
Need they no created light;
Thou its light, its joy, its crown,
Thou its sun, which goes not down.
There forever may we sing
Hallelujahs to our King.
' -p77 -sg9 -I00 -sg10 -I00 -sg11 -I00 -sg12 -VAs With Gladness -p78 -sg14 -(lp79 -I2 -aI1 -aI5 -aI8 -aI9 -aI13 -asg16 -Nsg17 -(lp80 -sg19 -g20 -sg21 -I1 -sg22 -I0 -sg23 -I00 -sg24 -I0 -sg25 -(dp81 -g27 -VW. C. Dix -p82 -sg29 -Vas with gladness@ -p83 -ssg31 -I0 -sg32 -(lp84 -g78 -a(lp85 -g82 -aaV -aV -asg35 -V -sg36 -g37 -sg38 -(lp86 -g78 -aVW. C. Dix -p87 -aV -asg41 -V -sg42 -g37 -sg43 -I00 -sg44 -I0 -sg45 -Nssg25 -(lp88 -(dp89 -g48 -VV1 -p90 -sg50 -VAs with gladness men of old\u000aDid the guiding star behold;\u000aAs with joy they hailed its light,\u000aLeading onward, beaming bright,\u000aSo, most gracious God, may we\u000aEvermore be led by Thee. -p91 -sg52 -VAs with gladness men of old -p92 -sa(dp93 -g48 -VV2 -p94 -sg50 -VAs with joyful steps they sped,\u000aSaviour, to Thy lowly bed,\u000aThere to bend the knee before\u000aThee whom heaven and earth adore,\u000aSo may we with willing feet\u000aEver seek Thy mercy-seat.\u000aAs they offered gifts most rare\u000aAt Thy cradle rude and bare,\u000aSo may we with holy joy,\u000aPure, and free from sin\u2019s alloy,\u000aAll our costliest treasures bring,\u000aChrist, to Thee, our heavenly King. -p95 -sg52 -VAs with joyful steps they sped -p96 -sa(dp97 -g48 -VV3 -p98 -sg50 -VHoly Jesus, every day\u000aKeep us in the narrow way;\u000aAnd, when earthly things are past,\u000aBring our ransomed souls at last\u000aWhere they need no star to guide,\u000aWhere no clouds Thy glory hide. -p99 -sg52 -VHoly Jesus, every day -p100 -sa(dp101 -g48 -VV4 -p102 -sg50 -VIn the heavenly country bright\u000aNeed they no created light;\u000aThou its light, its joy, its crown,\u000aThou its sun, which goes not down.\u000aThere forever may we sing\u000aHallelujahs to our King. -p103 -sg52 -VIn the heavenly country bright -p104 -sassa(dp105 -g3 -(dp106 -g5 -(dp107 -g7 -Nsg9 -I00 -sg10 -I00 -sg11 -I00 -sg12 -VPsalms 23:1-6 (KJV) -p108 -sg14 -(lp109 -I7 -aI1 -aI5 -aI14 -asg16 -Nsg17 -(lp110 -sg19 -V:/plugins/plugin_bibles.png -p111 -sg21 -I1 -sg22 -I0 -sg23 -I00 -sg24 -I0 -sg25 -V -sg31 -I0 -sg32 -V -sg35 -V -sg36 -Vbibles -p112 -sg38 -(lp113 -VPsalms 23:1-6 -p114 -aVKJV, Public Domain -p115 -asg41 -V -sg42 -g112 -sg43 -I00 -sg44 -I0 -sg45 -Nssg25 -(lp116 -(dp117 -g48 -Nsg50 -V{su}23:1{/su}  The LORD [is] my shepherd; I shall not want.\u000a {su}23:2{/su} He maketh me to lie down in green pastures: he leadeth me beside the still waters.\u000a {su}23:3{/su} He restoreth my soul: he leadeth me in the paths of righteousness for his name's sake.\u000a {su}23:4{/su} Yea, though I walk through the valley of the shadow of death, I will fear no evil: for thou [art] with me; thy rod and thy staff they comfort me.\u000a {su}23:5{/su} Thou preparest a table before me in the presence of mine enemies: thou anointest my head with oil; my cup runneth over.\u000a {su}23:6{/su} Surely goodness and mercy shall follow me all the days of my life: and I will dwell in the house of the LORD for ever.\u000a -p118 -sg52 -V{su}23:1{/su} \nBe Still and KnowAuthor UnknownBe still and know that I am God,
Be still and know that I am God,
Be still and know that I am God.
I am the Lord that healeth thee,
I am the Lord that healeth thee,
I am the Lord that healeth thee.
In Thee, O Lord, do I put my trust,
In Thee, O Lord, do I put my trust,
In Thee, O Lord, do I put my trust.
' -p123 -sg9 -I00 -sg10 -I00 -sg11 -I00 -sg12 -VBe Still and Know -p124 -sg14 -(lp125 -I2 -aI1 -aI5 -aI8 -aI9 -aI13 -asg16 -Nsg17 -(lp126 -sg19 -g20 -sg21 -I1 -sg22 -I0 -sg23 -I00 -sg24 -I0 -sg25 -(dp127 -g27 -VAuthor Unknown -p128 -sg29 -Vbe still and know@ -p129 -ssg31 -I0 -sg32 -(lp130 -g124 -a(lp131 -g128 -aaV -aV -asg35 -V -sg36 -g37 -sg38 -(lp132 -g124 -aVAuthor Unknown -p133 -aV -asg41 -V -sg42 -g37 -sg43 -I00 -sg44 -I0 -sg45 -Nssg25 -(lp134 -(dp135 -g48 -VV1 -p136 -sg50 -VBe still and know that I am God,\u000aBe still and know that I am God,\u000aBe still and know that I am God. -p137 -sg52 -VBe still and know that I am Go -p138 -sa(dp139 -g48 -VV2 -p140 -sg50 -VI am the Lord that healeth thee,\u000aI am the Lord that healeth thee,\u000aI am the Lord that healeth thee. -p141 -sg52 -VI am the Lord that healeth the -p142 -sa(dp143 -g48 -VV3 -p144 -sg50 -VIn Thee, O Lord, do I put my trust,\u000aIn Thee, O Lord, do I put my trust,\u000aIn Thee, O Lord, do I put my trust. -p145 -sg52 -VIn Thee, O Lord, do I put my t -p146 -sassa(dp147 -g3 -(dp148 -g5 -(dp149 -g7 -Nsg9 -I00 -sg10 -I00 -sg11 -I00 -sg12 -VImages -p150 -sg14 -(lp151 -I3 -aI1 -aI5 -aI6 -asg16 -I-1 -sg17 -(lp152 -sg19 -V:/plugins/plugin_images.png -p153 -sg21 -I2 -sg22 -I0 -sg23 -I00 -sg24 -I0 -sg25 -V -sg31 -I0 -sg32 -V -sg35 -V -sg36 -Vimages -p154 -sg38 -(lp155 -sg41 -V -sg42 -g154 -sg43 -I00 -sg44 -I0 -sg45 -Nssg25 -(lp156 -Vimagetest1.jpg -p157 -assa(dp158 -g3 -(dp159 -g5 -(dp160 -g7 -S'\nBlessed AssuranceFanny CrosbyBlessed assurance, Jesus is mine:
O what a foretaste of glory divine!
Heir of salvation, purchase of God;
Born of His Spirit, washed in His blood.
This is my story, this is my song,
Praising my Saviour all the day long.
This is my story, this is my song,
Praising my Saviour all the day long.
Perfect submission, perfect delight,
Visions of rapture burst on my sight;
Angels descending bring from above
Echoes of mercy, whispers of love.
Perfect submission, all is at rest,
I in my Saviour am happy and blessed;
Watching and waiting, looking above,
Filled with His goodness, lost in His love.
' -p161 -sg9 -I00 -sg10 -I00 -sg11 -I00 -sg12 -VBlessed Assurance -p162 -sg14 -(lp163 -I2 -aI1 -aI5 -aI8 -aI9 -aI13 -asg16 -Nsg17 -(lp164 -sg19 -g20 -sg21 -I1 -sg22 -I0 -sg23 -I00 -sg24 -I0 -sg25 -(dp165 -g27 -VFanny Crosby -p166 -sg29 -Vblessed assurance@ -p167 -ssg31 -I0 -sg32 -(lp168 -g162 -a(lp169 -g166 -aaV -aV -asg35 -V -sg36 -g37 -sg38 -(lp170 -g162 -aVFanny Crosby -p171 -aV -asg41 -V -sg42 -g37 -sg43 -I00 -sg44 -I0 -sg45 -Nssg25 -(lp172 -(dp173 -g48 -VV1 -p174 -sg50 -VBlessed assurance, Jesus is mine:\u000aO what a foretaste of glory divine!\u000aHeir of salvation, purchase of God;\u000aBorn of His Spirit, washed in His blood. -p175 -sg52 -VBlessed assurance, Jesus is mi -p176 -sa(dp177 -g48 -VV2 -p178 -sg50 -VThis is my story, this is my song,\u000aPraising my Saviour all the day long.\u000aThis is my story, this is my song,\u000aPraising my Saviour all the day long. -p179 -sg52 -VThis is my story, this is my s -p180 -sa(dp181 -g48 -VV3 -p182 -sg50 -VPerfect submission, perfect delight,\u000aVisions of rapture burst on my sight;\u000aAngels descending bring from above\u000aEchoes of mercy, whispers of love. -p183 -sg52 -VPerfect submission, perfect de -p184 -sa(dp185 -g48 -VV4 -p186 -sg50 -VPerfect submission, all is at rest,\u000aI in my Saviour am happy and blessed;\u000aWatching and waiting, looking above,\u000aFilled with His goodness, lost in His love. -p187 -sg52 -VPerfect submission, all is at -p188 -sassa(dp189 -g3 -(dp190 -g5 -(dp191 -g7 -S'\nCrown Him With Many CrownsMatthew BridgesGodfrey ThringCrown Him with many crowns,
The Lamb upon His throne;
Hark, how the heavenly anthem drowns
All music but its own!
Awake, my soul, and sing
Of Him who died for thee,
And hail Him as thy matchless King
Through all eternity.
Crown Him the Lord of life,
Who triumphed o\xe2\x80\x99er the grave
And rose victorious in the strife
For those He came to save:
His glories now we sing,
Who died and rose on high,
Who died eternal life to bring
And lives that death may die.
Crown Him the Lord of love;
Behold His hands and side,
Those wounds yet visible above
In beauty glorified:
No angel in the sky
Can fully bear that sight,
But downward bends His burning eye
At mysteries so bright.
Crown Him the Lord of peace,
Whose power a sceptre sways
From pole to pole, that wars may cease,
And all be prayer and praise:
His reign shall know no end,
And round His pierced feet
Fair flowers of paradise extend
Their fragrance ever sweet.
Crown Him the Lord of years,
The Potentate of time,
Creator of the rolling spheres,
Ineffably sublime!
All hail, Redeemer, hail!
For Thou hast died for me;
Thy praise shall never, never fail
Throughout eternity.
' -p192 -sg9 -I00 -sg10 -I00 -sg11 -I00 -sg12 -VCrown Him With Many Crowns -p193 -sg14 -(lp194 -I2 -aI1 -aI5 -aI8 -aI9 -aI13 -asg16 -Nsg17 -(lp195 -sg19 -g20 -sg21 -I1 -sg22 -I0 -sg23 -I00 -sg24 -I0 -sg25 -(dp196 -g27 -VMatthew Bridges, Godfrey Thring -p197 -sg29 -Vcrown him with many crowns@ -p198 -ssg31 -I0 -sg32 -(lp199 -g193 -a(lp200 -VMatthew Bridges -p201 -aVGodfrey Thring -p202 -aaV -aV -asg35 -V -sg36 -g37 -sg38 -(lp203 -g193 -aVMatthew Bridges og Godfrey Thring -p204 -aV -asg41 -V -sg42 -g37 -sg43 -I00 -sg44 -I0 -sg45 -Nssg25 -(lp205 -(dp206 -g48 -VV1 -p207 -sg50 -VCrown Him with many crowns,\u000aThe Lamb upon His throne;\u000aHark, how the heavenly anthem drowns\u000aAll music but its own!\u000aAwake, my soul, and sing\u000aOf Him who died for thee,\u000aAnd hail Him as thy matchless King\u000aThrough all eternity. -p208 -sg52 -VCrown Him with many crowns, -p209 -sa(dp210 -g48 -VV2 -p211 -sg50 -VCrown Him the Lord of life,\u000aWho triumphed o\u2019er the grave\u000aAnd rose victorious in the strife\u000aFor those He came to save:\u000aHis glories now we sing,\u000aWho died and rose on high,\u000aWho died eternal life to bring\u000aAnd lives that death may die. -p212 -sg52 -VCrown Him the Lord of life, -p213 -sa(dp214 -g48 -VV3 -p215 -sg50 -VCrown Him the Lord of love;\u000aBehold His hands and side,\u000aThose wounds yet visible above\u000aIn beauty glorified:\u000aNo angel in the sky\u000aCan fully bear that sight,\u000aBut downward bends His burning eye\u000aAt mysteries so bright. -p216 -sg52 -VCrown Him the Lord of love; -p217 -sa(dp218 -g48 -VV4 -p219 -sg50 -VCrown Him the Lord of peace,\u000aWhose power a sceptre sways\u000aFrom pole to pole, that wars may cease,\u000aAnd all be prayer and praise:\u000aHis reign shall know no end,\u000aAnd round His pierced feet\u000aFair flowers of paradise extend\u000aTheir fragrance ever sweet. -p220 -sg52 -VCrown Him the Lord of peace, -p221 -sa(dp222 -g48 -VV5 -p223 -sg50 -VCrown Him the Lord of years,\u000aThe Potentate of time,\u000aCreator of the rolling spheres,\u000aIneffably sublime!\u000aAll hail, Redeemer, hail!\u000aFor Thou hast died for me;\u000aThy praise shall never, never fail\u000aThroughout eternity. -p224 -sg52 -VCrown Him the Lord of years, -p225 -sassa(dp226 -g3 -(dp227 -g5 -(dp228 -g7 -Nsg9 -I00 -sg10 -I00 -sg11 -I00 -sg12 -g150 -sg14 -(lp229 -I3 -aI1 -aI5 -aI6 -asg16 -I-1 -sg17 -(lp230 -sg19 -g153 -sg21 -I2 -sg22 -I0 -sg23 -I00 -sg24 -I0 -sg25 -V -sg31 -I0 -sg32 -V -sg35 -V -sg36 -g154 -sg38 -(lp231 -sg41 -V -sg42 -g154 -sg43 -I00 -sg44 -I0 -sg45 -Nssg25 -(lp232 -Vimage_test2.jpg -p233 -assa(dp234 -g3 -(dp235 -g5 -(dp236 -g7 -Nsg9 -I00 -sg10 -I00 -sg11 -I00 -sg12 -VVideo_1.mov -p237 -sg14 -(lp238 -I16 -aI4 -asg16 -I-1 -sg17 -(lp239 -sg19 -V:/plugins/plugin_media.png -p240 -sg21 -I3 -sg22 -I0 -sg23 -I00 -sg24 -I0 -sg25 -V -sg31 -I0 -sg32 -V -sg35 -V -sg36 -Vmedia -p241 -sg38 -(lp242 -sg41 -V -sg42 -g241 -sg43 -I00 -sg44 -I0 -sg45 -VAutomatic -p243 -ssg25 -(lp244 -(dp245 -Vpath -p246 -V/home/openlp/test_media/all_free_to_users -p247 -sVimage -p248 -V:/media/slidecontroller_multimedia.png -p249 -sg12 -g237 -sassa(dp250 -g3 -(dp251 -g5 -(dp252 -g7 -S'\nFill Thou My LifeHoratius BonarFill thou my life, O Lord my God,
In every part with praise,
That my whole being may proclaim
Thy being and Thy ways.
Not for the lip of praise alone,
Nor e\xe2\x80\x99en the praising heart
I ask, but for a life made up
Of praise in every part:
Praise in the common things of life,
Its goings out and in;
Praise in each duty and each deed,
However small and mean.
Fill every part of me with praise;
Let all my being speak
Of Thee and of Thy love, O Lord,
Poor though I be and weak.
So shall Thou, gracious Lord, from me
Receive the glory due;
And so shall I begin on earth
The song forever new.
So shall no part of day or night
From sacredness be free;
But all my life, in every step,
Be fellowship with Thee.
' -p253 -sg9 -I00 -sg10 -I00 -sg11 -I00 -sg12 -VFill Thou My Life -p254 -sg14 -(lp255 -I2 -aI1 -aI5 -aI8 -aI9 -aI13 -asg16 -Nsg17 -(lp256 -sg19 -g20 -sg21 -I1 -sg22 -I0 -sg23 -I00 -sg24 -I0 -sg25 -(dp257 -g27 -VHoratius Bonar -p258 -sg29 -Vfill thou my life@ -p259 -ssg31 -I0 -sg32 -(lp260 -g254 -a(lp261 -g258 -aaV -aV -asg35 -V -sg36 -g37 -sg38 -(lp262 -g254 -aVHoratius Bonar -p263 -aV -asg41 -V -sg42 -g37 -sg43 -I00 -sg44 -I0 -sg45 -Nssg25 -(lp264 -(dp265 -g48 -VV1 -p266 -sg50 -VFill thou my life, O Lord my God,\u000aIn every part with praise,\u000aThat my whole being may proclaim\u000aThy being and Thy ways. -p267 -sg52 -VFill thou my life, O Lord my G -p268 -sa(dp269 -g48 -VV2 -p270 -sg50 -VNot for the lip of praise alone,\u000aNor e\u2019en the praising heart\u000aI ask, but for a life made up\u000aOf praise in every part: -p271 -sg52 -VNot for the lip of praise alon -p272 -sa(dp273 -g48 -VV3 -p274 -sg50 -VPraise in the common things of life,\u000aIts goings out and in;\u000aPraise in each duty and each deed,\u000aHowever small and mean. -p275 -sg52 -VPraise in the common things of -p276 -sa(dp277 -g48 -VV4 -p278 -sg50 -VFill every part of me with praise;\u000aLet all my being speak\u000aOf Thee and of Thy love, O Lord,\u000aPoor though I be and weak. -p279 -sg52 -VFill every part of me with pra -p280 -sa(dp281 -g48 -VV5 -p282 -sg50 -VSo shall Thou, gracious Lord, from me\u000aReceive the glory due;\u000aAnd so shall I begin on earth\u000aThe song forever new. -p283 -sg52 -VSo shall Thou, gracious Lord, -p284 -sa(dp285 -g48 -VV6 -p286 -sg50 -VSo shall no part of day or night\u000aFrom sacredness be free;\u000aBut all my life, in every step,\u000aBe fellowship with Thee. -p287 -sg52 -VSo shall no part of day or nig -p288 -sassa. diff --git a/tests/utils/osdinteraction.py b/tests/utils/osdinteraction.py index f275d18c2..8eb00fdb5 100644 --- a/tests/utils/osdinteraction.py +++ b/tests/utils/osdinteraction.py @@ -30,9 +30,8 @@ The :mod:`osdinteraction` provides miscellaneous functions for interacting with OSD files. """ - import os -import cPickle +import json from tests.utils.constants import TEST_RESOURCES_PATH @@ -45,5 +44,5 @@ def read_service_from_file(file_name): """ service_file = os.path.join(TEST_RESOURCES_PATH, file_name) with open(service_file, u'r') as open_file: - service = cPickle.load(open_file) + service = json.load(open_file) return service From e1f153f4f46185ae5c343b909d9820e5ace41ded Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Thu, 29 Aug 2013 17:40:07 +0100 Subject: [PATCH 4/4] Fix text --- openlp/core/ui/servicemanager.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 0f22cb25e..d75888405 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -706,7 +706,8 @@ class ServiceManager(QtGui.QWidget, ServiceManagerDialog): items = json.load(file_to) else: critical_error_message_box(message=translate('OpenLP.ServiceManager', - 'File is not in a supported format.\n The use OpenLP 2.0.2 or greater to create file.')) + 'The service file you are trying to open is in an old format.\n ' + 'Please save it using OpenLP 2.0.2 or greater.')) return file_to.close() self.new_file()