forked from 0x2620/pandora
oembed, dont leak private layers
This commit is contained in:
parent
9a47ddcdad
commit
49ae89eb9b
6 changed files with 112 additions and 20 deletions
|
@ -153,4 +153,13 @@ class AnnotationManager(Manager):
|
||||||
user)
|
user)
|
||||||
if conditions:
|
if conditions:
|
||||||
qs = qs.filter(conditions)
|
qs = qs.filter(conditions)
|
||||||
|
|
||||||
|
#anonymous can only see public items
|
||||||
|
public_layers = self.model.public_layers()
|
||||||
|
|
||||||
|
if user.is_anonymous():
|
||||||
|
qs = qs.filter(layer__in=public_layers)
|
||||||
|
#users can see public and own
|
||||||
|
else:
|
||||||
|
qs = qs.filter(Q(layer__in=public_layers)|Q(user=user))
|
||||||
return qs
|
return qs
|
||||||
|
|
|
@ -57,6 +57,14 @@ class Annotation(models.Model):
|
||||||
self.public_id = "%s/%s" % (self.item.itemId, ox.toAZ(public_id))
|
self.public_id = "%s/%s" % (self.item.itemId, ox.toAZ(public_id))
|
||||||
Annotation.objects.filter(id=self.id).update(public_id=self.public_id)
|
Annotation.objects.filter(id=self.id).update(public_id=self.public_id)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def public_layers(self):
|
||||||
|
layers = []
|
||||||
|
for layer in settings.CONFIG['layers']:
|
||||||
|
if not layer.get('private', False):
|
||||||
|
layers.append(layer['id'])
|
||||||
|
return layers
|
||||||
|
|
||||||
def get_layer(self):
|
def get_layer(self):
|
||||||
for layer in settings.CONFIG['layers']:
|
for layer in settings.CONFIG['layers']:
|
||||||
if layer['id'] == self.layer:
|
if layer['id'] == self.layer:
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# vi:si:et:sw=4:sts=4:ts=4
|
# vi:si:et:sw=4:sts=4:ts=4
|
||||||
try:
|
import re
|
||||||
import xml.etree.ElementTree as ET
|
|
||||||
except:
|
|
||||||
import elementtree.ElementTree as ET
|
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
|
|
||||||
|
@ -16,7 +13,7 @@ from ox.django.shortcuts import json_response, render_to_json_response
|
||||||
from ox.django.decorators import login_required_json
|
from ox.django.decorators import login_required_json
|
||||||
|
|
||||||
import ox
|
import ox
|
||||||
from ox.utils import json
|
from ox.utils import json, ET
|
||||||
|
|
||||||
import models
|
import models
|
||||||
|
|
||||||
|
@ -43,6 +40,15 @@ def embed(request, id):
|
||||||
})
|
})
|
||||||
return render_to_response('embed.html', context)
|
return render_to_response('embed.html', context)
|
||||||
|
|
||||||
|
def redirect_url(request, url):
|
||||||
|
if request.META['QUERY_STRING']:
|
||||||
|
url += "?" + request.META['QUERY_STRING']
|
||||||
|
|
||||||
|
if settings.CONFIG.get('sendReferrer', False):
|
||||||
|
return redirect(url)
|
||||||
|
else:
|
||||||
|
return HttpResponse('<script>document.location.href=%s;</script>'%json.dumps(url))
|
||||||
|
|
||||||
def opensearch_xml(request):
|
def opensearch_xml(request):
|
||||||
osd = ET.Element('OpenSearchDescription')
|
osd = ET.Element('OpenSearchDescription')
|
||||||
osd.attrib['xmlns']="http://a9.com/-/spec/opensearch/1.1/"
|
osd.attrib['xmlns']="http://a9.com/-/spec/opensearch/1.1/"
|
||||||
|
@ -124,14 +130,6 @@ def editPage(request):
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
actions.register(editPage)
|
actions.register(editPage)
|
||||||
|
|
||||||
def redirect_url(request, url):
|
|
||||||
if request.META['QUERY_STRING']:
|
|
||||||
url += "?" + request.META['QUERY_STRING']
|
|
||||||
|
|
||||||
if settings.CONFIG.get('sendReferrer', False):
|
|
||||||
return redirect(url)
|
|
||||||
else:
|
|
||||||
return HttpResponse('<script>document.location.href=%s;</script>'%json.dumps(url))
|
|
||||||
|
|
||||||
def init(request):
|
def init(request):
|
||||||
'''
|
'''
|
||||||
|
@ -146,3 +144,28 @@ def init(request):
|
||||||
response['data']['user'] = init_user(request.user, request)
|
response['data']['user'] = init_user(request.user, request)
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
actions.register(init)
|
actions.register(init)
|
||||||
|
|
||||||
|
|
||||||
|
def embedURL(request):
|
||||||
|
'''
|
||||||
|
|
||||||
|
param data {
|
||||||
|
url
|
||||||
|
maxwidth
|
||||||
|
maxheight
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
status: ...
|
||||||
|
data: {
|
||||||
|
html
|
||||||
|
...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {'status': {'code': int, 'text': string},
|
||||||
|
'data': {user: object}}
|
||||||
|
'''
|
||||||
|
data = json.loads(request.POST['data'])
|
||||||
|
response = json_response({})
|
||||||
|
response['data'] = ox.get_embed_code(data['url'], data.get('maxwidth'), data.get('maxheight'))
|
||||||
|
return render_to_json_response(response)
|
||||||
|
actions.register(embedURL)
|
||||||
|
|
|
@ -5,6 +5,7 @@ import os.path
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
import mimetypes
|
import mimetypes
|
||||||
import random
|
import random
|
||||||
|
from urlparse import urlparse
|
||||||
|
|
||||||
import Image
|
import Image
|
||||||
from django.db.models import Count, Sum, Max
|
from django.db.models import Count, Sum, Max
|
||||||
|
@ -13,7 +14,7 @@ from django.http import HttpResponse, HttpResponseForbidden, Http404
|
||||||
from django.shortcuts import get_object_or_404, redirect, render_to_response
|
from django.shortcuts import get_object_or_404, redirect, render_to_response
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
from ox.utils import json
|
from ox.utils import json, ET
|
||||||
|
|
||||||
from ox.django.decorators import login_required_json
|
from ox.django.decorators import login_required_json
|
||||||
from ox.django.shortcuts import render_to_json_response, get_object_or_404_json, json_response
|
from ox.django.shortcuts import render_to_json_response, get_object_or_404_json, json_response
|
||||||
|
@ -808,6 +809,51 @@ def random_annotation(request):
|
||||||
clip = item.annotations.all()[pos]
|
clip = item.annotations.all()[pos]
|
||||||
return redirect('/%s'% clip.public_id)
|
return redirect('/%s'% clip.public_id)
|
||||||
|
|
||||||
|
def oembed(request):
|
||||||
|
format = request.GET.get('format', 'json')
|
||||||
|
maxwidth = request.GET.get('maxwidth', 640)
|
||||||
|
maxheight = request.GET.get('maxheight', 480)
|
||||||
|
|
||||||
|
url = request.GET['url']
|
||||||
|
parts = urlparse(url).path.split('/')
|
||||||
|
itemId = parts[1]
|
||||||
|
#fixme: embed should reflect actuall url
|
||||||
|
item = get_object_or_404_json(models.Item, itemId=itemId)
|
||||||
|
embed_url = request.build_absolute_uri('/%s/embed' % item.itemId)
|
||||||
|
oembed = {}
|
||||||
|
oembed['version'] = '1.0'
|
||||||
|
oembed['type'] = 'video'
|
||||||
|
oembed['provider_name'] = settings.SITENAME
|
||||||
|
oembed['provider_url'] = request.build_absolute_uri('/')
|
||||||
|
oembed['title'] = item.get('title')
|
||||||
|
#oembed['author_name'] = item.get('director')
|
||||||
|
#oembed['author_url'] = ??
|
||||||
|
height = 96
|
||||||
|
width = 128
|
||||||
|
if maxheight > height or height > maxheight:
|
||||||
|
height = maxheight
|
||||||
|
if maxwidth > width or width > maxwidth:
|
||||||
|
width = maxwidth
|
||||||
|
oembed['html'] = '<iframe width="%s" height="%s" src="%s" frameborder="0" allowfullscreen></iframe>' % (height, width, embed_url)
|
||||||
|
oembed['width'] = width
|
||||||
|
oembed['height'] = height
|
||||||
|
thumbheight = 96
|
||||||
|
thumbwidth = int(thumbheight * item.sort.aspectratio)
|
||||||
|
thumbwidth -= thumbwidth % 2
|
||||||
|
oembed['thumbnail_height'] = thumbheight
|
||||||
|
oembed['thumbnail_width'] = thumbwidth
|
||||||
|
oembed['thumbnail_url'] = request.build_absolute_uri('/%s/%sp.jpg' % (item.itemId, thumbheight))
|
||||||
|
if format == 'xml':
|
||||||
|
oxml = ET.Element('oembed')
|
||||||
|
for key in oembed:
|
||||||
|
e = ET.SubElement(oxml, key)
|
||||||
|
e.text = unicode(oembed[key])
|
||||||
|
return HttpResponse(
|
||||||
|
'<?xml version="1.0" encoding="utf-8" standalone="yes"?>\n' + ET.tostring(oxml),
|
||||||
|
'application/xml'
|
||||||
|
)
|
||||||
|
return HttpResponse(json.dumps(oembed, indent=2), 'application/json')
|
||||||
|
|
||||||
def item(request, id):
|
def item(request, id):
|
||||||
id = id.split('/')[0]
|
id = id.split('/')[0]
|
||||||
template = 'index.html'
|
template = 'index.html'
|
||||||
|
@ -834,13 +880,17 @@ def item(request, id):
|
||||||
value = value = u', '.join([unicode(v) for v in value])
|
value = value = u', '.join([unicode(v) for v in value])
|
||||||
data.append({'key': key.capitalize(), 'value': value})
|
data.append({'key': key.capitalize(), 'value': value})
|
||||||
clips = []
|
clips = []
|
||||||
for c in item.clips.all():
|
clip = {'in': 0, 'annotations': []}
|
||||||
clip = {
|
for a in item.annotations.filter(
|
||||||
'in': c.start,
|
layer__in=models.Annotation.public_layers()).order_by('start', 'end', 'sortvalue'):
|
||||||
'annotations': '<br />\n'.join([a.value for a in c.annotations.all()])
|
if clip['in'] < a.start:
|
||||||
}
|
if clip['annotations']:
|
||||||
clips.append(clip)
|
clip['annotations'] = '<br />\n'.join(clip['annotations'])
|
||||||
|
clips.append(clip)
|
||||||
|
clip = {'in': a.start, 'annotations': []}
|
||||||
|
clip['annotations'].append(a.value)
|
||||||
ctx = {
|
ctx = {
|
||||||
|
'current_url': request.build_absolute_uri(request.get_full_path()),
|
||||||
'base_url': request.build_absolute_uri('/'),
|
'base_url': request.build_absolute_uri('/'),
|
||||||
'url': request.build_absolute_uri('/%s' % id),
|
'url': request.build_absolute_uri('/%s' % id),
|
||||||
'id': id,
|
'id': id,
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
<link rel="icon" href="/static/png/icon64.png" sizes="48x48"/>
|
<link rel="icon" href="/static/png/icon64.png" sizes="48x48"/>
|
||||||
<meta name="application-name" content="{{settings.SITENAME}}"/>
|
<meta name="application-name" content="{{settings.SITENAME}}"/>
|
||||||
<meta name="application-url" content="{{base_url}}"/>
|
<meta name="application-url" content="{{base_url}}"/>
|
||||||
|
<link rel="alternate" type="application/json+oembed" href="{{base_url}}oembed?url={{current_url|urlencode}}" title="oEmbed Profile" />
|
||||||
<link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="{{settings.SITENAME}}" />
|
<link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="{{settings.SITENAME}}" />
|
||||||
<script>
|
<script>
|
||||||
if (localStorage && !localStorage['Ox.theme'])
|
if (localStorage && !localStorage['Ox.theme'])
|
||||||
|
|
|
@ -29,6 +29,7 @@ urlpatterns = patterns('',
|
||||||
(r'^robots.txt$', serve_static_file, {'location': os.path.join(settings.STATIC_ROOT, 'robots.txt'), 'content_type': 'text/plain'}),
|
(r'^robots.txt$', serve_static_file, {'location': os.path.join(settings.STATIC_ROOT, 'robots.txt'), 'content_type': 'text/plain'}),
|
||||||
(r'^favicon.ico$', serve_static_file, {'location': os.path.join(settings.STATIC_ROOT, 'png/icon.16.png'), 'content_type': 'image/x-icon'}),
|
(r'^favicon.ico$', serve_static_file, {'location': os.path.join(settings.STATIC_ROOT, 'png/icon.16.png'), 'content_type': 'image/x-icon'}),
|
||||||
(r'^opensearch.xml$', 'app.views.opensearch_xml'),
|
(r'^opensearch.xml$', 'app.views.opensearch_xml'),
|
||||||
|
(r'^oembed$', 'item.views.oembed'),
|
||||||
(r'', include('item.urls')),
|
(r'', include('item.urls')),
|
||||||
)
|
)
|
||||||
#if settings.DEBUG:
|
#if settings.DEBUG:
|
||||||
|
|
Loading…
Reference in a new issue