Added importer for Lyrix and VideoPsalm + tests.

Added support for author-type in importers.
Migrated songselect and songbeamer tests to the SongImportTestHelper based structure.

bzr-revno: 2575
Fixes: https://launchpad.net/bugs/1509550
This commit is contained in:
second@tgc.dk 2015-12-21 09:47:19 +01:00 committed by Tomas Groth
commit 0baa733c91
21 changed files with 738 additions and 129 deletions

View File

@ -46,6 +46,8 @@ from .importers.propresenter import ProPresenterImport
from .importers.worshipassistant import WorshipAssistantImport
from .importers.powerpraise import PowerPraiseImport
from .importers.presentationmanager import PresentationManagerImport
from .importers.lyrix import LyrixImport
from .importers.videopsalm import VideoPsalmImport
log = logging.getLogger(__name__)
@ -166,6 +168,8 @@ class SongFormat(object):
WorshipAssistant = 21
WorshipCenterPro = 22
ZionWorx = 23
Lyrix = 24
VideoPsalm = 25
# Set optional attribute defaults
__defaults__ = {
@ -244,6 +248,13 @@ class SongFormat(object):
'prefix': 'foilPresenter',
'filter': '%s (*.foil)' % translate('SongsPlugin.ImportWizardForm', 'Foilpresenter Song Files')
},
Lyrix: {
'class': LyrixImport,
'name': 'LyriX',
'prefix': 'lyrix',
'filter': '%s (*.txt)' % translate('SongsPlugin.ImportWizardForm', 'LyriX Files'),
'comboBoxText': translate('SongsPlugin.ImportWizardForm', 'LyriX (Exported TXT-files)')
},
MediaShout: {
'name': 'MediaShout',
'prefix': 'mediaShout',
@ -324,6 +335,16 @@ class SongFormat(object):
'prefix': 'sundayPlus',
'filter': '%s (*.ptf)' % translate('SongsPlugin.ImportWizardForm', 'SundayPlus Song Files')
},
VideoPsalm: {
'class': VideoPsalmImport,
'name': 'VideoPsalm',
'prefix': 'videopsalm',
'selectMode': SongFormatSelect.SingleFile,
'filter': '%s (*.json)' % translate('SongsPlugin.ImportWizardForm', 'VideoPsalm Files'),
'comboBoxText': translate('SongsPlugin.ImportWizardForm', 'VideoPsalm'),
'descriptionText': translate('SongsPlugin.ImportWizardForm', 'The VideoPsalm songbooks are normally located'
' in %s') % 'C:\\Users\\Public\\Documents\\VideoPsalm\\SongBooks\\'
},
WordsOfWorship: {
'class': WordsOfWorshipImport,
'name': 'Words of Worship',
@ -393,7 +414,9 @@ class SongFormat(object):
SongFormat.WordsOfWorship,
SongFormat.WorshipAssistant,
SongFormat.WorshipCenterPro,
SongFormat.ZionWorx
SongFormat.ZionWorx,
SongFormat.Lyrix,
SongFormat.VideoPsalm
]
@staticmethod

View File

@ -48,7 +48,7 @@ class CCLIFileImport(SongImport):
:param manager: The song manager for the running OpenLP installation.
:param kwargs: The files to be imported.
"""
SongImport.__init__(self, manager, **kwargs)
super(CCLIFileImport, self).__init__(manager, **kwargs)
def do_import(self):
"""
@ -161,7 +161,7 @@ class CCLIFileImport(SongImport):
elif line.startswith('Author='):
song_author = line[7:].strip()
elif line.startswith('Copyright='):
self.copyright = line[10:].strip()
self.add_copyright(line[10:].strip())
elif line.startswith('Themes='):
song_topics = line[7:].strip().replace(' | ', '/t')
elif line.startswith('Fields='):
@ -318,14 +318,14 @@ class CCLIFileImport(SongImport):
if line_number == 2:
line_number += 1
if clean_line.startswith('©'):
self.copyright = clean_line
self.add_copyright(clean_line)
else:
song_author = clean_line
# n=3, authors
elif line_number == 3:
line_number += 1
if song_author:
self.copyright = clean_line
self.add_copyright(clean_line)
else:
song_author = clean_line
# line_number=4, comments lines before last line

View File

@ -0,0 +1,115 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2015 OpenLP Developers #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
"""
The :mod:`lyrix` module provides the functionality for importing songs which are
exproted from Lyrix."""
import logging
import re
from openlp.core.common import translate
from openlp.plugins.songs.lib.importers.songimport import SongImport
log = logging.getLogger(__name__)
class LyrixImport(SongImport):
"""
Import songs exported from Lyrix
"""
def __init__(self, manager, **kwargs):
"""
Initialise the class.
"""
super(LyrixImport, self).__init__(manager, **kwargs)
def do_import(self):
"""
Receive a single file or a list of files to import.
"""
if not isinstance(self.import_source, list):
return
self.import_wizard.progress_bar.setMaximum(len(self.import_source))
for filename in self.import_source:
if self.stop_import_flag:
return
song_file = open(filename, 'rt', encoding='cp1251')
self.do_import_file(song_file)
song_file.close()
def do_import_file(self, file):
"""
Process the Lyrix file - pass in a file-like object, not a file path.
"""
self.set_defaults()
# Setup variables
line_number = 0
song_title = 'Standard Song Title'
ccli = '0'
current_verse = ''
verses = []
author = ''
copyright = ''
try:
# Read the file
for line in file:
line = line.strip()
line_number += 1
if line_number == 4:
song_title = line
if line_number < 7:
continue
# Detect and get CCLI number
if line.lower().startswith('ccli'):
ccli = re.findall('\d+', line)[0]
try:
# If the CCLI was found, we are near the end
# Find author
line = next(file).strip()
author = line[line.find(':') + 2:]
# Find copyright
copyright = next(file).strip()
except StopIteration:
pass
break
if line == '':
if current_verse != '':
verses.append(current_verse)
current_verse = ''
else:
if current_verse == '':
current_verse += line
else:
current_verse += '\n' + line
except Exception as e:
self.log_error(translate('SongsPlugin.LyrixImport', 'File %s' % file.name),
translate('SongsPlugin.LyrixImport', 'Error: %s') % e)
return
self.title = song_title
self.parse_author(author)
self.ccli_number = ccli
self.add_copyright(copyright)
for verse in verses:
self.add_verse(verse, 'v')
if not self.finish():
self.log_error(file.name)

View File

@ -255,13 +255,13 @@ class SongImport(QtCore.QObject):
if author2:
self.add_author(author2)
def add_author(self, author):
def add_author(self, author, type=None):
"""
Add an author to the list
"""
if author in self.authors:
if (author, type) in self.authors:
return
self.authors.append(author)
self.authors.append((author, type))
def add_media_file(self, filename, weight=0):
"""
@ -360,13 +360,13 @@ class SongImport(QtCore.QObject):
song.comments = self.comments
song.theme_name = self.theme_name
song.ccli_number = self.ccli_number
for author_text in self.authors:
for author_text, author_type in self.authors:
author = self.manager.get_object_filtered(Author, Author.display_name == author_text)
if not author:
author = Author.populate(display_name=author_text,
last_name=author_text.split(' ')[-1],
first_name=' '.join(author_text.split(' ')[:-1]))
song.add_author(author)
song.add_author(author, author_type)
if self.song_book_name:
song_book = self.manager.get_object_filtered(Book, Book.name == self.song_book_name)
if song_book is None:

View File

@ -0,0 +1,123 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2015 OpenLP Developers #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
"""
The :mod:`lyrix` module provides the functionality for importing songs which are
exproted from Lyrix."""
import logging
import json
import os
from openlp.core.common import translate
from openlp.plugins.songs.lib import VerseType
from openlp.plugins.songs.lib.importers.songimport import SongImport
from openlp.plugins.songs.lib.db import AuthorType
log = logging.getLogger(__name__)
class VideoPsalmImport(SongImport):
"""
Import songs exported from Lyrix
"""
def __init__(self, manager, **kwargs):
"""
Initialise the class.
"""
super(VideoPsalmImport, self).__init__(manager, **kwargs)
def do_import(self):
"""
Process the VideoPsalm file - pass in a file-like object, not a file path.
"""
self.set_defaults()
# Open SongBook file
song_file = open(self.import_source, 'rt', encoding='utf-8-sig')
try:
file_content = song_file.read()
processed_content = ''
inside_quotes = False
# The VideoPsalm format is not valid json, it uses illegal line breaks and unquoted keys, this must be fixed
file_content_it = iter(file_content)
for c in file_content_it:
if c == '"':
inside_quotes = not inside_quotes
# Detect invalid linebreak
if c == '\n':
if inside_quotes:
processed_content += '\\n'
# Put keys in quotes
elif c.isalnum() and not inside_quotes:
processed_content += '"' + c
c = next(file_content_it)
while c.isalnum():
processed_content += c
c = next(file_content_it)
processed_content += '"' + c
else:
processed_content += c
songbook = json.loads(processed_content.strip())
# Get song array
songs = songbook['Songs']
self.import_wizard.progress_bar.setMaximum(len(songs))
songbook_name = songbook['Text']
media_folder = os.path.normpath(os.path.join(os.path.dirname(song_file.name), '..', 'Audio'))
for song in songs:
self.song_book_name = songbook_name
if 'Text' in song:
self.title = song['Text']
composer = None
author = None
if 'Composer' in song:
composer = song['Composer']
if 'Author' in song:
author = song['Author']
if author and composer == author:
self.add_author(author, AuthorType.WordsAndMusic)
else:
if author:
self.add_author(author, AuthorType.Words)
if composer:
self.add_author(composer, AuthorType.Music)
if 'Copyright' in song:
self.add_copyright(song['Copyright'].replace('\n', ' ').strip())
if 'CCLI' in song:
self.ccli_number = song['CCLI']
if 'Theme' in song:
self.topics = song['Theme'].splitlines()
if 'AudioFile' in song:
self.add_media_file(os.path.join(media_folder, song['AudioFile']))
if 'Memo1' in song:
self.add_comment(song['Memo1'])
if 'Memo2' in song:
self.add_comment(song['Memo2'])
if 'Memo3' in song:
self.add_comment(song['Memo3'])
for verse in song['Verses']:
self.add_verse(verse['Text'], 'v')
if not self.finish():
self.log_error('Could not import %s' % self.title)
except Exception as e:
self.log_error(translate('SongsPlugin.VideoPsalmImport', 'File %s' % file.name),
translate('SongsPlugin.VideoPsalmImport', 'Error: %s') % e)
song_file.close()

View File

@ -0,0 +1,53 @@
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2015 OpenLP Developers #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
"""
This module contains tests for the LyriX song importer.
"""
import os
from unittest import TestCase
from tests.helpers.songfileimport import SongImportTestHelper
from openlp.plugins.songs.lib.importers.opensong import OpenSongImport
from openlp.core.common import Registry
from tests.functional import patch, MagicMock
TEST_PATH = os.path.abspath(
os.path.join(os.path.dirname(__file__), '..', '..', '..', 'resources', 'lyrixsongs'))
class TestLyrixFileImport(SongImportTestHelper):
def __init__(self, *args, **kwargs):
self.importer_class_name = 'LyrixImport'
self.importer_module_name = 'lyrix'
super(TestLyrixFileImport, self).__init__(*args, **kwargs)
def test_song_import(self):
"""
Test that loading an LyriX file works correctly on various files
"""
self.file_import([os.path.join(TEST_PATH, 'A06.TXT')],
self.load_external_result_data(os.path.join(TEST_PATH, 'Amazing Grace.json')))
self.file_import([os.path.join(TEST_PATH, 'A002.TXT')],
self.load_external_result_data(os.path.join(TEST_PATH, 'Amazing Grace2.json')))
self.file_import([os.path.join(TEST_PATH, 'AO05.TXT')],
self.load_external_result_data(os.path.join(TEST_PATH, 'in die regterhand.json')))

View File

@ -26,27 +26,28 @@ This module contains tests for the Songbeamer song importer.
import os
from unittest import TestCase
from tests.helpers.songfileimport import SongImportTestHelper
from tests.functional import MagicMock, patch
from openlp.plugins.songs.lib.importers.songbeamer import SongBeamerImport
from openlp.plugins.songs.lib import VerseType
from openlp.core.common import Registry
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!\nAnbetung und Lob Ihm gebühret.\n', 'v'),
('2. Lobsingt Seiner Lieb´,\ndie einzig ihn trieb,\nzu sterben für unsere Sünden!\n', 'v'),
('3. Lobsingt Seiner Macht!\nSein Werk ist vollbracht:\nEr sitzet zur Rechten des Vaters.\n', 'v'),
('4. Lobsingt seiner Treu´,\ndie immerdar neu,\nbis Er uns zur Herrlichket führet!\n\n', 'v')
],
'song_book_name': 'Glaubenslieder I',
'song_number': "1",
'authors': ['Carl Brockhaus', 'Johann Jakob Vetter']
}
}
class TestSongBeamerFileImport(SongImportTestHelper):
def __init__(self, *args, **kwargs):
self.importer_class_name = 'SongBeamerImport'
self.importer_module_name = 'songbeamer'
super(TestSongBeamerFileImport, self).__init__(*args, **kwargs)
def test_song_import(self):
"""
Test that loading an OpenSong file works correctly on various files
"""
self.file_import([os.path.join(TEST_PATH, 'Lobsinget dem Herrn.sng')],
self.load_external_result_data(os.path.join(TEST_PATH, 'Lobsinget dem Herrn.json')))
class TestSongBeamerImport(TestCase):
@ -115,51 +116,6 @@ class TestSongBeamerImport(TestCase):
'do_import 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.importers.songbeamer.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, filenames=[])
importer.import_wizard = mocked_import_wizard
importer.stop_import_flag = False
importer.add_verse = 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']
song_authors = SONG_TEST_DATA[song_file]['authors']
# THEN: do_import should return none, the song data should be as expected, and finish should have been
# called.
self.assertIsNone(importer.do_import(), 'do_import should return None when it has completed')
self.assertEqual(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.assertEqual(importer.song_book_name, song_book_name,
'song_book_name for %s should be "%s"' % (song_file, song_book_name))
if song_number:
self.assertEqual(importer.song_number, song_number,
'song_number for %s should be %s' % (song_file, song_number))
if song_authors:
for author in importer.authors:
self.assertIn(author, song_authors)
mocked_finish.assert_called_with()
def check_verse_marks_test(self):
"""
Tests different lines to see if a verse mark is detected or not

View File

@ -28,6 +28,7 @@ from urllib.error import URLError
from PyQt4 import QtGui
from tests.helpers.songfileimport import SongImportTestHelper
from openlp.core import Registry
from openlp.plugins.songs.forms.songselectform import SongSelectForm, SearchWorker
from openlp.plugins.songs.lib import Song
@ -37,6 +38,9 @@ from openlp.plugins.songs.lib.importers.cclifile import CCLIFileImport
from tests.functional import MagicMock, patch, call
from tests.helpers.testmixin import TestMixin
TEST_PATH = os.path.abspath(
os.path.join(os.path.dirname(__file__), '..', '..', '..', 'resources', 'songselect'))
class TestSongSelectImport(TestCase, TestMixin):
"""
@ -645,68 +649,21 @@ class TestSongSelectForm(TestCase, TestMixin):
mocked_view_button.setEnabled.assert_called_with(True)
class TestSongSelectFileImport(TestCase, TestMixin):
"""
Test SongSelect file import
"""
def setUp(self):
"""
Initial setups
"""
Registry.create()
test_song_name = 'TestSong'
self.file_name = os.path.join('tests', 'resources', 'songselect', test_song_name)
self.title = 'Test Song'
self.ccli_number = '0000000'
self.authors = ['Author One', 'Author Two']
self.topics = ['Adoration', 'Praise']
class TestSongSelectFileImport(SongImportTestHelper):
def songselect_import_bin_file_test(self):
"""
Verify import SongSelect BIN file parses file properly
"""
# GIVEN: Text file to import and mocks
copyright_bin = '2011 OpenLP Programmer One (Admin. by OpenLP One) | ' \
'Openlp Programmer Two (Admin. by OpenLP Two)'
verses_bin = [
['v1', 'Line One Verse One\nLine Two Verse One\nLine Three Verse One\nLine Four Verse One', None],
['v2', 'Line One Verse Two\nLine Two Verse Two\nLine Three Verse Two\nLine Four Verse Two', None]
]
song_import = CCLIFileImport(manager=None, filename=['{}.bin'.format(self.file_name)])
def __init__(self, *args, **kwargs):
self.importer_class_name = 'CCLIFileImport'
self.importer_module_name = 'cclifile'
super(TestSongSelectFileImport, self).__init__(*args, **kwargs)
with patch.object(song_import, 'import_wizard'), patch.object(song_import, 'finish'):
# WHEN: We call the song importer
song_import.do_import()
# THEN: Song values should be equal to test values in setUp
self.assertEquals(song_import.title, self.title, 'Song title should match')
self.assertEquals(song_import.ccli_number, self.ccli_number, 'CCLI Song Number should match')
self.assertEquals(song_import.authors, self.authors, 'Author(s) should match')
self.assertEquals(song_import.copyright, copyright_bin, 'Copyright should match')
self.assertEquals(song_import.topics, self.topics, 'Theme(s) should match')
self.assertEquals(song_import.verses, verses_bin, 'Verses should match with test verses')
def songselect_import_text_file_test(self):
def test_song_import(self):
"""
Verify import SongSelect TEXT file parses file properly
Test that loading an OpenSong file works correctly on various files
"""
# GIVEN: Text file to import and mocks
copyright_txt = '© 2011 OpenLP Programmer One (Admin. by OpenLP One)'
verses_txt = [
['v1', 'Line One Verse One\r\nLine Two Verse One\r\nLine Three Verse One\r\nLine Four Verse One', None],
['v2', 'Line One Verse Two\r\nLine Two Verse Two\r\nLine Three Verse Two\r\nLine Four Verse Two', None]
]
song_import = CCLIFileImport(manager=None, filename=['{}.txt'.format(self.file_name)])
with patch.object(song_import, 'import_wizard'), patch.object(song_import, 'finish'):
# WHEN: We call the song importer
song_import.do_import()
# THEN: Song values should be equal to test values in setUp
self.assertEquals(song_import.title, self.title, 'Song title should match')
self.assertEquals(song_import.ccli_number, self.ccli_number, 'CCLI Song Number should match')
self.assertEquals(song_import.authors, self.authors, 'Author(s) should match')
self.assertEquals(song_import.copyright, copyright_txt, 'Copyright should match')
self.assertEquals(song_import.verses, verses_txt, 'Verses should match with test verses')
self.file_import([os.path.join(TEST_PATH, 'TestSong.bin')],
self.load_external_result_data(os.path.join(TEST_PATH, 'TestSong-bin.json')))
self.file_import([os.path.join(TEST_PATH, 'TestSong.txt')],
self.load_external_result_data(os.path.join(TEST_PATH, 'TestSong-txt.json')))
class TestSearchWorker(TestCase, TestMixin):

View File

@ -0,0 +1,49 @@
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2015 OpenLP Developers #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
"""
This module contains tests for the VideoPsalm song importer.
"""
import os
from unittest import TestCase
from tests.helpers.songfileimport import SongImportTestHelper
from openlp.plugins.songs.lib.importers.opensong import OpenSongImport
from openlp.core.common import Registry
from tests.functional import patch, MagicMock
TEST_PATH = os.path.abspath(
os.path.join(os.path.dirname(__file__), '..', '..', '..', 'resources', 'videopsalmsongs'))
class TestVideoPsalmFileImport(SongImportTestHelper):
def __init__(self, *args, **kwargs):
self.importer_class_name = 'VideoPsalmImport'
self.importer_module_name = 'videopsalm'
super(TestVideoPsalmFileImport, self).__init__(*args, **kwargs)
def test_song_import(self):
"""
Test that loading an VideoPsalm file works correctly on various files
"""
self.file_import(os.path.join(TEST_PATH, 'videopsalm-as-safe-a-stronghold.json'),
self.load_external_result_data(os.path.join(TEST_PATH, 'as-safe-a-stronghold.json')))

View File

@ -124,7 +124,10 @@ class SongImportTestHelper(TestCase):
self.assertEqual(importer.title, title, 'title for %s should be "%s"' % (source_file_name, title))
for author in author_calls:
self.mocked_add_author.assert_any_call(author)
if isinstance(author, str):
self.mocked_add_author.assert_any_call(author)
else:
self.mocked_add_author.assert_any_call(*author)
if song_copyright:
self.mocked_add_copyright.assert_called_with(song_copyright)
if ccli_number:

View File

@ -0,0 +1,34 @@
-------------
A002
AMAZING GRACE
-------------
1. AMAZING GRACE! HOW SWEET THE SOUND
THAT SAVED A WRETCH LIKE ME;
I ONCE WAS LOST, BUT NOW AM FOUND;
WAS BLIND, BUT NOW I SEE.
2. 'TWAS GRACE THAT TAUGHT MY HEART TO FEAR
AND GRACE MY FEARS RELIEVED;
HOW PRECIOUS DID THAT GRACE APPEAR,
THE HOUR I FIRST BELIEVED!
3. THROUGH MANY DANGERS, TRIALS AND SNARES
I HAVE ALREADY COME;
'TIS GRACE THAT BROUGHT ME SAFE THUS FAR
AND GRACE WILL LEAD ME HOME.
4. THE LORD HAS PROMISED GOOD TO ME,
HIS WORD MY HOPE SECURES;
HE WILL MY SHIELD AND FORTRESS BE
AS LONG AS LIFE ENDURES.
5. WHEN WE'VE BEEN THERE TEN THOUSAND YEARS
BRIGHT SHINING AS THE SUN,
WE'VE NO LESS DAYS TO SING GOD'S PRAISE
THAN WHEN WE'D FIRST BEGUN.
CCLI no.: 22025
Words/Music: Edwin Excell, John Newton, John P. Rees
Public Domain

View File

@ -0,0 +1,31 @@
----------------------------------
A06
AMAZING GRACE, HOW SWEET THE SOUND
----------------------------------
1. AMAZING GRACE, HOW SWEET THE SOUND
THAT SAVED A WRETCH LIKE ME
I ONCE WAS LOST, BUT NOW I'M FOUND
WAS BLIND, BUT NOW I SEE
2. 'TWAS GRACE THAT TAUGHT MY HEART TO FEAR
AND GRACE MY FEARS RELIEVED
HOW PRECIOUS DID THAT GRACE APPEAR
THE HOUR I FIRST BELIEVED
3. THROUGH MANY DANGERS, TOILS AND SNARES
I HAVE ALREADY COME, 'TWAS GRACE
THAT BROUGHT ME SAFE THUS FAR
AND GRACE WILL LEAD ME HOME
4. WHEN WE'VE BEEN THERE TEN THOUSAND YEARS
BRIGHT SHINING AS THE SUN
WE'VE NO LESS DAYS TO SING GOD'S PRAISE
THAN WHEN WE'VE FIRST BEGUN
5. PRAISE GOD, PRAISE GOD
PRAISE GOD, PRAISE GOD
PRAISE GOD, PRAISE GOD
PRAISE GOD..

View File

@ -0,0 +1,48 @@
--------------------------------
AO05
IN DIE REGTERHAND VAN HOM WAT IN
--------------------------------
1. IN DIE REGTERHAND VAN HOM
WAT IN MAJESTEIT REGEER
Lê DIE BOEKROL VAN VERLOSSING
SEWEMAAL VERSEëL
EN NIEMAND KON GEVIND WORD
OM SY SEëLS OOP TE BREEK
TOT DIE LAM VAN GOD NA VORE KOM
OM DIE BOEKROL SELF TE NEEM
DIE VIER-EN-TWINTIG OUDERLINGE
VAL TOE VOOR HOM NEER
SAAM MET AL DIE ENG'LE
IN DIE GANSE HEMELLEëR,
EN ELKE WESE WAT ASEM HET
OP DIE AARDE, IN DIE SEE, EN OOR DIE
LENGTE EN DIE BREEDTE
VAN DIE SKEPPING BRING HOM EER
2. HERE U ALLEEN IS WAARDIG
OM DIE LEWENSBOEK TE NEEM
EN U ALLEEN IS MAGTIG
OM SY SEëLS OOP TE BREEK,
WANT U'T VIR ONS GESTERWE,
MET U BLOED HET U BETAAL
OM ONS LOS TE KOOP
UIT ELKE STAM EN NASIE,VOLK EN TAAL
AL DIE LOF EN DIE KRAG
EN DIE EER
EN DIE HEERLIKHEID
EN RYKDON EN STERKTE
AAN U ALLEEN O HEER
AL DIE LOF EN DIE KRAG
EN DIE EER
EN WYSHEID AAN DIE LAM
OP DIE TROON
WAT NOU EN TOT IN
EWIGHEID REGEER
NOU EN TOT IN EWIGHEID
REGEER
DIE LAM WAT TOT IN
EWIGHEID REGEER

View File

@ -0,0 +1,26 @@
{
"title": "AMAZING GRACE, HOW SWEET THE SOUND",
"verse_order_list": [],
"verses": [
[
"1. AMAZING GRACE, HOW SWEET THE SOUND\nTHAT SAVED A WRETCH LIKE ME\nI ONCE WAS LOST, BUT NOW I'M FOUND\nWAS BLIND, BUT NOW I SEE",
"v"
],
[
"2. 'TWAS GRACE THAT TAUGHT MY HEART TO FEAR\nAND GRACE MY FEARS RELIEVED\nHOW PRECIOUS DID THAT GRACE APPEAR\nTHE HOUR I FIRST BELIEVED",
"v"
],
[
"3. THROUGH MANY DANGERS, TOILS AND SNARES\nI HAVE ALREADY COME, 'TWAS GRACE\nTHAT BROUGHT ME SAFE THUS FAR\nAND GRACE WILL LEAD ME HOME",
"v"
],
[
"4. 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'VE FIRST BEGUN",
"v"
],
[
"5. PRAISE GOD, PRAISE GOD\nPRAISE GOD, PRAISE GOD\nPRAISE GOD, PRAISE GOD\nPRAISE GOD..",
"v"
]
]
}

View File

@ -0,0 +1,33 @@
{
"authors": [
"John Newton",
"Edwin Excell",
"John P. Rees"
],
"ccli_number": "22025",
"copyright": "Public Domain",
"title": "AMAZING GRACE",
"verse_order_list": [],
"verses": [
[
"1. 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.",
"v"
],
[
"2. 'TWAS GRACE THAT TAUGHT MY HEART TO FEAR\nAND GRACE MY FEARS RELIEVED;\nHOW PRECIOUS DID THAT GRACE APPEAR,\nTHE HOUR I FIRST BELIEVED!",
"v"
],
[
"3. THROUGH MANY DANGERS, TRIALS AND SNARES\nI HAVE ALREADY COME;\n'TIS GRACE THAT BROUGHT ME SAFE THUS FAR\nAND GRACE WILL LEAD ME HOME.",
"v"
],
[
"4. THE LORD HAS PROMISED GOOD TO ME,\nHIS WORD MY HOPE SECURES;\nHE WILL MY SHIELD AND FORTRESS BE\nAS LONG AS LIFE ENDURES.",
"v"
],
[
"5. 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'D FIRST BEGUN.",
"v"
]
]
}

View File

@ -0,0 +1,18 @@
{
"title": "IN DIE REGTERHAND VAN HOM WAT IN",
"verse_order_list": [],
"verses": [
[
"1. IN DIE REGTERHAND VAN HOM\nWAT IN MAJESTEIT REGEER\nLк DIE BOEKROL VAN VERLOSSING\nSEWEMAAL VERSEлL\nEN NIEMAND KON GEVIND WORD\nOM SY SEлLS OOP TE BREEK\nTOT DIE LAM VAN GOD NA VORE KOM\nOM DIE BOEKROL SELF TE NEEM\nDIE VIER-EN-TWINTIG OUDERLINGE\nVAL TOE VOOR HOM NEER\nSAAM MET AL DIE ENG'LE\nIN DIE GANSE HEMELLEлR,\nEN ELKE WESE WAT ASEM HET\nOP DIE AARDE, IN DIE SEE, EN OOR DIE\nLENGTE EN DIE BREEDTE\nVAN DIE SKEPPING BRING HOM EER",
"v"
],
[
"2. HERE U ALLEEN IS WAARDIG\nOM DIE LEWENSBOEK TE NEEM\nEN U ALLEEN IS MAGTIG\nOM SY SEлLS OOP TE BREEK,\nWANT U'T VIR ONS GESTERWE,\nMET U BLOED HET U BETAAL\nOM ONS LOS TE KOOP\nUIT ELKE STAM EN NASIE,VOLK EN TAAL",
"v"
],
[
"AL DIE LOF EN DIE KRAG\nEN DIE EER\nEN DIE HEERLIKHEID\nEN RYKDON EN STERKTE\nAAN U ALLEEN O HEER\nAL DIE LOF EN DIE KRAG\nEN DIE EER\nEN WYSHEID AAN DIE LAM\nOP DIE TROON\nWAT NOU EN TOT IN\nEWIGHEID REGEER\nNOU EN TOT IN EWIGHEID\nREGEER\nDIE LAM WAT TOT IN\nEWIGHEID REGEER",
"v"
]
]
}

View File

@ -0,0 +1,12 @@
{
"title": "GL 1 - Lobsinget dem Herrn",
"verses": [
["1. Lobsinget dem Herrn,\no preiset Ihn gern!\nAnbetung und Lob Ihm gebühret.\n", "v"],
["2. Lobsingt Seiner Lieb´,\ndie einzig ihn trieb,\nzu sterben für unsere Sünden!\n", "v"],
["3. Lobsingt Seiner Macht!\nSein Werk ist vollbracht:\nEr sitzet zur Rechten des Vaters.\n", "v"],
["4. Lobsingt seiner Treu´,\ndie immerdar neu,\nbis Er uns zur Herrlichket führet!\n\n", "v"]
],
"song_book_name": "Glaubenslieder I",
"song_number": "1",
"authors": ["Carl Brockhaus", "Johann Jakob Vetter"]
}

View File

@ -0,0 +1,25 @@
{
"authors": [
"Author One",
"Author Two"
],
"ccli_number": "0000000",
"song_number": 0,
"title": "Test Song",
"topics": [
"Adoration",
"Praise"
],
"copyright": "2011 OpenLP Programmer One (Admin. by OpenLP One) | Openlp Programmer Two (Admin. by OpenLP Two)",
"verse_order_list": [],
"verses": [
[
"Line One Verse One\nLine Two Verse One\nLine Three Verse One\nLine Four Verse One\n",
"v"
],
[
"Line One Verse Two\nLine Two Verse Two\nLine Three Verse Two\nLine Four Verse Two\n",
"v"
]
]
}

View File

@ -0,0 +1,21 @@
{
"authors": [
"Author One",
"Author Two"
],
"ccli_number": "0000000",
"song_number": 0,
"title": "Test Song",
"copyright": "© 2011 OpenLP Programmer One (Admin. by OpenLP One)",
"verse_order_list": [],
"verses": [
[
"Line One Verse One\nLine Two Verse One\nLine Three Verse One\nLine Four Verse One\n",
"v"
],
[
"Line One Verse Two\nLine Two Verse Two\nLine Three Verse Two\nLine Four Verse Two\n",
"v"
]
]
}

View File

@ -0,0 +1,35 @@
{
"authors": [
["Martin Luther", "words"],
["Unknown", "music"]
],
"ccli_number": "12345",
"comments": "This is\nthe first comment\nThis is\nthe second comment\nThis is\nthe third comment\n",
"copyright": "Public Domain",
"song_book_name": "SongBook1",
"song_number": 0,
"title": "A Safe Stronghold Our God is Still",
"topics": [
"tema1",
"tema2"
],
"verse_order_list": [],
"verses": [
[
"As safe a stronghold our God is still,\nA trusty shield and weapon;\nHell help us clear from all the ill\nThat hath us now oertaken.\nThe ancient prince of hell\nHath risen with purpose fell;\nStrong mail of craft and power\nHe weareth in this hour;\nOn earth is not His fellow.",
"v"
],
[
"With force of arms we nothing can,\nFull soon were we down-ridden;\nBut for us fights the proper Man,\nWhom God Himself hath bidden.\nAsk ye: Who is this same?\nChrist Jesus is His name,\nThe Lord Sabaoths Son;\nHe, and no other one,\nShall conquer in the battle.",
"v"
],
[
"And were this world all devils oer,\nAnd watching to devour us,\nWe lay it not to heart so sore;\nNot they can overpower us.\nAnd let the prince of ill\nLook grim as eer he will,\nHe harms us not a whit;\nFor why? his doom is writ;\nA word shall quickly slay him.",
"v"
],
[
"Gods word, for all their craft and force,\nOne moment will not linger,\nBut, spite of hell, shall have its course;\nTis written by His finger.\nAnd though they take our life,\nGoods, honour, children, wife,\nYet is their profit small:\nThese things shall vanish all;\nThe city of God remaineth.",
"v"
]
]
}

View File

@ -0,0 +1,47 @@
{Abbreviation:"SB1",Copyright:"Public domain",Songs:[{ID:3,Composer:"Unknown",Author:"Martin Luther",Copyright:"Public
Domain",Theme:"tema1
tema2",CCLI:"12345",Alias:"A safe stronghold",Memo1:"This is
the first comment
",Memo2:"This is
the second comment
",Memo3:"This is
the third comment
",Reference:"reference",Guid:"jtCkrJdPIUOmECjaQylg/g",Verses:[{
Text:"As safe a stronghold our God is still,
A trusty shield and weapon;
Hell help us clear from all the ill
That hath us now oertaken.
The ancient prince of hell
Hath risen with purpose fell;
Strong mail of craft and power
He weareth in this hour;
On earth is not His fellow."},{ID:2,
Text:"With force of arms we nothing can,
Full soon were we down-ridden;
But for us fights the proper Man,
Whom God Himself hath bidden.
Ask ye: Who is this same?
Christ Jesus is His name,
The Lord Sabaoths Son;
He, and no other one,
Shall conquer in the battle."},{ID:3,
Text:"And were this world all devils oer,
And watching to devour us,
We lay it not to heart so sore;
Not they can overpower us.
And let the prince of ill
Look grim as eer he will,
He harms us not a whit;
For why? his doom is writ;
A word shall quickly slay him."},{ID:4,
Text:"Gods word, for all their craft and force,
One moment will not linger,
But, spite of hell, shall have its course;
Tis written by His finger.
And though they take our life,
Goods, honour, children, wife,
Yet is their profit small:
These things shall vanish all;
The city of God remaineth."}],AudioFile:"282.mp3",IsAudioFileEnabled:1,
Text:"A Safe Stronghold Our God is Still"}],Guid:"khiHU2blX0Kb41dGdbDLhA",VersionDate:"20121012000000",
Text:"SongBook1"}