Tomas Groth has proposed merging lp:~tomasgroth/openlp/json-service-format into lp:openlp.
Requested reviews: Andreas Preikschat (googol) Tim Bentley (trb143) Raoul Snyman (raoul-snyman) Tomas Groth (tomasgroth) Related bugs: Bug #903773 in OpenLP: "Support a more open format for service files" https://bugs.launchpad.net/openlp/+bug/903773 For more details, see: https://code.launchpad.net/~tomasgroth/openlp/json-service-format/+merge/173306 Merged trunk into the branch. -- https://code.launchpad.net/~tomasgroth/openlp/json-service-format/+merge/173306 Your team OpenLP Core is subscribed to branch lp:openlp.
=== modified file 'openlp/core/ui/servicemanager.py' --- openlp/core/ui/servicemanager.py 2013-06-24 16:54:23 +0000 +++ openlp/core/ui/servicemanager.py 2013-07-06 10:30:36 +0000 @@ -35,6 +35,7 @@ import os import shutil import zipfile +import json from tempfile import mkstemp from datetime import datetime, timedelta @@ -458,7 +459,7 @@ path_file_name = unicode(self.file_name()) path, file_name = os.path.split(path_file_name) base_name = os.path.splitext(file_name)[0] - service_file_name = '%s.osd' % base_name + service_file_name = '%s.osj' % base_name log.debug(u'ServiceManager.save_file - %s', path_file_name) Settings().setValue(self.main_window.service_manager_settings_section + u'/last directory', path) service = [] @@ -512,7 +513,7 @@ file_size = os.path.getsize(file_item) total_size += file_size log.debug(u'ServiceManager.save_file - ZIP contents size is %i bytes' % total_size) - service_content = cPickle.dumps(service) + service_content = json.dumps(service) # Usual Zip file cannot exceed 2GiB, file with Zip64 cannot be extracted using unzip in UNIX. allow_zip_64 = (total_size > 2147483648 + len(service_content)) log.debug(u'ServiceManager.save_file - allowZip64 is %s' % allow_zip_64) @@ -572,7 +573,7 @@ path_file_name = unicode(self.file_name()) path, file_name = os.path.split(path_file_name) base_name = os.path.splitext(file_name)[0] - service_file_name = '%s.osd' % base_name + service_file_name = '%s.osj' % base_name log.debug(u'ServiceManager.save_file - %s', path_file_name) Settings().setValue(self.main_window.service_manager_settings_section + u'/last directory', path) service = [] @@ -585,7 +586,7 @@ #TODO: check for file item on save. service.append({u'serviceitem': service_item}) self.main_window.increment_progress_bar() - service_content = cPickle.dumps(service) + service_content = json.dumps(service) zip_file = None success = True self.main_window.increment_progress_bar() @@ -698,11 +699,14 @@ log.debug(u'Extract file: %s', osfile) zip_info.filename = osfile zip_file.extract(zip_info, self.servicePath) - if osfile.endswith(u'osd'): + if osfile.endswith(u'osj') or osfile.endswith(u'osd'): p_file = os.path.join(self.servicePath, osfile) if 'p_file' in locals(): file_to = open(p_file, u'r') - items = cPickle.load(file_to) + if p_file.endswith(u'osj'): + items = json.load(file_to) + else: + items = cPickle.load(file_to) file_to.close() self.new_file() self.set_file_name(file_name) === added file 'tests/functional/openlp_core_lib/test_serviceitem_json.py' --- tests/functional/openlp_core_lib/test_serviceitem_json.py 1970-01-01 00:00:00 +0000 +++ tests/functional/openlp_core_lib/test_serviceitem_json.py 2013-07-06 10:30:36 +0000 @@ -0,0 +1,261 @@ +# -*- 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 + === added file 'tests/resources/serviceitem_custom_1.osj' --- tests/resources/serviceitem_custom_1.osj 1970-01-01 00:00:00 +0000 +++ tests/resources/serviceitem_custom_1.osj 2013-07-06 10:30:36 +0000 @@ -0,0 +1,1 @@ +[{"serviceitem": {"header": {"xml_version": null, "auto_play_slides_loop": false, "auto_play_slides_once": false, "will_auto_start": false, "title": "Test Custom", "capabilities": [2, 1, 5, 13, 8], "theme": null, "background_audio": [], "icon": ":/plugins/plugin_custom.png", "type": 1, "start_time": 0, "from_plugin": false, "media_length": 0, "data": "", "timed_slide_interval": 0, "audit": "", "search": "", "name": "custom", "footer": ["Test Custom Credits"], "notes": "", "plugin": "custom", "theme_overwritten": false, "end_time": 0, "processor": null}, "data": [{"verseTag": null, "raw_slide": "Slide 1", "title": "Slide 1"}, {"verseTag": null, "raw_slide": "Slide 2", "title": "Slide 2"}]}}] \ No newline at end of file === added file 'tests/resources/serviceitem_image_1.osj' --- tests/resources/serviceitem_image_1.osj 1970-01-01 00:00:00 +0000 +++ tests/resources/serviceitem_image_1.osj 2013-07-06 10:30:36 +0000 @@ -0,0 +1,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], "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": ["image_1.jpg"]}}] === added file 'tests/resources/serviceitem_image_2.osj' --- tests/resources/serviceitem_image_2.osj 1970-01-01 00:00:00 +0000 +++ tests/resources/serviceitem_image_2.osj 2013-07-06 10:30:36 +0000 @@ -0,0 +1,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], "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/openlp/image_1.jpg", "title": "image_1.jpg"}]}}, {"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], "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/openlp/image_2.jpg", "title": "image_2.jpg"}]}}] === added file 'tests/resources/serviceitem_osd2osj.osd' --- tests/resources/serviceitem_osd2osj.osd 1970-01-01 00:00:00 +0000 +++ tests/resources/serviceitem_osd2osj.osd 2013-07-06 10:30:36 +0000 @@ -0,0 +1,1037 @@ +(lp1 +(dp2 +Vserviceitem +p3 +(dp4 +Vheader +p5 +(dp6 +Vxml_version +p7 +S'<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n<song xmlns="http://openlyrics.info/namespace/2009/song" version="0.8" createdIn="OpenLP 2192" modifiedIn="OpenLP 2192" modifiedDate="2013-06-07T21:51:35"><properties><titles><title>Amazing Grace</title></titles><authors><author>John Newton</author></authors></properties><lyrics><verse name="v1"><lines>Amazing Grace! how sweet the sound<br/>That saved a wretch like me;<br/>I once was lost, but now am found,<br/>Was blind, but now I see.</lines></verse><verse name="v2"><lines>\xe2\x80\x99Twas grace that taught my heart to fear,<br/>And grace my fears relieved;<br/>How precious did that grace appear,<br/>The hour I first believed!</lines></verse><verse name="v3"><lines>Through many dangers, toils and snares<br/>I have already come;<br/>\xe2\x80\x99Tis grace that brought me safe thus far,<br/>And grace will lead me home.</lines></verse><verse name="v4"><lines>The Lord has promised good to me,<br/>His word my hope secures;<br/>He will my shield and portion be<br/>As long as life endures.</lines></verse><verse name="v5"><lines>Yes, when this heart and flesh shall fail,<br/>And mortal life shall cease,<br/>I shall possess within the veil<br/>A life of joy and peace.</lines></verse><verse name="v6"><lines>When we\xe2\x80\x99ve been there a thousand years,<br/>Bright shining as the sun,<br/>We\xe2\x80\x99ve no less days to sing God\xe2\x80\x99s praise<br/>Than when we first begun.</lines></verse></lyrics></song>' +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'<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n<song xmlns="http://openlyrics.info/namespace/2009/song" version="0.8" createdIn="OpenLP 2192" modifiedIn="OpenLP 2192" modifiedDate="2013-06-07T21:51:36"><properties><titles><title>As With Gladness</title></titles><authors><author>W. C. Dix</author></authors></properties><lyrics><verse name="v1"><lines>As with gladness men of old<br/>Did the guiding star behold;<br/>As with joy they hailed its light,<br/>Leading onward, beaming bright,<br/>So, most gracious God, may we<br/>Evermore be led by Thee.</lines></verse><verse name="v2"><lines>As with joyful steps they sped,<br/>Saviour, to Thy lowly bed,<br/>There to bend the knee before<br/>Thee whom heaven and earth adore,<br/>So may we with willing feet<br/>Ever seek Thy mercy-seat.<br/>As they offered gifts most rare<br/>At Thy cradle rude and bare,<br/>So may we with holy joy,<br/>Pure, and free from sin\xe2\x80\x99s alloy,<br/>All our costliest treasures bring,<br/>Christ, to Thee, our heavenly King.</lines></verse><verse name="v3"><lines>Holy Jesus, every day<br/>Keep us in the narrow way;<br/>And, when earthly things are past,<br/>Bring our ransomed souls at last<br/>Where they need no star to guide,<br/>Where no clouds Thy glory hide.</lines></verse><verse name="v4"><lines>In the heavenly country bright<br/>Need they no created light;<br/>Thou its light, its joy, its crown,<br/>Thou its sun, which goes not down.<br/>There forever may we sing<br/>Hallelujahs to our King.</lines></verse></lyrics></song>' +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} <A Psalm of David.> 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} <A Psalm of +p119 +sassa(dp120 +g3 +(dp121 +g5 +(dp122 +g7 +S'<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n<song xmlns="http://openlyrics.info/namespace/2009/song" version="0.8" createdIn="OpenLP 2192" modifiedIn="OpenLP 2192" modifiedDate="2013-06-07T21:51:38"><properties><titles><title>Be Still and Know</title></titles><authors><author>Author Unknown</author></authors></properties><lyrics><verse name="v1"><lines>Be still and know that I am God,<br/>Be still and know that I am God,<br/>Be still and know that I am God.</lines></verse><verse name="v2"><lines>I am the Lord that healeth thee,<br/>I am the Lord that healeth thee,<br/>I am the Lord that healeth thee.</lines></verse><verse name="v3"><lines>In Thee, O Lord, do I put my trust,<br/>In Thee, O Lord, do I put my trust,<br/>In Thee, O Lord, do I put my trust.</lines></verse></lyrics></song>' +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'<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n<song xmlns="http://openlyrics.info/namespace/2009/song" version="0.8" createdIn="OpenLP 2192" modifiedIn="OpenLP 2192" modifiedDate="2013-06-07T21:51:38"><properties><titles><title>Blessed Assurance</title></titles><authors><author>Fanny Crosby</author></authors></properties><lyrics><verse name="v1"><lines>Blessed assurance, Jesus is mine:<br/>O what a foretaste of glory divine!<br/>Heir of salvation, purchase of God;<br/>Born of His Spirit, washed in His blood.</lines></verse><verse name="v2"><lines>This is my story, this is my song,<br/>Praising my Saviour all the day long.<br/>This is my story, this is my song,<br/>Praising my Saviour all the day long.</lines></verse><verse name="v3"><lines>Perfect submission, perfect delight,<br/>Visions of rapture burst on my sight;<br/>Angels descending bring from above<br/>Echoes of mercy, whispers of love.</lines></verse><verse name="v4"><lines>Perfect submission, all is at rest,<br/>I in my Saviour am happy and blessed;<br/>Watching and waiting, looking above,<br/>Filled with His goodness, lost in His love.</lines></verse></lyrics></song>' +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'<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n<song xmlns="http://openlyrics.info/namespace/2009/song" version="0.8" createdIn="OpenLP 2192" modifiedIn="OpenLP 2192" modifiedDate="2013-06-07T21:51:41"><properties><titles><title>Crown Him With Many Crowns</title></titles><authors><author>Matthew Bridges</author><author>Godfrey Thring</author></authors></properties><lyrics><verse name="v1"><lines>Crown Him with many crowns,<br/>The Lamb upon His throne;<br/>Hark, how the heavenly anthem drowns<br/>All music but its own!<br/>Awake, my soul, and sing<br/>Of Him who died for thee,<br/>And hail Him as thy matchless King<br/>Through all eternity.</lines></verse><verse name="v2"><lines>Crown Him the Lord of life,<br/>Who triumphed o\xe2\x80\x99er the grave<br/>And rose victorious in the strife<br/>For those He came to save:<br/>His glories now we sing,<br/>Who died and rose on high,<br/>Who died eternal life to bring<br/>And lives that death may die.</lines></verse><verse name="v3"><lines>Crown Him the Lord of love;<br/>Behold His hands and side,<br/>Those wounds yet visible above<br/>In beauty glorified:<br/>No angel in the sky<br/>Can fully bear that sight,<br/>But downward bends His burning eye<br/>At mysteries so bright.</lines></verse><verse name="v4"><lines>Crown Him the Lord of peace,<br/>Whose power a sceptre sways<br/>From pole to pole, that wars may cease,<br/>And all be prayer and praise:<br/>His reign shall know no end,<br/>And round His pierced feet<br/>Fair flowers of paradise extend<br/>Their fragrance ever sweet.</lines></verse><verse name="v5"><lines>Crown Him the Lord of years,<br/>The Potentate of time,<br/>Creator of the rolling spheres,<br/>Ineffably sublime!<br/>All hail, Redeemer, hail!<br/>For Thou hast died for me;<br/>Thy praise shall never, never fail<br/>Throughout eternity.</lines></verse></lyrics></song>' +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'<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n<song xmlns="http://openlyrics.info/namespace/2009/song" version="0.8" createdIn="OpenLP 2192" modifiedIn="OpenLP 2192" modifiedDate="2013-06-07T21:51:41"><properties><titles><title>Fill Thou My Life</title></titles><authors><author>Horatius Bonar</author></authors></properties><lyrics><verse name="v1"><lines>Fill thou my life, O Lord my God,<br/>In every part with praise,<br/>That my whole being may proclaim<br/>Thy being and Thy ways.</lines></verse><verse name="v2"><lines>Not for the lip of praise alone,<br/>Nor e\xe2\x80\x99en the praising heart<br/>I ask, but for a life made up<br/>Of praise in every part:</lines></verse><verse name="v3"><lines>Praise in the common things of life,<br/>Its goings out and in;<br/>Praise in each duty and each deed,<br/>However small and mean.</lines></verse><verse name="v4"><lines>Fill every part of me with praise;<br/>Let all my being speak<br/>Of Thee and of Thy love, O Lord,<br/>Poor though I be and weak.</lines></verse><verse name="v5"><lines>So shall Thou, gracious Lord, from me<br/>Receive the glory due;<br/>And so shall I begin on earth<br/>The song forever new.</lines></verse><verse name="v6"><lines>So shall no part of day or night<br/>From sacredness be free;<br/>But all my life, in every step,<br/>Be fellowship with Thee.</lines></verse></lyrics></song>' +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.
_______________________________________________ Mailing list: https://launchpad.net/~openlp-core Post to : openlp-core@lists.launchpad.net Unsubscribe : https://launchpad.net/~openlp-core More help : https://help.launchpad.net/ListHelp