Merge lp:~john+ubuntu-g/openlp/singingthefaith into lp:openlp

Proposed by John Lines on 2019-06-30
Status: Superseded
Proposed branch: lp:~john+ubuntu-g/openlp/singingthefaith
Merge into: lp:openlp
Diff against target: 584 lines (+500/-11)
8 files modified
openlp/plugins/songs/lib/importer.py (+22/-10)
openlp/plugins/songs/lib/importers/singingthefaith.py (+347/-0)
tests/functional/openlp_plugins/songs/test_singingthefaithimport.py (+48/-0)
tests/helpers/songfileimport.py (+2/-1)
tests/resources/songs/singingthefaith/H1.txt (+9/-0)
tests/resources/songs/singingthefaith/H2.txt (+30/-0)
tests/resources/songs/singingthefaith/STF001.json (+13/-0)
tests/resources/songs/singingthefaith/STF002.json (+29/-0)
To merge this branch: bzr merge lp:~john+ubuntu-g/openlp/singingthefaith
Reviewer Review Type Date Requested Status
Raoul Snyman 2019-06-30 Pending
Review via email: mp+369489@code.launchpad.net

This proposal supersedes a proposal from 2019-06-27.

This proposal has been superseded by a proposal from 2019-06-30.

Commit message

Initial merge of SingingTheFaithImport, including update to importer.py

Description of the change

Singing The Faith is the new Authorized Hymn book for the Methodist Church of Great Britain.
There is an electronic version of the Hymn book, for Windows only, which can export Hymns as text files.

This import module smooths the process of converting these text files into OpenLP. The input format is messy and not intended for automatic processing so the importer uses a combination of heuristics and a hints file. This version has not been tested on all the hymns in Singing The Faith, but deals with most of the, more than 100, hymns it has been tested with.

Note that it includes a test module, which works for the single verse case. Multiple verse songs import OK, but tests fail.

To post a comment you must log in.
Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

Linux tests failed, please see https://ci.openlp.io/job/MP-02-Linux_Tests/191/ for more details

Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

The test is failing because the "add_verse" method is not called, or not called with that exact data. I've broken up the error message into 3 parts below for easier reading.

AssertionError:

add_verse('Amazing grace! How sweet the sound!\nThat saved a wretch like me!\nI once was lost, but now am found;\nWas blind, but now I see.', 'v1')

call not found

review: Needs Fixing
Phill (phill-ridout) wrote : Posted in a previous version of this proposal

A few in-line comments. Also you don't need to use parenthesis around the expressions in the if statements.

John Lines (john+ubuntu-g) wrote : Posted in a previous version of this proposal

> A few in-line comments. Also you don't need to use parenthesis around the
> expressions in the if statements.

Thanks - have updated to use Path more, and have removed redudant parentheses round expressions in if statements

Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

Hey John, a couple things.

1. You have a ton of linting issues. I started commenting, and then I realised that it would be better to just point you to flake8. See the link at the bottom of my comment for a quick introduction to linting and flake8.

2. You have some inconsistent indentation. Indentation in Python is very important, so we take it seriously. Also, please make sure you are indenting using spaces and not tabs.

3. You are not committing your code with the e-mail address associated with Launchpad. Please can you fix that by issuing a bzr whoami "John Lines <email address hidden>"

4. Once you've made all your changes, and you're ready for another review, you need to resubmit your merge proposal. Do this by clicking the "Resubmit" link in the top right hand corner of the page.

5. If you're struggling with anything, pop into our IRC channel, there's usually someone around who is happy to help.

https://medium.com/python-pandemonium/what-is-flake8-and-why-we-should-use-it-b89bd78073f2

review: Needs Fixing
John Lines (john+ubuntu-g) wrote : Posted in a previous version of this proposal

1. Thanks for the info on flake8 - is now flake8 clean - you are quite right - it is better for me to learn about the tools.
2. Think indentation is fixed - flake8 was handy as well
3. Email address now set in my bzr config
4. Can you have another look at the change now.

Raoul Snyman (raoul-snyman) wrote :

Linux tests passed!

Raoul Snyman (raoul-snyman) wrote :

Linting failed, please see https://ci.openlp.io/job/MP-03-Linting/132/ for more details

2889. By John Lines on 2019-06-30

Fix lint warning in tests and importer.py

John Lines (john+ubuntu-g) wrote :

Fix lint tests outside main importer code

2890. By John Lines on 2019-07-12

Minimize differences needed to run under OpenLP 2.4.6

2891. By John Lines on 2019-07-12

Convert double to single quotes, make hint variable names consistent

2892. By John Lines on 2019-07-12

New style string formatting, restructure indent=0 cases

2893. By John Lines on 2019-07-13

New hints for AddSpaceAfterSemi and CCLI

2894. By John Lines on 2019-07-15

Update GPL version, use constructor, add comment to signal unepected verse order

2895. By John Lines on 2019-07-16

Add AddSpaceAfterColon hint

2896. By John Lines on 2019-07-17

Add BlankLine hint and deal with a leading asterisk on a verse number

2897. By John Lines on 2019-07-19

Merge trunk updates

2898. By John Lines on 2019-07-19

enable whole song impoerter test

2899. By John Lines on 2019-07-27

Strip unwanted formatting characters

2900. By John Lines on 2019-07-28

Implement BoldLine hint

2901. By John Lines on 2019-07-28

Make Based on Psalm an automatic comment, do not automatically make Authors type Word

2902. By John Lines on 2019-07-28

Fix typo

2903. By John Lines on 2019-08-12

Merge trunk updates

2904. By John Lines on 2019-08-23

Use .format in importer.py

2905. By John Lines on 2019-08-23

Implement SongbookNumberInTitle hint

2906. By John Lines on 2019-08-29

Upload hints.tag into resources

2907. By John Lines on 2019-09-03

fix tests to allow for SongbookNumberInTitle defaulting to false and add hints tests

2908. By John Lines on 2019-09-03

Merge trunk updates

2909. By John Lines on 2019-09-03

add tests with hints subdirectory

2910. By John Lines on 2019-09-03

Linting fix

2911. By John Lines on 2019-09-04

put default hints plugin directory and chnage name to singingthefaith-hints.tag

2912. By John Lines on 2019-09-16

Merge trunk updates

2913. By John Lines on 2019-09-16

Tweaks to hints - now version 3, H470 and H567

Unmerged revisions

2913. By John Lines on 2019-09-16

Tweaks to hints - now version 3, H470 and H567

2912. By John Lines on 2019-09-16

Merge trunk updates

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'openlp/plugins/songs/lib/importer.py'
2--- openlp/plugins/songs/lib/importer.py 2019-04-13 13:00:22 +0000
3+++ openlp/plugins/songs/lib/importer.py 2019-06-30 19:14:23 +0000
4@@ -42,6 +42,7 @@
5 from .importers.powersong import PowerSongImport
6 from .importers.presentationmanager import PresentationManagerImport
7 from .importers.propresenter import ProPresenterImport
8+from .importers.singingthefaith import SingingTheFaithImport
9 from .importers.songbeamer import SongBeamerImport
10 from .importers.songpro import SongProImport
11 from .importers.songshowplus import SongShowPlusImport
12@@ -173,16 +174,17 @@
13 PowerSong = 16
14 PresentationManager = 17
15 ProPresenter = 18
16- SongBeamer = 19
17- SongPro = 20
18- SongShowPlus = 21
19- SongsOfFellowship = 22
20- SundayPlus = 23
21- VideoPsalm = 24
22- WordsOfWorship = 25
23- WorshipAssistant = 26
24- WorshipCenterPro = 27
25- ZionWorx = 28
26+ SingingTheFaith = 19
27+ SongBeamer = 20
28+ SongPro = 21
29+ SongShowPlus = 22
30+ SongsOfFellowship = 23
31+ SundayPlus = 24
32+ VideoPsalm = 25
33+ WordsOfWorship = 26
34+ WorshipAssistant = 27
35+ WorshipCenterPro = 28
36+ ZionWorx = 29
37
38 # Set optional attribute defaults
39 __defaults__ = {
40@@ -343,6 +345,15 @@
41 'filter': '{text} (*.pro4 *.pro5 *.pro6)'.format(text=translate('SongsPlugin.ImportWizardForm',
42 'ProPresenter Song Files'))
43 },
44+ SingingTheFaith: {
45+ 'class': SingingTheFaithImport,
46+ 'name': 'SingingTheFaith',
47+ 'prefix': 'singingTheFaith',
48+ 'filter': '%s (*.txt)' % translate('SongsPlugin.ImportWizardForm', 'Singing The Faith Exported Files'),
49+ 'descriptionText': translate('SongsPlugin.ImportWizardForm',
50+ 'First use Singing The Faith Electonic edition to export '
51+ 'the song(s) in Text format.')
52+ },
53 SongBeamer: {
54 'class': SongBeamerImport,
55 'name': 'SongBeamer',
56@@ -462,6 +473,7 @@
57 SongFormat.PowerSong,
58 SongFormat.PresentationManager,
59 SongFormat.ProPresenter,
60+ SongFormat.SingingTheFaith,
61 SongFormat.SongBeamer,
62 SongFormat.SongPro,
63 SongFormat.SongShowPlus,
64
65=== added file 'openlp/plugins/songs/lib/importers/singingthefaith.py'
66--- openlp/plugins/songs/lib/importers/singingthefaith.py 1970-01-01 00:00:00 +0000
67+++ openlp/plugins/songs/lib/importers/singingthefaith.py 2019-06-30 19:14:23 +0000
68@@ -0,0 +1,347 @@
69+# -*- coding: utf-8 -*-
70+# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
71+
72+###############################################################################
73+# OpenLP - Open Source Lyrics Projection #
74+# --------------------------------------------------------------------------- #
75+# Copyright (c) 2008-2019 OpenLP Developers #
76+# --------------------------------------------------------------------------- #
77+# This program is free software; you can redistribute it and/or modify it #
78+# under the terms of the GNU General Public License as published by the Free #
79+# Software Foundation; version 2 of the License. #
80+# #
81+# This program is distributed in the hope that it will be useful, but WITHOUT #
82+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
83+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
84+# more details. #
85+# #
86+# You should have received a copy of the GNU General Public License along #
87+# with this program; if not, write to the Free Software Foundation, Inc., 59 #
88+# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
89+###############################################################################
90+"""
91+The :mod:`singingthefaith` module provides the functionality for importing songs which are
92+exported from Singing The Faith - an Authorised songbook for the Methodist Church of
93+Great Britain."""
94+
95+import logging
96+import re
97+from pathlib import Path
98+
99+from openlp.core.common.i18n import translate
100+from openlp.plugins.songs.lib.importers.songimport import SongImport
101+
102+log = logging.getLogger(__name__)
103+
104+
105+class SingingTheFaithImport(SongImport):
106+ """
107+ Import songs exported from SingingTheFaith
108+ """
109+
110+ hints_available = False
111+ checks_needed = True
112+ hintline = {}
113+ hintfile_version = '0'
114+ hint_verseOrder = ''
115+ hint_songtitle = ''
116+ hint_comments = ''
117+ hint_ignoreIndent = False
118+
119+ def do_import(self):
120+ """
121+ Receive a single file or a list of files to import.
122+ """
123+ if not isinstance(self.import_source, list):
124+ return
125+ self.import_wizard.progress_bar.setMaximum(len(self.import_source))
126+ for file_path in self.import_source:
127+ if self.stop_import_flag:
128+ return
129+ with file_path.open('rt', encoding='cp1251') as song_file:
130+ self.do_import_file(song_file)
131+
132+ def do_import_file(self, file):
133+ """
134+ Process the SingingTheFaith file - pass in a file-like object, not a file path.
135+ """
136+ singingTheFaithVersion = 1
137+ self.set_defaults()
138+ # Setup variables
139+ line_number = 0
140+ old_indent = 0
141+ # The chorus indent is how many spaces the chorus is indented - it might be 6,
142+ # but we test for >= and I do not know how consistent to formatting of the
143+ # exported songs is.
144+ chorus_indent = 5
145+ song_title = 'STF000 -'
146+ song_number = '0'
147+ ccli = '0'
148+ current_verse = ''
149+ current_verse_type = 'v'
150+ current_verse_number = 1
151+ # Potentially we could try to track current chorus number to automatically handle
152+ # more than 1 chorus, currently unused.
153+ # current_chorus_number = 1
154+ has_chorus = False
155+ chorus_written = False
156+ auto_verse_order_ok = False
157+ copyright = ''
158+ # the check_flag is prepended to the title, removed if the import should be OK
159+ # all the songs which need manual editing should sort below all the OK songs
160+ check_flag = 'z'
161+
162+ self.add_comment("Imported with Singing The Faith Importer v " + str(singingTheFaithVersion))
163+
164+ # Get the file_song_number - so we can use it for hints
165+ filename = Path(file.name)
166+ song_number_file = filename.stem
167+ song_number_match = re.search(r'\d+', song_number_file)
168+ if song_number_match:
169+ song_number_file = song_number_match.group()
170+
171+ # See if there is a hints file in the same location as the file
172+ dir_path = filename.parent
173+ hints_file_path = dir_path / 'hints.tag'
174+ try:
175+ with hints_file_path.open('r') as hints_file:
176+ hints_available = self.read_hints(hints_file, song_number_file)
177+ except FileNotFoundError:
178+ hints_available = False
179+
180+ try:
181+ for line in file:
182+ line_number += 1
183+ if hints_available and (str(line_number) in self.hintline):
184+ hint = self.hintline[str(line_number)]
185+ if hint == "Comment":
186+ line.strip()
187+ self.add_comment(line)
188+ line_number += 1
189+ next(file)
190+ continue
191+ elif hint == "Ignore":
192+ line_number += 1
193+ next(file)
194+ continue
195+ elif hint == "Author":
196+ # add as a raw author - do not split and make them a words author
197+ line.strip()
198+ self.add_author(line, 'words')
199+ line_number += 1
200+ next(file)
201+ continue
202+ elif hint.startswith("VariantVerse"):
203+ (vv, hintverse, replace) = hint.split(" ", 2)
204+ this_verse = self.verses[int(hintverse) - 1]
205+ this_verse_str = this_verse[1]
206+ new_verse = this_verse_str
207+ # There might be multiple replace pairs separated by |
208+ replaces = replace.split("|")
209+ for rep in replaces:
210+ (source_str, dest_str) = rep.split("/")
211+ new_verse = new_verse.replace(source_str, dest_str)
212+ self.add_verse(new_verse, 'v')
213+ self.verse_order_list.append('v' + str(current_verse_number))
214+ current_verse_number += 1
215+ line_number += 1
216+ next(file)
217+ continue
218+ else:
219+ self.log_error(translate('SongsPlugin.SingingTheFaithImport', 'File %s' % file.name),
220+ translate('SongsPlugin.SingingTheFaithImport', 'Unknown hint %s' % hint))
221+ return
222+ # STF exported lines have a leading verse number at the start of each verse.
223+ # remove them - note that we want to track the indent as that shows a chorus
224+ # so will deal with that before stipping all leading spaces.
225+ indent = 0
226+ if line.strip():
227+ verse_num_match = re.search(r'^\d+', line)
228+ if verse_num_match:
229+ # Could extract the verse number and check it against the calculated
230+ # verse number - TODO
231+ # verse_num = verse_num_match.group()
232+ line = line.lstrip("0123456789")
233+ indent_match = re.search(r'^\s+', line)
234+ if indent_match:
235+ indent = len(indent_match.group())
236+ # Assuming we have sorted out what is verse and what is chorus, strip lines,
237+ # unless ignoreIndent
238+ if self.hint_ignoreIndent:
239+ line = line.rstrip()
240+ else:
241+ line = line.strip()
242+ if line_number == 2:
243+ # note that songs seem to start with a blank line
244+ song_title = line
245+ # Detect the 'Reproduced from Singing the Faith Electronic Words Edition' line
246+ if line.startswith('Reproduced from Singing the Faith Electronic Words Edition'):
247+ song_number_match = re.search(r'\d+', line)
248+ if song_number_match:
249+ song_number = song_number_match.group()
250+ continue
251+ # If the indent is 0 and it contains '(c)' then it is a Copyright line
252+ elif (indent == 0) and ("(c)" in line):
253+ copyright = line
254+ continue
255+ elif (indent == 0) and (line.startswith('Liturgical ')):
256+ self.add_comment(line)
257+ continue
258+ elif (indent == 0) and (line.startswith('From The ')):
259+ self.add_comment(line)
260+ continue
261+ elif (indent == 0) and (line.startswith('From Common ')):
262+ self.add_comment(line)
263+ continue
264+ # If indent is 0 it may be the author, unless it was one of the cases covered above
265+ elif (indent == 0) and len(line) > 0:
266+ # May have more than one author, separated by ' and '
267+ authors = line.split(' and ')
268+ for a in authors:
269+ self.parse_author(a)
270+ continue
271+ if line == '':
272+ if current_verse != '':
273+ self.add_verse(current_verse, current_verse_type)
274+ self.verse_order_list.append(current_verse_type + str(current_verse_number))
275+ if current_verse_type == 'c':
276+ chorus_written = True
277+ else:
278+ current_verse_number += 1
279+ current_verse = ''
280+ if chorus_written:
281+ current_verse_type = 'v'
282+ else:
283+ # If the line is indented more than or equal chorus_indent then assume it is a chorus
284+ # If the indent has just changed then start a new verse just like hitting a blank line
285+ if not self.hint_ignoreIndent and ((indent >= chorus_indent) and (old_indent < indent)):
286+ if current_verse != '':
287+ self.add_verse(current_verse, current_verse_type)
288+ self.verse_order_list.append(current_verse_type + str(current_verse_number))
289+ if current_verse_type == 'v':
290+ current_verse_number += 1
291+ current_verse = line
292+ current_verse_type = 'c'
293+ old_indent = indent
294+ chorus_written = False
295+ has_chorus = True
296+ continue
297+ if current_verse == '':
298+ current_verse += line
299+ else:
300+ current_verse += '\n' + line
301+ old_indent = indent
302+ except Exception as e:
303+ self.log_error(translate('SongsPlugin.SingingTheFaithImport', 'File %s' % file.name),
304+ translate('SongsPlugin.SingingTheFaithImport', 'Error: %s') % e)
305+ return
306+
307+ if self.hint_songtitle:
308+ song_title = self.hint_songtitle
309+ self.title = check_flag + "STF" + song_number.zfill(3) + " - " + song_title
310+ self.song_book_name = "Singing The Faith"
311+ self.song_number = song_number
312+ self.ccli_number = ccli
313+ self.add_copyright(copyright)
314+# If we have a chorus then the generated Verse order can not be used directly, but we can generate
315+# one for two special cases - Verse followed by one chorus (to be repeated after every verse)
316+# of Chorus, followed by verses. If hints for ManualCheck or VerseOrder are supplied ignore this
317+ if has_chorus and not self.hint_verseOrder and not self.checks_needed:
318+ auto_verse_order_ok = False
319+ # Popular case V1 C2 V2 ...
320+ if len(self.verse_order_list) >= 1: # protect against odd cases
321+ if (self.verse_order_list[0] == "v1") and (self.verse_order_list[1] == "c2"):
322+ new_verse_order_list = ['v1', 'c1']
323+ i = 2
324+ auto_verse_order_ok = True
325+ elif (self.verse_order_list[0] == "c1") and (self.verse_order_list[1] == "v1"):
326+ new_verse_order_list = ['c1', 'v1', 'c1']
327+ i = 2
328+ auto_verse_order_ok = True
329+ # if we are in a case we can deal with
330+ if auto_verse_order_ok:
331+ while i < len(self.verse_order_list):
332+ if self.verse_order_list[i].startswith('v'):
333+ new_verse_order_list.append(self.verse_order_list[i])
334+ new_verse_order_list.append("c1")
335+ else:
336+ # Would like to notify, but want a warning, which we will do via the
337+ # Check_needed mechanism, as log_error aborts input of that song.
338+ # self.log_error(translate('SongsPlugin.SingingTheFaithImport', 'File %s' % file.name),
339+ # 'Error: Strange verse order entry ' + self.verse_order_list[i])
340+ auto_verse_order_ok = False
341+ i += 1
342+ self.verse_order_list = new_verse_order_list
343+ else:
344+ if not auto_verse_order_ok:
345+ self.verse_order_list = []
346+ if self.hint_verseOrder:
347+ self.verse_order_list = self.hint_verseOrder.split(',')
348+ if self.hint_comments:
349+ self.add_comment(self.hint_comments)
350+ # Write the title last as by now we will know if we need checks
351+ if hints_available and not self.checks_needed:
352+ check_flag = ''
353+ elif not hints_available and not has_chorus:
354+ check_flag = ''
355+ elif not hints_available and has_chorus and auto_verse_order_ok:
356+ check_flag = ''
357+ self.title = check_flag + "STF" + song_number.zfill(3) + " - " + song_title
358+ if not self.finish():
359+ self.log_error(file.name)
360+
361+ def read_hints(self, file, song_number):
362+ hintfound = False
363+ self.hint_verseOrder = ''
364+ self.hintline.clear()
365+ self.hint_comments = ''
366+ self.hint_songtitle = ''
367+ self.hint_ignoreIndent = False
368+ for tl in file:
369+ if not tl.strip():
370+ return hintfound
371+ tagval = tl.split(':')
372+ tag = tagval[0].strip()
373+ val = tagval[1].strip()
374+ if tag == "Version":
375+ self.hintfile_version = val
376+ continue
377+ if (tag == "Hymn") and (val == song_number):
378+ self.add_comment("Using hints version " + str(self.hintfile_version))
379+ hintfound = True
380+ # Assume, unless the hints has ManualCheck that if hinted all will be OK
381+ self.checks_needed = False
382+ for tl in file:
383+ tagval = tl.split(':')
384+ tag = tagval[0].strip()
385+ val = tagval[1].strip()
386+ if tag == "End":
387+ return hintfound
388+ elif tag == "CommentsLine":
389+ vals = val.split(',')
390+ for v in vals:
391+ self.hintline[v] = "Comment"
392+ elif tag == "IgnoreLine":
393+ vals = val.split(',')
394+ for v in vals:
395+ self.hintline[v] = "Ignore"
396+ elif tag == "AuthorLine":
397+ vals = val.split(',')
398+ for v in vals:
399+ self.hintline[v] = "Author"
400+ elif tag == "VerseOrder":
401+ self.hint_verseOrder = val
402+ elif tag == "ManualCheck":
403+ self.checks_needed = True
404+ elif tag == "IgnoreIndent":
405+ self.hint_ignoreIndent = True
406+ elif tag == "VariantVerse":
407+ vvline = val.split(' ', 1)
408+ self.hintline[vvline[0].strip()] = "VariantVerse " + vvline[1].strip()
409+ elif tag == "SongTitle":
410+ self.hint_songtitle = val
411+ elif tag == "AddComment":
412+ self.hint_comments += '\n' + val
413+ else:
414+ self.log_error(file.name, "Unknown tag " + tag + " value " + val)
415+ return hintfound
416
417=== added file 'tests/functional/openlp_plugins/songs/test_singingthefaithimport.py'
418--- tests/functional/openlp_plugins/songs/test_singingthefaithimport.py 1970-01-01 00:00:00 +0000
419+++ tests/functional/openlp_plugins/songs/test_singingthefaithimport.py 2019-06-30 19:14:23 +0000
420@@ -0,0 +1,48 @@
421+# -*- coding: utf-8 -*-
422+# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
423+
424+##########################################################################
425+# OpenLP - Open Source Lyrics Projection #
426+# ---------------------------------------------------------------------- #
427+# Copyright (c) 2008-2019 OpenLP Developers #
428+# ---------------------------------------------------------------------- #
429+# This program is free software: you can redistribute it and/or modify #
430+# it under the terms of the GNU General Public License as published by #
431+# the Free Software Foundation, either version 3 of the License, or #
432+# (at your option) any later version. #
433+# #
434+# This program is distributed in the hope that it will be useful, #
435+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
436+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
437+# GNU General Public License for more details. #
438+# #
439+# You should have received a copy of the GNU General Public License #
440+# along with this program. If not, see <https://www.gnu.org/licenses/>. #
441+##########################################################################
442+"""
443+This module contains tests for the SingingTheFaith song importer.
444+"""
445+from tests.helpers.songfileimport import SongImportTestHelper
446+from tests.utils.constants import RESOURCE_PATH
447+
448+
449+TEST_PATH = RESOURCE_PATH / 'songs' / 'singingthefaith'
450+
451+
452+class TestSingingTheFaithFileImport(SongImportTestHelper):
453+
454+ def __init__(self, *args, **kwargs):
455+ self.importer_class_name = 'SingingTheFaithImport'
456+ self.importer_module_name = 'singingthefaith'
457+ super(TestSingingTheFaithFileImport, self).__init__(*args, **kwargs)
458+
459+ def test_song_import(self):
460+ """
461+ Test that loading a Singing The Faith file works correctly on various files
462+ """
463+ # Single verse
464+ self.file_import([TEST_PATH / 'H1.txt'],
465+ self.load_external_result_data(TEST_PATH / 'STF001.json'))
466+ # Whole song - currently not working - test needs debugging.
467+ # self.file_import([TEST_PATH / 'H2.txt'],
468+ # self.load_external_result_data(TEST_PATH / 'STF002.json'))
469
470=== modified file 'tests/helpers/songfileimport.py'
471--- tests/helpers/songfileimport.py 2019-05-22 06:47:00 +0000
472+++ tests/helpers/songfileimport.py 2019-06-30 19:14:23 +0000
473@@ -123,7 +123,8 @@
474 log.debug("Song copyright imported: %s" % importer.song_number)
475 log.debug("Topics imported: %s" % importer.topics)
476
477- assert importer.title == title, 'title for %s should be "%s"' % (source_file_name, title)
478+ assert importer.title == title, \
479+ 'title for %s should be "%s" and is "%s"' % (source_file_name, title, importer.title)
480 for author in author_calls:
481 if isinstance(author, str):
482 self.mocked_add_author.assert_any_call(author)
483
484=== added directory 'tests/resources/songs/singingthefaith'
485=== added file 'tests/resources/songs/singingthefaith/H1.txt'
486--- tests/resources/songs/singingthefaith/H1.txt 1970-01-01 00:00:00 +0000
487+++ tests/resources/songs/singingthefaith/H1.txt 2019-06-30 19:14:23 +0000
488@@ -0,0 +1,9 @@
489+
490+1 Amazing Grace! how sweet the sound!
491+ That saved a wretch like me!
492+ I once was lost, but now am found;
493+ Was blind, but now I see.
494+
495+John Newton (d. 1807)
496+
497+Reproduced from Singing the Faith Electronic Words Edition, number 1 - or not as this is a hand made test file
498
499=== added file 'tests/resources/songs/singingthefaith/H2.txt'
500--- tests/resources/songs/singingthefaith/H2.txt 1970-01-01 00:00:00 +0000
501+++ tests/resources/songs/singingthefaith/H2.txt 2019-06-30 19:14:23 +0000
502@@ -0,0 +1,30 @@
503+
504+1 Amazing Grace! how sweet the sound!
505+ That saved a wretch like me!
506+ I once was lost, but now am found;
507+ Was blind, but now I see.
508+
509+2 'Twas grace that taught my heart to fear,
510+ And grace my fears relieved.
511+ How precious did that grace appear,
512+ The hour I first believed.
513+
514+3 The Lord has promised good to me,
515+ His Word my hope secures.
516+ He will my shield and portion be
517+ As long as life endures.
518+
519+4 Thro' many dangers, toils and snares
520+ I have already come.
521+ 'Tis grace that brought me safe thus far,
522+ And grace will lead me home.
523+
524+5 When we've been there ten thousand years,
525+ Bright shining as the sun,
526+ We've no less days to sing God's praise,
527+ Than when we first begun.
528+
529+
530+John Newton (d. 1807)
531+
532+Reproduced from Singing the Faith Electronic Words Edition, number 2 - or not as this is a hand made test file
533
534=== added file 'tests/resources/songs/singingthefaith/STF001.json'
535--- tests/resources/songs/singingthefaith/STF001.json 1970-01-01 00:00:00 +0000
536+++ tests/resources/songs/singingthefaith/STF001.json 2019-06-30 19:14:23 +0000
537@@ -0,0 +1,13 @@
538+{
539+ "title": "STF001 - Amazing Grace! how sweet the sound!",
540+ "authors": [
541+ "John Newton (d. 1807)"
542+ ],
543+ "verse_order_list": ["v1"],
544+ "verses": [
545+ [
546+ "Amazing Grace! how sweet the sound!\nThat saved a wretch like me!\nI once was lost, but now am found;\nWas blind, but now I see.",
547+ "v"
548+ ]
549+ ]
550+}
551
552=== added file 'tests/resources/songs/singingthefaith/STF002.json'
553--- tests/resources/songs/singingthefaith/STF002.json 1970-01-01 00:00:00 +0000
554+++ tests/resources/songs/singingthefaith/STF002.json 2019-06-30 19:14:23 +0000
555@@ -0,0 +1,29 @@
556+{
557+ "title": "STF002 - Amazing Grace! how sweet the sound!",
558+ "authors": [
559+ "John Newton (d. 1807)"
560+ ],
561+ "verse_order_list": ["v1", "v2", "v3", "v4", "v5"],
562+ "verses": [
563+ [
564+ "Amazing Grace! how sweet the sound!\nThat saved a wretch like me!\nI once was lost, but now am found;\nWas blind, but now I see.",
565+ "v"
566+ ],
567+ [
568+ "'Twas grace that taught my heart to fear,\nAnd grace my fears relieved.\nHow precious did that grace appear,\nThe hour I first believed.",
569+ "v"
570+ ],
571+ [
572+ "The Lord has promised good to me,\nHis Word my hope secures.\nHe will my shield and portion be\nAs long as life endures.",
573+ "v"
574+ ],
575+ [
576+ "Thro' many dangers, toils and snares\nI have already come.\n'Tis grace that brought me safe thus far,\nAnd grace will lead me home.",
577+ "v"
578+ ],
579+ [
580+ "When we've been there ten thousand years,\nBright shining as the sun,\nWe've no less days to sing God's praise,\nThan when we first begun.",
581+ "v"
582+ ]
583+ ]
584+}