fixed same short lines

This commit is contained in:
Andreas Preikschat 2013-02-24 19:13:50 +01:00
parent 3b9fe00e0a
commit 31f28a7570
16 changed files with 216 additions and 270 deletions

View File

@ -404,19 +404,19 @@ class SlideController(DisplayController):
verse_type = sender_name[15:] if sender_name[:15] == u'shortcutAction_' else u''
if SONGS_PLUGIN_AVAILABLE:
if verse_type == u'V':
self.current_shortcut = VerseType.TranslatedTags[VerseType.Verse]
self.current_shortcut = VerseType.translated_tags[VerseType.Verse]
elif verse_type == u'C':
self.current_shortcut = VerseType.TranslatedTags[VerseType.Chorus]
self.current_shortcut = VerseType.translated_tags[VerseType.Chorus]
elif verse_type == u'B':
self.current_shortcut = VerseType.TranslatedTags[VerseType.Bridge]
self.current_shortcut = VerseType.translated_tags[VerseType.Bridge]
elif verse_type == u'P':
self.current_shortcut = VerseType.TranslatedTags[VerseType.PreChorus]
self.current_shortcut = VerseType.translated_tags[VerseType.PreChorus]
elif verse_type == u'I':
self.current_shortcut = VerseType.TranslatedTags[VerseType.Intro]
self.current_shortcut = VerseType.translated_tags[VerseType.Intro]
elif verse_type == u'E':
self.current_shortcut = VerseType.TranslatedTags[VerseType.Ending]
self.current_shortcut = VerseType.translated_tags[VerseType.Ending]
elif verse_type == u'O':
self.current_shortcut = VerseType.TranslatedTags[VerseType.Other]
self.current_shortcut = VerseType.translated_tags[VerseType.Other]
elif verse_type.isnumeric():
self.current_shortcut += verse_type
self.current_shortcut = self.current_shortcut.upper()

View File

@ -291,7 +291,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
verse_tags_translated = True
if index is None:
index = VerseType.from_tag(verse_tag)
verse[0][u'type'] = VerseType.Tags[index]
verse[0][u'type'] = VerseType.tags[index]
if verse[0][u'label'] == u'':
verse[0][u'label'] = u'1'
verse_def = u'%s%s' % (verse[0][u'type'], verse[0][u'label'])
@ -303,7 +303,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
for count, verse in enumerate(verses):
self.verseListWidget.setRowCount(self.verseListWidget.rowCount() + 1)
item = QtGui.QTableWidgetItem(verse)
verse_def = u'%s%s' % (VerseType.Tags[VerseType.Verse], unicode(count + 1))
verse_def = u'%s%s' % (VerseType.tags[VerseType.Verse], unicode(count + 1))
item.setData(QtCore.Qt.UserRole, verse_def)
self.verseListWidget.setItem(count, 0, item)
if self.song.verse_order:
@ -315,7 +315,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
verse_index = VerseType.from_translated_tag(verse_def[0], None)
if verse_index is None:
verse_index = VerseType.from_tag(verse_def[0])
verse_tag = VerseType.TranslatedTags[verse_index].upper()
verse_tag = VerseType.translated_tags[verse_index].upper()
translated.append(u'%s%s' % (verse_tag, verse_def[1:]))
self.verseOrderEdit.setText(u' '.join(translated))
else:
@ -547,7 +547,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
verse_name = parts
verse_num = u'1'
verse_index = VerseType.from_loose_input(verse_name)
verse_tag = VerseType.Tags[verse_index]
verse_tag = VerseType.tags[verse_index]
# Later we need to handle v1a as well.
#regex = re.compile(r'(\d+\w.)')
regex = re.compile(r'\D*(\d+)\D*')
@ -599,7 +599,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
if len(item) == 1:
verse_index = VerseType.from_translated_tag(item, None)
if verse_index is not None:
order.append(VerseType.Tags[verse_index] + u'1')
order.append(VerseType.tags[verse_index] + u'1')
else:
# it matches no verses anyway
order.append(u'')
@ -609,7 +609,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
# it matches no verses anyway
order.append(u'')
else:
verse_tag = VerseType.Tags[verse_index]
verse_tag = VerseType.tags[verse_index]
verse_num = item[1:].lower()
order.append(verse_tag + verse_num)
return order
@ -831,7 +831,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
ordertext = self.verseOrderEdit.text()
order = []
for item in ordertext.split():
verse_tag = VerseType.Tags[VerseType.from_translated_tag(item[0])]
verse_tag = VerseType.tags[VerseType.from_translated_tag(item[0])]
verse_num = item[1:].lower()
order.append(u'%s%s' % (verse_tag, verse_num))
self.song.verse_order = u' '.join(order)

View File

@ -74,13 +74,13 @@ class Ui_EditVerseDialog(object):
def retranslateUi(self, editVerseDialog):
editVerseDialog.setWindowTitle(translate('SongsPlugin.EditVerseForm', 'Edit Verse'))
self.verseTypeLabel.setText(translate('SongsPlugin.EditVerseForm', '&Verse type:'))
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.verseTypeComboBox.setItemText(VerseType.Verse, VerseType.translated_names[VerseType.Verse])
self.verseTypeComboBox.setItemText(VerseType.Chorus, VerseType.translated_names[VerseType.Chorus])
self.verseTypeComboBox.setItemText(VerseType.Bridge, VerseType.translated_names[VerseType.Bridge])
self.verseTypeComboBox.setItemText(VerseType.PreChorus, VerseType.translated_names[VerseType.PreChorus])
self.verseTypeComboBox.setItemText(VerseType.Intro, VerseType.translated_names[VerseType.Intro])
self.verseTypeComboBox.setItemText(VerseType.Ending, VerseType.translated_names[VerseType.Ending])
self.verseTypeComboBox.setItemText(VerseType.Other, VerseType.translated_names[VerseType.Other])
self.splitButton.setText(UiStrings().Split)
self.splitButton.setToolTip(UiStrings().SplitToolTip)
self.insertButton.setText(translate('SongsPlugin.EditVerseForm', '&Insert'))

View File

@ -82,8 +82,7 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
def onInsertButtonClicked(self):
verse_type_index = self.verseTypeComboBox.currentIndex()
self.insertVerse(VerseType.Tags[verse_type_index],
self.verseNumberBox.value())
self.insertVerse(VerseType.tags[verse_type_index], self.verseNumberBox.value())
def onVerseTypeComboBoxChanged(self):
self.updateSuggestedVerseNumber()
@ -93,12 +92,11 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
def updateSuggestedVerseNumber(self):
"""
Adjusts the verse number SpinBox in regard to the selected verse type
and the cursor's position.
Adjusts the verse number SpinBox in regard to the selected verse type and the cursor's position.
"""
position = self.verseTextEdit.textCursor().position()
text = self.verseTextEdit.toPlainText()
verse_name = VerseType.TranslatedNames[
verse_name = VerseType.translated_names[
self.verseTypeComboBox.currentIndex()]
if not text:
return
@ -120,8 +118,7 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
verse_num = 1
self.verseNumberBox.setValue(verse_num)
def setVerse(self, text, single=False,
tag=u'%s1' % VerseType.Tags[VerseType.Verse]):
def setVerse(self, text, single=False, tag=u'%s1' % VerseType.tags[VerseType.Verse]):
self.hasSingleVerse = single
if single:
verse_type_index = VerseType.from_tag(tag[0], None)
@ -132,7 +129,7 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
self.insertButton.setVisible(False)
else:
if not text:
text = u'---[%s:1]---\n' % VerseType.TranslatedNames[VerseType.Verse]
text = u'---[%s:1]---\n' % VerseType.translated_names[VerseType.Verse]
self.verseTypeComboBox.setCurrentIndex(0)
self.verseNumberBox.setValue(1)
self.insertButton.setVisible(True)
@ -141,12 +138,12 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
self.verseTextEdit.moveCursor(QtGui.QTextCursor.End)
def getVerse(self):
return self.verseTextEdit.toPlainText(), VerseType.Tags[self.verseTypeComboBox.currentIndex()], \
return self.verseTextEdit.toPlainText(), 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.TranslatedNames[VerseType.Verse], text)
text = u'---[%s:1]---\n%s' % (VerseType.translated_names[VerseType.Verse], text)
return text

View File

@ -37,8 +37,7 @@ from ui import SongStrings
WHITESPACE = re.compile(r'[\W_]+', re.UNICODE)
APOSTROPHE = re.compile(u'[\'`ʻ]', re.UNICODE)
PATTERN = re.compile(r"\\([a-z]{1,32})(-?\d{1,10})?[ ]?|\\'"
r"([0-9a-f]{2})|\\([^a-z])|([{}])|[\r\n]+|(.)", re.I)
PATTERN = re.compile(r"\\([a-z]{1,32})(-?\d{1,10})?[ ]?|\\'([0-9a-f]{2})|\\([^a-z])|([{}])|[\r\n]+|(.)", re.I)
# RTF control words which specify a "destination" to be ignored.
DESTINATIONS = frozenset((
u'aftncn', u'aftnsep', u'aftnsepc', u'annotation', u'atnauthor',
@ -138,8 +137,7 @@ CHARSET_MAPPING = {
class VerseType(object):
"""
VerseType provides an enumeration for the tags that may be associated
with verses in songs.
VerseType provides an enumeration for the tags that may be associated with verses in songs.
"""
Verse = 0
Chorus = 1
@ -149,7 +147,7 @@ class VerseType(object):
Ending = 5
Other = 6
Names = [
names = [
u'Verse',
u'Chorus',
u'Bridge',
@ -157,9 +155,9 @@ class VerseType(object):
u'Intro',
u'Ending',
u'Other']
Tags = [name[0].lower() for name in Names]
tags = [name[0].lower() for name in names]
TranslatedNames = [
translated_names = [
translate('SongsPlugin.VerseType', 'Verse'),
translate('SongsPlugin.VerseType', 'Chorus'),
translate('SongsPlugin.VerseType', 'Bridge'),
@ -167,13 +165,12 @@ class VerseType(object):
translate('SongsPlugin.VerseType', 'Intro'),
translate('SongsPlugin.VerseType', 'Ending'),
translate('SongsPlugin.VerseType', 'Other')]
TranslatedTags = [name[0].lower() for name in TranslatedNames]
tanslated_tags = [name[0].lower() for name in translated_names]
@staticmethod
def translated_tag(verse_tag, default=Other):
"""
Return the translated UPPERCASE tag for a given tag,
used to show translated verse tags in UI
Return the translated UPPERCASE tag for a given tag, used to show translated verse tags in UI
``verse_tag``
The string to return a VerseType for
@ -182,11 +179,11 @@ class VerseType(object):
Default return value if no matching tag is found
"""
verse_tag = verse_tag[0].lower()
for num, tag in enumerate(VerseType.Tags):
for num, tag in enumerate(VerseType.tags):
if verse_tag == tag:
return VerseType.TranslatedTags[num].upper()
if default in VerseType.TranslatedTags:
return VerseType.TranslatedTags[default].upper()
return VerseType.tanslated_tags[num].upper()
if default in VerseType.tanslated_tags:
return VerseType.tanslated_tags[default].upper()
@staticmethod
def translated_name(verse_tag, default=Other):
@ -200,11 +197,11 @@ class VerseType(object):
Default return value if no matching tag is found
"""
verse_tag = verse_tag[0].lower()
for num, tag in enumerate(VerseType.Tags):
for num, tag in enumerate(VerseType.tags):
if verse_tag == tag:
return VerseType.TranslatedNames[num]
if default in VerseType.TranslatedNames:
return VerseType.TranslatedNames[default]
return VerseType.translated_names[num]
if default in VerseType.translated_names:
return VerseType.translated_names[default]
@staticmethod
def from_tag(verse_tag, default=Other):
@ -218,7 +215,7 @@ class VerseType(object):
Default return value if no matching tag is found
"""
verse_tag = verse_tag[0].lower()
for num, tag in enumerate(VerseType.Tags):
for num, tag in enumerate(VerseType.tags):
if verse_tag == tag:
return num
return default
@ -235,7 +232,7 @@ class VerseType(object):
Default return value if no matching tag is found
"""
verse_tag = verse_tag[0].lower()
for num, tag in enumerate(VerseType.TranslatedTags):
for num, tag in enumerate(VerseType.translated_tags):
if verse_tag == tag:
return num
return default
@ -252,7 +249,7 @@ class VerseType(object):
Default return value if no matching tag is found
"""
verse_name = verse_name.lower()
for num, name in enumerate(VerseType.Names):
for num, name in enumerate(VerseType.names):
if verse_name == name.lower():
return num
return default
@ -266,7 +263,7 @@ class VerseType(object):
The string to return a VerseType for
"""
verse_name = verse_name.lower()
for num, translation in enumerate(VerseType.TranslatedNames):
for num, translation in enumerate(VerseType.translated_names):
if verse_name == translation.lower():
return num
@ -296,13 +293,11 @@ class VerseType(object):
def retrieve_windows_encoding(recommendation=None):
"""
Determines which encoding to use on an information source. The process uses
both automated detection, which is passed to this method as a
recommendation, and user confirmation to return an encoding.
Determines which encoding to use on an information source. The process uses both automated detection, which is
passed to this method as a recommendation, and user confirmation to return an encoding.
``recommendation``
A recommended encoding discovered programmatically for the user to
confirm.
A recommended encoding discovered programmatically for the user to confirm.
"""
# map chardet result to compatible windows standard code page
codepage_mapping = {'IBM866': u'cp866', 'TIS-620': u'cp874',
@ -355,24 +350,22 @@ def retrieve_windows_encoding(recommendation=None):
def clean_string(string):
"""
Strips punctuation from the passed string to assist searching
Strips punctuation from the passed string to assist searching.
"""
return WHITESPACE.sub(u' ', APOSTROPHE.sub(u'', string)).lower()
def clean_title(title):
"""
Cleans the song title by removing Unicode control chars groups C0 & C1,
as well as any trailing spaces
Cleans the song title by removing Unicode control chars groups C0 & C1, as well as any trailing spaces.
"""
return CONTROL_CHARS.sub(u'', title).rstrip()
def clean_song(manager, song):
"""
Cleans the search title, rebuilds the search lyrics, adds a default author
if the song does not have one and other clean ups. This should always
called when a new song is added or changed.
Cleans the search title, rebuilds the search lyrics, adds a default author if the song does not have one and other
clean ups. This should always called when a new song is added or changed.
``manager``
The song's manager.
@ -397,21 +390,20 @@ def clean_song(manager, song):
song.search_title = clean_string(song.title) + u'@' + clean_string(song.alternate_title)
# Only do this, if we the song is a 1.9.4 song (or older).
if song.lyrics.find(u'<lyrics language="en">') != -1:
# Remove the old "language" attribute from lyrics tag (prior to 1.9.5).
# This is not very important, but this keeps the database clean. This
# can be removed when everybody has cleaned his songs.
# Remove the old "language" attribute from lyrics tag (prior to 1.9.5). This is not very important, but this
# keeps the database clean. This can be removed when everybody has cleaned his songs.
song.lyrics = song.lyrics.replace(u'<lyrics language="en">', u'<lyrics>')
verses = SongXML().get_verses(song.lyrics)
song.search_lyrics = u' '.join([clean_string(verse[1])
for verse in verses])
# We need a new and clean SongXML instance.
sxml = SongXML()
# Rebuild the song's verses, to remove any wrong verse names (for
# example translated ones), which might have been added prior to 1.9.5.
# Rebuild the song's verses, to remove any wrong verse names (for example translated ones), which might have
# been added prior to 1.9.5.
# List for later comparison.
compare_order = []
for verse in verses:
verse_type = VerseType.Tags[VerseType.from_loose_input(verse[0][u'type'])]
verse_type = VerseType.tags[VerseType.from_loose_input(verse[0][u'type'])]
sxml.add_verse_to_lyrics(
verse_type,
verse[0][u'label'],
@ -422,15 +414,14 @@ def clean_song(manager, song):
if verse[0][u'label'] == u'1':
compare_order.append(verse_type.upper())
song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
# Rebuild the verse order, to convert translated verse tags, which might
# have been added prior to 1.9.5.
# Rebuild the verse order, to convert translated verse tags, which might have been added prior to 1.9.5.
if song.verse_order:
order = CONTROL_CHARS.sub(u'', song.verse_order).strip().split()
else:
order = []
new_order = []
for verse_def in order:
verse_type = VerseType.Tags[
verse_type = VerseType.tags[
VerseType.from_loose_input(verse_def[0])]
if len(verse_def) > 1:
new_order.append((u'%s%s' % (verse_type, verse_def[1:])).upper())
@ -463,16 +454,16 @@ def get_encoding(font, font_table, default_encoding, failed=False):
Finds an encoding to use. Asks user, if necessary.
``font``
The number of currently active font.
The number of currently active font.
``font_table``
Dictionary of fonts and respective encodings.
Dictionary of fonts and respective encodings.
``default_encoding``
The default encoding to use when font_table is empty or no font is used.
The default encoding to use when font_table is empty or no font is used.
``failed``
A boolean indicating whether the previous encoding didn't work.
A boolean indicating whether the previous encoding didn't work.
"""
encoding = None
if font in font_table:
@ -494,10 +485,10 @@ def strip_rtf(text, default_encoding=None):
http://stackoverflow.com/questions/188545
``text``
RTF-encoded text, a string.
RTF-encoded text, a string.
``default_encoding``
Default encoding to use when no encoding is specified.
Default encoding to use when no encoding is specified.
"""
# Current font is the font tag we last met.
font = u''
@ -589,8 +580,7 @@ def strip_rtf(text, default_encoding=None):
def natcmp(a, b):
"""
Natural string comparison which mimics the behaviour of Python's internal
cmp function.
Natural string comparison which mimics the behaviour of Python's internal cmp function.
"""
if len(a) <= len(b):
for i, key in enumerate(a):

View File

@ -188,13 +188,13 @@ class CCLIFileImport(SongImport):
words_list = song_words.split(u'/t')
for counter in range(len(field_list)):
if field_list[counter].startswith(u'Ver'):
verse_type = VerseType.Tags[VerseType.Verse]
verse_type = VerseType.tags[VerseType.Verse]
elif field_list[counter].startswith(u'Ch'):
verse_type = VerseType.Tags[VerseType.Chorus]
verse_type = VerseType.tags[VerseType.Chorus]
elif field_list[counter].startswith(u'Br'):
verse_type = VerseType.Tags[VerseType.Bridge]
verse_type = VerseType.tags[VerseType.Bridge]
else:
verse_type = VerseType.Tags[VerseType.Other]
verse_type = VerseType.tags[VerseType.Other]
check_first_verse_line = True
verse_text = unicode(words_list[counter])
verse_text = verse_text.replace(u'/n', u'\n')
@ -202,15 +202,15 @@ class CCLIFileImport(SongImport):
verse_lines = verse_text.split(u'\n', 1)
if check_first_verse_line:
if verse_lines[0].startswith(u'(PRE-CHORUS'):
verse_type = VerseType.Tags[VerseType.PreChorus]
verse_type = VerseType.tags[VerseType.PreChorus]
log.debug(u'USR verse PRE-CHORUS: %s', verse_lines[0])
verse_text = verse_lines[1]
elif verse_lines[0].startswith(u'(BRIDGE'):
verse_type = VerseType.Tags[VerseType.Bridge]
verse_type = VerseType.tags[VerseType.Bridge]
log.debug(u'USR verse BRIDGE')
verse_text = verse_lines[1]
elif verse_lines[0].startswith(u'('):
verse_type = VerseType.Tags[VerseType.Other]
verse_type = VerseType.tags[VerseType.Other]
verse_text = verse_lines[1]
if verse_text:
self.addVerse(verse_text, verse_type)
@ -292,31 +292,31 @@ class CCLIFileImport(SongImport):
verse_desc_parts = clean_line.split(u' ')
if len(verse_desc_parts) == 2:
if verse_desc_parts[0].startswith(u'Ver'):
verse_type = VerseType.Tags[VerseType.Verse]
verse_type = VerseType.tags[VerseType.Verse]
elif verse_desc_parts[0].startswith(u'Ch'):
verse_type = VerseType.Tags[VerseType.Chorus]
verse_type = VerseType.tags[VerseType.Chorus]
elif verse_desc_parts[0].startswith(u'Br'):
verse_type = VerseType.Tags[VerseType.Bridge]
verse_type = VerseType.tags[VerseType.Bridge]
else:
# we need to analyse the next line for
# verse type, so set flag
verse_type = VerseType.Tags[VerseType.Other]
verse_type = VerseType.tags[VerseType.Other]
check_first_verse_line = True
verse_number = verse_desc_parts[1]
else:
verse_type = VerseType.Tags[VerseType.Other]
verse_type = VerseType.tags[VerseType.Other]
verse_number = 1
verse_start = True
else:
# check first line for verse type
if check_first_verse_line:
if line.startswith(u'(PRE-CHORUS'):
verse_type = VerseType.Tags[VerseType.PreChorus]
verse_type = VerseType.tags[VerseType.PreChorus]
elif line.startswith(u'(BRIDGE'):
verse_type = VerseType.Tags[VerseType.Bridge]
verse_type = VerseType.tags[VerseType.Bridge]
# Handle all other misc types
elif line.startswith(u'('):
verse_type = VerseType.Tags[VerseType.Other]
verse_type = VerseType.tags[VerseType.Other]
else:
verse_text = verse_text + line
check_first_verse_line = False

View File

@ -175,12 +175,12 @@ class EasySlidesImport(SongImport):
# if the regions are inside verses
regionsInVerses = (regions and regionlines[regionlines.keys()[0]] > 1)
MarkTypes = {
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]
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]

View File

@ -178,7 +178,7 @@ class EasyWorshipSongImport(SongImport):
if result is None:
return
words, self.encoding = result
verse_type = VerseType.Tags[VerseType.Verse]
verse_type = VerseType.tags[VerseType.Verse]
for verse in SLIDE_BREAK_REGEX.split(words):
verse = verse.strip()
if not verse:
@ -187,17 +187,17 @@ class EasyWorshipSongImport(SongImport):
first_line_is_tag = False
# EW tags: verse, chorus, pre-chorus, bridge, tag,
# intro, ending, slide
for type in VerseType.Names+[u'tag', u'slide']:
type = type.lower()
for tag in VerseType.tags + [u'tag', u'slide']:
tag = tag.lower()
ew_tag = verse_split[0].strip().lower()
if ew_tag.startswith(type):
verse_type = type[0]
if type == u'tag' or type == u'slide':
verse_type = VerseType.Tags[VerseType.Other]
if ew_tag.startswith(tag):
verse_type = tag[0]
if tag == u'tag' or tag == u'slide':
verse_type = VerseType.tags[VerseType.Other]
first_line_is_tag = True
number_found = False
# check if tag is followed by number and/or note
if len(ew_tag) > len(type):
if len(ew_tag) > len(tag):
match = NUMBER_REGEX.search(ew_tag)
if match:
number = match.group()
@ -209,10 +209,7 @@ class EasyWorshipSongImport(SongImport):
if not number_found:
verse_type += u'1'
break
self.addVerse(
verse_split[-1].strip() \
if first_line_is_tag else verse,
verse_type)
self.addVerse(verse_split[-1].strip() if first_line_is_tag else verse, verse_type)
if len(self.comments) > 5:
self.comments += unicode(translate('SongsPlugin.EasyWorshipSongImport',
'\n[above are Song Tags with notes imported from EasyWorship]'))
@ -224,8 +221,7 @@ class EasyWorshipSongImport(SongImport):
self.memoFile.close()
def findField(self, field_name):
return [i for i, x in enumerate(self.fieldDescs)
if x.name == field_name][0]
return [i for i, x in enumerate(self.fieldDescs) if x.name == field_name][0]
def setRecordStruct(self, field_descs):
# Begin with empty field struct list

View File

@ -412,13 +412,13 @@ class FoilPresenter(object):
temp_sortnr_backup = 1
temp_sortnr_liste = []
verse_count = {
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
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_) if hasattr(strophe, u'text_') else u''
@ -438,25 +438,25 @@ class FoilPresenter(object):
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 = VerseType.Tags[VerseType.Chorus]
verse_type = VerseType.tags[VerseType.Chorus]
elif temp_verse_name == u'r':
verse_type = VerseType.Tags[VerseType.Chorus]
verse_type = VerseType.tags[VerseType.Chorus]
elif temp_verse_name == u'':
verse_type = VerseType.Tags[VerseType.Verse]
verse_type = VerseType.tags[VerseType.Verse]
elif temp_verse_name == u'v':
verse_type = VerseType.Tags[VerseType.Verse]
verse_type = VerseType.tags[VerseType.Verse]
elif temp_verse_name == u'bri':
verse_type = VerseType.Tags[VerseType.Bridge]
verse_type = VerseType.tags[VerseType.Bridge]
elif temp_verse_name == u'cod':
verse_type = VerseType.Tags[VerseType.Ending]
verse_type = VerseType.tags[VerseType.Ending]
elif temp_verse_name == u'sch':
verse_type = VerseType.Tags[VerseType.Ending]
verse_type = VerseType.tags[VerseType.Ending]
elif temp_verse_name == u'pre':
verse_type = VerseType.Tags[VerseType.PreChorus]
verse_type = VerseType.tags[VerseType.PreChorus]
elif temp_verse_name == u'int':
verse_type = VerseType.Tags[VerseType.Intro]
verse_type = VerseType.tags[VerseType.Intro]
else:
verse_type = VerseType.Tags[VerseType.Other]
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:
@ -469,7 +469,7 @@ class FoilPresenter(object):
if value == u''.join((verse_type, verse_number)):
verse_number = unicode(int(verse_number) + 1)
verse_type_index = VerseType.from_tag(verse_type[0])
verse_type = VerseType.Names[verse_type_index]
verse_type = VerseType.tags[verse_type_index]
temp_verse_order[verse_sortnr] = u''.join((verse_type[0],
verse_number))
temp_verse_order_backup.append(u''.join((verse_type[0],

View File

@ -430,7 +430,7 @@ class SongMediaItem(MediaManagerItem):
verse_index = VerseType.from_string(verse_tag, None)
if verse_index is None:
verse_index = VerseType.from_tag(verse_tag)
verse_tag = VerseType.TranslatedTags[verse_index].upper()
verse_tag = VerseType.translated_tags[verse_index].upper()
verse_def = u'%s%s' % (verse_tag, verse[0][u'label'])
service_item.add_from_text(unicode(verse[1]), verse_def)
else:
@ -445,7 +445,7 @@ class SongMediaItem(MediaManagerItem):
verse_index = VerseType.from_translated_tag(verse[0][u'type'])
else:
verse_index = VerseType.from_tag(verse[0][u'type'])
verse_tag = VerseType.TranslatedTags[verse_index]
verse_tag = VerseType.translated_tags[verse_index]
verse_def = u'%s%s' % (verse_tag, verse[0][u'label'])
service_item.add_from_text(verse[1], verse_def)
else:

View File

@ -160,7 +160,7 @@ class OpenSongImport(SongImport):
# keep track of verses appearance order
our_verse_order = []
# default verse
verse_tag = VerseType.Tags[VerseType.Verse]
verse_tag = VerseType.tags[VerseType.Verse]
verse_num = u'1'
# for the case where song has several sections with same marker
inst = 1
@ -184,21 +184,18 @@ class OpenSongImport(SongImport):
# drop the square brackets
right_bracket = this_line.find(u']')
content = this_line[1:right_bracket].lower()
# have we got any digits?
# If so, verse number is everything from the digits
# to the end (openlp does not have concept of part verses, so
# just ignore any non integers on the end (including floats))
# have we got any digits? If so, verse number is everything from the digits to the end (openlp does not
# have concept of part verses, so just ignore any non integers on the end (including floats))
match = re.match(u'(\D*)(\d+)', content)
if match is not None:
verse_tag = match.group(1)
verse_num = match.group(2)
else:
# otherwise we assume number 1 and take the whole prefix as
# the verse tag
# otherwise we assume number 1 and take the whole prefix as the verse tag
verse_tag = content
verse_num = u'1'
verse_index = VerseType.from_loose_input(verse_tag) if verse_tag else 0
verse_tag = VerseType.Tags[verse_index]
verse_tag = VerseType.tags[verse_index]
inst = 1
if [verse_tag, verse_num, inst] in our_verse_order and verse_num in verses.get(verse_tag, {}):
inst = len(verses[verse_tag][verse_num]) + 1
@ -236,8 +233,8 @@ class OpenSongImport(SongImport):
# figure out the presentation order, if present
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
# 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.lower().split()
for verse_def in order:
match = re.match(u'(\D*)(\d+.*)', verse_def)
@ -245,7 +242,7 @@ class OpenSongImport(SongImport):
verse_tag = match.group(1)
verse_num = match.group(2)
if not verse_tag:
verse_tag = VerseType.Tags[VerseType.Verse]
verse_tag = VerseType.tags[VerseType.Verse]
else:
# Assume it's no.1 if there are no digits
verse_tag = verse_def

View File

@ -27,8 +27,7 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
"""
The :mod:`songbeamerimport` module provides the functionality for importing
SongBeamer songs into the OpenLP database.
The :mod:`songbeamerimport` module provides the functionality for importing SongBeamer songs into the OpenLP database.
"""
import chardet
import codecs
@ -43,32 +42,31 @@ log = logging.getLogger(__name__)
class SongBeamerTypes(object):
MarkTypes = {
u'Refrain': VerseType.Tags[VerseType.Chorus],
u'Chorus': VerseType.Tags[VerseType.Chorus],
u'Vers': VerseType.Tags[VerseType.Verse],
u'Verse': VerseType.Tags[VerseType.Verse],
u'Strophe': VerseType.Tags[VerseType.Verse],
u'Intro': VerseType.Tags[VerseType.Intro],
u'Coda': VerseType.Tags[VerseType.Ending],
u'Ending': VerseType.Tags[VerseType.Ending],
u'Bridge': VerseType.Tags[VerseType.Bridge],
u'Interlude': VerseType.Tags[VerseType.Bridge],
u'Zwischenspiel': VerseType.Tags[VerseType.Bridge],
u'Pre-Chorus': VerseType.Tags[VerseType.PreChorus],
u'Pre-Refrain': VerseType.Tags[VerseType.PreChorus],
u'Pre-Bridge': VerseType.Tags[VerseType.Other],
u'Pre-Coda': VerseType.Tags[VerseType.Other],
u'Unbekannt': VerseType.Tags[VerseType.Other],
u'Unknown': VerseType.Tags[VerseType.Other],
u'Unbenannt': VerseType.Tags[VerseType.Other]
u'Refrain': VerseType.tags[VerseType.Chorus],
u'Chorus': VerseType.tags[VerseType.Chorus],
u'Vers': VerseType.tags[VerseType.Verse],
u'Verse': VerseType.tags[VerseType.Verse],
u'Strophe': VerseType.tags[VerseType.Verse],
u'Intro': VerseType.tags[VerseType.Intro],
u'Coda': VerseType.tags[VerseType.Ending],
u'Ending': VerseType.tags[VerseType.Ending],
u'Bridge': VerseType.tags[VerseType.Bridge],
u'Interlude': VerseType.tags[VerseType.Bridge],
u'Zwischenspiel': VerseType.tags[VerseType.Bridge],
u'Pre-Chorus': VerseType.tags[VerseType.PreChorus],
u'Pre-Refrain': VerseType.tags[VerseType.PreChorus],
u'Pre-Bridge': VerseType.tags[VerseType.Other],
u'Pre-Coda': VerseType.tags[VerseType.Other],
u'Unbekannt': VerseType.tags[VerseType.Other],
u'Unknown': VerseType.tags[VerseType.Other],
u'Unbenannt': VerseType.tags[VerseType.Other]
}
class SongBeamerImport(SongImport):
"""
Import Song Beamer files(s)
Song Beamer file format is text based
in the beginning are one or more control tags written
Import Song Beamer files(s). Song Beamer file format is text based in the beginning are one or more control tags
written.
"""
HTML_TAG_PAIRS = [
(re.compile(u'<b>'), u'{st}'),
@ -113,7 +111,7 @@ class SongBeamerImport(SongImport):
return
self.setDefaults()
self.currentVerse = u''
self.currentVerseType = VerseType.Tags[VerseType.Verse]
self.currentVerseType = VerseType.tags[VerseType.Verse]
read_verses = False
file_name = os.path.split(file)[1]
if os.path.isfile(file):
@ -137,7 +135,7 @@ class SongBeamerImport(SongImport):
self.replaceHtmlTags()
self.addVerse(self.currentVerse, self.currentVerseType)
self.currentVerse = u''
self.currentVerseType = VerseType.Tags[VerseType.Verse]
self.currentVerseType = VerseType.tags[VerseType.Verse]
read_verses = True
verse_start = True
elif read_verses:
@ -155,8 +153,7 @@ class SongBeamerImport(SongImport):
def replaceHtmlTags(self):
"""
This can be called to replace SongBeamer's specific (html) tags with
OpenLP's specific (html) tags.
This can be called to replace SongBeamer's specific (html) tags with OpenLP's specific (html) tags.
"""
for pair in SongBeamerImport.HTML_TAG_PAIRS:
self.currentVerse = pair[0].sub(pair[1], self.currentVerse)
@ -166,8 +163,7 @@ class SongBeamerImport(SongImport):
Parses a meta data line.
``line``
The line in the file. It should consist of a tag and a value
for this tag (unicode)::
The line in the file. It should consist of a tag and a value for this tag (unicode)::
u'#Title=Nearer my God to Thee'
"""
@ -272,8 +268,8 @@ class SongBeamerImport(SongImport):
def checkVerseMarks(self, line):
"""
Check and add the verse's MarkType. Returns ``True`` if the given line
contains a correct verse mark otherwise ``False``.
Check and add the verse's MarkType. Returns ``True`` if the given linE contains a correct verse mark otherwise
``False``.
``line``
The line to check for marks (unicode).

View File

@ -303,13 +303,13 @@ class SongImport(QtCore.QObject):
sxml = SongXML()
other_count = 1
for (verse_def, verse_text, lang) in self.verses:
if verse_def[0].lower() in VerseType.Tags:
if verse_def[0].lower() in VerseType.tags:
verse_tag = verse_def[0].lower()
else:
new_verse_def = u'%s%d' % (VerseType.Tags[VerseType.Other], other_count)
new_verse_def = u'%s%d' % (VerseType.tags[VerseType.Other], other_count)
verses_changed_to_other[verse_def] = new_verse_def
other_count += 1
verse_tag = VerseType.Tags[VerseType.Other]
verse_tag = VerseType.tags[VerseType.Other]
log.info(u'Versetype %s changing to %s', verse_def, new_verse_def)
verse_def = new_verse_def
sxml.add_verse_to_lyrics(verse_tag, verse_def[1:], verse_text, lang)

View File

@ -152,11 +152,11 @@ class SongShowPlusImport(SongImport):
elif block_key == CCLI_NO:
self.ccliNumber = int(data)
elif block_key == VERSE:
self.addVerse(unicode(data, u'cp1252'), "%s%s" % (VerseType.Tags[VerseType.Verse], verse_no))
self.addVerse(unicode(data, u'cp1252'), "%s%s" % (VerseType.tags[VerseType.Verse], verse_no))
elif block_key == CHORUS:
self.addVerse(unicode(data, u'cp1252'), "%s%s" % (VerseType.Tags[VerseType.Chorus], verse_no))
self.addVerse(unicode(data, u'cp1252'), "%s%s" % (VerseType.tags[VerseType.Chorus], verse_no))
elif block_key == BRIDGE:
self.addVerse(unicode(data, u'cp1252'), "%s%s" % (VerseType.Tags[VerseType.Bridge], verse_no))
self.addVerse(unicode(data, u'cp1252'), "%s%s" % (VerseType.tags[VerseType.Bridge], verse_no))
elif block_key == TOPIC:
self.topics.append(unicode(data, u'cp1252'))
elif block_key == COMMENTS:
@ -192,19 +192,19 @@ class SongShowPlusImport(SongImport):
verse_number = "1"
verse_type = verse_type.lower()
if verse_type == "verse":
verse_tag = VerseType.Tags[VerseType.Verse]
verse_tag = VerseType.tags[VerseType.Verse]
elif verse_type == "chorus":
verse_tag = VerseType.Tags[VerseType.Chorus]
verse_tag = VerseType.tags[VerseType.Chorus]
elif verse_type == "bridge":
verse_tag = VerseType.Tags[VerseType.Bridge]
verse_tag = VerseType.tags[VerseType.Bridge]
elif verse_type == "pre-chorus":
verse_tag = VerseType.Tags[VerseType.PreChorus]
verse_tag = VerseType.tags[VerseType.PreChorus]
else:
if verse_name not in self.otherList:
if ignore_unique:
return None
self.otherCount += 1
self.otherList[verse_name] = str(self.otherCount)
verse_tag = VerseType.Tags[VerseType.Other]
verse_tag = VerseType.tags[VerseType.Other]
verse_number = self.otherList[verse_name]
return verse_tag + verse_number

View File

@ -52,8 +52,7 @@ class SundayPlusImport(SongImport):
"""
Import Sunday Plus songs
The format examples can be found attached to bug report at
<http://support.openlp.org/issues/395>
The format examples can be found attached to bug report at <http://support.openlp.org/issues/395>
"""
def __init__(self, manager, **kwargs):
@ -90,7 +89,7 @@ class SundayPlusImport(SongImport):
self.logError(u'File is malformed')
return False
i = 1
verse_type = VerseType.Tags[VerseType.Verse]
verse_type = VerseType.tags[VerseType.Verse]
while i < len(data):
# Data is held as #name: value pairs inside groups marked as [].
# Now we are looking for the name.
@ -137,8 +136,7 @@ class SundayPlusImport(SongImport):
if name == 'MARKER_NAME':
value = value.strip()
if len(value):
verse_type = VerseType.Tags[
VerseType.from_loose_input(value[0])]
verse_type = VerseType.tags[VerseType.from_loose_input(value[0])]
if len(value) >= 2 and value[-1] in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']:
verse_type = "%s%s" % (verse_type, value[-1])
elif name == 'Hotkey':
@ -168,8 +166,7 @@ class SundayPlusImport(SongImport):
self.copyright = u'Public Domain'
continue
processed_lines.append(line)
self.addVerse('\n'.join(processed_lines).strip(),
verse_type)
self.addVerse('\n'.join(processed_lines).strip(), verse_type)
if end == -1:
break
i = end + 1

View File

@ -97,10 +97,8 @@ class SongXML(object):
Add a verse to the ``<lyrics>`` tag.
``type``
A string denoting the type of verse. Possible values are *v*,
*c*, *b*, *p*, *i*, *e* and *o*.
Any other type is **not** allowed, this also includes translated
types.
A string denoting the type of verse. Possible values are *v*, *c*, *b*, *p*, *i*, *e* and *o*. Any other
type is **not** allowed, this also includes translated types.
``number``
An integer denoting the number of the item, for example: verse 1.
@ -109,8 +107,7 @@ class SongXML(object):
The actual text of the verse to be stored.
``lang``
The verse's language code (ISO-639). This is not required, but
should be added if available.
The verse's language code (ISO-639). This is not required, but should be added if available.
"""
verse = etree.Element(u'verse', type=unicode(type),
label=unicode(number))
@ -128,24 +125,21 @@ class SongXML(object):
def get_verses(self, xml):
"""
Iterates through the verses in the XML and returns a list of verses
and their attributes.
Iterates through the verses in the XML and returns a list of verses and their attributes.
``xml``
The XML of the song to be parsed.
The returned list has the following format::
[[{'type': 'v', 'label': '1'},
u"optional slide split 1[---]optional slide split 2"],
[[{'type': 'v', 'label': '1'}, u"optional slide split 1[---]optional slide split 2"],
[{'lang': 'en', 'type': 'c', 'label': '1'}, u"English chorus"]]
"""
self.song_xml = None
verse_list = []
if not xml.startswith(u'<?xml') and not xml.startswith(u'<song'):
# This is an old style song, without XML. Let's handle it correctly
# by iterating through the verses, and then recreating the internal
# xml object as well.
# This is an old style song, without XML. Let's handle it correctly by iterating through the verses, and
# then recreating the internal xml object as well.
self.song_xml = objectify.fromstring(u'<song version="1.0" />')
self.lyrics = etree.SubElement(self.song_xml, u'lyrics')
verses = xml.split(u'\n\n')
@ -176,11 +170,10 @@ class SongXML(object):
class OpenLyrics(object):
"""
This class represents the converter for OpenLyrics XML (version 0.8)
to/from a song.
This class represents the converter for OpenLyrics XML (version 0.8) to/from a song.
As OpenLyrics has a rich set of different features, we cannot support them
all. The following features are supported by the :class:`OpenLyrics` class:
As OpenLyrics has a rich set of different features, we cannot support them all. The following features are
supported by the :class:`OpenLyrics` class:
``<authors>``
OpenLP does not support the attribute *type* and *lang*.
@ -189,8 +182,7 @@ class OpenLyrics(object):
This property is not supported.
``<comments>``
The ``<comments>`` property is fully supported. But comments in lyrics
are not supported.
The ``<comments>`` property is fully supported. But comments in lyrics are not supported.
``<copyright>``
This property is fully supported.
@ -208,23 +200,20 @@ class OpenLyrics(object):
This property is not supported.
``<lines>``
The attribute *part* is not supported. The *break* attribute is
supported.
The attribute *part* is not supported. The *break* attribute is supported.
``<publisher>``
This property is not supported.
``<songbooks>``
As OpenLP does only support one songbook, we cannot consider more than
one songbook.
As OpenLP does only support one songbook, we cannot consider more than one songbook.
``<tempo>``
This property is not supported.
``<themes>``
Topics, as they are called in OpenLP, are fully supported, whereby only
the topic text (e. g. Grace) is considered, but neither the *id* nor
*lang*.
Topics, as they are called in OpenLP, are fully supported, whereby only the topic text (e. g. Grace) is
considered, but neither the *id* nor *lang*.
``<transposition>``
This property is not supported.
@ -233,9 +222,8 @@ class OpenLyrics(object):
This property is not supported.
``<verse name="v1a" lang="he" translit="en">``
The attribute *translit* is not supported. Note, the attribute *lang* is
considered, but there is not further functionality implemented yet. The
following verse "types" are supported by OpenLP:
The attribute *translit* is not supported. Note, the attribute *lang* is considered, but there is not further
functionality implemented yet. The following verse "types" are supported by OpenLP:
* v
* c
@ -245,13 +233,10 @@ class OpenLyrics(object):
* e
* o
The verse "types" stand for *Verse*, *Chorus*, *Bridge*, *Pre-Chorus*,
*Intro*, *Ending* and *Other*. Any numeric value is allowed after the
verse type. The complete verse name in OpenLP always consists of the
verse type and the verse number. If not number is present *1* is
assumed.
OpenLP will merge verses which are split up by appending a letter to the
verse name, such as *v1a*.
The verse "types" stand for *Verse*, *Chorus*, *Bridge*, *Pre-Chorus*, *Intro*, *Ending* and *Other*. Any
numeric value is allowed after the verse type. The complete verse name in OpenLP always consists of the verse
type and the verse number. If not number is present *1* is assumed. OpenLP will merge verses which are split
up by appending a letter to the verse name, such as *v1a*.
``<verseOrder>``
OpenLP supports this property.
@ -359,17 +344,14 @@ class OpenLyrics(object):
def _get_missing_tags(self, text):
"""
Tests the given text for not closed formatting tags and returns a tuple
consisting of two unicode strings::
Tests the given text for not closed formatting tags and returns a tuple consisting of two unicode strings::
(u'{st}{r}', u'{/r}{/st}')
The first unicode string are the start tags (for the next slide). The
second unicode string are the end tags.
The first unicode string are the start tags (for the next slide). The second unicode string are the end tags.
``text``
The text to test. The text must **not** contain html tags, only
OpenLP formatting tags are allowed::
The text to test. The text must **not** contain html tags, only OpenLP formatting tags are allowed::
{st}{r}Text text text
"""
@ -379,9 +361,8 @@ class OpenLyrics(object):
continue
if text.count(tag[u'start tag']) != text.count(tag[u'end tag']):
tags.append((text.find(tag[u'start tag']), tag[u'start tag'], tag[u'end tag']))
# Sort the lists, so that the tags which were opened first on the first
# slide (the text we are checking) will be opened first on the next
# slide as well.
# Sort the lists, so that the tags which were opened first on the first slide (the text we are checking) will
# be opened first on the next slide as well.
tags.sort(key=lambda tag: tag[0])
end_tags = []
start_tags = []
@ -393,16 +374,15 @@ class OpenLyrics(object):
def xml_to_song(self, xml, parse_and_temporary_save=False):
"""
Create and save a song from OpenLyrics format xml to the database. Since
we also export XML from external sources (e. g. OpenLyrics import), we
cannot ensure, that it completely conforms to the OpenLyrics standard.
Create and save a song from OpenLyrics format xml to the database. Since we also export XML from external
sources (e. g. OpenLyrics import), we cannot ensure, that it completely conforms to the OpenLyrics standard.
``xml``
The XML to parse (unicode).
``parse_and_temporary_save``
Switch to skip processing the whole song and storing the songs in
the database with a temporary flag. Defaults to ``False``.
Switch to skip processing the whole song and storing the songs in the database with a temporary flag.
Defaults to ``False``.
"""
# No xml get out of here.
if not xml:
@ -448,8 +428,7 @@ class OpenLyrics(object):
def _add_tag_to_formatting(self, tag_name, tags_element):
"""
Add new formatting tag to the element ``<format>`` if the tag is not
present yet.
Add new formatting tag to the element ``<format>`` if the tag is not present yet.
"""
available_tags = FormattingTags.get_html_tags()
start_tag = '{%s}' % tag_name
@ -469,8 +448,7 @@ class OpenLyrics(object):
def _add_text_with_tags_to_lines(self, verse_element, text, tags_element):
"""
Convert text with formatting tags from OpenLP format to OpenLyrics
format and append it to element ``<lines>``.
Convert text with formatting tags from OpenLP format to OpenLyrics format and append it to element ``<lines>``.
"""
start_tags = OpenLyrics.START_TAGS_REGEX.findall(text)
end_tags = OpenLyrics.END_TAGS_REGEX.findall(text)
@ -478,8 +456,7 @@ class OpenLyrics(object):
for tag in start_tags:
# Tags already converted to xml structure.
xml_tags = tags_element.xpath(u'tag/attribute::name')
# Some formatting tag has only starting part e.g. <br>.
# Handle this case.
# Some formatting tag has only starting part e.g. <br>. Handle this case.
if tag in end_tags:
text = text.replace(u'{%s}' % tag, u'<tag name="%s">' % tag)
else:
@ -586,8 +563,8 @@ class OpenLyrics(object):
def _process_formatting_tags(self, song_xml, temporary):
"""
Process the formatting tags from the song and either add missing tags
temporary or permanently to the formatting tag list.
Process the formatting tags from the song and either add missing tags temporary or permanently to the
formatting tag list.
"""
if not hasattr(song_xml, u'format'):
return
@ -608,8 +585,8 @@ class OpenLyrics(object):
u'end html': tag.close.text if hasattr(tag, 'close') else u'',
u'protected': False,
}
# Add 'temporary' key in case the formatting tag should not be
# saved otherwise it is supposed that formatting tag is permanent.
# Add 'temporary' key in case the formatting tag should not be saved otherwise it is supposed that
# formatting tag is permanent.
if temporary:
openlp_tag[u'temporary'] = temporary
found_tags.append(openlp_tag)
@ -620,15 +597,14 @@ class OpenLyrics(object):
def _process_lines_mixed_content(self, element, newlines=True):
"""
Converts the xml text with mixed content to OpenLP representation.
Chords are skipped and formatting tags are converted.
Converts the xml text with mixed content to OpenLP representation. Chords are skipped and formatting tags are
converted.
``element``
The property object (lxml.etree.Element).
``newlines``
The switch to enable/disable processing of line breaks <br/>.
The <br/> is used since OpenLyrics 0.8.
The switch to enable/disable processing of line breaks <br/>. The <br/> is used since OpenLyrics 0.8.
"""
text = u''
use_endtag = True
@ -684,12 +660,10 @@ class OpenLyrics(object):
lines = etree.tostring(lines)
element = etree.XML(lines)
# OpenLyrics 0.8 uses <br/> for new lines.
# Append text from "lines" element to verse text.
# OpenLyrics 0.8 uses <br/> for new lines. Append text from "lines" element to verse text.
if version > '0.7':
text = self._process_lines_mixed_content(element)
# OpenLyrics version <= 0.7 contais <line> elements to represent lines.
# First child element is tested.
# OpenLyrics version <= 0.7 contais <line> elements to represent lines. First child element is tested.
else:
# Loop over the "line" elements removing comments and chords.
for line in element:
@ -742,16 +716,15 @@ class OpenLyrics(object):
text += u'\n[---]'
verse_def = verse.get(u'name', u' ').lower()
verse_tag, verse_number, verse_part = OpenLyrics.VERSE_TAG_SPLITTER.search(verse_def).groups()
if verse_tag not in VerseType.Tags:
verse_tag = VerseType.Tags[VerseType.Other]
# OpenLyrics allows e. g. "c", but we need "c1". However, this does
# not correct the verse order.
if verse_tag not in VerseType.tags:
verse_tag = VerseType.tags[VerseType.Other]
# OpenLyrics allows e. g. "c", but we need "c1". However, this does not correct the verse order.
if not verse_number:
verse_number = u'1'
lang = verse.get(u'lang')
translit = verse.get(u'translit')
# In OpenLP 1.9.6 we used v1a, v1b ... to represent visual slide
# breaks. In OpenLyrics 0.7 an attribute has been added.
# In OpenLP 1.9.6 we used v1a, v1b ... to represent visual slide breaks. In OpenLyrics 0.7 an attribute has
# been added.
if song_xml.get(u'modifiedIn') in (u'1.9.6', u'OpenLP 1.9.6') and \
song_xml.get(u'version') == u'0.7' and (verse_tag, verse_number, lang, translit) in verses:
verses[(verse_tag, verse_number, lang, translit, None)] += u'\n[---]\n' + text