diff options
| author | Étienne Loks <etienne.loks@peacefrogs.net> | 2012-10-09 00:50:54 +0200 | 
|---|---|---|
| committer | Étienne Loks <etienne.loks@peacefrogs.net> | 2012-10-09 00:50:54 +0200 | 
| commit | 14b6a6c93003b422cb08c5313f64a228e743d2ac (patch) | |
| tree | cf8ef814f1cc3c305b6eb3e527518c4230bbd293 /chimere/models.py | |
| parent | 80e20f22b4e79e79a5bb7d65f602f6642522ca3e (diff) | |
| download | Chimère-14b6a6c93003b422cb08c5313f64a228e743d2ac.tar.bz2 Chimère-14b6a6c93003b422cb08c5313f64a228e743d2ac.zip  | |
Admin: fix and improve moderation groups management
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)  | 
