Merge with 1e7732f40eee37ec5413bde828a78503fae33b68
authorymh <ymh.work@gmail.com>
Tue, 12 Oct 2010 16:35:06 +0200
changeset 84 6c3162d9e632
parent 83 ec31a4bd86d3 (current diff)
parent 80 1e7732f40eee (diff)
child 85 3b70d84e661a
Merge with 1e7732f40eee37ec5413bde828a78503fae33b68
web/ldt/ldt_utils/views.py
--- a/web/ldt/ldt_utils/tests.py	Tue Oct 12 16:11:15 2010 +0200
+++ b/web/ldt/ldt_utils/tests.py	Tue Oct 12 16:35:06 2010 +0200
@@ -6,6 +6,19 @@
 """
 
 from django.test import TestCase
+import unittest
+import lxml.etree
+from models import Project, Content
+from ldt.core.models import Owner
+from utils import LdtUtils, LdtSearch, create_ldt, create_empty_iri, copy_ldt
+import base64
+import uuid
+import tempfile
+from django.contrib.auth.models import *
+from views import get_attrib
+from django.conf import settings
+
+
 
 class SimpleTest(TestCase):
     def test_basic_addition(self):
@@ -21,3 +34,146 @@
 True
 """}
 
+
+
+class UtilsTest(unittest.TestCase):
+    def setUp(self):
+	self.user = Owner()
+	self.user.username = "toto"
+	self.LU = LdtUtils()
+
+	self.project = Project(title="titleproj1", owner=self.user)
+	self.project.ldt = '<iri ldtversion="1.0.3" xmlns:dc="http://dublincore.org/documents/dcmi-namespace/"><project id="af3b99e4-b695-11df-bfde-00145ea4a2be" user="admin" title="CA:reponse a TC" abstract=""/> <medias> <media extra="" id="laurentcantet_entrelesmurs" pict="" src="http://amateur.iri.centrepompidou.fr//atelier/static/media/ldt/laurentcantet_entrelesmurs/laurentcantet_entrelesmurs.iri" video="rtmp://media.iri.centrepompidou.fr/ddc_player/video/regardssignes/"/> </medias> <annotations> <content id="laurentcantet_entrelesmurs"> <ensemble id="ens_perso" idProject="fe0d5d4c-2201-11df-8a24-00145ea4a2be" title="Decoupages personnels" author="perso" abstract=""> <decoupage id="c_EFC3FFE7-0204-A086-EBEC-D2A03A0E56CB" author="perso"> <title>CA: prof et admin</title> <abstract/> <elements> <element id="s_442AAB3A-42DA-F9BF-75E7-D2A0663FD5FF" begin="985690" dur="373222" author="" date="2010/09/02" color="16711680" src=""> <title/> <abstract/> <audio source=""/> <tags/> </element> <element id="s_0050F043-3AD2-0A7C-6699-D2A03A1EBA02" begin="5052858" dur="124407" author="" date="2010/09/02" color="10053375" src=""> <title>conseil de classe</title> <abstract>Reprise de la figure precedente</abstract> <audio source="undefined"/> <tags/> </element> </elements> </decoupage> <decoupage id="c_EEEF5C29-86E1-4AAE-E068-04EB5B00E492" author="perso"> <title>TC: prof et admin</title> <abstract/> <elements> <element id="s_880D9D4B-8BC0-BA43-5ECA-04EBA9FC9E59" begin="2426894" dur="141478" author="" date="2010/02/25" color="10053375" src=""> <title>Conseil de classe</title> <abstract/> <audio source=""/> <tags> <tag>Argumentation</tag> </tags> </element> <element id="s_D568A57C-7110-DED2-3165-04EC54387060" begin="5052858" dur="124407" author="" date="2010/02/25" color="10053375" src=""> <title>conseil de classe</title> <abstract>Reprise de la figure precedente</abstract> <audio source="undefined"/> <tags/> </element> </elements> </decoupage> </ensemble> </content> </annotations> <displays> <display id="0" title="Init view" idsel="laurentcantet_entrelesmurs" tc="2426424" zoom="0" scroll="0" infoBAB=""> <audio source=""/> <content id="laurentcantet_entrelesmurs"> <decoupage idens="en_2" id="de_PPP" tagsSelect=""/> <decoupage idens="laurentcantet_entrelesmurs" id="c_14A2E638-1936-97DC-E303-2DBA6A82A8B3" tagsSelect=""/> <decoupage idens="ens_perso" id="c_EEEF5C29-86E1-4AAE-E068-04EB5B00E492" tagsSelect=""/> <decoupage idens="ens_perso" id="c_EFC3FFE7-0204-A086-EBEC-D2A03A0E56CB" tagsSelect=""/> </content> </display> </displays> <edits> <editing id="0" tags=""> <title>Bout a bout 1</title> <abstract/> <edit id="edit1" tags=""> <eList/> <caption/> <audio/> <mList/> </edit> <edit id="edit2" tags=""> <eList/> <caption/> <audio/> <mList/> </edit> </editing> </edits> </iri>'
+	self.project.id = "11"
+	self.project.ldt_id = str(uuid.uuid1())
+	self.project.save()
+	
+	self.projectcopy = Project(title="the2ndproject")
+	self.projectcopy.id="22"
+
+    def tearDown(self):
+	self.project.delete()
+	self.projectcopy.delete()
+	#self.cont1.delete()
+	#self.cont2.delete()
+
+    def test_generate_ldt(self):
+	self.cont1 = Content(iriurl="id1/iriurl1")
+	self.cont1.iri_id = "id1"
+	self.cont1.save()
+	
+	self.cont2 = Content(iriurl="id2/iriurl2")
+	self.cont2.iri_id = "id2"
+	self.cont2.save()
+	
+	self.project.contents.add(self.cont1,self.cont2)
+
+	f=tempfile.TemporaryFile(mode='r+')
+	self.LU.generateLdt(Content.objects.all(),f)
+	f.seek(0)
+	ldoc = lxml.etree.parse(f)
+	self.assertEqual(ldoc.xpath("/iri/displays/display/content")[9].get("id"),self.cont2.iri_id)
+	self.assertEqual(ldoc.xpath("/iri/medias/media")[8].get("id"), self.cont1.iri_id)
+	f.close()
+
+    def test_generate_init(self):
+	self.cont3 = Content(iriurl="id3/iriurl1")
+	self.cont3.iri_id = "id3"
+	self.cont3.save()
+	
+	self.cont4 = Content(iriurl="id4/iriurl2")
+	self.cont4.iri_id = "id4"
+	self.cont4.save()
+	
+	self.project.contents.add(self.cont3,self.cont4)
+	ldoc = self.LU.generateInit(None,None)
+	self.assertEqual(ldoc.xpath("/iri/files/init")[0].tag, "init")
+	self.assertEqual(ldoc.xpath("/iri/files/library")[0].tag, "library")
+	self.assertEqual(ldoc.xpath("/iri/files/init/file")[0].get("video"), settings.STREAM_URL)
+
+    def test_create_ldt(self):
+	self.cont5 = Content(iriurl="id5/iriurl1")
+	self.cont5.iri_id = "id5"
+	self.cont5.save()
+	
+	self.cont6 = Content(iriurl="id6/iriurl2")
+	self.cont6.iri_id = "id6"
+	self.cont6.save()
+	
+	self.project.contents.add(self.cont5,self.cont6)
+	self.project.ldt=""
+	create_ldt(self.project, self.user)
+	ldt = lxml.etree.fromstring(self.project.ldt)
+	self.assertEqual(ldt.xpath("/iri")[0].tag,"iri")
+	self.assertEqual(ldt.xpath("/iri/project")[0].get("title"), self.project.title)
+	self.assertEqual(ldt.xpath("/iri/medias/media")[0].get("src"), self.cont5.iri_url())
+	self.assertEqual(ldt.xpath("/iri/medias/media")[1].get("id"), self.cont6.iri_id)
+
+    def test_copy_ldt(self):
+	self.cont7 = Content(iriurl="id7/iriurl1")
+	self.cont7.iri_id = "id7"
+	self.cont7.save()
+	
+	self.cont8 = Content(iriurl="id8/iriurl2")
+	self.cont8.iri_id = "id8"
+	self.cont8.save()
+	
+	self.project.contents.add(self.cont7,self.cont8)
+	copy_ldt(self.project, self.projectcopy, self.user)
+	ldt1=lxml.etree.fromstring(self.project.ldt)
+	ldt2=lxml.etree.fromstring(self.projectcopy.ldt)
+	self.assertTrue(ldt1.xpath("/iri/project")[0].get("id")!= ldt2.xpath("/iri/project")[0].get("id"))
+	self.assertEqual(ldt1.xpath("/iri/medias/media")[0].get("id"),ldt2.xpath("/iri/medias/media")[0].get("id"))
+	self.assertEqual(ldt1.xpath("/iri/annotations/content/ensemble")[0].get("title"),ldt2.xpath("/iri/annotations/content/ensemble")[0].get("title"))
+	self.assertEqual(ldt1.xpath("/iri/annotations/content/ensemble/decoupage")[0].get("id"),ldt2.xpath("/iri/annotations/content/ensemble/decoupage")[0].get("id"))
+	self.assertEqual(ldt1.xpath("/iri/annotations/content/ensemble/decoupage/title")[1].text,ldt2.xpath("/iri/annotations/content/ensemble/decoupage/title")[1].text.strip("\n\t"))
+
+    def test_create_empty_iri(self):
+	self.cont9 = Content(iriurl="id9/iriurl1")
+	self.cont9.iri_id = "id9"
+	self.cont9.save()
+	
+	self.cont10 = Content(iriurl="id10/iriurl2")
+	self.cont10.iri_id = "id10"
+	self.cont10.save()
+	
+	self.project.contents.add(self.cont9,self.cont10)
+	tmp = tempfile.TemporaryFile(mode='r+')
+	create_empty_iri(tmp, self.cont9, "admin")
+	tmp.seek(0)
+	ldoc = lxml.etree.parse(tmp)
+	self.assertEqual(ldoc.xpath("/iri/head/meta")[0].get("content"), self.cont9.iri_id)
+	self.assertEqual(ldoc.xpath("/iri/body/medias/media/video")[0].get("id"), self.cont9.iri_id)
+	tmp.close()
+	
+
+
+
+class ViewsTest(unittest.TestCase):
+    def setUp(self):
+	self.project = Project()
+	self.project.id = "121"
+	self.project.save()
+        self.project.ldt = '<iri ldtversion="1.0.3" xmlns:dc="http://dublincore.org/documents/dcmi-namespace/"><project id="af3b99e4-b695-11df-bfde-00145ea4a2be" user="admin" title="CA:reponse a TC" abstract=""/> <medias> <media extra="" id="laurentcantet_entrelesmurs" pict="" src="http://amateur.iri.centrepompidou.fr//atelier/static/media/ldt/laurentcantet_entrelesmurs/laurentcantet_entrelesmurs.iri" video="rtmp://media.iri.centrepompidou.fr/ddc_player/video/regardssignes/"/> </medias> <annotations> <content id="laurentcantet_entrelesmurs"> <ensemble id="ens_perso" idProject="fe0d5d4c-2201-11df-8a24-00145ea4a2be" title="Decoupages personnels" author="perso" abstract=""> <decoupage id="c_EFC3FFE7-0204-A086-EBEC-D2A03A0E56CB" author="perso"> <title>CA: prof et admin</title> <abstract/> <elements> <element id="s_442AAB3A-42DA-F9BF-75E7-D2A0663FD5FF" begin="985690" dur="373222" author="" date="2010/09/02" color="16711680" src=""> <title/> <abstract/> <audio source=""/> <tags/> </element> <element id="s_0050F043-3AD2-0A7C-6699-D2A03A1EBA02" begin="5052858" dur="124407" author="" date="2010/09/02" color="10053375" src=""> <title>conseil de classe</title> <abstract>Reprise de la figure precedente</abstract> <audio source="undefined"/> <tags/> </element> </elements> </decoupage> <decoupage id="c_EEEF5C29-86E1-4AAE-E068-04EB5B00E492" author="perso"> <title>TC: prof et admin</title> <abstract/> <elements> <element id="s_880D9D4B-8BC0-BA43-5ECA-04EBA9FC9E59" begin="2426894" dur="141478" author="" date="2010/02/25" color="10053375" src=""> <title>Conseil de classe</title> <abstract/> <audio source=""/> <tags> <tag>Argumentation</tag> </tags> </element> <element id="s_D568A57C-7110-DED2-3165-04EC54387060" begin="5052858" dur="124407" author="" date="2010/02/25" color="10053375" src=""> <title>conseil de classe</title> <abstract>Reprise de la figure precedente</abstract> <audio source="undefined"/> <tags/> </element> </elements> </decoupage> </ensemble> </content> </annotations> <displays> <display id="0" title="Init view" idsel="laurentcantet_entrelesmurs" tc="2426424" zoom="0" scroll="0" infoBAB=""> <audio source=""/> <content id="laurentcantet_entrelesmurs"> <decoupage idens="en_2" id="de_PPP" tagsSelect=""/> <decoupage idens="laurentcantet_entrelesmurs" id="c_14A2E638-1936-97DC-E303-2DBA6A82A8B3" tagsSelect=""/> <decoupage idens="ens_perso" id="c_EEEF5C29-86E1-4AAE-E068-04EB5B00E492" tagsSelect=""/> <decoupage idens="ens_perso" id="c_EFC3FFE7-0204-A086-EBEC-D2A03A0E56CB" tagsSelect=""/> </content> </display> </displays> <edits> <editing id="0" tags=""> <title>Bout a bout 1</title> <abstract/> <edit id="edit1" tags=""> <eList/> <caption/> <audio/> <mList/> </edit> <edit id="edit2" tags=""> <eList/> <caption/> <audio/> <mList/> </edit> </editing> </edits> </iri>' 
+
+	self.cont1 = Content(iriurl="/laurentcantet_entrelesmurs/iriurl1")
+	self.cont1.iri_id = 'laurentcantet_entrelesmurs'
+	self.cont1.save()
+
+	self.cont2 = Content(iriurl="/content_notinldt/iriurl2")
+	self.cont2.iri_id = 'content_notinldt'
+	self.cont2.save()
+	
+	self.project.contents.add(self.cont1, self.cont2)
+
+    def tearDown(self):
+	self.project.delete()
+	##self.cont1.delete()
+	##self.cont2.delete()
+
+    def test_get_attrib(self):
+	get_attrib(self.project)
+	ldoc = lxml.etree.fromstring(self.project.ldt)	
+	self.assertEqual(self.project.title, ldoc.xpath("/iri/project")[0].get("title"))
+	self.assertEqual(ldoc.xpath("/iri/medias/media")[0].get('id'), self.cont1.iri_id)
+	self.assertTrue(self.cont2.iri_id not in self.project.contents.all())
--- a/web/ldt/ldt_utils/utils.py	Tue Oct 12 16:11:15 2010 +0200
+++ b/web/ldt/ldt_utils/utils.py	Tue Oct 12 16:35:06 2010 +0200
@@ -1,17 +1,11 @@
 import lucene
 from ldt.ldt_utils import STORE
 from ldt.ldt_utils import ANALYZER
-from Ft.Xml import MarkupWriter
 import uuid
 import django.core.urlresolvers
 from django.conf import settings
 import urllib
-import xml.dom
-import xml.dom.minidom
-import xml.dom.ext
-import xml.xpath
 import datetime
-import Ft
 import lxml.etree
 
 __BOOLEAN_DICT = {
@@ -57,206 +51,217 @@
     
     def generateLdt(self, contentList, file, title = u"", author=u"IRI Web", web_url=u"", media_url="", startSegment = None, contributions=None):
 
-        writer = MarkupWriter(file, indent = u"yes")
-        writer.startDocument()
-        writer.startElement(u"iri")
-        writer.simpleElement(u"project", attributes={u"id":unicode(str(uuid.uuid1())), u"title":unicode(title) , u"user":author, u"abstract":u""})
-        writer.startElement(u"medias")
-        for content in contentList:
-            videopath = unicode(settings.STREAM_URL)
-            if content.videopath :
-                videopath = unicode(content.videopath)
-            writer.simpleElement(u"media", attributes={u"id":content.iri_id,u"src":content.iri_url(web_url),u"video":videopath,u"pict":u"",u"extra":u""})
-        writer.endElement(u"medias")
+	iri = lxml.etree.Element(u'iri')
+	doc = lxml.etree.ElementTree(iri)
+
+	project = lxml.etree.SubElement(iri, u'project')
+	project.set(u"id",unicode(str(uuid.uuid1())))
+        project.set(u"title",unicode(title))
+	project.set(u"user",author)
+	project.set(u"abstract",u"")
+
+	medias = lxml.etree.SubElement(iri, u"medias")
+	for content in contentList:
+	    videopath = unicode(settings.STREAM_URL)
+	    if content.videopath :
+		videopath = unicode(content.videopath)
+	    media = lxml.etree.SubElement(medias, "media")
+	    media.set(u"id",content.iri_id)
+	    media.set(u"src",content.iri_url(web_url))
+	    media.set(u"video",videopath)
+            media.set(u"pict",u"")
+            media.set(u"extra",u"")
 
         if contributions is None:
             contributions = []
         annotations_nodes = {}
         for contrib in contributions:
-            doc = xml.dom.minidom.parseString(contrib.ldtproject.ldt.encode("utf-8"))
-            con = xml.xpath.Context.Context(doc, 1, 1, None)
-            res = xml.xpath.Evaluate("/iri/annotations/content", context=con)
+	    ldtdoc = lxml.etree.fromstring(contrib.ldtproject.ldt.encode("utf-8"))
+	    res = ldtdoc.xpath("/iri/annotations/content")
+
             for content in res:
-                contentid = content.getAttribute("id")
+		contentid = content.get("id")
                 if annotations_nodes.has_key(contentid):
                     contentnode = annotations_nodes[contentid]
                 else:
                     contentnode = {"id":contentid, "ensembles":[]}
                     annotations_nodes[contentid]=contentnode
                 for ens in content.childNodes:
-                    if ens.nodeType == xml.dom.Node.ELEMENT_NODE and ens.tagName.endswith("ensemble"):
-                        contentnode["ensembles"].append(ens.toprettyxml())
+		    if ens.tag.endswith("ensemble"):
+			contentnode["ensembles"].append(ens.tag)
+
 
         if len(annotations_nodes) > 0:
-            writer.startElement(u"annotations")
+	    annotations = lxml.etree.SubElement(iri, "annotations")
             for content in contentList:
                 if content.content_base.iri_id in annotations_nodes:
                     contentnode = annotations_nodes[content.content_base.iri_id]
                     if contentnode is not None:
                         if len(contentnode["ensembles"])>0:
-                            writer.startElement(u"content", attributes={"id":contentnode["id"]})
-                            writer.text(u"")
-                            for ens in contentnode["ensembles"]:
-                                writer.xmlFragment(ens.encode("utf-8"))
-                            writer.endElement(u"content")
+			    content = lxml.etree.SubElement(annotation, "content")
+			    content.set("id",contentnode["id"])
+                            content.text = u""
                         else:
-                            writer.simpleElement(u"content", attributes={"id":contentnode["id"]})
-            writer.endElement(u"annotations")
+			    content = lxml.etree.SubElement(annotation, "content")
+			    content.set("id",contentnode["id"])
+
         else:
-            writer.simpleElement(u"annotations")
+	    annotations = lxml.etree.SubElement(iri, "annotations")
 
 
-        writer.startElement(u"displays")
+	displays = lxml.etree.SubElement(iri, "displays")
         if len(contentList) > 0:
-            writer.startElement(u"display", attributes={u"id":u"0",u"title":u"generated",u"idsel":contentList[0].iri_id,u"tc":u"0"})
+	    display = lxml.etree.SubElement(displays, "display")
+	    display.set(u"id",u"0")
+	    display.set(u"title",u"generated")
+	    display.set(u"idsel",contentList[0].iri_id)
+	    display.set(u"tc",u"0")
             for content in contentList:
-                writer.startElement(u"content", attributes={u"id":content.iri_id})
+		contentd = lxml.etree.SubElement(display,"content")
+		contentd.set(u"id",content.iri_id)
                 filepath = urllib.urlopen(content.iri_url())
-                doc = xml.dom.minidom.parse(filepath)
-                con = xml.xpath.Context.Context(doc, 1, 1, None)
-                res = xml.xpath.Evaluate("/iri/body/ensembles/ensemble/decoupage", context=con)
+		
+		udoc = lxml.etree.parse(filepath)
+		res = udoc.xpath("/iri/body/ensembles/ensemble/decoupage")
                 for decoupagenode in res:
                     decoupage_id = decoupagenode.getAttribute(u"id")
                     ensemble_id = decoupagenode.parentNode.getAttribute(u"id")
-                    writer.simpleElement(u"decoupage", attributes={u"id":decoupage_id,u"idens":ensemble_id})
-                writer.endElement(u"content")
+		    decoupage_id = decoupagenode.get(u"id")
+		    ensemble_id = decoupagenode.getparent().get(u"id")
+		    decoupage = lxml.etree.SubElement(content,"decoupage")
+		    decoupage.set(u"id",decoupage_id)
+		    decoupage.set(u"idens",ensemble_id)
             if startSegment is not None:
-                writer.startElement(u"activeSegment")
-                writer.simpleElement(u"id",attributes={u"idctt" : startSegment["idcontent"],u"idens" : startSegment["idgroup"], u"idcut" : startSegment["idcutting"], u"idseg" : startSegment["idsegment"]})
-                writer.endElement(u"activeSegment")
+		activeSegment = lxml.etree.SubElement(display,"activeSegment")
+		idas = lxml.etree.SubElement(activeSegment,"id")
+		idas.set(u"idctt",startSegment["idcontent"])
+                idas.set(u"idens" ,startSegment["idgroup"])
+                idas.set(u"idcut",startSegment["idcutting"])
+                idas.set(u"idseg",startSegment["idsegment"])
 
-            writer.endElement(u"display")
-        writer.endElement(u"displays")
-        writer.simpleElement(u"edits")
-        writer.endElement(u"iri")
+	edits = lxml.etree.SubElement(iri, "edits")
+	
+	doc.write(file, pretty_print=True)
+
 
     def generateInit(self, url, method, search=None):
         
-        import xml.dom
-        import xml.dom.ext
-    
-        impl = xml.dom.getDOMImplementation()
-        doc = impl.createDocument(xml.dom.EMPTY_NAMESPACE, 'iri', None)
-    
-        elementFiles = doc.createElement('files')
-        doc.documentElement.appendChild(elementFiles)
-    
-        elementInit = doc.createElement('init')
-        elementFiles.appendChild(elementInit)
-    
-        elementfile = doc.createElement('file')
+	iri = lxml.etree.Element('iri')
+	impl = lxml.etree.ElementTree(iri)
+ 
+	elementFiles = lxml.etree.SubElement(iri,'files')    
+	elementInit = lxml.etree.SubElement(elementFiles, 'init')
+	elementfile = lxml.etree.SubElement(elementInit, 'file')
             
-        elementfile.setAttribute('src',settings.WEB_URL + django.core.urlresolvers.reverse(method, args=url))
-        elementfile.setAttribute('display', '1')
-        if(search):
-            elementfile.setAttribute("segsel",settings.WEB_URL + django.core.urlresolvers.reverse(search, args=url))
-    
+	elementfile.set('src',settings.WEB_URL + django.core.urlresolvers.reverse(method, args=url))
+	elementfile.set('display', '1')
+	if(search):
+	    elementfile.set("segsel",settings.WEB_URL + django.core.urlresolvers.reverse(search, args=url))   
+
     
         # /*chemin video : tant que le serveur de media n'est pas up, */
-        elementfile.setAttribute('video', settings.STREAM_URL)
-        elementfile.setAttribute('pict', "")
-        elementfile.setAttribute('extra', "")
-    
-        elementInit.appendChild(elementfile);
-    
-        elementRecent = doc.createElement('recent');
-        elementFiles.appendChild(elementRecent);
-    
-    
-        elementLibrary = doc.createElement('library');
-        elementFiles.appendChild(elementLibrary);
+	elementfile.set('video', settings.STREAM_URL)
+	elementfile.set('pict', "")
+	elementfile.set('extra', "")    
+
+    	elementRecent = lxml.etree.SubElement(elementFiles, 'recent')
+	elementLibrary = lxml.etree.SubElement(elementFiles, 'library')
     
         username = ''
         id = ''
-        elementUser = doc.createElement('user')
-        elementUser.setAttribute('name', username)
-        elementUser.setAttribute('id', id)
-        doc.documentElement.appendChild(elementUser)
+
+	elementUser = lxml.etree.SubElement(iri, 'user')
+	elementUser.set('name', username)
+	elementUser.set('id', id)
         
-        return doc
+        return iri 
+
+
 
 def create_ldt(project, user):
     
-    contentList=project.contents.all()
+    contentList = project.contents.all()
     
     """create xml"""
     
     # create a dom
-    impl = xml.dom.getDOMImplementation()
-    dom = impl.createDocument(xml.dom.EMPTY_NAMESPACE, 'iri', None)
+    iri = lxml.etree.Element('iri')
+    doc = lxml.etree.ElementTree(iri)
+    
     #node project
-    elementProject = dom.createElement('project')
-    dom.documentElement.appendChild(elementProject)
-    
+    elementProject = lxml.etree.SubElement(iri, 'project')
     
-    elementProject.setAttribute('abstract', "")
-    elementProject.setAttribute('title', project.title)
-    elementProject.setAttribute('user', user.username)
-    elementProject.setAttribute('id', project.ldt_id)
+    elementProject.set('abstract', "")
+    elementProject.set('title', project.title)
+    elementProject.set('user', user.username)
+    elementProject.set('id', project.ldt_id)
+
     #node medias
-    elementMedias = dom.createElement('medias')
-    dom.documentElement.appendChild(elementMedias)
+    elementMedias = lxml.etree.SubElement(iri, 'medias')
     
     idsel = None      
     for content in contentList:
         if not idsel:
             idsel = content.iri_id
-        elementMedia = dom.createElement('media')            
-        elementMedia.setAttribute('id', content.iri_id)
-        elementMedia.setAttribute('src', content.iri_url())
+	elementMedia = lxml.etree.SubElement(elementMedias, 'media')
+	elementMedia.set('id', content.iri_id)
+	elementMedia.set('src', content.iri_url())
+
         if content.videopath and content.videopath !="":
-            elementMedia.setAttribute('video', content.videopath)
+	    elementMedia.set('video', content.videopath)
         else:
-            elementMedia.setAttribute('video', settings.STREAM_URL)
-        elementMedia.setAttribute('pict', "")
-        elementMedia.setAttribute('extra', "")
-        elementMedias.appendChild(elementMedia)
+	    elementMedia.set('video', settings.STREAM_URL)
+	elementMedia.set('pict', "")
+	elementMedia.set('extra', "")
+
     if not idsel:
         idsel = ""
 
     #node annotations
-    elementAnnotations = dom.createElement('annotations')
-    dom.documentElement.appendChild(elementAnnotations)
+    elementAnnotations = lxml.etree.SubElement(iri, 'annotations')
+    
     #node displays
-    elementDisplays = dom.createElement('displays')
-    elementDisplay = dom.createElement('display')
-    elementDisplay.setAttribute('id', '0')
-    elementDisplay.setAttribute('title', 'Init view')
-    elementDisplay.setAttribute('idsel', idsel)
-    elementDisplay.setAttribute('tc', '0')
-    elementDisplay.setAttribute('zoom', '0')
-    elementDisplay.setAttribute('scroll', '0')
-    elementDisplay.setAttribute('infoBAB', '')
+    elementDisplays = lxml.etree.SubElement(iri, 'displays')
+    elementDisplay = lxml.etree.SubElement(elementDisplays, 'display')
+    elementDisplay.set('id', '0')
+    elementDisplay.set('title', 'Init view')
+    elementDisplay.set('idsel', idsel)
+    elementDisplay.set('tc', '0')
+    elementDisplay.set('zoom', '0')
+    elementDisplay.set('scroll', '0')
+    elementDisplay.set('infoBAB', '')
+
+    
     #node content
     for content in contentList:
-        elementContent = dom.createElement('content')
-        elementContent.setAttribute('id', content.iri_id)
+	elementContent = lxml.etree.SubElement(elementDisplay, 'content')
+	elementContent.set('id', content.iri_id)
+
         if not 'http' in content.iriurl:
         #eg: "iiiielizabethrosse/ENMI08-III_elizabethrosse.iri"
             url = content.iri_url()
         else:
             url =content.iriurl
         file = urllib.urlopen(url)
-        doc = xml.dom.minidom.parse(file)
-        con = xml.xpath.Context.Context(doc, 1, 1, None)
-        res = xml.xpath.Evaluate("/iri/body/ensembles/ensemble/decoupage", context=con)
-        #node decoupage
+	doc = lxml.etree.parse(file)
+	res = doc.xpath("/iri/body/ensembles/ensemble/decoupage")        
+
+
+	#node decoupage
         for decoupagenode in res:
-            decoupage_id = decoupagenode.getAttribute(u"id")
-            ensemble_id = decoupagenode.parentNode.getAttribute(u"id")
-            elementDecoupage = dom.createElement('decoupage')
-            elementDecoupage.setAttribute('idens', ensemble_id)
-            elementDecoupage.setAttribute('id', decoupage_id)
-            elementContent.appendChild(elementDecoupage)     
-        elementDisplay.appendChild(elementContent)   
+	    decoupage_id = decoupagenode.attrib(u"id")
+	    parent= decoupagenode.getparent()
+	    ensemble_id = parent.attrib(u"id")
+	    elementDecoupage = etree.SubElement(elementContent, 'decoupage')
+	    elementDecoupage.set('idens', ensemble_id)
+	    elementDecoupage.set('id', decoupage_id)
     
-    elementDisplays.appendChild(elementDisplay)
-    dom.documentElement.appendChild(elementDisplays)
+    #node edits
+    elementEdits = lxml.etree.SubElement(iri, 'edits')
     
-    elementEdits = dom.createElement('edits')
-    dom.documentElement.appendChild(elementEdits)
-    # write dom in Project.ldt 
-    project.ldt = dom.documentElement.toprettyxml()
+    #write dom in Project.ldt 
+    project.ldt = lxml.etree.tostring(iri, pretty_print=True)
+    
     #save Project
     project.save()
     return project        
@@ -272,67 +277,74 @@
     
     """create xml"""
     
-    # create a dom
-    dom = xml.dom.minidom.parseString(project.ldt.encode("utf-8"))
-    con = xml.xpath.Context.Context(dom, 1, 1, None)
-    res = xml.xpath.Evaluate("iri/project", context=con)
+    ldt = lxml.etree.fromstring(project.ldt.encode("utf-8"))
+    res = ldt.xpath("/iri/project")
     for elementProject in res:
-        elementProject.setAttribute('abstract', "")
-        elementProject.setAttribute('title', new_project.title)
-        elementProject.setAttribute('user', user.username)
-        elementProject.setAttribute('id', new_project.ldt_id)
+	elementProject.set('abstract', "")
+	elementProject.set('title', new_project.title)
+	elementProject.set('user', user.username)
+	elementProject.set('id', new_project.ldt_id)
         
-    new_project.ldt = dom.documentElement.toprettyxml()
+    new_project.ldt = lxml.etree.tostring(ldt, pretty_print=True)
+
     #save Project
     new_project.save()
     return new_project
 
 def create_empty_iri(file, content, username):
     
-    writer = MarkupWriter(file, indent = u"yes")
-    writer.startDocument()
-    writer.startElement(u"iri")
-    
-    writer.startElement(u"head")
-    
-    writer.simpleElement(u'meta', attributes={u'name':u'id', 'content':unicode(content.iri_id)})
-    writer.simpleElement(u'meta', attributes={u'name':u'title', 'content':unicode(content.title)})
-    writer.simpleElement(u'meta', attributes={u'name':u'abstract', 'content':unicode(content.description)})
-    writer.simpleElement(u'meta', attributes={u'name':u'author', 'content':unicode(username)})
-    writer.simpleElement(u'meta', attributes={u'name':u'contributor', 'content':unicode(username)})
-    writer.simpleElement(u'meta', attributes={u'name':u'date', 'content':unicode(datetime.date.today().isoformat())})
-    writer.simpleElement(u'meta', attributes={u'name':u'copyright', 'content':u'IRI'})
-    writer.simpleElement(u'meta', attributes={u'name':u'type', 'content':u'video'})    
-    
-    writer.endElement(u"head")
+    iri = lxml.etree.Element('iri')
+    doc = lxml.etree.ElementTree(iri)
 
-    writer.startElement(u"body")
-    
-    writer.startElement(u"ensembles")
-    writer.endElement(u"ensembles")
-    
-    writer.simpleElement(u'links')
-    writer.startElement(u"medias")
-
-    writer.startElement(u"media", attributes={u'id':u'video'})
-    writer.simpleElement(u'video', attributes={u'src':unicode(content.stream_src),u'id':unicode(content.iri_id),u'dur':unicode(content.duration),u'begin':u'0'})
-    writer.endElement(u"media")
+    head = lxml.etree.SubElement(iri, 'head')
+    meta1 = lxml.etree.SubElement(head, 'meta')
+    meta1.set(u'name', u'id')
+    meta1.set(u'content', unicode(content.iri_id))
+    meta2 = lxml.etree.SubElement(head, 'meta')
+    meta2.set(u'name',u'title')
+    meta2.set(u'content', unicode(content.title))
+    meta3 = lxml.etree.SubElement(head, 'meta')
+    meta3.set(u'name',u'abstract')
+    meta3.set(u'content', unicode(content.description))
+    meta4 = lxml.etree.SubElement(head, 'meta')
+    meta4.set(u'name',u'author')
+    meta4.set(u'content', unicode(username))
+    meta5 = lxml.etree.SubElement(head, 'meta')
+    meta5.set(u'name',u'contributor')
+    meta5.set(u'content', unicode(username))
+    meta6 = lxml.etree.SubElement(head, 'meta')
+    meta6.set(u'name',u'date')
+    meta6.set(u'content', unicode(datetime.date.today().isoformat()))
+    meta7 = lxml.etree.SubElement(head, 'meta')
+    meta7.set(u'name',u'copyright')
+    meta7.set(u'content', u'IRI')
+    meta8 = lxml.etree.SubElement(head, 'meta')
+    meta8.set(u'name', u'type')
+    meta8.set(u'content', u'video')
 
-    writer.startElement(u"media", attributes={u'id':u'tool'})
-    writer.simpleElement(u'tool')
-    writer.endElement(u"media")
+    body = lxml.etree.SubElement(iri, 'body')
+    ensembles = lxml.etree.SubElement(body, 'ensembles')
+    links = lxml.etree.SubElement(body, 'links')
+
+    medias = lxml.etree.SubElement(body, 'medias')
 
-    writer.endElement(u"medias")
-    
-    #writer.startElement(u'display', attributes={u'id':unicode(uuid.uuid1()), u'title':u"default", u"idsel":unicode(content.iri_id), u"tc":u"0", u"zoom":u"0", u"scroll":u"0", u"infoBAB":u""})
-    writer.simpleElement(u'display')
-    
-    writer.endElement(u"body")
+    media1 = lxml.etree.SubElement(medias, 'media')
+    media1.set(u'id',u'video')
+    video = lxml.etree.SubElement(media1, 'video')
+    video.set(u'src',unicode(content.stream_src))
+    video.set(u'id',unicode(content.iri_id))
+    video.set(u'dur',unicode(content.duration))
+    video.set(u'begin',u'0')
 
-    
-    writer.endElement(u"iri")
-    writer.endDocument()
-    
+    media2 = lxml.etree.SubElement(medias, 'media')
+    media2.set(u'id',u'tool')
+    tool = lxml.etree.SubElement(media2, 'tool')
+
+    display = lxml.etree.SubElement(body, 'display')
+
+    doc.write(file, pretty_print=True)
+
+
 def update_iri(filepath, content, username):
     
     # open xml
--- a/web/ldt/ldt_utils/views.py	Tue Oct 12 16:11:15 2010 +0200
+++ b/web/ldt/ldt_utils/views.py	Tue Oct 12 16:35:06 2010 +0200
@@ -34,10 +34,6 @@
 import tempfile
 import urllib2
 import uuid
-import xml.dom
-import xml.dom.ext
-import xml.dom.minidom
-
     
 def searchForm(request):
     form = SearchForm()
@@ -73,7 +69,7 @@
     doc = ldtgen.generateInit([field,query], 'ldt.ldt_utils.views.searchLdt', 'ldt.ldt_utils.views.searchSegments')
     
     resp = HttpResponse(mimetype="text/xml;charset=utf-8")
-    xml.dom.ext.PrettyPrint(doc, resp)
+    doc.write(resp, pretty_print=True)
     return resp
 
 def searchLdt(request, field, query, edition=None):
@@ -120,21 +116,25 @@
     if edition is not None:
         iri_ids = map(lambda t:t[0], filter(lambda id: id[0] is not None, Speak.objects.filter(session__day__edition=edition).order_by("session__start_ts", "order").values_list("content__iri_id")))
 
-    doc = xml.dom.getDOMImplementation().createDocument(None, "iri", None)
+    iri = lxml.etree.Element('iri')
+    doc = lxml.etree.ElementTree(iri)	
 
     for resultMap in res:
         if iri_ids is None or resultMap['iri_id'] in iri_ids:
-            elem = doc.createElement('seg')
-            elem.setAttribute('idctt', resultMap['iri_id'])
-            elem.setAttribute('idens', resultMap['ensemble_id'])
-            elem.setAttribute('iddec', resultMap['decoupage_id'])
-            elem.setAttribute('idseg', resultMap['element_id'])
-            elem.setAttribute('idvue', "")
-            elem.setAttribute('crit', "")
-            doc.documentElement.appendChild(elem)
+	    seg = etree.SubElement(iri, 'seg')
+	    seg.set('idctt', resultMap['iri_id'])
+            seg.set('idens', resultMap['ensemble_id'])
+            seg.set('iddec', resultMap['decoupage_id'])
+            seg.set('idseg', resultMap['element_id'])
+            seg.set('idvue', "")
+	    seg.set('crit', "")
 
-    return HttpResponse(doc.toprettyxml(encoding='utf-8'), mimetype="text/xml;charset=utf-8")
-    
+    return doc  
+  
+    return HttpResponse(lxml.etree.tostring(doc, pretty_print=True), mimetype="text/xml;charset=utf-8") 
+
+
+
 @login_required         
 def list_ldt(request):
     contents = Content.objects.all()
@@ -199,7 +199,7 @@
     resp = HttpResponse(mimetype="text/xml")
     resp['Cache-Control']='no-cache, must-revalidate'
     resp['Pragma']='no-cache'
-    xml.dom.ext.PrettyPrint(doc, resp)
+    doc.write(resp, pretty_print=True) 
     return resp
        
 def ldtProject(request, id):
@@ -215,7 +215,7 @@
 def project_json_id(request, id):
     
     project = get_object_or_404(Project,ldt_id=id)
-        
+
     return project_json(request, project)
 
 
@@ -327,32 +327,42 @@
         ldt = request.POST['ldt']
         id = request.POST['id']
         ldtproject=Project.objects.get(ldt_id=id)
-        #save xml ldt
+
+	    #save xml ldt
         ldtproject.ldt=ldt
-        #get new title
-        dom = xml.dom.minidom.parseString(ldt.encode( "utf-8" ))
-        con = xml.xpath.Context.Context(dom, 1, 1, None)
-        result = xml.xpath.Evaluate("/iri/project",context=con)
-        for pnode in result:
-            title=pnode.getAttribute("title")
-            break
-        #set new title
-        ldtproject.title=title
-        #get new content list
-        new_contents=[]
-        result = xml.xpath.Evaluate("/iri/medias/media", context=con)
-        for medianode in result:
-            id = medianode.attributes['id'].value
-            new_contents.append(id)
-        # set new content list
-        for c in ldtproject.contents.all():
-            if not c.iri_id in new_contents:
-                ldtproject.contents.remove(c)           
-        ldtproject.save()
+
+        ldtproj = get_attrib(ldtproject)
+        ldtproj.save()
     else:
         ldt = ''
+    
     return render_to_response('ldt/ldt_utils/save_done.html', {'ldt': ldt, 'id':id, 'title':title, 'contents': new_contents}, context_instance=RequestContext(request))
+
     
+def get_attrib(ldtproject):
+
+    doc = lxml.etree.fromstring(ldtproject.ldt.encode( "utf-8" ))
+    result = doc.xpath("/iri/project")
+	
+	#set new title
+    ldtproject.title = result[0].get("title")
+	
+	#get new content list
+    new_contents=[]
+    result = doc.xpath("/iri/medias/media")
+    for medianode in result:
+        id = medianode.get("id")
+        new_contents.append(id)
+
+    #set new content list
+    for c in ldtproject.contents.all():
+        if not c.iri_id in new_contents:
+            ldtproject.contents.remove(c)
+
+	return ldtproject
+
+
+
 @login_required    
 def publish(request, id, redirect=True):
     ldt = get_object_or_404(Project, ldt_id=id)
@@ -386,8 +396,6 @@
 
 def ldt(request, url, startSegment = None):
 
-    import Ft
-    from Ft.Xml import MarkupWriter
     
     resp = HttpResponse(mimetype="text/xml; charset=utf-8")
     resp['Cache-Control'] = 'no-cache'