umap-project 2.8.0__py3-none-any.whl → 2.8.0a0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. umap/__init__.py +1 -1
  2. umap/locale/en/LC_MESSAGES/django.po +13 -13
  3. umap/management/commands/empty_trash.py +2 -5
  4. umap/management/commands/migrate_to_S3.py +3 -3
  5. umap/settings/base.py +2 -2
  6. umap/static/umap/css/form.css +0 -3
  7. umap/static/umap/js/modules/data/features.js +4 -19
  8. umap/static/umap/js/modules/data/layer.js +19 -41
  9. umap/static/umap/js/modules/importer.js +20 -65
  10. umap/static/umap/js/modules/rendering/icon.js +1 -2
  11. umap/static/umap/js/modules/rendering/map.js +7 -7
  12. umap/static/umap/js/modules/rendering/popup.js +10 -9
  13. umap/static/umap/js/modules/rendering/template.js +9 -53
  14. umap/static/umap/js/modules/rendering/ui.js +2 -6
  15. umap/static/umap/js/modules/request.js +2 -2
  16. umap/static/umap/js/modules/schema.js +0 -1
  17. umap/static/umap/js/modules/ui/dialog.js +0 -5
  18. umap/static/umap/js/modules/umap.js +10 -33
  19. umap/static/umap/js/modules/utils.js +0 -2
  20. umap/static/umap/js/umap.controls.js +4 -7
  21. umap/static/umap/js/umap.forms.js +0 -44
  22. umap/static/umap/locale/en.js +1 -3
  23. umap/static/umap/locale/en.json +1 -3
  24. umap/static/umap/locale/fr.js +1 -3
  25. umap/static/umap/locale/fr.json +1 -3
  26. umap/static/umap/map.css +166 -34
  27. umap/static/umap/vars.css +1 -0
  28. umap/storage.py +216 -0
  29. umap/templates/base.html +0 -2
  30. umap/templates/umap/components/alerts/alert.html +0 -4
  31. umap/templates/umap/css.html +0 -3
  32. umap/templates/umap/js.html +0 -2
  33. umap/templates/umap/map_init.html +0 -2
  34. umap/templates/umap/user_dashboard.html +0 -2
  35. umap/tests/integration/test_edit_datalayer.py +0 -11
  36. umap/tests/integration/test_import.py +1 -20
  37. umap/tests/test_datalayer_s3.py +1 -1
  38. umap/tests/test_statics.py +1 -1
  39. umap/tests/test_team_views.py +1 -35
  40. umap/tests/test_views.py +74 -0
  41. umap/views.py +15 -20
  42. {umap_project-2.8.0.dist-info → umap_project-2.8.0a0.dist-info}/METADATA +1 -1
  43. {umap_project-2.8.0.dist-info → umap_project-2.8.0a0.dist-info}/RECORD +46 -52
  44. umap/settings/local_s3.py +0 -45
  45. umap/storage/__init__.py +0 -3
  46. umap/storage/fs.py +0 -101
  47. umap/storage/s3.py +0 -61
  48. umap/storage/staticfiles.py +0 -64
  49. umap/tests/fixtures/test_upload_simple_marker.json +0 -19
  50. umap/tests/test_dashboard.py +0 -82
  51. {umap_project-2.8.0.dist-info → umap_project-2.8.0a0.dist-info}/WHEEL +0 -0
  52. {umap_project-2.8.0.dist-info → umap_project-2.8.0a0.dist-info}/entry_points.txt +0 -0
  53. {umap_project-2.8.0.dist-info → umap_project-2.8.0a0.dist-info}/licenses/LICENSE +0 -0
umap/storage.py ADDED
@@ -0,0 +1,216 @@
1
+ import operator
2
+ import os
3
+ import shutil
4
+ import time
5
+ from gzip import GzipFile
6
+ from pathlib import Path
7
+
8
+ from botocore.exceptions import ClientError
9
+ from django.conf import settings
10
+ from django.contrib.staticfiles.storage import ManifestStaticFilesStorage
11
+ from django.core.files.storage import FileSystemStorage
12
+ from rcssmin import cssmin
13
+ from rjsmin import jsmin
14
+ from storages.backends.s3 import S3Storage
15
+
16
+
17
+ class UmapManifestStaticFilesStorage(ManifestStaticFilesStorage):
18
+ support_js_module_import_aggregation = True
19
+ max_post_process_passes = 15
20
+
21
+ # We remove `;` at the end of all regexps to match our biome config.
22
+ _js_module_import_aggregation_patterns = (
23
+ "*.js",
24
+ (
25
+ (
26
+ (
27
+ r"""(?P<matched>import(?s:(?P<import>[\s\{].*?))"""
28
+ r"""\s*from\s*['"](?P<url>[\.\/].*?)["']\s*)"""
29
+ ),
30
+ 'import%(import)s from "%(url)s"\n',
31
+ ),
32
+ (
33
+ (
34
+ r"""(?P<matched>export(?s:(?P<exports>[\s\{].*?))"""
35
+ r"""\s*from\s*["'](?P<url>[\.\/].*?)["']\s*)"""
36
+ ),
37
+ 'export%(exports)s from "%(url)s"\n',
38
+ ),
39
+ (
40
+ r"""(?P<matched>import\s*['"](?P<url>[\.\/].*?)["']\s*)""",
41
+ 'import"%(url)s"\n',
42
+ ),
43
+ (
44
+ r"""(?P<matched>import\(["'](?P<url>.*?)["']\)\.then)""",
45
+ """import("%(url)s").then""",
46
+ ),
47
+ (
48
+ r"""(?P<matched>await import\(["'](?P<url>.*?)["']\))""",
49
+ """await import("%(url)s")""",
50
+ ),
51
+ ),
52
+ )
53
+
54
+ def post_process(self, paths, **options):
55
+ collected = super().post_process(paths, **options)
56
+ for original_path, processed_path, processed in collected:
57
+ if isinstance(processed, Exception):
58
+ print("Error with file", original_path)
59
+ raise processed
60
+ if processed_path.endswith(".js"):
61
+ path = Path(settings.STATIC_ROOT) / processed_path
62
+ initial = path.read_text()
63
+ if "sourceMappingURL" not in initial: # Already minified.
64
+ minified = jsmin(initial)
65
+ path.write_text(minified)
66
+ if processed_path.endswith(".css"):
67
+ path = Path(settings.STATIC_ROOT) / processed_path
68
+ initial = path.read_text()
69
+ if "sourceMappingURL" not in initial: # Already minified.
70
+ minified = cssmin(initial)
71
+ path.write_text(minified)
72
+ yield original_path, processed_path, True
73
+
74
+
75
+ class UmapS3(S3Storage):
76
+ gzip = True
77
+
78
+ def get_reference_version(self, instance):
79
+ metadata = self.connection.meta.client.head_object(
80
+ Bucket=self.bucket_name, Key=instance.geojson.name
81
+ )
82
+ # Do not fail if bucket does not handle versioning
83
+ return metadata.get("VersionId", metadata["ETag"])
84
+
85
+ def make_filename(self, instance):
86
+ return f"{str(instance.pk)}.geojson"
87
+
88
+ def list_versions(self, instance):
89
+ response = self.connection.meta.client.list_object_versions(
90
+ Bucket=self.bucket_name, Prefix=instance.geojson.name
91
+ )
92
+ return [
93
+ {
94
+ "ref": version["VersionId"],
95
+ "at": version["LastModified"].timestamp() * 1000,
96
+ "size": version["Size"],
97
+ }
98
+ for version in response["Versions"]
99
+ ]
100
+
101
+ def get_version(self, ref, instance):
102
+ try:
103
+ data = self.connection.meta.client.get_object(
104
+ Bucket=self.bucket_name,
105
+ Key=instance.geojson.name,
106
+ VersionId=ref,
107
+ )
108
+ except ClientError:
109
+ raise ValueError(f"Invalid version reference: {ref}")
110
+ return GzipFile(mode="r", fileobj=data["Body"]).read()
111
+
112
+ def get_version_path(self, ref, instance):
113
+ return self.url(instance.geojson.name, parameters={"VersionId": ref})
114
+
115
+ def onDatalayerSave(self, instance):
116
+ pass
117
+
118
+ def onDatalayerDelete(self, instance):
119
+ return self.connection.meta.client.delete_object(
120
+ Bucket=self.bucket_name,
121
+ Key=instance.geojson.name,
122
+ )
123
+
124
+
125
+ class UmapFileSystem(FileSystemStorage):
126
+ def get_reference_version(self, instance):
127
+ return self._extract_version_ref(instance.geojson.name)
128
+
129
+ def make_filename(self, instance):
130
+ root = self._base_path(instance)
131
+ name = "%s_%s.geojson" % (instance.pk, int(time.time() * 1000))
132
+ return root / name
133
+
134
+ def list_versions(self, instance):
135
+ root = self._base_path(instance)
136
+ names = self.listdir(root)[1]
137
+ names = [name for name in names if self._is_valid_version(name, instance)]
138
+ versions = [self._version_metadata(name, instance) for name in names]
139
+ versions.sort(reverse=True, key=operator.itemgetter("at"))
140
+ return versions
141
+
142
+ def get_version(self, ref, instance):
143
+ with self.open(self.get_version_path(ref, instance), "r") as f:
144
+ return f.read()
145
+
146
+ def get_version_path(self, ref, instance):
147
+ base_path = Path(settings.MEDIA_ROOT) / self._base_path(instance)
148
+ fullpath = base_path / f"{instance.pk}_{ref}.geojson"
149
+ if instance.old_id and not fullpath.exists():
150
+ fullpath = base_path / f"{instance.old_id}_{ref}.geojson"
151
+ if not fullpath.exists():
152
+ raise ValueError(f"Invalid version reference: {ref}")
153
+ return fullpath
154
+
155
+ def onDatalayerSave(self, instance):
156
+ self._purge_gzip(instance)
157
+ self._purge_old_versions(instance, keep=settings.UMAP_KEEP_VERSIONS)
158
+
159
+ def onDatalayerDelete(self, instance):
160
+ self._purge_gzip(instance)
161
+ self._purge_old_versions(instance, keep=None)
162
+
163
+ def _extract_version_ref(self, path):
164
+ version = path.split(".")[0]
165
+ if "_" in version:
166
+ return version.split("_")[-1]
167
+ return version
168
+
169
+ def _base_path(self, instance):
170
+ path = ["datalayer", str(instance.map.pk)[-1]]
171
+ if len(str(instance.map.pk)) > 1:
172
+ path.append(str(instance.map.pk)[-2])
173
+ path.append(str(instance.map.pk))
174
+ return Path(os.path.join(*path))
175
+
176
+ def _is_valid_version(self, name, instance):
177
+ valid_prefixes = [name.startswith("%s_" % instance.pk)]
178
+ if instance.old_id:
179
+ valid_prefixes.append(name.startswith("%s_" % instance.old_id))
180
+ return any(valid_prefixes) and name.endswith(".geojson")
181
+
182
+ def _version_metadata(self, name, instance):
183
+ ref = self._extract_version_ref(name)
184
+ return {
185
+ "name": name,
186
+ "ref": ref,
187
+ "at": ref,
188
+ "size": self.size(self._base_path(instance) / name),
189
+ }
190
+
191
+ def _purge_old_versions(self, instance, keep=None):
192
+ root = self._base_path(instance)
193
+ versions = self.list_versions(instance)
194
+ if keep is not None:
195
+ versions = versions[keep:]
196
+ for version in versions:
197
+ name = version["name"]
198
+ # Should not be in the list, but ensure to not delete the file
199
+ # currently used in database
200
+ if keep is not None and instance.geojson.name.endswith(name):
201
+ continue
202
+ try:
203
+ self.delete(root / name)
204
+ except FileNotFoundError:
205
+ pass
206
+
207
+ def _purge_gzip(self, instance):
208
+ root = self._base_path(instance)
209
+ names = self.listdir(root)[1]
210
+ prefixes = [f"{instance.pk}_"]
211
+ if instance.old_id:
212
+ prefixes.append(f"{instance.old_id}_")
213
+ prefixes = tuple(prefixes)
214
+ for name in names:
215
+ if name.startswith(prefixes) and name.endswith(".gz"):
216
+ self.delete(root / name)
umap/templates/base.html CHANGED
@@ -18,7 +18,6 @@
18
18
  <meta name="viewport"
19
19
  content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
20
20
  {# See https://evilmartians.com/chronicles/how-to-favicon-in-2021-six-files-that-fit-most-needs #}
21
- {% autoescape off %}
22
21
  <link rel="icon"
23
22
  href="{% static 'umap/favicons/favicon.ico' %}"
24
23
  sizes="32x32">
@@ -29,7 +28,6 @@
29
28
  href="{% static 'umap/favicons/apple-touch-icon.png' %}">
30
29
  <!-- 180×180 -->
31
30
  <link rel="manifest" href="/manifest.webmanifest">
32
- {% endautoescape %}
33
31
  </head>
34
32
  <body class="{% block body_class %}{% endblock body_class %}">
35
33
  {% block header %}
@@ -1,10 +1,8 @@
1
1
  {% load i18n static %}
2
2
 
3
- {% autoescape off %}
4
3
  <style type="text/css">
5
4
  @import "{% static 'umap/js/components/alerts/alert.css' %}";
6
5
  </style>
7
- {% endautoescape %}
8
6
  <template id="umap-alert-template">
9
7
  <div role="dialog" class="dark window umap-alert">
10
8
  <div>
@@ -99,7 +97,6 @@
99
97
  </div>
100
98
  </template>
101
99
  <umap-alert-conflict></umap-alert-conflict>
102
- {% autoescape off %}
103
100
  <script type="module">
104
101
  import { register } from '{% static 'umap/js/components/base.js' %}'
105
102
  import {
@@ -111,4 +108,3 @@
111
108
  register(uMapAlertCreation, 'umap-alert-creation')
112
109
  register(uMapAlertConflict, 'umap-alert-conflict')
113
110
  </script>
114
- {% endautoescape %}
@@ -1,7 +1,5 @@
1
1
  {% load static %}
2
2
 
3
- {% autoescape off %}
4
-
5
3
  <link rel="stylesheet"
6
4
  href="{% static 'umap/vendors/leaflet/leaflet.css' %}" />
7
5
  <link rel="stylesheet"
@@ -41,4 +39,3 @@
41
39
  <link rel="stylesheet" href="{% static 'umap/css/tableeditor.css' %}" />
42
40
  <link rel="stylesheet" href="{% static 'umap/css/bar.css' %}" />
43
41
  <link rel="stylesheet" href="{% static 'umap/theme.css' %}" />
44
- {% endautoescape %}
@@ -1,6 +1,5 @@
1
1
  {% load static %}
2
2
 
3
- {% autoescape off %}
4
3
  <script type="module"
5
4
  src="{% static 'umap/vendors/leaflet/leaflet-src.esm.js' %}"
6
5
  defer></script>
@@ -43,4 +42,3 @@
43
42
  <script src="{% static 'umap/js/umap.forms.js' %}" defer></script>
44
43
  <script src="{% static 'umap/js/umap.controls.js' %}" defer></script>
45
44
  <script type="module" src="{% static 'umap/js/components/fragment.js' %}" defer></script>
46
- {% endautoescape %}
@@ -5,9 +5,7 @@
5
5
  </div>
6
6
  <!-- djlint:off -->
7
7
  <script defer type="module">
8
- {% autoescape off %}
9
8
  import Umap from '{% static "umap/js/modules/umap.js" %}'
10
- {% endautoescape %}
11
9
  U.MAP = new Umap("map", {{ map_settings|notag|safe }})
12
10
  </script>
13
11
  <!-- djlint:on -->
@@ -46,9 +46,7 @@
46
46
  {% block bottom_js %}
47
47
  {{ block.super }}
48
48
  <script type="module">
49
- {% autoescape off %}
50
49
  import Umap from '{% static "umap/js/modules/umap.js" %}'
51
- {% endautoescape %}
52
50
  const CACHE = {}
53
51
  for (const mapOpener of document.querySelectorAll("button.map-opener")) {
54
52
  mapOpener.addEventListener('click', (event) => {
@@ -221,14 +221,3 @@ def test_deleting_datalayer_should_remove_from_caption(
221
221
  page.locator(".panel.right").get_by_title("Delete layer").click()
222
222
  page.get_by_role("button", name="OK").click()
223
223
  expect(panel.get_by_text("test datalayer")).to_be_hidden()
224
-
225
-
226
- def test_can_edit_datalayer_name_in_list(live_server, openmap, datalayer, page):
227
- page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit")
228
- page.get_by_role("link", name="Manage layers").click()
229
- page.get_by_text("test datalayer").click()
230
- page.get_by_text("test datalayer").fill("test datalayer foobar")
231
- page.get_by_role("button", name="Open browser").click()
232
- expect(
233
- page.locator(".panel.left").get_by_text("test datalayer foobar")
234
- ).to_be_visible()
@@ -9,6 +9,7 @@ from playwright.sync_api import expect
9
9
 
10
10
  from umap.models import DataLayer
11
11
 
12
+ from ..base import mock_tiles
12
13
  from .helpers import save_and_get_json
13
14
 
14
15
  pytestmark = pytest.mark.django_db
@@ -764,23 +765,3 @@ def test_import_georss_from_textarea(tilelayer, live_server, page):
764
765
  # A layer has been created
765
766
  expect(layers).to_have_count(1)
766
767
  expect(markers).to_have_count(1)
767
-
768
-
769
- def test_import_from_multiple_files(live_server, page, tilelayer):
770
- page.goto(f"{live_server.url}/map/new/")
771
- page.get_by_title("Import data").click()
772
- file_input = page.locator("input[type='file']")
773
- with page.expect_file_chooser() as fc_info:
774
- file_input.click()
775
- file_chooser = fc_info.value
776
- FIXTURES = Path(__file__).parent.parent / "fixtures"
777
- paths = [
778
- FIXTURES / "test_upload_data.json",
779
- FIXTURES / "test_upload_simple_marker.json",
780
- ]
781
- file_chooser.set_files(paths)
782
- markers = page.locator(".leaflet-marker-icon")
783
- expect(markers).to_have_count(0)
784
- page.get_by_role("button", name="Import data", exact=True).click()
785
- # Two in one file, one in the other
786
- expect(markers).to_have_count(3)
@@ -27,7 +27,7 @@ def patch_storage():
27
27
 
28
28
  DataLayer.geojson.field.storage = storages.create_storage(
29
29
  {
30
- "BACKEND": "umap.storage.s3.S3DataStorage",
30
+ "BACKEND": "umap.storage.UmapS3",
31
31
  "OPTIONS": {
32
32
  "access_key": "testing",
33
33
  "secret_key": "testing",
@@ -15,7 +15,7 @@ def staticfiles(settings):
15
15
  # Make sure settings are properly reset after the test
16
16
  settings.STORAGES = deepcopy(settings.STORAGES)
17
17
  settings.STORAGES["staticfiles"]["BACKEND"] = (
18
- "umap.storage.staticfiles.UmapManifestStaticFilesStorage"
18
+ "umap.storage.UmapManifestStaticFilesStorage"
19
19
  )
20
20
  try:
21
21
  call_command("collectstatic", "--noinput")
@@ -1,7 +1,7 @@
1
1
  import pytest
2
2
  from django.urls import reverse
3
3
 
4
- from umap.models import Map, Team
4
+ from umap.models import Team
5
5
 
6
6
  pytestmark = pytest.mark.django_db
7
7
 
@@ -15,40 +15,6 @@ def test_can_see_team_maps(client, map, team):
15
15
  assert map.name in response.content.decode()
16
16
 
17
17
 
18
- @pytest.mark.parametrize("share_status", [Map.PRIVATE, Map.DRAFT])
19
- def test_others_cannot_see_team_private_maps_in_team_page(
20
- client, map, team, user, share_status
21
- ):
22
- map.team = team
23
- map.share_status = share_status
24
- map.save()
25
- url = reverse("team_maps", args=(team.pk,))
26
- response = client.get(url)
27
- assert response.status_code == 200
28
- assert map.name not in response.content.decode()
29
- # User is not in team
30
- client.login(username=user.username, password="123123")
31
- response = client.get(url)
32
- assert response.status_code == 200
33
- assert map.name not in response.content.decode()
34
-
35
-
36
- @pytest.mark.parametrize("share_status", [Map.PRIVATE, Map.DRAFT])
37
- def test_members_can_see_private_maps_in_team_page(
38
- client, map, team, user, share_status
39
- ):
40
- map.team = team
41
- map.share_status = share_status
42
- map.save()
43
- user.teams.add(team)
44
- user.save()
45
- url = reverse("team_maps", args=(team.pk,))
46
- client.login(username=user.username, password="123123")
47
- response = client.get(url)
48
- assert response.status_code == 200
49
- assert map.name in response.content.decode()
50
-
51
-
52
18
  def test_user_can_see_their_teams(client, team, user):
53
19
  user.teams.add(team)
54
20
  user.save()
umap/tests/test_views.py CHANGED
@@ -267,6 +267,80 @@ def test_change_user_slug(client, user, settings):
267
267
  assert f"/en/user/{user.pk}/" in response.content.decode()
268
268
 
269
269
 
270
+ @pytest.mark.django_db
271
+ def test_user_dashboard_is_restricted_to_logged_in(client):
272
+ response = client.get(reverse("user_dashboard"))
273
+ assert response.status_code == 302
274
+ assert response["Location"] == "/en/login/?next=/en/me"
275
+
276
+
277
+ @pytest.mark.django_db
278
+ def test_user_dashboard_display_user_maps(client, map):
279
+ client.login(username=map.owner.username, password="123123")
280
+ response = client.get(reverse("user_dashboard"))
281
+ assert response.status_code == 200
282
+ body = response.content.decode()
283
+ assert map.name in body
284
+ assert f"{map.get_absolute_url()}?edit" in body
285
+ assert f"{map.get_absolute_url()}?share" in body
286
+ assert f"/map/{map.pk}/download" in body
287
+ assert "Everyone (public)" in body
288
+ assert "Owner only" in body
289
+
290
+
291
+ @pytest.mark.django_db
292
+ def test_user_dashboard_do_not_display_blocked_user_maps(client, map):
293
+ map.share_status = Map.BLOCKED
294
+ map.save()
295
+ client.login(username=map.owner.username, password="123123")
296
+ response = client.get(reverse("user_dashboard"))
297
+ assert response.status_code == 200
298
+ body = response.content.decode()
299
+ assert map.name not in body
300
+
301
+
302
+ @pytest.mark.django_db
303
+ def test_user_dashboard_do_not_display_deleted_user_maps(client, map):
304
+ map.share_status = Map.DELETED
305
+ map.save()
306
+ client.login(username=map.owner.username, password="123123")
307
+ response = client.get(reverse("user_dashboard"))
308
+ assert response.status_code == 200
309
+ body = response.content.decode()
310
+ assert map.name not in body
311
+
312
+
313
+ @pytest.mark.django_db
314
+ def test_user_dashboard_display_user_team_maps(client, map, team, user):
315
+ user.teams.add(team)
316
+ user.save()
317
+ map.team = team
318
+ map.save()
319
+ client.login(username=user.username, password="123123")
320
+ response = client.get(reverse("user_dashboard"))
321
+ assert response.status_code == 200
322
+ body = response.content.decode()
323
+ assert map.name in body
324
+ assert map.get_absolute_url() in body
325
+
326
+
327
+ @pytest.mark.django_db
328
+ def test_user_dashboard_display_user_maps_distinct(client, map):
329
+ # cf https://github.com/umap-project/umap/issues/1325
330
+ anonymap = MapFactory(name="Map witout owner should not appear")
331
+ user1 = UserFactory(username="user1")
332
+ user2 = UserFactory(username="user2")
333
+ map.editors.add(user1)
334
+ map.editors.add(user2)
335
+ map.save()
336
+ client.login(username=map.owner.username, password="123123")
337
+ response = client.get(reverse("user_dashboard"))
338
+ assert response.status_code == 200
339
+ body = response.content.decode()
340
+ assert body.count(f'<a href="/en/map/test-map_{map.pk}">test map</a>') == 1
341
+ assert body.count(anonymap.name) == 0
342
+
343
+
270
344
  @pytest.mark.django_db
271
345
  def test_logout_should_return_redirect(client, user, settings):
272
346
  client.login(username=user.username, password="123123")
umap/views.py CHANGED
@@ -317,11 +317,7 @@ class TeamMaps(PaginatorMixin, DetailView):
317
317
  context_object_name = "current_team"
318
318
 
319
319
  def get_maps(self):
320
- qs = Map.public
321
- user = self.request.user
322
- if user.is_authenticated and user in self.object.users.all():
323
- qs = Map.objects
324
- return qs.filter(team=self.object).order_by("-modified_at")
320
+ return Map.public.filter(team=self.object).order_by("-modified_at")
325
321
 
326
322
  def get_context_data(self, **kwargs):
327
323
  kwargs.update(
@@ -456,27 +452,27 @@ showcase = MapsShowCase.as_view()
456
452
 
457
453
 
458
454
  def validate_url(request):
459
- assert request.method == "GET", "Wrong HTTP method"
455
+ assert request.method == "GET"
460
456
  url = request.GET.get("url")
461
- assert url, "Missing URL"
457
+ assert url
462
458
  try:
463
459
  URLValidator(url)
464
- except ValidationError as err:
465
- raise AssertionError(err)
466
- assert "HTTP_REFERER" in request.META, "Missing HTTP_REFERER"
460
+ except ValidationError:
461
+ raise AssertionError()
462
+ assert "HTTP_REFERER" in request.META
467
463
  referer = urlparse(request.META.get("HTTP_REFERER"))
468
464
  toproxy = urlparse(url)
469
465
  local = urlparse(settings.SITE_URL)
470
- assert toproxy.hostname, "No hostname"
471
- assert referer.hostname == local.hostname, f"{referer.hostname} != {local.hostname}"
472
- assert toproxy.hostname != "localhost", "Invalid localhost target"
473
- assert toproxy.netloc != local.netloc, "Invalid netloc"
466
+ assert toproxy.hostname
467
+ assert referer.hostname == local.hostname
468
+ assert toproxy.hostname != "localhost"
469
+ assert toproxy.netloc != local.netloc
474
470
  try:
475
471
  # clean this when in python 3.4
476
472
  ipaddress = socket.gethostbyname(toproxy.hostname)
477
- except Exception as err:
478
- raise AssertionError(err)
479
- assert not PRIVATE_IP.match(ipaddress), "Private IP"
473
+ except:
474
+ raise AssertionError()
475
+ assert not PRIVATE_IP.match(ipaddress)
480
476
  return url
481
477
 
482
478
 
@@ -484,8 +480,7 @@ class AjaxProxy(View):
484
480
  def get(self, *args, **kwargs):
485
481
  try:
486
482
  url = validate_url(self.request)
487
- except AssertionError as err:
488
- print(f"AjaxProxy: {err}")
483
+ except AssertionError:
489
484
  return HttpResponseBadRequest()
490
485
  try:
491
486
  ttl = int(self.request.GET.get("ttl"))
@@ -1173,7 +1168,7 @@ class DataLayerView(BaseDetailView):
1173
1168
  # (no gzip/cache-control/If-Modified-Since/If-None-Match)
1174
1169
  data = self.filedata
1175
1170
  response = HttpResponse(data, content_type="application/geo+json")
1176
- response["X-Datalayer-Version"] = self.fileversion
1171
+ response["X-Datalayer-Version"] = self.fileversion
1177
1172
  return response
1178
1173
 
1179
1174
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: umap-project
3
- Version: 2.8.0
3
+ Version: 2.8.0a0
4
4
  Summary: Create maps with OpenStreetMap layers in a minute and embed them in your site.
5
5
  Author-email: Yohan Boniface <yb@enix.org>
6
6
  Maintainer-email: David Larlet <david@larlet.fr>