diff options
| 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 |
| commit | 054fdbdf7a1e5106725b8b5a36db99242cfa65c1 (patch) | |
| tree | 1633b26e884feb1f29afedbb80cef7a6ecbdba2d /chimere | |
| parent | 8a5ba2650678ec22107a1a0a10650b6e0cc14683 (diff) | |
| parent | d02ec4246813eb0787bf3ab54af1af9ce32bd376 (diff) | |
| download | Chimè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')
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("&", "&").replace("\"", """).replace("<","<").replace(">",">") + +## 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 $('<ul>'); } + * 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 Binary files differindex 1215a36..1215a36 100755..100644 --- a/chimere/static/chimere/img/cloud-popup-relative.png +++ b/chimere/static/chimere/img/cloud-popup-relative.png 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 Binary files differindex b28c1ef..b28c1ef 100755..100644 --- a/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/btnNext.png +++ b/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/btnNext.png diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/btnPrevious.png b/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/btnPrevious.png Binary files differindex e0cd9c4..e0cd9c4 100755..100644 --- a/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/btnPrevious.png +++ b/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/btnPrevious.png diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/contentPattern.png b/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/contentPattern.png Binary files differindex e5a047c..e5a047c 100755..100644 --- a/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/contentPattern.png +++ b/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/contentPattern.png diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/default_thumbnail.gif b/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/default_thumbnail.gif Binary files differindex 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 diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/loader.gif b/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/loader.gif Binary files differindex 50820ee..50820ee 100755..100644 --- a/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/loader.gif +++ b/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/loader.gif diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/sprite.png b/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/sprite.png Binary files differindex fb8c0f8..fb8c0f8 100755..100644 --- a/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/sprite.png +++ b/chimere/static/prettyPhoto/images/prettyPhoto/dark_rounded/sprite.png diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/btnNext.png b/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/btnNext.png Binary files differindex b28c1ef..b28c1ef 100755..100644 --- a/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/btnNext.png +++ b/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/btnNext.png diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/btnPrevious.png b/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/btnPrevious.png Binary files differindex e0cd9c4..e0cd9c4 100755..100644 --- a/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/btnPrevious.png +++ b/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/btnPrevious.png diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/contentPattern.png b/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/contentPattern.png Binary files differindex 7b50aff..7b50aff 100755..100644 --- a/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/contentPattern.png +++ b/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/contentPattern.png diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/default_thumbnail.gif b/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/default_thumbnail.gif Binary files differindex 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 diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/loader.gif b/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/loader.gif Binary files differindex 50820ee..50820ee 100755..100644 --- a/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/loader.gif +++ b/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/loader.gif diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/sprite.png b/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/sprite.png Binary files differindex 4fe3547..4fe3547 100755..100644 --- a/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/sprite.png +++ b/chimere/static/prettyPhoto/images/prettyPhoto/dark_square/sprite.png diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/btnNext.png b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/btnNext.png Binary files differindex e809c3b..e809c3b 100755..100644 --- a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/btnNext.png +++ b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/btnNext.png diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/btnPrevious.png b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/btnPrevious.png Binary files differindex 0812542..0812542 100755..100644 --- a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/btnPrevious.png +++ b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/btnPrevious.png diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternBottom.png b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternBottom.png Binary files differindex a9be3b2..a9be3b2 100755..100644 --- a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternBottom.png +++ b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternBottom.png diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternLeft.png b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternLeft.png Binary files differindex 277c87a..277c87a 100755..100644 --- a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternLeft.png +++ b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternLeft.png diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternRight.png b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternRight.png Binary files differindex 76e50d0..76e50d0 100755..100644 --- a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternRight.png +++ b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternRight.png diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternTop.png b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternTop.png Binary files differindex 8b110ba..8b110ba 100755..100644 --- a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternTop.png +++ b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/contentPatternTop.png diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/default_thumbnail.gif b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/default_thumbnail.gif Binary files differindex 2b1280f..2b1280f 100755..100644 --- a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/default_thumbnail.gif +++ b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/default_thumbnail.gif diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/loader.gif b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/loader.gif Binary files differindex 7ac990c..7ac990c 100755..100644 --- a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/loader.gif +++ b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/loader.gif diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/sprite.png b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/sprite.png Binary files differindex 660a254..660a254 100755..100644 --- a/chimere/static/prettyPhoto/images/prettyPhoto/facebook/sprite.png +++ b/chimere/static/prettyPhoto/images/prettyPhoto/facebook/sprite.png diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/btnNext.png b/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/btnNext.png Binary files differindex b28c1ef..b28c1ef 100755..100644 --- a/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/btnNext.png +++ b/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/btnNext.png diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/btnPrevious.png b/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/btnPrevious.png Binary files differindex e0cd9c4..e0cd9c4 100755..100644 --- a/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/btnPrevious.png +++ b/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/btnPrevious.png diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/default_thumbnail.gif b/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/default_thumbnail.gif Binary files differindex 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 diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/loader.gif b/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/loader.gif Binary files differindex 7ac990c..7ac990c 100755..100644 --- a/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/loader.gif +++ b/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/loader.gif diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/sprite.png b/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/sprite.png Binary files differindex 7f28379..7f28379 100755..100644 --- a/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/sprite.png +++ b/chimere/static/prettyPhoto/images/prettyPhoto/light_rounded/sprite.png diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/light_square/btnNext.png b/chimere/static/prettyPhoto/images/prettyPhoto/light_square/btnNext.png Binary files differindex b28c1ef..b28c1ef 100755..100644 --- a/chimere/static/prettyPhoto/images/prettyPhoto/light_square/btnNext.png +++ b/chimere/static/prettyPhoto/images/prettyPhoto/light_square/btnNext.png diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/light_square/btnPrevious.png b/chimere/static/prettyPhoto/images/prettyPhoto/light_square/btnPrevious.png Binary files differindex e0cd9c4..e0cd9c4 100755..100644 --- a/chimere/static/prettyPhoto/images/prettyPhoto/light_square/btnPrevious.png +++ b/chimere/static/prettyPhoto/images/prettyPhoto/light_square/btnPrevious.png diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/light_square/default_thumbnail.gif b/chimere/static/prettyPhoto/images/prettyPhoto/light_square/default_thumbnail.gif Binary files differindex 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 diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/light_square/loader.gif b/chimere/static/prettyPhoto/images/prettyPhoto/light_square/loader.gif Binary files differindex 7ac990c..7ac990c 100755..100644 --- a/chimere/static/prettyPhoto/images/prettyPhoto/light_square/loader.gif +++ b/chimere/static/prettyPhoto/images/prettyPhoto/light_square/loader.gif diff --git a/chimere/static/prettyPhoto/images/prettyPhoto/light_square/sprite.png b/chimere/static/prettyPhoto/images/prettyPhoto/light_square/sprite.png Binary files differindex 4fe3547..4fe3547 100755..100644 --- a/chimere/static/prettyPhoto/images/prettyPhoto/light_square/sprite.png +++ b/chimere/static/prettyPhoto/images/prettyPhoto/light_square/sprite.png 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): |
