| author | cavaliet |
| Mon, 07 Jan 2013 17:01:02 +0100 | |
| changeset 1054 | 54b0ac8c4a1f |
| parent 1050 | 0eee72ebc2c0 |
| child 1055 | 43a60bdffe69 |
| permissions | -rw-r--r-- |
| 713 | 1 |
# -*- coding: utf-8 -*- |
|
315
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
2 |
from django.conf import settings |
| 504 | 3 |
from django.http import HttpResponse, HttpResponseForbidden |
| 319 | 4 |
from django.shortcuts import get_object_or_404, get_list_or_404 |
|
315
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
5 |
from django.utils import simplejson |
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
6 |
from django.utils.html import escape |
|
691
ff0b66633807
update project serializer for it to serialize the first bout à bout of a ldt project.
cavaliet
parents:
504
diff
changeset
|
7 |
from django.utils.translation import ugettext as _ |
| 319 | 8 |
from ldt.ldt_utils.models import Project |
| 886 | 9 |
from ldt.ldt_utils.projectserializer import ProjectJsonSerializer |
| 730 | 10 |
from ldt.ldt_utils.searchutils import search_generate_ldt |
| 1025 | 11 |
from operator import itemgetter |
| 713 | 12 |
from datetime import datetime |
| 504 | 13 |
import ldt.auth as ldt_auth |
| 713 | 14 |
import lxml.etree |
| 1025 | 15 |
import logging |
|
315
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
16 |
|
| 386 | 17 |
|
|
315
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
18 |
def project_json_id(request, id): |
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
19 |
|
| 404 | 20 |
project = get_object_or_404(Project.safe_objects, ldt_id=id) |
|
315
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
21 |
|
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
22 |
return project_json(request, project, False) |
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
23 |
|
| 366 | 24 |
def project_json_cutting_id(request, id, cutting_id): |
25 |
||
| 404 | 26 |
project = get_object_or_404(Project.safe_objects, ldt_id=id) |
| 366 | 27 |
|
28 |
return project_json(request, project, first_cutting=cutting_id) |
|
|
315
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
29 |
|
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
30 |
def project_json_externalid(request, id): |
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
31 |
|
| 404 | 32 |
res_proj = get_list_or_404(Project.safe_objects.order_by('-modification_date'), contents__external_id=id) #@UndefinedVariable |
|
315
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
33 |
|
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
34 |
return project_json(request, res_proj[0], False) |
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
35 |
|
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
36 |
|
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
37 |
|
| 382 | 38 |
def project_json(request, project, serialize_contents=True, first_cutting=None): |
|
315
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
39 |
|
| 504 | 40 |
if not ldt_auth.check_access(request.user, project): |
41 |
return HttpResponseForbidden(_("You can not access this project")) |
|
|
315
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
42 |
|
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
43 |
mimetype = request.REQUEST.get("mimetype") |
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
44 |
if mimetype is None: |
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
45 |
mimetype = "application/json; charset=utf-8" |
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
46 |
else: |
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
47 |
mimetype = mimetype.encode("utf-8") |
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
48 |
if "charset" not in mimetype: |
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
49 |
mimetype += "; charset=utf-8" |
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
50 |
resp = HttpResponse(mimetype=mimetype) |
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
51 |
resp['Cache-Control'] = 'no-cache, must-revalidate' |
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
52 |
resp['Pragma'] = 'no-cache' |
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
53 |
|
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
54 |
indent = request.REQUEST.get("indent") |
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
55 |
if indent is None: |
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
56 |
indent = settings.LDT_JSON_DEFAULT_INDENT |
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
57 |
else: |
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
58 |
indent = int(indent) |
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
59 |
|
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
60 |
callback = request.REQUEST.get("callback") |
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
61 |
escape_str = request.REQUEST.get("escape") |
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
62 |
escape_bool = False |
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
63 |
if escape_str: |
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
64 |
escape_bool = {'true': True, 'false': False, "0": False, "1": True}.get(escape_str.lower()) |
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
65 |
|
| 382 | 66 |
|
| 886 | 67 |
ps = ProjectJsonSerializer(project, serialize_contents, first_cutting=first_cutting) |
|
315
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
68 |
project_dict = ps.serialize_to_cinelab() |
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
69 |
|
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
70 |
json_str = simplejson.dumps(project_dict, ensure_ascii=False, indent=indent) |
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
71 |
|
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
72 |
if callback is not None: |
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
73 |
json_str = "%s(%s)" % (callback, json_str) |
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
74 |
|
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
75 |
if escape_bool: |
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
76 |
json_str = escape(json_str) |
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
77 |
|
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
78 |
resp.write(json_str) |
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
79 |
|
|
877f89ec1efa
Split big views.py files into several views grouped by "make sense".
cavaliet
parents:
diff
changeset
|
80 |
return resp |
| 713 | 81 |
|
82 |
||
83 |
||
84 |
def mashup_by_tag(request): |
|
85 |
# do we indent ? |
|
86 |
indent = request.REQUEST.get("indent") |
|
87 |
if indent is None: |
|
88 |
indent = settings.LDT_JSON_DEFAULT_INDENT |
|
89 |
else: |
|
90 |
indent = int(indent) |
|
91 |
# do we escape ? |
|
92 |
escape_str = request.REQUEST.get("escape") |
|
93 |
escape_bool = False |
|
94 |
if escape_str: |
|
95 |
escape_bool = {'true': True, 'false': False, "0": False, "1": True}.get(escape_str.lower()) |
|
|
1031
04f8cf193221
remove zero duration annotations parameter added in mashupbytag.
cavaliet
parents:
1030
diff
changeset
|
96 |
# do we remove annotations from mashup if the have duration=0 ? (yes by default) |
|
04f8cf193221
remove zero duration annotations parameter added in mashupbytag.
cavaliet
parents:
1030
diff
changeset
|
97 |
remove_zero_dur_str = request.REQUEST.get("removezeroduration") |
|
04f8cf193221
remove zero duration annotations parameter added in mashupbytag.
cavaliet
parents:
1030
diff
changeset
|
98 |
remove_zero_dur = True |
|
04f8cf193221
remove zero duration annotations parameter added in mashupbytag.
cavaliet
parents:
1030
diff
changeset
|
99 |
logging.debug("CC 1 " + str(remove_zero_dur)) |
|
04f8cf193221
remove zero duration annotations parameter added in mashupbytag.
cavaliet
parents:
1030
diff
changeset
|
100 |
if remove_zero_dur_str: |
|
04f8cf193221
remove zero duration annotations parameter added in mashupbytag.
cavaliet
parents:
1030
diff
changeset
|
101 |
remove_zero_dur = {'true': True, 'false': False, "0": False, "1": True}.get(remove_zero_dur_str.lower()) |
|
04f8cf193221
remove zero duration annotations parameter added in mashupbytag.
cavaliet
parents:
1030
diff
changeset
|
102 |
logging.debug("CC 2 " + str(remove_zero_dur)) |
| 713 | 103 |
|
104 |
# We search |
|
105 |
s = request.REQUEST.get("tag") |
|
| 1025 | 106 |
sort_type = request.REQUEST.get("sort", "") |
| 713 | 107 |
if s: |
108 |
# We get the projects with all the segments |
|
| 730 | 109 |
project_xml, results = search_generate_ldt(request, "tags", s, False) |
| 713 | 110 |
project = Project() |
111 |
project.ldt = lxml.etree.tostring(project_xml, pretty_print=True) |
|
|
714
a25d344cb446
second step for mashup json (works fine but does not sort mashup by weight).
cavaliet
parents:
713
diff
changeset
|
112 |
# Needed datas for jsonification |
|
a25d344cb446
second step for mashup json (works fine but does not sort mashup by weight).
cavaliet
parents:
713
diff
changeset
|
113 |
now = datetime.now() |
|
a25d344cb446
second step for mashup json (works fine but does not sort mashup by weight).
cavaliet
parents:
713
diff
changeset
|
114 |
project.modification_date = project.creation_date = now |
| 713 | 115 |
#return HttpResponse(lxml.etree.tostring(project_xml, pretty_print=True), mimetype="text/xml;charset=utf-8") |
| 886 | 116 |
ps = ProjectJsonSerializer(project, from_contents=False) |
| 713 | 117 |
mashup_dict = ps.serialize_to_cinelab() |
|
714
a25d344cb446
second step for mashup json (works fine but does not sort mashup by weight).
cavaliet
parents:
713
diff
changeset
|
118 |
# Now we build the mashup with the good segments (the ones between in and out) |
|
a25d344cb446
second step for mashup json (works fine but does not sort mashup by weight).
cavaliet
parents:
713
diff
changeset
|
119 |
if results: |
|
a25d344cb446
second step for mashup json (works fine but does not sort mashup by weight).
cavaliet
parents:
713
diff
changeset
|
120 |
tc_in = 0 |
|
a25d344cb446
second step for mashup json (works fine but does not sort mashup by weight).
cavaliet
parents:
713
diff
changeset
|
121 |
if request.REQUEST.get("in") : |
|
a25d344cb446
second step for mashup json (works fine but does not sort mashup by weight).
cavaliet
parents:
713
diff
changeset
|
122 |
tc_in = float(request.REQUEST.get("in")) |
|
a25d344cb446
second step for mashup json (works fine but does not sort mashup by weight).
cavaliet
parents:
713
diff
changeset
|
123 |
tc_out = float('inf') |
|
a25d344cb446
second step for mashup json (works fine but does not sort mashup by weight).
cavaliet
parents:
713
diff
changeset
|
124 |
if request.REQUEST.get("out") : |
|
a25d344cb446
second step for mashup json (works fine but does not sort mashup by weight).
cavaliet
parents:
713
diff
changeset
|
125 |
tc_out = float(request.REQUEST.get("out")) |
|
a25d344cb446
second step for mashup json (works fine but does not sort mashup by weight).
cavaliet
parents:
713
diff
changeset
|
126 |
# Since the timecodes are saved as strings, we filter after calculating float in and out. Timecodes are in milliseconds |
|
a25d344cb446
second step for mashup json (works fine but does not sort mashup by weight).
cavaliet
parents:
713
diff
changeset
|
127 |
mashup_list = { |
|
a25d344cb446
second step for mashup json (works fine but does not sort mashup by weight).
cavaliet
parents:
713
diff
changeset
|
128 |
"items": [], |
|
a25d344cb446
second step for mashup json (works fine but does not sort mashup by weight).
cavaliet
parents:
713
diff
changeset
|
129 |
"meta": { |
|
a25d344cb446
second step for mashup json (works fine but does not sort mashup by weight).
cavaliet
parents:
713
diff
changeset
|
130 |
"dc:contributor": "IRI", |
|
a25d344cb446
second step for mashup json (works fine but does not sort mashup by weight).
cavaliet
parents:
713
diff
changeset
|
131 |
"dc:creator": "IRI", |
|
a25d344cb446
second step for mashup json (works fine but does not sort mashup by weight).
cavaliet
parents:
713
diff
changeset
|
132 |
"dc:title": "Generated mashup with tag '"+s+"'", |
|
a25d344cb446
second step for mashup json (works fine but does not sort mashup by weight).
cavaliet
parents:
713
diff
changeset
|
133 |
"dc:modified": now.isoformat(), |
|
a25d344cb446
second step for mashup json (works fine but does not sort mashup by weight).
cavaliet
parents:
713
diff
changeset
|
134 |
"dc:created": now.isoformat(), |
|
a25d344cb446
second step for mashup json (works fine but does not sort mashup by weight).
cavaliet
parents:
713
diff
changeset
|
135 |
"listtype": "mashup", |
|
a25d344cb446
second step for mashup json (works fine but does not sort mashup by weight).
cavaliet
parents:
713
diff
changeset
|
136 |
"dc:description": "" |
|
a25d344cb446
second step for mashup json (works fine but does not sort mashup by weight).
cavaliet
parents:
713
diff
changeset
|
137 |
}, |
|
a25d344cb446
second step for mashup json (works fine but does not sort mashup by weight).
cavaliet
parents:
713
diff
changeset
|
138 |
"id": "generated_mashup_list" |
|
a25d344cb446
second step for mashup json (works fine but does not sort mashup by weight).
cavaliet
parents:
713
diff
changeset
|
139 |
} |
| 1025 | 140 |
# If sort_type = weight, we sort the result by the tag's weight |
141 |
if sort_type.lower() == "weight": |
|
142 |
# First we turn each string timecode to a float |
|
143 |
for res in results: |
|
144 |
res["start_ts"] = float(res["start_ts"]) |
|
145 |
res["duration"] = float(res["duration"]) |
|
146 |
# We sort to group by start_ts for each media/iri_id |
|
147 |
sorted_results = sorted(results, key=itemgetter("iri_id", "start_ts", "duration")) |
|
148 |
highest_weighted = [] |
|
149 |
current_weight = 1 |
|
150 |
nb_res = len(sorted_results) |
|
151 |
for i, res in enumerate(sorted_results): |
|
152 |
# Explanation : we calculate the weight, which is the number of segments |
|
153 |
# tagged with the searched tag for the same iri_id at the same start_ts. |
|
154 |
# Thanks to the previous sort, the last segment is the one with the longest duration and the one we finally keep |
|
155 |
next_res = None |
|
156 |
if i<(nb_res-1): |
|
157 |
next_res = sorted_results[i+1] |
|
158 |
if next_res and next_res["iri_id"]==res["iri_id"] and next_res["start_ts"]==res["start_ts"]: |
|
159 |
current_weight += 1 |
|
160 |
continue |
|
161 |
res["weight"] = current_weight |
|
162 |
highest_weighted.append(res) |
|
163 |
current_weight = 1 |
|
164 |
||
165 |
# Now that we have the weight for all temporal segments, we just have to sort the array. |
|
| 1050 | 166 |
highest_weighted = sorted(highest_weighted, key=lambda x: (-x["weight"],x["title"])) |
| 1025 | 167 |
for res in highest_weighted: |
168 |
cur_in = res["start_ts"] |
|
169 |
cur_out = cur_in + res["duration"] |
|
| 1054 | 170 |
if tc_in<=cur_in and cur_out<=tc_out and ((not remove_zero_dur) or (remove_zero_dur and res["duration"]>0.0)) and (res["element_id"] not in mashup_list["items"]): |
| 1025 | 171 |
#mashup_list["items"].append(res["iri_id"] + ", " + res["element_id"] + ", " + str(res["start_ts"]) + ", " + str(res["duration"]) + ", " + str(res["weight"])) |
| 1050 | 172 |
#mashup_list["items"].append(res["element_id"] + ", " + str(res["weight"]) + ", " + res["title"]) |
| 1025 | 173 |
mashup_list["items"].append(res["element_id"]) |
174 |
else: |
|
175 |
# no particular sorting |
|
176 |
for res in results: |
|
177 |
cur_in = float(res["start_ts"]) |
|
|
1031
04f8cf193221
remove zero duration annotations parameter added in mashupbytag.
cavaliet
parents:
1030
diff
changeset
|
178 |
dur = float(res["duration"]) |
|
04f8cf193221
remove zero duration annotations parameter added in mashupbytag.
cavaliet
parents:
1030
diff
changeset
|
179 |
cur_out = cur_in + dur |
|
04f8cf193221
remove zero duration annotations parameter added in mashupbytag.
cavaliet
parents:
1030
diff
changeset
|
180 |
if tc_in<=cur_in and cur_out<=tc_out and ((not remove_zero_dur) or (remove_zero_dur and dur>0.0)): |
| 1025 | 181 |
mashup_list["items"].append(res["element_id"]) |
|
714
a25d344cb446
second step for mashup json (works fine but does not sort mashup by weight).
cavaliet
parents:
713
diff
changeset
|
182 |
mashup_dict["lists"].append(mashup_list) |
| 713 | 183 |
|
| 1030 | 184 |
# If asked, we remove the annotations not used in the mashup. |
185 |
# It enabled a lighter response |
|
186 |
remove_not_used_str = request.REQUEST.get("removenotused") |
|
187 |
remove_not_used = False |
|
188 |
if remove_not_used_str: |
|
189 |
remove_not_used = {'true': True, 'false': False, "0": False, "1": True}.get(remove_not_used_str.lower()) |
|
190 |
if remove_not_used: |
|
191 |
for a in mashup_dict["annotations"]: |
|
192 |
if a["id"] not in mashup_list["items"]: |
|
193 |
mashup_dict["annotations"].remove(a) |
|
194 |
||
195 |
||
| 713 | 196 |
json_str = simplejson.dumps(mashup_dict, ensure_ascii=False, indent=indent) |
197 |
if escape_bool: |
|
198 |
json_str = escape(json_str) |
|
199 |
||
| 754 | 200 |
# Callback to allo jsonp |
201 |
callback = request.REQUEST.get("callback") |
|
202 |
if callback is not None: |
|
203 |
json_str = "%s(%s)" % (callback, json_str) |
|
204 |
||
| 713 | 205 |
resp = HttpResponse(mimetype="application/json; charset=utf-8") |
206 |
resp['Cache-Control'] = 'no-cache, must-revalidate' |
|
207 |
resp['Pragma'] = 'no-cache' |
|
208 |
resp.write(json_str) |
|
209 |
||
210 |
return resp |