from copy import deepcopy #@UnresolvedImport
from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist
from django.db import transaction
from ldt.utils import zipfileext
from models import Content, Media
import fnmatch
import lxml.etree
import mimetypes #@UnresolvedImport
import os.path
import shutil #@UnresolvedImport
import tempfile #@UnresolvedImport
import uuid #@UnresolvedImport
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 process_iri(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 = self.src
#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) #@UndefinedVariable
#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, #@UndefinedVariable
'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(settings.MEDIA_ROOT, "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)
@transaction.commit_on_success
def save_content(self):
defaults_media = {
'src':unicode(self.videourl),
'mimetype_field': mimetypes.guess_type(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 = {
'title':unicode(self.title),
'description':unicode(self.desc),
'media_obj':media,
'iriurl':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.process_iri()
self.save_content()
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.__check_existing_media = False
self.__flatten = flatten
def check_existing_media(): #@NoSelf
doc = """Docstring""" #@UnusedVariable
def fget(self):
return self.__check_existing_media
def fset(self, value):
self.__check_existing_media = value
def fdel(self):
del self.__check_existing_media
return locals()
check_existing_media = property(**check_existing_media())
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 process_ldt(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) #@UndefinedVariable
#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.check_existing_media:
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 process_file(self):
if self.filepath.name.endswith(".ldt"):
self.process_ldt()
elif self.filepath.name.endswith(".zip"):
self.process_zip()
else:
raise FileImportError("Bad file type")
def process_zip(self):
# """ extraire .zip, pass to method process_ldt"""
# 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.process_ldt(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 process_file_ldt(self):
# processedids = []
# ldtid = self.process_ldt(self.filepath)
# processedids.append(ldtid)
# return processedids