From b8ba0c6cb2ed1a8a05f72cf60110cccb9cab16ce Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Wed, 14 Nov 2012 17:29:42 +0100 Subject: Fix Vimeo video add (refs #439) --- chimere/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chimere/models.py b/chimere/models.py index 830f5a9..dffac29 100644 --- a/chimere/models.py +++ b/chimere/models.py @@ -609,8 +609,8 @@ IFRAME_LINKS = { re.compile(r'dailymotion.com/embed/video/([A-Za-z0-9]*)'), re.compile("http://www.dailymotion.com/embed/video/%s")), 'http://www.dailymotion.com/embed/video/%s'), - 'vimeo':((re.compile(r'vimeo.com/([A-Za-z0-9]*)'), - re.compile(r'vimeo.com/video/([A-Za-z0-9]*)')), + 'vimeo':((re.compile(r'vimeo.com/video/([A-Za-z0-9]*)'), + re.compile(r'vimeo.com/([A-Za-z0-9]*)'),), "http://player.vimeo.com/video/%s") } -- cgit v1.2.3 From 53626da019d22a6b7eeadbedad983ba187b2f54c Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Wed, 14 Nov 2012 19:40:16 +0100 Subject: Forms: don't allow empty area and smae order number (refs #414) --- chimere/forms.py | 11 +++++++++++ chimere/models.py | 2 +- chimere/tests.py | 29 ++++++++++++++++++++++++++++- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/chimere/forms.py b/chimere/forms.py index fea99b1..5761e2b 100644 --- a/chimere/forms.py +++ b/chimere/forms.py @@ -454,6 +454,17 @@ class AreaAdminForm(forms.ModelForm): keys['initial'] = dct super(AreaAdminForm, self).__init__(*args, **keys) + def clean(self): + ''' + Verify that the area is not empty + ''' + if not self.cleaned_data.get('upper_left_lat') \ + and not self.cleaned_data.get('upper_left_lon') \ + and not self.cleaned_data.get('lower_right_lat') \ + and not self.cleaned_data.get('lower_right_lon'): + msg = _(u"No area selected.") + raise forms.ValidationError(msg) + def save(self, *args, **keys): """ Custom save method in order to manage area diff --git a/chimere/models.py b/chimere/models.py index dffac29..2f59cf1 100644 --- a/chimere/models.py +++ b/chimere/models.py @@ -1107,7 +1107,7 @@ class Area(models.Model, SimpleArea): unique=True) welcome_message = models.TextField(_(u"Welcome message"), blank=True, null=True) - order = models.IntegerField(_(u"Order")) + order = models.IntegerField(_(u"Order"), unique=True) available = models.BooleanField(_(u"Available")) upper_left_corner = models.PointField(_(u"Upper left corner"), default='POINT(0 0)', srid=settings.CHIMERE_EPSG_DISPLAY_PROJECTION) diff --git a/chimere/tests.py b/chimere/tests.py index c372202..905978a 100644 --- a/chimere/tests.py +++ b/chimere/tests.py @@ -14,7 +14,7 @@ from django.test import TestCase from chimere.models import Area, Icon, Importer, Category, SubCategory, Marker,\ Route, News -from chimere.forms import MarkerForm +from chimere.forms import MarkerForm, AreaAdminForm from chimere.templatetags.chimere_tags import display_news from chimere.utils import ShapefileManager @@ -204,6 +204,33 @@ class MarkerFormTest(TestCase): form = MarkerForm(data) self.assertEqual(form.is_valid(), False) +class AreaAdminFormTest(TestCase): + def setUp(self): + self.areas = areas_setup() + + def test_area_creation(self): + base_data = {'name':u'New test', 'order':3, 'available':True, + 'urn':'area-new', + 'upper_left_lat':48.5, + 'upper_left_lon':-5, + 'lower_right_lat':48, + 'lower_right_lon':-4, + 'upper_left_corner':'SRID=4326;POINT(0 0)', + 'lower_right_corner':'SRID=4326;POINT(0 0)'} + # order already given + data = base_data.copy() + data['order'] = 1 + form = AreaAdminForm(data) + self.assertEqual(form.is_valid(), False) + # empty area + data = base_data.copy() + data.update({'upper_left_lat': 0, + 'upper_left_lon': 0, + 'lower_right_lat': 0, + 'lower_right_lon': 0}) + form = AreaAdminForm(data) + self.assertEqual(form.is_valid(), False) + class DynamicCategoryTest(TestCase): def setUp(self): self.areas = areas_setup() -- cgit v1.2.3 From ffa21eca6672e0b662b3ad30d4951135dc416e16 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Wed, 14 Nov 2012 19:49:43 +0100 Subject: Forms: check that only one default area is possible (refs #414) --- chimere/tests.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/chimere/tests.py b/chimere/tests.py index 905978a..ccbbfb5 100644 --- a/chimere/tests.py +++ b/chimere/tests.py @@ -27,7 +27,7 @@ def areas_setup(): available=True, upper_left_corner='SRID=4326;POINT(-3 47.5)', lower_right_corner='SRID=4326;POINT(-2.5 47)') - return [area_1] + return [area_1, area_2] def subcategory_setup(): category = Category.objects.create(name='Main category', @@ -208,6 +208,15 @@ class AreaAdminFormTest(TestCase): def setUp(self): self.areas = areas_setup() + def test_area_default(self): + area_1, area_2 = self.areas[0], self.areas[1] + area_1.default = True + area_1.save() + area_2.default = True + area_2.save() + area_1 = Area.objects.get(urn=area_1.urn) + self.assertEqual(area_1.default, False) + def test_area_creation(self): base_data = {'name':u'New test', 'order':3, 'available':True, 'urn':'area-new', -- cgit v1.2.3 From f098ec09ef8b6a71372390705f10eae10399152a Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Wed, 14 Nov 2012 20:14:45 +0100 Subject: Forms: prevent bad initialization of areas (refs #411, refs #414) --- chimere/forms.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/chimere/forms.py b/chimere/forms.py index 5761e2b..1d37b56 100644 --- a/chimere/forms.py +++ b/chimere/forms.py @@ -444,6 +444,17 @@ class AreaAdminForm(forms.ModelForm): """ Custom initialization method in order to manage area """ + if args: + vals = args[0] + for k in ('upper_left_lat', 'upper_left_lon', + 'lower_right_lat', 'lower_right_lon'): + v = vals.get(k) + try: + v = float(v) + except ValueError: + v = None + if not v: + args[0][k] = None if 'instance' in keys and keys['instance']: instance = keys['instance'] dct = {'area':(instance.upper_left_corner, -- cgit v1.2.3 From 27d48170fbf6989c9c933ece82c378afc4ed3094 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Thu, 15 Nov 2012 02:50:30 +0100 Subject: Add a template tags for a small OpenLayers map --- chimere/templates/chimere/blocks/ol_map.html | 19 +++++++++++++++++++ chimere/templatetags/chimere_tags.py | 7 +++++++ 2 files changed, 26 insertions(+) create mode 100644 chimere/templates/chimere/blocks/ol_map.html diff --git a/chimere/templates/chimere/blocks/ol_map.html b/chimere/templates/chimere/blocks/ol_map.html new file mode 100644 index 0000000..98743fa --- /dev/null +++ b/chimere/templates/chimere/blocks/ol_map.html @@ -0,0 +1,19 @@ +{% load unlocalize_point %} +
+ diff --git a/chimere/templatetags/chimere_tags.py b/chimere/templatetags/chimere_tags.py index 1258a3d..25e6122 100644 --- a/chimere/templatetags/chimere_tags.py +++ b/chimere/templatetags/chimere_tags.py @@ -10,6 +10,7 @@ from django.conf import settings from django.core.exceptions import ObjectDoesNotExist from django.core.urlresolvers import reverse from django.db.models import Q, Count +from django.template.loader import render_to_string from chimere.models import Marker, Area, News, SubCategory from chimere.widgets import get_map_layers @@ -208,3 +209,9 @@ def get_tinyfied_url(marker, area_name=''): return "" url = marker.get_absolute_url(area_name) return url + +@register.filter(name='ol_map') +def ol_map(geom, arg='map_id'): + rendered = render_to_string('chimere/blocks/ol_map.html', {'geom': geom, + 'map_id':arg}) + return rendered -- cgit v1.2.3 From 76704764573c45b42279087c90c69662c6951165 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Fri, 16 Nov 2012 00:40:31 +0100 Subject: Manage marker amendment in admin (refs #381) --- chimere/admin.py | 46 ++++++++++++++++++++++++++++++++--- chimere/forms.py | 6 ++--- chimere/templates/chimere/detail.html | 4 +-- chimere/tests.py | 34 ++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 10 deletions(-) diff --git a/chimere/admin.py b/chimere/admin.py index 7663bd5..4f7a49d 100644 --- a/chimere/admin.py +++ b/chimere/admin.py @@ -24,12 +24,13 @@ import datetime from django import forms from django.conf import settings -from django.contrib import admin +from django.contrib import admin, messages +from django.core.exceptions import ObjectDoesNotExist from django.db.models import Q -from django.http import HttpResponse +from django.http import HttpResponse, HttpResponseRedirect from django.shortcuts import render_to_response +from django.template import RequestContext from django.utils.translation import ugettext_lazy as _ - try: from chimere import tasks except ImportError: @@ -87,6 +88,42 @@ def export_to_csv(modeladmin, request, queryset): return response export_to_csv.short_description = _(u"Export to CSV") +def managed_modified(modeladmin, request, queryset): + if queryset.count() != 1: + messages.error(request, _(u"Only one item can be managed at a " + u"time.")) + return HttpResponseRedirect(request.get_full_path()) + + marker = queryset.all()[0] + if not marker.status == 'M': + try: + marker = Marker.objects.get(ref_item=marker, status='M') + except ObjectDoesNotExist: + messages.error(request, _(u"No modified item associated " + u"to the selected marker.")) + return HttpResponseRedirect(request.get_full_path()) + marker_ref = marker.ref_item + if request.POST.get('rapprochement'): + for k in request.POST: + if not request.POST[k]: + continue + if hasattr(marker_ref, k): + setattr(marker_ref, k, getattr(marker, k)) + marker_ref.save() + elif k.startswith('property_'): + try: + pm = PropertyModel.get(pk=int(k[len('property_'):])) + marker_ref.setProperty(pm, marker.getProperty(pm)) + except (ValueError, ObjectDoesNotExist): + pass + marker.delete() + messages.success(request, _(u"Modified item traited.")) + return HttpResponseRedirect(request.get_full_path()) + return render_to_response('admin/managed_modified_marker.html', + {'marker':marker, 'marker_ref':marker_ref}, + context_instance=RequestContext(request)) + + class PictureInline(admin.TabularInline): model = PictureFile extra = 1 @@ -108,7 +145,8 @@ class MarkerAdmin(admin.ModelAdmin): search_fields = ("name",) list_display = ('name', 'status') list_filter = ('status', 'categories') - actions = [validate, export_to_kml, export_to_shapefile, export_to_csv] + actions = [validate, export_to_kml, export_to_shapefile, export_to_csv, + managed_modified] exclude = ['submiter_session_key', 'import_key', 'import_version', 'available_date'] readonly_fields = ['submiter_email', 'submiter_comment', 'import_source', diff --git a/chimere/forms.py b/chimere/forms.py index 1d37b56..4e834d0 100644 --- a/chimere/forms.py +++ b/chimere/forms.py @@ -203,7 +203,7 @@ class MarkerAdminFormBase(forms.ModelForm): Custom save method in order to manage associated properties """ new_marker = super(MarkerAdminFormBase, self).save(*args, **keys) - if 'status' not in self.cleaned_data: + if 'status' not in self.cleaned_data and not new_marker.status: new_marker.status = 'S' if new_marker.status == 'A': tz = UTC() @@ -276,8 +276,8 @@ class RouteAdminForm(forms.ModelForm): Custom save method in order to manage associated properties """ new_route = super(RouteAdminForm, self).save(*args, **keys) - if 'status' not in self.cleaned_data: - new_route.status = 'S' + if 'status' not in self.cleaned_data and not new_route.status: + new_marker.status = 'S' new_route.save() return new_route diff --git a/chimere/templates/chimere/detail.html b/chimere/templates/chimere/detail.html index 3c43f42..33ddfd1 100644 --- a/chimere/templates/chimere/detail.html +++ b/chimere/templates/chimere/detail.html @@ -28,11 +28,9 @@ {% trans "Show multimedia gallery" %} {% endif %} - {% comment %} - {% trans "Submit a modification" %} + {% trans "Submit an amendment" %} - {% endcomment %} {% if moderator_emails %} {% trans "Propose amendment" %} diff --git a/chimere/tests.py b/chimere/tests.py index ccbbfb5..63eb28f 100644 --- a/chimere/tests.py +++ b/chimere/tests.py @@ -8,10 +8,15 @@ test_path = os.path.abspath(__file__) test_dir_path = os.path.dirname(test_path) + os.sep from django.conf import settings +from django.contrib.auth.models import User +from django.contrib.gis.geos import GEOSGeometry +from django.contrib.messages.storage.fallback import FallbackStorage from django.core.urlresolvers import reverse from django.template import Context from django.test import TestCase +from django.test.client import Client +from chimere.admin import managed_modified, MarkerAdmin from chimere.models import Area, Icon, Importer, Category, SubCategory, Marker,\ Route, News from chimere.forms import MarkerForm, AreaAdminForm @@ -264,3 +269,32 @@ class NewsTest(TestCase): self.assertEqual(len(context['news_lst']), 2) context = display_news(Context({'area_name':'area-2'})) self.assertEqual(len(context['news_lst']), 1) + +class RapprochementTest(TestCase): + def setUp(self): + self.areas = areas_setup() + self.markers = marker_setup() + self.adminuser = User.objects.create_superuser('admin', + 'admin@test.com', + 'pass') + self.client.login(username='admin', password='pass') + + def test_managed_modified(self): + ref_marker = self.markers[0] + new_vals = {'name':"Marker 1 - modified", + 'point':GEOSGeometry('SRID=4326;POINT(-4 48)')} + values = {'status':'M', 'ref_item':ref_marker} + values.update(new_vals) + modified_marker = Marker.objects.create(**values) + modified_marker.categories.add(ref_marker.categories.all()[0]) + response = self.client.post('/admin/chimere/marker/', + data={'action':['managed_modified'], + 'index':0, 'rapprochement':1, + 'name':1, 'point':1, + '_selected_action':[unicode(ref_marker.pk)] + }) + ref_marker = Marker.objects.get(pk=ref_marker.pk) + self.assertEqual(Marker.objects.filter(ref_item=ref_marker, + status='M').count(), 0) + for k in new_vals: + self.assertEqual(getattr(ref_marker, k), new_vals[k]) -- cgit v1.2.3 From 89fd5864f6f61e1d41d2146c46bbf1625f698060 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Fri, 16 Nov 2012 00:58:28 +0100 Subject: Fix starter point when a route is modified --- chimere/models.py | 1 + 1 file changed, 1 insertion(+) diff --git a/chimere/models.py b/chimere/models.py index 2f59cf1..b15a268 100644 --- a/chimere/models.py +++ b/chimere/models.py @@ -954,6 +954,7 @@ def route_post_save(sender, **kwargs): defaults=marker_dct) if not created: marker.status = instance.status + marker.point = marker_dct['point'] marker.save() properties = {} for pm in instance.properties(): -- cgit v1.2.3 From 14798fd25b0e8445d66e9d83f562caee044e1907 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Fri, 16 Nov 2012 02:36:12 +0100 Subject: Manage route amendment in admin (refs #381) --- chimere/admin.py | 56 +++++++++++++++------------ chimere/forms.py | 2 +- chimere/models.py | 8 ++++ chimere/templates/admin/managed_modified.html | 47 ++++++++++++++++++++++ chimere/templates/chimere/blocks/ol_map.html | 26 +++++++++---- chimere/templatetags/chimere_tags.py | 7 +++- 6 files changed, 113 insertions(+), 33 deletions(-) create mode 100644 chimere/templates/admin/managed_modified.html diff --git a/chimere/admin.py b/chimere/admin.py index 4f7a49d..399e6e1 100644 --- a/chimere/admin.py +++ b/chimere/admin.py @@ -94,35 +94,42 @@ def managed_modified(modeladmin, request, queryset): u"time.")) return HttpResponseRedirect(request.get_full_path()) - marker = queryset.all()[0] - if not marker.status == 'M': + item = queryset.all()[0] + if not item.status == 'M': try: - marker = Marker.objects.get(ref_item=marker, status='M') + item = modeladmin.model.objects.get(ref_item=item, status='M') except ObjectDoesNotExist: messages.error(request, _(u"No modified item associated " - u"to the selected marker.")) + u"to the selected item.")) return HttpResponseRedirect(request.get_full_path()) - marker_ref = marker.ref_item + item_ref = item.ref_item if request.POST.get('rapprochement'): - for k in request.POST: - if not request.POST[k]: - continue - if hasattr(marker_ref, k): - setattr(marker_ref, k, getattr(marker, k)) - marker_ref.save() - elif k.startswith('property_'): - try: - pm = PropertyModel.get(pk=int(k[len('property_'):])) - marker_ref.setProperty(pm, marker.getProperty(pm)) - except (ValueError, ObjectDoesNotExist): - pass - marker.delete() + couple = [(item, item_ref)] + if hasattr(item, 'associated_marker'): + couple.append((item.associated_marker, item_ref.associated_marker)) + for it, it_ref in couple: + for k in request.POST: + if not request.POST[k]: + continue + if hasattr(it_ref, k): + setattr(it_ref, k, getattr(it, k)) + it_ref.save() + elif k.startswith('property_'): + try: + pm = PropertyModel.get(pk=int(k[len('property_'):])) + it_ref.setProperty(pm, it.getProperty(pm)) + except (ValueError, ObjectDoesNotExist): + pass + if hasattr(item, 'associated_marker'): + for it in item.associated_marker.all(): + it.delete() + item.delete() messages.success(request, _(u"Modified item traited.")) return HttpResponseRedirect(request.get_full_path()) - return render_to_response('admin/managed_modified_marker.html', - {'marker':marker, 'marker_ref':marker_ref}, + return render_to_response('admin/managed_modified.html', + {'item':item, 'item_ref':item_ref}, context_instance=RequestContext(request)) - +managed_modified.short_description = _(u"Managed modified items") class PictureInline(admin.TabularInline): model = PictureFile @@ -145,8 +152,8 @@ class MarkerAdmin(admin.ModelAdmin): search_fields = ("name",) list_display = ('name', 'status') list_filter = ('status', 'categories') - actions = [validate, export_to_kml, export_to_shapefile, export_to_csv, - managed_modified] + actions = [validate, managed_modified, export_to_kml, export_to_shapefile, + export_to_csv] exclude = ['submiter_session_key', 'import_key', 'import_version', 'available_date'] readonly_fields = ['submiter_email', 'submiter_comment', 'import_source', @@ -177,7 +184,8 @@ class RouteAdmin(admin.ModelAdmin): exclude = ['height', 'width'] form = RouteAdminForm readonly_fields = ('associated_file',) - actions = [validate, export_to_kml, export_to_shapefile, export_to_csv] + actions = [validate, managed_modified, export_to_kml, export_to_shapefile, + export_to_csv] def queryset(self, request): qs = self.model._default_manager.get_query_set() diff --git a/chimere/forms.py b/chimere/forms.py index 4e834d0..4b4d49f 100644 --- a/chimere/forms.py +++ b/chimere/forms.py @@ -277,7 +277,7 @@ class RouteAdminForm(forms.ModelForm): """ new_route = super(RouteAdminForm, self).save(*args, **keys) if 'status' not in self.cleaned_data and not new_route.status: - new_marker.status = 'S' + new_route.status = 'S' new_route.save() return new_route diff --git a/chimere/models.py b/chimere/models.py index b15a268..12ec7a1 100644 --- a/chimere/models.py +++ b/chimere/models.py @@ -414,6 +414,10 @@ class Marker(GeographicItem): def geometry(self): return self.point.wkt + @property + def geom_attr(self): + return 'point' + class Meta: ordering = ('status', 'name') verbose_name = _(u"Point of interest") @@ -879,6 +883,10 @@ class Route(GeographicItem): def geometry(self): return self.route.wkt + @property + def geom_attr(self): + return 'route' + def get_init_multi(self): if not self.associated_marker.count(): return [] diff --git a/chimere/templates/admin/managed_modified.html b/chimere/templates/admin/managed_modified.html new file mode 100644 index 0000000..c55650d --- /dev/null +++ b/chimere/templates/admin/managed_modified.html @@ -0,0 +1,47 @@ +{% extends "admin/base_site.html" %} +{% load chimere_tags i18n admin_static %} + +{% block extrahead %} + + +{% endblock %} + + +{% block content %} +

{% trans "Be careful: after validation, the modified item will be deleted. There is no roll-back." %}

+
+
+{% csrf_token %} + + + + + + + + + + + + + + + + + +{% for property_ref in item_ref.getProperties %} +{% for property in item.getProperties %} +{% ifequal property_ref.propertymodel property.propertymodel %} + +{% endifequal %} +{% endfor %} +{% endfor %} + +
 {% trans "Reference" %}{% trans "Modified item" %}{% trans "Accept modification" %}
{% trans "Name" %}{{item_ref}}{{item}}
{% trans "Categories" %}{% for cat in item_ref.categories.all %}{%if forloop.counter0 %}, {%endif%}{{cat}}{%endfor%}{% for cat in item.categories.all %}{%if forloop.counter0 %}, {%endif%}{{cat}}{%endfor%}
{% trans "Emplacement" %}{{item_ref|ol_map:'map_ref_id'}}{{item|ol_map:'map_id'}}
{% trans "Description" %}{{item_ref.description|safe}}{{item.description|safe}}
{{property.propertymodel.name}}{{property_ref.value|safe}}{{property.value|safe}}
+
+
+ +{% endblock %} diff --git a/chimere/templates/chimere/blocks/ol_map.html b/chimere/templates/chimere/blocks/ol_map.html index 98743fa..a12651c 100644 --- a/chimere/templates/chimere/blocks/ol_map.html +++ b/chimere/templates/chimere/blocks/ol_map.html @@ -1,19 +1,31 @@ {% load unlocalize_point %} -
+
diff --git a/chimere/templatetags/chimere_tags.py b/chimere/templatetags/chimere_tags.py index 25e6122..7753bc0 100644 --- a/chimere/templatetags/chimere_tags.py +++ b/chimere/templatetags/chimere_tags.py @@ -211,7 +211,12 @@ def get_tinyfied_url(marker, area_name=''): return url @register.filter(name='ol_map') -def ol_map(geom, arg='map_id'): +def ol_map(item, arg='map_id'): + geom, geom_type = None, None + if hasattr(item, 'point'): + geom, geom_type = item.point, 'point' + elif hasattr(item, 'route'): + geom, geom_type = item.route, 'route' rendered = render_to_string('chimere/blocks/ol_map.html', {'geom': geom, 'map_id':arg}) return rendered -- cgit v1.2.3 From 9821fba04d499c5536e1d7877128f01ba7092e9e Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Fri, 16 Nov 2012 16:14:11 +0100 Subject: Admin: Fix check problems in imports - improve area and property model list (refs #413) --- chimere/admin.py | 5 ++++- chimere/forms.py | 14 +++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/chimere/admin.py b/chimere/admin.py index 399e6e1..8700c30 100644 --- a/chimere/admin.py +++ b/chimere/admin.py @@ -211,6 +211,7 @@ class AreaAdmin(admin.ModelAdmin): form = AreaAdminForm exclude = ['upper_left_corner', 'lower_right_corner'] inlines = [LayerInline] + list_display = ['name', 'order', 'default'] def importing(modeladmin, request, queryset): for importer in queryset: @@ -248,6 +249,8 @@ class ImporterAdmin(admin.ModelAdmin): actions = [importing, cancel_import, export_to_osm, cancel_export] admin.site.register(Importer, ImporterAdmin) +class PropertyModelAdmin(admin.ModelAdmin): + list_display = ('name', 'order', 'available') class NewsAdmin(admin.ModelAdmin): """ @@ -282,7 +285,7 @@ admin.site.register(Category, CategoryAdmin) admin.site.register(Icon, IconAdmin) admin.site.register(Marker, MarkerAdmin) admin.site.register(Route, RouteAdmin) -admin.site.register(PropertyModel) +admin.site.register(PropertyModel, PropertyModelAdmin) admin.site.register(Area, AreaAdmin) admin.site.register(ColorTheme, ColorThemeAdmin) admin.site.register(Layer) diff --git a/chimere/forms.py b/chimere/forms.py index 4b4d49f..6ab44d3 100644 --- a/chimere/forms.py +++ b/chimere/forms.py @@ -110,17 +110,17 @@ class ImporterAdminForm(forms.ModelForm): Verify that only one type of source is provided Verify that shapefiles are zipped ''' - if self.cleaned_data['importer_type'] == 'SHP' and \ - not self.cleaned_data['zipped']: + if self.cleaned_data.get('importer_type') == 'SHP' and \ + not self.cleaned_data.get('zipped'): raise forms.ValidationError(_(u"Shapefiles must be provided in a "\ u"zipped archive.")) - if self.cleaned_data['source'] and \ - self.cleaned_data['source_file']: + if self.cleaned_data.get('source') and \ + self.cleaned_data.get('source_file'): raise forms.ValidationError(_(u"You have to set \"source\" or " u"\"source file\" but not both.")) - if not self.cleaned_data['source'] and \ - not self.cleaned_data['source_file'] and \ - self.cleaned_data['importer_type'] != 'OSM': + if not self.cleaned_data.get('source') and \ + not self.cleaned_data.get('source_file') and \ + self.cleaned_data.get('importer_type') != 'OSM': raise forms.ValidationError(_(u"You have to set \"source\" or " u"\"source file\".")) return self.cleaned_data -- cgit v1.2.3 From ab5a93714115d6559eee54a5eb5a7327fe66be48 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Fri, 16 Nov 2012 16:25:29 +0100 Subject: Redirect to the main page when area is not available (refs #412) --- chimere/tests.py | 11 +++++++++++ chimere/views.py | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/chimere/tests.py b/chimere/tests.py index 63eb28f..e189fb9 100644 --- a/chimere/tests.py +++ b/chimere/tests.py @@ -209,6 +209,17 @@ class MarkerFormTest(TestCase): form = MarkerForm(data) self.assertEqual(form.is_valid(), False) +class AreaTest(TestCase): + def setUp(self): + self.areas = areas_setup() + + def test_area_availability(self): + area_1 = self.areas[0] + area_1.available = False + area_1.save() + response = self.client.get('/%s/' % area_1.urn) + self.assertRedirects(response, '/') + class AreaAdminFormTest(TestCase): def setUp(self): self.areas = areas_setup() diff --git a/chimere/views.py b/chimere/views.py index e78b092..817aa74 100644 --- a/chimere/views.py +++ b/chimere/views.py @@ -83,7 +83,7 @@ def get_base_response(area_name=""): area = None if area_name: try: - area = Area.objects.get(urn=area_name) + area = Area.objects.get(urn=area_name, available=True) except ObjectDoesNotExist: return None, redirect(reverse('chimere:index')) else: -- cgit v1.2.3 From e4e3aec612c769becdf38ea2ff7e4e9b0e6dffc5 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Fri, 16 Nov 2012 16:38:02 +0100 Subject: Admin: fix area modifications (refs #411) --- chimere/admin.py | 2 +- chimere/forms.py | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/chimere/admin.py b/chimere/admin.py index 8700c30..482c276 100644 --- a/chimere/admin.py +++ b/chimere/admin.py @@ -211,7 +211,7 @@ class AreaAdmin(admin.ModelAdmin): form = AreaAdminForm exclude = ['upper_left_corner', 'lower_right_corner'] inlines = [LayerInline] - list_display = ['name', 'order', 'default'] + list_display = ['name', 'order', 'available', 'default'] def importing(modeladmin, request, queryset): for importer in queryset: diff --git a/chimere/forms.py b/chimere/forms.py index 6ab44d3..4c26d52 100644 --- a/chimere/forms.py +++ b/chimere/forms.py @@ -472,9 +472,11 @@ class AreaAdminForm(forms.ModelForm): if not self.cleaned_data.get('upper_left_lat') \ and not self.cleaned_data.get('upper_left_lon') \ and not self.cleaned_data.get('lower_right_lat') \ - and not self.cleaned_data.get('lower_right_lon'): + and not self.cleaned_data.get('lower_right_lon') \ + and not self.cleaned_data.get('area'): msg = _(u"No area selected.") raise forms.ValidationError(msg) + return self.cleaned_data def save(self, *args, **keys): """ -- cgit v1.2.3 From 4399a14e200a28b88b6431f0c89b10f34bc7230c Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Mon, 19 Nov 2012 00:51:31 +0100 Subject: Import: manage way imports without marker associated --- ...r__add_field_importer_associate_marker_to_wa.py | 251 +++++++++++++++++++++ chimere/models.py | 53 +++-- chimere/tests.py | 38 +++- chimere/utils.py | 3 + 4 files changed, 318 insertions(+), 27 deletions(-) create mode 100644 chimere/migrations/0037_auto__add_unique_area_order__add_field_importer_associate_marker_to_wa.py diff --git a/chimere/migrations/0037_auto__add_unique_area_order__add_field_importer_associate_marker_to_wa.py b/chimere/migrations/0037_auto__add_unique_area_order__add_field_importer_associate_marker_to_wa.py new file mode 100644 index 0000000..4b40fb9 --- /dev/null +++ b/chimere/migrations/0037_auto__add_unique_area_order__add_field_importer_associate_marker_to_wa.py @@ -0,0 +1,251 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding unique constraint on 'Area', fields ['order'] + db.create_unique('chimere_area', ['order']) + + # Adding field 'Importer.associate_marker_to_way' + db.add_column('chimere_importer', 'associate_marker_to_way', + self.gf('django.db.models.fields.BooleanField')(default=True), + keep_default=False) + + # Adding field 'Route.has_associated_marker' + db.add_column('chimere_route', 'has_associated_marker', + self.gf('django.db.models.fields.BooleanField')(default=True), + keep_default=False) + + + def backwards(self, orm): + # Removing unique constraint on 'Area', fields ['order'] + db.delete_unique('chimere_area', ['order']) + + # Deleting field 'Importer.associate_marker_to_way' + db.delete_column('chimere_importer', 'associate_marker_to_way') + + # Deleting field 'Route.has_associated_marker' + db.delete_column('chimere_route', 'has_associated_marker') + + + models = { + 'chimere.area': { + 'Meta': {'ordering': "('order', 'name')", 'object_name': 'Area'}, + 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'default': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'default_subcategories': ('chimere.widgets.SelectMultipleField', [], {'to': "orm['chimere.SubCategory']", 'symmetrical': 'False', 'blank': 'True'}), + 'dynamic_categories': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'external_css': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'layers': ('chimere.widgets.SelectMultipleField', [], {'symmetrical': 'False', 'related_name': "'areas'", 'blank': 'True', 'through': "orm['chimere.AreaLayers']", 'to': "orm['chimere.Layer']"}), + 'lower_right_corner': ('django.contrib.gis.db.models.fields.PointField', [], {'default': "'POINT(0 0)'"}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'order': ('django.db.models.fields.IntegerField', [], {'unique': 'True'}), + 'restrict_to_extent': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'subcategories': ('chimere.widgets.SelectMultipleField', [], {'symmetrical': 'False', 'related_name': "'areas'", 'blank': 'True', 'db_table': "'chimere_subcategory_areas'", 'to': "orm['chimere.SubCategory']"}), + 'upper_left_corner': ('django.contrib.gis.db.models.fields.PointField', [], {'default': "'POINT(0 0)'"}), + 'urn': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'blank': 'True'}), + 'welcome_message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + 'chimere.arealayers': { + 'Meta': {'ordering': "('order',)", 'object_name': 'AreaLayers'}, + 'area': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Area']"}), + 'default': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'layer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Layer']"}), + 'order': ('django.db.models.fields.IntegerField', [], {}) + }, + 'chimere.category': { + 'Meta': {'ordering': "['order']", 'object_name': 'Category'}, + 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'order': ('django.db.models.fields.IntegerField', [], {}) + }, + 'chimere.color': { + 'Meta': {'ordering': "['order']", 'object_name': 'Color'}, + 'code': ('django.db.models.fields.CharField', [], {'max_length': '6'}), + 'color_theme': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.ColorTheme']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'order': ('django.db.models.fields.IntegerField', [], {}) + }, + 'chimere.colortheme': { + 'Meta': {'object_name': 'ColorTheme'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}) + }, + 'chimere.icon': { + 'Meta': {'object_name': 'Icon'}, + 'height': ('django.db.models.fields.IntegerField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'width': ('django.db.models.fields.IntegerField', [], {}) + }, + 'chimere.importer': { + 'Meta': {'object_name': 'Importer'}, + 'associate_marker_to_way': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'categories': ('chimere.widgets.SelectMultipleField', [], {'to': "orm['chimere.SubCategory']", 'symmetrical': 'False'}), + 'default_name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'filtr': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'importer_type': ('django.db.models.fields.CharField', [], {'max_length': '4'}), + 'license': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'origin': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'source': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'source_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'srid': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'state': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'zipped': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) + }, + 'chimere.layer': { + 'Meta': {'object_name': 'Layer'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'layer_code': ('django.db.models.fields.TextField', [], {'max_length': '300'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}) + }, + 'chimere.marker': { + 'Meta': {'ordering': "('status', 'name')", 'object_name': 'Marker'}, + 'available_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'categories': ('chimere.widgets.SelectMultipleField', [], {'to': "orm['chimere.SubCategory']", 'symmetrical': 'False'}), + 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'import_key': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'import_source': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'import_version': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'license': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'modified_since_import': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'not_for_osm': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'origin': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'point': ('chimere.widgets.PointField', [], {}), + 'ref_item': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'submited_marker'", 'null': 'True', 'to': "orm['chimere.Marker']"}), + 'route': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'associated_marker'", 'null': 'True', 'to': "orm['chimere.Route']"}), + 'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'status': ('django.db.models.fields.CharField', [], {'max_length': '1'}), + 'submiter_comment': ('django.db.models.fields.TextField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'submiter_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), + 'submiter_name': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}), + 'submiter_session_key': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}) + }, + 'chimere.multimediafile': { + 'Meta': {'object_name': 'MultimediaFile'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'marker': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'multimedia_files'", 'to': "orm['chimere.Marker']"}), + 'miniature': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'multimedia_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.MultimediaType']"}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'order': ('django.db.models.fields.IntegerField', [], {'default': '1'}), + 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'}) + }, + 'chimere.multimediatype': { + 'Meta': {'object_name': 'MultimediaType'}, + 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'iframe': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'media_type': ('django.db.models.fields.CharField', [], {'max_length': '1'}), + 'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}) + }, + 'chimere.news': { + 'Meta': {'object_name': 'News'}, + 'areas': ('chimere.widgets.SelectMultipleField', [], {'symmetrical': 'False', 'to': "orm['chimere.Area']", 'null': 'True', 'blank': 'True'}), + 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'content': ('django.db.models.fields.TextField', [], {}), + 'date': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '150'}) + }, + 'chimere.picturefile': { + 'Meta': {'object_name': 'PictureFile'}, + 'height': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'marker': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'pictures'", 'to': "orm['chimere.Marker']"}), + 'miniature': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'order': ('django.db.models.fields.IntegerField', [], {'default': '1'}), + 'picture': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}), + 'thumbnailfile': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'thumbnailfile_height': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'thumbnailfile_width': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'width': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}) + }, + 'chimere.property': { + 'Meta': {'object_name': 'Property'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'marker': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Marker']"}), + 'propertymodel': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.PropertyModel']"}), + 'value': ('django.db.models.fields.TextField', [], {}) + }, + 'chimere.propertymodel': { + 'Meta': {'ordering': "('order',)", 'object_name': 'PropertyModel'}, + 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mandatory': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'order': ('django.db.models.fields.IntegerField', [], {}), + 'subcategories': ('chimere.widgets.SelectMultipleField', [], {'symmetrical': 'False', 'related_name': "'properties'", 'blank': 'True', 'to': "orm['chimere.SubCategory']"}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '1'}) + }, + 'chimere.route': { + 'Meta': {'ordering': "('status', 'name')", 'object_name': 'Route'}, + 'associated_file': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.RouteFile']", 'null': 'True', 'blank': 'True'}), + 'categories': ('chimere.widgets.SelectMultipleField', [], {'to': "orm['chimere.SubCategory']", 'symmetrical': 'False'}), + 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'has_associated_marker': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'height': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'import_key': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'import_source': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'import_version': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'license': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'modified_since_import': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'not_for_osm': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'origin': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'picture': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'ref_item': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'submited_route'", 'null': 'True', 'to': "orm['chimere.Route']"}), + 'route': ('chimere.widgets.RouteField', [], {}), + 'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'status': ('django.db.models.fields.CharField', [], {'max_length': '1'}), + 'submiter_comment': ('django.db.models.fields.TextField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'submiter_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), + 'submiter_name': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}), + 'submiter_session_key': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}), + 'width': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}) + }, + 'chimere.routefile': { + 'Meta': {'ordering': "('name',)", 'object_name': 'RouteFile'}, + 'file_type': ('django.db.models.fields.CharField', [], {'max_length': '1'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'raw_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}), + 'simplified_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}) + }, + 'chimere.subcategory': { + 'Meta': {'ordering': "['category', 'order']", 'object_name': 'SubCategory'}, + 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'category': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'subcategories'", 'to': "orm['chimere.Category']"}), + 'color_theme': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.ColorTheme']", 'null': 'True', 'blank': 'True'}), + 'icon': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Icon']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'item_type': ('django.db.models.fields.CharField', [], {'max_length': '1'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'order': ('django.db.models.fields.IntegerField', [], {'default': '1000'}), + 'submission': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + 'chimere.tinyurl': { + 'Meta': {'object_name': 'TinyUrl'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'parameters': ('django.db.models.fields.CharField', [], {'max_length': '500'}) + } + } + + complete_apps = ['chimere'] \ No newline at end of file diff --git a/chimere/models.py b/chimere/models.py index 12ec7a1..924fd54 100644 --- a/chimere/models.py +++ b/chimere/models.py @@ -248,6 +248,8 @@ class Importer(models.Model): verbose_name=_(u"Associated subcategories")) state = models.CharField(_(u"State"), max_length=200, blank=True, null=True) + associate_marker_to_way = models.BooleanField(_(u"Automatically associate "\ + u"a marker to a way"), default=False) class Meta: verbose_name = _(u"Importer") @@ -848,6 +850,8 @@ 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) + has_associated_marker = models.BooleanField(_(u"Has an associated marker"), + default=True) objects = models.GeoManager() def __unicode__(self): @@ -952,28 +956,31 @@ def route_post_save(sender, **kwargs): return geometry_post_save(pre_save_route_values)(sender, **kwargs) instance = kwargs['instance'] - marker_fields = [f.attname for f in Marker._meta.fields] - route_fields = [f.attname for f in Route._meta.fields] - marker_dct = dict([(k, getattr(instance, k)) for k in marker_fields - if k in route_fields and k not in ('id', 'ref_item_id')]) - marker_dct['point'] = "SRID=%d;POINT(%f %f)" % (instance.route.srid, - instance.route[0][0], instance.route[0][1]) - marker, created = Marker.objects.get_or_create(route=instance, - defaults=marker_dct) - if not created: - marker.status = instance.status - marker.point = marker_dct['point'] - marker.save() - properties = {} - for pm in instance.properties(): - prop = instance.getProperty(pm) - if prop: - properties[pm.pk] = prop.python_value - # fix mis-initialized markers - if created: - for cat in instance.categories.all(): - marker.categories.add(cat) - marker.saveProperties(properties) + + # manage associated marker + if instance.has_associated_marker: + marker_fields = [f.attname for f in Marker._meta.fields] + route_fields = [f.attname for f in Route._meta.fields] + marker_dct = dict([(k, getattr(instance, k)) for k in marker_fields + if k in route_fields and k not in ('id', 'ref_item_id')]) + marker_dct['point'] = "SRID=%d;POINT(%f %f)" % (instance.route.srid, + instance.route[0][0], instance.route[0][1]) + marker, created = Marker.objects.get_or_create(route=instance, + defaults=marker_dct) + if not created: + marker.status = instance.status + marker.point = marker_dct['point'] + marker.save() + properties = {} + for pm in instance.properties(): + prop = instance.getProperty(pm) + if prop: + properties[pm.pk] = prop.python_value + # fix mis-initialized markers + if created: + for cat in instance.categories.all(): + marker.categories.add(cat) + marker.saveProperties(properties) post_save.connect(route_post_save, sender=Route) @@ -982,7 +989,7 @@ def sync_m2m_route(sender, **kwargs): return route = kwargs['instance'] marker = route.associated_marker - if not marker.count: + if not marker.count(): return marker = marker.all()[0] marker.categories.clear() diff --git a/chimere/tests.py b/chimere/tests.py index e189fb9..5e0ba7c 100644 --- a/chimere/tests.py +++ b/chimere/tests.py @@ -120,7 +120,7 @@ class KMLImporterTest(TestCase, ImporterTest): importer2 = Importer.objects.create(importer_type='KML', source=test_dir_path+'tests/sample.kml', - filtr="Subcategory 1") + filtr="Subcategory 1", associate_marker_to_way=True) importer2.categories.add(subcategory_1) importer2.categories.add(subcategory_2) @@ -138,14 +138,14 @@ class KMLImporterTest(TestCase, ImporterTest): class ShapefileImporterTest(TestCase, ImporterTest): def setUp(self): - subcategory_1, subcategory_2 = subcategory_setup() + self.subcategory_1, self.subcategory_2 = subcategory_setup() importer = Importer.objects.create(importer_type='SHP', source=test_dir_path+'tests/sample_nodes.shp.zip', zipped=True) - importer.categories.add(subcategory_1) + importer.categories.add(self.subcategory_1) importer2 = Importer.objects.create(importer_type='SHP', source=test_dir_path+'tests/sample_ways.shp.zip', zipped=True) - importer2.categories.add(subcategory_2) + importer2.categories.add(self.subcategory_2) self.marker_importers = [(importer, 29), (importer2, 5),] @@ -154,6 +154,23 @@ class ShapefileImporterTest(TestCase, ImporterTest): def test_export(self): filename, zip_stream = ShapefileManager.export(Marker.objects.all()) + def test_associate_marker_to_way(self): + importer, nb = self.marker_importers[1] + + importer.associate_marker_to_way = True + importer.save() + nb, nb_updated, res = importer.manager.get() + nb = Marker.objects.filter(categories__pk=self.subcategory_2.pk).count() + self.assertEqual(nb, 5) + Marker.objects.filter(categories__pk=self.subcategory_2.pk).delete() + Route.objects.filter(categories__pk=self.subcategory_2.pk).delete() + + importer.associate_marker_to_way = False + importer.save() + nb, nb_updated, res = importer.manager.get() + nb = Marker.objects.filter(categories__pk=self.subcategory_2.pk).count() + self.assertEqual(nb, 0) + class OSMImporterTest(TestCase, ImporterTest): def setUp(self): subcategory_1, subcategory_2 = subcategory_setup() @@ -309,3 +326,16 @@ class RapprochementTest(TestCase): status='M').count(), 0) for k in new_vals: self.assertEqual(getattr(ref_marker, k), new_vals[k]) + +class RouteTest(TestCase): + def setUp(self): + self.subcategories = subcategory_setup() + + def test_route_creation(self): + route_1 = Route.objects.create(name='Route 1', + route='SRID=4326;LINESTRING (30 10, 10 30, 40 40)') + self.assertEqual(Marker.objects.filter(route=route_1).count(), 1) + route_2 = Route.objects.create(name='Route 1', + route='SRID=4326;LINESTRING (30 10, 10 30, 40 40)', + has_associated_marker=False) + self.assertEqual(Marker.objects.filter(route=route_2).count(), 0) diff --git a/chimere/utils.py b/chimere/utils.py index 75c0ad4..3e85a70 100644 --- a/chimere/utils.py +++ b/chimere/utils.py @@ -102,6 +102,9 @@ class ImportManager: values.update({ 'import_source':self.importer_instance.source}) values['status'] = 'I' + if not self.importer_instance.associate_marker_to_way\ + and cls.__name__ == 'Route': + values['has_associated_marker'] = False try: item = cls.objects.create(**values) except TypeError: -- cgit v1.2.3 From 7d8c3719bb2dfaa70b1d6c5e2a19c53588091d3b Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Mon, 19 Nov 2012 00:59:27 +0100 Subject: Admin: Fix "order" check for areas --- chimere/forms.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/chimere/forms.py b/chimere/forms.py index 4c26d52..6a7d7aa 100644 --- a/chimere/forms.py +++ b/chimere/forms.py @@ -476,6 +476,12 @@ class AreaAdminForm(forms.ModelForm): and not self.cleaned_data.get('area'): msg = _(u"No area selected.") raise forms.ValidationError(msg) + if self.cleaned_data.get('order'): + q = Area.objects.filter(order=self.cleaned_data.get('order')) + if q.count(): + msg= _(u"The area \"%s\" has the same order, you need to " + u" choose another one.") % unicode(q.all()[0]) + raise forms.ValidationError(msg) return self.cleaned_data def save(self, *args, **keys): -- cgit v1.2.3