summaryrefslogtreecommitdiff
path: root/chimere
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@peacefrogs.net>2013-03-14 18:48:00 +0100
committerÉtienne Loks <etienne.loks@peacefrogs.net>2013-03-14 18:48:00 +0100
commit054fdbdf7a1e5106725b8b5a36db99242cfa65c1 (patch)
tree1633b26e884feb1f29afedbb80cef7a6ecbdba2d /chimere
parent8a5ba2650678ec22107a1a0a10650b6e0cc14683 (diff)
parentd02ec4246813eb0787bf3ab54af1af9ce32bd376 (diff)
downloadChimère-054fdbdf7a1e5106725b8b5a36db99242cfa65c1.tar.bz2
Chimère-054fdbdf7a1e5106725b8b5a36db99242cfa65c1.zip
Merge branch 'master' into saclay
Conflicts: chimere/locale/fr/LC_MESSAGES/django.po chimere/static/chimere/css/styles.css chimere/static/chimere/js/jquery.chimere.js chimere/templates/chimere/detail.html chimere/templatetags/chimere_tags.py chimere/utils.py chimere/views.py example_project/settings.py
Diffstat (limited to 'chimere')
-rw-r--r--chimere/__init__.py10
-rw-r--r--chimere/admin.py27
-rw-r--r--chimere/default_settings.py36
l---------chimere/external_utils1
-rw-r--r--chimere/external_utils/OsmApi.py747
-rw-r--r--chimere/external_utils/__init__.py0
-rw-r--r--chimere/fixtures/auth_group.json46
-rw-r--r--chimere/fixtures/initial_data.json44
-rw-r--r--chimere/fixtures/layers-geobretagne.json74
-rw-r--r--chimere/fixtures/layers-opencyclemap.json26
-rw-r--r--chimere/forms.py2
-rw-r--r--chimere/locale/fr/LC_MESSAGES/django.po426
-rw-r--r--chimere/migrations/0042_fix_rights.py261
-rw-r--r--chimere/migrations/0043_auto__add_field_importer_get_description.py245
-rw-r--r--chimere/migrations/0044_auto__add_field_importer_default_description.py246
-rw-r--r--chimere/models.py42
-rw-r--r--chimere/static/bsmSelect/GPL-LICENSE.txt278
-rw-r--r--chimere/static/bsmSelect/MIT-LICENSE.txt21
-rw-r--r--chimere/static/bsmSelect/README.md191
-rw-r--r--chimere/static/bsmSelect/css/jquery.bsmselect.css (renamed from chimere/static/chimere/js/jquery/bsmSelect/css/jquery.bsmselect.css)0
-rw-r--r--chimere/static/bsmSelect/css/jquery.bsmselect.custom.css (renamed from chimere/static/chimere/js/jquery/bsmSelect/css/jquery.bsmselect.custom.css)0
-rw-r--r--chimere/static/bsmSelect/js/jquery.bsmselect.compatibility.js (renamed from chimere/static/chimere/js/jquery/bsmSelect/js/jquery.bsmselect.compatibility.js)0
-rw-r--r--chimere/static/bsmSelect/js/jquery.bsmselect.js (renamed from chimere/static/chimere/js/jquery/bsmSelect/js/jquery.bsmselect.js)0
-rw-r--r--chimere/static/bsmSelect/js/jquery.bsmselect.sortable.js (renamed from chimere/static/chimere/js/jquery/bsmSelect/js/jquery.bsmselect.sortable.js)0
-rw-r--r--chimere/static/chimere/css/styles.css15
-rw-r--r--[-rwxr-xr-x]chimere/static/chimere/img/cloud-popup-relative.pngbin3177 -> 3177 bytes
-rw-r--r--chimere/static/chimere/js/importer_interface.js23
-rw-r--r--chimere/static/chimere/js/jquery.chimere.js14
-rw-r--r--chimere/static/jme/GPL-LICENSE-2.txt278
-rw-r--r--chimere/static/jme/MIT-LICENSE.txt20
-rw-r--r--chimere/static/openlayers/OpenLayers.js (renamed from chimere/static/chimere/js/OpenLayers.js)0
-rw-r--r--chimere/static/openlayers/SimplePanZoom.js (renamed from chimere/static/chimere/js/SimplePanZoom.js)0
-rwxr-xr-xchimere/static/prettyPhoto/README30
-rw-r--r--[-rwxr-xr-x]chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/btnNext.pngbin1411 -> 1411 bytes
-rw-r--r--[-rwxr-xr-x]chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/btnPrevious.pngbin1442 -> 1442 bytes
-rw-r--r--[-rwxr-xr-x]chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/contentPattern.pngbin130 -> 130 bytes
-rw-r--r--[-rwxr-xr-x]chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/default_thumbnail.gifbin227 -> 227 bytes
-rw-r--r--[-rwxr-xr-x]chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/loader.gifbin2545 -> 2545 bytes
-rw-r--r--[-rwxr-xr-x]chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/sprite.pngbin4076 -> 4076 bytes
-rw-r--r--[-rwxr-xr-x]chimere/static/prettyPhoto/images/prettyPhoto/dark_square/btnNext.pngbin1411 -> 1411 bytes
-rw-r--r--[-rwxr-xr-x]chimere/static/prettyPhoto/images/prettyPhoto/dark_square/btnPrevious.pngbin1442 -> 1442 bytes
-rw-r--r--[-rwxr-xr-x]chimere/static/prettyPhoto/images/prettyPhoto/dark_square/contentPattern.pngbin121 -> 121 bytes
-rw-r--r--[-rwxr-xr-x]chimere/static/prettyPhoto/images/prettyPhoto/dark_square/default_thumbnail.gifbin227 -> 227 bytes
-rw-r--r--[-rwxr-xr-x]chimere/static/prettyPhoto/images/prettyPhoto/dark_square/loader.gifbin2545 -> 2545 bytes
-rw-r--r--[-rwxr-xr-x]chimere/static/prettyPhoto/images/prettyPhoto/dark_square/sprite.pngbin3507 -> 3507 bytes
-rw-r--r--[-rwxr-xr-x]chimere/static/prettyPhoto/images/prettyPhoto/facebook/btnNext.pngbin845 -> 845 bytes
-rw-r--r--[-rwxr-xr-x]chimere/static/prettyPhoto/images/prettyPhoto/facebook/btnPrevious.pngbin828 -> 828 bytes
-rw-r--r--[-rwxr-xr-x]chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternBottom.pngbin142 -> 142 bytes
-rw-r--r--[-rwxr-xr-x]chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternLeft.pngbin137 -> 137 bytes
-rw-r--r--[-rwxr-xr-x]chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternRight.pngbin136 -> 136 bytes
-rw-r--r--[-rwxr-xr-x]chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternTop.pngbin142 -> 142 bytes
-rw-r--r--[-rwxr-xr-x]chimere/static/prettyPhoto/images/prettyPhoto/facebook/default_thumbnail.gifbin227 -> 227 bytes
-rw-r--r--[-rwxr-xr-x]chimere/static/prettyPhoto/images/prettyPhoto/facebook/loader.gifbin2545 -> 2545 bytes
-rw-r--r--[-rwxr-xr-x]chimere/static/prettyPhoto/images/prettyPhoto/facebook/sprite.pngbin4227 -> 4227 bytes
-rw-r--r--[-rwxr-xr-x]chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/btnNext.pngbin1411 -> 1411 bytes
-rw-r--r--[-rwxr-xr-x]chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/btnPrevious.pngbin1442 -> 1442 bytes
-rw-r--r--[-rwxr-xr-x]chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/default_thumbnail.gifbin227 -> 227 bytes
-rw-r--r--[-rwxr-xr-x]chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/loader.gifbin2545 -> 2545 bytes
-rw-r--r--[-rwxr-xr-x]chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/sprite.pngbin4099 -> 4099 bytes
-rw-r--r--[-rwxr-xr-x]chimere/static/prettyPhoto/images/prettyPhoto/light_square/btnNext.pngbin1411 -> 1411 bytes
-rw-r--r--[-rwxr-xr-x]chimere/static/prettyPhoto/images/prettyPhoto/light_square/btnPrevious.pngbin1442 -> 1442 bytes
-rw-r--r--[-rwxr-xr-x]chimere/static/prettyPhoto/images/prettyPhoto/light_square/default_thumbnail.gifbin227 -> 227 bytes
-rw-r--r--[-rwxr-xr-x]chimere/static/prettyPhoto/images/prettyPhoto/light_square/loader.gifbin2545 -> 2545 bytes
-rw-r--r--[-rwxr-xr-x]chimere/static/prettyPhoto/images/prettyPhoto/light_square/sprite.pngbin3507 -> 3507 bytes
-rw-r--r--chimere/templates/admin/chimere/marker/change_form.html2
-rw-r--r--chimere/templates/chimere/blocks/areas.html1
-rw-r--r--chimere/templates/chimere/blocks/map.html5
-rw-r--r--chimere/templates/chimere/detail.html6
-rw-r--r--chimere/templates/chimere/edit.html3
-rw-r--r--chimere/templates/chimere/edit_route.html3
-rw-r--r--chimere/templatetags/chimere_tags.py7
-rw-r--r--chimere/tests.py27
-rw-r--r--chimere/tests/data_license1
-rw-r--r--chimere/utils.py45
-rw-r--r--chimere/views.py15
-rw-r--r--chimere/widgets.py8
76 files changed, 2865 insertions, 361 deletions
diff --git a/chimere/__init__.py b/chimere/__init__.py
index a7083c7..2ef2100 100644
--- a/chimere/__init__.py
+++ b/chimere/__init__.py
@@ -1,14 +1,8 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# Copyright (C) 2012 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
+# Copyright (C) 2012-2013 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
-from django.utils.translation import ugettext as _
-
-# templates/chimere/edit.html, templates/chimere/edit_route.html
-_(u"Multimedia files")
-_(u"Picture files")
-
-VERSION = (2, 0)
+VERSION = (2, 0, 2)
def get_version():
return u'.'.join((unicode(num) for num in VERSION))
diff --git a/chimere/admin.py b/chimere/admin.py
index 3c24de0..c9107a5 100644
--- a/chimere/admin.py
+++ b/chimere/admin.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# Copyright (C) 2008-2012 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
+# Copyright (C) 2008-2013 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as
@@ -97,7 +97,8 @@ export_to_csv.short_description = _(u"Export to CSV")
def managed_modified(modeladmin, request, queryset):
# not very clean... There is must be a better way to do that
redirect_url = request.get_full_path().split('admin_modification')[0]
- if queryset.count() != 1:
+ if queryset.count() != 1 and len(set([i.ref_item or i
+ for i in queryset.all()])) != 1:
messages.error(request, _(u"Only one item can be managed at a "
u"time."))
return HttpResponseRedirect(redirect_url)
@@ -105,8 +106,9 @@ def managed_modified(modeladmin, request, queryset):
item = queryset.all()[0]
if not item.ref_item or item.ref_item == item:
try:
- item = modeladmin.model.objects.get(ref_item=item)
- except ObjectDoesNotExist:
+ item = modeladmin.model.objects.filter(ref_item=item
+ ).exclude(pk=item.pk).all()[0]
+ except IndexError:
messages.error(request, _(u"No modified item associated "
u"to the selected item."))
return HttpResponseRedirect(redirect_url)
@@ -179,8 +181,8 @@ class MarkerAdmin(admin.ModelAdmin):
Specialized the Point field.
"""
search_fields = ("name",)
- list_display = ('name', 'status')
- list_filter = ('status', 'categories')
+ list_display = ('name', 'status', 'start_date', 'end_date')
+ list_filter = ('status', 'categories', 'start_date', 'end_date')
actions = [validate, disable, managed_modified, export_to_kml,
export_to_shapefile, export_to_csv]
exclude = ['submiter_session_key', 'import_key', 'import_version',
@@ -208,17 +210,19 @@ class MarkerAdmin(admin.ModelAdmin):
}),
)
inlines = [MultimediaInline, PictureInline]
+ has_properties = True
def __init__(self, *args, **kwargs):
"""
Manage properties in fieldsets.
"""
- main_fields = self.fieldsets[0][1]['fields']
- for pm in PropertyModel.objects.filter(available=True).order_by('order'
+ if self.has_properties:
+ main_fields = self.fieldsets[0][1]['fields']
+ for pm in PropertyModel.objects.filter(available=True).order_by('order'
).all():
- pm_name = pm.getNamedId()
- if pm_name not in main_fields:
- main_fields.append(pm_name)
+ pm_name = pm.getNamedId()
+ if pm_name not in main_fields:
+ main_fields.append(pm_name)
super(MarkerAdmin, self).__init__(*args, **kwargs)
def queryset(self, request):
@@ -284,6 +288,7 @@ class RouteAdmin(MarkerAdmin):
}),
)
inlines = []
+ has_properties = False
def queryset(self, request):
qs = self.model._default_manager.get_query_set()
diff --git a/chimere/default_settings.py b/chimere/default_settings.py
deleted file mode 100644
index 049520f..0000000
--- a/chimere/default_settings.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
-Here are the default settings for the Chimere app.
-Feel free to set these settings in your project, they will override these defaults.
-"""
-# The height and width of the POI icons
-CHIMERE_ICON_HEIGHT = 20
-CHIMERE_ICON_WIDTH = 20
-# The offset of the POI icons
-CHIMERE_ICON_OFFSET_X = 0
-CHIMERE_ICON_OFFSET_Y = 0
-
-# default center of the map
-CHIMERE_DEFAULT_CENTER = (2.49, 48.7)
-# Default zoom level
-CHIMERE_DEFAULT_ZOOM = 10
-# projection used by the main map
-# most public map providers use spherical mercator : 900913
-CHIMERE_EPSG_PROJECTION = 900913
-# projection displayed to the end user by openlayers
-# chimere use the same projection to save its data in the database
-CHIMERE_EPSG_DISPLAY_PROJECTION = 4326
-# display of shortcuts for areas
-CHIMERE_DISPLAY_AREAS = True
-# number of day before an event to display
-# if equal to 0: disable event management
-# if you change this value from 0 to a value in a production environnement
-# don't forget to run the upgrade.py script to create appropriate fields in
-# the database
-CHIMERE_DAYS_BEFORE_EVENT = 30
-
-# JS definition of the main map cf. OpenLayers documentation for more details
-CHIMERE_DEFAULT_MAP_LAYER = "new OpenLayers.Layer.OSM.Mapnik('Mapnik')" # OSM mapnik map
-
-# display picture inside the description by default or inside a galery?
-CHIMERE_MINIATURE_BY_DEFAULT = True
diff --git a/chimere/external_utils b/chimere/external_utils
deleted file mode 120000
index 19985ba..0000000
--- a/chimere/external_utils
+++ /dev/null
@@ -1 +0,0 @@
-../utils/ \ No newline at end of file
diff --git a/chimere/external_utils/OsmApi.py b/chimere/external_utils/OsmApi.py
new file mode 100644
index 0000000..3b1b9b1
--- /dev/null
+++ b/chimere/external_utils/OsmApi.py
@@ -0,0 +1,747 @@
+#-*- coding: utf-8 -*-
+
+###########################################################################
+## ##
+## Copyrights Etienne Chové <chove@crans.org> 2009-2010 ##
+## ##
+## This program is free software: you can redistribute it and/or modify ##
+## it under the terms of the GNU General Public License as published by ##
+## the Free Software Foundation, either version 3 of the License, or ##
+## (at your option) any later version. ##
+## ##
+## This program is distributed in the hope that it will be useful, ##
+## but WITHOUT ANY WARRANTY; without even the implied warranty of ##
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ##
+## GNU General Public License for more details. ##
+## ##
+## You should have received a copy of the GNU General Public License ##
+## along with this program. If not, see <http://www.gnu.org/licenses/>. ##
+## ##
+###########################################################################
+
+## HomePage : http://wiki.openstreetmap.org/wiki/PythonOsmApi
+
+###########################################################################
+## History ##
+###########################################################################
+## 0.2.19 2010-05-24 Add debug message on ApiError ##
+## 0.2.18 2010-04-20 Fix ChangesetClose and _http_request ##
+## 0.2.17 2010-01-02 Capabilities implementation ##
+## 0.2.16 2010-01-02 ChangesetsGet by Alexander Rampp ##
+## 0.2.15 2009-12-16 xml encoding error for < and > ##
+## 0.2.14 2009-11-20 changesetautomulti parameter ##
+## 0.2.13 2009-11-16 modify instead update for osc ##
+## 0.2.12 2009-11-14 raise ApiError on 4xx errors -- Xoff ##
+## 0.2.11 2009-10-14 unicode error on ChangesetUpload ##
+## 0.2.10 2009-10-14 RelationFullRecur definition ##
+## 0.2.9 2009-10-13 automatic changeset management ##
+## ChangesetUpload implementation ##
+## 0.2.8 2009-10-13 *(Create|Update|Delete) use not unique _do method ##
+## 0.2.7 2009-10-09 implement all missing fonctions except ##
+## ChangesetsGet and GetCapabilities ##
+## 0.2.6 2009-10-09 encoding clean-up ##
+## 0.2.5 2009-10-09 implements NodesGet, WaysGet, RelationsGet ##
+## ParseOsm, ParseOsc ##
+## 0.2.4 2009-10-06 clean-up ##
+## 0.2.3 2009-09-09 keep http connection alive for multiple request ##
+## (Node|Way|Relation)Get return None when object ##
+## have been deleted (raising error before) ##
+## 0.2.2 2009-07-13 can identify applications built on top of the lib ##
+## 0.2.1 2009-05-05 some changes in constructor -- chove@crans.org ##
+## 0.2 2009-05-01 initial import ##
+###########################################################################
+
+__version__ = '0.2.19'
+
+import httplib, base64, xml.dom.minidom, time, sys, urllib
+
+class ApiError(Exception):
+
+ def __init__(self, status, reason, payload):
+ self.status = status
+ self.reason = reason
+ self.payload = payload
+
+ def __str__(self):
+ return "Request failed: " + str(self.status) + " - " + self.reason + " - " + self.payload
+
+###########################################################################
+## Main class ##
+
+class OsmApi:
+
+ def __init__(self,
+ username = None,
+ password = None,
+ passwordfile = None,
+ appid = "",
+ created_by = "PythonOsmApi/"+__version__,
+ api = "www.openstreetmap.org",
+ changesetauto = False,
+ changesetautotags = {},
+ changesetautosize = 500,
+ changesetautomulti = 1,
+ debug = False
+ ):
+
+ # debug
+ self._debug = debug
+
+ # Get username
+ if username:
+ self._username = username
+ elif passwordfile:
+ self._username = open(passwordfile).readline().split(":")[0].strip()
+
+ # Get password
+ if password:
+ self._password = password
+ elif passwordfile:
+ for l in open(passwordfile).readlines():
+ l = l.strip().split(":")
+ if l[0] == self._username:
+ self._password = l[1]
+
+ # Changest informations
+ self._changesetauto = changesetauto # auto create and close changesets
+ self._changesetautotags = changesetautotags # tags for automatic created changesets
+ self._changesetautosize = changesetautosize # change count for auto changeset
+ self._changesetautosize = changesetautosize # change count for auto changeset
+ self._changesetautomulti = changesetautomulti # close a changeset every # upload
+ self._changesetautocpt = 0
+ self._changesetautodata = [] # data to upload for auto group
+
+ # Get API
+ self._api = api
+
+ # Get created_by
+ if not appid:
+ self._created_by = created_by
+ else:
+ self._created_by = appid + " (" + created_by + ")"
+
+ # Initialisation
+ self._CurrentChangesetId = 0
+
+ # Http connection
+ self._conn = httplib.HTTPConnection(self._api, 80)
+
+ def __del__(self):
+ if self._changesetauto:
+ self._changesetautoflush(True)
+ return None
+
+ #######################################################################
+ # Capabilities #
+ #######################################################################
+
+ def Capabilities(self):
+ """ Returns ApiCapabilities. """
+ uri = "/api/capabilities"
+ data = self._get(uri)
+ data = xml.dom.minidom.parseString(data)
+ print data.getElementsByTagName("osm")
+ data = data.getElementsByTagName("osm")[0].getElementsByTagName("api")[0]
+ result = {}
+ for elem in data.childNodes:
+ if elem.nodeType <> elem.ELEMENT_NODE:
+ continue
+ result[elem.nodeName] = {}
+ print elem.nodeName
+ for k, v in elem.attributes.items():
+ try:
+ result[elem.nodeName][k] = float(v)
+ except:
+ result[elem.nodeName][k] = v
+ return result
+
+ #######################################################################
+ # Node #
+ #######################################################################
+
+ def NodeGet(self, NodeId, NodeVersion = -1):
+ """ Returns NodeData for node #NodeId. """
+ uri = "/api/0.6/node/"+str(NodeId)
+ if NodeVersion <> -1: uri += "/"+str(NodeVersion)
+ data = self._get(uri)
+ if not data: return data
+ data = xml.dom.minidom.parseString(data)
+ data = data.getElementsByTagName("osm")[0].getElementsByTagName("node")[0]
+ return self._DomParseNode(data)
+
+ def NodeCreate(self, NodeData):
+ """ Creates a node. Returns updated NodeData (without timestamp). """
+ return self._do("create", "node", NodeData)
+
+ def NodeUpdate(self, NodeData):
+ """ Updates node with NodeData. Returns updated NodeData (without timestamp). """
+ return self._do("modify", "node", NodeData)
+
+ def NodeDelete(self, NodeData):
+ """ Delete node with NodeData. Returns updated NodeData (without timestamp). """
+ return self._do("delete", "node", NodeData)
+
+ def NodeHistory(self, NodeId):
+ """ Returns dict(NodeVerrsion: NodeData). """
+ uri = "/api/0.6/node/"+str(NodeId)+"/history"
+ data = self._get(uri)
+ data = xml.dom.minidom.parseString(data)
+ result = {}
+ for data in data.getElementsByTagName("osm")[0].getElementsByTagName("node"):
+ data = self._DomParseNode(data)
+ result[data[u"version"]] = data
+ return result
+
+ def NodeWays(self, NodeId):
+ """ Returns [WayData, ... ] containing node #NodeId. """
+ uri = "/api/0.6/node/%d/ways"%NodeId
+ data = self._get(uri)
+ data = xml.dom.minidom.parseString(data)
+ result = []
+ for data in data.getElementsByTagName("osm")[0].getElementsByTagName("way"):
+ data = self._DomParseRelation(data)
+ result.append(data)
+ return result
+
+ def NodeRelations(self, NodeId):
+ """ Returns [RelationData, ... ] containing node #NodeId. """
+ uri = "/api/0.6/node/%d/relations"%NodeId
+ data = self._get(uri)
+ data = xml.dom.minidom.parseString(data)
+ result = []
+ for data in data.getElementsByTagName("osm")[0].getElementsByTagName("relation"):
+ data = self._DomParseRelation(data)
+ result.append(data)
+ return result
+
+ def NodesGet(self, NodeIdList):
+ """ Returns dict(NodeId: NodeData) for each node in NodeIdList """
+ uri = "/api/0.6/nodes?nodes=" + ",".join([str(x) for x in NodeIdList])
+ data = self._get(uri)
+ data = xml.dom.minidom.parseString(data)
+ result = {}
+ for data in data.getElementsByTagName("osm")[0].getElementsByTagName("node"):
+ data = self._DomParseNode(data)
+ result[data[u"id"]] = data
+ return result
+
+ #######################################################################
+ # Way #
+ #######################################################################
+
+ def WayGet(self, WayId, WayVersion = -1):
+ """ Returns WayData for way #WayId. """
+ uri = "/api/0.6/way/"+str(WayId)
+ if WayVersion <> -1: uri += "/"+str(WayVersion)
+ data = self._get(uri)
+ if not data: return data
+ data = xml.dom.minidom.parseString(data)
+ data = data.getElementsByTagName("osm")[0].getElementsByTagName("way")[0]
+ return self._DomParseWay(data)
+
+ def WayCreate(self, WayData):
+ """ Creates a way. Returns updated WayData (without timestamp). """
+ return self._do("create", "way", WayData)
+
+ def WayUpdate(self, WayData):
+ """ Updates way with WayData. Returns updated WayData (without timestamp). """
+ return self._do("modify", "way", WayData)
+
+ def WayDelete(self, WayData):
+ """ Delete way with WayData. Returns updated WayData (without timestamp). """
+ return self._do("delete", "way", WayData)
+
+ def WayHistory(self, WayId):
+ """ Returns dict(WayVerrsion: WayData). """
+ uri = "/api/0.6/way/"+str(WayId)+"/history"
+ data = self._get(uri)
+ data = xml.dom.minidom.parseString(data)
+ result = {}
+ for data in data.getElementsByTagName("osm")[0].getElementsByTagName("way"):
+ data = self._DomParseWay(data)
+ result[data[u"version"]] = data
+ return result
+
+ def WayRelations(self, WayId):
+ """ Returns [RelationData, ...] containing way #WayId. """
+ uri = "/api/0.6/way/%d/relations"%WayId
+ data = self._get(uri)
+ data = xml.dom.minidom.parseString(data)
+ result = []
+ for data in data.getElementsByTagName("osm")[0].getElementsByTagName("relation"):
+ data = self._DomParseRelation(data)
+ result.append(data)
+ return result
+
+ def WayFull(self, WayId):
+ """ Return full data for way WayId as list of {type: node|way|relation, data: {}}. """
+ uri = "/api/0.6/way/"+str(WayId)+"/full"
+ data = self._get(uri)
+ return self.ParseOsm(data)
+
+ def WaysGet(self, WayIdList):
+ """ Returns dict(WayId: WayData) for each way in WayIdList """
+ uri = "/api/0.6/ways?ways=" + ",".join([str(x) for x in WayIdList])
+ data = self._get(uri)
+ data = xml.dom.minidom.parseString(data)
+ result = {}
+ for data in data.getElementsByTagName("osm")[0].getElementsByTagName("way"):
+ data = self._DomParseWay(data)
+ result[data[u"id"]] = data
+ return result
+
+ #######################################################################
+ # Relation #
+ #######################################################################
+
+ def RelationGet(self, RelationId, RelationVersion = -1):
+ """ Returns RelationData for relation #RelationId. """
+ uri = "/api/0.6/relation/"+str(RelationId)
+ if RelationVersion <> -1: uri += "/"+str(RelationVersion)
+ data = self._get(uri)
+ if not data: return data
+ data = xml.dom.minidom.parseString(data)
+ data = data.getElementsByTagName("osm")[0].getElementsByTagName("relation")[0]
+ return self._DomParseRelation(data)
+
+ def RelationCreate(self, RelationData):
+ """ Creates a relation. Returns updated RelationData (without timestamp). """
+ return self._do("create", "relation", RelationData)
+
+ def RelationUpdate(self, RelationData):
+ """ Updates relation with RelationData. Returns updated RelationData (without timestamp). """
+ return self._do("modify", "relation", RelationData)
+
+ def RelationDelete(self, RelationData):
+ """ Delete relation with RelationData. Returns updated RelationData (without timestamp). """
+ return self._do("delete", "relation", RelationData)
+
+ def RelationHistory(self, RelationId):
+ """ Returns dict(RelationVerrsion: RelationData). """
+ uri = "/api/0.6/relation/"+str(RelationId)+"/history"
+ data = self._get(uri)
+ data = xml.dom.minidom.parseString(data)
+ result = {}
+ for data in data.getElementsByTagName("osm")[0].getElementsByTagName("relation"):
+ data = self._DomParseRelation(data)
+ result[data[u"version"]] = data
+ return result
+
+ def RelationRelations(self, RelationId):
+ """ Returns list of RelationData containing relation #RelationId. """
+ uri = "/api/0.6/relation/%d/relations"%RelationId
+ data = self._get(uri)
+ data = xml.dom.minidom.parseString(data)
+ result = []
+ for data in data.getElementsByTagName("osm")[0].getElementsByTagName("relation"):
+ data = self._DomParseRelation(data)
+ result.append(data)
+ return result
+
+ def RelationFullRecur(self, RelationId):
+ """ Return full data for relation RelationId. Recurisve version relation of relations. """
+ data = []
+ todo = [RelationId]
+ done = []
+ while todo:
+ rid = todo.pop(0)
+ done.append(rid)
+ temp = self.RelationFull(rid)
+ for item in temp:
+ if item["type"] <> "relation":
+ continue
+ if item["data"]["id"] in done:
+ continue
+ todo.append(item["data"]["id"])
+ data += temp
+ return data
+
+ def RelationFull(self, RelationId):
+ """ Return full data for relation RelationId as list of {type: node|way|relation, data: {}}. """
+ uri = "/api/0.6/relation/"+str(RelationId)+"/full"
+ data = self._get(uri)
+ return self.ParseOsm(data)
+
+ def RelationsGet(self, RelationIdList):
+ """ Returns dict(RelationId: RelationData) for each relation in RelationIdList """
+ uri = "/api/0.6/relations?relations=" + ",".join([str(x) for x in RelationIdList])
+ data = self._get(uri)
+ data = xml.dom.minidom.parseString(data)
+ result = {}
+ for data in data.getElementsByTagName("osm")[0].getElementsByTagName("relation"):
+ data = self._DomParseRelation(data)
+ result[data[u"id"]] = data
+ return result
+
+ #######################################################################
+ # Changeset #
+ #######################################################################
+
+ def ChangesetGet(self, ChangesetId):
+ """ Returns ChangesetData for changeset #ChangesetId. """
+ data = self._get("/api/0.6/changeset/"+str(ChangesetId))
+ data = xml.dom.minidom.parseString(data)
+ data = data.getElementsByTagName("osm")[0].getElementsByTagName("changeset")[0]
+ return self._DomParseChangeset(data)
+
+ def ChangesetUpdate(self, ChangesetTags = {}):
+ """ Updates current changeset with ChangesetTags. """
+ if self._CurrentChangesetId == -1:
+ raise Exception, "No changeset currently opened"
+ if u"created_by" not in ChangesetTags:
+ ChangesetTags[u"created_by"] = self._created_by
+ result = self._put("/api/0.6/changeset/"+str(self._CurrentChangesetId), self._XmlBuild("changeset", {u"tag": ChangesetTags}))
+ return self._CurrentChangesetId
+
+ def ChangesetCreate(self, ChangesetTags = {}):
+ """ Opens a changeset. Returns #ChangesetId. """
+ if self._CurrentChangesetId:
+ raise Exception, "Changeset alreadey opened"
+ if u"created_by" not in ChangesetTags:
+ ChangesetTags[u"created_by"] = self._created_by
+ result = self._put("/api/0.6/changeset/create", self._XmlBuild("changeset", {u"tag": ChangesetTags}))
+ self._CurrentChangesetId = int(result)
+ return self._CurrentChangesetId
+
+ def ChangesetClose(self):
+ """ Closes current changeset. Returns #ChangesetId. """
+ if not self._CurrentChangesetId:
+ raise Exception, "No changeset currently opened"
+ result = self._put("/api/0.6/changeset/"+str(self._CurrentChangesetId)+"/close", u"")
+ CurrentChangesetId = self._CurrentChangesetId
+ self._CurrentChangesetId = 0
+ return CurrentChangesetId
+
+ def ChangesetUpload(self, ChangesData):
+ """ Upload data. ChangesData is a list of dict {type: node|way|relation, action: create|delete|modify, data: {}}. Returns list with updated ids. """
+ data = ""
+ data += u"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ data += u"<osmChange version=\"0.6\" generator=\"" + self._created_by + "\">\n"
+ for change in ChangesData:
+ data += u"<"+change["action"]+">\n"
+ change["data"]["changeset"] = self._CurrentChangesetId
+ data += self._XmlBuild(change["type"], change["data"], False).decode("utf-8")
+ data += u"</"+change["action"]+">\n"
+ data += u"</osmChange>"
+ data = self._http("POST", "/api/0.6/changeset/"+str(self._CurrentChangesetId)+"/upload", True, data.encode("utf-8"))
+ data = xml.dom.minidom.parseString(data)
+ data = data.getElementsByTagName("diffResult")[0]
+ data = [x for x in data.childNodes if x.nodeType == x.ELEMENT_NODE]
+ for i in range(len(ChangesData)):
+ if ChangesData[i]["action"] == "delete":
+ ChangesData[i]["data"].pop("version")
+ else:
+ ChangesData[i]["data"]["version"] = int(data[i].getAttribute("new_id"))
+ return ChangesData
+
+ def ChangesetDownload(self, ChangesetId):
+ """ Download data from a changeset. Returns list of dict {type: node|way|relation, action: create|delete|modify, data: {}}. """
+ uri = "/api/0.6/changeset/"+str(ChangesetId)+"/download"
+ data = self._get(uri)
+ return self.ParseOsc(data)
+
+ def ChangesetsGet(self, min_lon=None, min_lat=None, max_lon=None, max_lat=None,
+ userid=None, username=None,
+ closed_after=None, created_before=None,
+ only_open=False, only_closed=False):
+ """ Returns dict(ChangsetId: ChangesetData) matching all criteria. """
+
+ uri = "/api/0.6/changesets"
+ params = {}
+ if min_lon or min_lat or max_lon or max_lat:
+ params["bbox"] = ",".join([str(min_lon),str(min_lat),str(max_lon),str(max_lat)])
+ if userid:
+ params["user"] = userid
+ if username:
+ params["display_name"] = username
+ if closed_after and not created_before:
+ params["time"] = closed_after
+ if created_before:
+ if not closed_after:
+ closed_after = "1970-01-01T00:00:00Z"
+ params["time"] = closed_after + "," + created_before
+ if only_open:
+ params["open"] = 1
+ if only_closed:
+ params["closed"] = 1
+
+ if params:
+ uri += "?" + urllib.urlencode(params)
+
+ data = self._get(uri)
+ data = xml.dom.minidom.parseString(data)
+ data = data.getElementsByTagName("osm")[0].getElementsByTagName("changeset")
+ result = {}
+ for curChangeset in data:
+ tmpCS = self._DomParseChangeset(curChangeset)
+ result[tmpCS["id"]] = tmpCS
+ return result
+
+ #######################################################################
+ # Other #
+ #######################################################################
+
+ def Map(self, min_lon, min_lat, max_lon, max_lat):
+ """ Download data in bounding box. Returns list of dict {type: node|way|relation, data: {}}. """
+ uri = "/api/0.6/map?bbox=%f,%f,%f,%f"%(min_lon, min_lat, max_lon, max_lat)
+ data = self._get(uri)
+ return self.ParseOsm(data)
+
+ #######################################################################
+ # Data parser #
+ #######################################################################
+
+ def ParseOsm(self, data):
+ """ Parse osm data. Returns list of dict {type: node|way|relation, data: {}}. """
+ data = xml.dom.minidom.parseString(data)
+ data = data.getElementsByTagName("osm")[0]
+ result = []
+ for elem in data.childNodes:
+ if elem.nodeName == u"node":
+ result.append({u"type": elem.nodeName, u"data": self._DomParseNode(elem)})
+ elif elem.nodeName == u"way":
+ result.append({u"type": elem.nodeName, u"data": self._DomParseWay(elem)})
+ elif elem.nodeName == u"relation":
+ result.append({u"type": elem.nodeName, u"data": self._DomParseRelation(elem)})
+ return result
+
+ def ParseOsc(self, data):
+ """ Parse osc data. Returns list of dict {type: node|way|relation, action: create|delete|modify, data: {}}. """
+ data = xml.dom.minidom.parseString(data)
+ data = data.getElementsByTagName("osmChange")[0]
+ result = []
+ for action in data.childNodes:
+ if action.nodeName == u"#text": continue
+ for elem in action.childNodes:
+ if elem.nodeName == u"node":
+ result.append({u"action":action.nodeName, u"type": elem.nodeName, u"data": self._DomParseNode(elem)})
+ elif elem.nodeName == u"way":
+ result.append({u"action":action.nodeName, u"type": elem.nodeName, u"data": self._DomParseWay(elem)})
+ elif elem.nodeName == u"relation":
+ result.append({u"action":action.nodeName, u"type": elem.nodeName, u"data": self._DomParseRelation(elem)})
+ return result
+
+ #######################################################################
+ # Internal http function #
+ #######################################################################
+
+ def _do(self, action, OsmType, OsmData):
+ if self._changesetauto:
+ self._changesetautodata.append({"action":action, "type":OsmType, "data":OsmData})
+ self._changesetautoflush()
+ return None
+ else:
+ return self._do_manu(action, OsmType, OsmData)
+
+ def _do_manu(self, action, OsmType, OsmData):
+ if not self._CurrentChangesetId:
+ raise Exception, "You need to open a changeset before uploading data"
+ if u"timestamp" in OsmData:
+ OsmData.pop(u"timestamp")
+ OsmData[u"changeset"] = self._CurrentChangesetId
+ if action == "create":
+ if OsmData.get(u"id", -1) > 0:
+ raise Exception, "This "+OsmType+" already exists"
+ result = self._put("/api/0.6/"+OsmType+"/create", self._XmlBuild(OsmType, OsmData))
+ OsmData[u"id"] = int(result.strip())
+ OsmData[u"version"] = 1
+ return OsmData
+ elif action == "modify":
+ result = self._put("/api/0.6/"+OsmType+"/"+str(OsmData[u"id"]), self._XmlBuild(OsmType, OsmData))
+ OsmData[u"version"] = int(result.strip())
+ return OsmData
+ elif action =="delete":
+ result = self._delete("/api/0.6/"+OsmType+"/"+str(OsmData[u"id"]), self._XmlBuild(OsmType, OsmData))
+ OsmData[u"version"] = int(result.strip())
+ OsmData[u"visible"] = False
+ return OsmData
+
+ def flush(self):
+ return self._changesetautoflush(True)
+
+ def _changesetautoflush(self, force = False):
+ while (len(self._changesetautodata) >= self._changesetautosize) or (force and self._changesetautodata):
+ if self._changesetautocpt == 0:
+ self.ChangesetCreate(self._changesetautotags)
+ self.ChangesetUpload(self._changesetautodata[:self._changesetautosize])
+ self._changesetautodata = self._changesetautodata[self._changesetautosize:]
+ self._changesetautocpt += 1
+ if self._changesetautocpt == self._changesetautomulti:
+ self.ChangesetClose()
+ self._changesetautocpt = 0
+ if self._changesetautocpt and force:
+ self.ChangesetClose()
+ self._changesetautocpt = 0
+ return None
+
+ def _http_request(self, cmd, path, auth, send):
+ if self._debug:
+ path2 = path
+ if len(path2) > 50:
+ path2 = path2[:50]+"[...]"
+ print >>sys.stderr, "%s %s %s"%(time.strftime("%Y-%m-%d %H:%M:%S"),cmd,path2)
+ self._conn.putrequest(cmd, path)
+ self._conn.putheader('User-Agent', self._created_by)
+ if auth:
+ self._conn.putheader('Authorization', 'Basic ' + base64.encodestring(self._username + ':' + self._password).strip())
+ if send <> None:
+ self._conn.putheader('Content-Length', len(send))
+ self._conn.endheaders()
+ if send:
+ self._conn.send(send)
+ response = self._conn.getresponse()
+ if response.status <> 200:
+ payload = response.read().strip()
+ if response.status == 410:
+ return None
+ raise ApiError(response.status, response.reason, payload)
+ if self._debug:
+ print >>sys.stderr, "%s %s %s done"%(time.strftime("%Y-%m-%d %H:%M:%S"),cmd,path2)
+ return response.read()
+
+ def _http(self, cmd, path, auth, send):
+ i = 0
+ while True:
+ i += 1
+ try:
+ return self._http_request(cmd, path, auth, send)
+ except ApiError, e:
+ if e.status >= 500:
+ if i == 5: raise
+ if i <> 1: time.sleep(5)
+ self._conn = httplib.HTTPConnection(self._api, 80)
+ else: raise
+ except Exception:
+ if i == 5: raise
+ if i <> 1: time.sleep(5)
+ self._conn = httplib.HTTPConnection(self._api, 80)
+
+ def _get(self, path):
+ return self._http('GET', path, False, None)
+
+ def _put(self, path, data):
+ return self._http('PUT', path, True, data)
+
+ def _delete(self, path, data):
+ return self._http('DELETE', path, True, data)
+
+ #######################################################################
+ # Internal dom function #
+ #######################################################################
+
+ def _DomGetAttributes(self, DomElement):
+ """ Returns a formated dictionnary of attributes of a DomElement. """
+ result = {}
+ for k, v in DomElement.attributes.items():
+ if k == u"uid" : v = int(v)
+ elif k == u"changeset" : v = int(v)
+ elif k == u"version" : v = int(v)
+ elif k == u"id" : v = int(v)
+ elif k == u"lat" : v = float(v)
+ elif k == u"lon" : v = float(v)
+ elif k == u"open" : v = v=="true"
+ elif k == u"visible" : v = v=="true"
+ elif k == u"ref" : v = int(v)
+ result[k] = v
+ return result
+
+ def _DomGetTag(self, DomElement):
+ """ Returns the dictionnary of tags of a DomElement. """
+ result = {}
+ for t in DomElement.getElementsByTagName("tag"):
+ k = t.attributes["k"].value
+ v = t.attributes["v"].value
+ result[k] = v
+ return result
+
+ def _DomGetNd(self, DomElement):
+ """ Returns the list of nodes of a DomElement. """
+ result = []
+ for t in DomElement.getElementsByTagName("nd"):
+ result.append(int(int(t.attributes["ref"].value)))
+ return result
+
+ def _DomGetMember(self, DomElement):
+ """ Returns a list of relation members. """
+ result = []
+ for m in DomElement.getElementsByTagName("member"):
+ result.append(self._DomGetAttributes(m))
+ return result
+
+ def _DomParseNode(self, DomElement):
+ """ Returns NodeData for the node. """
+ result = self._DomGetAttributes(DomElement)
+ result[u"tag"] = self._DomGetTag(DomElement)
+ return result
+
+ def _DomParseWay(self, DomElement):
+ """ Returns WayData for the way. """
+ result = self._DomGetAttributes(DomElement)
+ result[u"tag"] = self._DomGetTag(DomElement)
+ result[u"nd"] = self._DomGetNd(DomElement)
+ return result
+
+ def _DomParseRelation(self, DomElement):
+ """ Returns RelationData for the relation. """
+ result = self._DomGetAttributes(DomElement)
+ result[u"tag"] = self._DomGetTag(DomElement)
+ result[u"member"] = self._DomGetMember(DomElement)
+ return result
+
+ def _DomParseChangeset(self, DomElement):
+ """ Returns ChangesetData for the changeset. """
+ result = self._DomGetAttributes(DomElement)
+ result[u"tag"] = self._DomGetTag(DomElement)
+ return result
+
+ #######################################################################
+ # Internal xml builder #
+ #######################################################################
+
+ def _XmlBuild(self, ElementType, ElementData, WithHeaders = True):
+
+ xml = u""
+ if WithHeaders:
+ xml += u"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ xml += u"<osm version=\"0.6\" generator=\"" + self._created_by + "\">\n"
+
+ # <element attr="val">
+ xml += u" <" + ElementType
+ if u"id" in ElementData:
+ xml += u" id=\"" + str(ElementData[u"id"]) + u"\""
+ if u"lat" in ElementData:
+ xml += u" lat=\"" + str(ElementData[u"lat"]) + u"\""
+ if u"lon" in ElementData:
+ xml += u" lon=\"" + str(ElementData[u"lon"]) + u"\""
+ if u"version" in ElementData:
+ xml += u" version=\"" + str(ElementData[u"version"]) + u"\""
+ xml += u" visible=\"" + str(ElementData.get(u"visible", True)).lower() + u"\""
+ if ElementType in [u"node", u"way", u"relation"]:
+ xml += u" changeset=\"" + str(self._CurrentChangesetId) + u"\""
+ xml += u">\n"
+
+ # <tag... />
+ for k, v in ElementData.get(u"tag", {}).items():
+ xml += u" <tag k=\""+self._XmlEncode(k)+u"\" v=\""+self._XmlEncode(v)+u"\"/>\n"
+
+ # <member... />
+ for member in ElementData.get(u"member", []):
+ xml += u" <member type=\""+member[u"type"]+"\" ref=\""+str(member[u"ref"])+u"\" role=\""+self._XmlEncode(member[u"role"])+"\"/>\n"
+
+ # <nd... />
+ for ref in ElementData.get(u"nd", []):
+ xml += u" <nd ref=\""+str(ref)+u"\"/>\n"
+
+ # </element>
+ xml += u" </" + ElementType + u">\n"
+
+ if WithHeaders:
+ xml += u"</osm>\n"
+
+ return xml.encode("utf8")
+
+ def _XmlEncode(self, text):
+ return text.replace("&", "&amp;").replace("\"", "&quot;").replace("<","&lt;").replace(">","&gt;")
+
+## End of main class ##
+###########################################################################
diff --git a/chimere/external_utils/__init__.py b/chimere/external_utils/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/chimere/external_utils/__init__.py
diff --git a/chimere/fixtures/auth_group.json b/chimere/fixtures/auth_group.json
new file mode 100644
index 0000000..e04291c
--- /dev/null
+++ b/chimere/fixtures/auth_group.json
@@ -0,0 +1,46 @@
+[
+ {
+ "pk": 1,
+ "model": "auth.group",
+ "fields": {
+ "name": "Application administrator",
+ "permissions": [
+ 67,
+ 68,
+ 40,
+ 41,
+ 42,
+ 37,
+ 38,
+ 39,
+ 34,
+ 35,
+ 36,
+ 43,
+ 44,
+ 45,
+ 49,
+ 50,
+ 51,
+ 55,
+ 56,
+ 57,
+ 28,
+ 29,
+ 30,
+ 58,
+ 59,
+ 60,
+ 64,
+ 65,
+ 66,
+ 61,
+ 62,
+ 63,
+ 46,
+ 47,
+ 48
+ ]
+ }
+ }
+]
diff --git a/chimere/fixtures/initial_data.json b/chimere/fixtures/initial_data.json
index 222c81c..c44eb63 100644
--- a/chimere/fixtures/initial_data.json
+++ b/chimere/fixtures/initial_data.json
@@ -221,49 +221,5 @@
"layer_code": "new OpenLayers.Layer.MapQuestOSM()",
"name": "OSM - MapQuest"
}
- },
- {
- "pk": 1,
- "model": "auth.group",
- "fields": {
- "name": "Application administrator",
- "permissions": [
- 67,
- 68,
- 40,
- 41,
- 42,
- 37,
- 38,
- 39,
- 34,
- 35,
- 36,
- 43,
- 44,
- 45,
- 49,
- 50,
- 51,
- 55,
- 56,
- 57,
- 28,
- 29,
- 30,
- 58,
- 59,
- 60,
- 64,
- 65,
- 66,
- 61,
- 62,
- 63,
- 46,
- 47,
- 48
- ]
- }
}
]
diff --git a/chimere/fixtures/layers-geobretagne.json b/chimere/fixtures/layers-geobretagne.json
new file mode 100644
index 0000000..b5a406e
--- /dev/null
+++ b/chimere/fixtures/layers-geobretagne.json
@@ -0,0 +1,74 @@
+[
+ {
+ "pk": null,
+ "model": "chimere.layer",
+ "fields": {
+ "layer_code": "new OpenLayers.Layer.WMS(\r\n \"Cassini - G\u00e9obretagne\", \"http://geobretagne.fr/wmsouvert\",\r\n { layers: 'cassini', format: 'image/png', transparent:\r\nfalse},\r\n {\r\n attribution: \"Collection David Rumsey\",\r\n visibility: false,\r\n numZoomLevels:19,\r\n projection: new OpenLayers.Projection(\"EPSG:900913\"),\r\n displayProjection: new OpenLayers.Projection(\"EPSG:4326\"),\r\n}\r\n)\r\n",
+ "name": "Cassini - G\u00e9obretagne"
+ }
+ },
+ {
+ "pk": null,
+ "model": "chimere.layer",
+ "fields": {
+ "layer_code": "new OpenLayers.Layer.WMS(\r\n \"Orthophotographie 2010 BMO - G\u00e9obretagne\", \"http://geobretagne.fr/wmsouvert\",\r\n { layers: 'ortho-bmo-2010', format: 'image/png', transparent:\r\nfalse},\r\n {\r\n attribution: \"Brest Metropole Oceane - SIG - juin 2010\",\r\n visibility: false,\r\n numZoomLevels:19,\r\n projection: new OpenLayers.Projection(\"EPSG:900913\"),\r\n displayProjection: new OpenLayers.Projection(\"EPSG:4326\"),\r\n}\r\n)\r\n",
+ "name": "Orthophotographie 2010 BMO - G\u00e9obretagne"
+ }
+ },
+ {
+ "pk": null,
+ "model": "chimere.layer",
+ "fields": {
+ "layer_code": "new OpenLayers.Layer.WMS(\r\n \"Orthophotographie 2010 Lannion Tregor - G\u00e9obretagne\", \"http://geobretagne.fr/wmsouvert\",\r\n { layers: 'ortho-lanniontregor', format: 'image/png', transparent:\r\nfalse},\r\n {\r\n attribution: \"Lannion Tregor agglomeration\",\r\n visibility: false,\r\n numZoomLevels:19,\r\n projection: new OpenLayers.Projection(\"EPSG:900913\"),\r\n displayProjection: new OpenLayers.Projection(\"EPSG:4326\"),\r\n}\r\n)\r\n",
+ "name": "Orthophotographie 2010 Lannion Tregor - G\u00e9obretagne"
+ }
+ },
+ {
+ "pk": null,
+ "model": "chimere.layer",
+ "fields": {
+ "layer_code": "new OpenLayers.Layer.WMS(\r\n \"Orthophotographie 2011 Rennes Metropole - G\u00e9obretagne\", \"http://geobretagne.fr/wmsouvert\",\r\n { layers: 'ortho-rennesmetropole', format: 'image/png', transparent:\r\nfalse},\r\n {\r\n attribution: \"Rennes Métropole\",\r\n visibility: false,\r\n numZoomLevels:19,\r\n projection: new OpenLayers.Projection(\"EPSG:900913\"),\r\n displayProjection: new OpenLayers.Projection(\"EPSG:4326\"),\r\n}\r\n)\r\n",
+ "name": "Orthophotographie 2011 Rennes Metropole - G\u00e9obretagne"
+ }
+ },
+ {
+ "pk": null,
+ "model": "chimere.layer",
+ "fields": {
+ "layer_code": "new OpenLayers.Layer.WMS(\r\n \"Orthophotographie 2004 BMO - G\u00e9obretagne\", \"http://geobretagne.fr/wmsouvert\",\r\n { layers: 'ortho-bmo-2004', format: 'image/png', transparent:\r\nfalse},\r\n {\r\n attribution: \"Brest Metropole Oceane - SIG - Sept. 2004\",\r\n visibility: false,\r\n numZoomLevels:19,\r\n projection: new OpenLayers.Projection(\"EPSG:900913\"),\r\n displayProjection: new OpenLayers.Projection(\"EPSG:4326\"),\r\n}\r\n)\r\n",
+ "name": "Orthophotographie 2004 BMO - G\u00e9obretagne"
+ }
+ },
+ {
+ "pk": null,
+ "model": "chimere.layer",
+ "fields": {
+ "layer_code": "new OpenLayers.Layer.WMS(\r\n \"Orthophotographie 2005 Cap l'Orient - G\u00e9obretagne\", \"http://geobretagne.fr/wmsouvert\",\r\n { layers: 'ortho-caplorient', format: 'image/png', transparent:\r\nfalse},\r\n {\r\n attribution: \"Cap l'Orient 2005\",\r\n visibility: false,\r\n numZoomLevels:19,\r\n projection: new OpenLayers.Projection(\"EPSG:900913\"),\r\n displayProjection: new OpenLayers.Projection(\"EPSG:4326\"),\r\n}\r\n)\r\n",
+ "name": "Orthophotographie 2005 Cap l'Orient - G\u00e9obretagne"
+ }
+ },
+ {
+ "pk": null,
+ "model": "chimere.layer",
+ "fields": {
+ "layer_code": "new OpenLayers.Layer.WMS(\r\n \"Orthophotographie 2008 Quimper Communauté - G\u00e9obretagne\", \"http://geobretagne.fr/wmsouvert\",\r\n { layers: 'ortho-quimpercommunaute', format: 'image/png', transparent:\r\nfalse},\r\n {\r\n attribution: \"Quimper Communauté 2008\",\r\n visibility: false,\r\n numZoomLevels:19,\r\n projection: new OpenLayers.Projection(\"EPSG:900913\"),\r\n displayProjection: new OpenLayers.Projection(\"EPSG:4326\"),\r\n}\r\n)\r\n",
+ "name": "Orthophotographie 2008 Quimper Communauté - G\u00e9obretagne"
+ }
+ },
+ {
+ "pk": null,
+ "model": "chimere.layer",
+ "fields": {
+ "layer_code": "new OpenLayers.Layer.WMS(\r\n \"Orthophotographie 2010 Morbihan - G\u00e9obretagne\", \"http://geobretagne.fr/wmsouvert\",\r\n { layers: 'ortho-megalis-56', format: 'image/png', transparent:\r\nfalse},\r\n {\r\n attribution: \"e-Megalis - Mars 2010\",\r\n visibility: false,\r\n numZoomLevels:19,\r\n projection: new OpenLayers.Projection(\"EPSG:900913\"),\r\n displayProjection: new OpenLayers.Projection(\"EPSG:4326\"),\r\n}\r\n)\r\n",
+ "name": "Orthophotographie 2010 Morbihan - G\u00e9obretagne"
+ }
+ },
+ {
+ "pk": null,
+ "model": "chimere.layer",
+ "fields": {
+ "layer_code": "new OpenLayers.Layer.WMS(\r\n \"Orthophotographie infrarouge 2010 Morbihan - G\u00e9obretagne\", \"http://geobretagne.fr/wmsouvert\",\r\n { layers: 'ir-megalis-56', format: 'image/png', transparent:\r\nfalse},\r\n {\r\n attribution: \"e-Megalis - Mars 2010\",\r\n visibility: false,\r\n numZoomLevels:19,\r\n projection: new OpenLayers.Projection(\"EPSG:900913\"),\r\n displayProjection: new OpenLayers.Projection(\"EPSG:4326\"),\r\n}\r\n)\r\n",
+ "name": "Orthophotographie infrarouge 2010 Morbihan - G\u00e9obretagne"
+ }
+ }
+]
diff --git a/chimere/fixtures/layers-opencyclemap.json b/chimere/fixtures/layers-opencyclemap.json
new file mode 100644
index 0000000..5f3ef47
--- /dev/null
+++ b/chimere/fixtures/layers-opencyclemap.json
@@ -0,0 +1,26 @@
+[
+ {
+ "pk": null,
+ "model": "chimere.layer",
+ "fields": {
+ "layer_code": "new OpenLayers.Layer.OSM(\"OpenCycleMap - Cycle\", [\r\n 'http://a.tile.opencyclemap.org/cycle/${z}/${x}/${y}.png',\r\n 'http://b.tile.opencyclemap.org/cycle/${z}/${x}/${y}.png',\r\n 'http://c.tile.opencyclemap.org/cycle/${z}/${x}/${y}.png'],\r\n{attribution:\"Tiles courtesy of <a href='http://www.opencyclemap.org/' target='_blank'>Andy Allan</a>\"})",
+ "name": "OpenCycleMap - Cycle"
+ }
+ },
+ {
+ "pk": null,
+ "model": "chimere.layer",
+ "fields": {
+ "layer_code": "new OpenLayers.Layer.OSM(\"OpenCycleMap - Transport\", [\r\n 'http://a.tile2.opencyclemap.org/transport/${z}/${x}/${y}.png',\r\n 'http://b.tile2.opencyclemap.org/transport/${z}/${x}/${y}.png',\r\n 'http://c.tile2.opencyclemap.org/transport/${z}/${x}/${y}.png'],\r\n{attribution:\"Tiles courtesy of <a href='http://www.opencyclemap.org/' target='_blank'>Andy Allan</a>\"})",
+ "name": "OpenCycleMap - Transport"
+ }
+ },
+ {
+ "pk": null,
+ "model": "chimere.layer",
+ "fields": {
+ "layer_code": "new OpenLayers.Layer.OSM(\"OpenCycleMap - Landscape\", [\r\n 'http://a.tile3.opencyclemap.org/landscape/${z}/${x}/${y}.png',\r\n 'http://b.tile3.opencyclemap.org/landscape/${z}/${x}/${y}.png',\r\n 'http://c.tile3.opencyclemap.org/landscape/${z}/${x}/${y}.png'],\r\n{attribution:\"Tiles courtesy of <a href='http://www.opencyclemap.org/' target='_blank'>Andy Allan</a>\"})",
+ "name": "OpenCycleMap - Landscape"
+ }
+ }
+]
diff --git a/chimere/forms.py b/chimere/forms.py
index 1d403c8..22cdc8f 100644
--- a/chimere/forms.py
+++ b/chimere/forms.py
@@ -139,6 +139,8 @@ class ImporterAdminForm(forms.ModelForm):
filtr = forms.CharField(widget=ImportFiltrWidget, required=False)
importer_type = forms.ChoiceField(widget=ImporterChoicesWidget,
choices=[('', '--')]+list(IMPORTER_CHOICES))
+ default_description = forms.CharField(widget=TextareaAdminWidget,
+ required=False)
class Meta:
model = Importer
widgets = {
diff --git a/chimere/locale/fr/LC_MESSAGES/django.po b/chimere/locale/fr/LC_MESSAGES/django.po
index d15aa9a..9cdf92a 100644
--- a/chimere/locale/fr/LC_MESSAGES/django.po
+++ b/chimere/locale/fr/LC_MESSAGES/django.po
@@ -1,5 +1,5 @@
# Chimère
-# Copyright (C) 2008-2012
+# Copyright (C) 2008-2013
# This file is distributed under the same license as the Chimère package.
# Étienne Loks <etienne.loks@peacefrogs.net>, 2008-2011.
#
@@ -7,21 +7,13 @@ msgid ""
msgstr ""
"Project-Id-Version: 0.2\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2012-12-13 15:52+0100\n"
+"POT-Creation-Date: 2013-03-14 18:43+0100\n"
"PO-Revision-Date: 2010-03-20 20:00+0100\n"
"Last-Translator: Étienne Loks <etienne.loks@peacefrogs.net>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: __init__.py:8 models.py:768
-msgid "Multimedia files"
-msgstr "Fichiers multimedias"
-
-#: __init__.py:9 models.py:840
-msgid "Picture files"
-msgstr "Fichiers d'image"
-
#: actions.py:39
msgid "View"
msgstr "Voir"
@@ -67,73 +59,73 @@ msgstr "Exporter en Shapefile"
msgid "Export to CSV"
msgstr "Exporter en CSV"
-#: admin.py:101
+#: admin.py:102
msgid "Only one item can be managed at a time."
msgstr "Seul un élément à la fois peut-être géré."
-#: admin.py:110
+#: admin.py:112
msgid "No modified item associated to the selected item."
msgstr "Pas d'élément modifié associé à l'élément sélectionné."
-#: admin.py:156
+#: admin.py:158
msgid "Modified item traited."
msgstr "Élément modifié traité."
-#: admin.py:161
+#: admin.py:163
msgid "Managed modified items"
msgstr "Gérer les éléments modifiés"
-#: admin.py:195 admin.py:270
+#: admin.py:197 admin.py:274
msgid "Submitter"
msgstr "Demandeur"
-#: admin.py:200 admin.py:275 admin.py:326
+#: admin.py:202 admin.py:279 admin.py:331
msgid "Import"
msgstr "Import"
-#: admin.py:205 admin.py:280
+#: admin.py:207 admin.py:284
msgid "Associated items"
msgstr "Éléments associés"
-#: admin.py:332
+#: admin.py:337
msgid "Cancel import"
msgstr "Annuler l'import"
-#: admin.py:338
+#: admin.py:343
msgid "Cancel export"
msgstr "Annuler l'export"
-#: admin.py:342
+#: admin.py:347
msgid "Can manage only one OSM export at a time."
msgstr "Ne peux gérer qu'un seul export OSM à la fois."
-#: admin.py:347
+#: admin.py:352
msgid ""
"You must treat all item with the status \"imported\" before exporting to OSM."
msgstr ""
"Vous devez traiter tous les éléments avec le status « importé » avant "
"d'exporter vers OSM."
-#: admin.py:351
+#: admin.py:356
msgid "Only OSM importer are managed for export."
msgstr "Seul les imports de type OSM peuvent être gérés pour les exports."
-#: admin.py:358
+#: admin.py:363
msgid "No point of interest are concerned by this export."
msgstr "Aucun point d'intérêt n'est concerné par cet export."
-#: admin.py:370
+#: admin.py:375
msgid "Export launched."
msgstr "Export lancé."
-#: admin.py:374
+#: admin.py:379
#, python-format
msgid ""
"%s point(s) of interest concerned by this export before bounding box filter."
msgstr ""
"%s point(s) d'intérêt concerné par cet export (avant le filtre sur la zone)"
-#: admin.py:379
+#: admin.py:384
msgid "Export to osm"
msgstr "Exporter vers osm"
@@ -174,7 +166,7 @@ msgstr "Objet"
msgid "OSM user"
msgstr "Utilisateur OSM"
-#: forms.py:118 models.py:1457
+#: forms.py:118 models.py:1500
msgid "Password"
msgstr "Mot de passe"
@@ -192,7 +184,7 @@ msgstr "API de test - %s"
msgid "Main API - %s"
msgstr "API principale - %s"
-#: forms.py:156 forms.py:160
+#: forms.py:158 forms.py:162
msgid ""
"For OSM import you must be provide a filter. Select an area and node/way "
"filter."
@@ -200,73 +192,73 @@ msgstr ""
"Pour les imports OSM vous devez fournir un filtre. Sélectionnez une zone et "
"un filtre sur les nœuds/routes."
-#: forms.py:164
+#: forms.py:166
msgid "Shapefiles must be provided in a zipped archive."
msgstr ""
"Les fichiers Shapefiles doivent être fournis regroupés dans une archive zip."
-#: forms.py:168
+#: forms.py:170
msgid "You have to set \"source\" or \"source file\" but not both."
msgstr ""
"Vous devez spécifier le champ « Source » ou « Fichier source » mais pas les "
"deux."
-#: forms.py:173
+#: forms.py:175
msgid "You have to set \"source\" or \"source file\"."
msgstr "Vous devez spécifier le champ « Source » ou « Fichier source »."
-#: forms.py:234
+#: forms.py:236
msgid "End date has been set with no start date"
msgstr "Une date de fin a été donnée sans date de début"
-#: forms.py:238
+#: forms.py:240
msgid "End date can't be before start date"
msgstr "La date de fin ne peut pas être antérieure à la date de début"
-#: forms.py:248
+#: forms.py:250
msgid "This field is mandatory for the selected categories"
msgstr "Ce champ est obligatoire pour les catégories sélectionnées"
-#: forms.py:499
+#: forms.py:501
msgid "File"
msgstr "Fichier"
-#: forms.py:505
+#: forms.py:507
msgid "Bad file format: this must be a GPX or KML file"
msgstr "Mauvais format de fichier : KML et GPX sont supportés"
-#: forms.py:510 models.py:53 models.py:101 models.py:163 models.py:184
-#: models.py:197 models.py:212 models.py:364 models.py:702 models.py:758
-#: models.py:817 models.py:933 models.py:1262 models.py:1274 models.py:1447
-#: utils.py:470 templates/admin/chimere/managed_modified.html:23
-#: templates/chimere/edit.html:39 templates/chimere/edit_route.html:36
+#: forms.py:512 models.py:53 models.py:101 models.py:163 models.py:184
+#: models.py:197 models.py:212 models.py:375 models.py:720 models.py:776
+#: models.py:835 models.py:953 models.py:1304 models.py:1316 models.py:1490
+#: utils.py:485 templates/admin/chimere/managed_modified.html:23
+#: templates/chimere/edit.html:40 templates/chimere/edit_route.html:37
#: templates/chimere/blocks/alternate_multimedia.html:39
msgid "Name"
msgstr "Nom"
-#: forms.py:519 models.py:1311
+#: forms.py:521 models.py:1353
msgid "Area"
msgstr "Zone"
-#: forms.py:559
+#: forms.py:561
msgid "No area selected."
msgstr "Pas de zone sélectionnée."
-#: forms.py:566
+#: forms.py:568
#, python-format
msgid "The area \"%s\" has the same order, you need to choose another one."
msgstr ""
"La zone « %s » a le même numéro d'ordre, vous devez un choisir un autre."
-#: forms.py:611
+#: forms.py:613
msgid "Start"
msgstr "Départ"
-#: forms.py:612
+#: forms.py:614
msgid "Finish"
msgstr "Arrivée"
-#: forms.py:613
+#: forms.py:615
msgid "Speed"
msgstr "Vitesse"
@@ -274,13 +266,13 @@ msgstr "Vitesse"
msgid "Mnemonic"
msgstr "Mnémonique"
-#: models.py:56 models.py:102 models.py:185 models.py:213 models.py:375
-#: models.py:706 models.py:1280 models.py:1449 models.py:1490
+#: models.py:56 models.py:102 models.py:185 models.py:213 models.py:368
+#: models.py:724 models.py:1322 models.py:1492 models.py:1533
msgid "Available"
msgstr "Disponible"
-#: models.py:57 models.py:173 models.py:186 models.py:230 models.py:760
-#: models.py:832 models.py:1279 models.py:1436 models.py:1448
+#: models.py:57 models.py:173 models.py:186 models.py:230 models.py:778
+#: models.py:850 models.py:1321 models.py:1479 models.py:1491
msgid "Order"
msgstr "Ordre"
@@ -292,15 +284,15 @@ msgstr "Chemin du patron"
msgid "Page"
msgstr "Page"
-#: models.py:103 models.py:457
+#: models.py:103 models.py:469
msgid "Is front page"
msgstr "Est en page principale"
-#: models.py:105 models.py:1458
+#: models.py:105 models.py:1501
msgid "Date"
msgstr "Date"
-#: models.py:107 models.py:759
+#: models.py:107 models.py:777
msgid "Url"
msgstr "Url"
@@ -337,16 +329,16 @@ msgstr "Couleur"
msgid "Category"
msgstr "Catégorie"
-#: models.py:198 models.py:698 models.py:818 models.py:999
+#: models.py:198 models.py:716 models.py:836 models.py:1019
#: templates/chimere/blocks/alternate_multimedia.html:43
msgid "Image"
msgstr "Image"
-#: models.py:200 models.py:820 models.py:1001
+#: models.py:200 models.py:838 models.py:1021
msgid "Height"
msgstr "Hauteur"
-#: models.py:201 models.py:821 models.py:1002
+#: models.py:201 models.py:839 models.py:1022
msgid "Width"
msgstr "Largeur"
@@ -362,8 +354,8 @@ msgstr "Disponible pour soumission"
msgid "Marker"
msgstr "Point d'intérêt"
-#: models.py:217 models.py:995 models.py:1012
-#: templates/chimere/edit_route.html:27
+#: models.py:217 models.py:1015 models.py:1032
+#: templates/chimere/edit_route.html:28
msgid "Route"
msgstr "Trajet"
@@ -431,283 +423,299 @@ msgstr "Fichier zippé"
msgid "Overwrite existing data"
msgstr "Écraser les données existantes"
-#: models.py:334 models.py:391
+#: models.py:334
+msgid "Get description from source"
+msgstr "Obtenir une description depuis la source"
+
+#: models.py:336
+msgid "Default description"
+msgstr "Description par défaut"
+
+#: models.py:338 models.py:396
msgid "Origin"
msgstr "Origine"
-#: models.py:336 models.py:393
+#: models.py:340 models.py:398
msgid "License"
msgstr "Licence"
-#: models.py:339
+#: models.py:343
msgid "Associated subcategories"
msgstr "Sous-catégories associées"
-#: models.py:340 utils.py:474
+#: models.py:344 utils.py:489
msgid "State"
msgstr "État"
-#: models.py:342
+#: models.py:346
msgid "Automatically associate a marker to a way"
msgstr "Associer automatiquement un marqueur à une route"
-#: models.py:346
+#: models.py:350
msgid "Importer"
msgstr "Import"
-#: models.py:366
-msgid "Submitter session key"
-msgstr "Clé de session du demandeur"
-
-#: models.py:368
-msgid "Submitter name or nickname"
-msgstr "Nom ou pseudo du demandeur"
-
-#: models.py:370
-msgid "Submitter email"
-msgstr "Courriel du demandeur"
-
-#: models.py:372
-msgid "Submitter comment"
-msgstr "Commentaire du demandeur"
-
-#: models.py:374
+#: models.py:367
msgid "Submited"
msgstr "Soumis"
-#: models.py:376
+#: models.py:369
msgid "Modified"
msgstr "Modifié"
-#: models.py:377
+#: models.py:370
msgid "Disabled"
msgstr "Désactivé"
-#: models.py:378
+#: models.py:371
msgid "Imported"
msgstr "Importé"
-#: models.py:380
+#: models.py:377
+msgid "Submitter session key"
+msgstr "Clé de session du demandeur"
+
+#: models.py:379
+msgid "Submitter name or nickname"
+msgstr "Nom ou pseudo du demandeur"
+
+#: models.py:381
+msgid "Submitter email"
+msgstr "Courriel du demandeur"
+
+#: models.py:383
+msgid "Submitter comment"
+msgstr "Commentaire du demandeur"
+
+#: models.py:385 models.py:1195
msgid "Status"
msgstr "État"
-#: models.py:381
+#: models.py:386
msgid "Import key"
msgstr "Clé d'import"
-#: models.py:383
+#: models.py:388
msgid "Import version"
msgstr "Version de l'import"
-#: models.py:385
+#: models.py:390
msgid "Source"
msgstr "Source"
-#: models.py:387
+#: models.py:392
msgid "Modified since last import"
msgstr "Modifié depuis le dernier import"
-#: models.py:389
+#: models.py:394
msgid "Not to be exported to OSM"
msgstr "À ne pas exporter vers OSM"
-#: models.py:395 templates/chimere/edit.html:56
-#: templates/chimere/edit_route.html:52
+#: models.py:400 templates/chimere/edit.html:57
+#: templates/chimere/edit_route.html:53
msgid "Start date"
msgstr "Date de début"
-#: models.py:396
+#: models.py:401
msgid "Not mandatory. Set it for dated item such as event. Format YYYY-MM-DD"
msgstr ""
"Optionnel. Précisez ce champ pour les éléments datés comme un événement. "
"Format du champ : AAAA-MM-JJ"
-#: models.py:398 templates/chimere/edit.html:62
-#: templates/chimere/edit_route.html:58
+#: models.py:403 templates/chimere/edit.html:63
+#: templates/chimere/edit_route.html:59
msgid "End date"
msgstr "Date de fin"
-#: models.py:399
+#: models.py:404
msgid ""
"Not mandatory. Set it only if you have a multi-day event. Format YYYY-MM-DD"
msgstr ""
"Optionnel. Précisez ce champ seulement pour des événements durant plusieurs "
"jours. Format du champ : AAAA-MM-JJ"
-#: models.py:449
+#: models.py:461
msgid "Reference marker"
msgstr "Point d'intérêt de référence"
-#: models.py:450 utils.py:476
+#: models.py:462 utils.py:491
msgid "Localisation"
msgstr "Localisation"
-#: models.py:452
+#: models.py:464
msgid "Available Date"
msgstr "Date de mise en disponibilité"
-#: models.py:456 utils.py:475 templates/admin/chimere/managed_modified.html:31
-#: templates/chimere/edit.html:49 templates/chimere/edit_route.html:46
+#: models.py:468 utils.py:490 templates/admin/chimere/managed_modified.html:31
+#: templates/chimere/edit.html:50 templates/chimere/edit_route.html:47
msgid "Description"
msgstr "Description"
-#: models.py:524 models.py:1500
+#: models.py:539 models.py:1543
msgid "Point of interest"
msgstr "Point d'intérêt"
-#: models.py:696
+#: models.py:714
msgid "Audio"
msgstr "Audio"
-#: models.py:697
+#: models.py:715
msgid "Video"
msgstr "Vidéo"
-#: models.py:699
+#: models.py:717
msgid "Other"
msgstr "Autre"
-#: models.py:700
+#: models.py:718
msgid "Media type"
msgstr "Type de media"
-#: models.py:703
+#: models.py:721
msgid "Mime type"
msgstr "Type mime"
-#: models.py:705
+#: models.py:723
msgid "Inside an iframe"
msgstr "À l'intérieur d'un iframe"
-#: models.py:709
+#: models.py:727
msgid "Multimedia type"
msgstr "Type de multimedia"
-#: models.py:710
+#: models.py:728
msgid "Multimedia types"
msgstr "Types de multimedia"
-#: models.py:719
+#: models.py:737
msgid "Automatic recognition"
msgstr "Reconnaissance automatique"
-#: models.py:745
+#: models.py:763
msgid "Extension name"
msgstr "Nom de l'extension"
-#: models.py:747
+#: models.py:765
msgid "Associated multimedia type"
msgstr "Type de multimedia associé"
-#: models.py:751
+#: models.py:769
msgid "Multimedia extension"
msgstr "Extension multimedia"
-#: models.py:752
+#: models.py:770
msgid "Multimedia extensions"
msgstr "Extensions multimedia"
-#: models.py:762 models.py:822
+#: models.py:780 models.py:840
msgid "Display inside the description?"
msgstr "Apparaît dans la description ?"
-#: models.py:767
+#: models.py:785
msgid "Multimedia file"
msgstr "Fichier multimedia"
-#: models.py:824
+#: models.py:786
+msgid "Multimedia files"
+msgstr "Fichiers multimedias"
+
+#: models.py:842
msgid "Thumbnail"
msgstr "Miniature"
-#: models.py:828
+#: models.py:846
msgid "Thumbnail height"
msgstr "Hauteur de la miniature"
-#: models.py:830
+#: models.py:848
msgid "Thumbnail width"
msgstr "Largeur de la miniature"
-#: models.py:839
+#: models.py:857
msgid "Picture file"
msgstr "Fichier d'image"
-#: models.py:934
+#: models.py:858
+msgid "Picture files"
+msgstr "Fichiers d'image"
+
+#: models.py:954
msgid "Raw file (gpx or kml)"
msgstr "Fichier brut (gpx ou kml)"
-#: models.py:936
+#: models.py:956
msgid "Simplified file"
msgstr "Fichier simplifié"
-#: models.py:938
+#: models.py:958
msgid "KML"
msgstr "KML"
-#: models.py:938
+#: models.py:958
msgid "GPX"
msgstr "GPX"
-#: models.py:943
+#: models.py:963
msgid "Route file"
msgstr "Fichier de trajet"
-#: models.py:944
+#: models.py:964
msgid "Route files"
msgstr "Fichiers de trajet"
-#: models.py:994
+#: models.py:1014
msgid "Reference route"
msgstr "Trajet de référence"
-#: models.py:998
+#: models.py:1018
msgid "Associated file"
msgstr "Fichier associé"
-#: models.py:1003
+#: models.py:1023
msgid "Has an associated marker"
msgstr "Dispose d'un marqueur associé"
-#: models.py:1263
+#: models.py:1305
msgid "Layer code"
msgstr "Code pour la couche"
-#: models.py:1269
+#: models.py:1311
msgid "Layer"
msgstr "Couche"
-#: models.py:1275
+#: models.py:1317
msgid "Area urn"
msgstr "Urn de la zone"
-#: models.py:1277 templates/chimere/blocks/welcome.html:3
+#: models.py:1319 templates/chimere/blocks/welcome.html:3
msgid "Welcome message"
msgstr "Message d'accueil"
-#: models.py:1281
+#: models.py:1323
msgid "Upper left corner"
msgstr "Coin en haut à gauche"
-#: models.py:1283
+#: models.py:1325
msgid "Lower right corner"
msgstr "Coin en bas à droite"
-#: models.py:1285
+#: models.py:1327
msgid "Default area"
msgstr "Zone par défaut"
-#: models.py:1286
+#: models.py:1328
msgid "Only one area is set by default"
msgstr "Seule une zone est définie par défaut"
-#: models.py:1290
+#: models.py:1332
msgid "Sub-categories checked by default"
msgstr "Sous-catégories cochées par défaut"
-#: models.py:1292
+#: models.py:1334
msgid "Sub-categories dynamicaly displayed"
msgstr "Sous-categories affichées dynamiquement"
-#: models.py:1293
+#: models.py:1335
msgid ""
"If checked, categories are only displayed in the menu if they are available "
"on the current extent."
@@ -715,72 +723,72 @@ msgstr ""
"Si coché, les catégories sont disponibles sur le menu seulement si elles "
"apparaissent sur la zone affichée."
-#: models.py:1297 models.py:1452
+#: models.py:1339 models.py:1495
msgid "Restricted to theses sub-categories"
msgstr "Restreindre à ces sous-categories"
-#: models.py:1298
+#: models.py:1340
msgid "If no sub-category is set all sub-categories are available"
msgstr ""
"Si aucune sous-catégorie n'est définie toutes les sous-catégories sont "
"disponibles"
-#: models.py:1300
+#: models.py:1342
msgid "Link to an external CSS"
msgstr "Lien vers une feuille de style externe"
-#: models.py:1302
+#: models.py:1344
msgid "Restrict to the area extent"
msgstr "Restreindre à l'étendue de la zone"
-#: models.py:1437 widgets.py:88
+#: models.py:1480 widgets.py:88
msgid "Default layer"
msgstr "Couche par défaut"
-#: models.py:1441 models.py:1442
+#: models.py:1484 models.py:1485
msgid "Layers"
msgstr "Couches"
-#: models.py:1450
+#: models.py:1493
msgid "Mandatory"
msgstr "Obligatoire"
-#: models.py:1453
+#: models.py:1496
msgid ""
"If no sub-category is set all the property applies to all sub-categories"
msgstr ""
"Si aucune sous-catégorie n'est précisée, cette propriété est disponible pour "
"toutes les sous-catégories"
-#: models.py:1455
+#: models.py:1498
msgid "Text"
msgstr "Texte"
-#: models.py:1456
+#: models.py:1499
msgid "Long text"
msgstr "Texte long"
-#: models.py:1459
+#: models.py:1502
msgid "Choices"
msgstr "Choix"
-#: models.py:1467
+#: models.py:1510
msgid "Type"
msgstr "Type"
-#: models.py:1472 models.py:1488 models.py:1502
+#: models.py:1515 models.py:1531 models.py:1545
msgid "Property model"
msgstr "Modèle de propriété"
-#: models.py:1489 models.py:1503
+#: models.py:1532 models.py:1546
msgid "Value"
msgstr "Valeur"
-#: models.py:1495
+#: models.py:1538
msgid "Model property choice"
msgstr "Choix pour les modèles de propriété"
-#: models.py:1514
+#: models.py:1557
msgid "Property"
msgstr "Propriété"
@@ -834,69 +842,69 @@ msgstr "Export échoué"
msgid "Export canceled"
msgstr "Export annulé"
-#: utils.py:135 utils.py:184
+#: utils.py:148 utils.py:197
msgid "Bad zip file"
msgstr "Mauvais fichier zip"
-#: utils.py:187
+#: utils.py:200
msgid "Missing file(s) inside the zip file"
msgstr "Fichier(s) manquant(s) dans l'archive zip"
-#: utils.py:228
+#: utils.py:241
msgid "Bad XML file"
msgstr "Mauvais fichier XML"
-#: utils.py:313
+#: utils.py:328
msgid "Error while reading the data source."
msgstr "Erreur lors de la lecture de la source."
-#: utils.py:331
+#: utils.py:346
#, python-format
msgid "SRID cannot be guessed. The default SRID (%s) has been used."
msgstr "Le SRID n'a pu être trouvé. Le SRID par défaut (%s) a été utilisé."
-#: utils.py:352
+#: utils.py:367
msgid "Type of geographic item of this shapefile is not managed by Chimère."
msgstr ""
"Les types des éléments géographiques de ce fichier Shapefile ne sont pas "
"gérés par Chimère."
-#: utils.py:372
+#: utils.py:387
msgid "Bad Shapefile"
msgstr "Mauvais fichier Shapefile"
-#: utils.py:414
+#: utils.py:429
msgid "Could not create file!"
msgstr "Ne peut pas créer le fichier !"
-#: utils.py:425
+#: utils.py:440
msgid "Failed to create field"
msgstr "Ne peut pas créer un champ"
-#: utils.py:471 templates/admin/chimere/managed_modified.html:25
-#: templates/chimere/edit.html:44 templates/chimere/edit_route.html:41
+#: utils.py:486 templates/admin/chimere/managed_modified.html:25
+#: templates/chimere/edit.html:45 templates/chimere/edit_route.html:42
#: templates/chimere/main_map.html:13
#: templates/chimere/main_map_simple.html:10
msgid "Categories"
msgstr "Catégories"
-#: utils.py:504
+#: utils.py:519
msgid "Invalid CSV format"
msgstr "Fichier CSV non valide"
-#: utils.py:579
+#: utils.py:597
msgid "RSS feed is not well formed"
msgstr "Flux RSS non valide"
-#: utils.py:654
+#: utils.py:673
msgid "Nothing to import"
msgstr "Rien à importer"
-#: utils.py:742
+#: utils.py:757
msgid "New items imported - validate them before exporting"
msgstr "Nouveaux éléments importés - valider ceux-ci avant d'exporter"
-#: utils.py:744
+#: utils.py:759
msgid ""
"There are items from a former import not yet validated - validate them "
"before exporting"
@@ -904,19 +912,19 @@ msgstr ""
"Il y a des éléments d'un import précédent pas encore validé - Validez les "
"avant d'exporter"
-#: utils.py:756
+#: utils.py:771
msgid "Bad params - programming error"
msgstr "Mauvais paramètres - erreur de programmation"
-#: utils.py:766
+#: utils.py:781
msgid "Bad param"
msgstr "Mauvais paramètre"
-#: utils.py:781
+#: utils.py:796
msgid "No non ambigious tag is defined in the XAPI request"
msgstr "Pas de tag non ambigü définis dans la requête XAPI"
-#: utils.py:783
+#: utils.py:798
msgid ""
"No bounding box is defined in the XAPI request.If you are sure to manage the "
"entire planet set the bounding box to -180,-90,180,90"
@@ -925,19 +933,19 @@ msgstr ""
"vouloir lancer la requête sur la planète entière fixez la « bounding box » "
"à -180,-90,180,90"
-#: views.py:278
+#: views.py:290
msgid "There are missing field(s) and/or errors in the submited form."
msgstr "Il y a des champs manquants ou des erreurs dans ce formulaire."
-#: views.py:363
+#: views.py:375
msgid "Bad file. Please check it with an external software."
msgstr "Fichier incohérent. Merci de le vérifier avec un logiciel externe."
-#: views.py:475
+#: views.py:487
msgid "Comments/request on the map"
msgstr "Commentaires/requètes sur la carte"
-#: views.py:478
+#: views.py:490
msgid ""
"Thank you for your contribution. It will be taken into account. If you have "
"left your email you may be contacted soon for more details."
@@ -946,19 +954,19 @@ msgstr ""
"laissé votre courriel vous serez peut-être contacté bientôt pour plus de "
"détails."
-#: views.py:482
+#: views.py:494
msgid "Temporary error. Renew your message later."
msgstr "Erreur temporaire. Réenvoyez votre message plus tard."
-#: views.py:656
+#: views.py:663
msgid "No category available in this area."
msgstr "Pas de catégorie disponible sur cette zone."
-#: views.py:756
+#: views.py:763
msgid "Bad geometry"
msgstr "Géométrie incorrecte"
-#: views.py:841
+#: views.py:848
msgid "Incorrect choice in the list"
msgstr "Choix incorrect dans la liste"
@@ -1267,27 +1275,39 @@ msgstr "Je souhaiterais proposer une modification pour cet élément :"
msgid "Error"
msgstr "Erreur"
-#: templates/chimere/edit.html:24
-msgid "Add/modify a point of interest"
+#: templates/chimere/edit.html:23 templates/chimere/edit_route.html:20
+msgid ""
+"You are logged as an administrator. Your modifications will be taking into "
+"account immediately."
+msgstr ""
+"Vous êtes connecté comme administrateur. Vos modifications vont être prises "
+"en compte immédiatement."
+
+#: templates/chimere/edit.html:25
+msgid "Modify a point of interest"
+msgstr "Modifier un point d'intérêt"
+
+#: templates/chimere/edit.html:25
+msgid "Add a point of interest"
msgstr "Ajout d'un point d'intérêt"
-#: templates/chimere/edit.html:30
+#: templates/chimere/edit.html:31
msgid "Point"
msgstr "Point"
-#: templates/chimere/edit.html:31 templates/chimere/edit_route.html:28
+#: templates/chimere/edit.html:32 templates/chimere/edit_route.html:29
msgid "Select a location for this new site"
msgstr "Choisissez une localisation pour ce nouveau site"
-#: templates/chimere/edit.html:37 templates/chimere/edit_route.html:34
+#: templates/chimere/edit.html:38 templates/chimere/edit_route.html:35
msgid "indicates a mandatory field"
msgstr "indique un champ obligatoire"
-#: templates/chimere/edit.html:113
+#: templates/chimere/edit.html:114
msgid "Personal information"
msgstr "Informations personnelles"
-#: templates/chimere/edit.html:115
+#: templates/chimere/edit.html:116
msgid ""
"This fields are not mandatory. If you provided them they not will be made "
"public and they will only used to join you for this project."
@@ -1296,29 +1316,33 @@ msgstr ""
"pas publiés et ne seront utilisés seulement pour vous joindre dans le cadre "
"de ce projet."
-#: templates/chimere/edit.html:118
+#: templates/chimere/edit.html:119
msgid "Your name or nickname"
msgstr "Votre nom ou pseudo"
-#: templates/chimere/edit.html:123
+#: templates/chimere/edit.html:124
msgid "Your email"
msgstr "Votre courriel"
-#: templates/chimere/edit.html:128
+#: templates/chimere/edit.html:129
msgid "Comments about your submission"
msgstr "Commentaires au sujet de votre proposition"
-#: templates/chimere/edit.html:134
+#: templates/chimere/edit.html:135
msgid "Upload in progress. Please wait..."
msgstr "Dépôt en cours. Veuillez patienter..."
-#: templates/chimere/edit.html:152 templates/chimere/edit_route.html:77
+#: templates/chimere/edit.html:153 templates/chimere/edit_route.html:78
msgid "Propose"
msgstr "Proposez"
-#: templates/chimere/edit_route.html:21
-msgid "Add/modify a route"
-msgstr "Ajout ou modifier un trajet"
+#: templates/chimere/edit_route.html:22
+msgid "Modify a route"
+msgstr "Modifier un trajet"
+
+#: templates/chimere/edit_route.html:22
+msgid "Add a route"
+msgstr "Ajout d'un nouveau trajet"
#: templates/chimere/main_map.html:35
msgid "Simple map"
diff --git a/chimere/migrations/0042_fix_rights.py b/chimere/migrations/0042_fix_rights.py
new file mode 100644
index 0000000..6b64313
--- /dev/null
+++ b/chimere/migrations/0042_fix_rights.py
@@ -0,0 +1,261 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import DataMigration
+from django.db import models
+from django.contrib.auth.models import ContentType, Permission, Group, User
+
+class Migration(DataMigration):
+
+ def forwards(self, orm):
+ "Fix bad migration of content type."
+ # chimère migration: we can use auth models directly
+ for ct in ContentType.objects.filter(app_label='main').all():
+ new_ct, n = ContentType.objects.get_or_create(app_label='chimere',
+ model=ct.model,
+ defaults={'name':ct.name})
+ if not new_ct.name and ct.name:
+ new_ct.name = ct.name
+ new_ct.save()
+ for perm in Permission.objects.filter(content_type_id=ct.pk).all():
+ new_perm, n = Permission.objects.get_or_create(
+ content_type=new_ct, codename=perm.codename,
+ defaults={'name':perm.name})
+ groups = Group.objects.filter(permissions=perm).distinct()
+ for group in groups.all():
+ group.permissions.remove(perm)
+ group.permissions.add(new_perm)
+ users = User.objects.filter(user_permissions=perm).distinct()
+ for user in users.all():
+ user.user_permissions.remove(perm)
+ user.user_permissions.add(new_perm)
+ perm.delete()
+ ct.delete()
+
+ def backwards(self, orm):
+ pass
+
+ 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': 'False'}),
+ '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'}),
+ '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.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': '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'})
+ },
+ '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'},
+ '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': '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'},
+ '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']
+ symmetrical = True
diff --git a/chimere/migrations/0043_auto__add_field_importer_get_description.py b/chimere/migrations/0043_auto__add_field_importer_get_description.py
new file mode 100644
index 0000000..295d3b2
--- /dev/null
+++ b/chimere/migrations/0043_auto__add_field_importer_get_description.py
@@ -0,0 +1,245 @@
+# -*- 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 field 'Importer.get_description'
+ db.add_column('chimere_importer', 'get_description',
+ self.gf('django.db.models.fields.BooleanField')(default=False),
+ keep_default=False)
+
+
+ def backwards(self, orm):
+ # Deleting field 'Importer.get_description'
+ db.delete_column('chimere_importer', 'get_description')
+
+
+ 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': 'False'}),
+ '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'}),
+ '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.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': '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'})
+ },
+ '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'},
+ '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': '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'},
+ '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/migrations/0044_auto__add_field_importer_default_description.py b/chimere/migrations/0044_auto__add_field_importer_default_description.py
new file mode 100644
index 0000000..ccabcd4
--- /dev/null
+++ b/chimere/migrations/0044_auto__add_field_importer_default_description.py
@@ -0,0 +1,246 @@
+# -*- 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 field 'Importer.default_description'
+ db.add_column('chimere_importer', 'default_description',
+ self.gf('django.db.models.fields.TextField')(null=True, blank=True),
+ keep_default=False)
+
+
+ def backwards(self, orm):
+ # Deleting field 'Importer.default_description'
+ db.delete_column('chimere_importer', 'default_description')
+
+
+ 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': '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.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': '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'})
+ },
+ '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'},
+ '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': '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'},
+ '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 a059b35..90cb06a 100644
--- a/chimere/models.py
+++ b/chimere/models.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# Copyright (C) 2008-2012 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
+# Copyright (C) 2008-2013 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as
@@ -331,6 +331,10 @@ class Importer(models.Model):
zipped = models.BooleanField(_(u"Zipped file"), default=False)
overwrite = models.BooleanField(_(u"Overwrite existing data"),
default=False)
+ get_description = models.BooleanField(_(u"Get description from source"),
+ default=False)
+ default_description = models.TextField(_(u"Default description"),
+ blank=True, null=True)
origin = models.CharField(_(u"Origin"), max_length=100,
blank=True, null=True)
license = models.CharField(_(u"License"), max_length=100,
@@ -425,6 +429,13 @@ class GeographicItem(models.Model):
self.import_key = new_keys
self.save()
+ def has_modified(self):
+ if (self.ref_item and self.ref_item != self) \
+ or self.__class__.objects.filter(ref_item=self
+ ).exclude(pk=self.pk).count():
+ return True
+ return False
+
@classmethod
def properties(cls):
return [pm for pm in PropertyModel.objects.filter(available=True)]
@@ -505,7 +516,10 @@ class Marker(GeographicItem):
@property
def date(self):
- if settings.CHIMERE_DAYS_BEFORE_EVENT:
+ if settings.CHIMERE_DAYS_BEFORE_EVENT and self.start_date:
+ today = datetime.date.today()
+ if self.end_date and self.start_date < today:
+ return self.end_date
return self.start_date
@property
@@ -629,11 +643,14 @@ class Marker(GeographicItem):
def default_category(self):
# Should we select only available ones ?
# Should we catch if not exists ?
- return self.categories.all()[0]
+ cats = self.categories
+ if cats.count():
+ return cats.all()[0]
def get_absolute_url(self, area_name=''):
- parameters = 'current_feature=%d&checked_categories=%s' % (self.id,
- self.default_category.pk)
+ parameters = 'current_feature=%d' % self.id
+ if self.default_category:
+ parameters += '&checked_categories=%s' % self.default_category.pk
urn = TinyUrl.getUrnByParameters(parameters)
area_name = area_name + '/' if area_name else ''
url = reverse('chimere:tiny', args=[area_name, urn])
@@ -890,7 +907,7 @@ def picturefile_post_save(sender, **kwargs):
basename, format = os.path.splitext(filetail)
basename = defaultfilters.slugify(basename)
basename = re.sub(r'-','_', basename)
- miniature = basename + '_thumb' + format
+ miniature = basename + '_thumb.jpg'
filename = file.path
miniature_filename = os.path.join(filehead, miniature)
try:
@@ -910,10 +927,12 @@ def picturefile_post_save(sender, **kwargs):
image.thumbnail([image_x, image_y], Image.ANTIALIAS)
temp_image = open(miniature_filename, 'w')
+ if image.mode != "RGB":
+ image = image.convert('RGB')
try:
- image.save(temp_image, image.format, quality=90, optimize=1)
+ image.save(temp_image, 'JPEG', quality=90, optimize=1)
except:
- image.save(temp_image, image.format, quality=90)
+ image.save(temp_image, 'JPEG', quality=90)
short_name = miniature_filename[len(settings.MEDIA_ROOT):]
picturefile.thumbnailfile = short_name
@@ -1396,8 +1415,8 @@ def area_post_save(sender, **kwargs):
perm = Permission.objects.filter(codename=mnemo)
lbl = "Can change " + area.name
if not perm.count():
- content_type = ContentType.objects.get(app_label="chimere",
- model="area")
+ content_type, created = ContentType.objects.get_or_create(
+ app_label="chimere", model="area")
perm = Permission(name=lbl, content_type_id=content_type.id,
codename=mnemo)
perm.save()
@@ -1424,7 +1443,8 @@ def area_post_save(sender, **kwargs):
('chimere', 'multimediafile'),
('chimere', 'picturefile'),
('chimere', 'routefile')):
- ct = ContentType.objects.get(app_label=app_label, model=model)
+ ct, created = ContentType.objects.get_or_create(app_label=app_label,
+ model=model)
for p in Permission.objects.filter(content_type=ct).all():
group.permissions.add(p)
diff --git a/chimere/static/bsmSelect/GPL-LICENSE.txt b/chimere/static/bsmSelect/GPL-LICENSE.txt
new file mode 100644
index 0000000..76927f5
--- /dev/null
+++ b/chimere/static/bsmSelect/GPL-LICENSE.txt
@@ -0,0 +1,278 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES. \ No newline at end of file
diff --git a/chimere/static/bsmSelect/MIT-LICENSE.txt b/chimere/static/bsmSelect/MIT-LICENSE.txt
new file mode 100644
index 0000000..908016b
--- /dev/null
+++ b/chimere/static/bsmSelect/MIT-LICENSE.txt
@@ -0,0 +1,21 @@
+Copyright (c) 2008 by Ryan Cramer, http://www.ryancramer.com
+Copyright (c) 2010 by Victor Berchet
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file
diff --git a/chimere/static/bsmSelect/README.md b/chimere/static/bsmSelect/README.md
new file mode 100644
index 0000000..bd14c6a
--- /dev/null
+++ b/chimere/static/bsmSelect/README.md
@@ -0,0 +1,191 @@
+# bsmSelect - Better Select Multiple #
+
+based on asmSelect - Alternate Select Multiple by Ryan Cramer
+
+ * [Google code project](http://code.google.com/p/jquery-asmselect/)
+ * [Github page](http://github.com/ryancramerdesign/jquery-asmSelect)
+ * [Ryan's article about asmSelect](http://www.ryancramer.com/journal/entries/select_multiple/)
+ * the original README can be found in the project root folder
+
+## Demo ##
+
+[bsmSelect demo](http://www.suumit.com/projects/bsmSelect/examples/index.html)
+
+## Usage ##
+
+Include jquery, bsmSelect, and css in document head:
+
+ <script type="text/javascript" src="jquery.js"></script>
+ <script type="text/javascript" src="jquery.bsmselect.js"></script>
+ <link rel="stylesheet" type="text/css" href="jquery.bsmselect.css" />
+
+Use a jQuery selector in your document ready function:
+
+ jQuery(function($) {
+ $("select[multiple]").bsmSelect();
+ });
+
+If desired, you can specify options when you call the plugin:
+
+ jQuery(function($) {
+ $("select[multiple]").bsmSelect({
+ addItemTarget: 'top'
+ });
+ });
+
+The newly created select default option is the original select title attribute:
+
+ <select name="cities" multiple="multiple" title="Please select a city">
+ ...
+ </select>
+
+## Requirements ##
+
+* jQuery 1.4+ (you might need a newer version for IE9 compatibility)
+
+## Options ##
+
+### Primary Options ###
+
+* listType:
+
+ * Specify what list will be created or used as part of the bsmSelect.
+ * Can accept a callback that accepts the original <select> as an argument and returns a jQuery object with a single list.
+ * Allowed values:
+ * 'ol'
+ * 'ul'
+ * function(originalSelect) { // your code; return $('&lt;ul&gt;'); }
+ * Default: 'ol'
+
+* highlightEffect:
+
+ * Show a quick highlight of what item was added or removed?
+ * Allowed values:
+ * an animation function
+ * Default: $.noop (no effect)
+
+* showEffect:
+
+ * Animate the addition of an item to the list
+ * Allowed values:
+ * an animation function
+ * Default: $.bsmSelect.effects.show
+
+* hideEffect:
+
+ * Animate the removal of an items from the list
+ * Allowed values:
+ * an animation function
+ * Default: $.bsmSelect.effects.remove
+
+* hideWhenAdded:
+
+ * Stop showing in select after item has been added?
+ * Allowed values: true or false
+ * Default: false
+ * Note: Only functional in Firefox 3 at this time.
+
+* addItemTarget:
+
+ * Where to place new selected items that are added to the list.
+ * Allowed values: 'top' or 'bottom' or 'original' to keep the original select sort order
+ * Default: 'bottom'
+ * Note: When using the 'original' mode, the sort order can be overriden by setting the 'bsm-order' data on each option.
+
+* debugMode:
+
+ * Keeps original select multiple visible so that you can monitor live changes made to it when debugging.
+ * Default: false
+
+* extractLabel:
+
+ * A function to compute the list element name from the option object
+ * Default: extract the option html
+
+* plugins
+
+ * An array of plugins objects to enable (they only are required to have an `init` method which is called on init with the Bsmselect instance as single argument).
+ * Default: an empty array (no plugin enabled by default)
+
+### Text Labels ###
+
+* title
+
+ * Text used for the default select label (when original select title attribute is not set)
+ * Default: 'Select...'
+
+* removeLabel:
+
+ * Text used for the remove link of each list item.
+ * Default: 'remove'
+
+* highlightAddedLabel:
+
+ * Text that precedes highlight of item added.
+ * Default: 'Added: '
+
+* highlightRemovedLabel:
+
+ * Text that precedes highlight of item removed.
+ * Default: 'Removed: '
+
+### Modifiable CSS Classes ###
+
+* containerClass:
+
+ * Class for container that wraps the entire bsmSelect.
+ * Default: 'bsmContainer'
+
+* selectClass:
+
+ * Class for the newly created <select>.
+ * Default: 'bsmSelect'
+
+* listClass:
+
+ * Class for the newly created list of listType (ol or ul).
+ * Default: 'bsmList'
+
+* listSortableClass:
+
+ * Another class given to the list when sortable is active.
+ * Default: 'bsmListSortable'
+
+* listItemClass:
+
+ * Class given to the <li> list items.
+ * Default: 'bsmListItem'
+
+* listItemLabelClass:
+
+ * Class for the label text that appears in list items.
+ * Default: 'bsmListItemLabel'
+
+* removeClass:
+
+ * Class given to the remove link in each list item.
+ * Any element found in the <li> with this class will remove it.
+ * If you give the <li> this class, clicking anywhere on the <li> will remove it.
+ * Default: 'bsmListItemRemove'
+
+* highlightClass:
+
+ * Class given to the highlight <span>.
+ * Default: 'bsmHighlight'
+
+## Authors and contributors ##
+
+ * [Ryan Cramer](http://www.ryancramer.com/) is the author of the original asmSelect
+ * [Victor Berchet](http://github.com/vicb) is the author of bsmSelect
+ * [Andy Fowler](http://github.com/andyfowler) has contributed many enhancements
+ * [Cracky](https://github.com/Cracky)
+ * [Marc Busqué](https://github.com/laMarciana) has contributed to fix [issue #21](https://github.com/vicb/bsmSelect/issues/21) and with minimal CSS
+
+## History ##
+
+see [history.md](history.md).
+
+## Related Projects ##
+
+ * [Chosen](https://github.com/harvesthq/chosen/)
+
diff --git a/chimere/static/chimere/js/jquery/bsmSelect/css/jquery.bsmselect.css b/chimere/static/bsmSelect/css/jquery.bsmselect.css
index ad770d0..ad770d0 100644
--- a/chimere/static/chimere/js/jquery/bsmSelect/css/jquery.bsmselect.css
+++ b/chimere/static/bsmSelect/css/jquery.bsmselect.css
diff --git a/chimere/static/chimere/js/jquery/bsmSelect/css/jquery.bsmselect.custom.css b/chimere/static/bsmSelect/css/jquery.bsmselect.custom.css
index 8c48aeb..8c48aeb 100644
--- a/chimere/static/chimere/js/jquery/bsmSelect/css/jquery.bsmselect.custom.css
+++ b/chimere/static/bsmSelect/css/jquery.bsmselect.custom.css
diff --git a/chimere/static/chimere/js/jquery/bsmSelect/js/jquery.bsmselect.compatibility.js b/chimere/static/bsmSelect/js/jquery.bsmselect.compatibility.js
index a743a07..a743a07 100644
--- a/chimere/static/chimere/js/jquery/bsmSelect/js/jquery.bsmselect.compatibility.js
+++ b/chimere/static/bsmSelect/js/jquery.bsmselect.compatibility.js
diff --git a/chimere/static/chimere/js/jquery/bsmSelect/js/jquery.bsmselect.js b/chimere/static/bsmSelect/js/jquery.bsmselect.js
index 25527c6..25527c6 100644
--- a/chimere/static/chimere/js/jquery/bsmSelect/js/jquery.bsmselect.js
+++ b/chimere/static/bsmSelect/js/jquery.bsmselect.js
diff --git a/chimere/static/chimere/js/jquery/bsmSelect/js/jquery.bsmselect.sortable.js b/chimere/static/bsmSelect/js/jquery.bsmselect.sortable.js
index 3e4b9f8..3e4b9f8 100644
--- a/chimere/static/chimere/js/jquery/bsmSelect/js/jquery.bsmselect.sortable.js
+++ b/chimere/static/bsmSelect/js/jquery.bsmselect.sortable.js
diff --git a/chimere/static/chimere/css/styles.css b/chimere/static/chimere/css/styles.css
index 67a28a4..41502c2 100644
--- a/chimere/static/chimere/css/styles.css
+++ b/chimere/static/chimere/css/styles.css
@@ -90,16 +90,6 @@ div.warning,
border:1px solid #ff3f3f;
}
-/* opacity */
-
-#welcome{
- opacity:0.9;
-}
-
-#panel, #areas, #detail, #category_description, #chimere_itinerary_panel{
- opacity:0.8;
-}
-
/* rounded */
/* entête */
@@ -1107,3 +1097,8 @@ div.pp_default .pp_expand{
left:10px;
background-position: -15px -80px;
}
+
+.olControlAttribution{
+ left:6px;
+ bottom:5px;
+}
diff --git a/chimere/static/chimere/img/cloud-popup-relative.png b/chimere/static/chimere/img/cloud-popup-relative.png
index 1215a36..1215a36 100755..100644
--- a/chimere/static/chimere/img/cloud-popup-relative.png
+++ b/chimere/static/chimere/img/cloud-popup-relative.png
Binary files differ
diff --git a/chimere/static/chimere/js/importer_interface.js b/chimere/static/chimere/js/importer_interface.js
index aa332d4..b14b986 100644
--- a/chimere/static/chimere/js/importer_interface.js
+++ b/chimere/static/chimere/js/importer_interface.js
@@ -4,16 +4,18 @@ django.jQuery(function($) {
'field-source', 'field-overwrite'),
KML:new Array('field-source', 'field-source_file', 'field-default_name',
'field-filtr', 'field-zipped', 'field-origin',
- 'field-license', 'field-categories', 'field-overwrite'),
+ 'field-license', 'field-categories', 'field-overwrite',
+ 'field-get_description'),
SHP:new Array('field-source', 'field-source_file', 'field-default_name',
'field-zipped', 'field-origin', 'field-srid',
'field-license', 'field-categories', 'field-overwrite'),
RSS:new Array('field-source', 'field-default_name', 'field-origin',
'field-srid', 'field-license', 'field-categories',
- 'field-overwrite'),
+ 'field-overwrite', 'field-get_description'),
CSV:new Array('field-source', 'field-source_file', 'field-default_name',
'field-origin', 'field-srid', 'field-license',
- 'field-categories', 'field-overwrite')
+ 'field-categories', 'field-overwrite',
+ 'field-get_description')
}
var map_initialized;
function refresh_importer_form(){
@@ -50,9 +52,24 @@ django.jQuery(function($) {
$('.input-osm').hide();
if($('#id_source').val() == default_xapi) $('#id_source').val('');
}
+ refresh_default_desc();
+ }
+ function refresh_default_desc(){
+ if (!$('.form-row.field-get_description').is(':visible')){
+ $('.form-row.field-default_description').show();
+ $('.form-row.field-get_description input').attr('checked', false);
+ } else {
+ if (!$('.form-row.field-get_description input').is(':checked')){
+ $('.form-row.field-default_description').show();
+ } else {
+ $('.form-row.field-default_description').hide();
+ $('.form-row.field-default_description textarea').val("");
+ }
+ }
}
refresh_importer_form();
$('.field-importer_type select').change(refresh_importer_form);
+ $('.field-get_description input').change(refresh_default_desc);
function refresh_filtr_form(){
if (!$('#upper_left_lat').val() ||
!parseFloat($('#upper_left_lat').val())){
diff --git a/chimere/static/chimere/js/jquery.chimere.js b/chimere/static/chimere/js/jquery.chimere.js
index 3e148b0..104e527 100644
--- a/chimere/static/chimere/js/jquery.chimere.js
+++ b/chimere/static/chimere/js/jquery.chimere.js
@@ -61,6 +61,7 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
dynamic_categories: false,
display_submited: false,
display_feature: null,
+ display_route: null,
area_id: null,
checked_categories: [],
zoom: null,
@@ -174,6 +175,8 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
/* Create map object */
settings.map = map = new OpenLayers.Map(map_element, map_options);
+ map.addControl(new OpenLayers.Control.Attribution());
+
/* Manage permalink */
if (!settings.edition){
if (settings.permalink == null && !settings.edition) {
@@ -372,7 +375,6 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
if (settings.zoom && settings.lon && settings.lat) {
var centerLonLat = new OpenLayers.LonLat(settings.lon,
settings.lat);
- centerLonLat.transform(EPSG_DISPLAY_PROJECTION, EPSG_PROJECTION);
settings.map.setCenter(centerLonLat, settings.zoom);
}
/* if not zoom to the extent in cookies */
@@ -901,7 +903,10 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
settings.current_feature = feature;
_popup(feature);
methods.display_feature_detail(feature.pk);
- _repan_popup();
+ if (!settings.display_route){
+ settings.map.setCenter(feature.lonlat, 16);
+ _repan_popup();
+ }
settings.display_feature = null;
//methods.loadCategories();
}
@@ -943,6 +948,11 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
settings.current_feature.style = style;
settings.current_feature.geometry = linestring;
settings.layerVectors.addFeatures([settings.current_feature]);
+ if (settings.display_route && settings.display_route == route.properties.pk){
+ var dataExtent = settings.current_feature.geometry.getBounds();
+ map.zoomToExtent(dataExtent, closest=true);
+ methods.loadCategories();
+ }
},
/*
* Put a multiline on the map
diff --git a/chimere/static/jme/GPL-LICENSE-2.txt b/chimere/static/jme/GPL-LICENSE-2.txt
new file mode 100644
index 0000000..3c993fd
--- /dev/null
+++ b/chimere/static/jme/GPL-LICENSE-2.txt
@@ -0,0 +1,278 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES. \ No newline at end of file
diff --git a/chimere/static/jme/MIT-LICENSE.txt b/chimere/static/jme/MIT-LICENSE.txt
new file mode 100644
index 0000000..e197885
--- /dev/null
+++ b/chimere/static/jme/MIT-LICENSE.txt
@@ -0,0 +1,20 @@
+Copyright (c) 2010 Alexander Farkas, http://protofunc.com/
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file
diff --git a/chimere/static/chimere/js/OpenLayers.js b/chimere/static/openlayers/OpenLayers.js
index d94ff5b..d94ff5b 100644
--- a/chimere/static/chimere/js/OpenLayers.js
+++ b/chimere/static/openlayers/OpenLayers.js
diff --git a/chimere/static/chimere/js/SimplePanZoom.js b/chimere/static/openlayers/SimplePanZoom.js
index 45619c3..45619c3 100644
--- a/chimere/static/chimere/js/SimplePanZoom.js
+++ b/chimere/static/openlayers/SimplePanZoom.js
diff --git a/chimere/static/prettyPhoto/README b/chimere/static/prettyPhoto/README
new file mode 100755
index 0000000..1e56842
--- /dev/null
+++ b/chimere/static/prettyPhoto/README
@@ -0,0 +1,30 @@
+prettyPhoto v3.1.4
+© Copyright, Stephane Caron
+http://www.no-margin-for-errors.com
+
+
+============================= Released under =============================
+
+Creative Commons 2.5
+http://creativecommons.org/licenses/by/2.5/
+
+OR
+
+GPLV2 license
+http://www.gnu.org/licenses/gpl-2.0.html
+
+You are free to use prettyPhoto in commercial projects as long as the
+copyright header is left intact.
+
+============================ More information ============================
+http://www.no-margin-for-errors.com/projects/prettyPhoto/
+
+
+============================== Description ===============================
+
+prettyPhoto is a jQuery based lightbox clone. Not only does it support images,
+it also add support for videos, flash, YouTube, iFrame. It's a full blown
+media modal box.
+
+Please refer to http://www.no-margin-for-errors.com/projects/prettyPhoto/
+for all the details on how to use.
diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/btnNext.png b/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/btnNext.png
index b28c1ef..b28c1ef 100755..100644
--- a/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/btnNext.png
+++ b/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/btnNext.png
Binary files differ
diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/btnPrevious.png b/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/btnPrevious.png
index e0cd9c4..e0cd9c4 100755..100644
--- a/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/btnPrevious.png
+++ b/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/btnPrevious.png
Binary files differ
diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/contentPattern.png b/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/contentPattern.png
index e5a047c..e5a047c 100755..100644
--- a/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/contentPattern.png
+++ b/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/contentPattern.png
Binary files differ
diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/default_thumbnail.gif b/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/default_thumbnail.gif
index 2b1280f..2b1280f 100755..100644
--- a/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/default_thumbnail.gif
+++ b/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/default_thumbnail.gif
Binary files differ
diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/loader.gif b/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/loader.gif
index 50820ee..50820ee 100755..100644
--- a/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/loader.gif
+++ b/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/loader.gif
Binary files differ
diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/sprite.png b/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/sprite.png
index fb8c0f8..fb8c0f8 100755..100644
--- a/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/sprite.png
+++ b/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/sprite.png
Binary files differ
diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/btnNext.png b/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/btnNext.png
index b28c1ef..b28c1ef 100755..100644
--- a/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/btnNext.png
+++ b/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/btnNext.png
Binary files differ
diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/btnPrevious.png b/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/btnPrevious.png
index e0cd9c4..e0cd9c4 100755..100644
--- a/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/btnPrevious.png
+++ b/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/btnPrevious.png
Binary files differ
diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/contentPattern.png b/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/contentPattern.png
index 7b50aff..7b50aff 100755..100644
--- a/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/contentPattern.png
+++ b/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/contentPattern.png
Binary files differ
diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/default_thumbnail.gif b/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/default_thumbnail.gif
index 2b1280f..2b1280f 100755..100644
--- a/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/default_thumbnail.gif
+++ b/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/default_thumbnail.gif
Binary files differ
diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/loader.gif b/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/loader.gif
index 50820ee..50820ee 100755..100644
--- a/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/loader.gif
+++ b/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/loader.gif
Binary files differ
diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/sprite.png b/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/sprite.png
index 4fe3547..4fe3547 100755..100644
--- a/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/sprite.png
+++ b/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/sprite.png
Binary files differ
diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/btnNext.png b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/btnNext.png
index e809c3b..e809c3b 100755..100644
--- a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/btnNext.png
+++ b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/btnNext.png
Binary files differ
diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/btnPrevious.png b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/btnPrevious.png
index 0812542..0812542 100755..100644
--- a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/btnPrevious.png
+++ b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/btnPrevious.png
Binary files differ
diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternBottom.png b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternBottom.png
index a9be3b2..a9be3b2 100755..100644
--- a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternBottom.png
+++ b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternBottom.png
Binary files differ
diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternLeft.png b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternLeft.png
index 277c87a..277c87a 100755..100644
--- a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternLeft.png
+++ b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternLeft.png
Binary files differ
diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternRight.png b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternRight.png
index 76e50d0..76e50d0 100755..100644
--- a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternRight.png
+++ b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternRight.png
Binary files differ
diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternTop.png b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternTop.png
index 8b110ba..8b110ba 100755..100644
--- a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternTop.png
+++ b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternTop.png
Binary files differ
diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/default_thumbnail.gif b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/default_thumbnail.gif
index 2b1280f..2b1280f 100755..100644
--- a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/default_thumbnail.gif
+++ b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/default_thumbnail.gif
Binary files differ
diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/loader.gif b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/loader.gif
index 7ac990c..7ac990c 100755..100644
--- a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/loader.gif
+++ b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/loader.gif
Binary files differ
diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/sprite.png b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/sprite.png
index 660a254..660a254 100755..100644
--- a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/sprite.png
+++ b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/sprite.png
Binary files differ
diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/btnNext.png b/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/btnNext.png
index b28c1ef..b28c1ef 100755..100644
--- a/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/btnNext.png
+++ b/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/btnNext.png
Binary files differ
diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/btnPrevious.png b/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/btnPrevious.png
index e0cd9c4..e0cd9c4 100755..100644
--- a/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/btnPrevious.png
+++ b/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/btnPrevious.png
Binary files differ
diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/default_thumbnail.gif b/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/default_thumbnail.gif
index 2b1280f..2b1280f 100755..100644
--- a/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/default_thumbnail.gif
+++ b/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/default_thumbnail.gif
Binary files differ
diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/loader.gif b/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/loader.gif
index 7ac990c..7ac990c 100755..100644
--- a/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/loader.gif
+++ b/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/loader.gif
Binary files differ
diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/sprite.png b/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/sprite.png
index 7f28379..7f28379 100755..100644
--- a/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/sprite.png
+++ b/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/sprite.png
Binary files differ
diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/light_square/btnNext.png b/chimere/static/prettyPhoto/images/prettyPhoto/light_square/btnNext.png
index b28c1ef..b28c1ef 100755..100644
--- a/chimere/static/prettyPhoto/images/prettyPhoto/light_square/btnNext.png
+++ b/chimere/static/prettyPhoto/images/prettyPhoto/light_square/btnNext.png
Binary files differ
diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/light_square/btnPrevious.png b/chimere/static/prettyPhoto/images/prettyPhoto/light_square/btnPrevious.png
index e0cd9c4..e0cd9c4 100755..100644
--- a/chimere/static/prettyPhoto/images/prettyPhoto/light_square/btnPrevious.png
+++ b/chimere/static/prettyPhoto/images/prettyPhoto/light_square/btnPrevious.png
Binary files differ
diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/light_square/default_thumbnail.gif b/chimere/static/prettyPhoto/images/prettyPhoto/light_square/default_thumbnail.gif
index 2b1280f..2b1280f 100755..100644
--- a/chimere/static/prettyPhoto/images/prettyPhoto/light_square/default_thumbnail.gif
+++ b/chimere/static/prettyPhoto/images/prettyPhoto/light_square/default_thumbnail.gif
Binary files differ
diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/light_square/loader.gif b/chimere/static/prettyPhoto/images/prettyPhoto/light_square/loader.gif
index 7ac990c..7ac990c 100755..100644
--- a/chimere/static/prettyPhoto/images/prettyPhoto/light_square/loader.gif
+++ b/chimere/static/prettyPhoto/images/prettyPhoto/light_square/loader.gif
Binary files differ
diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/light_square/sprite.png b/chimere/static/prettyPhoto/images/prettyPhoto/light_square/sprite.png
index 4fe3547..4fe3547 100755..100644
--- a/chimere/static/prettyPhoto/images/prettyPhoto/light_square/sprite.png
+++ b/chimere/static/prettyPhoto/images/prettyPhoto/light_square/sprite.png
Binary files differ
diff --git a/chimere/templates/admin/chimere/marker/change_form.html b/chimere/templates/admin/chimere/marker/change_form.html
index 64c48f9..3b3d238 100644
--- a/chimere/templates/admin/chimere/marker/change_form.html
+++ b/chimere/templates/admin/chimere/marker/change_form.html
@@ -1,7 +1,7 @@
{% extends "admin/change_form.html" %}
{% load i18n %}
{% block field_sets %}
-{% if original.ref_item and original.ref_item != orginal %}
+{% if original.has_modified %}
<p class='errornote'>
{% url admin:admin-modification object_id as rapprochement_form %}
{% blocktrans %}
diff --git a/chimere/templates/chimere/blocks/areas.html b/chimere/templates/chimere/blocks/areas.html
index 8c4b981..a1ebe76 100644
--- a/chimere/templates/chimere/blocks/areas.html
+++ b/chimere/templates/chimere/blocks/areas.html
@@ -3,6 +3,7 @@
<div id='areas-div'>
<label for='areas-select'>{% trans "Areas:" %}</label>
<select id='areas-select'>
+ {% if not has_default_area %}<option value=''>--</option>{% endif %}
{% for area in areas %}
<option value='{{area.urn}}'{% if area_name and area.urn == area_name %} selected='selected'{% endif %}{% if not area_name and area.default %} selected='selected'{% endif %}>{{area.name}}</option>
{% endfor %}
diff --git a/chimere/templates/chimere/blocks/map.html b/chimere/templates/chimere/blocks/map.html
index 6304e13..4affb19 100644
--- a/chimere/templates/chimere/blocks/map.html
+++ b/chimere/templates/chimere/blocks/map.html
@@ -43,8 +43,9 @@
chimere_init_options["checked_categories"] = [{% for cc in checked_categories %}{% if forloop.counter0 > 0 %}, {% endif %}{{cc}}{% endfor %}];
{% if area_id %}chimere_init_options['area_id'] = "{{area_id}}";{% endif %}
{% if p_current_feature %}
- chimere_init_options["display_feature"] = {{ p_current_feature }};
- {% endif %}
+ chimere_init_options["display_feature"] = {{ p_current_feature }};{% endif %}
+ {% if p_current_route %}
+ chimere_init_options["display_route"] = {{ p_current_route }};{% endif %}
{% if restricted_extent %}{{ restricted_extent }}
chimere_init_options["restricted_extent"] = bounds;
{% endif %}
diff --git a/chimere/templates/chimere/detail.html b/chimere/templates/chimere/detail.html
index 134c03e..4b5c168 100644
--- a/chimere/templates/chimere/detail.html
+++ b/chimere/templates/chimere/detail.html
@@ -24,11 +24,11 @@
{% endfor %}
{% if marker.origin %}<p class='detail_source'><strong>{% trans "Source:" %}</strong> <span>{{marker.origin}}</span></p>{% endif %}
{% if marker.license %}<p class='detail_license'><strong>{% trans "License:" %}</strong> <span>{{marker.license}}</span></p>{% endif %}
- {% if marker.multimedia_items %}
+ {% if marker.multimedia_items %}<p class='detail_multimedia'>
<a href='#' class='show_gallery_link'>{% trans "Show multimedia gallery" %}</a>
- {% endif %}
+ </p>{% endif %}
</div>
- <a href='{% if marker.route %}{% url chimere:editroute-item area_name_slash|default_if_none:"" marker.route.pk "" %}{%else%}{% url chimere:edit-item area_name_slash|default_if_none:"" marker.pk "" %}{%endif%}'>
+ <p class='detail_amendment'><a href='{% if marker.route %}{% url chimere:editroute-item area_name_slash|default_if_none:"" marker.route.pk "" %}{%else%}{% url chimere:edit-item area_name_slash|default_if_none:"" marker.pk "" %}{%endif%}'>
{% trans "Submit an amendment" %}
</a>
{% if moderator_emails %}
diff --git a/chimere/templates/chimere/edit.html b/chimere/templates/chimere/edit.html
index 9732005..f9706d3 100644
--- a/chimere/templates/chimere/edit.html
+++ b/chimere/templates/chimere/edit.html
@@ -20,8 +20,9 @@
<legend>{% trans "Error" %}</legend>
<p>{{ error_message }}</p>
{% endif %}</fieldset>
+ {% if is_modification and is_superuser %}<div class='warning'><p>{% trans "You are logged as an administrator. Your modifications will be taking into account immediately." %}</p></div>{% endif %}
<fieldset class='edit'>
- <legend>{% trans "Add/modify a point of interest" %}</legend>
+ <legend>{% if is_modification %}{% trans "Modify a point of interest" %}{% else %}{% trans "Add a point of interest" %}{% endif %}</legend>
<form enctype="multipart/form-data" method='post' action='.'>
{% csrf_token %}
<div class='rightWrapper'>
diff --git a/chimere/templates/chimere/edit_route.html b/chimere/templates/chimere/edit_route.html
index 0221949..10f4d5e 100644
--- a/chimere/templates/chimere/edit_route.html
+++ b/chimere/templates/chimere/edit_route.html
@@ -17,8 +17,9 @@
{{ block.super }}
{% if submited %}{% submited %}{% endif %}
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
+ {% if is_modification and is_superuser %}<div class='warning'><p>{% trans "You are logged as an administrator. Your modifications will be taking into account immediately." %}</p></div>{% endif %}
<fieldset class='edit'>
- <legend>{% trans "Add/modify a route" %}</legend>
+ <legend>{% if is_modification %}{% trans "Modify a route" %}{% else %}{% trans "Add a route" %}{% endif %}</legend>
<form enctype="multipart/form-data" method='post' action='.'>
{% csrf_token %}
<div class='rightWrapper'>
diff --git a/chimere/templatetags/chimere_tags.py b/chimere/templatetags/chimere_tags.py
index b73413a..14860b8 100644
--- a/chimere/templatetags/chimere_tags.py
+++ b/chimere/templatetags/chimere_tags.py
@@ -51,9 +51,9 @@ def get_news(area=None):
# Retrieve active markers
today = date.today()
after = today + timedelta(settings.CHIMERE_DAYS_BEFORE_EVENT)
- q = Q(end_date__gte=today) | Q(end_date__isnull=True)
- q = Marker.objects.filter(status='A', start_date__lte=after,
- is_front_page=True).filter(q)
+ q = Marker.objects.filter(status='A').filter(start_date__lte=after,
+ is_front_page=True).filter(Q(end_date__gte=today)|
+ (Q(end_date__isnull=True) & Q(start_date__gte=today)))
if area:
q = q.filter(area.getIncludeMarker())
news += list(q)
@@ -246,6 +246,7 @@ bounds.extend(new OpenLayers.LonLat(%f, %f));
return context_data
request = context['request']
# Default values
+ context_data['p_current_route'] = context.get('current_route')
if request.GET:
for key in ('zoom', 'lon', 'lat', 'display_submited',
'current_feature', 'routing_start_lon', 'routing_start_lat',
diff --git a/chimere/tests.py b/chimere/tests.py
index af342c5..fb48205 100644
--- a/chimere/tests.py
+++ b/chimere/tests.py
@@ -189,12 +189,31 @@ class KMLImporterTest(TestCase, ImporterTest):
importer3.categories.add(subcategories[2])
importer4 = Importer.objects.create(importer_type='KML',
- source=test_dir_path+'tests/sample.kml.zip', zipped=True)
+ source=test_dir_path+'tests/sample.kml.zip', zipped=True,
+ default_description="Default description")
importer4.categories.add(subcategories[3])
self.marker_importers = [(importer1, 1), (importer2, 3), (importer3, 0),
(importer4, 4)]
+ def test_defaultdescription(self):
+ Marker.objects.all().delete()
+ importer = self.marker_importers[-1][0]
+ importer.overwrite = True
+ importer.save()
+ importer.manager.get()
+ last_marker = Marker.objects.order_by('-pk').all()[0]
+ self.assertEqual(last_marker.description,
+ importer.default_description)
+ # don't overwrite description on update
+ new_desc = u"Description set by an user"
+ last_marker.description = new_desc
+ last_marker.save()
+ importer.manager.get()
+ last_marker = Marker.objects.order_by('-pk').all()[0]
+ self.assertEqual(last_marker.description,
+ new_desc)
+
class ShapefileImporterTest(TestCase, ImporterTest):
def setUp(self):
self.subcategories = subcategory_setup()
@@ -401,6 +420,12 @@ class NewsTest(TestCase):
def setUp(self):
self.areas = areas_setup()
self.markers = marker_setup()
+ current_date = datetime.datetime.now()
+ marker = Marker.objects.create(name="Marker 4", status='A',
+ point='SRID=4326;POINT(-4.5 48.45)',
+ available_date=current_date - datetime.timedelta(days=90),
+ start_date=current_date - datetime.timedelta(days=90),
+ end_date=None)
self.news = []
self.news.append(News.objects.create(is_front_page=True,
title=u"Test news 1", available=True))
diff --git a/chimere/tests/data_license b/chimere/tests/data_license
deleted file mode 100644
index bee3231..0000000
--- a/chimere/tests/data_license
+++ /dev/null
@@ -1 +0,0 @@
-eqs7day-M5.xml is a georss feed from the website http://www.usgs.gov/ published under the US public domain
diff --git a/chimere/utils.py b/chimere/utils.py
index 0d97757..33ebdf7 100644
--- a/chimere/utils.py
+++ b/chimere/utils.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# Copyright (C) 2012 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
+# Copyright (C) 2012-2013 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as
@@ -46,11 +46,13 @@ from chimere import get_version
from external_utils import OsmApi
def unicode_normalize(string):
+ if type(string) == str:
+ string = unicode(string.decode('utf-8'))
return ''.join(
(c for c in unicodedata.normalize('NFD', string)
if unicodedata.category(c) != 'Mn'))
-class ImportManager:
+class ImportManager(object):
u"""
Generic class for specific importers
"""
@@ -74,8 +76,11 @@ class ImportManager:
key='', pk=None):
updated, created, item = False, False, None
import_key = unicode(import_key).replace(':', '^')
+ if not values.get('name'):
+ values['name'] = self.default_name
if not key:
key = self.importer_instance.importer_type
+ item = None
if import_key or pk:
dct_import = {
'import_key__icontains':'%s:%s;' % (key, import_key),
@@ -85,7 +90,10 @@ class ImportManager:
if pk:
ref_item = cls.objects.get(pk=pk)
else:
- ref_item = cls.objects.get(**dct_import)
+ ref_item = cls.objects.filter(**dct_import)
+ if not ref_item.count():
+ raise ObjectDoesNotExist
+ ref_item = ref_item.all()[0]
if version and ref_item.import_version == int(version):
# no update since the last import
return ref_item, None, None
@@ -95,7 +103,8 @@ class ImportManager:
else:
item = ref_item
for k in values:
- setattr(item, k, values[k])
+ if values[k]:
+ setattr(item, k, values[k])
try:
item.save()
# force the modified_since_import status
@@ -108,6 +117,10 @@ class ImportManager:
except ObjectDoesNotExist:
pass
if not item:
+ if not self.importer_instance.get_description and \
+ self.importer_instance.default_description:
+ values['description'] = \
+ self.importer_instance.default_description
values.update({
'import_source':self.importer_instance.source})
values['status'] = 'I'
@@ -197,7 +210,7 @@ class KMLManager(ImportManager):
XPATH = '//kml:Folder/kml:name[text()="%s"]/../kml:Placemark'
DEFAULT_XPATH = '//kml:Placemark'
def __init__(self, importer_instance, ns=''):
- self.importer_instance = importer_instance
+ super(KMLManager, self).__init__(importer_instance)
self.ns = ns
def get(self):
@@ -237,6 +250,7 @@ class KMLManager(ImportManager):
pl_id = placemark.attrib.get('id')
pl_key = 'kml-%d' % self.importer_instance.pk
ns = '{%s}' % self.ns
+ description = ''
for item in placemark:
if item.tag == ns + 'name':
name = item.text
@@ -244,7 +258,8 @@ class KMLManager(ImportManager):
# if no ID is provided assume that name is a key
pl_id = name
elif item.tag == ns + 'description':
- description = item.text
+ if self.importer_instance.get_description:
+ description = item.text
elif item.tag == ns + 'Point':
for coord in item:
if coord.tag == ns + 'coordinates':
@@ -506,7 +521,10 @@ class CSVManager(ImportManager):
if len(row) < len(cols):
continue
pk, name, cats, state = row[0], row[1], row[2], row[3]
- description, geom = row[4], row[5].upper()
+ geom = row[5]
+ description = ''
+ if self.importer_instance.get_description:
+ description = row[4]
COL_INDEX = 6
dct = {'description':description,
'name':name,
@@ -595,10 +613,11 @@ class GeoRSSManager(ImportManager):
y = item['geo_lat']
x = item['geo_long']
dct['point'] = 'SRID=4326;POINT(%s %s)' % (x, y)
- for k in ['description', 'summary', 'value']:
- if k in item:
- dct['description'] = item[k]
- break
+ if self.importer_instance.get_description:
+ for k in ['description', 'summary', 'value']:
+ if k in item:
+ dct['description'] = item[k]
+ break
else:
cls = Route
points = item['georss_line'].split(' ')
@@ -675,8 +694,6 @@ class OSMManager(ImportManager):
name = item.attrib.get('v')
if item.tag == 'nd':
points.append(item.get('ref'))
- if not name:
- name = self.default_name
if not points:
continue
wkt = 'SRID=4326;LINESTRING(%s)' % ",".join([nodes[point_id]
@@ -710,8 +727,6 @@ class OSMManager(ImportManager):
k = item.attrib.get('k')
if k == 'name':
name = item.attrib.get('v')
- if not name:
- name = self.default_name
point = 'SRID=4326;POINT(%s %s)' % (node.get('lon'),
node.get('lat'))
dct = {'point':point,
diff --git a/chimere/views.py b/chimere/views.py
index 47ce281..a8c3f19 100644
--- a/chimere/views.py
+++ b/chimere/views.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# Copyright (C) 2008-2012 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
+# Copyright (C) 2008-2013 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
#
# RSS : Copyright (C) 2010 Pierre Clarenc <pierre.crc_AT_gmailDOTcom>,
# Samuel Renard <renard.samuel_AT_gmailDOTcom>,
@@ -158,6 +158,13 @@ def index(request, area_name=None, default_area=None, simple=False,
if settings.CHIMERE_ENABLE_ROUTING:
response_dct['itinerary_form'] = RoutingForm()
response_dct['routing_transport'] = settings.CHIMERE_ROUTING_TRANSPORT
+ if request.GET and 'current_feature' in request.GET:
+ try:
+ m = Marker.objects.get(pk=request.GET['current_feature'])
+ if m.route:
+ response_dct['current_route'] = m.route.pk
+ except:
+ pass
response_dct.update({
'actions':actions(response_dct['area_name']),
'action_selected':('view',),
@@ -167,7 +174,9 @@ def index(request, area_name=None, default_area=None, simple=False,
'map_layer':settings.CHIMERE_DEFAULT_MAP_LAYER,
'dynamic_categories':response_dct['dynamic_categories'],
'zoomout':zoomout,
- 'contact_email':settings.CONTACT_EMAIL
+ 'contact_email':settings.CONTACT_EMAIL,
+ 'has_default_area':Area.objects.filter(default=True).count(),
+ 'zoomout':zoomout
})
response_dct['share_networks'], net_dct = \
getShareNetwork(request, response_dct['area_name'])
@@ -211,6 +220,7 @@ def get_edit_page(redirect_url, item_cls, item_form,
submiter_session_key=request.session.session_key)
if modified_item.count():
init_item = modified_item.all()[0]
+ response_dct['is_modification'] = True
init_multi = init_item.get_init_multi() if init_item else None
init_picture = init_item.get_init_picture() if init_item else None
@@ -220,6 +230,7 @@ def get_edit_page(redirect_url, item_cls, item_form,
# hide personal information
for k in ('submiter_name', 'submiter_email', 'submiter_comment'):
setattr(init_item, k, '')
+ response_dct['is_superuser'] = request.user.is_superuser
# If the form has been submited
if request.method == 'POST':
inst = None
diff --git a/chimere/widgets.py b/chimere/widgets.py
index 481a5c9..45161e1 100644
--- a/chimere/widgets.py
+++ b/chimere/widgets.py
@@ -675,13 +675,13 @@ class AreaField(forms.MultiValueField):
class MultiSelectWidget(forms.SelectMultiple):
class Media:
css = {'all': list(settings.JQUERY_CSS_URLS) + [
- settings.STATIC_URL + 'chimere/js/jquery/bsmSelect/css/jquery.bsmselect.css',
- settings.STATIC_URL + 'chimere/js/jquery/bsmSelect/css/jquery.bsmselect.custom.css',
+ settings.STATIC_URL + 'bsmSelect/css/jquery.bsmselect.css',
+ settings.STATIC_URL + 'bsmSelect/css/jquery.bsmselect.custom.css',
]
}
js = list(settings.JQUERY_JS_URLS) + [
- settings.STATIC_URL + 'chimere/js/jquery/bsmSelect/js/jquery.bsmselect.js',
- settings.STATIC_URL + 'chimere/js/jquery/bsmSelect/js/jquery.bsmselect.compatibility.js',
+ settings.STATIC_URL + 'bsmSelect/js/jquery.bsmselect.js',
+ settings.STATIC_URL + 'bsmSelect/js/jquery.bsmselect.compatibility.js',
]
def render(self, name, value, attrs=None):