create undefined places/events

This commit is contained in:
j 2012-02-01 15:25:18 +00:00
parent daaabba071
commit 1f1683c5a5
7 changed files with 120 additions and 43 deletions

View file

@ -7,6 +7,8 @@ from django.db import models
from django.db.models import Q
from django.contrib.auth.models import User
from django.conf import settings
from django.db.models.signals import pre_delete
import ox
from archive import extract
@ -152,17 +154,23 @@ class Annotation(models.Model):
#update clip.findvalue
self.clip.save()
if filter(lambda l: l['type'] == 'place' or l.get('hasPlaces'),
settings.CONFIG['layers']):
#update_matching_places.delay(self.id)
#editAnnotations needs to be in snyc
if layer.get('type') == 'place' or layer.get('hasPlace'):
update_matching_places(self.id)
if filter(lambda l: l['type'] == 'event' or l.get('hasEvents'),
settings.CONFIG['layers']):
#update_matching_events.delay(self.id)
#editAnnotations needs to be in snyc
if layer.get('type') == 'event' or layer.get('hasEvents'):
update_matching_events(self.id)
def cleanup_undefined_relations(self):
layer = self.get_layer()
if layer.get('type') == 'place':
for p in self.places.filter(defined=False):
if p.annotations.exclude(id=self.id).count() == 0:
p.delete()
elif layer.get('type') == 'event':
for e in self.events.filter(defined=False):
if e.annotations.exclude(id=self.id).count() == 0:
e.delete()
def json(self, layer=False, keys=None, user=None):
j = {
'user': self.user.username,
@ -181,11 +189,11 @@ class Annotation(models.Model):
l = self.get_layer()
if l['type'] == 'place':
qs = self.places.all()
qs = self.places.filter(defined=True)
if qs.count() > 0:
j['place'] = qs[0].json(user=user)
elif l['type'] == 'event':
qs = self.events.all()
qs = self.events.filter(defined=True)
if qs.count() > 0:
j['event'] = qs[0].json(user=user)
@ -211,3 +219,6 @@ class Annotation(models.Model):
def __unicode__(self):
return u"%s %s-%s" %(self.public_id, self.start, self.end)
def cleanup_related(sender, **kwargs):
kwargs['instance'].cleanup_undefined_relations()
pre_delete.connect(cleanup_related, sender=Annotation)

View file

@ -9,6 +9,12 @@ import models
def update_matching_events(id):
from event.models import Event
annotation = models.Annotation.objects.get(pk=id)
for e in annotation.events.filter(defined=False):
if e.annotations.exclude(id=id).count() == 0:
e.delete()
if annotation.get_layer().get('type') == 'event' \
and annotation.events.count() == 0:
annotations.events.add(Event.get_or_create(annotation.value))
for e in annotation.events.all():
e.update_matches()
ids = [e['id'] for e in Event.objects.all().values('id')]
@ -23,6 +29,12 @@ def update_matching_events(id):
def update_matching_places(id):
from place.models import Place
annotation = models.Annotation.objects.get(pk=id)
for p in annotation.places.filter(defined=False):
if p.annotations.exclude(id=id).count() == 0:
p.delete()
if annotation.get_layer().get('type') == 'place' \
and annotation.places.count() == 0:
annotation.places.add(Place.get_or_create(annotation.value))
for p in annotation.places.all():
p.update_matches()
ids = [e['id'] for e in Place.objects.all().values('id')]

View file

@ -32,6 +32,7 @@ class Event(models.Model):
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')
@ -46,14 +47,14 @@ class Event(models.Model):
#start yyyy-mm-dd|mm-dd|dow 00:00|00:00
start = models.CharField(default='', max_length=255)
startTime = models.BigIntegerField(default=0)
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=0)
endTime = models.BigIntegerField(default=None, null=True)
duration = models.CharField(default='', max_length=255)
durationTime = models.BigIntegerField(default=0)
durationTime = models.BigIntegerField(default=None, null=True)
type = models.CharField(default='', max_length=255)
@ -64,9 +65,21 @@ class Event(models.Model):
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 (self.user == user or user.get_profile().capability('canEditEvents')):
and (not self.user or \
self.user == user or \
user.get_profile().capability('canEditEvents')):
return True
return False
@ -109,9 +122,19 @@ class Event(models.Model):
if not self.name_sort:
self.set_name_sort()
self.name_find = '||' + self.name + '||'.join(self.alternativeNames) + '||'
self.defined = len(filter(None, [getattr(self, key)
for key in ('start', 'end', 'startTime', 'endTime')])) > 0
if self.defined:
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)

View file

@ -30,11 +30,14 @@ def addEvent(request):
data = json.loads(request.POST['data'])
existing_names = []
exists = False
for name in [data['name']] + data.get('alternativeNames', []):
if models.Event.objects.filter(name_find__icontains=u'|%s|'%name).count() != 0:
names = [data['name']] + data.get('alternativeNames', [])
for name in names:
if models.Event.objects.filter(defined=True,
name_find__icontains=u'|%s|'%name).count() != 0:
exists = True
existing_names.append(name)
if not exists:
models.Event.objects.filter(defined=False, name__in=names).delete()
event = models.Event(name = data['name'])
for key in ('start', 'startTime', 'end', 'endTime', 'duration', 'durationTime',
'type', 'alternativeNames'):
@ -74,10 +77,12 @@ def editEvent(request):
conflict_names = []
names = [data.get('name', event.name)] + data.get('alternativeNames', [])
for name in names:
if models.Event.objects.filter(name_find__icontains=u'|%s|'%name).exclude(id=event.id).count() != 0:
if models.Event.objects.filter(defined=True,
name_find__icontains=u'|%s|'%name).exclude(id=event.id).count() != 0:
conflict = True
conflict_names.append(name)
if not conflict:
models.Event.objects.filter(defined=False, name__in=names).delete()
if 'name' in data:
event.set_name_sort(data['name'])
for key in ('name', 'start', 'startTime', 'end', 'endTime', 'duration', 'durationTime',

View file

@ -23,6 +23,8 @@ class Place(models.Model):
'''
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
defined = models.BooleanField(default=True)
user = models.ForeignKey(User, null=True, related_name='places')
name = models.CharField(max_length=1024)
@ -30,20 +32,20 @@ class Place(models.Model):
name_sort = models.CharField(max_length=200)
name_find = models.TextField(default='', editable=False)
geoname = models.CharField(max_length=1024, unique=True)
geoname_sort = models.CharField(max_length=1024, unique=True)
geoname = models.CharField(max_length=1024, unique=True, null=True)
geoname_sort = models.CharField(max_length=1024, unique=True, null=True)
countryCode = models.CharField(max_length=16, default='')
wikipediaId = models.CharField(max_length=1000, blank=True)
type = models.CharField(max_length=1000, default='')
south = models.FloatField(default=0)
west = models.FloatField(default=0)
north = models.FloatField(default=0)
east = models.FloatField(default=0)
lat = models.FloatField(default=0)
lng = models.FloatField(default=0)
area = models.FloatField(default=0)
south = models.FloatField(default=None, null=True)
west = models.FloatField(default=None, null=True)
north = models.FloatField(default=None, null=True)
east = models.FloatField(default=None, null=True)
lat = models.FloatField(default=None, null=True)
lng = models.FloatField(default=None, null=True)
area = models.FloatField(default=None, null=True)
matches = models.IntegerField(default=0)
items = models.ManyToManyField(Item, blank=True, related_name='places')
@ -57,9 +59,21 @@ class Place(models.Model):
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 (self.user == user or user.get_profile().capability('canEditPlaces')):
and (not self.user or \
self.user == user or \
user.get_profile().capability('canEditPlaces')):
return True
return False
@ -69,9 +83,10 @@ class Place(models.Model):
def json(self, keys=None, user=None):
j = {
'id': self.get_id(),
'user': self.user.username,
'editable': self.editable(user)
}
if self.user:
j['user'] = self.user.username
for key in ('created', 'modified',
'name', 'alternativeNames', 'geoname', 'countryCode',
'south', 'west', 'north', 'east',
@ -106,18 +121,25 @@ class Place(models.Model):
self.matches = numberofmatches
self.save()
def make_undefined(self):
self.defined = False
self.south = None
self.west = None
self.north = None
self.east = None
self.lat = None
self.lng = None
self.area = None
def save(self, *args, **kwargs):
if not self.name_sort:
self.name_sort = self.name #', '.join(self.name)
if self.geoname:
self.geoname_sort = ', '.join(reversed(self.geoname.split(', ')))
self.name_find = '|%s|'%'|'.join([self.name]+list(self.alternativeNames))
#update center
#self.lat = ox.location.center(self.south, self.north)
#self.lng = ox.location.center(self.east, self.west)
#update area
#self.area= ox.location.area(self.south, self.west, self.north, self.east)
self.defined = len(filter(None, [getattr(self, key)
for key in ('south', 'west', 'north', 'east')])) > 0
super(Place, self).save(*args, **kwargs)

View file

@ -19,7 +19,6 @@ import tasks
@login_required_json
def addPlace(request):
#FIXME: require admin
'''
param data {
name: "",
@ -36,20 +35,24 @@ def addPlace(request):
type: ""
}
'''
#FIXME: check permissions
data = json.loads(request.POST['data'])
exists = False
existing_names = []
existing_geoname = ''
names = data.pop('name')
for name in [names] + data.get('alternativeNames', []):
if models.Place.objects.filter(name_find__icontains=u'|%s|'%name).count() != 0:
if models.Place.objects.filter(defined=True,
name_find__icontains=u'|%s|'%name).count() != 0:
exists = True
existing_names.append(name)
if 'geoname' in data:
if models.Place.objects.filter(geoname=data['geoname']).count() > 0:
if models.Place.objects.filter(defined=True,
geoname=data['geoname']).count() > 0:
exists = True
existing_geoname = data['geoname']
if not exists:
models.Place.objects.filter(defined=False, name__in=names).delete()
place = models.Place()
place.user = request.user
place.name = names
@ -96,14 +99,17 @@ def editPlace(request):
alternative_names = filter(lambda n: n.strip(), alternative_names)
data['alternativeNames'] = alternative_names
for name in names + alternative_names:
if models.Place.objects.filter(name_find__icontains=u'|%s|'%name).exclude(id=place.id).count() != 0:
if models.Place.objects.filter(defined=True,
name_find__icontains=u'|%s|'%name).exclude(id=place.id).count() != 0:
conflict = True
conflict_names.append(name)
if 'geoname' in data:
if models.Place.objects.filter(geoname=data['geoname']).exclude(id=place.id).count() != 0:
if models.Place.objects.filter(defined=True,
geoname=data['geoname']).exclude(id=place.id).count() != 0:
conflict = True
conflict_geoname = data['geoname']
if not conflict:
models.Place.objects.filter(defined=False, name__in=names+alternative_names).delete()
for key in data:
if key != 'id':
value = data[key]

View file

@ -121,8 +121,6 @@ pandora.URL = (function() {
if (state.find) {
if (!state.item) {
set.find = state.find;
} else if (pandora.isItemFind(state.find)) {
set.itemFind = state.find;
}
}