diff --git a/pandora/itemlist/models.py b/pandora/itemlist/models.py index ebf09537..802cabf9 100644 --- a/pandora/itemlist/models.py +++ b/pandora/itemlist/models.py @@ -7,6 +7,11 @@ from django.contrib.auth.models import User from ox.django.fields import DictField +from item.models import Item + +import managers + + class List(models.Model): class Meta: @@ -18,12 +23,26 @@ class List(models.Model): name = models.CharField(max_length=255) public = models.BooleanField(default=False) featured = models.BooleanField(default=False) - query = DictField(default={}) items = models.ManyToManyField('item.Item', related_name='lists', through='ListItem') + objects = managers.ListManager() + + def save(self, *args, **kwargs): + if self.query: + self.smart = True + else: + self.smart = False + super(List, self).save(*args, **kwargs) + + def get_number_of_items(self, user=None): + if not self.query: + return self.items.count() + else: + return Item.objects.find({'query': self.query}, user).count() + def add(self, item): q = self.items.filter(id=item.id) if q.count() == 0: @@ -36,7 +55,7 @@ class List(models.Model): self.ListItem.objects.all().filter(item=item, list=self).delete() def __unicode__(self): - return u'%s (%s)' % (self.title, self.user) + return u'%s (%s)' % (self.name, self.user) def editable(self, user): #FIXME: make permissions work @@ -44,6 +63,15 @@ class List(models.Model): return True return False + def json(self, user=None): + return { + 'user': self.user.username, + 'name': self.name, + 'public': self.public, + 'featured': self.featured, + 'query': self.query, + 'items': self.get_number_of_items(user) + } class ListItem(models.Model): created = models.DateTimeField(auto_now_add=True) diff --git a/pandora/itemlist/views.py b/pandora/itemlist/views.py index 56716b40..a6faaaf9 100644 --- a/pandora/itemlist/views.py +++ b/pandora/itemlist/views.py @@ -10,6 +10,72 @@ import models from api.actions import actions +def _order_query(qs, sort): + order_by = [] + for e in sort: + operator = e['operator'] + if operator != '-': + operator = '' + key = e['key'] + order = '%s%s' % (operator, key) + order_by.append(order) + if order_by: + qs = qs.order_by(*order_by) + return qs + +def _parse_query(data, user): + query = {} + query['range'] = [0, 100] + query['sort'] = [{'key':'user', 'operator':'+'}, {'key':'name', 'operator':'+'}] + for key in ('sort', 'keys', 'group', 'list', 'range', 'ids'): + if key in data: + query[key] = data[key] + query['qs'] = models.List.objects.find(data, user) + return query + +def findList(request): + ''' + FIXME: support key: subscribed + param data { + query: { + conditions: [ + { + key: 'user', + value: 'something', + operator: '=' + } + ] + operator: "," + }, + sort: [{key: 'name', operator: '+'}], + range: [0, 100] + } + + possible query keys: + name, user, featured, subscribed + + } + return {status: {code: int, text: string}, + data: { + lists: [ + {name:, user:, featured:, public...} + ] + } + } + ''' + data = json.loads(request.POST['data']) + query = _parse_query(data, request.user) + + #order + qs = _order_query(query['qs'], query['sort']) + #range + qs = qs[query['range'][0]:query['range'][1]] + + response = json_response() + response['data']['lists'] = [l.json(request.user) for l in qs] + return render_to_json_response(response) +actions.register(findList) + @login_required_json def addListItem(request): ''' @@ -18,8 +84,11 @@ def addListItem(request): item: itemId, quert: ... } - return {'status': {'code': int, 'text': string}, - 'data': {}} + return { + status: {'code': int, 'text': string}, + data: { + } + } ''' data = json.loads(request.POST['data']) list = get_object_or_404_json(models.List, pk=data['list']) @@ -47,8 +116,11 @@ def removeListItem(request): item: itemId, quert: ... } - return {'status': {'code': int, 'text': string}, - 'data': {}} + return { + status: {'code': int, 'text': string}, + data: { + } + } ''' data = json.loads(request.POST['data']) list = get_object_or_404_json(models.List, pk=data['list']) @@ -73,14 +145,19 @@ def addList(request): ''' param data {name: value} - return {'status': {'code': int, 'text': string}, - 'data': {}} + return { + status: {'code': int, 'text': string}, + data: { + list: + } + } ''' data = json.loads(request.POST['data']) if models.List.filter(name=data['name'], user=request.user).count() == 0: list = models.List(name = data['name'], user=request.user) list.save() response = json_response(status=200, text='created') + response['data']['list'] = list.json() else: response = json_response(status=200, text='list already exists') response['data']['errors'] = {'name': 'List already exists'} @@ -91,11 +168,14 @@ actions.register(addList) @login_required_json def editList(request): ''' - param data - {key: value} - keys: name, public - return {'status': {'code': int, 'text': string}, - 'data': {} + param data { + key: value + } + keys: name, public, query, featured (if admin) + return { + status: {'code': int, 'text': string}, + data: { + } } ''' data = json.loads(request.POST['data']) @@ -116,13 +196,21 @@ actions.register(editList) @login_required_json def removeList(request): ''' - param data - {key: value} - return {'status': {'code': int, 'text': string}, - 'data': {}} + param data { + name: value, + user: username(only admins) + } + return { + status: {'code': int, 'text': string}, + data: { + } + } ''' data = json.loads(request.POST['data']) - list = get_object_or_404_json(models.List, pk=data['list']) + user = request.user.username + if user.has_perm('Ox.admin') and 'user' in data: + user = data.get('user') + list = get_object_or_404_json(models.List, name=data['name'], user__username=user) if list.editable(request.user): list.delete() else: diff --git a/pandora/settings.py b/pandora/settings.py index 0c33a85a..0a67a711 100644 --- a/pandora/settings.py +++ b/pandora/settings.py @@ -182,6 +182,13 @@ POSTER_PRECEDENCE = ( 'other' ) +DEFAULT_LISTS = [ + {"name": "Favorites"}, + {"name": "1960s", "query": { + "conditions": [{"key": "year", "value": "196", "operator": "^"}], + "operator": ""} + } +] #0xdb.org #POSTER_SERVICES=['http://data.0xdb.org/poster/'] diff --git a/pandora/user/models.py b/pandora/user/models.py index 13c985f0..9692519a 100644 --- a/pandora/user/models.py +++ b/pandora/user/models.py @@ -8,8 +8,11 @@ from django.db import models from django.conf import settings from ox.utils import json +from ox.django.fields import DictField from app.models import site_config +from itemlist.models import List + class UserProfile(models.Model): reset_token = models.TextField(blank=True, null=True, unique=True) @@ -17,7 +20,7 @@ class UserProfile(models.Model): files_updated = models.DateTimeField(default=datetime.now) newsletter = models.BooleanField(default=True) - + ui = DictField(default={}) def user_post_save(sender, instance, **kwargs): profile, new = UserProfile.objects.get_or_create(user=instance) diff --git a/pandora/user/views.py b/pandora/user/views.py index 0dfc42ca..b298c934 100644 --- a/pandora/user/views.py +++ b/pandora/user/views.py @@ -162,6 +162,14 @@ def signup(request): user.is_superuser = first_user user.is_staff = first_user user.save() + #create default user lists: + for l in settings.DEFAULT_LISTS: + list = models.List(name=l['name'], user=user) + for key in ('query', 'public', 'featured'): + if key in l: + setattr(list, key, l[key]) + list.save() + user = authenticate(username=form.data['username'], password=form.data['password']) login(request, user) @@ -399,3 +407,20 @@ def preferences(request): models.set_preference(request.user, key, data[key]) return render_to_json_response(response) actions.register(preferences) + + +@login_required_json +def setUI(request): + ''' + ''' + data = json.loads(request.POST['data']) + keys = data.keys()[0].split('.') + value = data.values()[0] + ui = user.profile.ui + while keys: + key = keys.pop(0) + + response = json_response() + return render_to_json_response(response) +actions.register(preferences) +