openlp-core team mailing list archive
-
openlp-core team
-
Mailing list archive
-
Message #02307
[Merge] lp:~meths/openlp/testing into lp:openlp
Jon Tibble has proposed merging lp:~meths/openlp/testing into lp:openlp.
Requested reviews:
OpenLP Core (openlp-core)
I think I'm looking for comments at this stage unless everyone thinks it's okay.
Two questions:
1 - Is the code okay to merge at the moment or do people want it refactored in one rather than stages?
2 - Should it go into trunk or go to Martin's branch first?
What it does:
* Enforce the plugin isolation
* Songs and custom now each control their own XML
* Move code to more logical areas for what it does
* Remove some unused code
* Start refactoring songs (objectify) so it doesn't get confused with xml modules
--
https://code.launchpad.net/~meths/openlp/testing/+merge/29151
Your team OpenLP Core is requested to review the proposed merge of lp:~meths/openlp/testing into lp:openlp.
=== modified file 'documentation/source/core/lib.rst'
--- documentation/source/core/lib.rst 2010-05-01 20:00:01 +0000
+++ documentation/source/core/lib.rst 2010-07-03 18:02:24 +0000
@@ -60,18 +60,6 @@
.. autoclass:: openlp.core.lib.settingstab.SettingsTab
:members:
-:mod:`SongXMLBuilder`
----------------------
-
-.. autoclass:: openlp.core.lib.songxmlhandler.SongXMLBuilder
- :members:
-
-:mod:`SongXMLParser`
---------------------
-
-.. autoclass:: openlp.core.lib.songxmlhandler.SongXMLParser
- :members:
-
:mod:`ThemeXML`
---------------
@@ -83,10 +71,3 @@
.. autoclass:: openlp.core.lib.toolbar.OpenLPToolbar
:members:
-
-:mod:`XmlRootClass`
--------------------
-
-.. autoclass:: openlp.core.lib.xmlrootclass.XmlRootClass
- :members:
-
=== modified file 'openlp/core/lib/__init__.py'
--- openlp/core/lib/__init__.py 2010-06-25 00:30:26 +0000
+++ openlp/core/lib/__init__.py 2010-07-03 18:02:24 +0000
@@ -202,28 +202,17 @@
return False
return True
-
-class ThemeLevel(object):
- """
- Provides an enumeration for the level a theme applies to
- """
- Global = 1
- Service = 2
- Song = 3
-
from eventreceiver import Receiver
from settingsmanager import SettingsManager
from plugin import PluginStatus, Plugin
from pluginmanager import PluginManager
from settingstab import SettingsTab
-from xmlrootclass import XmlRootClass
from serviceitem import ServiceItem
from serviceitem import ServiceItemType
from serviceitem import ItemCapabilities
from toolbar import OpenLPToolbar
from dockwidget import OpenLPDockWidget
-from songxmlhandler import SongXMLBuilder, SongXMLParser
-from themexmlhandler import ThemeXML
+from theme import ThemeLevel, ThemeXML
from renderer import Renderer
from rendermanager import RenderManager
from mediamanageritem import MediaManagerItem
=== renamed file 'openlp/core/lib/themexmlhandler.py' => 'openlp/core/lib/theme.py'
--- openlp/core/lib/themexmlhandler.py 2010-06-25 00:24:56 +0000
+++ openlp/core/lib/theme.py 2010-07-03 18:02:24 +0000
@@ -79,6 +79,14 @@
</theme>
'''
+class ThemeLevel(object):
+ """
+ Provides an enumeration for the level a theme applies to
+ """
+ Global = 1
+ Service = 2
+ Song = 3
+
class ThemeXML(object):
"""
A class to encapsulate the Theme XML.
@@ -313,7 +321,6 @@
element.appendChild(value)
background.appendChild(element)
-
def child_element(self, element, tag, value):
"""
Generic child element creator.
@@ -414,4 +421,3 @@
if key[0:1] != u'_':
theme_strings.append(u'%30s: %s' % (key, getattr(self, key)))
return u'\n'.join(theme_strings)
-
=== removed file 'openlp/core/lib/xmlrootclass.py'
--- openlp/core/lib/xmlrootclass.py 2010-06-12 20:22:58 +0000
+++ openlp/core/lib/xmlrootclass.py 1970-01-01 00:00:00 +0000
@@ -1,104 +0,0 @@
-# -*- coding: utf-8 -*-
-# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
-
-###############################################################################
-# OpenLP - Open Source Lyrics Projection #
-# --------------------------------------------------------------------------- #
-# Copyright (c) 2008-2010 Raoul Snyman #
-# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
-# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
-# Thompson, Jon Tibble, Carsten Tinggaard #
-# --------------------------------------------------------------------------- #
-# This program is free software; you can redistribute it and/or modify it #
-# under the terms of the GNU General Public License as published by the Free #
-# Software Foundation; version 2 of the License. #
-# #
-# This program is distributed in the hope that it will be useful, but WITHOUT #
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
-# more details. #
-# #
-# You should have received a copy of the GNU General Public License along #
-# with this program; if not, write to the Free Software Foundation, Inc., 59 #
-# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
-###############################################################################
-
-import os
-import sys
-
-from xml.etree.ElementTree import ElementTree, XML
-
-sys.path.append(os.path.abspath(os.path.join(u'.', u'..', u'..')))
-
-class XmlRootClass(object):
- """
- Root class for themes, songs etc
-
- This class provides interface for parsing xml files into object attributes.
-
- If you overload this class and provide a function called `post_tag_hook`,
- it will be called thusly for each `tag, value` pair::
-
- (element.tag, val) = self.post_tag_hook(element.tag, val)
- """
- def _set_from_xml(self, xml, root_tag):
- """
- Set song properties from given xml content.
-
- ``xml``
- Formatted xml tags and values.
- ``root_tag``
- The root tag of the xml.
- """
- root = ElementTree(element=XML(xml))
- xml_iter = root.getiterator()
- for element in xml_iter:
- if element.tag != root_tag:
- text = element.text
- if text is None:
- val = text
- elif isinstance(text, basestring):
- # Strings need special handling to sort the colours out
- if text[0] == u'$':
- # This might be a hex number, let's try to convert it.
- try:
- val = int(text[1:], 16)
- except ValueError:
- pass
- else:
- # Let's just see if it's a integer.
- try:
- val = int(text)
- except ValueError:
- # Ok, it seems to be a string.
- val = text
- if hasattr(self, u'post_tag_hook'):
- (element.tag, val) = \
- self.post_tag_hook(element.tag, val)
- setattr(self, element.tag, val)
-
- def __str__(self):
- """
- Return string with all public attributes
-
- The string is formatted with one attribute per line
- If the string is split on newline then the length of the
- list is equal to the number of attributes
- """
- attributes = []
- for attrib in dir(self):
- if not attrib.startswith(u'_'):
- attributes.append(
- u'%30s : %s' % (attrib, getattr(self, attrib)))
- return u'\n'.join(attributes)
-
- def _get_as_string(self):
- """
- Return one string with all public attributes
- """
- result = u''
- for attrib in dir(self):
- if not attrib.startswith(u'_'):
- result += u'_%s_' % getattr(self, attrib)
- return result
-
=== modified file 'openlp/plugins/custom/forms/editcustomform.py'
--- openlp/plugins/custom/forms/editcustomform.py 2010-06-28 13:38:29 +0000
+++ openlp/plugins/custom/forms/editcustomform.py 2010-07-03 18:02:24 +0000
@@ -28,7 +28,8 @@
from PyQt4 import QtCore, QtGui
from editcustomdialog import Ui_customEditDialog
-from openlp.core.lib import SongXMLBuilder, SongXMLParser, Receiver, translate
+from openlp.core.lib import Receiver, translate
+from openlp.plugins.custom.lib import CustomXMLBuilder, CustomXMLParser
from openlp.plugins.custom.lib.db import CustomSlide
log = logging.getLogger(__name__)
@@ -119,8 +120,8 @@
self.customSlide = self.custommanager.get_object(CustomSlide, id)
self.TitleEdit.setText(self.customSlide.title)
self.CreditEdit.setText(self.customSlide.credits)
- songXML = SongXMLParser(self.customSlide.text)
- verseList = songXML.get_verses()
+ customXML = CustomXMLParser(self.customSlide.text)
+ verseList = customXML.get_verses()
for verse in verseList:
self.VerseListView.addItem(verse[1])
theme = self.customSlide.theme_name
@@ -152,7 +153,7 @@
translate('CustomPlugin.EditCustomForm', 'Error'), message,
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
return False
- sxml = SongXMLBuilder()
+ sxml = CustomXMLBuilder()
sxml.new_document()
sxml.add_lyrics_to_song()
count = 1
=== modified file 'openlp/plugins/custom/lib/__init__.py'
--- openlp/plugins/custom/lib/__init__.py 2010-06-15 02:08:22 +0000
+++ openlp/plugins/custom/lib/__init__.py 2010-07-03 18:02:24 +0000
@@ -23,5 +23,6 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
+from customxmlhandler import CustomXMLBuilder, CustomXMLParser
from mediaitem import CustomMediaItem
from customtab import CustomTab
=== added file 'openlp/plugins/custom/lib/customxmlhandler.py'
--- openlp/plugins/custom/lib/customxmlhandler.py 1970-01-01 00:00:00 +0000
+++ openlp/plugins/custom/lib/customxmlhandler.py 2010-07-03 18:02:24 +0000
@@ -0,0 +1,156 @@
+# -*- coding: utf-8 -*-
+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
+
+###############################################################################
+# OpenLP - Open Source Lyrics Projection #
+# --------------------------------------------------------------------------- #
+# Copyright (c) 2008-2010 Raoul Snyman #
+# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
+# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
+# Thompson, Jon Tibble, Carsten Tinggaard #
+# --------------------------------------------------------------------------- #
+# This program is free software; you can redistribute it and/or modify it #
+# under the terms of the GNU General Public License as published by the Free #
+# Software Foundation; version 2 of the License. #
+# #
+# This program is distributed in the hope that it will be useful, but WITHOUT #
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
+# more details. #
+# #
+# You should have received a copy of the GNU General Public License along #
+# with this program; if not, write to the Free Software Foundation, Inc., 59 #
+# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
+###############################################################################
+"""
+The :mod:`customxmlhandler` module provides the XML functionality for custom
+slides
+
+The basic XML is of the format::
+
+ <?xml version="1.0" encoding="UTF-8"?>
+ <song version="1.0">
+ <lyrics language="en">
+ <verse type="chorus" label="1">
+ <![CDATA[ ... ]]>
+ </verse>
+ </lyrics>
+ </song>
+"""
+
+import logging
+
+from xml.dom.minidom import Document
+from xml.etree.ElementTree import ElementTree, XML, dump
+from xml.parsers.expat import ExpatError
+
+log = logging.getLogger(__name__)
+
+class CustomXMLBuilder(object):
+ """
+ This class builds the XML used to describe songs.
+ """
+ log.info(u'CustomXMLBuilder Loaded')
+
+ def __init__(self):
+ """
+ Set up the song builder.
+ """
+ # Create the minidom document
+ self.song_xml = Document()
+
+ def new_document(self):
+ """
+ Create a new song XML document.
+ """
+ # Create the <song> base element
+ self.song = self.song_xml.createElement(u'song')
+ self.song_xml.appendChild(self.song)
+ self.song.setAttribute(u'version', u'1.0')
+
+ def add_lyrics_to_song(self):
+ """
+ Set up and add a ``<lyrics>`` tag which contains the lyrics of the
+ song.
+ """
+ # Create the main <lyrics> element
+ self.lyrics = self.song_xml.createElement(u'lyrics')
+ self.lyrics.setAttribute(u'language', u'en')
+ self.song.appendChild(self.lyrics)
+
+ def add_verse_to_lyrics(self, type, number, content):
+ """
+ Add a verse to the ``<lyrics>`` tag.
+
+ ``type``
+ A string denoting the type of verse. Possible values are "Chorus",
+ "Verse", "Bridge", and "Custom".
+
+ ``number``
+ An integer denoting the number of the item, for example: verse 1.
+
+ ``content``
+ The actual text of the verse to be stored.
+ """
+ #log.debug(u'add_verse_to_lyrics %s, %s\n%s' % (type, number, content))
+ verse = self.song_xml.createElement(u'verse')
+ verse.setAttribute(u'type', type)
+ verse.setAttribute(u'label', number)
+ self.lyrics.appendChild(verse)
+ # add data as a CDATA section to protect the XML from special chars
+ cds = self.song_xml.createCDATASection(content)
+ verse.appendChild(cds)
+
+ def dump_xml(self):
+ """
+ Debugging aid to dump XML so that we can see what we have.
+ """
+ return self.song_xml.toprettyxml(indent=u' ')
+
+ def extract_xml(self):
+ """
+ Extract our newly created XML song.
+ """
+ return self.song_xml.toxml(u'utf-8')
+
+
+class CustomXMLParser(object):
+ """
+ A class to read in and parse a song's XML.
+ """
+ log.info(u'CustomXMLParser Loaded')
+
+ def __init__(self, xml):
+ """
+ Set up our song XML parser.
+
+ ``xml``
+ The XML of the song to be parsed.
+ """
+ self.song_xml = None
+ try:
+ self.song_xml = ElementTree(
+ element=XML(unicode(xml).encode('unicode-escape')))
+ except ExpatError:
+ log.exception(u'Invalid xml %s', xml)
+
+ def get_verses(self):
+ """
+ Iterates through the verses in the XML and returns a list of verses
+ and their attributes.
+ """
+ xml_iter = self.song_xml.getiterator()
+ verse_list = []
+ for element in xml_iter:
+ if element.tag == u'verse':
+ if element.text is None:
+ element.text = u''
+ verse_list.append([element.attrib,
+ unicode(element.text).decode('unicode-escape')])
+ return verse_list
+
+ def dump_xml(self):
+ """
+ Debugging aid to dump XML so that we can see what we have.
+ """
+ return dump(self.song_xml)
=== modified file 'openlp/plugins/custom/lib/mediaitem.py'
--- openlp/plugins/custom/lib/mediaitem.py 2010-07-02 17:00:23 +0000
+++ openlp/plugins/custom/lib/mediaitem.py 2010-07-03 18:02:24 +0000
@@ -27,8 +27,9 @@
from PyQt4 import QtCore, QtGui
-from openlp.core.lib import MediaManagerItem, SongXMLParser, BaseListWithDnD, \
+from openlp.core.lib import MediaManagerItem, BaseListWithDnD, \
Receiver, ItemCapabilities, translate, check_item_selected
+from openlp.plugins.custom.lib import CustomXMLParser
from openlp.plugins.custom.lib.db import CustomSlide
log = logging.getLogger(__name__)
@@ -170,8 +171,8 @@
theme = customSlide.theme_name
if theme:
service_item.theme = theme
- songXML = SongXMLParser(customSlide.text)
- verseList = songXML.get_verses()
+ customXML = CustomXMLParser(customSlide.text)
+ verseList = customXML.get_verses()
for verse in verseList:
raw_slides.append(verse[1])
service_item.title = title
=== modified file 'openlp/plugins/songs/forms/editsongform.py'
--- openlp/plugins/songs/forms/editsongform.py 2010-07-02 18:21:45 +0000
+++ openlp/plugins/songs/forms/editsongform.py 2010-07-03 18:02:24 +0000
@@ -28,9 +28,9 @@
from PyQt4 import QtCore, QtGui
-from openlp.core.lib import SongXMLBuilder, SongXMLParser, Receiver, translate
+from openlp.core.lib import Receiver, translate
from openlp.plugins.songs.forms import EditVerseForm
-from openlp.plugins.songs.lib import VerseType
+from openlp.plugins.songs.lib import SongXMLBuilder, SongXMLParser, VerseType
from openlp.plugins.songs.lib.db import Book, Song, Author, Topic
from editsongdialog import Ui_EditSongDialog
@@ -639,8 +639,6 @@
log.debug(u'processLyrics')
try:
sxml = SongXMLBuilder()
- sxml.new_document()
- sxml.add_lyrics_to_song()
text = u''
multiple = []
for i in range (0, self.VerseListWidget.rowCount()):
=== modified file 'openlp/plugins/songs/lib/__init__.py'
--- openlp/plugins/songs/lib/__init__.py 2010-06-30 22:05:51 +0000
+++ openlp/plugins/songs/lib/__init__.py 2010-07-03 18:02:24 +0000
@@ -137,6 +137,7 @@
unicode(VerseType.to_string(VerseType.Other)).lower():
return VerseType.Other
+from songxmlhandler import SongXMLBuilder, SongXMLParser
from songstab import SongsTab
from mediaitem import SongMediaItem
from songimport import SongImport
=== modified file 'openlp/plugins/songs/lib/mediaitem.py'
--- openlp/plugins/songs/lib/mediaitem.py 2010-07-02 12:13:46 +0000
+++ openlp/plugins/songs/lib/mediaitem.py 2010-07-03 18:02:24 +0000
@@ -27,10 +27,11 @@
from PyQt4 import QtCore, QtGui
-from openlp.core.lib import MediaManagerItem, SongXMLParser, \
- BaseListWithDnD, Receiver, ItemCapabilities, translate, check_item_selected
+from openlp.core.lib import MediaManagerItem, BaseListWithDnD, Receiver, \
+ ItemCapabilities, translate, check_item_selected
from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm, \
ImportWizardForm
+from openlp.plugins.songs.lib import SongXMLParser
from openlp.plugins.songs.lib.db import Song
log = logging.getLogger(__name__)
=== modified file 'openlp/plugins/songs/lib/songimport.py'
--- openlp/plugins/songs/lib/songimport.py 2010-06-30 22:05:51 +0000
+++ openlp/plugins/songs/lib/songimport.py 2010-07-03 18:02:24 +0000
@@ -25,8 +25,8 @@
import re
-from openlp.core.lib import SongXMLBuilder, translate
-from openlp.plugins.songs.lib import VerseType
+from openlp.core.lib import translate
+from openlp.plugins.songs.lib import SongXMLBuilder, VerseType
from openlp.plugins.songs.lib.db import Song, Author, Topic, Book
class SongImport(object):
@@ -276,8 +276,6 @@
song.song_number = self.song_number
song.search_lyrics = u''
sxml = SongXMLBuilder()
- sxml.new_document()
- sxml.add_lyrics_to_song()
for (versetag, versetext) in self.verses:
if versetag[0] == u'C':
versetype = VerseType.to_string(VerseType.Chorus)
=== modified file 'openlp/plugins/songs/lib/songxml.py'
--- openlp/plugins/songs/lib/songxml.py 2010-06-09 17:09:32 +0000
+++ openlp/plugins/songs/lib/songxml.py 2010-07-03 18:02:24 +0000
@@ -24,18 +24,18 @@
###############################################################################
import logging
-import sys
-import os
+#import sys
+#import os
from types import ListType
-
-sys.path.append(os.path.abspath(u'./../../../..'))
-
-from openlp.core.lib import XmlRootClass
+from xml.etree.ElementTree import ElementTree, XML
+
+# Do we need these two lines?
+#sys.path.append(os.path.abspath(u'./../../../..'))
+#sys.path.append(os.path.abspath(os.path.join(u'.', u'..', u'..')))
log = logging.getLogger(__name__)
-
class SongException(Exception):
pass
@@ -74,23 +74,78 @@
</song>
'''
-class _OpenSong(XmlRootClass):
- """Class for import of OpenSong"""
-
+class _OpenSong(object):
+ """
+ Class for import of OpenSong
+ """
def __init__(self, xmlContent = None):
- """Initialize from given xml content"""
- super(_OpenSong, self).__init__()
- self.from_buffer(xmlContent)
-
- def _reset(self):
- """Reset all song attributes"""
- self._setFromXml(_BLANK_OPENSONG_XML, 'song')
-
- def from_buffer(self, xmlContent):
- """Initialize from buffer(string) with xml content"""
- self._reset()
+ """
+ Initialize from given xml content
+ """
+ self._set_from_xml(_BLANK_OPENSONG_XML, 'song')
if xmlContent:
- self._setFromXml(xmlContent, 'song')
+ self._set_from_xml(xmlContent, 'song')
+
+ def _set_from_xml(self, xml, root_tag):
+ """
+ Set song properties from given xml content.
+
+ ``xml``
+ Formatted xml tags and values.
+ ``root_tag``
+ The root tag of the xml.
+ """
+ root = ElementTree(element=XML(xml))
+ xml_iter = root.getiterator()
+ for element in xml_iter:
+ if element.tag != root_tag:
+ text = element.text
+ if text is None:
+ val = text
+ elif isinstance(text, basestring):
+ # Strings need special handling to sort the colours out
+ if text[0] == u'$':
+ # This might be a hex number, let's try to convert it.
+ try:
+ val = int(text[1:], 16)
+ except ValueError:
+ pass
+ else:
+ # Let's just see if it's a integer.
+ try:
+ val = int(text)
+ except ValueError:
+ # Ok, it seems to be a string.
+ val = text
+ if hasattr(self, u'post_tag_hook'):
+ (element.tag, val) = \
+ self.post_tag_hook(element.tag, val)
+ setattr(self, element.tag, val)
+
+ def __str__(self):
+ """
+ Return string with all public attributes
+
+ The string is formatted with one attribute per line
+ If the string is split on newline then the length of the
+ list is equal to the number of attributes
+ """
+ attributes = []
+ for attrib in dir(self):
+ if not attrib.startswith(u'_'):
+ attributes.append(
+ u'%30s : %s' % (attrib, getattr(self, attrib)))
+ return u'\n'.join(attributes)
+
+ def _get_as_string(self):
+ """
+ Return one string with all public attributes
+ """
+ result = u''
+ for attrib in dir(self):
+ if not attrib.startswith(u'_'):
+ result += u'_%s_' % getattr(self, attrib)
+ return result
def get_author_list(self):
"""Convert author field to an authorlist
@@ -252,14 +307,6 @@
self.set_lyrics(u'')
return
- def set_songid(self, songid):
- """Set the songid for the database"""
- self.songid = songid
-
- def get_songid(self):
- """Return the songid for the database"""
- return self.songid
-
def from_opensong_buffer(self, xmlcontent):
"""Initialize from buffer(string) of xml lines in opensong format"""
self._reset()
@@ -323,10 +370,6 @@
"""Return title value"""
return self.title
- def get_search_title(self):
- """Return search_title"""
- return self.search_title
-
def from_ccli_text_buffer(self, textList):
"""
Create song from a list of texts (strings) - CCLI text format expected
=== renamed file 'openlp/core/lib/songxmlhandler.py' => 'openlp/plugins/songs/lib/songxmlhandler.py'
--- openlp/core/lib/songxmlhandler.py 2010-06-10 21:30:50 +0000
+++ openlp/plugins/songs/lib/songxmlhandler.py 2010-07-03 18:02:24 +0000
@@ -38,10 +38,10 @@
"""
import logging
+import StringIO
-from xml.dom.minidom import Document
-from xml.etree.ElementTree import ElementTree, XML, dump
-from xml.parsers.expat import ExpatError
+from lxml import etree, objectify
+#from lxml.etree import SubElement, XMLSyntaxError, dump
log = logging.getLogger(__name__)
@@ -51,31 +51,18 @@
"""
log.info(u'SongXMLBuilder Loaded')
- def __init__(self):
+ def __init__(self, song_language=None):
"""
Set up the song builder.
- """
- # Create the minidom document
- self.song_xml = Document()
-
- def new_document(self):
- """
- Create a new song XML document.
- """
- # Create the <song> base element
- self.song = self.song_xml.createElement(u'song')
- self.song_xml.appendChild(self.song)
- self.song.setAttribute(u'version', u'1.0')
-
- def add_lyrics_to_song(self):
- """
- Set up and add a ``<lyrics>`` tag which contains the lyrics of the
- song.
- """
- # Create the main <lyrics> element
- self.lyrics = self.song_xml.createElement(u'lyrics')
- self.lyrics.setAttribute(u'language', u'en')
- self.song.appendChild(self.lyrics)
+
+ ``song_language``
+ The language used in this song
+ """
+ lang = u'en'
+ if song_language:
+ lang = song_language
+ self.song_xml = objectify.fromstring(u'<song version="1.0" />')
+ self.lyrics = etree.SubElement(self.song_xml, u'lyrics', language=lang)
def add_verse_to_lyrics(self, type, number, content):
"""
@@ -92,25 +79,20 @@
The actual text of the verse to be stored.
"""
#log.debug(u'add_verse_to_lyrics %s, %s\n%s' % (type, number, content))
- verse = self.song_xml.createElement(u'verse')
- verse.setAttribute(u'type', type)
- verse.setAttribute(u'label', number)
- self.lyrics.appendChild(verse)
- # add data as a CDATA section to protect the XML from special chars
- cds = self.song_xml.createCDATASection(content)
- verse.appendChild(cds)
+ verse = etree.SubElement(self.lyrics, u'verse', type=type, label=number)
+ verse.text = etree.CDATA(content)
def dump_xml(self):
"""
Debugging aid to dump XML so that we can see what we have.
"""
- return self.song_xml.toprettyxml(indent=u' ')
+ return etree.tostring(self.song_xml, pretty_print=True)
def extract_xml(self):
"""
Extract our newly created XML song.
"""
- return self.song_xml.toxml(u'utf-8')
+ return etree.tostring(self.song_xml, encoding=u'utf-8')
class SongXMLParser(object):
@@ -128,9 +110,8 @@
"""
self.song_xml = None
try:
- self.song_xml = ElementTree(
- element=XML(unicode(xml).encode('unicode-escape')))
- except ExpatError:
+ self.song_xml = objectify.fromstring(str(xml))
+ except etree.XMLSyntaxError:
log.exception(u'Invalid xml %s', xml)
def get_verses(self):
=== modified file 'openlp/plugins/songs/lib/xml.py'
--- openlp/plugins/songs/lib/xml.py 2010-05-29 19:50:50 +0000
+++ openlp/plugins/songs/lib/xml.py 2010-07-03 18:02:24 +0000
@@ -136,4 +136,3 @@
song_output = u'<?xml version="1.0" encoding="UTF-8"?>' + \
u'<song version="1.0">%s</song>' % lyrics_output
return song_output
-
Follow ups