diff options
Diffstat (limited to 'chimere/models.py')
-rw-r--r-- | chimere/models.py | 111 |
1 files changed, 96 insertions, 15 deletions
diff --git a/chimere/models.py b/chimere/models.py index 593d712..88c1f0c 100644 --- a/chimere/models.py +++ b/chimere/models.py @@ -25,16 +25,16 @@ import simplejson as json from lxml import etree from PIL import Image from subprocess import Popen, PIPE - from django import forms from django.conf import settings from django.contrib import admin -from django.contrib.auth.models import Permission, ContentType +from django.contrib.auth.models import User, Permission, ContentType, Group from django.contrib.gis.db import models from django.contrib.gis.gdal import SpatialReference from django.core.files import File from django.core.exceptions import ValidationError, ObjectDoesNotExist from django.core.urlresolvers import reverse +from django.db.models import Q from django.db.models.signals import post_save, pre_save, m2m_changed from django.template import defaultfilters from django.utils.translation import ugettext_lazy as _ @@ -513,6 +513,12 @@ class Marker(GeographicItem): url = reverse('chimere:tiny', args=[area_name, urn]) return url + +PRE_ATTRS = { + 'Marker':('name', 'geometry', 'import_version'), + 'Route':('name', 'geometry', 'import_version'), + 'Area':('urn', 'name'), + } def geometry_pre_save(cls, pre_save_geom_values): def geom_pre_save(sender, **kwargs): if not kwargs['instance'] or not kwargs['instance'].pk: @@ -520,8 +526,8 @@ def geometry_pre_save(cls, pre_save_geom_values): instance = kwargs['instance'] try: instance = cls.objects.get(pk=instance.pk) - pre_save_geom_values[instance.pk] = (instance.name, - instance.geometry, instance.import_version) + pre_save_geom_values[instance.pk] = [getattr(instance, attr) + for attr in PRE_ATTRS[cls.__name__]] except ObjectDoesNotExist: pass return geom_pre_save @@ -836,7 +842,7 @@ class Route(GeographicItem): null=True, height_field='height', width_field='width') height = models.IntegerField(_(u"Height"), blank=True, null=True) width = models.IntegerField(_(u"Width"), blank=True, null=True) - objects = BaseGeoManager() + objects = models.GeoManager() def __unicode__(self): return self.name @@ -1139,20 +1145,34 @@ class Area(models.Model, SimpleArea): ''' return cls.objects.filter(available=True) - def getIncludeSql(self, geometry='"chimere_marker".point'): - """ - Get the sql statement for the test if the point is included in the area - """ - area = "ST_GeometryFromText('POLYGON((%f %f,%f %f,%f %f,%f %f, %f %f"\ - "))', %d)" % (self.upper_left_corner.x, self.upper_left_corner.y, + def getWkt(self): + return "SRID=%d;POLYGON((%f %f,%f %f,%f %f,%f %f, %f %f))" % ( + settings.CHIMERE_EPSG_DISPLAY_PROJECTION, + self.upper_left_corner.x, self.upper_left_corner.y, self.lower_right_corner.x, self.upper_left_corner.y, self.lower_right_corner.x, self.lower_right_corner.y, self.upper_left_corner.x, self.lower_right_corner.y, self.upper_left_corner.x, self.upper_left_corner.y, - settings.CHIMERE_EPSG_DISPLAY_PROJECTION ) - sql = "ST_Contains(" + area + ", " + geometry + ")" - return sql + + def getIncludeMarker(self): + """ + Get the sql statement for the test if the point is included in the area + """ + return Q(point__contained=self.getWkt()) + + def getIncludeRoute(self): + """ + Get the sql statement for the test if the route is included in the area + """ + return Q(route__contained=self.getWkt()) + +pre_save_area_values = {} +def area_pre_save(sender, **kwargs): + if not kwargs['instance']: + return + geometry_pre_save(Area, pre_save_area_values)(sender, **kwargs) +pre_save.connect(area_pre_save, sender=Area) def area_post_save(sender, **kwargs): if not kwargs['instance']: @@ -1163,21 +1183,82 @@ def area_post_save(sender, **kwargs): for default in defaults: default.default = False default.save() + # manage permissions + old_urn, old_name = area.urn, area.name + if area.pk in pre_save_area_values: + old_urn, old_name = pre_save_area_values[area.pk] + perm, old_groups, old_users = None, [], [] + if area.urn != old_urn: + oldmnemo = 'change_area_' + old_urn + old_perm = Permission.objects.filter(codename=oldmnemo) + if old_perm.count(): + perm = old_perm.all()[0] + perm.codename = 'change_area_' + area.urn + perm.save() if not area.urn: area.urn = defaultfilters.slugify(area.name) area.save() mnemo = 'change_area_' + area.urn perm = Permission.objects.filter(codename=mnemo) + lbl = "Can change " + area.name if not perm.count(): - lbl = "Can change " + area.name content_type = ContentType.objects.get(app_label="chimere", model="area") perm = Permission(name=lbl, content_type_id=content_type.id, codename=mnemo) perm.save() + else: + perm = perm.all()[0] + if old_name != area.name: + perm.name = lbl + perm.save() + # manage moderation group + groupname = area.name + " moderation" + if old_name != area.name: + old_groupname = old_name + " moderation" + old_gp = Group.objects.filter(name=old_groupname) + if old_gp.count(): + old_gp = old_gp.all()[0] + old_gp.name = groupname + old_gp.save() + group = Group.objects.filter(name=groupname) + if not group.count(): + group = Group.objects.create(name=groupname) + group.permissions.add(perm) + for app_label, model in (('chimere', 'marker'), + ('chimere', 'route'), + ('chimere', 'multimediafile'), + ('chimere', 'picturefile'), + ('chimere', 'routefile')): + ct = ContentType.objects.get(app_label=app_label, model=model) + for p in Permission.objects.filter(content_type=ct).all(): + group.permissions.add(p) post_save.connect(area_post_save, sender=Area) +def get_areas_for_user(user): + """ + Getting subcats for a specific user + """ + perms = user.get_all_permissions() + areas = set() + prefix = 'chimere.change_area_' + for perm in perms: + if perm.startswith(prefix): + try: + area = Area.objects.get(urn=perm[len(prefix):]) + areas.add(area) + except ObjectDoesNotExist: + pass + return areas + +def get_users_by_area(area): + if not area: + return [] + perm = 'change_area_'+area.urn + return User.objects.filter(Q(groups__permissions__codename=perm)| + Q(user_permissions__codename=perm)).all() + class AreaLayers(models.Model): area = models.ForeignKey(Area) layer = models.ForeignKey(Layer) |