diff --git a/openlp/plugins/songs/lib/importers/sundayplus.py b/openlp/plugins/songs/lib/importers/sundayplus.py index 9f34611c4..7d42b9aa1 100644 --- a/openlp/plugins/songs/lib/importers/sundayplus.py +++ b/openlp/plugins/songs/lib/importers/sundayplus.py @@ -53,8 +53,8 @@ class SundayPlusImport(SongImport): """ Initialise the class. """ - SongImport.__init__(self, manager, **kwargs) - self.encoding = 'us-ascii' + super(SundayPlusImport, self).__init__(manager, **kwargs) + self.encoding = 'cp1252' def do_import(self): self.import_wizard.progress_bar.setMaximum(len(self.import_source)) @@ -73,7 +73,7 @@ class SundayPlusImport(SongImport): if not self.parse(file.read()): self.log_error(file.name) return - if not self.title: + if self.title == '': self.title = self.title_from_filename(file.name) if not self.finish(): self.log_error(file.name) @@ -86,39 +86,39 @@ class SundayPlusImport(SongImport): :param cell: ? :return: """ - if len(data) == 0 or data[0:1] != '[' or data[-1] != ']': - self.log_error('File is malformed') + if cell == False and (len(data) == 0 or data[0:1] != b'[' or data.strip()[-1:] != b']'): + log.log_error('File is malformed') return False i = 1 verse_type = VerseType.tags[VerseType.Verse] while i < len(data): # Data is held as #name: value pairs inside groups marked as []. # Now we are looking for the name. - if data[i:i + 1] == '#': - name_end = data.find(':', i + 1) - name = data[i + 1:name_end].upper() + if data[i:i + 1] == b'#': + name_end = data.find(b':', i + 1) + name = data[i + 1:name_end].decode(self.encoding).upper() i = name_end + 1 - while data[i:i + 1] == ' ': + while data[i:i + 1] == b' ': i += 1 - if data[i:i + 1] == '"': - end = data.find('"', i + 1) + if data[i:i + 1] == b'"': + end = data.find(b'"', i + 1) value = data[i + 1:end] - elif data[i:i + 1] == '[': + elif data[i:i + 1] == b'[': j = i inside_quotes = False while j < len(data): char = data[j:j + 1] - if char == '"': + if char == b'"': inside_quotes = not inside_quotes - elif not inside_quotes and char == ']': + elif not inside_quotes and char == b']': end = j + 1 break j += 1 value = data[i:end] else: - end = data.find(',', i + 1) - if data.find('(', i, end) != -1: - end = data.find(')', i) + 1 + end = data.find(b',', i + 1) + if data.find(b'(', i, end) != -1: + end = data.find(b')', i) + 1 value = data[i:end] # If we are in the main group. if not cell: @@ -129,27 +129,29 @@ class SundayPlusImport(SongImport): if len(author): self.add_author(author) elif name == 'COPYRIGHT': - self.copyright = self.decode(self.unescape(value)) + self.add_copyright(self.decode(self.unescape(value))) elif name[0:4] == 'CELL': self.parse(value, cell=name[4:]) # We are in a verse group. else: if name == 'MARKER_NAME': - value = value.strip() + value = self.decode(value).strip() if len(value): verse_type = VerseType.tags[VerseType.from_loose_input(value[0])] if len(value) >= 2 and value[-1] in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']: verse_type = "%s%s" % (verse_type, value[-1]) elif name == 'HOTKEY': + value = self.decode(value).strip() # HOTKEY always appears after MARKER_NAME, so it # effectively overrides MARKER_NAME, if present. if len(value) and value in list(HOTKEY_TO_VERSE_TYPE.keys()): verse_type = HOTKEY_TO_VERSE_TYPE[value] if name == 'RTF': value = self.unescape(value) + value = self.decode(value) result = strip_rtf(value, self.encoding) if result is None: - return + return False verse, self.encoding = result lines = verse.strip().split('\n') # If any line inside any verse contains CCLI or @@ -164,7 +166,7 @@ class SundayPlusImport(SongImport): self.ccli_number = int(m.group(0)) continue elif line.lower() == 'public domain': - self.copyright = 'Public Domain' + self.add_copyright('Public Domain') continue processed_lines.append(line) self.add_verse('\n'.join(processed_lines).strip(), verse_type) @@ -192,11 +194,11 @@ class SundayPlusImport(SongImport): def decode(self, blob): while True: try: - return str(blob, self.encoding) - except: + return blob.decode(self.encoding) + except Exception as e: self.encoding = retrieve_windows_encoding() def unescape(self, text): - text = text.replace('^^', '"') - text = text.replace('^', '\'') + text = text.replace(b'^^', b'"') + text = text.replace(b'^', b'\'') return text.strip() diff --git a/tests/functional/openlp_plugins/songs/test_sundayplusimport.py b/tests/functional/openlp_plugins/songs/test_sundayplusimport.py new file mode 100644 index 000000000..45dc68caf --- /dev/null +++ b/tests/functional/openlp_plugins/songs/test_sundayplusimport.py @@ -0,0 +1,52 @@ +# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4 + +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2008-2016 OpenLP Developers # +# --------------------------------------------------------------------------- # +# This program is free software; you can redistribute it and/or modify it # +# under the terms of the GNU General Public License as published by the Free # +# Software Foundation; version 2 of the License. # +# # +# This program is distributed in the hope that it will be useful, but WITHOUT # +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # +# more details. # +# # +# You should have received a copy of the GNU General Public License along # +# with this program; if not, write to the Free Software Foundation, Inc., 59 # +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # +############################################################################### +""" +This module contains tests for the VideoPsalm song importer. +""" + +import os +from unittest import TestCase + +from tests.helpers.songfileimport import SongImportTestHelper +from tests.functional import patch + +TEST_PATH = os.path.abspath( + os.path.join(os.path.dirname(__file__), '..', '..', '..', 'resources', 'sundayplussongs')) + + +class TestSundayPlusFileImport(SongImportTestHelper): + + def __init__(self, *args, **kwargs): + self.importer_class_name = 'SundayPlusImport' + self.importer_module_name = 'sundayplus' + super(TestSundayPlusFileImport, self).__init__(*args, **kwargs) + + def test_song_import(self): + """ + Test that loading an SundayPlus file works correctly on various files + """ + with patch('openlp.plugins.songs.lib.importers.sundayplus.retrieve_windows_encoding') as \ + mocked_retrieve_windows_encoding: + mocked_retrieve_windows_encoding.return_value = 'cp1252' + #self.file_import([os.path.join(TEST_PATH, 'Abba Fader.ptf')], + # self.load_external_result_data(os.path.join(TEST_PATH, 'abba-fader.json'))) + self.file_import([os.path.join(TEST_PATH, 'Amazing Grace.ptf')], + self.load_external_result_data(os.path.join(TEST_PATH, 'Amazing Grace.json'))) diff --git a/tests/resources/sundayplussongs/Abba Fader.ptf b/tests/resources/sundayplussongs/Abba Fader.ptf new file mode 100644 index 000000000..28dc36cb3 --- /dev/null +++ b/tests/resources/sundayplussongs/Abba Fader.ptf @@ -0,0 +1,8 @@ +[#PTFVersion: 2, #GLOBAL_RECT: rect(47,2,1026,770), #opacity: 100, #SHADOW_ON: 0, #SHADOW_COLOR: rgb( 0, 0, 0), #SHADOW_OPACITY: 100, #SHADOW_POSITION: "RB", #SHADOW_OFFSET: [0, 0], #FILE_TYPE: "Song", #title: "Abba Fader", #Author: "Okänd", #Copyright: "ccc", #CELL1: [#MARKER_NAME: "Abba Fader", #Hotkey: "1", #rtf: "{\rtf1\ansi\ansicpg1252\deff0\deflang1053{\fonttbl{\f0\froman\fprq2\fcharset0 Verdana;}{\f1\froman\fcharset0 Verdana;}} +{\colortbl ;\red255\green255\blue0;\red224\green223\blue227;} +\viewkind4\uc1\pard\cf1\b\f0\fs86 Abba Fader\par +\par +Vi \^e4r h\^e4r f\^f6r att prisa Dig\line Vi \^e4r h\^e4r med f\^f6rv\^e4ntan\line Vi \^e4r h\^e4r som ett enat folk\line Vi kommer fram till Dig\line Med v\^e5r lovs\^e5ng\line\fs59\line\fs86 Vi ropar Abba Fader\line Du som har all makt\line Vi ropar Abba Fader\line Till Dig st\^e5r allt v\^e5rt hopp\line Vi ropar Abba Fader\line V\^e5r fr\^e4lsare, befriare \^e4r Du\b0\line\pard\tx720\f1\par +\cf2\par +} +", #Align: #Left]] \ No newline at end of file diff --git a/tests/resources/sundayplussongs/Amazing Grace.json b/tests/resources/sundayplussongs/Amazing Grace.json new file mode 100644 index 000000000..a8be7accb --- /dev/null +++ b/tests/resources/sundayplussongs/Amazing Grace.json @@ -0,0 +1,26 @@ +{ + "title": "Amazing Grace", + "authors": [ + "John Newton" + ], + "copyright": "Public Domain", + "cclinumber": "1234", + "verses": [ + [ + "Amazing grace how sweet the sound\nThat saved a wretch like me;\nI once was lost, but now am found,\nWas blind, but now I see.", + "v" + ], + [ + "’Twas grace that taught my heart to fear,\nAnd grace my fears relieved;\nHow precious did that grace appear,\nThe hour I first believed!", + "v" + ], + [ + "Through many dangers, toils and snares\nI have already come;\n’Tis grace hath brought me safe thus far,\nAnd grace will lead me home.", + "v" + ], + [ + "When we’ve been there ten thousand years,\nBright shining as the sun,\nWe’ve no less days to sing God’s praise\nThan when we first begun.", + "v" + ] + ] +} diff --git a/tests/resources/sundayplussongs/Amazing Grace.ptf b/tests/resources/sundayplussongs/Amazing Grace.ptf new file mode 100644 index 000000000..568f2d7f6 --- /dev/null +++ b/tests/resources/sundayplussongs/Amazing Grace.ptf @@ -0,0 +1,43 @@ +[#GLOBAL_RECT: rect(100, 150, 900, 1024), #Opacity: 100, #SHADOW_ON: 1, #SHADOW_COLOR: rgb( 0, 0, 0 ), #SHADOW_OPACITY: 100, #SHADOW_POSITION: "RB", #SHADOW_OFFSET: [4, 4], #FILE_TYPE: "Song", #title: "", #Author: "John Newton", #Copyright: "Public Domain", #CCLI: "1234", #Cell1: [#rtf: "{\rtf1\ansi\deff0 {\fonttbl{\f0\fswiss Arial;}{\f1\fmodern Monotype Corsiva;}{\f2\fswiss MS Serif;}{\f3\fnil Verdana;}}{\colortbl +\red0\green0\blue0;\red0\green0\blue224;\red224\green0\blue0;\red224\green0\blue224;\red102\green102\blue153;\red51\green153\blue102; +\red0\green255\blue0;\red255\green255\blue0;\red248\green248\blue248;}{\stylesheet{\s0\fs24\ql\li0\ri0\fi0\sb0\sa0\sl0 Normal;}{\s2 +\fs24\ql\li0\ri0\fi0\sb0\sa0\sl0 Normal Text;}{\s3\fs24\ql\li0\ri0\fi0\sb0\sa0\sl0 Plain Text;}{\s4\fs130\cf4\ql\li0\ri0\fi0\sb0\sa0 +\sl0 heading 1;}{\s5\fs192\cf5\ql\li0\ri0\fi0\sb0\sa0\sl0 heading 2;}{\s6\fs96\cf4\ql\li0\ri0\fi0\sb0\sa0\sl0 Body Text;}{\s7\b\fs96 +\cf6\ql\li0\ri0\fi0\sb0\sa0\sl0 Author;}{\s8\b\fs40\ql\li0\ri0\fi0\sb0\sa0\sl0 CCLI;}{\s9\b\fs40\ql\li0\ri0\fi0\sb0\sa0\sl0 Copyright;} +{\s10\fs120\cf7\ql\li0\ri0\fi0\sb0\sa0\sl0 Lyrics;}{\s11\b\f1\fs144\ql\li0\ri0\fi0\sb0\sa0\sl0 Title;}{\s12\f2\fs16 02 VERSES;}{\s13 +\f2\fs16 03 CHORUS (itals);}{\s14\f2\fs12 01a ATTRIBUTION (1 fig);}{\s15\f2\fs12 01b ATTRIBUTION (2 fig);}{\s16\f2\fs12 01c ATTRIBUTION (3 fig);} +{\s17\f2\fs12 01d ATTRIBUTION (4 fig);}}\margl1800 \margr1800 \margt1440 \margb1440 \pard \f0\fs24{\pard \s12\b\f3\fs96\cf8\ql\li0 +\ri0\fi0\sb0\sa0\sl0 Amazing grace how sweet the sound\par +That saved a wretch like me;\par +I once was lost, but now am found,\par +Was blind, but now I see.\par +\par +}}", #Align: #left, #MARKER_NAME: "AMAZING GRACE", #Hotkey: "1"], #Cell2: [#rtf: "{\rtf1\ansi\deff0 {\fonttbl{\f0\fswiss Arial;}{\f1\fmodern Monotype Corsiva;}{\f2\fswiss MS Serif;}{\f3\fnil Verdana;}}{\colortbl +\red0\green0\blue0;\red0\green0\blue224;\red224\green0\blue0;\red224\green0\blue224;\red102\green102\blue153;\red51\green153\blue102; +\red0\green255\blue0;\red255\green255\blue0;\red248\green248\blue248;}{\stylesheet{\s0\fs24\ql\li0\ri0\fi0\sb0\sa0\sl0 Normal Text;} +{\s2\fs24\ql\li0\ri0\fi0\sb0\sa0\sl0 Normal;}{\s3\fs24\ql\li0\ri0\fi0\sb0\sa0\sl0 Plain Text;}{\s4\fs130\cf4\ql\li0\ri0\fi0\sb0\sa0 +\sl0 heading 1;}{\s5\fs192\cf5\ql\li0\ri0\fi0\sb0\sa0\sl0 heading 2;}{\s6\fs96\cf4\ql\li0\ri0\fi0\sb0\sa0\sl0 Body Text;}{\s7\b\fs96 +\cf6 Author;}{\s8\b\fs40 CCLI;}{\s9\b\fs40 Copyright;}{\s10\fs120\cf7 Lyrics;}{\s11\b\f1\fs144 Title;}{\s12\f2\fs16 02 VERSES;}}\margl1800 +\margr1800 \margt1440 \margb1440 \pard \f0\fs24{\b\f3\fs96\cf8 \^92Twas grace that taught my heart to fear,\par +And grace my fears relieved;\par +How precious did that grace appear,\par +The hour I first believed!\par +\par +}}", #Align: #left, #MARKER_NAME: "AMAZING GRACE", #Hotkey: "2"], #Cell3: [#rtf: "{\rtf1\ansi\deff0 {\fonttbl{\f0\fswiss Arial;}{\f1\fmodern Monotype Corsiva;}{\f2\fswiss MS Serif;}{\f3\fnil Verdana;}}{\colortbl +\red0\green0\blue0;\red0\green0\blue224;\red224\green0\blue0;\red224\green0\blue224;\red102\green102\blue153;\red51\green153\blue102; +\red0\green255\blue0;\red255\green255\blue0;\red248\green248\blue248;}{\stylesheet{\s0\fs24\ql\li0\ri0\fi0\sb0\sa0\sl0 Normal Text;} +{\s2\fs24\ql\li0\ri0\fi0\sb0\sa0\sl0 Normal;}{\s3\fs24\ql\li0\ri0\fi0\sb0\sa0\sl0 Plain Text;}{\s4\fs130\cf4\ql\li0\ri0\fi0\sb0\sa0 +\sl0 heading 1;}{\s5\fs192\cf5\ql\li0\ri0\fi0\sb0\sa0\sl0 heading 2;}{\s6\fs96\cf4\ql\li0\ri0\fi0\sb0\sa0\sl0 Body Text;}{\s7\b\fs96 +\cf6 Author;}{\s8\b\fs40 CCLI;}{\s9\b\fs40 Copyright;}{\s10\fs120\cf7 Lyrics;}{\s11\b\f1\fs144 Title;}{\s12\f2\fs16 02 VERSES;}}\margl1800 +\margr1800 \margt1440 \margb1440 \pard \f0\fs24{\b\f3\fs96\cf8 Through many dangers, toils and snares\par +I have already come;\par +\^92Tis grace hath brought me safe thus far,\par +And grace will lead me home.\par +\par +}}", #Align: #left, #MARKER_NAME: "AMAZING GRACE", #Hotkey: "3"], #CELL4: [#rtf: "{\rtf1\ansi\deff0 {\fonttbl{\f0\fswiss Arial;}{\f1\fnil Verdana;}}{\colortbl\red0\green0\blue0;\red0\green0\blue224;\red224\green0 +\blue0;\red224\green0\blue224;\red248\green248\blue248;}{\stylesheet{\s0\fs24 Normal Text;}}\margl1800 \margr1800 \margt1440 \margb1440 +\pard \f0\fs24{\b\f1\fs96\cf4 When we\^92ve been there ten thousand years,\par +Bright shining as the sun,\par +We\^92ve no less days to sing God\^92s praise\par +Than when we first begun.\par +}}", #Align: #left, #MARKER_NAME: "AMAZING GRACE", #Hotkey: "4"], #CELL5: [:]] diff --git a/tests/resources/sundayplussongs/abba-fader.json b/tests/resources/sundayplussongs/abba-fader.json new file mode 100644 index 000000000..7172872e5 --- /dev/null +++ b/tests/resources/sundayplussongs/abba-fader.json @@ -0,0 +1,13 @@ +{ + "authors": [ + ["Okänd"] + ], + "title": "Abba Fader", + "verse_order_list": [], + "verses": [ + [ + "Abba Fader\n\nVi är här för att prisa Dig\nVi är här med förväntan\nVi är här som ett enat folk\nVi kommer fram till Dig\nMed vÃ¥r lovsÃ¥ng\n\nVi ropar Abba Fader\nDu som har all makt\nVi ropar Abba Fader\nTill Dig stÃ¥r allt vÃ¥rt hopp\nVi ropar Abba Fader\nVÃ¥r frälsare, befriare är Du", + "v1" + ] + ] +}