diff --git a/openlp/plugins/songs/lib/importers/chordpro.py b/openlp/plugins/songs/lib/importers/chordpro.py index e3c1a37b9..49c3d9f4f 100644 --- a/openlp/plugins/songs/lib/importers/chordpro.py +++ b/openlp/plugins/songs/lib/importers/chordpro.py @@ -24,26 +24,22 @@ The :mod:`chordpro` module provides the functionality for importing ChordPro files into the current database. """ -import os -import re +import logging -from openlp.core.common import translate -from openlp.core.ui.lib.wizard import WizardStrings from .songimport import SongImport log = logging.getLogger(__name__) -# This importer is based on the information available on these webpages: -# http://webchord.sourceforge.net/tech.html -# http://www.vromans.org/johan/projects/Chordii/chordpro/ -# http://www.tenbyten.com/software/songsgen/help/HtmlHelp/files_reference.htm -# http://linkesoft.com/songbook/chordproformat.html - class ChordProImport(SongImport): """ The :class:`ChordProImport` class provides OpenLP with the ability to import ChordPro files. + This importer is based on the information available on these webpages: + http://webchord.sourceforge.net/tech.html + http://www.vromans.org/johan/projects/Chordii/chordpro/ + http://www.tenbyten.com/software/songsgen/help/HtmlHelp/files_reference.htm + http://linkesoft.com/songbook/chordproformat.html """ def do_import(self): self.import_wizard.progress_bar.setMaximum(len(self.import_source)) @@ -80,7 +76,7 @@ class ChordProImport(SongImport): if tag_value.lower().startswith('chorus'): if current_verse.strip(): # Add collected verse to the lyrics - self.add_verse(current_verse.strip(), current_verse_type) + self.add_verse(current_verse.rstrip(), current_verse_type) current_verse_type = 'v' current_verse = '' self.repeat_verse('c1') @@ -90,13 +86,13 @@ class ChordProImport(SongImport): current_verse_type = 'c' elif tag_name in ['end_of_chorus', 'eoc']: # Add collected chorus to the lyrics - self.add_verse(current_verse, current_verse_type) + self.add_verse(current_verse.rstrip(), current_verse_type) current_verse_type = 'v' current_verse = '' elif tag_name in ['start_of_tab', 'sot']: if current_verse.strip(): # Add collected verse to the lyrics - self.add_verse(current_verse.strip(), current_verse_type) + self.add_verse(current_verse.rstrip(), current_verse_type) current_verse_type = 'v' current_verse = '' skip_block = True @@ -106,7 +102,7 @@ class ChordProImport(SongImport): # A new song starts below this tag if self.verses and self.title: if current_verse.strip(): - self.add_verse(current_verse.strip(), current_verse_type) + self.add_verse(current_verse.rstrip(), current_verse_type) if not self.finish(): self.log_error(song_file.name) self.set_defaults() @@ -126,13 +122,16 @@ class ChordProImport(SongImport): continue elif line == '' and current_verse.strip() and current_verse_type != 'c': # Add collected verse to the lyrics - self.add_verse(current_verse.strip(), current_verse_type) + self.add_verse(current_verse.rstrip(), current_verse_type) current_verse_type = 'v' current_verse = '' else: - current_verse += line + '\n' + if current_verse.strip() == '': + current_verse = line + '\n' + else: + current_verse += line + '\n' if current_verse.strip(): - self.add_verse(current_verse.strip(), current_verse_type) + self.add_verse(current_verse.rstrip(), current_verse_type) if not self.finish(): self.log_error(song_file.name) diff --git a/tests/functional/openlp_plugins/songs/test_chordproimport.py b/tests/functional/openlp_plugins/songs/test_chordproimport.py new file mode 100644 index 000000000..11461e387 --- /dev/null +++ b/tests/functional/openlp_plugins/songs/test_chordproimport.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# 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 OpenSong song importer. +""" +import os + +from tests.helpers.songfileimport import SongImportTestHelper +from tests.functional import patch, MagicMock + +TEST_PATH = os.path.abspath( + os.path.join(os.path.dirname(__file__), '..', '..', '..', 'resources', 'chordprosongs')) + + +class TestChordProFileImport(SongImportTestHelper): + + def __init__(self, *args, **kwargs): + self.importer_class_name = 'ChordProImport' + self.importer_module_name = 'chordpro' + super(TestChordProFileImport, self).__init__(*args, **kwargs) + + @patch('openlp.plugins.songs.lib.importers.opensong.Settings') + def test_song_import(self, mocked_settings): + """ + Test that loading an ChordPro file works correctly on various files + """ + # Mock out the settings - always return False + mocked_returned_settings = MagicMock() + mocked_returned_settings.value.return_value = False + mocked_settings.return_value = mocked_returned_settings + # Do the test import + self.file_import([os.path.join(TEST_PATH, 'swing-low.chordpro')], + self.load_external_result_data(os.path.join(TEST_PATH, 'swing-low.json'))) diff --git a/tests/resources/chordprosongs/swing-low.chordpro b/tests/resources/chordprosongs/swing-low.chordpro new file mode 100644 index 000000000..cd4569c64 --- /dev/null +++ b/tests/resources/chordprosongs/swing-low.chordpro @@ -0,0 +1,29 @@ +{title:Swing Low Sweet Chariot} +{st:Traditional} + +{start_of_chorus} +Swing [D]low, sweet [G]chari[D]ot, +Comin' for to carry me [A7]home. +Swing [D7]low, sweet [G]chari[D]ot, +Comin' for to [A7]carry me [D]home. +{end_of_chorus} + +I looked over Jordan, and what did I see, + Comin' for to carry me home. +A band of angels comin' after me, + Comin' for to carry me home. + +{c:Chorus} + +If you get there before I do, + Comin' for to carry me home. +Just tell my friends that I'm a comin' too. + Comin' for to carry me home. + +{c:Chorus} + +I'm sometimes up and sometimes down, + Comin' for to carry me home. +But still my soul feels heavenly bound. + Comin' for to carry me home. +{c:Chorus} diff --git a/tests/resources/chordprosongs/swing-low.json b/tests/resources/chordprosongs/swing-low.json new file mode 100644 index 000000000..271d1680f --- /dev/null +++ b/tests/resources/chordprosongs/swing-low.json @@ -0,0 +1,22 @@ +{ + "title": "Swing Low Sweet Chariot", + "alternative_title": "Traditional", + "verses": [ + [ + "Swing [D]low, sweet [G]chari[D]ot,\nComin' for to carry me [A7]home.\nSwing [D7]low, sweet [G]chari[D]ot,\nComin' for to [A7]carry me [D]home.", + "c" + ], + [ + "I looked over Jordan, and what did I see,\n Comin' for to carry me home.\nA band of angels comin' after me,\n Comin' for to carry me home.", + "v" + ], + [ + "If you get there before I do,\n Comin' for to carry me home.\nJust tell my friends that I'm a comin' too.\n Comin' for to carry me home.", + "v" + ], + [ + "I'm sometimes up and sometimes down,\n Comin' for to carry me home.\nBut still my soul feels heavenly bound.\n Comin' for to carry me home.", + "v" + ] + ] +}