update dependencies and upgrade code for django where needed/possible

This commit is contained in:
Laura Klünder 2022-04-03 16:33:43 +02:00
parent 0f4e699e37
commit 03437a3a40
67 changed files with 331 additions and 207 deletions

View file

@ -5,8 +5,6 @@ from rest_framework.renderers import JSONRenderer
from c3nav.mapdata.utils.json import json_encoder_reindent
default_app_config = 'c3nav.api.apps.APIConfig'
orig_render = JSONRenderer.render

View file

@ -1,7 +1,7 @@
from django.contrib.auth import login, logout
from django.contrib.auth.forms import AuthenticationForm
from django.middleware import csrf
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from rest_framework.authentication import SessionAuthentication
from rest_framework.decorators import action
from rest_framework.exceptions import ParseError, PermissionDenied

View file

@ -3,7 +3,7 @@ import string
from django.conf import settings
from django.db import models
from django.utils.crypto import constant_time_compare, get_random_string
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
class Token(models.Model):

View file

@ -2,7 +2,7 @@ import inspect
import re
from collections import OrderedDict
from django.conf.urls import include, url
from django.urls import include, path, re_path
from django.utils.functional import cached_property
from rest_framework.generics import GenericAPIView
from rest_framework.response import Response
@ -20,7 +20,7 @@ from c3nav.mapdata.utils.user import can_access_editor
from c3nav.routing.api import RoutingViewSet
router = SimpleRouter()
router.register(r'map', MapViewSet, base_name='map')
router.register(r'map', MapViewSet, basename='map')
router.register(r'levels', LevelViewSet)
router.register(r'buildings', BuildingViewSet)
router.register(r'spaces', SpaceViewSet)
@ -40,18 +40,18 @@ router.register(r'accessrestrictions', AccessRestrictionViewSet)
router.register(r'accessrestrictiongroups', AccessRestrictionGroupViewSet)
router.register(r'locations', LocationViewSet)
router.register(r'locations/by_slug', LocationBySlugViewSet, base_name='location-by-slug')
router.register(r'locations/dynamic', DynamicLocationPositionViewSet, base_name='dynamic-location')
router.register(r'locations/by_slug', LocationBySlugViewSet, basename='location-by-slug')
router.register(r'locations/dynamic', DynamicLocationPositionViewSet, basename='dynamic-location')
router.register(r'locationgroupcategories', LocationGroupCategoryViewSet)
router.register(r'locationgroups', LocationGroupViewSet)
router.register(r'updates', UpdatesViewSet, base_name='updates')
router.register(r'updates', UpdatesViewSet, basename='updates')
router.register(r'routing', RoutingViewSet, base_name='routing')
router.register(r'routing', RoutingViewSet, basename='routing')
router.register(r'editor', EditorViewSet, base_name='editor')
router.register(r'editor', EditorViewSet, basename='editor')
router.register(r'changesets', ChangeSetViewSet)
router.register(r'session', SessionViewSet, base_name='session')
router.register(r'session', SessionViewSet, basename='session')
class APIRoot(GenericAPIView):
@ -94,6 +94,7 @@ class APIRoot(GenericAPIView):
urlpatterns = [
url(r'^$', APIRoot.as_view()),
url(r'', include(router.urls)),
# todo: does this work? can it be better?
re_path(r'^$', APIRoot.as_view()),
path('', include(router.urls)),
]

View file

@ -2,7 +2,7 @@ from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.models import User
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from c3nav.control.models import UserPermissions

View file

@ -11,8 +11,8 @@ from django.contrib.auth.models import User
from django.db.models import Prefetch
from django.forms import ChoiceField, Form, IntegerField, ModelForm, Select
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ungettext_lazy
from django.utils.translation import gettext_lazy as _
from django.utils.translation import ngettext_lazy
from c3nav.control.models import UserPermissions, UserSpaceAccess
from c3nav.mapdata.forms import I18nModelFormMixin
@ -81,9 +81,9 @@ class AccessPermissionForm(Form):
# construct choice field for access permissions
choices = [('', _('choose permissions…')),
('all', ungettext_lazy('everything possible (%d permission)',
'everything possible (%d permissions)',
len(access_restrictions)) % len(access_restrictions))]
('all', ngettext_lazy('everything possible (%d permission)',
'everything possible (%d permissions)',
len(access_restrictions)) % len(access_restrictions))]
choices.append((_('Access Permission Groups'), tuple(
('g%d' % group.pk, group.title)
@ -102,18 +102,18 @@ class AccessPermissionForm(Form):
]
for minutes in range(15, 60, 15):
expire_choices.append(
(str(minutes), ungettext_lazy('in %d minute', 'in %d minutes', minutes) % minutes))
(str(minutes), ngettext_lazy('in %d minute', 'in %d minutes', minutes) % minutes))
for hours in chain(range(1, 6), range(6, 24, 6)):
expire_choices.append(
(str(hours*60), ungettext_lazy('in %d hour', 'in %d hours', hours) % hours)
(str(hours*60), ngettext_lazy('in %d hour', 'in %d hours', hours) % hours)
)
expire_choices.insert(
5, (str(90), _('in 1½ hour'))
)
for days in range(1, 14):
expire_choices.append(
(str(days*24*60), ungettext_lazy('in %d day', 'in %d days', days) % days)
(str(days*24*60), ngettext_lazy('in %d day', 'in %d days', days) % days)
)
self.fields['expires'] = ChoiceField(required=False, initial='60', choices=expire_choices)

View file

@ -6,7 +6,7 @@ from django.contrib.auth.models import User
from django.core.cache import cache
from django.db import models, transaction
from django.utils.functional import cached_property, lazy
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from c3nav.mapdata.models import Space

View file

@ -1,15 +1,15 @@
from django.conf.urls import url
from django.urls import path
from c3nav.control.views import (announcement_detail, announcement_list, grant_access, grant_access_qr, main_index,
map_updates, user_detail, user_list)
urlpatterns = [
url(r'^users/$', user_list, name='control.users'),
url(r'^users/(?P<user>\d+)/$', user_detail, name='control.users.detail'),
url(r'^access/$', grant_access, name='control.access'),
url(r'^access/(?P<token>[^/]+)$', grant_access_qr, name='control.access.qr'),
url(r'^announcements/$', announcement_list, name='control.announcements'),
url(r'^announcements/(?P<announcement>\d+)/$', announcement_detail, name='control.announcements.detail'),
url(r'^mapupdates/$', map_updates, name='control.map_updates'),
url(r'^$', main_index, name='control.index'),
path('users/', user_list, name='control.users'),
path('users/<int:user>/', user_detail, name='control.users.detail'),
path('access/', grant_access, name='control.access'),
path('access/<str:token>', grant_access_qr, name='control.access.qr'),
path('announcements/', announcement_list, name='control.announcements'),
path('announcements/<int:annoucement>/', announcement_detail, name='control.announcements.detail'),
path('mapupdates/', map_updates, name='control.map_updates'),
path('', main_index, name='control.index'),
]

View file

@ -17,7 +17,7 @@ from django.urls import reverse
from django.utils import timezone
from django.utils.crypto import get_random_string
from django.utils.timezone import make_aware
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from c3nav.control.forms import (AccessPermissionForm, AnnouncementForm, MapUpdateFilterForm, MapUpdateForm,
UserPermissionsForm, UserSpaceAccessForm)

View file

@ -1 +0,0 @@
default_app_config = 'c3nav.editor.apps.EditorConfig'

View file

@ -4,7 +4,7 @@ from itertools import chain
from django.db.models import Prefetch, Q
from django.urls import Resolver404, resolve
from django.utils.functional import cached_property
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from rest_framework.authentication import SessionAuthentication
from rest_framework.decorators import action
from rest_framework.exceptions import NotFound, ParseError, PermissionDenied, ValidationError

View file

@ -0,0 +1,8 @@
class EditPkConverter:
regex = r'c?\d+'
def to_python(self, value):
return value
def to_url(self, value):
return value

View file

@ -13,7 +13,7 @@ from django.db.models import Q
from django.forms import (BooleanField, CharField, ChoiceField, DecimalField, Form, ModelChoiceField, ModelForm,
MultipleChoiceField, Select, ValidationError)
from django.forms.widgets import HiddenInput
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from shapely.geometry.geo import mapping
from c3nav.editor.models import ChangeSet, ChangeSetUpdate

View file

@ -6,7 +6,7 @@ from itertools import chain
from django.contrib.contenttypes.models import ContentType
from django.db import models
from django.db.models import CharField, DecimalField, Field, TextField
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from c3nav.editor.wrappers import ModelInstanceWrapper, is_created_pk
from c3nav.mapdata.fields import I18nField, JSONField

View file

@ -14,8 +14,8 @@ from django.db.models import Q
from django.urls import reverse
from django.utils.http import int_to_base36
from django.utils.timezone import make_naive
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ungettext_lazy
from django.utils.translation import gettext_lazy as _
from django.utils.translation import ngettext_lazy
from c3nav.editor.models.changedobject import ApplyToInstanceError, ChangedObject, NoopChangedObject
from c3nav.editor.tasks import send_changeset_proposed_notification
@ -804,7 +804,7 @@ class ChangeSet(models.Model):
if self.direct_editing:
return _('Direct editing active')
return _('No objects changed')
return (ungettext_lazy('%(num)d object changed', '%(num)d objects changed', 'num') %
return (ngettext_lazy('%(num)d object changed', '%(num)d objects changed', 'num') %
{'num': self.changed_objects_count})
@property

View file

@ -2,7 +2,7 @@ from collections import OrderedDict
from django.conf import settings
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from c3nav.editor.models import ChangeSet

View file

@ -1,11 +1,14 @@
from django.apps import apps
from django.conf.urls import url
from django.urls import path, register_converter
from c3nav.editor.converters import EditPkConverter
from c3nav.editor.views.account import change_password_view, login_view, logout_view, register_view
from c3nav.editor.views.changes import changeset_detail, changeset_edit, changeset_redirect
from c3nav.editor.views.edit import edit, graph_edit, level_detail, list_objects, main_index, sourceimage, space_detail
from c3nav.editor.views.users import user_detail, user_redirect
register_converter(EditPkConverter, 'editpk')
def add_editor_urls(model_name, parent_model_name=None, with_list=True, explicit_edit=False):
model = apps.get_model('mapdata', model_name)
@ -13,42 +16,43 @@ def add_editor_urls(model_name, parent_model_name=None, with_list=True, explicit
if parent_model_name:
parent_model = apps.get_model('mapdata', parent_model_name)
parent_model_name_plural = parent_model._meta.default_related_name
prefix = (parent_model_name_plural+r'/(?P<'+parent_model_name.lower()+'>c?[0-9]+)/')+model_name_plural
prefix = (parent_model_name_plural+r'/<editpk:'+parent_model_name.lower()+'>/')+model_name_plural
else:
prefix = model_name_plural
name_prefix = 'editor.'+model_name_plural+'.'
kwargs = {'model': model_name, 'explicit_edit': explicit_edit}
explicit_edit = r'edit' if explicit_edit else ''
explicit_edit = 'edit' if explicit_edit else ''
result = []
if with_list:
result.append(url(r'^'+prefix+r'/$', list_objects, name=name_prefix+'list', kwargs=kwargs))
result.append(path(prefix+'/', list_objects, name=name_prefix+'list', kwargs=kwargs))
result.extend([
url(r'^'+prefix+r'/(?P<pk>c?\d+)/'+explicit_edit+'$', edit, name=name_prefix+'edit', kwargs=kwargs),
url(r'^'+prefix+r'/create$', edit, name=name_prefix+'create', kwargs=kwargs),
path(prefix+'/<editpk:pk>/'+explicit_edit, edit, name=name_prefix+'edit', kwargs=kwargs),
path(prefix+'/create', edit, name=name_prefix+'create', kwargs=kwargs),
])
return result
# todo: custom path converters
urlpatterns = [
url(r'^$', main_index, name='editor.index'),
url(r'^levels/(?P<pk>c?[0-9]+)/$', level_detail, name='editor.levels.detail'),
url(r'^levels/(?P<level>c?[0-9]+)/spaces/(?P<pk>c?[0-9]+)/$', space_detail, name='editor.spaces.detail'),
url(r'^levels/(?P<on_top_of>c?[0-9]+)/levels_on_top/create$', edit, name='editor.levels_on_top.create',
kwargs={'model': 'Level'}),
url(r'^levels/(?P<level>c?[0-9]+)/graph/$', graph_edit, name='editor.levels.graph'),
url(r'^spaces/(?P<space>c?[0-9]+)/graph/$', graph_edit, name='editor.spaces.graph'),
url(r'^changeset/$', changeset_redirect, name='editor.changesets.current'),
url(r'^changesets/(?P<pk>[0-9]+)/$', changeset_detail, name='editor.changesets.detail'),
url(r'^changesets/(?P<pk>[0-9]+)/edit$', changeset_edit, name='editor.changesets.edit'),
url(r'^sourceimage/(?P<filename>[^/]+)$', sourceimage, name='editor.sourceimage'),
url(r'^user/$', user_redirect, name='editor.users.redirect'),
url(r'^users/(?P<pk>[0-9]+)/$', user_detail, name='editor.users.detail'),
url(r'^login$', login_view, name='editor.login'),
url(r'^logout$', logout_view, name='editor.logout'),
url(r'^register$', register_view, name='editor.register'),
url(r'^change_password$', change_password_view, name='editor.change_password'),
path('levels/<editpk:pk>/', level_detail, name='editor.levels.detail'),
path('levels/<editpk:level>/spaces/<editpk:pk>/', space_detail, name='editor.spaces.detail'),
path('levels/<editpk:on_top_of>/levels_on_top/create', edit, {'model': 'Level'},
name='editor.levels_on_top.create'),
path('levels/<editpk:level>/graph/', graph_edit, name='editor.levels.graph'),
path('spaces/<editpk:space>/graph/', graph_edit, name='editor.spaces.graph'),
path('changeset/', changeset_redirect, name='editor.changesets.current'),
path('changesets/<editpk:pk>/', changeset_detail, name='editor.changesets.detail'),
path('changesets/<editpk:pk>/edit', changeset_edit, name='editor.changesets.edit'),
path('sourceimage/<str:filename>', sourceimage, name='editor.sourceimage'),
path('user/', user_redirect, name='editor.users.redirect'),
path('users/<int:pk>/', user_detail, name='editor.users.detail'),
path('login', login_view, name='editor.login'),
path('logout', logout_view, name='editor.logout'),
path('register', register_view, name='editor.register'),
path('change_password', change_password_view, name='editor.change_password'),
path('', main_index, name='editor.index'),
]
urlpatterns.extend(add_editor_urls('Level', with_list=False, explicit_edit=True))
urlpatterns.extend(add_editor_urls('LocationGroupCategory'))

View file

@ -4,7 +4,7 @@ from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import AuthenticationForm, PasswordChangeForm, UserCreationForm
from django.shortcuts import redirect, render
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from c3nav.editor.views.base import sidebar_view

View file

@ -13,7 +13,7 @@ from django.http import HttpResponse, HttpResponseNotModified, HttpResponseRedir
from django.shortcuts import redirect, render
from django.utils.cache import patch_vary_headers
from django.utils.translation import get_language
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from rest_framework.response import Response as APIResponse
from c3nav.editor.models import ChangeSet

View file

@ -10,7 +10,7 @@ from django.shortcuts import get_object_or_404, redirect, render
from django.urls import NoReverseMatch, reverse
from django.utils.text import format_lazy
from django.utils.translation import get_language_info
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from c3nav.editor.forms import ChangeSetForm, RejectForm
from c3nav.editor.models import ChangeSet

View file

@ -12,7 +12,7 @@ from django.db.models import Q
from django.http import Http404, HttpResponse
from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from django.views.decorators.http import etag
from c3nav.editor.forms import GraphEdgeSettingsForm, GraphEditorActionForm

View file

@ -2,7 +2,7 @@ from django.contrib import messages
from django.contrib.auth.models import User
from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from c3nav.editor.models import ChangeSet
from c3nav.editor.views.base import sidebar_view

View file

@ -5,9 +5,9 @@ from functools import reduce, wraps
from itertools import chain
from django.core.cache import cache
from django.core.exceptions import ObjectDoesNotExist
from django.core.exceptions import ObjectDoesNotExist, FieldDoesNotExist
from django.db import models
from django.db.models import FieldDoesNotExist, Manager, ManyToManyRel, Prefetch, Q
from django.db.models import Manager, ManyToManyRel, Prefetch, Q
from django.db.models.fields.related_descriptors import ReverseOneToOneDescriptor
from django.utils.functional import cached_property

View file

@ -1 +0,0 @@
default_app_config = 'c3nav.mapdata.apps.MapdataConfig'

View file

@ -11,7 +11,7 @@ from django.shortcuts import redirect
from django.utils.cache import get_conditional_response
from django.utils.http import http_date, quote_etag, urlsafe_base64_encode
from django.utils.translation import get_language
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from rest_framework.decorators import action
from rest_framework.exceptions import NotFound, ValidationError
from rest_framework.generics import get_object_or_404

View file

@ -0,0 +1,48 @@
class SignedIntConverter:
regex = r'-?\d+'
def to_python(self, value):
return int(value)
def to_url(self, value):
return str(value)
class AccessPermissionsConverter:
regex = r'\d+(-\d+)*'
def to_python(self, value):
return set(int(i) for i in value.split('-'))
def to_url(self, value):
return '-'.join(str(i) for i in value)
class HistoryModeConverter:
regex = '(base|composite)'
def to_python(self, value):
return value
def to_url(self, value):
return value
class HistoryFileExtConverter:
regex = '(png|data)'
def to_python(self, value):
return value
def to_url(self, value):
return value
class ArchiveFileExtConverter:
regex = r'(tar|tar\.gz|tar\.xz)'
def to_python(self, value):
return value
def to_url(self, value):
return value

View file

@ -9,7 +9,7 @@ from django.db import models
from django.utils.functional import cached_property, lazy
from django.utils.text import format_lazy
from django.utils.translation import get_language
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from shapely import validation
from shapely.geometry import LineString, MultiPolygon, Point, Polygon, mapping, shape
from shapely.geometry.base import BaseGeometry

View file

@ -6,7 +6,7 @@ from django.forms import CharField, ModelForm
from django.utils import timezone
from django.utils.text import capfirst, format_lazy
from django.utils.translation import get_language_info
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from c3nav.mapdata.fields import I18nField
from c3nav.mapdata.models.locations import Position

View file

@ -4,7 +4,7 @@ import os
from django.conf import settings
from django.core.management.base import BaseCommand
from django.db import DatabaseError
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from c3nav.mapdata.tasks import process_map_updates

View file

@ -5,7 +5,7 @@ import socket
import dateutil
from django.conf import settings
from django.core.management.base import BaseCommand
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from c3nav.mapdata.utils.cache.stats import convert_stats

View file

@ -4,7 +4,7 @@ import re
from xml.etree import ElementTree
from django.core.management.base import BaseCommand, CommandError
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from shapely.affinity import scale, translate
from shapely.geometry import Polygon

View file

@ -3,7 +3,7 @@ import logging
from django.conf import settings
from django.core.management.base import BaseCommand
from django.db import DatabaseError
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from c3nav.mapdata.tasks import process_map_updates

View file

@ -3,8 +3,8 @@ import os
from django.conf import settings
from django.core.management.base import BaseCommand, CommandError
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ungettext_lazy
from django.utils.translation import gettext_lazy as _
from django.utils.translation import ngettext_lazy
from c3nav.mapdata.models import AccessRestriction, Level, Source
from c3nav.mapdata.render.engines import get_engine, get_engine_filetypes
@ -25,7 +25,7 @@ class Command(BaseCommand):
not_found = values - set(level.short_label for level in levels)
if not_found:
raise argparse.ArgumentTypeError(
ungettext_lazy('Unknown level: %s', 'Unknown levels: %s', len(not_found)) % ', '.join(not_found)
ngettext_lazy('Unknown level: %s', 'Unknown levels: %s', len(not_found)) % ', '.join(not_found)
)
return levels
@ -43,8 +43,8 @@ class Command(BaseCommand):
not_found = values - set(str(permission.pk) for permission in permissions)
if not_found:
raise argparse.ArgumentTypeError(
ungettext_lazy('Unknown access restriction: %s',
'Unknown access restrictions: %s', len(not_found)) % ', '.join(not_found)
ngettext_lazy('Unknown access restriction: %s',
'Unknown access restrictions: %s', len(not_found)) % ', '.join(not_found)
)
return permissions

View file

@ -3,7 +3,7 @@ import os
from django.conf import settings
from django.core.management.base import BaseCommand
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from c3nav.mapdata.utils.cache.stats import stats_snapshot

View file

@ -9,8 +9,8 @@ from django.core.cache import cache
from django.db import models, transaction
from django.db.models import Q
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ungettext_lazy
from django.utils.translation import gettext_lazy as _
from django.utils.translation import ngettext_lazy
from c3nav.mapdata.models import MapUpdate
from c3nav.mapdata.models.base import SerializableMixin, TitledMixin
@ -130,7 +130,7 @@ class AccessPermissionToken(models.Model):
@property
def redeem_success_message(self):
return ungettext_lazy('Area successfully unlocked.', 'Areas successfully unlocked.', len(self.restrictions))
return ngettext_lazy('Area successfully unlocked.', 'Areas successfully unlocked.', len(self.restrictions))
class AccessPermission(models.Model):

View file

@ -4,7 +4,7 @@ from django.core.cache import cache
from django.db import models
from django.db.models import Q
from django.utils.translation import get_language, get_language_info
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from c3nav.mapdata.fields import I18nField
from c3nav.mapdata.models import MapUpdate

View file

@ -3,7 +3,7 @@ from contextlib import contextmanager
from django.db import models
from django.utils.functional import cached_property
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from shapely.geometry import Point, box
from shapely.ops import unary_union

View file

@ -10,7 +10,7 @@ from django.db import models
from django.urls import reverse
from django.utils.functional import cached_property
from django.utils.text import format_lazy
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from scipy.sparse.csgraph._shortest_path import dijkstra
from shapely import prepared
from shapely.affinity import scale

View file

@ -7,7 +7,7 @@ from django.db import models
from django.urls import reverse
from django.utils.functional import cached_property
from django.utils.text import format_lazy
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from shapely.geometry import CAP_STYLE, JOIN_STYLE, mapping
from c3nav.mapdata.fields import GeometryField, I18nField, JSONField

View file

@ -2,7 +2,7 @@ from decimal import Decimal
from django.core.validators import MinValueValidator
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from c3nav.mapdata.fields import GeometryField, I18nField
from c3nav.mapdata.models.access import AccessRestrictionMixin

View file

@ -6,7 +6,7 @@ from django.core.validators import MinValueValidator
from django.db import models
from django.urls import reverse
from django.utils.functional import cached_property
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from shapely.ops import cascaded_union
from c3nav.mapdata.models.locations import SpecificLocation

View file

@ -6,16 +6,16 @@ from operator import attrgetter
from django.conf import settings
from django.core.cache import cache
from django.core.exceptions import FieldDoesNotExist
from django.core.validators import MaxValueValidator, MinValueValidator, RegexValidator
from django.db import models, transaction
from django.db.models import FieldDoesNotExist, Prefetch
from django.db.models import Prefetch
from django.urls import reverse
from django.utils import timezone
from django.utils.crypto import get_random_string
from django.utils.functional import cached_property
from django.utils.text import format_lazy
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ungettext_lazy
from django.utils.translation import gettext_lazy as _, ngettext_lazy
from c3nav.mapdata.fields import I18nField
from c3nav.mapdata.grid import grid
@ -396,7 +396,7 @@ class LocationGroup(Location, models.Model):
if hasattr(self, 'locations'):
return format_lazy(_('{category_title}, {num_locations}'),
category_title=result,
num_locations=(ungettext_lazy('%(num)d location', '%(num)d locations', 'num') %
num_locations=(ngettext_lazy('%(num)d location', '%(num)d locations', 'num') %
{'num': len(self.locations)}))
return result

View file

@ -8,7 +8,7 @@ from django.db.models import Q
from django.urls import reverse
from django.utils.crypto import get_random_string
from django.utils.functional import cached_property
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from c3nav.mapdata.fields import I18nField
from c3nav.mapdata.models.geometry.level import LevelGeometryMixin
@ -172,7 +172,7 @@ class ReportUpdate(models.Model):
report = models.ForeignKey(Report, on_delete=models.CASCADE, related_name='updates')
datetime = models.DateTimeField(auto_now_add=True, verbose_name=_('datetime'))
author = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.PROTECT, verbose_name=_('author'))
open = models.NullBooleanField(verbose_name=_('open'))
open = models.BooleanField(null=True, verbose_name=_('open'))
comment = models.TextField(verbose_name=_('comment'), blank=True)
assigned_to = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.PROTECT,
related_name='report_update_assigns', verbose_name=_('assigned to'))

View file

@ -2,7 +2,7 @@ import os
from django.conf import settings
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from c3nav.mapdata.models.access import AccessRestrictionMixin
from c3nav.mapdata.models.base import BoundsMixin

View file

@ -10,7 +10,7 @@ from django.core.cache import cache
from django.db import models, transaction
from django.utils.http import int_to_base36
from django.utils.timezone import make_naive
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from c3nav.mapdata.tasks import process_map_updates

View file

@ -4,8 +4,8 @@ import time
from celery.exceptions import MaxRetriesExceededError
from django.core.cache import cache
from django.utils.formats import date_format
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ungettext_lazy
from django.utils.translation import gettext_lazy as _
from django.utils.translation import ngettext_lazy
from c3nav.celery import app
@ -40,7 +40,7 @@ def process_map_updates(self):
if updates:
print()
logger.info(ungettext_lazy('%d map update processed.', '%d map updates processed.', len(updates)) % len(updates))
logger.info(ngettext_lazy('%d map update processed.', '%d map updates processed.', len(updates)) % len(updates))
if updates:
logger.info(_('Last processed update: %(date)s (#%(id)d)') % {

View file

@ -1,12 +1,18 @@
from django.conf.urls import url
from django.urls import path, register_converter
from c3nav.mapdata.converters import SignedIntConverter, AccessPermissionsConverter, HistoryModeConverter, \
HistoryFileExtConverter, ArchiveFileExtConverter
from c3nav.mapdata.views import get_cache_package, map_history, tile
register_converter(SignedIntConverter, 'sint')
register_converter(AccessPermissionsConverter, 'a_perms')
register_converter(HistoryModeConverter, 'h_mode')
register_converter(HistoryFileExtConverter, 'h_fileext')
register_converter(ArchiveFileExtConverter, 'archive_fileext')
urlpatterns = [
url(r'^(?P<level>\d+)/(?P<zoom>-?\d+)/(?P<x>-?\d+)/(?P<y>-?\d+).png$', tile, name='mapdata.tile'),
url(r'^(?P<level>\d+)/(?P<zoom>-?\d+)/(?P<x>-?\d+)/(?P<y>-?\d+)/(?P<access_permissions>\d+(-\d+)*).png$', tile,
name='mapdata.tile'),
url(r'^history/(?P<level>\d+)/(?P<mode>base|composite)\.(?P<filetype>png|data)$', map_history,
name='mapdata.map_history'),
url(r'^cache/package\.(?P<filetype>tar|tar\.gz|tar\.xz)$', get_cache_package, name='mapdata.cache_package'),
path('<int:level>/<sint:zoom>/<sint:x>/<sint:y>.png', tile, name='mapdata.tile'),
path('<int:level>/<sint:zoom>/<sint:x>/<sint:Y>/<a_perms:access_permissions>.png', tile, name='mapdata.tile'),
path('history/<int:level>/<h_mode:mode>.<h_fileext:filetype>', map_history, name='mapdata.map_history'),
path('cache/package.<archive_fileext:filetype>', get_cache_package, name='mapdata.cache_package'),
]

View file

@ -9,7 +9,7 @@ from typing import List, Mapping, Optional, Union
from django.apps import apps
from django.db.models import Prefetch, Q
from django.utils.functional import cached_property
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from shapely.ops import cascaded_union
from c3nav.mapdata.grid import grid

View file

@ -1,7 +1,7 @@
from django.conf import settings
from django.utils.functional import lazy
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ungettext_lazy
from django.utils.translation import gettext_lazy as _
from django.utils.translation import ngettext_lazy
from c3nav.mapdata.models.access import AccessPermission
from c3nav.mapdata.models.locations import Position
@ -18,7 +18,7 @@ def get_user_data(request):
if permissions:
result.update({
'title': _('not logged in'),
'subtitle': ungettext_lazy('%d area unlocked', '%d areas unlocked', len(permissions)) % len(permissions),
'subtitle': ngettext_lazy('%d area unlocked', '%d areas unlocked', len(permissions)) % len(permissions),
'permissions': tuple(permissions),
})
else:

View file

@ -1,6 +1,6 @@
from django.core.exceptions import ValidationError
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.viewsets import ViewSet

View file

@ -1,5 +1,5 @@
from django import forms
from django.utils.translation import ugettext_lazy
from django.utils.translation import gettext_lazy
from c3nav.mapdata.utils.locations import get_location_by_id_for_request
@ -15,11 +15,11 @@ class RouteForm(forms.Form):
def clean_origin(self):
location = get_location_by_id_for_request(self.cleaned_data['origin'], self.request)
if location is None:
raise forms.ValidationError(ugettext_lazy('Unknown origin.'))
raise forms.ValidationError(gettext_lazy('Unknown origin.'))
return location
def clean_destination(self):
location = get_location_by_id_for_request(self.cleaned_data['destination'], self.request)
if location is None:
raise forms.ValidationError(ugettext_lazy('Unknown destination.'))
raise forms.ValidationError(gettext_lazy('Unknown destination.'))
return location

View file

@ -9,7 +9,7 @@ from functools import reduce
import numpy as np
from django.conf import settings
from django.core.exceptions import ValidationError
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from c3nav.mapdata.models import MapUpdate, Space
from c3nav.mapdata.utils.locations import CustomLocation

View file

@ -6,7 +6,7 @@ from django.conf import settings
from django.core.cache import cache
from django.core.exceptions import ValidationError
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from c3nav.mapdata.fields import JSONField
from c3nav.mapdata.models import MapUpdate, WayType

View file

@ -4,7 +4,7 @@ from collections import OrderedDict, deque
import numpy as np
from django.utils.functional import cached_property
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
def describe_location(location, locations):

View file

@ -8,7 +8,7 @@ from contextlib import suppress
import sass
from django.contrib.messages import constants as messages
from django.utils.crypto import get_random_string
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
config = configparser.RawConfigParser()
if 'C3NAV_CONFIG' in os.environ:
@ -141,6 +141,7 @@ DATABASES = {
'CONN_MAX_AGE': 0 if db_backend == 'sqlite3' else 120
}
}
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
STATIC_URL = config.get('urls', 'static', fallback='/static/')
@ -407,6 +408,8 @@ MESSAGE_TAGS = {
}
MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage'
SILENCED_SYSTEM_CHECKS = ['debug_toolbar.W006']
loglevel = 'DEBUG' if DEBUG else 'INFO'
LOGGING = {

View file

@ -0,0 +1,53 @@
from collections import namedtuple
class LocationConverter:
regex = '[a-zA-Z0-9-_.:]+'
def to_python(self, value):
return value
def to_url(self, value):
return value
class CoordinatesConverter:
regex = r'[a-z0-9-_:]+:-?\d+(\.\d+)?:-?\d+(\.\d+)?'
def to_python(self, value):
return value
def to_url(self, value):
return value
AtPos = namedtuple('AtPos', ('level', 'x', 'y', 'zoom'))
class AtPositionConverter:
regex = r'(@[a-z0-9-_:]+,-?\d+(\.\d+)?,-?\d+(\.\d+)?,-?\d+(\.\d+)?)?'
def to_python(self, value):
if not value:
return None
value = AtPos(*value.split(','))
return AtPos(value.level, float(value.x), float(value.y), float(value.zoom))
def to_url(self, value):
return ','.join(str(s) for s in value)
class ConditionalConverter:
def __init_subclass__(cls, /, name):
cls.path = '%s/' % name
cls.regex = '(%s/)?' % name
def to_python(self, value):
return value != ''
def to_url(self, value):
return self.path if value else ''
class IsEmbedConverter(ConditionalConverter, name='embed'):
pass

View file

@ -2,7 +2,7 @@ from operator import attrgetter
from django.db import transaction
from django.forms import Form, ModelChoiceField, ModelForm
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from c3nav.mapdata.forms import I18nModelFormMixin
from c3nav.mapdata.models.locations import Position

View file

@ -5,7 +5,7 @@ from django.core.cache import cache
from django.db import models, transaction
from django.db.models import Q
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from c3nav.mapdata.fields import I18nField

View file

@ -1,42 +1,48 @@
from django.conf.urls import url
from django.urls import path, register_converter
from c3nav.site.converters import LocationConverter, CoordinatesConverter, AtPositionConverter, IsEmbedConverter
from c3nav.site.views import (about_view, access_redeem_view, account_view, change_password_view, choose_language,
login_view, logout_view, map_index, position_create, position_detail, position_list,
position_set, qr_code, register_view, report_create, report_detail, report_list)
slug = r'(?P<slug>[a-zA-Z0-9-_.:]+)'
coordinates = r'(?P<coordinates>[a-z0-9-_:]+:-?\d+(\.\d+)?:-?\d+(\.\d+)?)'
slug2 = r'(?P<slug2>[a-zA-Z0-9-_.:]+)'
details = r'(?P<details>details/)?'
nearby = r'(?P<nearby>nearby/)?'
options = r'(?P<options>options/)?'
pos = r'(@(?P<level>[a-z0-9-_:]+),(?P<x>-?\d+(\.\d+)?),(?P<y>-?\d+(\.\d+)?),(?P<zoom>-?\d+(\.\d+)?))?'
embed = r'(?P<embed>embed/)?'
register_converter(LocationConverter, 'loc')
register_converter(CoordinatesConverter, 'coords')
register_converter(AtPositionConverter, 'at_pos')
register_converter(IsEmbedConverter, 'is_embed')
embed = '<is_embed:embed>'
pos = '<at_pos:pos>'
urlpatterns = [
url(r'^%s(?P<mode>[l])/%s/(%s|%s)%s$' % (embed, slug, details, nearby, pos), map_index, name='site.index'),
url(r'^%s(?P<mode>[od])/%s/%s$' % (embed, slug, pos), map_index, name='site.index'),
url(r'^%sr/%s/%s/(%s|%s)%s$' % (embed, slug, slug2, details, options, pos), map_index, name='site.index'),
url(r'^%s(?P<mode>r)/%s$' % (embed, pos), map_index, name='site.index'),
url(r'^%s%s$' % (embed, pos), map_index, name='site.index'),
url(r'^qr/(?P<path>.*)$', qr_code, name='site.qr'),
url(r'^login$', login_view, name='site.login'),
url(r'^logout$', logout_view, name='site.logout'),
url(r'^register$', register_view, name='site.register'),
url(r'^account/$', account_view, name='site.account'),
url(r'^account/change_password$', change_password_view, name='site.account.change_password'),
url(r'^access/(?P<token>[^/]+)$', access_redeem_view, name='site.access.redeem'),
url(r'^lang/$', choose_language, name='site.language'),
url(r'^about/$', about_view, name='site.about'),
url(r'^reports/(?P<filter>(open|all))/$', report_list, name='site.report_list'),
url(r'^reports/(?P<pk>\d+)/$', report_detail, name='site.report_detail'),
url(r'^reports/(?P<pk>\d+)/(?P<secret>[^/]+)/$', report_detail, name='site.report_detail'),
url(r'^report/l/%s/$' % coordinates, report_create, name='site.report_create'),
url(r'^report/l/(?P<location>\d+)/$', report_create, name='site.report_create'),
url(r'^report/r/(?P<origin>[^/]+)/(?P<destination>[^/]+)/(?P<options>[^/]+)/$',
report_create, name='site.report_create'),
url(r'^positions/$', position_list, name='site.position_list'),
url(r'^positions/create/$', position_create, name='site.position_create'),
url(r'^positions/(?P<pk>\d+)/$', position_detail, name='site.position_detail'),
url(r'^positions/set/%s/$' % coordinates, position_set, name='site.position_set'),
path(f'{embed}l/<loc:slug>/{pos}', map_index, {'mode': 'l'}, name='site.index', ),
path(f'{embed}l/<loc:slug>/details/{pos}', map_index, {'mode': 'l', 'details': True}, name='site.index'),
path(f'{embed}l/<loc:slug>/nearby/{pos}', map_index, {'mode': 'l', 'nearby': True}, name='site.index'),
path(f'{embed}o/<loc:slug>/{pos}', map_index, {'mode': 'o'}, name='site.index'),
path(f'{embed}d/<loc:slug>/{pos}', map_index, {'mode': 'd'}, name='site.index'),
path(f'{embed}r/{pos}', map_index, {'mode': 'r'}, name='site.index'),
path(f'{embed}r/<loc:slug>/<loc:slug2>/{pos}', map_index, {'mode': 'r'}, name='site.index'),
path(f'{embed}r/<loc:slug>/<loc:slug2>/details{pos}', map_index, {'mode': 'r', 'details': True}, name='site.index'),
path(f'{embed}r/<loc:slug>/<loc:slug2>/options{pos}', map_index, {'mode': 'r', 'options': True}, name='site.index'),
path(f'{embed}r/<loc:slug>/<loc:slug2>/options{pos}', map_index, {'mode': 'r', 'options': True}, name='site.index'),
path(f'{embed}{pos}', map_index, name='site.index'),
path('qr/<path:path>', qr_code, name='site.qr'),
path('login', login_view, name='site.login'),
path('logout', logout_view, name='site.logout'),
path('register', register_view, name='site.register'),
path('account/', account_view, name='site.account'),
path('account/change_password', change_password_view, name='site.account.change_password'),
path('access/<str:token>', access_redeem_view, name='site.access.redeem'),
path('lang/', choose_language, name='site.language'),
path('about/', about_view, name='site.about'),
path('reports/open/', report_list, {'filter': 'open'}, name='site.report_list'),
path('reports/all/', report_list, {'filter': 'all'}, name='site.report_list'),
path('reports/<int:pk>/', report_detail, name='site.report_detail'),
path('reports/<int:pk>/<str:secret>/', report_detail, name='site.report_detail'),
path('report/l/<coords:coordinates>/', report_create, name='site.report_create'),
path('report/l/<int:location>/', report_create, name='site.report_create'),
path('report/r/<str:origin>/<str:destination>/<str:options>/', report_create, name='site.report_create'),
path('positions/', position_list, name='site.position_list'),
path('positions/create/', position_create, name='site.position_create'),
path('positions/<int:pk>/', position_detail, name='site.position_detail'),
path('positions/set/<coords:coordinates>/', position_set, name='site.position_set'),
]

View file

@ -18,8 +18,8 @@ from django.middleware import csrf
from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ungettext_lazy
from django.utils.translation import gettext_lazy as _
from django.utils.translation import ngettext_lazy
from django.views.decorators.cache import cache_control, never_cache
from django.views.decorators.clickjacking import xframe_options_exempt
from django.views.decorators.http import etag
@ -59,8 +59,7 @@ def check_location(location: Optional[str], request) -> Optional[SpecificLocatio
return location
def map_index(request, mode=None, slug=None, slug2=None, details=None, options=None, nearby=None,
level=None, x=None, y=None, zoom=None, embed=None):
def map_index(request, mode=None, slug=None, slug2=None, details=None, options=None, nearby=None, pos=None, embed=None):
# check for access token
access_signed_data = request.GET.get('access')
@ -83,8 +82,8 @@ def map_index(request, mode=None, slug=None, slug2=None, details=None, options=N
token.redeem(request.user)
token.save()
messages.success(request, ungettext_lazy('Area successfully unlocked.',
'Areas successfully unlocked.', num_restrictions))
messages.success(request, ngettext_lazy('Area successfully unlocked.',
'Areas successfully unlocked.', num_restrictions))
return redirect('site.index')
origin = None
@ -115,12 +114,12 @@ def map_index(request, mode=None, slug=None, slug2=None, details=None, options=N
levels = levels_by_short_label_for_request(request)
level = levels.get(level, None) if level else None
level = levels.get(pos.level, None) if pos else None
if level is not None:
state.update({
'level': level.pk,
'center': (float(x), float(y)),
'zoom': float(zoom),
'center': (pos.x, pos.y),
'zoom': pos.zoom,
})
initial_bounds = settings.INITIAL_BOUNDS
@ -336,15 +335,15 @@ def access_redeem_view(request, token):
token.redeem(request.user)
token.save()
messages.success(request, ungettext_lazy('Area successfully unlocked.',
'Areas successfully unlocked.', num_restrictions))
messages.success(request, ngettext_lazy('Area successfully unlocked.',
'Areas successfully unlocked.', num_restrictions))
return redirect('site.index')
return render(request, 'site/confirm.html', {
'title': ungettext_lazy('Unlock area', 'Unlock areas', num_restrictions),
'texts': (ungettext_lazy('You have been invited to unlock the following area:',
'You have been invited to unlock the following areas:',
num_restrictions),
'title': ngettext_lazy('Unlock area', 'Unlock areas', num_restrictions),
'texts': (ngettext_lazy('You have been invited to unlock the following area:',
'You have been invited to unlock the following areas:',
num_restrictions),
', '.join(str(restriction.title) for restriction in token.restrictions)),
})

View file

@ -1,7 +1,7 @@
from contextlib import suppress
from django.conf import settings
from django.conf.urls import include, url
from django.urls import include, path
from django.contrib import admin
import c3nav.api.urls
@ -11,16 +11,16 @@ import c3nav.mapdata.urls
import c3nav.site.urls
urlpatterns = [
url(r'^editor/', include(c3nav.editor.urls)),
url(r'^api/', include((c3nav.api.urls, 'api'), namespace='api')),
url(r'^map/', include(c3nav.mapdata.urls)),
url(r'^admin/', admin.site.urls),
url(r'^control/', include(c3nav.control.urls)),
url(r'^locales/', include('django.conf.urls.i18n')),
url(r'^', include(c3nav.site.urls)),
path('editor/', include(c3nav.editor.urls)),
path('api/', include((c3nav.api.urls, 'api'), namespace='api')),
path('map/', include(c3nav.mapdata.urls)),
path('admin/', admin.site.urls),
path('control/', include(c3nav.control.urls)),
path('locales/', include('django.conf.urls.i18n')),
path('', include(c3nav.site.urls)),
]
if settings.DEBUG:
with suppress(ImportError):
import debug_toolbar
urlpatterns.insert(0, url(r'^__debug__/', include(debug_toolbar.urls)))
urlpatterns.insert(0, path('__debug__/', include(debug_toolbar.urls)))

View file

@ -1,4 +1,4 @@
flake8==3.7.9
pycodestyle==2.5.0
flake8==4.0.1
pycodestyle==2.8.0
isort
django-debug-toolbar

View file

@ -1 +1 @@
ModernGL==5.5.4
ModernGL==5.6.4

View file

@ -1,17 +1,17 @@
Django==2.2.13
django-bootstrap3==12.0.0
django-compressor==2.3
Django==4.0.3
django-bootstrap3==21.2
django-compressor==3.1
csscompressor==0.9.5
djangorestframework==3.10.3
django-filter==2.2.0
shapely==1.6.4.post2
pybind11==2.4.3
MeshPy==2018.2.1
djangorestframework==3.13.1
django-filter==21.1
shapely==1.8.1.post1
pybind11==2.9.2
MeshPy==2020.1
# rtree==0.9.1
celery==4.3.0
requests==2.22.0
Pillow==6.2.1
qrcode==6.1
matplotlib==3.1.2
scipy==1.3.3
django_libsass==0.7
celery==5.2.3
requests==2.27.1
Pillow==9.1.0
qrcode==7.3.1
matplotlib==3.5.1
scipy==1.8.0
django_libsass==0.9

View file

@ -1,2 +1,2 @@
django-redis==4.10.0
redis==3.3.11
django-redis==5.2.0
redis==4.2.1

View file

@ -1,2 +1,2 @@
pgi==0.0.11.2
cairocffi==1.1.0
cairocffi==1.3.0

View file

@ -1 +1 @@
sentry-sdk==0.13.5
sentry-sdk==1.5.8