pandora/pandora/event/models.py
Will Thompson 0c98cd080e Entity.alternativeNames: default to () not [] (fixes #2896)
Otherwise this:

    self.name_find = '||' + '||'.join((self.name,) + self.alternativeNames) + '||'
                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

fails because () + [] is an error. I guess this must have been
introduced by the DictField/TupleField rewrite.

Without this fix, it is impossible to create a new entity.

Basically the same logic is used for Event and Place too so I've made
the same change to those, and, in passing, fix another copy of the bug
fixed for Entity.name_find in fe7f961.
2016-03-04 17:11:36 +00:00

162 lines
5.7 KiB
Python

# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
from __future__ import division, with_statement
from django.db import models, transaction
from django.contrib.auth.models import User
import ox
from oxdjango import fields
from annotation.models import Annotation, get_matches, get_super_matches
from item.models import Item
from item import utils
from person.models import get_name_sort
from title.models import get_title_sort
import managers
class Event(models.Model):
'''
Events are events in time that can be once or recurring,
From Mondays to Spring to 1989 to Roman Empire
'''
#class Meta:
# ordering = ('name_sort', )
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
defined = models.BooleanField(default=False)
user = models.ForeignKey(User, null=True, related_name='events')
name = models.CharField(null=True, max_length=255, unique=True)
name_sort = models.CharField(null=True, max_length=255, db_index=True)
name_find = models.TextField(default='', editable=True)
wikipediaId = models.CharField(max_length=1000, blank=True)
alternativeNames = fields.TupleField(default=())
objects = managers.EventManager()
#start yyyy-mm-dd|mm-dd|dow 00:00|00:00
start = models.CharField(default='', max_length=255)
startTime = models.BigIntegerField(default=None, null=True)
#end yyyy-mm-dd|mm-dd|dow 00:00|00:01
end = models.CharField(default='', max_length=255)
endTime = models.BigIntegerField(default=None, null=True)
duration = models.CharField(default='', max_length=255)
durationTime = models.BigIntegerField(default=None, null=True)
type = models.CharField(default='', max_length=255)
matches = models.IntegerField(default=0)
items = models.ManyToManyField(Item, blank=True, related_name='events')
annotations = models.ManyToManyField(Annotation, blank=True, related_name='events')
def __unicode__(self):
return self.name
@classmethod
def get_or_create(model, name):
qs = model.objects.filter(name_find__icontains=u'|%s|'%name)
if qs.count() == 0:
instance = model(name=name)
instance.save()
else:
instance = qs[0]
return instance
def editable(self, user):
if user and not user.is_anonymous() \
and (not self.user or \
self.user == user or \
user.profile.capability('canEditEvents')):
return True
return False
def get_matches(self, qs=None):
return get_matches(self, Event, 'event', qs)
def get_super_matches(self):
return get_super_matches(self, Event)
@transaction.atomic
def update_matches(self, annotations=None):
matches = self.get_matches(annotations)
if not annotations:
numberofmatches = matches.count()
annotations = self.annotations.all()
else:
numberofmatches = -1
for a in annotations.exclude(id__in=matches):
self.annotations.remove(a)
#annotations of type event always need an event
if a.get_layer().get('type') == 'event' and a.events.count() == 0:
a.events.add(Event.get_or_create(a.value))
for e in a.events.exclude(id=self.id):
e.update_matches()
for a in matches.exclude(id__in=self.annotations.all()):
#need to check again since editEvent might have been called again
if self.annotations.filter(id=a.id).count() == 0:
self.annotations.add(a)
ids = list(set([a['item_id'] for a in self.annotations.all().values('item_id')]))
for i in self.items.exclude(id__in=ids):
self.items.remove(i)
for i in Item.objects.filter(id__in=ids).exclude(id__in=self.items.all()):
if self.items.filter(id=i.id).count() == 0:
self.items.add(i)
if numberofmatches < 0:
numberofmatches = self.annotations.all().count()
if self.matches != numberofmatches:
self.matches = numberofmatches
if numberofmatches:
Event.objects.filter(id=self.id).update(matches=numberofmatches)
else:
self.save()
def set_name_sort(self, value=None):
if not value:
value = self.name
if self.type == 'person':
value = get_name_sort(value)
else:
value = get_title_sort(value)
self.name_sort = utils.sort_string(value)
def save(self, *args, **kwargs):
if not self.name_sort:
self.set_name_sort()
self.name_find = '||' + '||'.join((self.name,) + self.alternativeNames) + '||'
self.defined = len(filter(None, [getattr(self, key)
for key in ('start', 'end')])) > 0
if self.endTime and self.startTime:
self.durationTime = self.endTime - self.startTime
super(Event, self).save(*args, **kwargs)
def make_undefined(self):
self.defined = False
self.start = self.end = ''
self.durationTime = self.endTime = self.startTime = None
def get_id(self):
return ox.toAZ(self.id)
def json(self, user=None):
j = {
'id': self.get_id(),
'editable': self.editable(user)
}
if self.user:
j['user'] = self.user.username
for key in ('created', 'modified',
'name', 'alternativeNames',
'start', 'end', 'duration',
'type', 'matches'):
j[key] = getattr(self, key)
j['nameSort'] = self.name_sort
return j