forked from openlp/openlp
Added SongShow Plus importer.
This commit is contained in:
parent
eabff22221
commit
1913da71cc
@ -140,6 +140,12 @@ class SongImportForm(OpenLPWizard):
|
|||||||
QtCore.QObject.connect(self.songBeamerRemoveButton,
|
QtCore.QObject.connect(self.songBeamerRemoveButton,
|
||||||
QtCore.SIGNAL(u'clicked()'),
|
QtCore.SIGNAL(u'clicked()'),
|
||||||
self.onSongBeamerRemoveButtonClicked)
|
self.onSongBeamerRemoveButtonClicked)
|
||||||
|
QtCore.QObject.connect(self.songShowPlusAddButton,
|
||||||
|
QtCore.SIGNAL(u'clicked()'),
|
||||||
|
self.onSongShowPlusAddButtonClicked)
|
||||||
|
QtCore.QObject.connect(self.songShowPlusRemoveButton,
|
||||||
|
QtCore.SIGNAL(u'clicked()'),
|
||||||
|
self.onSongShowPlusRemoveButtonClicked)
|
||||||
|
|
||||||
def addCustomPages(self):
|
def addCustomPages(self):
|
||||||
"""
|
"""
|
||||||
@ -188,6 +194,8 @@ class SongImportForm(OpenLPWizard):
|
|||||||
self.addFileSelectItem(u'ew', single_select=True)
|
self.addFileSelectItem(u'ew', single_select=True)
|
||||||
# Words of Worship
|
# Words of Worship
|
||||||
self.addFileSelectItem(u'songBeamer')
|
self.addFileSelectItem(u'songBeamer')
|
||||||
|
# Song Show Plus
|
||||||
|
self.addFileSelectItem(u'songShowPlus')
|
||||||
# Commented out for future use.
|
# Commented out for future use.
|
||||||
# self.addFileSelectItem(u'csv', u'CSV', single_select=True)
|
# self.addFileSelectItem(u'csv', u'CSV', single_select=True)
|
||||||
self.sourceLayout.addLayout(self.formatStack)
|
self.sourceLayout.addLayout(self.formatStack)
|
||||||
@ -237,6 +245,8 @@ class SongImportForm(OpenLPWizard):
|
|||||||
translate('SongsPlugin.ImportWizardForm', 'EasyWorship'))
|
translate('SongsPlugin.ImportWizardForm', 'EasyWorship'))
|
||||||
self.formatComboBox.setItemText(10,
|
self.formatComboBox.setItemText(10,
|
||||||
translate('SongsPlugin.ImportWizardForm', 'SongBeamer'))
|
translate('SongsPlugin.ImportWizardForm', 'SongBeamer'))
|
||||||
|
self.formatComboBox.setItemText(11,
|
||||||
|
translate('SongsPlugin.ImportWizardForm', 'SongShow Plus'))
|
||||||
# self.formatComboBox.setItemText(11,
|
# self.formatComboBox.setItemText(11,
|
||||||
# translate('SongsPlugin.ImportWizardForm', 'CSV'))
|
# translate('SongsPlugin.ImportWizardForm', 'CSV'))
|
||||||
self.openLP2FilenameLabel.setText(
|
self.openLP2FilenameLabel.setText(
|
||||||
@ -301,6 +311,10 @@ class SongImportForm(OpenLPWizard):
|
|||||||
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
|
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
|
||||||
self.songBeamerRemoveButton.setText(
|
self.songBeamerRemoveButton.setText(
|
||||||
translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
|
translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
|
||||||
|
self.songShowPlusAddButton.setText(
|
||||||
|
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
|
||||||
|
self.songShowPlusRemoveButton.setText(
|
||||||
|
translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
|
||||||
# self.csvFilenameLabel.setText(
|
# self.csvFilenameLabel.setText(
|
||||||
# translate('SongsPlugin.ImportWizardForm', 'Filename:'))
|
# translate('SongsPlugin.ImportWizardForm', 'Filename:'))
|
||||||
# self.csvBrowseButton.setText(
|
# self.csvBrowseButton.setText(
|
||||||
@ -438,6 +452,16 @@ class SongImportForm(OpenLPWizard):
|
|||||||
'file to import from.'))
|
'file to import from.'))
|
||||||
self.songBeamerAddButton.setFocus()
|
self.songBeamerAddButton.setFocus()
|
||||||
return False
|
return False
|
||||||
|
elif source_format == SongFormat.SongShowPlus:
|
||||||
|
if self.songShowPlusFileListWidget.count() == 0:
|
||||||
|
critical_error_message_box(
|
||||||
|
translate('SongsPlugin.ImportWizardForm',
|
||||||
|
'No SongShow Plus Files Selected'),
|
||||||
|
translate('SongsPlugin.ImportWizardForm',
|
||||||
|
'You need to add at least one SongShow Plus '
|
||||||
|
'file to import from.'))
|
||||||
|
self.wordsOfWorshipAddButton.setFocus()
|
||||||
|
return False
|
||||||
return True
|
return True
|
||||||
elif self.currentPage() == self.progressPage:
|
elif self.currentPage() == self.progressPage:
|
||||||
return True
|
return True
|
||||||
@ -672,6 +696,24 @@ class SongImportForm(OpenLPWizard):
|
|||||||
"""
|
"""
|
||||||
self.removeSelectedItems(self.songBeamerFileListWidget)
|
self.removeSelectedItems(self.songBeamerFileListWidget)
|
||||||
|
|
||||||
|
def onSongShowPlusAddButtonClicked(self):
|
||||||
|
"""
|
||||||
|
Get SongShow Plus song database files
|
||||||
|
"""
|
||||||
|
self.getFiles(
|
||||||
|
translate('SongsPlugin.ImportWizardForm',
|
||||||
|
'Select SongShow Plus Files'),
|
||||||
|
self.songShowPlusFileListWidget, u'%s (*.sbsong)'
|
||||||
|
% translate('SongsPlugin.ImportWizardForm',
|
||||||
|
'SongShow Plus Song Files')
|
||||||
|
)
|
||||||
|
|
||||||
|
def onSongShowPlusRemoveButtonClicked(self):
|
||||||
|
"""
|
||||||
|
Remove selected SongShow Plus files from the import list
|
||||||
|
"""
|
||||||
|
self.removeSelectedItems(self.songShowPlusFileListWidget)
|
||||||
|
|
||||||
def registerFields(self):
|
def registerFields(self):
|
||||||
"""
|
"""
|
||||||
Register song import wizard fields.
|
Register song import wizard fields.
|
||||||
@ -697,6 +739,7 @@ class SongImportForm(OpenLPWizard):
|
|||||||
self.easiSlidesFilenameEdit.setText(u'')
|
self.easiSlidesFilenameEdit.setText(u'')
|
||||||
self.ewFilenameEdit.setText(u'')
|
self.ewFilenameEdit.setText(u'')
|
||||||
self.songBeamerFileListWidget.clear()
|
self.songBeamerFileListWidget.clear()
|
||||||
|
self.songShowPlusFileListWidget.clear()
|
||||||
#self.csvFilenameEdit.setText(u'')
|
#self.csvFilenameEdit.setText(u'')
|
||||||
|
|
||||||
def preWizard(self):
|
def preWizard(self):
|
||||||
@ -773,6 +816,12 @@ class SongImportForm(OpenLPWizard):
|
|||||||
importer = self.plugin.importSongs(SongFormat.SongBeamer,
|
importer = self.plugin.importSongs(SongFormat.SongBeamer,
|
||||||
filenames=self.getListOfFiles(self.songBeamerFileListWidget)
|
filenames=self.getListOfFiles(self.songBeamerFileListWidget)
|
||||||
)
|
)
|
||||||
|
elif source_format == SongFormat.SongShowPlus:
|
||||||
|
# Import ShongShow Plus songs
|
||||||
|
importer = self.plugin.importSongs(SongFormat.SongShowPlus,
|
||||||
|
filenames=self.getListOfFiles(
|
||||||
|
self.songShowPlusFileListWidget)
|
||||||
|
)
|
||||||
if importer.do_import():
|
if importer.do_import():
|
||||||
self.progressLabel.setText(
|
self.progressLabel.setText(
|
||||||
translate('SongsPlugin.SongImportForm', 'Finished import.'))
|
translate('SongsPlugin.SongImportForm', 'Finished import.'))
|
||||||
|
@ -34,6 +34,7 @@ from wowimport import WowImport
|
|||||||
from cclifileimport import CCLIFileImport
|
from cclifileimport import CCLIFileImport
|
||||||
from ewimport import EasyWorshipSongImport
|
from ewimport import EasyWorshipSongImport
|
||||||
from songbeamerimport import SongBeamerImport
|
from songbeamerimport import SongBeamerImport
|
||||||
|
from songshowplusimport import SongShowPlusImport
|
||||||
# Imports that might fail
|
# Imports that might fail
|
||||||
try:
|
try:
|
||||||
from olp1import import OpenLP1SongImport
|
from olp1import import OpenLP1SongImport
|
||||||
@ -71,6 +72,7 @@ class SongFormat(object):
|
|||||||
EasiSlides = 8
|
EasiSlides = 8
|
||||||
EasyWorship = 9
|
EasyWorship = 9
|
||||||
SongBeamer = 10
|
SongBeamer = 10
|
||||||
|
SongShowPlus = 11
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_class(format):
|
def get_class(format):
|
||||||
@ -102,6 +104,8 @@ class SongFormat(object):
|
|||||||
return EasyWorshipSongImport
|
return EasyWorshipSongImport
|
||||||
elif format == SongFormat.SongBeamer:
|
elif format == SongFormat.SongBeamer:
|
||||||
return SongBeamerImport
|
return SongBeamerImport
|
||||||
|
elif format == SongFormat.SongShowPlus:
|
||||||
|
return SongShowPlusImport
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -120,7 +124,8 @@ class SongFormat(object):
|
|||||||
SongFormat.Generic,
|
SongFormat.Generic,
|
||||||
SongFormat.EasiSlides,
|
SongFormat.EasiSlides,
|
||||||
SongFormat.EasyWorship,
|
SongFormat.EasyWorship,
|
||||||
SongFormat.SongBeamer
|
SongFormat.SongBeamer,
|
||||||
|
SongFormat.SongShowPlus
|
||||||
]
|
]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
212
openlp/plugins/songs/lib/songshowplusimport.py
Normal file
212
openlp/plugins/songs/lib/songshowplusimport.py
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# OpenLP - Open Source Lyrics Projection #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||||
|
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
|
||||||
|
# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian #
|
||||||
|
# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
|
||||||
|
# Carsten Tinggaard, 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:`wowimport` module provides the functionality for importing Words of
|
||||||
|
Worship songs into the OpenLP database.
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
|
import struct
|
||||||
|
|
||||||
|
from openlp.plugins.songs.lib.songimport import SongImport
|
||||||
|
|
||||||
|
TITLE = 1
|
||||||
|
AUTHOR = 2
|
||||||
|
COPYRIGHT = 3
|
||||||
|
CCLI_NO = 5
|
||||||
|
VERSE = 12
|
||||||
|
CHORUS = 20
|
||||||
|
TOPIC = 29
|
||||||
|
COMMENTS = 30
|
||||||
|
VERSE_ORDER = 31
|
||||||
|
SONG_BOOK = 35
|
||||||
|
SONG_NUMBER = 36
|
||||||
|
CUSTOM_VERSE = 37
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
class SongShowPlusImport(SongImport):
|
||||||
|
"""
|
||||||
|
The :class:`SongShowPlusImport` class provides the ability to import song
|
||||||
|
files from SongShow Plus.
|
||||||
|
|
||||||
|
**SongShow Plus Song File Format:**
|
||||||
|
|
||||||
|
The SongShow Plus song file format is as follows:
|
||||||
|
|
||||||
|
* Each piece of data in the song file has some information that precedes
|
||||||
|
it.
|
||||||
|
* The general format of this data is as follows:
|
||||||
|
4 Bytes, forming a 32 bit number, a key if you will, this describes what
|
||||||
|
the data is (see blockKey below)
|
||||||
|
4 Bytes, forming a 32 bit number, which is the number of bytes until the
|
||||||
|
next block starts
|
||||||
|
1 Byte, which tells how namy bytes follows
|
||||||
|
1 or 4 Bytes, describes how long the string is, if its 1 byte, the string
|
||||||
|
is less than 255
|
||||||
|
The next bytes are the actuall data.
|
||||||
|
The next block of data follows on.
|
||||||
|
|
||||||
|
This description does differ for verses. Which includes extra bytes
|
||||||
|
stating the verse type or number. In some cases a "custom" verse is used,
|
||||||
|
in that case, this block will in include 2 strings, with the associated
|
||||||
|
string length descriptors. The first string is the name of the verse, the
|
||||||
|
second is the verse content.
|
||||||
|
|
||||||
|
The file is ended with four null bytes.
|
||||||
|
|
||||||
|
Valid extensions for a SongShow Plus song file are:
|
||||||
|
|
||||||
|
* .sbsong
|
||||||
|
"""
|
||||||
|
otherList = {}
|
||||||
|
otherCount = 0
|
||||||
|
|
||||||
|
def __init__(self, master_manager, **kwargs):
|
||||||
|
"""
|
||||||
|
Initialise the import.
|
||||||
|
|
||||||
|
``master_manager``
|
||||||
|
The song manager for the running OpenLP installation.
|
||||||
|
"""
|
||||||
|
SongImport.__init__(self, master_manager)
|
||||||
|
if kwargs.has_key(u'filename'):
|
||||||
|
self.import_source = kwargs[u'filename']
|
||||||
|
if kwargs.has_key(u'filenames'):
|
||||||
|
self.import_source = kwargs[u'filenames']
|
||||||
|
log.debug(self.import_source)
|
||||||
|
|
||||||
|
def do_import(self):
|
||||||
|
"""
|
||||||
|
Receive a single file or a list of files to import.
|
||||||
|
"""
|
||||||
|
if isinstance(self.import_source, list):
|
||||||
|
self.import_wizard.progressBar.setMaximum(len(self.import_source))
|
||||||
|
for file in self.import_source:
|
||||||
|
author = u''
|
||||||
|
copyright = u''
|
||||||
|
self.sspVerseOrderList = []
|
||||||
|
otherCount = 0
|
||||||
|
otherList = {}
|
||||||
|
file_name = os.path.split(file)[1]
|
||||||
|
self.import_wizard.incrementProgressBar(
|
||||||
|
u'Importing %s' % (file_name), 0)
|
||||||
|
songData = open(file, 'rb')
|
||||||
|
while (1):
|
||||||
|
blockKey, = struct.unpack("I",songData.read(4))
|
||||||
|
# The file ends with 4 NUL's
|
||||||
|
if blockKey == 0:
|
||||||
|
break
|
||||||
|
nextBlockStarts, = struct.unpack("I",songData.read(4))
|
||||||
|
if blockKey == VERSE or blockKey == CHORUS:
|
||||||
|
null, verseNo, = struct.unpack("BB",songData.read(2))
|
||||||
|
elif blockKey == CUSTOM_VERSE:
|
||||||
|
null, verseNameLength, = struct.unpack("BB",
|
||||||
|
songData.read(2))
|
||||||
|
verseName = songData.read(verseNameLength)
|
||||||
|
lengthDescriptorSize, = struct.unpack("B",songData.read(1))
|
||||||
|
# Detect if/how long the length descriptor is
|
||||||
|
if lengthDescriptorSize == 12:
|
||||||
|
lengthDescriptor, = struct.unpack("I",songData.read(4))
|
||||||
|
elif lengthDescriptorSize == 2:
|
||||||
|
lengthDescriptor = 1
|
||||||
|
elif lengthDescriptorSize == 9:
|
||||||
|
lengthDescriptor = 0
|
||||||
|
else:
|
||||||
|
lengthDescriptor, = struct.unpack("B",songData.read(1))
|
||||||
|
data = songData.read(lengthDescriptor)
|
||||||
|
|
||||||
|
if blockKey == TITLE:
|
||||||
|
self.title = unicode(data, u'cp1252')
|
||||||
|
elif blockKey == AUTHOR:
|
||||||
|
authors = data.split(" / ")
|
||||||
|
for author in authors:
|
||||||
|
if author.find(",") !=-1:
|
||||||
|
authorParts = author.split(", ")
|
||||||
|
author = authorParts[1] + " " + authorParts[0]
|
||||||
|
self.parse_author(unicode(author, u'cp1252'))
|
||||||
|
elif blockKey == COPYRIGHT:
|
||||||
|
self.add_copyright(unicode(data, u'cp1252'))
|
||||||
|
elif blockKey == CCLI_NO:
|
||||||
|
self.ccli_number = int(data)
|
||||||
|
elif blockKey == VERSE:
|
||||||
|
self.add_verse(unicode(data, u'cp1252'),
|
||||||
|
"V%s" % verseNo)
|
||||||
|
elif blockKey == CHORUS:
|
||||||
|
self.add_verse(unicode(data, u'cp1252'),
|
||||||
|
"C%s" % verseNo)
|
||||||
|
elif blockKey == TOPIC:
|
||||||
|
self.topics.append(unicode(data, u'cp1252'))
|
||||||
|
elif blockKey == COMMENTS:
|
||||||
|
self.comments = unicode(data, u'cp1252')
|
||||||
|
elif blockKey == VERSE_ORDER:
|
||||||
|
verseTag = self.toOpenLPVerseTag(data)
|
||||||
|
self.sspVerseOrderList.append(unicode(verseTag,
|
||||||
|
u'cp1252'))
|
||||||
|
elif blockKey == SONG_BOOK:
|
||||||
|
self.song_book_name = unicode(data, u'cp1252')
|
||||||
|
elif blockKey == SONG_NUMBER:
|
||||||
|
self.song_number = ord(data)
|
||||||
|
elif blockKey == CUSTOM_VERSE:
|
||||||
|
verseTag = self.toOpenLPVerseTag(verseName)
|
||||||
|
self.add_verse(unicode(data, u'cp1252'), verseTag)
|
||||||
|
else:
|
||||||
|
log.debug("Unrecognised blockKey: %s, data: %s"
|
||||||
|
%(blockKey, data))
|
||||||
|
self.verse_order_list = self.sspVerseOrderList
|
||||||
|
songData.close()
|
||||||
|
self.finish()
|
||||||
|
self.import_wizard.incrementProgressBar(
|
||||||
|
u'Importing %s' % (file_name))
|
||||||
|
return True
|
||||||
|
|
||||||
|
def toOpenLPVerseTag(self, verseName):
|
||||||
|
if verseName.find(" ")!=-1:
|
||||||
|
verseParts = verseName.split(" ")
|
||||||
|
verseType = verseParts[0]
|
||||||
|
verseNumber = verseParts[1]
|
||||||
|
else:
|
||||||
|
verseType = verseName
|
||||||
|
verseNumber = "1"
|
||||||
|
verseType = verseType.lower()
|
||||||
|
if verseType == "verse":
|
||||||
|
verseTag = "V"
|
||||||
|
elif verseType == "chorus":
|
||||||
|
verseTag = "C"
|
||||||
|
elif verseType == "bridge":
|
||||||
|
verseTag = "B"
|
||||||
|
elif verseType == "pre-chorus":
|
||||||
|
verseTag = "P"
|
||||||
|
elif verseType == "bridge":
|
||||||
|
verseTag = "B"
|
||||||
|
else:
|
||||||
|
if not self.otherList.has_key(verseName):
|
||||||
|
self.otherCount = self.otherCount + 1
|
||||||
|
self.otherList[verseName] = str(self.otherCount)
|
||||||
|
verseTag = "O"
|
||||||
|
verseNumber = self.otherList[verseName]
|
||||||
|
verseTag = verseTag + verseNumber
|
||||||
|
return verseTag
|
Loading…
Reference in New Issue
Block a user