a lot of changes for better code

This commit is contained in:
Mattias Põldaru 2011-01-12 17:10:20 +02:00
parent 39bd27d0df
commit f1a437891a
1 changed files with 164 additions and 103 deletions

View File

@ -83,93 +83,145 @@ class EasiSlidesImport(SongImport):
not a filename not a filename
""" """
self.set_defaults() self.set_defaults()
# determines, if ENTIRELY UPPERCASE lines should be converted to lower
self.toLower = True
# determines, if title should be prepended to lyrics
self.titleIsLyrics = True
try: try:
context = etree.iterparse(file) context = etree.iterparse(file)
except (Error, LxmlError): except (Error, LxmlError):
log.exception(u'Error parsing XML') log.exception(u'Error parsing XML')
return return
song_dict = {} data = {}
for action, elem in context: for action, elem in context:
if not elem.text: if not elem.text:
text = None text = None
else: else:
text = elem.text text = unicode(elem.text)
song_dict[elem.tag] = text data[elem.tag.lower()] = text
if elem.tag.lower() == u"item": if elem.tag.lower() == u"item":
self.parse_song(song_dict) self.parse_song(data)
self.import_wizard.incrementProgressBar( self.import_wizard.incrementProgressBar(
unicode(translate('SongsPlugin.ImportWizardForm', unicode(translate('SongsPlugin.ImportWizardForm',
'Importing %s, song %s...')) % 'Importing %s, song %s...')) %
(os.path.split(self.filename)[-1], self.title)) (os.path.split(self.filename)[-1], self.title))
if self.commit: if self.commit:
self.finish() self.finish()
song_dict = {} data = {}
def notCapsLock(self, string): def notCapsLock(self, string):
if string.upper() == string: if self.toLower and string.upper() == string:
return string.lower() return string.lower()
else: else:
return string return string
def notCapsLockTitle(self, string): def notCapsLockTitle(self, string):
if string.upper() == string: if self.toLower and string.upper() == string:
ret = string.lower() ret = string.lower()
return u"%s%s" % (ret[0].upper(), ret[1:]) return u"%s%s" % (ret[0].upper(), ret[1:])
else: else:
return string return string
def parse_song(self, song_dict): def parse_song(self, data):
#for i in song_dict: # We should also check if the title is already used, if yes,
#if i != 'Contents' and song_dict[i] != None: # maybe user sould decide if we should import
#print u"%s = '%s'" % (i, song_dict[i])
toLower = True
title = unicode(song_dict['Title1']) # set title
if toLower: self.title = self.notCapsLockTitle(data['title1'])
self.title = self.notCapsLockTitle(title)
if song_dict['Title2'] != None: # set alternate title, if present
alttitle = unicode(song_dict['Title2']) if data['title2'] != None:
if toLower: self.alternate_title = self.notCapsLockTitle(data['title2'])
self.alternate_title = self.notCapsLockTitle(alttitle)
if song_dict['SongNumber'] != None: # folder name, we have no use for it, usually only one folder is
self.song_number = int(song_dict['SongNumber']) # used in easislides and this contains no actual data, easislides
# default database is named English, but usersmay not follow their
# example
# data['folder']
# set song number, if present, 0 otherwise
if data['songnumber'] != None:
self.song_number = int(data['songnumber'])
else: else:
self.song_number = 0 self.song_number = 0
#song_dict['Notations'] # Don't know how to use Notations
if song_dict['Sequence'] != None: # data['notations']
seq = song_dict['Sequence'].split(",")
print seq
if song_dict['Writer'] != None: # set song authors
self.authors.append(song_dict['Writer']) if data['writer'] != None:
authors = data['writer'].split(u',')
for author in authors:
self.authors.append(author.strip())
lyrics = unicode(song_dict['Contents']) # set copyright data
# licenceadmins may contain Public Domain or CCLI, as shown in examples
# let's just concatenate these fields, it should be determined, if song
# No is actually CCLI nr, if it is set
copyright = []
if data['copyright']:
copyright.append(data['copyright'].strip())
if data['licenceadmin1']:
copyright.append(data['licenceadmin1'].strip())
if data['licenceadmin2']:
copyright.append(data['licenceadmin2'].strip())
self.add_copyright(" ".join(copyright))
titleIsFirstLine = True # set topic data, I have seen no example, and should not use it,
if titleIsFirstLine: # I even was not able to find place to set categories in easislides
# but then again, it would not hurt either
if data['category']:
for topic in data['category'].split(u','):
self.topics.append(topic.strip())
# don't know what to do with timing data
# may be either 3/4 or 4/4
# data['timing']
# don't know what to do with music key
# data['musickey'], may be Db, C, G, F#, F#m
# data['capo'], is a number from 0 to 11, determing where to
# place a capo on guitar neck
# set book data
if data['bookreference']:
for book in data['bookreference'].split(u','):
self.books.append(book.strip())
# don't know what to do with user
# data['userreference'], this is simple text entry, no
# notable restrictions
# there is nothing to do with formatdata, this for sure is a messy
# thing, see an example:
# 21=1>23=0>22=2>25=2>26=-16777216>
# 27=-16777216>28=11>29=-1>30=-256>31=2>32=2>
# 41=16>42=16>43=Microsoft Sans Serif>
# 44=Microsoft Sans Serif>45=0>46=45>47=20>48=40>
# 50=0>51=>52=50>53=-1>54=0>55=1>61=>62=2>
# 63=1>64=2>65=2>66=0>71=0>72=Fade>73=Fade>
#
# data['formatdata']
# don't know what to do with settings data either, this is similar
# nonsense: 10=2;5;0;0;1;0;»126;232;>
# data['settings']
# LYRICS LYRICS LYRICS
# the big and messy part to handle lyrics
lyrics = data['contents']
# we add title to first line, if supposed to do so
if self.titleIsLyrics:
lyrics = u"%s\n%s" % (self.title, lyrics) lyrics = u"%s\n%s" % (self.title, lyrics)
# we count the [region 2] and [whatever] separartors, to be able
# data storage while importing # to tell how region data is used
verses = {}
# keep track of a "default" verse order, in case none is specified
our_verse_order = []
verses_seen = {}
# in the absence of any other indication, verses are the default,
# erm, versetype!
versetype = u'V'
versenum = None
seenorder = []
lines = lyrics.split(u'\n')
length = len(lines)
regions = 0 regions = 0
separators = 0 separators = 0
if lyrics.find(u'[') != -1: if lyrics.find(u'[') != -1:
@ -183,36 +235,43 @@ class EasiSlidesImport(SongImport):
else: else:
separators = separators+1 separators = separators+1
# data storage while importing
verses = {}
# keep track of a "default" verse order, in case none is specified
our_verse_order = []
lines = lyrics.split(u'\n')
length = len(lines)
for i in range(length): for i in range(length):
thisline = lines[i].strip() thisline = lines[i].strip()
if i < length-1: if i < length-1:
nextline = lines[i+1].strip() nextline = lines[i+1].strip()
# we don't care about nextline at the last line
else: else:
# there is no nextline at the last line
nextline = False nextline = False
if len(thisline) is 0: if len(thisline) is 0:
if separators == 0: if separators == 0:
# empty line starts a new verse or chorus # empty line starts a new verse or chorus
if nextline and nextline is nextline.upper(): if nextline and nextline is nextline.upper():
# the next line is all uppercase, it is chorus # the next line is all uppercase, it must be chorus
versetype = u'C' versetype = u'C'
else: else:
# if the next line is not uppercase, it must be verse # if the next line is not uppercase, it must be verse
versetype = u'V' versetype = u'V'
if verses.has_key(versetype): if verses.has_key(versetype):
keys = verses[versetype].keys() versenum = len(verses[versetype].keys())+1
#print keys
versenum = len(keys)+1
else: else:
versenum = u'1' versenum = u'1'
seenorder.append([versetype, versenum]) our_verse_order.append([versetype, versenum])
else:
# separators are not used, something must be done
continue
continue continue
# verse/chorus/etc. marker # verse/chorus/etc. marker, this line contains no other data
if thisline[0] == u'[': if thisline[0] == u'[':
if regions > 1: if regions > 1:
# region markers are inside verse markers # region markers are inside verse markers
@ -236,6 +295,11 @@ class EasiSlidesImport(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 normally is one of the following:
# not set for verse (only number)
# prechorus (p), chorus (c), bridge (w),
# ending, none of these is numbered in sequence
# empty line means split screen
versetype = match.group(1) versetype = match.group(1)
versenum = match.group(2) versenum = match.group(2)
else: else:
@ -243,65 +307,51 @@ class EasiSlidesImport(SongImport):
# the versetype # the versetype
versetype = content versetype = content
versenum = u'1' versenum = u'1'
seenorder.append([versetype, versenum]) our_verse_order.append([versetype, versenum])
continue continue
if i == 0: if i == 0:
# this is the first line, but no separator is found, # this is the first line, but still no separator is found,
# let's say it's V1 # we say it's V1
versetype = u'V' versetype = u'V'
versenum = u'1' versenum = u'1'
seenorder.append([versetype, versenum]) our_verse_order.append([versetype, versenum])
words = None # We have versetype/number data, if it was there, now
# number at start of line.. it's verse number # we parse text
if thisline[0].isdigit(): if not verses.has_key(versetype):
versenum = thisline[0] verses[versetype] = {}
words = thisline[1:].strip() if not verses[versetype].has_key(versenum):
if words is None: verses[versetype][versenum] = []
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('_', '')
if toLower:
words = self.notCapsLock(words)
verses[versetype][versenum].append(words) # Tidy text and remove the ____s from extended words
words = self.tidy_text(thisline)
words = words.replace('_', '')
words = self.notCapsLock(words)
verses[versetype][versenum].append(words)
# done parsing # done parsing
versetypes = verses.keys() # we use our_verse_order to ensure, we insert lyrics in the same order
versetags = {} # as these appeared originally in the file
for tag in our_verse_order:
versetype = tag[0]
versenum = tag[1]
for tag in seenorder: if not versetype in verses:
vtype = tag[0]
vnum = tag[1]
if not vtype in verses:
# something may have gone wrong # something may have gone wrong
continue continue
if not vnum in verses[vtype]: if not versenum in verses[versetype]:
# this most likely is caused by an extra empty line at the end, # this most likely is caused by an extra empty line at the end,
# to be debugged later # to be debugged later
continue continue
versetag = u'%s%s' % (vtype, vnum) versetag = u'%s%s' % (versetype, versenum)
lines = u'\n'.join(verses[vtype][vnum]) lines = u'\n'.join(verses[versetype][versenum])
self.verses.append([versetag, lines]) self.verses.append([versetag, lines])
if song_dict['Sequence'] != None: # Make use of Sequence data, determining the order of verses, choruses
order = song_dict['Sequence'].split(u',') if data['sequence'] != None:
order = data['sequence'].split(u',')
for tag in order: for tag in order:
if tag[0].isdigit(): if tag[0].isdigit():
# Assume it's a verse if it has no prefix # Assume it's a verse if it has no prefix
@ -315,5 +365,16 @@ class EasiSlidesImport(SongImport):
else: else:
self.verse_order_list.append(tag) self.verse_order_list.append(tag)
else: else:
for tag in seenorder: for tag in our_verse_order:
if not tag[0] in verses:
log.info(u'Got order from our_verse_order %s but not in'
u'versetags, dropping this item from presentation order'
u'missing was versetag %s', tag, tag[0])
continue
if not tag[1] in verses[tag[0]]:
log.info(u'Got order from our_verse_order %s but not in'
u'versetags, dropping this item from presentation order'
u'missing was versenum %s for versetag %s',
tag, tag[1], tag[0])
continue
self.verse_order_list.append(u'%s%s' % (tag[0], tag[1])) self.verse_order_list.append(u'%s%s' % (tag[0], tag[1]))