diff --git a/pandora/config.0xdb.jsonc b/pandora/config.0xdb.jsonc index 3de865367..5d08a295c 100644 --- a/pandora/config.0xdb.jsonc +++ b/pandora/config.0xdb.jsonc @@ -56,6 +56,7 @@ "canImportItems": {}, "canManageDocuments": {"staff": true, "admin": true}, "canManageEntities": {"staff": true, "admin": true}, + "canManageHome": {"staff": true, "admin": true}, "canManagePlacesAndEvents": {"staff": true, "admin": true}, "canManageTitlesAndNames": {"staff": true, "admin": true}, "canManageUsers": {"staff": true, "admin": true}, diff --git a/pandora/config.indiancinema.jsonc b/pandora/config.indiancinema.jsonc index 7b78a233e..085fd3fdc 100644 --- a/pandora/config.indiancinema.jsonc +++ b/pandora/config.indiancinema.jsonc @@ -58,6 +58,7 @@ "canImportItems": {}, "canManageDocuments": {"member": true, "researcher": true, "staff": true, "admin": true}, "canManageEntities": {"member": true, "researcher": true, "staff": true, "admin": true}, + "canManageHome": {"staff": true, "admin": true}, "canManagePlacesAndEvents": {"member": true, "researcher": true, "staff": true, "admin": true}, "canManageTitlesAndNames": {"member": true, "researcher": true, "staff": true, "admin": true}, "canManageUsers": {"staff": true, "admin": true}, diff --git a/pandora/config.padma.jsonc b/pandora/config.padma.jsonc index f68942a1b..5a7b1fd92 100644 --- a/pandora/config.padma.jsonc +++ b/pandora/config.padma.jsonc @@ -56,6 +56,7 @@ "canImportItems": {"member": true, "staff": true, "admin": true}, "canManageDocuments": {"member": true, "staff": true, "admin": true}, "canManageEntities": {"member": true, "staff": true, "admin": true}, + "canManageHome": {"staff": true, "admin": true}, "canManagePlacesAndEvents": {"member": true, "staff": true, "admin": true}, "canManageTitlesAndNames": {"member": true, "staff": true, "admin": true}, "canManageUsers": {"staff": true, "admin": true}, diff --git a/pandora/config.pandora.jsonc b/pandora/config.pandora.jsonc index a6df8ca73..3fdb7edd3 100644 --- a/pandora/config.pandora.jsonc +++ b/pandora/config.pandora.jsonc @@ -60,6 +60,7 @@ examples (config.SITENAME.jsonc) that are part of this pan.do/ra distribution. "canImportItems": {"member": true, "staff": true, "admin": true}, "canManageDocuments": {"member": true, "staff": true, "admin": true}, "canManageEntities": {"member": true, "staff": true, "admin": true}, + "canManageHome": {"staff": true, "admin": true}, "canManagePlacesAndEvents": {"member": true, "staff": true, "admin": true}, "canManageTitlesAndNames": {"member": true, "staff": true, "admin": true}, "canManageUsers": {"staff": true, "admin": true}, diff --git a/pandora/home/__init__.py b/pandora/home/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/pandora/home/admin.py b/pandora/home/admin.py new file mode 100644 index 000000000..8c38f3f3d --- /dev/null +++ b/pandora/home/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/pandora/home/apps.py b/pandora/home/apps.py new file mode 100644 index 000000000..1d6cbbdf0 --- /dev/null +++ b/pandora/home/apps.py @@ -0,0 +1,7 @@ +from __future__ import unicode_literals + +from django.apps import AppConfig + + +class HomeConfig(AppConfig): + name = 'home' diff --git a/pandora/home/migrations/0001_initial.py b/pandora/home/migrations/0001_initial.py new file mode 100644 index 000000000..6027b5b18 --- /dev/null +++ b/pandora/home/migrations/0001_initial.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2017-01-24 17:22 +from __future__ import unicode_literals + +from django.db import migrations, models +import oxdjango.fields + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Item', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created', models.DateTimeField(auto_now_add=True)), + ('modified', models.DateTimeField(auto_now=True)), + ('active', models.BooleanField(default=True)), + ('index', models.IntegerField(default=0)), + ('data', oxdjango.fields.DictField(default={}, editable=False)), + ], + ), + ] diff --git a/pandora/home/migrations/__init__.py b/pandora/home/migrations/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/pandora/home/models.py b/pandora/home/models.py new file mode 100644 index 000000000..5811ff51a --- /dev/null +++ b/pandora/home/models.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- +# vi:si:et:sw=4:sts=4:ts=4 +from __future__ import division, print_function, absolute_import + +from six import string_types +from django.db import models +from django.db.models import Max +import ox + +from oxdjango import fields + + +class Item(models.Model): + created = models.DateTimeField(auto_now_add=True) + modified = models.DateTimeField(auto_now=True) + + active = models.BooleanField(default=True) + index = models.IntegerField(default=-1) + data = fields.DictField(default={}, editable=False) + + def editable(self, user): + return user.is_authenticated() and user.profile.capability("canManageHome") + + def edit(self, data): + changed = False + for key in ( + 'contentid', + 'crop', + 'image', + 'text', + 'title', + 'type', + ): + if key in data and self.data.get(key) != data[key]: + if key == 'crop': + if not (isinstance(data[key], list) + and len([d for d in data[key] if isinstance(d, int)]) == 4): + return False + else: + if not isinstance(data[key], string_types): + return False + self.data[key] = data[key] + changed = True + if 'active' in data: + self.active = data['active'] is True + if changed: + self.save() + return True + + def save(self, *args, **kwargs): + if self.index == -1: + idx = Item.objects.all().aggregate(Max('index'))['index__max'] + idx = 0 if idx is None else idx + 1 + self.index = idx + super(Item, self).save(*args, **kwargs) + + def get(self, id): + return self.objects.get(id=ox.fromAZ(id)) + + def get_id(self): + return ox.toAZ(self.id) + + def json(self, keys=None): + j = { + 'id': self.get_id(), + 'active': self.active, + 'index': self.index, + } + j.update(self.data) + if keys: + for key in list(j): + if key not in keys: + del j[key] + return j + + def __unicode__(self): + return u"%s" %(self.get_id()) diff --git a/pandora/home/tests.py b/pandora/home/tests.py new file mode 100644 index 000000000..7ce503c2d --- /dev/null +++ b/pandora/home/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/pandora/home/views.py b/pandora/home/views.py new file mode 100644 index 000000000..c598ab3a4 --- /dev/null +++ b/pandora/home/views.py @@ -0,0 +1,106 @@ +from django.shortcuts import render +import ox + +from oxdjango.shortcuts import render_to_json_response, get_object_or_404_json, json_response +from user.decorators import capability_required_json +from oxdjango.api import actions + +from . import models + + +@capability_required_json('canManageHome') +def addHomeItem(request, data): + ''' + add new home item + takes { + type: + ... + } + returns { + id: + ... + } + ''' + item = models.Item() + if not item.edit(data): + response = json_response(status=500, text='invalid data') + else: + response = json_response() + return render_to_json_response(response) +actions.register(addHomeItem, cache=False) + +@capability_required_json('canManageHome') +def editHomeItem(request, data): + ''' + edit home item + takes { + id: + ... + } + returns { + id: + ... + } + ''' + item = get_object_or_404_json(models.Item, id=ox.fromAZ(data['id'])) + if not item.edit(data): + response = json_response(status=500, text='failed to edit item') + else: + response = json_response() + return render_to_json_response(response) +actions.register(editHomeItem, cache=False) + +@capability_required_json('canManageHome') +def removeHomeItem(request, data): + ''' + remove home item + takes { + id: + } + returns { + } + ''' + item = get_object_or_404_json(models.Item, id=ox.fromAZ(data['id'])) + item.delete() + response = json_response() + return render_to_json_response(response) +actions.register(removeHomeItem, cache=False) + +@capability_required_json('canManageHome') +def sortHomeItems(request, data): + ''' + sort home times + takes { + ids: [] + } + returns { + } + ''' + response = json_response() + ids = data['ids'] + index = 0 + for id in ids: + item = get_object_or_404_json(models.Item, id=ox.fromAZ(id)) + if item.index != index: + item.index = index + item.save() + index += 1 + return render_to_json_response(response) +actions.register(sortHomeItems, cache=False) + +def getHomeItems(request, data): + ''' + takes { + active: true // if active is set only return active + } + returns { + items: [] + } + ''' + response = json_response() + qs = models.Item.objects.all().order_by('index', 'created') + if 'active' in data: + qs = qs.filter(active=data['active'] is True) + response['data']['items'] = [i.json() for i in qs] + return render_to_json_response(response) +actions.register(getHomeItems) diff --git a/pandora/settings.py b/pandora/settings.py index 51f6b1502..a04358266 100644 --- a/pandora/settings.py +++ b/pandora/settings.py @@ -144,6 +144,7 @@ INSTALLED_APPS = ( 'entity', 'websocket', 'taskqueue', + 'home', ) # Log errors into db