diff --git a/umap/static/umap/favicons/apple-touch-icon.png b/umap/static/umap/favicons/apple-touch-icon.png new file mode 100644 index 00000000..6bace25e Binary files /dev/null and b/umap/static/umap/favicons/apple-touch-icon.png differ diff --git a/umap/static/umap/favicons/favicon.ico b/umap/static/umap/favicons/favicon.ico new file mode 100644 index 00000000..4deae7d7 Binary files /dev/null and b/umap/static/umap/favicons/favicon.ico differ diff --git a/umap/static/umap/favicons/icon-192.png b/umap/static/umap/favicons/icon-192.png new file mode 100644 index 00000000..d46f0a3b Binary files /dev/null and b/umap/static/umap/favicons/icon-192.png differ diff --git a/umap/static/umap/favicons/icon-512.png b/umap/static/umap/favicons/icon-512.png new file mode 100644 index 00000000..5e44c836 Binary files /dev/null and b/umap/static/umap/favicons/icon-512.png differ diff --git a/umap/static/umap/favicons/icon.svg b/umap/static/umap/favicons/icon.svg new file mode 100644 index 00000000..9bb4774a --- /dev/null +++ b/umap/static/umap/favicons/icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/umap/static/umap/favicons/manifest.webmanifest b/umap/static/umap/favicons/manifest.webmanifest new file mode 100644 index 00000000..a893e5b7 --- /dev/null +++ b/umap/static/umap/favicons/manifest.webmanifest @@ -0,0 +1,6 @@ +{ + "icons": [ + { "src": "/icon-192.png", "type": "image/png", "sizes": "192x192" }, + { "src": "/icon-512.png", "type": "image/png", "sizes": "512x512" } + ] +} diff --git a/umap/templates/base.html b/umap/templates/base.html index 4d93f5bd..9e5a8d34 100644 --- a/umap/templates/base.html +++ b/umap/templates/base.html @@ -15,6 +15,11 @@ {% endblock extra_head %} + {# See https://evilmartians.com/chronicles/how-to-favicon-in-2021-six-files-that-fit-most-needs #} + + + + {% block header %} diff --git a/umap/urls.py b/umap/urls.py index 630ea45a..6f52c00f 100644 --- a/umap/urls.py +++ b/umap/urls.py @@ -183,7 +183,15 @@ urlpatterns += i18n_patterns( re_path(r"^user/(?P.+)/$", views.user_maps, name="user_maps"), re_path(r"", include(i18n_urls)), ) -urlpatterns += (path("stats/", cache_page(60 * 60)(views.stats), name="stats"),) +urlpatterns += ( + path("stats/", cache_page(60 * 60)(views.stats), name="stats"), + path("favicon.ico", views.favicon_file), + path("icon.svg", views.favicon_file), + path("apple-touch-icon.png", views.favicon_file), + path("manifest.webmanifest", views.favicon_file), + path("icon-192.png", views.favicon_file), + path("icon-512.png", views.favicon_file), +) if settings.DEBUG and settings.MEDIA_ROOT: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/umap/views.py b/umap/views.py index 0d341585..fc885589 100644 --- a/umap/views.py +++ b/umap/views.py @@ -21,6 +21,7 @@ from django.core.signing import BadSignature, Signer from django.core.validators import URLValidator, ValidationError from django.db.models import Q from django.http import ( + FileResponse, HttpResponse, HttpResponseBadRequest, HttpResponseForbidden, @@ -34,6 +35,8 @@ from django.utils.encoding import smart_bytes from django.utils.http import http_date from django.utils.translation import gettext as _ from django.utils.translation import to_locale +from django.views.decorators.cache import cache_control +from django.views.decorators.http import require_GET from django.views.generic import DetailView, TemplateView, View from django.views.generic.base import RedirectView from django.views.generic.detail import BaseDetailView @@ -469,9 +472,7 @@ class MapDetailMixin: else: map_statuses = AnonymousMapPermissionsForm.STATUS datalayer_statuses = AnonymousDataLayerPermissionsForm.STATUS - properties["edit_statuses"] = [ - (i, str(label)) for i, label in map_statuses - ] + properties["edit_statuses"] = [(i, str(label)) for i, label in map_statuses] properties["datalayer_edit_statuses"] = [ (i, str(label)) for i, label in datalayer_statuses ] @@ -1016,6 +1017,17 @@ def stats(request): ) +@require_GET +@cache_control(max_age=60 * 60 * 24, immutable=True, public=True) # one day +def favicon_file(request): + # See https://adamj.eu/tech/2022/01/18/how-to-add-a-favicon-to-your-django-site/ + name = request.path.lstrip("/") + file = (Path(settings.PROJECT_DIR) / "static" / "umap" / "favicons" / name).open( + "rb" + ) + return FileResponse(file) + + def logout(request): do_logout(request) if is_ajax(request):