diff options
Diffstat (limited to 'chimere/main')
-rw-r--r-- | chimere/main/admin.py | 42 | ||||
-rw-r--r-- | chimere/main/forms.py | 17 | ||||
-rw-r--r-- | chimere/main/models.py | 38 | ||||
-rw-r--r-- | chimere/main/widgets.py | 9 |
4 files changed, 92 insertions, 14 deletions
diff --git a/chimere/main/admin.py b/chimere/main/admin.py index 195e7c4..31c9d5c 100644 --- a/chimere/main/admin.py +++ b/chimere/main/admin.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (C) 2008 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> +# Copyright (C) 2008-2010 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as @@ -29,6 +29,19 @@ from chimere.main.widgets import TextareaWidget from django.contrib import admin +def get_areas_for_user(user): + """ + Getting subcats for a specific user + """ + perms = user.get_all_permissions() + areas = set() + prefix = 'main.change_area_' + for perm in perms: + if perm.startswith(prefix): + area = Area.objects.get(urn=perm[len(prefix):]) + areas.add(area) + return areas + class MarkerAdmin(admin.ModelAdmin): """ Specialized the Point field. @@ -38,6 +51,19 @@ class MarkerAdmin(admin.ModelAdmin): list_filter = ('status', 'subcategory') form = MarkerAdminForm + def queryset(self, request): + qs = self.model._default_manager.get_query_set() + if not request.user.is_superuser: + areas = get_areas_for_user(request.user) + if not areas: + return self.model.objects.extra(where=['1=0']) + in_areas = " or ".join([area.getIncludeSql() for area in areas]) + qs = qs.extra(where=[in_areas]) + ordering = self.ordering or () + if ordering: + qs = qs.order_by(*ordering) + return qs + class RouteAdmin(admin.ModelAdmin): """ Specialized the Route field. @@ -47,6 +73,20 @@ class RouteAdmin(admin.ModelAdmin): list_filter = ('status', 'subcategory') form = RouteAdminForm + def queryset(self, request): + qs = self.model._default_manager.get_query_set() + if not request.user.is_superuser: + areas = get_areas_for_user(request.user) + if not areas: + return self.model.objects.extra(where=['1=0']) + in_areas = " or ".join([area.getIncludeSql( + geometry='"main_route".route') for area in areas]) + qs = qs.extra(where=[in_areas]) + ordering = self.ordering or () + if ordering: + qs = qs.order_by(*ordering) + return qs + class AreaAdmin(admin.ModelAdmin): """ Specialized the area field. diff --git a/chimere/main/forms.py b/chimere/main/forms.py index 74577d1..4618321 100644 --- a/chimere/main/forms.py +++ b/chimere/main/forms.py @@ -23,7 +23,7 @@ Forms from django import forms from django.contrib.gis.db import models from django.utils.translation import ugettext as _ -from django.contrib.auth.models import User +from django.contrib.auth.models import User, Permission, ContentType from django.core.mail import EmailMessage, BadHeaderError from chimere import settings @@ -250,4 +250,19 @@ class AreaAdminForm(forms.ModelForm): new_area.upper_left_corner = 'POINT(%s %s)' % (area[0][0], area[0][1]) new_area.lower_right_corner = 'POINT(%s %s)' % (area[1][0], area[1][1]) + content_type = ContentType.objects.get(app_label="main", + model="area") + if new_area.urn: + mnemo = 'change_area_' + new_area.urn + perm = Permission.objects.filter(codename=mnemo) + if not perm: + perm = Permission(name='Can change ' + new_area.name, + content_type_id=content_type.id, codename=mnemo) + perm.save() + else: + if 'urn' in self.initial: + mnemo = 'change_area_' + self.initial['urn'] + perm = Permission.objects.filter(codename=mnemo) + if perm: + perm[0].delete() return new_area diff --git a/chimere/main/models.py b/chimere/main/models.py index 710623c..4197a23 100644 --- a/chimere/main/models.py +++ b/chimere/main/models.py @@ -23,6 +23,7 @@ Models description from django.utils.translation import ugettext_lazy as _ from django.contrib.gis.db import models +from django.contrib.gis.gdal import SpatialReference from django.contrib import admin from chimere import settings @@ -292,14 +293,14 @@ class SimpleArea: return True return False - def getCategories(self, status='A'): + def getCategories(self, status='A', filter_available=True): """ Get categories for this area """ equal_status = '' if len(status) == 1: equal_status = "='%s'" % status[0] - else: + elif status: equal_status = " in ('%s')" % "','".join(status) 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, @@ -314,9 +315,12 @@ subcat.name as name, subcat.available as available, subcat.icon_id as icon_id, subcat.color_theme_id as color_theme_id, subcat.order as order, subcat.item_type as item_type from main_subcategory subcat''' sql = sql_main + ''' -inner join main_marker mark on mark.subcategory_id=subcat.id and mark.status%s -and ST_Contains(%s, mark.point) where subcat.available = TRUE''' % ( - equal_status, area) +inner join main_marker mark on mark.subcategory_id=subcat.id + and ST_Contains(%s, mark.point)''' % area + if equal_status: + sql += ' and mark.status' + equal_status + if filter_available: + sql += ' where subcat.available = TRUE' # django > 1.1 #subcats = SubCategory.objects.raw(sql) from django.db import connection, transaction @@ -326,9 +330,12 @@ and ST_Contains(%s, mark.point) where subcat.available = TRUE''' % ( for r in cursor.fetchall(): subcats.add(SubCategory.objects.get(id=r[0])) sql = sql_main + ''' -inner join main_route rt on rt.subcategory_id=subcat.id and rt.status%s -and (ST_Intersects(%s, rt.route) or ST_Contains(%s, rt.route)) -where subcat.available = TRUE''' % (equal_status, area, area) +inner join main_route rt on rt.subcategory_id=subcat.id +and (ST_Intersects(%s, rt.route) or ST_Contains(%s, rt.route))''' % (area, area) + if equal_status: + sql += ' and rt.status' + equal_status + if filter_available: + sql += ' where subcat.available = TRUE' # django > 1.1 #subcats += SubCategory.objects.raw(sql) cursor.execute(sql, []) @@ -366,6 +373,21 @@ class Area(models.Model, SimpleArea): ''' return cls.objects.filter(available=True) + def getIncludeSql(self, geometry='"main_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, + 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.EPSG_DISPLAY_PROJECTION + ) + sql = "ST_Contains(" + area + ", " + geometry + ")" + return sql + class PropertyModel(models.Model): '''Model for a property ''' diff --git a/chimere/main/widgets.py b/chimere/main/widgets.py index 2653c19..4ad6475 100644 --- a/chimere/main/widgets.py +++ b/chimere/main/widgets.py @@ -265,8 +265,9 @@ class AreaWidget(forms.TextInput): init();""" if value: tpl += """var extent = new OpenLayers.Bounds(%f, %f, %f, %f); -map.zoomToExtent(extent, true);""" % (upper_left_lat, upper_left_lon, lower_right_lat, - lower_right_lon) +extent.transform(epsg_display_projection, epsg_projection); +map.zoomToExtent(extent, true);""" % (upper_left_lon, upper_left_lat, + lower_right_lon, lower_right_lat) tpl += """// --></script> <hr class='spacer'/> """ @@ -277,8 +278,8 @@ map.zoomToExtent(extent, true);""" % (upper_left_lat, upper_left_lon, lower_righ Return the appropriate values """ values = [] - for keys in (('upper_left_lat', 'upper_left_lon',), - ('lower_right_lat', 'lower_right_lon')): + for keys in (('upper_left_lon', 'upper_left_lat',), + ('lower_right_lon', 'lower_right_lat')): value = [] for key in keys: val = data.get(key, None) |