Revisited Words of Worship importer. A few tweeks, some to make it more robust, and to provide more information to the user.

This commit is contained in:
Philip Ridout 2012-03-07 17:25:39 +00:00
parent 0e95ffe55f
commit 247114c656

View File

@ -31,6 +31,7 @@ Worship songs into the OpenLP database.
import os import os
import logging import logging
from openlp.core.lib import translate
from openlp.plugins.songs.lib.songimport import SongImport from openlp.plugins.songs.lib.songimport import SongImport
BLOCK_TYPES = (u'V', u'C', u'B') BLOCK_TYPES = (u'V', u'C', u'B')
@ -52,18 +53,19 @@ class WowImport(SongImport):
* A block can be a verse, chorus or bridge. * A block can be a verse, chorus or bridge.
File Header: File Header:
Bytes are counted from one, i.e. the first byte is byte 1. These bytes, Bytes are counted from one, i.e. the first byte is byte 1. The first 19
up to the 56 byte, can change but no real meaning has been found. The bytes should be "WoW File \\nSong Words" The bytes after this and up to
the 56th byte, can change but no real meaning has been found. The
56th byte specifies how many blocks there are. The first block starts 56th byte specifies how many blocks there are. The first block starts
with byte 83 after the "CSongDoc::CBlock" declaration. with byte 83 after the "CSongDoc::CBlock" declaration.
Blocks: Blocks:
Each block has a starting header, some lines of text, and an ending Each block has a starting header, some lines of text, and an ending
footer. Each block starts with 4 bytes, the first byte specifies how footer. Each block starts with a 32 bit number, which specifies how
many lines are in that block, the next three bytes are null bytes. many lines are in that block.
Each block ends with 4 bytes, the first of which defines what type of Each block ends with a 32 bit number, which defines what type of
block it is, and the rest which are null bytes: block it is:
* ``NUL`` (0x00) - Verse * ``NUL`` (0x00) - Verse
* ``SOH`` (0x01) - Chorus * ``SOH`` (0x01) - Chorus
@ -76,7 +78,6 @@ class WowImport(SongImport):
Each line starts with a byte which specifies how long that line is, Each line starts with a byte which specifies how long that line is,
the line text, and ends with a null byte. the line text, and ends with a null byte.
Footer: Footer:
The footer follows on after the last block, the first byte specifies The footer follows on after the last block, the first byte specifies
the length of the author text, followed by the author text, if the length of the author text, followed by the author text, if
@ -107,22 +108,28 @@ class WowImport(SongImport):
for file in self.importSource: for file in self.importSource:
if self.stopImportFlag: if self.stopImportFlag:
return return
file_name = os.path.split(file)[1] self.setDefaults()
# Get the song title
self.title = file_name.rpartition(u'.')[0]
song_data = open(file, 'rb') song_data = open(file, 'rb')
if song_data.read(19) != u'WoW File\nSong Words': if song_data.read(19) != u'WoW File\nSong Words':
self.logError(file) self.logError(file, unicode(
translate('SongsPlugin.WordsofWorshipSongImport',
'Invalid Words of Worship song file. Missing \
"Wow File\\nSong Words" header.')))
continue continue
# Seek to byte which stores number of blocks in the song # Seek to byte which stores number of blocks in the song
song_data.seek(56) song_data.seek(56)
no_of_blocks = ord(song_data.read(1)) no_of_blocks = ord(song_data.read(1))
song_data.seek(66)
if song_data.read(16) != u'CSongDoc::CBlock':
self.logError(file, unicode(
translate('SongsPlugin.WordsofWorshipSongImport',
'Invalid Words of Worship song file. Missing \
"CSongDoc::CBlock" string.')))
continue
# Seek to the beging of the first block # Seek to the beging of the first block
song_data.seek(82) song_data.seek(82)
for block in range(no_of_blocks): for block in range(no_of_blocks):
self.linesToRead = ord(song_data.read(1)) self.linesToRead = ord(song_data.read(4)[:1])
# Skip 3 nulls to the beginnig of the 1st line
song_data.seek(3, os.SEEK_CUR)
block_text = u'' block_text = u''
while self.linesToRead: while self.linesToRead:
self.lineText = unicode( self.lineText = unicode(
@ -132,9 +139,7 @@ class WowImport(SongImport):
block_text += u'\n' block_text += u'\n'
block_text += self.lineText block_text += self.lineText
self.linesToRead -= 1 self.linesToRead -= 1
block_type = BLOCK_TYPES[ord(song_data.read(1))] block_type = BLOCK_TYPES[ord(song_data.read(4)[:1])]
# Skip 3 nulls at the end of the block
song_data.seek(3, os.SEEK_CUR)
# Blocks are seperated by 2 bytes, skip them, but not if # Blocks are seperated by 2 bytes, skip them, but not if
# this is the last block! # this is the last block!
if block + 1 < no_of_blocks: if block + 1 < no_of_blocks:
@ -150,6 +155,9 @@ class WowImport(SongImport):
if copyright_length: if copyright_length:
self.addCopyright(unicode( self.addCopyright(unicode(
song_data.read(copyright_length), u'cp1252')) song_data.read(copyright_length), u'cp1252'))
file_name = os.path.split(file)[1]
# Get the song title
self.title = file_name.rpartition(u'.')[0]
song_data.close() song_data.close()
if not self.finish(): if not self.finish():
self.logError(file) self.logError(file)