From ce883bc9ac9fe760bfb498025b7d76d45f4e9a70 Mon Sep 17 00:00:00 2001 From: Carsten Tinggaard Date: Tue, 28 Oct 2008 20:24:04 +0000 Subject: [PATCH] Initial Song class including test suite bzr-revno: 45 --- openlp/song/__init__.py | 18 ++++ openlp/song/song.py | 152 ++++++++++++++++++++++++++++++++++ openlp/song/test/test_song.py | 64 ++++++++++++++ 3 files changed, 234 insertions(+) create mode 100644 openlp/song/__init__.py create mode 100644 openlp/song/song.py create mode 100644 openlp/song/test/test_song.py diff --git a/openlp/song/__init__.py b/openlp/song/__init__.py new file mode 100644 index 000000000..6ebe74164 --- /dev/null +++ b/openlp/song/__init__.py @@ -0,0 +1,18 @@ +""" +OpenLP - Open Source Lyrics Projection +Copyright (c) 2008 Raoul Snyman +Portions copyright (c) 2008 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 +""" +from song import Song diff --git a/openlp/song/song.py b/openlp/song/song.py new file mode 100644 index 000000000..c6ed875d3 --- /dev/null +++ b/openlp/song/song.py @@ -0,0 +1,152 @@ +""" +OpenLP - Open Source Lyrics Projection +Copyright (c) 2008 Raoul Snyman +Portions copyright (c) 2008 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 platform +ver = platform.python_version() +if ver >= '2.5': + from xml.etree.ElementTree import ElementTree, XML +else: + from elementtree import ElementTree, XML + + +# borrowed from theme - can be common +DelphiColors={"clRed":0xFF0000, + "clBlack":0x000000, + "clWhite":0xFFFFFF} + +class RootClass(object): + """Root class for themes, songs etc + + provides interface for parsing xml files into object attributes + """ + def _setFromXml(self, xml, rootTag): + """Set song properties from given xml content + + xml (string) -- formatted as xml tags and values + rootTag -- main tag of the xml + """ + root=ElementTree(element=XML(xml)) + iter=root.getiterator() + for element in iter: + if element.tag != rootTag: + t=element.text + #print element.tag, t, type(t) + if type(t) == type(None): # easy! + val=t + if type(t) == type(" "): # strings need special handling to sort the colours out + #print "str", + if t[0] == "$": # might be a hex number + #print "hex", + try: + val=int(t[1:], 16) + except ValueError: # nope + #print "nope", + pass + elif DelphiColors.has_key(t): + #print "colour", + val=DelphiColors[t] + else: + #print "last chance", + try: + val=int(t) + #print "int", + except ValueError: + #print "give up", + val=t + if (element.tag.find("Color") > 0 or + (element.tag.find("BackgroundParameter") == 0 and type(val) == type(0))): + # convert to a QtGui.Color + val= QtGui.QColor((val>>16) & 0xFF, (val>>8)&0xFF, val&0xFF) + #print [val] + setattr(self,element.tag, val) + pass + + 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 + """ + l = [] + for k in dir(self): + if not k.startswith("_"): + l.append("%30s : %s" %(k,getattr(self,k))) + return "\n".join(l) + + def _get_as_string(self): + """Return one string with all public attributes""" + s="" + for k in dir(self): + if not k.startswith("_"): + s+= "_%s_" %(getattr(self,k)) + return s + + +blankSongXml = \ +''' + + BlankSong + + + + + 1 + 1 + 1 + 1 + + + + + + + + +''' + +class Song(RootClass) : + """Class for handling song properties""" + + def __init__(self, xmlContent = None): + """Initialize from given xml content + + xmlContent (string) -- xml formatted string + + attributes + title -- title of the song + searchableTitle -- title without punctuation chars + authorList -- list of authors + songCcliNo -- CCLI number for this song + copyright -- copyright string + showTitle -- 0: no show, 1: show + showAuthorList -- 0: no show, 1: show + showCopyright -- 0: no show, 1: show + showCcliNo -- 0: no show, 1: show + theme -- name of theme or blank + categoryArray -- list of user defined properties (hymn, gospel) + songBook -- name of originating book + songNumber -- number of the song, related to a songbook + comments -- free comment + verseOrder -- presentation order of the slides + lyrics -- simple or xml formatted (tbd) + """ + super(Song, self).__init__() + global blankSongXml + self._setFromXml(blankSongXml, "Song") + diff --git a/openlp/song/test/test_song.py b/openlp/song/test/test_song.py new file mode 100644 index 000000000..71b996e24 --- /dev/null +++ b/openlp/song/test/test_song.py @@ -0,0 +1,64 @@ +""" +OpenLP - Open Source Lyrics Projection +Copyright (c) 2008 Raoul Snyman +Portions copyright (c) 2008 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 unittest +import os +import sys +mypath=os.path.split(os.path.abspath(__file__))[0] +sys.path.insert(0,(os.path.join(mypath, '..' ,'..', '..'))) + +from openlp.song import Song + +class SongTest_Init(unittest.TestCase): + """Class for first initialization check""" + + def testCreation(self): + """Init: Create as empty""" + s = Song() + self.assertTrue(True) + + def test_str(self): + """Init: Empty, use __str__ to count attributes""" + s = Song() + r = s.__str__() + l = r.split("\n") + #print r + self.assertEqual(len(l), 16) + + def test_asString(self): + """Init: Empty asString""" + s = Song() + r = s._get_as_string() + #print r + self.assertEqual(len(r), 89) + +class SongTest_ParseText(unittest.TestCase): + """Test cases for converting from text format to Song""" + + def testSimple(self): + """Text: Simply return True""" + self.failUnless(True) + + +if "__main__" == __name__: + suite1 = unittest.TestLoader().loadTestsFromTestCase(SongTest_ParseText) + suite2 = unittest.TestLoader().loadTestsFromTestCase(SongTest_Init) + + alltests = unittest.TestSuite([suite1, suite2]) + unittest.TextTestRunner(verbosity=2).run(alltests) + \ No newline at end of file