Looks good. What versions of MediaShout has this been tested with? I can test with 4.5 if needed. On Jul 6, 2012 5:33 AM, "Jonathan Corwin" <j...@corwin.co.uk> wrote:
> Jonathan Corwin has proposed merging lp:~j-corwin/openlp/bug-1015823 into > lp:openlp. > > Requested reviews: > Jonathan Corwin (j-corwin) > > For more details, see: > https://code.launchpad.net/~j-corwin/openlp/bug-1015823/+merge/113634 > > This adds imports for the SongPro text file export format and MediaShout > Access Database > > The SongPro one is based on Martin Barrett's example attached to > http://support.openlp.org/issues/569, although somewhat rewritten. > > The MediaShout import is currently Windows only (due to odbc driver > complexities). It also requires an Access ODBC driver, but if MediaShout is > on the same PC then they will already have this, otherwise the MDAC can be > freely downloaded from Microsoft. > Windows developers will need to easy_install pyodbc once this is merged. > -- > https://code.launchpad.net/~j-corwin/openlp/bug-1015823/+merge/113634 > You are subscribed to branch lp:openlp. > > === modified file 'openlp/plugins/songs/lib/__init__.py' > --- openlp/plugins/songs/lib/__init__.py 2012-07-04 09:50:31 +0000 > +++ openlp/plugins/songs/lib/__init__.py 2012-07-05 19:32:19 +0000 > @@ -476,7 +476,7 @@ > Dictionary of fonts and respective encodings. > > ``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`` > A boolean indicating whether the previous encoding didn't work. > > === modified file 'openlp/plugins/songs/lib/importer.py' > --- openlp/plugins/songs/lib/importer.py 2012-07-04 09:50:31 +0000 > +++ openlp/plugins/songs/lib/importer.py 2012-07-05 19:32:19 +0000 > @@ -28,6 +28,7 @@ > """ > The :mod:`importer` modules provides the general song import > functionality. > """ > +import os > import logging > > from openlp.core.lib import translate > @@ -44,6 +45,7 @@ > from ewimport import EasyWorshipSongImport > from songbeamerimport import SongBeamerImport > from songshowplusimport import SongShowPlusImport > +from songproimport import SongProImport > from sundayplusimport import SundayPlusImport > from foilpresenterimport import FoilPresenterImport > from zionworximport import ZionWorxImport > @@ -67,6 +69,13 @@ > except ImportError: > log.exception('Error importing %s', 'OooImport') > 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): > @@ -141,15 +150,16 @@ > EasySlides = 6 > EasyWorship = 7 > FoilPresenter = 8 > - OpenSong = 9 > - PowerSong = 10 > - SongBeamer = 11 > - SongShowPlus = 12 > - SongsOfFellowship = 13 > - SundayPlus = 14 > - WordsOfWorship = 15 > - ZionWorx = 16 > - #CSV = 17 > + MediaShout = 9 > + OpenSong = 10 > + PowerSong = 11 > + SongBeamer = 12 > + SongPro = 13 > + SongShowPlus = 14 > + SongsOfFellowship = 15 > + SundayPlus = 16 > + WordsOfWorship = 17 > + ZionWorx = 18 > > # Set optional attribute defaults > __defaults__ = { > @@ -240,6 +250,14 @@ > u'filter': u'%s (*.foil)' % translate( > '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: { > u'class': OpenSongImport, > u'name': WizardStrings.OS, > @@ -260,6 +278,18 @@ > u'filter': u'%s (*.sng)' % > translate('SongsPlugin.ImportWizardForm', > '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: { > u'class': SongShowPlusImport, > u'name': u'SongShow Plus', > @@ -302,12 +332,6 @@ > 'First convert your ZionWorx database to a CSV text file, > as ' > 'explained in the <a href=" > http://manual.openlp.org/songs.html' > '#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 @@ > SongFormat.EasySlides, > SongFormat.EasyWorship, > SongFormat.FoilPresenter, > + SongFormat.MediaShout, > SongFormat.OpenSong, > SongFormat.PowerSong, > SongFormat.SongBeamer, > + SongFormat.SongPro, > SongFormat.SongShowPlus, > SongFormat.SongsOfFellowship, > SongFormat.SundayPlus, > @@ -383,5 +409,8 @@ > SongFormat.set(SongFormat.Generic, u'availability', HAS_OOO) > if HAS_OOO: > 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'] > > === added file 'openlp/plugins/songs/lib/mediashoutimport.py' > --- openlp/plugins/songs/lib/mediashoutimport.py 1970-01-01 > 00:00:00 +0000 > +++ openlp/plugins/songs/lib/mediashoutimport.py 2012-07-05 > 19:32:19 +0000 > @@ -0,0 +1,114 @@ > +# -*- 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 logging > +import pyodbc > + > +from openlp.core.lib import translate > +from openlp.plugins.songs.lib.songimport import SongImport > + > +log = logging.getLogger(__name__) > + > +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() > > === added file 'openlp/plugins/songs/lib/songproimport.py' > --- openlp/plugins/songs/lib/songproimport.py 1970-01-01 00:00:00 +0000 > +++ openlp/plugins/songs/lib/songproimport.py 2012-07-05 19:32:19 +0000 > @@ -0,0 +1,148 @@ > +# -*- 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 > +import logging > + > +from openlp.core.lib import translate > +from openlp.plugins.songs.lib import strip_rtf > +from openlp.plugins.songs.lib.songimport import SongImport > + > +log = logging.getLogger(__name__) > + > +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 > + self.importWizard.incrementProgressBar(u'Processing song ' + > text, > + 0) > + 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:]) > > > -- https://code.launchpad.net/~j-corwin/openlp/bug-1015823/+merge/113634 Your team OpenLP Core is subscribed to branch lp:openlp. _______________________________________________ Mailing list: https://launchpad.net/~openlp-core Post to : openlp-core@lists.launchpad.net Unsubscribe : https://launchpad.net/~openlp-core More help : https://help.launchpad.net/ListHelp