From 64d0494ff16321c79d4840162b2aac1a9054b668 Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Sat, 23 Jun 2012 23:47:26 +0100 Subject: [PATCH 01/11] SongPro import --- openlp/plugins/songs/lib/importer.py | 30 ++++++++++++++++++---------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/openlp/plugins/songs/lib/importer.py b/openlp/plugins/songs/lib/importer.py index 6f54114b2..04ac6df56 100644 --- a/openlp/plugins/songs/lib/importer.py +++ b/openlp/plugins/songs/lib/importer.py @@ -44,6 +44,7 @@ from powersongimport import PowerSongImport from ewimport import EasyWorshipSongImport from songbeamerimport import SongBeamerImport from songshowplusimport import SongShowPlusImport +from songproimport import SongProImport from foilpresenterimport import FoilPresenterImport from zionworximport import ZionWorxImport # Imports that might fail @@ -143,11 +144,11 @@ class SongFormat(object): OpenSong = 9 PowerSong = 10 SongBeamer = 11 - SongShowPlus = 12 - SongsOfFellowship = 13 - WordsOfWorship = 14 - ZionWorx = 15 - #CSV = 16 + SongPro = 12 + SongShowPlus = 13 + SongsOfFellowship = 14 + WordsOfWorship = 15 + ZionWorx = 16 # Set optional attribute defaults __defaults__ = { @@ -258,6 +259,18 @@ class SongFormat(object): 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', @@ -293,12 +306,6 @@ class SongFormat(object): 'First convert your ZionWorx database to a CSV text file, as ' 'explained in the User Manual.') -# }, -# CSV: { -# u'class': CSVImport, -# u'name': WizardStrings.CSV, -# u'prefix': u'csv', -# u'selectMode': SongFormatSelect.SingleFile } } @@ -320,6 +327,7 @@ class SongFormat(object): SongFormat.OpenSong, SongFormat.PowerSong, SongFormat.SongBeamer, + SongFormat.SongPro, SongFormat.SongShowPlus, SongFormat.SongsOfFellowship, SongFormat.WordsOfWorship, From f70b9d35474b49322e7e28b90c690848665e6478 Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Mon, 25 Jun 2012 23:26:46 +0100 Subject: [PATCH 02/11] Include the import class too perhaps --- openlp/plugins/songs/lib/songproimport.py | 263 ++++++++++++++++++++++ 1 file changed, 263 insertions(+) create mode 100644 openlp/plugins/songs/lib/songproimport.py diff --git a/openlp/plugins/songs/lib/songproimport.py b/openlp/plugins/songs/lib/songproimport.py new file mode 100644 index 000000000..a22f18d14 --- /dev/null +++ b/openlp/plugins/songs/lib/songproimport.py @@ -0,0 +1,263 @@ +# -*- 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, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # +# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # +# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # +# Maikel Stuivenberg, Martin Thompson, Jon Tibble, 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.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. + """ + 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 = striprtf(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 <= '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:]) + +# replace with mahfiaz's shared one when his import is merged +def striprtf(text): + pattern = re.compile(r"\\([a-z]{1,32})(-?\d{1,10})?[ ]?|\\'([0-9a-f]{2})|\\([^a-z])|([{}])|[\r\n]+|(.)", re.I) + # control words which specify a "destionation". + destinations = frozenset(( + 'aftncn','aftnsep','aftnsepc','annotation','atnauthor','atndate','atnicn','atnid', + 'atnparent','atnref','atntime','atrfend','atrfstart','author','background', + 'bkmkend','bkmkstart','blipuid','buptim','category','colorschememapping', + 'colortbl','comment','company','creatim','datafield','datastore','defchp','defpap', + 'do','doccomm','docvar','dptxbxtext','ebcend','ebcstart','factoidname','falt', + 'fchars','ffdeftext','ffentrymcr','ffexitmcr','ffformat','ffhelptext','ffl', + 'ffname','ffstattext','field','file','filetbl','fldinst','fldrslt','fldtype', + 'fname','fontemb','fontfile','fonttbl','footer','footerf','footerl','footerr', + 'footnote','formfield','ftncn','ftnsep','ftnsepc','g','generator','gridtbl', + 'header','headerf','headerl','headerr','hl','hlfr','hlinkbase','hlloc','hlsrc', + 'hsv','htmltag','info','keycode','keywords','latentstyles','lchars','levelnumbers', + 'leveltext','lfolevel','linkval','list','listlevel','listname','listoverride', + 'listoverridetable','listpicture','liststylename','listtable','listtext', + 'lsdlockedexcept','macc','maccPr','mailmerge','maln','malnScr','manager','margPr', + 'mbar','mbarPr','mbaseJc','mbegChr','mborderBox','mborderBoxPr','mbox','mboxPr', + 'mchr','mcount','mctrlPr','md','mdeg','mdegHide','mden','mdiff','mdPr','me', + 'mendChr','meqArr','meqArrPr','mf','mfName','mfPr','mfunc','mfuncPr','mgroupChr', + 'mgroupChrPr','mgrow','mhideBot','mhideLeft','mhideRight','mhideTop','mhtmltag', + 'mlim','mlimloc','mlimlow','mlimlowPr','mlimupp','mlimuppPr','mm','mmaddfieldname', + 'mmath','mmathPict','mmathPr','mmaxdist','mmc','mmcJc','mmconnectstr', + 'mmconnectstrdata','mmcPr','mmcs','mmdatasource','mmheadersource','mmmailsubject', + 'mmodso','mmodsofilter','mmodsofldmpdata','mmodsomappedname','mmodsoname', + 'mmodsorecipdata','mmodsosort','mmodsosrc','mmodsotable','mmodsoudl', + 'mmodsoudldata','mmodsouniquetag','mmPr','mmquery','mmr','mnary','mnaryPr', + 'mnoBreak','mnum','mobjDist','moMath','moMathPara','moMathParaPr','mopEmu', + 'mphant','mphantPr','mplcHide','mpos','mr','mrad','mradPr','mrPr','msepChr', + 'mshow','mshp','msPre','msPrePr','msSub','msSubPr','msSubSup','msSubSupPr','msSup', + 'msSupPr','mstrikeBLTR','mstrikeH','mstrikeTLBR','mstrikeV','msub','msubHide', + 'msup','msupHide','mtransp','mtype','mvertJc','mvfmf','mvfml','mvtof','mvtol', + 'mzeroAsc','mzeroDesc','mzeroWid','nesttableprops','nextfile','nonesttables', + 'objalias','objclass','objdata','object','objname','objsect','objtime','oldcprops', + 'oldpprops','oldsprops','oldtprops','oleclsid','operator','panose','password', + 'passwordhash','pgp','pgptbl','picprop','pict','pn','pnseclvl','pntext','pntxta', + 'pntxtb','printim','private','propname','protend','protstart','protusertbl','pxe', + 'result','revtbl','revtim','rsidtbl','rxe','shp','shpgrp','shpinst', + 'shppict','shprslt','shptxt','sn','sp','staticval','stylesheet','subject','sv', + 'svb','tc','template','themedata','title','txe','ud','upr','userprops', + 'wgrffmtfilter','windowcaption','writereservation','writereservhash','xe','xform', + 'xmlattrname','xmlattrvalue','xmlclose','xmlname','xmlnstbl', + 'xmlopen', + )) + # Translation of some special characters. + specialchars = { + 'par': '\n', + 'sect': '\n\n', + 'page': '\n\n', + 'line': '\n', + 'tab': '\t', + 'emdash': u'\u2014', + 'endash': u'\u2013', + 'emspace': u'\u2003', + 'enspace': u'\u2002', + 'qmspace': u'\u2005', + 'bullet': u'\u2022', + 'lquote': u'\u2018', + 'rquote': u'\u2019', + 'ldblquote': u'\201C', + 'rdblquote': u'\u201D', + } + stack = [] + ignorable = False # Whether this group (and all inside it) are "ignorable". + ucskip = 1 # Number of ASCII characters to skip after a unicode character. + curskip = 0 # Number of ASCII characters left to skip + out = [] # Output buffer. + for match in pattern.finditer(text): + word,arg,hex,char,brace,tchar = match.groups() + if brace: + curskip = 0 + if brace == '{': + # Push state + stack.append((ucskip,ignorable)) + elif brace == '}': + # Pop state + ucskip,ignorable = stack.pop() + elif char: # \x (not a letter) + curskip = 0 + if char == '~': + if not ignorable: + out.append(u'\xA0') + elif char in '{}\\': + if not ignorable: + out.append(char) + elif char == '*': + ignorable = True + elif word: # \foo + curskip = 0 + if word in destinations: + ignorable = True + elif ignorable: + pass + elif word in specialchars: + out.append(specialchars[word]) + elif word == 'uc': + ucskip = int(arg) + elif word == 'u': + c = int(arg) + if c < 0: c += 0x10000 + if c > 127: out.append(unichr(c)) + else: out.append(chr(c)) + curskip = ucskip + elif hex: # \'xx + if curskip > 0: + curskip -= 1 + elif not ignorable: + c = int(hex,16) + if c > 127: out.append(unichr(c)) + else: out.append(chr(c)) + elif tchar: + if curskip > 0: + curskip -= 1 + elif not ignorable: + out.append(tchar) + return ''.join(out) From 30943752334e76fcf3b901ca27ed31978b41b147 Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Tue, 3 Jul 2012 22:14:12 +0100 Subject: [PATCH 03/11] Share ew strip_rtf routine --- openlp/plugins/songs/lib/__init__.py | 96 +++++++++++++++++ openlp/plugins/songs/lib/ewimport.py | 98 +---------------- openlp/plugins/songs/lib/songproimport.py | 124 +--------------------- 3 files changed, 100 insertions(+), 218 deletions(-) diff --git a/openlp/plugins/songs/lib/__init__.py b/openlp/plugins/songs/lib/__init__.py index ce41b6faa..7f0bfd2fa 100644 --- a/openlp/plugins/songs/lib/__init__.py +++ b/openlp/plugins/songs/lib/__init__.py @@ -36,6 +36,7 @@ from ui import SongStrings WHITESPACE = re.compile(r'[\W_]+', re.UNICODE) APOSTROPHE = re.compile(u'[\'`’ʻ′]', re.UNICODE) +RTF_STRIPPING_REGEX = re.compile(r'\{\\tx[^}]*\}') class VerseType(object): """ @@ -366,6 +367,101 @@ def clean_song(manager, song): if song.copyright: song.copyright = CONTROL_CHARS.sub(u'', song.copyright).strip() +def strip_rtf(blob, encoding): + depth = 0 + control = False + clear_text = [] + control_word = [] + + # workaround for \tx bug: remove one pair of curly braces + # if \tx is encountered + match = RTF_STRIPPING_REGEX.search(blob) + if match: + # start and end indices of match are curly braces - filter them out + blob = ''.join([blob[i] for i in xrange(len(blob)) + if i != match.start() and i !=match.end()]) + for c in blob: + if control: + # for delimiters, set control to False + if c == '{': + if control_word: + depth += 1 + control = False + elif c == '}': + if control_word: + depth -= 1 + control = False + elif c == '\\': + new_control = bool(control_word) + control = False + elif c.isspace(): + control = False + else: + control_word.append(c) + if len(control_word) == 3 and control_word[0] == '\'': + control = False + if not control: + if not control_word: + if c == '{' or c == '}' or c == '\\': + clear_text.append(c) + else: + control_str = ''.join(control_word) + if control_str == 'par' or control_str == 'line': + clear_text.append(u'\n') + elif control_str == 'tab': + clear_text.append(u'\t') + # Prefer the encoding specified by the RTF data to that + # specified by the Paradox table header + # West European encoding + elif control_str == 'fcharset0': + encoding = u'cp1252' + # Greek encoding + elif control_str == 'fcharset161': + encoding = u'cp1253' + # Turkish encoding + elif control_str == 'fcharset162': + encoding = u'cp1254' + # Vietnamese encoding + elif control_str == 'fcharset163': + encoding = u'cp1258' + # Hebrew encoding + elif control_str == 'fcharset177': + encoding = u'cp1255' + # Arabic encoding + elif control_str == 'fcharset178': + encoding = u'cp1256' + # Baltic encoding + elif control_str == 'fcharset186': + encoding = u'cp1257' + # Cyrillic encoding + elif control_str == 'fcharset204': + encoding = u'cp1251' + # Thai encoding + elif control_str == 'fcharset222': + encoding = u'cp874' + # Central+East European encoding + elif control_str == 'fcharset238': + encoding = u'cp1250' + elif control_str[0] == '\'': + s = chr(int(control_str[1:3], 16)) + clear_text.append(s.decode(encoding)) + del control_word[:] + if c == '\\' and new_control: + control = True + elif c == '{': + depth += 1 + elif c == '}': + depth -= 1 + elif depth > 2: + continue + elif c == '\n' or c == '\r': + continue + elif c == '\\': + control = True + else: + clear_text.append(c) + return u''.join(clear_text) + from xml import OpenLyrics, SongXML from songstab import SongsTab from mediaitem import SongMediaItem diff --git a/openlp/plugins/songs/lib/ewimport.py b/openlp/plugins/songs/lib/ewimport.py index 227b8e4b6..020c489bb 100644 --- a/openlp/plugins/songs/lib/ewimport.py +++ b/openlp/plugins/songs/lib/ewimport.py @@ -36,110 +36,14 @@ import re from openlp.core.lib import translate from openlp.plugins.songs.lib import VerseType -from openlp.plugins.songs.lib import retrieve_windows_encoding +from openlp.plugins.songs.lib import retrieve_windows_encoding, strip_rtf from songimport import SongImport -RTF_STRIPPING_REGEX = re.compile(r'\{\\tx[^}]*\}') # regex: at least two newlines, can have spaces between them SLIDE_BREAK_REGEX = re.compile(r'\n *?\n[\n ]*') NUMBER_REGEX = re.compile(r'[0-9]+') NOTE_REGEX = re.compile(r'\(.*?\)') -def strip_rtf(blob, encoding): - depth = 0 - control = False - clear_text = [] - control_word = [] - - # workaround for \tx bug: remove one pair of curly braces - # if \tx is encountered - match = RTF_STRIPPING_REGEX.search(blob) - if match: - # start and end indices of match are curly braces - filter them out - blob = ''.join([blob[i] for i in xrange(len(blob)) - if i != match.start() and i !=match.end()]) - - for c in blob: - if control: - # for delimiters, set control to False - if c == '{': - if control_word: - depth += 1 - control = False - elif c == '}': - if control_word: - depth -= 1 - control = False - elif c == '\\': - new_control = bool(control_word) - control = False - elif c.isspace(): - control = False - else: - control_word.append(c) - if len(control_word) == 3 and control_word[0] == '\'': - control = False - if not control: - if not control_word: - if c == '{' or c == '}' or c == '\\': - clear_text.append(c) - else: - control_str = ''.join(control_word) - if control_str == 'par' or control_str == 'line': - clear_text.append(u'\n') - elif control_str == 'tab': - clear_text.append(u'\t') - # Prefer the encoding specified by the RTF data to that - # specified by the Paradox table header - # West European encoding - elif control_str == 'fcharset0': - encoding = u'cp1252' - # Greek encoding - elif control_str == 'fcharset161': - encoding = u'cp1253' - # Turkish encoding - elif control_str == 'fcharset162': - encoding = u'cp1254' - # Vietnamese encoding - elif control_str == 'fcharset163': - encoding = u'cp1258' - # Hebrew encoding - elif control_str == 'fcharset177': - encoding = u'cp1255' - # Arabic encoding - elif control_str == 'fcharset178': - encoding = u'cp1256' - # Baltic encoding - elif control_str == 'fcharset186': - encoding = u'cp1257' - # Cyrillic encoding - elif control_str == 'fcharset204': - encoding = u'cp1251' - # Thai encoding - elif control_str == 'fcharset222': - encoding = u'cp874' - # Central+East European encoding - elif control_str == 'fcharset238': - encoding = u'cp1250' - elif control_str[0] == '\'': - s = chr(int(control_str[1:3], 16)) - clear_text.append(s.decode(encoding)) - del control_word[:] - if c == '\\' and new_control: - control = True - elif c == '{': - depth += 1 - elif c == '}': - depth -= 1 - elif depth > 2: - continue - elif c == '\n' or c == '\r': - continue - elif c == '\\': - control = True - else: - clear_text.append(c) - return u''.join(clear_text) class FieldDescEntry: def __init__(self, name, type, size): diff --git a/openlp/plugins/songs/lib/songproimport.py b/openlp/plugins/songs/lib/songproimport.py index a22f18d14..ddc5a79b5 100644 --- a/openlp/plugins/songs/lib/songproimport.py +++ b/openlp/plugins/songs/lib/songproimport.py @@ -33,6 +33,7 @@ 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__) @@ -110,7 +111,7 @@ class SongProImport(SongImport): self.finish() return if u'rtf1' in text: - text = striprtf(text).rstrip() + text = strip_rtf(text, u'cp1252').rstrip() if not text: return if tag == u'A': @@ -136,128 +137,9 @@ class SongProImport(SongImport): self.verseOrderList.append(u'B1') elif char == u'D': self.verseOrderList.append(u'E1') - elif u'1' <= char <= '7': + 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:]) - -# replace with mahfiaz's shared one when his import is merged -def striprtf(text): - pattern = re.compile(r"\\([a-z]{1,32})(-?\d{1,10})?[ ]?|\\'([0-9a-f]{2})|\\([^a-z])|([{}])|[\r\n]+|(.)", re.I) - # control words which specify a "destionation". - destinations = frozenset(( - 'aftncn','aftnsep','aftnsepc','annotation','atnauthor','atndate','atnicn','atnid', - 'atnparent','atnref','atntime','atrfend','atrfstart','author','background', - 'bkmkend','bkmkstart','blipuid','buptim','category','colorschememapping', - 'colortbl','comment','company','creatim','datafield','datastore','defchp','defpap', - 'do','doccomm','docvar','dptxbxtext','ebcend','ebcstart','factoidname','falt', - 'fchars','ffdeftext','ffentrymcr','ffexitmcr','ffformat','ffhelptext','ffl', - 'ffname','ffstattext','field','file','filetbl','fldinst','fldrslt','fldtype', - 'fname','fontemb','fontfile','fonttbl','footer','footerf','footerl','footerr', - 'footnote','formfield','ftncn','ftnsep','ftnsepc','g','generator','gridtbl', - 'header','headerf','headerl','headerr','hl','hlfr','hlinkbase','hlloc','hlsrc', - 'hsv','htmltag','info','keycode','keywords','latentstyles','lchars','levelnumbers', - 'leveltext','lfolevel','linkval','list','listlevel','listname','listoverride', - 'listoverridetable','listpicture','liststylename','listtable','listtext', - 'lsdlockedexcept','macc','maccPr','mailmerge','maln','malnScr','manager','margPr', - 'mbar','mbarPr','mbaseJc','mbegChr','mborderBox','mborderBoxPr','mbox','mboxPr', - 'mchr','mcount','mctrlPr','md','mdeg','mdegHide','mden','mdiff','mdPr','me', - 'mendChr','meqArr','meqArrPr','mf','mfName','mfPr','mfunc','mfuncPr','mgroupChr', - 'mgroupChrPr','mgrow','mhideBot','mhideLeft','mhideRight','mhideTop','mhtmltag', - 'mlim','mlimloc','mlimlow','mlimlowPr','mlimupp','mlimuppPr','mm','mmaddfieldname', - 'mmath','mmathPict','mmathPr','mmaxdist','mmc','mmcJc','mmconnectstr', - 'mmconnectstrdata','mmcPr','mmcs','mmdatasource','mmheadersource','mmmailsubject', - 'mmodso','mmodsofilter','mmodsofldmpdata','mmodsomappedname','mmodsoname', - 'mmodsorecipdata','mmodsosort','mmodsosrc','mmodsotable','mmodsoudl', - 'mmodsoudldata','mmodsouniquetag','mmPr','mmquery','mmr','mnary','mnaryPr', - 'mnoBreak','mnum','mobjDist','moMath','moMathPara','moMathParaPr','mopEmu', - 'mphant','mphantPr','mplcHide','mpos','mr','mrad','mradPr','mrPr','msepChr', - 'mshow','mshp','msPre','msPrePr','msSub','msSubPr','msSubSup','msSubSupPr','msSup', - 'msSupPr','mstrikeBLTR','mstrikeH','mstrikeTLBR','mstrikeV','msub','msubHide', - 'msup','msupHide','mtransp','mtype','mvertJc','mvfmf','mvfml','mvtof','mvtol', - 'mzeroAsc','mzeroDesc','mzeroWid','nesttableprops','nextfile','nonesttables', - 'objalias','objclass','objdata','object','objname','objsect','objtime','oldcprops', - 'oldpprops','oldsprops','oldtprops','oleclsid','operator','panose','password', - 'passwordhash','pgp','pgptbl','picprop','pict','pn','pnseclvl','pntext','pntxta', - 'pntxtb','printim','private','propname','protend','protstart','protusertbl','pxe', - 'result','revtbl','revtim','rsidtbl','rxe','shp','shpgrp','shpinst', - 'shppict','shprslt','shptxt','sn','sp','staticval','stylesheet','subject','sv', - 'svb','tc','template','themedata','title','txe','ud','upr','userprops', - 'wgrffmtfilter','windowcaption','writereservation','writereservhash','xe','xform', - 'xmlattrname','xmlattrvalue','xmlclose','xmlname','xmlnstbl', - 'xmlopen', - )) - # Translation of some special characters. - specialchars = { - 'par': '\n', - 'sect': '\n\n', - 'page': '\n\n', - 'line': '\n', - 'tab': '\t', - 'emdash': u'\u2014', - 'endash': u'\u2013', - 'emspace': u'\u2003', - 'enspace': u'\u2002', - 'qmspace': u'\u2005', - 'bullet': u'\u2022', - 'lquote': u'\u2018', - 'rquote': u'\u2019', - 'ldblquote': u'\201C', - 'rdblquote': u'\u201D', - } - stack = [] - ignorable = False # Whether this group (and all inside it) are "ignorable". - ucskip = 1 # Number of ASCII characters to skip after a unicode character. - curskip = 0 # Number of ASCII characters left to skip - out = [] # Output buffer. - for match in pattern.finditer(text): - word,arg,hex,char,brace,tchar = match.groups() - if brace: - curskip = 0 - if brace == '{': - # Push state - stack.append((ucskip,ignorable)) - elif brace == '}': - # Pop state - ucskip,ignorable = stack.pop() - elif char: # \x (not a letter) - curskip = 0 - if char == '~': - if not ignorable: - out.append(u'\xA0') - elif char in '{}\\': - if not ignorable: - out.append(char) - elif char == '*': - ignorable = True - elif word: # \foo - curskip = 0 - if word in destinations: - ignorable = True - elif ignorable: - pass - elif word in specialchars: - out.append(specialchars[word]) - elif word == 'uc': - ucskip = int(arg) - elif word == 'u': - c = int(arg) - if c < 0: c += 0x10000 - if c > 127: out.append(unichr(c)) - else: out.append(chr(c)) - curskip = ucskip - elif hex: # \'xx - if curskip > 0: - curskip -= 1 - elif not ignorable: - c = int(hex,16) - if c > 127: out.append(unichr(c)) - else: out.append(chr(c)) - elif tchar: - if curskip > 0: - curskip -= 1 - elif not ignorable: - out.append(tchar) - return ''.join(out) From 9c1005ac3cbf4ffacef292d9f55a1d8dc76adfd0 Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Wed, 4 Jul 2012 19:53:03 +0100 Subject: [PATCH 04/11] Fix copyrights --- openlp/plugins/songs/lib/songproimport.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/openlp/plugins/songs/lib/songproimport.py b/openlp/plugins/songs/lib/songproimport.py index ddc5a79b5..9ca30ca95 100644 --- a/openlp/plugins/songs/lib/songproimport.py +++ b/openlp/plugins/songs/lib/songproimport.py @@ -6,10 +6,11 @@ # --------------------------------------------------------------------------- # # Copyright (c) 2008-2012 Raoul Snyman # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan # -# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, # -# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias # -# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # -# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund # +# 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 # From 1edfac99e63662df26d9fd454284a1db658ac572 Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Thu, 5 Jul 2012 00:04:11 +0100 Subject: [PATCH 05/11] Add mediashout import --- openlp/plugins/songs/lib/importer.py | 27 +++-- openlp/plugins/songs/lib/mediashoutimport.py | 108 +++++++++++++++++++ 2 files changed, 127 insertions(+), 8 deletions(-) create mode 100644 openlp/plugins/songs/lib/mediashoutimport.py diff --git a/openlp/plugins/songs/lib/importer.py b/openlp/plugins/songs/lib/importer.py index 04ac6df56..e5f9344e8 100644 --- a/openlp/plugins/songs/lib/importer.py +++ b/openlp/plugins/songs/lib/importer.py @@ -47,6 +47,7 @@ from songshowplusimport import SongShowPlusImport from songproimport import SongProImport from foilpresenterimport import FoilPresenterImport from zionworximport import ZionWorxImport +from mediashoutimport import MediaShoutImport # Imports that might fail log = logging.getLogger(__name__) try: @@ -141,14 +142,15 @@ class SongFormat(object): EasySlides = 6 EasyWorship = 7 FoilPresenter = 8 - OpenSong = 9 - PowerSong = 10 - SongBeamer = 11 - SongPro = 12 - SongShowPlus = 13 - SongsOfFellowship = 14 - WordsOfWorship = 15 - ZionWorx = 16 + MediaShout = 9 + OpenSong = 10 + PowerSong = 11 + SongBeamer = 12 + SongPro = 13 + SongShowPlus = 14 + SongsOfFellowship = 15 + WordsOfWorship = 16 + ZionWorx = 17 # Set optional attribute defaults __defaults__ = { @@ -239,6 +241,14 @@ class SongFormat(object): u'filter': u'%s (*.foil)' % translate( 'SongsPlugin.ImportWizardForm', 'Foilpresenter Song Files') }, + MediaShout: { + u'class': MediaShoutImport, + u'name': u'MediaShout', + u'prefix': u'mediaShout', + u'selectMode': SongFormatSelect.SingleFile, + u'filter': u'%s (*.mdb)' % translate('SongsPlugin.ImportWizardForm', + 'MediaShout Database') + }, OpenSong: { u'class': OpenSongImport, u'name': WizardStrings.OS, @@ -324,6 +334,7 @@ class SongFormat(object): SongFormat.EasySlides, SongFormat.EasyWorship, SongFormat.FoilPresenter, + SongFormat.MediaShout, SongFormat.OpenSong, SongFormat.PowerSong, SongFormat.SongBeamer, diff --git a/openlp/plugins/songs/lib/mediashoutimport.py b/openlp/plugins/songs/lib/mediashoutimport.py new file mode 100644 index 000000000..c8e21644b --- /dev/null +++ b/openlp/plugins/songs/lib/mediashoutimport.py @@ -0,0 +1,108 @@ +# -*- 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. + """ + conn = pyodbc.connect(u'DRIVER={Microsoft Access Driver (*.mdb)};' + u'DBQ=%s;PWD=6NOZ4eHK7k' % self.importSource) + 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() From ef29c0e97e6fddf3d4e2e95ddd244dee45268c4c Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Thu, 5 Jul 2012 00:13:19 +0100 Subject: [PATCH 06/11] Available tests --- openlp/plugins/songs/lib/importer.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/openlp/plugins/songs/lib/importer.py b/openlp/plugins/songs/lib/importer.py index e5f9344e8..bfc186fb3 100644 --- a/openlp/plugins/songs/lib/importer.py +++ b/openlp/plugins/songs/lib/importer.py @@ -47,7 +47,6 @@ from songshowplusimport import SongShowPlusImport from songproimport import SongProImport from foilpresenterimport import FoilPresenterImport from zionworximport import ZionWorxImport -from mediashoutimport import MediaShoutImport # Imports that might fail log = logging.getLogger(__name__) try: @@ -68,7 +67,13 @@ try: 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): """ @@ -242,9 +247,9 @@ class SongFormat(object): 'SongsPlugin.ImportWizardForm', 'Foilpresenter Song Files') }, MediaShout: { - u'class': MediaShoutImport, 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') @@ -392,5 +397,8 @@ if HAS_SOF: 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'] From 3668adc6ffcd24b3b85a467f016ec73b54bbb49c Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Thu, 5 Jul 2012 19:39:47 +0100 Subject: [PATCH 07/11] ewimport and __init__ back now mahfiaz has merged his --- openlp/plugins/songs/lib/__init__.py | 96 --------------------------- openlp/plugins/songs/lib/ewimport.py | 98 +++++++++++++++++++++++++++- 2 files changed, 97 insertions(+), 97 deletions(-) diff --git a/openlp/plugins/songs/lib/__init__.py b/openlp/plugins/songs/lib/__init__.py index 7f0bfd2fa..ce41b6faa 100644 --- a/openlp/plugins/songs/lib/__init__.py +++ b/openlp/plugins/songs/lib/__init__.py @@ -36,7 +36,6 @@ from ui import SongStrings WHITESPACE = re.compile(r'[\W_]+', re.UNICODE) APOSTROPHE = re.compile(u'[\'`’ʻ′]', re.UNICODE) -RTF_STRIPPING_REGEX = re.compile(r'\{\\tx[^}]*\}') class VerseType(object): """ @@ -367,101 +366,6 @@ def clean_song(manager, song): if song.copyright: song.copyright = CONTROL_CHARS.sub(u'', song.copyright).strip() -def strip_rtf(blob, encoding): - depth = 0 - control = False - clear_text = [] - control_word = [] - - # workaround for \tx bug: remove one pair of curly braces - # if \tx is encountered - match = RTF_STRIPPING_REGEX.search(blob) - if match: - # start and end indices of match are curly braces - filter them out - blob = ''.join([blob[i] for i in xrange(len(blob)) - if i != match.start() and i !=match.end()]) - for c in blob: - if control: - # for delimiters, set control to False - if c == '{': - if control_word: - depth += 1 - control = False - elif c == '}': - if control_word: - depth -= 1 - control = False - elif c == '\\': - new_control = bool(control_word) - control = False - elif c.isspace(): - control = False - else: - control_word.append(c) - if len(control_word) == 3 and control_word[0] == '\'': - control = False - if not control: - if not control_word: - if c == '{' or c == '}' or c == '\\': - clear_text.append(c) - else: - control_str = ''.join(control_word) - if control_str == 'par' or control_str == 'line': - clear_text.append(u'\n') - elif control_str == 'tab': - clear_text.append(u'\t') - # Prefer the encoding specified by the RTF data to that - # specified by the Paradox table header - # West European encoding - elif control_str == 'fcharset0': - encoding = u'cp1252' - # Greek encoding - elif control_str == 'fcharset161': - encoding = u'cp1253' - # Turkish encoding - elif control_str == 'fcharset162': - encoding = u'cp1254' - # Vietnamese encoding - elif control_str == 'fcharset163': - encoding = u'cp1258' - # Hebrew encoding - elif control_str == 'fcharset177': - encoding = u'cp1255' - # Arabic encoding - elif control_str == 'fcharset178': - encoding = u'cp1256' - # Baltic encoding - elif control_str == 'fcharset186': - encoding = u'cp1257' - # Cyrillic encoding - elif control_str == 'fcharset204': - encoding = u'cp1251' - # Thai encoding - elif control_str == 'fcharset222': - encoding = u'cp874' - # Central+East European encoding - elif control_str == 'fcharset238': - encoding = u'cp1250' - elif control_str[0] == '\'': - s = chr(int(control_str[1:3], 16)) - clear_text.append(s.decode(encoding)) - del control_word[:] - if c == '\\' and new_control: - control = True - elif c == '{': - depth += 1 - elif c == '}': - depth -= 1 - elif depth > 2: - continue - elif c == '\n' or c == '\r': - continue - elif c == '\\': - control = True - else: - clear_text.append(c) - return u''.join(clear_text) - from xml import OpenLyrics, SongXML from songstab import SongsTab from mediaitem import SongMediaItem diff --git a/openlp/plugins/songs/lib/ewimport.py b/openlp/plugins/songs/lib/ewimport.py index 020c489bb..227b8e4b6 100644 --- a/openlp/plugins/songs/lib/ewimport.py +++ b/openlp/plugins/songs/lib/ewimport.py @@ -36,14 +36,110 @@ import re from openlp.core.lib import translate from openlp.plugins.songs.lib import VerseType -from openlp.plugins.songs.lib import retrieve_windows_encoding, strip_rtf +from openlp.plugins.songs.lib import retrieve_windows_encoding from songimport import SongImport +RTF_STRIPPING_REGEX = re.compile(r'\{\\tx[^}]*\}') # regex: at least two newlines, can have spaces between them SLIDE_BREAK_REGEX = re.compile(r'\n *?\n[\n ]*') NUMBER_REGEX = re.compile(r'[0-9]+') NOTE_REGEX = re.compile(r'\(.*?\)') +def strip_rtf(blob, encoding): + depth = 0 + control = False + clear_text = [] + control_word = [] + + # workaround for \tx bug: remove one pair of curly braces + # if \tx is encountered + match = RTF_STRIPPING_REGEX.search(blob) + if match: + # start and end indices of match are curly braces - filter them out + blob = ''.join([blob[i] for i in xrange(len(blob)) + if i != match.start() and i !=match.end()]) + + for c in blob: + if control: + # for delimiters, set control to False + if c == '{': + if control_word: + depth += 1 + control = False + elif c == '}': + if control_word: + depth -= 1 + control = False + elif c == '\\': + new_control = bool(control_word) + control = False + elif c.isspace(): + control = False + else: + control_word.append(c) + if len(control_word) == 3 and control_word[0] == '\'': + control = False + if not control: + if not control_word: + if c == '{' or c == '}' or c == '\\': + clear_text.append(c) + else: + control_str = ''.join(control_word) + if control_str == 'par' or control_str == 'line': + clear_text.append(u'\n') + elif control_str == 'tab': + clear_text.append(u'\t') + # Prefer the encoding specified by the RTF data to that + # specified by the Paradox table header + # West European encoding + elif control_str == 'fcharset0': + encoding = u'cp1252' + # Greek encoding + elif control_str == 'fcharset161': + encoding = u'cp1253' + # Turkish encoding + elif control_str == 'fcharset162': + encoding = u'cp1254' + # Vietnamese encoding + elif control_str == 'fcharset163': + encoding = u'cp1258' + # Hebrew encoding + elif control_str == 'fcharset177': + encoding = u'cp1255' + # Arabic encoding + elif control_str == 'fcharset178': + encoding = u'cp1256' + # Baltic encoding + elif control_str == 'fcharset186': + encoding = u'cp1257' + # Cyrillic encoding + elif control_str == 'fcharset204': + encoding = u'cp1251' + # Thai encoding + elif control_str == 'fcharset222': + encoding = u'cp874' + # Central+East European encoding + elif control_str == 'fcharset238': + encoding = u'cp1250' + elif control_str[0] == '\'': + s = chr(int(control_str[1:3], 16)) + clear_text.append(s.decode(encoding)) + del control_word[:] + if c == '\\' and new_control: + control = True + elif c == '{': + depth += 1 + elif c == '}': + depth -= 1 + elif depth > 2: + continue + elif c == '\n' or c == '\r': + continue + elif c == '\\': + control = True + else: + clear_text.append(c) + return u''.join(clear_text) class FieldDescEntry: def __init__(self, name, type, size): From 614dc2648bc3945760f6e22c94df52c37fe9af15 Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Thu, 5 Jul 2012 20:24:56 +0100 Subject: [PATCH 08/11] Use new strip_rtf routine and error trap --- openlp/plugins/songs/lib/__init__.py | 2 +- openlp/plugins/songs/lib/importer.py | 1 + openlp/plugins/songs/lib/mediashoutimport.py | 8 +++++++- openlp/plugins/songs/lib/songproimport.py | 4 +++- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/openlp/plugins/songs/lib/__init__.py b/openlp/plugins/songs/lib/__init__.py index a51f3f2fc..d984d5a8d 100644 --- a/openlp/plugins/songs/lib/__init__.py +++ b/openlp/plugins/songs/lib/__init__.py @@ -476,7 +476,7 @@ def get_encoding(font, font_table, default_encoding, failed=False): 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. diff --git a/openlp/plugins/songs/lib/importer.py b/openlp/plugins/songs/lib/importer.py index 665377c65..209539475 100644 --- a/openlp/plugins/songs/lib/importer.py +++ b/openlp/plugins/songs/lib/importer.py @@ -28,6 +28,7 @@ """ The :mod:`importer` modules provides the general song import functionality. """ +import os import logging from openlp.core.lib import translate diff --git a/openlp/plugins/songs/lib/mediashoutimport.py b/openlp/plugins/songs/lib/mediashoutimport.py index c8e21644b..2af9e8cfd 100644 --- a/openlp/plugins/songs/lib/mediashoutimport.py +++ b/openlp/plugins/songs/lib/mediashoutimport.py @@ -56,8 +56,14 @@ class MediaShoutImport(SongImport): """ Receive a single file to import. """ - conn = pyodbc.connect(u'DRIVER={Microsoft Access Driver (*.mdb)};' + 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') diff --git a/openlp/plugins/songs/lib/songproimport.py b/openlp/plugins/songs/lib/songproimport.py index 9ca30ca95..9f4148308 100644 --- a/openlp/plugins/songs/lib/songproimport.py +++ b/openlp/plugins/songs/lib/songproimport.py @@ -81,6 +81,7 @@ class SongProImport(SongImport): """ 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'' @@ -112,7 +113,8 @@ class SongProImport(SongImport): self.finish() return if u'rtf1' in text: - text = strip_rtf(text, u'cp1252').rstrip() + text, self.encoding = strip_rtf(text, self.encoding) + text = text.rstrip() if not text: return if tag == u'A': From 1717e4fa4ca8259074978b5bec5cb0b39cfcb815 Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Fri, 6 Jul 2012 07:31:00 +0100 Subject: [PATCH 09/11] Fix comment location --- openlp/plugins/songs/lib/mediashoutimport.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openlp/plugins/songs/lib/mediashoutimport.py b/openlp/plugins/songs/lib/mediashoutimport.py index 2af9e8cfd..5194b4b7b 100644 --- a/openlp/plugins/songs/lib/mediashoutimport.py +++ b/openlp/plugins/songs/lib/mediashoutimport.py @@ -59,7 +59,8 @@ class MediaShoutImport(SongImport): try: conn = pyodbc.connect(u'DRIVER={Microsoft Access Driver (*.mdb)};' u'DBQ=%s;PWD=6NOZ4eHK7k' % self.importSource) - except: # Unfortunately no specific exception type + except: + # Unfortunately no specific exception type self.logError(self.importSource, translate('SongsPlugin.MediaShoutImport', 'Unable to open the MediaShout database.')) From ca3e938afe08c6a76f2946d04da83c80fcdda0a1 Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Sat, 7 Jul 2012 22:33:17 +0100 Subject: [PATCH 10/11] Remove redundant logging and incrementProgressBar --- openlp/plugins/songs/lib/mediashoutimport.py | 3 --- openlp/plugins/songs/lib/songproimport.py | 7 ++----- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/openlp/plugins/songs/lib/mediashoutimport.py b/openlp/plugins/songs/lib/mediashoutimport.py index 5194b4b7b..f81b208ac 100644 --- a/openlp/plugins/songs/lib/mediashoutimport.py +++ b/openlp/plugins/songs/lib/mediashoutimport.py @@ -31,14 +31,11 @@ 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): diff --git a/openlp/plugins/songs/lib/songproimport.py b/openlp/plugins/songs/lib/songproimport.py index 9f4148308..a813f0519 100644 --- a/openlp/plugins/songs/lib/songproimport.py +++ b/openlp/plugins/songs/lib/songproimport.py @@ -31,14 +31,11 @@ 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 @@ -106,8 +103,8 @@ class SongProImport(SongImport): self.setDefaults() if text: self.title = text - self.importWizard.incrementProgressBar(u'Processing song ' + text, - 0) + #self.importWizard.incrementProgressBar(u'Processing song ' + text, + # 0) return elif tag == u'E': self.finish() From 18fc43f739311a27252349e2395a8eef5fb49ceb Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Sun, 8 Jul 2012 09:56:33 +0100 Subject: [PATCH 11/11] Oops. Don't forget to remove the code after temporarily commenting out --- openlp/plugins/songs/lib/songproimport.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/openlp/plugins/songs/lib/songproimport.py b/openlp/plugins/songs/lib/songproimport.py index a813f0519..44bf0cb44 100644 --- a/openlp/plugins/songs/lib/songproimport.py +++ b/openlp/plugins/songs/lib/songproimport.py @@ -103,8 +103,6 @@ class SongProImport(SongImport): self.setDefaults() if text: self.title = text - #self.importWizard.incrementProgressBar(u'Processing song ' + text, - # 0) return elif tag == u'E': self.finish()