From 285508fd2d1b968df936f6df9dc4546d25666a7e Mon Sep 17 00:00:00 2001 From: "s.mehrbrodt@gmail.com" Date: Thu, 26 Sep 2013 17:05:10 +0200 Subject: [PATCH 1/8] Fix Import for SongBeamer files --- openlp/plugins/songs/lib/songbeamerimport.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/openlp/plugins/songs/lib/songbeamerimport.py b/openlp/plugins/songs/lib/songbeamerimport.py index f00e98e63..813e5fea4 100644 --- a/openlp/plugins/songs/lib/songbeamerimport.py +++ b/openlp/plugins/songs/lib/songbeamerimport.py @@ -33,6 +33,7 @@ import chardet import codecs import logging import os +import io import re from openlp.plugins.songs.lib import VerseType @@ -105,7 +106,7 @@ class SongBeamerImport(SongImport): self.import_wizard.progress_bar.setMaximum(len(self.import_source)) if not isinstance(self.import_source, list): return - for file in self.import_source: + for _file in self.import_source: # TODO: check that it is a valid SongBeamer file if self.stop_import_flag: return @@ -113,12 +114,9 @@ class SongBeamerImport(SongImport): self.currentVerse = '' self.currentVerseType = VerseType.tags[VerseType.Verse] read_verses = False - file_name = os.path.split(file)[1] - if os.path.isfile(file): - detect_file = open(file, 'r') - details = chardet.detect(detect_file.read()) - detect_file.close() - infile = codecs.open(file, 'r', details['encoding']) + file_name = os.path.split(_file)[1] + if os.path.isfile(_file): + infile = io.open(_file, 'r', encoding="Latin-1") song_data = infile.readlines() infile.close() else: @@ -149,7 +147,7 @@ class SongBeamerImport(SongImport): self.replaceHtmlTags() self.addVerse(self.currentVerse, self.currentVerseType) if not self.finish(): - self.logError(file) + self.logError(_file) def replaceHtmlTags(self): """ From 9dbb2e12b05d541994738110492932685594f484 Mon Sep 17 00:00:00 2001 From: "s.mehrbrodt@gmail.com" Date: Thu, 26 Sep 2013 17:08:27 +0200 Subject: [PATCH 2/8] Remove now unused imports --- openlp/plugins/songs/lib/songbeamerimport.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/openlp/plugins/songs/lib/songbeamerimport.py b/openlp/plugins/songs/lib/songbeamerimport.py index 813e5fea4..ab570ba8b 100644 --- a/openlp/plugins/songs/lib/songbeamerimport.py +++ b/openlp/plugins/songs/lib/songbeamerimport.py @@ -29,8 +29,6 @@ """ The :mod:`songbeamerimport` module provides the functionality for importing SongBeamer songs into the OpenLP database. """ -import chardet -import codecs import logging import os import io From c78a2a110329d28ae457d1a17f96e996f9f8c3f4 Mon Sep 17 00:00:00 2001 From: "s.mehrbrodt@gmail.com" Date: Thu, 26 Sep 2013 18:18:04 +0200 Subject: [PATCH 3/8] Open Songbeamer Files in binary mode to detect the encoding --- openlp/plugins/songs/lib/songbeamerimport.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/openlp/plugins/songs/lib/songbeamerimport.py b/openlp/plugins/songs/lib/songbeamerimport.py index ab570ba8b..b085b9463 100644 --- a/openlp/plugins/songs/lib/songbeamerimport.py +++ b/openlp/plugins/songs/lib/songbeamerimport.py @@ -29,9 +29,10 @@ """ The :mod:`songbeamerimport` module provides the functionality for importing SongBeamer songs into the OpenLP database. """ +import chardet +import codecs import logging import os -import io import re from openlp.plugins.songs.lib import VerseType @@ -114,7 +115,11 @@ class SongBeamerImport(SongImport): read_verses = False file_name = os.path.split(_file)[1] if os.path.isfile(_file): - infile = io.open(_file, 'r', encoding="Latin-1") + # First open in binary mode to detect the encoding + detect_file = open(_file, 'rb') + details = chardet.detect(detect_file.read()) + detect_file.close() + infile = codecs.open(_file, 'r', details['encoding']) song_data = infile.readlines() infile.close() else: From fb6336484b71c5431b9cfa829124235240406fe6 Mon Sep 17 00:00:00 2001 From: "s.mehrbrodt@gmail.com" Date: Sat, 28 Sep 2013 22:24:05 +0200 Subject: [PATCH 4/8] Rename variable --- openlp/plugins/songs/lib/songbeamerimport.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/openlp/plugins/songs/lib/songbeamerimport.py b/openlp/plugins/songs/lib/songbeamerimport.py index b085b9463..3d376e092 100644 --- a/openlp/plugins/songs/lib/songbeamerimport.py +++ b/openlp/plugins/songs/lib/songbeamerimport.py @@ -105,7 +105,7 @@ class SongBeamerImport(SongImport): self.import_wizard.progress_bar.setMaximum(len(self.import_source)) if not isinstance(self.import_source, list): return - for _file in self.import_source: + for import_file in self.import_source: # TODO: check that it is a valid SongBeamer file if self.stop_import_flag: return @@ -113,13 +113,13 @@ class SongBeamerImport(SongImport): self.currentVerse = '' self.currentVerseType = VerseType.tags[VerseType.Verse] read_verses = False - file_name = os.path.split(_file)[1] - if os.path.isfile(_file): + file_name = os.path.split(import_file)[1] + if os.path.isfile(import_file): # First open in binary mode to detect the encoding - detect_file = open(_file, 'rb') + detect_file = open(import_file, 'rb') details = chardet.detect(detect_file.read()) detect_file.close() - infile = codecs.open(_file, 'r', details['encoding']) + infile = codecs.open(import_file, 'r', details['encoding']) song_data = infile.readlines() infile.close() else: @@ -150,7 +150,7 @@ class SongBeamerImport(SongImport): self.replaceHtmlTags() self.addVerse(self.currentVerse, self.currentVerseType) if not self.finish(): - self.logError(_file) + self.logError(import_file) def replaceHtmlTags(self): """ From c471fc79ba3b83eb65905a101f04c3b179044653 Mon Sep 17 00:00:00 2001 From: "s.mehrbrodt@gmail.com02" Date: Mon, 7 Oct 2013 00:07:49 +0200 Subject: [PATCH 5/8] Add Songbeamer Import test --- openlp/plugins/songs/lib/songbeamerimport.py | 2 +- .../songs/test_songbeamerimport.py | 127 ++++++++++++++++++ .../songbeamersongs/Lobsinget dem Herrn.sng | 25 ++++ 3 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 tests/functional/openlp_plugins/songs/test_songbeamerimport.py create mode 100644 tests/resources/songbeamersongs/Lobsinget dem Herrn.sng diff --git a/openlp/plugins/songs/lib/songbeamerimport.py b/openlp/plugins/songs/lib/songbeamerimport.py index 3d376e092..79e6f6263 100644 --- a/openlp/plugins/songs/lib/songbeamerimport.py +++ b/openlp/plugins/songs/lib/songbeamerimport.py @@ -102,9 +102,9 @@ class SongBeamerImport(SongImport): """ Receive a single file or a list of files to import. """ - self.import_wizard.progress_bar.setMaximum(len(self.import_source)) if not isinstance(self.import_source, list): return + self.import_wizard.progress_bar.setMaximum(len(self.import_source)) for import_file in self.import_source: # TODO: check that it is a valid SongBeamer file if self.stop_import_flag: diff --git a/tests/functional/openlp_plugins/songs/test_songbeamerimport.py b/tests/functional/openlp_plugins/songs/test_songbeamerimport.py new file mode 100644 index 000000000..e6b1c4570 --- /dev/null +++ b/tests/functional/openlp_plugins/songs/test_songbeamerimport.py @@ -0,0 +1,127 @@ +""" +This module contains tests for the Songbeamer song importer. +""" + +import os +from unittest import TestCase +from mock import patch, MagicMock + +from openlp.plugins.songs.lib.songbeamerimport import SongBeamerImport + +TEST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../resources/songbeamersongs')) +SONG_TEST_DATA = {'Lobsinget dem Herrn.sng': + {'title': 'GL 1 - Lobsinget dem Herrn', + 'verses': + [('1. Lobsinget dem Herrn,\no preiset Ihn gern!\n' + 'Anbetung und Lob Ihm gebühret.\n', 'v'), + ('2. Lobsingt Seiner Lieb´,\ndie einzig ihn trieb,\n' + 'zu sterben für unsere Sünden!\n', 'v'), + ('3. Lobsingt Seiner Macht!\nSein Werk ist vollbracht:\n' + 'Er sitzet zur Rechten des Vaters.\n', 'v'), + ('4. Lobsingt seiner Treu´,\ndie immerdar neu,\n' + 'bis Er uns zur Herrlichket führet!\n\n', 'v')], + 'song_book_name': 'Glaubenslieder I', + 'song_number': "1"} + } + + +class TestSongBeamerImport(TestCase): + """ + Test the functions in the :mod:`songbeamerimport` module. + """ + def create_importer_test(self): + """ + Test creating an instance of the SongBeamer file importer + """ + # GIVEN: A mocked out SongImport class, and a mocked out "manager" + with patch('openlp.plugins.songs.lib.songbeamerimport.SongImport'): + mocked_manager = MagicMock() + + # WHEN: An importer object is created + importer = SongBeamerImport(mocked_manager) + + # THEN: The importer object should not be None + self.assertIsNotNone(importer, 'Import should not be none') + + def invalid_import_source_test(self): + """ + Test SongBeamerImport.doImport handles different invalid import_source values + """ + # GIVEN: A mocked out SongImport class, and a mocked out "manager" + with patch('openlp.plugins.songs.lib.songbeamerimport.SongImport'): + mocked_manager = MagicMock() + mocked_import_wizard = MagicMock() + importer = SongBeamerImport(mocked_manager) + importer.import_wizard = mocked_import_wizard + importer.stop_import_flag = True + + # WHEN: Import source is not a list + for source in ['not a list', 0]: + importer.import_source = source + + # THEN: doImport should return none and the progress bar maximum should not be set. + self.assertIsNone(importer.doImport(), 'doImport should return None when import_source is not a list') + self.assertEquals(mocked_import_wizard.progress_bar.setMaximum.called, False, + 'setMaxium on import_wizard.progress_bar should not have been called') + + def valid_import_source_test(self): + """ + Test SongBeamerImport.doImport handles different invalid import_source values + """ + # GIVEN: A mocked out SongImport class, and a mocked out "manager" + with patch('openlp.plugins.songs.lib.songbeamerimport.SongImport'): + mocked_manager = MagicMock() + mocked_import_wizard = MagicMock() + importer = SongBeamerImport(mocked_manager) + importer.import_wizard = mocked_import_wizard + importer.stop_import_flag = True + + # WHEN: Import source is a list + importer.import_source = ['List', 'of', 'files'] + + # THEN: doImport should return none and the progress bar setMaximum should be called with the length of + # import_source. + self.assertIsNone(importer.doImport(), + 'doImport should return None when import_source is a list and stop_import_flag is True') + mocked_import_wizard.progress_bar.setMaximum.assert_called_with(len(importer.import_source)) + + def file_import_test(self): + """ + Test the actual import of real song files and check that the imported data is correct. + """ + + # GIVEN: Test files with a mocked out SongImport class, a mocked out "manager", a mocked out "import_wizard", + # and mocked out "author", "add_copyright", "add_verse", "finish" methods. + with patch('openlp.plugins.songs.lib.songbeamerimport.SongImport'): + for song_file in SONG_TEST_DATA: + mocked_manager = MagicMock() + mocked_import_wizard = MagicMock() + mocked_add_verse = MagicMock() + mocked_finish = MagicMock() + mocked_finish.return_value = True + importer = SongBeamerImport(mocked_manager) + importer.import_wizard = mocked_import_wizard + importer.stop_import_flag = False + importer.addVerse = mocked_add_verse + importer.finish = mocked_finish + + # WHEN: Importing each file + importer.import_source = [os.path.join(TEST_PATH, song_file)] + title = SONG_TEST_DATA[song_file]['title'] + add_verse_calls = SONG_TEST_DATA[song_file]['verses'] + song_book_name = SONG_TEST_DATA[song_file]['song_book_name'] + song_number = SONG_TEST_DATA[song_file]['song_number'] + + # THEN: doImport should return none, the song data should be as expected, and finish should have been + # called. + self.assertIsNone(importer.doImport(), 'doImport should return None when it has completed') + self.assertEquals(importer.title, title, 'title for %s should be "%s"' % (song_file, title)) + for verse_text, verse_tag in add_verse_calls: + mocked_add_verse.assert_any_call(verse_text, verse_tag) + if song_book_name: + self.assertEquals(importer.songBookName, song_book_name, 'songBookName for %s should be "%s"' + % (song_file, song_book_name)) + if song_number: + self.assertEquals(importer.songNumber, song_number, 'songNumber for %s should be %s' + % (song_file, song_number)) + mocked_finish.assert_called_with() diff --git a/tests/resources/songbeamersongs/Lobsinget dem Herrn.sng b/tests/resources/songbeamersongs/Lobsinget dem Herrn.sng new file mode 100644 index 000000000..fbc9aa9fc --- /dev/null +++ b/tests/resources/songbeamersongs/Lobsinget dem Herrn.sng @@ -0,0 +1,25 @@ +#LangCount=1 +#Title=GL 1 - Lobsinget dem Herrn +#Editor=SongBeamer 4.20 +#Version=3 +#Format=F/K// +#TitleFormat=U +#ChurchSongID=0001 +#Songbook=Glaubenslieder I / 1 +--- +1. Lobsinget dem Herrn, +o preiset Ihn gern! +Anbetung und Lob Ihm gebühret. + --- +2. Lobsingt Seiner Lieb´, +die einzig ihn trieb, +zu sterben für unsere Sünden! + --- +3. Lobsingt Seiner Macht! +Sein Werk ist vollbracht: +Er sitzet zur Rechten des Vaters. + --- +4. Lobsingt seiner Treu´, +die immerdar neu, +bis Er uns zur Herrlichket führet! + From 24dba5264017ed541de15d9c957024a40599c449 Mon Sep 17 00:00:00 2001 From: Samuel Mehrbrodt Date: Tue, 22 Oct 2013 17:09:10 +0200 Subject: [PATCH 6/8] Fix Import, use system-independent path --- .../songs/test_songbeamerimport.py | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/tests/functional/openlp_plugins/songs/test_songbeamerimport.py b/tests/functional/openlp_plugins/songs/test_songbeamerimport.py index e6b1c4570..b6c5b2f1b 100644 --- a/tests/functional/openlp_plugins/songs/test_songbeamerimport.py +++ b/tests/functional/openlp_plugins/songs/test_songbeamerimport.py @@ -1,14 +1,44 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 + +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2008-2013 Raoul Snyman # +# Portions copyright (c) 2008-2013 Tim Bentley, Gerald Britton, Jonathan # +# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, # +# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. # +# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, # +# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # +# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, # +# Frode Woldsund, Martin Zibricky, Patrick Zimmermann # +# --------------------------------------------------------------------------- # +# 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 Songbeamer song importer. """ import os from unittest import TestCase -from mock import patch, MagicMock +from tests.functional import MagicMock, patch from openlp.plugins.songs.lib.songbeamerimport import SongBeamerImport -TEST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../resources/songbeamersongs')) +TEST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), + '..', '..', '..', 'resources', 'songbeamersongs')) SONG_TEST_DATA = {'Lobsinget dem Herrn.sng': {'title': 'GL 1 - Lobsinget dem Herrn', 'verses': From 636dead5c3fd16ed5848727edc8390944d68066f Mon Sep 17 00:00:00 2001 From: Samuel Mehrbrodt Date: Sat, 26 Oct 2013 19:25:07 +0200 Subject: [PATCH 7/8] Fix vim header (textwidth=120) --- copyright.txt | 2 +- tests/functional/openlp_plugins/songs/test_songbeamerimport.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/copyright.txt b/copyright.txt index f56b7712d..64d028205 100644 --- a/copyright.txt +++ b/copyright.txt @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 +# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4 ############################################################################### # OpenLP - Open Source Lyrics Projection # diff --git a/tests/functional/openlp_plugins/songs/test_songbeamerimport.py b/tests/functional/openlp_plugins/songs/test_songbeamerimport.py index b6c5b2f1b..7fbb0a101 100644 --- a/tests/functional/openlp_plugins/songs/test_songbeamerimport.py +++ b/tests/functional/openlp_plugins/songs/test_songbeamerimport.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 +# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4 ############################################################################### # OpenLP - Open Source Lyrics Projection # @@ -26,7 +26,6 @@ # 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 Songbeamer song importer. """ From f74697a987106128d0e5cd8332ce745c8b93efdd Mon Sep 17 00:00:00 2001 From: Samuel Mehrbrodt Date: Sat, 26 Oct 2013 19:31:35 +0200 Subject: [PATCH 8/8] Try to fix encoding... --- tests/functional/openlp_plugins/songs/test_songbeamerimport.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/functional/openlp_plugins/songs/test_songbeamerimport.py b/tests/functional/openlp_plugins/songs/test_songbeamerimport.py index 7fbb0a101..37d4a1223 100644 --- a/tests/functional/openlp_plugins/songs/test_songbeamerimport.py +++ b/tests/functional/openlp_plugins/songs/test_songbeamerimport.py @@ -53,7 +53,6 @@ SONG_TEST_DATA = {'Lobsinget dem Herrn.sng': 'song_number': "1"} } - class TestSongBeamerImport(TestCase): """ Test the functions in the :mod:`songbeamerimport` module.