openlp-core team mailing list archive
-
openlp-core team
-
Mailing list archive
-
Message #06320
[Merge] lp:~mahfiaz/openlp/opensongfixes into lp:openlp
mahfiaz has proposed merging lp:~mahfiaz/openlp/opensongfixes into lp:openlp.
Requested reviews:
Tim Bentley (trb143)
Jon Tibble (meths)
For more details, see:
https://code.launchpad.net/~mahfiaz/openlp/opensongfixes/+merge/50217
More changes, now internally tags are held not as Salm:1 (previously), nor v:1 (in the meantime), but just as in openlyrics format, v1. The v1a is not yet supported, it requires spinboxes to be changed first.
--
https://code.launchpad.net/~mahfiaz/openlp/opensongfixes/+merge/50217
Your team OpenLP Core is subscribed to branch lp:openlp.
=== modified file 'openlp/core/ui/slidecontroller.py'
--- openlp/core/ui/slidecontroller.py 2011-02-14 21:06:48 +0000
+++ openlp/core/ui/slidecontroller.py 2011-02-17 19:49:33 +0000
@@ -603,14 +603,15 @@
slideHeight = 0
if self.serviceItem.is_text():
if frame[u'verseTag']:
- bits = frame[u'verseTag'].split(u':')
- tag = u'%s\n%s' % (bits[0][0], bits[1][0:] )
- tag1 = u'%s%s' % (bits[0][0], bits[1][0:] )
- row = tag
+ # These tags are already translated.
+ versetag = frame[u'verseTag']
+ versetag = u'%s%s' % (versetag[0].upper(), versetag[1:])
+ twolineTag = u'%s\n%s' % (versetag[0], versetag[1:] )
+ row = twolineTag
if self.isLive:
- if tag1 not in self.slideList:
- self.slideList[tag1] = framenumber
- self.songMenu.menu().addAction(tag1,
+ if versetag not in self.slideList:
+ self.slideList[versetag] = framenumber
+ self.songMenu.menu().addAction(versetag,
self.onSongBarHandler)
else:
row += 1
=== modified file 'openlp/plugins/songs/forms/editsongform.py'
--- openlp/plugins/songs/forms/editsongform.py 2011-02-15 01:58:18 +0000
+++ openlp/plugins/songs/forms/editsongform.py 2011-02-17 19:49:33 +0000
@@ -228,7 +228,14 @@
self.verseListWidget.clear()
self.verseListWidget.setRowCount(0)
if self.song.verse_order:
- self.verseOrderEdit.setText(self.song.verse_order)
+ # we translate verse order
+ translated = []
+ for versetag in self.song.verse_order.split():
+ verseindex = VerseType.from_tag(versetag[0])
+ versetype = VerseType.TranslatedTags[verseindex]
+ versenum = versetag[1:]
+ translated.append(u'%s%s' % (versetype.upper(), versenum))
+ self.verseOrderEdit.setText(u' '.join(translated))
else:
self.verseOrderEdit.setText(u'')
if self.song.comments:
@@ -256,7 +263,20 @@
for count, verse in enumerate(verseList):
self.verseListWidget.setRowCount(
self.verseListWidget.rowCount() + 1)
- variant = u'%s:%s' % (verse[0][u'type'], verse[0][u'label'])
+ # This silently migrates from localized verse type markup.
+ # If we trusted the database, this would be unnecessary.
+ vtype = verse[0][u'type']
+ index = None
+ if len(vtype) > 1:
+ index = VerseType.from_translated_string(vtype)
+ if index is None:
+ index = VerseType.from_string(vtype)
+ if index is None:
+ index = VerseType.from_tag(vtype)
+ if index is None:
+ index = VerseType.Other
+ verse[0][u'type'] = VerseType.Tags[index]
+ variant = u'%s%s' % (verse[0][u'type'], verse[0][u'label'])
item = QtGui.QTableWidgetItem(verse[1])
item.setData(QtCore.Qt.UserRole, QtCore.QVariant(variant))
self.verseListWidget.setItem(count, 0, item)
@@ -267,7 +287,7 @@
self.verseListWidget.rowCount() + 1)
item = QtGui.QTableWidgetItem(verse)
variant = u'%s:%s' % \
- (VerseType.to_string(VerseType.Verse), unicode(count + 1))
+ (VerseType.Tags[VerseType.Verse], unicode(count + 1))
item.setData(QtCore.Qt.UserRole, QtCore.QVariant(variant))
self.verseListWidget.setItem(count, 0, item)
self.verseListWidget.resizeRowsToContents()
@@ -297,9 +317,10 @@
rowLabel = []
for row in range(0, self.verseListWidget.rowCount()):
item = self.verseListWidget.item(row, 0)
- data = unicode(item.data(QtCore.Qt.UserRole).toString())
- bit = data.split(u':')
- rowTag = u'%s%s' % (bit[0][0:1], bit[1])
+ versetag = unicode(item.data(QtCore.Qt.UserRole).toString())
+ versetype = VerseType.TranslatedTags[
+ VerseType.from_tag(versetag[0])].upper()
+ rowTag = u'%s%s' % (versetype, versetag[1:])
rowLabel.append(rowTag)
self.verseListWidget.setVerticalHeaderLabels(rowLabel)
@@ -420,10 +441,10 @@
def onVerseAddButtonClicked(self):
self.verse_form.setVerse(u'', True)
if self.verse_form.exec_():
- afterText, verse, subVerse = self.verse_form.getVerse()
- data = u'%s:%s' % (verse, subVerse)
+ afterText, versetype, versenum = self.verse_form.getVerse()
+ versetag = u'%s%s' % (versetype, versenum)
item = QtGui.QTableWidgetItem(afterText)
- item.setData(QtCore.Qt.UserRole, QtCore.QVariant(data))
+ item.setData(QtCore.Qt.UserRole, QtCore.QVariant(versetag))
item.setText(afterText)
self.verseListWidget.setRowCount(
self.verseListWidget.rowCount() + 1)
@@ -440,9 +461,9 @@
verseId = unicode(item.data(QtCore.Qt.UserRole).toString())
self.verse_form.setVerse(tempText, True, verseId)
if self.verse_form.exec_():
- afterText, verse, subVerse = self.verse_form.getVerse()
- data = u'%s:%s' % (verse, subVerse)
- item.setData(QtCore.Qt.UserRole, QtCore.QVariant(data))
+ afterText, versetype, versenum = self.verse_form.getVerse()
+ versetag = u'%s%s' % (versetype, versenum)
+ item.setData(QtCore.Qt.UserRole, QtCore.QVariant(versetag))
item.setText(afterText)
# number of lines has change so repaint the list moving the data
if len(tempText.split(u'\n')) != len(afterText.split(u'\n')):
@@ -467,7 +488,10 @@
for row in range(0, self.verseListWidget.rowCount()):
item = self.verseListWidget.item(row, 0)
field = unicode(item.data(QtCore.Qt.UserRole).toString())
- verse_list += u'---[%s]---\n' % field
+ versetypeindex = VerseType.from_tag(field[0])
+ versetype = VerseType.TranslatedNames[versetypeindex]
+ versenum = field[1:]
+ verse_list += u'---[%s:%s]---\n' % (versetype, versenum)
verse_list += item.text()
verse_list += u'\n'
self.verse_form.setVerse(verse_list)
@@ -483,9 +507,28 @@
for count, parts in enumerate(match.split(u']---\n')):
if len(parts) > 1:
if count == 0:
- # make sure the tag is correctly cased
- variant = u'%s%s' % \
- (parts[0:1].upper(), parts[1:].lower())
+ # handling carefully user inputted versetags
+ separator = parts.find(u':')
+ if separator >= 0:
+ versetype = parts[0:separator].strip()
+ versenum = parts[separator+1:].strip()
+ else:
+ versetype = parts
+ versenum = u'1'
+ verseindex = \
+ VerseType.from_loose_input(versetype)
+ if verseindex is None:
+ verseindex = VerseType.Verse
+ versetype = VerseType.Tags[verseindex]
+ # Later we need to handle v1a as well.
+ #regex = re.compile(r'(\d+\w.)')
+ regex = re.compile(r'\D*(\d+)\D*')
+ match = regex.match(versenum)
+ if match:
+ versenum = match.group(1)
+ else:
+ versenum = u'1'
+ variant = u'%s%s' % (versetype, versenum)
else:
if parts.endswith(u'\n'):
parts = parts.rstrip(u'\n')
@@ -543,12 +586,16 @@
order_names = unicode(self.verseOrderEdit.text()).split()
for item in order_names:
if len(item) == 1:
- order.append(item.lower() + u'1')
+ order.append(VerseType.Tags[VerseType.from_translated_tag(
+ item)] + u'1')
else:
- order.append(item.lower())
+ versetag = VerseType.Tags[
+ VerseType.from_translated_tag(item[0])]
+ versenum = item[1:].lower()
+ order.append(u'%s%s' % (versetag, versenum))
verses = []
verse_names = []
- for index in range (0, self.verseListWidget.rowCount()):
+ for index in range(0, self.verseListWidget.rowCount()):
verse = self.verseListWidget.item(index, 0)
verse = unicode(verse.data(QtCore.Qt.UserRole).toString())
if verse not in verse_names:
@@ -561,7 +608,7 @@
self.verseOrderEdit.setFocus()
valid = verses.pop(0)
for verse in verses:
- valid = valid + u', ' + verse
+ valid = valid + u', ' + verse.upper()
critical_error_message_box(
message=unicode(translate('SongsPlugin.EditSongForm',
'The verse order is invalid. There is no verse '
@@ -572,12 +619,17 @@
if verse not in order:
self.songTabWidget.setCurrentIndex(0)
self.verseOrderEdit.setFocus()
+ versetype = verse_names[count][0]
+ versenum = verse_names[count][1:]
+ verseindex = VerseType.from_tag(versetype)
+ versetype = VerseType.TranslatedTags[verseindex].upper()
+ versename = u'%s%s' % (versetype, versenum)
answer = QtGui.QMessageBox.warning(self,
translate('SongsPlugin.EditSongForm', 'Warning'),
unicode(translate('SongsPlugin.EditSongForm',
'You have not used %s anywhere in the verse '
'order. Are you sure you want to save the song '
- 'like this?')) % verse_names[count].replace(u':', u' '),
+ 'like this?')) % versename,
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
if answer == QtGui.QMessageBox.No:
return False
@@ -684,7 +736,14 @@
else:
self.song.search_title = self.song.title
self.song.comments = unicode(self.commentsEdit.toPlainText())
- self.song.verse_order = unicode(self.verseOrderEdit.text())
+ ordertext = unicode(self.verseOrderEdit.text())
+ order = []
+ for item in ordertext.split():
+ versetag = VerseType.Tags[
+ VerseType.from_translated_tag(item[0])]
+ versenum = item[1:].lower()
+ order.append(u'%s%s' % (versetag, versenum))
+ self.song.verse_order = u' '.join(order)
self.song.ccli_number = unicode(self.CCLNumberEdit.text())
self.song.song_number = unicode(self.songBookNumberEdit.text())
book_name = unicode(self.songBookComboBox.currentText())
@@ -727,12 +786,14 @@
for i in range(0, self.verseListWidget.rowCount()):
item = self.verseListWidget.item(i, 0)
verseId = unicode(item.data(QtCore.Qt.UserRole).toString())
- bits = verseId.split(u':')
- sxml.add_verse_to_lyrics(bits[0], bits[1], unicode(item.text()))
+ versetype = verseId[0]
+ versenum = verseId[1:]
+ sxml.add_verse_to_lyrics(versetype, versenum,
+ unicode(item.text()))
text = text + self.whitespace.sub(u' ',
unicode(self.verseListWidget.item(i, 0).text())) + u' '
- if (bits[1] > u'1') and (bits[0][0] not in multiple):
- multiple.append(bits[0][0])
+ if (versenum > u'1') and (versetype not in multiple):
+ multiple.append(versetype)
self.song.search_lyrics = text.lower()
self.song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
for verse in multiple:
=== modified file 'openlp/plugins/songs/forms/editversedialog.py'
--- openlp/plugins/songs/forms/editversedialog.py 2011-02-10 00:36:00 +0000
+++ openlp/plugins/songs/forms/editversedialog.py 2011-02-17 19:49:33 +0000
@@ -70,19 +70,19 @@
translate('SongsPlugin.EditVerseForm', 'Edit Verse'))
self.verseTypeLabel.setText(
translate('SongsPlugin.EditVerseForm', '&Verse type:'))
- self.verseTypeComboBox.setItemText(0,
- VerseType.to_string(VerseType.Verse))
- self.verseTypeComboBox.setItemText(1,
- VerseType.to_string(VerseType.Chorus))
- self.verseTypeComboBox.setItemText(2,
- VerseType.to_string(VerseType.Bridge))
- self.verseTypeComboBox.setItemText(3,
- VerseType.to_string(VerseType.PreChorus))
- self.verseTypeComboBox.setItemText(4,
- VerseType.to_string(VerseType.Intro))
- self.verseTypeComboBox.setItemText(5,
- VerseType.to_string(VerseType.Ending))
- self.verseTypeComboBox.setItemText(6,
- VerseType.to_string(VerseType.Other))
+ self.verseTypeComboBox.setItemText(VerseType.Verse,
+ VerseType.TranslatedNames[VerseType.Verse])
+ self.verseTypeComboBox.setItemText(VerseType.Chorus,
+ VerseType.TranslatedNames[VerseType.Chorus])
+ self.verseTypeComboBox.setItemText(VerseType.Bridge,
+ VerseType.TranslatedNames[VerseType.Bridge])
+ self.verseTypeComboBox.setItemText(VerseType.PreChorus,
+ VerseType.TranslatedNames[VerseType.PreChorus])
+ self.verseTypeComboBox.setItemText(VerseType.Intro,
+ VerseType.TranslatedNames[VerseType.Intro])
+ self.verseTypeComboBox.setItemText(VerseType.Ending,
+ VerseType.TranslatedNames[VerseType.Ending])
+ self.verseTypeComboBox.setItemText(VerseType.Other,
+ VerseType.TranslatedNames[VerseType.Other])
self.insertButton.setText(
translate('SongsPlugin.EditVerseForm', '&Insert'))
=== modified file 'openlp/plugins/songs/forms/editverseform.py'
--- openlp/plugins/songs/forms/editverseform.py 2011-02-02 23:12:31 +0000
+++ openlp/plugins/songs/forms/editverseform.py 2011-02-17 19:49:33 +0000
@@ -57,22 +57,23 @@
QtCore.QObject.connect(self.verseTypeComboBox,
QtCore.SIGNAL(u'currentIndexChanged(int)'),
self.onVerseTypeComboBoxChanged)
- self.verse_regex = re.compile(r'---\[([-\w]+):([\d]+)\]---')
+ self.verse_regex = re.compile(r'---\[(.+):\D*(\d+)\D*\]---')
def contextMenu(self, point):
item = self.serviceManagerList.itemAt(point)
- def insertVerse(self, title, num=1):
+ def insertVerse(self, versetype, num=1):
if self.verseTextEdit.textCursor().columnNumber() != 0:
self.verseTextEdit.insertPlainText(u'\n')
- self.verseTextEdit.insertPlainText(u'---[%s:%s]---\n' % (title, num))
+ versetype = VerseType.TranslatedNames[VerseTag.from_tag(versetype)]
+ self.verseTextEdit.insertPlainText(u'---[%s:%s]---\n' % \
+ (versetype, num))
self.verseTextEdit.setFocus()
def onInsertButtonClicked(self):
- verse_type = self.verseTypeComboBox.currentIndex()
- if VerseType.to_string(verse_type) is not None:
- self.insertVerse(VerseType.to_string(verse_type),
- self.verseNumberBox.value())
+ vtypeindex = self.verseTypeComboBox.currentIndex()
+ self.insertVerse(VerseType.Tags[vtypeindex],
+ self.verseNumberBox.value())
def onVerseTypeComboBoxChanged(self):
"""
@@ -81,7 +82,8 @@
"""
position = self.verseTextEdit.textCursor().position()
text = unicode(self.verseTextEdit.toPlainText())
- verse_type = VerseType.to_string(self.verseTypeComboBox.currentIndex())
+ verse_type = VerseType.TranslatedNames[
+ self.verseTypeComboBox.currentIndex()]
if not text:
return
position = text.rfind(u'---[%s' % verse_type, 0, position)
@@ -97,7 +99,7 @@
if match:
verse_type = match.group(1)
verse_number = int(match.group(2))
- verse_type_index = VerseType.from_string(verse_type)
+ verse_type_index = VerseType.from_loose_input(verse_type)
if verse_type_index is not None:
self.verseNumberBox.setValue(verse_number)
@@ -123,26 +125,28 @@
text = text[:position + 4]
match = self.verse_regex.match(text)
if match:
- verse_type = match.group(1)
- verse_number = int(match.group(2))
- verse_type_index = VerseType.from_string(verse_type)
- if verse_type_index is not None:
- self.verseTypeComboBox.setCurrentIndex(verse_type_index)
- self.verseNumberBox.setValue(verse_number)
+ versetype = match.group(1)
+ vtypeindex = VerseType.from_loose_input(versetype)
+ regex = re.compile(r'(\d+)')
+ versenum = int(match.group(2))
+ if vtypeindex is not None:
+ self.verseTypeComboBox.setCurrentIndex(vtypeindex)
+ self.verseNumberBox.setValue(versenum)
def setVerse(self, text, single=False,
- tag=u'%s:1' % VerseType.to_string(VerseType.Verse)):
+ tag=u'%s1' % VerseType.Tags[VerseType.Verse]):
self.hasSingleVerse = single
if single:
- verse_type, verse_number = tag.split(u':')
- verse_type_index = VerseType.from_string(verse_type)
+ verse_type_index = VerseType.from_tag(tag[0])
+ verse_number = tag[1:]
if verse_type_index is not None:
self.verseTypeComboBox.setCurrentIndex(verse_type_index)
self.verseNumberBox.setValue(int(verse_number))
self.insertButton.setVisible(False)
else:
if not text:
- text = u'---[%s:1]---\n' % VerseType.to_string(VerseType.Verse)
+ text = u'---[%s:1]---\n' % \
+ VerseType.TranslatedNames[VerseType.Verse]
self.verseTypeComboBox.setCurrentIndex(0)
self.verseNumberBox.setValue(1)
self.insertButton.setVisible(True)
@@ -152,14 +156,14 @@
def getVerse(self):
return self.verseTextEdit.toPlainText(), \
- VerseType.to_string(self.verseTypeComboBox.currentIndex()), \
+ VerseType.Tags[self.verseTypeComboBox.currentIndex()], \
unicode(self.verseNumberBox.value())
def getVerseAll(self):
text = self.verseTextEdit.toPlainText()
if not text.startsWith(u'---['):
- text = u'---[%s:1]---\n%s' % (VerseType.to_string(VerseType.Verse),
- text)
+ text = u'---[%s:1]---\n%s' % \
+ (VerseType.TranslatedNames[VerseType.Verse], text)
return text
def accept(self):
=== modified file 'openlp/plugins/songs/lib/__init__.py'
--- openlp/plugins/songs/lib/__init__.py 2011-02-07 16:29:06 +0000
+++ openlp/plugins/songs/lib/__init__.py 2011-02-17 19:49:33 +0000
@@ -40,37 +40,55 @@
Ending = 5
Other = 6
- @staticmethod
- def to_string(verse_type):
- """
- Return a string for a given VerseType
-
- ``verse_type``
- The type to return a string for
- """
- if not isinstance(verse_type, int):
- verse_type = verse_type.lower()
- if verse_type == VerseType.Verse or verse_type == \
- unicode(VerseType.to_string(VerseType.Verse)).lower()[0]:
- return translate('SongsPlugin.VerseType', 'Verse')
- elif verse_type == VerseType.Chorus or verse_type == \
- unicode(VerseType.to_string(VerseType.Chorus)).lower()[0]:
- return translate('SongsPlugin.VerseType', 'Chorus')
- elif verse_type == VerseType.Bridge or verse_type == \
- unicode(VerseType.to_string(VerseType.Bridge)).lower()[0]:
- return translate('SongsPlugin.VerseType', 'Bridge')
- elif verse_type == VerseType.PreChorus or verse_type == \
- unicode(VerseType.to_string(VerseType.PreChorus)).lower()[0]:
- return translate('SongsPlugin.VerseType', 'Pre-Chorus')
- elif verse_type == VerseType.Intro or verse_type == \
- unicode(VerseType.to_string(VerseType.Intro)).lower()[0]:
- return translate('SongsPlugin.VerseType', 'Intro')
- elif verse_type == VerseType.Ending or verse_type == \
- unicode(VerseType.to_string(VerseType.Ending)).lower()[0]:
- return translate('SongsPlugin.VerseType', 'Ending')
- elif verse_type == VerseType.Other or verse_type == \
- unicode(VerseType.to_string(VerseType.Other)).lower()[0]:
- return translate('SongsPlugin.VerseType', 'Other')
+ Names = [
+ u'Verse',
+ u'Chorus',
+ u'Bridge',
+ u'Pre-Chorus',
+ u'Intro',
+ u'Ending',
+ u'Other']
+ Tags = []
+ for name in Names:
+ Tags.append(name[0].lower())
+
+ TranslatedNames = [
+ unicode(translate('SongsPlugin.VerseType', 'Verse')),
+ unicode(translate('SongsPlugin.VerseType', 'Chorus')),
+ unicode(translate('SongsPlugin.VerseType', 'Bridge')),
+ unicode(translate('SongsPlugin.VerseType', 'Pre-Chorus')),
+ unicode(translate('SongsPlugin.VerseType', 'Intro')),
+ unicode(translate('SongsPlugin.VerseType', 'Ending')),
+ unicode(translate('SongsPlugin.VerseType', 'Other'))]
+ TranslatedTags = []
+ for name in TranslatedNames:
+ TranslatedTags.append(name[0].lower())
+
+ @staticmethod
+ def from_tag(verse_type):
+ """
+ Return the VerseType for a given tag
+
+ ``verse_type``
+ The string to return a VerseType for
+ """
+ verse_type = verse_type[0].lower()
+ for num, string in enumerate(VerseType.Tags):
+ if verse_type == string:
+ return num
+
+ @staticmethod
+ def from_translated_tag(verse_type):
+ """
+ Return the VerseType for a given tag
+
+ ``verse_type``
+ The string to return a VerseType for
+ """
+ verse_type = verse_type[0].lower()
+ for vtypeIndex, vtypeTag in enumerate(VerseType.TranslatedTags):
+ if verse_type == vtypeTag:
+ return vtypeIndex
@staticmethod
def from_string(verse_type):
@@ -81,27 +99,41 @@
The string to return a VerseType for
"""
verse_type = verse_type.lower()
- if verse_type == unicode(VerseType.to_string(VerseType.Verse)).lower():
- return VerseType.Verse
- elif verse_type == \
- unicode(VerseType.to_string(VerseType.Chorus)).lower():
- return VerseType.Chorus
- elif verse_type == \
- unicode(VerseType.to_string(VerseType.Bridge)).lower():
- return VerseType.Bridge
- elif verse_type == \
- unicode(VerseType.to_string(VerseType.PreChorus)).lower():
- return VerseType.PreChorus
- elif verse_type == \
- unicode(VerseType.to_string(VerseType.Intro)).lower():
- return VerseType.Intro
- elif verse_type == \
- unicode(VerseType.to_string(VerseType.Ending)).lower():
- return VerseType.Ending
- elif verse_type == \
- unicode(VerseType.to_string(VerseType.Other)).lower():
- return VerseType.Other
-
+ for vtypeIndex, vtypeName in enumerate(VerseType.Names):
+ if verse_type == vtypeName.lower():
+ return vtypeIndex
+
+ @staticmethod
+ def from_translated_string(verse_type):
+ """
+ Return the VerseType for a given string
+
+ ``verse_type``
+ The string to return a VerseType for
+ """
+ verse_type = verse_type.lower()
+ for num, translation in enumerate(VerseType.TranslatedNames):
+ if verse_type == translation.lower():
+ return num
+
+ @staticmethod
+ def from_loose_input(verse_type):
+ """
+ Return the VerseType for a given string, Other if not found
+
+ ``verse_type``
+ The string to return a VerseType for
+ """
+ verseIndex = None
+ if len(verse_type) > 1:
+ verseIndex = VerseType.from_translated_string(verse_type)
+ if verseIndex is None:
+ verseIndex = VerseType.from_string(verse_type)
+ if verseIndex is None:
+ verseIndex = VerseType.from_translated_tag(verse_type)
+ elif verseIndex is None:
+ verseIndex = VerseType.from_tag(verse_type)
+ return verseIndex
def retrieve_windows_encoding(recommendation=None):
"""
=== modified file 'openlp/plugins/songs/lib/mediaitem.py'
--- openlp/plugins/songs/lib/mediaitem.py 2011-02-10 18:38:40 +0000
+++ openlp/plugins/songs/lib/mediaitem.py 2011-02-17 19:49:33 +0000
@@ -36,7 +36,7 @@
from openlp.core.lib.ui import UiStrings
from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm, \
SongImportForm, SongExportForm
-from openlp.plugins.songs.lib import OpenLyrics, SongXML
+from openlp.plugins.songs.lib import OpenLyrics, SongXML, VerseType
from openlp.plugins.songs.lib.db import Author, Song
from openlp.core.lib.searchedit import SearchEdit
@@ -344,22 +344,38 @@
if song.lyrics.startswith(u'<?xml version='):
verseList = SongXML().get_verses(song.lyrics)
# no verse list or only 1 space (in error)
- if not song.verse_order or not song.verse_order.strip():
+ if not song.verse_order.strip():
for verse in verseList:
- verseTag = u'%s:%s' % (
- verse[0][u'type'], verse[0][u'label'])
+ # We cannot use from_loose_input() here, because database
+ # is supposed to contain English lowercase singlechar tags.
+ verse_type = verse[0][u'type']
+ verseIndex = None
+ if len(verse_type) > 1:
+ verseIndex = \
+ VerseType.from_translated_string(verse_type)
+ if verseIndex is None:
+ verseIndex = VerseType.from_string(verse_type)
+ if verseIndex is None:
+ verseIndex = VerseType.from_tag(verse_type)
+ if verseIndex is None:
+ verseIndex = VerseType.Other
+ versetype = VerseType.TranslatedTags[verseIndex].upper()
+ verseTag = u'%s%s' % (versetype, verse[0][u'label'])
service_item.add_from_text(
verse[1][:30], unicode(verse[1]), verseTag)
else:
# Loop through the verse list and expand the song accordingly.
- for order in song.verse_order.upper().split():
+ for order in song.verse_order.lower().split():
if len(order) == 0:
break
for verse in verseList:
if verse[0][u'type'][0] == order[0] and \
(verse[0][u'label'] == order[1:] or not order[1:]):
- verseTag = u'%s:%s' % \
- (verse[0][u'type'], verse[0][u'label'])
+ verseindex = VerseType.from_tag(verse[0][u'type'])
+ versetype = VerseType.TranslatedTags[verseindex]\
+ .upper()
+ verseTag = u'%s%s' % (versetype,
+ verse[0][u'label'])
service_item.add_from_text(
verse[1][:30], verse[1], verseTag)
else:
=== modified file 'openlp/plugins/songs/lib/opensongimport.py'
--- openlp/plugins/songs/lib/opensongimport.py 2011-02-08 16:25:46 +0000
+++ openlp/plugins/songs/lib/opensongimport.py 2011-02-17 19:49:33 +0000
@@ -149,23 +149,25 @@
unicode(translate('SongsPlugin.ImportWizardForm',
'Importing %s...')) % parts[-1])
songfile = z.open(song)
- self.do_import_file(songfile)
- if self.commit:
+ if self.do_import_file(songfile) and self.commit and \
+ not self.stop_import_flag:
self.finish()
- if self.stop_import_flag:
- success = False
- break
+ else:
+ success = False
+ break
else:
# not a zipfile
log.info(u'Direct import %s', filename)
self.import_wizard.incrementProgressBar(
unicode(translate('SongsPlugin.ImportWizardForm',
'Importing %s...')) % os.path.split(filename)[-1])
- file = open(filename)
- self.do_import_file(file)
- if self.commit:
+ songfile = open(filename)
+ if self.do_import_file(songfile) and self.commit and \
+ not self.stop_import_flag:
self.finish()
-
+ else:
+ success = False
+ break
return success
def do_import_file(self, file):
@@ -178,7 +180,7 @@
tree = objectify.parse(file)
except (Error, LxmlError):
log.exception(u'Error parsing XML')
- return
+ return False
root = tree.getroot()
fields = dir(root)
decode = {
@@ -196,19 +198,22 @@
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:
self.topics.append(unicode(root.alttheme))
# data storage while importing
verses = {}
- # keep track of a "default" verse order, in case none is specified
+ # keep track of verses appearance order
our_verse_order = []
- verses_seen = {}
- # in the absence of any other indication, verses are the default,
- # erm, versetype!
- versetype = u'V'
- versenum = None
+ # default versetype
+ versetype = u'v'
+ versenum = u'1'
+ # for the case where song has several sections with same marker
+ inst = 1
lyrics = unicode(root.lyrics)
for thisline in lyrics.split(u'\n'):
# remove comments
@@ -216,17 +221,17 @@
if semicolon >= 0:
thisline = thisline[:semicolon]
thisline = thisline.strip()
- if len(thisline) == 0:
+ if not len(thisline):
continue
- # skip inthisline guitar chords and page and column breaks
- if thisline[0] == u'.' or thisline.startswith(u'---') \
+ # skip guitar chords and page and column breaks
+ if thisline.startswith(u'.') or thisline.startswith(u'---') \
or thisline.startswith(u'-!!'):
continue
# verse/chorus/etc. marker
- if thisline[0] == u'[':
+ if thisline.startswith(u'['):
# drop the square brackets
right_bracket = thisline.find(u']')
- content = thisline[1:right_bracket].upper()
+ content = thisline[1:right_bracket].lower()
# have we got any digits?
# If so, versenumber is everything from the digits
# to the end (even if there are some alpha chars on the end)
@@ -239,71 +244,57 @@
# the versetype
versetype = content
versenum = u'1'
+ inst = 1
+ if [versetype, versenum, inst] in our_verse_order \
+ and verses.has_key(versetype) \
+ and verses[versetype].has_key(versenum):
+ inst = len(verses[versetype][versenum])+1
+ our_verse_order.append([versetype, versenum, inst])
continue
- words = None
# number at start of line.. it's verse number
if thisline[0].isdigit():
versenum = thisline[0]
- words = thisline[1:].strip()
- if words is None:
- words = thisline
- if not versenum:
- versenum = u'1'
- if versenum is not None:
- versetag = u'%s%s' % (versetype, versenum)
- if not verses.has_key(versetype):
- verses[versetype] = {}
- if not verses[versetype].has_key(versenum):
- # storage for lines in this verse
- verses[versetype][versenum] = []
- if not verses_seen.has_key(versetag):
- verses_seen[versetag] = 1
- our_verse_order.append(versetag)
- if words:
- # Tidy text and remove the ____s from extended words
- words = self.tidy_text(words)
- words = words.replace('_', '')
- verses[versetype][versenum].append(words)
+ thisline = thisline[1:].strip()
+ our_verse_order.append([versetype, versenum, inst])
+ if not verses.has_key(versetype):
+ verses[versetype] = {}
+ if not verses[versetype].has_key(versenum):
+ verses[versetype][versenum] = {}
+ if not verses[versetype][versenum].has_key(inst):
+ verses[versetype][versenum][inst] = []
+ # Tidy text and remove the ____s from extended words
+ thisline = self.tidy_text(thisline)
+ thisline = thisline.replace(u'_', u'')
+ thisline = thisline.replace(u'|', u'\n')
+ verses[versetype][versenum][inst].append(thisline)
# done parsing
- versetypes = verses.keys()
- versetypes.sort()
- versetags = {}
- for versetype in versetypes:
- our_verse_type = versetype
- if our_verse_type == u'':
- our_verse_type = u'V'
- versenums = verses[versetype].keys()
- versenums.sort()
- for num in versenums:
- versetag = u'%s%s' % (our_verse_type, num)
- lines = u'\n'.join(verses[versetype][num])
- self.add_verse(lines, versetag)
- # Keep track of what we have for error checking later
- versetags[versetag] = 1
- # now figure out the presentation order
- order = []
+ # add verses in original order
+ for (versetype, versenum, inst) in our_verse_order:
+ vtag = u'%s%s' % (versetype, versenum)
+ lines = u'\n'.join(verses[versetype][versenum][inst])
+ self.add_verse(lines, vtag)
+ # figure out the presentation order, if present
if u'presentation' in fields and root.presentation != u'':
order = unicode(root.presentation)
- # We make all the tags in the lyrics upper case, so match that here
+ # We make all the tags in the lyrics lower case, so match that here
# and then split into a list on the whitespace
- order = order.upper().split()
- else:
- if len(our_verse_order) > 0:
- order = our_verse_order
- else:
- log.warn(u'No verse order available for %s, skipping.',
- self.title)
- # TODO: make sure that the default order list will be overwritten, if
- # the songs provides its own order list.
- for tag in order:
- if tag[0].isdigit():
- # Assume it's a verse if it has no prefix
- tag = u'V' + tag
- elif not re.search('\d+', tag):
- # Assume it's no.1 if there's no digits
- tag = tag + u'1'
- if not versetags.has_key(tag):
- log.info(u'Got order %s but not in versetags, dropping this'
- u'item from presentation order', tag)
- else:
- self.verse_order_list.append(tag)
+ order = order.lower().split()
+ for tag in order:
+ match = re.match(u'(.*)(\d+.*)', tag)
+ if match is not None:
+ versetype = match.group(1)
+ versenum = match.group(2)
+ if not len(versetype):
+ versetype = u'v'
+ else:
+ # Assume it's no.1 if there are no digits
+ versetype = tag
+ versenum = u'1'
+ vtagString = u'%s%s' % (versetype, versenum)
+ if verses.has_key(versetype) \
+ and verses[versetype].has_key(versenum):
+ self.verse_order_list.append(vtagString)
+ else:
+ log.info(u'Got order %s but not in versetags, dropping'
+ u'this item from presentation order', vtagString)
+ return True
=== modified file 'openlp/plugins/songs/lib/songimport.py'
--- openlp/plugins/songs/lib/songimport.py 2011-02-10 05:25:08 +0000
+++ openlp/plugins/songs/lib/songimport.py 2011-02-17 19:49:33 +0000
@@ -75,6 +75,8 @@
self.media_files = []
self.song_book_name = u''
self.song_book_pub = u''
+ self.verse_order_list_generated_useful = False
+ self.verse_order_list_generated = []
self.verse_order_list = []
self.verses = []
self.versecounts = {}
@@ -136,12 +138,12 @@
def process_verse_text(self, text):
lines = text.split(u'\n')
if text.lower().find(self.copyright_string) >= 0 \
- or text.lower().find(self.copyright_symbol) >= 0:
+ or text.find(self.copyright_symbol) >= 0:
copyright_found = False
for line in lines:
if (copyright_found or
line.lower().find(self.copyright_string) >= 0 or
- line.lower().find(self.copyright_symbol) >= 0):
+ line.find(self.copyright_symbol) >= 0):
copyright_found = True
self.add_copyright(line)
else:
@@ -198,7 +200,7 @@
return
self.media_files.append(filename)
- def add_verse(self, versetext, versetag=u'V', lang=None):
+ def add_verse(self, versetext, versetag=u'v', lang=None):
"""
Add a verse. This is the whole verse, lines split by \\n. It will also
attempt to detect duplicates. In this case it will just add to the verse
@@ -217,7 +219,9 @@
"""
for (oldversetag, oldverse, oldlang) in self.verses:
if oldverse.strip() == versetext.strip():
- self.verse_order_list.append(oldversetag)
+ # this verse is already present
+ self.verse_order_list_generated.append(oldversetag)
+ self.verse_order_list_generated_useful = True
return
if versetag[0] in self.versecounts:
self.versecounts[versetag[0]] += 1
@@ -228,15 +232,15 @@
elif int(versetag[1:]) > self.versecounts[versetag[0]]:
self.versecounts[versetag[0]] = int(versetag[1:])
self.verses.append([versetag, versetext.rstrip(), lang])
- self.verse_order_list.append(versetag)
- if versetag.startswith(u'V') and u'C1' in self.verse_order_list:
- self.verse_order_list.append(u'C1')
+ self.verse_order_list_generated.append(versetag)
def repeat_verse(self):
"""
Repeat the previous verse in the verse order
"""
- self.verse_order_list.append(self.verse_order_list[-1])
+ self.verse_order_list_generated.append(
+ self.verse_order_list_generated[-1])
+ self.verse_order_list_generated_useful = True
def check_complete(self):
"""
@@ -274,29 +278,23 @@
sxml = SongXML()
other_count = 1
for (versetag, versetext, lang) in self.verses:
- if versetag[0] == u'C':
- versetype = VerseType.to_string(VerseType.Chorus)
- elif versetag[0] == u'V':
- versetype = VerseType.to_string(VerseType.Verse)
- elif versetag[0] == u'B':
- versetype = VerseType.to_string(VerseType.Bridge)
- elif versetag[0] == u'I':
- versetype = VerseType.to_string(VerseType.Intro)
- elif versetag[0] == u'P':
- versetype = VerseType.to_string(VerseType.PreChorus)
- elif versetag[0] == u'E':
- versetype = VerseType.to_string(VerseType.Ending)
+ if versetag[0].lower() in VerseType.Tags:
+ versetype = versetag[0].lower()
else:
- newversetag = u'O%d' % other_count
+ newversetag = u'%s%d' % (VerseType.Tags[VerseType.Other],
+ other_count)
verses_changed_to_other[versetag] = newversetag
other_count += 1
- versetype = VerseType.to_string(VerseType.Other)
+ versetype = VerseType.Tags[VerseType.Other]
log.info(u'Versetype %s changing to %s' , versetag, newversetag)
versetag = newversetag
sxml.add_verse_to_lyrics(versetype, versetag[1:], versetext, lang)
song.search_lyrics += u' ' + self.remove_punctuation(versetext)
song.search_lyrics = song.search_lyrics.lower()
song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
+ if not len(self.verse_order_list) and \
+ self.verse_order_list_generated_useful:
+ self.verse_order_list = self.verse_order_list_generated
for i, current_verse_tag in enumerate(self.verse_order_list):
if verses_changed_to_other.has_key(current_verse_tag):
self.verse_order_list[i] = \
@@ -348,6 +346,7 @@
for (versetag, versetext, lang) in self.verses:
print u'VERSE ' + versetag + u': ' + versetext
print u'ORDER: ' + u' '.join(self.verse_order_list)
+ print u'GENERATED ORDER: ' + u' '.join(self.verse_order_list_generated)
for author in self.authors:
print u'AUTHOR: ' + author
if self.copyright:
=== modified file 'openlp/plugins/songs/lib/xml.py'
--- openlp/plugins/songs/lib/xml.py 2011-02-10 17:42:13 +0000
+++ openlp/plugins/songs/lib/xml.py 2011-02-17 19:49:33 +0000
@@ -464,7 +464,10 @@
text += u'\n'
text += u'\n'.join([unicode(line) for line in lines.line])
verse_name = self._get(verse, u'name')
- verse_type = unicode(VerseType.to_string(verse_name[0]))
+ verse_type_index = VerseType.from_tag(verse_name[0])
+ if verse_type_index is None:
+ verse_type_index = VerseType.Other
+ verse_type = VerseType.Names[verse_type_index]
verse_number = re.compile(u'[a-zA-Z]*').sub(u'', verse_name)
verse_part = re.compile(u'[0-9]*').sub(u'', verse_name[1:])
# OpenLyrics allows e. g. "c", but we need "c1".
Follow ups