Compare commits
No commits in common. "5ae83a571be75bd16550e921a5de7ee46610e860" and "5ab11428a5815a0edfd61575e0e2bbdb334a4967" have entirely different histories.
5ae83a571b
...
5ab11428a5
|
@ -28,14 +28,6 @@ Can be set through env var too: `ALLOWED_HOSTS=umap.mydomain.org,u.mydomain.org`
|
||||||
|
|
||||||
Set it to `True` for easier debugging in case of error.
|
Set it to `True` for easier debugging in case of error.
|
||||||
|
|
||||||
#### DEPRECATED_AUTHENTICATION_PROVIDERS
|
|
||||||
|
|
||||||
List of auth providers to deprecate. Defining this will display a message to
|
|
||||||
all users using this provider, to encourage them to configure another provider to
|
|
||||||
their account.
|
|
||||||
|
|
||||||
DEPRECATED_AUTHENTICATION_PROVIDERS = ["social_core.backends.twitter_oauth2.TwitterOAuth2"]
|
|
||||||
|
|
||||||
#### EMAIL_BACKEND
|
#### EMAIL_BACKEND
|
||||||
|
|
||||||
Must be configured if you want uMap to send emails to anonymous users.
|
Must be configured if you want uMap to send emails to anonymous users.
|
||||||
|
@ -106,12 +98,7 @@ Eg.: `SHORT_SITE_URL=https://u.umap.org`
|
||||||
|
|
||||||
#### SITE_NAME
|
#### SITE_NAME
|
||||||
|
|
||||||
The name of the site, to be used in header.
|
The name of the site, to be used in header and HTML title.
|
||||||
|
|
||||||
|
|
||||||
#### SITE_DESCRIPTION
|
|
||||||
|
|
||||||
The description of the site, to be used in HTML title.
|
|
||||||
|
|
||||||
|
|
||||||
#### SITE_URL
|
#### SITE_URL
|
||||||
|
|
|
@ -7,7 +7,6 @@ def settings(request):
|
||||||
return {
|
return {
|
||||||
"UMAP_HELP_URL": djsettings.UMAP_HELP_URL,
|
"UMAP_HELP_URL": djsettings.UMAP_HELP_URL,
|
||||||
"SITE_NAME": djsettings.SITE_NAME,
|
"SITE_NAME": djsettings.SITE_NAME,
|
||||||
"SITE_DESCRIPTION": djsettings.SITE_DESCRIPTION,
|
|
||||||
"SITE_URL": djsettings.SITE_URL,
|
"SITE_URL": djsettings.SITE_URL,
|
||||||
"ENABLE_ACCOUNT_LOGIN": djsettings.ENABLE_ACCOUNT_LOGIN,
|
"ENABLE_ACCOUNT_LOGIN": djsettings.ENABLE_ACCOUNT_LOGIN,
|
||||||
"UMAP_READONLY": djsettings.UMAP_READONLY,
|
"UMAP_READONLY": djsettings.UMAP_READONLY,
|
||||||
|
|
|
@ -2,7 +2,7 @@ from datetime import datetime, timedelta
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
|
|
||||||
from umap.models import DataLayer, Map
|
from umap.models import Map
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
|
@ -33,14 +33,3 @@ class Command(BaseCommand):
|
||||||
if not options["dry_run"]:
|
if not options["dry_run"]:
|
||||||
map.delete()
|
map.delete()
|
||||||
print(f"Deleted map {map_name} ({map_id}), trashed at {trashed_at}")
|
print(f"Deleted map {map_name} ({map_id}), trashed at {trashed_at}")
|
||||||
print(f"Deleting layers in trash since {since}")
|
|
||||||
layers = DataLayer.objects.filter(
|
|
||||||
share_status=DataLayer.DELETED, modified_at__lt=since
|
|
||||||
)
|
|
||||||
for layer in layers:
|
|
||||||
layer_id = layer.uuid
|
|
||||||
layer_name = layer.name
|
|
||||||
trashed_at = layer.modified_at.date()
|
|
||||||
if not options["dry_run"]:
|
|
||||||
layer.delete()
|
|
||||||
print(f"Deleted layer {layer_name} ({layer_id}), trashed at {trashed_at}")
|
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
# Generated by Django 5.1.4 on 2025-01-29 18:06
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
dependencies = [
|
|
||||||
("umap", "0025_alter_datalayer_geojson"),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name="datalayer",
|
|
||||||
name="modified_at",
|
|
||||||
field=models.DateTimeField(auto_now=True),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name="datalayer",
|
|
||||||
name="share_status",
|
|
||||||
field=models.SmallIntegerField(
|
|
||||||
choices=[(0, "Inherit"), (99, "Deleted")],
|
|
||||||
default=0,
|
|
||||||
verbose_name="share status",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -247,13 +247,9 @@ class Map(NamedModel):
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
@property
|
|
||||||
def datalayers(self):
|
|
||||||
return self.datalayer_set.filter(share_status=DataLayer.INHERIT).all()
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def preview_settings(self):
|
def preview_settings(self):
|
||||||
layers = self.datalayers
|
layers = self.datalayer_set.all()
|
||||||
datalayer_data = [c.metadata() for c in layers]
|
datalayer_data = [c.metadata() for c in layers]
|
||||||
map_settings = self.settings
|
map_settings = self.settings
|
||||||
if "properties" not in map_settings:
|
if "properties" not in map_settings:
|
||||||
|
@ -282,7 +278,6 @@ class Map(NamedModel):
|
||||||
def delete(self, **kwargs):
|
def delete(self, **kwargs):
|
||||||
# Explicitely call datalayers.delete, so we can deal with removing files
|
# Explicitely call datalayers.delete, so we can deal with removing files
|
||||||
# (the cascade delete would not call the model delete method)
|
# (the cascade delete would not call the model delete method)
|
||||||
# Use datalayer_set so to get also the deleted ones.
|
|
||||||
for datalayer in self.datalayer_set.all():
|
for datalayer in self.datalayer_set.all():
|
||||||
datalayer.delete()
|
datalayer.delete()
|
||||||
return super().delete(**kwargs)
|
return super().delete(**kwargs)
|
||||||
|
@ -292,7 +287,7 @@ class Map(NamedModel):
|
||||||
umapjson["type"] = "umap"
|
umapjson["type"] = "umap"
|
||||||
umapjson["uri"] = request.build_absolute_uri(self.get_absolute_url())
|
umapjson["uri"] = request.build_absolute_uri(self.get_absolute_url())
|
||||||
datalayers = []
|
datalayers = []
|
||||||
for datalayer in self.datalayers:
|
for datalayer in self.datalayer_set.all():
|
||||||
with datalayer.geojson.open("rb") as f:
|
with datalayer.geojson.open("rb") as f:
|
||||||
layer = json.loads(f.read())
|
layer = json.loads(f.read())
|
||||||
if datalayer.settings:
|
if datalayer.settings:
|
||||||
|
@ -411,7 +406,7 @@ class Map(NamedModel):
|
||||||
new.save()
|
new.save()
|
||||||
for editor in self.editors.all():
|
for editor in self.editors.all():
|
||||||
new.editors.add(editor)
|
new.editors.add(editor)
|
||||||
for datalayer in self.datalayers:
|
for datalayer in self.datalayer_set.all():
|
||||||
datalayer.clone(map_inst=new)
|
datalayer.clone(map_inst=new)
|
||||||
return new
|
return new
|
||||||
|
|
||||||
|
@ -463,11 +458,6 @@ class DataLayer(NamedModel):
|
||||||
ANONYMOUS = 1
|
ANONYMOUS = 1
|
||||||
COLLABORATORS = 2
|
COLLABORATORS = 2
|
||||||
OWNER = 3
|
OWNER = 3
|
||||||
DELETED = 99
|
|
||||||
SHARE_STATUS = (
|
|
||||||
(INHERIT, _("Inherit")),
|
|
||||||
(DELETED, _("Deleted")),
|
|
||||||
)
|
|
||||||
EDIT_STATUS = (
|
EDIT_STATUS = (
|
||||||
(INHERIT, _("Inherit")),
|
(INHERIT, _("Inherit")),
|
||||||
(ANONYMOUS, _("Everyone")),
|
(ANONYMOUS, _("Everyone")),
|
||||||
|
@ -500,12 +490,6 @@ class DataLayer(NamedModel):
|
||||||
default=INHERIT,
|
default=INHERIT,
|
||||||
verbose_name=_("edit status"),
|
verbose_name=_("edit status"),
|
||||||
)
|
)
|
||||||
share_status = models.SmallIntegerField(
|
|
||||||
choices=SHARE_STATUS,
|
|
||||||
default=INHERIT,
|
|
||||||
verbose_name=_("share status"),
|
|
||||||
)
|
|
||||||
modified_at = models.DateTimeField(auto_now=True)
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ("rank",)
|
ordering = ("rank",)
|
||||||
|
@ -584,10 +568,6 @@ class DataLayer(NamedModel):
|
||||||
can = True
|
can = True
|
||||||
return can
|
return can
|
||||||
|
|
||||||
def move_to_trash(self):
|
|
||||||
self.share_status = DataLayer.DELETED
|
|
||||||
self.save()
|
|
||||||
|
|
||||||
|
|
||||||
class Star(models.Model):
|
class Star(models.Model):
|
||||||
at = models.DateTimeField(auto_now=True)
|
at = models.DateTimeField(auto_now=True)
|
||||||
|
|
|
@ -267,7 +267,6 @@ UMAP_KEEP_VERSIONS = env.int("UMAP_KEEP_VERSIONS", default=10)
|
||||||
SITE_URL = env("SITE_URL", default="http://umap.org")
|
SITE_URL = env("SITE_URL", default="http://umap.org")
|
||||||
SHORT_SITE_URL = env("SHORT_SITE_URL", default=None)
|
SHORT_SITE_URL = env("SHORT_SITE_URL", default=None)
|
||||||
SITE_NAME = "uMap"
|
SITE_NAME = "uMap"
|
||||||
SITE_DESCRIPTION = "Online map creator"
|
|
||||||
UMAP_DEMO_SITE = env("UMAP_DEMO_SITE", default=False)
|
UMAP_DEMO_SITE = env("UMAP_DEMO_SITE", default=False)
|
||||||
UMAP_EXCLUDE_DEFAULT_MAPS = False
|
UMAP_EXCLUDE_DEFAULT_MAPS = False
|
||||||
UMAP_MAPS_PER_PAGE = 5
|
UMAP_MAPS_PER_PAGE = 5
|
||||||
|
@ -306,7 +305,6 @@ LOGIN_URL = "login"
|
||||||
SOCIAL_AUTH_LOGIN_REDIRECT_URL = "/login/popup/end/"
|
SOCIAL_AUTH_LOGIN_REDIRECT_URL = "/login/popup/end/"
|
||||||
|
|
||||||
AUTHENTICATION_BACKENDS = ()
|
AUTHENTICATION_BACKENDS = ()
|
||||||
DEPRECATED_AUTHENTICATION_BACKENDS = []
|
|
||||||
|
|
||||||
SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_KEY = env(
|
SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_KEY = env(
|
||||||
"SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_KEY", default=""
|
"SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_KEY", default=""
|
||||||
|
|
BIN
umap/static/umap/bitbucket.png
Normal file
After Width: | Height: | Size: 8.9 KiB |
|
@ -41,14 +41,33 @@ body.login header {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-grid span,
|
|
||||||
.login-grid a {
|
.login-grid a {
|
||||||
border: 1px solid #e5e5e5;
|
border: 1px solid #e5e5e5;
|
||||||
|
padding: 5px;
|
||||||
color: #000;
|
color: #000;
|
||||||
|
background-position: center bottom;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: 92px 92px;
|
||||||
height: 92px;
|
height: 92px;
|
||||||
width: 92px;
|
width: 92px;
|
||||||
margin-inline-end: 10px;
|
margin-inline-end: 10px;
|
||||||
}
|
}
|
||||||
|
.login-grid .login-github {
|
||||||
|
background-image: url("./github.png");
|
||||||
|
}
|
||||||
|
.login-grid .login-bitbucket {
|
||||||
|
background-image: url("./bitbucket.png");
|
||||||
|
}
|
||||||
|
.login-grid .login-twitter-oauth2 {
|
||||||
|
background-image: url("./twitter.png");
|
||||||
|
}
|
||||||
|
.login-grid .login-openstreetmap,
|
||||||
|
.login-grid .login-openstreetmap-oauth2 {
|
||||||
|
background-image: url("./openstreetmap.png");
|
||||||
|
}
|
||||||
|
.login-grid .login-keycloak {
|
||||||
|
background-image: url("./keycloak.png");
|
||||||
|
}
|
||||||
|
|
||||||
/* **************************** */
|
/* **************************** */
|
||||||
/* home */
|
/* home */
|
||||||
|
|
BIN
umap/static/umap/github.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 608 B |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 545 B |
|
@ -1191,13 +1191,11 @@ Fields.TernaryChoices = class extends Fields.MultiChoice {
|
||||||
|
|
||||||
Fields.NullableChoices = class extends Fields.TernaryChoices {
|
Fields.NullableChoices = class extends Fields.TernaryChoices {
|
||||||
getChoices() {
|
getChoices() {
|
||||||
return (
|
return [
|
||||||
this.properties.choices || [
|
[true, translate('always')],
|
||||||
[true, translate('always')],
|
[false, translate('never')],
|
||||||
[false, translate('never')],
|
['null', translate('hidden')],
|
||||||
['null', translate('hidden')],
|
]
|
||||||
]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -447,11 +447,6 @@ export const SCHEMA = {
|
||||||
label: translate('Display label'),
|
label: translate('Display label'),
|
||||||
inheritable: true,
|
inheritable: true,
|
||||||
default: false,
|
default: false,
|
||||||
choices: [
|
|
||||||
[true, translate('always')],
|
|
||||||
[false, translate('never')],
|
|
||||||
['null', translate('on hover')],
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
slideshow: {
|
slideshow: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
|
BIN
umap/static/umap/keycloak.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
umap/static/umap/openstreetmap.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
umap/static/umap/twitter.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
|
@ -2,10 +2,6 @@
|
||||||
|
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block head_title %}
|
|
||||||
{% blocktranslate %}{{ current_user }}’s maps{% endblocktranslate %} - {{ SITE_DESCRIPTION }}
|
|
||||||
{% endblock head_title %}
|
|
||||||
|
|
||||||
{% block maincontent %}
|
{% block maincontent %}
|
||||||
<div class="col wide">
|
<div class="col wide">
|
||||||
<h2 class="section">
|
<h2 class="section">
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
{% extends "umap/content.html" %}
|
{% extends "umap/content.html" %}
|
||||||
|
|
||||||
{% load i18n static %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block head_title %}
|
|
||||||
{% translate "My Profile" %} - {{ SITE_DESCRIPTION }}
|
|
||||||
{% endblock head_title %}
|
|
||||||
{% block maincontent %}
|
{% block maincontent %}
|
||||||
{% include "umap/dashboard_menu.html" with selected="profile" %}
|
{% include "umap/dashboard_menu.html" with selected="profile" %}
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
|
@ -31,10 +28,8 @@
|
||||||
</h3>
|
</h3>
|
||||||
<ul>
|
<ul>
|
||||||
{% for name in providers %}
|
{% for name in providers %}
|
||||||
<li class="login-grid">
|
<li>
|
||||||
{% with "umap/img/providers/"|add:name|add:".png" as path %}
|
{{ name|title }}
|
||||||
<img src="{% static path %}" width="92px" height="92px" alt="{{ name }}" />
|
|
||||||
{% endwith %}
|
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -51,7 +46,9 @@
|
||||||
{% for name in backends.backends %}
|
{% for name in backends.backends %}
|
||||||
{% if name not in providers %}
|
{% if name not in providers %}
|
||||||
<li>
|
<li>
|
||||||
{% include "umap/components/provider.html" with name=name %}
|
<a href="{% url "social:begin" name %}"
|
||||||
|
class="umap-login-popup login-{{ name }}"
|
||||||
|
title="{{ name|title }}"></a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
|
@ -2,10 +2,6 @@
|
||||||
|
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block head_title %}
|
|
||||||
{% blocktranslate %}{{ current_user }}’s starred maps{% endblocktranslate %} - {{ SITE_DESCRIPTION }}
|
|
||||||
{% endblock head_title %}
|
|
||||||
|
|
||||||
{% block maincontent %}
|
{% block maincontent %}
|
||||||
<div class="col wide">
|
<div class="col wide">
|
||||||
<h2 class="section">
|
<h2 class="section">
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<head>
|
<head>
|
||||||
<title>
|
<title>
|
||||||
{% block head_title %}
|
{% block head_title %}
|
||||||
{{ SITE_NAME }} - {{ SITE_DESCRIPTION }}
|
{{ SITE_NAME }}
|
||||||
{% endblock head_title %}
|
{% endblock head_title %}
|
||||||
</title>
|
</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block head_title %}
|
{% block head_title %}
|
||||||
{% trans "Login" %} - {{ SITE_DESCRIPTION }}
|
{% trans "Login" %}
|
||||||
{% endblock head_title %}
|
{% endblock head_title %}
|
||||||
{% load umap_tags i18n %}
|
{% load umap_tags i18n %}
|
||||||
|
|
||||||
|
@ -55,7 +55,10 @@
|
||||||
<ul class="login-grid block-grid">
|
<ul class="login-grid block-grid">
|
||||||
{% for name in backends.backends %}
|
{% for name in backends.backends %}
|
||||||
<li>
|
<li>
|
||||||
{% include "umap/components/provider.html" with name=name %}
|
<a rel="nofollow"
|
||||||
|
href="{% url "social:begin" name %}"
|
||||||
|
class="umap-login-popup login-{{ name }}"
|
||||||
|
title="{{ name|title }}"></a>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
{% extends "umap/content.html" %}
|
{% extends "umap/content.html" %}
|
||||||
{% load i18n %}
|
|
||||||
|
|
||||||
{% block head_title %}
|
|
||||||
{% translate "About" %} - {{ SITE_DESCRIPTION }}
|
|
||||||
{% endblock head_title %}
|
|
||||||
|
|
||||||
{% block maincontent %}
|
{% block maincontent %}
|
||||||
{% include "umap/about_summary.html" %}
|
{% include "umap/about_summary.html" %}
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
{% load static %}
|
|
||||||
<a href="{% url "social:begin" name %}"
|
|
||||||
class="umap-login-popup"
|
|
||||||
title="{{ name|title }}">
|
|
||||||
{% with "umap/img/providers/"|add:name|add:".png" as path %}
|
|
||||||
<img src="{% static path %}" width="92px" height="92px" alt="{{ name }}" />
|
|
||||||
{% endwith %}
|
|
||||||
</a>
|
|
|
@ -3,7 +3,7 @@
|
||||||
{% load umap_tags i18n %}
|
{% load umap_tags i18n %}
|
||||||
|
|
||||||
{% block head_title %}
|
{% block head_title %}
|
||||||
{{ map.name }} - {{ SITE_NAME }} - {{ SITE_DESCRIPTION }}
|
{{ map.name }} - {{ SITE_NAME }}
|
||||||
{% endblock head_title %}
|
{% endblock head_title %}
|
||||||
{% block body_class %}
|
{% block body_class %}
|
||||||
map_detail
|
map_detail
|
||||||
|
|
|
@ -2,10 +2,6 @@
|
||||||
|
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block head_title %}
|
|
||||||
{% translate "Password change" %} - {{ SITE_DESCRIPTION }}
|
|
||||||
{% endblock head_title %}
|
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h2 class="section">
|
<h2 class="section">
|
||||||
{% trans "Password change" %}
|
{% trans "Password change" %}
|
||||||
|
|
|
@ -2,10 +2,6 @@
|
||||||
|
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block head_title %}
|
|
||||||
{% translate "Password change successful" %} - {{ SITE_DESCRIPTION }}
|
|
||||||
{% endblock head_title %}
|
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h2 class="section">
|
<h2 class="section">
|
||||||
{% trans "Password change successful" %}
|
{% trans "Password change successful" %}
|
||||||
|
|
|
@ -2,10 +2,6 @@
|
||||||
|
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block head_title %}
|
|
||||||
{% translate "Explore maps" %} - {{ SITE_DESCRIPTION }}
|
|
||||||
{% endblock head_title %}
|
|
||||||
|
|
||||||
{% block messages %}
|
{% block messages %}
|
||||||
{# We don't want maps from the results list to display errors in the main page. #}
|
{# We don't want maps from the results list to display errors in the main page. #}
|
||||||
{% endblock messages %}
|
{% endblock messages %}
|
||||||
|
|
|
@ -2,10 +2,6 @@
|
||||||
|
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block head_title %}
|
|
||||||
{% translate "Team deletion" %} - {{ SITE_DESCRIPTION }}
|
|
||||||
{% endblock head_title %}
|
|
||||||
|
|
||||||
{% block maincontent %}
|
{% block maincontent %}
|
||||||
{% include "umap/dashboard_menu.html" with selected="teams" %}
|
{% include "umap/dashboard_menu.html" with selected="teams" %}
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
|
|
|
@ -2,10 +2,6 @@
|
||||||
|
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block head_title %}
|
|
||||||
{% blocktranslate %}{{ current_team }}’s maps{% endblocktranslate %} - {{ SITE_DESCRIPTION }}
|
|
||||||
{% endblock head_title %}
|
|
||||||
|
|
||||||
{% block maincontent %}
|
{% block maincontent %}
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
|
@ -2,10 +2,6 @@
|
||||||
|
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block head_title %}
|
|
||||||
{% translate "Create or edit a team" %} - {{ SITE_DESCRIPTION }}
|
|
||||||
{% endblock head_title %}
|
|
||||||
|
|
||||||
{% block maincontent %}
|
{% block maincontent %}
|
||||||
{% include "umap/dashboard_menu.html" with selected="teams" %}
|
{% include "umap/dashboard_menu.html" with selected="teams" %}
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
{% load i18n static %}
|
{% load i18n static %}
|
||||||
|
|
||||||
{% block head_title %}
|
{% block head_title %}
|
||||||
{% translate "My Dashboard" %} - {{ SITE_DESCRIPTION }}
|
{{ SITE_NAME }} - {% trans "My Dashboard" %}
|
||||||
{% endblock head_title %}
|
{% endblock head_title %}
|
||||||
{% block maincontent %}
|
{% block maincontent %}
|
||||||
{% trans "Search my maps" as placeholder %}
|
{% trans "Search my maps" as placeholder %}
|
||||||
|
|
|
@ -2,10 +2,6 @@
|
||||||
|
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block head_title %}
|
|
||||||
{% translate "My Teams" %} - {{ SITE_DESCRIPTION }}
|
|
||||||
{% endblock head_title %}
|
|
||||||
|
|
||||||
{% block maincontent %}
|
{% block maincontent %}
|
||||||
{% include "umap/dashboard_menu.html" with selected="teams" %}
|
{% include "umap/dashboard_menu.html" with selected="teams" %}
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
|
|
|
@ -8,7 +8,7 @@ from umap.models import Map
|
||||||
|
|
||||||
def test_page_title(page, live_server):
|
def test_page_title(page, live_server):
|
||||||
page.goto(live_server.url)
|
page.goto(live_server.url)
|
||||||
expect(page).to_have_title("uMap - Online map creator")
|
expect(page).to_have_title("uMap")
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
|
@ -83,7 +83,7 @@ def test_login_from_map_page(live_server, page, tilelayer, settings, user, conte
|
||||||
page.get_by_role("button", name="Save").click()
|
page.get_by_role("button", name="Save").click()
|
||||||
assert Map.objects.count() == 0
|
assert Map.objects.count() == 0
|
||||||
login_page = login_page_info.value
|
login_page = login_page_info.value
|
||||||
expect(login_page).to_have_title("Login - Online map creator")
|
expect(login_page).to_have_title("Login")
|
||||||
login_page.get_by_placeholder("Username").fill(user.username)
|
login_page.get_by_placeholder("Username").fill(user.username)
|
||||||
login_page.get_by_placeholder("Password").fill("123123")
|
login_page.get_by_placeholder("Password").fill("123123")
|
||||||
with page.expect_response(re.compile(r".*/map/create/")):
|
with page.expect_response(re.compile(r".*/map/create/")):
|
||||||
|
|
|
@ -158,14 +158,11 @@ def test_should_not_be_possible_to_update_with_wrong_map_id_in_url(
|
||||||
|
|
||||||
|
|
||||||
def test_delete(client, datalayer, map):
|
def test_delete(client, datalayer, map):
|
||||||
assert map.datalayers.count() == 1
|
|
||||||
url = reverse("datalayer_delete", args=(map.pk, datalayer.pk))
|
url = reverse("datalayer_delete", args=(map.pk, datalayer.pk))
|
||||||
client.login(username=map.owner.username, password="123123")
|
client.login(username=map.owner.username, password="123123")
|
||||||
response = client.post(url, {}, follow=True)
|
response = client.post(url, {}, follow=True)
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
assert DataLayer.objects.filter(pk=datalayer.pk).count()
|
assert not DataLayer.objects.filter(pk=datalayer.pk).count()
|
||||||
assert map.datalayers.count() == 0
|
|
||||||
assert DataLayer.objects.get(pk=datalayer.pk).share_status == DataLayer.DELETED
|
|
||||||
# Check that map has not been impacted
|
# Check that map has not been impacted
|
||||||
assert Map.objects.filter(pk=map.pk).exists()
|
assert Map.objects.filter(pk=map.pk).exists()
|
||||||
# Test response is a json
|
# Test response is a json
|
||||||
|
|
|
@ -4,17 +4,15 @@ from unittest import mock
|
||||||
import pytest
|
import pytest
|
||||||
from django.core.management import call_command
|
from django.core.management import call_command
|
||||||
|
|
||||||
from umap.models import DataLayer, Map
|
from umap.models import Map
|
||||||
|
|
||||||
from .base import DataLayerFactory, MapFactory
|
from .base import MapFactory
|
||||||
|
|
||||||
pytestmark = pytest.mark.django_db
|
pytestmark = pytest.mark.django_db
|
||||||
|
|
||||||
|
|
||||||
def test_empty_trash(user):
|
def test_empty_trash(user):
|
||||||
recent = MapFactory(owner=user)
|
recent = MapFactory(owner=user)
|
||||||
recent_layer = DataLayerFactory(map=recent)
|
|
||||||
deleted_layer = DataLayerFactory(map=recent)
|
|
||||||
recent_deleted = MapFactory(owner=user)
|
recent_deleted = MapFactory(owner=user)
|
||||||
recent_deleted.move_to_trash()
|
recent_deleted.move_to_trash()
|
||||||
recent_deleted.save()
|
recent_deleted.save()
|
||||||
|
@ -22,20 +20,15 @@ def test_empty_trash(user):
|
||||||
mocked.return_value = datetime.utcnow() - timedelta(days=8)
|
mocked.return_value = datetime.utcnow() - timedelta(days=8)
|
||||||
old_deleted = MapFactory(owner=user)
|
old_deleted = MapFactory(owner=user)
|
||||||
old_deleted.move_to_trash()
|
old_deleted.move_to_trash()
|
||||||
deleted_layer.move_to_trash()
|
old_deleted.save()
|
||||||
old = MapFactory(owner=user)
|
old = MapFactory(owner=user)
|
||||||
assert Map.objects.count() == 4
|
assert Map.objects.count() == 4
|
||||||
assert DataLayer.objects.count() == 2
|
|
||||||
call_command("empty_trash", "--days=7", "--dry-run")
|
call_command("empty_trash", "--days=7", "--dry-run")
|
||||||
assert Map.objects.count() == 4
|
assert Map.objects.count() == 4
|
||||||
assert DataLayer.objects.count() == 2
|
|
||||||
call_command("empty_trash", "--days=9")
|
call_command("empty_trash", "--days=9")
|
||||||
assert Map.objects.count() == 4
|
assert Map.objects.count() == 4
|
||||||
assert DataLayer.objects.count() == 2
|
|
||||||
call_command("empty_trash", "--days=7")
|
call_command("empty_trash", "--days=7")
|
||||||
assert not Map.objects.filter(pk=old_deleted.pk)
|
assert not Map.objects.filter(pk=old_deleted.pk)
|
||||||
assert Map.objects.filter(pk=old.pk)
|
assert Map.objects.filter(pk=old.pk)
|
||||||
assert Map.objects.filter(pk=recent.pk)
|
assert Map.objects.filter(pk=recent.pk)
|
||||||
assert Map.objects.filter(pk=recent_deleted.pk)
|
assert Map.objects.filter(pk=recent_deleted.pk)
|
||||||
assert not DataLayer.objects.filter(pk=deleted_layer.pk)
|
|
||||||
assert DataLayer.objects.filter(pk=recent_layer.pk)
|
|
||||||
|
|
|
@ -810,17 +810,6 @@ def test_oembed_shared_status_map(client, map, datalayer, share_status):
|
||||||
assert response.status_code == 403
|
assert response.status_code == 403
|
||||||
|
|
||||||
|
|
||||||
def test_download_does_not_include_delete_datalayers(client, map, datalayer):
|
|
||||||
datalayer.share_status = DataLayer.DELETED
|
|
||||||
datalayer.save()
|
|
||||||
url = reverse("map_download", args=(map.pk,))
|
|
||||||
response = client.get(url)
|
|
||||||
assert response.status_code == 200
|
|
||||||
# Test response is a json
|
|
||||||
j = json.loads(response.content.decode())
|
|
||||||
assert j["layers"] == []
|
|
||||||
|
|
||||||
|
|
||||||
def test_oembed_no_url_map(client, map, datalayer):
|
def test_oembed_no_url_map(client, map, datalayer):
|
||||||
url = reverse("map_oembed")
|
url = reverse("map_oembed")
|
||||||
response = client.get(url)
|
response = client.get(url)
|
||||||
|
|
|
@ -15,7 +15,7 @@ from urllib.request import Request, build_opener
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.contrib.auth import BACKEND_SESSION_KEY, get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.contrib.auth import logout as do_logout
|
from django.contrib.auth import logout as do_logout
|
||||||
from django.contrib.gis.measure import D
|
from django.contrib.gis.measure import D
|
||||||
from django.contrib.postgres.search import SearchQuery, SearchVector
|
from django.contrib.postgres.search import SearchQuery, SearchVector
|
||||||
|
@ -742,14 +742,14 @@ class MapView(MapDetailMixin, PermissionsMixin, DetailView):
|
||||||
def get_datalayers(self):
|
def get_datalayers(self):
|
||||||
# When initializing datalayers from map, we cannot get the reference version
|
# When initializing datalayers from map, we cannot get the reference version
|
||||||
# the normal way, which is from the header X-Reference-Version
|
# the normal way, which is from the header X-Reference-Version
|
||||||
return [dl.metadata(self.request) for dl in self.object.datalayers]
|
return [dl.metadata(self.request) for dl in self.object.datalayer_set.all()]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def edit_mode(self):
|
def edit_mode(self):
|
||||||
edit_mode = "disabled"
|
edit_mode = "disabled"
|
||||||
if self.object.can_edit(self.request):
|
if self.object.can_edit(self.request):
|
||||||
edit_mode = "advanced"
|
edit_mode = "advanced"
|
||||||
elif any(d.can_edit(self.request) for d in self.object.datalayers):
|
elif any(d.can_edit(self.request) for d in self.object.datalayer_set.all()):
|
||||||
edit_mode = "simple"
|
edit_mode = "simple"
|
||||||
return edit_mode
|
return edit_mode
|
||||||
|
|
||||||
|
@ -1325,7 +1325,7 @@ class DataLayerDelete(DeleteView):
|
||||||
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.move_to_trash()
|
self.object.delete()
|
||||||
return simple_json_response(info=_("Layer successfully deleted."))
|
return simple_json_response(info=_("Layer successfully deleted."))
|
||||||
|
|
||||||
|
|
||||||
|
@ -1419,18 +1419,3 @@ class LoginPopupEnd(TemplateView):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
template_name = "umap/login_popup_end.html"
|
template_name = "umap/login_popup_end.html"
|
||||||
|
|
||||||
def get(self, *args, **kwargs):
|
|
||||||
backend = self.request.session[BACKEND_SESSION_KEY]
|
|
||||||
if backend in settings.DEPRECATED_AUTHENTICATION_BACKENDS:
|
|
||||||
name = backend.split(".")[-1]
|
|
||||||
messages.error(
|
|
||||||
self.request,
|
|
||||||
_(
|
|
||||||
"Using “%(name)s” to authenticate is deprecated. "
|
|
||||||
"Please configure another provider in your profile page."
|
|
||||||
)
|
|
||||||
% {"name": name},
|
|
||||||
)
|
|
||||||
return HttpResponseRedirect(reverse("user_profile"))
|
|
||||||
return super().get(*args, **kwargs)
|
|
||||||
|
|