add per item document api

This commit is contained in:
j 2013-05-27 11:21:08 +00:00
parent 8da6badf4c
commit 71846d5461
5 changed files with 230 additions and 18 deletions

View file

@ -0,0 +1,127 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding model 'ItemProperties'
db.create_table('document_itemproperties', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('created', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
('modified', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, blank=True)),
('item', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['item.Item'])),
('document', self.gf('django.db.models.fields.related.ForeignKey')(related_name='descriptions', to=orm['document.Document'])),
('description', self.gf('django.db.models.fields.TextField')(default='')),
('index', self.gf('django.db.models.fields.IntegerField')(default=0)),
))
db.send_create_signal('document', ['ItemProperties'])
# Adding unique constraint on 'ItemProperties', fields ['item', 'document']
db.create_unique('document_itemproperties', ['item_id', 'document_id'])
def backwards(self, orm):
# Removing unique constraint on 'ItemProperties', fields ['item', 'document']
db.delete_unique('document_itemproperties', ['item_id', 'document_id'])
# Deleting model 'ItemProperties'
db.delete_table('document_itemproperties')
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '255', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'document.document': {
'Meta': {'unique_together': "(('user', 'name', 'extension'),)", 'object_name': 'Document'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.TextField', [], {'default': "''"}),
'description_sort': ('django.db.models.fields.CharField', [], {'max_length': '512'}),
'extension': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'file': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'items': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'documents'", 'symmetrical': 'False', 'through': "orm['document.ItemProperties']", 'to': "orm['item.Item']"}),
'matches': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'name_sort': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'oshash': ('django.db.models.fields.CharField', [], {'max_length': '16', 'unique': 'True', 'null': 'True'}),
'ratio': ('django.db.models.fields.FloatField', [], {'default': '1'}),
'size': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'uploading': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'files'", 'to': "orm['auth.User']"})
},
'document.itemproperties': {
'Meta': {'unique_together': "(('item', 'document'),)", 'object_name': 'ItemProperties'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.TextField', [], {'default': "''"}),
'document': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'descriptions'", 'to': "orm['document.Document']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'index': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'item': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['item.Item']"}),
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
},
'item.item': {
'Meta': {'object_name': 'Item'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'data': ('ox.django.fields.DictField', [], {'default': '{}'}),
'external_data': ('ox.django.fields.DictField', [], {'default': '{}'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'items'", 'blank': 'True', 'to': "orm['auth.Group']"}),
'icon': ('django.db.models.fields.files.ImageField', [], {'default': 'None', 'max_length': '100', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'itemId': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128', 'blank': 'True'}),
'json': ('ox.django.fields.DictField', [], {'default': '{}'}),
'level': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'oxdbId': ('django.db.models.fields.CharField', [], {'max_length': '42', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
'poster': ('django.db.models.fields.files.ImageField', [], {'default': 'None', 'max_length': '100', 'blank': 'True'}),
'poster_frame': ('django.db.models.fields.FloatField', [], {'default': '-1'}),
'poster_height': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'poster_source': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'poster_width': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'rendered': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}),
'stream_aspect': ('django.db.models.fields.FloatField', [], {'default': '1.3333333333333333'}),
'stream_info': ('ox.django.fields.DictField', [], {'default': '{}'}),
'torrent': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '1000', 'blank': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'items'", 'null': 'True', 'to': "orm['auth.User']"})
}
}
complete_apps = ['document']

View file

@ -7,12 +7,15 @@ import subprocess
from urllib import quote, unquote from urllib import quote, unquote
from django.db import models from django.db import models
from django.db.models import Max
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.db.models.signals import pre_delete from django.db.models.signals import pre_delete
import Image import Image
import ox import ox
from item.models import Item
import managers import managers
@ -41,6 +44,8 @@ class Document(models.Model):
name_sort = models.CharField(max_length=255) name_sort = models.CharField(max_length=255)
description_sort = models.CharField(max_length=512) description_sort = models.CharField(max_length=512)
items = models.ManyToManyField(Item, through='ItemProperties', related_name='documents')
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
if not self.uploading: if not self.uploading:
if self.file: if self.file:
@ -56,6 +61,15 @@ class Document(models.Model):
def __unicode__(self): def __unicode__(self):
return self.get_id() return self.get_id()
def add(self, item):
p, created = ItemProperties.objects.get_or_create(item=item, document=self)
if created:
p.index = ItemProperties.objects.filter(item=item).aggregate(Max('index'))['index__max'] + 1
p.save()
def remove(self, item):
ItemProperties.objects.filter(item=item, document=self).delete()
@classmethod @classmethod
def get(cls, id): def get(cls, id):
username, name, extension = cls.parse_id(id) username, name, extension = cls.parse_id(id)
@ -86,7 +100,7 @@ class Document(models.Model):
return True return True
return False return False
def edit(self, data, user): def edit(self, data, user, item=None):
for key in data: for key in data:
if key == 'name': if key == 'name':
data['name'] = re.sub(' \[\d+\]$', '', data['name']).strip() data['name'] = re.sub(' \[\d+\]$', '', data['name']).strip()
@ -98,10 +112,15 @@ class Document(models.Model):
num += 1 num += 1
name = data['name'] + ' [%d]' % num name = data['name'] + ' [%d]' % num
self.name = name self.name = name
elif key == 'description': elif key == 'description' and not item:
self.description = ox.sanitize_html(data['description']) self.description = ox.sanitize_html(data['description'])
if item:
p, created = ItemProperties.objects.get_or_create(item=item, document=self)
if 'description' in data:
p.description = ox.sanitize_html(data['description'])
p.save()
def json(self, keys=None, user=None): def json(self, keys=None, user=None, item=None):
if not keys: if not keys:
keys=[ keys=[
'description', 'description',
@ -126,6 +145,12 @@ class Document(models.Model):
response[key] = self.user.username response[key] = self.user.username
elif hasattr(self, _map.get(key, key)): elif hasattr(self, _map.get(key, key)):
response[key] = getattr(self, _map.get(key,key)) response[key] = getattr(self, _map.get(key,key))
if item:
d = self.descriptions.filter(item=item)
if d.exists():
if 'description' in keys and d[0].description:
response['description'] = d[0].description
response['index'] = d[0].index
return response return response
def path(self, name=''): def path(self, name=''):
@ -202,3 +227,16 @@ def delete_document(sender, **kwargs):
t.file.delete() t.file.delete()
pre_delete.connect(delete_document, sender=Document) pre_delete.connect(delete_document, sender=Document)
class ItemProperties(models.Model):
class Meta:
unique_together = ("item", "document")
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
item = models.ForeignKey(Item)
document = models.ForeignKey(Document, related_name='descriptions')
description = models.TextField(default="")
index = models.IntegerField(default=0)

View file

@ -39,8 +39,8 @@ def addDocument(request):
item = Item.objects.get(itemId=data['item']) item = Item.objects.get(itemId=data['item'])
if item.editable(request.user): if item.editable(request.user):
for id in ids: for id in ids:
file = models.Document.get(id) document = models.Document.get(id)
item.documents.add(file) document.add(item)
else: else:
response = json_response(status=403, file='permission denied') response = json_response(status=403, file='permission denied')
return render_to_json_response(response) return render_to_json_response(response)
@ -53,6 +53,7 @@ def editDocument(request):
id: string id: string
name: string name: string
description: string description: string
item(optional): edit descriptoin per item
} }
returns { returns {
id: id:
@ -61,16 +62,17 @@ def editDocument(request):
''' '''
response = json_response() response = json_response()
data = json.loads(request.POST['data']) data = json.loads(request.POST['data'])
item = 'item' in data and Item.objects.get(itemId=data['item']) or None
if data['id']: if data['id']:
file = models.Document.get(data['id']) document = models.Document.get(data['id'])
if file.editable(request.user): if document.editable(request.user):
file.edit(data, request.user) document.edit(data, request.user, item=item)
file.save() document.save()
response['data'] = file.json(user=request.user) response['data'] = document.json(user=request.user, item=item)
else: else:
response = json_response(status=403, file='permission denied') response = json_response(status=403, text='permission denied')
else: else:
response = json_response(status=500, file='invalid request') response = json_response(status=500, text='invalid request')
return render_to_json_response(response) return render_to_json_response(response)
actions.register(editDocument, cache=False) actions.register(editDocument, cache=False)
@ -160,7 +162,11 @@ def removeDocument(request):
id: string, id: string,
or or
ids: [string] ids: [string]
item: string
} }
if item is passed, remove relation to item
otherwise remove document
returns { returns {
} }
''' '''
@ -171,16 +177,50 @@ def removeDocument(request):
ids = data['ids'] ids = data['ids']
else: else:
ids = [data['id']] ids = [data['id']]
for id in ids: item = 'item' in data and Item.objects.get(itemId=data['item']) or None
file = models.Document.get(id) if item:
if file.editable(request.user): if item.editable(request.user):
file.delete() for id in ids:
document = models.Document.get(id)
document.remove(item)
else: else:
response = json_response(status=403, file='not allowed') response = json_response(status=403, text='not allowed')
break else:
for id in ids:
document = models.Document.get(id)
if document.editable(request.user):
document.delete()
else:
response = json_response(status=403, text='not allowed')
break
return render_to_json_response(response) return render_to_json_response(response)
actions.register(removeDocument, cache=False) actions.register(removeDocument, cache=False)
@login_required_json
def sortDocuments(request):
'''
takes {
item: string
ids: [string]
}
returns {
}
'''
data = json.loads(request.POST['data'])
index = 0
item = Item.objects.get(itemId=data['item'])
ids = data['ids']
if item.editable(request.user):
for i in ids:
document = models.Document.get(i)
models.ItemProperties.objects.filter(item=item, document=document).update(index=index)
index += 1
response = json_response()
else:
response = json_response(status=403, text='permission denied')
return render_to_json_response(response)
actions.register(sortDocuments, cache=False)
def file(request, id): def file(request, id):
document = models.Document.get(id) document = models.Document.get(id)
return HttpFileResponse(document.file.path) return HttpFileResponse(document.file.path)

View file

@ -507,6 +507,11 @@ class Item(models.Model):
for a in qs.order_by('start'): for a in qs.order_by('start'):
ll.append(a.json(user=user)) ll.append(a.json(user=user))
return layers return layers
def get_documents(self, user=None):
qs = self.documents.all()
documents = [d.json(item=self) for d in qs]
return sorted(documents, key=lambda d: d['index'])
def get_json(self, keys=None): def get_json(self, keys=None):
i = { i = {

View file

@ -468,6 +468,8 @@ def get(request):
info['stream'] = item.get_stream() info['stream'] = item.get_stream()
if data['keys'] and 'layers' in data['keys']: if data['keys'] and 'layers' in data['keys']:
info['layers'] = item.get_layers(request.user) info['layers'] = item.get_layers(request.user)
if data['keys'] and 'documents' in data['keys']:
info['documents'] = item.get_documents(request.user)
if data['keys'] and 'files' in data['keys']: if data['keys'] and 'files' in data['keys']:
info['files'] = item.get_files(request.user) info['files'] = item.get_files(request.user)
if not data['keys'] or 'groups' in data['keys'] \ if not data['keys'] or 'groups' in data['keys'] \