From fdc22b4e4cb57e35fefba48f9797951fa8db06cf Mon Sep 17 00:00:00 2001 From: Tomas Groth Date: Fri, 18 Mar 2016 23:09:49 +0100 Subject: [PATCH] Add translations support --- openlp/plugins/songs/lib/importers/opspro.py | 63 ++++++++++++++----- .../openlp_plugins/songs/test_opsproimport.py | 27 ++++++-- .../resources/opsprosongs/amazing grace2.txt | 29 +++++++++ 3 files changed, 101 insertions(+), 18 deletions(-) create mode 100644 tests/resources/opsprosongs/amazing grace2.txt diff --git a/openlp/plugins/songs/lib/importers/opspro.py b/openlp/plugins/songs/lib/importers/opspro.py index 85d58f7c9..69b864116 100644 --- a/openlp/plugins/songs/lib/importers/opspro.py +++ b/openlp/plugins/songs/lib/importers/opspro.py @@ -75,7 +75,6 @@ class OpsProImport(SongImport): 'ORDER BY CategoryName' % song.ID) topics = cursor.fetchall() self.process_song(song, lyrics, topics) - break def process_song(self, song, lyrics, topics): """ @@ -105,21 +104,16 @@ class OpsProImport(SongImport): for topic in topics: self.topics.append(topic.CategoryName) # Try to split lyrics based on various rules - print(song.ID) if lyrics: lyrics_text = lyrics.Lyrics - # Remove whitespaces around the join-tag to keep verses joint - lyrics_text = re.sub('\s*\[join\]\s*', '[join]', lyrics_text, flags=re.IGNORECASE) - lyrics_text = re.sub('\s*\[splits?\]\s*', '[split]', lyrics_text, flags=re.IGNORECASE) verses = re.split('\r\n\s*?\r\n', lyrics_text) verse_tag_defs = {} verse_tag_texts = {} - chorus = '' for verse_text in verses: if verse_text.strip() == '': continue verse_def = 'v' - # Try to detect verse number + # Detect verse number verse_number = re.match('^(\d+)\r\n', verse_text) if verse_number: verse_text = re.sub('^\d+\r\n', '', verse_text) @@ -143,19 +137,60 @@ class OpsProImport(SongImport): if tag in verse_tag_defs: verse_text = verse_tag_texts[tag] verse_def = verse_tag_defs[tag] - # Try to detect end tag + # Detect end tag elif re.match('^\[slot\]\r\n', verse_text, re.IGNORECASE): verse_def = 'e' verse_text = re.sub('^\[slot\]\r\n', '', verse_text, flags=re.IGNORECASE) - # Handle tags # Replace the join tag with line breaks - verse_text = re.sub('\[join\]', '\r\n\r\n', verse_text) + verse_text = re.sub('\[join\]', '', verse_text) # Replace the split tag with line breaks and an optional split - verse_text = re.sub('\[split\]', '\r\n\r\n[---]\r\n', verse_text) + verse_text = re.sub('\[split\]', '\r\n[---]', verse_text) # Handle translations - #if lyrics.IsDualLanguage: - # ... - + if lyrics.IsDualLanguage: + language = None + translation = True + translation_verse_text = '' + start_tag = '{translation}' + end_tag = '{/translation}' + verse_text_lines = verse_text.splitlines() + idx = 0 + while idx < len(verse_text_lines): + # Detect if translation is turned on or off + if verse_text_lines[idx] in ['[trans off]', '[vertaal uit]']: + translation = False + idx += 1 + elif verse_text_lines[idx] in ['[trans on]', '[vertaal aan]']: + translation = True + idx += 1 + elif verse_text_lines[idx] == '[taal a]': + language = 'a' + idx += 1 + elif verse_text_lines[idx] == '[taal b]': + language = 'b' + idx += 1 + # Handle the text based on whether translation is off or on + if language: + translation_verse_text += verse_text_lines[idx] + '\r\n' + idx += 1 + while idx < len(verse_text_lines) and not verse_text_lines[idx].startswith('['): + if language == 'a': + translation_verse_text += verse_text_lines[idx] + '\r\n' + else: + translation_verse_text += start_tag + verse_text_lines[idx] + end_tag + '\r\n' + idx += 1 + language = None + elif translation: + translation_verse_text += verse_text_lines[idx] + '\r\n' + idx += 1 + translation_verse_text += start_tag + verse_text_lines[idx] + end_tag + '\r\n' + idx += 1 + else: + translation_verse_text += verse_text_lines[idx] + '\r\n' + idx += 1 + while idx < len(verse_text_lines) and not verse_text_lines[idx].startswith('['): + translation_verse_text += verse_text_lines[idx] + '\r\n' + idx += 1 + verse_text = translation_verse_text # Remove comments verse_text = re.sub('\(.*?\)\r\n', '', verse_text, flags=re.IGNORECASE) self.add_verse(verse_text, verse_def) diff --git a/tests/functional/openlp_plugins/songs/test_opsproimport.py b/tests/functional/openlp_plugins/songs/test_opsproimport.py index b3501f2bf..e4ce742b7 100644 --- a/tests/functional/openlp_plugins/songs/test_opsproimport.py +++ b/tests/functional/openlp_plugins/songs/test_opsproimport.py @@ -78,7 +78,7 @@ class TestOpsProSongImport(TestCase): mocked_manager = MagicMock() importer = OpsProImport(mocked_manager, filenames=[]) importer.finish = MagicMock() - song, lyrics = self._build_test_data('you are so faithfull.txt') + song, lyrics = self._build_test_data('you are so faithfull.txt', False) # WHEN: An importer object is created importer.process_song(song, lyrics, []) @@ -97,7 +97,26 @@ class TestOpsProSongImport(TestCase): mocked_manager = MagicMock() importer = OpsProImport(mocked_manager, filenames=[]) importer.finish = MagicMock() - song, lyrics = self._build_test_data('amazing grace.txt') + song, lyrics = self._build_test_data('amazing grace.txt', False) + # WHEN: An importer object is created + importer.process_song(song, lyrics, []) + + # THEN: The imported data should look like expected + result_file = open(os.path.join(TEST_PATH, 'Amazing Grace.json'), 'rb') + result_data = json.loads(result_file.read().decode()) + self.assertListEqual(importer.verses, self._get_data(result_data, 'verses')) + self.assertListEqual(importer.verse_order_list_generated, self._get_data(result_data, 'verse_order_list')) + + @patch('openlp.plugins.songs.lib.importers.opspro.SongImport') + def trans_off_tag_test(self, mocked_songimport): + """ + Test importing lyrics with a split and join and translations tags works in OPS Pro + """ + # GIVEN: A mocked out SongImport class, a mocked out "manager" and a mocked song and lyrics entry + mocked_manager = MagicMock() + importer = OpsProImport(mocked_manager, filenames=[]) + importer.finish = MagicMock() + song, lyrics = self._build_test_data('amazing grace2.txt', True) # WHEN: An importer object is created importer.process_song(song, lyrics, []) @@ -112,7 +131,7 @@ class TestOpsProSongImport(TestCase): return data[key] return '' - def _build_test_data(self, test_file): + def _build_test_data(self, test_file, dual_language): song = MagicMock() song.ID = 100 song.SongNumber = 123 @@ -125,5 +144,5 @@ class TestOpsProSongImport(TestCase): test_file = open(os.path.join(TEST_PATH, test_file), 'rb') lyrics.Lyrics = test_file.read().decode() lyrics.Type = 1 - lyrics.IsDualLanguage = True + lyrics.IsDualLanguage = dual_language return song, lyrics diff --git a/tests/resources/opsprosongs/amazing grace2.txt b/tests/resources/opsprosongs/amazing grace2.txt new file mode 100644 index 000000000..1e18a6b62 --- /dev/null +++ b/tests/resources/opsprosongs/amazing grace2.txt @@ -0,0 +1,29 @@ +[trans off] +Amazing 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. +[join] +[trans off] +'Twas grace that taught my heart to fear, +And grace my fears relieved. +How precious did that grace appear, +The hour I first believed. + +[trans off] +The Lord has promised good to me, +His Word my hope secures. +He will my shield and portion be +As long as life endures. + +[trans off] +Thro' many dangers, toils and snares +I have already come. +'Tis grace that brought me safe thus far, +And grace will lead me home. +[trans off] +[split] +When we've been there ten thousand years, +Bright shining as the sun, +We've no less days to sing God's praise, +Than when we first begun.