From f92afc296b862efe040f656c525cc9709680e9b8 Mon Sep 17 00:00:00 2001 From: Samuel Mehrbrodt Date: Wed, 25 Jun 2014 14:23:31 +0200 Subject: [PATCH 01/11] First go at an importer for Worship Assistant --- openlp/plugins/songs/lib/importer.py | 31 ++-- .../songs/lib/worshipassistantimport.py | 144 ++++++++++++++++++ 2 files changed, 166 insertions(+), 9 deletions(-) create mode 100644 openlp/plugins/songs/lib/worshipassistantimport.py diff --git a/openlp/plugins/songs/lib/importer.py b/openlp/plugins/songs/lib/importer.py index 7ce637285..6d01da309 100644 --- a/openlp/plugins/songs/lib/importer.py +++ b/openlp/plugins/songs/lib/importer.py @@ -50,6 +50,7 @@ from .sundayplusimport import SundayPlusImport from .foilpresenterimport import FoilPresenterImport from .zionworximport import ZionWorxImport from .propresenterimport import ProPresenterImport +from .worshipassistantimport import WorshipAssistantImport # Imports that might fail @@ -167,8 +168,9 @@ class SongFormat(object): SongsOfFellowship = 16 SundayPlus = 17 WordsOfWorship = 18 - WorshipCenterPro = 19 - ZionWorx = 20 + WorshipAssistant = 19 + WorshipCenterPro = 20 + ZionWorx = 21 # Set optional attribute defaults __defaults__ = { @@ -321,6 +323,16 @@ class SongFormat(object): 'prefix': 'wordsOfWorship', 'filter': '%s (*.wsg *.wow-song)' % translate('SongsPlugin.ImportWizardForm', 'Words Of Worship Song Files') }, + WorshipAssistant: { + 'class': WorshipAssistantImport, + 'name': 'Worship Assistant 0', + 'prefix': 'worshipAssistant', + 'selectMode': SongFormatSelect.SingleFile, + 'filter': '%s (*.csv)' % translate('SongsPlugin.ImportWizardForm', 'Worship Assistant Files'), + 'comboBoxText': translate('SongsPlugin.ImportWizardForm', 'Worship Assistant (CSV)'), + 'descriptionText': translate('SongsPlugin.ImportWizardForm', + 'In Worship Assistant, export your Database to a CSV file.') + }, WorshipCenterPro: { 'name': 'WorshipCenter Pro', 'prefix': 'worshipCenterPro', @@ -370,16 +382,17 @@ class SongFormat(object): SongFormat.SongsOfFellowship, SongFormat.SundayPlus, SongFormat.WordsOfWorship, + SongFormat.WorshipAssistant, SongFormat.WorshipCenterPro, SongFormat.ZionWorx ] @staticmethod - def get(format, *attributes): + def get(song_format, *attributes): """ Return requested song format attribute(s). - :param format: A song format from SongFormat. + :param song_format: A song format from SongFormat. :param attributes: Zero or more song format attributes from SongFormat. Return type depends on number of supplied attributes: @@ -389,23 +402,23 @@ class SongFormat(object): :>1: Return tuple of requested attribute values. """ if not attributes: - return SongFormat.__attributes__.get(format) + return SongFormat.__attributes__.get(song_format) elif len(attributes) == 1: default = SongFormat.__defaults__.get(attributes[0]) - return SongFormat.__attributes__[format].get(attributes[0], default) + return SongFormat.__attributes__[song_format].get(attributes[0], default) else: values = [] for attr in attributes: default = SongFormat.__defaults__.get(attr) - values.append(SongFormat.__attributes__[format].get(attr, default)) + values.append(SongFormat.__attributes__[song_format].get(attr, default)) return tuple(values) @staticmethod - def set(format, attribute, value): + def set(song_format, attribute, value): """ Set specified song format attribute to the supplied value. """ - SongFormat.__attributes__[format][attribute] = value + SongFormat.__attributes__[song_format][attribute] = value SongFormat.set(SongFormat.SongsOfFellowship, 'availability', HAS_SOF) diff --git a/openlp/plugins/songs/lib/worshipassistantimport.py b/openlp/plugins/songs/lib/worshipassistantimport.py new file mode 100644 index 000000000..683ec6456 --- /dev/null +++ b/openlp/plugins/songs/lib/worshipassistantimport.py @@ -0,0 +1,144 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4 + +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2008-2014 Raoul Snyman # +# Portions copyright (c) 2008-2014 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 # +############################################################################### +""" +The :mod:`worshipassistantimport` module provides the functionality for importing +Worship Assistant songs into the OpenLP database. +""" +import csv +import logging + +from openlp.core.common import translate +from openlp.plugins.songs.lib.songimport import SongImport + +log = logging.getLogger(__name__) + +# Used to strip control chars (except 10=LF, 13=CR) +CONTROL_CHARS_MAP = dict.fromkeys(list(range(10)) + [11, 12] + list(range(14, 32)) + [127]) + + +class WorshipAssistantImport(SongImport): + """ + The :class:`WorshipAssistantImport` class provides the ability to import songs + from Worship Assistant, via a dump of the database to a CSV file. + + The following fields are in the exported CSV file: + + * ``SONGNR`` Song ID (Discarded by importer) + * ``TITLE`` Song title + * ``AUTHOR`` Song author. May containt multiple authors. + * ``COPYRIGHT`` Copyright information + * ``FIRSTLINE`` Unknown (Discarded by importer) + * ``PRIKEY`` Primary chord key + * ``ALTKEY`` Alternate chord key + * ``TEMPO`` Tempo + * ``FOCUS`` Unknown (Discarded by importer) + * ``THEME`` Theme (Discarded by importer) + * ``SCRIPTURE`` Associated scripture (Discarded by importer) + * ``ACTIVE`` Boolean value (Discarded by importer) + * ``SONGBOOK`` Boolean value (Discarded by importer) + * ``TIMESIG`` Unknown (Discarded by importer) + * ``INTRODUCED`` Date the song was created (Discarded by importer) + * ``LASTUSED`` Date the song was last used (Discarded by importer) + * ``TIMESUSED`` How many times the song was used (Discarded by importer) + * ``TIMESUSED`` How many times the song was used (Discarded by importer) + * ``CCLINR`` CCLI Number + * ``USER1`` User Field 1 (Discarded by importer) + * ``USER2`` User Field 2 (Discarded by importer) + * ``USER3`` User Field 3 (Discarded by importer) + * ``USER4`` User Field 4 (Discarded by importer) + * ``USER5`` User Field 5 (Discarded by importer) + * ``ROADMAP`` Verse order + * ``FILELINK1`` Associated file 1 (Discarded by importer) + * ``OVERMAP`` Unknown (Discarded by importer) + * ``FILELINK2`` Associated file 2 (Discarded by importer) + * ``LYRICS`` The song lyrics as plain text (Discarded by importer) + * ``INFO`` Unknown (Discarded by importer) + * ``LYRICS2`` The song lyrics with verse numbers + * ``BACKGROUND`` Unknown (Discarded by importer) + """ + def do_import(self): + """ + Receive a CSV file to import. + """ + with open(self.import_source, 'r', encoding='latin-1') as songs_file: + field_names = ['SongNum', 'Title1', 'Title2', 'Lyrics', 'Writer', 'Copyright', 'Keywords', + 'DefaultStyle'] + songs_reader = csv.DictReader(songs_file)#, field_names) + try: + records = list(songs_reader) + except csv.Error as e: + self.log_error(translate('SongsPlugin.WorshipAssistantImport', 'Error reading CSV file.'), + translate('SongsPlugin.WorshipAssistantImport', 'Line %d: %s') % + (songs_reader.line_num, e)) + return + num_records = len(records) + log.info('%s records found in CSV file' % num_records) + self.import_wizard.progress_bar.setMaximum(num_records) + for index, record in enumerate(records, 1): + if self.stop_import_flag: + return + # The CSV file has a line in the middle of the file where the headers are repeated. + # We need to skip this line. + if record['TITLE'] == "TITLE" and record['COPYRIGHT'] == 'COPYRIGHT' and record['AUTHOR'] == 'AUTHOR': + continue + self.set_defaults() + try: + self.title = self._decode(record['TITLE']) + self.parse_author(self._decode(record['AUTHOR'])) + self.add_copyright(self._decode(record['COPYRIGHT'])) + lyrics = self._decode(record['LYRICS2']) + except UnicodeDecodeError as e: + self.log_error(translate('SongsPlugin.WorshipAssistantImport', 'Record %d' % index), + translate('SongsPlugin.WorshipAssistantImport', 'Decoding error: %s') % e) + continue + except TypeError as e: + self.log_error(translate('SongsPlugin.WorshipAssistantImport', + 'File not valid WorshipAssistant CSV format.'), 'TypeError: %s' % e) + return + verse = '' + for line in lyrics.splitlines(): + if line and not line.isspace(): + verse += line + '\n' + elif verse: + self.add_verse(verse) + verse = '' + if verse: + self.add_verse(verse) + if not self.finish(): + self.log_error(translate('SongsPlugin.ZionWorxImport', 'Record %d') % index + + (': "' + self.title + '"' if self.title else '')) + + def _decode(self, str): + """ + Decodes CSV input to unicode, stripping all control characters (except new lines). + """ + # This encoding choice seems OK. ZionWorx has no option for setting the + # encoding for its songs, so we assume encoding is always the same. + return str + #return str(str, 'cp1252').translate(CONTROL_CHARS_MAP) From 4ebfa33aac66b26eb106e2b2daf58edf6a40cec1 Mon Sep 17 00:00:00 2001 From: Samuel Mehrbrodt Date: Wed, 25 Jun 2014 15:49:03 +0200 Subject: [PATCH 02/11] Parse verse names --- .../songs/lib/worshipassistantimport.py | 30 ++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/openlp/plugins/songs/lib/worshipassistantimport.py b/openlp/plugins/songs/lib/worshipassistantimport.py index 683ec6456..ee9cd52cd 100644 --- a/openlp/plugins/songs/lib/worshipassistantimport.py +++ b/openlp/plugins/songs/lib/worshipassistantimport.py @@ -32,8 +32,10 @@ Worship Assistant songs into the OpenLP database. """ import csv import logging +import re from openlp.core.common import translate +from openlp.plugins.songs.lib import VerseType from openlp.plugins.songs.lib.songimport import SongImport log = logging.getLogger(__name__) @@ -87,9 +89,7 @@ class WorshipAssistantImport(SongImport): Receive a CSV file to import. """ with open(self.import_source, 'r', encoding='latin-1') as songs_file: - field_names = ['SongNum', 'Title1', 'Title2', 'Lyrics', 'Writer', 'Copyright', 'Keywords', - 'DefaultStyle'] - songs_reader = csv.DictReader(songs_file)#, field_names) + songs_reader = csv.DictReader(songs_file) try: records = list(songs_reader) except csv.Error as e: @@ -105,7 +105,7 @@ class WorshipAssistantImport(SongImport): return # The CSV file has a line in the middle of the file where the headers are repeated. # We need to skip this line. - if record['TITLE'] == "TITLE" and record['COPYRIGHT'] == 'COPYRIGHT' and record['AUTHOR'] == 'AUTHOR': + if record['TITLE'] == "TITLE" and record['AUTHOR'] == 'AUTHOR' and record['LYRICS2'] == 'LYRICS2': continue self.set_defaults() try: @@ -123,13 +123,29 @@ class WorshipAssistantImport(SongImport): return verse = '' for line in lyrics.splitlines(): - if line and not line.isspace(): + if line.startswith('['): # verse marker + # drop the square brackets + right_bracket = line.find(']') + content = line[1:right_bracket].lower() + # have we got any digits? If so, verse number is everything from the digits to the end (openlp does not + # have concept of part verses, so just ignore any non integers on the end (including floats)) + match = re.match('(\D*)(\d+)', content) + if match is not None: + verse_tag = match.group(1) + verse_num = match.group(2) + else: + # otherwise we assume number 1 and take the whole prefix as the verse tag + verse_tag = content + verse_num = '1' + verse_index = VerseType.from_loose_input(verse_tag) if verse_tag else 0 + verse_tag = VerseType.tags[verse_index] + elif line and not line.isspace(): verse += line + '\n' elif verse: - self.add_verse(verse) + self.add_verse(verse, verse_tag+verse_num) verse = '' if verse: - self.add_verse(verse) + self.add_verse(verse, verse_tag+verse_num) if not self.finish(): self.log_error(translate('SongsPlugin.ZionWorxImport', 'Record %d') % index + (': "' + self.title + '"' if self.title else '')) From c3e9d0c5b31a38dd23096c9192eb3b44d42ca1f2 Mon Sep 17 00:00:00 2001 From: Samuel Mehrbrodt Date: Wed, 25 Jun 2014 17:03:00 +0200 Subject: [PATCH 03/11] Add test --- openlp/plugins/songs/lib/cclifileimport.py | 2 +- .../songs/lib/worshipassistantimport.py | 162 +++++++++--------- .../songs/test_opensongimport.py | 6 +- .../songs/test_propresenterimport.py | 2 +- .../songs/test_songshowplusimport.py | 6 +- tests/helpers/songfileimport.py | 2 +- 6 files changed, 92 insertions(+), 88 deletions(-) diff --git a/openlp/plugins/songs/lib/cclifileimport.py b/openlp/plugins/songs/lib/cclifileimport.py index eda235ca1..69c20d1cc 100644 --- a/openlp/plugins/songs/lib/cclifileimport.py +++ b/openlp/plugins/songs/lib/cclifileimport.py @@ -64,7 +64,7 @@ class CCLIFileImport(SongImport): filename = str(filename) log.debug('Importing CCLI File: %s', filename) if os.path.isfile(filename): - detect_file = open(filename, 'r') + detect_file = open(filename, 'rb') detect_content = detect_file.read(2048) try: str(detect_content, 'utf-8') diff --git a/openlp/plugins/songs/lib/worshipassistantimport.py b/openlp/plugins/songs/lib/worshipassistantimport.py index ee9cd52cd..d371044b1 100644 --- a/openlp/plugins/songs/lib/worshipassistantimport.py +++ b/openlp/plugins/songs/lib/worshipassistantimport.py @@ -30,6 +30,7 @@ The :mod:`worshipassistantimport` module provides the functionality for importing Worship Assistant songs into the OpenLP database. """ +import chardet import csv import logging import re @@ -40,8 +41,7 @@ from openlp.plugins.songs.lib.songimport import SongImport log = logging.getLogger(__name__) -# Used to strip control chars (except 10=LF, 13=CR) -CONTROL_CHARS_MAP = dict.fromkeys(list(range(10)) + [11, 12] + list(range(14, 32)) + [127]) +EMPTY_STR = 'NULL' class WorshipAssistantImport(SongImport): @@ -53,12 +53,12 @@ class WorshipAssistantImport(SongImport): * ``SONGNR`` Song ID (Discarded by importer) * ``TITLE`` Song title - * ``AUTHOR`` Song author. May containt multiple authors. + * ``AUTHOR`` Song author. * ``COPYRIGHT`` Copyright information * ``FIRSTLINE`` Unknown (Discarded by importer) - * ``PRIKEY`` Primary chord key - * ``ALTKEY`` Alternate chord key - * ``TEMPO`` Tempo + * ``PRIKEY`` Primary chord key (Discarded by importer) + * ``ALTKEY`` Alternate chord key (Discarded by importer) + * ``TEMPO`` Tempo (Discarded by importer) * ``FOCUS`` Unknown (Discarded by importer) * ``THEME`` Theme (Discarded by importer) * ``SCRIPTURE`` Associated scripture (Discarded by importer) @@ -75,86 +75,90 @@ class WorshipAssistantImport(SongImport): * ``USER3`` User Field 3 (Discarded by importer) * ``USER4`` User Field 4 (Discarded by importer) * ``USER5`` User Field 5 (Discarded by importer) - * ``ROADMAP`` Verse order + * ``ROADMAP`` Verse order used for the presentation (Discarded by importer) * ``FILELINK1`` Associated file 1 (Discarded by importer) - * ``OVERMAP`` Unknown (Discarded by importer) + * ``OVERMAP`` Verse order used for printing (Discarded by importer) * ``FILELINK2`` Associated file 2 (Discarded by importer) - * ``LYRICS`` The song lyrics as plain text (Discarded by importer) + * ``LYRICS`` The song lyrics used for printing (Discarded by importer, LYRICS2 is used instead) * ``INFO`` Unknown (Discarded by importer) - * ``LYRICS2`` The song lyrics with verse numbers + * ``LYRICS2`` The song lyrics used for the presentation * ``BACKGROUND`` Unknown (Discarded by importer) """ def do_import(self): """ Receive a CSV file to import. """ - with open(self.import_source, 'r', encoding='latin-1') as songs_file: - songs_reader = csv.DictReader(songs_file) - try: - records = list(songs_reader) - except csv.Error as e: - self.log_error(translate('SongsPlugin.WorshipAssistantImport', 'Error reading CSV file.'), - translate('SongsPlugin.WorshipAssistantImport', 'Line %d: %s') % - (songs_reader.line_num, e)) - return - num_records = len(records) - log.info('%s records found in CSV file' % num_records) - self.import_wizard.progress_bar.setMaximum(num_records) - for index, record in enumerate(records, 1): - if self.stop_import_flag: - return - # The CSV file has a line in the middle of the file where the headers are repeated. - # We need to skip this line. - if record['TITLE'] == "TITLE" and record['AUTHOR'] == 'AUTHOR' and record['LYRICS2'] == 'LYRICS2': - continue - self.set_defaults() - try: - self.title = self._decode(record['TITLE']) - self.parse_author(self._decode(record['AUTHOR'])) - self.add_copyright(self._decode(record['COPYRIGHT'])) - lyrics = self._decode(record['LYRICS2']) - except UnicodeDecodeError as e: - self.log_error(translate('SongsPlugin.WorshipAssistantImport', 'Record %d' % index), - translate('SongsPlugin.WorshipAssistantImport', 'Decoding error: %s') % e) - continue - except TypeError as e: - self.log_error(translate('SongsPlugin.WorshipAssistantImport', - 'File not valid WorshipAssistant CSV format.'), 'TypeError: %s' % e) - return - verse = '' - for line in lyrics.splitlines(): - if line.startswith('['): # verse marker - # drop the square brackets - right_bracket = line.find(']') - content = line[1:right_bracket].lower() - # have we got any digits? If so, verse number is everything from the digits to the end (openlp does not - # have concept of part verses, so just ignore any non integers on the end (including floats)) - match = re.match('(\D*)(\d+)', content) - if match is not None: - verse_tag = match.group(1) - verse_num = match.group(2) - else: - # otherwise we assume number 1 and take the whole prefix as the verse tag - verse_tag = content - verse_num = '1' - verse_index = VerseType.from_loose_input(verse_tag) if verse_tag else 0 - verse_tag = VerseType.tags[verse_index] - elif line and not line.isspace(): - verse += line + '\n' - elif verse: - self.add_verse(verse, verse_tag+verse_num) - verse = '' - if verse: - self.add_verse(verse, verse_tag+verse_num) - if not self.finish(): - self.log_error(translate('SongsPlugin.ZionWorxImport', 'Record %d') % index - + (': "' + self.title + '"' if self.title else '')) + # Get encoding + detect_file = open(self.import_source, 'rb') + detect_content = detect_file.read() + details = chardet.detect(detect_content) + detect_file.close() + songs_file = open(self.import_source, 'r', encoding=details['encoding']) - def _decode(self, str): - """ - Decodes CSV input to unicode, stripping all control characters (except new lines). - """ - # This encoding choice seems OK. ZionWorx has no option for setting the - # encoding for its songs, so we assume encoding is always the same. - return str - #return str(str, 'cp1252').translate(CONTROL_CHARS_MAP) + songs_reader = csv.DictReader(songs_file) + try: + records = list(songs_reader) + except csv.Error as e: + self.log_error(translate('SongsPlugin.WorshipAssistantImport', 'Error reading CSV file.'), + translate('SongsPlugin.WorshipAssistantImport', 'Line %d: %s') % + (songs_reader.line_num, e)) + return + num_records = len(records) + log.info('%s records found in CSV file' % num_records) + self.import_wizard.progress_bar.setMaximum(num_records) + for index, record in enumerate(records, 1): + if self.stop_import_flag: + return + # Ensure that all keys are uppercase + record = dict((k.upper(), v) for k, v in record.items()) + # The CSV file has a line in the middle of the file where the headers are repeated. + # We need to skip this line. + if record['TITLE'] == "TITLE" and record['AUTHOR'] == 'AUTHOR' and record['LYRICS2'] == 'LYRICS2': + continue + self.set_defaults() + try: + self.title = record['TITLE'] + if record['AUTHOR'] != EMPTY_STR: + self.parse_author(record['AUTHOR']) + if record['COPYRIGHT']!= EMPTY_STR: + self.add_copyright(record['COPYRIGHT']) + if record['CCLINR'] != EMPTY_STR: + self.ccli_number = record['CCLINR'] + lyrics = record['LYRICS2'] + except UnicodeDecodeError as e: + self.log_error(translate('SongsPlugin.WorshipAssistantImport', 'Record %d' % index), + translate('SongsPlugin.WorshipAssistantImport', 'Decoding error: %s') % e) + continue + except TypeError as e: + self.log_error(translate('SongsPlugin.WorshipAssistantImport', + 'File not valid WorshipAssistant CSV format.'), 'TypeError: %s' % e) + return + verse = '' + for line in lyrics.splitlines(): + if line.startswith('['): # verse marker + # drop the square brackets + right_bracket = line.find(']') + content = line[1:right_bracket].lower() + # have we got any digits? If so, verse number is everything from the digits to the end (openlp does not + # have concept of part verses, so just ignore any non integers on the end (including floats)) + match = re.match('(\D*)(\d+)', content) + if match is not None: + verse_tag = match.group(1) + verse_num = match.group(2) + else: + # otherwise we assume number 1 and take the whole prefix as the verse tag + verse_tag = content + verse_num = '1' + verse_index = VerseType.from_loose_input(verse_tag) if verse_tag else 0 + verse_tag = VerseType.tags[verse_index] + elif line and not line.isspace(): + verse += line + '\n' + elif verse: + self.add_verse(verse, verse_tag+verse_num) + verse = '' + if verse: + self.add_verse(verse, verse_tag+verse_num) + if not self.finish(): + self.log_error(translate('SongsPlugin.ZionWorxImport', 'Record %d') % index + + (': "' + self.title + '"' if self.title else '')) + songs_file.close() diff --git a/tests/functional/openlp_plugins/songs/test_opensongimport.py b/tests/functional/openlp_plugins/songs/test_opensongimport.py index 70d3b342a..96d6bff0b 100644 --- a/tests/functional/openlp_plugins/songs/test_opensongimport.py +++ b/tests/functional/openlp_plugins/songs/test_opensongimport.py @@ -52,11 +52,11 @@ class TestOpenSongFileImport(SongImportTestHelper): """ Test that loading an OpenSong file works correctly on various files """ - self.file_import(os.path.join(TEST_PATH, 'Amazing Grace'), + self.file_import([os.path.join(TEST_PATH, 'Amazing Grace')], self.load_external_result_data(os.path.join(TEST_PATH, 'Amazing Grace.json'))) - self.file_import(os.path.join(TEST_PATH, 'Beautiful Garden Of Prayer'), + self.file_import([os.path.join(TEST_PATH, 'Beautiful Garden Of Prayer')], self.load_external_result_data(os.path.join(TEST_PATH, 'Beautiful Garden Of Prayer.json'))) - self.file_import(os.path.join(TEST_PATH, 'One, Two, Three, Four, Five'), + self.file_import([os.path.join(TEST_PATH, 'One, Two, Three, Four, Five')], self.load_external_result_data(os.path.join(TEST_PATH, 'One, Two, Three, Four, Five.json'))) diff --git a/tests/functional/openlp_plugins/songs/test_propresenterimport.py b/tests/functional/openlp_plugins/songs/test_propresenterimport.py index 971ddbdf6..10e2defc6 100644 --- a/tests/functional/openlp_plugins/songs/test_propresenterimport.py +++ b/tests/functional/openlp_plugins/songs/test_propresenterimport.py @@ -50,5 +50,5 @@ class TestProPresenterFileImport(SongImportTestHelper): """ Test that loading an ProPresenter file works correctly """ - self.file_import(os.path.join(TEST_PATH, 'Amazing Grace.pro4'), + self.file_import([os.path.join(TEST_PATH, 'Amazing Grace.pro4')], self.load_external_result_data(os.path.join(TEST_PATH, 'Amazing Grace.json'))) diff --git a/tests/functional/openlp_plugins/songs/test_songshowplusimport.py b/tests/functional/openlp_plugins/songs/test_songshowplusimport.py index 08400fdc5..dfee265e3 100644 --- a/tests/functional/openlp_plugins/songs/test_songshowplusimport.py +++ b/tests/functional/openlp_plugins/songs/test_songshowplusimport.py @@ -53,11 +53,11 @@ class TestSongShowPlusFileImport(SongImportTestHelper): """ Test that loading a SongShow Plus file works correctly on various files """ - self.file_import(os.path.join(TEST_PATH, 'Amazing Grace.sbsong'), + self.file_import([os.path.join(TEST_PATH, 'Amazing Grace.sbsong')], self.load_external_result_data(os.path.join(TEST_PATH, 'Amazing Grace.json'))) - self.file_import(os.path.join(TEST_PATH, 'Beautiful Garden Of Prayer.sbsong'), + self.file_import([os.path.join(TEST_PATH, 'Beautiful Garden Of Prayer.sbsong')], self.load_external_result_data(os.path.join(TEST_PATH, 'Beautiful Garden Of Prayer.json'))) - self.file_import(os.path.join(TEST_PATH, 'a mighty fortress is our god.sbsong'), + self.file_import([os.path.join(TEST_PATH, 'a mighty fortress is our god.sbsong')], self.load_external_result_data(os.path.join(TEST_PATH, 'a mighty fortress is our god.json'))) diff --git a/tests/helpers/songfileimport.py b/tests/helpers/songfileimport.py index 36beef6e5..80b2ee268 100644 --- a/tests/helpers/songfileimport.py +++ b/tests/helpers/songfileimport.py @@ -95,7 +95,7 @@ class SongImportTestHelper(TestCase): importer.topics = [] # WHEN: Importing the source file - importer.import_source = [source_file_name] + importer.import_source = source_file_name add_verse_calls = self._get_data(result_data, 'verses') author_calls = self._get_data(result_data, 'authors') ccli_number = self._get_data(result_data, 'ccli_number') From 5eb0ac618ecc733a00a0fdc1e16b7ffd0d5e32da Mon Sep 17 00:00:00 2001 From: Samuel Mehrbrodt Date: Wed, 25 Jun 2014 17:04:13 +0200 Subject: [PATCH 04/11] PEP8 --- openlp/plugins/songs/lib/worshipassistantimport.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/openlp/plugins/songs/lib/worshipassistantimport.py b/openlp/plugins/songs/lib/worshipassistantimport.py index d371044b1..980f7a801 100644 --- a/openlp/plugins/songs/lib/worshipassistantimport.py +++ b/openlp/plugins/songs/lib/worshipassistantimport.py @@ -120,7 +120,7 @@ class WorshipAssistantImport(SongImport): self.title = record['TITLE'] if record['AUTHOR'] != EMPTY_STR: self.parse_author(record['AUTHOR']) - if record['COPYRIGHT']!= EMPTY_STR: + if record['COPYRIGHT'] != EMPTY_STR: self.add_copyright(record['COPYRIGHT']) if record['CCLINR'] != EMPTY_STR: self.ccli_number = record['CCLINR'] @@ -135,12 +135,10 @@ class WorshipAssistantImport(SongImport): return verse = '' for line in lyrics.splitlines(): - if line.startswith('['): # verse marker + if line.startswith('['): # verse marker # drop the square brackets right_bracket = line.find(']') content = line[1:right_bracket].lower() - # have we got any digits? If so, verse number is everything from the digits to the end (openlp does not - # have concept of part verses, so just ignore any non integers on the end (including floats)) match = re.match('(\D*)(\d+)', content) if match is not None: verse_tag = match.group(1) From 93c3a57ea9f3dcbce52ea925dc83190f25d33b6c Mon Sep 17 00:00:00 2001 From: Samuel Mehrbrodt Date: Wed, 25 Jun 2014 17:04:28 +0200 Subject: [PATCH 05/11] Add missing files --- .../songs/test_worshipassistantimport.py | 54 +++++++++++++++++++ .../worshipassistantsongs/du_herr.csv | 30 +++++++++++ .../worshipassistantsongs/du_herr.json | 21 ++++++++ 3 files changed, 105 insertions(+) create mode 100644 tests/functional/openlp_plugins/songs/test_worshipassistantimport.py create mode 100644 tests/resources/worshipassistantsongs/du_herr.csv create mode 100644 tests/resources/worshipassistantsongs/du_herr.json diff --git a/tests/functional/openlp_plugins/songs/test_worshipassistantimport.py b/tests/functional/openlp_plugins/songs/test_worshipassistantimport.py new file mode 100644 index 000000000..9d968beaa --- /dev/null +++ b/tests/functional/openlp_plugins/songs/test_worshipassistantimport.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=120 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 # +############################################################################### +""" +The :mod:`worshipassistantimport` module provides the functionality for importing +WorshipAssistant song files into the current installation database. +""" + +import os + +from tests.helpers.songfileimport import SongImportTestHelper + +TEST_PATH = os.path.abspath( + os.path.join(os.path.dirname(__file__), '..', '..', '..', 'resources', 'worshipassistantsongs')) + + +class TestWorshipAssistantFileImport(SongImportTestHelper): + + def __init__(self, *args, **kwargs): + self.importer_class_name = 'WorshipAssistantImport' + self.importer_module_name = 'worshipassistantimport' + super(TestWorshipAssistantFileImport, self).__init__(*args, **kwargs) + + def test_song_import(self): + """ + Test that loading an Worship Assistant file works correctly + """ + self.file_import(os.path.join(TEST_PATH, 'du_herr.csv'), + self.load_external_result_data(os.path.join(TEST_PATH, 'du_herr.json'))) diff --git a/tests/resources/worshipassistantsongs/du_herr.csv b/tests/resources/worshipassistantsongs/du_herr.csv new file mode 100644 index 000000000..72c5b4735 --- /dev/null +++ b/tests/resources/worshipassistantsongs/du_herr.csv @@ -0,0 +1,30 @@ +"SongID","SongNr","Title","Author","Copyright","FirstLine","PriKey","AltKey","Tempo","Focus","Theme","Scripture","Active","Songbook","TimeSig","Introduced","LastUsed","TimesUsed","CCLINr","User1","User2","User3","User4","User5","Roadmap","Overmap","FileLink1","FileLink2","Updated","Lyrics","Info","Lyrics2","Background" +"4ee399dc-edda-4aa9-891e-a859ca093c78","NULL","Du, Herr, verläßt mich nicht","Carl Brockhaus / Johann Georg Bäßler 1806","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","1","1","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","2014-06-25 12:15:28.317","","NULL","[1] +Du, Herr, verläßt mich nicht. +Auf Dich mein Herz allein vertraut, +Mein Auge glaubend auf Dich schaut. +Du bist mein Heil, mein Licht, +Mein Fels, mein sichrer Hort. +Bin ich versucht, gibt's Not und Leid, +Du bleibst mein Trost, mein Arm im Streit, +Mein Licht am dunklen Ort. + +[2] +Ich weiß, daß Du mich liebst. +Bist mir in jeder Lage nah', +Wohin ich gehe – Du bist da, +Ja, Du mir alles gibst. +Ich überlaß mich Dir; +Denn Du, Herr, kennst mich ganz und gar +Und führst mich sicher, wunderbar, +Und bist selbst alles mir. + +[3] +In dieser Wüste hier +Find't nirgend meine Seele Ruh', +Denn meine Ruh' bist, Jesu, Du. +Wohl mir, ich geh' zu Dir! +Bald werd' ich bei Dir sein, +Bald mit den Deinen ewiglich +Anbeten, loben, preisen Dich, +Mich Deiner stets erfreun.","NULL" diff --git a/tests/resources/worshipassistantsongs/du_herr.json b/tests/resources/worshipassistantsongs/du_herr.json new file mode 100644 index 000000000..56f3a7f0c --- /dev/null +++ b/tests/resources/worshipassistantsongs/du_herr.json @@ -0,0 +1,21 @@ +{ + "authors": [ + "Carl Brockhaus / Johann Georg Bäßler 1806" + ], + "title": "Du, Herr, verläßt mich nicht", + "verse_order_list": [], + "verses": [ + [ + "Du, Herr, verläßt mich nicht.\nAuf Dich mein Herz allein vertraut,\nMein Auge glaubend auf Dich schaut.\nDu bist mein Heil, mein Licht,\nMein Fels, mein sichrer Hort.\nBin ich versucht, gibt's Not und Leid,\nDu bleibst mein Trost, mein Arm im Streit,\nMein Licht am dunklen Ort.\n", + "v1" + ], + [ + "Ich weiß, daß Du mich liebst.\nBist mir in jeder Lage nah',\nWohin ich gehe – Du bist da,\nJa, Du mir alles gibst.\nIch überlaß mich Dir;\nDenn Du, Herr, kennst mich ganz und gar\nUnd führst mich sicher, wunderbar,\nUnd bist selbst alles mir.\n", + "v2" + ], + [ + "In dieser Wüste hier\nFind't nirgend meine Seele Ruh',\nDenn meine Ruh' bist, Jesu, Du.\nWohl mir, ich geh' zu Dir!\nBald werd' ich bei Dir sein,\nBald mit den Deinen ewiglich\nAnbeten, loben, preisen Dich,\nMich Deiner stets erfreun.\n", + "v3" + ] + ] +} \ No newline at end of file From 66827a7676b1a7a9bce3966483430200cd424140 Mon Sep 17 00:00:00 2001 From: Samuel Mehrbrodt Date: Thu, 26 Jun 2014 09:58:59 +0200 Subject: [PATCH 06/11] Parse verse order --- openlp/plugins/songs/lib/songimport.py | 1 + .../songs/lib/worshipassistantimport.py | 18 ++++++++++++++---- .../songs/test_worshipassistantimport.py | 2 ++ .../worshipassistantsongs/du_herr.json | 2 +- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/openlp/plugins/songs/lib/songimport.py b/openlp/plugins/songs/lib/songimport.py index b8fcc604b..18bb571d3 100644 --- a/openlp/plugins/songs/lib/songimport.py +++ b/openlp/plugins/songs/lib/songimport.py @@ -266,6 +266,7 @@ class SongImport(QtCore.QObject): """ Add an author to the list """ + print(author) if author in self.authors: return self.authors.append(author) diff --git a/openlp/plugins/songs/lib/worshipassistantimport.py b/openlp/plugins/songs/lib/worshipassistantimport.py index 980f7a801..6831ec450 100644 --- a/openlp/plugins/songs/lib/worshipassistantimport.py +++ b/openlp/plugins/songs/lib/worshipassistantimport.py @@ -68,21 +68,20 @@ class WorshipAssistantImport(SongImport): * ``INTRODUCED`` Date the song was created (Discarded by importer) * ``LASTUSED`` Date the song was last used (Discarded by importer) * ``TIMESUSED`` How many times the song was used (Discarded by importer) - * ``TIMESUSED`` How many times the song was used (Discarded by importer) * ``CCLINR`` CCLI Number * ``USER1`` User Field 1 (Discarded by importer) * ``USER2`` User Field 2 (Discarded by importer) * ``USER3`` User Field 3 (Discarded by importer) * ``USER4`` User Field 4 (Discarded by importer) * ``USER5`` User Field 5 (Discarded by importer) - * ``ROADMAP`` Verse order used for the presentation (Discarded by importer) + * ``ROADMAP`` Verse order used for the presentation * ``FILELINK1`` Associated file 1 (Discarded by importer) * ``OVERMAP`` Verse order used for printing (Discarded by importer) * ``FILELINK2`` Associated file 2 (Discarded by importer) * ``LYRICS`` The song lyrics used for printing (Discarded by importer, LYRICS2 is used instead) * ``INFO`` Unknown (Discarded by importer) * ``LYRICS2`` The song lyrics used for the presentation - * ``BACKGROUND`` Unknown (Discarded by importer) + * ``BACKGROUND`` Custom background (Discarded by importer) """ def do_import(self): """ @@ -116,14 +115,18 @@ class WorshipAssistantImport(SongImport): if record['TITLE'] == "TITLE" and record['AUTHOR'] == 'AUTHOR' and record['LYRICS2'] == 'LYRICS2': continue self.set_defaults() + verse_order_list = [] try: self.title = record['TITLE'] if record['AUTHOR'] != EMPTY_STR: self.parse_author(record['AUTHOR']) + print(record['AUTHOR']) if record['COPYRIGHT'] != EMPTY_STR: self.add_copyright(record['COPYRIGHT']) if record['CCLINR'] != EMPTY_STR: self.ccli_number = record['CCLINR'] + if record['ROADMAP'] != EMPTY_STR: + verse_order_list = record['ROADMAP'].split(',') lyrics = record['LYRICS2'] except UnicodeDecodeError as e: self.log_error(translate('SongsPlugin.WorshipAssistantImport', 'Record %d' % index), @@ -149,6 +152,11 @@ class WorshipAssistantImport(SongImport): verse_num = '1' verse_index = VerseType.from_loose_input(verse_tag) if verse_tag else 0 verse_tag = VerseType.tags[verse_index] + # Update verse order when the verse name has changed + if content != verse_tag + verse_num: + for i in range(len(verse_order_list)): + if verse_order_list[i].lower() == content.lower(): + verse_order_list[i] = verse_tag + verse_num elif line and not line.isspace(): verse += line + '\n' elif verse: @@ -156,7 +164,9 @@ class WorshipAssistantImport(SongImport): verse = '' if verse: self.add_verse(verse, verse_tag+verse_num) + if verse_order_list: + self.verse_order_list = verse_order_list if not self.finish(): - self.log_error(translate('SongsPlugin.ZionWorxImport', 'Record %d') % index + self.log_error(translate('SongsPlugin.WorshipAssistantImport', 'Record %d') % index + (': "' + self.title + '"' if self.title else '')) songs_file.close() diff --git a/tests/functional/openlp_plugins/songs/test_worshipassistantimport.py b/tests/functional/openlp_plugins/songs/test_worshipassistantimport.py index 9d968beaa..c0c5c7416 100644 --- a/tests/functional/openlp_plugins/songs/test_worshipassistantimport.py +++ b/tests/functional/openlp_plugins/songs/test_worshipassistantimport.py @@ -52,3 +52,5 @@ class TestWorshipAssistantFileImport(SongImportTestHelper): """ self.file_import(os.path.join(TEST_PATH, 'du_herr.csv'), self.load_external_result_data(os.path.join(TEST_PATH, 'du_herr.json'))) + self.file_import(os.path.join(TEST_PATH, 'would_you_be_free.csv'), + self.load_external_result_data(os.path.join(TEST_PATH, 'would_you_be_free.json'))) diff --git a/tests/resources/worshipassistantsongs/du_herr.json b/tests/resources/worshipassistantsongs/du_herr.json index 56f3a7f0c..1df700df8 100644 --- a/tests/resources/worshipassistantsongs/du_herr.json +++ b/tests/resources/worshipassistantsongs/du_herr.json @@ -18,4 +18,4 @@ "v3" ] ] -} \ No newline at end of file +} From c63883402383702fb2750e003f53e42de1707d7b Mon Sep 17 00:00:00 2001 From: Samuel Mehrbrodt Date: Thu, 26 Jun 2014 09:59:16 +0200 Subject: [PATCH 07/11] Add missing files --- .../would_you_be_free.csv | 30 +++++++++++++++++++ .../would_you_be_free.json | 19 ++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 tests/resources/worshipassistantsongs/would_you_be_free.csv create mode 100644 tests/resources/worshipassistantsongs/would_you_be_free.json diff --git a/tests/resources/worshipassistantsongs/would_you_be_free.csv b/tests/resources/worshipassistantsongs/would_you_be_free.csv new file mode 100644 index 000000000..a454ddbf5 --- /dev/null +++ b/tests/resources/worshipassistantsongs/would_you_be_free.csv @@ -0,0 +1,30 @@ +SONGNR,TITLE,AUTHOR,COPYRIGHT,FIRSTLINE,PRIKEY,ALTKEY,TEMPO,FOCUS,THEME,SCRIPTURE,ACTIVE,SONGBOOK,TIMESIG,INTRODUCED,LASTUSED,TIMESUSED,CCLINR,USER1,USER2,USER3,USER4,USER5,ROADMAP,FILELINK1,OVERMAP,FILELINK2,LYRICS,INFO,LYRICS2,Background +"7","Would You Be Free","Jones, Lewis E.","Public Domain","Would you be free from your burden of sin?","G","","Moderate","Only To Others","","","N","Y","","1899-12-30","1899-12-30","","","","","","","","1,C,1","","","",".G C G + Would you be free from your burden of sin? +. D D7 G + There's power in the blood, power in the blood +. C G + Would you o'er evil a victory win? +. D D7 G + There's wonderful power in the blood + +.G C G + There is power, power, wonder working power +.D G + In the blood of the Lamb +. C G + There is power, power, wonder working power +. D G + In the precious blood of the Lamb +","","[1] +Would you be free from your burden of sin? +There's power in the blood, power in the blood +Would you o'er evil a victory win? +There's wonderful power in the blood + +[C] +There is power, power, wonder working power +In the blood of the Lamb +There is power, power, wonder working power +In the precious blood of the Lamb +","" diff --git a/tests/resources/worshipassistantsongs/would_you_be_free.json b/tests/resources/worshipassistantsongs/would_you_be_free.json new file mode 100644 index 000000000..96bc06a59 --- /dev/null +++ b/tests/resources/worshipassistantsongs/would_you_be_free.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "Jones", + "Lewis E" + ], + "title": "Would You Be Free", + "verse_order_list": ["v1", "c1", "v1"], + "copyright": "Public Domain", + "verses": [ + [ + "Would you be free from your burden of sin? \nThere's power in the blood, power in the blood \nWould you o'er evil a victory win? \nThere's wonderful power in the blood \n", + "v1" + ], + [ + "There is power, power, wonder working power \nIn the blood of the Lamb \nThere is power, power, wonder working power \nIn the precious blood of the Lamb \n", + "c1" + ] + ] +} From a52dc69c89f4e965f6224ba6022dd99a71f42215 Mon Sep 17 00:00:00 2001 From: Samuel Mehrbrodt Date: Thu, 26 Jun 2014 10:04:33 +0200 Subject: [PATCH 08/11] Remove debug output --- openlp/plugins/songs/lib/songimport.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openlp/plugins/songs/lib/songimport.py b/openlp/plugins/songs/lib/songimport.py index 18bb571d3..b8fcc604b 100644 --- a/openlp/plugins/songs/lib/songimport.py +++ b/openlp/plugins/songs/lib/songimport.py @@ -266,7 +266,6 @@ class SongImport(QtCore.QObject): """ Add an author to the list """ - print(author) if author in self.authors: return self.authors.append(author) From 78f1756380b4576a8c57ef98db16b7d95c507bcc Mon Sep 17 00:00:00 2001 From: Samuel Mehrbrodt Date: Thu, 26 Jun 2014 10:35:53 +0200 Subject: [PATCH 09/11] Fix biblegateway url --- openlp/plugins/bibles/lib/http.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openlp/plugins/bibles/lib/http.py b/openlp/plugins/bibles/lib/http.py index 64b024639..6b26dfabe 100644 --- a/openlp/plugins/bibles/lib/http.py +++ b/openlp/plugins/bibles/lib/http.py @@ -225,7 +225,7 @@ class BGExtract(RegistryProperties): url_book_name = urllib.parse.quote(book_name.encode("utf-8")) url_params = 'search=%s+%s&version=%s' % (url_book_name, chapter, version) soup = get_soup_for_bible_ref( - 'http://www.biblegateway.com/passage/?%s' % url_params, + 'http://legacy.biblegateway.com/passage/?%s' % url_params, pre_parse_regex=r'', pre_parse_substitute='') if not soup: return None @@ -252,7 +252,7 @@ class BGExtract(RegistryProperties): """ log.debug('BGExtract.get_books_from_http("%s")', version) url_params = urllib.parse.urlencode({'action': 'getVersionInfo', 'vid': '%s' % version}) - reference_url = 'http://www.biblegateway.com/versions/?%s#books' % url_params + reference_url = 'http://legacy.biblegateway.com/versions/?%s#books' % url_params page = get_web_page(reference_url) if not page: send_error_message('download') From b4be73b616bad50b9fe732cddd45b092cdbaa1d6 Mon Sep 17 00:00:00 2001 From: Samuel Mehrbrodt Date: Thu, 26 Jun 2014 11:21:46 +0200 Subject: [PATCH 10/11] Fix bzr tags test --- tests/utils/test_bzr_tags.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/utils/test_bzr_tags.py b/tests/utils/test_bzr_tags.py index 393f4ce25..acadbd8c4 100644 --- a/tests/utils/test_bzr_tags.py +++ b/tests/utils/test_bzr_tags.py @@ -50,10 +50,6 @@ TAGS = [ ['1.9.11', '2039'], ['1.9.12', '2063'], ['2.0', '2118'], - ['2.0.1', '?'], - ['2.0.2', '?'], - ['2.0.3', '?'], - ['2.0.4', '?'], ['2.1.0', '2119'] ] From 7364d4962f7b70aa9f2536a2c347269e402a9a29 Mon Sep 17 00:00:00 2001 From: Samuel Mehrbrodt Date: Mon, 30 Jun 2014 09:18:26 +0200 Subject: [PATCH 11/11] Small fixes --- openlp/plugins/songs/lib/worshipassistantimport.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openlp/plugins/songs/lib/worshipassistantimport.py b/openlp/plugins/songs/lib/worshipassistantimport.py index 6831ec450..772fe8622 100644 --- a/openlp/plugins/songs/lib/worshipassistantimport.py +++ b/openlp/plugins/songs/lib/worshipassistantimport.py @@ -93,7 +93,6 @@ class WorshipAssistantImport(SongImport): details = chardet.detect(detect_content) detect_file.close() songs_file = open(self.import_source, 'r', encoding=details['encoding']) - songs_reader = csv.DictReader(songs_file) try: records = list(songs_reader) @@ -109,7 +108,7 @@ class WorshipAssistantImport(SongImport): if self.stop_import_flag: return # Ensure that all keys are uppercase - record = dict((k.upper(), v) for k, v in record.items()) + record = dict((field.upper(), value) for field, value in record.items()) # The CSV file has a line in the middle of the file where the headers are repeated. # We need to skip this line. if record['TITLE'] == "TITLE" and record['AUTHOR'] == 'AUTHOR' and record['LYRICS2'] == 'LYRICS2':