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/tests.py | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'chimere/tests.py') 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(-) (limited to 'chimere/tests.py') 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 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(-) (limited to 'chimere/tests.py') 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 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(-) (limited to 'chimere/tests.py') 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 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 (limited to 'chimere/tests.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