mirror of https://gitlab.com/openlp/openlp.git
Add ewsx song importer
This commit is contained in:
parent
39833c770d
commit
fa05ee4b2d
|
@ -166,28 +166,29 @@ class SongFormat(object):
|
|||
EasyWorshipDB = 7
|
||||
EasyWorshipSqliteDB = 8
|
||||
EasyWorshipService = 9
|
||||
FoilPresenter = 10
|
||||
LiveWorship = 11
|
||||
Lyrix = 12
|
||||
MediaShout = 13
|
||||
OpenSong = 14
|
||||
OPSPro = 15
|
||||
PowerPraise = 16
|
||||
PowerSong = 17
|
||||
PresentationManager = 18
|
||||
ProPresenter = 19
|
||||
SingingTheFaith = 20
|
||||
SongBeamer = 21
|
||||
SongPro = 22
|
||||
SongShowPlus = 23
|
||||
SongsOfFellowship = 24
|
||||
SundayPlus = 25
|
||||
VideoPsalm = 26
|
||||
WordsOfWorship = 27
|
||||
WorshipAssistant = 28
|
||||
WorshipCenterPro = 29
|
||||
ZionWorx = 30
|
||||
Datasoul = 31
|
||||
EasyWorshipServiceSqliteDB = 10
|
||||
FoilPresenter = 11
|
||||
LiveWorship = 12
|
||||
Lyrix = 13
|
||||
MediaShout = 14
|
||||
OpenSong = 15
|
||||
OPSPro = 16
|
||||
PowerPraise = 17
|
||||
PowerSong = 18
|
||||
PresentationManager = 19
|
||||
ProPresenter = 20
|
||||
SingingTheFaith = 21
|
||||
SongBeamer = 22
|
||||
SongPro = 23
|
||||
SongShowPlus = 24
|
||||
SongsOfFellowship = 25
|
||||
SundayPlus = 26
|
||||
VideoPsalm = 27
|
||||
WordsOfWorship = 28
|
||||
WorshipAssistant = 29
|
||||
WorshipCenterPro = 30
|
||||
ZionWorx = 31
|
||||
Datasoul = 32
|
||||
|
||||
# Set optional attribute defaults
|
||||
__defaults__ = {
|
||||
|
@ -278,6 +279,14 @@ class SongFormat(object):
|
|||
'filter': '{text} (*.ews)'.format(text=translate('SongsPlugin.ImportWizardForm',
|
||||
'EasyWorship 2007/2009 Service File'))
|
||||
},
|
||||
EasyWorshipServiceSqliteDB: {
|
||||
'class': EasyWorshipSongImport,
|
||||
'name': 'EasyWorship 6/7 Service File',
|
||||
'prefix': 'ew',
|
||||
'selectMode': SongFormatSelect.SingleFile,
|
||||
'filter': '{text} (*.ewsx)'.format(text=translate('SongsPlugin.ImportWizardForm',
|
||||
'EasyWorship 6/7 Service File'))
|
||||
},
|
||||
FoilPresenter: {
|
||||
'class': FoilPresenterImport,
|
||||
'name': 'Foilpresenter',
|
||||
|
@ -487,6 +496,7 @@ class SongFormat(object):
|
|||
SongFormat.EasyWorshipDB,
|
||||
SongFormat.EasyWorshipSqliteDB,
|
||||
SongFormat.EasyWorshipService,
|
||||
SongFormat.EasyWorshipServiceSqliteDB,
|
||||
SongFormat.FoilPresenter,
|
||||
SongFormat.LiveWorship,
|
||||
SongFormat.Lyrix,
|
||||
|
|
|
@ -28,6 +28,8 @@ import sqlite3
|
|||
import struct
|
||||
import zlib
|
||||
from pathlib import Path
|
||||
from tempfile import NamedTemporaryFile
|
||||
from zipfile import ZipFile
|
||||
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.plugins.songs.lib import VerseType, retrieve_windows_encoding, strip_rtf
|
||||
|
@ -83,6 +85,8 @@ class EasyWorshipSongImport(SongImport):
|
|||
self.import_ews()
|
||||
elif ext == '.db':
|
||||
self.import_db()
|
||||
elif ext == '.ewsx':
|
||||
self.import_ewsx()
|
||||
else:
|
||||
self.import_sqlite_db()
|
||||
except Exception:
|
||||
|
@ -346,6 +350,65 @@ class EasyWorshipSongImport(SongImport):
|
|||
db_file.close()
|
||||
self.memo_file.close()
|
||||
|
||||
def import_ewsx(self):
|
||||
"""
|
||||
Imports songs from an EasyWorship 6/7 service file, which is just a zip file with an Sqlite DB with text
|
||||
resources. Non-text recources is also in the zip file, but is ignored.
|
||||
"""
|
||||
invalid_ewsx_msg = translate('SongsPlugin.EasyWorshipSongImport',
|
||||
'This is not a valid Easy Worship 6/7 service file.')
|
||||
# Open ewsx file if it exists
|
||||
if not self.import_source.is_file():
|
||||
log.debug('Given ewsx file does not exists.')
|
||||
return
|
||||
tmp_db_file = NamedTemporaryFile(delete=False)
|
||||
with ZipFile(self.import_source, 'r') as eswx_file:
|
||||
db_zfile = eswx_file.open('main.db')
|
||||
# eswx has bad CRC for the database for some reason (custom CRC?), so skip the CRC
|
||||
db_zfile._expected_crc = None
|
||||
db_data = db_zfile.read()
|
||||
tmp_db_file.write(db_data)
|
||||
tmp_db_file.close()
|
||||
ewsx_conn = sqlite3.connect(tmp_db_file.file.name)
|
||||
if ewsx_conn is None:
|
||||
self.log_error(self.import_source, invalid_ewsx_msg)
|
||||
return
|
||||
ewsx_db = ewsx_conn.cursor()
|
||||
# Take a stab at how text is encoded
|
||||
self.encoding = 'cp1252'
|
||||
self.encoding = retrieve_windows_encoding(self.encoding)
|
||||
if not self.encoding:
|
||||
log.debug('No encoding set.')
|
||||
return
|
||||
# get list of songs in service file, presentation_type=6 means songs
|
||||
songs_exec = ewsx_db.execute('SELECT rowid, title, author, copyright, reference_number '
|
||||
'FROM presentation WHERE presentation_type=6;')
|
||||
songs = songs_exec.fetchall()
|
||||
for song in songs:
|
||||
self.title = title = song[1]
|
||||
self.author = song[2]
|
||||
self.copyright = song[3]
|
||||
self.ccli_number = song[4]
|
||||
# get slides for the song, element_type=6 means songs, element_style_type=4 means song text
|
||||
slides = ewsx_db.execute('SELECT rt.rtf '
|
||||
'FROM element as e '
|
||||
'JOIN slide as s ON e.slide_id = s.rowid '
|
||||
'JOIN resource_text as rt ON rt.resource_id = e.foreground_resource_id '
|
||||
'WHERE e.element_type=6 AND e.element_style_type=4 AND s.presentation_id = ? '
|
||||
'ORDER BY s.order_index;', (song[0],))
|
||||
for slide in slides:
|
||||
if slide:
|
||||
self.set_song_import_object(self.author, slide[0].encode())
|
||||
# save song
|
||||
if not self.finish():
|
||||
self.log_error(self.import_source,
|
||||
translate('SongsPlugin.EasyWorshipSongImport',
|
||||
'"{title}" could not be imported. {entry}').
|
||||
format(title=title, entry=self.entry_error_log))
|
||||
# close database handles
|
||||
ewsx_conn.close()
|
||||
Path(tmp_db_file.file.name).unlink()
|
||||
|
||||
def import_sqlite_db(self):
|
||||
"""
|
||||
Import the songs from an EasyWorship 6 SQLite database
|
||||
|
|
|
@ -498,6 +498,48 @@ def test_ews_file_import(mocked_retrieve_windows_encoding: MagicMock, MockSongIm
|
|||
mocked_finish.assert_called_with()
|
||||
|
||||
|
||||
@patch('openlp.plugins.songs.lib.importers.easyworship.SongImport')
|
||||
@patch('openlp.plugins.songs.lib.importers.easyworship.retrieve_windows_encoding')
|
||||
def test_ewsx_file_import(mocked_retrieve_windows_encoding: MagicMock, MockSongImport: MagicMock,
|
||||
registry: Registry, settings: Settings):
|
||||
"""
|
||||
Test the actual import of song from ewsx file 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.
|
||||
mocked_retrieve_windows_encoding.return_value = 'cp1252'
|
||||
mocked_manager = MagicMock()
|
||||
mocked_import_wizard = MagicMock()
|
||||
mocked_add_author = MagicMock()
|
||||
mocked_add_verse = MagicMock()
|
||||
mocked_finish = MagicMock()
|
||||
mocked_title = MagicMock()
|
||||
mocked_finish.return_value = True
|
||||
importer = EasyWorshipSongImportLogger(mocked_manager)
|
||||
importer.import_wizard = mocked_import_wizard
|
||||
importer.stop_import_flag = False
|
||||
importer.add_author = mocked_add_author
|
||||
importer.add_verse = mocked_add_verse
|
||||
importer.title = mocked_title
|
||||
importer.finish = mocked_finish
|
||||
importer.topics = []
|
||||
|
||||
# WHEN: Importing ews file
|
||||
importer.import_source = str(TEST_PATH / 'test1.ewsx')
|
||||
import_result = importer.do_import()
|
||||
|
||||
# THEN: do_import should return none, the song data should be as expected, and finish should have been
|
||||
# called.
|
||||
title = EWS_SONG_TEST_DATA['title']
|
||||
assert import_result is None, 'do_import should return None when it has completed'
|
||||
assert title in importer._title_assignment_list, 'title for should be "%s"' % title
|
||||
mocked_add_author.assert_any_call(EWS_SONG_TEST_DATA['authors'][0])
|
||||
for verse_text, verse_tag in EWS_SONG_TEST_DATA['verses']:
|
||||
mocked_add_verse.assert_any_call(verse_text, verse_tag)
|
||||
mocked_finish.assert_called_with()
|
||||
|
||||
|
||||
@patch('openlp.plugins.songs.lib.importers.easyworship.SongImport')
|
||||
def test_import_rtf_unescaped_unicode(MockSongImport: MagicMock, registry: Registry, settings: Settings):
|
||||
"""
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue