diff -r 85b071fb75b2 -r eb9188f2ee4f web/ldt/ldt_utils/fileimport.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/web/ldt/ldt_utils/fileimport.py Fri Oct 22 18:14:30 2010 +0200 @@ -0,0 +1,398 @@ +from copy import deepcopy +from django.conf import settings +from django.core.exceptions import ObjectDoesNotExist +from ldt.utils import zipfileext +from models import Content, Media +import fnmatch +import lxml.etree +import os.path +import shutil +import tempfile +import urllib +import uuid + +class FileImportError(Exception): + def __init__(self, value): + self.value = value + def __str__(self): + return repr(self.value) + + +def Property(func): + return property(**func()) + +class IriInfo(object): + + + def __init__(self, id, order, titledesc, basepath="", videopath=settings.STREAM_URL, decoupage_blacklist = settings.DECOUPAGE_BLACKLIST, flatten = True): + self.id = id + self.basepath = basepath + self.order = order + self.src = "" + self.annotations = None + self.videopath = videopath + self.videourl = "" + self.title = None + self.desc = None + self.duration = None + self.created = False + self.content = None + self.decoupage_blacklist = decoupage_blacklist + if self.decoupage_blacklist is None: + self.decoupage_blacklist = () + self.flatten = flatten + + + + def processIri(self): + # for just import a file ldt and get the title for every media + if 'http' in self.src: + #url = urllib.urlopen(self.src) + path = url + #doc = xml.dom.minidom.parse(url) + #for import a zip, get title and copy file .iri in the media directory + else: + path = os.path.join(self.basepath, self.src) + #doc = xml.dom.minidom.parse(path) + + doc = lxml.etree.parse(path) + + + #doc = Ft.Xml.Domlette.ConvertDocument(doc) + #con = xml.xpath.Context.Context(doc, 1, 1, None) + + res = doc.xpath("/iri/head/meta[@name='title']/@content") + #res = xml.xpath.Evaluate("/iri/head/meta[@name='title']/@content", context=con) + #self.title = res[0].value + self.title = res[0] + + + #res = xml.xpath.Evaluate("/iri/body/ensembles",context=con) + res = doc.xpath("/iri/body/ensembles") + ensemblesnode = res[0] + + ensembleids = [] + + for node in ensemblesnode: #ensemblesnode.childNodes: + #if node.nodeType == xml.dom.Node.ELEMENT_NODE and node.tagName == "ensemble": + if node.tag == "ensemble": + #id = node.getAttributeNS(None,u"id") + id = node.attrib["id"] + if id not in ensembleids: + ensembleids.append(id) + + if self.annotations is not None: + newEnsemble = None + #for cnode in self.annotations.childNodes: + for cnode in self.annotations: + #if cnode.nodeType == xml.dom.Node.ELEMENT_NODE and cnode.tagName == "decoupage": + if cnode.tag == "decoupage": + if newEnsemble is None: + #newensemble = doc.createElementNS(None,'ensemble') + ensembleid = self.id+"_"+str(uuid.uuid1()) + newensemble = lxml.etree.SubElement(ensemblesnode, + 'ensemble', + {'id' : ensembleid, + 'title' : self.annotations.get('title') or "", + 'author' : self.annotations.get('author') or "", + 'date' : self.annotations.get('date') or "", + 'abstract' : self.annotations.get('abstract') or "" + } + ) + ensembleids.append(ensembleid) + newDecoupageNode = deepcopy(cnode) + newensemble.append(newDecoupageNode) + #elif cnode.nodeType == xml.dom.Node.ELEMENT_NODE and cnode.tagName == "ensemble": + elif cnode.tag == "ensemble": + #ensembleid = cnode.getAttribute(u"id") + ensembleid = cnode.attrib['id'] + cloneNode = deepcopy(cnode) + if ensembleid in ensembleids: + ensembleid = self.id+"_"+str(uuid.uuid1()) + cloneNode.set(u"id", ensembleid) + ensembleids.append(ensembleid) + ensemblesnode.append(cloneNode) + + res = doc.xpath("/iri/body/medias/media[@id='video']/video") + if self.flatten: + src_video = res[0].get('src') + self.videourl = os.path.basename(src_video) + res[0].set('src', self.videourl) + self.duration = res[0].get(u'dur') + + f = open(path, "w") + try: + #etree = lxml.etree.ElementTree(doc) + doc.write(f, encoding="UTF-8", pretty_print=True, xml_declaration=True) +# xml.dom.ext.Print(doc, stream=f) + finally: + f.close() + + + destPath = os.path.join(os.path.join(os.path.join(settings.MEDIA_ROOT, "media"), "ldt"), self.id); + if not os.path.exists(destPath): + os.makedirs(destPath) + shutil.move(os.path.join(self.basepath, self.src), os.path.join(destPath, os.path.basename(self.src))) + self.src = self.id + u"/" + os.path.basename(self.src) + + + + def saveContent(self): + + defaults_media = {'src':unicode(self.videourl), 'title':unicode(self.title), 'description':unicode(self.desc), 'videopath': unicode(self.videopath.rstrip("/") + "/")} + media, media_created = Media.objects.get_or_create(src=unicode(self.videourl), defaults = defaults_media) + if not media_created: + for key, value in defaults_media.items(): + setattr(media, key, value) + + media.save() + + defaults_content = { + 'iriurl': unicode(self.src), + 'title':unicode(self.title), + 'description':unicode(self.desc), + 'media':media, + 'iri':unicode(self.id + u"/" + os.path.basename(self.src)), + 'duration':int(self.duration) + } + content, self.created = Content.objects.get_or_create(iri_id=self.id, defaults = defaults_content) + if not self.created: + for key, value in defaults_content.items(): + setattr(content, key, value) + + content.save() + + self.content = content + + def process(self): + self.processIri() + self.saveContent() + +class BaseFileImport(object): + + def __init__(self, filepath, videopath): + self.__filepath = filepath + self.__tempdir = "" + self.__videopath = videopath + self.__author = None + + + def filepath(): #@NoSelf + doc = """Docstring""" #@UnusedVariable + + def fget(self): + return self.__filepath + + def fset(self, value): + self.__filepath = value + + def fdel(self): + del self.__filepath + + return locals() + + filepath = property(**filepath()) + + def videopath(): #@NoSelf + doc = """Docstring""" #@UnusedVariable + + def fget(self): + return self.__videopath + + def fset(self, value): + self.__videopath = value + + def fdel(self): + del self.__videopath + + return locals() + + videopath = property(**videopath()) + + def author(): #@NoSelf + doc = """Docstring""" #@UnusedVariable + + def fget(self): + return self.__author + + def fset(self, value): + self.__author = value + + def fdel(self): + del self.__author + + return locals() + + author = property(**author()) + + +class FileImport(BaseFileImport): + + def __init__(self, filepath, videopath, flatten): + BaseFileImport.__init__(self, filepath, videopath) + self.__checkExistingMedia = False + self.__flatten = flatten + + def checkExistingMedia(): #@NoSelf + doc = """Docstring""" #@UnusedVariable + + def fget(self): + return self.__checkExistingMedia + + def fset(self, value): + self.__checkExistingMedia = value + + def fdel(self): + del self.__checkExistingMedia + + return locals() + + checkExistingMedia = property(**checkExistingMedia()) + + def flatten(): #@NoSelf + doc = """Docstring""" #@UnusedVariable + + def fget(self): + return self.__flatten + + def fset(self, value): + self.__flatten = value + + def fdel(self): + del self.__flatten + + return locals() + flatten = property(**flatten()) + + def processLdt(self, ldtpath=None): + + # list iri + # see if there is some comments + # inject comment in iri + # copy iri in folder + # create or update content + contents = {} + filepath = ldtpath if ldtpath else self.filepath + doc = lxml.etree.parse(filepath) + #if ldtpath: + #doc = xml.dom.minidom.parse(ldtpath) + # doc = lxml.etree.parse(ldtpath) + #else: + #doc = xml.dom.minidom.parse(self.filepath) + + #con = xml.xpath.Context.Context(doc, 1, 1, None) + + #get author from file ldt + #result = xml.xpath.Evaluate("/iri/project", context=con) + result = doc.xpath("/iri/project") + for pnode in result: + #author = pnode.getAttributeNS(None,u"user") + author = pnode.attrib[u"user"] + if author: + self.author = unicode(author) + break + + result = doc.xpath("/iri/medias/media") + + for i, medianode in enumerate(result): + # get iri file's id from file ldt + #id = medianode.attributes['id'].value + id = medianode.attrib['id'] + if self.checkExistingMedia: + try: + Content.objects.get(iri_id=id) + do_pass = True + except ObjectDoesNotExist: #Content.DoesNotExist + do_pass = False + else: + do_pass = False + if not do_pass: + if not (contents.has_key(id)): + # Create instance iriInfo(id, order, titledesc, basepath="", videopath=settings.STREAM_URL) + if ldtpath: + contents[id] = IriInfo(id, i, "", os.path.dirname(ldtpath), flatten=self.flatten) + else: + contents[id] = IriInfo(id, i, "", flatten=self.flatten) + # Get iri file's url from ldt. This url can be relative path or absolute path. + #contents[id].src = medianode.attributes['src'].value + contents[id].src = medianode.attrib['src'] + if medianode.attrib['video'] !="": + contents[id].videopath = medianode.attrib['video'] + elif self.videopath !="" or self.videopath: + contents[id].videopath = self.videopath + else: + contents[id].videopath =settings.STREAM_URL + + + #get annotation of file ldt + result = doc.xpath("/iri/annotations/content") + + for contentnode in result: + id = contentnode.attrib['id'] + if contents.has_key(id): + if self.author: + contentnode.set("author", unicode(self.author)) + contents[id].annotations = contentnode + + #go throught values + for iriinfo in contents.values(): + + iriinfo.process() + + # if yes update + # if no create + # move iri file to the proper place + #return list of iriInfo + + def processFile(self): + if self.filepath.name.endswith(".ldt"): + self.processLdt() + elif self.filepath.name.endswith(".zip"): + self.processZip() + else: + raise FileImportError("Bad file type") + + + def processZip(self): + # """ extraire .zip, pass to method processLdt""" + # create temp directory + self.__tempdir = tempfile.mkdtemp() + openfiles = [] + flvfiles = [] + processedids = [] + + try: + zipfile = zipfileext.ZipFileExt(self.filepath) + zipfile.unzip_into_dir(self.__tempdir) + #load ldt + foldersToProcess = [self.__tempdir] + while len(foldersToProcess): + currentFolder = foldersToProcess.pop() + for entry in os.listdir(currentFolder): + if entry in settings.ZIP_BLACKLIST: + continue + entryPath = os.path.join(currentFolder, entry) + if(os.path.isdir(entryPath)): + foldersToProcess.append(entryPath) + elif fnmatch.fnmatch(entry, "*.ldt"): + ldtid = self.processLdt(entryPath) + processedids.append(ldtid) + elif fnmatch.fnmatch(entry, "*.flv"): + flvfiles.append(entryPath) + + if settings.CONTENT_ROOT and os.path.exists(settings.CONTENT_ROOT): + for entry in flvfiles: + shutil.copy(entry, settings.CONTENT_ROOT) + + finally: + for f in openfiles: + f.close() + shutil.rmtree(self.__tempdir) + # delete directory + return processedids + + # def processFileLdt(self): + # processedids = [] + # ldtid = self.processLdt(self.filepath) + # processedids.append(ldtid) + # return processedids