forked from openlp/openlp
r2031
This commit is contained in:
commit
a0012b794d
@ -208,6 +208,20 @@ class OpenLP(QtGui.QApplication):
|
||||
return QtGui.QApplication.event(self, event)
|
||||
|
||||
|
||||
def set_up_logging(log_path):
|
||||
"""
|
||||
Setup our logging using log_path
|
||||
"""
|
||||
check_directory_exists(log_path)
|
||||
filename = os.path.join(log_path, u'openlp.log')
|
||||
logfile = logging.FileHandler(filename, u'w')
|
||||
logfile.setFormatter(logging.Formatter(
|
||||
u'%(asctime)s %(name)-55s %(levelname)-8s %(message)s'))
|
||||
log.addHandler(logfile)
|
||||
if log.isEnabledFor(logging.DEBUG):
|
||||
print 'Logging to:', filename
|
||||
|
||||
|
||||
def main(args=None):
|
||||
"""
|
||||
The main function which parses command line options and then runs
|
||||
@ -231,21 +245,12 @@ def main(args=None):
|
||||
help='Set the Qt4 style (passed directly to Qt4).')
|
||||
parser.add_option('--testing', dest='testing',
|
||||
action='store_true', help='Run by testing framework')
|
||||
# Set up logging
|
||||
log_path = AppLocation.get_directory(AppLocation.CacheDir)
|
||||
check_directory_exists(log_path)
|
||||
filename = os.path.join(log_path, u'openlp.log')
|
||||
logfile = logging.FileHandler(filename, u'w')
|
||||
logfile.setFormatter(logging.Formatter(
|
||||
u'%(asctime)s %(name)-55s %(levelname)-8s %(message)s'))
|
||||
log.addHandler(logfile)
|
||||
# Parse command line options and deal with them.
|
||||
# Use args supplied programatically if possible.
|
||||
(options, args) = parser.parse_args(args) if args else parser.parse_args()
|
||||
qt_args = []
|
||||
if options.loglevel.lower() in ['d', 'debug']:
|
||||
log.setLevel(logging.DEBUG)
|
||||
print 'Logging to:', filename
|
||||
elif options.loglevel.lower() in ['w', 'warning']:
|
||||
log.setLevel(logging.WARNING)
|
||||
else:
|
||||
@ -261,11 +266,13 @@ def main(args=None):
|
||||
app.setOrganizationName(u'OpenLP')
|
||||
app.setOrganizationDomain(u'openlp.org')
|
||||
if options.portable:
|
||||
log.info(u'Running portable')
|
||||
app.setApplicationName(u'OpenLPPortable')
|
||||
Settings.setDefaultFormat(Settings.IniFormat)
|
||||
# Get location OpenLPPortable.ini
|
||||
app_path = AppLocation.get_directory(AppLocation.AppDir)
|
||||
set_up_logging(os.path.abspath(os.path.join(app_path, u'..',
|
||||
u'..', u'Other')))
|
||||
log.info(u'Running portable')
|
||||
portable_settings_file = os.path.abspath(os.path.join(app_path, u'..',
|
||||
u'..', u'Data', u'OpenLP.ini'))
|
||||
# Make this our settings file
|
||||
@ -282,6 +289,7 @@ def main(args=None):
|
||||
portable_settings.sync()
|
||||
else:
|
||||
app.setApplicationName(u'OpenLP')
|
||||
set_up_logging(AppLocation.get_directory(AppLocation.CacheDir))
|
||||
app.setApplicationVersion(get_application_version()[u'version'])
|
||||
# Instance check
|
||||
if not options.testing:
|
||||
|
@ -130,15 +130,15 @@ class Ui_FormattingTagDialog(object):
|
||||
translate('OpenLP.FormattingTagDialog', 'Description'))
|
||||
self.tagLabel.setText(translate('OpenLP.FormattingTagDialog', 'Tag'))
|
||||
self.startTagLabel.setText(
|
||||
translate('OpenLP.FormattingTagDialog', 'Start tag'))
|
||||
translate('OpenLP.FormattingTagDialog', 'Start HTML'))
|
||||
self.endTagLabel.setText(
|
||||
translate('OpenLP.FormattingTagDialog', 'End tag'))
|
||||
translate('OpenLP.FormattingTagDialog', 'End HTML'))
|
||||
self.deletePushButton.setText(UiStrings().Delete)
|
||||
self.newPushButton.setText(UiStrings().New)
|
||||
self.tagTableWidget.horizontalHeaderItem(0).setText(
|
||||
translate('OpenLP.FormattingTagDialog', 'Description'))
|
||||
self.tagTableWidget.horizontalHeaderItem(1).setText(
|
||||
translate('OpenLP.FormattingTagDialog', 'Tag Id'))
|
||||
translate('OpenLP.FormattingTagDialog', 'Tag'))
|
||||
self.tagTableWidget.horizontalHeaderItem(2).setText(
|
||||
translate('OpenLP.FormattingTagDialog', 'Start HTML'))
|
||||
self.tagTableWidget.horizontalHeaderItem(3).setText(
|
||||
|
@ -49,7 +49,7 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog):
|
||||
QtGui.QDialog.__init__(self, parent)
|
||||
self.setupUi(self)
|
||||
QtCore.QObject.connect(self.tagTableWidget,
|
||||
QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onRowSelected)
|
||||
QtCore.SIGNAL(u'itemSelectionChanged()'),self.onRowSelected)
|
||||
QtCore.QObject.connect(self.newPushButton,
|
||||
QtCore.SIGNAL(u'clicked()'), self.onNewClicked)
|
||||
QtCore.QObject.connect(self.savePushButton,
|
||||
|
@ -226,7 +226,7 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
||||
|
||||
def onCurrentIdChanged(self, pageId):
|
||||
"""
|
||||
Detects Page changes and updates as approprate.
|
||||
Detects Page changes and updates as appropriate.
|
||||
"""
|
||||
enabled = self.page(pageId) == self.areaPositionPage
|
||||
self.setOption(QtGui.QWizard.HaveCustomButton1, enabled)
|
||||
|
@ -172,6 +172,11 @@ def _get_os_dir_path(dir_type):
|
||||
u'Library', u'Application Support', u'openlp')
|
||||
else:
|
||||
if dir_type == AppLocation.LanguageDir:
|
||||
prefixes = [u'/usr/local', u'/usr']
|
||||
for prefix in prefixes:
|
||||
directory = os.path.join(prefix, u'share', u'openlp')
|
||||
if os.path.exists(directory):
|
||||
return directory
|
||||
return os.path.join(u'/usr', u'share', u'openlp')
|
||||
if XDG_BASE_AVAILABLE:
|
||||
if dir_type == AppLocation.ConfigDir:
|
||||
|
@ -569,7 +569,9 @@ class BibleMediaItem(MediaManagerItem):
|
||||
if bible:
|
||||
if QtGui.QMessageBox.question(self, UiStrings().ConfirmDelete,
|
||||
unicode(translate('BiblesPlugin.MediaItem',
|
||||
'Are you sure you want to delete "%s"?')) % bible,
|
||||
'Are you sure you want to completely delete "%s" Bible from '
|
||||
'OpenLP?\n\nYou will need to re-import this Bible to use it '
|
||||
'again.'))% bible,
|
||||
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes |
|
||||
QtGui.QMessageBox.No),
|
||||
QtGui.QMessageBox.Yes) == QtGui.QMessageBox.No:
|
||||
|
@ -61,14 +61,14 @@ class AuthorsForm(QtGui.QDialog, Ui_AuthorsDialog):
|
||||
def onFirstNameEditTextEdited(self, display_name):
|
||||
if not self._autoDisplayName:
|
||||
return
|
||||
if not self.lastNameEdit.text():
|
||||
if self.lastNameEdit.text():
|
||||
display_name = display_name + u' ' + self.lastNameEdit.text()
|
||||
self.displayEdit.setText(display_name)
|
||||
|
||||
def onLastNameEditTextEdited(self, display_name):
|
||||
if not self._autoDisplayName:
|
||||
return
|
||||
if not self.firstNameEdit.text():
|
||||
if self.firstNameEdit.text():
|
||||
display_name = self.firstNameEdit.text() + u' ' + display_name
|
||||
self.displayEdit.setText(display_name)
|
||||
|
||||
|
@ -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.
|
||||
|
@ -48,15 +48,8 @@ class EasySlidesImport(SongImport):
|
||||
Initialise the class.
|
||||
"""
|
||||
SongImport.__init__(self, manager, **kwargs)
|
||||
self.commit = True
|
||||
|
||||
def doImport(self):
|
||||
"""
|
||||
Import either each of the files in self.importSources - each element of
|
||||
which can be either a single opensong file, or a zipfile containing
|
||||
multiple opensong files. If `self.commit` is set False, the
|
||||
import will not be committed to the database (useful for test scripts).
|
||||
"""
|
||||
log.info(u'Importing EasySlides XML file %s', self.importSource)
|
||||
parser = etree.XMLParser(remove_blank_text=True)
|
||||
parsed_file = etree.parse(self.importSource, parser)
|
||||
|
@ -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 powersongimport import PowerSongImport
|
||||
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 @@ 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):
|
||||
@ -100,6 +109,7 @@ class SongFormat(object):
|
||||
|
||||
``u'canDisable'``
|
||||
Whether song format importer is disablable.
|
||||
If ``True``, then ``u'disabledLabelText'`` must also be defined.
|
||||
|
||||
``u'availability'``
|
||||
Whether song format importer is available.
|
||||
@ -141,15 +151,16 @@ class SongFormat(object):
|
||||
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__ = {
|
||||
@ -158,7 +169,8 @@ class SongFormat(object):
|
||||
u'selectMode': SongFormatSelect.MultipleFiles,
|
||||
u'filter': u'',
|
||||
u'comboBoxText': None,
|
||||
u'disabledLabelText': u'',
|
||||
u'disabledLabelText': translate('SongsPlugin.ImportWizardForm',
|
||||
'This importer has been disabled.'),
|
||||
u'getFilesTitle': None,
|
||||
u'invalidSourceMsg': None,
|
||||
u'descriptionText': None
|
||||
@ -240,6 +252,19 @@ class SongFormat(object):
|
||||
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'),
|
||||
u'disabledLabelText': translate('SongsPlugin.ImportWizardForm',
|
||||
'The MediaShout importer is only supported on Windows. It has '
|
||||
'been disabled due to a missing Python module. If you want to '
|
||||
'use this importer, you will need to install the "pyodbc" '
|
||||
'module.')
|
||||
},
|
||||
OpenSong: {
|
||||
u'class': OpenSongImport,
|
||||
u'name': WizardStrings.OS,
|
||||
@ -260,6 +285,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',
|
||||
@ -302,12 +339,6 @@ class SongFormat(object):
|
||||
'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 +357,11 @@ class SongFormat(object):
|
||||
SongFormat.EasySlides,
|
||||
SongFormat.EasyWorship,
|
||||
SongFormat.FoilPresenter,
|
||||
SongFormat.MediaShout,
|
||||
SongFormat.OpenSong,
|
||||
SongFormat.PowerSong,
|
||||
SongFormat.SongBeamer,
|
||||
SongFormat.SongPro,
|
||||
SongFormat.SongShowPlus,
|
||||
SongFormat.SongsOfFellowship,
|
||||
SongFormat.SundayPlus,
|
||||
@ -383,5 +416,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']
|
||||
|
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:])
|
@ -37,6 +37,9 @@ from openlp.plugins.songs.lib.songimport import SongImport
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
# Used to strip control chars (except 10=LF, 13=CR)
|
||||
CONTROL_CHARS_MAP = dict.fromkeys(range(10) + [11, 12] + range(14,32) + [127])
|
||||
|
||||
class ZionWorxImport(SongImport):
|
||||
"""
|
||||
The :class:`ZionWorxImport` class provides the ability to import songs
|
||||
@ -78,13 +81,10 @@ class ZionWorxImport(SongImport):
|
||||
"""
|
||||
Receive a CSV file (from a ZionWorx database dump) to import.
|
||||
"""
|
||||
# Used to strip control chars (10=LF, 13=CR, 127=DEL)
|
||||
self.control_chars_map = dict.fromkeys(
|
||||
range(10) + [11, 12] + range(14,32) + [127])
|
||||
with open(self.importSource, 'rb') as songs_file:
|
||||
fieldnames = [u'SongNum', u'Title1', u'Title2', u'Lyrics',
|
||||
field_names = [u'SongNum', u'Title1', u'Title2', u'Lyrics',
|
||||
u'Writer', u'Copyright', u'Keywords', u'DefaultStyle']
|
||||
songs_reader = csv.DictReader(songs_file, fieldnames)
|
||||
songs_reader = csv.DictReader(songs_file, field_names)
|
||||
try:
|
||||
records = list(songs_reader)
|
||||
except csv.Error, e:
|
||||
@ -140,4 +140,4 @@ class ZionWorxImport(SongImport):
|
||||
"""
|
||||
# This encoding choice seems OK. ZionWorx has no option for setting the
|
||||
# encoding for its songs, so we assume encoding is always the same.
|
||||
return unicode(str, u'cp1252').translate(self.control_chars_map)
|
||||
return unicode(str, u'cp1252').translate(CONTROL_CHARS_MAP)
|
||||
|
34
resources/__init__.py
Normal file
34
resources/__init__.py
Normal file
@ -0,0 +1,34 @@
|
||||
# -*- 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:`resources` module contains a bunch of resources for OpenLP.
|
||||
|
||||
DO NOT REMOVE THIS FILE, IT IS REQUIRED FOR INCLUDING THE RESOURCES ON SOME
|
||||
PLATFORMS!
|
||||
"""
|
||||
|
49
setup.py
49
setup.py
@ -28,10 +28,56 @@
|
||||
###############################################################################
|
||||
|
||||
from setuptools import setup, find_packages
|
||||
import re
|
||||
|
||||
VERSION_FILE = 'openlp/.version'
|
||||
SPLIT_ALPHA_DIGITS = re.compile(r'(\d+|\D+)')
|
||||
|
||||
def try_int(s):
|
||||
"""
|
||||
Convert string s to an integer if possible. Fail silently and return
|
||||
the string as-is if it isn't an integer.
|
||||
|
||||
``s``
|
||||
The string to try to convert.
|
||||
"""
|
||||
try:
|
||||
return int(s)
|
||||
except Exception:
|
||||
return s
|
||||
|
||||
def natural_sort_key(s):
|
||||
"""
|
||||
Return a tuple by which s is sorted.
|
||||
|
||||
``s``
|
||||
A string value from the list we want to sort.
|
||||
"""
|
||||
return map(try_int, SPLIT_ALPHA_DIGITS.findall(s))
|
||||
|
||||
def natural_compare(a, b):
|
||||
"""
|
||||
Compare two strings naturally and return the result.
|
||||
|
||||
``a``
|
||||
A string to compare.
|
||||
|
||||
``b``
|
||||
A string to compare.
|
||||
"""
|
||||
return cmp(natural_sort_key(a), natural_sort_key(b))
|
||||
|
||||
def natural_sort(seq, compare=natural_compare):
|
||||
"""
|
||||
Returns a copy of seq, sorted by natural string sort.
|
||||
"""
|
||||
import copy
|
||||
temp = copy.copy(seq)
|
||||
temp.sort(compare)
|
||||
return temp
|
||||
|
||||
try:
|
||||
# Try to import Bazaar
|
||||
from bzrlib.branch import Branch
|
||||
b = Branch.open_containing('.')[0]
|
||||
b.lock_read()
|
||||
@ -46,7 +92,8 @@ try:
|
||||
if revision_id in tags:
|
||||
version = u'%s' % tags[revision_id][0]
|
||||
else:
|
||||
version = '%s-bzr%s' % (sorted(b.tags.get_tag_dict().keys())[-1], revno)
|
||||
version = '%s-bzr%s' % \
|
||||
(natural_sort(b.tags.get_tag_dict().keys())[-1], revno)
|
||||
ver_file = open(VERSION_FILE, u'w')
|
||||
ver_file.write(version)
|
||||
ver_file.close()
|
||||
|
Loading…
Reference in New Issue
Block a user