diff --git a/pandora/itemlist/managers.py b/pandora/itemlist/managers.py index 7ba22d0..51059d5 100644 --- a/pandora/itemlist/managers.py +++ b/pandora/itemlist/managers.py @@ -7,7 +7,7 @@ from django.db.models import Q, Manager import models -def parseCondition(condition): +def parseCondition(condition, user): ''' condition: { value: "war" @@ -35,10 +35,9 @@ def parseCondition(condition): exclude = False if k == 'subscribed': print "FXIME, subscribed needs work" - k = 'public' - v = True - - if isinstance(v, bool): #featured and public flag + key = 'subscribed_users__username' + v = user.username + elif isinstance(v, bool): #featured and public flag key = k else: if op == '=': @@ -58,7 +57,7 @@ def parseCondition(condition): q = Q(**{key: v}) return q -def parseConditions(conditions, operator): +def parseConditions(conditions, operator, user): ''' conditions: [ { @@ -81,14 +80,14 @@ def parseConditions(conditions, operator): for condition in conditions: if 'conditions' in condition: q = parseConditions(condition['conditions'], - condition.get('operator', '&')) + condition.get('operator', '&'), user) if q: conn.append(q) pass else: if condition.get('value', '') != '' or \ condition.get('operator', '') == '=': - conn.append(parseCondition(condition)) + conn.append(parseCondition(condition, user)) if conn: q = conn[0] for c in conn[1:]: @@ -129,8 +128,9 @@ class ListManager(Manager): #join query with operator qs = self.get_query_set() - conditions = parseConditions(data['query']['conditions'], - data['query'].get('operator', '&')) + conditions = parseConditions(data['query'].get('conditions', []), + data['query'].get('operator', '&'), + user) if conditions: qs = qs.filter(conditions) diff --git a/pandora/itemlist/models.py b/pandora/itemlist/models.py index e886aa6..9943ddd 100644 --- a/pandora/itemlist/models.py +++ b/pandora/itemlist/models.py @@ -19,7 +19,7 @@ class List(models.Model): created = models.DateTimeField(auto_now_add=True) modified = models.DateTimeField(auto_now=True) - user = models.ForeignKey(User) + user = models.ForeignKey(User, related_name='lists') name = models.CharField(max_length=255) status = models.CharField(max_length=20, default='private') _status = ['private', 'public', 'featured'] @@ -28,6 +28,8 @@ class List(models.Model): items = models.ManyToManyField('item.Item', related_name='lists', through='ListItem') + subscribed_users = models.ManyToManyField(User, related_name='subscribed_lists') + objects = managers.ListManager() def save(self, *args, **kwargs): @@ -53,22 +55,29 @@ class List(models.Model): def __unicode__(self): return u'%s (%s)' % (self.name, self.user) + def get_id(self): + return '%s:%s' % (self.user.username, self.name) + def editable(self, user): #FIXME: make permissions work - if self.user == user or user.has_perm('Ox.admin'): + if self.user == user or user.is_staff: return True return False - def json(self, keys, user=None): + def json(self, keys=['id', 'name', 'user', 'query', 'status'], user=None): response = {} for key in keys: if key == 'items': response[key] = self.get_number_of_items(user) + elif key == 'id': + response[key] = self.get_id() elif key == 'user': response[key] = self.user.username elif key == 'query': if not self.query.get('static', False): response[key] = self.query + elif key == 'ui': + response[key] = site_conf['uiDefaults']['list'] else: response[key] = getattr(self, key) return response @@ -81,3 +90,4 @@ class ListItem(models.Model): def __unicode__(self): return u'%s in %s' % (self.item, self.list) + diff --git a/pandora/itemlist/views.py b/pandora/itemlist/views.py index 169feb2..edf8d40 100644 --- a/pandora/itemlist/views.py +++ b/pandora/itemlist/views.py @@ -160,7 +160,7 @@ def addList(request): } ''' data = json.loads(request.POST['data']) - if models.List.filter(name=data['name'], user=request.user).count() == 0: + if models.List.objects.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') @@ -186,8 +186,10 @@ def editList(request): } ''' data = json.loads(request.POST['data']) - list = get_object_or_404_json(models.List, pk=data['list']) + username, listname = data['id'].split(':') + list = get_object_or_404_json(models.List, user__username=username, name=listname) if list.editable(request.user): + response = json_response() for key in data: if key in ('name', 'status', 'query'): if key in data: @@ -200,7 +202,7 @@ def editList(request): setattr(list, key, value) else: setattr(list, key, data[key]) - if user.has_perm('Ox.admin') and 'featured' in data: + if request.user.is_staff and 'featured' in data: list.featured = data['featured'] else: response = json_response(status=403, text='not allowed') @@ -223,7 +225,7 @@ def removeList(request): ''' data = json.loads(request.POST['data']) user = request.user.username - if user.has_perm('Ox.admin') and 'user' in data: + if user.is_staff 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): @@ -232,3 +234,49 @@ def removeList(request): response = json_response(status=403, text='not allowed') return render_to_json_response(response) actions.register(removeList) + + +@login_required_json +def subscribeToList(request): + ''' + param data { + id: listId, + user: username(only admins) + } + return { + status: {'code': int, 'text': string}, + data: { + } + } + ''' + data = json.loads(request.POST['data']) + username, listname = data['id'].split(':') + list = get_object_or_404_json(models.List, user__username=username, name=listname) + user = request.user + if list.subscribed_users.filter(username=user.username).count() == 0: + list.subscribed_users.add(user) + response = json_response() + return render_to_json_response(response) +actions.register(subscribeToList) + +@login_required_json +def unsubscribeFromList(request): + ''' + param data { + id: listId, + user: username(only admins) + } + return { + status: {'code': int, 'text': string}, + data: { + } + } + ''' + data = json.loads(request.POST['data']) + username, listname = data['id'].split(':') + list = get_object_or_404_json(models.List, user__username=username, name=listname) + user = request.user + list.subscribed_users.remove(user) + response = json_response() + return render_to_json_response(response) +actions.register(unsubscribeFromList) diff --git a/pandora/templates/site.json b/pandora/templates/site.json index 65600cd..9b17cf5 100644 --- a/pandora/templates/site.json +++ b/pandora/templates/site.json @@ -124,6 +124,16 @@ {"id": "size", "admin": true}, {"id": "pixels"} ], + "uiDefaults": { + "list": { + "columns": ["id", "title", "director", "country", "year", "language", "runtime", "genre"], + "listView": "icons", + "selected": [], + "sort": [ + {"key": "director", "operator": ""} + ] + } + }, "user": { "group": "guest", "lists": { @@ -131,13 +141,14 @@ {"id": "all_movies", "title": "All Movies", "query": {}} ], "my": [ + {"user": "foo", "name": "Favorites", "featured": false, "public": true}, {"id": "favorites", "title": "Favorites", "public": true, "items": []}, {"id": "most_popular", "title": "Most Popular", "query": {}}, {"id": "recently_viewed", "title": "Recently Viewed", "query": {}}, {"id": "1960s", "title": "1960s", "query": {"conditions": [{"key": "year", "value": "196", "operator": "^"}], "operator": ""}} ], "public": [ - {"id": "rlx_watchme", "title": "rlx: watchme", "public": true, "items": [0, 1, 2, 3, 4]} + {"id": "rlx:watchme", "title": "rlx: watchme", "public": true, "items": [0, 1, 2, 3, 4]} ], "featured": [ {"id": "situationist_film", "title": "Situationist Film", "query": {}}, @@ -147,17 +158,26 @@ "preferences": {}, "ui": { "annotationsSize": 256, - "columns": ["id", "title", "director", "country", "year", "language", "runtime", "genre"], "findQuery": {"conditions": [], "operator": ""}, "groups": ["director", "country", "year", "language", "genre"], "groupsQuery": {"conditions": [], "operator": "|"}, "groupsSize": 176, "item": "", "itemView": "timeline", + "list": "", "listQuery": {"conditions": [], "operator": ""}, - "listView": "icons", + "lists": { + "": { + "columns": ["id", "title", "director", "country", "year", "language", "runtime", "genre"], + "listView": "icons", + "selected": [], + "sort": [ + {"key": "director", "operator": ""} + ] + } + }, "section": "items", - "sections": ["history", "my", "public", "featured"], + "sections": ["my", "public", "featured"], "showAnnotations": true, "showGroups": true, "showInfo": true, @@ -165,9 +185,6 @@ "showSidebar": true, "sidebarSize": 256, "sitePage": "home", - "sort": [ - {"key": "director", "operator": ""} - ], "theme": "classic" }, "username": "" diff --git a/pandora/timeline/models.py b/pandora/timeline/models.py index cd8dae5..4f5af8c 100644 --- a/pandora/timeline/models.py +++ b/pandora/timeline/models.py @@ -24,7 +24,7 @@ class Timeline(models.Model): def editable(self, user): #FIXME: make permissions work - if self.user == user or user.has_perm('Ox.admin'): + if self.user == user or user.is_staff: return True return False diff --git a/pandora/user/models.py b/pandora/user/models.py index 3565b33..a20ebdf 100644 --- a/pandora/user/models.py +++ b/pandora/user/models.py @@ -23,6 +23,26 @@ class UserProfile(models.Model): ui = DictField(default={}) preferences = DictField(default={}) + def get_preferences(self): + prefs = self.preferences + prefs['email'] = self.user.email + return prefs + + def get_ui(self): + ui = {} + ui.update(site_config['user']['ui']) + ui.update(self.ui) + if not 'lists' in ui: + ui['lists'] = {} + ui['lists'][''] = site_config['uiDefaults']['list'] + ids = [l.get_id() for l in self.user.lists.all()] + ids += [l.get_id() for l in self.user.subscribed_lists.all()] + ids += [l.get_id() for l in List.objects.filter(status='featured').exclude(user=self.user)] + for l in ids: + if l not in ui['lists']: + ui['lists'][l] = ui['lists'][''] + return ui + def user_post_save(sender, instance, **kwargs): profile, new = UserProfile.objects.get_or_create(user=instance) @@ -30,6 +50,7 @@ models.signals.post_save.connect(user_post_save, sender=User) def get_user_json(user): + profile = user.get_profile() result = {} for key in ('username', ): result[key] = getattr(user, key) @@ -38,61 +59,6 @@ def get_user_json(user): result['group'] = 'admin' elif user.has_perm('0x.vip'): #FIXME: permissions result['group'] = 'vip' - result['preferences'] = get_preferences(user) - result['ui'] = get_ui(user) + result['preferences'] = profile.get_preferences() + result['ui'] = profile.get_ui() return result - - -def get_ui(user): - return site_config['user']['ui'] - ''' - return { - "columns": ["id", "title", "director", "country", "year", "language", "genre"], - "findQuery": {"conditions": [], "operator": ""}, - "groupsQuery": {"conditions": [], "operator": "|"}, - "groupsSize": 128, - "itemView": "timeline", - "listQuery": {"conditions": [], "operator": ""}, - "listsSize": 192, - "listView": "icons", - "sections": ["history", "lists", "public", "featured"], - "showGroups": True, - "showInfo": True, - "showLists": True, - "showMovies": True, - "sort": settings.DEFAULT_SORT, - "theme": settings.DEFAULT_THEME - } - ''' - - -def get_preferences(user): - prefs = user.get_profile().preferences - prefs['email'] = user.email - return prefs - - -def get_preference(user, key, value=None): - if key in ('email', ): - value = getattr(user, key) - else: - q = Preference.objects.filter(user=user, key=key) - if q.count() > 0: - value = json.loads(q[0].value) - return value - - -def set_preference(user, key, value): - if key in ('email', ): - setattr(user, key, value) - user.save() - else: - value = json.dumps(value) - q = Preference.objects.filter(user=user, key=key) - if q.count() > 0: - p = q[0] - p.value = value - p.save() - else: - p = Preference(user=user, key=key, value=value) - p.save() diff --git a/pandora/user/views.py b/pandora/user/views.py index 4272df4..9e38ada 100644 --- a/pandora/user/views.py +++ b/pandora/user/views.py @@ -408,7 +408,12 @@ def setUI(request): param data { key.subkey: value } - return + you can set nested keys + api.setUI({"lists.my.listView": "icons"}) + + return { + 'status': {'code': int, 'text': string} + } ''' data = json.loads(request.POST['data']) keys = data.keys()[0].split('.')