summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2016-09-22 23:06:12 +0200
committerÉtienne Loks <etienne.loks@iggdrasil.net>2016-09-22 23:06:12 +0200
commit8a8f25e156367807d174bbe858e8f66416306001 (patch)
tree001e62218954de6391f83e2436de816cc6c7a48a
parent792fed91a5c0c218ede19b01d5d818730193a6b2 (diff)
downloadChimère-8a8f25e156367807d174bbe858e8f66416306001.tar.bz2
Chimère-8a8f25e156367807d174bbe858e8f66416306001.zip
Going to python3 and Django 1.8!
-rw-r--r--.gitlab-ci.yml4
-rw-r--r--chimere/__init__.py7
-rw-r--r--chimere/actions.py2
-rw-r--r--chimere/admin.py74
-rw-r--r--chimere/external_utils/OsmApi.py747
-rw-r--r--chimere/external_utils/__init__.py0
-rw-r--r--chimere/forms.py24
-rw-r--r--chimere/management/commands/chimere_import.py28
-rw-r--r--chimere/migrations/0037_recopy_marker_to_route.py4
-rw-r--r--chimere/models.py644
-rw-r--r--chimere/route.py4
-rw-r--r--chimere/tasks.py18
-rw-r--r--chimere/templates/admin/chimere/managed_modified.html2
-rw-r--r--chimere/templates/admin/chimere/marker/change_form.html2
-rw-r--r--chimere/templates/admin/chimere/osm_export.html2
-rw-r--r--chimere/templates/chimere/blocks/actions.html2
-rw-r--r--chimere/templates/chimere/blocks/head_chimere.html2
-rw-r--r--chimere/templates/chimere/blocks/share_bar.html2
-rw-r--r--chimere/templates/chimere/category_item_detail.html2
-rw-r--r--chimere/templates/chimere/detail.html2
-rw-r--r--chimere/templates/chimere/edit.html4
-rw-r--r--chimere/templates/chimere/edit_marker.html2
-rw-r--r--chimere/templates/chimere/upload_file.html2
-rw-r--r--chimere/templatetags/chimere_tags.py4
-rw-r--r--chimere/templatetags/sanitize.py9
-rw-r--r--chimere/templatetags/unlocalize_point.py5
-rw-r--r--chimere/tests.py18
-rw-r--r--chimere/urls.py2
-rw-r--r--chimere/utils.py99
-rw-r--r--chimere/views.py40
-rw-r--r--chimere/widgets.py211
-rw-r--r--chimere_example_project/local_settings.py.gitlab-ci2
-rwxr-xr-xchimere_example_project/manage.py24
-rw-r--r--chimere_example_project/settings.py32
-rw-r--r--chimere_example_project/urls.py13
-rw-r--r--requirements.txt15
-rw-r--r--requirements_searchengine.txt24
37 files changed, 664 insertions, 1414 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 37b8ead..8bb096a 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,6 +1,8 @@
before_script:
- apt-get update
- - apt-get install -q -y locales-all python-pip libpq-dev python-dev libjpeg-dev zlib1g-dev libxml2-dev libxslt1-dev libgeos-dev python-pyexiv2 python-gdal
+ - apt-get install -q -y locales-all python-pip libpq-dev python-dev libjpeg-dev zlib1g-dev libxml2-dev libxslt1-dev libgeos-dev libexiv2-dev libgdal-dev
+ - export CPLUS_INCLUDE_PATH=/usr/include/gdal
+ - export C_INCLUDE_PATH=/usr/include/gdal
- pip install -q -r requirements.txt
- cp Makefile.example Makefile
- cp chimere_example_project/local_settings.py.gitlab-ci chimere_example_project/local_settings.py
diff --git a/chimere/__init__.py b/chimere/__init__.py
index 19d78a9..0dce1db 100644
--- a/chimere/__init__.py
+++ b/chimere/__init__.py
@@ -1,10 +1,11 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# Copyright (C) 2012-2013 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
+# Copyright (C) 2012-2016 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
+
+VERSION = (3, 0, 0)
-VERSION = (2, 0, 3)
def get_version():
- return u'.'.join((unicode(num) for num in VERSION))
+ return '.'.join((str(num) for num in VERSION))
__version__ = get_version()
diff --git a/chimere/actions.py b/chimere/actions.py
index ecbd07a..d7c25c9 100644
--- a/chimere/actions.py
+++ b/chimere/actions.py
@@ -24,7 +24,7 @@ from django.conf import settings
from django.core.urlresolvers import reverse, NoReverseMatch
from django.utils.translation import ugettext_lazy as _
-from models import Page, Area
+from chimere.models import Page, Area
class Action:
diff --git a/chimere/admin.py b/chimere/admin.py
index cdcd053..fda0dd7 100644
--- a/chimere/admin.py
+++ b/chimere/admin.py
@@ -26,7 +26,7 @@ from copy import deepcopy
from django.conf import settings
from django.contrib import admin, messages
from django.contrib.admin import SimpleListFilter
-from django.contrib.admin.util import flatten_fieldsets
+from django.contrib.admin.utils import flatten_fieldsets
from django.contrib.auth.admin import UserAdmin as VanillaUserAdmin
from django.contrib.auth.models import User
from django.core.exceptions import ObjectDoesNotExist
@@ -57,18 +57,18 @@ def disable(modeladmin, request, queryset):
for item in queryset:
item.status = 'D'
item.save()
-disable.short_description = _(u"Disable")
+disable.short_description = _("Disable")
def validate(modeladmin, request, queryset):
for item in queryset:
item.status = 'A'
item.save()
-validate.short_description = _(u"Validate")
+validate.short_description = _("Validate")
def export_to_kml(modeladmin, request, queryset):
- u"""
+ """
Export data to KML
"""
filename, result = KMLManager.export(queryset)
@@ -76,11 +76,11 @@ def export_to_kml(modeladmin, request, queryset):
mimetype='application/vnd.google-earth.kml+xml')
response['Content-Disposition'] = 'attachment; filename=%s' % filename
return response
-export_to_kml.short_description = _(u"Export to KML")
+export_to_kml.short_description = _("Export to KML")
def export_to_shapefile(modeladmin, request, queryset):
- u"""
+ """
Export data to Shapefile
"""
filename, zip_stream = ShapefileManager.export(queryset)
@@ -91,18 +91,18 @@ def export_to_shapefile(modeladmin, request, queryset):
response['Content-Type'] = 'application/zip'
response.write(zip_stream)
return response
-export_to_shapefile.short_description = _(u"Export to Shapefile")
+export_to_shapefile.short_description = _("Export to Shapefile")
def export_to_csv(modeladmin, request, queryset):
- u"""
+ """
Export data to CSV
"""
filename, result = CSVManager.export(queryset)
response = HttpResponse(result, mimetype='text/csv')
response['Content-Disposition'] = 'attachment; filename=%s' % filename
return response
-export_to_csv.short_description = _(u"Export to CSV")
+export_to_csv.short_description = _("Export to CSV")
def managed_modified(modeladmin, request, queryset):
@@ -110,8 +110,8 @@ def managed_modified(modeladmin, request, queryset):
redirect_url = request.get_full_path().split('admin_modification')[0]
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."))
+ messages.error(request, _("Only one item can be managed at a "
+ "time."))
return HttpResponseRedirect(redirect_url)
item = queryset.all()[0]
@@ -120,8 +120,8 @@ def managed_modified(modeladmin, request, queryset):
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."))
+ messages.error(request, _("No modified item associated "
+ "to the selected item."))
return HttpResponseRedirect(redirect_url)
item_ref = item.ref_item
if request.POST.get('rapprochement'):
@@ -155,12 +155,12 @@ def managed_modified(modeladmin, request, queryset):
except (ValueError, ObjectDoesNotExist):
pass
item.delete()
- messages.success(request, _(u"Modified item traited."))
+ messages.success(request, _("Modified item traited."))
return HttpResponseRedirect(redirect_url)
return render_to_response('admin/chimere/managed_modified.html',
{'item': item, 'item_ref': item_ref},
context_instance=RequestContext(request))
-managed_modified.short_description = _(u"Managed modified items")
+managed_modified.short_description = _("Managed modified items")
class CatLimitInline(admin.TabularInline):
@@ -252,10 +252,10 @@ class CategoriesListFilter(SimpleListFilter):
def lookups(self, request, model_admin):
if request.user.subcategory_limit_to.count():
q = request.user.subcategory_limit_to
- return [(l.subcategory.pk, unicode(l.subcategory))
+ return [(l.subcategory.pk, str(l.subcategory))
for l in q.all()]
q = SubCategory.objects
- return [(cat.pk, unicode(cat)) for cat in q.all()]
+ return [(cat.pk, str(cat)) for cat in q.all()]
def queryset(self, request, queryset):
if self.value():
@@ -285,16 +285,16 @@ MARKER_FIELDSETS = [
'fields': ['point', 'name', 'status', 'categories', 'description',
'keywords', 'start_date', 'end_date']
}],
- [_(u"Submitter"), {
+ [_("Submitter"), {
'classes': ('collapse',),
'fields': ('submiter_name', 'submiter_email', 'submiter_comment')
}],
- [_(u"Import"), {
+ [_("Import"), {
'classes': ('collapse',),
'fields': ('not_for_osm', 'modified_since_import', 'import_source',
'origin', 'license')
}],
- [_(u"Associated items"), {
+ [_("Associated items"), {
'classes': ('collapse',),
'fields': ['ref_item', ]
}]
@@ -363,7 +363,7 @@ class MarkerAdmin(admin.ModelAdmin):
self, request, Marker.objects.filter(pk=item_id))
def get_urls(self):
- from django.conf.urls.defaults import patterns, url
+ from django.conf.urls import patterns, url
urls = super(MarkerAdmin, self).get_urls()
my_urls = patterns(
'',
@@ -384,7 +384,7 @@ class MarkerAdmin(admin.ModelAdmin):
return form
form = type('MarkerAdminLimit', (form,),
{'categories_choices': [
- (l.subcategory.pk, unicode(l.subcategory))
+ (l.subcategory.pk, str(l.subcategory))
for l in q.all()]})
return form
@@ -455,48 +455,48 @@ class AreaAdmin(admin.ModelAdmin):
def importing(modeladmin, request, queryset):
for importer in queryset:
- importer.state = unicode(tasks.IMPORT_MESSAGES['import_pending'][0])
+ importer.state = str(tasks.IMPORT_MESSAGES['import_pending'][0])
importer.save()
tasks.importing(importer.pk)
-importing.short_description = _(u"Import")
+importing.short_description = _("Import")
def cancel_import(modeladmin, request, queryset):
for importer in queryset:
importer.state = tasks.IMPORT_MESSAGES['import_cancel'][0]
importer.save()
-cancel_import.short_description = _(u"Cancel import")
+cancel_import.short_description = _("Cancel import")
def cancel_export(modeladmin, request, queryset):
for importer in queryset:
importer.state = tasks.IMPORT_MESSAGES['export_cancel'][0]
importer.save()
-cancel_export.short_description = _(u"Cancel export")
+cancel_export.short_description = _("Cancel export")
def export_to_osm(modeladmin, request, queryset):
if queryset.count() > 1:
messages.error(request,
- _(u"Can manage only one OSM export at a time."))
+ _("Can manage only one OSM export at a time."))
return HttpResponseRedirect(request.get_full_path())
importer = queryset.all()[0]
if Marker.objects.filter(categories__in=importer.categories.all(),
status='I').count():
- messages.error(request, _(u"You must treat all item with the status "
- u"\"imported\" before exporting to OSM."))
+ messages.error(request, _("You must treat all item with the status "
+ "\"imported\" before exporting to OSM."))
return HttpResponseRedirect(request.get_full_path())
if importer.importer_type != 'OSM':
messages.error(request,
- _(u"Only OSM importer are managed for export."))
+ _("Only OSM importer are managed for export."))
return HttpResponseRedirect(request.get_full_path())
item_nb = Marker.objects.filter(
status='A', categories=importer.categories.all(), not_for_osm=False,
modified_since_import=True, route=None).count()
if not item_nb:
messages.error(request,
- _(u"No point of interest are concerned by this "
- u"export."))
+ _("No point of interest are concerned by this "
+ "export."))
return HttpResponseRedirect(request.get_full_path())
form = None
if request.method == 'POST' and (
@@ -504,21 +504,21 @@ def export_to_osm(modeladmin, request, queryset):
or 'password' in request.POST):
form = OSMForm(request.POST)
if form.is_valid():
- importer.state = unicode(
+ importer.state = str(
tasks.IMPORT_MESSAGES['export_pending'][0])
importer.save()
tasks.exporting(importer.pk, form.cleaned_data)
- messages.success(request, _(u"Export launched."))
+ messages.success(request, _("Export launched."))
return HttpResponseRedirect(request.get_full_path())
else:
form = OSMForm()
- msg_item = _(u"%s point(s) of interest concerned by this export before "
- u"bounding box filter.") % item_nb
+ msg_item = _("%s point(s) of interest concerned by this export before "
+ "bounding box filter.") % item_nb
return render_to_response('admin/chimere/osm_export.html',
{'item': importer, 'form': form,
'msg_item': msg_item},
context_instance=RequestContext(request))
-export_to_osm.short_description = _(u"Export to osm")
+export_to_osm.short_description = _("Export to osm")
class ImporterKeyInline(admin.TabularInline):
diff --git a/chimere/external_utils/OsmApi.py b/chimere/external_utils/OsmApi.py
deleted file mode 100644
index 3b1b9b1..0000000
--- a/chimere/external_utils/OsmApi.py
+++ /dev/null
@@ -1,747 +0,0 @@
-#-*- coding: utf-8 -*-
-
-###########################################################################
-## ##
-## Copyrights Etienne Chové <chove@crans.org> 2009-2010 ##
-## ##
-## This program is free software: you can redistribute it and/or modify ##
-## it under the terms of the GNU General Public License as published by ##
-## the Free Software Foundation, either version 3 of the License, or ##
-## (at your option) any later version. ##
-## ##
-## This program is distributed in the hope that it will be useful, ##
-## but WITHOUT ANY WARRANTY; without even the implied warranty of ##
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ##
-## GNU General Public License for more details. ##
-## ##
-## You should have received a copy of the GNU General Public License ##
-## along with this program. If not, see <http://www.gnu.org/licenses/>. ##
-## ##
-###########################################################################
-
-## HomePage : http://wiki.openstreetmap.org/wiki/PythonOsmApi
-
-###########################################################################
-## History ##
-###########################################################################
-## 0.2.19 2010-05-24 Add debug message on ApiError ##
-## 0.2.18 2010-04-20 Fix ChangesetClose and _http_request ##
-## 0.2.17 2010-01-02 Capabilities implementation ##
-## 0.2.16 2010-01-02 ChangesetsGet by Alexander Rampp ##
-## 0.2.15 2009-12-16 xml encoding error for < and > ##
-## 0.2.14 2009-11-20 changesetautomulti parameter ##
-## 0.2.13 2009-11-16 modify instead update for osc ##
-## 0.2.12 2009-11-14 raise ApiError on 4xx errors -- Xoff ##
-## 0.2.11 2009-10-14 unicode error on ChangesetUpload ##
-## 0.2.10 2009-10-14 RelationFullRecur definition ##
-## 0.2.9 2009-10-13 automatic changeset management ##
-## ChangesetUpload implementation ##
-## 0.2.8 2009-10-13 *(Create|Update|Delete) use not unique _do method ##
-## 0.2.7 2009-10-09 implement all missing fonctions except ##
-## ChangesetsGet and GetCapabilities ##
-## 0.2.6 2009-10-09 encoding clean-up ##
-## 0.2.5 2009-10-09 implements NodesGet, WaysGet, RelationsGet ##
-## ParseOsm, ParseOsc ##
-## 0.2.4 2009-10-06 clean-up ##
-## 0.2.3 2009-09-09 keep http connection alive for multiple request ##
-## (Node|Way|Relation)Get return None when object ##
-## have been deleted (raising error before) ##
-## 0.2.2 2009-07-13 can identify applications built on top of the lib ##
-## 0.2.1 2009-05-05 some changes in constructor -- chove@crans.org ##
-## 0.2 2009-05-01 initial import ##
-###########################################################################
-
-__version__ = '0.2.19'
-
-import httplib, base64, xml.dom.minidom, time, sys, urllib
-
-class ApiError(Exception):
-
- def __init__(self, status, reason, payload):
- self.status = status
- self.reason = reason
- self.payload = payload
-
- def __str__(self):
- return "Request failed: " + str(self.status) + " - " + self.reason + " - " + self.payload
-
-###########################################################################
-## Main class ##
-
-class OsmApi:
-
- def __init__(self,
- username = None,
- password = None,
- passwordfile = None,
- appid = "",
- created_by = "PythonOsmApi/"+__version__,
- api = "www.openstreetmap.org",
- changesetauto = False,
- changesetautotags = {},
- changesetautosize = 500,
- changesetautomulti = 1,
- debug = False
- ):
-
- # debug
- self._debug = debug
-
- # Get username
- if username:
- self._username = username
- elif passwordfile:
- self._username = open(passwordfile).readline().split(":")[0].strip()
-
- # Get password
- if password:
- self._password = password
- elif passwordfile:
- for l in open(passwordfile).readlines():
- l = l.strip().split(":")
- if l[0] == self._username:
- self._password = l[1]
-
- # Changest informations
- self._changesetauto = changesetauto # auto create and close changesets
- self._changesetautotags = changesetautotags # tags for automatic created changesets
- self._changesetautosize = changesetautosize # change count for auto changeset
- self._changesetautosize = changesetautosize # change count for auto changeset
- self._changesetautomulti = changesetautomulti # close a changeset every # upload
- self._changesetautocpt = 0
- self._changesetautodata = [] # data to upload for auto group
-
- # Get API
- self._api = api
-
- # Get created_by
- if not appid:
- self._created_by = created_by
- else:
- self._created_by = appid + " (" + created_by + ")"
-
- # Initialisation
- self._CurrentChangesetId = 0
-
- # Http connection
- self._conn = httplib.HTTPConnection(self._api, 80)
-
- def __del__(self):
- if self._changesetauto:
- self._changesetautoflush(True)
- return None
-
- #######################################################################
- # Capabilities #
- #######################################################################
-
- def Capabilities(self):
- """ Returns ApiCapabilities. """
- uri = "/api/capabilities"
- data = self._get(uri)
- data = xml.dom.minidom.parseString(data)
- print data.getElementsByTagName("osm")
- data = data.getElementsByTagName("osm")[0].getElementsByTagName("api")[0]
- result = {}
- for elem in data.childNodes:
- if elem.nodeType <> elem.ELEMENT_NODE:
- continue
- result[elem.nodeName] = {}
- print elem.nodeName
- for k, v in elem.attributes.items():
- try:
- result[elem.nodeName][k] = float(v)
- except:
- result[elem.nodeName][k] = v
- return result
-
- #######################################################################
- # Node #
- #######################################################################
-
- def NodeGet(self, NodeId, NodeVersion = -1):
- """ Returns NodeData for node #NodeId. """
- uri = "/api/0.6/node/"+str(NodeId)
- if NodeVersion <> -1: uri += "/"+str(NodeVersion)
- data = self._get(uri)
- if not data: return data
- data = xml.dom.minidom.parseString(data)
- data = data.getElementsByTagName("osm")[0].getElementsByTagName("node")[0]
- return self._DomParseNode(data)
-
- def NodeCreate(self, NodeData):
- """ Creates a node. Returns updated NodeData (without timestamp). """
- return self._do("create", "node", NodeData)
-
- def NodeUpdate(self, NodeData):
- """ Updates node with NodeData. Returns updated NodeData (without timestamp). """
- return self._do("modify", "node", NodeData)
-
- def NodeDelete(self, NodeData):
- """ Delete node with NodeData. Returns updated NodeData (without timestamp). """
- return self._do("delete", "node", NodeData)
-
- def NodeHistory(self, NodeId):
- """ Returns dict(NodeVerrsion: NodeData). """
- uri = "/api/0.6/node/"+str(NodeId)+"/history"
- data = self._get(uri)
- data = xml.dom.minidom.parseString(data)
- result = {}
- for data in data.getElementsByTagName("osm")[0].getElementsByTagName("node"):
- data = self._DomParseNode(data)
- result[data[u"version"]] = data
- return result
-
- def NodeWays(self, NodeId):
- """ Returns [WayData, ... ] containing node #NodeId. """
- uri = "/api/0.6/node/%d/ways"%NodeId
- data = self._get(uri)
- data = xml.dom.minidom.parseString(data)
- result = []
- for data in data.getElementsByTagName("osm")[0].getElementsByTagName("way"):
- data = self._DomParseRelation(data)
- result.append(data)
- return result
-
- def NodeRelations(self, NodeId):
- """ Returns [RelationData, ... ] containing node #NodeId. """
- uri = "/api/0.6/node/%d/relations"%NodeId
- data = self._get(uri)
- data = xml.dom.minidom.parseString(data)
- result = []
- for data in data.getElementsByTagName("osm")[0].getElementsByTagName("relation"):
- data = self._DomParseRelation(data)
- result.append(data)
- return result
-
- def NodesGet(self, NodeIdList):
- """ Returns dict(NodeId: NodeData) for each node in NodeIdList """
- uri = "/api/0.6/nodes?nodes=" + ",".join([str(x) for x in NodeIdList])
- data = self._get(uri)
- data = xml.dom.minidom.parseString(data)
- result = {}
- for data in data.getElementsByTagName("osm")[0].getElementsByTagName("node"):
- data = self._DomParseNode(data)
- result[data[u"id"]] = data
- return result
-
- #######################################################################
- # Way #
- #######################################################################
-
- def WayGet(self, WayId, WayVersion = -1):
- """ Returns WayData for way #WayId. """
- uri = "/api/0.6/way/"+str(WayId)
- if WayVersion <> -1: uri += "/"+str(WayVersion)
- data = self._get(uri)
- if not data: return data
- data = xml.dom.minidom.parseString(data)
- data = data.getElementsByTagName("osm")[0].getElementsByTagName("way")[0]
- return self._DomParseWay(data)
-
- def WayCreate(self, WayData):
- """ Creates a way. Returns updated WayData (without timestamp). """
- return self._do("create", "way", WayData)
-
- def WayUpdate(self, WayData):
- """ Updates way with WayData. Returns updated WayData (without timestamp). """
- return self._do("modify", "way", WayData)
-
- def WayDelete(self, WayData):
- """ Delete way with WayData. Returns updated WayData (without timestamp). """
- return self._do("delete", "way", WayData)
-
- def WayHistory(self, WayId):
- """ Returns dict(WayVerrsion: WayData). """
- uri = "/api/0.6/way/"+str(WayId)+"/history"
- data = self._get(uri)
- data = xml.dom.minidom.parseString(data)
- result = {}
- for data in data.getElementsByTagName("osm")[0].getElementsByTagName("way"):
- data = self._DomParseWay(data)
- result[data[u"version"]] = data
- return result
-
- def WayRelations(self, WayId):
- """ Returns [RelationData, ...] containing way #WayId. """
- uri = "/api/0.6/way/%d/relations"%WayId
- data = self._get(uri)
- data = xml.dom.minidom.parseString(data)
- result = []
- for data in data.getElementsByTagName("osm")[0].getElementsByTagName("relation"):
- data = self._DomParseRelation(data)
- result.append(data)
- return result
-
- def WayFull(self, WayId):
- """ Return full data for way WayId as list of {type: node|way|relation, data: {}}. """
- uri = "/api/0.6/way/"+str(WayId)+"/full"
- data = self._get(uri)
- return self.ParseOsm(data)
-
- def WaysGet(self, WayIdList):
- """ Returns dict(WayId: WayData) for each way in WayIdList """
- uri = "/api/0.6/ways?ways=" + ",".join([str(x) for x in WayIdList])
- data = self._get(uri)
- data = xml.dom.minidom.parseString(data)
- result = {}
- for data in data.getElementsByTagName("osm")[0].getElementsByTagName("way"):
- data = self._DomParseWay(data)
- result[data[u"id"]] = data
- return result
-
- #######################################################################
- # Relation #
- #######################################################################
-
- def RelationGet(self, RelationId, RelationVersion = -1):
- """ Returns RelationData for relation #RelationId. """
- uri = "/api/0.6/relation/"+str(RelationId)
- if RelationVersion <> -1: uri += "/"+str(RelationVersion)
- data = self._get(uri)
- if not data: return data
- data = xml.dom.minidom.parseString(data)
- data = data.getElementsByTagName("osm")[0].getElementsByTagName("relation")[0]
- return self._DomParseRelation(data)
-
- def RelationCreate(self, RelationData):
- """ Creates a relation. Returns updated RelationData (without timestamp). """
- return self._do("create", "relation", RelationData)
-
- def RelationUpdate(self, RelationData):
- """ Updates relation with RelationData. Returns updated RelationData (without timestamp). """
- return self._do("modify", "relation", RelationData)
-
- def RelationDelete(self, RelationData):
- """ Delete relation with RelationData. Returns updated RelationData (without timestamp). """
- return self._do("delete", "relation", RelationData)
-
- def RelationHistory(self, RelationId):
- """ Returns dict(RelationVerrsion: RelationData). """
- uri = "/api/0.6/relation/"+str(RelationId)+"/history"
- data = self._get(uri)
- data = xml.dom.minidom.parseString(data)
- result = {}
- for data in data.getElementsByTagName("osm")[0].getElementsByTagName("relation"):
- data = self._DomParseRelation(data)
- result[data[u"version"]] = data
- return result
-
- def RelationRelations(self, RelationId):
- """ Returns list of RelationData containing relation #RelationId. """
- uri = "/api/0.6/relation/%d/relations"%RelationId
- data = self._get(uri)
- data = xml.dom.minidom.parseString(data)
- result = []
- for data in data.getElementsByTagName("osm")[0].getElementsByTagName("relation"):
- data = self._DomParseRelation(data)
- result.append(data)
- return result
-
- def RelationFullRecur(self, RelationId):
- """ Return full data for relation RelationId. Recurisve version relation of relations. """
- data = []
- todo = [RelationId]
- done = []
- while todo:
- rid = todo.pop(0)
- done.append(rid)
- temp = self.RelationFull(rid)
- for item in temp:
- if item["type"] <> "relation":
- continue
- if item["data"]["id"] in done:
- continue
- todo.append(item["data"]["id"])
- data += temp
- return data
-
- def RelationFull(self, RelationId):
- """ Return full data for relation RelationId as list of {type: node|way|relation, data: {}}. """
- uri = "/api/0.6/relation/"+str(RelationId)+"/full"
- data = self._get(uri)
- return self.ParseOsm(data)
-
- def RelationsGet(self, RelationIdList):
- """ Returns dict(RelationId: RelationData) for each relation in RelationIdList """
- uri = "/api/0.6/relations?relations=" + ",".join([str(x) for x in RelationIdList])
- data = self._get(uri)
- data = xml.dom.minidom.parseString(data)
- result = {}
- for data in data.getElementsByTagName("osm")[0].getElementsByTagName("relation"):
- data = self._DomParseRelation(data)
- result[data[u"id"]] = data
- return result
-
- #######################################################################
- # Changeset #
- #######################################################################
-
- def ChangesetGet(self, ChangesetId):
- """ Returns ChangesetData for changeset #ChangesetId. """
- data = self._get("/api/0.6/changeset/"+str(ChangesetId))
- data = xml.dom.minidom.parseString(data)
- data = data.getElementsByTagName("osm")[0].getElementsByTagName("changeset")[0]
- return self._DomParseChangeset(data)
-
- def ChangesetUpdate(self, ChangesetTags = {}):
- """ Updates current changeset with ChangesetTags. """
- if self._CurrentChangesetId == -1:
- raise Exception, "No changeset currently opened"
- if u"created_by" not in ChangesetTags:
- ChangesetTags[u"created_by"] = self._created_by
- result = self._put("/api/0.6/changeset/"+str(self._CurrentChangesetId), self._XmlBuild("changeset", {u"tag": ChangesetTags}))
- return self._CurrentChangesetId
-
- def ChangesetCreate(self, ChangesetTags = {}):
- """ Opens a changeset. Returns #ChangesetId. """
- if self._CurrentChangesetId:
- raise Exception, "Changeset alreadey opened"
- if u"created_by" not in ChangesetTags:
- ChangesetTags[u"created_by"] = self._created_by
- result = self._put("/api/0.6/changeset/create", self._XmlBuild("changeset", {u"tag": ChangesetTags}))
- self._CurrentChangesetId = int(result)
- return self._CurrentChangesetId
-
- def ChangesetClose(self):
- """ Closes current changeset. Returns #ChangesetId. """
- if not self._CurrentChangesetId:
- raise Exception, "No changeset currently opened"
- result = self._put("/api/0.6/changeset/"+str(self._CurrentChangesetId)+"/close", u"")
- CurrentChangesetId = self._CurrentChangesetId
- self._CurrentChangesetId = 0
- return CurrentChangesetId
-
- def ChangesetUpload(self, ChangesData):
- """ Upload data. ChangesData is a list of dict {type: node|way|relation, action: create|delete|modify, data: {}}. Returns list with updated ids. """
- data = ""
- data += u"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
- data += u"<osmChange version=\"0.6\" generator=\"" + self._created_by + "\">\n"
- for change in ChangesData:
- data += u"<"+change["action"]+">\n"
- change["data"]["changeset"] = self._CurrentChangesetId
- data += self._XmlBuild(change["type"], change["data"], False).decode("utf-8")
- data += u"</"+change["action"]+">\n"
- data += u"</osmChange>"
- data = self._http("POST", "/api/0.6/changeset/"+str(self._CurrentChangesetId)+"/upload", True, data.encode("utf-8"))
- data = xml.dom.minidom.parseString(data)
- data = data.getElementsByTagName("diffResult")[0]
- data = [x for x in data.childNodes if x.nodeType == x.ELEMENT_NODE]
- for i in range(len(ChangesData)):
- if ChangesData[i]["action"] == "delete":
- ChangesData[i]["data"].pop("version")
- else:
- ChangesData[i]["data"]["version"] = int(data[i].getAttribute("new_id"))
- return ChangesData
-
- def ChangesetDownload(self, ChangesetId):
- """ Download data from a changeset. Returns list of dict {type: node|way|relation, action: create|delete|modify, data: {}}. """
- uri = "/api/0.6/changeset/"+str(ChangesetId)+"/download"
- data = self._get(uri)
- return self.ParseOsc(data)
-
- def ChangesetsGet(self, min_lon=None, min_lat=None, max_lon=None, max_lat=None,
- userid=None, username=None,
- closed_after=None, created_before=None,
- only_open=False, only_closed=False):
- """ Returns dict(ChangsetId: ChangesetData) matching all criteria. """
-
- uri = "/api/0.6/changesets"
- params = {}
- if min_lon or min_lat or max_lon or max_lat:
- params["bbox"] = ",".join([str(min_lon),str(min_lat),str(max_lon),str(max_lat)])
- if userid:
- params["user"] = userid
- if username:
- params["display_name"] = username
- if closed_after and not created_before:
- params["time"] = closed_after
- if created_before:
- if not closed_after:
- closed_after = "1970-01-01T00:00:00Z"
- params["time"] = closed_after + "," + created_before
- if only_open:
- params["open"] = 1
- if only_closed:
- params["closed"] = 1
-
- if params:
- uri += "?" + urllib.urlencode(params)
-
- data = self._get(uri)
- data = xml.dom.minidom.parseString(data)
- data = data.getElementsByTagName("osm")[0].getElementsByTagName("changeset")
- result = {}
- for curChangeset in data:
- tmpCS = self._DomParseChangeset(curChangeset)
- result[tmpCS["id"]] = tmpCS
- return result
-
- #######################################################################
- # Other #
- #######################################################################
-
- def Map(self, min_lon, min_lat, max_lon, max_lat):
- """ Download data in bounding box. Returns list of dict {type: node|way|relation, data: {}}. """
- uri = "/api/0.6/map?bbox=%f,%f,%f,%f"%(min_lon, min_lat, max_lon, max_lat)
- data = self._get(uri)
- return self.ParseOsm(data)
-
- #######################################################################
- # Data parser #
- #######################################################################
-
- def ParseOsm(self, data):
- """ Parse osm data. Returns list of dict {type: node|way|relation, data: {}}. """
- data = xml.dom.minidom.parseString(data)
- data = data.getElementsByTagName("osm")[0]
- result = []
- for elem in data.childNodes:
- if elem.nodeName == u"node":
- result.append({u"type": elem.nodeName, u"data": self._DomParseNode(elem)})
- elif elem.nodeName == u"way":
- result.append({u"type": elem.nodeName, u"data": self._DomParseWay(elem)})
- elif elem.nodeName == u"relation":
- result.append({u"type": elem.nodeName, u"data": self._DomParseRelation(elem)})
- return result
-
- def ParseOsc(self, data):
- """ Parse osc data. Returns list of dict {type: node|way|relation, action: create|delete|modify, data: {}}. """
- data = xml.dom.minidom.parseString(data)
- data = data.getElementsByTagName("osmChange")[0]
- result = []
- for action in data.childNodes:
- if action.nodeName == u"#text": continue
- for elem in action.childNodes:
- if elem.nodeName == u"node":
- result.append({u"action":action.nodeName, u"type": elem.nodeName, u"data": self._DomParseNode(elem)})
- elif elem.nodeName == u"way":
- result.append({u"action":action.nodeName, u"type": elem.nodeName, u"data": self._DomParseWay(elem)})
- elif elem.nodeName == u"relation":
- result.append({u"action":action.nodeName, u"type": elem.nodeName, u"data": self._DomParseRelation(elem)})
- return result
-
- #######################################################################
- # Internal http function #
- #######################################################################
-
- def _do(self, action, OsmType, OsmData):
- if self._changesetauto:
- self._changesetautodata.append({"action":action, "type":OsmType, "data":OsmData})
- self._changesetautoflush()
- return None
- else:
- return self._do_manu(action, OsmType, OsmData)
-
- def _do_manu(self, action, OsmType, OsmData):
- if not self._CurrentChangesetId:
- raise Exception, "You need to open a changeset before uploading data"
- if u"timestamp" in OsmData:
- OsmData.pop(u"timestamp")
- OsmData[u"changeset"] = self._CurrentChangesetId
- if action == "create":
- if OsmData.get(u"id", -1) > 0:
- raise Exception, "This "+OsmType+" already exists"
- result = self._put("/api/0.6/"+OsmType+"/create", self._XmlBuild(OsmType, OsmData))
- OsmData[u"id"] = int(result.strip())
- OsmData[u"version"] = 1
- return OsmData
- elif action == "modify":
- result = self._put("/api/0.6/"+OsmType+"/"+str(OsmData[u"id"]), self._XmlBuild(OsmType, OsmData))
- OsmData[u"version"] = int(result.strip())
- return OsmData
- elif action =="delete":
- result = self._delete("/api/0.6/"+OsmType+"/"+str(OsmData[u"id"]), self._XmlBuild(OsmType, OsmData))
- OsmData[u"version"] = int(result.strip())
- OsmData[u"visible"] = False
- return OsmData
-
- def flush(self):
- return self._changesetautoflush(True)
-
- def _changesetautoflush(self, force = False):
- while (len(self._changesetautodata) >= self._changesetautosize) or (force and self._changesetautodata):
- if self._changesetautocpt == 0:
- self.ChangesetCreate(self._changesetautotags)
- self.ChangesetUpload(self._changesetautodata[:self._changesetautosize])
- self._changesetautodata = self._changesetautodata[self._changesetautosize:]
- self._changesetautocpt += 1
- if self._changesetautocpt == self._changesetautomulti:
- self.ChangesetClose()
- self._changesetautocpt = 0
- if self._changesetautocpt and force:
- self.ChangesetClose()
- self._changesetautocpt = 0
- return None
-
- def _http_request(self, cmd, path, auth, send):
- if self._debug:
- path2 = path
- if len(path2) > 50:
- path2 = path2[:50]+"[...]"
- print >>sys.stderr, "%s %s %s"%(time.strftime("%Y-%m-%d %H:%M:%S"),cmd,path2)
- self._conn.putrequest(cmd, path)
- self._conn.putheader('User-Agent', self._created_by)
- if auth:
- self._conn.putheader('Authorization', 'Basic ' + base64.encodestring(self._username + ':' + self._password).strip())
- if send <> None:
- self._conn.putheader('Content-Length', len(send))
- self._conn.endheaders()
- if send:
- self._conn.send(send)
- response = self._conn.getresponse()
- if response.status <> 200:
- payload = response.read().strip()
- if response.status == 410:
- return None
- raise ApiError(response.status, response.reason, payload)
- if self._debug:
- print >>sys.stderr, "%s %s %s done"%(time.strftime("%Y-%m-%d %H:%M:%S"),cmd,path2)
- return response.read()
-
- def _http(self, cmd, path, auth, send):
- i = 0
- while True:
- i += 1
- try:
- return self._http_request(cmd, path, auth, send)
- except ApiError, e:
- if e.status >= 500:
- if i == 5: raise
- if i <> 1: time.sleep(5)
- self._conn = httplib.HTTPConnection(self._api, 80)
- else: raise
- except Exception:
- if i == 5: raise
- if i <> 1: time.sleep(5)
- self._conn = httplib.HTTPConnection(self._api, 80)
-
- def _get(self, path):
- return self._http('GET', path, False, None)
-
- def _put(self, path, data):
- return self._http('PUT', path, True, data)
-
- def _delete(self, path, data):
- return self._http('DELETE', path, True, data)
-
- #######################################################################
- # Internal dom function #
- #######################################################################
-
- def _DomGetAttributes(self, DomElement):
- """ Returns a formated dictionnary of attributes of a DomElement. """
- result = {}
- for k, v in DomElement.attributes.items():
- if k == u"uid" : v = int(v)
- elif k == u"changeset" : v = int(v)
- elif k == u"version" : v = int(v)
- elif k == u"id" : v = int(v)
- elif k == u"lat" : v = float(v)
- elif k == u"lon" : v = float(v)
- elif k == u"open" : v = v=="true"
- elif k == u"visible" : v = v=="true"
- elif k == u"ref" : v = int(v)
- result[k] = v
- return result
-
- def _DomGetTag(self, DomElement):
- """ Returns the dictionnary of tags of a DomElement. """
- result = {}
- for t in DomElement.getElementsByTagName("tag"):
- k = t.attributes["k"].value
- v = t.attributes["v"].value
- result[k] = v
- return result
-
- def _DomGetNd(self, DomElement):
- """ Returns the list of nodes of a DomElement. """
- result = []
- for t in DomElement.getElementsByTagName("nd"):
- result.append(int(int(t.attributes["ref"].value)))
- return result
-
- def _DomGetMember(self, DomElement):
- """ Returns a list of relation members. """
- result = []
- for m in DomElement.getElementsByTagName("member"):
- result.append(self._DomGetAttributes(m))
- return result
-
- def _DomParseNode(self, DomElement):
- """ Returns NodeData for the node. """
- result = self._DomGetAttributes(DomElement)
- result[u"tag"] = self._DomGetTag(DomElement)
- return result
-
- def _DomParseWay(self, DomElement):
- """ Returns WayData for the way. """
- result = self._DomGetAttributes(DomElement)
- result[u"tag"] = self._DomGetTag(DomElement)
- result[u"nd"] = self._DomGetNd(DomElement)
- return result
-
- def _DomParseRelation(self, DomElement):
- """ Returns RelationData for the relation. """
- result = self._DomGetAttributes(DomElement)
- result[u"tag"] = self._DomGetTag(DomElement)
- result[u"member"] = self._DomGetMember(DomElement)
- return result
-
- def _DomParseChangeset(self, DomElement):
- """ Returns ChangesetData for the changeset. """
- result = self._DomGetAttributes(DomElement)
- result[u"tag"] = self._DomGetTag(DomElement)
- return result
-
- #######################################################################
- # Internal xml builder #
- #######################################################################
-
- def _XmlBuild(self, ElementType, ElementData, WithHeaders = True):
-
- xml = u""
- if WithHeaders:
- xml += u"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
- xml += u"<osm version=\"0.6\" generator=\"" + self._created_by + "\">\n"
-
- # <element attr="val">
- xml += u" <" + ElementType
- if u"id" in ElementData:
- xml += u" id=\"" + str(ElementData[u"id"]) + u"\""
- if u"lat" in ElementData:
- xml += u" lat=\"" + str(ElementData[u"lat"]) + u"\""
- if u"lon" in ElementData:
- xml += u" lon=\"" + str(ElementData[u"lon"]) + u"\""
- if u"version" in ElementData:
- xml += u" version=\"" + str(ElementData[u"version"]) + u"\""
- xml += u" visible=\"" + str(ElementData.get(u"visible", True)).lower() + u"\""
- if ElementType in [u"node", u"way", u"relation"]:
- xml += u" changeset=\"" + str(self._CurrentChangesetId) + u"\""
- xml += u">\n"
-
- # <tag... />
- for k, v in ElementData.get(u"tag", {}).items():
- xml += u" <tag k=\""+self._XmlEncode(k)+u"\" v=\""+self._XmlEncode(v)+u"\"/>\n"
-
- # <member... />
- for member in ElementData.get(u"member", []):
- xml += u" <member type=\""+member[u"type"]+"\" ref=\""+str(member[u"ref"])+u"\" role=\""+self._XmlEncode(member[u"role"])+"\"/>\n"
-
- # <nd... />
- for ref in ElementData.get(u"nd", []):
- xml += u" <nd ref=\""+str(ref)+u"\"/>\n"
-
- # </element>
- xml += u" </" + ElementType + u">\n"
-
- if WithHeaders:
- xml += u"</osm>\n"
-
- return xml.encode("utf8")
-
- def _XmlEncode(self, text):
- return text.replace("&", "&amp;").replace("\"", "&quot;").replace("<","&lt;").replace(">","&gt;")
-
-## End of main class ##
-###########################################################################
diff --git a/chimere/external_utils/__init__.py b/chimere/external_utils/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/chimere/external_utils/__init__.py
+++ /dev/null
diff --git a/chimere/forms.py b/chimere/forms.py
index 8691fa6..11fafc9 100644
--- a/chimere/forms.py
+++ b/chimere/forms.py
@@ -121,7 +121,7 @@ def notifyByEmail(subject, body, user_list, sender=None):
def notifySubmission(absolute_uri, geo_object):
- category = u" - ".join([unicode(cat)
+ category = u" - ".join([str(cat)
for cat in geo_object.categories.all()])
subject = u'%s %s' % (_(u"New submission for"), category)
message = _(u'The new item "%s" has been submited in the category: ') % \
@@ -151,6 +151,9 @@ class SubCategoryAdminForm(forms.ModelForm):
'''
description = forms.CharField(widget=FullTextareaWidget, required=False)
+ class Meta:
+ exclude = []
+
class PageAdminForm(forms.ModelForm):
"""
@@ -160,6 +163,7 @@ class PageAdminForm(forms.ModelForm):
class Meta:
model = Page
+ exclude = []
class OSMForm(forms.Form):
@@ -189,6 +193,7 @@ class NewsAdminForm(forms.ModelForm):
class Meta:
model = News
+ exclude = []
class ImporterAdminForm(forms.ModelForm):
@@ -205,6 +210,7 @@ class ImporterAdminForm(forms.ModelForm):
'source': forms.TextInput(attrs={'size': 80}),
'filtr': forms.Textarea(attrs={'size': 80}),
}
+ exclude = []
def clean(self):
'''
@@ -254,6 +260,7 @@ class CategoryAdminForm(forms.ModelForm):
class Meta:
model = Category
+ exclude = []
def get_properties(queryset):
@@ -267,7 +274,7 @@ def get_properties(queryset):
).order_by('value')
fields[key] = forms.ChoiceField(
label=prop.name, choices=[('', '--')] +
- [(choice.pk, unicode(choice)) for choice in choices],
+ [(choice.pk, str(choice)) for choice in choices],
required=False)
elif prop.type == 'A':
widget = PropertyModel.TYPE_WIDGET[prop.type]
@@ -287,12 +294,13 @@ class MarkerAdminFormBase(forms.ModelForm):
Main form for marker
"""
is_admin = True
- name = forms.CharField(_(u"Name"), required=True)
+ name = forms.CharField(label=_(u"Name"), required=True)
description = forms.CharField(widget=TextareaAdminWidget, required=False)
_PROPERTY_FILTERS = {}
class Meta:
model = Marker
+ exclude = []
@classmethod
def _set_cls_fields(cls):
@@ -459,10 +467,11 @@ class RouteAdminForm(forms.ModelForm):
Main form for route
"""
is_admin = True
- name = forms.CharField(_(u"Name"), required=True)
+ name = forms.CharField(label=_(u"Name"), required=True)
class Meta:
model = Route
+ exclude = []
def __init__(self, *args, **keys):
"""
@@ -576,6 +585,7 @@ class PolygonAdminForm(MarkerAdminForm):
"""
class Meta:
model = Polygon
+ exclude = []
class PolygonForm(PolygonAdminForm):
@@ -633,6 +643,7 @@ class BaseFileForm(forms.ModelForm):
class MultimediaFileAdminForm(forms.ModelForm):
class Meta:
model = MultimediaFile
+ exclude = []
class Media:
js = list(settings.JQUERY_JS_URLS) + [
@@ -668,6 +679,7 @@ MultimediaFileFormSet = formset_factory(MultimediaFileForm, can_delete=True)
class PictureFileAdminForm(forms.ModelForm):
class Meta:
model = PictureFile
+ exclude = []
class Media:
js = list(settings.JQUERY_JS_URLS) + [
@@ -719,6 +731,7 @@ class AreaAdminForm(forms.ModelForm):
class Meta:
model = Area
+ exclude = []
def __init__(self, *args, **keys):
"""
@@ -762,7 +775,7 @@ class AreaAdminForm(forms.ModelForm):
q = q.exclude(pk=self.instance.pk)
if q.count():
msg = _(u"The area \"%s\" has the same order, you need to"
- u" choose another one.") % unicode(q.all()[0])
+ u" choose another one.") % str(q.all()[0])
raise forms.ValidationError(msg)
return self.cleaned_data
@@ -800,6 +813,7 @@ class AreaForm(AreaAdminForm):
"""
class Meta:
model = Area
+ exclude = []
CHIMERE_ROUTING_TRANSPORT = []
ROUTING_INIT = None
diff --git a/chimere/management/commands/chimere_import.py b/chimere/management/commands/chimere_import.py
index faddd5e..2f15632 100644
--- a/chimere/management/commands/chimere_import.py
+++ b/chimere/management/commands/chimere_import.py
@@ -1,8 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-import csv
-import datetime, time
+import time
from optparse import make_option
from django.core.management.base import BaseCommand, CommandError
@@ -11,18 +10,19 @@ from django.core.exceptions import ObjectDoesNotExist
from chimere.models import Importer
from chimere import tasks
+
class Command(BaseCommand):
args = '<import_id>'
help = "Launch import from an external source. Import configuration must "\
"be beforehand inserted in the database with the web admin."
option_list = BaseCommand.option_list + (
- make_option('--all',
+ make_option(
+ '--all',
action='store_true',
dest='all',
default=False,
help='Update all imports set to be automatically updated'),
- )
-
+ )
def handle(self, *args, **options):
importers = []
@@ -32,26 +32,27 @@ class Command(BaseCommand):
try:
importers = [Importer.objects.get(pk=int(args[0]))]
except (ValueError, ObjectDoesNotExist):
- raise CommandError("Import with ID '%s' doesn't exist." % \
- args[0])
+ raise CommandError(
+ "Import with ID '%s' doesn't exist." % args[0])
else:
- imports = dict([(imp.pk, imp)
- for imp in Importer.objects.order_by('pk').all()])
+ imports = dict(
+ [(imp.pk, imp)
+ for imp in Importer.objects.order_by('pk').all()])
while not importers:
self.stdout.write('* Choose the import: \n')
for k in imports:
- self.stdout.write(' %s\n' % unicode(imports[k]).encode(
- 'ascii', 'ignore'))
+ self.stdout.write(' %s\n' % str(imports[k]).encode(
+ 'ascii', 'ignore'))
self.stdout.flush()
self.stdout.write('\nImport ID: ')
v = raw_input()
try:
importers = [Importer.objects.get(pk=int(v))]
except (ValueError, ObjectDoesNotExist):
- self.stdout.write("Import with ID '%s' doesn't exist.\n\n" \
+ self.stdout.write("Import with ID '%s' doesn't exist.\n\n"
% v)
for imprt in importers:
- pending_state = unicode(tasks.IMPORT_MESSAGES['import_pending'][0])
+ pending_state = str(tasks.IMPORT_MESSAGES['import_pending'][0])
imprt.state = pending_state
imprt.save()
tasks.importing(imprt.pk)
@@ -62,4 +63,3 @@ class Command(BaseCommand):
time.sleep(1)
state = Importer.objects.get(pk=int(imprt.pk)).state
self.stdout.write(state + '\n')
-
diff --git a/chimere/migrations/0037_recopy_marker_to_route.py b/chimere/migrations/0037_recopy_marker_to_route.py
index 82dbc9d..8d2c8b0 100644
--- a/chimere/migrations/0037_recopy_marker_to_route.py
+++ b/chimere/migrations/0037_recopy_marker_to_route.py
@@ -18,8 +18,8 @@ class Migration(SchemaMigration):
val = getattr(m, attr)
if getattr(route, attr) == val:
continue
- modified.append(u" ".join([m.name, attr, unicode(val),
- unicode(getattr(route, attr))]))
+ modified.append(u" ".join([m.name, attr, str(val),
+ str(getattr(route, attr))]))
setattr(route, attr, val)
for picture in orm['chimere.PictureFile'].objects.filter(
marker=m).all():
diff --git a/chimere/models.py b/chimere/models.py
index 825b4c0..cb69684 100644
--- a/chimere/models.py
+++ b/chimere/models.py
@@ -20,16 +20,17 @@
"""
Models description
"""
-import os
+import copy
import datetime
+import json
+import os
import pyexiv2
import re
-import copy
-import simplejson as json
+
from lxml import etree
from PIL import Image
from subprocess import Popen, PIPE
-from BeautifulSoup import BeautifulSoup
+from bs4 import BeautifulSoup
from django import forms
from django.conf import settings
@@ -54,21 +55,21 @@ from chimere.utils import KMLManager, OSMManager, ShapefileManager, \
class Page(models.Model):
"""Simple extra pages
"""
- title = models.CharField(_(u"Name"), max_length=150)
- mnemonic = models.CharField(_(u"Mnemonic"), max_length=10, blank=True,
+ title = models.CharField(_("Name"), max_length=150)
+ mnemonic = models.CharField(_("Mnemonic"), max_length=10, blank=True,
null=True)
- available = models.BooleanField(_(u"Available"), default=True)
- order = models.IntegerField(_(u"Order"), default=10, blank=True, null=True)
- template_path = models.CharField(_(u"Template path"), max_length=150,
+ available = models.BooleanField(_("Available"), default=True)
+ order = models.IntegerField(_("Order"), default=10, blank=True, null=True)
+ template_path = models.CharField(_("Template path"), max_length=150,
blank=True, null=True)
content = models.TextField(blank=True, null=True)
class Meta:
ordering = ["order"]
- verbose_name = _(u"Page")
- verbose_name_plural = _(u"Page")
+ verbose_name = _("Page")
+ verbose_name_plural = _("Page")
- def __unicode__(self):
+ def __str__(self):
return self.title
@@ -107,22 +108,22 @@ def shortify(text):
class News(models.Model):
"""News of the site
"""
- title = models.CharField(_(u"Name"), max_length=150)
- available = models.BooleanField(_(u"Available"))
- is_front_page = models.NullBooleanField(_(u"Is front page"), blank=True,
+ title = models.CharField(_("Name"), max_length=150)
+ available = models.BooleanField(_("Available"))
+ is_front_page = models.NullBooleanField(_("Is front page"), blank=True,
null=True)
- date = models.DateField(_(u"Date"))
+ date = models.DateField(_("Date"))
content = models.TextField()
- url = models.URLField(_(u"Url"), max_length=200, blank=True, null=True)
- areas = SelectMultipleField('Area', verbose_name=_(u"Associated areas"),
- blank=True, null=True)
+ url = models.URLField(_("Url"), max_length=200, blank=True, null=True)
+ areas = SelectMultipleField('Area', verbose_name=_("Associated areas"),
+ blank=True)
class Meta:
ordering = ["-date"]
- verbose_name = _(u"News")
- verbose_name_plural = _(u"News")
+ verbose_name = _("News")
+ verbose_name_plural = _("News")
- def __unicode__(self):
+ def __str__(self):
return self.title
@property
@@ -133,15 +134,15 @@ class News(models.Model):
class TinyUrl(models.Model):
"""Tinyfied version of permalink parameters
"""
- parameters = models.CharField(_(u"Parameters"), max_length=500,
+ parameters = models.CharField(_("Parameters"), max_length=500,
unique=True)
digits = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
base = len(digits)
class Meta:
- verbose_name = _(u"TinyUrl")
+ verbose_name = _("TinyUrl")
- def __unicode__(self):
+ def __str__(self):
return self.parameters
@classmethod
@@ -167,7 +168,7 @@ class TinyUrl(models.Model):
while 1:
idx = n % cls.base
urn = cls.digits[idx] + urn
- n = n / cls.base
+ n = int(n / cls.base)
if n == 0:
break
return urn
@@ -176,31 +177,31 @@ class TinyUrl(models.Model):
class ColorTheme(models.Model):
"""Color theme
"""
- name = models.CharField(_(u"Name"), max_length=150)
+ name = models.CharField(_("Name"), max_length=150)
class Meta:
- verbose_name = _(u"Color theme")
+ verbose_name = _("Color theme")
- def __unicode__(self):
+ def __str__(self):
return self.name
class Color(models.Model):
"""Color
"""
- code = models.CharField(_(u"Code/name"), max_length=200,
- help_text=_(u"HTML code/name"))
- inner_code = models.CharField(_(u"Code/name (inner)"), max_length=200,
- help_text=_(u"HTML code/name"),
+ code = models.CharField(_("Code/name"), max_length=200,
+ help_text=_("HTML code/name"))
+ inner_code = models.CharField(_("Code/name (inner)"), max_length=200,
+ help_text=_("HTML code/name"),
blank=True, null=True)
- order = models.IntegerField(_(u"Order"))
- color_theme = models.ForeignKey(ColorTheme, verbose_name=_(u"Color theme"))
+ order = models.IntegerField(_("Order"))
+ color_theme = models.ForeignKey(ColorTheme, verbose_name=_("Color theme"))
class Meta:
ordering = ["order"]
- verbose_name = _(u"Color")
+ verbose_name = _("Color")
- def __unicode__(self):
+ def __str__(self):
return self.code
@property
@@ -215,96 +216,96 @@ class Color(models.Model):
class Category(models.Model):
"""Category of Point Of Interest (POI)
"""
- name = models.CharField(_(u"Name"), max_length=150)
- available = models.BooleanField(_(u"Available"))
- order = models.IntegerField(_(u"Order"))
+ name = models.CharField(_("Name"), max_length=150)
+ available = models.BooleanField(_("Available"))
+ order = models.IntegerField(_("Order"))
description = models.TextField(blank=True, null=True)
class Meta:
ordering = ["order"]
- verbose_name = _(u"Category")
+ verbose_name = _("Category")
- def __unicode__(self):
+ def __str__(self):
return self.name
class Icon(models.Model):
'''Icon
'''
- name = models.CharField(_(u"Name"), max_length=150)
- image = models.ImageField(_(u"Image"), upload_to='icons',
+ name = models.CharField(_("Name"), max_length=150)
+ image = models.ImageField(_("Image"), upload_to='icons',
height_field='height', width_field='width')
- height = models.IntegerField(_(u"Height"))
- width = models.IntegerField(_(u"Width"))
+ height = models.IntegerField(_("Height"))
+ width = models.IntegerField(_("Width"))
offset_x = models.IntegerField(
- _(u"Offset x"), default=10,
- help_text=_(u"Common value is half the icon width"))
+ _("Offset x"), default=10,
+ help_text=_("Common value is half the icon width"))
offset_y = models.IntegerField(
- _(u"Offset y"), default=20,
- help_text=_(u"Common value is icon height"))
- popup_offset_x = models.IntegerField(_(u"Popup offset x"), default=0,
- help_text=_(u"Common value is 0"))
+ _("Offset y"), default=20,
+ help_text=_("Common value is icon height"))
+ popup_offset_x = models.IntegerField(_("Popup offset x"), default=0,
+ help_text=_("Common value is 0"))
popup_offset_y = models.IntegerField(
- _(u"Popup offset y"), default=20,
- help_text=_(u"Common value is icon height"))
+ _("Popup offset y"), default=20,
+ help_text=_("Common value is icon height"))
- def __unicode__(self):
+ def __str__(self):
return self.name
class Meta:
- verbose_name = _(u"Icon")
+ verbose_name = _("Icon")
class SubCategory(models.Model):
'''Sub-category
'''
- category = models.ForeignKey(Category, verbose_name=_(u"Category"),
+ category = models.ForeignKey(Category, verbose_name=_("Category"),
related_name='subcategories')
- name = models.CharField(_(u"Name"), max_length=150)
- available = models.BooleanField(_(u"Available"), default=True)
- submission = models.BooleanField(_(u"Available for submission"),
+ name = models.CharField(_("Name"), max_length=150)
+ available = models.BooleanField(_("Available"), default=True)
+ submission = models.BooleanField(_("Available for submission"),
default=True)
- TYPE = (('M', _(u'Marker')),
- ('R', _(u'Route')),
- ('P', _(u'Polygon')),
- ('B', _(u'Both')),)
- item_type = models.CharField(_(u"Item type"), max_length=1, choices=TYPE)
- dated = models.BooleanField(_(u"Is dated"), default=False)
+ TYPE = (('M', _('Marker')),
+ ('R', _('Route')),
+ ('P', _('Polygon')),
+ ('B', _('Both')),)
+ item_type = models.CharField(_("Item type"), max_length=1, choices=TYPE)
+ dated = models.BooleanField(_("Is dated"), default=False)
description = models.TextField(blank=True, null=True)
- icon = models.ForeignKey(Icon, verbose_name=_(u"Icon"))
+ icon = models.ForeignKey(Icon, verbose_name=_("Icon"))
hover_icon = models.ForeignKey(
- Icon, verbose_name=_(u"Hover icon"), blank=True, null=True,
+ Icon, verbose_name=_("Hover icon"), blank=True, null=True,
related_name='subcat_hovered')
- color_theme = models.ForeignKey(ColorTheme, verbose_name=_(u"Color theme"),
+ color_theme = models.ForeignKey(ColorTheme, verbose_name=_("Color theme"),
blank=True, null=True,
related_name='subcategories')
- as_layer = models.BooleanField(_(u"Displayed in the layer menu"),
+ as_layer = models.BooleanField(_("Displayed in the layer menu"),
default=False)
- weight_formula = models.TextField(_(u"Weight formula"), default="",
+ weight_formula = models.TextField(_("Weight formula"), default="",
blank=True, null=True)
- routing_warn = models.BooleanField(_(u"Routing warn"), default=False)
- order = models.IntegerField(_(u"Order"), default=1000)
- keywords = models.TextField(_(u"Keywords"), max_length=200,
+ routing_warn = models.BooleanField(_("Routing warn"), default=False)
+ order = models.IntegerField(_("Order"), default=1000)
+ keywords = models.TextField(_("Keywords"), max_length=200,
blank=True, null=True)
min_zoom = models.IntegerField(
- _(u"Minimum zoom for loading details"), blank=True, null=True,
- help_text=_(u"Optimization when too many data have to be displayed. "
- u"Currently available only for route and polygon."))
+ _("Minimum zoom for loading details"), blank=True, null=True,
+ help_text=_("Optimization when too many data have to be displayed. "
+ "Currently available only for route and polygon."))
simplify_tolerance = models.FloatField(
- _(u"Simplify tolerance for lower zoom"), blank=True, null=True,
- help_text=_(u"Only relevant when Minimum zoom is set. Use the "
- u"Douglas-Peucker algorythm to simplify the geometry when "
- u"details is not alvailable. Adjust to your data volume "
- u"and your performance need. 0.0003 is a good starting "
- u"point. Note: typology is not preserved."))
+ _("Simplify tolerance for lower zoom"), blank=True, null=True,
+ help_text=_("Only relevant when Minimum zoom is set. Use the "
+ "Douglas-Peucker algorythm to simplify the geometry when "
+ "details is not alvailable. Adjust to your data volume "
+ "and your performance need. 0.0003 is a good starting "
+ "point. Note: typology is not preserved."))
class Meta:
ordering = ["category", "order"]
- verbose_name = _(u"Sub-category")
- verbose_name_plural = _(u"Sub-categories")
+ verbose_name = _("Sub-category")
+ verbose_name_plural = _("Sub-categories")
- def __unicode__(self):
- return u"%s / %s" % (self.category.name, self.name)
+ def __str__(self):
+ return "%s / %s" % (self.category.name, self.name)
@classmethod
def getAvailable(cls, item_types=None, area_name=None, public=False,
@@ -351,7 +352,7 @@ class SubCategory(models.Model):
cats = []
for cat, subcats in cls.getAvailable(item_types=item_types,
area_name=area_name):
- cats.append((unicode(cat),
+ cats.append((str(cat),
[(subcat.pk, subcat.name) for subcat in subcats]))
return cats
@@ -402,19 +403,19 @@ class SubCategoryUserLimit(models.Model):
SubCategory, related_name='limited_for_user')
user = models.ForeignKey(User, related_name='subcategory_limit_to')
- def __unicode__(self):
- return u"{} / {}".format(self.user, self.subcategory)
+ def __str__(self):
+ return "{} / {}".format(self.user, self.subcategory)
class Meta:
- verbose_name = _(u"Sub-category limit for user")
- verbose_name_plural = _(u"Sub-category limits for users")
+ verbose_name = _("Sub-category limit for user")
+ verbose_name_plural = _("Sub-category limits for users")
-STATUS = (('S', _(u'Submited')),
- ('A', _(u'Available')),
- ('M', _(u'Modified')),
- ('D', _(u'Disabled')),
- ('I', _(u'Imported')))
+STATUS = (('S', _('Submited')),
+ ('A', _('Available')),
+ ('M', _('Modified')),
+ ('D', _('Disabled')),
+ ('I', _('Imported')))
STATUS_DCT = dict(STATUS)
IMPORTERS = {'KML': KMLManager,
@@ -446,60 +447,60 @@ class Importer(models.Model):
'''
Data importer for a specific subcategory
'''
- importer_type = models.CharField(_(u"Importer type"), max_length=4,
+ importer_type = models.CharField(_("Importer type"), max_length=4,
choices=IMPORTER_CHOICES)
- filtr = models.TextField(_(u"Filter"), blank=True, null=True)
- source = models.CharField(_(u"Web address"), max_length=200,
+ filtr = models.TextField(_("Filter"), blank=True, null=True)
+ source = models.CharField(_("Web address"), max_length=200,
blank=True, null=True,
- help_text=_(u"Don't forget the trailing slash"))
+ help_text=_("Don't forget the trailing slash"))
source_file = models.FileField(
- _(u"Source file"), upload_to='import_files', blank=True, null=True)
+ _("Source file"), upload_to='import_files', blank=True, null=True)
source_file_alt = models.FileField(
- _(u"Alt source file"), upload_to='import_files', blank=True, null=True)
- default_name = models.CharField(_(u"Name by default"), max_length=200,
+ _("Alt source file"), upload_to='import_files', blank=True, null=True)
+ default_name = models.CharField(_("Name by default"), max_length=200,
blank=True, null=True)
- srid = models.IntegerField(_(u"SRID"), blank=True, null=True)
- zipped = models.BooleanField(_(u"Zipped file"), default=False)
- overwrite = models.BooleanField(_(u"Overwrite existing data"),
+ srid = models.IntegerField(_("SRID"), blank=True, null=True)
+ zipped = models.BooleanField(_("Zipped file"), default=False)
+ overwrite = models.BooleanField(_("Overwrite existing data"),
default=False)
- get_description = models.BooleanField(_(u"Get description from source"),
+ get_description = models.BooleanField(_("Get description from source"),
default=False)
- default_description = models.TextField(_(u"Default description"),
+ default_description = models.TextField(_("Default description"),
blank=True, null=True)
- origin = models.CharField(_(u"Origin"), max_length=1000,
+ origin = models.CharField(_("Origin"), max_length=1000,
blank=True, null=True)
- license = models.CharField(_(u"License"), max_length=1000,
+ license = models.CharField(_("License"), max_length=1000,
blank=True, null=True)
categories = SelectMultipleField(
- SubCategory, blank=True, null=True,
- verbose_name=_(u"Associated subcategories"))
- state = models.TextField(_(u"State"), blank=True, null=True)
- automatic_update = models.BooleanField(_(u"Automatically updated"),
+ SubCategory, blank=True,
+ verbose_name=_("Associated subcategories"))
+ state = models.TextField(_("State"), blank=True, null=True)
+ automatic_update = models.BooleanField(_("Automatically updated"),
default=False)
- default_status = models.CharField(_(u"Default status"), max_length=1,
+ default_status = models.CharField(_("Default status"), max_length=1,
choices=STATUS, default='I')
default_localisation = PointField(
- _(u"Default localisation"),
+ _("Default localisation"),
srid=settings.CHIMERE_EPSG_DISPLAY_PROJECTION, blank=True, null=True,
widget=HiddenPointChooserWidget)
class Meta:
- verbose_name = _(u"Importer")
+ verbose_name = _("Importer")
- def __unicode__(self):
+ def __str__(self):
vals = [IMPORTER_CHOICES_DICT[self.importer_type],
self.source, self.source_file.name,
- u", ".join([unicode(cat) for cat in self.categories.all()]),
+ ", ".join([str(cat) for cat in self.categories.all()]),
self.default_name]
- return u' %d: %s' % (self.pk, u" - ".join([unicode(v)
- for v in vals if v]))
+ return ' %d: %s' % (self.pk, " - ".join([str(v)
+ for v in vals if v]))
@property
def manager(self):
return IMPORTERS[self.importer_type](self)
def display_categories(self):
- return u"\n".join([cat.name for cat in self.categories.all()])
+ return "\n".join([cat.name for cat in self.categories.all()])
def get_key_category_dict(self):
dct = {}
@@ -519,65 +520,65 @@ class ImporterKeyCategories(models.Model):
"""
Association between key and categories
"""
- importer = models.ForeignKey(Importer, verbose_name=_(u"Importer"),
+ importer = models.ForeignKey(Importer, verbose_name=_("Importer"),
related_name='key_categories')
- category = models.ForeignKey(SubCategory, verbose_name=_(u"Category"))
- key = models.CharField(_(u"Import key"), max_length=200)
+ category = models.ForeignKey(SubCategory, verbose_name=_("Category"))
+ key = models.CharField(_("Import key"), max_length=200)
class Meta:
- verbose_name = _(u"Importer - Key categories")
+ verbose_name = _("Importer - Key categories")
class GeographicItem(models.Model):
categories = SelectMultipleField(SubCategory)
- name = models.TextField(_(u"Name"))
+ name = models.TextField(_("Name"))
submiter_session_key = models.CharField(
- _(u"Submitter session key"), blank=True, null=True, max_length=40)
- submiter_name = models.CharField(_(u"Submitter name or nickname"),
+ _("Submitter session key"), blank=True, null=True, max_length=40)
+ submiter_name = models.CharField(_("Submitter name or nickname"),
blank=True, null=True, max_length=40)
- submiter_email = models.EmailField(_(u"Submitter email"), blank=True,
+ submiter_email = models.EmailField(_("Submitter email"), blank=True,
null=True)
- submiter_comment = models.TextField(_(u"Submitter comment"),
+ submiter_comment = models.TextField(_("Submitter comment"),
max_length=200, blank=True, null=True)
- status = models.CharField(_(u"Status"), max_length=1, choices=STATUS)
- keywords = models.TextField(_(u"Keywords"), max_length=200, blank=True,
+ status = models.CharField(_("Status"), max_length=1, choices=STATUS)
+ keywords = models.TextField(_("Keywords"), max_length=200, blank=True,
null=True)
- import_key = models.CharField(_(u"Import key"), max_length=200,
+ import_key = models.CharField(_("Import key"), max_length=200,
blank=True, null=True)
- import_version = models.IntegerField(_(u"Import version"),
+ import_version = models.IntegerField(_("Import version"),
blank=True, null=True)
- import_source = models.CharField(_(u"Source"), max_length=200,
+ import_source = models.CharField(_("Source"), max_length=200,
blank=True, null=True)
modified_since_import = models.BooleanField(
- _(u"Modified since last import"), default=True)
- not_for_osm = models.BooleanField(_(u"Not to be exported to OSM"),
+ _("Modified since last import"), default=True)
+ not_for_osm = models.BooleanField(_("Not to be exported to OSM"),
default=False)
- origin = models.CharField(_(u"Origin"), max_length=1000,
+ origin = models.CharField(_("Origin"), max_length=1000,
blank=True, null=True)
- license = models.CharField(_(u"License"), max_length=1000,
+ license = models.CharField(_("License"), max_length=1000,
blank=True, null=True)
start_date = models.DateField(
- _(u"Start date"), blank=True, null=True,
- help_text=_(u"Not mandatory. Set it for dated item such as event. "
- u"Format YYYY-MM-DD"))
+ _("Start date"), blank=True, null=True,
+ help_text=_("Not mandatory. Set it for dated item such as event. "
+ "Format YYYY-MM-DD"))
end_date = models.DateField(
- _(u"End date"), blank=True, null=True,
- help_text=_(u"Not mandatory. Set it only if you have a multi-day "
- u"event. Format YYYY-MM-DD"))
+ _("End date"), blank=True, null=True,
+ help_text=_("Not mandatory. Set it only if you have a multi-day "
+ "event. Format YYYY-MM-DD"))
weight = models.FloatField(
- _(u"Weight"), blank=True, null=True,
+ _("Weight"), blank=True, null=True,
help_text=_(
- u"Weight are used for heatmap and clustering. A formula must "
- u"defined in the associated category."))
+ "Weight are used for heatmap and clustering. A formula must "
+ "defined in the associated category."))
normalised_weight = models.FloatField(
- _(u"Normalised weight"), blank=True, null=True,
- help_text=_(u"The weight normalised to be between 0 and 1. "
- u"Automatically recalculated."))
+ _("Normalised weight"), blank=True, null=True,
+ help_text=_("The weight normalised to be between 0 and 1. "
+ "Automatically recalculated."))
class Meta:
abstract = True
- def __unicode__(self):
+ def __str__(self):
return self.name
def __init__(self, *args, **kwargs):
@@ -637,7 +638,7 @@ class GeographicItem(models.Model):
return properties
def setProperty(self, pm, value):
- u"""
+ """
Set a property
"""
if not hasattr(pm, 'pk'):
@@ -678,9 +679,9 @@ class GeographicItem(models.Model):
Save properties
"""
for propertymodel in PropertyModel.objects.filter(available=True):
- val = u""
- if unicode(propertymodel.id) in values:
- val = values[unicode(propertymodel.id)]
+ val = ""
+ if str(propertymodel.id) in values:
+ val = values[str(propertymodel.id)]
self.setProperty(propertymodel, val)
def get_key(self, key):
@@ -740,7 +741,7 @@ class GeographicItem(models.Model):
dct = {}
# get all property even the one not displayed
for pm in PropertyModel.objects.all():
- dct[pm.slug] = unicode(self.getProperty(pm))
+ dct[pm.slug] = str(self.getProperty(pm))
return dct
def calculate_weight(self, formula):
@@ -811,20 +812,20 @@ class Marker(GeographicItem):
'''Marker for a POI
'''
ref_item = models.ForeignKey(
- "Marker", blank=True, null=True, verbose_name=_(u"Reference marker"),
+ "Marker", blank=True, null=True, verbose_name=_("Reference marker"),
related_name='submited_marker')
- point = PointField(_(u"Localisation"),
+ point = PointField(_("Localisation"),
srid=settings.CHIMERE_EPSG_DISPLAY_PROJECTION)
- available_date = models.DateTimeField(_(u"Available Date"), blank=True,
+ available_date = models.DateTimeField(_("Available Date"), blank=True,
null=True) # used by feeds
- description = models.TextField(_(u"Description"), blank=True, null=True)
- is_front_page = models.NullBooleanField(_(u"Is front page"), blank=True,
+ description = models.TextField(_("Description"), blank=True, null=True)
+ is_front_page = models.NullBooleanField(_("Is front page"), blank=True,
null=True)
objects = models.GeoManager()
class Meta:
ordering = ('status', 'name')
- verbose_name = _(u"Point of interest")
+ verbose_name = _("Point of interest")
@property
def multimedia_items(self):
@@ -885,8 +886,8 @@ class Marker(GeographicItem):
'pk': self.id,
'key': "marker-{}".format(self.id),
'name': self.name,
- 'icon_path': unicode(cat.icon.image),
- 'icon_hover_path': unicode(cat.hover_icon.image)
+ 'icon_path': str(cat.icon.image),
+ 'icon_hover_path': str(cat.hover_icon.image)
if cat.hover_icon else '',
'icon_offset_x': cat.icon.offset_x,
'icon_offset_y': cat.icon.offset_y,
@@ -925,8 +926,8 @@ class Marker(GeographicItem):
except SubCategory.DoesNotExist:
continue
cats[item['categories__pk']] = {
- 'icon_path': unicode(cat.icon.image),
- 'icon_hover_path': unicode(cat.hover_icon.image)
+ 'icon_path': str(cat.icon.image),
+ 'icon_hover_path': str(cat.hover_icon.image)
if cat.hover_icon else '',
'icon_offset_x': cat.icon.offset_x,
'icon_offset_y': cat.icon.offset_y,
@@ -1036,26 +1037,26 @@ class Polygon(GeographicItem):
'''Polygon on the map
'''
ref_item = models.ForeignKey(
- "Polygon", blank=True, null=True, verbose_name=_(u"Reference polygon"),
+ "Polygon", blank=True, null=True, verbose_name=_("Reference polygon"),
related_name='submited_polygon')
polygon = PolygonField(
- _(u"Polygon"), srid=settings.CHIMERE_EPSG_DISPLAY_PROJECTION)
+ _("Polygon"), srid=settings.CHIMERE_EPSG_DISPLAY_PROJECTION)
picture = models.ImageField(
- _(u"Image"), upload_to='upload', blank=True, null=True,
+ _("Image"), upload_to='upload', blank=True, null=True,
height_field='height', width_field='width')
- height = models.IntegerField(_(u"Height"), blank=True, null=True)
- width = models.IntegerField(_(u"Width"), blank=True, null=True)
+ height = models.IntegerField(_("Height"), blank=True, null=True)
+ width = models.IntegerField(_("Width"), blank=True, null=True)
color = models.CharField(
- _(u"Color"), max_length=200, help_text=_(u"HTML code/name"),
+ _("Color"), max_length=200, help_text=_("HTML code/name"),
blank=True, null=True)
inner_color = models.CharField(
- _(u"Inner color"), max_length=200,
- help_text=_(u"HTML code/name"), blank=True, null=True)
+ _("Inner color"), max_length=200,
+ help_text=_("HTML code/name"), blank=True, null=True)
objects = models.GeoManager()
class Meta:
ordering = ('status', 'name')
- verbose_name = _(u"Polygon")
+ verbose_name = _("Polygon")
@property
def geom_attr(self):
@@ -1142,7 +1143,7 @@ class AggregatedPolygon(models.Model):
'''
polygon = models.MultiPolygonField()
subcategory = models.ForeignKey(SubCategory)
- status = models.CharField(_(u"Status"), max_length=1, choices=STATUS)
+ status = models.CharField(_("Status"), max_length=1, choices=STATUS)
class Meta:
managed = False
@@ -1180,28 +1181,28 @@ class AggregatedPolygon(models.Model):
'color': color,
'inner_color': inner_color,
'key': "aggpoly-{}".format(self.pk),
- "pk": self.id, "name": u'Aggregated polygon'}}
+ "pk": self.id, "name": 'Aggregated polygon'}}
return json.dumps(attributes)
class MultimediaType(models.Model):
- MEDIA_TYPES = (('A', _(u"Audio")),
- ('V', _(u"Video")),
- ('I', _(u"Image")),
- ('O', _(u"Other")),)
- media_type = models.CharField(_(u"Media type"), max_length=1,
+ MEDIA_TYPES = (('A', _("Audio")),
+ ('V', _("Video")),
+ ('I', _("Image")),
+ ('O', _("Other")),)
+ media_type = models.CharField(_("Media type"), max_length=1,
choices=MEDIA_TYPES)
- name = models.CharField(_(u"Name"), max_length=150)
- mime_type = models.CharField(_(u"Mime type"), max_length=50, blank=True,
+ name = models.CharField(_("Name"), max_length=150)
+ mime_type = models.CharField(_("Mime type"), max_length=50, blank=True,
null=True)
- iframe = models.BooleanField(_(u"Inside an iframe"), default=False)
- available = models.BooleanField(_(u"Available"), default=True)
+ iframe = models.BooleanField(_("Inside an iframe"), default=False)
+ available = models.BooleanField(_("Available"), default=True)
class Meta:
- verbose_name = _(u"Multimedia type")
- verbose_name_plural = _(u"Multimedia types")
+ verbose_name = _("Multimedia type")
+ verbose_name_plural = _("Multimedia types")
- def __unicode__(self):
+ def __str__(self):
return self.name
@classmethod
@@ -1236,26 +1237,26 @@ IFRAME_LINKS = {
class MultimediaExtension(models.Model):
- name = models.CharField(_(u"Extension name"), max_length=6)
+ name = models.CharField(_("Extension name"), max_length=6)
multimedia_type = models.ForeignKey(
- MultimediaType, verbose_name=_(u"Associated multimedia type"),
+ MultimediaType, verbose_name=_("Associated multimedia type"),
related_name='extensions')
class Meta:
- verbose_name = _(u"Multimedia extension")
- verbose_name_plural = _(u"Multimedia extensions")
+ verbose_name = _("Multimedia extension")
+ verbose_name_plural = _("Multimedia extensions")
- def __unicode__(self):
+ def __str__(self):
return self.name
class MultimediaFile(models.Model):
- name = models.CharField(_(u"Name"), max_length=150)
- url = models.URLField(_(u"Url"), max_length=200)
- order = models.IntegerField(_(u"Order"), default=1)
+ name = models.CharField(_("Name"), max_length=150)
+ url = models.URLField(_("Url"), max_length=200)
+ order = models.IntegerField(_("Order"), default=1)
multimedia_type = models.ForeignKey(MultimediaType, blank=True, null=True)
miniature = models.BooleanField(
- _(u"Display inside the description?"),
+ _("Display inside the description?"),
default=settings.CHIMERE_MINIATURE_BY_DEFAULT)
marker = models.ForeignKey(Marker, related_name='multimedia_files',
blank=True, null=True)
@@ -1265,11 +1266,11 @@ class MultimediaFile(models.Model):
blank=True, null=True)
class Meta:
- verbose_name = _(u"Multimedia file")
- verbose_name_plural = _(u"Multimedia files")
+ verbose_name = _("Multimedia file")
+ verbose_name_plural = _("Multimedia files")
- def __unicode__(self):
- return self.name or u""
+ def __str__(self):
+ return self.name or ""
def multimediafile_post_save(sender, **kwargs):
@@ -1320,22 +1321,22 @@ post_save.connect(multimediafile_post_save, sender=MultimediaFile)
class PictureFile(models.Model):
- name = models.CharField(_(u"Name"), max_length=150)
- picture = models.ImageField(_(u"Image"), upload_to='pictures',
+ name = models.CharField(_("Name"), max_length=150)
+ picture = models.ImageField(_("Image"), upload_to='pictures',
height_field='height', width_field='width')
- height = models.IntegerField(_(u"Height"), blank=True, null=True)
- width = models.IntegerField(_(u"Width"), blank=True, null=True)
+ height = models.IntegerField(_("Height"), blank=True, null=True)
+ width = models.IntegerField(_("Width"), blank=True, null=True)
miniature = models.BooleanField(
- _(u"Display inside the description?"),
+ _("Display inside the description?"),
default=settings.CHIMERE_MINIATURE_BY_DEFAULT)
thumbnailfile = models.ImageField(
- _(u"Thumbnail"), upload_to='pictures', blank=True, null=True,
+ _("Thumbnail"), upload_to='pictures', blank=True, null=True,
height_field='thumbnailfile_height', width_field='thumbnailfile_width')
- thumbnailfile_height = models.IntegerField(_(u"Thumbnail height"),
+ thumbnailfile_height = models.IntegerField(_("Thumbnail height"),
blank=True, null=True)
- thumbnailfile_width = models.IntegerField(_(u"Thumbnail width"),
+ thumbnailfile_width = models.IntegerField(_("Thumbnail width"),
blank=True, null=True)
- order = models.IntegerField(_(u"Order"), default=1)
+ order = models.IntegerField(_("Order"), default=1)
marker = models.ForeignKey(Marker, related_name='pictures', blank=True,
null=True)
route = models.ForeignKey('Route', related_name='pictures',
@@ -1343,12 +1344,12 @@ class PictureFile(models.Model):
polygon = models.ForeignKey(Polygon, related_name='pictures', blank=True,
null=True)
- def __unicode__(self):
- return self.name or u""
+ def __str__(self):
+ return self.name or ""
class Meta:
- verbose_name = _(u"Picture file")
- verbose_name_plural = _(u"Picture files")
+ verbose_name = _("Picture file")
+ verbose_name_plural = _("Picture files")
def scale_image(max_x, pair):
@@ -1363,8 +1364,6 @@ IMAGE_EXIF_ORIENTATION_MAP = {
6: 4,
}
-PYEXIV2_OLD_API = not hasattr(pyexiv2, 'ImageMetadata')
-
def picturefile_post_save(sender, **kwargs):
if not kwargs['instance']:
@@ -1374,23 +1373,14 @@ def picturefile_post_save(sender, **kwargs):
if kwargs['created']:
filename = picturefile.picture.path
metadata, orientation = None, None
- if PYEXIV2_OLD_API:
- metadata = pyexiv2.Image(filename)
- metadata.readMetadata()
- orientation = metadata['Exif.Image.Orientation'] \
- if 'Exif.Image.Orientation' in metadata.exifKeys() else None
- else:
- metadata = pyexiv2.ImageMetadata(filename)
- metadata.read()
- orientation = metadata['Exif.Image.Orientation'].value \
- if 'Exif.Image.Orientation' in metadata else None
+ metadata = pyexiv2.ImageMetadata(filename)
+ metadata.read()
+ orientation = metadata['Exif.Image.Orientation'].value \
+ if 'Exif.Image.Orientation' in metadata else None
if orientation and orientation in IMAGE_EXIF_ORIENTATION_MAP \
and orientation > 1:
metadata['Exif.Image.Orientation'] = 1
- if PYEXIV2_OLD_API:
- metadata.writeMetadata()
- else:
- metadata.write()
+ metadata.write()
im = Image.open(filename)
im = im.transpose(IMAGE_EXIF_ORIENTATION_MAP[orientation])
im.save(filename)
@@ -1444,20 +1434,20 @@ post_save.connect(picturefile_post_save, sender=PictureFile)
class RouteFile(models.Model):
- name = models.CharField(_(u"Name"), max_length=150)
- raw_file = models.FileField(_(u"Raw file (gpx or kml)"),
+ name = models.CharField(_("Name"), max_length=150)
+ raw_file = models.FileField(_("Raw file (gpx or kml)"),
upload_to='route_files')
simplified_file = models.FileField(
- _(u"Simplified file"), upload_to='route_files', blank=True, null=True)
- TYPE = (('K', _(u'KML')), ('G', _(u'GPX')))
+ _("Simplified file"), upload_to='route_files', blank=True, null=True)
+ TYPE = (('K', _('KML')), ('G', _('GPX')))
file_type = models.CharField(max_length=1, choices=TYPE)
class Meta:
ordering = ('name',)
- verbose_name = _(u"Route file")
- verbose_name_plural = _(u"Route files")
+ verbose_name = _("Route file")
+ verbose_name_plural = _("Route files")
- def __unicode__(self):
+ def __str__(self):
return self.name
def process(self):
@@ -1476,7 +1466,7 @@ class RouteFile(models.Model):
p = Popen(cli_args, stderr=PIPE)
p.wait()
if p.returncode:
- print p.stderr.read()
+ print(p.stderr.read())
# logger.error(p.stderr.read())
else:
self.simplified_file = File(open(output_name))
@@ -1495,34 +1485,34 @@ class RouteFile(models.Model):
if not pt.tag.endswith('trkpt'):
continue
pts.append((pt.get("lon"), pt.get("lat")))
- wkt_tpl = u'LINESTRING(%s)'
- return wkt_tpl % u','.join([u'%s %s' % (pt[0], pt[1])
- for pt in pts])
+ wkt_tpl = 'LINESTRING(%s)'
+ return wkt_tpl % ','.join(['%s %s' % (pt[0], pt[1])
+ for pt in pts])
class Route(GeographicItem):
'''Route on the map
'''
ref_item = models.ForeignKey(
- "Route", blank=True, null=True, verbose_name=_(u"Reference route"),
+ "Route", blank=True, null=True, verbose_name=_("Reference route"),
related_name='submited_route')
- route = RouteField(_(u"Route"),
+ route = RouteField(_("Route"),
srid=settings.CHIMERE_EPSG_DISPLAY_PROJECTION)
associated_file = models.ForeignKey(RouteFile, blank=True, null=True,
- verbose_name=_(u"Associated file"))
+ verbose_name=_("Associated file"))
picture = models.ImageField(
- _(u"Image"), upload_to='upload', blank=True, null=True,
+ _("Image"), upload_to='upload', blank=True, null=True,
height_field='height', width_field='width')
- height = models.IntegerField(_(u"Height"), blank=True, null=True)
- width = models.IntegerField(_(u"Width"), blank=True, null=True)
+ height = models.IntegerField(_("Height"), blank=True, null=True)
+ width = models.IntegerField(_("Width"), blank=True, null=True)
color = models.CharField(
- _(u"Color"), max_length=200, help_text=_(u"HTML code/name"),
+ _("Color"), max_length=200, help_text=_("HTML code/name"),
blank=True, null=True)
objects = models.GeoManager()
class Meta:
ordering = ('status', 'name')
- verbose_name = _(u"Route")
+ verbose_name = _("Route")
@property
def geom_attr(self):
@@ -1632,7 +1622,7 @@ class AggregatedRoute(models.Model):
'''
route = models.MultiLineStringField()
subcategory = models.ForeignKey(SubCategory)
- status = models.CharField(_(u"Status"), max_length=1, choices=STATUS)
+ status = models.CharField(_("Status"), max_length=1, choices=STATUS)
class Meta:
managed = False
@@ -1651,7 +1641,7 @@ class AggregatedRoute(models.Model):
'color': color, 'geometry': geom,
'type': "Feature", "properties": {
'key': "aggroute-{}".format(self.pk),
- "pk": self.id, "name": u'Aggregated route'}}
+ "pk": self.id, "name": 'Aggregated route'}}
return json.dumps(attributes)
@@ -1667,14 +1657,17 @@ class SimpleArea:
"""
Rectangular area of a map (not in the database)
"""
- def __init__(self, area):
+ def __init__(self, area=None):
"""
- Defining upper left corner ans lower right corner from a tuple
+ Defining upper left corner and lower right corner from a tuple
"""
+ if not area:
+ return super(SimpleArea, self).__init__()
assert len(area) == 4
x1, y1, x2, y2 = area
self.upper_left_corner = SimplePoint(x1, y1)
self.lower_right_corner = SimplePoint(x2, y2)
+ return super(SimpleArea, self).__init__()
def isIn(self, area):
"""
@@ -1696,7 +1689,7 @@ class SimpleArea:
subcategory_pks = []
for cat, subcats in SubCategory.getAvailable(area_name=area_name):
for subcat in subcats:
- subcategory_pks.append(unicode(subcat.pk))
+ subcategory_pks.append(str(subcat.pk))
if filter_available:
wheres += ['subcat.available = TRUE', 'cat.available = TRUE']
wheres += ['subcat.id in (%s)' % ",".join(subcategory_pks)]
@@ -1707,8 +1700,8 @@ class SimpleArea:
equal_status = "='%s'" % status[0]
elif status:
equal_status = " in ('%s')" % "','".join(status)
- area = u"ST_GeometryFromText('POLYGON((%f %f,%f %f,%f %f,%f %f, %f %f"\
- u"))', %d)" % (
+ area = "ST_GeometryFromText('POLYGON((%f %f,%f %f,%f %f,%f %f, %f %f"\
+ "))', %d)" % (
self.upper_left_corner.x, self.upper_left_corner.y,
self.lower_right_corner.x, self.upper_left_corner.y,
self.lower_right_corner.x, self.lower_right_corner.y,
@@ -1767,20 +1760,20 @@ class SimpleArea:
return subcats
def getExtent(self):
- return (unicode(self.upper_left_corner.x),
- unicode(self.upper_left_corner.y),
- unicode(self.lower_right_corner.x),
- unicode(self.lower_right_corner.y))
+ return (str(self.upper_left_corner.x),
+ str(self.upper_left_corner.y),
+ str(self.lower_right_corner.x),
+ str(self.lower_right_corner.y))
class Layer(models.Model):
- name = models.CharField(_(u"Name"), max_length=150)
- layer_code = models.TextField(_(u"Layer code"))
+ name = models.CharField(_("Name"), max_length=150)
+ layer_code = models.TextField(_("Layer code"))
extra_js_code = models.TextField(
- _(u"Extra JS code"), blank=True, null=True, default='',
- help_text=_(u"This code is loaded before the layer code."))
+ _("Extra JS code"), blank=True, null=True, default='',
+ help_text=_("This code is loaded before the layer code."))
- def __unicode__(self):
+ def __str__(self):
return self.name
class Meta:
@@ -1790,57 +1783,57 @@ class Layer(models.Model):
class Area(models.Model, SimpleArea):
"""Rectangular area of the map
"""
- name = models.CharField(_(u"Name"), max_length=150)
- urn = models.SlugField(_(u"Area urn"), max_length=50, blank=True,
+ name = models.CharField(_("Name"), max_length=150)
+ urn = models.SlugField(_("Area urn"), max_length=50, blank=True,
unique=True)
- welcome_message = models.TextField(_(u"Welcome message"), blank=True,
+ welcome_message = models.TextField(_("Welcome message"), blank=True,
null=True)
- order = models.IntegerField(_(u"Order"), unique=True)
- available = models.BooleanField(_(u"Available"))
+ order = models.IntegerField(_("Order"), unique=True)
+ available = models.BooleanField(_("Available"))
upper_left_corner = models.PointField(
- _(u"Upper left corner"), default='POINT(0 0)',
+ _("Upper left corner"), default='POINT(0 0)',
srid=settings.CHIMERE_EPSG_DISPLAY_PROJECTION)
lower_right_corner = models.PointField(
- _(u"Lower right corner"), default='POINT(0 0)',
+ _("Lower right corner"), default='POINT(0 0)',
srid=settings.CHIMERE_EPSG_DISPLAY_PROJECTION)
default = models.NullBooleanField(
- _(u"Default area"), help_text=_(u"Only one area is set by default"))
+ _("Default area"), help_text=_("Only one area is set by default"))
layers = SelectMultipleField(Layer, related_name='areas',
through='AreaLayers', blank=True)
default_subcategories = SelectMultipleField(
SubCategory, blank=True,
- verbose_name=_(u"Sub-categories checked by default"))
+ verbose_name=_("Sub-categories checked by default"))
dynamic_categories = models.NullBooleanField(
- _(u"Sub-categories dynamicaly displayed"),
- help_text=_(u"If checked, categories are only displayed in the menu "
- u"if they are available on the current extent."))
+ _("Sub-categories dynamicaly displayed"),
+ help_text=_("If checked, categories are only displayed in the menu "
+ "if they are available on the current extent."))
subcategories = SelectMultipleField(
SubCategory, related_name='areas',
blank=True, db_table='chimere_subcategory_areas',
- verbose_name=_(u"Restricted to theses sub-categories"),
- help_text=_(u"If no sub-category is set all sub-categories are "
- u"available"))
+ verbose_name=_("Restricted to theses sub-categories"),
+ help_text=_("If no sub-category is set all sub-categories are "
+ "available"))
display_category_menu = models.BooleanField(
- _(u"Display category menu"), default=True,
- help_text=_(u"If set to False, category menu will be hide and all "
- u"categories will be always displayed."))
- external_css = models.URLField(_(u"Link to an external CSS"), blank=True,
+ _("Display category menu"), default=True,
+ help_text=_("If set to False, category menu will be hide and all "
+ "categories will be always displayed."))
+ external_css = models.URLField(_("Link to an external CSS"), blank=True,
null=True)
- restrict_to_extent = models.BooleanField(_(u"Restrict to the area extent"),
+ restrict_to_extent = models.BooleanField(_("Restrict to the area extent"),
default=False)
- allow_point_edition = models.BooleanField(_(u"Allow point edition"),
+ allow_point_edition = models.BooleanField(_("Allow point edition"),
default=True)
- allow_route_edition = models.BooleanField(_(u"Allow route edition"),
+ allow_route_edition = models.BooleanField(_("Allow route edition"),
default=True)
- allow_polygon_edition = models.BooleanField(_(u"Allow polygon edition"),
+ allow_polygon_edition = models.BooleanField(_("Allow polygon edition"),
default=True)
extra_map_def = models.TextField(
- _(u"Extra map definition"), blank=True, null=True,
- help_text=_(u"Extra javascript script loaded for this area. "
- u"Carreful! To prevent breaking the map must be valid."))
+ _("Extra map definition"), blank=True, null=True,
+ help_text=_("Extra javascript script loaded for this area. "
+ "Carreful! To prevent breaking the map must be valid."))
objects = models.GeoManager()
- def __unicode__(self):
+ def __str__(self):
return self.name
class Meta:
@@ -1984,8 +1977,8 @@ def get_users_by_area(area):
class AreaLayers(models.Model):
area = models.ForeignKey(Area)
layer = models.ForeignKey(Layer)
- order = models.IntegerField(_(u"Order"))
- default = models.NullBooleanField(_(u"Default layer"))
+ order = models.IntegerField(_("Order"))
+ default = models.NullBooleanField(_("Default layer"))
class Meta:
ordering = ('order',)
@@ -1996,21 +1989,20 @@ class AreaLayers(models.Model):
class PropertyModel(models.Model):
'''Model for a property
'''
- name = models.CharField(_(u"Name"), max_length=150)
- slug = models.SlugField(_(u"Slug"), blank=True, null=True)
- order = models.IntegerField(_(u"Order"))
- available = models.BooleanField(_(u"Available"))
- mandatory = models.BooleanField(_(u"Mandatory"))
+ name = models.CharField(_("Name"), max_length=150)
+ slug = models.SlugField(_("Slug"), blank=True, null=True)
+ order = models.IntegerField(_("Order"))
+ available = models.BooleanField(_("Available"))
+ mandatory = models.BooleanField(_("Mandatory"))
subcategories = SelectMultipleField(
SubCategory, related_name='properties',
- blank=True, verbose_name=_(u"Restricted to theses sub-categories"),
- help_text=_(u"If no sub-category is set all the property applies to "
- u"all sub-categories"))
+ blank=True, verbose_name=_("Restricted to theses sub-categories"),
+ help_text=_("If no sub-category is set all the property applies to "
+ "all sub-categories"))
areas = SelectMultipleField(
- 'Area', verbose_name=_(u"Restrict to theses areas"), blank=True,
- null=True,
- help_text=_(u"If no area is set the property apply to "
- u"all areas"))
+ 'Area', verbose_name=_("Restrict to theses areas"), blank=True,
+ help_text=_("If no area is set the property apply to "
+ "all areas"))
TYPE = (('T', _('Text')),
('L', _('Long text')),
('P', _('Password')),
@@ -2027,13 +2019,13 @@ class PropertyModel(models.Model):
'A': JQueryAutoComplete,
'B': forms.CheckboxInput,
}
- type = models.CharField(_(u"Type"), max_length=1, choices=TYPE)
+ type = models.CharField(_("Type"), max_length=1, choices=TYPE)
class Meta:
ordering = ('order',)
verbose_name = _("Property model")
- def __unicode__(self):
+ def __str__(self):
return self.name
def getAttrName(self):
@@ -2064,41 +2056,41 @@ class PropertyModelChoice(models.Model):
'''Choices for property model
'''
propertymodel = models.ForeignKey(PropertyModel, related_name='choices',
- verbose_name=_(u"Property model"))
- value = models.CharField(_(u"Value"), max_length=150)
- available = models.BooleanField(_(u"Available"), default=True)
+ verbose_name=_("Property model"))
+ value = models.CharField(_("Value"), max_length=150)
+ available = models.BooleanField(_("Available"), default=True)
class Meta:
- verbose_name = _(u"Model property choice")
+ verbose_name = _("Model property choice")
- def __unicode__(self):
- return unicode(self.value)
+ def __str__(self):
+ return str(self.value)
class Property(models.Model):
'''Property for a POI
'''
marker = models.ForeignKey(
- Marker, verbose_name=_(u"Point of interest"), blank=True, null=True)
+ Marker, verbose_name=_("Point of interest"), blank=True, null=True)
polygon = models.ForeignKey(
- Polygon, verbose_name=_(u"Polygon"), blank=True, null=True)
+ Polygon, verbose_name=_("Polygon"), blank=True, null=True)
propertymodel = models.ForeignKey(PropertyModel,
- verbose_name=_(u"Property model"))
- value = models.TextField(_(u"Value"))
+ verbose_name=_("Property model"))
+ value = models.TextField(_("Value"))
- def __unicode__(self):
+ def __str__(self):
if self.propertymodel.type == 'C':
if not self.value:
return ''
try:
- return unicode(PropertyModelChoice.objects.get(
+ return str(PropertyModelChoice.objects.get(
pk=self.value).value)
except (self.DoesNotExist, ValueError):
return ""
- return unicode(self.value)
+ return str(self.value)
class Meta:
- verbose_name = _(u"Property")
+ verbose_name = _("Property")
@property
def python_value(self):
diff --git a/chimere/route.py b/chimere/route.py
index 31cf4f0..406d7d9 100644
--- a/chimere/route.py
+++ b/chimere/route.py
@@ -26,7 +26,7 @@ import os
import re
import shutil
import tempfile
-from BeautifulSoup import BeautifulSoup
+from bs4 import BeautifulSoup
from subprocess import Popen, PIPE
from django.contrib.gis.gdal import DataSource
from django.contrib.gis.gdal.error import OGRException
@@ -64,7 +64,7 @@ class RoutinoRouter(Router):
]
if speed:
args += [
- "--speed-%s=%s" % (highway, unicode(speed))
+ "--speed-%s=%s" % (highway, str(speed))
for highway in (
'motorway', 'trunk', 'primary', 'secondary', 'tertiary',
'unclassified', 'residential', 'service', 'track',
diff --git a/chimere/tasks.py b/chimere/tasks.py
index 9eff7f5..01ee113 100644
--- a/chimere/tasks.py
+++ b/chimere/tasks.py
@@ -85,13 +85,13 @@ def importing(importer_pk):
if importer.state != IMPORT_MESSAGES['import_pending'][0]:
# import canceled or done
return
- importer.state = unicode(IMPORT_MESSAGES['import_process'][0])
+ importer.state = str(IMPORT_MESSAGES['import_process'][0])
importer.save()
new_item, updated_item, error = importer.manager.get()
importer.state = error + '\n' if error else ''
- importer.state += unicode(IMPORT_MESSAGES['import_done'][0])
+ importer.state += str(IMPORT_MESSAGES['import_done'][0])
importer.state += \
- u" - " + unicode(IMPORT_MESSAGES['import_done'][1]) % {
+ u" - " + str(IMPORT_MESSAGES['import_done'][1]) % {
'new': new_item, 'updated': updated_item}
importer.state = importer.state
importer.save()
@@ -109,20 +109,20 @@ def exporting(importer_pk, extra_args=[]):
if importer.state != IMPORT_MESSAGES['export_pending'][0]:
# import canceled or done
return
- importer.state = unicode(IMPORT_MESSAGES['export_process'][0])
+ importer.state = str(IMPORT_MESSAGES['export_process'][0])
importer.save()
error = None
try:
updated_item, error = importer.manager.put(extra_args)
- except OsmApi.ApiError, error:
+ except OsmApi.ApiError as error:
pass
if error:
- importer.state = unicode(IMPORT_MESSAGES['export_failed'][0]) \
- + u" - " + unicode(IMPORT_MESSAGES['export_failed'][1]) % error
+ importer.state = str(IMPORT_MESSAGES['export_failed'][0]) \
+ + u" - " + str(IMPORT_MESSAGES['export_failed'][1]) % error
importer.save()
return
- importer.state = unicode(IMPORT_MESSAGES['export_done'][0]) + u" - " \
- + unicode(IMPORT_MESSAGES['export_done'][1]) % {
+ importer.state = str(IMPORT_MESSAGES['export_done'][0]) + u" - " \
+ + str(IMPORT_MESSAGES['export_done'][1]) % {
'updated': updated_item}
importer.save()
return True
diff --git a/chimere/templates/admin/chimere/managed_modified.html b/chimere/templates/admin/chimere/managed_modified.html
index c55650d..6933abb 100644
--- a/chimere/templates/admin/chimere/managed_modified.html
+++ b/chimere/templates/admin/chimere/managed_modified.html
@@ -40,7 +40,7 @@
</table>
</fieldset>
<div class='submit-row'>
-<p class='deletelink-box'><a href="{% if item.point %}{% url admin:chimere_marker_changelist %}{%else%}{% url admin:chimere_route_changelist %}{%endif%}">{% trans "Back to list" %}</a></p>
+<p class='deletelink-box'><a href="{% if item.point %}{% url 'admin:chimere_marker_changelist' %}{%else%}{% url 'admin:chimere_route_changelist' %}{%endif%}">{% trans "Back to list" %}</a></p>
<input class='default' type='submit' value='{% trans "Validate" %}'/>
</div>
</form>
diff --git a/chimere/templates/admin/chimere/marker/change_form.html b/chimere/templates/admin/chimere/marker/change_form.html
index 3b3d238..808d3f8 100644
--- a/chimere/templates/admin/chimere/marker/change_form.html
+++ b/chimere/templates/admin/chimere/marker/change_form.html
@@ -3,7 +3,7 @@
{% block field_sets %}
{% if original.has_modified %}
<p class='errornote'>
-{% url admin:admin-modification object_id as rapprochement_form %}
+{% url 'admin:admin-modification' object_id as rapprochement_form %}
{% blocktrans %}
This item has a reference item associated to it. You should treat it via the <a href='{{ rapprochement_form }}'>rapprochement form</a>.
{% endblocktrans %}
diff --git a/chimere/templates/admin/chimere/osm_export.html b/chimere/templates/admin/chimere/osm_export.html
index dab123e..c6615b6 100644
--- a/chimere/templates/admin/chimere/osm_export.html
+++ b/chimere/templates/admin/chimere/osm_export.html
@@ -24,7 +24,7 @@
</ul>
<p class='errornote'>{% blocktrans %}Ensure that all the data exported to OSM have an appropriate license. You can exclude some points of interest by checking the checkbox "Not to be imported in OSM" in the point of interest form. <strong>If you are not sure of what you are doing: DON'T EXPORT TO OSM</strong>!{% endblocktrans %}</p>
<div class='submit-row'>
-<p class='deletelink-box'><a href="{% if item.point %}{% url admin:chimere_marker_changelist %}{%else%}{% url admin:chimere_route_changelist %}{%endif%}">{% trans "Back to list" %}</a></p>
+<p class='deletelink-box'><a href="{% if item.point %}{% url 'admin:chimere_marker_changelist' %}{%else%}{% url 'admin:chimere_route_changelist' %}{%endif%}">{% trans "Back to list" %}</a></p>
<input class='default' type='submit' value='{% trans "Export to OSM" %}'/>
</div>
</form>
diff --git a/chimere/templates/chimere/blocks/actions.html b/chimere/templates/chimere/blocks/actions.html
index e31e1cc..54accc4 100644
--- a/chimere/templates/chimere/blocks/actions.html
+++ b/chimere/templates/chimere/blocks/actions.html
@@ -33,7 +33,7 @@
<li id='news-lnk'>
<a data-toggle='modal' data-target="#news" href='#' id='news_button'><span class='fa fa-chimere-action fa-newspaper-o'></span><span class='lbl'>{% trans "News"%}</span></a>
</li>
- <!-- <li id="simple_button-lnk"><a id='simple_button' href='{% url chimere:simple_index area_name_slash %}'><span class='fa fa-chimere-action fa-simplybuilt'></span><span class='lbl'> {% trans "Simple map" %}</span></a></li> -->
+ <!-- <li id="simple_button-lnk"><a id='simple_button' href='{% url 'chimere:simple_index' area_name_slash %}'><span class='fa fa-chimere-action fa-simplybuilt'></span><span class='lbl'> {% trans "Simple map" %}</span></a></li> -->
<li class='selection-sep'> </li>
{% endif %}
</ul>
diff --git a/chimere/templates/chimere/blocks/head_chimere.html b/chimere/templates/chimere/blocks/head_chimere.html
index 0554f4c..a33424b 100644
--- a/chimere/templates/chimere/blocks/head_chimere.html
+++ b/chimere/templates/chimere/blocks/head_chimere.html
@@ -24,5 +24,5 @@
EPSG_DISPLAY_PROJECTION, EPSG_PROJECTION);
var restricted_extent;
{% if area_name %}var area_name = '{{ area_name }}';{% endif %}
- var get_share_url = '{% url chimere:get-share-url %}';
+ var get_share_url = '{% url 'chimere:get-share-url' %}';
</script>
diff --git a/chimere/templates/chimere/blocks/share_bar.html b/chimere/templates/chimere/blocks/share_bar.html
index 5367628..9e91a3a 100644
--- a/chimere/templates/chimere/blocks/share_bar.html
+++ b/chimere/templates/chimere/blocks/share_bar.html
@@ -11,7 +11,7 @@
$(function(){
$('.share_link').click(function(){
var href = $(this).attr('href');
- var url = '{% url chimere:get-share-url %}';
+ var url = '{% url 'chimere:get-share-url' %}';
var classes = $(this).attr('class').split(' ');
prefix = 'share_id_';
var share_id;
diff --git a/chimere/templates/chimere/category_item_detail.html b/chimere/templates/chimere/category_item_detail.html
index 284dfd0..2984a47 100644
--- a/chimere/templates/chimere/category_item_detail.html
+++ b/chimere/templates/chimere/category_item_detail.html
@@ -27,7 +27,7 @@
{% if marker.license %}<p class='detail_license'><strong>{% trans "License:" %}</strong> <span>{{marker.license}}</span></p>{% endif %}
{% share_bar marker.name %}
<a href="{% get_tinyfied_url marker area_name %}">{% trans "See on the map" %}</a>
- <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:editmarker-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:editmarker-item' area_name_slash|default_if_none:"" marker.pk "" %}{%endif%}'>
{% trans "Submit an amendment" %}
</a>
{% if moderator_emails %}
diff --git a/chimere/templates/chimere/detail.html b/chimere/templates/chimere/detail.html
index 93388b5..c7a56ec 100644
--- a/chimere/templates/chimere/detail.html
+++ b/chimere/templates/chimere/detail.html
@@ -31,7 +31,7 @@
</p>{% endif %}
</div>
{% share_bar marker.name %}
- <p class='detail_amendment'><a href='{% if marker.polygon %}{% url chimere:editpolygon-item area_name_slash|default_if_none:"" marker.pk "" %}{% else %}{% if marker.route %}{% url chimere:editroute-item area_name_slash|default_if_none:"" marker.pk "" %}{% else %}{% url chimere:editmarker-item area_name_slash|default_if_none:"" marker.pk "" %}{% endif %}{% endif %}'>
+ <p class='detail_amendment'><a href='{% if marker.polygon %}{% url 'chimere:editpolygon-item' area_name_slash|default_if_none:"" marker.pk "" %}{% else %}{% if marker.route %}{% url 'chimere:editroute-item' area_name_slash|default_if_none:"" marker.pk "" %}{% else %}{% url 'chimere:editmarker-item' area_name_slash|default_if_none:"" marker.pk "" %}{% endif %}{% endif %}'>
{% trans "Submit an amendment" %}
</a>
{% if moderator_emails %}
diff --git a/chimere/templates/chimere/edit.html b/chimere/templates/chimere/edit.html
index 869510a..e416458 100644
--- a/chimere/templates/chimere/edit.html
+++ b/chimere/templates/chimere/edit.html
@@ -1,5 +1,5 @@
{% extends "chimere/base.html" %}
-{% load i18n chimere_tags adminmedia inline_formset%}
+{% load i18n chimere_tags inline_formset staticfiles %}
{% block extra_head %}
{{ form.media }}
{{ block.super }}
@@ -8,7 +8,7 @@
<!--script type="text/javascript" src="{{extra_url}}media/js/core.js"></script-->
<script type="text/javascript" src="{{ STATIC_URL }}chimere/js/utils.js"></script>
<script type="text/javascript">
- window.__admin_media_prefix__ = "{% filter escapejs %}{% admin_media_prefix %}{% endfilter %}";
+ window.__admin_media_prefix__ = "{% filter escapejs %}{% static 'admin' %}{% endfilter %}";
</script>
{% endif %}
{% endblock %}
diff --git a/chimere/templates/chimere/edit_marker.html b/chimere/templates/chimere/edit_marker.html
index c3e4fa2..04dc06c 100644
--- a/chimere/templates/chimere/edit_marker.html
+++ b/chimere/templates/chimere/edit_marker.html
@@ -1,5 +1,5 @@
{% extends "chimere/edit.html" %}
-{% load i18n chimere_tags adminmedia inline_formset%}
+{% load i18n chimere_tags inline_formset%}
{% block legend %}<legend>{% if is_modification %}{% trans "Modify a point of interest" %}{% else %}{% trans "Add a point of interest" %}{% endif %}</legend>{% endblock %}
diff --git a/chimere/templates/chimere/upload_file.html b/chimere/templates/chimere/upload_file.html
index 91a1444..638d4a1 100644
--- a/chimere/templates/chimere/upload_file.html
+++ b/chimere/templates/chimere/upload_file.html
@@ -23,7 +23,7 @@
{% if gpx_id %}
<script type="text/javascript"><!--
jQuery(document).ready(function() {
- jQuery.get("{% url chimere:process_route_file gpx_id %}", function(data) {
+ jQuery.get("{% url 'chimere:process_route_file' gpx_id %}", function(data) {
var data = eval(data);
var main_page = opener.document;
jQuery(main_page).find("#id_route").val(data.wkt);
diff --git a/chimere/templatetags/chimere_tags.py b/chimere/templatetags/chimere_tags.py
index 460a6f8..7765452 100644
--- a/chimere/templatetags/chimere_tags.py
+++ b/chimere/templatetags/chimere_tags.py
@@ -287,8 +287,8 @@ def map(context, map_id='map'):
if not context_data['checked_categories']:
cat = ''
if SubCategory.objects.filter(available=True).count():
- cat = unicode(SubCategory.objects.filter(available=True
- ).all()[0].pk)
+ cat = str(SubCategory.objects.filter(
+ available=True).all()[0].pk)
context_data['checked_categories'] = cat
context_data['dynamic_categories'] = \
'true' if area and area.dynamic_categories else 'false'
diff --git a/chimere/templatetags/sanitize.py b/chimere/templatetags/sanitize.py
index ccb936c..75df318 100644
--- a/chimere/templatetags/sanitize.py
+++ b/chimere/templatetags/sanitize.py
@@ -2,11 +2,12 @@
# -*- coding: utf-8 -*-
from django import template
-from BeautifulSoup import BeautifulSoup, Comment
+from bs4 import BeautifulSoup, Comment
import re
register = template.Library()
+
def sanitize(value, allowed_tags):
"""Argument should be in form 'tag2:attr1:attr2 tag2:attr1 tag3', where tags
are allowed HTML tags, and attrs are the allowed attributes for that tag.
@@ -23,9 +24,9 @@ def sanitize(value, allowed_tags):
if tag.name not in allowed_tags:
tag.hidden = True
else:
- tag.attrs = [(attr, js_regex.sub('', val)) for attr, val in tag.attrs
- if attr in allowed_tags[tag.name]]
+ tag.attrs = {
+ attr: js_regex.sub('', tag.attrs[attr]) for attr in tag.attrs
+ if attr in allowed_tags[tag.name]}
return soup.renderContents().decode('utf8')
register.filter(sanitize)
-
diff --git a/chimere/templatetags/unlocalize_point.py b/chimere/templatetags/unlocalize_point.py
index f52a90a..bbcd722 100644
--- a/chimere/templatetags/unlocalize_point.py
+++ b/chimere/templatetags/unlocalize_point.py
@@ -2,15 +2,14 @@
# -*- coding: utf-8 -*-
from django import template
-import re
register = template.Library()
+
def unlocalize_point(value):
"""
Basic unlocalize filter for django 1.2
"""
- return unicode(value).replace(',', '.')
+ return str(value).replace(',', '.')
register.filter(unlocalize_point)
-
diff --git a/chimere/tests.py b/chimere/tests.py
index 71fa12b..90e6143 100644
--- a/chimere/tests.py
+++ b/chimere/tests.py
@@ -137,7 +137,7 @@ class ImporterTest:
self.assertEqual(
nb, awaited_nb,
msg=u"{}: get test failed - got {} when {} was awaited - {}"
- .format(unicode(self.__class__), nb, awaited_nb, res))
+ .format(str(self.__class__), nb, awaited_nb, res))
self.assertEqual(nb_updated, 0)
for cat in importer.categories.all():
if cat not in nb_by_cat:
@@ -150,7 +150,7 @@ class ImporterTest:
self.assertEqual(
nb_by_cat[cat], nb,
msg=u"{} - category association test failed: {}/{}".format(
- unicode(cat), nb, nb_by_cat[cat]))
+ str(cat), nb, nb_by_cat[cat]))
# update
for importer, awaited_nb in self.marker_importers:
importer.overwrite = True
@@ -161,7 +161,7 @@ class ImporterTest:
self.assertEqual(
nb, 0,
msg=u"{}: update test failed - new items have been add"
- .format(unicode(self.__class__)))
+ .format(str(self.__class__)))
# TODO: v3 - retablir overwrite
"""
# manage overwrite
@@ -188,7 +188,7 @@ class ImporterTest:
continue
self.assertEqual(
nb, 1, msg=u"%s: overwrite test failed" %
- unicode(self.__class__))"""
+ str(self.__class__))"""
class KMLImporterTest(TestCase, ImporterTest):
@@ -410,14 +410,14 @@ class AdminTest(AdministratorsTest):
self.client.post(
'/admin/chimere/marker/',
data={'action': ['disable'],
- '_selected_action': [unicode(m.pk) for m in self.markers],
+ '_selected_action': [str(m.pk) for m in self.markers],
})
self.assertEqual(q_markers.count(),
q_markers.filter(status='D').count())
# validate
self.client.post('/admin/chimere/marker/',
data={'action': ['validate'],
- '_selected_action': [unicode(m.pk)
+ '_selected_action': [str(m.pk)
for m in self.markers]
})
self.assertEqual(q_markers.count(),
@@ -613,7 +613,7 @@ class RapprochementTest(TestCase):
'/admin/chimere/marker/',
data={'action': ['managed_modified'],
'index': 0, 'rapprochement': 1, 'name': 1, 'point': 1,
- '_selected_action': [unicode(ref_marker.pk)]})
+ '_selected_action': [str(ref_marker.pk)]})
ref_marker = Marker.objects.get(pk=ref_marker.pk)
self.assertEqual(Marker.objects.filter(ref_item=ref_marker,
status='M').count(), 0)
@@ -634,7 +634,7 @@ class RapprochementTest(TestCase):
data={'action': ['managed_modified'],
'index': 0, 'rapprochement': 1,
'name': 1, 'point': 1,
- '_selected_action': [unicode(ref_marker.pk)]
+ '_selected_action': [str(ref_marker.pk)]
})
ref_marker = Marker.objects.get(pk=ref_marker.pk)
self.assertEqual(Marker.objects.filter(ref_item=ref_marker,
@@ -654,7 +654,7 @@ class RapprochementTest(TestCase):
data={'action': ['managed_modified'],
'index': 0, 'rapprochement': 1,
'name': 1, 'route': 1, 'categories': 1,
- '_selected_action': [unicode(ref_route.pk)]
+ '_selected_action': [str(ref_route.pk)]
})
ref_route = Route.objects.get(pk=ref_route.pk)
self.assertEqual(Route.objects.filter(ref_item=ref_route,
diff --git a/chimere/urls.py b/chimere/urls.py
index 966ef4f..a956e44 100644
--- a/chimere/urls.py
+++ b/chimere/urls.py
@@ -18,7 +18,7 @@
# See the file COPYING for details.
from django.conf import settings
-from django.conf.urls.defaults import *
+from django.conf.urls import patterns, url
from django.contrib import admin
from django.core.exceptions import ImproperlyConfigured
admin.autodiscover()
diff --git a/chimere/utils.py b/chimere/utils.py
index bd09b9e..37c580f 100644
--- a/chimere/utils.py
+++ b/chimere/utils.py
@@ -25,16 +25,17 @@ import csv
import collections
import datetime
import feedparser
+import io
import json
import os
import re
-import StringIO
import tempfile
-import urllib2
+import urllib
import unicodedata
import zipfile
from osgeo import ogr, osr
+from osmapi import OsmApi
from lxml import etree
from django.conf import settings
@@ -45,12 +46,9 @@ from django.shortcuts import render_to_response
from django.utils.translation import ugettext_lazy as _
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) not in ('Mn', 'Sm', 'Sc')))
@@ -82,7 +80,7 @@ class ImportManager(object):
key='', pk=None, category=None):
from models import PropertyModel
updated, created, item = False, False, None
- import_key = unicode(import_key).replace(':', '^')
+ import_key = str(import_key).replace(':', '^')
if not values.get('name'):
values['name'] = self.default_name
if not key:
@@ -199,16 +197,16 @@ class ImportManager(object):
url = source
if extra_url:
url += extra_url
- remotehandle = urllib2.urlopen(url)
- source = StringIO.StringIO(remotehandle.read())
+ remotehandle = urllib.request.urlopen(url)
+ source = io.StringIO(remotehandle.read())
remotehandle.close()
except ValueError:
# assume it is a local file
try:
source = open(source)
- except IOError, msg:
+ except IOError as msg:
return (None, msg)
- except (urllib2.URLError, AttributeError) as error:
+ except (urllib.error.URLError, AttributeError) as error:
return (None, error.message)
if self.importer_instance.zipped:
try:
@@ -256,7 +254,7 @@ class KMLManager(ImportManager):
for idx, line in enumerate(splitted):
if line.strip():
break
- doc = StringIO.StringIO("\n".join(splitted[idx:]))
+ doc = io.StringIO("\n".join(splitted[idx:]))
try:
tree = etree.parse(doc)
except:
@@ -319,7 +317,7 @@ class KMLManager(ImportManager):
def export(cls, queryset):
dct = {
'name': settings.PROJECT_NAME,
- 'description': unicode(datetime.date.today()),
+ 'description': str(datetime.date.today()),
'locations': queryset.all()
}
filename = unicode_normalize(settings.PROJECT_NAME + dct['description']
@@ -444,10 +442,10 @@ class ShapefileManager(ImportManager):
for k in filtr:
val = feat.get(k)
try:
- val = unicode(val)
+ val = str(val)
except UnicodeDecodeError:
try:
- val = unicode(
+ val = str(
val.decode(settings.CHIMERE_SHAPEFILE_ENCODING))
except:
continue
@@ -482,7 +480,7 @@ class ShapefileManager(ImportManager):
@classmethod
def export(cls, queryset):
- date = unicode(datetime.date.today())
+ date = str(datetime.date.today())
tmp = tempfile.NamedTemporaryFile(suffix='.shp', mode='w+b')
tmp.close()
@@ -496,7 +494,7 @@ class ShapefileManager(ImportManager):
dr = ogr.GetDriverByName('ESRI Shapefile')
ds = dr.CreateDataSource(tmp_name)
if ds is None:
- raise Exception(_(u'Could not create file!'))
+ raise Exception(_('Could not create file!'))
ogr_type = OGRGeomType(geo_field.geom_type).num
srs = osr.SpatialReference()
srs.ImportFromEPSG(geo_field.srid)
@@ -507,7 +505,7 @@ class ShapefileManager(ImportManager):
field_defn = ogr.FieldDefn(str(field_name), ogr.OFTString)
field_defn.SetWidth(255)
if layer.CreateField(field_defn) != 0:
- raise Exception(_(u'Failed to create field'))
+ raise Exception(_('Failed to create field'))
feature_def = layer.GetLayerDefn()
@@ -536,7 +534,7 @@ class ShapefileManager(ImportManager):
# writing to a zip file
filename = unicode_normalize(settings.PROJECT_NAME) + '-' + date
- buff = StringIO.StringIO()
+ buff = io.StringIO()
zip_file = zipfile.ZipFile(buff, 'w', zipfile.ZIP_DEFLATED)
suffixes = ['shp', 'shx', 'prj', 'dbf']
for suffix in suffixes:
@@ -632,7 +630,7 @@ class CSVManager(ImportManager):
@classmethod
def export(cls, queryset):
- dct = {'description': unicode(datetime.date.today()), 'data': []}
+ dct = {'description': str(datetime.date.today()), 'data': []}
# cls_name = queryset.model.__name__.lower()
cols = list(cls.COLS)
for pm in queryset.model.all_properties():
@@ -714,7 +712,7 @@ class GeoRSSManager(ImportManager):
points = item['georss_line'].split(' ')
reordered_points = []
# lat, lon -> x, y
- for idx in xrange(len(points) / 2):
+ for idx in range(len(points) / 2):
reordered_points.append("%s %s" % (points[idx * 2 + 1],
points[idx * 2]))
dct['route'] = 'SRID=4326;LINESTRING(%s)' % \
@@ -829,7 +827,7 @@ class JsonManager(ImportManager):
dct[key] += filtr[k]
cls = Marker
pl_id = (dct.pop('id') if 'id' in dct else dct['name']) \
- + "-" + unicode(self.importer_instance.pk)
+ + "-" + str(self.importer_instance.pk)
it, updated, created = self.create_or_update_item(cls, dct, pl_id)
if updated:
updated_item += 1
@@ -901,9 +899,9 @@ class OSMManager(ImportManager):
dct = {'route': wkt,
'name': name,
'origin': self.importer_instance.origin
- or u'OpenStreetMap.org',
+ or 'OpenStreetMap.org',
'license': self.importer_instance.license
- or u'ODbL',
+ or 'ODbL',
'import_version': version}
item, updated, created = self.create_or_update_item(
Route, dct, node_id, version)
@@ -932,9 +930,9 @@ class OSMManager(ImportManager):
dct = {'point': point,
'name': name,
'origin': self.importer_instance.origin
- or u'OpenStreetMap.org',
+ or 'OpenStreetMap.org',
'license': self.importer_instance.license
- or u'ODbL',
+ or 'ODbL',
'import_version': version}
item, updated, created = self.create_or_update_item(
Marker, dct, node_id, version)
@@ -1022,7 +1020,7 @@ class OSMManager(ImportManager):
dct['version'] = item.import_version
node = api.NodeUpdate(dct)
updated = True
- except OsmApi.ApiError, error:
+ except OsmApi.ApiError as error:
if error.status == 404:
dct.pop('id')
dct.pop('version')
@@ -1039,8 +1037,8 @@ class OSMManager(ImportManager):
import chardet
-import HTMLParser
-from BeautifulSoup import BeautifulSoup
+from html.parser import HTMLParser
+from bs4 import BeautifulSoup
RE_CLEANS = ((re.compile('(\n)*|^( )*(\n)*( )*|( )*(\n)*( )*$'), ''),
@@ -1049,25 +1047,18 @@ RE_CLEANS = ((re.compile('(\n)*|^( )*(\n)*( )*|( )*(\n)*( )*$'), ''),
'<a href="%(base_url)s\\1"'),
)
-from calendar import TimeEncoding, month_name
+from calendar import month_name, different_locale
def get_month_name(month_no, locale):
- with TimeEncoding(locale) as encoding:
- s = month_name[month_no]
- if encoding is not None:
- s = s.decode(encoding)
- return s
+ with different_locale(locale):
+ return month_name[month_no]
MONTH_NAMES = {locale: [get_month_name(no_month, locale + '.UTF-8')
- for no_month in xrange(1, 13)] for locale in ['fr_FR']}
+ for no_month in range(1, 13)] for locale in ['fr_FR']}
-try:
- UNI_MONTH_NAMES = {locale: [m.decode('utf-8') for m in MONTH_NAMES[locale]]
- for locale in MONTH_NAMES}
-except UnicodeEncodeError:
- UNI_MONTH_NAMES = {locale: [m for m in MONTH_NAMES[locale]]
- for locale in MONTH_NAMES}
+UNI_MONTH_NAMES = {locale: [m for m in MONTH_NAMES[locale]]
+ for locale in MONTH_NAMES}
DATE_PARSINGS = {
'fr_FR': [
@@ -1127,9 +1118,9 @@ class HtmlXsltManager(ImportManager):
from models import Marker
self.marker_cls = Marker
try:
- main_page = urllib2.urlopen(self.importer_instance.source)
+ main_page = urllib.request.urlopen(self.importer_instance.source)
assert main_page.getcode() == 200
- except (urllib2.URLError, AssertionError):
+ except (urllib.error.URLError, AssertionError):
return (0, 0, _(u"Source page is unreachable."))
data = main_page.read()
encoding = chardet.detect(data)
@@ -1159,7 +1150,7 @@ class HtmlXsltManager(ImportManager):
except (etree.XSLTParseError, etree.XMLSyntaxError, TypeError):
return (0, 0,
_(u"The alt source file is not a valid XSLT file."))
- base_url = u"/".join(self.importer_instance.source.split(u'/')[:-1])
+ base_url = u"/".join(self.importer_instance.source.split('/')[:-1])
base_url += u"/"
for item in newdom.getroot():
c_item = {child.tag: clean_field(child.text)
@@ -1171,9 +1162,9 @@ class HtmlXsltManager(ImportManager):
not c_item['link'].startswith('https://'):
c_item['link'] = base_url + c_item['link']
try:
- child_page = urllib2.urlopen(c_item['link'])
+ child_page = urllib.request.urlopen(c_item['link'])
assert child_page.getcode() == 200
- except (urllib2.URLError, AssertionError):
+ except (urllib.error.URLError, AssertionError):
# don't stop the export for a bad link
items.append(c_item)
continue
@@ -1188,7 +1179,7 @@ class HtmlXsltManager(ImportManager):
for extra in extra_keys[0].getchildren()})
items.append(c_item)
# change relative link to full link, simplify, unescape HTML entities
- html_unescape = HTMLParser.HTMLParser().unescape
+ html_unescape = HTMLParser().unescape
for item in items:
for k in item:
val = item[k]
@@ -1205,7 +1196,7 @@ class HtmlXsltManager(ImportManager):
msg = _(
u"Names \"%s\" doesn't match existing categories. "
u"Modify the import to match theses names with categories.") %\
- (u'", "'.join(self.missing_cats))
+ ('", "'.join(self.missing_cats))
return (self.new_item, self.updated_item, msg)
@classmethod
@@ -1338,17 +1329,17 @@ class IcalManager(ImportManager):
dct = default_dct.copy()
dct['name'] = event.get('SUMMARY', '')
if dct['name']:
- dct['name'] = unicode(dct['name'])
+ dct['name'] = str(dct['name'])
dct['description'] = event.get('DESCRIPTION', '')
if dct['description']:
- dct['description'] = unicode(dct['description'])
+ dct['description'] = str(dct['description'])
loc = event.get('LOCATION', None)
if loc:
- dct['description'] += u"<br/>{}".format(unicode(loc))
+ dct['description'] += u"<br/>{}".format(str(loc))
url = event.get('URL', None)
if url:
dct['description'] += u"<br/><a href='{}'>{}</a>".format(
- unicode(url), unicode(_(u'Link')))
+ str(url), unicode(_('Link')))
dct['start_date'] = event.get('DTSTART', None)
if dct['start_date']:
dct['start_date'] = event.decoded('DTSTART')
@@ -1366,8 +1357,8 @@ class IcalManager(ImportManager):
cls = Marker
pl_id = event.get('UID', None)
if not pl_id:
- pl_id = dct['name'] + "-" + unicode(self.importer_instance.pk)
- pl_id += "-" + unicode(self.importer_instance.pk)
+ pl_id = dct['name'] + "-" + str(self.importer_instance.pk)
+ pl_id += "-" + str(self.importer_instance.pk)
it, updated, created = self.create_or_update_item(cls, dct, pl_id)
if updated:
updated_item += 1
diff --git a/chimere/views.py b/chimere/views.py
index 8de3b1d..0866c90 100644
--- a/chimere/views.py
+++ b/chimere/views.py
@@ -23,20 +23,20 @@ Views of the project
import datetime
from itertools import groupby
+import json
import re
from django.conf import settings
from django.contrib.gis.geos import GEOSGeometry, Polygon as GEOSPolygon
from django.contrib.gis.gdal.error import OGRException
from django.contrib.gis.measure import D
-from django.contrib.sites.models import get_current_site
+from django.contrib.sites.shortcuts import get_current_site
from django.core.exceptions import ObjectDoesNotExist
from django.core.urlresolvers import reverse
from django.db.models import Q
from django.http import HttpResponseRedirect, HttpResponse, Http404
from django.shortcuts import get_object_or_404, redirect, render_to_response
from django.template import RequestContext, defaultfilters
-from django.utils import simplejson as json
from django.utils.http import urlquote
from django.utils.translation import ugettext as _
from django.views.generic import TemplateView, ListView
@@ -134,8 +134,8 @@ def getShareNetwork(request, area_name='', marker=None):
"""
parameters = ""
if marker:
- parameters = u'current_feature=%d' % marker.pk
- parameters += u"&checked_categories=%s" % "_".join(
+ parameters = 'current_feature=%d' % marker.pk
+ parameters += "&checked_categories=%s" % "_".join(
[str(m.id) for m in marker.categories.all()])
net_dct = getTinyfiedUrl(request, parameters, area_name)
share_networks = []
@@ -237,7 +237,7 @@ def get_edit_page(redirect_url, item_cls, item_form,
if subcategories:
for cat, subcats in subcategories:
listed_subcats.append(
- (unicode(cat),
+ (str(cat),
[(subcat.pk, subcat.name) for subcat in subcats]))
# if an item_id is provided: modification
init_item, ref_item = None, None
@@ -319,8 +319,8 @@ def get_edit_page(redirect_url, item_cls, item_form,
item.ref_item.pk, 'submited'), None, subcategories
else:
response_dct['error_message'] = _(
- u"There are missing field(s)"
- u" and/or errors in the submited form.")
+ "There are missing field(s)"
+ " and/or errors in the submited form.")
else:
form = item_form(instance=init_item, subcategories=listed_subcats,
area_name=area_name)
@@ -360,7 +360,7 @@ def uploadFile(request, category_id='', area_name=''):
if category_id:
try:
category = SubCategory.objects.get(pk=category_id)
- response_dct['category'] = unicode(category)
+ response_dct['category'] = str(category)
except:
pass
# If the form has been submited
@@ -382,7 +382,7 @@ def uploadFile(request, category_id='', area_name=''):
routefile.process()
if not routefile.route:
response_dct['errors'] = _(
- u"Bad file. Please check it with an external software.")
+ "Bad file. Please check it with an external software.")
response_dct.update({'form': form})
return render_to_response(
'chimere/upload_file.html', response_dct,
@@ -528,14 +528,14 @@ def contactus(request, area_name=""):
# All validation rules pass
if form.is_valid():
response = notifyStaff(
- _(u"Comments/request on the map"),
+ _("Comments/request on the map"),
form.cleaned_data['content'], form.cleaned_data['email'])
if response:
- msg = _(u"Thank you for your contribution. It will be taken "
- u"into account. If you have left your email you may "
- u"be contacted soon for more details.")
+ msg = _("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.")
else:
- msg = _(u"Temporary error. Renew your message later.")
+ msg = _("Temporary error. Renew your message later.")
else:
form = ContactForm()
response_dct, redir = get_base_response(request, area_name)
@@ -783,7 +783,7 @@ def getGeoObjects(request, area_name, category_ids, status):
if not status:
status = 'A'
status = status.split('_')
- category_ids = unicode(category_ids).split('_')
+ category_ids = str(category_ids).split('_')
bounding_box = []
for attr in ['min_lon', 'min_lat', 'max_lon', 'max_lat']:
@@ -918,7 +918,7 @@ def getTinyfiedUrl(request, parameters, area_name=''):
for item in parameters.split('&'):
if 'current_feature' in item:
try:
- text = unicode(Marker.objects.get(id=item.split('=')[1]))
+ text = str(Marker.objects.get(id=item.split('=')[1]))
except (IndexError, Marker.DoesNotExist):
pass
data["urn"] = urlquote(urn)
@@ -994,7 +994,7 @@ class CategoryView(TemplateView):
raise Http404(_("Category does not exist"))
items, zoom_need_reload = _getGeoObjects(
- self.area_name, [unicode(self.category.pk)], getjson=False,
+ self.area_name, [str(self.category.pk)], getjson=False,
item_types=('Marker',))
return items
@@ -1032,9 +1032,9 @@ def route(request, area_name, lon1, lat1, lonlat_steps, lon2, lat2,
if transport not in dict(settings.CHIMERE_ROUTING_TRANSPORT):
transport = settings.CHIMERE_ROUTING_TRANSPORT[0][0]
if speed:
- speed = unicode(speed)
+ speed = str(speed)
available_speed = [
- unicode(sp)
+ str(sp)
for sp, lbl in settings.CHIMERE_ROUTING_SPEEDS[transport]]
if speed not in available_speed:
speed = None
@@ -1053,7 +1053,7 @@ def route(request, area_name, lon1, lat1, lonlat_steps, lon2, lat2,
try:
route = GEOSGeometry(jsons[0])
except OGRException:
- return HttpResponse(_(u"Bad geometry"), status=500)
+ return HttpResponse(_("Bad geometry"), status=500)
cats = SubCategory.objects.filter(routing_warn=True)
message = ''
if cats.count():
diff --git a/chimere/widgets.py b/chimere/widgets.py
index b4bbee6..480eb9b 100644
--- a/chimere/widgets.py
+++ b/chimere/widgets.py
@@ -28,8 +28,7 @@ from django.conf import settings
from django.contrib.gis.db import models
from django.core.exceptions import ObjectDoesNotExist
from django.core.urlresolvers import reverse
-from django.forms.widgets import RadioInput, RadioFieldRenderer, flatatt
-from django.utils.encoding import force_unicode, smart_unicode
+from django.forms.widgets import RadioSelect, RadioFieldRenderer, flatatt
from django.utils.html import conditional_escape, escape
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext as _
@@ -42,22 +41,22 @@ def getMapJS(area_name=''):
'''Variable initialization for drawing the map
'''
# projection, center and bounds definitions
- js = u"var epsg_display_projection = 'EPSG:%d';\n" \
+ js = "var epsg_display_projection = 'EPSG:%d';\n" \
% settings.CHIMERE_EPSG_DISPLAY_PROJECTION
- js += u"var epsg_projection = 'EPSG:%d';\n" % \
+ js += "var epsg_projection = 'EPSG:%d';\n" % \
settings.CHIMERE_EPSG_PROJECTION
- js += u"var centerLonLat = ol.proj.transform("\
- u"[%f, %f], epsg_display_projection, epsg_projection);\n" % \
+ js += "var centerLonLat = ol.proj.transform("\
+ "[%f, %f], epsg_display_projection, epsg_projection);\n" % \
settings.CHIMERE_DEFAULT_CENTER
- js += u"var media_path = '%s';\n" % settings.MEDIA_URL
- js += u"var static_path = '%s';\n" % settings.STATIC_URL
- js += u"var map_layer = %s;\n" % settings.CHIMERE_DEFAULT_MAP_LAYER
- js += u"var restricted_extent;\n"
+ js += "var media_path = '%s';\n" % settings.MEDIA_URL
+ js += "var static_path = '%s';\n" % settings.STATIC_URL
+ js += "var map_layer = %s;\n" % settings.CHIMERE_DEFAULT_MAP_LAYER
+ js += "var restricted_extent;\n"
if area_name:
- js += u"var area_name='%s';\n" % area_name
- js = u"<script type='text/javascript'><!--\n"\
- u"%s// !--></script>\n" % js
+ js += "var area_name='%s';\n" % area_name
+ js = "<script type='text/javascript'><!--\n"\
+ "%s// !--></script>\n" % js
return js
@@ -89,10 +88,10 @@ def get_map_layers(area_name='', get_area_zoom=False):
else:
map_layers[0][2] = True
elif settings.CHIMERE_DEFAULT_MAP_LAYER:
- map_layers = [(_(u"Default layer"), settings.CHIMERE_DEFAULT_MAP_LAYER,
+ map_layers = [(_("Default layer"), settings.CHIMERE_DEFAULT_MAP_LAYER,
True, '')]
else:
- map_layers = [(u"OSM", """new ol.layer.Tile({
+ map_layers = [("OSM", """new ol.layer.Tile({
style: 'Road',
source: new ol.source.OSM()
})""", True, '')]
@@ -120,9 +119,9 @@ class ChosenSelectWidget(forms.Select):
kwargs['attrs'] = {}
kwargs['attrs'].update({'class': 'chzn-select'})
rendered = super(ChosenSelectWidget, self).render(*args, **kwargs)
- rendered += u"\n<script type='text/javascript'>\n"\
- u" $('#%s').chosen();\n"\
- u"</script>\n" % kwargs['attrs']['id']
+ rendered += "\n<script type='text/javascript'>\n"\
+ " $('#%s').chosen();\n"\
+ "</script>\n" % kwargs['attrs']['id']
return mark_safe(rendered)
"""
@@ -130,7 +129,7 @@ JQuery UI button select widget.
"""
-class ButtonRadioInput(RadioInput):
+class ButtonRadioInput(RadioSelect):
def render(self, name=None, value=None, attrs=None, choices=()):
name = name or self.name
value = value or self.value
@@ -139,7 +138,7 @@ class ButtonRadioInput(RadioInput):
label_for = ' for="%s_%s"' % (self.attrs['id'], self.index)
else:
label_for = ''
- choice_label = conditional_escape(force_unicode(self.choice_label))
+ choice_label = conditional_escape(str(self.choice_label))
return mark_safe(u'%s <label%s>%s</label>' % (self.tag(), label_for,
choice_label))
@@ -151,7 +150,7 @@ class ButtonRadioFieldRenderer(RadioFieldRenderer):
choice, i)
def render(self):
- return mark_safe(u'\n'.join([force_unicode(w) for w in self]))
+ return mark_safe('\n'.join([str(w) for w in self]))
class ButtonSelectWidget(forms.RadioSelect):
@@ -162,9 +161,9 @@ class ButtonSelectWidget(forms.RadioSelect):
def render(self, *args, **kwargs):
rendered = "<div id='%s'>\n" % kwargs['attrs']['id']
rendered += super(ButtonSelectWidget, self).render(*args, **kwargs)
- rendered += u"\n<script type='text/javascript'>\n"\
- u" $('#%s').buttonset();\n"\
- u"</script>\n</div>\n" % kwargs['attrs']['id']
+ rendered += "\n<script type='text/javascript'>\n"\
+ " $('#%s').buttonset();\n"\
+ "</script>\n</div>\n" % kwargs['attrs']['id']
return mark_safe(rendered)
@@ -224,7 +223,7 @@ class FullTextareaWidget(TextareaWidgetBase):
kwargs['attrs']['class'] += ' '
kwargs['attrs']['class'] += 'mceEditor'
rendered = super(FullTextareaWidget, self).render(*args, **kwargs)
- rendered += u"""<script type='text/javascript'>
+ rendered += """<script type='text/javascript'>
tinyMCE.init({
mode : "textareas",
theme : "advanced",
@@ -257,10 +256,10 @@ class DatePickerWidget(forms.TextInput):
"""
def render(self, *args, **kwargs):
rendered = super(DatePickerWidget, self).render(*args, **kwargs)
- rendered += u"\n<script type='text/javascript'>\n"\
- u" $(function() {$('#%s').datepicker("\
- u"{ dateFormat: 'yy-mm-dd' });});\n"\
- u"</script>\n" % kwargs['attrs']['id']
+ rendered += "\n<script type='text/javascript'>\n"\
+ " $(function() {$('#%s').datepicker("\
+ "{ dateFormat: 'yy-mm-dd' });});\n"\
+ "</script>\n" % kwargs['attrs']['id']
return mark_safe(rendered)
@@ -291,14 +290,14 @@ class JQueryAutoComplete(forms.TextInput):
selected_value, rendered_value = "", ""
if value:
- val = escape(smart_unicode(value))
+ val = escape(str(value))
attrs_hidden['value'] = val
attrs_select['value'] = val
selected_value = val
if val:
from chimere.models import PropertyModelChoice
try:
- attrs_select['value'] = unicode(
+ attrs_select['value'] = str(
PropertyModelChoice.objects.get(
pk=value, propertymodel__slug=self.slug))
rendered_value = attrs_select['value']
@@ -330,9 +329,9 @@ class NominatimWidget(forms.TextInput):
def render(self, name, value, attrs=None, area_name=''):
dct = {'id': name, 'nominatim_url': settings.NOMINATIM_URL,
- 'label': _(u"Street, City, Country")}
+ 'label': _("Street, City, Country")}
- tpl = u"""
+ tpl = """
<input type='hidden' name='nominatim_%(id)s_lat' id='nominatim_%(id)s_lat'/>
<input type='hidden' name='nominatim_%(id)s_lon' id='nominatim_%(id)s_lon'/>
<input type='text' class='nominatim-widget' name='nominatim_%(id)s'
@@ -372,7 +371,7 @@ class PointChooserWidget(forms.TextInput):
val = str(value)
if hasattr(value, 'x') and hasattr(value, 'y'):
value_x, value_y = value.x, value.y
- elif isinstance(value, unicode) and value.startswith('POINT('):
+ elif isinstance(value, str) and value.startswith('POINT('):
try:
value_x, value_y = value.split('(')[1][:-1].split(' ')
value_x, value_y = float(value_x), float(value_y)
@@ -479,8 +478,8 @@ class RouteChooserWidget(forms.TextInput):
center=list(settings.CHIMERE_DEFAULT_CENTER),
zoom=zoom,
edition_type="route",
- map_layers=u", ".join(map_layers),
- extra_js=u"\n".join(extra_js),
+ map_layers=", ".join(map_layers),
+ extra_js="\n".join(extra_js),
))
@@ -546,32 +545,32 @@ class AreaWidget(forms.TextInput):
upper_left_lat, upper_left_lon, lower_right_lat, lower_right_lon = \
self.get_bounding_box_from_value(value)
tpl = getMapJS()
- tpl += u"</div>\n"\
- u"<input type='hidden' name='upper_left_lat' id='upper_left_lat' "\
- u"value='%f'/>\n"\
- u"<input type='hidden' name='upper_left_lon' id='upper_left_lon' "\
- u"value='%f'/>\n"\
- u"<input type='hidden' name='lower_right_lat' id='lower_right_lat'"\
- u" value='%f'/>\n"\
- u"<input type='hidden' name='lower_right_lon' id='lower_right_lon'"\
- u" value='%f'/>\n" % (
+ tpl += "</div>\n"\
+ "<input type='hidden' name='upper_left_lat' id='upper_left_lat' "\
+ "value='%f'/>\n"\
+ "<input type='hidden' name='upper_left_lon' id='upper_left_lon' "\
+ "value='%f'/>\n"\
+ "<input type='hidden' name='lower_right_lat' id='lower_right_lat'"\
+ " value='%f'/>\n"\
+ "<input type='hidden' name='lower_right_lon' id='lower_right_lon'"\
+ " value='%f'/>\n" % (
upper_left_lat, upper_left_lon, lower_right_lat,
lower_right_lon)
- help_msg = _(u"Hold CTRL, click and drag to select area on the map")
- tpl += u"<p class='help-osm'>%s</p>\n" % help_msg
- tpl += u"<script type='text/javascript'>\n"
- tpl += u"function init_map_form (){\ninit('map_edit_area');\n"
+ help_msg = _("Hold CTRL, click and drag to select area on the map")
+ tpl += "<p class='help-osm'>%s</p>\n" % help_msg
+ tpl += "<script type='text/javascript'>\n"
+ tpl += "function init_map_form (){\ninit('map_edit_area');\n"
if value:
- tpl += u"extent = ol.proj.transformExtent([%f, %f, %f, %f], "\
- u"epsg_display_projection, epsg_projection);\n"\
- u"initArea(extent);\n" % (
+ tpl += "extent = ol.proj.transformExtent([%f, %f, %f, %f], "\
+ "epsg_display_projection, epsg_projection);\n"\
+ "initArea(extent);\n" % (
upper_left_lon, upper_left_lat, lower_right_lon,
lower_right_lat)
- tpl += u"}\n"
+ tpl += "}\n"
if initialized:
- tpl += u"$(document).ready(function($) {init_map_form()});\n"
- tpl += u"</script>\n"
- tpl += u"<div id='map_edit_area'>\n"
+ tpl += "$(document).ready(function($) {init_map_form()});\n"
+ tpl += "</script>\n"
+ tpl += "<div id='map_edit_area'>\n"
return mark_safe(tpl)
def value_from_datadict(self, data, files, name):
@@ -628,8 +627,8 @@ class PolygonChooserWidget(forms.TextInput):
center=list(settings.CHIMERE_DEFAULT_CENTER),
zoom=zoom,
edition_type="polygon",
- map_layers=u", ".join(map_layers),
- extra_js=u"\n".join(extra_js),
+ map_layers=", ".join(map_layers),
+ extra_js="\n".join(extra_js),
))
@@ -666,50 +665,50 @@ class ImportFiltrWidget(AreaWidget):
"""
tpl = super(ImportFiltrWidget, self).render(name, value, attrs,
initialized=False)
- tpl += u"</div><hr class='spacer'/>"
- vals = {'lbl': _(u"Type:"), 'name': name, 'node': _(u"Node"),
- 'way': _(u"Way")}
+ tpl += "</div><hr class='spacer'/>"
+ vals = {'lbl': _("Type:"), 'name': name, 'node': _("Node"),
+ 'way': _("Way")}
vals['way_selected'] = ' checked="checked"'\
if self.xapi_type == 'way' else ''
vals['node_selected'] = ' checked="checked"'\
if self.xapi_type == 'node' else ''
- tpl += u"<div class='input-osm'><label>%(lbl)s</label>"\
- u"<input type='radio' name='id_%(name)s_type' "\
- u"id='id_%(name)s_node' value='node'%(node_selected)s/> "\
- u"<label for='id_%(name)s_node'>"\
- u"%(node)s</label> <input type='radio' name='id_%(name)s_type' "\
- u"id='id_%(name)s_way' value='way'%(way_selected)s/> <label "\
- u"for='id_%(name)s_way'>%(way)s</label></div>" % vals
+ tpl += "<div class='input-osm'><label>%(lbl)s</label>"\
+ "<input type='radio' name='id_%(name)s_type' "\
+ "id='id_%(name)s_node' value='node'%(node_selected)s/> "\
+ "<label for='id_%(name)s_node'>"\
+ "%(node)s</label> <input type='radio' name='id_%(name)s_type' "\
+ "id='id_%(name)s_way' value='way'%(way_selected)s/> <label "\
+ "for='id_%(name)s_way'>%(way)s</label></div>" % vals
help_msg = _(
- u"Enter an OSM \"tag=value\" string such as "
- u"\"amenity=pub\". A list of common tag is available "
- u"<a href='https://wiki.openstreetmap.org/wiki/Map_Features' "
- u" target='_blank'>here</a>.")
- tpl += u"<p class='help-osm'>%s</p>\n" % help_msg
- tpl += u"<div class='input-osm'><label for='id_%s_tag'>%s</label>"\
- u"<input type='text' id='id_%s_tag' value=\"%s\"/></div>" % (
- name, _(u"Tag:"), name, self.xapi_tag)
- tpl += u"<script type='text/javascript'>\n"
- tpl += u"var default_xapi='%s';" % settings.CHIMERE_XAPI_URL
+ "Enter an OSM \"tag=value\" string such as "
+ "\"amenity=pub\". A list of common tag is available "
+ "<a href='https://wiki.openstreetmap.org/wiki/Map_Features' "
+ " target='_blank'>here</a>.")
+ tpl += "<p class='help-osm'>%s</p>\n" % help_msg
+ tpl += "<div class='input-osm'><label for='id_%s_tag'>%s</label>"\
+ "<input type='text' id='id_%s_tag' value=\"%s\"/></div>" % (
+ name, _("Tag:"), name, self.xapi_tag)
+ tpl += "<script type='text/javascript'>\n"
+ tpl += "var default_xapi='%s';" % settings.CHIMERE_XAPI_URL
tpl += u'var msg_missing_area = "%s";' % \
- _(u"You have to select an area.")
+ _("You have to select an area.")
tpl += u'var msg_missing_type = "%s";' % \
- _(u"You have to select a type.")
+ _("You have to select a type.")
tpl += u'var msg_missing_filtr = "%s";' % \
- _(u"You have to insert a filter tag.")
- tpl += u"</script>\n"
- help_msg = _(u"If you change the above form don't forget to refresh "
- u"before submit!")
- tpl += u"<p class='help-osm errornote'>%s</p>\n" % help_msg
- help_msg = _(u"You can put a Folder name of the KML file to filter on "
- u"it.")
- tpl += u"<p class='help-kml'>%s</p>\n" % help_msg
+ _("You have to insert a filter tag.")
+ tpl += "</script>\n"
+ help_msg = _("If you change the above form don't forget to refresh "
+ "before submit!")
+ tpl += "<p class='help-osm errornote'>%s</p>\n" % help_msg
+ help_msg = _("You can put a Folder name of the KML file to filter on "
+ "it.")
+ tpl += "<p class='help-kml'>%s</p>\n" % help_msg
if not value:
value = ''
- tpl += u"<div><textarea id='id_%s' name='id_%s' "\
- u">%s</textarea> <input type='button' id='id_refresh_%s' "\
- u"value='%s' class='input-osm'/>" % (name, name, value, name,
- _(u"Refresh"))
+ tpl += "<div><textarea id='id_%s' name='id_%s' "\
+ ">%s</textarea> <input type='button' id='id_refresh_%s' "\
+ "value='%s' class='input-osm'/>" % (name, name, value, name,
+ _("Refresh"))
return mark_safe(tpl)
def value_from_datadict(self, data, files, name):
@@ -768,17 +767,17 @@ class MultiSelectWidget(forms.SelectMultiple):
def render(self, name, value, attrs=None):
rendered = super(MultiSelectWidget, self).render(name, value, attrs)
- rendered += u"<hr class='spacer'/><script type='text/javascript'>\n"\
- u"$.bsmSelect.conf['title'] = \"%(title)s\";\n"\
- u"$(\"#id_%(name)s\").bsmSelect({\n"\
- u" removeLabel: '<strong>X</strong>',\n"\
- u" containerClass: 'bsmContainer',\n"\
- u" listClass: 'bsmList-custom',\n"\
- u" listItemClass: 'bsmListItem-custom',\n"\
- u" listItemLabelClass: 'bsmListItemLabel-custom',\n"\
- u" removeClass: 'bsmListItemRemove-custom'\n"\
- u"});\n"\
- u"</script>\n" % {'name': name, 'title': _("Select...")}
+ rendered += "<hr class='spacer'/><script type='text/javascript'>\n"\
+ "$.bsmSelect.conf['title'] = \"%(title)s\";\n"\
+ "$(\"#id_%(name)s\").bsmSelect({\n"\
+ " removeLabel: '<strong>X</strong>',\n"\
+ " containerClass: 'bsmContainer',\n"\
+ " listClass: 'bsmList-custom',\n"\
+ " listItemClass: 'bsmListItem-custom',\n"\
+ " listItemLabelClass: 'bsmListItemLabel-custom',\n"\
+ " removeClass: 'bsmListItemRemove-custom'\n"\
+ "});\n"\
+ "</script>\n" % {'name': name, 'title': _("Select...")}
return mark_safe(rendered)
@@ -791,9 +790,3 @@ class SelectMultipleField(models.ManyToManyField):
defaults = {'widget': MultiSelectWidget}
keys.update(defaults)
return super(SelectMultipleField, self).formfield(**keys)
-
-from south.modelsinspector import add_introspection_rules
-add_introspection_rules([], ["^chimere\.widgets\.PointField"])
-add_introspection_rules([], ["^chimere\.widgets\.SelectMultipleField"])
-add_introspection_rules([], ["^chimere\.widgets\.RouteField"])
-add_introspection_rules([], ["^chimere\.widgets\.PolygonField"])
diff --git a/chimere_example_project/local_settings.py.gitlab-ci b/chimere_example_project/local_settings.py.gitlab-ci
index 9ad355a..5abd801 100644
--- a/chimere_example_project/local_settings.py.gitlab-ci
+++ b/chimere_example_project/local_settings.py.gitlab-ci
@@ -1,6 +1,8 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
+SECRET_KEY = "Not so secret..."
+
DATABASES = {
'default': {
'ENGINE': 'django.contrib.gis.db.backends.postgis',
diff --git a/chimere_example_project/manage.py b/chimere_example_project/manage.py
index 20f85bc..504c115 100755
--- a/chimere_example_project/manage.py
+++ b/chimere_example_project/manage.py
@@ -1,17 +1,13 @@
-#!/usr/bin/env python
-import os, sys
-from django.core.management import execute_manager
-sys.path.insert(0, os.path.abspath('./..'))
+#!/usr/bin/env python3
+
+import os
+import sys
-try:
- import settings # Assumed to be in the same directory.
- if settings.DEBUG:
- sys.path.insert(0, os.path.abspath('./../chimere'))
- sys.path.insert(0, os.path.abspath('./../../geo-django-fla/'))
-except ImportError:
- import sys
- sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
- sys.exit(1)
if __name__ == "__main__":
- execute_manager(settings)
+ sys.path.insert(0, os.path.abspath('./../'))
+ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
+
+ from django.core.management import execute_from_command_line
+
+ execute_from_command_line(sys.argv)
diff --git a/chimere_example_project/settings.py b/chimere_example_project/settings.py
index 8ab1da4..6878def 100644
--- a/chimere_example_project/settings.py
+++ b/chimere_example_project/settings.py
@@ -219,7 +219,7 @@ MIDDLEWARE_CLASSES = [
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
- 'django.middleware.doc.XViewMiddleware',
+ 'django.contrib.admindocs.middleware.XViewMiddleware',
'django.contrib.messages.middleware.MessageMiddleware'
]
@@ -261,7 +261,6 @@ except ImportError:
pass
INSTALLED_APPS += [
- 'south',
'chimere',
]
@@ -273,8 +272,8 @@ CHIMERE_EDIT_RENDERER = 'openlayers' # 'openlayers'
try:
from local_settings import *
-except ImportError, e:
- print 'Unable to load local_settings.py:', e
+except ImportError as e:
+ print('Unable to load local_settings.py:', e)
if CHIMERE_SEARCH_ENGINE:
INSTALLED_APPS.insert(INSTALLED_APPS.index('south'), 'haystack')
@@ -361,17 +360,20 @@ if DEBUG_TOOLBAR:
global DEBUG_TOOLBAR_CONFIG
MIDDLEWARE_CLASSES += ['debug_toolbar.middleware.DebugToolbarMiddleware']
INSTALLED_APPS += ['debug_toolbar']
- DEBUG_TOOLBAR_PANELS = (
- 'debug_toolbar.panels.version.VersionDebugPanel',
- 'debug_toolbar.panels.timer.TimerDebugPanel',
- 'debug_toolbar.panels.settings_vars.SettingsVarsDebugPanel',
- 'debug_toolbar.panels.headers.HeaderDebugPanel',
- 'debug_toolbar.panels.request_vars.RequestVarsDebugPanel',
- 'debug_toolbar.panels.template.TemplateDebugPanel',
- 'debug_toolbar.panels.sql.SQLDebugPanel',
- 'debug_toolbar.panels.signals.SignalDebugPanel',
- 'debug_toolbar.panels.logger.LoggingPanel',
- )
+ DEBUG_TOOLBAR_PANELS = [
+ 'debug_toolbar.panels.versions.VersionsPanel',
+ 'debug_toolbar.panels.timer.TimerPanel',
+ 'debug_toolbar.panels.settings.SettingsPanel',
+ 'debug_toolbar.panels.headers.HeadersPanel',
+ 'debug_toolbar.panels.request.RequestPanel',
+ 'debug_toolbar.panels.sql.SQLPanel',
+ 'debug_toolbar.panels.staticfiles.StaticFilesPanel',
+ 'debug_toolbar.panels.templates.TemplatesPanel',
+ 'debug_toolbar.panels.cache.CachePanel',
+ 'debug_toolbar.panels.signals.SignalsPanel',
+ 'debug_toolbar.panels.logging.LoggingPanel',
+ 'debug_toolbar.panels.redirects.RedirectsPanel',
+ ]
DEBUG_TOOLBAR_CONFIG = {'INTERCEPT_REDIRECTS': False}
diff --git a/chimere_example_project/urls.py b/chimere_example_project/urls.py
index fff1366..155696a 100644
--- a/chimere_example_project/urls.py
+++ b/chimere_example_project/urls.py
@@ -18,27 +18,28 @@
# See the file COPYING for details.
from django.conf import settings
-from django.conf.urls.defaults import *
+from django.conf.urls import patterns, url, include
from django.contrib import admin
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
admin.autodiscover()
-urlpatterns = patterns('django.views.static',
+urlpatterns = patterns(
+ 'django.views.static',
(r'^%s(?P<path>.*)' % settings.MEDIA_URL[1:], 'serve',
{'document_root': settings.MEDIA_ROOT}),
)
if "tinymce" in settings.INSTALLED_APPS:
- urlpatterns += patterns('django.views.static',
+ urlpatterns += patterns(
+ 'django.views.static',
(r'^tinymce/', include('tinymce.urls')),)
urlpatterns += staticfiles_urlpatterns()
-urlpatterns += patterns('',
+urlpatterns += patterns(
+ '',
(r'^admin/doc/', include('django.contrib.admindocs.urls')),
(r'^admin/', include(admin.site.urls)),
url(r'^', include('chimere.urls', namespace="chimere")),
)
-
-
diff --git a/requirements.txt b/requirements.txt
index 9b5ca45..4c314f4 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,11 +1,12 @@
-django>=1.4,<1.4.99
-beautifulsoup
+django>=1.8,<1.8.99
+beautifulsoup4==4.3.2
psycopg2
-Pillow
-lxml
-south>=0.7.3,<0.7.99
-simplejson
+Pillow==3.3
+lxml==3.4
feedparser==5.2.1
-django-tinymce
+django-tinymce==1.5.3
icalendar==3.8
chardet==2.3
+py3exiv2==0.2.1
+gdal==1.10
+osmapi==0.6.2
diff --git a/requirements_searchengine.txt b/requirements_searchengine.txt
index 3383004..4d17bf8 100644
--- a/requirements_searchengine.txt
+++ b/requirements_searchengine.txt
@@ -1,13 +1,15 @@
-django>=1.4,<1.4.99
-beautifulsoup
+django>=1.8,<1.8.99
+beautifulsoup4==4.3.2
psycopg2
-pil
-lxml
-south>=0.7.3,<0.7.99
-simplejson
-feedparser
-django-tinymce
-django-haystack==2.1
-geopy
-pysolr
+Pillow==3.3
+lxml==3.4
+feedparser==5.2.1
+django-tinymce==1.5.3
+django-haystack==2.3
+geopy==1.3
+pysolr==3.2
icalendar==3.8
+chardet==2.3
+py3exiv2==0.2.1
+gdal==1.10
+osmapi==0.6.2