From 82accfcae7ef4ea6c3dceca9a7954355c0d02924 Mon Sep 17 00:00:00 2001 From: Thomas Uher Date: Wed, 25 Jan 2023 14:35:23 +0100 Subject: [PATCH] support for django 4 --- localcosmos_server/__init__.py | 2 +- localcosmos_server/anycluster_schema_urls.py | 1 - localcosmos_server/app_admin/apps.py | 2 +- localcosmos_server/datasets/apps.py | 2 +- localcosmos_server/datasets/fields.py | 15 +- .../widgets/mobile_position_input.html | 291 +-------- .../datasets/widgets/point_or_area_input.html | 64 ++ localcosmos_server/datasets/widgets.py | 27 +- localcosmos_server/decorators.py | 2 +- localcosmos_server/generic_views.py | 25 +- .../0003_alter_localcosmosuser_follows.py | 19 + localcosmos_server/models.py | 2 +- .../server_control_panel/apps.py | 2 +- localcosmos_server/settings.py | 2 +- localcosmos_server/static/maps/MapManager.js | 480 ++++++++++++++ .../maps/leaflet-draw/src/Control.Draw.js | 118 ++++ .../leaflet-draw/src/Leaflet.Draw.Event.js | 177 ++++++ .../maps/leaflet-draw/src/Leaflet.draw.js | 189 ++++++ .../static/maps/leaflet-draw/src/Toolbar.js | 334 ++++++++++ .../static/maps/leaflet-draw/src/Tooltip.js | 118 ++++ .../static/maps/leaflet-draw/src/copyright.js | 7 + .../maps/leaflet-draw/src/draw/DrawToolbar.js | 110 ++++ .../src/draw/handler/Draw.Circle.js | 83 +++ .../src/draw/handler/Draw.CircleMarker.js | 42 ++ .../src/draw/handler/Draw.Feature.js | 104 +++ .../src/draw/handler/Draw.Marker.js | 127 ++++ .../src/draw/handler/Draw.Polygon.js | 129 ++++ .../src/draw/handler/Draw.Polyline.js | 592 ++++++++++++++++++ .../src/draw/handler/Draw.Rectangle.js | 98 +++ .../src/draw/handler/Draw.SimpleShape.js | 119 ++++ .../maps/leaflet-draw/src/edit/EditToolbar.js | 194 ++++++ .../src/edit/handler/Edit.Circle.js | 69 ++ .../src/edit/handler/Edit.CircleMarker.js | 53 ++ .../src/edit/handler/Edit.Marker.js | 84 +++ .../src/edit/handler/Edit.Poly.js | 527 ++++++++++++++++ .../src/edit/handler/Edit.Rectangle.js | 125 ++++ .../src/edit/handler/Edit.SimpleShape.js | 229 +++++++ .../src/edit/handler/EditToolbar.Delete.js | 161 +++++ .../src/edit/handler/EditToolbar.Edit.js | 290 +++++++++ .../maps/leaflet-draw/src/ext/GeometryUtil.js | 165 +++++ .../maps/leaflet-draw/src/ext/LatLngUtil.js | 28 + .../src/ext/LineUtil.Intersect.js | 22 + .../leaflet-draw/src/ext/Polygon.Intersect.js | 33 + .../src/ext/Polyline.Intersect.js | 106 ++++ .../maps/leaflet-draw/src/ext/TouchEvents.js | 272 ++++++++ .../src/images/spritesheet-2x.png | Bin 0 -> 3581 bytes .../leaflet-draw/src/images/spritesheet.png | Bin 0 -> 1906 bytes .../leaflet-draw/src/images/spritesheet.svg | 155 +++++ .../maps/leaflet-draw/src/leaflet.draw.css | 325 ++++++++++ localcosmos_server/template_content/apps.py | 2 +- .../taxon_autocomplete_widget_base.html | 2 +- .../templatetags/localcosmos_tags.py | 7 +- localcosmos_server/tests/mixins.py | 9 +- localcosmos_server/tests/test_models.py | 8 +- localcosmos_server/views.py | 4 +- localcosmos_server/widgets.py | 11 - setup.py | 17 +- 57 files changed, 5817 insertions(+), 364 deletions(-) create mode 100644 localcosmos_server/datasets/templates/datasets/widgets/point_or_area_input.html create mode 100644 localcosmos_server/migrations/0003_alter_localcosmosuser_follows.py create mode 100644 localcosmos_server/static/maps/MapManager.js create mode 100644 localcosmos_server/static/maps/leaflet-draw/src/Control.Draw.js create mode 100755 localcosmos_server/static/maps/leaflet-draw/src/Leaflet.Draw.Event.js create mode 100755 localcosmos_server/static/maps/leaflet-draw/src/Leaflet.draw.js create mode 100755 localcosmos_server/static/maps/leaflet-draw/src/Toolbar.js create mode 100644 localcosmos_server/static/maps/leaflet-draw/src/Tooltip.js create mode 100644 localcosmos_server/static/maps/leaflet-draw/src/copyright.js create mode 100644 localcosmos_server/static/maps/leaflet-draw/src/draw/DrawToolbar.js create mode 100644 localcosmos_server/static/maps/leaflet-draw/src/draw/handler/Draw.Circle.js create mode 100644 localcosmos_server/static/maps/leaflet-draw/src/draw/handler/Draw.CircleMarker.js create mode 100644 localcosmos_server/static/maps/leaflet-draw/src/draw/handler/Draw.Feature.js create mode 100644 localcosmos_server/static/maps/leaflet-draw/src/draw/handler/Draw.Marker.js create mode 100644 localcosmos_server/static/maps/leaflet-draw/src/draw/handler/Draw.Polygon.js create mode 100644 localcosmos_server/static/maps/leaflet-draw/src/draw/handler/Draw.Polyline.js create mode 100644 localcosmos_server/static/maps/leaflet-draw/src/draw/handler/Draw.Rectangle.js create mode 100644 localcosmos_server/static/maps/leaflet-draw/src/draw/handler/Draw.SimpleShape.js create mode 100644 localcosmos_server/static/maps/leaflet-draw/src/edit/EditToolbar.js create mode 100644 localcosmos_server/static/maps/leaflet-draw/src/edit/handler/Edit.Circle.js create mode 100644 localcosmos_server/static/maps/leaflet-draw/src/edit/handler/Edit.CircleMarker.js create mode 100644 localcosmos_server/static/maps/leaflet-draw/src/edit/handler/Edit.Marker.js create mode 100644 localcosmos_server/static/maps/leaflet-draw/src/edit/handler/Edit.Poly.js create mode 100644 localcosmos_server/static/maps/leaflet-draw/src/edit/handler/Edit.Rectangle.js create mode 100644 localcosmos_server/static/maps/leaflet-draw/src/edit/handler/Edit.SimpleShape.js create mode 100644 localcosmos_server/static/maps/leaflet-draw/src/edit/handler/EditToolbar.Delete.js create mode 100644 localcosmos_server/static/maps/leaflet-draw/src/edit/handler/EditToolbar.Edit.js create mode 100755 localcosmos_server/static/maps/leaflet-draw/src/ext/GeometryUtil.js create mode 100644 localcosmos_server/static/maps/leaflet-draw/src/ext/LatLngUtil.js create mode 100644 localcosmos_server/static/maps/leaflet-draw/src/ext/LineUtil.Intersect.js create mode 100644 localcosmos_server/static/maps/leaflet-draw/src/ext/Polygon.Intersect.js create mode 100644 localcosmos_server/static/maps/leaflet-draw/src/ext/Polyline.Intersect.js create mode 100644 localcosmos_server/static/maps/leaflet-draw/src/ext/TouchEvents.js create mode 100644 localcosmos_server/static/maps/leaflet-draw/src/images/spritesheet-2x.png create mode 100644 localcosmos_server/static/maps/leaflet-draw/src/images/spritesheet.png create mode 100644 localcosmos_server/static/maps/leaflet-draw/src/images/spritesheet.svg create mode 100644 localcosmos_server/static/maps/leaflet-draw/src/leaflet.draw.css diff --git a/localcosmos_server/__init__.py b/localcosmos_server/__init__.py index 4de7ac2..ac5a52e 100644 --- a/localcosmos_server/__init__.py +++ b/localcosmos_server/__init__.py @@ -1,2 +1,2 @@ name = 'localcosmos_server' -__version__ = '0.12.0' +__version__ = '0.13.0' diff --git a/localcosmos_server/anycluster_schema_urls.py b/localcosmos_server/anycluster_schema_urls.py index ce0f470..5cca1e7 100644 --- a/localcosmos_server/anycluster_schema_urls.py +++ b/localcosmos_server/anycluster_schema_urls.py @@ -1,4 +1,3 @@ -from django.conf.urls import url from django.urls import path from . import anycluster_schema_views as views diff --git a/localcosmos_server/app_admin/apps.py b/localcosmos_server/app_admin/apps.py index 38fbfe1..34ff27c 100644 --- a/localcosmos_server/app_admin/apps.py +++ b/localcosmos_server/app_admin/apps.py @@ -2,4 +2,4 @@ class AppAdminConfig(AppConfig): - name = 'app_admin' + name = 'localcosmos_server.app_admin' diff --git a/localcosmos_server/datasets/apps.py b/localcosmos_server/datasets/apps.py index 058d380..483fa23 100644 --- a/localcosmos_server/datasets/apps.py +++ b/localcosmos_server/datasets/apps.py @@ -2,4 +2,4 @@ class DatasetsConfig(AppConfig): - name = 'datasets' + name = 'localcosmos_server.datasets' diff --git a/localcosmos_server/datasets/fields.py b/localcosmos_server/datasets/fields.py index 6f7db27..a98bf2a 100644 --- a/localcosmos_server/datasets/fields.py +++ b/localcosmos_server/datasets/fields.py @@ -6,7 +6,8 @@ import json -from .widgets import JSONWidget, SelectDateTimeWidget, MobilePositionInput, CameraAndAlbumWidget +from .widgets import (JSONWidget, SelectDateTimeWidget, MobilePositionInput, CameraAndAlbumWidget, + PointOrAreaInput) class JSONField(forms.MultiValueField): @@ -83,6 +84,18 @@ def compress(self, data_list): return None +class GeoJSONField(JSONField): + + widget = PointOrAreaInput + + def compress(self, data_list): + + if data_list: + return json.loads(data_list[1]) + + return None + + class PictureField(forms.ImageField): diff --git a/localcosmos_server/datasets/templates/datasets/widgets/mobile_position_input.html b/localcosmos_server/datasets/templates/datasets/widgets/mobile_position_input.html index dac6b36..faf7ef7 100644 --- a/localcosmos_server/datasets/templates/datasets/widgets/mobile_position_input.html +++ b/localcosmos_server/datasets/templates/datasets/widgets/mobile_position_input.html @@ -30,18 +30,6 @@ (function () { - var map_type = "leaflet"; - - // the buttons - var position_json_input = document.getElementById("{{ widget.attrs.id }}"), - verbose_position = document.getElementById("{{ widget.attrs.id }}_0"), - gps_button = document.getElementById("{{ widget.attrs.id }}_gpsbutton"), - delete_button = document.getElementById("{{ widget.attrs.id }}_delete"); - - if (gps_button != null){ - var gps_indicator = gps_button.firstElementChild; - } - {% if widget.attrs.readonly %} var readonly = true; {% else %} @@ -60,286 +48,9 @@ var initial_accuracy = 0; {% endif %} - var maps = { - "leaflet" : { - "create" : function(div_id){ - var layerSources = { - "osm" : L.tileLayer('https://{s}.tile.openstreetmap.de/{z}/{x}/{y}.png', - { - attribution: 'Map data © OpenStreetMap contributors', - subdomains: 'ab', - maxZoom: 20, - maxNativeZoom: 18 - }), - - "satellite_tiles" : L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', - { - attribution: 'Tiles © Esri', - maxZoom: 20, - maxNativeZoom: 18 - }), - "satellite_names": L.tileLayer('https://{s}.tile.stamen.com/toner-labels/{z}/{x}/{y}.{ext}', { - attribution: '— Map data © OpenStreetMap', - subdomains: 'abcd', - minZoom: 0, - maxNativeZoom: 18, - maxZoom: 20, - ext: 'png' - }) - }; - - var center = [initial_latitude, initial_longitude]; - var zoom = 15; - - var map = L.map(div_id, { - center: center, - zoom : zoom, - maxZoom: 24, - scrollWheelZoom: false - }); - - // add tile layers - var satellite = L.layerGroup([layerSources.satellite_tiles, layerSources.satellite_names]); - - satellite.addTo(map); - - var baseLayers = { - "Satellite" : satellite, - "Streets" : layerSources["osm"] - }; - - L.control.layers(baseLayers, {}, {"position":"topright"}).addTo(map); - - return map; - - }, - "place_marker" : function(manager, lat, lng){ - var latLng = L.latLng(lat, lng); - if (manager.marker != null){ - manager.marker.remove(); - } - var marker = L.marker([lat, lng]).addTo(manager.map); - manager.marker = marker; - }, - "attach_map_click_listener" : function(manager){ - // place a marker on click - function setMarker(event) { - maps.leaflet.place_marker(manager, event.latlng.lat, event.latlng.lng); - - var position = manager.latLngToPosition(event.latlng.lat, event.latlng.lng); - manager.position = position; - manager.set_position_field_values(position); - manager.clearWatch(); - } - - manager.map.on('click', setMarker); - }, - "position_to_latlng" : function(position){ - return L.latLng(position.coords.latitude, position.coords.longitude); - }, - "set_map_center" : function(map, latitude, longitude){ - var latLng = L.latLng(latitude, longitude); - map.setView(latLng); - }, - "remove_marker" : function(manager){ - if (manager.marker != null){ - manager.marker.remove(); - } - } - }, - "google" : { - "create" : function(div_id){ - var map = new google.maps.Map(document.getElementById(div_id), { - zoom: 14, - center: {lat: initial_latitude, lng: initial_longitude}, - mapTypeId: google.maps.MapTypeId.TERRAIN, - streetViewControl: false, - }); - - return map; - - }, - "place_marker" : function(manager, lat, lng){ - - var latLng = new google.maps.LatLng(lat, lng); - - if (manager.marker == null){ - var marker = new google.maps.Marker({ - position: { lat: lat, lng: lng}, - map: null - }); - manager.marker = marker; - } - - manager.marker.setMap(manager.map); - manager.marker.setPosition(latLng); - }, - "attach_map_click_listener" : function(manager){ - - // place a marker on click - google.maps.event.addListener(manager.map, "click", function(event){ - - maps.google.place_marker(manager, event.latLng.lat(), event.latLng.lng()); - - var position = manager.latLngToPosition(event.latLng.lat(), event.latLng.lng()); - manager.position = position; - manager.set_position_field_values(position); - manager.clearWatch(); - }); - }, - "position_to_latlng" : function(position){ - return new google.maps.LatLng(position.coords.latitude, position.coords.longitude); - }, - "set_map_center" : function(map, latitude, longitude){ - var latLng = new google.maps.LatLng(latitude, longitude); - map.setCenter(latLng); - }, - "remove_marker" : function(manager){ - manager.marker.setMap(null); - manager.position = null; - } - } - }; - - // within the manager google.maps.latlng is used - // for the interface the position object is used - var MapManager = { - create : function(div_id, initial_latitude, initial_longitude, readonly){ - var self = Object.create(this); - - self.readonly = readonly || false; - - self.watchId = null; - self.position = null; // the position of the map marker if it was set by a human, not the position of the inputs or the gps sensor - - self.map = maps[map_type].create(div_id); - - if (value == null){ - self.marker = null; - } - else { - self.marker = maps[map_type].place_marker(self, initial_latitude, initial_longitude); - } - - if (readonly == false){ - maps[map_type].attach_map_click_listener(self); - } - - return self; - }, - - set_position_field_values : function(position){ - position_json_input.value = JSON.stringify(position); - var verbose = "" + position.coords.latitude.toFixed(4) + "N " + position.coords.longitude.toFixed(4) + "E"; - verbose_position.value = verbose; - }, - - latLngToPosition : function(latitude, longitude){ - var position = { - coords : { - latitude : latitude, - longitude : longitude, - accuracy : 0 - } - }; - return position; - }, - - clean_position : function (position){ - try { - if (typeof(position.coords.latitude) == "number" && typeof(position.coords.longitude) == "number" && typeof(position.coords.accuracy == "number")){ - var position_cleaned = { - coords : { - latitude : position.coords.latitude, - longitude : position.coords.longitude, - accuracy : position.coords.accuracy - } - }; - return position_cleaned; - } - else { - return null; - } - } - catch (e){ - return null; - } - }, - - removeMarker : function(){ - maps[map_type].remove_marker(this); - }, - - onSuccess : function(position){ - var valid_position = this.clean_position(position); - - if (valid_position != null) { - maps[map_type].place_marker(this, position.coords.latitude, position.coords.longitude); - maps[map_type].set_map_center(this.map, position.coords.latitude, position.coords.longitude); - - if (position.coords.accuracy < 100){ - this.clearWatch(); - } - this.set_position_field_values(valid_position); - } - }, - - onError : function(e){ - console.log(e); - }, - - watchPosition : function() { - - var mapmanager = this; - - if (this.watchId == null){ - this.watchId = navigator.geolocation.watchPosition(function(position){ - mapmanager.onSuccess(position); - }, - function(e){ - mapmanager.onError(e); - }, {enableHighAccuracy:true, timeout:60000, maximumAge:0}); - gps_indicator.classList.remove("glyphicon-refresh"); - gps_indicator.classList.add("blink"); - gps_indicator.classList.add("glyphicon-hourglass"); - } - }, - - clearWatch : function() { - navigator.geolocation.clearWatch(this.watchId); - this.watchId = null; - gps_indicator.classList.remove("blink"); - gps_indicator.classList.remove("glyphicon-hourglass"); - gps_indicator.classList.add("glyphicon-refresh"); - } - - }; - - // fill the form on successful position - var mapmanager = MapManager.create('{{ widget.attrs.id }}_map', initial_latitude, initial_longitude, readonly); - - if (readonly == false){ - delete_button.addEventListener('click', function(){ - position_json_input.value = null; - verbose_position.value = null; - mapmanager.removeMarker(); - }); - - gps_button.addEventListener('click', function(){ - mapmanager.watchPosition(); - }); - - // start watching position if possible - if (navigator.geolocation) { - // conditionally start position fetching - if (typeof(position_json_input.value) == "undefined" || position_json_input.value == null || position_json_input.value == "" ){ - mapmanager.watchPosition(); - } - } - - } + var mapmanager = new MapManager('{{ widget.attrs.id }}', initial_latitude, initial_longitude, readonly, value); })(); diff --git a/localcosmos_server/datasets/templates/datasets/widgets/point_or_area_input.html b/localcosmos_server/datasets/templates/datasets/widgets/point_or_area_input.html new file mode 100644 index 0000000..b8ce27c --- /dev/null +++ b/localcosmos_server/datasets/templates/datasets/widgets/point_or_area_input.html @@ -0,0 +1,64 @@ +{% load i18n static %} + +
+
+
+
+ {% if not widget.attrs.readonly %} +
+
+ +
+
+ {% endif %} + + + + + {% if not widget.attrs.readonly %} +
+
+ +
+
+ {% endif %} +
+ +
+
+
+ + +
+
+
+ + diff --git a/localcosmos_server/datasets/widgets.py b/localcosmos_server/datasets/widgets.py index 163dbe6..0abce6b 100644 --- a/localcosmos_server/datasets/widgets.py +++ b/localcosmos_server/datasets/widgets.py @@ -1,19 +1,13 @@ from django.conf import settings from django.contrib.gis import forms from django.forms.widgets import * -from django.forms.utils import flatatt -from django.template import loader, Context -from django.utils.encoding import ( - force_str, force_text -) +from django.utils.encoding import force_str from localcosmos_server.utils import datetime_from_cron -from django.utils.html import conditional_escape, format_html, html_safe +import re, json, datetime, time - -from localcosmos_server.taxonomy.widgets import TaxonAutocompleteWidget as BackboneTaxonAutocompleteWidget - -import json +from django.utils.formats import get_format +from django.utils import timezone ''' JSONWidget consist of one hidden TextInput (the json) @@ -94,17 +88,12 @@ def get_context(self, name, value, attrs): return context - +class PointOrAreaInput(JSONWidget): -from django.forms.widgets import Widget, Select -import re -import datetime, time -from django.utils.dates import MONTHS -from django.utils import datetime_safe -from django.utils.formats import get_format -from django.utils.safestring import mark_safe -from django.utils import timezone + template_name = 'datasets/widgets/point_or_area_input.html' + + class SelectDateTimeWidget(JSONWidget): """ A Widget that splits date and time input into three {% for choice in taxon_source_choices %} - + {% endfor %} diff --git a/localcosmos_server/templatetags/localcosmos_tags.py b/localcosmos_server/templatetags/localcosmos_tags.py index 713f7e0..79c49f8 100644 --- a/localcosmos_server/templatetags/localcosmos_tags.py +++ b/localcosmos_server/templatetags/localcosmos_tags.py @@ -157,4 +157,9 @@ def get_app_locale(context, key): @register.simple_tag def content_image_url(instance, image_type): content_image = instance.image(image_type) - return content_image.image_url() \ No newline at end of file + return content_image.image_url() + + +@register.filter +def is_ajax(request): + return request.headers.get('x-requested-with') == 'XMLHttpRequest' \ No newline at end of file diff --git a/localcosmos_server/tests/mixins.py b/localcosmos_server/tests/mixins.py index d115c07..cb51267 100644 --- a/localcosmos_server/tests/mixins.py +++ b/localcosmos_server/tests/mixins.py @@ -227,11 +227,10 @@ def create_validation_routine(self): step.save() -from localcosmos_server.online_content.models import (TemplateContent, LocalizedTemplateContent, - LocalizedDraftImageMicroContent, DraftImageMicroContent, DraftTextMicroContent, LocalizedDraftTextMicroContent) +from localcosmos_server.template_content.models import (TemplateContent, LocalizedTemplateContent) -class WithOnlineContent: +class WithTemplateContent: template_content_title = 'Test template content' template_content_navigation_link_name = 'Test navigation link' @@ -266,7 +265,7 @@ def create_secondary_language_ltcs(self): localized_template_content = LocalizedTemplateContent.objects.create(self.user, self.template_content, language, draft_title, draft_navigation_link_name) - + ''' def create_draft_image_microcontent(self, template_content, microcontent_type, language): im = Image.new(mode='RGB', size=(200, 200)) # create a new image using PIL @@ -321,7 +320,7 @@ def create_localized_draft_microcontent(self, microcontent, language): draft_lmc.save() return draft_lmc - + ''' def get_view(self, view_class, url_name): diff --git a/localcosmos_server/tests/test_models.py b/localcosmos_server/tests/test_models.py index 937fe37..90ffeae 100644 --- a/localcosmos_server/tests/test_models.py +++ b/localcosmos_server/tests/test_models.py @@ -252,7 +252,7 @@ def test_get_installed_app_path(self): self.app.published_version_path = self.published_version_path self.app.save() - + ''' def test_get_online_content_app_state(self): app_state = self.app.get_online_content_app_state() @@ -287,7 +287,7 @@ def test_get_online_content_templates(self): # check that the correct templates have been loaded self.assertEqual(templates, available_templates[template_type]) - def test_get_online_content_temaplate(self): + def test_get_online_content_template(self): template_names = ['feature/news.html', 'page/test.html', 'page/free_page.html',] for template_name in template_names: @@ -296,6 +296,7 @@ def test_get_online_content_temaplate(self): with self.assertRaises(TemplateDoesNotExist): template = self.app.get_online_content_template('page/PREVIEW.html') + ''' def test_get_locale(self): for language in self.app.languages(): @@ -418,7 +419,7 @@ def test_get_features(self): self.assertFalse('REVIEW' in published_features) self.assertFalse('PREVIEW' in published_features) - + ''' def test_get_online_content_app_state(self): app_state = self.app.get_online_content_app_state() @@ -477,6 +478,7 @@ def test_get_online_content_template(self): for template_name in template_names: template = self.app.get_online_content_template(template_name) self.assertTrue(isinstance(template, Template)) + ''' from localcosmos_server.models import APP_USER_ROLES diff --git a/localcosmos_server/views.py b/localcosmos_server/views.py index 55eb8a5..8c10bc0 100644 --- a/localcosmos_server/views.py +++ b/localcosmos_server/views.py @@ -1,7 +1,7 @@ from django.conf import settings from django.views.generic import TemplateView, FormView from django.contrib.auth.views import LoginView -from django.utils.http import is_safe_url +from django.utils.http import url_has_allowed_host_and_scheme from django.http import Http404 from localcosmos_server.forms import EmailOrUsernameAuthenticationForm, ManageContentImageForm @@ -22,7 +22,7 @@ def get_redirect_url(self): self.redirect_field_name, self.request.POST.get(self.redirect_field_name, '') ) - url_is_safe = is_safe_url( + url_is_safe = url_has_allowed_host_and_scheme( url=redirect_to, allowed_hosts=self.get_success_url_allowed_hosts(), require_https=self.request.is_secure(), diff --git a/localcosmos_server/widgets.py b/localcosmos_server/widgets.py index e68e22e..5ae0bf3 100644 --- a/localcosmos_server/widgets.py +++ b/localcosmos_server/widgets.py @@ -1,17 +1,6 @@ -from django import forms -from django.forms.utils import flatatt -from django.template import loader, Context -from django.utils.encoding import ( - force_str, force_text -) -from django.utils.html import conditional_escape, format_html, html_safe -from django.utils.safestring import mark_safe - from django.forms.widgets import FileInput, HiddenInput - from django.contrib.contenttypes.models import ContentType -from django.utils import translation class ImageInputWithPreview(FileInput): diff --git a/setup.py b/setup.py index 3437017..5c8817f 100644 --- a/setup.py +++ b/setup.py @@ -4,26 +4,27 @@ long_description = fh.read() install_requires = [ - 'django==3.1.*', - 'djangorestframework==3.11.2', + 'django==4.1.*', + 'djangorestframework==3.14.0', 'drf-spectacular==0.24.*', 'djangorestframework-simplejwt==5.2.*', - 'django-imagekit==4.0.2', - 'django-road', + 'django-imagekit==4.1.*', 'content-licencing', 'anycluster', - 'rules==2.2', + 'rules==3.3', 'django-el-pagination==3.3.0', 'django-octicons==1.0.2', - 'django-countries==6.1.3', - 'django-cors-headers==3.5.0', + 'django-countries==7.5', + 'django-cors-headers==3.13.0', 'Pillow', 'matplotlib', + 'django-taggit==3.1.0', + 'django-road', ] setup( name='localcosmos_server', - version='0.12.8', + version='0.13.1', description='LocalCosmos Private Server. Run your own server for localcosmos.org apps.', long_description=long_description, long_description_content_type="text/markdown",