black on views.py
This commit is contained in:
parent
97e2df0a8d
commit
3aa34d124e
1 changed files with 159 additions and 168 deletions
327
umap/views.py
327
umap/views.py
|
@ -50,11 +50,13 @@ except ImportError:
|
||||||
User = get_user_model()
|
User = get_user_model()
|
||||||
|
|
||||||
|
|
||||||
PRIVATE_IP = re.compile(r'((^127\.)|(^10\.)'
|
PRIVATE_IP = re.compile(
|
||||||
r'|(^172\.1[6-9]\.)'
|
r"((^127\.)|(^10\.)"
|
||||||
r'|(^172\.2[0-9]\.)'
|
r"|(^172\.1[6-9]\.)"
|
||||||
r'|(^172\.3[0-1]\.)'
|
r"|(^172\.2[0-9]\.)"
|
||||||
r'|(^192\.168\.))')
|
r"|(^172\.3[0-1]\.)"
|
||||||
|
r"|(^192\.168\.))"
|
||||||
|
)
|
||||||
ANONYMOUS_COOKIE_MAX_AGE = 60 * 60 * 24 * 30 # One month
|
ANONYMOUS_COOKIE_MAX_AGE = 60 * 60 * 24 * 30 # One month
|
||||||
|
|
||||||
|
|
||||||
|
@ -63,7 +65,7 @@ class PaginatorMixin(object):
|
||||||
|
|
||||||
def paginate(self, qs, per_page=None):
|
def paginate(self, qs, per_page=None):
|
||||||
paginator = Paginator(qs, per_page or self.per_page)
|
paginator = Paginator(qs, per_page or self.per_page)
|
||||||
page = self.request.GET.get('p')
|
page = self.request.GET.get("p")
|
||||||
try:
|
try:
|
||||||
qs = paginator.page(page)
|
qs = paginator.page(page)
|
||||||
except PageNotAnInteger:
|
except PageNotAnInteger:
|
||||||
|
@ -82,9 +84,11 @@ class Home(TemplateView, PaginatorMixin):
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
qs = Map.public
|
qs = Map.public
|
||||||
if (settings.UMAP_EXCLUDE_DEFAULT_MAPS and
|
if (
|
||||||
'spatialite' not in settings.DATABASES['default']['ENGINE']):
|
settings.UMAP_EXCLUDE_DEFAULT_MAPS
|
||||||
# Unsupported query type for sqlite.
|
and "spatialite" not in settings.DATABASES["default"]["ENGINE"]
|
||||||
|
):
|
||||||
|
# Unsupported query type for sqlite.
|
||||||
qs = qs.filter(center__distance_gt=(DEFAULT_CENTER, D(km=1)))
|
qs = qs.filter(center__distance_gt=(DEFAULT_CENTER, D(km=1)))
|
||||||
demo_map = None
|
demo_map = None
|
||||||
if hasattr(settings, "UMAP_DEMO_PK"):
|
if hasattr(settings, "UMAP_DEMO_PK"):
|
||||||
|
@ -102,14 +106,14 @@ class Home(TemplateView, PaginatorMixin):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
qs = qs.exclude(id=showcase_map.pk)
|
qs = qs.exclude(id=showcase_map.pk)
|
||||||
maps = qs.order_by('-modified_at')[:50]
|
maps = qs.order_by("-modified_at")[:50]
|
||||||
maps = self.paginate(maps, settings.UMAP_MAPS_PER_PAGE)
|
maps = self.paginate(maps, settings.UMAP_MAPS_PER_PAGE)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"maps": maps,
|
"maps": maps,
|
||||||
"demo_map": demo_map,
|
"demo_map": demo_map,
|
||||||
"showcase_map": showcase_map,
|
"showcase_map": showcase_map,
|
||||||
"DEMO_SITE": settings.UMAP_DEMO_SITE
|
"DEMO_SITE": settings.UMAP_DEMO_SITE,
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_template_names(self):
|
def get_template_names(self):
|
||||||
|
@ -121,6 +125,7 @@ class Home(TemplateView, PaginatorMixin):
|
||||||
else:
|
else:
|
||||||
return [self.template_name]
|
return [self.template_name]
|
||||||
|
|
||||||
|
|
||||||
home = Home.as_view()
|
home = Home.as_view()
|
||||||
|
|
||||||
|
|
||||||
|
@ -128,13 +133,14 @@ class About(Home):
|
||||||
|
|
||||||
template_name = "umap/about.html"
|
template_name = "umap/about.html"
|
||||||
|
|
||||||
|
|
||||||
about = About.as_view()
|
about = About.as_view()
|
||||||
|
|
||||||
|
|
||||||
class UserMaps(DetailView, PaginatorMixin):
|
class UserMaps(DetailView, PaginatorMixin):
|
||||||
model = User
|
model = User
|
||||||
slug_url_kwarg = 'username'
|
slug_url_kwarg = "username"
|
||||||
slug_field = 'username'
|
slug_field = "username"
|
||||||
list_template_name = "umap/map_list.html"
|
list_template_name = "umap/map_list.html"
|
||||||
context_object_name = "current_user"
|
context_object_name = "current_user"
|
||||||
|
|
||||||
|
@ -148,11 +154,9 @@ class UserMaps(DetailView, PaginatorMixin):
|
||||||
else:
|
else:
|
||||||
per_page = settings.UMAP_MAPS_PER_PAGE
|
per_page = settings.UMAP_MAPS_PER_PAGE
|
||||||
limit = 50
|
limit = 50
|
||||||
maps = maps.distinct().order_by('-modified_at')[:limit]
|
maps = maps.distinct().order_by("-modified_at")[:limit]
|
||||||
maps = self.paginate(maps, per_page)
|
maps = self.paginate(maps, per_page)
|
||||||
kwargs.update({
|
kwargs.update({"maps": maps})
|
||||||
"maps": maps
|
|
||||||
})
|
|
||||||
return super(UserMaps, self).get_context_data(**kwargs)
|
return super(UserMaps, self).get_context_data(**kwargs)
|
||||||
|
|
||||||
def get_template_names(self):
|
def get_template_names(self):
|
||||||
|
@ -164,6 +168,7 @@ class UserMaps(DetailView, PaginatorMixin):
|
||||||
else:
|
else:
|
||||||
return super(UserMaps, self).get_template_names()
|
return super(UserMaps, self).get_template_names()
|
||||||
|
|
||||||
|
|
||||||
user_maps = UserMaps.as_view()
|
user_maps = UserMaps.as_view()
|
||||||
|
|
||||||
|
|
||||||
|
@ -172,20 +177,17 @@ class Search(TemplateView, PaginatorMixin):
|
||||||
list_template_name = "umap/map_list.html"
|
list_template_name = "umap/map_list.html"
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
q = self.request.GET.get('q')
|
q = self.request.GET.get("q")
|
||||||
results = []
|
results = []
|
||||||
if q:
|
if q:
|
||||||
where = "to_tsvector(name) @@ plainto_tsquery(%s)"
|
where = "to_tsvector(name) @@ plainto_tsquery(%s)"
|
||||||
if getattr(settings, 'UMAP_USE_UNACCENT', False):
|
if getattr(settings, "UMAP_USE_UNACCENT", False):
|
||||||
where = "to_tsvector(unaccent(name)) @@ plainto_tsquery(unaccent(%s))" # noqa
|
where = "to_tsvector(unaccent(name)) @@ plainto_tsquery(unaccent(%s))" # noqa
|
||||||
results = Map.objects.filter(share_status=Map.PUBLIC)
|
results = Map.objects.filter(share_status=Map.PUBLIC)
|
||||||
results = results.extra(where=[where], params=[q])
|
results = results.extra(where=[where], params=[q])
|
||||||
results = results.order_by('-modified_at')
|
results = results.order_by("-modified_at")
|
||||||
results = self.paginate(results)
|
results = self.paginate(results)
|
||||||
kwargs.update({
|
kwargs.update({"maps": results, "q": q})
|
||||||
'maps': results,
|
|
||||||
'q': q
|
|
||||||
})
|
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
def get_template_names(self):
|
def get_template_names(self):
|
||||||
|
@ -197,57 +199,52 @@ class Search(TemplateView, PaginatorMixin):
|
||||||
else:
|
else:
|
||||||
return super(Search, self).get_template_names()
|
return super(Search, self).get_template_names()
|
||||||
|
|
||||||
|
|
||||||
search = Search.as_view()
|
search = Search.as_view()
|
||||||
|
|
||||||
|
|
||||||
class MapsShowCase(View):
|
class MapsShowCase(View):
|
||||||
|
|
||||||
def get(self, *args, **kwargs):
|
def get(self, *args, **kwargs):
|
||||||
maps = Map.public.filter(center__distance_gt=(DEFAULT_CENTER, D(km=1)))
|
maps = Map.public.filter(center__distance_gt=(DEFAULT_CENTER, D(km=1)))
|
||||||
maps = maps.order_by('-modified_at')[:2500]
|
maps = maps.order_by("-modified_at")[:2500]
|
||||||
|
|
||||||
def make(m):
|
def make(m):
|
||||||
description = m.description or ""
|
description = m.description or ""
|
||||||
if m.owner:
|
if m.owner:
|
||||||
description = u"{description}\n{by} [[{url}|{name}]]".format(
|
description = "{description}\n{by} [[{url}|{name}]]".format(
|
||||||
description=description,
|
description=description,
|
||||||
by=_("by"),
|
by=_("by"),
|
||||||
url=reverse('user_maps',
|
url=reverse("user_maps", kwargs={"username": m.owner.username}),
|
||||||
kwargs={"username": m.owner.username}),
|
|
||||||
name=m.owner,
|
name=m.owner,
|
||||||
)
|
)
|
||||||
description = u"{}\n[[{}|{}]]".format(
|
description = "{}\n[[{}|{}]]".format(
|
||||||
description, m.get_absolute_url(), _("View the map"))
|
description, m.get_absolute_url(), _("View the map")
|
||||||
geometry = m.settings.get('geometry', json.loads(m.center.geojson))
|
)
|
||||||
|
geometry = m.settings.get("geometry", json.loads(m.center.geojson))
|
||||||
return {
|
return {
|
||||||
"type": "Feature",
|
"type": "Feature",
|
||||||
"geometry": geometry,
|
"geometry": geometry,
|
||||||
"properties": {
|
"properties": {"name": m.name, "description": description},
|
||||||
"name": m.name,
|
|
||||||
"description": description
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
geojson = {
|
geojson = {"type": "FeatureCollection", "features": [make(m) for m in maps]}
|
||||||
"type": "FeatureCollection",
|
|
||||||
"features": [make(m) for m in maps]
|
|
||||||
}
|
|
||||||
return HttpResponse(smart_bytes(json.dumps(geojson)))
|
return HttpResponse(smart_bytes(json.dumps(geojson)))
|
||||||
|
|
||||||
|
|
||||||
showcase = MapsShowCase.as_view()
|
showcase = MapsShowCase.as_view()
|
||||||
|
|
||||||
|
|
||||||
def validate_url(request):
|
def validate_url(request):
|
||||||
assert request.method == "GET"
|
assert request.method == "GET"
|
||||||
assert is_ajax(request)
|
assert is_ajax(request)
|
||||||
url = request.GET.get('url')
|
url = request.GET.get("url")
|
||||||
assert url
|
assert url
|
||||||
try:
|
try:
|
||||||
URLValidator(url)
|
URLValidator(url)
|
||||||
except ValidationError:
|
except ValidationError:
|
||||||
raise AssertionError()
|
raise AssertionError()
|
||||||
assert 'HTTP_REFERER' in request.META
|
assert "HTTP_REFERER" in request.META
|
||||||
referer = urlparse(request.META.get('HTTP_REFERER'))
|
referer = urlparse(request.META.get("HTTP_REFERER"))
|
||||||
toproxy = urlparse(url)
|
toproxy = urlparse(url)
|
||||||
local = urlparse(settings.SITE_URL)
|
local = urlparse(settings.SITE_URL)
|
||||||
assert toproxy.hostname
|
assert toproxy.hostname
|
||||||
|
@ -264,38 +261,39 @@ def validate_url(request):
|
||||||
|
|
||||||
|
|
||||||
class AjaxProxy(View):
|
class AjaxProxy(View):
|
||||||
|
|
||||||
def get(self, *args, **kwargs):
|
def get(self, *args, **kwargs):
|
||||||
# You should not use this in production (use Nginx or so)
|
# You should not use this in production (use Nginx or so)
|
||||||
try:
|
try:
|
||||||
url = validate_url(self.request)
|
url = validate_url(self.request)
|
||||||
except AssertionError:
|
except AssertionError:
|
||||||
return HttpResponseBadRequest()
|
return HttpResponseBadRequest()
|
||||||
headers = {
|
headers = {"User-Agent": "uMapProxy +http://wiki.openstreetmap.org/wiki/UMap"}
|
||||||
'User-Agent': 'uMapProxy +http://wiki.openstreetmap.org/wiki/UMap'
|
|
||||||
}
|
|
||||||
request = Request(url, headers=headers)
|
request = Request(url, headers=headers)
|
||||||
opener = build_opener()
|
opener = build_opener()
|
||||||
try:
|
try:
|
||||||
proxied_request = opener.open(request)
|
proxied_request = opener.open(request)
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
return HttpResponse(e.msg, status=e.code,
|
return HttpResponse(e.msg, status=e.code, content_type="text/plain")
|
||||||
content_type='text/plain')
|
|
||||||
else:
|
else:
|
||||||
status_code = proxied_request.code
|
status_code = proxied_request.code
|
||||||
mimetype = proxied_request.headers.get('Content-Type') or mimetypes.guess_type(url) # noqa
|
mimetype = proxied_request.headers.get(
|
||||||
|
"Content-Type"
|
||||||
|
) or mimetypes.guess_type(
|
||||||
|
url
|
||||||
|
) # noqa
|
||||||
content = proxied_request.read()
|
content = proxied_request.read()
|
||||||
# Quick hack to prevent Django from adding a Vary: Cookie header
|
# Quick hack to prevent Django from adding a Vary: Cookie header
|
||||||
self.request.session.accessed = False
|
self.request.session.accessed = False
|
||||||
response = HttpResponse(content, status=status_code,
|
response = HttpResponse(content, status=status_code, content_type=mimetype)
|
||||||
content_type=mimetype)
|
|
||||||
try:
|
try:
|
||||||
ttl = int(self.request.GET.get('ttl'))
|
ttl = int(self.request.GET.get("ttl"))
|
||||||
except (TypeError, ValueError):
|
except (TypeError, ValueError):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
response['X-Accel-Expires'] = ttl
|
response["X-Accel-Expires"] = ttl
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
ajax_proxy = AjaxProxy.as_view()
|
ajax_proxy = AjaxProxy.as_view()
|
||||||
|
|
||||||
|
|
||||||
|
@ -303,6 +301,7 @@ ajax_proxy = AjaxProxy.as_view()
|
||||||
# Utils #
|
# Utils #
|
||||||
# ############## #
|
# ############## #
|
||||||
|
|
||||||
|
|
||||||
def _urls_for_js(urls=None):
|
def _urls_for_js(urls=None):
|
||||||
"""
|
"""
|
||||||
Return templated URLs prepared for javascript.
|
Return templated URLs prepared for javascript.
|
||||||
|
@ -310,10 +309,12 @@ def _urls_for_js(urls=None):
|
||||||
if urls is None:
|
if urls is None:
|
||||||
# prevent circular import
|
# prevent circular import
|
||||||
from .urls import urlpatterns, i18n_urls
|
from .urls import urlpatterns, i18n_urls
|
||||||
urls = [url.name for url in urlpatterns + i18n_urls
|
|
||||||
if getattr(url, 'name', None)]
|
urls = [
|
||||||
|
url.name for url in urlpatterns + i18n_urls if getattr(url, "name", None)
|
||||||
|
]
|
||||||
urls = dict(zip(urls, [get_uri_template(url) for url in urls]))
|
urls = dict(zip(urls, [get_uri_template(url) for url in urls]))
|
||||||
urls.update(getattr(settings, 'UMAP_EXTRA_URLS', {}))
|
urls.update(getattr(settings, "UMAP_EXTRA_URLS", {}))
|
||||||
return urls
|
return urls
|
||||||
|
|
||||||
|
|
||||||
|
@ -321,14 +322,8 @@ def render_to_json(templates, context, request):
|
||||||
"""
|
"""
|
||||||
Generate a JSON HttpResponse with rendered template HTML.
|
Generate a JSON HttpResponse with rendered template HTML.
|
||||||
"""
|
"""
|
||||||
html = render_to_string(
|
html = render_to_string(templates, context=context, request=request)
|
||||||
templates,
|
_json = json.dumps({"html": html})
|
||||||
context=context,
|
|
||||||
request=request
|
|
||||||
)
|
|
||||||
_json = json.dumps({
|
|
||||||
"html": html
|
|
||||||
})
|
|
||||||
return HttpResponse(_json)
|
return HttpResponse(_json)
|
||||||
|
|
||||||
|
|
||||||
|
@ -342,15 +337,16 @@ def simple_json_response(**kwargs):
|
||||||
|
|
||||||
|
|
||||||
class FormLessEditMixin:
|
class FormLessEditMixin:
|
||||||
http_method_names = [u'post', ]
|
http_method_names = [
|
||||||
|
"post",
|
||||||
|
]
|
||||||
|
|
||||||
def form_invalid(self, form):
|
def form_invalid(self, form):
|
||||||
return simple_json_response(errors=form.errors,
|
return simple_json_response(errors=form.errors, error=str(form.errors))
|
||||||
error=str(form.errors))
|
|
||||||
|
|
||||||
def get_form(self, form_class=None):
|
def get_form(self, form_class=None):
|
||||||
kwargs = self.get_form_kwargs()
|
kwargs = self.get_form_kwargs()
|
||||||
kwargs['error_class'] = FlatErrorList
|
kwargs["error_class"] = FlatErrorList
|
||||||
return self.get_form_class()(**kwargs)
|
return self.get_form_class()(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
@ -361,20 +357,22 @@ class MapDetailMixin:
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
properties = {
|
properties = {
|
||||||
'urls': _urls_for_js(),
|
"urls": _urls_for_js(),
|
||||||
'tilelayers': TileLayer.get_list(),
|
"tilelayers": TileLayer.get_list(),
|
||||||
'allowEdit': self.is_edit_allowed(),
|
"allowEdit": self.is_edit_allowed(),
|
||||||
'default_iconUrl': "%sumap/img/marker.png" % settings.STATIC_URL, # noqa
|
"default_iconUrl": "%sumap/img/marker.png" % settings.STATIC_URL, # noqa
|
||||||
'umap_id': self.get_umap_id(),
|
"umap_id": self.get_umap_id(),
|
||||||
'licences': dict((l.name, l.json) for l in Licence.objects.all()),
|
"licences": dict((l.name, l.json) for l in Licence.objects.all()),
|
||||||
'edit_statuses': [(i, str(label)) for i, label in Map.EDIT_STATUS],
|
"edit_statuses": [(i, str(label)) for i, label in Map.EDIT_STATUS],
|
||||||
'share_statuses': [(i, str(label))
|
"share_statuses": [
|
||||||
for i, label in Map.SHARE_STATUS if i != Map.BLOCKED],
|
(i, str(label)) for i, label in Map.SHARE_STATUS if i != Map.BLOCKED
|
||||||
'anonymous_edit_statuses': [(i, str(label)) for i, label
|
],
|
||||||
in AnonymousMapPermissionsForm.STATUS],
|
"anonymous_edit_statuses": [
|
||||||
|
(i, str(label)) for i, label in AnonymousMapPermissionsForm.STATUS
|
||||||
|
],
|
||||||
}
|
}
|
||||||
if self.get_short_url():
|
if self.get_short_url():
|
||||||
properties['shortUrl'] = self.get_short_url()
|
properties["shortUrl"] = self.get_short_url()
|
||||||
|
|
||||||
if settings.USE_I18N:
|
if settings.USE_I18N:
|
||||||
locale = settings.LANGUAGE_CODE
|
locale = settings.LANGUAGE_CODE
|
||||||
|
@ -382,23 +380,21 @@ class MapDetailMixin:
|
||||||
if hasattr(self.request, "LANGUAGE_CODE"):
|
if hasattr(self.request, "LANGUAGE_CODE"):
|
||||||
locale = self.request.LANGUAGE_CODE
|
locale = self.request.LANGUAGE_CODE
|
||||||
locale = to_locale(locale)
|
locale = to_locale(locale)
|
||||||
properties['locale'] = locale
|
properties["locale"] = locale
|
||||||
context['locale'] = locale
|
context["locale"] = locale
|
||||||
user = self.request.user
|
user = self.request.user
|
||||||
if not user.is_anonymous:
|
if not user.is_anonymous:
|
||||||
properties['user'] = {
|
properties["user"] = {
|
||||||
'id': user.pk,
|
"id": user.pk,
|
||||||
'name': user.get_username(),
|
"name": user.get_username(),
|
||||||
'url': reverse(settings.USER_MAPS_URL,
|
"url": reverse(settings.USER_MAPS_URL, args=(user.get_username(),)),
|
||||||
args=(user.get_username(), ))
|
|
||||||
}
|
}
|
||||||
map_settings = self.get_geojson()
|
map_settings = self.get_geojson()
|
||||||
if "properties" not in map_settings:
|
if "properties" not in map_settings:
|
||||||
map_settings['properties'] = {}
|
map_settings["properties"] = {}
|
||||||
map_settings['properties'].update(properties)
|
map_settings["properties"].update(properties)
|
||||||
map_settings['properties']['datalayers'] = self.get_datalayers()
|
map_settings["properties"]["datalayers"] = self.get_datalayers()
|
||||||
context['map_settings'] = json.dumps(map_settings,
|
context["map_settings"] = json.dumps(map_settings, indent=settings.DEBUG)
|
||||||
indent=settings.DEBUG)
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def get_datalayers(self):
|
def get_datalayers(self):
|
||||||
|
@ -414,12 +410,12 @@ class MapDetailMixin:
|
||||||
return {
|
return {
|
||||||
"geometry": {
|
"geometry": {
|
||||||
"coordinates": [DEFAULT_LONGITUDE, DEFAULT_LATITUDE],
|
"coordinates": [DEFAULT_LONGITUDE, DEFAULT_LATITUDE],
|
||||||
"type": "Point"
|
"type": "Point",
|
||||||
},
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
"zoom": getattr(settings, 'LEAFLET_ZOOM', 6),
|
"zoom": getattr(settings, "LEAFLET_ZOOM", 6),
|
||||||
"datalayers": [],
|
"datalayers": [],
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_short_url(self):
|
def get_short_url(self):
|
||||||
|
@ -427,25 +423,27 @@ class MapDetailMixin:
|
||||||
|
|
||||||
|
|
||||||
class PermissionsMixin:
|
class PermissionsMixin:
|
||||||
|
|
||||||
def get_permissions(self):
|
def get_permissions(self):
|
||||||
permissions = {}
|
permissions = {}
|
||||||
permissions['edit_status'] = self.object.edit_status
|
permissions["edit_status"] = self.object.edit_status
|
||||||
permissions['share_status'] = self.object.share_status
|
permissions["share_status"] = self.object.share_status
|
||||||
if self.object.owner:
|
if self.object.owner:
|
||||||
permissions['owner'] = {
|
permissions["owner"] = {
|
||||||
'id': self.object.owner.pk,
|
"id": self.object.owner.pk,
|
||||||
'name': self.object.owner.get_username(),
|
"name": self.object.owner.get_username(),
|
||||||
'url': reverse(settings.USER_MAPS_URL,
|
"url": reverse(
|
||||||
args=(self.object.owner.get_username(), ))
|
settings.USER_MAPS_URL, args=(self.object.owner.get_username(),)
|
||||||
|
),
|
||||||
}
|
}
|
||||||
permissions['editors'] = [{
|
permissions["editors"] = [
|
||||||
'id': editor.pk,
|
{
|
||||||
'name': editor.get_username(),
|
"id": editor.pk,
|
||||||
} for editor in self.object.editors.all()]
|
"name": editor.get_username(),
|
||||||
if (not self.object.owner
|
}
|
||||||
and self.object.is_anonymous_owner(self.request)):
|
for editor in self.object.editors.all()
|
||||||
permissions['anonymous_edit_url'] = self.get_anonymous_edit_url()
|
]
|
||||||
|
if not self.object.owner and self.object.is_anonymous_owner(self.request):
|
||||||
|
permissions["anonymous_edit_url"] = self.get_anonymous_edit_url()
|
||||||
return permissions
|
return permissions
|
||||||
|
|
||||||
def get_anonymous_edit_url(self):
|
def get_anonymous_edit_url(self):
|
||||||
|
@ -454,13 +452,12 @@ class PermissionsMixin:
|
||||||
|
|
||||||
|
|
||||||
class MapView(MapDetailMixin, PermissionsMixin, DetailView):
|
class MapView(MapDetailMixin, PermissionsMixin, DetailView):
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
self.object = self.get_object()
|
self.object = self.get_object()
|
||||||
canonical = self.get_canonical_url()
|
canonical = self.get_canonical_url()
|
||||||
if not request.path == canonical:
|
if not request.path == canonical:
|
||||||
if request.META.get('QUERY_STRING'):
|
if request.META.get("QUERY_STRING"):
|
||||||
canonical = "?".join([canonical, request.META['QUERY_STRING']])
|
canonical = "?".join([canonical, request.META["QUERY_STRING"]])
|
||||||
return HttpResponsePermanentRedirect(canonical)
|
return HttpResponsePermanentRedirect(canonical)
|
||||||
if not self.object.can_view(request):
|
if not self.object.can_view(request):
|
||||||
return HttpResponseForbidden()
|
return HttpResponseForbidden()
|
||||||
|
@ -481,29 +478,26 @@ class MapView(MapDetailMixin, PermissionsMixin, DetailView):
|
||||||
|
|
||||||
def get_short_url(self):
|
def get_short_url(self):
|
||||||
shortUrl = None
|
shortUrl = None
|
||||||
if hasattr(settings, 'SHORT_SITE_URL'):
|
if hasattr(settings, "SHORT_SITE_URL"):
|
||||||
short_path = reverse_lazy('map_short_url',
|
short_path = reverse_lazy("map_short_url", kwargs={"pk": self.object.pk})
|
||||||
kwargs={'pk': self.object.pk})
|
|
||||||
shortUrl = "%s%s" % (settings.SHORT_SITE_URL, short_path)
|
shortUrl = "%s%s" % (settings.SHORT_SITE_URL, short_path)
|
||||||
return shortUrl
|
return shortUrl
|
||||||
|
|
||||||
def get_geojson(self):
|
def get_geojson(self):
|
||||||
map_settings = self.object.settings
|
map_settings = self.object.settings
|
||||||
if "properties" not in map_settings:
|
if "properties" not in map_settings:
|
||||||
map_settings['properties'] = {}
|
map_settings["properties"] = {}
|
||||||
map_settings['properties']['name'] = self.object.name
|
map_settings["properties"]["name"] = self.object.name
|
||||||
map_settings['properties']['permissions'] = self.get_permissions()
|
map_settings["properties"]["permissions"] = self.get_permissions()
|
||||||
return map_settings
|
return map_settings
|
||||||
|
|
||||||
|
|
||||||
class MapViewGeoJSON(MapView):
|
class MapViewGeoJSON(MapView):
|
||||||
|
|
||||||
def get_canonical_url(self):
|
def get_canonical_url(self):
|
||||||
return reverse('map_geojson', args=(self.object.pk, ))
|
return reverse("map_geojson", args=(self.object.pk,))
|
||||||
|
|
||||||
def render_to_response(self, context, *args, **kwargs):
|
def render_to_response(self, context, *args, **kwargs):
|
||||||
return HttpResponse(context['map_settings'],
|
return HttpResponse(context["map_settings"], content_type="application/json")
|
||||||
content_type='application/json')
|
|
||||||
|
|
||||||
|
|
||||||
class MapNew(MapDetailMixin, TemplateView):
|
class MapNew(MapDetailMixin, TemplateView):
|
||||||
|
@ -529,19 +523,17 @@ class MapCreate(FormLessEditMixin, PermissionsMixin, CreateView):
|
||||||
msg = _("Congratulations, your map has been created!")
|
msg = _("Congratulations, your map has been created!")
|
||||||
permissions = self.get_permissions()
|
permissions = self.get_permissions()
|
||||||
# User does not have the cookie yet.
|
# User does not have the cookie yet.
|
||||||
permissions['anonymous_edit_url'] = anonymous_url
|
permissions["anonymous_edit_url"] = anonymous_url
|
||||||
response = simple_json_response(
|
response = simple_json_response(
|
||||||
id=self.object.pk,
|
id=self.object.pk,
|
||||||
url=self.object.get_absolute_url(),
|
url=self.object.get_absolute_url(),
|
||||||
permissions=permissions,
|
permissions=permissions,
|
||||||
info=msg
|
info=msg,
|
||||||
)
|
)
|
||||||
if not self.request.user.is_authenticated:
|
if not self.request.user.is_authenticated:
|
||||||
key, value = self.object.signed_cookie_elements
|
key, value = self.object.signed_cookie_elements
|
||||||
response.set_signed_cookie(
|
response.set_signed_cookie(
|
||||||
key=key,
|
key=key, value=value, max_age=ANONYMOUS_COOKIE_MAX_AGE
|
||||||
value=value,
|
|
||||||
max_age=ANONYMOUS_COOKIE_MAX_AGE
|
|
||||||
)
|
)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
@ -549,7 +541,7 @@ class MapCreate(FormLessEditMixin, PermissionsMixin, CreateView):
|
||||||
class MapUpdate(FormLessEditMixin, PermissionsMixin, UpdateView):
|
class MapUpdate(FormLessEditMixin, PermissionsMixin, UpdateView):
|
||||||
model = Map
|
model = Map
|
||||||
form_class = MapSettingsForm
|
form_class = MapSettingsForm
|
||||||
pk_url_kwarg = 'map_id'
|
pk_url_kwarg = "map_id"
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
self.object.settings = form.cleaned_data["settings"]
|
self.object.settings = form.cleaned_data["settings"]
|
||||||
|
@ -564,7 +556,7 @@ class MapUpdate(FormLessEditMixin, PermissionsMixin, UpdateView):
|
||||||
|
|
||||||
class UpdateMapPermissions(FormLessEditMixin, UpdateView):
|
class UpdateMapPermissions(FormLessEditMixin, UpdateView):
|
||||||
model = Map
|
model = Map
|
||||||
pk_url_kwarg = 'map_id'
|
pk_url_kwarg = "map_id"
|
||||||
|
|
||||||
def get_form_class(self):
|
def get_form_class(self):
|
||||||
if self.object.owner:
|
if self.object.owner:
|
||||||
|
@ -576,25 +568,25 @@ class UpdateMapPermissions(FormLessEditMixin, UpdateView):
|
||||||
form = super().get_form(form_class)
|
form = super().get_form(form_class)
|
||||||
user = self.request.user
|
user = self.request.user
|
||||||
if self.object.owner and not user == self.object.owner:
|
if self.object.owner and not user == self.object.owner:
|
||||||
del form.fields['edit_status']
|
del form.fields["edit_status"]
|
||||||
del form.fields['share_status']
|
del form.fields["share_status"]
|
||||||
del form.fields['owner']
|
del form.fields["owner"]
|
||||||
return form
|
return form
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
self.object = form.save()
|
self.object = form.save()
|
||||||
return simple_json_response(
|
return simple_json_response(info=_("Map editors updated with success!"))
|
||||||
info=_("Map editors updated with success!"))
|
|
||||||
|
|
||||||
|
|
||||||
class AttachAnonymousMap(View):
|
class AttachAnonymousMap(View):
|
||||||
|
|
||||||
def post(self, *args, **kwargs):
|
def post(self, *args, **kwargs):
|
||||||
self.object = kwargs['map_inst']
|
self.object = kwargs["map_inst"]
|
||||||
if (self.object.owner
|
if (
|
||||||
or not self.object.is_anonymous_owner(self.request)
|
self.object.owner
|
||||||
or not self.object.can_edit(self.request.user, self.request)
|
or not self.object.is_anonymous_owner(self.request)
|
||||||
or not self.request.user.is_authenticated):
|
or not self.object.can_edit(self.request.user, self.request)
|
||||||
|
or not self.request.user.is_authenticated
|
||||||
|
):
|
||||||
return HttpResponseForbidden()
|
return HttpResponseForbidden()
|
||||||
self.object.owner = self.request.user
|
self.object.owner = self.request.user
|
||||||
self.object.save()
|
self.object.save()
|
||||||
|
@ -608,30 +600,27 @@ class MapDelete(DeleteView):
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
self.object = self.get_object()
|
self.object = self.get_object()
|
||||||
if self.object.owner and self.request.user != self.object.owner:
|
if self.object.owner and self.request.user != self.object.owner:
|
||||||
return HttpResponseForbidden(
|
return HttpResponseForbidden(_("Only its owner can delete the map."))
|
||||||
_('Only its owner can delete the map.'))
|
if not self.object.owner and not self.object.is_anonymous_owner(self.request):
|
||||||
if not self.object.owner\
|
|
||||||
and not self.object.is_anonymous_owner(self.request):
|
|
||||||
return HttpResponseForbidden()
|
return HttpResponseForbidden()
|
||||||
self.object.delete()
|
self.object.delete()
|
||||||
return simple_json_response(redirect="/")
|
return simple_json_response(redirect="/")
|
||||||
|
|
||||||
|
|
||||||
class MapClone(PermissionsMixin, View):
|
class MapClone(PermissionsMixin, View):
|
||||||
|
|
||||||
def post(self, *args, **kwargs):
|
def post(self, *args, **kwargs):
|
||||||
if not getattr(settings, "UMAP_ALLOW_ANONYMOUS", False) \
|
if (
|
||||||
and not self.request.user.is_authenticated:
|
not getattr(settings, "UMAP_ALLOW_ANONYMOUS", False)
|
||||||
|
and not self.request.user.is_authenticated
|
||||||
|
):
|
||||||
return HttpResponseForbidden()
|
return HttpResponseForbidden()
|
||||||
owner = self.request.user if self.request.user.is_authenticated else None
|
owner = self.request.user if self.request.user.is_authenticated else None
|
||||||
self.object = kwargs['map_inst'].clone(owner=owner)
|
self.object = kwargs["map_inst"].clone(owner=owner)
|
||||||
response = simple_json_response(redirect=self.object.get_absolute_url())
|
response = simple_json_response(redirect=self.object.get_absolute_url())
|
||||||
if not self.request.user.is_authenticated:
|
if not self.request.user.is_authenticated:
|
||||||
key, value = self.object.signed_cookie_elements
|
key, value = self.object.signed_cookie_elements
|
||||||
response.set_signed_cookie(
|
response.set_signed_cookie(
|
||||||
key=key,
|
key=key, value=value, max_age=ANONYMOUS_COOKIE_MAX_AGE
|
||||||
value=value,
|
|
||||||
max_age=ANONYMOUS_COOKIE_MAX_AGE
|
|
||||||
)
|
)
|
||||||
msg = _(
|
msg = _(
|
||||||
"Your map has been cloned! If you want to edit this map from "
|
"Your map has been cloned! If you want to edit this map from "
|
||||||
|
@ -649,10 +638,10 @@ class MapShortUrl(RedirectView):
|
||||||
permanent = True
|
permanent = True
|
||||||
|
|
||||||
def get_redirect_url(self, **kwargs):
|
def get_redirect_url(self, **kwargs):
|
||||||
map_inst = get_object_or_404(Map, pk=kwargs['pk'])
|
map_inst = get_object_or_404(Map, pk=kwargs["pk"])
|
||||||
url = map_inst.get_absolute_url()
|
url = map_inst.get_absolute_url()
|
||||||
if self.query_string:
|
if self.query_string:
|
||||||
args = self.request.META.get('QUERY_STRING', '')
|
args = self.request.META.get("QUERY_STRING", "")
|
||||||
if args:
|
if args:
|
||||||
url = "%s?%s" % (url, args)
|
url = "%s?%s" % (url, args)
|
||||||
return url
|
return url
|
||||||
|
@ -665,7 +654,7 @@ class MapAnonymousEditUrl(RedirectView):
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
signer = Signer()
|
signer = Signer()
|
||||||
try:
|
try:
|
||||||
pk = signer.unsign(self.kwargs['signature'])
|
pk = signer.unsign(self.kwargs["signature"])
|
||||||
except BadSignature:
|
except BadSignature:
|
||||||
return HttpResponseForbidden()
|
return HttpResponseForbidden()
|
||||||
else:
|
else:
|
||||||
|
@ -675,9 +664,7 @@ class MapAnonymousEditUrl(RedirectView):
|
||||||
if not map_inst.owner:
|
if not map_inst.owner:
|
||||||
key, value = map_inst.signed_cookie_elements
|
key, value = map_inst.signed_cookie_elements
|
||||||
response.set_signed_cookie(
|
response.set_signed_cookie(
|
||||||
key=key,
|
key=key, value=value, max_age=ANONYMOUS_COOKIE_MAX_AGE
|
||||||
value=value,
|
|
||||||
max_age=ANONYMOUS_COOKIE_MAX_AGE
|
|
||||||
)
|
)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
@ -734,15 +721,16 @@ class DataLayerView(GZipMixin, BaseDetailView):
|
||||||
|
|
||||||
if getattr(settings, 'UMAP_XSENDFILE_HEADER', None):
|
if getattr(settings, 'UMAP_XSENDFILE_HEADER', None):
|
||||||
response = HttpResponse()
|
response = HttpResponse()
|
||||||
path = path.replace(settings.MEDIA_ROOT, '/internal')
|
path = path.replace(settings.MEDIA_ROOT, "/internal")
|
||||||
response[settings.UMAP_XSENDFILE_HEADER] = path
|
response[settings.UMAP_XSENDFILE_HEADER] = path
|
||||||
else:
|
else:
|
||||||
# TODO IMS
|
# TODO IMS
|
||||||
statobj = os.stat(path)
|
statobj = os.stat(path)
|
||||||
with open(path, 'rb') as f:
|
with open(path, "rb") as f:
|
||||||
|
# Should not be used in production!
|
||||||
response = HttpResponse(
|
response = HttpResponse(
|
||||||
f.read(), # should not be used in production!
|
f.read(),
|
||||||
content_type='application/json'
|
content_type="application/json"
|
||||||
)
|
)
|
||||||
response["Last-Modified"] = http_date(statobj.st_mtime)
|
response["Last-Modified"] = http_date(statobj.st_mtime)
|
||||||
response['ETag'] = self.etag()
|
response['ETag'] = self.etag()
|
||||||
|
@ -754,11 +742,11 @@ class DataLayerView(GZipMixin, BaseDetailView):
|
||||||
|
|
||||||
|
|
||||||
class DataLayerVersion(DataLayerView):
|
class DataLayerVersion(DataLayerView):
|
||||||
|
|
||||||
def _path(self):
|
def _path(self):
|
||||||
return '{root}/{path}'.format(
|
return "{root}/{path}".format(
|
||||||
root=settings.MEDIA_ROOT,
|
root=settings.MEDIA_ROOT,
|
||||||
path=self.object.get_version_path(self.kwargs['name']))
|
path=self.object.get_version_path(self.kwargs["name"]),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class DataLayerCreate(FormLessEditMixin, GZipMixin, CreateView):
|
class DataLayerCreate(FormLessEditMixin, GZipMixin, CreateView):
|
||||||
|
@ -798,7 +786,7 @@ class DataLayerUpdate(FormLessEditMixin, GZipMixin, UpdateView):
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
self.object = self.get_object()
|
self.object = self.get_object()
|
||||||
if self.object.map != self.kwargs['map_inst']:
|
if self.object.map != self.kwargs["map_inst"]:
|
||||||
return HttpResponseForbidden()
|
return HttpResponseForbidden()
|
||||||
if not self.if_match():
|
if not self.if_match():
|
||||||
return HttpResponse(status=412)
|
return HttpResponse(status=412)
|
||||||
|
@ -810,7 +798,7 @@ class DataLayerDelete(DeleteView):
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
self.object = self.get_object()
|
self.object = self.get_object()
|
||||||
if self.object.map != self.kwargs['map_inst']:
|
if self.object.map != self.kwargs["map_inst"]:
|
||||||
return HttpResponseForbidden()
|
return HttpResponseForbidden()
|
||||||
self.object.delete()
|
self.object.delete()
|
||||||
return simple_json_response(info=_("Layer successfully deleted."))
|
return simple_json_response(info=_("Layer successfully deleted."))
|
||||||
|
@ -827,6 +815,7 @@ class DataLayerVersions(BaseDetailView):
|
||||||
# Picto #
|
# Picto #
|
||||||
# ############## #
|
# ############## #
|
||||||
|
|
||||||
|
|
||||||
class PictogramJSONList(ListView):
|
class PictogramJSONList(ListView):
|
||||||
model = Pictogram
|
model = Pictogram
|
||||||
|
|
||||||
|
@ -839,6 +828,7 @@ class PictogramJSONList(ListView):
|
||||||
# Generic #
|
# Generic #
|
||||||
# ############## #
|
# ############## #
|
||||||
|
|
||||||
|
|
||||||
def logout(request):
|
def logout(request):
|
||||||
do_logout(request)
|
do_logout(request)
|
||||||
return simple_json_response(redirect="/")
|
return simple_json_response(redirect="/")
|
||||||
|
@ -849,4 +839,5 @@ class LoginPopupEnd(TemplateView):
|
||||||
End of a loggin process in popup.
|
End of a loggin process in popup.
|
||||||
Basically close the popup.
|
Basically close the popup.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
template_name = "umap/login_popup_end.html"
|
template_name = "umap/login_popup_end.html"
|
||||||
|
|
Loading…
Reference in a new issue