Better handling of memo files larger than 16MiB.

Handle blank fields more intelligently.

bzr-revno: 1060
This commit is contained in:
Jeffrey Smith 2010-09-25 14:54:06 +02:00 committed by Raoul Snyman
commit 5d61520b6e

View File

@ -1,6 +1,28 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 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, Jeffrey Smith #
# --------------------------------------------------------------------------- #
# 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:`ewimport` module provides the functionality for importing The :mod:`ewimport` module provides the functionality for importing
EasyWorship song databases into the current installation database. EasyWorship song databases into the current installation database.
@ -10,6 +32,7 @@ import sys
import os import os
import struct import struct
from openlp.core.lib import translate
from songimport import SongImport from songimport import SongImport
def strip_rtf(blob): def strip_rtf(blob):
@ -146,27 +169,44 @@ class EasyWorshipSongImport(SongImport):
raw_record = db_file.read(record_size) raw_record = db_file.read(record_size)
self.fields = self.record_struct.unpack(raw_record) self.fields = self.record_struct.unpack(raw_record)
self.set_defaults() self.set_defaults()
self.title = self.get_field(fi_title) # Get title and update progress bar message
self.import_wizard.incrementProgressBar( title = self.get_field(fi_title)
u'Importing "%s"...' % self.title, 0) if title:
self.copyright = self.get_field(fi_copy) + \ self.import_wizard.incrementProgressBar(
u', Administered by ' + self.get_field(fi_admin) unicode(translate('SongsPlugin.ImportWizardForm',
self.ccli_number = self.get_field(fi_ccli) 'Importing "%s"...')) % title, 0)
# Format the lyrics self.title = title
if self.stop_import_flag: # Get remaining fields
success = False copy = self.get_field(fi_copy)
break admin = self.get_field(fi_admin)
words = self.get_field(fi_words) ccli = self.get_field(fi_ccli)
words = strip_rtf(words)
for verse in words.split(u'\n\n'):
self.add_verse(verse.strip(), u'V')
# Split up the authors
authors = self.get_field(fi_author) authors = self.get_field(fi_author)
author_list = authors.split(u'/') words = self.get_field(fi_words)
if len(author_list) < 2: # Set the SongImport object members
author_list = authors.split(u',') if copy:
for author_name in author_list: self.copyright = copy
self.add_author(author_name.strip()) if admin:
if copy:
self.copyright += u', '
self.copyright += \
unicode(translate('SongsPlugin.ImportWizardForm',
'Administered by %s')) % admin
if ccli:
self.ccli_number = ccli
if authors:
# Split up the authors
author_list = authors.split(u'/')
if len(author_list) < 2:
author_list = authors.split(u';')
if len(author_list) < 2:
author_list = authors.split(u',')
for author_name in author_list:
self.add_author(author_name.strip())
if words:
# Format the lyrics
words = strip_rtf(words)
for verse in words.split(u'\n\n'):
self.add_verse(verse.strip(), u'V')
if self.stop_import_flag: if self.stop_import_flag:
success = False success = False
break break
@ -214,12 +254,12 @@ class EasyWorshipSongImport(SongImport):
def get_field(self, field_desc_index): def get_field(self, field_desc_index):
field = self.fields[field_desc_index] field = self.fields[field_desc_index]
field_desc = self.field_descs[field_desc_index] field_desc = self.field_descs[field_desc_index]
# Check for 'blank' entries # Return None in case of 'blank' entries
if isinstance(field, str): if isinstance(field, str):
if len(field.rstrip('\0')) == 0: if len(field.rstrip('\0')) == 0:
return u'' return None
elif field == 0: elif field == 0:
return 0 return None
# Format the field depending on the field type # Format the field depending on the field type
if field_desc.type == 1: if field_desc.type == 1:
# string # string
@ -235,19 +275,20 @@ class EasyWorshipSongImport(SongImport):
return (field ^ 0x80 == 1) return (field ^ 0x80 == 1)
elif field_desc.type == 0x0c or field_desc.type == 0x0d: elif field_desc.type == 0x0c or field_desc.type == 0x0d:
# Memo or Blob # Memo or Blob
sub_block, block_start, blob_size = \ block_start, blob_size = \
struct.unpack_from('<bhxi', field, len(field)-10) struct.unpack_from('<II', field, len(field)-10)
self.memo_file.seek(block_start * 256) sub_block = block_start & 0xff;
block_start &= ~0xff
self.memo_file.seek(block_start)
memo_block_type, = struct.unpack('b', self.memo_file.read(1)) memo_block_type, = struct.unpack('b', self.memo_file.read(1))
if memo_block_type == 2: if memo_block_type == 2:
self.memo_file.seek(8, os.SEEK_CUR) self.memo_file.seek(8, os.SEEK_CUR)
elif memo_block_type == 3: elif memo_block_type == 3:
if sub_block < 0 or sub_block > 63: if sub_block > 63:
return u''; return u'';
self.memo_file.seek(11 + (5 * sub_block), os.SEEK_CUR) self.memo_file.seek(11 + (5 * sub_block), os.SEEK_CUR)
sub_block_start, = struct.unpack('B', self.memo_file.read(1)) sub_block_start, = struct.unpack('B', self.memo_file.read(1))
self.memo_file.seek((block_start * 256) + self.memo_file.seek(block_start + (sub_block_start * 16))
(sub_block_start * 16))
else: else:
return u''; return u'';
return self.memo_file.read(blob_size) return self.memo_file.read(blob_size)