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
|
EasyWorshipDB = 7
|
||||||
EasyWorshipSqliteDB = 8
|
EasyWorshipSqliteDB = 8
|
||||||
EasyWorshipService = 9
|
EasyWorshipService = 9
|
||||||
FoilPresenter = 10
|
EasyWorshipServiceSqliteDB = 10
|
||||||
LiveWorship = 11
|
FoilPresenter = 11
|
||||||
Lyrix = 12
|
LiveWorship = 12
|
||||||
MediaShout = 13
|
Lyrix = 13
|
||||||
OpenSong = 14
|
MediaShout = 14
|
||||||
OPSPro = 15
|
OpenSong = 15
|
||||||
PowerPraise = 16
|
OPSPro = 16
|
||||||
PowerSong = 17
|
PowerPraise = 17
|
||||||
PresentationManager = 18
|
PowerSong = 18
|
||||||
ProPresenter = 19
|
PresentationManager = 19
|
||||||
SingingTheFaith = 20
|
ProPresenter = 20
|
||||||
SongBeamer = 21
|
SingingTheFaith = 21
|
||||||
SongPro = 22
|
SongBeamer = 22
|
||||||
SongShowPlus = 23
|
SongPro = 23
|
||||||
SongsOfFellowship = 24
|
SongShowPlus = 24
|
||||||
SundayPlus = 25
|
SongsOfFellowship = 25
|
||||||
VideoPsalm = 26
|
SundayPlus = 26
|
||||||
WordsOfWorship = 27
|
VideoPsalm = 27
|
||||||
WorshipAssistant = 28
|
WordsOfWorship = 28
|
||||||
WorshipCenterPro = 29
|
WorshipAssistant = 29
|
||||||
ZionWorx = 30
|
WorshipCenterPro = 30
|
||||||
Datasoul = 31
|
ZionWorx = 31
|
||||||
|
Datasoul = 32
|
||||||
|
|
||||||
# Set optional attribute defaults
|
# Set optional attribute defaults
|
||||||
__defaults__ = {
|
__defaults__ = {
|
||||||
|
@ -278,6 +279,14 @@ class SongFormat(object):
|
||||||
'filter': '{text} (*.ews)'.format(text=translate('SongsPlugin.ImportWizardForm',
|
'filter': '{text} (*.ews)'.format(text=translate('SongsPlugin.ImportWizardForm',
|
||||||
'EasyWorship 2007/2009 Service File'))
|
'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: {
|
FoilPresenter: {
|
||||||
'class': FoilPresenterImport,
|
'class': FoilPresenterImport,
|
||||||
'name': 'Foilpresenter',
|
'name': 'Foilpresenter',
|
||||||
|
@ -487,6 +496,7 @@ class SongFormat(object):
|
||||||
SongFormat.EasyWorshipDB,
|
SongFormat.EasyWorshipDB,
|
||||||
SongFormat.EasyWorshipSqliteDB,
|
SongFormat.EasyWorshipSqliteDB,
|
||||||
SongFormat.EasyWorshipService,
|
SongFormat.EasyWorshipService,
|
||||||
|
SongFormat.EasyWorshipServiceSqliteDB,
|
||||||
SongFormat.FoilPresenter,
|
SongFormat.FoilPresenter,
|
||||||
SongFormat.LiveWorship,
|
SongFormat.LiveWorship,
|
||||||
SongFormat.Lyrix,
|
SongFormat.Lyrix,
|
||||||
|
|
|
@ -28,6 +28,8 @@ import sqlite3
|
||||||
import struct
|
import struct
|
||||||
import zlib
|
import zlib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from tempfile import NamedTemporaryFile
|
||||||
|
from zipfile import ZipFile
|
||||||
|
|
||||||
from openlp.core.common.i18n import translate
|
from openlp.core.common.i18n import translate
|
||||||
from openlp.plugins.songs.lib import VerseType, retrieve_windows_encoding, strip_rtf
|
from openlp.plugins.songs.lib import VerseType, retrieve_windows_encoding, strip_rtf
|
||||||
|
@ -83,6 +85,8 @@ class EasyWorshipSongImport(SongImport):
|
||||||
self.import_ews()
|
self.import_ews()
|
||||||
elif ext == '.db':
|
elif ext == '.db':
|
||||||
self.import_db()
|
self.import_db()
|
||||||
|
elif ext == '.ewsx':
|
||||||
|
self.import_ewsx()
|
||||||
else:
|
else:
|
||||||
self.import_sqlite_db()
|
self.import_sqlite_db()
|
||||||
except Exception:
|
except Exception:
|
||||||
|
@ -346,6 +350,65 @@ class EasyWorshipSongImport(SongImport):
|
||||||
db_file.close()
|
db_file.close()
|
||||||
self.memo_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):
|
def import_sqlite_db(self):
|
||||||
"""
|
"""
|
||||||
Import the songs from an EasyWorship 6 SQLite database
|
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()
|
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')
|
@patch('openlp.plugins.songs.lib.importers.easyworship.SongImport')
|
||||||
def test_import_rtf_unescaped_unicode(MockSongImport: MagicMock, registry: Registry, settings: Settings):
|
def test_import_rtf_unescaped_unicode(MockSongImport: MagicMock, registry: Registry, settings: Settings):
|
||||||
"""
|
"""
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue