forked from openlp/openlp
Added ZionWorx importer. Added descriptionLabel to song import wizard.
bzr-revno: 1986
This commit is contained in:
commit
f1afae1813
@ -80,6 +80,10 @@ class UiStrings(object):
|
||||
self.Help = translate('OpenLP.Ui', 'Help')
|
||||
self.Hours = translate('OpenLP.Ui', 'h',
|
||||
'The abbreviated unit for hours')
|
||||
self.IFdSs = translate('OpenLP.Ui', 'Invalid Folder Selected',
|
||||
'Singular')
|
||||
self.IFSs = translate('OpenLP.Ui', 'Invalid File Selected', 'Singular')
|
||||
self.IFSp = translate('OpenLP.Ui', 'Invalid Files Selected', 'Plural')
|
||||
self.Image = translate('OpenLP.Ui', 'Image')
|
||||
self.Import = translate('OpenLP.Ui', 'Import')
|
||||
self.LayoutStyle = translate('OpenLP.Ui', 'Layout style:')
|
||||
|
@ -44,20 +44,9 @@ class WizardStrings(object):
|
||||
# Applications/Formats we import from or export to. These get used in
|
||||
# multiple places but do not need translating unless you find evidence of
|
||||
# the writers translating their own product name.
|
||||
CCLI = u'CCLI/SongSelect'
|
||||
CSV = u'CSV'
|
||||
DB = u'DreamBeam'
|
||||
EW = u'EasyWorship'
|
||||
ES = u'EasySlides'
|
||||
FP = u'Foilpresenter'
|
||||
OL = u'OpenLyrics'
|
||||
OS = u'OpenSong'
|
||||
OSIS = u'OSIS'
|
||||
PS = u'PowerSong 1.0'
|
||||
SB = u'SongBeamer'
|
||||
SoF = u'Songs of Fellowship'
|
||||
SSP = u'SongShow Plus'
|
||||
WoW = u'Words of Worship'
|
||||
# These strings should need a good reason to be retranslated elsewhere.
|
||||
FinishedImport = translate('OpenLP.Ui', 'Finished import.')
|
||||
FormatLabel = translate('OpenLP.Ui', 'Format:')
|
||||
@ -76,10 +65,12 @@ class WizardStrings(object):
|
||||
PercentSymbolFormat = unicode(translate('OpenLP.Ui', '%p%'))
|
||||
Ready = translate('OpenLP.Ui', 'Ready.')
|
||||
StartingImport = translate('OpenLP.Ui', 'Starting import...')
|
||||
YouSpecifyFile = unicode(translate('OpenLP.Ui', 'You need to specify at '
|
||||
YouSpecifyFile = unicode(translate('OpenLP.Ui', 'You need to specify one '
|
||||
'%s file to import from.', 'A file type e.g. OpenSong'))
|
||||
YouSpecifyFiles = unicode(translate('OpenLP.Ui', 'You need to specify at '
|
||||
'least one %s file to import from.', 'A file type e.g. OpenSong'))
|
||||
YouSpecifyFolder = unicode(translate('OpenLP.Ui', 'You need to specify a '
|
||||
'%s folder to import from.', 'A file type e.g. OpenSong'))
|
||||
YouSpecifyFolder = unicode(translate('OpenLP.Ui', 'You need to specify one '
|
||||
'%s folder to import from.', 'A song format e.g. PowerSong'))
|
||||
|
||||
|
||||
class OpenLPWizard(QtGui.QWizard):
|
||||
@ -108,7 +99,7 @@ class OpenLPWizard(QtGui.QWizard):
|
||||
|
||||
def setupUi(self, image):
|
||||
"""
|
||||
Set up the wizard UI
|
||||
Set up the wizard UI.
|
||||
"""
|
||||
self.setModal(True)
|
||||
self.setWizardStyle(QtGui.QWizard.ModernStyle)
|
||||
|
@ -73,7 +73,7 @@ class CSVBible(BibleDB):
|
||||
|
||||
def __init__(self, parent, **kwargs):
|
||||
"""
|
||||
Loads a Bible from a set of CVS files.
|
||||
Loads a Bible from a set of CSV files.
|
||||
This class assumes the files contain all the information and
|
||||
a clean bible is being loaded.
|
||||
"""
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -29,6 +29,9 @@ The :mod:`importer` modules provides the general song import functionality.
|
||||
"""
|
||||
import logging
|
||||
|
||||
from openlp.core.lib import translate
|
||||
from openlp.core.lib.ui import UiStrings
|
||||
from openlp.core.ui.wizard import WizardStrings
|
||||
from opensongimport import OpenSongImport
|
||||
from easyslidesimport import EasySlidesImport
|
||||
from olpimport import OpenLPSongImport
|
||||
@ -41,6 +44,7 @@ from ewimport import EasyWorshipSongImport
|
||||
from songbeamerimport import SongBeamerImport
|
||||
from songshowplusimport import SongShowPlusImport
|
||||
from foilpresenterimport import FoilPresenterImport
|
||||
from zionworximport import ZionWorxImport
|
||||
# Imports that might fail
|
||||
log = logging.getLogger(__name__)
|
||||
try:
|
||||
@ -62,13 +66,58 @@ except ImportError:
|
||||
log.exception('Error importing %s', 'OooImport')
|
||||
HAS_OOO = False
|
||||
|
||||
class SongFormatSelect(object):
|
||||
"""
|
||||
This is a special enumeration class listing available file selection modes.
|
||||
"""
|
||||
SingleFile = 0
|
||||
MultipleFiles = 1
|
||||
SingleFolder = 2
|
||||
|
||||
class SongFormat(object):
|
||||
"""
|
||||
This is a special enumeration class that holds the various types of songs,
|
||||
plus a few helper functions to facilitate generic handling of song types
|
||||
for importing.
|
||||
This is a special static class that holds an enumeration of the various
|
||||
song formats handled by the importer, the attributes of each song format,
|
||||
and a few helper functions.
|
||||
|
||||
Required attributes for each song format:
|
||||
|
||||
``u'class'``
|
||||
Import class, e.g. ``OpenLyricsImport``
|
||||
``u'name'``
|
||||
Name of the format, e.g. ``u'OpenLyrics'``
|
||||
``u'prefix'``
|
||||
Prefix for Qt objects. Use mixedCase, e.g. ``u'openLyrics'``
|
||||
See ``SongImportForm.addFileSelectItem()``
|
||||
|
||||
Optional attributes for each song format:
|
||||
|
||||
``u'canDisable'``
|
||||
Whether song format importer is disablable.
|
||||
``u'availability'``
|
||||
Whether song format importer is available.
|
||||
``u'selectMode'``
|
||||
Whether format accepts single file, multiple files, or single folder
|
||||
(as per ``SongFormatSelect`` options).
|
||||
``u'filter'``
|
||||
File extension filter for ``QFileDialog``.
|
||||
|
||||
Optional/custom text Strings for ``SongImportForm`` widgets:
|
||||
|
||||
``u'comboBoxText'``
|
||||
Combo box selector (default value is the format's ``u'name'``).
|
||||
``u'disabledLabelText'``
|
||||
Required for disablable song formats.
|
||||
``u'getFilesTitle'``
|
||||
Title for ``QFileDialog`` (default includes the format's ``u'name'``).
|
||||
``u'invalidSourceMsg'``
|
||||
Message displayed if ``isValidSource()`` returns ``False``.
|
||||
``u'descriptionText'``
|
||||
Short description (1-2 lines) about the song format.
|
||||
"""
|
||||
_format_availability = {}
|
||||
# Song formats (ordered alphabetically after Generic)
|
||||
# * Numerical order of song formats is significant as it determines the
|
||||
# order used by formatComboBox.
|
||||
Unknown = -1
|
||||
OpenLyrics = 0
|
||||
OpenLP2 = 1
|
||||
@ -85,50 +134,164 @@ class SongFormat(object):
|
||||
SongShowPlus = 12
|
||||
SongsOfFellowship = 13
|
||||
WordsOfWorship = 14
|
||||
#CSV = 15
|
||||
ZionWorx = 15
|
||||
#CSV = 16
|
||||
|
||||
# Set optional attribute defaults
|
||||
__defaults__ = {
|
||||
u'canDisable': False,
|
||||
u'availability': True,
|
||||
u'selectMode': SongFormatSelect.MultipleFiles,
|
||||
u'filter': u'',
|
||||
u'comboBoxText': None,
|
||||
u'disabledLabelText': u'',
|
||||
u'getFilesTitle': None,
|
||||
u'invalidSourceMsg': None,
|
||||
u'descriptionText': None
|
||||
}
|
||||
|
||||
# Set attribute values for each Song Format
|
||||
__attributes__ = {
|
||||
OpenLyrics: {
|
||||
u'class': OpenLyricsImport,
|
||||
u'name': u'OpenLyrics',
|
||||
u'prefix': u'openLyrics',
|
||||
u'filter': u'%s (*.xml)' % translate('SongsPlugin.ImportWizardForm',
|
||||
'OpenLyrics Files'),
|
||||
u'comboBoxText': translate('SongsPlugin.ImportWizardForm',
|
||||
'OpenLyrics or OpenLP 2.0 Exported Song')
|
||||
},
|
||||
OpenLP2: {
|
||||
u'class': OpenLPSongImport,
|
||||
u'name': UiStrings().OLPV2,
|
||||
u'prefix': u'openLP2',
|
||||
u'selectMode': SongFormatSelect.SingleFile,
|
||||
u'filter': u'%s (*.sqlite)' % (translate(
|
||||
'SongsPlugin.ImportWizardForm', 'OpenLP 2.0 Databases'))
|
||||
},
|
||||
OpenLP1: {
|
||||
u'name': UiStrings().OLPV1,
|
||||
u'prefix': u'openLP1',
|
||||
u'canDisable': True,
|
||||
u'selectMode': SongFormatSelect.SingleFile,
|
||||
u'filter': u'%s (*.olp)' % translate('SongsPlugin.ImportWizardForm',
|
||||
'openlp.org v1.x Databases'),
|
||||
u'disabledLabelText': WizardStrings.NoSqlite
|
||||
},
|
||||
Generic: {
|
||||
u'name': translate('SongsPlugin.ImportWizardForm',
|
||||
'Generic Document/Presentation'),
|
||||
u'prefix': u'generic',
|
||||
u'canDisable': True,
|
||||
u'disabledLabelText': translate('SongsPlugin.ImportWizardForm',
|
||||
'The generic document/presentation importer has been disabled '
|
||||
'because OpenLP cannot access OpenOffice or LibreOffice.'),
|
||||
u'getFilesTitle': translate('SongsPlugin.ImportWizardForm',
|
||||
'Select Document/Presentation Files')
|
||||
},
|
||||
CCLI: {
|
||||
u'class': CCLIFileImport,
|
||||
u'name': u'CCLI/SongSelect',
|
||||
u'prefix': u'ccli',
|
||||
u'filter': u'%s (*.usr *.txt)' % translate(
|
||||
'SongsPlugin.ImportWizardForm', 'CCLI SongSelect Files')
|
||||
},
|
||||
DreamBeam: {
|
||||
u'class': DreamBeamImport,
|
||||
u'name': u'DreamBeam',
|
||||
u'prefix': u'dreamBeam',
|
||||
u'filter': u'%s (*.xml)' % translate('SongsPlugin.ImportWizardForm',
|
||||
'DreamBeam Song Files')
|
||||
},
|
||||
EasySlides: {
|
||||
u'class': EasySlidesImport,
|
||||
u'name': u'EasySlides',
|
||||
u'prefix': u'easySlides',
|
||||
u'selectMode': SongFormatSelect.SingleFile,
|
||||
u'filter': u'%s (*.xml)' % translate('SongsPlugin.ImportWizardForm',
|
||||
'EasySlides XML File')
|
||||
},
|
||||
EasyWorship: {
|
||||
u'class': EasyWorshipSongImport,
|
||||
u'name': u'EasyWorship',
|
||||
u'prefix': u'ew',
|
||||
u'selectMode': SongFormatSelect.SingleFile,
|
||||
u'filter': u'%s (*.db)' % translate('SongsPlugin.ImportWizardForm',
|
||||
'EasyWorship Song Database')
|
||||
},
|
||||
FoilPresenter: {
|
||||
u'class': FoilPresenterImport,
|
||||
u'name': u'Foilpresenter',
|
||||
u'prefix': u'foilPresenter',
|
||||
u'filter': u'%s (*.foil)' % translate(
|
||||
'SongsPlugin.ImportWizardForm', 'Foilpresenter Song Files')
|
||||
},
|
||||
OpenSong: {
|
||||
u'class': OpenSongImport,
|
||||
u'name': WizardStrings.OS,
|
||||
u'prefix': u'openSong'
|
||||
},
|
||||
PowerSong: {
|
||||
u'class': PowerSongImport,
|
||||
u'name': u'PowerSong 1.0',
|
||||
u'prefix': u'powerSong',
|
||||
u'selectMode': SongFormatSelect.SingleFolder,
|
||||
u'invalidSourceMsg': translate('SongsPlugin.ImportWizardForm',
|
||||
'You need to specify a valid PowerSong 1.0 database folder.')
|
||||
},
|
||||
SongBeamer: {
|
||||
u'class': SongBeamerImport,
|
||||
u'name': u'SongBeamer',
|
||||
u'prefix': u'songBeamer',
|
||||
u'filter': u'%s (*.sng)' % translate('SongsPlugin.ImportWizardForm',
|
||||
'SongBeamer Files')
|
||||
},
|
||||
SongShowPlus: {
|
||||
u'class': SongShowPlusImport,
|
||||
u'name': u'SongShow Plus',
|
||||
u'prefix': u'songShowPlus',
|
||||
u'filter': u'%s (*.sbsong)' % translate(
|
||||
'SongsPlugin.ImportWizardForm', 'SongShow Plus Song Files')
|
||||
},
|
||||
SongsOfFellowship: {
|
||||
u'name': u'Songs of Fellowship',
|
||||
u'prefix': u'songsOfFellowship',
|
||||
u'canDisable': True,
|
||||
u'filter': u'%s (*.rtf)' % translate('SongsPlugin.ImportWizardForm',
|
||||
'Songs Of Fellowship Song Files'),
|
||||
u'disabledLabelText': translate('SongsPlugin.ImportWizardForm',
|
||||
'The Songs of Fellowship importer has been disabled because '
|
||||
'OpenLP cannot access OpenOffice or LibreOffice.')
|
||||
},
|
||||
WordsOfWorship: {
|
||||
u'class': WowImport,
|
||||
u'name': u'Words of Worship',
|
||||
u'prefix': u'wordsOfWorship',
|
||||
u'filter': u'%s (*.wsg *.wow-song)' % translate(
|
||||
'SongsPlugin.ImportWizardForm', 'Words Of Worship Song Files')
|
||||
},
|
||||
ZionWorx: {
|
||||
u'class': ZionWorxImport,
|
||||
u'name': u'ZionWorx',
|
||||
u'prefix': u'zionWorx',
|
||||
u'selectMode': SongFormatSelect.SingleFile,
|
||||
u'comboBoxText': translate('SongsPlugin.ImportWizardForm',
|
||||
'ZionWorx (CSV)'),
|
||||
u'descriptionText': translate('SongsPlugin.ImportWizardForm',
|
||||
'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
|
||||
}
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def get_class(format):
|
||||
"""
|
||||
Return the appropriate implementation class.
|
||||
|
||||
``format``
|
||||
The song format.
|
||||
"""
|
||||
if format == SongFormat.OpenLP2:
|
||||
return OpenLPSongImport
|
||||
elif format == SongFormat.OpenLP1:
|
||||
return OpenLP1SongImport
|
||||
elif format == SongFormat.OpenLyrics:
|
||||
return OpenLyricsImport
|
||||
elif format == SongFormat.OpenSong:
|
||||
return OpenSongImport
|
||||
elif format == SongFormat.SongsOfFellowship:
|
||||
return SofImport
|
||||
elif format == SongFormat.WordsOfWorship:
|
||||
return WowImport
|
||||
elif format == SongFormat.Generic:
|
||||
return OooImport
|
||||
elif format == SongFormat.CCLI:
|
||||
return CCLIFileImport
|
||||
elif format == SongFormat.DreamBeam:
|
||||
return DreamBeamImport
|
||||
elif format == SongFormat.PowerSong:
|
||||
return PowerSongImport
|
||||
elif format == SongFormat.EasySlides:
|
||||
return EasySlidesImport
|
||||
elif format == SongFormat.EasyWorship:
|
||||
return EasyWorshipSongImport
|
||||
elif format == SongFormat.SongBeamer:
|
||||
return SongBeamerImport
|
||||
elif format == SongFormat.SongShowPlus:
|
||||
return SongShowPlusImport
|
||||
elif format == SongFormat.FoilPresenter:
|
||||
return FoilPresenterImport
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def get_formats_list():
|
||||
def get_format_list():
|
||||
"""
|
||||
Return a list of the supported song formats.
|
||||
"""
|
||||
@ -138,7 +301,7 @@ class SongFormat(object):
|
||||
SongFormat.OpenLP1,
|
||||
SongFormat.Generic,
|
||||
SongFormat.CCLI,
|
||||
SongFormat.DreamBeam,
|
||||
SongFormat.DreamBeam,
|
||||
SongFormat.EasySlides,
|
||||
SongFormat.EasyWorship,
|
||||
SongFormat.FoilPresenter,
|
||||
@ -147,26 +310,55 @@ class SongFormat(object):
|
||||
SongFormat.SongBeamer,
|
||||
SongFormat.SongShowPlus,
|
||||
SongFormat.SongsOfFellowship,
|
||||
SongFormat.WordsOfWorship
|
||||
SongFormat.WordsOfWorship,
|
||||
SongFormat.ZionWorx
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
def get(format, *attributes):
|
||||
"""
|
||||
Return requested song format attribute(s).
|
||||
|
||||
``format``
|
||||
A song format from SongFormat.
|
||||
|
||||
``*attributes``
|
||||
Zero or more song format attributes from SongFormat.
|
||||
|
||||
Return type depends on number of supplied attributes:
|
||||
:0: Return dict containing all defined attributes for the format.
|
||||
:1: Return the attribute value.
|
||||
:>1: Return tuple of requested attribute values.
|
||||
"""
|
||||
if not attributes:
|
||||
return SongFormat.__attributes__.get(format)
|
||||
elif len(attributes) == 1:
|
||||
default = SongFormat.__defaults__.get(attributes[0])
|
||||
return SongFormat.__attributes__[format].get(attributes[0],
|
||||
default)
|
||||
else:
|
||||
values = []
|
||||
for attr in attributes:
|
||||
default = SongFormat.__defaults__.get(attr)
|
||||
values.append(SongFormat.__attributes__[format].get(attr,
|
||||
default))
|
||||
return tuple(values)
|
||||
|
||||
@staticmethod
|
||||
def set_availability(format, available):
|
||||
def set(format, attribute, value):
|
||||
"""
|
||||
Set the availability for a given song format.
|
||||
Set specified song format attribute to the supplied value.
|
||||
"""
|
||||
SongFormat._format_availability[format] = available
|
||||
SongFormat.__attributes__[format][attribute] = value
|
||||
|
||||
@staticmethod
|
||||
def get_availability(format):
|
||||
"""
|
||||
Return the availability of a given song format.
|
||||
"""
|
||||
return SongFormat._format_availability.get(format, True)
|
||||
|
||||
SongFormat.set_availability(SongFormat.OpenLP1, HAS_OPENLP1)
|
||||
SongFormat.set_availability(SongFormat.SongsOfFellowship, HAS_SOF)
|
||||
SongFormat.set_availability(SongFormat.Generic, HAS_OOO)
|
||||
|
||||
__all__ = [u'SongFormat']
|
||||
SongFormat.set(SongFormat.OpenLP1, u'availability', HAS_OPENLP1)
|
||||
if HAS_OPENLP1:
|
||||
SongFormat.set(SongFormat.OpenLP1, u'class', OpenLP1SongImport)
|
||||
SongFormat.set(SongFormat.SongsOfFellowship, u'availability', HAS_SOF)
|
||||
if HAS_SOF:
|
||||
SongFormat.set(SongFormat.SongsOfFellowship, u'class', SofImport)
|
||||
SongFormat.set(SongFormat.Generic, u'availability', HAS_OOO)
|
||||
if HAS_OOO:
|
||||
SongFormat.set(SongFormat.Generic, u'class', OooImport)
|
||||
|
||||
__all__ = [u'SongFormat', u'SongFormatSelect']
|
||||
|
@ -33,7 +33,6 @@ import fnmatch
|
||||
import os
|
||||
|
||||
from openlp.core.lib import translate
|
||||
from openlp.core.ui.wizard import WizardStrings
|
||||
from openlp.plugins.songs.lib.songimport import SongImport
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@ -71,26 +70,25 @@ class PowerSongImport(SongImport):
|
||||
|
||||
* .song
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def isValidSource(**kwargs):
|
||||
def isValidSource(import_source):
|
||||
"""
|
||||
Checks if source is a PowerSong 1.0 folder:
|
||||
* is a directory
|
||||
* contains at least one *.song file
|
||||
"""
|
||||
if u'folder' in kwargs:
|
||||
dir = kwargs[u'folder']
|
||||
if os.path.isdir(dir):
|
||||
for file in os.listdir(dir):
|
||||
if fnmatch.fnmatch(file, u'*.song'):
|
||||
return True
|
||||
if os.path.isdir(import_source):
|
||||
for file in os.listdir(import_source):
|
||||
if fnmatch.fnmatch(file, u'*.song'):
|
||||
return True
|
||||
return False
|
||||
|
||||
def doImport(self):
|
||||
"""
|
||||
Receive either a list of files or a folder (unicode) to import.
|
||||
"""
|
||||
from importer import SongFormat
|
||||
PS_string = SongFormat.get(SongFormat.PowerSong, u'name')
|
||||
if isinstance(self.importSource, unicode):
|
||||
if os.path.isdir(self.importSource):
|
||||
dir = self.importSource
|
||||
@ -104,7 +102,7 @@ class PowerSongImport(SongImport):
|
||||
self.logError(unicode(translate('SongsPlugin.PowerSongImport',
|
||||
'No songs to import.')),
|
||||
unicode(translate('SongsPlugin.PowerSongImport',
|
||||
'No %s files found.' % WizardStrings.PS)))
|
||||
'No %s files found.' % PS_string)))
|
||||
return
|
||||
self.importWizard.progressBar.setMaximum(len(self.importSource))
|
||||
for file in self.importSource:
|
||||
@ -124,7 +122,7 @@ class PowerSongImport(SongImport):
|
||||
self.logError(os.path.basename(file), unicode(
|
||||
translate('SongsPlugin.PowerSongImport',
|
||||
'Invalid %s file. Unexpected byte value.'
|
||||
% WizardStrings.PS)))
|
||||
% PS_string)))
|
||||
break
|
||||
else:
|
||||
if label == u'TITLE':
|
||||
@ -142,15 +140,14 @@ class PowerSongImport(SongImport):
|
||||
if not self.title:
|
||||
self.logError(os.path.basename(file), unicode(
|
||||
translate('SongsPlugin.PowerSongImport',
|
||||
'Invalid %s file. Missing "TITLE" header.'
|
||||
% WizardStrings.PS)))
|
||||
'Invalid %s file. Missing "TITLE" header.' % PS_string)))
|
||||
continue
|
||||
# Check that file had COPYRIGHTLINE label
|
||||
if not found_copyright:
|
||||
self.logError(self.title, unicode(
|
||||
translate('SongsPlugin.PowerSongImport',
|
||||
'Invalid %s file. Missing "COPYRIGHTLINE" '
|
||||
'header.' % WizardStrings.PS)))
|
||||
'header.' % PS_string)))
|
||||
continue
|
||||
# Check that file had at least one verse
|
||||
if not self.verses:
|
||||
|
@ -51,11 +51,11 @@ class SongImport(QtCore.QObject):
|
||||
as necessary
|
||||
"""
|
||||
@staticmethod
|
||||
def isValidSource(**kwargs):
|
||||
def isValidSource(import_source):
|
||||
"""
|
||||
Override this method to validate the source prior to import.
|
||||
"""
|
||||
pass
|
||||
return True
|
||||
|
||||
def __init__(self, manager, **kwargs):
|
||||
"""
|
||||
|
142
openlp/plugins/songs/lib/zionworximport.py
Normal file
142
openlp/plugins/songs/lib/zionworximport.py
Normal file
@ -0,0 +1,142 @@
|
||||
# -*- 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:`zionworximport` module provides the functionality for importing
|
||||
ZionWorx songs into the OpenLP database.
|
||||
"""
|
||||
import csv
|
||||
import logging
|
||||
|
||||
from openlp.core.lib import translate
|
||||
from openlp.plugins.songs.lib.songimport import SongImport
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
class ZionWorxImport(SongImport):
|
||||
"""
|
||||
The :class:`ZionWorxImport` class provides the ability to import songs
|
||||
from ZionWorx, via a dump of the ZionWorx database to a CSV file.
|
||||
|
||||
ZionWorx song database fields:
|
||||
|
||||
* ``SongNum`` Song ID. (Discarded by importer)
|
||||
* ``Title1`` Main Title.
|
||||
* ``Title2`` Alternate Title.
|
||||
* ``Lyrics`` Song verses, separated by blank lines.
|
||||
* ``Writer`` Song author(s).
|
||||
* ``Copyright`` Copyright information
|
||||
* ``Keywords`` (Discarded by importer)
|
||||
* ``DefaultStyle`` (Discarded by importer)
|
||||
|
||||
ZionWorx has no native export function; it uses the proprietary TurboDB
|
||||
database engine. The TurboDB vendor, dataWeb, provides tools which can
|
||||
export TurboDB tables to other formats, such as freeware console tool
|
||||
TurboDB Data Exchange which is available for Windows and Linux. This command
|
||||
exports the ZionWorx songs table to a CSV file:
|
||||
|
||||
``tdbdatax MainTable.dat songstable.csv -fsdf -s, -qd``
|
||||
|
||||
* -f Table format: ``sdf`` denotes text file.
|
||||
* -s Separator character between fields.
|
||||
* -q Quote character surrounding fields. ``d`` denotes double-quote.
|
||||
|
||||
CSV format expected by importer:
|
||||
|
||||
* Field separator character is comma ``,``
|
||||
* Fields surrounded by double-quotes ``"``. This enables fields (such as
|
||||
Lyrics) to include new-lines and commas. Double-quotes within a field
|
||||
are denoted by two double-quotes ``""``
|
||||
* Note: This is the default format of the Python ``csv`` module.
|
||||
|
||||
"""
|
||||
def doImport(self):
|
||||
"""
|
||||
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',
|
||||
u'Writer', u'Copyright', u'Keywords', u'DefaultStyle']
|
||||
songs_reader = csv.DictReader(songs_file, fieldnames)
|
||||
try:
|
||||
records = list(songs_reader)
|
||||
except csv.Error, e:
|
||||
self.logError(unicode(translate('SongsPlugin.ZionWorxImport',
|
||||
'Error reading CSV file.')),
|
||||
unicode(translate('SongsPlugin.ZionWorxImport',
|
||||
'Line %d: %s' % (songs_reader.line_num, e))))
|
||||
return
|
||||
num_records = len(records)
|
||||
log.info(u'%s records found in CSV file' % num_records)
|
||||
self.importWizard.progressBar.setMaximum(num_records)
|
||||
for index, record in enumerate(records, 1):
|
||||
if self.stopImportFlag:
|
||||
return
|
||||
self.setDefaults()
|
||||
try:
|
||||
self.title = self._decode(record[u'Title1'])
|
||||
if record[u'Title2']:
|
||||
self.alternateTitle = self._decode(record[u'Title2'])
|
||||
self.parseAuthor(self._decode(record[u'Writer']))
|
||||
self.addCopyright(self._decode(record[u'Copyright']))
|
||||
lyrics = self._decode(record[u'Lyrics'])
|
||||
except UnicodeDecodeError, e:
|
||||
self.logError(unicode(translate(
|
||||
'SongsPlugin.ZionWorxImport', 'Record %d' % index)),
|
||||
unicode(translate('SongsPlugin.ZionWorxImport',
|
||||
'Decoding error: %s' % e)))
|
||||
continue
|
||||
except TypeError, e:
|
||||
self.logError(unicode(translate(
|
||||
'SongsPlugin.ZionWorxImport', 'File not valid ZionWorx '
|
||||
'CSV format.')), u'TypeError: %s' % e)
|
||||
return
|
||||
verse = u''
|
||||
for line in lyrics.splitlines():
|
||||
if line and not line.isspace():
|
||||
verse += line + u'\n'
|
||||
elif verse:
|
||||
self.addVerse(verse)
|
||||
verse = u''
|
||||
if verse:
|
||||
self.addVerse(verse)
|
||||
title = self.title
|
||||
if not self.finish():
|
||||
self.logError(unicode(translate(
|
||||
'SongsPlugin.ZionWorxImport', 'Record %d' % index))
|
||||
+ (u': "' + title + u'"' if title else u''))
|
||||
|
||||
def _decode(self, str):
|
||||
"""
|
||||
Decodes CSV input to unicode, stripping all control characters (except
|
||||
new lines).
|
||||
"""
|
||||
# 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)
|
@ -194,7 +194,7 @@ class SongsPlugin(Plugin):
|
||||
self.manager.save_object(song)
|
||||
|
||||
def importSongs(self, format, **kwargs):
|
||||
class_ = SongFormat.get_class(format)
|
||||
class_ = SongFormat.get(format, u'class')
|
||||
importer = class_(self.manager, **kwargs)
|
||||
importer.register(self.mediaItem.importWizard)
|
||||
return importer
|
||||
|
Loading…
Reference in New Issue
Block a user