display code in api browser

This commit is contained in:
j 2011-01-26 18:55:26 +05:30
commit 97fc9179c9
10 changed files with 31 additions and 6 deletions

View file

View file

@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
from django.contrib import admin
import models
class LayerAdmin(admin.ModelAdmin):
search_fields = ['name', 'title']
admin.site.register(models.Layer, LayerAdmin)
class AnnotationAdmin(admin.ModelAdmin):
search_fields = ['name', 'title']
admin.site.register(models.Annotation, AnnotationAdmin)

View file

@ -0,0 +1,94 @@
# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
from __future__ import division, with_statement
from django.db import models
from django.contrib.auth.models import User
import utils
class Layer(models.Model):
class Meta:
ordering = ('position', )
enabled = models.BooleanField(default=True)
name = models.CharField(null=True, max_length=255, unique=True)
title = models.CharField(null=True, max_length=255)
#text, string, string from list(fixme), date, place, person, pingback,
#What about: smart layers? for date, place, person
type = models.CharField(null=True, max_length=255)
#can this be changed per user?
position = models.IntegerField(default=0)
overlap = models.BooleanField(default=True)
overlay = models.BooleanField(default=True)
public = models.BooleanField(default=True) #false=users only see there own bins
#find/sort integration
find = models.BooleanField(default=True) #true part of find all
#words / item duration(wpm), total words, cuts per minute, cuts, number of annotations, number of annotations/duration
sort = models.CharField(null=True, max_length=255)
def properties(self):
p = {}
if self.find:
p[self.name] = {'type': 'bin', 'find': True}
if self.sort:
print 'FIXME: need to add sort stuff'
return p
def json(self):
return {'id': self.name, 'title': self.title, 'type': self.type}
def __unicode__(self):
return self.title
class Annotation(models.Model):
#FIXME: here having a item,start index would be good
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
user = models.ForeignKey(User)
item = models.ForeignKey('item.Item', related_name='annotations')
#seconds
start = models.FloatField(default=-1)
end = models.FloatField(default=-1)
layer = models.ForeignKey(Layer)
value = models.TextField()
def editable(self, user):
if user.is_authenticated():
if user.is_staff or \
self.user == user or \
user.groups.filter(id__in=self.groups.all()).count() > 0:
return True
return False
def html(self):
if self.layer.type == 'string':
return utils.html_parser(self.value)
else:
return self.value
def get_id(self):
return ox.to32(self.id)
def json(self):
return {
'id': self.get_id(),
'user': self.user.username,
'start': self.start,
'end': self.end,
'value': self.value,
'value_html': self.html(),
'layer': self.layer.name
}
def __unicode__(self):
return u"%s/%s-%s" %(self.item, self.start, self.end)

View file

@ -0,0 +1,24 @@
"""
This file demonstrates two different styles of tests (one doctest and one
unittest). These will both pass when you run "manage.py test".
Replace these with more appropriate tests for your application.
"""
from django.test import TestCase
class SimpleTest(TestCase):
def test_basic_addition(self):
"""
Tests that 1 + 1 always equals 2.
"""
self.failUnlessEqual(1 + 1, 2)
__test__ = {"doctest": """
Another way to test that 1 + 1 is equal to 2.
>>> 1 + 1 == 2
True
"""}

View file

@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
# ci:si:et:sw=4:sts=4:ts=4
import re
import ox
def html_parser(text, nofollow=True):
text = text.replace('<i>', '__i__').replace('</i>', '__/i__')
text = text.replace('<b>', '__b__').replace('</b>', '__/b__')
#truns links into wiki links, make sure to only take http links
text = re.sub('<a .*?href="(http.*?)".*?>(.*?)</a>', '[\\1 \\2]', text)
text = ox.escape(text)
text = text.replace('__i__', '<i>').replace('__/i__', '</i>')
text = text.replace('__b__', '<b>').replace('__/b__', '</b>')
if nofollow:
nofollow_rel = ' rel="nofollow"'
else:
nofollow_rel = ''
links = re.compile('(\[(http.*?) (.*?)\])').findall(text)
for t, link, txt in links:
link = link.replace('http', '__LINK__').replace('.', '__DOT__')
ll = '<a href="%s"%s>%s</a>' % (link, nofollow_rel, txt)
text = text.replace(t, ll)
links = re.compile('(\[(http.*?)\])').findall(text)
for t, link in links:
link = link.replace('http', '__LINK__').replace('.', '__DOT__')
ll = '<a href="%s"%s>%s</a>' % (link, nofollow_rel, link)
text = text.replace(t, ll)
text = ox.urlize(text, nofollow=nofollow)
#inpage links
text = re.sub('\[(/.+?) (.+?)\]', '<a href="\\1">\\2</a>', text)
text = text.replace('__LINK__', 'http').replace('__DOT__', '.')
text = text.replace("\n", '<br />')
return text

117
pandora/annotation/views.py Normal file
View file

@ -0,0 +1,117 @@
# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
from __future__ import division
from ox.utils import 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
import models
from api.actions import actions
def findAnnotations(request):
'''
param data {
fixme
}
return {
'status': {'code': int, 'text': string}
'data': {
annotations = [{..}, {...}, ...]
}
}
'''
#FIXME: implement findItem like queries
data = json.loads(request.POST['data'])
response = json_response(status=200, text='ok')
qs = models.Annotations.objects.filter(item__itemId=data['item'])
response['data']['annotations'] = [a.json() for a in qs]
return render_to_json_response(response)
actions.register(findAnnotations)
@login_required_json
def addAnnotation(request):
'''
param data {
item: itemId,
layer: layerId,
start: float,
end: float,
value: string
}
return {'status': {'code': int, 'text': string},
'data': {
'annotation': {}s
}
}
'''
data = json.loads(request.POST['data'])
for key in ('item', 'layer', 'start', 'end', 'value'):
if key not in data:
return render_to_json_response(json_response(status=400,
text='invalid data'))
item = get_object_or_404_json(models.Item, itemId=data['item'])
layer = get_object_or_404_json(models.Layer, layerId=data['layer'])
annotation = models.Annotation(
item=item,
layer=layer,
user=request.user,
start=float(data['start']), end=float(data['end']),
value=data['value'])
annotation.save()
response = json_response()
response['data']['annotation'] = annotation.json()
return render_to_json_response(response)
response = {'status': {'code': 501, 'text': 'not implemented'}}
return render_to_json_response(response)
actions.register(addAnnotation, cache=False)
@login_required_json
def removeAnnotation(request):
'''
param data {
id:
}
return {'status': {'code': int, 'text': string},
'data': {
}
}
'''
response = {'status': {'code': 501, 'text': 'not implemented'}}
return render_to_json_response(response)
actions.register(removeAnnotation, cache=False)
@login_required_json
def editAnnotation(request):
'''
param data {
id:,
start: float,
end: float,
value: string,
}
return {'status': {'code': int, 'text': string},
'data': {
}
}
'''
response = json_response({})
data = json.loads(request.POST['data'])
layer = get_object_or_404_json(models.Layer, pk=data['id'])
if layer.editable(request.user):
response = json_response(status=501, text='not implemented')
else:
response = json_response(status=403, text='permission denied')
return render_to_json_response(response)
response = json_response(status=501, text='not implemented')
return render_to_json_response(response)
actions.register(editAnnotation, cache=False)