web/ldt/ldt_utils/views.py
changeset 94 9927a619d2b5
parent 91 9c83809fda01
parent 88 7f2c2d9adf58
child 95 9bae869b2146
--- a/web/ldt/ldt_utils/views.py	Thu Oct 14 12:17:31 2010 +0200
+++ b/web/ldt/ldt_utils/views.py	Fri Oct 15 12:36:43 2010 +0200
@@ -1,32 +1,45 @@
-import django.core.urlresolvers
-from django.http import HttpResponse, HttpResponseRedirect
-from django.shortcuts import render_to_response, get_object_or_404, get_list_or_404
+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.models import Q
+from django.forms.util import ErrorList
+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
-from django.core.urlresolvers import reverse
-from django.contrib.auth.decorators import login_required
-from django.conf import settings
-from django.core import serializers
+from django.template.loader import render_to_string
 from django.utils import simplejson
 from django.utils.html import escape
+from django.utils.translation import ugettext as _, ungettext
 from fileimport import *
-from forms import LdtImportForm, LdtAddForm, SearchForm, AddProjectForm, CopyProjectForm, ContentForm, MediaForm
+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 models import *
-from utils import *
-from contentindexer import *
 from projectserializer import *
 from string import Template
+from urllib2 import urlparse
+from utils import *
+import StringIO
+import base64
 import cgi
-import uuid
-import base64
+import django.core.urlresolvers
+import ldt.auth as ldt_auth
+import ldt.utils.path as ldt_utils_path
+import logging
 import lucene
+import lxml.etree
 import tempfile
 import urllib2
-from urllib2 import urlparse
-from jogging import logging
-import lxml.etree
-from django.db.models import Q
-from django.template.loader import render_to_string
+import uuid
 
 
 @login_required
@@ -39,24 +52,36 @@
     project_list = Project.objects.all()
 
     # render list
-    return render_to_response("ldt/workspace.html",
+    return render_to_response("ldt/ldt_utils/workspace.html",
                               {'contents': content_list, 'projects': project_list},
                               context_instance=RequestContext(request))
 
+
 def popup_embed(request):
 
     json_url = request.GET.get("json_url")
     player_id = request.GET.get("player_id")
+    ldt_id = request.GET.get("ldt_id")
 
 
-    embed_rendered = escape(render_to_string('ldt/ldt_utils/embed.html', {'json_url':json_url,'player_id':player_id}, context_instance=RequestContext(request)))
+    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)
 
-    return render_to_response("ldt/embed_popup.html",
-                              {'json_url':json_url,'player_id':player_id, 'player_embed_rendered':embed_rendered},
+    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))
 
 
+
 @login_required
 def projectsfilter(request, filter, is_owner=False, status=0):
 
@@ -76,34 +101,39 @@
     if status > 0:
         query &= Q(state=status)
 
-    if filter and filter != "_":
+    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/projectslist.html",
+    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 == "_":
-        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/contentslist.html",
+    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_utils/search_form.html',{'form': form} , context_instance=RequestContext(request))    
+    return render_to_response('ldt/ldt_utils/search_form.html',{'form': form} , context_instance=RequestContext(request))    
 
 def searchIndex(request):
     
@@ -126,7 +156,7 @@
 
     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('irisuser/ldt/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))
+    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):
     
@@ -230,11 +260,15 @@
         if form.is_valid():
             user = request.user
             Project.create_project(title=form.cleaned_data['title'], user=user, contents=form.cleaned_data['contents'])
-            return HttpResponseRedirect(reverse("ldt.ldt_utils.views.list_ldt"))
+            form_status = "saved"
+            contents=[]
+            #return HttpResponseRedirect(reverse("ldt.ldt_utils.views.list_ldt"))
     else:
         form = LdtAddForm()
-        contents = Content.objects.all()    
-        return render_to_response('ldt/ldt_utils/create_ldt.html', {'contents': contents, 'form': form,'create_project_action':reverse(create_ldt_view)}, context_instance=RequestContext(request))
+        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))
@@ -261,7 +295,8 @@
     resp = HttpResponse(mimetype="text/xml")
     resp['Cache-Control']='no-cache, must-revalidate'
     resp['Pragma']='no-cache'
-    doc.write(resp, pretty_print=True) 
+
+    resp.write( etree.tostring(doc, pretty_print=True, xml_declaration=True, encoding="utf-8")) 
     return resp
        
 def ldtProject(request, id):
@@ -278,19 +313,22 @@
     
     project = get_object_or_404(Project,ldt_id=id)
 
-    return project_json(request, project)
+    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])
+    return project_json(request, res_proj[0], False)
 
 
 
-def project_json(request, project):
-
+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"
@@ -315,7 +353,7 @@
         escape_bool = {'true': True, 'false': False, "0": False, "1": True}.get(escape_str.lower())
         
         
-    ps = ProjectSerializer(project)
+    ps = ProjectSerializer(project, serialize_contents)
     project_dict = ps.serialize_to_cinelab()
     
     json_str = simplejson.dumps(project_dict, ensure_ascii=False, indent=indent)
@@ -330,49 +368,96 @@
 
     return resp
 
+def project_annotations_rdf(request, 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"))
+
+    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_content=False, from_display=True) 
+    annotations = project.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))
+    
+    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"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")
+    resp.write(u"<!DOCTYPE rdf:RDF PUBLIC \"-//DUBLIN CORE//DCMES DTD 2002/07/31//EN\" \"http://dublincore.org/documents/2002/07/31/dcmes-xml/dcmes-xml-dtd.dtd\">\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)
-        
-	#save xml ldt
+
+	    #save xml ldt
         ldtproject.ldt=ldt
 
-	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))
-
+        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)
     
-def get_attrib(ldtproject):
-       	doc = lxml.etree.fromstring(ldtproject.ldt.encode( "utf-8" ))
-	result = doc.xpath("/iri/project")
-	 
-	for pnode in result:
-	    title = pnode.get("title")
-            break
-
-	#set new title
-        ldtproject.title=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))
 
-	return ldtproject
+
+
 
 
 
@@ -437,7 +522,42 @@
             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, 'iri_id':iri_id, 'create_project_action':reverse("ldt.ldt_utils.views.create_project",args=[iri_id])}, context_instance=RequestContext(request))
+    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):
@@ -486,53 +606,71 @@
                 media = None
             elif media_input_type == "link":
                 media = content_form.cleaned_data["media_obj"]
-            elif media_input_type == "url" or  media_input_type == "upload" or  media_input_type == "create":                
+                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
-                if media_input_type != "create":
-                    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
-                            
-    
-                        destination_filepath = os.path.join(settings.STREAM_PATH, source_filename)
-                        base_source_filename = source_filename
-                        i = 0
-                        while os.path.exists(destination_filepath):
-                            base_source_filename = source_filename+"(%d)" % (i)
-                            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
+                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)
-                        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"
-                    finally:
-                        if destination_file:
-                            destination_file.close()
-                        if source_file:
-                            source_file.close()
+        
+                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:
@@ -540,10 +678,13 @@
                     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)
-                    if 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()
+                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"
@@ -586,18 +727,59 @@
     
     return content_form, media_form, form_status
 
-
+@login_required
 def write_content(request, iri_id=None):
     
-    logging.debug("write_content : " + str(iri_id) )
-    content_form, media_form, form_status = write_content_base(request, iri_id)
-    
+    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')
     
-    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}, context_instance=RequestContext(request))
+    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))
+
+@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.objects.all()[0].project_set.all()
+            projects_nb = len(projects)
+            if projects_nb > 0:
+                project_titles = [lambda p: p.title for p in 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':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()