Added SongShow Plus importer.

This commit is contained in:
Philip Ridout 2011-02-13 15:13:52 +00:00
parent eabff22221
commit 1913da71cc
3 changed files with 267 additions and 1 deletions

View File

@ -140,6 +140,12 @@ class SongImportForm(OpenLPWizard):
QtCore.QObject.connect(self.songBeamerRemoveButton,
QtCore.SIGNAL(u'clicked()'),
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):
"""
@ -188,6 +194,8 @@ class SongImportForm(OpenLPWizard):
self.addFileSelectItem(u'ew', single_select=True)
# Words of Worship
self.addFileSelectItem(u'songBeamer')
# Song Show Plus
self.addFileSelectItem(u'songShowPlus')
# Commented out for future use.
# self.addFileSelectItem(u'csv', u'CSV', single_select=True)
self.sourceLayout.addLayout(self.formatStack)
@ -237,6 +245,8 @@ class SongImportForm(OpenLPWizard):
translate('SongsPlugin.ImportWizardForm', 'EasyWorship'))
self.formatComboBox.setItemText(10,
translate('SongsPlugin.ImportWizardForm', 'SongBeamer'))
self.formatComboBox.setItemText(11,
translate('SongsPlugin.ImportWizardForm', 'SongShow Plus'))
# self.formatComboBox.setItemText(11,
# translate('SongsPlugin.ImportWizardForm', 'CSV'))
self.openLP2FilenameLabel.setText(
@ -301,6 +311,10 @@ class SongImportForm(OpenLPWizard):
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
self.songBeamerRemoveButton.setText(
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(
# translate('SongsPlugin.ImportWizardForm', 'Filename:'))
# self.csvBrowseButton.setText(
@ -438,6 +452,16 @@ class SongImportForm(OpenLPWizard):
'file to import from.'))
self.songBeamerAddButton.setFocus()
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
elif self.currentPage() == self.progressPage:
return True
@ -671,6 +695,24 @@ class SongImportForm(OpenLPWizard):
Remove selected SongBeamer files from the import list
"""
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):
"""
@ -697,6 +739,7 @@ class SongImportForm(OpenLPWizard):
self.easiSlidesFilenameEdit.setText(u'')
self.ewFilenameEdit.setText(u'')
self.songBeamerFileListWidget.clear()
self.songShowPlusFileListWidget.clear()
#self.csvFilenameEdit.setText(u'')
def preWizard(self):
@ -773,6 +816,12 @@ class SongImportForm(OpenLPWizard):
importer = self.plugin.importSongs(SongFormat.SongBeamer,
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():
self.progressLabel.setText(
translate('SongsPlugin.SongImportForm', 'Finished import.'))

View File

@ -34,6 +34,7 @@ from wowimport import WowImport
from cclifileimport import CCLIFileImport
from ewimport import EasyWorshipSongImport
from songbeamerimport import SongBeamerImport
from songshowplusimport import SongShowPlusImport
# Imports that might fail
try:
from olp1import import OpenLP1SongImport
@ -71,6 +72,7 @@ class SongFormat(object):
EasiSlides = 8
EasyWorship = 9
SongBeamer = 10
SongShowPlus = 11
@staticmethod
def get_class(format):
@ -102,6 +104,8 @@ class SongFormat(object):
return EasyWorshipSongImport
elif format == SongFormat.SongBeamer:
return SongBeamerImport
elif format == SongFormat.SongShowPlus:
return SongShowPlusImport
return None
@staticmethod
@ -120,7 +124,8 @@ class SongFormat(object):
SongFormat.Generic,
SongFormat.EasiSlides,
SongFormat.EasyWorship,
SongFormat.SongBeamer
SongFormat.SongBeamer,
SongFormat.SongShowPlus
]
@staticmethod

View 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