# -*- coding: utf-8 -*- from urllib.parse import quote from django.db import models from django.db.models import Max from django.db.models.signals import pre_delete from oxdjango.fields import JSONField import ox from itemlist.models import List from edit.models import Edit from documentcollection.models import Collection 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 = JSONField(default=dict, 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', 'link', '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], str): return False self.data[key] = data[key] if key == 'contentid' and self.data[key]: content = self.get_content() if not content: return False changed = True if 'type' in data: if data['type'] == 'custom': if 'contentid' in self.data: del self.data['contentid'] changed = True else: for key in list(self.data): if key not in ('contentid', 'type'): del self.data[key] changed = True if 'active' in data: self.active = data['active'] is True idx = Item.objects.filter(active=self.active).aggregate(Max('index'))['index__max'] if idx is None: self.index = 0 else: self.index = idx + 1 changed = 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 get_content(self): content_keys = [ 'description', 'modified', 'name', 'user', ] type = self.data.get('type') contentid = self.data.get('contentid') if not contentid: return None data = None content = None try: if type == 'list': content = List.get(contentid) data = content.json(keys=content_keys) data['link'] = '/list==' + quote(data['user'] + ':' + data['name']) elif type == 'edit': content = Edit.get(contentid) data = content.json(keys=content_keys) data['link'] = '/edits/' + quote(data['user'] + ':' + data['name']) elif type == 'collection': content = Collection.get(contentid) data = content.json(keys=content_keys) data['link'] = '/documents/collection==' + quote(data['user'] + ':' + data['name']) except: return None if content and content.status == 'private': self.delete() data = None return data def is_public(self): type = self.data.get('type') return type == 'custom' or self.get_content() is not None def json(self, keys=None): j = { 'id': self.get_id(), 'active': self.active, 'index': self.index, } j.update(self.data) if 'contentid' in j: try: content = self.get_content() if content: j['title'] = content['name'] j['text'] = content['description'] j['link'] = content['link'] j['image'] = '/' + '/'.join([ j['type'], quote(content['user'] + ':' + content['name']), 'icon256.jpg?%s' % content['modified'].strftime('%Y-%m-%dT%H:%M:%SZ') ]) except: pass if keys: for key in list(j): if key not in keys: del j[key] return j def __str__(self): return "%s" % (self.get_id()) def delete_item(type, contentid): for home in Item.objects.all(): if type == home.data.get('type') and contentid == home.data.get('contentid'): home.delete() def delete_list(sender, **kwargs): delete_item('list', kwargs['instance'].get_id()) pre_delete.connect(delete_list, sender=List) def delete_edit(sender, **kwargs): delete_item('edit', kwargs['instance'].get_id()) pre_delete.connect(delete_edit, sender=Edit) def delete_collection(sender, **kwargs): delete_item('collection', kwargs['instance'].get_id()) pre_delete.connect(delete_collection, sender=Collection)