# HG changeset patch # User verrierj # Date 1325868383 -3600 # Node ID 5f919a978f50350d32c2339f0ca22f17b793d027 # Parent 24eea54ed5f9c104eff0dd2d1543e4a4f1cc918d Stats for annotations volume can be computed using ./manage.py statannotation [-c content_id] or in the admin pages of module ldt_utils. diff -r 24eea54ed5f9 -r 5f919a978f50 src/ldt/ldt/api/ldt/handlers.py --- a/src/ldt/ldt/api/ldt/handlers.py Fri Jan 06 11:28:10 2012 +0100 +++ b/src/ldt/ldt/api/ldt/handlers.py Fri Jan 06 17:46:23 2012 +0100 @@ -1,9 +1,10 @@ -from ldt.ldt_utils.models import Project +from ldt.ldt_utils.models import Project, Content from piston.handler import BaseHandler from piston.utils import rc, require_extended from ldt.ldt_utils.utils import LdtAnnotation +from ldt.ldt_utils.stat import add_annotation_to_stat +from ldt.security.utils import protect_instance, unprotect_instance import logging #@UnresolvedImport -import lxml.etree class ProjectHandler(BaseHandler): @@ -152,8 +153,9 @@ except Project.DoesNotExist: return rc.NOT_HERE - adder = LdtAnnotation(project, force_save=True) + adder = LdtAnnotation(project) logging.debug("request json " + repr(request.data)) + unprotect_instance(project) # allows anonymous user to save project meta = request.data['meta'] author = meta['creator'] @@ -165,10 +167,20 @@ begin = str(a['begin']) new_id = adder.add(a['media'], a['type'], a['type_title'], a['content']['data'], '', a['tags'], begin, dur, author, date) if not new_id: + protect_instance(project) return rc.BAD_REQUEST + adder.save() + + content = project.contents.get(iri_id=a['media']) + unprotect_instance(content) + add_annotation_to_stat(content, a['begin'], a['end']) + protect_instance(content) + a['id'] = new_id + protect_instance(project) + return request.data else: @@ -185,6 +197,23 @@ project.ldt = ldt_str + unprotect_instance(project) project.save() + protect_instance(project) return rc.ALL_OK + + +class ContentHandler(BaseHandler): + allowed_methods = ('GET', ) + model = Content + exclude = ( + ("media_obj"), + ) + + def read(self, request, iri_id): + """ + returns a single content + """ + return Content.objects.get(iri_id=iri_id) + diff -r 24eea54ed5f9 -r 5f919a978f50 src/ldt/ldt/api/ldt/urls.py --- a/src/ldt/ldt/api/ldt/urls.py Fri Jan 06 11:28:10 2012 +0100 +++ b/src/ldt/ldt/api/ldt/urls.py Fri Jan 06 17:46:23 2012 +0100 @@ -1,9 +1,12 @@ from django.conf.urls.defaults import patterns, url from piston.resource import Resource -from ldt.api.ldt.handlers import ProjectHandler +from ldt.api.ldt.handlers import ProjectHandler, ContentHandler project_handler = Resource(ProjectHandler, None) +content_handler = Resource(ContentHandler, None) urlpatterns = patterns('', url(r'projects/(?P[^/.]+)\.?(?P.*)$', project_handler, name='project_api'), + url(r'contents/(?P[^/.]+)\.?(?P.*)$', content_handler, name='content_api'), ) + diff -r 24eea54ed5f9 -r 5f919a978f50 src/ldt/ldt/ldt_utils/admin.py --- a/src/ldt/ldt/ldt_utils/admin.py Fri Jan 06 11:28:10 2012 +0100 +++ b/src/ldt/ldt/ldt_utils/admin.py Fri Jan 06 17:46:23 2012 +0100 @@ -4,8 +4,9 @@ from django.template import RequestContext from ldt.ldt_utils.contentindexer import ContentIndexer, ProjectIndexer from ldt.ldt_utils.fileimport import FileImport, FileImportError -from ldt.ldt_utils.forms import LdtImportForm, ReindexForm +from ldt.ldt_utils.forms import LdtImportForm, ReindexForm, StatAnnotationForm from ldt.ldt_utils.models import Content, Project, Media, Author +from ldt.ldt_utils.stat import compute_stats_for import ldt.indexation from guardian.admin import GuardedModelAdmin @@ -79,13 +80,38 @@ return render_to_response('admin/ldt_utils/content/reindex_form.html', {'form': form, 'message':message, 'current_app': self.admin_site.name, 'current_action' : 'reindex' }, context_instance=RequestContext(request)) + def stats_annotations(self, request): + + message = None + if request.method == "POST": + content_form = StatAnnotationForm(request.POST) + + if content_form.is_valid(): + + if content_form.cleaned_data['choose_all']: + contents = Content.objects.all() + else: + contents = content_form.cleaned_data['contents'] + + for content in contents: + compute_stats_for(content) + message = "Stats computed for :" + repr(contents) + else: + content_form = StatAnnotationForm() + + return render_to_response('admin/ldt_utils/content/stats_form.html', {'form': content_form, 'message':message, 'current_app': self.admin_site.name, 'current_action' : 'stats' }, context_instance=RequestContext(request)) + + def get_urls(self): urls = super(ContentAdmin, self).get_urls() content_urls = patterns('', url(r'^reindex/$', self.admin_site.admin_view(self.reindex), name="ldt_content_reindex"), # (r'^admin/ldt/content/import/upload/$', 'ldt.ldt_utils.views.uploadFile'), - url(r'^import/$', self.admin_site.admin_view(self.import_file), name="ldt_content_import_file") + url(r'^import/$', self.admin_site.admin_view(self.import_file), name="ldt_content_import_file"), + url(r'^stats/$', self.admin_site.admin_view(self.stats_annotations), name="ldt_content_compute_stats") + ) + return content_urls + urls diff -r 24eea54ed5f9 -r 5f919a978f50 src/ldt/ldt/ldt_utils/forms.py --- a/src/ldt/ldt/ldt_utils/forms.py Fri Jan 06 11:28:10 2012 +0100 +++ b/src/ldt/ldt/ldt_utils/forms.py Fri Jan 06 17:46:23 2012 +0100 @@ -23,6 +23,10 @@ class ReindexForm(forms.Form): contents = forms.ModelMultipleChoiceField(Content.objects.all()) index_projects = forms.BooleanField(required=False, initial=False) + +class StatAnnotationForm(forms.Form): + contents = forms.ModelMultipleChoiceField(Content.objects.all()) + choose_all = forms.BooleanField(required=False, initial=False) class SearchForm(forms.Form): search = forms.CharField(label=_("Search")) diff -r 24eea54ed5f9 -r 5f919a978f50 src/ldt/ldt/ldt_utils/models.py --- a/src/ldt/ldt/ldt_utils/models.py Fri Jan 06 11:28:10 2012 +0100 +++ b/src/ldt/ldt/ldt_utils/models.py Fri Jan 06 17:46:23 2012 +0100 @@ -127,9 +127,9 @@ content_creation_date = models.DateTimeField(null=True, blank=True, verbose_name=_('content.content_creation_date')) tags = tagging.fields.TagField(max_length=2048, null=True, blank=True) media_obj = models.ForeignKey('Media', blank=True, null=True) - image = ImageField(upload_to=settings.MEDIA_ROOT+"thumbnails/contents/", default=settings.DEFAULT_CONTENT_ICON) - + stat_annotation = models.CommaSeparatedIntegerField(max_length=1024, null=True, blank=True, verbose_name=_("content.stat_annotation")) + class Meta: ordering = ["title"] permissions = ( @@ -328,12 +328,24 @@ assign('view_media', everyone, self.media_obj) else: remove_perm('view_content', everyone, self) - remove_perm('vew_media', everyone, self.media_obj) + remove_perm('view_media', everyone, self.media_obj) return locals() is_public = property(**is_public()) - + + def nb_annotation(): #@NoSelf + + def fget(self): + if self.stat_annotation: + return sum([int(x) for x in self.stat_annotation.split(',')]) + else: + return 0 + + return locals() + + nb_annotation = property(**nb_annotation()) + class Project(Document, SafeModel): diff -r 24eea54ed5f9 -r 5f919a978f50 src/ldt/ldt/ldt_utils/stat.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ldt/ldt/ldt_utils/stat.py Fri Jan 06 17:46:23 2012 +0100 @@ -0,0 +1,85 @@ +from django.conf import settings +import lxml.etree + +def compute_stats_for(content, verbose=False): + number_division = settings.DIVISIONS_FOR_STAT_ANNOTATION + + print "analysing content %s" % content.iri_id + + size_division = content.duration / number_division + limits = [x * size_division for x in range(number_division+1)] + buckets = [0] * number_division + + for project in content.project_set.all(): + if verbose: + print "analysing project %s " % project + + doc = lxml.etree.fromstring(project.ldt) + + annotations = doc.xpath('/iri/annotations/content[@id="' + content.iri_id + '"]/ensemble/decoupage/elements/element') + for ann in annotations: + + begin = int(ann.get('begin')) + end = int(ann.get('dur')) + begin + + #print "%s - %s" % (begin, end) + #print ann.xpath('title')[0].text + + buckets = find_buckets(buckets, limits, begin, end) + + #print buckets + + content.stat_annotation = get_string_from_buckets(buckets) + content.save() + + if verbose: + print "%s : %s" % (content.iri_id, buckets) + + return buckets + +def get_string_from_buckets(buckets): + s = "%s" % buckets + s = s[1:-1].replace(' ', '') + return s + +def find_buckets(buckets, limits, begin, end): + + if len(buckets)+1 != len(limits): + raise ValueError("There should be as many buckets as those defined by limits.") + + has_started = False + + for i in range(len(limits)-1): + if not has_started: + if limits[i] <= begin and begin <= limits[i+1]: + buckets[i] += 1 + has_started = True + #print "Starts after timecode %s" % limits[i] + elif limits[i] > end: + #print "Ends before timecode %s" % limits[i] + break + else: + buckets[i] += 1 + + return buckets + +def add_annotation_to_stat(content, begin, end): + stats = content.stat_annotation + + if stats: + + number_division = settings.DIVISIONS_FOR_STAT_ANNOTATION + size_division = content.duration / number_division + + limits = [x * size_division for x in range(number_division+1)] + buckets = [int(x) for x in stats.split(',')] + + buckets = find_buckets(buckets, limits, begin, end) + content.stat_annotation = get_string_from_buckets(buckets) + content.save() + else: + return None + + + + \ No newline at end of file diff -r 24eea54ed5f9 -r 5f919a978f50 src/ldt/ldt/ldt_utils/templates/admin/ldt_utils/app_index.html --- a/src/ldt/ldt/ldt_utils/templates/admin/ldt_utils/app_index.html Fri Jan 06 11:28:10 2012 +0100 +++ b/src/ldt/ldt/ldt_utils/templates/admin/ldt_utils/app_index.html Fri Jan 06 17:46:23 2012 +0100 @@ -25,6 +25,11 @@   + + Compute stats + +   + diff -r 24eea54ed5f9 -r 5f919a978f50 src/ldt/ldt/ldt_utils/templates/admin/ldt_utils/content/stats_form.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ldt/ldt/ldt_utils/templates/admin/ldt_utils/content/stats_form.html Fri Jan 06 17:46:23 2012 +0100 @@ -0,0 +1,23 @@ +{% extends "admin/ldt_utils/app_action.html" %} +{% load i18n %} +{# reindex contents #} +{% block content %} +{% if message %} +
+

{{ message }}

+
+{% endif %} {% if form. %} +
+{% endif %} +
+
{% csrf_token %} + + {{ form.as_table }} +
+
+
+ +Back to administration page + +{% endblock %} diff -r 24eea54ed5f9 -r 5f919a978f50 src/ldt/ldt/ldt_utils/utils.py --- a/src/ldt/ldt/ldt_utils/utils.py Fri Jan 06 11:28:10 2012 +0100 +++ b/src/ldt/ldt/ldt_utils/utils.py Fri Jan 06 17:46:23 2012 +0100 @@ -169,7 +169,7 @@ self.parser = lxml.etree.XMLParser(remove_blank_text=True) self.ldtdoc = lxml.etree.parse(StringIO(project.ldt.encode("utf-8")), self.parser) self.to_add = True - self.force_save = force_save + # add( a['media'], a['type'], a['type_title, a[data], '', a['tags'], begin, dur, author, date) def add(self, media, cutting_id, cutting_title, title, text, tags_list, begin, dur, author, date, view_id=None, color="16776960"): """ @@ -269,10 +269,7 @@ if self.to_add: self.project.ldt = lxml.etree.tostring(self.ldtdoc, pretty_print=True) #assert False, " TIBO SAVE " + self.project.ldt - if self.force_save: - self.project.save_base() - else: - self.project.save() + self.project.save() def __del__(self): self.save() diff -r 24eea54ed5f9 -r 5f919a978f50 src/ldt/ldt/ldt_utils/views_old.py --- a/src/ldt/ldt/ldt_utils/views_old.py Fri Jan 06 11:28:10 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1383 +0,0 @@ -from django.conf import settings -from django.contrib.auth.decorators import login_required -from django.contrib.auth.models import User, Group -from django.core.cache import cache -from django.core.urlresolvers import reverse -from django.core.paginator import Paginator, InvalidPage, EmptyPage -from django.db.models import Q -from django.forms.models import model_to_dict -from django.forms.util import ErrorList -from django.http import (HttpResponse, HttpResponseRedirect, - HttpResponseForbidden, HttpResponseServerError) -from ldt.indexation import get_results_with_context, highlight_documents -from django.shortcuts import (render_to_response, get_object_or_404, - get_list_or_404) -from django.template import RequestContext -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 forms import (LdtAddForm, SearchForm, AddProjectForm, CopyProjectForm, - ContentForm, MediaForm, GroupAddForm) -from guardian.shortcuts import remove_perm, get_objects_for_group, get_objects_for_user -from ldt.ldt_utils.models import Content -from ldt.ldt_utils.utils import boolean_convert, LdtUtils, LdtSearch -from ldt.security.utils import (assign_perm_to_obj, set_forbidden_stream, - add_change_attr, get_userlist, get_userlist_model, get_userlist_group) -from ldt.security.cache import get_cached_checker, cached_assign -from lxml.html import fragment_fromstring -from models import Media, Project -from projectserializer import ProjectSerializer -from urllib2 import urlparse -from operator import itemgetter -from itertools import groupby -import base64 -import django.core.urlresolvers -import ldt.auth as ldt_auth -import ldt.utils.path as ldt_utils_path -import logging -import lxml.etree -import mimetypes -import os -import urllib2 -import subprocess -import re -import datetime - - -@login_required -def workspace(request): - - # list of contents - content_list = add_change_attr(request.user, Content.safe_objects.all()) #@UndefinedVariable - - # get list of projects owned by the current user - project_list = add_change_attr(request.user, Project.safe_objects.filter(owner=request.user)) #@UndefinedVariable - - is_gecko = ((request.META['HTTP_USER_AGENT'].lower().find("firefox")) > -1); - - # render list - return render_to_response("ldt/ldt_utils/workspace.html", - {'contents': content_list, 'projects': project_list, - 'is_gecko': is_gecko}, - context_instance=RequestContext(request)) - -@login_required -def groups(request): - - # get list of all published projects - group_list = request.user.groups.exclude(name=settings.PUBLIC_GROUP_NAME) - - group_list = sorted(group_list.all(), key=lambda group: group.name.lower()) - group_list = add_change_attr(request.user, group_list) - - can_add_group = True if request.user.user_permissions.filter(codename='add_group') else False - is_gecko = ((request.META['HTTP_USER_AGENT'].lower().find("firefox")) > -1); - # render list - return render_to_response("ldt/ldt_utils/groups.html", - {'groups': group_list, - 'is_gecko': is_gecko, - 'can_add_group': can_add_group}, - context_instance=RequestContext(request)) - - -@login_required -def published_project(request): - - # get list of all published projects - project_list = Project.safe_objects.filter(state=2) #@UndefinedVariable - # Search form - form = SearchForm() - - is_gecko = ((request.META['HTTP_USER_AGENT'].lower().find("firefox")) > -1); - - # render list - return render_to_response("ldt/ldt_utils/published_projects.html", - {'projects': project_list, 'form': form, - 'is_gecko': is_gecko}, - 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") - - project = Project.safe_objects.get(ldt_id=ldt_id); #@UndefinedVariable - - stream_mode = project.stream_mode - if stream_mode != "video": - stream_mode = 'radio' - - player_width = 650 - player_height = 480 - - if stream_mode == 'radio': - player_height = 1 - - if not ldt_auth.check_access(request.user, project): - return HttpResponseForbidden(_("You can not access this project")) - - ps = ProjectSerializer(project, from_contents=False, from_display=True) - annotations = ps.get_annotations(first_cutting=True) - - rend_dict = {'json_url':json_url, 'player_id':player_id, 'annotations':annotations, 'ldt_id': ldt_id, 'stream_mode': stream_mode, 'player_width': player_width, 'player_height': player_height} - - embed_rendered = dict((typestr, - (lambda s:escape(lxml.etree.tostring(fragment_fromstring(render_to_string("ldt/ldt_utils/partial/embed_%s.html" % (s), rend_dict, context_instance=RequestContext(request))), pretty_print=True)))(typestr)) - for typestr in ('player', 'seo_body', 'seo_meta', 'links')) - - rend_dict['embed_rendered'] = embed_rendered - - return render_to_response("ldt/ldt_utils/embed_popup.html", - rend_dict, - context_instance=RequestContext(request)) - - -@login_required -def projects_filter(request, filter, is_owner=False, status=0, id_group=0): - is_owner = boolean_convert(is_owner) - status = int(status) - id_group = int(id_group) - query = Q() - - if is_owner: - owner = None - try: - owner = 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) - - is_gecko = ((request.META['HTTP_USER_AGENT'].lower().find("firefox")) > -1); - show_username = True - - if id_group > 0: # Search inside a group - grp = Group.objects.get(id=id_group) - project_list = get_objects_for_group(grp, 'ldt_utils.view_project').filter(query) - elif id_group == -1:# Search inside projects shared with a specific user - project_list = get_objects_for_user(request.user, 'ldt_utils.view_project', use_groups=False).exclude(owner=request.user) - else: - project_list = Project.safe_objects.filter(query) - show_username = False - - project_list = add_change_attr(request.user, project_list) - - if status == 2: - url_templ = "ldt/ldt_utils/partial/publishedprojectslist.html" - else: - url_templ = "ldt/ldt_utils/partial/projectslist.html" - - return render_to_response(url_templ, - {'projects': project_list, 'show_username':show_username, - 'is_gecko': is_gecko, 'group_id':id_group}, - context_instance=RequestContext(request)) - -def share_filter(request, filter, use_groups=False): - use_groups = boolean_convert(use_groups) - if not filter or len(filter) == 0: - raise AttributeError("filter should be a string") - - filter = filter[1:] - resp = get_userlist(request.user, filter=filter) - - if use_groups: - groups = Group.objects.filter(name__icontains=filter).exclude(name=settings.PUBLIC_GROUP_NAME)[0:20] - - for g in groups: - resp.append({'name': g.name, 'id': g.id, 'type': 'group'}) - - resp = sorted(resp, key=lambda elem: elem['name'].lower()) - - return render_to_response("ldt/ldt_utils/partial/sharewith.html", {'elem_list' : resp}, context_instance=RequestContext(request)) - -@login_required -def contents_filter(request, filter): - if filter and len(filter) > 0 and filter[0] == '_': - filter = filter[1:] - - if filter: - content_list = Content.safe_objects.filter(title__icontains=filter) #@UndefinedVariable - else: - content_list = Content.safe_objects.all() #@UndefinedVariable - - content_list = add_change_attr(request.user, content_list) - - return render_to_response("ldt/ldt_utils/partial/contentslist.html", - {'contents': content_list}, - context_instance=RequestContext(request)) - -@login_required -def groups_filter(request, filter): - if filter and len(filter) > 0 and filter[0] == '_': - filter = filter[1:] - - if filter: - group_list = request.user.groups.filter(name__icontains=filter) - search_active = True - else: - group_list = request.user.groups.all() - search_active = False - - group_list = group_list.exclude(name=settings.PUBLIC_GROUP_NAME) - group_list = sorted(group_list.all(), key=lambda group: group.name.lower()) - group_list = add_change_attr(request.user, group_list) - - - return render_to_response("ldt/ldt_utils/partial/groupslist.html", - {'groups': group_list, 'search_active': search_active}, - context_instance=RequestContext(request)) - - -def search_form(request): - form = SearchForm() - return render_to_response('ldt/ldt_utils/search_form.html', {'form': form} , context_instance=RequestContext(request)) - - -@login_required -def search_index(request): - - sform = SearchForm(request.POST) - if sform.is_valid(): - search = sform.cleaned_data["search"] - queryStr = base64.urlsafe_b64encode(search.encode('utf8')) - field = request.POST["field"] - language_code = request.LANGUAGE_CODE[:2] - - if request.POST.has_key("ldt_pres"): - url = settings.WEB_URL + django.core.urlresolvers.reverse("ldt.ldt_utils.views.search_init", args=[field, queryStr]) - return render_to_response('ldt/ldt_utils/init_ldt_full.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: - results = get_results_with_context(field, search) - complete_results = [] - proj_list = Project.safe_objects.all() - results.sort(key=lambda k: k['iri_id']) - for iri_id, item in groupby(results, itemgetter('iri_id')): - try: - content = Content.objects.get(iri_id=iri_id) - except Content.DoesNotExist: - continue - segments = list(item) - to_delete = [] - for s in segments: - if not s['project_id']: - s['project_id'] = '_' - else: - project = proj_list.filter(ldt_id=s['project_id']) - if len(project) == 0: - to_delete.append(s) - - for e in to_delete: - segments.remove(e) - - if not segments: - continue - - score = sum([seg['score'] for seg in segments]) - desc = content.description if content.description else '' - complete_results.append({'list' : segments, 'score' : score, 'content_title' : content.title, 'content_id' : content.iri_id, 'content_description' : desc }) - - complete_results.sort(key=lambda k: k['score']) - - cache.set('complete_results_%s' % request.user.username, complete_results) - cache.set('search_%s' % request.user.username, search) - cache.set('field_%s' % request.user.username, field) - - paginator = Paginator (complete_results, settings.LDT_RESULTS_PER_PAGE) - page = 1 - - try: - results = paginator.page(page) - except (EmptyPage, InvalidPage): - results = paginator.page(paginator.num_pages) - - results.object_list = highlight_documents(results.object_list, search, field) - - return render_to_response('ldt/ldt_utils/search_results.html', {'results': results, 'nb_results' : paginator.count, 'search' : search, '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/'}, context_instance=RequestContext(request)) - - else: - return HttpResponseRedirect(reverse('ldt.ldt_utils.views.published_project')) - - -def search_listing(request): - if not cache.get('complete_results_%s' % request.user.username): - return HttpResponseRedirect(reverse('ldt.ldt_utils.views.published_project')) - - complete_results = cache.get('complete_results_%s' % request.user.username) - search = cache.get('search_%s' % request.user.username) - field = cache.get('field_%s' % request.user.username) - paginator = Paginator(complete_results, settings.LDT_RESULTS_PER_PAGE) - language_code = request.LANGUAGE_CODE[:2] - - try: - page = int(request.GET.get('page', '1')) - except ValueError: - page = 1 - - try: - results = paginator.page(page) - except (EmptyPage, InvalidPage): - results = paginator.page(paginator.num_pages) - - results.object_list = highlight_documents(results.object_list, search, field) - - return render_to_response('ldt/ldt_utils/search_results.html', {'results': results, 'nb_results' : paginator.count, 'search' : search, '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/'}, context_instance=RequestContext(request)) - -def search_index_get(request, field, query): - - language_code = request.LANGUAGE_CODE[:2] - - url = settings.WEB_URL + django.core.urlresolvers.reverse("ldt.ldt_utils.views.search_init", 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 search_init(request, field, query): - - ldtgen = LdtUtils() - - doc = ldtgen.generate_init([field, query], 'ldt.ldt_utils.views.search_ldt', 'ldt.ldt_utils.views.search_segments') - - resp = HttpResponse(mimetype="text/xml;charset=utf-8") - resp.write(lxml.etree.tostring(doc, pretty_print=True, encoding="utf-8")) - return resp - -def search_ldt(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 = {} - projIds = {} - - for result in searcher.query(field, queryStr): - ids[result["iri_id"]] = "" - projIds[result["project_id"]] = "" - - id_list = ids.keys() - projId_list = projIds.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) #@UndefinedVariable - projectList = Project.safe_objects.filter(ldt_id__in=projId_list) - - ldtgen = LdtUtils() - # generate_ldt(contentList, title=u"", author=u"IRI Web", web_url=u"", startSegment=None, projects=None): - doc = ldtgen.generate_ldt(contentList, title=u"Recherche : " + queryStr, projects=projectList) - doc = set_forbidden_stream(doc, request.user) - doc.write(resp, pretty_print=True) - - return resp - - -def search_segments(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 = lxml.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.safe_objects.all() #@UndefinedVariable - try: - owner = request.user #@UndefinedVariable - except: - return HttpResponseRedirect(settings.LOGIN_URL) - ldtProjects = Project.safe_objects.filter(owner=owner) #@UndefinedVariable - 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.safe_objects.all() #@UndefinedVariable - 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): - groups = request.user.groups.exclude(name=settings.PUBLIC_GROUP_NAME) - redirect_to = '' - if request.method == "POST" : - form = LdtAddForm(request.POST) - form_status = "none" - contents = Content.safe_objects.all() - - if form.is_valid(): - - user = request.user - project = Project.create_project(title=form.cleaned_data['title'], user=user, - contents=form.cleaned_data['contents'], - description=form.cleaned_data['description']) - - if form.cleaned_data["share"]: - assign_perm_to_obj(project, form.cleaned_data["read_list"], form.cleaned_data["write_list"], user) - form_status = "saved" - is_gecko = ((request.META['HTTP_USER_AGENT'].lower().find("firefox")) > -1); - if is_gecko : - redirect_to = reverse('index_project_full', args=[project.ldt_id]) - else: - return HttpResponseRedirect(reverse('index_project', args=[project.ldt_id])) - - else: - form = LdtAddForm() - contents = Content.safe_objects.all() - form_status = "none" - - return render_to_response('ldt/ldt_utils/create_ldt.html', {'contents': contents, 'form': form, 'form_status':form_status, - 'redirect_to': redirect_to, 'create_project_action':reverse(create_ldt_view), 'language_code' : settings.LANGUAGE_CODE[2:], - 'elem_list': get_userlist(request.user)}, context_instance=RequestContext(request)) - -def created_ldt(request): - return render_to_response('ldt/ldt_utils/save_done.html', context_instance=RequestContext(request)) - - -def index_segment(request, project_id, content_id, cutting_id, ensemble_id, segment_id): - url_str = settings.WEB_URL + reverse("ldt.ldt_utils.views.init_segment", args=[project_id, content_id, ensemble_id, cutting_id, segment_id]) - post_url = "" - language_code = request.LANGUAGE_CODE[:2] - readonly = 'true' - template_path = 'ldt/ldt_utils/init_ldt.html' - - return render_to_response(template_path, {'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_str, 'posturl': post_url, 'id': id, 'readonly': readonly}, context_instance=RequestContext(request)) - -def init_segment(request, project_id, content_id, ensemble_id, cutting_id, segment_id): - - if project_id != u"_": - get_object_or_404(Project.safe_objects, ldt_id=project_id) - - ldtgen = LdtUtils() - doc = ldtgen.generate_init([project_id, content_id, ensemble_id, cutting_id, segment_id], 'ldt.ldt_utils.views.ldt_segment', 'ldt.ldt_utils.views.highlight_segment') - - return HttpResponse(lxml.etree.tostring(lxml.etree.ElementTree(doc), pretty_print=True), mimetype="text/xml;charset=utf-8") - -def highlight_segment(request, project_id, content_id, ensemble_id, cutting_id, segment_id): - if project_id != u"_": - get_object_or_404(Project.safe_objects, ldt_id=project_id) - - iri = lxml.etree.Element('iri') - doc = lxml.etree.ElementTree(iri) - - seg = lxml.etree.SubElement(iri, 'seg') - seg.set('idctt', content_id) - seg.set('idens', ensemble_id) - seg.set('iddec', cutting_id) - seg.set('idseg', segment_id) - seg.set('idvue', "") - seg.set('crit', "") - - return HttpResponse(lxml.etree.tostring(doc, pretty_print=True), mimetype="text/xml;charset=utf-8") - - -def ldt_segment(request, project_id, content_id, ensemble_id, cutting_id, segment_id): - - resp = HttpResponse(mimetype="text/xml") - resp['Cache-Control'] = 'no-cache, must-revalidate' - resp['Pragma'] = 'no-cache' - - if project_id and project_id != "_" : - project = Project.safe_objects.get(ldt_id=project_id) #@UndefinedVariable - ldtdoc = lxml.etree.fromstring(project.ldt.encode("utf-8")) - ldtdoc = set_forbidden_stream(ldtdoc, request.user) - displays_node = ldtdoc.find("displays") - if not displays_node: - displays_node = lxml.etree.SubElement(ldtdoc, u"displays") - res = displays_node.xpath("display") - if len(res) > 0: - display_node = res[0] - else: - display_node = lxml.etree.SubElement(displays_node, u"display", attrib={u'id':u'0', u'title': u'generated', u'idsel':unicode(content_id), u'tc':u'0'}) - - res = display_node.xpath("content[@id='%s']/decoupage[(@id='%s') and (@idens='%s')]" % (content_id, cutting_id, ensemble_id)) - if len(res) == 0: - #create node - res = display_node.xpath("content[@id='%s']" % (content_id)) - if len(res) == 0: - content_node = lxml.etree.SubElement(display_node, u"content") - else: - content_node = res[0] - lxml.etree.SubElement(content_node, u"decoupage", attrib={u'id':unicode(cutting_id), u'idens':unicode(ensemble_id)}) - active_segment_node = displays_node.find(u"activeSegment") - if not active_segment_node: - active_segment_node = lxml.etree.SubElement(displays_node, u"activeSegment") - id_node = active_segment_node.find(u"id") - if id_node: - active_segment_node.remove(id_node) - lxml.etree.SubElement(active_segment_node, u"id", attrib={u"idctt":unicode(content_id), u"idens": unicode(ensemble_id), "idcut":unicode(cutting_id), u"idseg":unicode(segment_id)}) - - resp.write(lxml.etree.tostring(ldtdoc, xml_declaration=True, encoding='utf-8', pretty_print=True)) - else: - # generate ldt from - ldtgen = LdtUtils() - content_list = Content.safe_objects.filter(iri_id=content_id) - if request.user and request.user.username: - username = request.user.username - else: - username = "webuser" - - start_segment = { - 'idcontent': content_id, - 'idgroup' : ensemble_id, - 'idcutting' : cutting_id, - 'idsegment' : segment_id - } - - doc = ldtgen.generate_ldt(content_list, "segment : ", author=username, startSegment=start_segment) - doc = set_forbidden_stream(doc, request.user) - doc.write(resp, pretty_print=('DEBUG' in dir(settings) and settings.DEBUG)) - - return resp - - -@login_required -def index_project(request, id, full=False): - - urlStr = settings.WEB_URL + reverse("space_ldt_init", args=['ldt_project', id]) - posturl = settings.WEB_URL + reverse("ldt.ldt_utils.views.save_ldt_project") - language_code = request.LANGUAGE_CODE[:2] - - try: - ldt = Project.safe_objects.get(ldt_id=id) - except Project.DoesNotExist: - return HttpResponseRedirect(reverse("ldt.ldt_utils.views.workspace")) - - if ldt.state == 2 or not request.user.has_perm('change_project', ldt): #published - readonly = 'true' - else: - readonly = 'false' - - if full: - template_path = 'ldt/ldt_utils/init_ldt_full.html' - else: - template_path = 'ldt/ldt_utils/init_ldt.html' - - return render_to_response(template_path, {'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)) - - -def init(request, method, url): - ldtgen = LdtUtils() - - doc = ldtgen.generate_init([url], 'ldt.ldt_utils.views.' + method, None) - - library = doc.xpath('/iri/files/library')[0] - for c in Content.safe_objects.all(): - elem = lxml.etree.SubElement(library, 'file') - elem.set('src', c.iri_url()) - elem.set('video', c.videopath) - elem.set('title', c.title) - elem.set('author', '') - elem.set('category', '') - elem.set('pict', '') - elem.set('img', '') - - resp = HttpResponse(mimetype="text/xml") - resp['Cache-Control'] = 'no-cache, must-revalidate' - resp['Pragma'] = 'no-cache' - - resp.write(lxml.etree.tostring(doc, pretty_print=True, xml_declaration=True, encoding="utf-8")) - return resp - -def ldt_project(request, id): - resp = HttpResponse(mimetype="text/xml") - resp['Cache-Control'] = 'no-cache, must-revalidate' - resp['Pragma'] = 'no-cache' - - project = Project.safe_objects.get(ldt_id=id) #@UndefinedVariable - - doc = lxml.etree.fromstring(project.ldt) - doc = set_forbidden_stream(doc, request.user) - resp.write(lxml.etree.tostring(doc, pretty_print=True, xml_declaration=True, encoding="utf-8")) - - return resp - - -def project_json_id(request, id): - - project = get_object_or_404(Project.safe_objects, ldt_id=id) - - return project_json(request, project, False) - - -def project_json_externalid(request, id): - - res_proj = get_list_or_404(Project.safe_objects.order_by('-modification_date'), contents__external_id=id) #@UndefinedVariable - - return project_json(request, res_proj[0], False) - - - -def project_json(request, project, serialize_contents=True): # Not checked - - if not ldt_auth.check_access(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.safe_objects.get(ldt_id=ldt_id); #@UndefinedVariable - - if not ldt_auth.check_access(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.get_annotations(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 = lxml.etree.Element(rdf + u"RDF", nsmap=nsmap) - - logging.debug("RDF annotations : " + repr(annotations)) #@UndefinedVariable - - for annotation in annotations: - uri = u"" - if 'uri' in annotation and annotation['uri']: - uri = unicode(annotation['uri']) - annot_desc = lxml.etree.SubElement(rdf_root, rdf + u"Description") - annot_desc.set(rdf + u'about', uri) - if annotation['title']: - lxml.etree.SubElement(annot_desc, dc + 'title').text = lxml.etree.CDATA(unicode(annotation['title'])) - if annotation['desc']: - lxml.etree.SubElement(annot_desc, dc + 'description').text = lxml.etree.CDATA(unicode(annotation['desc'])) - if annotation['tags']: - for tag in annotation['tags']: - lxml.etree.SubElement(annot_desc, dc + 'subject').text = lxml.etree.CDATA(unicode(tag)) - lxml.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(lxml.etree.tostring(rdf_root, xml_declaration=False, encoding="utf-8", pretty_print=True)) - - return resp - -def save_ldt_project(request): - if request.method == "POST": - ldt = request.POST['ldt'] - id = request.POST['id'] - ldtproject = Project.safe_objects.get(ldt_id=id) #@UndefinedVariable - - #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)) - -@login_required -def publish(request, id, redirect=True): - ldt = get_object_or_404(Project.safe_objects, ldt_id=id) - ldt.publish() - 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.safe_objects, ldt_id=id) - ldt.unpublish() - 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): - - resp = HttpResponse(mimetype="text/xml; charset=utf-8") - resp['Cache-Control'] = 'no-cache' - - contentList = Content.safe_objects.filter(iri_id=url) #@UndefinedVariable - - ldtgen = LdtUtils() - doc = ldtgen.generate_ldt(contentList, title=contentList[0].title, startSegment=startSegment) - doc = set_forbidden_stream(doc, request.user) - doc.write(resp, pretty_print=True) - - 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.safe_objects, iri_id=iri_id) - contents = [ content, ] - groups = request.user.groups.exclude(name=settings.PUBLIC_GROUP_NAME) - redirect_to = '' - form_status = "none" - - 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, description=form.cleaned_data['description']) - form_status = "saved" - - if form.cleaned_data["share"]: - assign_perm_to_obj(project, form.cleaned_data["read_list"], form.cleaned_data["write_list"], user) - - # Modal window is not used with firefox - is_gecko = ((request.META['HTTP_USER_AGENT'].lower().find("firefox")) > -1); - if is_gecko : - redirect_to = reverse('index_project_full', args=[project.ldt_id]) - else: - return HttpResponseRedirect(reverse('index_project', args=[project.ldt_id])) - else: - form = AddProjectForm() - - return render_to_response('ldt/ldt_utils/create_ldt.html', {'form':form, 'form_status': form_status, 'contents':contents,'groups' : groups, - 'redirect_to': redirect_to, 'elem_list': get_userlist(request.user), '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.safe_objects, ldt_id=ldt_id) - contents = project.contents.all() - groups = request.user.groups.exclude(name=settings.PUBLIC_GROUP_NAME) - member_list, admin_list = get_userlist_model(project, request.user) - - 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 = 'none' - form = AddProjectForm(request.POST) - - if form.is_valid(): - if project.title != form.cleaned_data['title'] or project.description != form.cleaned_data['description']: - project.title = form.cleaned_data['title'] - project.description = form.cleaned_data['description'] - ldt = lxml.etree.fromstring(project.ldt.encode("utf-8")) - res = ldt.xpath("/iri/project") - res[0].set("title", project.title) - res[0].set("abstract", project.description) - project.ldt = lxml.etree.tostring(ldt, pretty_print=True) - project.save() - - if form.cleaned_data["share"]: - assign_perm_to_obj(project, form.cleaned_data["read_list"], form.cleaned_data["write_list"], request.user) - form_status = "saved" - else: - form = AddProjectForm({'title':unicode(project.title), 'description':unicode(project.get_description())}) - - form_status = 'none' - - return render_to_response('ldt/ldt_utils/create_ldt.html', {'form':form, 'form_status':form_status, 'groups': groups, 'elem_list': get_userlist(request.user), - 'ldt_id': ldt_id, 'contents':contents, 'member_list': member_list, 'admin_list': admin_list, - '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, group_id=0): - - project = get_object_or_404(Project.safe_objects, ldt_id=ldt_id) - if request.method == "POST" : - form = CopyProjectForm(request.POST) - - if form.is_valid(): - user = request.user - group_id = form.cleaned_data['group'] - group = Group.objects.get(id=group_id) if group_id and group_id > 0 else None - project = project.copy_project(title=form.cleaned_data['title'], user=user, group=group) - is_gecko = ((request.META['HTTP_USER_AGENT'].lower().find("firefox")) > -1); - if is_gecko: - return HttpResponseRedirect(reverse('index_project_full', args=[project.ldt_id])) - else: - return HttpResponseRedirect(reverse('index_project', args=[project.ldt_id])) - else: - form = CopyProjectForm() - # Modal window is not used with firefox, so we ask to submit the form in _parent in firefox case. - target_parent = ((request.META['HTTP_USER_AGENT'].lower().find("firefox")) > -1); - return render_to_response('ldt/ldt_utils/copy_ldt.html', {'form':form, 'project':project, 'group_id':group_id, 'target_parent':target_parent}, context_instance=RequestContext(request)) - - -def write_content_base(request, iri_id=None): - - if iri_id: - instance_content = Content.safe_objects.get(iri_id=iri_id) #@UndefinedVariable - 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)) #@UndefinedVariable - else: - logging.debug("No iri_id") #@UndefinedVariable - instance_content = None - instance_media = None - - form_status = 'none' - if request.method == "POST": - - if instance_content is not None: - content_instance_val = model_to_dict(instance_content, exclude=ContentForm.Meta.exclude) - else: - content_instance_val = {} - - if instance_media is not None: - media_instance_val = model_to_dict(instance_media, exclude=MediaForm.Meta.exclude) - else: - media_instance_val = {} - #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_instance_val['read_list'] = request.POST.getlist('read_list') - content_instance_val['write_list'] = request.POST.getlist('write_list') - content_instance_val['share'] = request.POST.get('share', False) - - 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)) #@UndefinedVariable - - 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 - # if the source is already http:// or rtmp:// we don't have to add STREAM_URL - if cleaned_data['src'].startswith("rtmp://") or cleaned_data['src'].startswith("http://"): - cleaned_data['videopath'] = '' - media, created = Media.objects.get_or_create(src=cleaned_data['src'], defaults=cleaned_data) #@UndefinedVariable - elif media_input_type == "url" or media_input_type == "upload" : - # copy file - #complet src - destination_file = None - source_file = 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'] - # At this point the file has already be uploaded thanks to the upload view, and original file name is sent through a post var - source_filename = request.POST["media-local_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 - - if media_input_type == "url": - # we upload the file if we are in url case - destination_file = open(destination_filepath, "wb") - chunck = source_file.read(2048) - while chunck: - destination_file.write(chunck) - chunck = source_file.read(2048) - - elif media_input_type == "upload": - # The media file has been uploaded in the session temp folder - # so we just have to move to the regular folder and rename it. - if os.path.exists(os.path.join(settings.STREAM_PATH, "tmp/" + request.COOKIES[settings.SESSION_COOKIE_NAME] + "/", source_filename)): - os.rename(os.path.join(settings.STREAM_PATH, "tmp/" + request.COOKIES[settings.SESSION_COOKIE_NAME] + "/", source_filename), os.path.join(settings.STREAM_PATH, base_source_filename)) - - - 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 - - - except Exception as inst: - logging.debug("write_content_base : POST error when processing file:" + str(inst)) #@UndefinedVariable - 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 : ") + url) - elif media_input_type == "upload": - errors = media_form._errors.setdefault("media_file", ErrorList()) - errors.append(_("Problem when uploading file : ") + str(inst)) - finally: - if media_input_type == "url": - 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 - mimetype = cleaned_data.get('mimetype_field', None) - if not mimetype: - mimetype = mimetypes.guess_type(cleaned_data['src']) - cleaned_data['mimetype_field'] = mimetype - media, created = Media.safe_objects.get_or_create(src=cleaned_data['src'], defaults=cleaned_data) #@UndefinedVariable - cached_assign('view_media', request.user, media) - 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)) - mimetype = cleaned_data.get('mimetype_field', None) - if not mimetype: - mimetype = mimetypes.guess_type(media.src) - media.mimetype_field = mimetype - cached_assign('view_media', request.user, media) - cached_assign('change_media', request.user, media) - media.save() - - if form_status != "error": - content_defaults = {} - content_defaults.update(content_form.cleaned_data) - content_defaults['media_obj'] = media - - for key in ["media_input_type", "groups", "is_public", "read_list", "write_list", "share" ]: - del content_defaults[key] - - content, created = Content.safe_objects.get_or_create(iri_id=content_form.cleaned_data['iri_id'], defaults=content_defaults) #@UndefinedVariable - if not created: - content.save() # Check if user is allowed to change object before assigning permissions. - cached_assign('change_content', request.user, content) - cached_assign('view_content', request.user, content) - everyone = Group.objects.get(name=settings.PUBLIC_GROUP_NAME) - if content_form.cleaned_data['is_public']: - cached_assign('view_content', everyone, content) - if media: - cached_assign('view_media', everyone, media) - elif content_form.cleaned_data["share"]: - remove_perm('view_content', everyone, content) - assign_perm_to_obj(content, content_form.cleaned_data['read_list'], content_form.cleaned_data['write_list'], request.user) - if media: - assign_perm_to_obj(media, content_form.cleaned_data['read_list'], content_form.cleaned_data['write_list'], request.user) - 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") - else: - form_status = 'error' - else: - form_status = 'empty' - initial = { 'media_input_type':"link"} - if instance_content: - initial['is_public'] = instance_content.is_public - - 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" - - return content_form, media_form, form_status - -@login_required -def write_content(request, iri_id=None): - submit_action = request.REQUEST.get("submit_button", False) - groups = request.user.groups.exclude(name=settings.PUBLIC_GROUP_NAME) - member_list = admin_list = [] - - 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: - member_list, admin_list = get_userlist_model(Content.objects.get(iri_id=iri_id), request.user) - - 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') - - session_key = request.COOKIES[settings.SESSION_COOKIE_NAME] - cookie_name = settings.SESSION_COOKIE_NAME - content_form.fields["media_obj"].queryset = Media.safe_objects.all() - - 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, - 'elem_list': get_userlist(request.user), 'member_list': member_list, 'admin_list': admin_list, 'iri_id': iri_id, 'session_key':session_key, 'cookie_name':cookie_name}, 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.safe_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.safe_objects.get(iri_id=iri_id).delete() - - -def upload(request): - if request.method == 'POST': - for field_name in request.FILES: - # We get the file name - source_file = request.FILES[field_name] - source_filename = source_file.name - # We sanitize the file name : no space, only lower case. - source_filename = ldt_utils_path.sanitize_filename(source_filename) - # We create the session temp folder if necessary - if not os.path.exists(os.path.join(settings.STREAM_PATH, "tmp/" + request.COOKIES[settings.SESSION_COOKIE_NAME])): - os.makedirs(os.path.join(settings.STREAM_PATH, "tmp/" + request.COOKIES[settings.SESSION_COOKIE_NAME])) - destination_filepath = os.path.join(settings.STREAM_PATH, "tmp/" + request.COOKIES[settings.SESSION_COOKIE_NAME] + "/", source_filename) - # We delete the existing file if necessary - if os.path.exists(destination_filepath): - os.remove(destination_filepath) - - destination_file = open(destination_filepath, "wb") - - for chunk in source_file.chunks(): - destination_file.write(chunk) - destination_file.close() - - # indicate that everything is OK for SWFUpload - return HttpResponse("ok", mimetype="text/plain") - else: - return HttpResponse("notok", mimetype="text/plain") - -def remove_temp_file(request): - # The filename arrives with a GET var. - file_path = os.path.join(settings.STREAM_PATH, "tmp/" + request.COOKIES[settings.SESSION_COOKIE_NAME] + "/", ldt_utils_path.sanitize_filename(request.GET["filename"])) - if os.path.exists(file_path): - os.remove(file_path) - return HttpResponse("remove ok", mimetype="text/plain") - -def get_duration(request): - try: - # The filename arrives with a GET var. - file_path = os.path.join(settings.STREAM_PATH, "tmp/" + request.COOKIES[settings.SESSION_COOKIE_NAME] + "/", ldt_utils_path.sanitize_filename(request.GET["filename"])) - if hasattr(settings, 'FFMPEG_PATH') and os.path.exists(file_path): - output = str(subprocess.Popen([settings.FFMPEG_PATH, "-i", file_path], stderr=subprocess.PIPE).communicate()[1]) - m = re.search("Duration:\s*?([\d.:]+)", output, re.M) - dur_arr = m.group(1).split(":") - td = datetime.timedelta(hours=int(dur_arr[0]), minutes=int(dur_arr[1]), seconds=float(dur_arr[2])) - str_duration = str((td.microseconds + (td.seconds + td.days * 24 * 3600) * 10 ** 6) / 10 ** 3) - return HttpResponse(str_duration, mimetype="text/plain") - else: - return HttpResponse("", mimetype="text/plain") - except Exception as inst: - return HttpResponse(str(inst), mimetype="text/plain") - - -@login_required -def get_group_projects(request): - - # Get group, user and project_list - grp_id = request.POST["id_group"] - if grp_id == "-1": - project_list = get_objects_for_user(request.user, 'ldt_utils.view_project', use_groups=False).exclude(owner=request.user) - else: - grp = Group.objects.get(id=grp_id) - everyone = Group.objects.get(name=settings.PUBLIC_GROUP_NAME) - project_list = get_objects_for_group(grp, 'ldt_utils.view_project') | get_objects_for_group(everyone, 'ldt_utils.view_project').filter(owner__in=[grp]) - - project_list = add_change_attr(request.user, project_list) - - is_gecko = ((request.META['HTTP_USER_AGENT'].lower().find("firefox")) > -1); - - return render_to_response("ldt/ldt_utils/partial/projectslist.html", - {'projects': project_list, 'show_username':True, - 'is_gecko': is_gecko, 'group_id': grp_id}, - context_instance=RequestContext(request)) - -@login_required -def create_group(request): - if not request.user.user_permissions.filter(codename='add_group'): - return HttpResponseServerError('

User %s can not create a group.

' % request.user.username) - - form_status = '' - - if request.method == 'POST': - form = GroupAddForm(request.POST) - - if form.is_valid(): - name = form.cleaned_data['name'] - members_list = form.cleaned_data['read_list'] - admin_list = form.cleaned_data['write_list'] - - group = Group.objects.create(name=name) - group.save() - cached_assign('is_owner_group', request.user, group) - cached_assign('change_group', request.user, group) - request.user.groups.add(group) - - for elem in members_list: - if hasattr(elem, 'username'): - elem.groups.add(group) - if elem in admin_list: - cached_assign('change_group', elem, group) - - form_status = 'saved' - - else: - form = GroupAddForm() - - return render_to_response("ldt/ldt_utils/create_group.html", {'group_edition': True, 'form' : form, 'form_status' : form_status, 'elem_list' : get_userlist(request.user)}, context_instance=RequestContext(request)) - -@login_required -def update_group(request, group_id): - group = get_object_or_404(Group, id=group_id) - checker = get_cached_checker(request.user) - - if not checker.has_perm('change_group', group): - form_status = 'none' - return render_to_response("ldt/ldt_utils/create_group.html", {'form_status' : form_status}, context_instance=RequestContext(request)) - - form_status = '' - is_owner_group = checker.has_perm('is_owner_group', group) - - if request.method == "POST": - form = GroupAddForm(request.POST, instance=group) - submit_action = request.REQUEST.get("submit_button", False) - - if submit_action == 'delete': - if is_owner_group: - group.delete() - form_status = 'deleted' - else: - if form.is_valid(): - name = form.cleaned_data['name'] - new_member_list = form.cleaned_data['read_list'] - old_member_list = group.user_set.exclude(id=request.user.id) - admin_list = form.cleaned_data['write_list'] - group.name = name - - for user in new_member_list: - if not hasattr(user, 'username'): - raise AttributeError('new_member_list should only contain users') - if user != request.user: - group.user_set.add(user) - if is_owner_group: - if user in admin_list: - cached_assign('change_group', user, group) - else: - remove_perm('change_group', user, group) - - for user in old_member_list: - if user not in new_member_list: - group.user_set.remove(user) - remove_perm('change_group', user, group) - - group.save() - form_status = 'saved' - else: - form = GroupAddForm(initial={'name':unicode(group.name)}) - - if form_status != 'deleted': - member_list, admin_list = get_userlist_group(group, request.user) - else: - member_list = admin_list = [] - - return render_to_response("ldt/ldt_utils/create_group.html", {'group_id' : group_id, 'form' : form, 'form_status' : form_status, 'group_edition': True, - 'elem_list' : get_userlist(request.user), 'member_list': member_list, 'admin_list': admin_list, - 'is_owner_group': is_owner_group}, context_instance=RequestContext(request)) diff -r 24eea54ed5f9 -r 5f919a978f50 src/ldt/ldt/management/commands/statannotation.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ldt/ldt/management/commands/statannotation.py Fri Jan 06 17:46:23 2012 +0100 @@ -0,0 +1,37 @@ +from django.core.management.base import BaseCommand +from ldt.ldt_utils.models import Content +from ldt.ldt_utils.stat import compute_stats_for +from optparse import make_option + +class Command(BaseCommand): + help = 'Computes annotation volume for a given content' + + option_list = BaseCommand.option_list + ( + make_option("-c", "--content", + dest="content", + action="store", + help="The id of the content we want to compute annotation volume on"), + ) + + def handle(self, *args, **options): + parser = self.create_parser("statannotation", "") + options, args = parser.parse_args() + + verbose = (options.verbosity == "2") + + id_content = options.content + if id_content: + contents = Content.objects.filter(iri_id=id_content) + if not len(contents): + print "No content found with iri_id %s" % id_content + return None + else: + contents = Content.objects.all() + print "analysing all contents" + + + for content in contents: + compute_stats_for(content, verbose) + + return None + \ No newline at end of file diff -r 24eea54ed5f9 -r 5f919a978f50 src/ldt/ldt/security/utils.py --- a/src/ldt/ldt/security/utils.py Fri Jan 06 11:28:10 2012 +0100 +++ b/src/ldt/ldt/security/utils.py Fri Jan 06 17:46:23 2012 +0100 @@ -2,6 +2,7 @@ from django.contrib.contenttypes.models import ContentType from guardian.shortcuts import assign, remove_perm, get_users_with_perms, get_groups_with_perms, get_objects_for_user from cache import get_cached_userlist +import types try: from threading import local @@ -60,9 +61,25 @@ del cls.old_delete cls.safe_objects.user = None +def unprotect_instance(instance): + if hasattr(instance, 'old_save'): + instance.save = instance.old_save + instance.delete = instance.old_delete + +def protect_instance(instance): + class_name = instance.__class__.__name__.lower() + cls = ContentType.objects.get(model=class_name) + cls = cls.model_class() + + save = types.MethodType(change_security('project')(cls.save), instance, cls) + instance.save = save + + delete = types.MethodType(change_security('project')(cls.delete), instance, cls) + instance.delete = delete + def change_security(cls_name): def wrapper(func): - def wrapped(self, *args, **kwargs): + def wrapped(self, *args, **kwargs): if self.pk and not get_current_user().has_perm('change_%s' % cls_name, self): raise AttributeError('User %s is not allowed to change object %s' % (get_current_user(), self)) diff -r 24eea54ed5f9 -r 5f919a978f50 web/ldtplatform/settings.py --- a/web/ldtplatform/settings.py Fri Jan 06 11:28:10 2012 +0100 +++ b/web/ldtplatform/settings.py Fri Jan 06 17:46:23 2012 +0100 @@ -213,6 +213,8 @@ WEB_VERSION = ldtplatform.get_version() +DIVISIONS_FOR_STAT_ANNOTATION = 64 + from config import * if not "LOGIN_URL" in locals():