Fix SongImport

Ignore Case for versetags when importing Songbeamer files

The issue with importing songs was because the SongFormat list was reordered, but the ordering wasn't passed through to get_format_list()
This error should not happen again, added a testcase just to be sure

bzr-revno: 2601
This commit is contained in:
simon.hanna@serve-me.info 2016-01-10 07:23:31 +00:00 committed by Tim Bentley
commit 764eebcda6
4 changed files with 58 additions and 38 deletions

View File

@ -390,7 +390,7 @@ class SongFormat(object):
""" """
Return a list of the supported song formats. Return a list of the supported song formats.
""" """
return [ return sorted([
SongFormat.OpenLyrics, SongFormat.OpenLyrics,
SongFormat.OpenLP2, SongFormat.OpenLP2,
SongFormat.Generic, SongFormat.Generic,
@ -400,6 +400,7 @@ class SongFormat(object):
SongFormat.EasyWorshipDB, SongFormat.EasyWorshipDB,
SongFormat.EasyWorshipService, SongFormat.EasyWorshipService,
SongFormat.FoilPresenter, SongFormat.FoilPresenter,
SongFormat.Lyrix,
SongFormat.MediaShout, SongFormat.MediaShout,
SongFormat.OpenSong, SongFormat.OpenSong,
SongFormat.PowerPraise, SongFormat.PowerPraise,
@ -411,13 +412,12 @@ class SongFormat(object):
SongFormat.SongShowPlus, SongFormat.SongShowPlus,
SongFormat.SongsOfFellowship, SongFormat.SongsOfFellowship,
SongFormat.SundayPlus, SongFormat.SundayPlus,
SongFormat.VideoPsalm,
SongFormat.WordsOfWorship, SongFormat.WordsOfWorship,
SongFormat.WorshipAssistant, SongFormat.WorshipAssistant,
SongFormat.WorshipCenterPro, SongFormat.WorshipCenterPro,
SongFormat.ZionWorx, SongFormat.ZionWorx,
SongFormat.Lyrix, ])
SongFormat.VideoPsalm
]
@staticmethod @staticmethod
def get(song_format, *attributes): def get(song_format, *attributes):

View File

@ -36,28 +36,28 @@ log = logging.getLogger(__name__)
class SongBeamerTypes(object): class SongBeamerTypes(object):
MarkTypes = { MarkTypes = {
'Refrain': VerseType.tags[VerseType.Chorus], 'refrain': VerseType.tags[VerseType.Chorus],
'Chorus': VerseType.tags[VerseType.Chorus], 'chorus': VerseType.tags[VerseType.Chorus],
'Vers': VerseType.tags[VerseType.Verse], 'vers': VerseType.tags[VerseType.Verse],
'Verse': VerseType.tags[VerseType.Verse], 'verse': VerseType.tags[VerseType.Verse],
'Strophe': VerseType.tags[VerseType.Verse], 'strophe': VerseType.tags[VerseType.Verse],
'Intro': VerseType.tags[VerseType.Intro], 'intro': VerseType.tags[VerseType.Intro],
'Coda': VerseType.tags[VerseType.Ending], 'coda': VerseType.tags[VerseType.Ending],
'Ending': VerseType.tags[VerseType.Ending], 'ending': VerseType.tags[VerseType.Ending],
'Bridge': VerseType.tags[VerseType.Bridge], 'bridge': VerseType.tags[VerseType.Bridge],
'Interlude': VerseType.tags[VerseType.Bridge], 'interlude': VerseType.tags[VerseType.Bridge],
'Zwischenspiel': VerseType.tags[VerseType.Bridge], 'zwischenspiel': VerseType.tags[VerseType.Bridge],
'Pre-Chorus': VerseType.tags[VerseType.PreChorus], 'pre-chorus': VerseType.tags[VerseType.PreChorus],
'Pre-Refrain': VerseType.tags[VerseType.PreChorus], 'pre-refrain': VerseType.tags[VerseType.PreChorus],
'Misc': VerseType.tags[VerseType.Other], 'misc': VerseType.tags[VerseType.Other],
'Pre-Bridge': VerseType.tags[VerseType.Other], 'pre-bridge': VerseType.tags[VerseType.Other],
'Pre-Coda': VerseType.tags[VerseType.Other], 'pre-coda': VerseType.tags[VerseType.Other],
'Part': VerseType.tags[VerseType.Other], 'part': VerseType.tags[VerseType.Other],
'Teil': VerseType.tags[VerseType.Other], 'teil': VerseType.tags[VerseType.Other],
'Unbekannt': VerseType.tags[VerseType.Other], 'unbekannt': VerseType.tags[VerseType.Other],
'Unknown': VerseType.tags[VerseType.Other], 'unknown': VerseType.tags[VerseType.Other],
'Unbenannt': VerseType.tags[VerseType.Other], 'unbenannt': VerseType.tags[VerseType.Other],
'$$M=': VerseType.tags[VerseType.Other] '$$m=': VerseType.tags[VerseType.Other]
} }
@ -267,20 +267,20 @@ class SongBeamerImport(SongImport):
def check_verse_marks(self, line): def check_verse_marks(self, line):
""" """
Check and add the verse's MarkType. Returns ``True`` if the given linE contains a correct verse mark otherwise Check and add the verse's MarkType. Returns ``True`` if the given line contains a correct verse mark otherwise
``False``. ``False``.
:param line: The line to check for marks (unicode). :param line: The line to check for marks (unicode).
""" """
marks = line.split(' ') marks = line.split(' ')
if len(marks) <= 2 and marks[0] in SongBeamerTypes.MarkTypes: if len(marks) <= 2 and marks[0].lower() in SongBeamerTypes.MarkTypes:
self.current_verse_type = SongBeamerTypes.MarkTypes[marks[0]] self.current_verse_type = SongBeamerTypes.MarkTypes[marks[0].lower()]
if len(marks) == 2: if len(marks) == 2:
# If we have a digit, we append it to current_verse_type. # If we have a digit, we append it to current_verse_type.
if marks[1].isdigit(): if marks[1].isdigit():
self.current_verse_type += marks[1] self.current_verse_type += marks[1]
return True return True
elif marks[0].startswith('$$M='): # this verse-mark cannot be numbered elif marks[0].lower().startswith('$$m='): # this verse-mark cannot be numbered
self.current_verse_type = SongBeamerTypes.MarkTypes['$$M='] self.current_verse_type = SongBeamerTypes.MarkTypes['$$m=']
return True return True
return False return False

View File

@ -28,7 +28,7 @@ from unittest import TestCase
from tests.helpers.songfileimport import SongImportTestHelper from tests.helpers.songfileimport import SongImportTestHelper
from tests.functional import MagicMock, patch from tests.functional import MagicMock, patch
from openlp.plugins.songs.lib.importers.songbeamer import SongBeamerImport from openlp.plugins.songs.lib.importers.songbeamer import SongBeamerImport, SongBeamerTypes
from openlp.core.common import Registry from openlp.core.common import Registry
TEST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), TEST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__),
@ -131,22 +131,22 @@ class TestSongBeamerImport(TestCase):
self.assertEqual(self.current_verse_type, 'c', '<Refrain> should be interpreted as <c>') self.assertEqual(self.current_verse_type, 'c', '<Refrain> should be interpreted as <c>')
# GIVEN: line with unnumbered verse-type and trailing space # GIVEN: line with unnumbered verse-type and trailing space
line = 'Refrain ' line = 'ReFrain '
self.current_verse_type = None self.current_verse_type = None
# WHEN: line is being checked for verse marks # WHEN: line is being checked for verse marks
result = SongBeamerImport.check_verse_marks(self, line) result = SongBeamerImport.check_verse_marks(self, line)
# THEN: we should get back true and c as self.current_verse_type # THEN: we should get back true and c as self.current_verse_type
self.assertTrue(result, 'Versemark for <Refrain > should be found, value true') self.assertTrue(result, 'Versemark for <ReFrain > should be found, value true')
self.assertEqual(self.current_verse_type, 'c', '<Refrain > should be interpreted as <c>') self.assertEqual(self.current_verse_type, 'c', '<ReFrain > should be interpreted as <c>')
# GIVEN: line with numbered verse-type # GIVEN: line with numbered verse-type
line = 'Verse 1' line = 'VersE 1'
self.current_verse_type = None self.current_verse_type = None
# WHEN: line is being checked for verse marks # WHEN: line is being checked for verse marks
result = SongBeamerImport.check_verse_marks(self, line) result = SongBeamerImport.check_verse_marks(self, line)
# THEN: we should get back true and v1 as self.current_verse_type # THEN: we should get back true and v1 as self.current_verse_type
self.assertTrue(result, 'Versemark for <Verse 1> should be found, value true') self.assertTrue(result, 'Versemark for <VersE 1> should be found, value true')
self.assertEqual(self.current_verse_type, 'v1', u'<Verse 1> should be interpreted as <v1>') self.assertEqual(self.current_verse_type, 'v1', u'<VersE 1> should be interpreted as <v1>')
# GIVEN: line with special unnumbered verse-mark (used in Songbeamer to allow usage of non-supported tags) # GIVEN: line with special unnumbered verse-mark (used in Songbeamer to allow usage of non-supported tags)
line = '$$M=special' line = '$$M=special'
@ -192,3 +192,12 @@ class TestSongBeamerImport(TestCase):
# THEN: we should get back false and none as self.current_verse_type # THEN: we should get back false and none as self.current_verse_type
self.assertFalse(result, 'No versemark for <> should be found, value false') self.assertFalse(result, 'No versemark for <> should be found, value false')
self.assertIsNone(self.current_verse_type, '<> should be interpreted as none versemark') self.assertIsNone(self.current_verse_type, '<> should be interpreted as none versemark')
def test_verse_marks_defined_in_lowercase(self):
"""
Test that the verse marks are all defined in lowercase
"""
# GIVEN: SongBeamber MarkTypes
for tag in SongBeamerTypes.MarkTypes.keys():
# THEN: tag should be defined in lowercase
self.assertEquals(tag, tag.lower(), 'Tags should be defined in lowercase')

View File

@ -81,3 +81,14 @@ class TestSongFormat(TestCase):
# THEN: Return all attributes that were specified # THEN: Return all attributes that were specified
self.assertEquals(len(SongFormat.get(song_format, 'canDisable', 'availability')), 2, self.assertEquals(len(SongFormat.get(song_format, 'canDisable', 'availability')), 2,
"Did not return the correct number of attributes when retrieving multiple attributes at once") "Did not return the correct number of attributes when retrieving multiple attributes at once")
def test_get_format_list_returns_ordered_list(self):
"""
Test that get_format_list() returns a list that is ordered
according to the order specified in SongFormat
"""
# GIVEN: The SongFormat class
# WHEN: Retrieving all formats
# THEN: The returned list should be sorted according to the ordering defined in SongFormat
self.assertEquals(sorted(SongFormat.get_format_list()), SongFormat.get_format_list(),
"The list returned should be sorted according to the ordering in SongFormat")