forked from openlp/openlp
Add SongPro and MediaShout song importer
bzr-revno: 2022
This commit is contained in:
commit
c1db424460
@ -476,7 +476,7 @@ def get_encoding(font, font_table, default_encoding, failed=False):
|
|||||||
Dictionary of fonts and respective encodings.
|
Dictionary of fonts and respective encodings.
|
||||||
|
|
||||||
``default_encoding``
|
``default_encoding``
|
||||||
The defaul encoding to use when font_table is empty or no font is used.
|
The default encoding to use when font_table is empty or no font is used.
|
||||||
|
|
||||||
``failed``
|
``failed``
|
||||||
A boolean indicating whether the previous encoding didn't work.
|
A boolean indicating whether the previous encoding didn't work.
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
"""
|
"""
|
||||||
The :mod:`importer` modules provides the general song import functionality.
|
The :mod:`importer` modules provides the general song import functionality.
|
||||||
"""
|
"""
|
||||||
|
import os
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from openlp.core.lib import translate
|
from openlp.core.lib import translate
|
||||||
@ -44,6 +45,7 @@ from powersongimport import PowerSongImport
|
|||||||
from ewimport import EasyWorshipSongImport
|
from ewimport import EasyWorshipSongImport
|
||||||
from songbeamerimport import SongBeamerImport
|
from songbeamerimport import SongBeamerImport
|
||||||
from songshowplusimport import SongShowPlusImport
|
from songshowplusimport import SongShowPlusImport
|
||||||
|
from songproimport import SongProImport
|
||||||
from sundayplusimport import SundayPlusImport
|
from sundayplusimport import SundayPlusImport
|
||||||
from foilpresenterimport import FoilPresenterImport
|
from foilpresenterimport import FoilPresenterImport
|
||||||
from zionworximport import ZionWorxImport
|
from zionworximport import ZionWorxImport
|
||||||
@ -67,6 +69,13 @@ try:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
log.exception('Error importing %s', 'OooImport')
|
log.exception('Error importing %s', 'OooImport')
|
||||||
HAS_OOO = False
|
HAS_OOO = False
|
||||||
|
HAS_MEDIASHOUT = False
|
||||||
|
if os.name == u'nt':
|
||||||
|
try:
|
||||||
|
from mediashoutimport import MediaShoutImport
|
||||||
|
HAS_MEDIASHOUT = True
|
||||||
|
except ImportError:
|
||||||
|
log.exception('Error importing %s', 'MediaShoutImport')
|
||||||
|
|
||||||
|
|
||||||
class SongFormatSelect(object):
|
class SongFormatSelect(object):
|
||||||
@ -141,15 +150,16 @@ class SongFormat(object):
|
|||||||
EasySlides = 6
|
EasySlides = 6
|
||||||
EasyWorship = 7
|
EasyWorship = 7
|
||||||
FoilPresenter = 8
|
FoilPresenter = 8
|
||||||
OpenSong = 9
|
MediaShout = 9
|
||||||
PowerSong = 10
|
OpenSong = 10
|
||||||
SongBeamer = 11
|
PowerSong = 11
|
||||||
SongShowPlus = 12
|
SongBeamer = 12
|
||||||
SongsOfFellowship = 13
|
SongPro = 13
|
||||||
SundayPlus = 14
|
SongShowPlus = 14
|
||||||
WordsOfWorship = 15
|
SongsOfFellowship = 15
|
||||||
ZionWorx = 16
|
SundayPlus = 16
|
||||||
#CSV = 17
|
WordsOfWorship = 17
|
||||||
|
ZionWorx = 18
|
||||||
|
|
||||||
# Set optional attribute defaults
|
# Set optional attribute defaults
|
||||||
__defaults__ = {
|
__defaults__ = {
|
||||||
@ -240,6 +250,14 @@ class SongFormat(object):
|
|||||||
u'filter': u'%s (*.foil)' % translate(
|
u'filter': u'%s (*.foil)' % translate(
|
||||||
'SongsPlugin.ImportWizardForm', 'Foilpresenter Song Files')
|
'SongsPlugin.ImportWizardForm', 'Foilpresenter Song Files')
|
||||||
},
|
},
|
||||||
|
MediaShout: {
|
||||||
|
u'name': u'MediaShout',
|
||||||
|
u'prefix': u'mediaShout',
|
||||||
|
u'canDisable': True,
|
||||||
|
u'selectMode': SongFormatSelect.SingleFile,
|
||||||
|
u'filter': u'%s (*.mdb)' % translate('SongsPlugin.ImportWizardForm',
|
||||||
|
'MediaShout Database')
|
||||||
|
},
|
||||||
OpenSong: {
|
OpenSong: {
|
||||||
u'class': OpenSongImport,
|
u'class': OpenSongImport,
|
||||||
u'name': WizardStrings.OS,
|
u'name': WizardStrings.OS,
|
||||||
@ -260,6 +278,18 @@ class SongFormat(object):
|
|||||||
u'filter': u'%s (*.sng)' % translate('SongsPlugin.ImportWizardForm',
|
u'filter': u'%s (*.sng)' % translate('SongsPlugin.ImportWizardForm',
|
||||||
'SongBeamer Files')
|
'SongBeamer Files')
|
||||||
},
|
},
|
||||||
|
SongPro: {
|
||||||
|
u'class': SongProImport,
|
||||||
|
u'name': u'SongPro',
|
||||||
|
u'prefix': u'songPro',
|
||||||
|
u'selectMode': SongFormatSelect.SingleFile,
|
||||||
|
u'filter': u'%s (*.txt)' % translate('SongsPlugin.ImportWizardForm',
|
||||||
|
'SongPro Text Files'),
|
||||||
|
u'comboBoxText': translate('SongsPlugin.ImportWizardForm',
|
||||||
|
'SongPro (Export File)'),
|
||||||
|
u'descriptionText': translate('SongsPlugin.ImportWizardForm',
|
||||||
|
'In SongPro, export your songs using the File -> Export menu')
|
||||||
|
},
|
||||||
SongShowPlus: {
|
SongShowPlus: {
|
||||||
u'class': SongShowPlusImport,
|
u'class': SongShowPlusImport,
|
||||||
u'name': u'SongShow Plus',
|
u'name': u'SongShow Plus',
|
||||||
@ -302,12 +332,6 @@ class SongFormat(object):
|
|||||||
'First convert your ZionWorx database to a CSV text file, as '
|
'First convert your ZionWorx database to a CSV text file, as '
|
||||||
'explained in the <a href="http://manual.openlp.org/songs.html'
|
'explained in the <a href="http://manual.openlp.org/songs.html'
|
||||||
'#importing-from-zionworx">User Manual</a>.')
|
'#importing-from-zionworx">User Manual</a>.')
|
||||||
# },
|
|
||||||
# CSV: {
|
|
||||||
# u'class': CSVImport,
|
|
||||||
# u'name': WizardStrings.CSV,
|
|
||||||
# u'prefix': u'csv',
|
|
||||||
# u'selectMode': SongFormatSelect.SingleFile
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,9 +350,11 @@ class SongFormat(object):
|
|||||||
SongFormat.EasySlides,
|
SongFormat.EasySlides,
|
||||||
SongFormat.EasyWorship,
|
SongFormat.EasyWorship,
|
||||||
SongFormat.FoilPresenter,
|
SongFormat.FoilPresenter,
|
||||||
|
SongFormat.MediaShout,
|
||||||
SongFormat.OpenSong,
|
SongFormat.OpenSong,
|
||||||
SongFormat.PowerSong,
|
SongFormat.PowerSong,
|
||||||
SongFormat.SongBeamer,
|
SongFormat.SongBeamer,
|
||||||
|
SongFormat.SongPro,
|
||||||
SongFormat.SongShowPlus,
|
SongFormat.SongShowPlus,
|
||||||
SongFormat.SongsOfFellowship,
|
SongFormat.SongsOfFellowship,
|
||||||
SongFormat.SundayPlus,
|
SongFormat.SundayPlus,
|
||||||
@ -383,5 +409,8 @@ if HAS_SOF:
|
|||||||
SongFormat.set(SongFormat.Generic, u'availability', HAS_OOO)
|
SongFormat.set(SongFormat.Generic, u'availability', HAS_OOO)
|
||||||
if HAS_OOO:
|
if HAS_OOO:
|
||||||
SongFormat.set(SongFormat.Generic, u'class', OooImport)
|
SongFormat.set(SongFormat.Generic, u'class', OooImport)
|
||||||
|
SongFormat.set(SongFormat.MediaShout, u'availability', HAS_MEDIASHOUT)
|
||||||
|
if HAS_MEDIASHOUT:
|
||||||
|
SongFormat.set(SongFormat.MediaShout, u'class', MediaShoutImport)
|
||||||
|
|
||||||
__all__ = [u'SongFormat', u'SongFormatSelect']
|
__all__ = [u'SongFormat', u'SongFormatSelect']
|
||||||
|
112
openlp/plugins/songs/lib/mediashoutimport.py
Normal file
112
openlp/plugins/songs/lib/mediashoutimport.py
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# OpenLP - Open Source Lyrics Projection #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||||
|
# Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
|
||||||
|
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
|
||||||
|
# Meinert Jordan, Armin Köhler, Edwin Lunando, 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 #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# 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:`mediashoutimport` module provides the functionality for importing
|
||||||
|
a MediaShout database into the OpenLP database.
|
||||||
|
"""
|
||||||
|
import re
|
||||||
|
import os
|
||||||
|
import pyodbc
|
||||||
|
|
||||||
|
from openlp.core.lib import translate
|
||||||
|
from openlp.plugins.songs.lib.songimport import SongImport
|
||||||
|
|
||||||
|
VERSE_TAGS = [u'V', u'C', u'B', u'O', u'P', u'I', u'E']
|
||||||
|
|
||||||
|
class MediaShoutImport(SongImport):
|
||||||
|
"""
|
||||||
|
The :class:`MediaShoutImport` class provides the ability to import the
|
||||||
|
MediaShout Access Database
|
||||||
|
"""
|
||||||
|
def __init__(self, manager, **kwargs):
|
||||||
|
"""
|
||||||
|
Initialise the MediaShout importer.
|
||||||
|
"""
|
||||||
|
SongImport.__init__(self, manager, **kwargs)
|
||||||
|
|
||||||
|
def doImport(self):
|
||||||
|
"""
|
||||||
|
Receive a single file to import.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
conn = pyodbc.connect(u'DRIVER={Microsoft Access Driver (*.mdb)};'
|
||||||
|
u'DBQ=%s;PWD=6NOZ4eHK7k' % self.importSource)
|
||||||
|
except:
|
||||||
|
# Unfortunately no specific exception type
|
||||||
|
self.logError(self.importSource,
|
||||||
|
translate('SongsPlugin.MediaShoutImport',
|
||||||
|
'Unable to open the MediaShout database.'))
|
||||||
|
return
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute(u'SELECT Record, Title, Author, Copyright, '
|
||||||
|
u'SongID, CCLI, Notes FROM Songs ORDER BY Title')
|
||||||
|
songs = cursor.fetchall()
|
||||||
|
self.importWizard.progressBar.setMaximum(len(songs))
|
||||||
|
for song in songs:
|
||||||
|
if self.stopImportFlag:
|
||||||
|
break
|
||||||
|
cursor.execute(u'SELECT Type, Number, Text FROM Verses '
|
||||||
|
u'WHERE Record = %s ORDER BY Type, Number' % song.Record)
|
||||||
|
verses = cursor.fetchall()
|
||||||
|
cursor.execute(u'SELECT Type, Number, POrder FROM PlayOrder '
|
||||||
|
u'WHERE Record = %s ORDER BY POrder' % song.Record)
|
||||||
|
verse_order = cursor.fetchall()
|
||||||
|
cursor.execute(u'SELECT Name FROM Themes INNER JOIN SongThemes '
|
||||||
|
u'ON SongThemes.ThemeId = Themes.ThemeId '
|
||||||
|
u'WHERE SongThemes.Record = %s' % song.Record)
|
||||||
|
topics = cursor.fetchall()
|
||||||
|
cursor.execute(u'SELECT Name FROM Groups INNER JOIN SongGroups '
|
||||||
|
u'ON SongGroups.GroupId = Groups.GroupId '
|
||||||
|
u'WHERE SongGroups.Record = %s' % song.Record)
|
||||||
|
topics += cursor.fetchall()
|
||||||
|
self.processSong(song, verses, verse_order, topics)
|
||||||
|
|
||||||
|
def processSong(self, song, verses, verse_order, topics):
|
||||||
|
"""
|
||||||
|
Create the song, i.e. title, verse etc.
|
||||||
|
"""
|
||||||
|
self.setDefaults()
|
||||||
|
self.title = song.Title
|
||||||
|
self.parseAuthor(song.Author)
|
||||||
|
self.addCopyright(song.Copyright)
|
||||||
|
self.comments = song.Notes
|
||||||
|
for topic in topics:
|
||||||
|
self.topics.append(topic.Name)
|
||||||
|
if u'-' in song.SongID:
|
||||||
|
self.songBookName, self.songNumber = song.SongID.split(u'-', 1)
|
||||||
|
else:
|
||||||
|
self.songBookName = song.SongID
|
||||||
|
for verse in verses:
|
||||||
|
tag = VERSE_TAGS[verse.Type] + unicode(verse.Number) \
|
||||||
|
if verse.Type < len(VERSE_TAGS) else u'O'
|
||||||
|
self.addVerse(verse.Text, tag)
|
||||||
|
for order in verse_order:
|
||||||
|
if order.Type < len(VERSE_TAGS):
|
||||||
|
self.verseOrderList.append(VERSE_TAGS[order.Type]
|
||||||
|
+ unicode(order.Number))
|
||||||
|
self.finish()
|
143
openlp/plugins/songs/lib/songproimport.py
Normal file
143
openlp/plugins/songs/lib/songproimport.py
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# OpenLP - Open Source Lyrics Projection #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||||
|
# Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
|
||||||
|
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
|
||||||
|
# Meinert Jordan, Armin Köhler, Edwin Lunando, 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 #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# 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:`songproimport` module provides the functionality for importing SongPro
|
||||||
|
songs into the OpenLP database.
|
||||||
|
"""
|
||||||
|
import re
|
||||||
|
import os
|
||||||
|
|
||||||
|
from openlp.core.lib import translate
|
||||||
|
from openlp.plugins.songs.lib import strip_rtf
|
||||||
|
from openlp.plugins.songs.lib.songimport import SongImport
|
||||||
|
|
||||||
|
class SongProImport(SongImport):
|
||||||
|
"""
|
||||||
|
The :class:`SongProImport` class provides the ability to import song files
|
||||||
|
from SongPro export files.
|
||||||
|
|
||||||
|
**SongPro Song File Format:**
|
||||||
|
|
||||||
|
SongPro has the option to export under its File menu
|
||||||
|
This produces files containing single or multiple songs
|
||||||
|
The file is text with lines tagged with # followed by an identifier.
|
||||||
|
This is documented here: http://creationsoftware.com/ImportIdentifiers.php
|
||||||
|
An example here: http://creationsoftware.com/ExampleImportingManySongs.txt
|
||||||
|
|
||||||
|
#A - next line is the Song Author
|
||||||
|
#B - the lines following until next tagged line are the "Bridge" words
|
||||||
|
(can be in rtf or plain text) which we map as B1
|
||||||
|
#C - the lines following until next tagged line are the chorus words
|
||||||
|
(can be in rtf or plain text)
|
||||||
|
which we map as C1
|
||||||
|
#D - the lines following until next tagged line are the "Ending" words
|
||||||
|
(can be in rtf or plain text) which we map as E1
|
||||||
|
#E - this song ends here, so we process the song -
|
||||||
|
and start again at the next line
|
||||||
|
#G - next line is the Group
|
||||||
|
#M - next line is the Song Number
|
||||||
|
#N - next line are Notes
|
||||||
|
#R - next line is the SongCopyright
|
||||||
|
#O - next line is the Verse Sequence
|
||||||
|
#T - next line is the Song Title
|
||||||
|
#1 - #7 the lines following until next tagged line are the verse x words
|
||||||
|
(can be in rtf or plain text)
|
||||||
|
"""
|
||||||
|
def __init__(self, manager, **kwargs):
|
||||||
|
"""
|
||||||
|
Initialise the SongPro importer.
|
||||||
|
"""
|
||||||
|
SongImport.__init__(self, manager, **kwargs)
|
||||||
|
|
||||||
|
def doImport(self):
|
||||||
|
"""
|
||||||
|
Receive a single file or a list of files to import.
|
||||||
|
"""
|
||||||
|
self.encoding = None
|
||||||
|
with open(self.importSource, 'r') as songs_file:
|
||||||
|
self.importWizard.progressBar.setMaximum(0)
|
||||||
|
tag = u''
|
||||||
|
text = u''
|
||||||
|
for file_line in songs_file:
|
||||||
|
if self.stopImportFlag:
|
||||||
|
break
|
||||||
|
file_line = unicode(file_line, u'cp1252')
|
||||||
|
file_text = file_line.rstrip()
|
||||||
|
if file_text and file_text[0] == u'#':
|
||||||
|
self.processSection(tag, text.rstrip())
|
||||||
|
tag = file_text[1:]
|
||||||
|
text = u''
|
||||||
|
else:
|
||||||
|
text += file_line
|
||||||
|
|
||||||
|
def processSection(self, tag, text):
|
||||||
|
"""
|
||||||
|
Process a section of the song, i.e. title, verse etc.
|
||||||
|
"""
|
||||||
|
if tag == u'T':
|
||||||
|
self.setDefaults()
|
||||||
|
if text:
|
||||||
|
self.title = text
|
||||||
|
return
|
||||||
|
elif tag == u'E':
|
||||||
|
self.finish()
|
||||||
|
return
|
||||||
|
if u'rtf1' in text:
|
||||||
|
text, self.encoding = strip_rtf(text, self.encoding)
|
||||||
|
text = text.rstrip()
|
||||||
|
if not text:
|
||||||
|
return
|
||||||
|
if tag == u'A':
|
||||||
|
self.parseAuthor(text)
|
||||||
|
elif tag in [u'B', u'C']:
|
||||||
|
self.addVerse(text, tag)
|
||||||
|
elif tag == u'D':
|
||||||
|
self.addVerse(text, u'E')
|
||||||
|
elif tag == u'G':
|
||||||
|
self.topics.append(text)
|
||||||
|
elif tag == u'M':
|
||||||
|
matches = re.findall(r'\d+', text)
|
||||||
|
if matches:
|
||||||
|
self.songNumber = matches[-1]
|
||||||
|
self.songBookName = text[:text.rfind(self.songNumber)]
|
||||||
|
elif tag == u'N':
|
||||||
|
self.comments = text
|
||||||
|
elif tag == u'O':
|
||||||
|
for char in text:
|
||||||
|
if char == u'C':
|
||||||
|
self.verseOrderList.append(u'C1')
|
||||||
|
elif char == u'B':
|
||||||
|
self.verseOrderList.append(u'B1')
|
||||||
|
elif char == u'D':
|
||||||
|
self.verseOrderList.append(u'E1')
|
||||||
|
elif u'1' <= char <= u'7':
|
||||||
|
self.verseOrderList.append(u'V' + char)
|
||||||
|
elif tag == u'R':
|
||||||
|
self.addCopyright(text)
|
||||||
|
elif u'1' <= tag <= u'7':
|
||||||
|
self.addVerse(text, u'V' + tag[1:])
|
Loading…
Reference in New Issue
Block a user