diff -r 5bb249eefdd1 -r 22ab430e9b64 web/ldt/ldt_utils/views.py --- a/web/ldt/ldt_utils/views.py Tue Nov 16 12:20:59 2010 +0100 +++ b/web/ldt/ldt_utils/views.py Tue Nov 16 14:15:07 2010 +0100 @@ -1,12 +1,14 @@ +from contentindexer import * from django.conf import settings from django.contrib.auth.decorators import login_required from django.core import serializers from django.core.urlresolvers import reverse -from django.db import IntegrityError from django.db.models import Q +from django.forms.forms import get_declared_fields +from django.forms.models import model_to_dict from django.forms.util import ErrorList -from django.http import HttpResponse, Http404, HttpResponseRedirect, \ - HttpResponseForbidden, HttpResponseServerError, HttpResponseBadRequest +from django.http import HttpResponse, HttpResponseRedirect, \ + HttpResponseForbidden, HttpResponseServerError from django.shortcuts import render_to_response, get_object_or_404, \ get_list_or_404 from django.template import RequestContext @@ -14,12 +16,17 @@ from django.utils import simplejson from django.utils.html import escape from django.utils.translation import ugettext as _, ungettext -from httplib import CONFLICT +from fileimport import * +from forms import LdtImportForm, LdtAddForm, SearchForm, AddProjectForm, \ + CopyProjectForm, ContentForm, MediaForm from ldt.core.models import Owner +from ldt.ldt_utils.models import Content, Project, Owner +from ldt.ldt_utils.projectserializer import ProjectSerializer from ldt.ldt_utils.utils import boolean_convert from lxml import etree from lxml.html import fromstring, fragment_fromstring -from ldt.ldt_utils.models import * +from models import * +from projectserializer import * from string import Template from urllib2 import urlparse from utils import * @@ -31,226 +38,767 @@ import ldt.utils.path as ldt_utils_path import logging import lucene +import lxml.etree import tempfile +import urllib2 import uuid -## Filters the annotation depending on the request parameters -## Returns an xml containing the resulting annotations -def filter_annotation(request, uri=None, filter=None, limit=None, creator=None): - annotlist = None - query = Q() - - if request.GET.get('uri'): - query &= Q(uri=request.GET.get('uri')) - if request.GET.get('creator'): - query &= Q(creator=request.GET.get('creator')) - if request.GET.get('filter') and len(request.GET.get('filter')) > 0: - query &= Q(text__icontains=request.GET.get('filter')) +@login_required +def workspace(request): + + # list of contents + content_list = Content.objects.all() - annotlist = Annotation.objects.filter(query) - - if request.GET.get('limit'): - nb = request.GET.get('limit') - #offset = request.GET.get('limit')[1] - annotlist = annotlist[:nb] + # get list of projects + project_list = Project.objects.all() + + # render list + return render_to_response("ldt/ldt_utils/workspace.html", + {'contents': content_list, 'projects': project_list}, + context_instance=RequestContext(request)) + + +def popup_embed(request): - #create xml - iri = lxml.etree.Element('iri') - doc = lxml.etree.ElementTree(iri) - - for annot in annotlist: - textannotation = lxml.etree.SubElement(iri, 'text-annotation') - id = lxml.etree.SubElement(textannotation,'id') - id.text = annot.id - uri = lxml.etree.SubElement(textannotation,'uri') - uri.text = annot.uri - - if annot.tags: - if type(annot.tags) is unicode: - annot.tags = eval(annot.tags) - tags = lxml.etree.SubElement(textannotation,'tags') - ltags = normalize_tags(annot.tags) - for t in ltags: - tag = lxml.etree.SubElement(tags, 'tag') - tag.text = t - - content = lxml.etree.SubElement(textannotation,'content') - color = lxml.etree.SubElement(content,'color') - color.text = annot.color - description = lxml.etree.SubElement(content,'description') - description.text = annot.description - title = lxml.etree.SubElement(content,'title') - title.text = annot.title - text = lxml.etree.SubElement(content,'text') - text.text = annot.text - - meta = lxml.etree.SubElement(textannotation,'meta') - contributor = lxml.etree.SubElement(meta, "contributor") - contributor.text = annot.contributor - creator = lxml.etree.SubElement(meta, "contributor") - creator.text = annot.creator - creationdate = lxml.etree.SubElement(meta, "created") - #creationdate.text = annot.creation_date - updatedate = lxml.etree.SubElement(meta, "modified") - #updatedate.text = annot.update_date - - return HttpResponse(lxml.etree.tostring(doc, pretty_print=True), mimetype="text/xml;charset=utf-8") + json_url = request.GET.get("json_url") + player_id = request.GET.get("player_id") + ldt_id = request.GET.get("ldt_id") + + + project = Project.objects.get(ldt_id=ldt_id); + + if not ldt_auth.checkAccess(request.user, project): + return HttpResponseForbidden(_("You can not access this project")) + + ps = ProjectSerializer(project, from_contents=False, from_display=True) + annotations = ps.getAnnotations(first_cutting=True) + + embed_rendered = dict((typestr, + (lambda s:escape(lxml.etree.tostring(fragment_fromstring(render_to_string("ldt/ldt_utils/partial/embed_%s.html"%(s), {'json_url':json_url,'player_id':player_id, 'annotations':annotations, 'ldt_id': ldt_id}, context_instance=RequestContext(request))),pretty_print=True)))(typestr)) + for typestr in ('player','seo_body', 'seo_meta', 'links') ) + + return render_to_response("ldt/ldt_utils/embed_popup.html", + {'json_url':json_url,'player_id':player_id, 'embed_rendered':embed_rendered, 'annotations':annotations}, + context_instance=RequestContext(request)) + -## Creates an annotation from a urlencoded xml content -## Returns an xml-structured annotation -#@login_required -def create_annotation(request, content): - cont = base64.urlsafe_b64decode(request.POST["content"]) - doc = lxml.etree.fromstring(cont) - - id = unicode(doc.xpath("/iri/text-annotation/id/text()")[0]) - if id is None: - id = generate_uuid() - - uri = unicode(doc.xpath("/iri/text-annotation/uri/text()")[0]) - ltags = [] - for tag in doc.xpath("/iri/text-annotation/tags/tag/text()"): - ltags.append(unicode(tag)) - tags=normalize_tags(ltags) +@login_required +def projectsfilter(request, filter, is_owner=False, status=0): + + project_list = None + is_owner = boolean_convert(is_owner) + status = int(status) + query = Q() + + if is_owner: + owner = None + try: + owner = Owner.objects.get(user=request.user) + except: + return HttpResponseServerError("

User not found

") + query &= Q(owner=owner) + + if status > 0: + query &= Q(state=status) + + if filter: + if len(filter) > 0 and filter[0] == '_': + filter = filter[1:] + query &= Q(title__icontains=filter) + + project_list = Project.objects.filter(query) + + return render_to_response("ldt/ldt_utils/partial/projectslist.html", + {'projects': project_list}, + context_instance=RequestContext(request)) + + + + + +@login_required +def contentsfilter(request, filter): + if filter and len(filter) > 0 and filter[0] == '_': + filter = filter[1:] + + if filter: + content_list = Content.objects.filter(title__icontains=filter) + else: + content_list = Content.objects.all() + + return render_to_response("ldt/ldt_utils/partial/contentslist.html", + {'contents': content_list}, + context_instance=RequestContext(request)) + + +def searchForm(request): + form = SearchForm() + return render_to_response('ldt/ldt_utils/search_form.html',{'form': form} , context_instance=RequestContext(request)) + +def searchIndex(request): - title = unicode(doc.xpath("/iri/text-annotation/content/title/text()")[0]) - desc = unicode(doc.xpath("/iri/text-annotation/content/description/text()")[0]) - text = unicode(doc.xpath("/iri/text-annotation/content/text/text()")[0]) - color = unicode(doc.xpath("/iri/text-annotation/content/color/text()")[0]) - - creator = unicode(doc.xpath("/iri/text-annotation/meta/creator/text()")[0]) - contributor = unicode(doc.xpath("/iri/text-annotation/meta/contributor/text()")[0]) - creation_date = unicode(doc.xpath("/iri/text-annotation/meta/created/text()")[0]) - update_date = unicode(doc.xpath("/iri/text-annotation/meta/modified/text()")[0]) - - try: - annotation = Annotation.create_annotation(id=id, uri=uri, tags=tags, title=title, description=desc, text=text, color=color, creator=creator, contributor=contributor, creation_date=creation_date, update_date=update_date) - annotation.save() - return HttpResponse(lxml.etree.tostring(doc, pretty_print=True), mimetype="text/xml;charset=utf-8") - #return doc - except: - #except Annotation.IntegrityError: - #print 'This id is already used! Please choose another one!' - raise CONFLICT - + sform = SearchForm(request.POST) + if sform.is_valid(): + search = sform.cleaned_data["search"] -## Gets an annotation (from its id) -## Returns the xml-structured annotation -def get_annotation(request, id): + queryStr = base64.urlsafe_b64encode(search.encode('utf8')) + field = request.POST["field"] + language_code = request.LANGUAGE_CODE[:2] + + url = settings.WEB_URL + django.core.urlresolvers.reverse("ldt.ldt_utils.views.searchInit", args=[field, queryStr]) + return render_to_response('ldt/ldt_utils/init_ldt.html', {'LDT_MEDIA_PREFIX': settings.LDT_MEDIA_PREFIX, 'colorurl': settings.LDT_MEDIA_PREFIX+'swf/ldt/pkg/color.xml', 'i18nurl': settings.LDT_MEDIA_PREFIX+'swf/ldt/pkg/i18n', 'language': language_code, 'baseurl': settings.LDT_MEDIA_PREFIX+'swf/ldt/', 'url': url}, context_instance=RequestContext(request)) + else: + resp = HttpResponse() + resp.write("Error : No result"); + +def searchIndexGet(request, field, query): + + language_code = request.LANGUAGE_CODE[:2] + url = settings.WEB_URL + django.core.urlresolvers.reverse("ldt.ldt_utils.views.searchInit", args=[field, query]) + return render_to_response('ldt/ldt_utils/init_ldt.html', {'LDT_MEDIA_PREFIX': settings.LDT_MEDIA_PREFIX, 'colorurl': settings.LDT_MEDIA_PREFIX+'swf/ldt/pkg/color.xml', 'i18nurl': settings.LDT_MEDIA_PREFIX+'swf/ldt/pkg/i18n', 'language': language_code, 'baseurl': settings.LDT_MEDIA_PREFIX+'swf/ldt/', 'url': url}, context_instance=RequestContext(request)) + +def searchInit(request, field, query): + + ldtgen = LdtUtils() + + doc = ldtgen.generateInit([field,query], 'ldt.ldt_utils.views.searchLdt', 'ldt.ldt_utils.views.searchSegments') + + resp = HttpResponse(mimetype="text/xml;charset=utf-8") + doc.write(resp, pretty_print=True) + return resp + +def searchLdt(request, field, query, edition=None): + + contentList = [] + resp = HttpResponse(mimetype="text/xml") + queryStr = "" + + if query and len(query)>0: + queryStr = base64.urlsafe_b64decode(query.encode("ascii")).decode("utf8") + searcher = LdtSearch() + ids = {} + + for result in searcher.query(field, queryStr): + ids[result["iri_id"]] = "" + + id_list = ids.keys() + + if edition is not None: + ids_editions = 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"))) + id_list = filter(lambda id: id in id_list, ids_editions) + + contentList = Content.objects.filter(iri_id__in=id_list) + + + ldtgen = LdtUtils() + ldtgen.generateLdt(contentList, file=resp, title = u"Recherche : " + queryStr) + + return resp + + +def searchSegments(request, field, query, edition=None): + + if query and len(query)>0: + searcher = LdtSearch() + + queryStr = base64.urlsafe_b64decode(query.encode("ascii")).decode("utf8") + res = searcher.query(field, queryStr) + else: + res = [] + + iri_ids = None + + 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"))) + + 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: + 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 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() try: - annot = Annotation.objects.get(id=request.GET.get('id','')) + owner = Owner.objects.get(user=request.user) except: - #except Annotation.DoesNotExist: - raise Http404 - iri = lxml.etree.Element('iri') - doc = lxml.etree.ElementTree(iri) + return HttpResponseRedirect(settings.LOGIN_URL) + ldtProjects = Project.objects.filter(owner=owner) + context={ + 'contents': contents, + 'projects': ldtProjects.reverse(), + } + return render_to_response('ldt/ldt_utils/ldt_list.html', context, context_instance=RequestContext(request)) + +@login_required +def list_content(request): + contents = Content.objects.all() + context={ + 'contents': contents, + } + return render_to_response('ldt/ldt_utils/content_list.html', context, context_instance=RequestContext(request)) + +@login_required +def create_ldt_view(request): + if request.method == "POST" : + form = LdtAddForm(request.POST) + if form.is_valid(): + user = request.user + Project.create_project(title=form.cleaned_data['title'], user=user, contents=form.cleaned_data['contents']) + form_status = "saved" + contents=[] + #return HttpResponseRedirect(reverse("ldt.ldt_utils.views.list_ldt")) + else: + form = LdtAddForm() + contents = Content.objects.all() + form_status = "none" + + return render_to_response('ldt/ldt_utils/create_ldt.html', {'contents': contents, 'form': form, 'form_status':form_status,'create_project_action':reverse(create_ldt_view)}, context_instance=RequestContext(request)) + +def created_ldt(request): + return render_to_response('ldt/ldt_utils/save_done.html', context_instance=RequestContext(request)) - textannotation = lxml.etree.SubElement(iri, 'text-annotation') - id = lxml.etree.SubElement(textannotation,'id') - id.text = annot.id - uri = lxml.etree.SubElement(textannotation,'uri') - uri.text = annot.uri +def indexProject(request, id): + + urlStr = settings.WEB_URL + reverse("space_ldt_init", args=['ldtProject', id]) + posturl= settings.WEB_URL + reverse("ldt.ldt_utils.views.save_ldtProject") + language_code = request.LANGUAGE_CODE[:2] + + ldt = get_object_or_404(Project, ldt_id=id) + if ldt.state ==2: #published + readonly = 'true' + else: + readonly = 'false' + + return render_to_response('ldt/ldt_utils/init_ldt.html', {'LDT_MEDIA_PREFIX': settings.LDT_MEDIA_PREFIX, 'colorurl': settings.LDT_MEDIA_PREFIX+'swf/ldt/pkg/color.xml', 'i18nurl': settings.LDT_MEDIA_PREFIX+'swf/ldt/pkg/i18n', 'language': language_code, 'baseurl': settings.LDT_MEDIA_PREFIX+'swf/ldt/', 'url': urlStr, 'posturl': posturl, 'id': id, 'readonly': readonly}, context_instance=RequestContext(request)) - if annot.tags: - if type(annot.tags) is unicode: - annot.tags = eval(annot.tags) - tags = lxml.etree.SubElement(textannotation,'tags') - ltags = normalize_tags(annot.tags) - for t in ltags: - tag = lxml.etree.SubElement(tags, 'tag') - tag.text = t +def init(request, method, url): + ldtgen = LdtUtils() + + doc = ldtgen.generateInit([url], 'ldt.ldt_utils.views.'+method, None) + + resp = HttpResponse(mimetype="text/xml") + resp['Cache-Control']='no-cache, must-revalidate' + resp['Pragma']='no-cache' + + resp.write( etree.tostring(doc, pretty_print=True, xml_declaration=True, encoding="utf-8")) + return resp + +def ldtProject(request, id): + resp = HttpResponse(mimetype="text/xml") + resp['Cache-Control']='no-cache, must-revalidate' + resp['Pragma']='no-cache' + + project = Project.objects.get(ldt_id=id) + resp.write(project.ldt) + return resp + + +def project_json_id(request, id): + + project = get_object_or_404(Project,ldt_id=id) + + return project_json(request, project, False) + + +def project_json_externalid(request, id): + + res_proj = get_list_or_404(Project.objects.order_by('-modification_date'),contents__external_id = id) + + return project_json(request, res_proj[0], False) + + + +def project_json(request, project, serialize_contents = True): + + if not ldt_auth.checkAccess(request.user, project): + return HttpResponseForbidden(_("You can not access this project")) + + mimetype = request.REQUEST.get("mimetype") + if mimetype is None: + mimetype = "application/json; charset=utf-8" + else: + mimetype = mimetype.encode("utf-8") + if "charset" not in mimetype: + mimetype += "; charset=utf-8" + resp = HttpResponse(mimetype=mimetype) + resp['Cache-Control']='no-cache, must-revalidate' + resp['Pragma']='no-cache' + + indent = request.REQUEST.get("indent") + if indent is None: + indent = settings.LDT_JSON_DEFAULT_INDENT + else: + indent = int(indent) + + callback = request.REQUEST.get("callback") + escape_str = request.REQUEST.get("escape") + escape_bool = False + if escape_str: + escape_bool = {'true': True, 'false': False, "0": False, "1": True}.get(escape_str.lower()) + + + ps = ProjectSerializer(project, serialize_contents) + project_dict = ps.serialize_to_cinelab() + + json_str = simplejson.dumps(project_dict, ensure_ascii=False, indent=indent) + + if callback is not None: + json_str = "%s(%s)" % (callback,json_str) + + if escape_bool: + json_str = escape(json_str) + + resp.write(json_str) + + return resp + +def project_annotations_rdf(request, ldt_id): + + project = Project.objects.get(ldt_id=ldt_id); - content = lxml.etree.SubElement(textannotation,'content') - color = lxml.etree.SubElement(content,'color') - color.text = annot.color - description = lxml.etree.SubElement(content,'description') - description.text = annot.description - title = lxml.etree.SubElement(content,'title') - title.text = annot.title - text = lxml.etree.SubElement(content,'text') - text.text = annot.text + if not ldt_auth.checkAccess(request.user, project): + return HttpResponseForbidden(_("You can not access this project")) + + mimetype = request.REQUEST.get("mimetype") + if mimetype is None: + mimetype = "application/rdf+xml; charset=utf-8" + else: + mimetype = mimetype.encode("utf-8") + if "charset" not in mimetype: + mimetype += "; charset=utf-8" + resp = HttpResponse(mimetype=mimetype) + resp['Cache-Control']='no-cache, must-revalidate' + resp['Pragma']='no-cache' + + ps = ProjectSerializer(project, from_contents=False, from_display=True) + annotations = ps.getAnnotations(first_cutting=True) + + rdf_ns = u"http://www.w3.org/1999/02/22-rdf-syntax-ns#" + dc_ns = u"http://purl.org/dc/elements/1.1/" + rdf = u"{%s}" % rdf_ns + dc = u"{%s}" % dc_ns + nsmap = {u'rdf' : rdf_ns, u'dc':dc_ns} + + rdf_root = etree.Element(rdf+u"RDF", nsmap=nsmap) + + logging.debug("RDF annotations : " + repr(annotations)) - meta = lxml.etree.SubElement(textannotation,'meta') - contributor = lxml.etree.SubElement(meta, "contributor") - contributor.text = annot.contributor - creator = lxml.etree.SubElement(meta, "creator") - creator.text = annot.creator - creationdate = lxml.etree.SubElement(meta, "created") - #creationdate.text = annot.creation_date - updatedate = lxml.etree.SubElement(meta, "modified") - #updatedate.text = annot.update_date + for annotation in annotations: + uri = u"" + if 'uri' in annotation and annotation['uri']: + uri = unicode(annotation['uri']) + annot_desc = etree.SubElement(rdf_root, rdf+u"Description") + annot_desc.set(rdf+u'about',uri) + if annotation['title']: + etree.SubElement(annot_desc, dc+'title').text = etree.CDATA(unicode(annotation['title'])) + if annotation['desc']: + etree.SubElement(annot_desc, dc+'description').text = etree.CDATA(unicode(annotation['desc'])) + if annotation['tags']: + for tag in annotation['tags']: + etree.SubElement(annot_desc, dc+'subject').text = etree.CDATA(unicode(tag)) + etree.SubElement(annot_desc,dc+'coverage').text = u"start=%s, duration=%s" % (annotation['begin'], annotation['duration']) + + resp.write(u"\n") + resp.write(u"\n") + + resp.write(etree.tostring(rdf_root, xml_declaration=False, encoding="utf-8", pretty_print=True)) + + return resp + +def save_ldtProject(request): + if request.method=="POST": + ldt = request.POST['ldt'] + id = request.POST['id'] + ldtproject=Project.objects.get(ldt_id=id) - #return doc - return HttpResponse(lxml.etree.tostring(doc, pretty_print=True), mimetype="text/xml;charset=utf-8") + #save xml ldt + ldtproject.ldt=ldt + + + 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) + + ldtproject.save() + else: + ldt = '' + new_contents=[] + + return render_to_response('ldt/ldt_utils/save_done.html', {'ldt': ldt, 'id':id, 'title':ldtproject.title, 'contents': new_contents}, context_instance=RequestContext(request)) + -## Deletes an annotation (from its id) -## Returns an empty xml-structured annotation -#@login_required -def delete_annotation(request, id): - try: - annot = Annotation.objects.get(id=request.POST["id"]) - annot.delete() - #except Annotation.DoesNotExist: - except: - raise Http404 +@login_required +def publish(request, id, redirect=True): + ldt = get_object_or_404(Project, ldt_id=id) + ldt.state = 2 #published + ldt.save() + redirect = boolean_convert(redirect) + if redirect: + return HttpResponseRedirect(reverse("ldt.ldt_utils.views.list_ldt")) + else: + return HttpResponse(simplejson.dumps({'res':True, 'ldt': {'id': ldt.id, 'state':ldt.state,'ldt_id': ldt.ldt_id}}, ensure_ascii=False),mimetype='application/json') + +@login_required +def unpublish(request, id, redirect=True): + ldt = get_object_or_404(Project, ldt_id=id) + ldt.state = 1 #edition + ldt.save() + redirect = boolean_convert(redirect) + if redirect: + return HttpResponseRedirect(reverse("ldt.ldt_utils.views.list_ldt")) + else: + return HttpResponse(simplejson.dumps({'res':True, 'ldt': {'id': ldt.id, 'state':ldt.state,'ldt_id': ldt.ldt_id}}, ensure_ascii=False),mimetype='application/json') + + +def index(request, url): + + urlStr = settings.WEB_URL + reverse("ldt_init", args=['ldt',url]) + language_code = request.LANGUAGE_CODE[:2] + + return render_to_response('ldt/ldt_utils/init_ldt.html', {'LDT_MEDIA_PREFIX': settings.LDT_MEDIA_PREFIX, 'colorurl': settings.LDT_MEDIA_PREFIX+'swf/ldt/pkg/color.xml', 'i18nurl': settings.LDT_MEDIA_PREFIX+'swf/ldt/pkg/i18n', 'language': language_code, 'baseurl': settings.LDT_MEDIA_PREFIX+'swf/ldt/', 'url': urlStr, 'weburl':settings.WEB_URL+settings.BASE_URL}, context_instance=RequestContext(request)) + + +def ldt(request, url, startSegment = None): - doc=create_empty_annotation() - #return doc - return HttpResponse(lxml.etree.tostring(doc, pretty_print=True), mimetype="text/xml;charset=utf-8") + resp = HttpResponse(mimetype="text/xml; charset=utf-8") + resp['Cache-Control'] = 'no-cache' + + contentList = Content.objects.filter(iri_id=url) + + ldtgen = LdtUtils() + ldtgen.generateLdt(contentList, file=resp, title = contentList[0].title, startSegment=startSegment) + + return resp + + +def loading(request): + return render_to_response('ldt/ldt_utils/loading.html', context_instance=RequestContext(request)) + + +@login_required +def create_project(request, iri_id): + + content = get_object_or_404(Content, iri_id=iri_id) + contents = [ content, ] + if request.method == "POST" : + form = AddProjectForm(request.POST) + if form.is_valid(): + user=request.user + project = Project.create_project(title=form.cleaned_data['title'], user=user, contents=contents) + return HttpResponseRedirect(reverse('ldt.ldt_utils.views.indexProject', args=[project.ldt_id])) + else: + form = AddProjectForm() + return render_to_response('ldt/ldt_utils/create_ldt.html', {'form':form, 'contents':contents, 'create_project_action':reverse("ldt.ldt_utils.views.create_project",args=[iri_id])}, context_instance=RequestContext(request)) + +@login_required +def update_project(request, ldt_id): + + project = get_object_or_404(Project, ldt_id=ldt_id) + contents = project.contents.all() + if request.method == "POST" : + submit_action = request.REQUEST.get("submit_button",False) + if submit_action == "prepare_delete": + errors = [] + if project.state == 2: + errors.append(_("the project %(title)s is published. please unpublish before deleting.")%{'title':project.title}) + message = _("can not delete the project. Please correct the following error") + title = _('title error deleting project') + else: + message = _("please confirm deleting project %(title)s")%{'title':project.title} + title = _("confirm deletion") + return render_to_response('ldt/ldt_utils/error_confirm.html', {'errors':errors, 'message':message, 'title': title}, context_instance=RequestContext(request)) + elif submit_action == "delete": + if project.state != 2: + project.delete() + form_status= 'deleted' + form = AddProjectForm() + else: + form_status= 'saved' + form = AddProjectForm(request.POST) + if form.is_valid(): + project.title=form.cleaned_data['title'] + project.save() + else: + form = AddProjectForm({'title':unicode(project.title)}) + form_status= 'none' + + return render_to_response('ldt/ldt_utils/create_ldt.html', {'form':form, 'form_status':form_status, 'ldt_id': ldt_id, 'contents':contents, 'create_project_action':reverse("ldt.ldt_utils.views.update_project",args=[ldt_id])}, context_instance=RequestContext(request)) + + +@login_required +def copy_project(request, ldt_id): + + project = get_object_or_404(Project, ldt_id=ldt_id) + if request.method == "POST" : + form = CopyProjectForm(request.POST) + if form.is_valid(): + user=request.user + project = project.copy_project(title=request.POST['title'], user=user) + return HttpResponseRedirect(reverse('ldt.ldt_utils.views.indexProject', args=[project.ldt_id])) + else: + form = CopyProjectForm + return render_to_response('ldt/ldt_utils/copy_ldt.html', {'form':form, 'project':project}, context_instance=RequestContext(request)) -## Updates the content of an annotation -## Returns the xml-structured updated annotation -#@login_required -def update_annotation(request, content, id): - try: - annot = Annotation.objects.get(id=request.POST["id"]) - #except Annotation.DoesNotExist: - except: - raise Http404 - - cont = base64.urlsafe_b64decode(request.POST["content"]) - doc = lxml.etree.fromstring(cont) - - uri = doc.xpath("/iri/text-annotation/uri/text()") - if uri != [] and annot.uri != uri[0]: - annot.uri = unicode(uri[0]) +def write_content_base(request, iri_id=None): + + if iri_id: + instance_content = Content.objects.get(iri_id=iri_id) + instance_media = instance_content.media_obj + logging.debug("write_content_base : valid form: for instance : media -> " + repr(instance_media) + " content : for instance : " + repr(instance_content) ) + else: + logging.debug("No iri_id") + instance_content = None + instance_media = None - tags = [] - for tag in doc.xpath("/iri/text-annotation/tags/tag"): - tags.append(unicode(tag.text)) - if annot.tags is not None: - if type(annot.tags) is unicode: - annot.tags = eval(annot.tags) - tags += annot.tags - tags = normalize_tags(tags) - annot.tags=tags + form_status= 'none' + if request.method =="POST": + + content_instance_val = model_to_dict(instance_content,exclude=ContentForm.Meta.exclude) + media_instance_val = model_to_dict(instance_media, exclude=MediaForm.Meta.exclude) + #add prefix + + def add_prefix(dict, prefix): + for key,value in dict.items(): + dict['%s-%s' % (prefix, key)] = value + del(dict[key]) + + add_prefix(content_instance_val, "content") + add_prefix(media_instance_val, "media") + + for k in request.POST.keys(): + value = request.POST.get(k) + content_instance_val[k] = value + media_instance_val[k] = value + + content_form = ContentForm(content_instance_val, prefix="content", instance=instance_content) + media_form = MediaForm(media_instance_val, request.FILES, prefix="media", instance=instance_media) + + media_valid = media_form.is_valid() + content_valid = content_form.is_valid() + + logging.debug("write_content_base : valid form: for instance : " + repr(instance_media) + " -> media " + str(media_valid) +" content : for instance : " + repr(instance_content) + " : " + str(content_valid) ) + + if media_valid and content_valid : + + # see if media must be created + cleaned_data = {} + cleaned_data.update(media_form.cleaned_data) + + media_input_type = content_form.cleaned_data["media_input_type"] + + if media_input_type == "none": + media = None + elif media_input_type == "link": + media = content_form.cleaned_data["media_obj"] + created = False + elif media_input_type == "create": + del cleaned_data["media_file"] + if not cleaned_data['videopath']: + cleaned_data['videopath'] = settings.STREAM_URL + media, created = Media.objects.get_or_create(src=cleaned_data['src'], defaults=cleaned_data) + elif media_input_type == "url" or media_input_type == "upload" : + # copy file + #complet src + destination_file = None + source_file = None + destination_file_path = None + try: + if media_input_type == "url": + url = cleaned_data["external_src_url"] + source_file = urllib2.urlopen(url) + source_filename = source_file.info().get('Content-Disposition', None) + if not source_filename: + source_filename = urlparse.urlparse(url).path.rstrip("/").split('/')[-1] + elif media_input_type == "upload": + source_file = request.FILES['media-media_file'] + source_filename = source_file.name + + source_filename = ldt_utils_path.sanitize_filename(source_filename) + destination_filepath = os.path.join(settings.STREAM_PATH, source_filename) + base_source_filename = source_filename + extension = base_source_filename.split(".")[-1] + if extension == base_source_filename: + extension = "" + base_basename_filename = base_source_filename + else: + base_basename_filename = base_source_filename[:-1 *(len(extension)+1)] + i = 0 + while os.path.exists(destination_filepath): + base_source_filename = "%s.%d.%s" % (base_basename_filename,i,extension) + destination_filepath = os.path.join(settings.STREAM_PATH, base_source_filename) + i += 1 + + destination_file = open(destination_filepath, "w") + src_prefix = settings.STREAM_SRC_PREFIX.rstrip("/") + if len(src_prefix) > 0: + cleaned_data["src"] = src_prefix + "/" + base_source_filename + else: + cleaned_data["src"] = base_source_filename + + chunck = source_file.read(2048) + while chunck: + destination_file.write(chunck) + chunck = source_file.read(2048) + + except Exception as inst: + logging.debug("write_content_base : POST error when processing file:" + str(inst)) + form_status = "error" + #set error for form + if media_input_type == "url": + errors = media_form._errors.setdefault("external_src_url", ErrorList()) + errors.append(_("Problem when downloading file from url : ")+str(inst)) + elif media_input_type == "upload": + errors = media_form._errors.setdefault("media_file", ErrorList()) + errors.append(_("Problem when uploading file : ") + str(inst)) + finally: + if destination_file: + destination_file.close() + if source_file: + source_file.close() + + if form_status != "error": + #try: + del cleaned_data["media_file"] + if not cleaned_data['videopath']: + cleaned_data['videopath'] = settings.STREAM_URL + media, created = Media.objects.get_or_create(src=cleaned_data['src'], defaults=cleaned_data) + else: + media = None + + if media and not created: + for attribute in ('external_id', 'external_permalink', 'external_publication_url', 'external_src_url', 'media_creation_date', 'videopath', 'duration', 'description', 'title'): + setattr(media, attribute, cleaned_data.get(attribute)) + media.save() + #except Exception as inst: +# logging.debug("write_content_base : POST error when saving media:" + str(inst)) + # form_status = "error" + #TODO: set error message + #media_form.errors = _("Error when saving the media : " + e.message) + + #if needed preparetemp file and copy temp file to destination + + + if form_status != "error": + #try: + content_defaults = {} + content_defaults.update(content_form.cleaned_data) + content_defaults['media_obj'] = media + del content_defaults["media_input_type"] + content, created = Content.objects.get_or_create(iri_id = content_form.cleaned_data['iri_id'], defaults = content_defaults) + if not created: + + for attribute in ('iriurl', 'title', 'description', 'duration', 'content_creation_date', 'tags', 'media_obj'): + setattr(content, attribute, content_defaults[attribute]) + content.save() + form_status = 'saved' + media_form = MediaForm(instance=media, prefix="media") + content_form = ContentForm(instance=content, prefix="content") + #except: + #logging.debug("write_content_base : POST error when saving content:" + str(inst)) + #form_status = "error" + #TODO : set error on content form + else: + form_status = 'error' + else: + form_status = 'empty' + initial = { 'media_input_type':"link"} + + content_form = ContentForm(prefix="content", instance=instance_content, initial = initial ) + media_form = MediaForm(prefix="media", instance=instance_media) + + if instance_content is not None: + content_form.media_input_type = "link" - title = doc.xpath("/iri/text-annotation/content/title/text()") - if title != [] and annot.title != title[0]: - annot.title = unicode(title[0]) - desc = doc.xpath("/iri/text-annotation/content/description/text()") - if desc != [] and annot.description != desc[0]: - annot.description = unicode(desc[0]) - text = doc.xpath("/iri/text-annotation/content/text/text()") - if text != [] and annot.text != text[0]: - annot.text = unicode(text[0]) - color = doc.xpath("/iri/text-annotation/content/color/text()") - if color != [] and annot.color != color[0]: - annot.color = unicode(color[0]) + return content_form, media_form, form_status + +@login_required +def write_content(request, iri_id=None): + + submit_action = request.REQUEST.get("submit_button",False) + + if submit_action == "prepare_delete": + errors, titles = prepare_delete_content(request, iri_id) + if errors and len(errors) > 0: + message = ungettext("There is %(count)d error when deleting content", "There are %(count)d errors when deleting content", len(errors)) % { 'count': len(errors)} + title_msg = _('title error deleting content') + else: + message = _("Confirm delete content %(titles)s") % { 'titles' : ",".join(titles) } + title_msg = _("confirm delete content") + return render_to_response('ldt/ldt_utils/error_confirm.html', {'errors':errors, 'message':message, 'title': title_msg}, context_instance=RequestContext(request)) + elif submit_action == "delete": + delete_content(request, iri_id) + form_status = "deleted" + content_form = ContentForm() + media_form = MediaForm() + else: + content_form, media_form, form_status = write_content_base(request, iri_id) + + if iri_id: + create_content_action = reverse('ldt.ldt_utils.views.write_content', kwargs={'iri_id':iri_id}) + else: + create_content_action = reverse('ldt.ldt_utils.views.write_content') - contributor = doc.xpath("/iri/text-annotation/meta/contributor/text()") - if contributor != [] and annot.contributor != contributor[0]: - annot.contributor = unicode(contributor[0]) - update_date = doc.xpath("/iri/text-annotation/meta/modified/text()") - if update_date != [] and annot.update_date != update_date[0]: - annot.update_date = unicode(update_date[0]) + return render_to_response('ldt/ldt_utils/create_content.html', {'content_form': content_form, 'media_form': media_form,'form_status': form_status,'create_content_action': create_content_action, 'iri_id': iri_id}, context_instance=RequestContext(request)) - annot.save() +@login_required +def prepare_delete_content(request, iri_id=None): + errors = [] + titles = [] + if not iri_id: + iri_id = request.REQUEST.get("iri_id", None) + + if iri_id: + for content in Content.objects.filter(iri_id=iri_id): + titles.append(unicode(content.title)) + projects = content.project_set.all() + projects_nb = len(projects) + if projects_nb > 0: + project_titles = map(lambda p: unicode(p.title), projects) + errors.append(ungettext("Content '%(title)s' is referenced by this project : %(project_titles)s. Please delete it beforehand.", "Content '%(title)s' is referenced by %(count)d projects: %(project_titles)s. Please delete them beforehand.", projects_nb)%{'title':unicode(content.title),'count':projects_nb, 'project_titles': ",".join(project_titles)}) + + + return errors, titles + + +@login_required +def delete_content(request, iri_id=None): + if not iri_id: + iri_id = request.REQUEST.get("iri_id", None) + + if iri_id: + Content.objects.filter(iri_id=iri_id).delete() - return get_annotation(id) -