diff options
author | Étienne Loks <etienne.loks@peacefrogs.net> | 2013-06-16 21:02:24 +0200 |
---|---|---|
committer | Étienne Loks <etienne.loks@peacefrogs.net> | 2013-06-16 21:02:24 +0200 |
commit | 81cc55bdada577a8b3c3cf1304f48c64810083aa (patch) | |
tree | 1565a321cbe395e21d11687937fe86532dc58358 | |
parent | 3635b97e30090c38946af1050a42fee8f6faca43 (diff) | |
download | Chimère-81cc55bdada577a8b3c3cf1304f48c64810083aa.tar.bz2 Chimère-81cc55bdada577a8b3c3cf1304f48c64810083aa.zip |
Display/write rights management on maps
-rw-r--r-- | chimere/admin.py | 8 | ||||
-rw-r--r-- | chimere/forms.py | 2 | ||||
-rw-r--r-- | chimere/migrations/0006_auto__add_mapusers__add_field_map_public_read__add_field_map_public_pr.py | 359 | ||||
-rw-r--r-- | chimere/models.py | 16 | ||||
-rw-r--r-- | chimere/src/default-bg.xcf | bin | 0 -> 3214457 bytes | |||
-rw-r--r-- | chimere/src/default_bg.xcf | bin | 0 -> 3231304 bytes | |||
-rw-r--r-- | chimere/static/chimere/css/styles.css | 24 | ||||
-rw-r--r-- | chimere/static/chimere/img/default-bg.jpg | bin | 0 -> 82181 bytes | |||
-rw-r--r-- | chimere/templates/chimere/main_map.html | 16 | ||||
-rw-r--r-- | chimere/templates/chimere/no_map.html | 40 | ||||
-rw-r--r-- | chimere/urls.py | 1 | ||||
-rw-r--r-- | chimere/views.py | 102 |
12 files changed, 536 insertions, 32 deletions
diff --git a/chimere/admin.py b/chimere/admin.py index f30c00b..67e0e51 100644 --- a/chimere/admin.py +++ b/chimere/admin.py @@ -42,7 +42,7 @@ from chimere.forms import MarkerAdminForm, RouteAdminForm, MapAdminForm,\ from chimere.models import Category, Icon, SubCategory, Marker, \ PropertyModel, News, Route, Map, ColorTheme, Color, \ MultimediaFile, PictureFile, Importer, Layer, MapLayers,\ - PropertyModelChoice, MultimediaExtension, Page,\ + PropertyModelChoice, MultimediaExtension, Page, MapUsers,\ get_maps_for_user, get_users_by_map from chimere.utils import unicode_normalize, ShapefileManager, KMLManager,\ CSVManager @@ -317,13 +317,17 @@ class LayerInline(admin.TabularInline): model = MapLayers extra = 1 +class UserInline(admin.TabularInline): + model = MapUsers + extra = 1 + class MapAdmin(admin.ModelAdmin): """ Specialized the map field. """ form = MapAdminForm exclude = ['upper_left_corner', 'lower_right_corner'] - inlines = [LayerInline] + inlines = [UserInline, LayerInline] list_display = ['name', 'order', 'available', 'default'] def importing(modeladmin, request, queryset): diff --git a/chimere/forms.py b/chimere/forms.py index b6d5feb..09b46ae 100644 --- a/chimere/forms.py +++ b/chimere/forms.py @@ -580,7 +580,7 @@ class MapAdminForm(forms.ModelForm): new_area.lower_right_corner = 'POINT(%s %s)' % (area[1][0], area[1][1]) content_type = ContentType.objects.get(app_label="chimere", - model="area") + model="map") if new_area.urn: mnemo = 'change_map_' + new_area.urn perm = Permission.objects.filter(codename=mnemo) diff --git a/chimere/migrations/0006_auto__add_mapusers__add_field_map_public_read__add_field_map_public_pr.py b/chimere/migrations/0006_auto__add_mapusers__add_field_map_public_read__add_field_map_public_pr.py new file mode 100644 index 0000000..65f9281 --- /dev/null +++ b/chimere/migrations/0006_auto__add_mapusers__add_field_map_public_read__add_field_map_public_pr.py @@ -0,0 +1,359 @@ +# -*- 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 model 'MapUsers' + db.create_table('chimere_mapusers', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('map', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['chimere.Map'])), + ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])), + ('read', self.gf('django.db.models.fields.BooleanField')(default=False)), + ('propose', self.gf('django.db.models.fields.BooleanField')(default=False)), + ('write', self.gf('django.db.models.fields.BooleanField')(default=False)), + )) + db.send_create_signal('chimere', ['MapUsers']) + + # Adding field 'Map.public_read' + db.add_column('chimere_map', 'public_read', + self.gf('django.db.models.fields.BooleanField')(default=False), + keep_default=False) + + # Adding field 'Map.public_propose' + db.add_column('chimere_map', 'public_propose', + self.gf('django.db.models.fields.BooleanField')(default=False), + keep_default=False) + + # Adding field 'Map.public_write' + db.add_column('chimere_map', 'public_write', + self.gf('django.db.models.fields.BooleanField')(default=False), + keep_default=False) + + + def backwards(self, orm): + # Deleting model 'MapUsers' + db.delete_table('chimere_mapusers') + + # Deleting field 'Map.public_read' + db.delete_column('chimere_map', 'public_read') + + # Deleting field 'Map.public_propose' + db.delete_column('chimere_map', 'public_propose') + + # Deleting field 'Map.public_write' + db.delete_column('chimere_map', 'public_write') + + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'chimere.aggregatedroute': { + 'Meta': {'object_name': 'AggregatedRoute', 'db_table': "'chimere_aggregated_routes'", 'managed': 'False'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'route': ('django.contrib.gis.db.models.fields.MultiLineStringField', [], {}), + 'status': ('django.db.models.fields.CharField', [], {'max_length': '1'}), + 'subcategory': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.SubCategory']"}) + }, + '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', [], {'related_name': "'colors'", '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': 'False'}), + 'categories': ('chimere.widgets.SelectMultipleField', [], {'to': "orm['chimere.SubCategory']", 'symmetrical': 'False'}), + 'default_description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + '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'}), + 'get_description': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + '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'}), + 'overwrite': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + '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.map': { + 'Meta': {'ordering': "('order', 'name')", 'object_name': 'Map'}, + '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': "'maps'", 'blank': 'True', 'through': "orm['chimere.MapLayers']", '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'}), + 'public_propose': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'public_read': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'public_write': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'restrict_to_extent': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'subcategories': ('chimere.widgets.SelectMultipleField', [], {'symmetrical': 'False', 'related_name': "'maps'", 'blank': 'True', 'db_table': "'chimere_subcategory_maps'", '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'}), + 'users': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.User']", 'through': "orm['chimere.MapUsers']", 'symmetrical': 'False'}), + 'welcome_message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + 'chimere.maplayers': { + 'Meta': {'ordering': "('order',)", 'object_name': 'MapLayers'}, + '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']"}), + 'map': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Map']"}), + 'order': ('django.db.models.fields.IntegerField', [], {}) + }, + 'chimere.mapusers': { + 'Meta': {'object_name': 'MapUsers'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'map': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Map']"}), + 'propose': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'read': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}), + 'write': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) + }, + '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'}), + 'is_front_page': ('django.db.models.fields.NullBooleanField', [], {'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': 'True'}), + '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'}), + 'weight': ('django.db.models.fields.IntegerField', [], {'default': '0', 'null': 'True', 'blank': 'True'}) + }, + 'chimere.multimediaextension': { + 'Meta': {'object_name': 'MultimediaExtension'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'multimedia_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'extensions'", 'to': "orm['chimere.MultimediaType']"}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '6'}) + }, + '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']", 'null': 'True', 'blank': 'True'}), + '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'}, + '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'}), + 'is_front_page': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'maps': ('chimere.widgets.SelectMultipleField', [], {'symmetrical': 'False', 'to': "orm['chimere.Map']", 'null': 'True', 'blank': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}) + }, + 'chimere.page': { + 'Meta': {'object_name': 'Page'}, + 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'content': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mnemonic': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), + 'order': ('django.db.models.fields.IntegerField', [], {'default': '10', 'null': 'True', 'blank': 'True'}), + 'template_path': ('django.db.models.fields.CharField', [], {'max_length': '150', 'null': 'True', 'blank': '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.propertymodelchoice': { + 'Meta': {'object_name': 'PropertyModelChoice'}, + 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'propertymodel': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'choices'", 'to': "orm['chimere.PropertyModel']"}), + 'value': ('django.db.models.fields.CharField', [], {'max_length': '150'}) + }, + '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': 'True'}), + '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'}, + 'as_layer': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + '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'}), + 'dated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'hover_icon': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'subcat_hovered'", 'null': 'True', 'to': "orm['chimere.Icon']"}), + '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'}), + 'routing_warn': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'submission': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'weighted': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) + }, + 'chimere.tinyurl': { + 'Meta': {'object_name': 'TinyUrl'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'parameters': ('django.db.models.fields.CharField', [], {'max_length': '500'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + } + } + + complete_apps = ['chimere']
\ No newline at end of file diff --git a/chimere/models.py b/chimere/models.py index 60e4cd1..a1d96d0 100644 --- a/chimere/models.py +++ b/chimere/models.py @@ -1353,12 +1353,13 @@ class Map(models.Model, SimpleArea): """A map """ name = models.CharField(_(u"Name"), max_length=150) + available = models.BooleanField(_(u"Available")) + users = models.ManyToManyField(User, through='MapUsers') urn = models.SlugField(_(u"Map urn"), max_length=50, blank=True, unique=True) welcome_message = models.TextField(_(u"Welcome message"), blank=True, null=True) 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) lower_right_corner = models.PointField(_(u"Lower right corner"), @@ -1380,6 +1381,9 @@ class Map(models.Model, SimpleArea): u"available")) external_css = models.URLField(_(u"Link to an external CSS"), blank=True, null=True) + public_read = models.BooleanField(_(u"Public can read the map")) + public_propose = models.BooleanField(_(u"Public can propose item to the map")) + public_write = models.BooleanField(_(u"Public can write without moderation to the map")) restrict_to_extent = models.BooleanField(_(u"Restrict to the area extent"), default=False) objects = models.GeoManager() @@ -1522,6 +1526,16 @@ def get_users_by_map(map): return User.objects.filter(Q(groups__permissions__codename=perm)| Q(user_permissions__codename=perm)).all() +class MapUsers(models.Model): + map = models.ForeignKey(Map, related_name='mapusers') + user = models.ForeignKey(User, related_name='mapusers') + read = models.BooleanField(_(u"Can read the map")) + propose = models.BooleanField(_(u"Can propose item to the map")) + write = models.BooleanField(_(u"Can write without moderation to the map")) + class Meta: + verbose_name = _("Map - user") + verbose_name_plural = _("Map - users") + class MapLayers(models.Model): map = models.ForeignKey(Map) layer = models.ForeignKey(Layer) diff --git a/chimere/src/default-bg.xcf b/chimere/src/default-bg.xcf Binary files differnew file mode 100644 index 0000000..71ad247 --- /dev/null +++ b/chimere/src/default-bg.xcf diff --git a/chimere/src/default_bg.xcf b/chimere/src/default_bg.xcf Binary files differnew file mode 100644 index 0000000..453bf15 --- /dev/null +++ b/chimere/src/default_bg.xcf diff --git a/chimere/static/chimere/css/styles.css b/chimere/static/chimere/css/styles.css index 6986189..c0844df 100644 --- a/chimere/static/chimere/css/styles.css +++ b/chimere/static/chimere/css/styles.css @@ -51,6 +51,7 @@ body, h2, h3, th, background-image:None; } +#no-content .alert, fieldset, .action li, #content, #layer_selection #layer_list, #map-footer, #panel, #chimere_itinerary_panel, #maps, @@ -74,6 +75,7 @@ div.warning, .errorlist{ border:1px solid #54c200; } +#no-content .alert, #layer_selection h4, #layer_selection #layer_list, #maps, #detail, #main-map, @@ -234,6 +236,28 @@ ul#action-2 { padding:20px; } +#no-content{ + position:absolute; + bottom:0; + top:0; + right:0; + left:0; + background-image:url(../img/default-bg.jpg) +} + +#no-content .alert{ + width:400px; + padding:0.5em; + margin-left:auto; + margin-right:auto; + margin-top:25%; + padding:0.5em 1em; +} + +#auth p{ + text-align:center; +} + #footer{ margin:5px; text-align:center; diff --git a/chimere/static/chimere/img/default-bg.jpg b/chimere/static/chimere/img/default-bg.jpg Binary files differnew file mode 100644 index 0000000..a3e96f0 --- /dev/null +++ b/chimere/static/chimere/img/default-bg.jpg diff --git a/chimere/templates/chimere/main_map.html b/chimere/templates/chimere/main_map.html index 4187440..b6a0774 100644 --- a/chimere/templates/chimere/main_map.html +++ b/chimere/templates/chimere/main_map.html @@ -1,5 +1,6 @@ {% extends "chimere/base.html" %} {% load i18n unlocalize_point chimere_tags %} +{% load url from future %} {% block extra_head %} {% head_jquery %} {% head_chimere %} @@ -8,6 +9,19 @@ {% endblock %} {% block message_edit %}{% endblock %} {% block sidebar %} + {{block.super}} + <div id='auth'> + {% if not is_authenticated %} + <form action='.' method='post'> + <table> + {{auth_form.as_table}} + <tr><td></td><td><input type='submit' value='Ok'/></td></tr> + </table> + </form> + {% else %} + <p>{% trans "Identified as: " %}{{user}} - <a href='{% url "chimere:logout" %}'>{% trans "Logout"%}</a></p> + {% endif %} + </div> <div id='panel' class='draggable ui-widget ui-corner-all'> <h2 class='ui-widget ui-state-default ui-corner-all ui-widget-header'>{% trans "Categories"%}</h2> <form method='post' name='frm_categories' id='frm_categories'> @@ -31,7 +45,7 @@ {% display_welcome %} {% display_news news_visible %} <div id='permalink' class='ui-widget ui-button ui-state-default ui-corner-all'></div> - <a id='simple_button' class='ui-widget ui-button ui-state-default ui-corner-all' href='{% url chimere:simple_index map_name_slash %}'>{% trans "Simple map" %}</a> + <a id='simple_button' class='ui-widget ui-button ui-state-default ui-corner-all' href='{% url "chimere:simple_index" map_name_slash %}'>{% trans "Simple map" %}</a> </div> <div id='detail' class='ui-widget ui-corner-all'></div> {% endblock %} diff --git a/chimere/templates/chimere/no_map.html b/chimere/templates/chimere/no_map.html new file mode 100644 index 0000000..c707a0b --- /dev/null +++ b/chimere/templates/chimere/no_map.html @@ -0,0 +1,40 @@ +{% extends "chimere/base.html" %} +{% load i18n unlocalize_point chimere_tags %} +{% block extra_head %} +{% head_jquery %} +{% head_chimere %} +{% head_jme %} +{{ block.super }} +{% endblock %} +{% block sidebar %} + {{block.super}} + <div id='auth'> + {% if not is_authenticated %} + <form action='.' method='post'> + <table> + {{auth_form.as_table}} + <tr><td></td><td><input type='submit' value='Ok'/></td></tr> + </table> + </form> + {% else %} + <p>{% trans "Identified as: " %}{{user}} - <a href='{% url "chimere:logout" %}'>{% trans "Logout"%}</a></p> + {% endif %} + </div> +{% endblock %} +{% block content %} + {{block.super}} + <div id='no-content'> + <div class='alert'> + <p> + {% if is_authenticated %} + {% trans "No map are currently available for your account." %} + {% else %} + {% trans "No map are currently available for public access. If you have an account identify yourself." %} + {% endif %} + </p> + </div> + </div> +{% endblock %} +{% block footer %} + <p class='map-footer'>{% include "chimere/blocks/footer.html" %}</p> +{% endblock %} diff --git a/chimere/urls.py b/chimere/urls.py index 36275ab..f87522e 100644 --- a/chimere/urls.py +++ b/chimere/urls.py @@ -69,6 +69,7 @@ if hasattr(settings, 'CHIMERE_ENABLE_ROUTING') \ ) urlpatterns += patterns('chimere.views', + url(r'^logout/?$', 'logout_view', name="logout"), url(r'^charte/?$', 'charte', name="charte"), url(r'^(?P<map_name>[a-zA-Z0-9_-]+/)?contact/?$', 'contactus', name="contact"), diff --git a/chimere/views.py b/chimere/views.py index f48a3b1..18039b7 100644 --- a/chimere/views.py +++ b/chimere/views.py @@ -29,6 +29,8 @@ from itertools import groupby import re from django.conf import settings +from django.contrib.auth import authenticate, login, logout +from django.contrib.auth.forms import AuthenticationForm from django.contrib.gis.geos import GEOSGeometry from django.contrib.gis.gdal.error import OGRException from django.contrib.gis.measure import D @@ -69,11 +71,12 @@ def get_base_uri(request): return base_uri #TODO: convert to requestcontext -def get_base_response(map_name=""): +def get_base_response(request, map_name="", edit=False): """ Get the base url """ - base_response_dct = {'media_path':settings.MEDIA_URL,} + base_response_dct = {'media_path':settings.MEDIA_URL, + 'is_authenticated':request.user.is_authenticated()} base_url = reverse("chimere:index") if not base_url.startswith('/'): base_url = '/' + base_url @@ -85,18 +88,39 @@ def get_base_response(map_name=""): base_url += '/' base_url += map_name + '/' base_response_dct['extra_url'] = base_url - map = None + map_filter = {'available':True} if map_name: - try: - map = Map.objects.get(urn=map_name, available=True) - except ObjectDoesNotExist: - return None, redirect(reverse('chimere:index')) + map_filter['urn'] = map_name else: - try: - map = Map.objects.get(default=True) - map_name = map.urn - except ObjectDoesNotExist: - pass + map_filter['default'] = True + filters = [{'public_write':True}, + {'public_propose':True}, + ] if edit else [ + {'public_read':True}] + if base_response_dct['is_authenticated']: + filters += [{'mapusers__user':request.user, 'mapusers__write':True}, + {'mapusers__user':request.user, 'mapusers__propose':True}, + ] if edit else [ + {'mapusers__user':request.user, 'mapusers__read':True},] + query = None + for fltr in filters: + fltr.update(map_filter) + if not query: + query = Q(**fltr) + else: + query = query | Q(**fltr) + map = None + try: + map = Map.objects.get(query) + map_name = map.urn + except ObjectDoesNotExist: + if map_name: + return None, redirect(reverse('chimere:index')) + + if edit and map: + base_response_dct['can_write'] = bool(map.public_write or + Map.objects.filter(pk=map.pk, mapusers__user=request.user, + mapusers__write=True).count()) base_response_dct['map'] = map base_response_dct['map_name'] = map_name @@ -134,6 +158,11 @@ def getShareNetwork(request, map_name='', marker=None): share_networks.append((network[0], network[1] % net_dct, network[2])) return share_networks, net_dct + +def logout_view(request): + logout(request) + return redirect(reverse('chimere:index')) + def index(request, map_name=None, default_map=None, simple=False, get_response=False): """ @@ -147,9 +176,28 @@ def index(request, map_name=None, default_map=None, simple=False, request.session['last_visit'] != today: request.session['last_visit'] = today news_visible = True - response_dct, redir = get_base_response(map_name) + response_dct, redir = get_base_response(request, map_name) if redir: return redir + + if request.POST: + auth_form = AuthenticationForm(None, request.POST) + invalid_msg = _(u"Invalid user or password.") + if auth_form.is_valid(): + user = authenticate( + username=auth_form.cleaned_data['username'], + password=auth_form.cleaned_data['password']) + if user is not None and user.is_active: + login(request, user) + return redirect(reverse('chimere:index')) + else: + response_dct['auth_form'] = auth_form + else: + response_dct['auth_form'] = AuthenticationForm() + + if not response_dct['map']: + return render_to_response('chimere/no_map.html', response_dct, + context_instance=RequestContext(request)) # don't mess with permalink zoomout = True if request.GET and 'lat' in request.GET \ @@ -197,7 +245,7 @@ def get_edit_page(redirect_url, item_cls, item_form, Edition page """ def func(request, map_name="", item_id=None, cat_type=['M']): - response_dct, redir = get_base_response(map_name) + response_dct, redir = get_base_response(request, map_name) if redir: return redir, None, None if 'map_name' in response_dct: @@ -284,7 +332,7 @@ def get_edit_page(redirect_url, item_cls, item_form, f.save(marker) base_uri = get_base_uri(request) notifySubmission(base_uri, item) - response_dct = get_base_response(map_name) + response_dct = get_base_response(request, map_name) return redirect(redirect_url + '-item', map_name + '/' if map_name else '', item.ref_item.pk, 'submited'), None, subcategories @@ -346,7 +394,7 @@ def edit(request, map_name="", item_id=None, submited=False): context_instance=RequestContext(request)) def uploadFile(request, category_id='', map_name=''): - response_dct, redir = get_base_response(map_name) + response_dct, redir = get_base_response(request, map_name) if redir: return redir Form = FileForm if not category_id else FullFileForm @@ -455,7 +503,7 @@ def submited(request, map_name="", action=""): """ Successful submission page """ - response_dct, redir = get_base_response(map_name) + response_dct, redir = get_base_response(request, map_name) if redir: return redir response_dct.update({'actions':actions(response_dct['map_name']), @@ -467,7 +515,7 @@ def charte(request, map_name=""): """ Affichage de la charte """ - response_dct, redir = get_base_response(map_name) + response_dct, redir = get_base_response(request, map_name) if redir: return redir response_dct.update({'actions':actions(response_dct['map_name']), @@ -496,7 +544,7 @@ def contactus(request, map_name=""): msg = _(u"Temporary error. Renew your message later.") else: form = ContactForm() - response_dct, redir = get_base_response(map_name) + response_dct, redir = get_base_response(request, map_name) if redir: return redir response_dct.update({'actions':actions(response_dct['map_name']), @@ -513,7 +561,7 @@ def extraPage(request, map_name="", page_id=""): page = Page.objects.get(available=True, mnemonic=page_id) except ObjectDoesNotExist: return redirect(reverse('chimere:index')) - response_dct, redir = get_base_response(map_name) + response_dct, redir = get_base_response(request, map_name) if redir: return redir response_dct.update({'actions':actions(response_dct['map_name']), @@ -534,7 +582,7 @@ def getDetail(request, map_name, marker_id): status__in=['A', 'S'])[0] except (ValueError, IndexError): return HttpResponse('no results') - response_dct, redir = get_base_response(map_name) + response_dct, redir = get_base_response(request, map_name) if redir: return redir response_dct['marker'] = marker @@ -564,7 +612,7 @@ def getDescriptionDetail(request, map_name, category_id): category = Category.objects.filter(id=int(category_id))[0] except (ValueError, IndexError): return HttpResponse('no results') - response_dct, redir = get_base_response(map_name) + response_dct, redir = get_base_response(request, map_name) if redir: return redir response_dct['category'] = category @@ -650,7 +698,7 @@ def get_all_categories(request, map_name=None): ''' Get all available categories in JSON ''' - context_data, redir = get_base_response(map_name) + context_data, redir = get_base_response(request, map_name) map = context_data["map"] subcategories = [] if map: @@ -669,7 +717,7 @@ def get_available_categories(request, map_name=None, map=None, status='A', ''' Get category menu for a designed map ''' - context_data, redir = get_base_response(map_name) + context_data, redir = get_base_response(request, map_name) map = context_data["map"] if redir: return redir @@ -731,7 +779,7 @@ def getTinyfiedUrl(request, parameters, map_name=''): urn = TinyUrl.getUrnByParameters(parameters) except: return {} - response_dct, redir = get_base_response(map_name) + response_dct, redir = get_base_response(request, map_name) if redir: return redir url = reverse('chimere:tiny', args=[(response_dct['map_name'] \ @@ -757,7 +805,7 @@ def redirectFromTinyURN(request, map_name='', tiny_urn=''): Redirect from a tiny Urn """ parameters = '?' + TinyUrl.getParametersByUrn(tiny_urn) - response_dct, redir = get_base_response(map_name) + response_dct, redir = get_base_response(request, map_name) if redir: return redir return HttpResponseRedirect(response_dct['extra_url'] + parameters) @@ -836,7 +884,7 @@ def rss(request, map_name=''): ''' Redirect to RSS subscription page ''' - response_dct, redir = get_base_response(map_name) + response_dct, redir = get_base_response(request, map_name) if redir: return redir response_dct.update({'actions':actions(response_dct['map_name']), |