summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
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
commit14b6a6c93003b422cb08c5313f64a228e743d2ac (patch)
treecf8ef814f1cc3c305b6eb3e527518c4230bbd293
parent80e20f22b4e79e79a5bb7d65f602f6642522ca3e (diff)
downloadChimère-14b6a6c93003b422cb08c5313f64a228e743d2ac.tar.bz2
Chimère-14b6a6c93003b422cb08c5313f64a228e743d2ac.zip
Admin: fix and improve moderation groups management
-rw-r--r--chimere/admin.py42
-rw-r--r--chimere/fixtures/initial_data.json44
-rw-r--r--chimere/forms.py3
-rw-r--r--chimere/models.py111
-rw-r--r--chimere/templates/chimere/detail.html17
-rw-r--r--chimere/views.py3
6 files changed, 168 insertions, 52 deletions
diff --git a/chimere/admin.py b/chimere/admin.py
index 42835a2..7663bd5 100644
--- a/chimere/admin.py
+++ b/chimere/admin.py
@@ -25,6 +25,7 @@ import datetime
from django import forms
from django.conf import settings
from django.contrib import admin
+from django.db.models import Q
from django.http import HttpResponse
from django.shortcuts import render_to_response
from django.utils.translation import ugettext_lazy as _
@@ -38,25 +39,13 @@ from chimere.forms import MarkerAdminForm, RouteAdminForm, AreaAdminForm,\
NewsAdminForm, CategoryAdminForm, ImporterAdminForm, \
PictureFileAdminForm, MultimediaFileAdminForm
from chimere.models import Category, Icon, SubCategory, Marker, \
- PropertyModel, News, Route, Area, ColorTheme, Color, MultimediaType, \
- MultimediaFile, PictureFile, Importer, Layer, AreaLayers
+ PropertyModel, News, Route, Area, ColorTheme, Color, \
+ MultimediaFile, PictureFile, Importer, Layer, AreaLayers,\
+ get_areas_for_user, get_users_by_area
from chimere.utils import unicode_normalize, ShapefileManager, KMLManager,\
CSVManager
from chimere.widgets import TextareaWidget
-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):
- area = Area.objects.get(urn=perm[len(prefix):])
- areas.add(area)
- return areas
-
def validate(modeladmin, request, queryset):
for item in queryset:
item.status = 'A'
@@ -131,13 +120,14 @@ class MarkerAdmin(admin.ModelAdmin):
qs = self.model._default_manager.get_query_set()
if not request.user.is_superuser:
areas = get_areas_for_user(request.user)
- if areas:
- in_areas = " or ".join([area.getIncludeSql() for area in areas])
- qs = qs.extra(where=[in_areas])
+ contained = Q()
+ for area in areas:
+ contained = contained | area.getIncludeMarker()
+ qs = qs.filter(contained)
ordering = self.ordering or ()
if ordering:
qs = qs.order_by(*ordering)
- return qs
+ return qs.distinct()
class RouteAdmin(admin.ModelAdmin):
"""
@@ -155,10 +145,10 @@ class RouteAdmin(admin.ModelAdmin):
qs = self.model._default_manager.get_query_set()
if not request.user.is_superuser:
areas = get_areas_for_user(request.user)
- if areas:
- in_areas = " or ".join([area.getIncludeSql(
- geometry='"chimere_route".route') for area in areas])
- qs = qs.extra(where=[in_areas])
+ contained = Q()
+ for area in areas:
+ contained = contained | area.getIncludeRoute()
+ qs = qs.filter(contained)
ordering = self.ordering or ()
if ordering:
qs = qs.order_by(*ordering)
@@ -240,11 +230,6 @@ class ColorThemeAdmin(admin.ModelAdmin):
class IconAdmin(admin.ModelAdmin):
exclude = ['height', 'width']
-class MultimediaTypeAdmin(admin.ModelAdmin):
- search_fields = ("name",)
- list_display = ('name', 'media_type', 'mime_type', 'iframe', 'available')
- list_filter = ('media_type', 'available')
-
# register of differents database fields
admin.site.register(News, NewsAdmin)
admin.site.register(Category, CategoryAdmin)
@@ -254,5 +239,4 @@ admin.site.register(Route, RouteAdmin)
admin.site.register(PropertyModel)
admin.site.register(Area, AreaAdmin)
admin.site.register(ColorTheme, ColorThemeAdmin)
-admin.site.register(MultimediaType, MultimediaTypeAdmin)
admin.site.register(Layer)
diff --git a/chimere/fixtures/initial_data.json b/chimere/fixtures/initial_data.json
index 473640c..21ba13c 100644
--- a/chimere/fixtures/initial_data.json
+++ b/chimere/fixtures/initial_data.json
@@ -195,5 +195,49 @@
"layer_code": "new OpenLayers.Layer.MapQuestOSM()",
"name": "OSM - MapQuest"
}
+ },
+ {
+ "pk": 1,
+ "model": "auth.group",
+ "fields": {
+ "name": "Application administrator",
+ "permissions": [
+ 67,
+ 68,
+ 40,
+ 41,
+ 42,
+ 37,
+ 38,
+ 39,
+ 34,
+ 35,
+ 36,
+ 43,
+ 44,
+ 45,
+ 49,
+ 50,
+ 51,
+ 55,
+ 56,
+ 57,
+ 28,
+ 29,
+ 30,
+ 58,
+ 59,
+ 60,
+ 64,
+ 65,
+ 66,
+ 61,
+ 62,
+ 63,
+ 46,
+ 47,
+ 48
+ ]
+ }
}
]
diff --git a/chimere/forms.py b/chimere/forms.py
index ea08474..bb31ffe 100644
--- a/chimere/forms.py
+++ b/chimere/forms.py
@@ -433,7 +433,8 @@ class AreaAdminForm(forms.ModelForm):
Admin page to create an area
"""
area = AreaField(label=_("Area"), fields=(PointField(), PointField()))
- welcome_message = forms.CharField(widget=TextareaAdminWidget)
+ welcome_message = forms.CharField(widget=TextareaAdminWidget,
+ required=False)
class Meta:
model = Area
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)
diff --git a/chimere/templates/chimere/detail.html b/chimere/templates/chimere/detail.html
index 7cf678e..c195fbe 100644
--- a/chimere/templates/chimere/detail.html
+++ b/chimere/templates/chimere/detail.html
@@ -27,7 +27,17 @@
{% if marker.multimedia_items %}
<a href='#' id='show_gallery_link'>{% trans "Show multimedia gallery" %}</a>
{% endif %}
- </div>{% if share_networks %}
+ </div>
+ {% comment %}
+ <a href='{% if marker.route %}{% url chimere:editroute-item area_name_slash|default_if_none:"" marker.route.pk "" %}{%else%}{% url chimere:edit-item area_name_slash|default_if_none:"" marker.pk "" %}{%endif%}'>
+ {% trans "Submit a modification" %}
+ </a>
+ {% endcomment %}
+ {% if moderator_emails %}
+ <a href="mailto:?from={{moderator_emails}}&subject={% trans "Propose amendment" %}&body={% trans "I would like to propose an amendment for this item:"%} {{share_url}}">
+ {% trans "Propose amendment" %}
+ </a>{%endif%}
+ {% if share_networks %}
{% if simple %}{% trans "Share on"%}{% for share_network in share_networks %}
<a href='{{share_network.1}}'>{{share_network.0}}</a>
{% endfor %}{%else%}
@@ -35,11 +45,6 @@
<li>{% trans "Share"%}</li>{% for share_network in share_networks %}
<li><a href='{{share_network.1}}'><img src="{{share_network.2}}" alt="{{share_network.0}}"/></a></li>
{% endfor %}</ul>{% endif %}
- {% comment %}
- <a href='{% if marker.route %}{% url chimere:editroute-item area_name_slash|default_if_none:"" marker.route.pk "" %}{%else%}{% url chimere:edit-item area_name_slash|default_if_none:"" marker.pk "" %}{%endif%}'>
- {% trans "Submit a modification" %}
- </a>
- {% endcomment %}
{% endif %}
</div>
{% if marker.multimedia_items %}
diff --git a/chimere/views.py b/chimere/views.py
index f96a66b..567840e 100644
--- a/chimere/views.py
+++ b/chimere/views.py
@@ -42,7 +42,8 @@ from django.utils.translation import ugettext as _
from chimere.actions import actions
from chimere.models import Category, SubCategory, PropertyModel, \
- Marker, Route, News, SimpleArea, Area, Color, TinyUrl, RouteFile
+ Marker, Route, News, SimpleArea, Area, Color, TinyUrl, RouteFile, \
+ get_users_by_area
from chimere.widgets import getMapJS, PointChooserWidget, \
RouteChooserWidget, AreaWidget