forked from openlp/openlp
Add translations support
This commit is contained in:
parent
302fcb221b
commit
fdc22b4e4c
@ -75,7 +75,6 @@ class OpsProImport(SongImport):
|
|||||||
'ORDER BY CategoryName' % song.ID)
|
'ORDER BY CategoryName' % song.ID)
|
||||||
topics = cursor.fetchall()
|
topics = cursor.fetchall()
|
||||||
self.process_song(song, lyrics, topics)
|
self.process_song(song, lyrics, topics)
|
||||||
break
|
|
||||||
|
|
||||||
def process_song(self, song, lyrics, topics):
|
def process_song(self, song, lyrics, topics):
|
||||||
"""
|
"""
|
||||||
@ -105,21 +104,16 @@ class OpsProImport(SongImport):
|
|||||||
for topic in topics:
|
for topic in topics:
|
||||||
self.topics.append(topic.CategoryName)
|
self.topics.append(topic.CategoryName)
|
||||||
# Try to split lyrics based on various rules
|
# Try to split lyrics based on various rules
|
||||||
print(song.ID)
|
|
||||||
if lyrics:
|
if lyrics:
|
||||||
lyrics_text = lyrics.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)
|
verses = re.split('\r\n\s*?\r\n', lyrics_text)
|
||||||
verse_tag_defs = {}
|
verse_tag_defs = {}
|
||||||
verse_tag_texts = {}
|
verse_tag_texts = {}
|
||||||
chorus = ''
|
|
||||||
for verse_text in verses:
|
for verse_text in verses:
|
||||||
if verse_text.strip() == '':
|
if verse_text.strip() == '':
|
||||||
continue
|
continue
|
||||||
verse_def = 'v'
|
verse_def = 'v'
|
||||||
# Try to detect verse number
|
# Detect verse number
|
||||||
verse_number = re.match('^(\d+)\r\n', verse_text)
|
verse_number = re.match('^(\d+)\r\n', verse_text)
|
||||||
if verse_number:
|
if verse_number:
|
||||||
verse_text = re.sub('^\d+\r\n', '', verse_text)
|
verse_text = re.sub('^\d+\r\n', '', verse_text)
|
||||||
@ -143,19 +137,60 @@ class OpsProImport(SongImport):
|
|||||||
if tag in verse_tag_defs:
|
if tag in verse_tag_defs:
|
||||||
verse_text = verse_tag_texts[tag]
|
verse_text = verse_tag_texts[tag]
|
||||||
verse_def = verse_tag_defs[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):
|
elif re.match('^\[slot\]\r\n', verse_text, re.IGNORECASE):
|
||||||
verse_def = 'e'
|
verse_def = 'e'
|
||||||
verse_text = re.sub('^\[slot\]\r\n', '', verse_text, flags=re.IGNORECASE)
|
verse_text = re.sub('^\[slot\]\r\n', '', verse_text, flags=re.IGNORECASE)
|
||||||
# Handle tags
|
|
||||||
# Replace the join tag with line breaks
|
# 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
|
# 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
|
# 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
|
# Remove comments
|
||||||
verse_text = re.sub('\(.*?\)\r\n', '', verse_text, flags=re.IGNORECASE)
|
verse_text = re.sub('\(.*?\)\r\n', '', verse_text, flags=re.IGNORECASE)
|
||||||
self.add_verse(verse_text, verse_def)
|
self.add_verse(verse_text, verse_def)
|
||||||
|
@ -78,7 +78,7 @@ class TestOpsProSongImport(TestCase):
|
|||||||
mocked_manager = MagicMock()
|
mocked_manager = MagicMock()
|
||||||
importer = OpsProImport(mocked_manager, filenames=[])
|
importer = OpsProImport(mocked_manager, filenames=[])
|
||||||
importer.finish = MagicMock()
|
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
|
# WHEN: An importer object is created
|
||||||
importer.process_song(song, lyrics, [])
|
importer.process_song(song, lyrics, [])
|
||||||
|
|
||||||
@ -97,7 +97,26 @@ class TestOpsProSongImport(TestCase):
|
|||||||
mocked_manager = MagicMock()
|
mocked_manager = MagicMock()
|
||||||
importer = OpsProImport(mocked_manager, filenames=[])
|
importer = OpsProImport(mocked_manager, filenames=[])
|
||||||
importer.finish = MagicMock()
|
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
|
# WHEN: An importer object is created
|
||||||
importer.process_song(song, lyrics, [])
|
importer.process_song(song, lyrics, [])
|
||||||
|
|
||||||
@ -112,7 +131,7 @@ class TestOpsProSongImport(TestCase):
|
|||||||
return data[key]
|
return data[key]
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def _build_test_data(self, test_file):
|
def _build_test_data(self, test_file, dual_language):
|
||||||
song = MagicMock()
|
song = MagicMock()
|
||||||
song.ID = 100
|
song.ID = 100
|
||||||
song.SongNumber = 123
|
song.SongNumber = 123
|
||||||
@ -125,5 +144,5 @@ class TestOpsProSongImport(TestCase):
|
|||||||
test_file = open(os.path.join(TEST_PATH, test_file), 'rb')
|
test_file = open(os.path.join(TEST_PATH, test_file), 'rb')
|
||||||
lyrics.Lyrics = test_file.read().decode()
|
lyrics.Lyrics = test_file.read().decode()
|
||||||
lyrics.Type = 1
|
lyrics.Type = 1
|
||||||
lyrics.IsDualLanguage = True
|
lyrics.IsDualLanguage = dual_language
|
||||||
return song, lyrics
|
return song, lyrics
|
||||||
|
29
tests/resources/opsprosongs/amazing grace2.txt
Normal file
29
tests/resources/opsprosongs/amazing grace2.txt
Normal file
@ -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.
|
Loading…
Reference in New Issue
Block a user