forked from openlp/openlp
fix opensong order shuffling + refactoring
This commit is contained in:
parent
893a1a6859
commit
7e18b8e3e6
@ -149,10 +149,10 @@ class OpenSongImport(SongImport):
|
|||||||
unicode(translate('SongsPlugin.ImportWizardForm',
|
unicode(translate('SongsPlugin.ImportWizardForm',
|
||||||
'Importing %s...')) % parts[-1])
|
'Importing %s...')) % parts[-1])
|
||||||
songfile = z.open(song)
|
songfile = z.open(song)
|
||||||
self.do_import_file(songfile)
|
if self.do_import_file(songfile) and self.commit and \
|
||||||
if self.commit:
|
not self.stop_import_flag:
|
||||||
self.finish()
|
self.finish()
|
||||||
if self.stop_import_flag:
|
else:
|
||||||
success = False
|
success = False
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
@ -161,11 +161,13 @@ class OpenSongImport(SongImport):
|
|||||||
self.import_wizard.incrementProgressBar(
|
self.import_wizard.incrementProgressBar(
|
||||||
unicode(translate('SongsPlugin.ImportWizardForm',
|
unicode(translate('SongsPlugin.ImportWizardForm',
|
||||||
'Importing %s...')) % os.path.split(filename)[-1])
|
'Importing %s...')) % os.path.split(filename)[-1])
|
||||||
file = open(filename)
|
songfile = open(filename)
|
||||||
self.do_import_file(file)
|
if self.do_import_file(songfile) and self.commit and \
|
||||||
if self.commit:
|
not self.stop_import_flag:
|
||||||
self.finish()
|
self.finish()
|
||||||
|
else:
|
||||||
|
success = False
|
||||||
|
break
|
||||||
return success
|
return success
|
||||||
|
|
||||||
def do_import_file(self, file):
|
def do_import_file(self, file):
|
||||||
@ -178,7 +180,7 @@ class OpenSongImport(SongImport):
|
|||||||
tree = objectify.parse(file)
|
tree = objectify.parse(file)
|
||||||
except (Error, LxmlError):
|
except (Error, LxmlError):
|
||||||
log.exception(u'Error parsing XML')
|
log.exception(u'Error parsing XML')
|
||||||
return
|
return False
|
||||||
root = tree.getroot()
|
root = tree.getroot()
|
||||||
fields = dir(root)
|
fields = dir(root)
|
||||||
decode = {
|
decode = {
|
||||||
@ -196,19 +198,22 @@ class OpenSongImport(SongImport):
|
|||||||
setattr(self, fn_or_string, ustring)
|
setattr(self, fn_or_string, ustring)
|
||||||
else:
|
else:
|
||||||
fn_or_string(ustring)
|
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:
|
if u'theme' in fields and unicode(root.theme) not in self.topics:
|
||||||
self.topics.append(unicode(root.theme))
|
self.topics.append(unicode(root.theme))
|
||||||
if u'alttheme' in fields and unicode(root.alttheme) not in self.topics:
|
if u'alttheme' in fields and unicode(root.alttheme) not in self.topics:
|
||||||
self.topics.append(unicode(root.alttheme))
|
self.topics.append(unicode(root.alttheme))
|
||||||
# data storage while importing
|
# data storage while importing
|
||||||
verses = {}
|
verses = {}
|
||||||
# keep track of a "default" verse order, in case none is specified
|
# keep track of verses appearance order
|
||||||
our_verse_order = []
|
our_verse_order = []
|
||||||
verses_seen = {}
|
# default versetype
|
||||||
# in the absence of any other indication, verses are the default,
|
vt = u'V'
|
||||||
# erm, versetype!
|
vn = u'1'
|
||||||
versetype = u'V'
|
# for the case where song has several sections with same marker
|
||||||
versenum = None
|
inst = 1
|
||||||
lyrics = unicode(root.lyrics)
|
lyrics = unicode(root.lyrics)
|
||||||
for thisline in lyrics.split(u'\n'):
|
for thisline in lyrics.split(u'\n'):
|
||||||
# remove comments
|
# remove comments
|
||||||
@ -216,14 +221,14 @@ class OpenSongImport(SongImport):
|
|||||||
if semicolon >= 0:
|
if semicolon >= 0:
|
||||||
thisline = thisline[:semicolon]
|
thisline = thisline[:semicolon]
|
||||||
thisline = thisline.strip()
|
thisline = thisline.strip()
|
||||||
if len(thisline) == 0:
|
if not len(thisline):
|
||||||
continue
|
continue
|
||||||
# skip inthisline guitar chords and page and column breaks
|
# skip guitar chords and page and column breaks
|
||||||
if thisline[0] == u'.' or thisline.startswith(u'---') \
|
if thisline.startswith(u'.') or thisline.startswith(u'---') \
|
||||||
or thisline.startswith(u'-!!'):
|
or thisline.startswith(u'-!!'):
|
||||||
continue
|
continue
|
||||||
# verse/chorus/etc. marker
|
# verse/chorus/etc. marker
|
||||||
if thisline[0] == u'[':
|
if thisline.startswith(u'['):
|
||||||
# drop the square brackets
|
# drop the square brackets
|
||||||
right_bracket = thisline.find(u']')
|
right_bracket = thisline.find(u']')
|
||||||
content = thisline[1:right_bracket].upper()
|
content = thisline[1:right_bracket].upper()
|
||||||
@ -232,78 +237,63 @@ class OpenSongImport(SongImport):
|
|||||||
# to the end (even if there are some alpha chars on the end)
|
# to the end (even if there are some alpha chars on the end)
|
||||||
match = re.match(u'(.*)(\d+.*)', content)
|
match = re.match(u'(.*)(\d+.*)', content)
|
||||||
if match is not None:
|
if match is not None:
|
||||||
versetype = match.group(1)
|
vt = match.group(1)
|
||||||
versenum = match.group(2)
|
vn = match.group(2)
|
||||||
else:
|
else:
|
||||||
# otherwise we assume number 1 and take the whole prefix as
|
# otherwise we assume number 1 and take the whole prefix as
|
||||||
# the versetype
|
# the versetype
|
||||||
versetype = content
|
vt = content
|
||||||
versenum = u'1'
|
vn = u'1'
|
||||||
|
inst = 1
|
||||||
|
if [vt, vn, inst] in our_verse_order and verses.has_key(vt) \
|
||||||
|
and verses[vt].has_key(vn):
|
||||||
|
inst = len(verses[vt][vn])+1
|
||||||
|
our_verse_order.append([vt, vn, inst])
|
||||||
continue
|
continue
|
||||||
words = None
|
|
||||||
# number at start of line.. it's verse number
|
# number at start of line.. it's verse number
|
||||||
if thisline[0].isdigit():
|
if thisline[0].isdigit():
|
||||||
versenum = thisline[0]
|
vn = thisline[0]
|
||||||
words = thisline[1:].strip()
|
thisline = thisline[1:].strip()
|
||||||
if words is None:
|
our_verse_order.append([vt, vn, inst])
|
||||||
words = thisline
|
if not verses.has_key(vt):
|
||||||
if not versenum:
|
verses[vt] = {}
|
||||||
versenum = u'1'
|
if not verses[vt].has_key(vn):
|
||||||
if versenum is not None:
|
verses[vt][vn] = {}
|
||||||
versetag = u'%s%s' % (versetype, versenum)
|
if not verses[vt][vn].has_key(inst):
|
||||||
if not verses.has_key(versetype):
|
verses[vt][vn][inst] = []
|
||||||
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:
|
if words:
|
||||||
# Tidy text and remove the ____s from extended words
|
# Tidy text and remove the ____s from extended words
|
||||||
words = self.tidy_text(words)
|
thisline = self.tidy_text(thisline)
|
||||||
words = words.replace('_', '')
|
thisline = thisline.replace(u'_', u'')
|
||||||
verses[versetype][versenum].append(words)
|
thisline = thisline.replace(u'|', u'\n')
|
||||||
|
verses[vt][vn][inst].append(thisline)
|
||||||
# done parsing
|
# done parsing
|
||||||
versetypes = verses.keys()
|
# add verses in original order
|
||||||
versetypes.sort()
|
for (vt, vn, inst) in our_verse_order:
|
||||||
versetags = {}
|
vtag = u'%s%s' % (vt, vn)
|
||||||
for versetype in versetypes:
|
lines = u'\n'.join(verses[vt][vn][inst])
|
||||||
our_verse_type = versetype
|
self.add_verse(lines, vtag)
|
||||||
if our_verse_type == u'':
|
# figure out the presentation order, if present
|
||||||
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 = []
|
|
||||||
if u'presentation' in fields and root.presentation != u'':
|
if u'presentation' in fields and root.presentation != u'':
|
||||||
order = unicode(root.presentation)
|
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 upper case, so match that here
|
||||||
# and then split into a list on the whitespace
|
# and then split into a list on the whitespace
|
||||||
order = order.upper().split()
|
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:
|
for tag in order:
|
||||||
if tag[0].isdigit():
|
match = re.match(u'(.*)(\d+.*)', tag)
|
||||||
# Assume it's a verse if it has no prefix
|
if match is not None:
|
||||||
tag = u'V' + tag
|
vt = match.group(1)
|
||||||
elif not re.search('\d+', tag):
|
vn = match.group(2)
|
||||||
# Assume it's no.1 if there's no digits
|
if not len(vt):
|
||||||
tag = tag + u'1'
|
vt = u'V'
|
||||||
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:
|
else:
|
||||||
self.verse_order_list.append(tag)
|
# Assume it's no.1 if there are no digits
|
||||||
|
vt = tag
|
||||||
|
vn = u'1'
|
||||||
|
vtagString = u'%s%s' % (vt, vn)
|
||||||
|
if verses.has_key(vt) and verses[vt].has_key(vn):
|
||||||
|
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
|
||||||
|
@ -75,6 +75,8 @@ class SongImport(QtCore.QObject):
|
|||||||
self.media_files = []
|
self.media_files = []
|
||||||
self.song_book_name = u''
|
self.song_book_name = u''
|
||||||
self.song_book_pub = u''
|
self.song_book_pub = u''
|
||||||
|
self.verse_order_list_generated_useful = False
|
||||||
|
self.verse_order_list_generated = []
|
||||||
self.verse_order_list = []
|
self.verse_order_list = []
|
||||||
self.verses = []
|
self.verses = []
|
||||||
self.versecounts = {}
|
self.versecounts = {}
|
||||||
@ -217,7 +219,8 @@ class SongImport(QtCore.QObject):
|
|||||||
"""
|
"""
|
||||||
for (oldversetag, oldverse, oldlang) in self.verses:
|
for (oldversetag, oldverse, oldlang) in self.verses:
|
||||||
if oldverse.strip() == versetext.strip():
|
if oldverse.strip() == versetext.strip():
|
||||||
self.verse_order_list.append(oldversetag)
|
self.verse_order_list_generated.append(oldversetag)
|
||||||
|
self.verse_order_list_generated_useful = True
|
||||||
return
|
return
|
||||||
if versetag[0] in self.versecounts:
|
if versetag[0] in self.versecounts:
|
||||||
self.versecounts[versetag[0]] += 1
|
self.versecounts[versetag[0]] += 1
|
||||||
@ -228,15 +231,15 @@ class SongImport(QtCore.QObject):
|
|||||||
elif int(versetag[1:]) > self.versecounts[versetag[0]]:
|
elif int(versetag[1:]) > self.versecounts[versetag[0]]:
|
||||||
self.versecounts[versetag[0]] = int(versetag[1:])
|
self.versecounts[versetag[0]] = int(versetag[1:])
|
||||||
self.verses.append([versetag, versetext.rstrip(), lang])
|
self.verses.append([versetag, versetext.rstrip(), lang])
|
||||||
self.verse_order_list.append(versetag)
|
self.verse_order_list_generated.append(versetag)
|
||||||
if versetag.startswith(u'V') and u'C1' in self.verse_order_list:
|
|
||||||
self.verse_order_list.append(u'C1')
|
|
||||||
|
|
||||||
def repeat_verse(self):
|
def repeat_verse(self):
|
||||||
"""
|
"""
|
||||||
Repeat the previous verse in the verse order
|
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):
|
def check_complete(self):
|
||||||
"""
|
"""
|
||||||
@ -297,6 +300,9 @@ class SongImport(QtCore.QObject):
|
|||||||
song.search_lyrics += u' ' + self.remove_punctuation(versetext)
|
song.search_lyrics += u' ' + self.remove_punctuation(versetext)
|
||||||
song.search_lyrics = song.search_lyrics.lower()
|
song.search_lyrics = song.search_lyrics.lower()
|
||||||
song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
|
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):
|
for i, current_verse_tag in enumerate(self.verse_order_list):
|
||||||
if verses_changed_to_other.has_key(current_verse_tag):
|
if verses_changed_to_other.has_key(current_verse_tag):
|
||||||
self.verse_order_list[i] = \
|
self.verse_order_list[i] = \
|
||||||
@ -348,6 +354,7 @@ class SongImport(QtCore.QObject):
|
|||||||
for (versetag, versetext, lang) in self.verses:
|
for (versetag, versetext, lang) in self.verses:
|
||||||
print u'VERSE ' + versetag + u': ' + versetext
|
print u'VERSE ' + versetag + u': ' + versetext
|
||||||
print u'ORDER: ' + u' '.join(self.verse_order_list)
|
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:
|
for author in self.authors:
|
||||||
print u'AUTHOR: ' + author
|
print u'AUTHOR: ' + author
|
||||||
if self.copyright:
|
if self.copyright:
|
||||||
|
Loading…
Reference in New Issue
Block a user