Update songs for multi-language lyrics

bzr-revno: 1231
This commit is contained in:
Andreas Preikschat 2011-01-20 21:39:03 +00:00 committed by Jon Tibble
commit dfc2671323
6 changed files with 60 additions and 31 deletions

View File

@ -654,7 +654,7 @@ class SongImportForm(OpenLPWizard):
'Select EasiSlides songfile'), 'Select EasiSlides songfile'),
self.easiSlidesFilenameEdit self.easiSlidesFilenameEdit
) )
def onEWBrowseButtonClicked(self): def onEWBrowseButtonClicked(self):
""" """
Get EasyWorship song database files Get EasyWorship song database files

View File

@ -313,7 +313,6 @@ class EasiSlidesImport(SongImport):
tag = SeqTypes[tag.lower()] tag = SeqTypes[tag.lower()]
else: else:
continue continue
if tag in versetags: if tag in versetags:
self.verse_order_list.append(tag) self.verse_order_list.append(tag)
else: else:

View File

@ -61,17 +61,18 @@ class OpenLyricsImport(SongImport):
Imports the songs. Imports the songs.
""" """
self.import_wizard.progressBar.setMaximum(len(self.import_source)) self.import_wizard.progressBar.setMaximum(len(self.import_source))
parser = etree.XMLParser(remove_blank_text=True)
for file_path in self.import_source: for file_path in self.import_source:
if self.stop_import_flag: if self.stop_import_flag:
return False return False
self.import_wizard.incrementProgressBar(unicode(translate( self.import_wizard.incrementProgressBar(unicode(translate(
'SongsPlugin.OpenLyricsImport', 'Importing %s...')) % 'SongsPlugin.OpenLyricsImport', 'Importing %s...')) %
os.path.basename(file_path)) os.path.basename(file_path))
parser = etree.XMLParser(remove_blank_text=True) try:
parsed_file = etree.parse(file_path, parser) parsed_file = etree.parse(file_path, parser)
xml = unicode(etree.tostring(parsed_file)) xml = unicode(etree.tostring(parsed_file))
if self.openLyrics.xml_to_song(xml) is None: if self.openLyrics.xml_to_song(xml) is None:
log.debug(u'File could not be imported: %s' % file_path) log.debug(u'File could not be imported: %s' % file_path)
# Importing this song failed! For now we stop import. except etree.XMLSyntaxError:
return False log.exception(u'XML syntax error in file %s' % file_path)
return True return True

View File

@ -197,16 +197,24 @@ class SongImport(QtCore.QObject):
return return
self.media_files.append(filename) self.media_files.append(filename)
def add_verse(self, verse, versetag=u'V'): def add_verse(self, versetext, versetag=u'V', lang=None):
""" """
Add a verse. This is the whole verse, lines split by \n Add a verse. This is the whole verse, lines split by \n. It will also
Verse tag can be V1/C1/B etc, or 'V' and 'C' (will count the verses/ attempt to detect duplicates. In this case it will just add to the verse
choruses itself) or None, where it will assume verse order.
It will also attempt to detect duplicates. In this case it will just
add to the verse order ``versetext``
The text of the verse.
``versetag``
The verse tag can be V1/C1/B etc, or 'V' and 'C' (will count the
verses/choruses itself) or None, where it will assume verse.
``lang``
The language code (ISO-639) of the verse, for example *en* or *de*.
""" """
for (oldversetag, oldverse) in self.verses: for (oldversetag, oldverse, oldlang) in self.verses:
if oldverse.strip() == verse.strip(): if oldverse.strip() == versetext.strip():
self.verse_order_list.append(oldversetag) self.verse_order_list.append(oldversetag)
return return
if versetag[0] in self.versecounts: if versetag[0] in self.versecounts:
@ -217,7 +225,7 @@ class SongImport(QtCore.QObject):
versetag += unicode(self.versecounts[versetag[0]]) versetag += unicode(self.versecounts[versetag[0]])
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, verse.rstrip()]) self.verses.append([versetag, versetext.rstrip(), lang])
self.verse_order_list.append(versetag) self.verse_order_list.append(versetag)
if versetag.startswith(u'V') and self.contains_verse(u'C1'): if versetag.startswith(u'V') and self.contains_verse(u'C1'):
self.verse_order_list.append(u'C1') self.verse_order_list.append(u'C1')
@ -266,7 +274,7 @@ class SongImport(QtCore.QObject):
verses_changed_to_other = {} verses_changed_to_other = {}
sxml = SongXML() sxml = SongXML()
other_count = 1 other_count = 1
for (versetag, versetext) in self.verses: for (versetag, versetext, lang) in self.verses:
if versetag[0] == u'C': if versetag[0] == u'C':
versetype = VerseType.to_string(VerseType.Chorus) versetype = VerseType.to_string(VerseType.Chorus)
elif versetag[0] == u'V': elif versetag[0] == u'V':
@ -286,7 +294,7 @@ class SongImport(QtCore.QObject):
versetype = VerseType.to_string(VerseType.Other) versetype = VerseType.to_string(VerseType.Other)
log.info(u'Versetype %s changing to %s' , versetag, newversetag) log.info(u'Versetype %s changing to %s' , versetag, newversetag)
versetag = newversetag versetag = newversetag
sxml.add_verse_to_lyrics(versetype, versetag[1:], versetext) sxml.add_verse_to_lyrics(versetype, versetag[1:], versetext, lang)
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')
@ -338,7 +346,7 @@ class SongImport(QtCore.QObject):
+ u'========================================' + u'========================================'
print u'TITLE: ' + self.title print u'TITLE: ' + self.title
print u'ALT TITLE: ' + self.alternate_title print u'ALT TITLE: ' + self.alternate_title
for (versetag, versetext) 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)
for author in self.authors: for author in self.authors:

View File

@ -31,7 +31,7 @@ The basic XML for storing the lyrics in the song database is of the format::
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<song version="1.0"> <song version="1.0">
<lyrics> <lyrics>
<verse type="chorus" label="1"> <verse type="Chorus" label="1" lang="en">
<![CDATA[ ... ]]> <![CDATA[ ... ]]>
</verse> </verse>
</lyrics> </lyrics>
@ -84,7 +84,7 @@ class SongXML(object):
self.song_xml = objectify.fromstring(u'<song version="1.0" />') self.song_xml = objectify.fromstring(u'<song version="1.0" />')
self.lyrics = etree.SubElement(self.song_xml, u'lyrics') self.lyrics = etree.SubElement(self.song_xml, u'lyrics')
def add_verse_to_lyrics(self, type, number, content): def add_verse_to_lyrics(self, type, number, content, lang=None):
""" """
Add a verse to the *<lyrics>* tag. Add a verse to the *<lyrics>* tag.
@ -97,9 +97,15 @@ class SongXML(object):
``content`` ``content``
The actual text of the verse to be stored. 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.
""" """
verse = etree.Element(u'verse', type=unicode(type), verse = etree.Element(u'verse', type=unicode(type),
label=unicode(number)) label=unicode(number))
if lang:
verse.set(u'lang', lang)
verse.text = etree.CDATA(content) verse.text = etree.CDATA(content)
self.lyrics.append(verse) self.lyrics.append(verse)
@ -117,6 +123,11 @@ class SongXML(object):
``xml`` ``xml``
The XML of the song to be parsed. The XML of the song to be parsed.
The returned list has the following format::
[[{'lang': 'en', 'type': 'V', 'label': '1'}, u"The English verse."],
[{'lang': 'en', 'type': 'C', 'label': '1'}, u"The English chorus."]]
""" """
self.song_xml = None self.song_xml = None
if xml[:5] == u'<?xml': if xml[:5] == u'<?xml':
@ -196,7 +207,7 @@ class OpenLyrics(object):
This property is not supported. This property is not supported.
*<verse name="v1a" lang="he" translit="en">* *<verse name="v1a" lang="he" translit="en">*
The attribute *translit* and *lang* are not supported. The attribute *translit* is not supported.
*<verseOrder>* *<verseOrder>*
OpenLP supports this property. OpenLP supports this property.
@ -268,13 +279,16 @@ class OpenLyrics(object):
# No xml get out of here. # No xml get out of here.
if not xml: if not xml:
return None return None
song = Song()
if xml[:5] == u'<?xml': if xml[:5] == u'<?xml':
xml = xml[38:] xml = xml[38:]
# Remove chords from xml. # Remove chords from xml.
xml = re.compile(u'<chord name=".*?"/>').sub(u'', xml) xml = re.compile(u'<chord name=".*?"/>').sub(u'', xml)
song_xml = objectify.fromstring(xml) song_xml = objectify.fromstring(xml)
properties = song_xml.properties try:
properties = song_xml.properties
except AttributeError:
return None
song = Song()
self._process_copyright(properties, song) self._process_copyright(properties, song)
self._process_cclinumber(properties, song) self._process_cclinumber(properties, song)
self._process_titles(properties, song) self._process_titles(properties, song)
@ -442,7 +456,10 @@ class OpenLyrics(object):
if not verse_number: if not verse_number:
verse_number = u'1' verse_number = u'1'
temp_verse_order.append((verse_type, verse_number, verse_part)) temp_verse_order.append((verse_type, verse_number, verse_part))
sxml.add_verse_to_lyrics(verse_type, verse_number, text) lang = None
if self._get(verse, u'lang'):
lang = self._get(verse, u'lang')
sxml.add_verse_to_lyrics(verse_type, verse_number, text, lang)
search_text = search_text + text search_text = search_text + text
song.search_lyrics = search_text.lower() song.search_lyrics = search_text.lower()
song.lyrics = unicode(sxml.extract_xml(), u'utf-8') song.lyrics = unicode(sxml.extract_xml(), u'utf-8')

View File

@ -134,7 +134,7 @@ class SongsPlugin(Plugin):
def onToolsReindexItemTriggered(self): def onToolsReindexItemTriggered(self):
""" """
Rebuild the search title of each song. Rebuild each song.
""" """
maxSongs = self.manager.get_object_count(Song) maxSongs = self.manager.get_object_count(Song)
progressDialog = QtGui.QProgressDialog( progressDialog = QtGui.QProgressDialog(
@ -150,8 +150,13 @@ class SongsPlugin(Plugin):
song.title = u'' song.title = u''
if song.alternate_title is None: if song.alternate_title is None:
song.alternate_title = u'' song.alternate_title = u''
song.search_title = self.whitespace.sub(u' ', song.title.lower() + \ song.search_title = self.whitespace.sub(u' ', song.title.lower() +
u' ' + song.alternate_title.lower()) u' ' + song.alternate_title.lower())
# Remove the "language" attribute from lyrics tag. This is not very
# important, but this keeps the database clean. This can be removed
# when everybody has run the reindex tool once.
song.lyrics = song.lyrics.replace(
u'<lyrics language="en">', u'<lyrics>')
lyrics = u'' lyrics = u''
verses = SongXML().get_verses(song.lyrics) verses = SongXML().get_verses(song.lyrics)
for verse in verses: for verse in verses:
@ -159,8 +164,7 @@ class SongsPlugin(Plugin):
song.search_lyrics = lyrics.lower() song.search_lyrics = lyrics.lower()
progressDialog.setValue(counter) progressDialog.setValue(counter)
self.manager.save_objects(songs) self.manager.save_objects(songs)
counter += 1 progressDialog.setValue(counter + 1)
progressDialog.setValue(counter)
self.mediaItem.displayResultsSong( self.mediaItem.displayResultsSong(
self.manager.get_all_objects(Song, order_by_ref=Song.search_title)) self.manager.get_all_objects(Song, order_by_ref=Song.search_title))