fix wrong 'themes' usage (themes -> topics), improved methods, make sure a missing property does not crash openlp

This commit is contained in:
Andreas Preikschat 2011-01-03 08:16:21 +01:00
parent 909fa25e7b
commit 9fc113abce
1 changed files with 76 additions and 36 deletions

View File

@ -42,8 +42,10 @@ import logging
import re import re
from lxml import etree, objectify from lxml import etree, objectify
from openlp.core.lib import translate
from openlp.plugins.songs.lib import VerseType from openlp.plugins.songs.lib import VerseType
from openlp.plugins.songs.lib.db import Author, Song from openlp.plugins.songs.lib.db import Author, Song, Topic
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -246,7 +248,7 @@ class OpenLyricsParser(object):
This class represents the converter for Song to/from This class represents the converter for Song to/from
`OpenLyrics <http://openlyrics.info/>`_ XML. `OpenLyrics <http://openlyrics.info/>`_ XML.
""" """
# TODO: complete OpenLyrics standard implementation! # TODO: complete OpenLyrics standard implementation as fare as possible!
def __init__(self, manager): def __init__(self, manager):
self.manager = manager self.manager = manager
@ -288,7 +290,7 @@ class OpenLyricsParser(object):
""" """
Create and save a Song from OpenLyrics format xml. Create and save a Song from OpenLyrics format xml.
""" """
# No xml get out of here # No xml get out of here.
if not xml: if not xml:
return 0 return 0
song = Song() song = Song()
@ -296,19 +298,18 @@ class OpenLyricsParser(object):
xml = xml[38:] xml = xml[38:]
song_xml = objectify.fromstring(xml) song_xml = objectify.fromstring(xml)
properties = song_xml.properties properties = song_xml.properties
song.copyright = unicode(properties.copyright.text) # Process Copyright
if song.copyright == u'None': try:
song.copyright = unicode(properties.copyright.text)
if song.copyright == u'None':
song.copyright = u''
except AttributeError:
song.copyright = u'' song.copyright = u''
song.topics = [] # Process CCLI number
song.book = None
try: try:
song.ccli_number = unicode(properties.ccliNo.text) song.ccli_number = unicode(properties.ccliNo.text)
except AttributeError: except AttributeError:
song.ccli_number = u'' song.ccli_number = u''
try:
song.theme_name = unicode(properties.themes.theme)
except AttributeError:
song.theme_name = u''
# Process Titles # Process Titles
for title in properties.titles.title: for title in properties.titles.title:
if not song.title: if not song.title:
@ -325,26 +326,29 @@ class OpenLyricsParser(object):
search_text = u'' search_text = u''
song.verse_order = u'' song.verse_order = u''
for lyrics in song_xml.lyrics: for lyrics in song_xml.lyrics:
for verse in song_xml.lyrics.verse: for verse in lyrics.verse:
text = u'' text = u''
for line in verse.lines.line: # Note that the <verses> element will not be in OpenLyrics 0.8:
line = unicode(line) # http://code.google.com/p/openlyrics/issues/detail?id=8
if not text: for line in verse.lines:
text = line for line in line.line:
else: line = unicode(line)
text += u'\n' + line if not text:
type = VerseType.expand_string(verse.attrib[u'name'][0]) text = line
# Here we need to create the verse order for the case that the else:
# song does not have a verseOrder property. text += u'\n' + line
sxml.add_verse_to_lyrics(type, verse.attrib[u'name'][1], text) type_ = VerseType.expand_string(verse.attrib[u'name'][0])
# TODO: Here we need to create the verse order for the case that
# the song does not have a verseOrder property.
sxml.add_verse_to_lyrics(type_, verse.attrib[u'name'][1], text)
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')
# Process verse order
try: try:
song.verse_order = unicode(properties.verseOrder.text) song.verse_order = unicode(properties.verseOrder.text)
except AttributeError: except AttributeError:
# TODO: Do not allow empty verse order. # TODO: Do not allow empty verse order.
# Do not worry!
pass pass
if song.verse_order == u'None': if song.verse_order == u'None':
song.verse_order = u'' song.verse_order = u''
@ -358,16 +362,26 @@ class OpenLyricsParser(object):
song.comments += u'\n' + comment song.comments += u'\n' + comment
except AttributeError: except AttributeError:
pass pass
song.song_number = u''
# Process Authors # Process Authors
try: try:
for author in properties.authors.author: for author in properties.authors.author:
self._process_author(author.text, song) self._process_author(author.text, song)
except AttributeError: except AttributeError:
# No Author in XML so ignore
pass pass
if not song.authors:
# Add "Author unknown" (can be translated)
self._process_author(translate('SongsPlugin.XML',
'Author unknown'), song)
# Process Topcis
try:
for topic in properties.themes.theme:
self._process_topic(topic.text, song)
except AttributeError:
pass
# Properties not yet supported.
song.book = None
song.song_number = u''
self.manager.save_object(song) self.manager.save_object(song)
# TODO: better return song itself, instead of song.id
return song.id return song.id
def _add_text_to_element(self, tag, parent, text=None, label=None): def _add_text_to_element(self, tag, parent, text=None, label=None):
@ -396,17 +410,43 @@ class OpenLyricsParser(object):
def _process_author(self, name, song): def _process_author(self, name, song):
""" """
Find or create an Author from display_name. Finds an existing Author or creates a new Author and adds it to the song
object.
``name``
The display_name of the song (string).
``song``
The song the Author will be added to.
""" """
if not name:
return
name = unicode(name) name = unicode(name)
author = self.manager.get_object_filtered(Author, author = self.manager.get_object_filtered(Author,
Author.display_name == name) Author.display_name == name)
if author: if author is None:
# should only be one! so take the first # We need to create a new author, as the author does not exist.
song.authors.append(author) author = Author.populate(first_name=name.rsplit(u' ', 1)[0],
else: last_name=name.rsplit(u' ', 1)[1], display_name=name)
# Need a new author self.manager.save_object(author)
new_author = Author.populate(first_name=name.rsplit(u' ', 1)[0], song.authors.append(author)
last_name=name.rsplit(u' ', 1)[1], display_name=name)
self.manager.save_object(new_author) def _process_topic(self, topictext, song):
song.authors.append(new_author) """
Finds an existing Topic or creates a new Topic and adds it to the song
object.
``topictext``
The topictext we add to the song (string).
``song``
The song the Topic will be added to.
"""
topictext = unicode(topictext)
# Check if topic already exists in the database.
topic = self.manager.get_object_filtered(Topic, Topic.name == topictext)
if topic is None:
# We need to create a new topic, as the topic does not exist.
topic = Topic.populate(name=topictext)
self.manager.save_object(topic)
song.topics.append(topic)