openlp-core team mailing list archive
-
openlp-core team
-
Mailing list archive
-
Message #08203
[Merge] lp:~googol-hush/openlp/songs into lp:openlp
Andreas Preikschat has proposed merging lp:~googol-hush/openlp/songs into lp:openlp.
Requested reviews:
Tim Bentley (trb143)
Raoul Snyman (raoul-snyman)
For more details, see:
https://code.launchpad.net/~googol-hush/openlp/songs/+merge/58733
Hello,
1) Attempt to improve the song importers by allowing them to give feedback to the user. (I worry that the dialog needs some love.)
s) Do not abort a song import, always try to continue and log which songs could not be imported.
3) Clean ups (close files, deduplication, ...)
Once this is merged, I would write to the mailing list and ask people to look at the importers again and adapt them where possible.
NOTE:
1) I could NOT test all importers so please test them (best would be when you leave me a comment which you tested). I'll try to test more importers while this is being reviewed.
I tested:
- OpenSong
- OpenLyrics
- SongBeamer
- OLP1
- OLP2
- FoliPresenter
2) Strings I added/changed:
- Copy
- Save to File
- Your song import failed.
- The file does not have a valid extension.
- Not a valid openlp.org 1.x song database.
- Not a valid OpenLP 2.0 song database.
- The following songs could not be imported:
- Title and/or verses not found
- XML syntax error
--
https://code.launchpad.net/~googol-hush/openlp/songs/+merge/58733
Your team OpenLP Core is subscribed to branch lp:openlp.
=== modified file 'openlp/core/ui/wizard.py'
--- openlp/core/ui/wizard.py 2011-04-15 21:43:59 +0000
+++ openlp/core/ui/wizard.py 2011-04-21 18:26:24 +0000
@@ -95,6 +95,10 @@
self.customSignals()
QtCore.QObject.connect(self, QtCore.SIGNAL(u'currentIdChanged(int)'),
self.onCurrentIdChanged)
+ QtCore.QObject.connect(self.errorCopyToButton,
+ QtCore.SIGNAL(u'clicked()'), self.onErrorCopyToButtonClicked)
+ QtCore.QObject.connect(self.errorSaveToButton,
+ QtCore.SIGNAL(u'clicked()'), self.onErrorSaveToButtonClicked)
def setupUi(self, image):
"""
@@ -129,10 +133,36 @@
self.progressLayout.setObjectName(u'progressLayout')
self.progressLabel = QtGui.QLabel(self.progressPage)
self.progressLabel.setObjectName(u'progressLabel')
+ self.progressLabel.setWordWrap(True)
self.progressLayout.addWidget(self.progressLabel)
self.progressBar = QtGui.QProgressBar(self.progressPage)
self.progressBar.setObjectName(u'progressBar')
self.progressLayout.addWidget(self.progressBar)
+ # Add a QTextEdit and a copy to file and copy to clipboard button to be
+ # able to provide feedback to the user. Hidden by default.
+ self.errorReportTextEdit = QtGui.QTextEdit(self.progressPage)
+ self.errorReportTextEdit.setObjectName(u'progresserrorReportTextEdit')
+ self.errorReportTextEdit.setHidden(True)
+ self.errorReportTextEdit.setReadOnly(True)
+ self.progressLayout.addWidget(self.errorReportTextEdit)
+ self.errorButtonLayout = QtGui.QHBoxLayout()
+ self.errorButtonLayout.setObjectName(u'errorButtonLayout')
+ spacer = QtGui.QSpacerItem(40, 20,
+ QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
+ self.errorButtonLayout.addItem(spacer)
+ self.errorCopyToButton = QtGui.QPushButton(self.progressPage)
+ self.errorCopyToButton.setObjectName(u'errorCopyToButton')
+ self.errorCopyToButton.setHidden(True)
+ self.errorCopyToButton.setIcon(
+ build_icon(u':/system/system_edit_copy.png'))
+ self.errorButtonLayout.addWidget(self.errorCopyToButton)
+ self.errorSaveToButton = QtGui.QPushButton(self.progressPage)
+ self.errorSaveToButton.setObjectName(u'errorSaveToButton')
+ self.errorSaveToButton.setHidden(True)
+ self.errorSaveToButton.setIcon(
+ build_icon(u':/general/general_save.png'))
+ self.errorButtonLayout.addWidget(self.errorSaveToButton)
+ self.progressLayout.addLayout(self.errorButtonLayout)
self.addPage(self.progressPage)
def exec_(self):
@@ -160,6 +190,18 @@
self.performWizard()
self.postWizard()
+ def onErrorCopyToButtonClicked(self):
+ """
+ Called when the ``onErrorCopyToButtonClicked`` has been clicked.
+ """
+ pass
+
+ def onErrorSaveToButtonClicked(self):
+ """
+ Called when the ``onErrorSaveToButtonClicked`` has been clicked.
+ """
+ pass
+
def incrementProgressBar(self, status_text, increment=1):
"""
Update the wizard progress page.
@@ -219,4 +261,5 @@
if filename:
editbox.setText(filename)
SettingsManager.set_last_dir(self.plugin.settingsSection,
- filename, 1)
\ No newline at end of file
+ filename, 1)
+
=== modified file 'openlp/plugins/songs/forms/songimportform.py'
--- openlp/plugins/songs/forms/songimportform.py 2011-04-15 21:43:59 +0000
+++ openlp/plugins/songs/forms/songimportform.py 2011-04-21 18:26:24 +0000
@@ -26,6 +26,7 @@
"""
The song import functions for OpenLP.
"""
+import codecs
import logging
import os
@@ -55,6 +56,7 @@
``plugin``
The songs plugin.
"""
+ self.clipboard = plugin.formparent.clipboard
OpenLPWizard.__init__(self, parent, plugin, u'songImportWizard',
u':/wizards/wizard_importsong.bmp')
@@ -330,6 +332,10 @@
'Please wait while your songs are imported.'))
self.progressLabel.setText(WizardStrings.Ready)
self.progressBar.setFormat(WizardStrings.PercentSymbolFormat)
+ self.errorCopyToButton.setText(translate('SongsPlugin.ImportWizardForm',
+ 'Copy'))
+ self.errorSaveToButton.setText(translate('SongsPlugin.ImportWizardForm',
+ 'Save to File'))
# Align all QFormLayouts towards each other.
width = max(self.formatLabel.minimumSizeHint().width(),
self.openLP2FilenameLabel.minimumSizeHint().width())
@@ -459,10 +465,7 @@
"""
Return a list of file from the listbox
"""
- files = []
- for row in range(0, listbox.count()):
- files.append(unicode(listbox.item(row).text()))
- return files
+ return [unicode(listbox.item(i).text()) for i in range(listbox.count())]
def removeSelectedItems(self, listbox):
"""
@@ -659,6 +662,10 @@
self.songShowPlusFileListWidget.clear()
self.foilPresenterFileListWidget.clear()
#self.csvFilenameEdit.setText(u'')
+ self.errorReportTextEdit.clear()
+ self.errorReportTextEdit.setHidden(True)
+ self.errorCopyToButton.setHidden(True)
+ self.errorSaveToButton.setHidden(True)
def preWizard(self):
"""
@@ -743,12 +750,30 @@
importer = self.plugin.importSongs(SongFormat.FoilPresenter,
filenames=self.getListOfFiles(self.foilPresenterFileListWidget)
)
- if importer.do_import():
+ importer.do_import()
+ if importer.error_log:
+ self.progressLabel.setText(translate(
+ 'SongsPlugin.SongImportForm', 'Your song import failed.'))
+ else:
self.progressLabel.setText(WizardStrings.FinishedImport)
- else:
- self.progressLabel.setText(
- translate('SongsPlugin.SongImportForm',
- 'Your song import failed.'))
+
+ def onErrorCopyToButtonClicked(self):
+ """
+ Copy the error report to the clipboard.
+ """
+ self.clipboard.setText(self.errorReportTextEdit.toPlainText())
+
+ def onErrorSaveToButtonClicked(self):
+ """
+ Save the error report to a file.
+ """
+ filename = QtGui.QFileDialog.getSaveFileName(self,
+ SettingsManager.get_last_dir(self.plugin.settingsSection, 1))
+ if not filename:
+ return
+ file = codecs.open(filename, u'w', u'utf-8')
+ file.write(self.errorReportTextEdit.toPlainText())
+ file.close()
def addFileSelectItem(self, prefix, obj_prefix=None, can_disable=False,
single_select=False):
@@ -836,4 +861,4 @@
setattr(self, prefix + u'DisabledLayout', disabledLayout)
setattr(self, prefix + u'DisabledLabel', disabledLabel)
setattr(self, prefix + u'ImportWidget', importWidget)
- return importWidget
\ No newline at end of file
+ return importWidget
=== modified file 'openlp/plugins/songs/lib/cclifileimport.py'
--- openlp/plugins/songs/lib/cclifileimport.py 2011-04-03 13:35:58 +0000
+++ openlp/plugins/songs/lib/cclifileimport.py 2011-04-21 18:26:24 +0000
@@ -59,16 +59,10 @@
Import either a ``.usr`` or a ``.txt`` SongSelect file.
"""
log.debug(u'Starting CCLI File Import')
- song_total = len(self.import_source)
- self.import_wizard.progressBar.setMaximum(song_total)
- song_count = 1
+ self.import_wizard.progressBar.setMaximum(len(self.import_source))
for filename in self.import_source:
- self.import_wizard.incrementProgressBar(unicode(translate(
- 'SongsPlugin.CCLIFileImport', 'Importing song %d of %d')) %
- (song_count, song_total))
filename = unicode(filename)
log.debug(u'Importing CCLI File: %s', filename)
- self.set_defaults()
lines = []
if os.path.isfile(filename):
detect_file = open(filename, u'r')
@@ -81,19 +75,23 @@
detect_file.close()
infile = codecs.open(filename, u'r', details['encoding'])
lines = infile.readlines()
+ infile.close()
ext = os.path.splitext(filename)[1]
if ext.lower() == u'.usr':
log.info(u'SongSelect .usr format file found: %s', filename)
- self.do_import_usr_file(lines)
+ if not self.do_import_usr_file(lines):
+ self.log_error(filename)
elif ext.lower() == u'.txt':
log.info(u'SongSelect .txt format file found: %s', filename)
- self.do_import_txt_file(lines)
+ if not self.do_import_txt_file(lines):
+ self.log_error(filename)
else:
+ self.log_error(filename,
+ translate('SongsPlugin.CCLIFileImport',
+ 'The file does not have a valid extension.'))
log.info(u'Extension %s is not valid', filename)
- song_count += 1
if self.stop_import_flag:
- return False
- return True
+ return
def do_import_usr_file(self, textList):
"""
@@ -218,7 +216,7 @@
else:
self.add_author(author)
self.topics = [topic.strip() for topic in song_topics.split(u'/t')]
- self.finish()
+ return self.finish()
def do_import_txt_file(self, textList):
"""
@@ -334,6 +332,5 @@
if len(author_list) < 2:
author_list = song_author.split(u'|')
# Clean spaces before and after author names.
- for author_name in author_list:
- self.add_author(author_name.strip())
- self.finish()
+ [self.add_author(author_name.strip()) for author_name in author_list]
+ return self.finish()
=== modified file 'openlp/plugins/songs/lib/easislidesimport.py'
--- openlp/plugins/songs/lib/easislidesimport.py 2011-03-24 19:04:02 +0000
+++ openlp/plugins/songs/lib/easislidesimport.py 2011-04-21 18:26:24 +0000
@@ -26,11 +26,13 @@
import logging
import os
+import re
+
from lxml import etree, objectify
-import re
from openlp.core.lib import translate
from openlp.core.ui.wizard import WizardStrings
+from openlp.plugins.songs.lib import VerseType
from openlp.plugins.songs.lib.songimport import SongImport
log = logging.getLogger(__name__)
@@ -56,26 +58,16 @@
multiple opensong files. If `self.commit` is set False, the
import will not be committed to the database (useful for test scripts).
"""
- self.import_wizard.progressBar.setMaximum(1)
log.info(u'Importing EasiSlides XML file %s', self.import_source)
parser = etree.XMLParser(remove_blank_text=True)
file = etree.parse(self.import_source, parser)
xml = unicode(etree.tostring(file))
song_xml = objectify.fromstring(xml)
- self.import_wizard.incrementProgressBar(
- WizardStrings.ImportingType % os.path.split(self.import_source)[-1])
self.import_wizard.progressBar.setMaximum(len(song_xml.Item))
for song in song_xml.Item:
- self.import_wizard.incrementProgressBar(
- unicode(translate('SongsPlugin.ImportWizardForm',
- u'Importing %s, song %s...')) %
- (os.path.split(self.import_source)[-1], song.Title1))
- success = self._parse_song(song)
- if not success or self.stop_import_flag:
- return False
- elif self.commit:
- self.finish()
- return True
+ if self.stop_import_flag:
+ return
+ self._parse_song(song)
def _parse_song(self, song):
self._success = True
@@ -90,7 +82,11 @@
self._add_copyright(song.LicenceAdmin2)
self._add_unicode_attribute(u'song_book_name', song.BookReference)
self._parse_and_add_lyrics(song)
- return self._success
+ if self._success:
+ if not self.finish():
+ self.log_error(song.Title1 if song.Title1 else u'')
+ else:
+ self.set_defaults()
def _add_unicode_attribute(self, self_attribute, import_attribute,
mandatory=False):
@@ -122,10 +118,8 @@
def _add_authors(self, song):
try:
authors = unicode(song.Writer).split(u',')
- for author in authors:
- author = author.strip()
- if len(author):
- self.authors.append(author)
+ self.authors = \
+ [author.strip() for author in authors if author.strip()]
except UnicodeDecodeError:
log.exception(u'Unicode decode error while decoding Writer')
self._success = False
@@ -188,12 +182,13 @@
# if the regions are inside verses
regionsInVerses = (regions and regionlines[regionlines.keys()[0]] > 1)
MarkTypes = {
- u'CHORUS': u'C',
- u'VERSE': u'V',
- u'INTRO': u'I',
- u'ENDING': u'E',
- u'BRIDGE': u'B',
- u'PRECHORUS': u'P'}
+ u'CHORUS': VerseType.Tags[VerseType.Chorus],
+ u'VERSE': VerseType.Tags[VerseType.Verse],
+ u'INTRO': VerseType.Tags[VerseType.Intro],
+ u'ENDING': VerseType.Tags[VerseType.Ending],
+ u'BRIDGE': VerseType.Tags[VerseType.Bridge],
+ u'PRECHORUS': VerseType.Tags[VerseType.PreChorus]
+ }
verses = {}
# list as [region, versetype, versenum, instance]
our_verse_order = []
=== modified file 'openlp/plugins/songs/lib/ewimport.py'
--- openlp/plugins/songs/lib/ewimport.py 2011-03-24 19:04:02 +0000
+++ openlp/plugins/songs/lib/ewimport.py 2011-04-21 18:26:24 +0000
@@ -33,6 +33,7 @@
from openlp.core.lib import translate
from openlp.core.ui.wizard import WizardStrings
+from openlp.plugins.songs.lib import VerseType
from openlp.plugins.songs.lib import retrieve_windows_encoding
from songimport import SongImport
@@ -142,12 +143,12 @@
# Open the DB and MB files if they exist
import_source_mb = self.import_source.replace('.DB', '.MB')
if not os.path.isfile(self.import_source):
- return False
+ return
if not os.path.isfile(import_source_mb):
- return False
+ return
db_size = os.path.getsize(self.import_source)
if db_size < 0x800:
- return False
+ return
db_file = open(self.import_source, 'rb')
self.memo_file = open(import_source_mb, 'rb')
# Don't accept files that are clearly not paradox files
@@ -156,7 +157,7 @@
if header_size != 0x800 or block_size < 1 or block_size > 4:
db_file.close()
self.memo_file.close()
- return False
+ return
# Take a stab at how text is encoded
self.encoding = u'cp1252'
db_file.seek(106)
@@ -183,7 +184,7 @@
self.encoding = u'cp874'
self.encoding = retrieve_windows_encoding(self.encoding)
if not self.encoding:
- return False
+ return
# There does not appear to be a _reliable_ way of getting the number
# of songs/records, so let's use file blocks for measuring progress.
total_blocks = (db_size - header_size) / (block_size * 1024)
@@ -203,8 +204,8 @@
field_size))
self.set_record_struct(field_descs)
# Pick out the field description indexes we will need
- success = True
try:
+ success = True
fi_title = self.find_field(u'Title')
fi_author = self.find_field(u'Author')
fi_copy = self.find_field(u'Copyright')
@@ -223,31 +224,25 @@
# Loop through each record within the current block
for i in range(rec_count):
if self.stop_import_flag:
- success = False
break
raw_record = db_file.read(record_size)
self.fields = self.record_struct.unpack(raw_record)
self.set_defaults()
- # Get title and update progress bar message
- title = self.get_field(fi_title)
- if title:
- self.import_wizard.incrementProgressBar(
- WizardStrings.ImportingType % title, 0)
- self.title = title
- # Get remaining fields
+ self.title = self.get_field(fi_title)
+ # Get remaining fields.
copy = self.get_field(fi_copy)
admin = self.get_field(fi_admin)
ccli = self.get_field(fi_ccli)
authors = self.get_field(fi_author)
words = self.get_field(fi_words)
- # Set the SongImport object members
+ # Set the SongImport object members.
if copy:
self.copyright = copy
if admin:
if copy:
self.copyright += u', '
self.copyright += \
- unicode(translate('SongsPlugin.ImportWizardForm',
+ unicode(translate('SongsPlugin.EasyWorshipSongImport',
'Administered by %s')) % admin
if ccli:
self.ccli_number = ccli
@@ -264,19 +259,17 @@
# Format the lyrics
words = strip_rtf(words, self.encoding)
for verse in words.split(u'\n\n'):
- self.add_verse(verse.strip(), u'V')
+ self.add_verse(
+ verse.strip(), VerseType.Tags[VerseType.Verse])
if self.stop_import_flag:
- success = False
break
- self.finish()
- if not self.stop_import_flag:
- self.import_wizard.incrementProgressBar(u'')
+ if not self.finish():
+ self.log_error(self.import_source)
db_file.close()
self.memo_file.close()
- return success
def find_field(self, field_name):
- return [i for i, x in enumerate(self.field_descs) \
+ return [i for i, x in enumerate(self.field_descs)
if x.name == field_name][0]
def set_record_struct(self, field_descs):
=== modified file 'openlp/plugins/songs/lib/foilpresenterimport.py'
--- openlp/plugins/songs/lib/foilpresenterimport.py 2011-03-24 19:04:02 +0000
+++ openlp/plugins/songs/lib/foilpresenterimport.py 2011-04-21 18:26:24 +0000
@@ -97,6 +97,7 @@
from openlp.plugins.songs.lib import clean_song, VerseType
from openlp.plugins.songs.lib.songimport import SongImport
from openlp.plugins.songs.lib.db import Author, Book, Song, Topic
+from openlp.plugins.songs.lib.ui import SongStrings
from openlp.plugins.songs.lib.xml import SongXML
log = logging.getLogger(__name__)
@@ -121,17 +122,16 @@
parser = etree.XMLParser(remove_blank_text=True)
for file_path in self.import_source:
if self.stop_import_flag:
- return False
+ return
self.import_wizard.incrementProgressBar(
WizardStrings.ImportingType % os.path.basename(file_path))
try:
parsed_file = etree.parse(file_path, parser)
xml = unicode(etree.tostring(parsed_file))
- if self.FoilPresenter.xml_to_song(xml) is None:
- log.debug(u'File could not be imported: %s' % file_path)
+ self.FoilPresenter.xml_to_song(xml)
except etree.XMLSyntaxError:
+ self.log_error(file_path, SongStrings.XMLSyntaxError)
log.exception(u'XML syntax error in file %s' % file_path)
- return True
class FoilPresenter(object):
@@ -211,7 +211,7 @@
"""
# No xml get out of here.
if not xml:
- return None
+ return
if xml[:5] == u'<?xml':
xml = xml[38:]
song = Song()
@@ -235,7 +235,6 @@
self._process_topics(foilpresenterfolie, song)
clean_song(self.manager, song)
self.manager.save_object(song)
- return song.id
def _child(self, element):
"""
@@ -305,9 +304,8 @@
for marker in markers:
copyright = re.compile(marker).sub(u'<marker>', copyright, re.U)
copyright = re.compile(u'(?<=<marker>) *:').sub(u'', copyright)
- i = 0
x = 0
- while i != 1:
+ while True:
if copyright.find(u'<marker>') != -1:
temp = copyright.partition(u'<marker>')
if temp[0].strip() and x > 0:
@@ -316,9 +314,9 @@
x += 1
elif x > 0:
strings.append(copyright)
- i = 1
+ break
else:
- i = 1
+ break
author_temp = []
for author in strings:
temp = re.split(u',(?=\D{2})|(?<=\D),|\/(?=\D{3,})|(?<=\D);',
@@ -349,8 +347,8 @@
if author is None:
# We need to create a new author, as the author does not exist.
author = Author.populate(display_name=display_name,
- last_name = display_name.split(u' ')[-1],
- first_name = u' '.join(display_name.split(u' ')[:-1]))
+ last_name=display_name.split(u' ')[-1],
+ first_name=u' '.join(display_name.split(u' ')[:-1]))
self.manager.save_object(author)
song.authors.append(author)
@@ -414,8 +412,15 @@
temp_verse_order_backup = []
temp_sortnr_backup = 1
temp_sortnr_liste = []
- versenumber = {u'V': 1, u'C': 1, u'B': 1, u'E': 1, u'O': 1, u'I': 1,
- u'P': 1}
+ versenumber = {
+ VerseType.Tags[VerseType.Verse]: 1,
+ VerseType.Tags[VerseType.Chorus]: 1,
+ VerseType.Tags[VerseType.Bridge]: 1,
+ VerseType.Tags[VerseType.Ending]: 1,
+ VerseType.Tags[VerseType.Other]: 1,
+ VerseType.Tags[VerseType.Intro]: 1,
+ VerseType.Tags[VerseType.PreChorus]: 1
+ }
for strophe in foilpresenterfolie.strophen.strophe:
text = self._child(strophe.text_)
verse_name = self._child(strophe.key)
@@ -434,25 +439,25 @@
temp_verse_name = re.compile(u'[0-9].*').sub(u'', verse_name)
temp_verse_name = temp_verse_name[:3].lower()
if temp_verse_name == u'ref':
- verse_type = u'C'
+ verse_type = VerseType.Tags[VerseType.Chorus]
elif temp_verse_name == u'r':
- verse_type = u'C'
+ verse_type = VerseType.Tags[VerseType.Chorus]
elif temp_verse_name == u'':
- verse_type = u'V'
+ verse_type = VerseType.Tags[VerseType.Verse]
elif temp_verse_name == u'v':
- verse_type = u'V'
+ verse_type = VerseType.Tags[VerseType.Verse]
elif temp_verse_name == u'bri':
- verse_type = u'B'
+ verse_type = VerseType.Tags[VerseType.Bridge]
elif temp_verse_name == u'cod':
- verse_type = u'E'
+ verse_type = VerseType.Tags[VerseType.Ending]
elif temp_verse_name == u'sch':
- verse_type = u'E'
+ verse_type = VerseType.Tags[VerseType.Ending]
elif temp_verse_name == u'pre':
- verse_type = u'P'
+ verse_type = VerseType.Tags[VerseType.PreChorus]
elif temp_verse_name == u'int':
- verse_type = u'I'
+ verse_type = VerseType.Tags[VerseType.Intro]
else:
- verse_type = u'O'
+ verse_type = VerseType.Tags[VerseType.Other]
verse_number = re.compile(u'[a-zA-Z.+-_ ]*').sub(u'', verse_name)
# Foilpresenter allows e. g. "C", but we need "C1".
if not verse_number:
@@ -466,8 +471,8 @@
verse_number = unicode(int(verse_number) + 1)
verse_type_index = VerseType.from_tag(verse_type[0])
verse_type = VerseType.Names[verse_type_index]
- temp_verse_order[verse_sortnr] = (u''.join((verse_type[0],
- verse_number)))
+ temp_verse_order[verse_sortnr] = u''.join((verse_type[0],
+ verse_number))
temp_verse_order_backup.append(u''.join((verse_type[0],
verse_number)))
sxml.add_verse_to_lyrics(verse_type, verse_number, text)
=== modified file 'openlp/plugins/songs/lib/olp1import.py'
--- openlp/plugins/songs/lib/olp1import.py 2011-03-24 19:04:02 +0000
+++ openlp/plugins/songs/lib/olp1import.py 2011-04-21 18:26:24 +0000
@@ -32,7 +32,7 @@
from chardet.universaldetector import UniversalDetector
import sqlite
-from openlp.core.ui.wizard import WizardStrings
+from openlp.core.lib import translate
from openlp.plugins.songs.lib import retrieve_windows_encoding
from songimport import SongImport
@@ -61,10 +61,15 @@
"""
Run the import for an openlp.org 1.x song database.
"""
- # Connect to the database
+ if not self.import_source.endswith(u'.olp'):
+ self.log_error(self.import_source,
+ translate('SongsPlugin.OpenLP1SongImport',
+ 'Not a valid openlp.org 1.x song database.'))
+ return
encoding = self.get_encoding()
if not encoding:
- return False
+ return
+ # Connect to the database
connection = sqlite.connect(self.import_source, mode=0444,
encoding=(encoding, 'replace'))
cursor = connection.cursor()
@@ -72,12 +77,6 @@
cursor.execute(u'SELECT name FROM sqlite_master '
u'WHERE type = \'table\' AND name = \'tracks\'')
new_db = len(cursor.fetchall()) > 0
- # Count the number of records we need to import, for the progress bar
- cursor.execute(u'-- types int')
- cursor.execute(u'SELECT COUNT(songid) FROM songs')
- count = cursor.fetchone()[0]
- success = True
- self.import_wizard.progressBar.setMaximum(count)
# "cache" our list of authors
cursor.execute(u'-- types int, unicode')
cursor.execute(u'SELECT authorid, authorname FROM authors')
@@ -92,37 +91,29 @@
cursor.execute(u'SELECT songid, songtitle, lyrics || \'\' AS lyrics, '
u'copyrightinfo FROM songs')
songs = cursor.fetchall()
+ self.import_wizard.progressBar.setMaximum(len(songs))
for song in songs:
self.set_defaults()
if self.stop_import_flag:
- success = False
break
song_id = song[0]
- title = song[1]
+ self.title = song[1]
lyrics = song[2].replace(u'\r\n', u'\n')
- copyright = song[3]
- self.import_wizard.incrementProgressBar(
- WizardStrings.ImportingType % title)
- self.title = title
+ self.add_copyright(song[3])
verses = lyrics.split(u'\n\n')
- for verse in verses:
- if verse.strip() != u'':
- self.add_verse(verse.strip())
- self.add_copyright(copyright)
+ [self.add_verse(verse.strip()) for verse in verses if verse.strip()]
cursor.execute(u'-- types int')
cursor.execute(u'SELECT authorid FROM songauthors '
u'WHERE songid = %s' % song_id)
author_ids = cursor.fetchall()
for author_id in author_ids:
if self.stop_import_flag:
- success = False
break
for author in authors:
if author[0] == author_id[0]:
self.parse_author(author[1])
break
if self.stop_import_flag:
- success = False
break
if new_db:
cursor.execute(u'-- types int')
@@ -131,17 +122,15 @@
track_ids = cursor.fetchall()
for track_id in track_ids:
if self.stop_import_flag:
- success = False
break
for track in tracks:
if track[0] == track_id[0]:
self.add_media_file(track[1])
break
if self.stop_import_flag:
- success = False
break
- self.finish()
- return success
+ if not self.finish():
+ self.log_error(self.import_source)
def get_encoding(self):
"""
=== modified file 'openlp/plugins/songs/lib/olpimport.py'
--- openlp/plugins/songs/lib/olpimport.py 2011-03-24 19:04:02 +0000
+++ openlp/plugins/songs/lib/olpimport.py 2011-04-21 18:26:24 +0000
@@ -36,6 +36,7 @@
from openlp.core.lib import translate
from openlp.core.lib.db import BaseModel
+from openlp.core.ui.wizard import WizardStrings
from openlp.plugins.songs.lib import clean_song
from openlp.plugins.songs.lib.db import Author, Book, Song, Topic #, MediaFile
from songimport import SongImport
@@ -93,13 +94,18 @@
The database providing the data to import.
"""
SongImport.__init__(self, manager, **kwargs)
- self.import_source = u'sqlite:///%s' % self.import_source
self.source_session = None
def do_import(self):
"""
Run the import for an OpenLP version 2 song database.
"""
+ if not self.import_source.endswith(u'.sqlite'):
+ self.log_error(self.import_source,
+ translate('SongsPlugin.OpenLPSongImport',
+ 'Not a valid OpenLP 2.0 song database.'))
+ return
+ self.import_source = u'sqlite:///%s' % self.import_source
engine = create_engine(self.import_source)
source_meta = MetaData()
source_meta.reflect(engine)
@@ -124,10 +130,10 @@
mapper(OldMediaFile, source_media_files_table)
song_props = {
'authors': relation(OldAuthor, backref='songs',
- secondary=source_authors_songs_table),
+ secondary=source_authors_songs_table),
'book': relation(OldBook, backref='songs'),
'topics': relation(OldTopic, backref='songs',
- secondary=source_songs_topics_table)
+ secondary=source_songs_topics_table)
}
if has_media_files:
song_props['media_files'] = relation(OldMediaFile, backref='songs',
@@ -150,15 +156,9 @@
mapper(OldTopic, source_topics_table)
source_songs = self.source_session.query(OldSong).all()
- song_total = len(source_songs)
if self.import_wizard:
- self.import_wizard.progressBar.setMaximum(song_total)
- song_count = 1
+ self.import_wizard.progressBar.setMaximum(len(source_songs))
for song in source_songs:
- if self.import_wizard:
- self.import_wizard.incrementProgressBar(
- unicode(translate('SongsPlugin.OpenLPSongImport',
- 'Importing song %d of %d.')) % (song_count, song_total))
new_song = Song()
new_song.title = song.title
if has_media_files and hasattr(song, 'alternate_title'):
@@ -213,8 +213,9 @@
# file_name=media_file.file_name))
clean_song(self.manager, new_song)
self.manager.save_object(new_song)
- song_count += 1
+ if self.import_wizard:
+ self.import_wizard.incrementProgressBar(
+ WizardStrings.ImportingType % new_song.title)
if self.stop_import_flag:
- return False
+ break
engine.dispose()
- return True
=== modified file 'openlp/plugins/songs/lib/oooimport.py'
--- openlp/plugins/songs/lib/oooimport.py 2011-04-11 14:17:43 +0000
+++ openlp/plugins/songs/lib/oooimport.py 2011-04-21 18:26:24 +0000
@@ -56,13 +56,11 @@
self.process_started = False
def do_import(self):
- self.stop_import_flag = False
- self.import_wizard.progressBar.setMaximum(0)
self.start_ooo()
+ self.import_wizard.progressBar.setMaximum(len(self.import_source))
for filename in self.import_source:
if self.stop_import_flag:
- self.import_wizard.incrementProgressBar(u'Import cancelled', 0)
- return
+ break
filename = unicode(filename)
if os.path.isfile(filename):
self.open_ooo_file(filename)
@@ -70,9 +68,6 @@
self.process_ooo_document()
self.close_ooo_file()
self.close_ooo()
- self.import_wizard.progressBar.setMaximum(1)
- self.import_wizard.incrementProgressBar(u'', 1)
- return True
def process_ooo_document(self):
"""
=== modified file 'openlp/plugins/songs/lib/openlyricsimport.py'
--- openlp/plugins/songs/lib/openlyricsimport.py 2011-04-12 09:55:02 +0000
+++ openlp/plugins/songs/lib/openlyricsimport.py 2011-04-21 18:26:24 +0000
@@ -35,6 +35,7 @@
from openlp.core.ui.wizard import WizardStrings
from openlp.plugins.songs.lib.songimport import SongImport
+from openlp.plugins.songs.lib.ui import SongStrings
from openlp.plugins.songs.lib import OpenLyrics
log = logging.getLogger(__name__)
@@ -59,7 +60,7 @@
parser = etree.XMLParser(remove_blank_text=True)
for file_path in self.import_source:
if self.stop_import_flag:
- return False
+ return
self.import_wizard.incrementProgressBar(
WizardStrings.ImportingType % os.path.basename(file_path))
try:
@@ -67,8 +68,7 @@
# special characters in the path (see lp:757673 and lp:744337).
parsed_file = etree.parse(open(file_path, u'r'), parser)
xml = unicode(etree.tostring(parsed_file))
- if self.openLyrics.xml_to_song(xml) is None:
- log.debug(u'File could not be imported: %s' % file_path)
+ self.openLyrics.xml_to_song(xml)
except etree.XMLSyntaxError:
log.exception(u'XML syntax error in file %s' % file_path)
- return True
+ self.log_error(file_path, SongStrings.XMLSyntaxError)
=== modified file 'openlp/plugins/songs/lib/opensongimport.py'
--- openlp/plugins/songs/lib/opensongimport.py 2011-03-24 19:04:02 +0000
+++ openlp/plugins/songs/lib/opensongimport.py 2011-04-21 18:26:24 +0000
@@ -26,13 +26,15 @@
import logging
import os
+import re
from zipfile import ZipFile
+
from lxml import objectify
from lxml.etree import Error, LxmlError
-import re
-from openlp.core.ui.wizard import WizardStrings
+from openlp.plugins.songs.lib import VerseType
from openlp.plugins.songs.lib.songimport import SongImport
+from openlp.plugins.songs.lib.ui import SongStrings
log = logging.getLogger(__name__)
@@ -105,77 +107,62 @@
Initialise the class.
"""
SongImport.__init__(self, manager, **kwargs)
- self.commit = True
def do_import(self):
"""
Import either each of the files in self.import_source - each element of
which can be either a single opensong file, or a zipfile containing
- multiple opensong files. If `self.commit` is set False, the
- import will not be committed to the database (useful for test scripts).
+ multiple opensong files.
"""
- success = True
numfiles = 0
for filename in self.import_source:
ext = os.path.splitext(filename)[1]
if ext.lower() == u'.zip':
z = ZipFile(filename, u'r')
numfiles += len(z.infolist())
+ z.close()
else:
numfiles += 1
log.debug(u'Total number of files: %d', numfiles)
self.import_wizard.progressBar.setMaximum(numfiles)
for filename in self.import_source:
if self.stop_import_flag:
- success = False
- break
+ return
ext = os.path.splitext(filename)[1]
if ext.lower() == u'.zip':
log.debug(u'Zipfile found %s', filename)
z = ZipFile(filename, u'r')
for song in z.infolist():
if self.stop_import_flag:
- success = False
- break
+ z.close()
+ return
parts = os.path.split(song.filename)
if parts[-1] == u'':
- #No final part => directory
+ # No final part => directory
continue
log.info(u'Zip importing %s', parts[-1])
- self.import_wizard.incrementProgressBar(
- WizardStrings.ImportingType % parts[-1])
- songfile = z.open(song)
- if self.do_import_file(songfile) and self.commit and \
- not self.stop_import_flag:
- self.finish()
- else:
- success = False
- break
+ song_file = z.open(song)
+ self.do_import_file(song_file)
+ song_file.close()
+ z.close()
else:
# not a zipfile
log.info(u'Direct import %s', filename)
- self.import_wizard.incrementProgressBar(
- WizardStrings.ImportingType % os.path.split(filename)[-1])
song_file = open(filename)
- if self.do_import_file(song_file) and self.commit and \
- not self.stop_import_flag:
- self.finish()
- else:
- success = False
- break
- return success
+ self.do_import_file(song_file)
+ song_file.close()
def do_import_file(self, file):
"""
- Process the OpenSong file - pass in a file-like object,
- not a filename
+ Process the OpenSong file - pass in a file-like object, not a file path.
"""
self.set_defaults()
try:
tree = objectify.parse(file)
except (Error, LxmlError):
+ self.log_error(file.name, SongStrings.XMLSyntaxError)
log.exception(u'Error parsing XML')
- return False
+ return
root = tree.getroot()
fields = dir(root)
decode = {
@@ -193,9 +180,6 @@
setattr(self, fn_or_string, ustring)
else:
fn_or_string(ustring)
- if not len(self.title):
- # to prevent creation of empty songs from wrong files
- return False
if u'theme' in fields and unicode(root.theme) not in self.topics:
self.topics.append(unicode(root.theme))
if u'alttheme' in fields and unicode(root.alttheme) not in self.topics:
@@ -205,7 +189,7 @@
# keep track of verses appearance order
our_verse_order = []
# default verse
- verse_tag = u'v'
+ verse_tag = VerseType.Tags[VerseType.Verse]
verse_num = u'1'
# for the case where song has several sections with same marker
inst = 1
@@ -243,7 +227,7 @@
if [verse_tag, verse_num, inst] in our_verse_order \
and verses.has_key(verse_tag) \
and verses[verse_tag].has_key(verse_num):
- inst = len(verses[verse_tag][verse_num])+1
+ inst = len(verses[verse_tag][verse_num]) + 1
our_verse_order.append([verse_tag, verse_num, inst])
continue
# number at start of line.. it's verse number
@@ -269,7 +253,7 @@
lines = u'\n'.join(verses[verse_tag][verse_num][inst])
self.add_verse(lines, verse_def)
# figure out the presentation order, if present
- if u'presentation' in fields and root.presentation != u'':
+ if u'presentation' in fields and root.presentation:
order = unicode(root.presentation)
# We make all the tags in the lyrics lower case, so match that here
# and then split into a list on the whitespace
@@ -280,16 +264,17 @@
verse_tag = match.group(1)
verse_num = match.group(2)
if not len(verse_tag):
- verse_tag = u'v'
+ verse_tag = VerseType.Tags[VerseType.Verse]
else:
# Assume it's no.1 if there are no digits
verse_tag = verse_def
verse_num = u'1'
verse_def = u'%s%s' % (verse_tag, verse_num)
- if verses.has_key(verse_tag) \
- and verses[verse_tag].has_key(verse_num):
+ if verses.has_key(verse_tag) and \
+ verses[verse_tag].has_key(verse_num):
self.verse_order_list.append(verse_def)
else:
log.info(u'Got order %s but not in verse tags, dropping'
u'this item from presentation order', verse_def)
- return True
+ if not self.finish():
+ self.log_error(file.name)
=== modified file 'openlp/plugins/songs/lib/sofimport.py'
--- openlp/plugins/songs/lib/sofimport.py 2011-03-24 19:04:02 +0000
+++ openlp/plugins/songs/lib/sofimport.py 2011-04-21 18:26:24 +0000
@@ -88,7 +88,6 @@
paragraphs = self.document.getText().createEnumeration()
while paragraphs.hasMoreElements():
if self.stop_import_flag:
- self.import_wizard.incrementProgressBar(u'Import cancelled', 0)
return
paragraph = paragraphs.nextElement()
if paragraph.supportsService("com.sun.star.text.Paragraph"):
=== modified file 'openlp/plugins/songs/lib/songbeamerimport.py'
--- openlp/plugins/songs/lib/songbeamerimport.py 2011-03-24 19:04:02 +0000
+++ openlp/plugins/songs/lib/songbeamerimport.py 2011-04-21 18:26:24 +0000
@@ -33,9 +33,9 @@
import os
import re
-from openlp.core.ui.wizard import WizardStrings
from openlp.plugins.songs.lib import VerseType
from openlp.plugins.songs.lib.songimport import SongImport
+from openlp.plugins.songs.lib.ui import SongStrings
log = logging.getLogger(__name__)
@@ -78,58 +78,55 @@
"""
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:
- # TODO: check that it is a valid SongBeamer file
- self.set_defaults()
- self.current_verse = u''
- self.current_verse_type = VerseType.Tags[VerseType.Verse]
- read_verses = False
- file_name = os.path.split(file)[1]
- self.import_wizard.incrementProgressBar(
- WizardStrings.ImportingType % file_name, 0)
- if os.path.isfile(file):
- detect_file = open(file, u'r')
- details = chardet.detect(detect_file.read(2048))
- detect_file.close()
- infile = codecs.open(file, u'r', details['encoding'])
- songData = infile.readlines()
- infile.close()
- else:
- return False
- self.title = file_name.split('.sng')[0]
- read_verses = False
- for line in songData:
- # Just make sure that the line is of the type 'Unicode'.
- line = unicode(line).strip()
- if line.startswith(u'#') and not read_verses:
- self.parse_tags(line)
- elif line.startswith(u'---'):
- if self.current_verse:
- self.replace_html_tags()
- self.add_verse(self.current_verse,
- self.current_verse_type)
- self.current_verse = u''
- self.current_verse_type = VerseType.Tags[VerseType.Verse]
- read_verses = True
- verse_start = True
- elif read_verses:
- if verse_start:
- verse_start = False
- if not self.check_verse_marks(line):
- self.current_verse = line + u'\n'
- else:
- self.current_verse += line + u'\n'
- if self.current_verse:
- self.replace_html_tags()
- self.add_verse(self.current_verse, self.current_verse_type)
- if self.check_complete():
- self.finish()
- self.import_wizard.incrementProgressBar(
- WizardStrings.ImportingType % file_name)
- return True
+ self.import_wizard.progressBar.setMaximum(len(self.import_source))
+ if not isinstance(self.import_source, list):
+ return
+ for file in self.import_source:
+ # TODO: check that it is a valid SongBeamer file
+ if self.stop_import_flag:
+ return
+ self.set_defaults()
+ self.current_verse = u''
+ self.current_verse_type = VerseType.Tags[VerseType.Verse]
+ read_verses = False
+ file_name = os.path.split(file)[1]
+ if os.path.isfile(file):
+ detect_file = open(file, u'r')
+ details = chardet.detect(detect_file.read(2048))
+ detect_file.close()
+ infile = codecs.open(file, u'r', details['encoding'])
+ songData = infile.readlines()
+ infile.close()
+ else:
+ continue
+ self.title = file_name.split('.sng')[0]
+ read_verses = False
+ for line in songData:
+ # Just make sure that the line is of the type 'Unicode'.
+ line = unicode(line).strip()
+ if line.startswith(u'#') and not read_verses:
+ self.parse_tags(line)
+ elif line.startswith(u'---'):
+ if self.current_verse:
+ self.replace_html_tags()
+ self.add_verse(self.current_verse,
+ self.current_verse_type)
+ self.current_verse = u''
+ self.current_verse_type = VerseType.Tags[VerseType.Verse]
+ read_verses = True
+ verse_start = True
+ elif read_verses:
+ if verse_start:
+ verse_start = False
+ if not self.check_verse_marks(line):
+ self.current_verse = line + u'\n'
+ else:
+ self.current_verse += line + u'\n'
+ if self.current_verse:
+ self.replace_html_tags()
+ self.add_verse(self.current_verse, self.current_verse_type)
+ if not self.finish():
+ self.log_error(file)
def replace_html_tags(self):
"""
@@ -189,7 +186,7 @@
elif tag_val[0] == u'#Bible':
pass
elif tag_val[0] == u'#Categories':
- self.topics = line.split(',')
+ self.topics = tag_val[1].split(',')
elif tag_val[0] == u'#CCLI':
self.ccli_number = tag_val[1]
elif tag_val[0] == u'#Chords':
@@ -236,11 +233,12 @@
pass
elif tag_val[0] == u'#Rights':
song_book_pub = tag_val[1]
- elif tag_val[0] == u'#Songbook':
- book_num = tag_val[1].split(' / ')
- self.song_book_name = book_num[0]
- if len(book_num) == book_num[1]:
- self.song_number = u''
+ elif tag_val[0] == u'#Songbook' or tag_val[0] == u'#SongBook':
+ book_data = tag_val[1].split(u'/')
+ self.song_book_name = book_data[0].strip()
+ if len(book_data) == 2:
+ number = book_data[1].strip()
+ self.song_number = number if number.isdigit() else u''
elif tag_val[0] == u'#Speed':
pass
elif tag_val[0] == u'Tempo':
@@ -287,5 +285,4 @@
if marks[1].isdigit():
self.current_verse_type += marks[1]
return True
- else:
- return False
+ return False
=== modified file 'openlp/plugins/songs/lib/songimport.py'
--- openlp/plugins/songs/lib/songimport.py 2011-03-24 19:04:02 +0000
+++ openlp/plugins/songs/lib/songimport.py 2011-04-21 18:26:24 +0000
@@ -23,12 +23,14 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
-
import logging
import re
+
from PyQt4 import QtCore
-from openlp.core.lib import Receiver, translate
+from openlp.core.lib import Receiver, translate, check_directory_exists
+from openlp.core.ui.wizard import WizardStrings
+from openlp.core.utils import AppLocation
from openlp.plugins.songs.lib import clean_song, VerseType
from openlp.plugins.songs.lib.db import Song, Author, Topic, Book, MediaFile
from openlp.plugins.songs.lib.ui import SongStrings
@@ -66,6 +68,7 @@
self.song = None
self.stop_import_flag = False
self.set_defaults()
+ self.error_log = []
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_import)
@@ -94,6 +97,31 @@
self.copyright_string = unicode(translate(
'SongsPlugin.SongImport', 'copyright'))
+ def log_error(self, filepath, reason=SongStrings.SongIncomplete):
+ """
+ This should be called, when a song could not be imported.
+
+ ``filepath``
+ This should be the file path if ``self.import_source`` is a list
+ with different files. If it is not a list, but a single file (for
+ instance a database), then this should be the song's title.
+
+ ``reason``
+ The reason, why the import failed. The string should be as
+ informative as possible.
+ """
+ if self.import_wizard is None:
+ return
+ if self.import_wizard.errorReportTextEdit.isHidden():
+ self.import_wizard.errorReportTextEdit.setText(
+ translate('SongsPlugin.SongImport',
+ 'The following songs could not be imported:'))
+ self.import_wizard.errorReportTextEdit.setVisible(True)
+ self.import_wizard.errorCopyToButton.setVisible(True)
+ self.import_wizard.errorSaveToButton.setVisible(True)
+ self.import_wizard.errorReportTextEdit.append(
+ u'- %s (%s)' % (filepath, reason))
+
def stop_import(self):
"""
Sets the flag for importers to stop their import
@@ -240,7 +268,7 @@
Author not checked here, if no author then "Author unknown" is
automatically added
"""
- if self.title == u'' or len(self.verses) == 0:
+ if not self.title or not len(self.verses):
return False
else:
return True
@@ -249,9 +277,15 @@
"""
All fields have been set to this song. Write the song to disk.
"""
+ if not self.check_complete():
+ self.set_defaults()
+ return False
log.info(u'committing song %s to database', self.title)
song = Song()
song.title = self.title
+ if self.import_wizard is not None:
+ self.import_wizard.incrementProgressBar(
+ WizardStrings.ImportingType % song.title)
song.alternate_title = self.alternate_title
# Values will be set when cleaning the song.
song.search_title = u''
@@ -308,7 +342,7 @@
publisher=self.song_book_pub)
song.book = song_book
for topictext in self.topics:
- if len(topictext) == 0:
+ if not topictext:
continue
topic = self.manager.get_object_filtered(Topic,
Topic.name == topictext)
@@ -318,6 +352,7 @@
clean_song(self.manager, song)
self.manager.save_object(song)
self.set_defaults()
+ return True
def print_song(self):
"""
=== modified file 'openlp/plugins/songs/lib/songshowplusimport.py'
--- openlp/plugins/songs/lib/songshowplusimport.py 2011-03-24 19:04:02 +0000
+++ openlp/plugins/songs/lib/songshowplusimport.py 2011-04-21 18:26:24 +0000
@@ -32,6 +32,7 @@
import struct
from openlp.core.ui.wizard import WizardStrings
+from openlp.plugins.songs.lib import VerseType
from openlp.plugins.songs.lib.songimport import SongImport
TITLE = 1
@@ -97,83 +98,81 @@
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''
- self.sspVerseOrderList = []
- otherCount = 0
- otherList = {}
- file_name = os.path.split(file)[1]
- self.import_wizard.incrementProgressBar(
- WizardStrings.ImportingType % 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, True)
- if verseTag:
- 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(
- WizardStrings.ImportingType % file_name)
- return True
+ return
+ self.import_wizard.progressBar.setMaximum(len(self.import_source))
+ for file in self.import_source:
+ self.sspVerseOrderList = []
+ otherCount = 0
+ otherList = {}
+ file_name = os.path.split(file)[1]
+ self.import_wizard.incrementProgressBar(
+ WizardStrings.ImportingType % file_name, 0)
+ songData = open(file, 'rb')
+ while True:
+ 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, True)
+ if verseTag:
+ 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()
+ if not self.finish():
+ self.log_error(file)
def toOpenLPVerseTag(self, verseName, ignoreUnique=False):
if verseName.find(" ") != -1:
@@ -185,22 +184,19 @@
verseNumber = "1"
verseType = verseType.lower()
if verseType == "verse":
- verseTag = "V"
+ verseTag = VerseType.Tags[VerseType.Verse]
elif verseType == "chorus":
- verseTag = "C"
+ verseTag = VerseType.Tags[VerseType.Chorus]
elif verseType == "bridge":
- verseTag = "B"
+ verseTag = VerseType.Tags[VerseType.Bridge]
elif verseType == "pre-chorus":
- verseTag = "P"
- elif verseType == "bridge":
- verseTag = "B"
+ verseTag = VerseType.Tags[VerseType.PreChorus]
else:
if not self.otherList.has_key(verseName):
if ignoreUnique:
return None
self.otherCount = self.otherCount + 1
self.otherList[verseName] = str(self.otherCount)
- verseTag = "O"
+ verseTag = VerseType.Tags[VerseType.Other]
verseNumber = self.otherList[verseName]
- verseTag = verseTag + verseNumber
- return verseTag
+ return verseTag + verseNumber
=== modified file 'openlp/plugins/songs/lib/ui.py'
--- openlp/plugins/songs/lib/ui.py 2011-03-24 19:04:02 +0000
+++ openlp/plugins/songs/lib/ui.py 2011-04-21 18:26:24 +0000
@@ -40,6 +40,8 @@
CopyrightSymbol = translate('OpenLP.Ui', '\xa9', 'Copyright symbol.')
SongBook = translate('OpenLP.Ui', 'Song Book', 'Singular')
SongBooks = translate('OpenLP.Ui', 'Song Books', 'Plural')
+ SongIncomplete = translate('OpenLP.Ui','Title and/or verses not found')
SongMaintenance = translate('OpenLP.Ui', 'Song Maintenance')
Topic = translate('OpenLP.Ui', 'Topic', 'Singular')
Topics = translate('OpenLP.Ui', 'Topics', 'Plural')
+ XMLSyntaxError = translate('OpenLP.Ui', 'XML syntax error')
=== modified file 'openlp/plugins/songs/lib/wowimport.py'
--- openlp/plugins/songs/lib/wowimport.py 2011-03-24 19:04:02 +0000
+++ openlp/plugins/songs/lib/wowimport.py 2011-04-21 18:26:24 +0000
@@ -105,11 +105,7 @@
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''
file_name = os.path.split(file)[1]
- self.import_wizard.incrementProgressBar(
- WizardStrings.ImportingType % file_name, 0)
# Get the song title
self.title = file_name.rpartition(u'.')[0]
songData = open(file, 'rb')
@@ -129,7 +125,7 @@
self.line_text = unicode(
songData.read(ord(songData.read(1))), u'cp1252')
songData.seek(1, os.SEEK_CUR)
- if block_text != u'':
+ if block_text:
block_text += u'\n'
block_text += self.line_text
self.lines_to_read -= 1
@@ -138,22 +134,19 @@
songData.seek(3, os.SEEK_CUR)
# Blocks are seperated by 2 bytes, skip them, but not if
# this is the last block!
- if (block + 1) < no_of_blocks:
+ if block + 1 < no_of_blocks:
songData.seek(2, os.SEEK_CUR)
self.add_verse(block_text, block_type)
# Now to extract the author
author_length = ord(songData.read(1))
- if author_length != 0:
- author = unicode(songData.read(author_length), u'cp1252')
+ if author_length:
+ self.parse_author(
+ unicode(songData.read(author_length), u'cp1252'))
# Finally the copyright
copyright_length = ord(songData.read(1))
- if copyright_length != 0:
- copyright = unicode(
- songData.read(copyright_length), u'cp1252')
- self.parse_author(author)
- self.add_copyright(copyright)
+ if copyright_length:
+ self.add_copyright(unicode(
+ songData.read(copyright_length), u'cp1252'))
songData.close()
- self.finish()
- self.import_wizard.incrementProgressBar(
- WizardStrings.ImportingType % file_name)
- return True
+ if not self.finish():
+ self.log_error(file)
Follow ups