From 85c5fafe0d1d326dd47364528141a07d2b0c8cb0 Mon Sep 17 00:00:00 2001 From: j Date: Sun, 31 Dec 2017 14:06:27 +0100 Subject: [PATCH] add groups to collections, edits and lists, towards #3063 --- .../migrations/0002_collection_groups.py | 21 +++++++++++ pandora/documentcollection/models.py | 29 +++++++++++++-- pandora/edit/migrations/0004_edit_groups.py | 21 +++++++++++ pandora/edit/models.py | 12 ++++++- pandora/item/models.py | 11 ++---- .../itemlist/migrations/0002_list_groups.py | 21 +++++++++++ pandora/itemlist/models.py | 35 +++++++++++++++---- pandora/user/utils.py | 12 +++++++ 8 files changed, 143 insertions(+), 19 deletions(-) create mode 100644 pandora/documentcollection/migrations/0002_collection_groups.py create mode 100644 pandora/edit/migrations/0004_edit_groups.py create mode 100644 pandora/itemlist/migrations/0002_list_groups.py diff --git a/pandora/documentcollection/migrations/0002_collection_groups.py b/pandora/documentcollection/migrations/0002_collection_groups.py new file mode 100644 index 000000000..a79e3690e --- /dev/null +++ b/pandora/documentcollection/migrations/0002_collection_groups.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.2 on 2017-12-31 12:33 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('auth', '0008_auto_20171231_1233'), + ('documentcollection', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='collection', + name='groups', + field=models.ManyToManyField(blank=True, related_name='collections', to='auth.Group'), + ), + ] diff --git a/pandora/documentcollection/models.py b/pandora/documentcollection/models.py index 5753619f9..a560638da 100644 --- a/pandora/documentcollection/models.py +++ b/pandora/documentcollection/models.py @@ -9,7 +9,7 @@ from glob import glob 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, Group from django.conf import settings from django.utils.encoding import python_2_unicode_compatible @@ -18,6 +18,7 @@ import ox from oxdjango.fields import DictField, TupleField from archive import extract +from user.utils import update_groups from . import managers @@ -43,6 +44,7 @@ class Collection(models.Model): created = models.DateTimeField(auto_now_add=True) modified = models.DateTimeField(auto_now=True) user = models.ForeignKey(User, related_name='collections') + groups = models.ManyToManyField(Group, blank=True, related_name='collections') name = models.CharField(max_length=255) status = models.CharField(max_length=20, default='private') _status = ['private', 'public', 'featured'] @@ -123,12 +125,16 @@ class Collection(models.Model): if user.is_anonymous(): return False if self.user == user or \ + self.groups.filter(id__in=user.groups.all()).count() > 0 or \ user.is_staff or \ - user.profile.capability('canEditFeaturedCollections') is True: + user.profile.capability('canEditFeaturedCollections'): return True return False def edit(self, data, user): + if 'groups' in data: + groups = data.pop('groups') + update_groups(self, groups) for key in data: if key == 'query' and not data['query']: setattr(self, key, {"static": True}) @@ -212,7 +218,20 @@ class Collection(models.Model): def json(self, keys=None, user=None): if not keys: - keys = ['id', 'name', 'user', 'type', 'query', 'status', 'subscribed', 'posterFrames', 'description', 'view'] + keys = [ + 'description', + 'editable', + 'groups', + 'id', + 'name', + 'posterFrames', + 'query', + 'status', + 'subscribed', + 'type', + 'user', + 'view', + ] response = {} for key in keys: if key in ('items', 'documents'): @@ -221,6 +240,10 @@ class Collection(models.Model): response[key] = self.get_id() elif key == 'user': response[key] = self.user.username + elif key == 'groups': + response[key] = [g.name for g in self.groups.all()] + elif key == 'editable': + response[key] = self.editable(user) elif key == 'query': if not self.query.get('static', False): response[key] = self.query diff --git a/pandora/edit/migrations/0004_edit_groups.py b/pandora/edit/migrations/0004_edit_groups.py new file mode 100644 index 000000000..18a49ac40 --- /dev/null +++ b/pandora/edit/migrations/0004_edit_groups.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.2 on 2017-12-31 12:33 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('auth', '0008_auto_20171231_1233'), + ('edit', '0003_auto_20170415_1029'), + ] + + operations = [ + migrations.AddField( + model_name='edit', + name='groups', + field=models.ManyToManyField(blank=True, related_name='edits', to='auth.Group'), + ), + ] diff --git a/pandora/edit/models.py b/pandora/edit/models.py index cebc5c49e..f14c0d86a 100644 --- a/pandora/edit/models.py +++ b/pandora/edit/models.py @@ -15,7 +15,7 @@ from oxdjango.fields import DictField, TupleField from django.conf import settings from django.db import models, transaction from django.db.models import Max -from django.contrib.auth.models import User +from django.contrib.auth.models import User, Group from django.utils.encoding import python_2_unicode_compatible from annotation.models import Annotation @@ -24,6 +24,7 @@ from item.utils import get_by_id import clip.models from archive import extract +from user.utils import update_groups from . import managers @@ -41,6 +42,7 @@ class Edit(models.Model): created = models.DateTimeField(auto_now_add=True) modified = models.DateTimeField(auto_now=True) user = models.ForeignKey(User, related_name='edits') + groups = models.ManyToManyField(Group, blank=True, related_name='edits') name = models.CharField(max_length=255) status = models.CharField(max_length=20, default='private') @@ -134,12 +136,16 @@ class Edit(models.Model): if not user or user.is_anonymous(): return False if self.user == user or \ + self.groups.filter(id__in=user.groups.all()).count() > 0 or \ user.is_staff or \ user.profile.capability('canEditFeaturedEdits'): return True return False def edit(self, data, user): + if 'groups' in data: + groups = data.pop('groups') + update_groups(self, groups) for key in data: if key == 'status': value = data[key] @@ -344,6 +350,8 @@ class Edit(models.Model): 'description', 'duration', 'editable', + 'editable', + 'groups', 'id', 'items', 'name', @@ -387,6 +395,8 @@ class Edit(models.Model): response[key] = self.editable(user) elif key == 'user': response[key] = self.user.username + elif key == 'groups': + response[key] = [g.name for g in self.groups.all()] elif key == 'subscribers': response[key] = self.subscribed_users.all().count() elif key == 'subscribed': diff --git a/pandora/item/models.py b/pandora/item/models.py index df9e7930f..4032aed48 100644 --- a/pandora/item/models.py +++ b/pandora/item/models.py @@ -41,6 +41,7 @@ from clip.models import Clip, get_layers from person.models import get_name_sort from sequence.tasks import get_sequences from title.models import get_title_sort +from user.utils import update_groups import archive.models @@ -247,15 +248,7 @@ class Item(models.Model): del data['id'] if 'groups' in data: groups = data.pop('groups') - if isinstance(groups, list): - groups = list(filter(lambda g: g.strip(), groups)) - groups = [ox.escape_html(g) for g in groups] - for g in self.groups.exclude(name__in=groups): - self.groups.remove(g) - current_groups = [g.name for g in self.groups.all()] - for g in list(filter(lambda g: g not in current_groups, groups)): - group, created = Group.objects.get_or_create(name=g) - self.groups.add(group) + update_groups(self, groups) keys = [k['id'] for k in list(filter(lambda i: i.get('description'), settings.CONFIG['itemKeys']))] for k in keys: diff --git a/pandora/itemlist/migrations/0002_list_groups.py b/pandora/itemlist/migrations/0002_list_groups.py new file mode 100644 index 000000000..9cf01a3b6 --- /dev/null +++ b/pandora/itemlist/migrations/0002_list_groups.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.2 on 2017-12-31 12:33 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('auth', '0008_auto_20171231_1233'), + ('itemlist', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='list', + name='groups', + field=models.ManyToManyField(blank=True, related_name='lists', to='auth.Group'), + ), + ] diff --git a/pandora/itemlist/models.py b/pandora/itemlist/models.py index d6f2e4279..4a35cd8c1 100644 --- a/pandora/itemlist/models.py +++ b/pandora/itemlist/models.py @@ -9,7 +9,7 @@ from glob import glob 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, Group from django.conf import settings from django.utils.encoding import python_2_unicode_compatible import ox @@ -17,6 +17,7 @@ import ox from oxdjango.fields import DictField, TupleField from archive import extract +from user.utils import update_groups from . import managers @@ -35,6 +36,7 @@ class List(models.Model): created = models.DateTimeField(auto_now_add=True) modified = models.DateTimeField(auto_now=True) user = models.ForeignKey(User, related_name='lists') + groups = models.ManyToManyField(Group, blank=True, related_name='lists') name = models.CharField(max_length=255) status = models.CharField(max_length=20, default='private') _status = ['private', 'public', 'featured'] @@ -116,20 +118,24 @@ class List(models.Model): if user.is_anonymous(): return False if self.user == user or \ + self.groups.filter(id__in=user.groups.all()).count() > 0 or \ user.is_staff or \ - user.profile.capability('canEditFeaturedLists') == True: + user.profile.capability('canEditFeaturedLists'): return True return False def edit(self, data, user): + if 'groups' in data: + groups = data.pop('groups') + update_groups(self, groups) for key in data: if key == 'query' and not data['query']: - setattr(self, key, {"static":True}) + setattr(self, key, {"static": True}) elif key == 'query' and isinstance(data[key], dict): setattr(self, key, data[key]) elif key == 'type': if data[key] == 'static': - self.query = {"static":True} + self.query = {"static": True} self.type = 'static' else: self.type = 'smart' @@ -198,14 +204,27 @@ class List(models.Model): if 'view' in data: self.view = data['view'] if 'sort' in data: - self.sort= tuple(data['sort']) + self.sort = tuple(data['sort']) self.save() if 'posterFrames' in data: self.update_icon() def json(self, keys=None, user=None): if not keys: - keys=['id', 'name', 'user', 'type', 'query', 'status', 'subscribed', 'posterFrames', 'description', 'view'] + keys = [ + 'description', + 'editable', + 'groups', + 'id', + 'name', + 'posterFrames', + 'query', + 'status', + 'subscribed', + 'type', + 'user', + 'view', + ] response = {} for key in keys: if key == 'items': @@ -214,6 +233,10 @@ class List(models.Model): response[key] = self.get_id() elif key == 'user': response[key] = self.user.username + elif key == 'groups': + response[key] = [g.name for g in self.groups.all()] + elif key == 'editable': + response[key] = self.editable(user) elif key == 'query': if not self.query.get('static', False): response[key] = self.query diff --git a/pandora/user/utils.py b/pandora/user/utils.py index e7b7c38a0..fe312b3cd 100644 --- a/pandora/user/utils.py +++ b/pandora/user/utils.py @@ -1,4 +1,5 @@ from django.contrib.gis.geoip2 import GeoIP2 +from django.contrib.auth.models import Group import ox @@ -69,3 +70,14 @@ def rename_user(user, new): # update user item find item.models.ItemFind.objects.filter(key='user', value=old).update(value=new) user.username = new + +def update_groups(model, groups): + if isinstance(groups, list): + groups = list(filter(lambda g: g.strip(), groups)) + groups = [ox.escape_html(g) for g in groups] + for g in model.groups.exclude(name__in=groups): + model.groups.remove(g) + current_groups = [g.name for g in model.groups.all()] + for g in list(filter(lambda g: g not in current_groups, groups)): + group, created = Group.objects.get_or_create(name=g) + model.groups.add(group)