Update for Django 4.
authorRadek Czajka <rczajka@rczajka.pl>
Mon, 25 Jul 2022 10:05:52 +0000 (12:05 +0200)
committerRadek Czajka <rczajka@rczajka.pl>
Mon, 25 Jul 2022 10:05:52 +0000 (12:05 +0200)
29 files changed:
requirements/requirements.txt
src/apiclient/urls.py
src/cover/forms.py
src/cover/models.py
src/cover/urls.py
src/documents/forms.py
src/documents/models/book.py
src/documents/models/chunk.py
src/documents/models/image.py
src/documents/models/project.py
src/documents/models/publish_log.py
src/documents/templatetags/book_list.py
src/documents/templatetags/documents.py
src/documents/templatetags/wall.py
src/documents/urls.py
src/documents/views.py
src/dvcs/models.py
src/dvcs/signals.py
src/email_mangler/templatetags/email.py
src/redakcja/urls.py
src/toolbar/admin.py
src/toolbar/models.py
src/wiki/forms.py
src/wiki/models.py
src/wiki/urls.py
src/wiki/views.py
src/wiki_img/forms.py
src/wiki_img/urls.py
src/wiki_img/views.py

index 5341b62..2f146c9 100644 (file)
@@ -7,25 +7,25 @@ Pillow
 oauth2
 httplib2 # oauth2 dependency
 python-slugify
-python-docx==0.8.10
+python-docx==0.8.11
 Wikidata==0.6.1
 
-librarian==2.4.7
+librarian==2.4.8
 
 ## Django
-Django==3.2.14
-fnpdjango==0.5
-django-pipeline==2.0.7
+Django==4.0.6
+fnpdjango==0.6
+django-pipeline==2.0.8
 django-cas-ng==4.3.0
 sorl-thumbnail==12.8.0
-fnp-django-pagination==2.2.4
+fnp-django-pagination==2.2.5
 django-gravatar2==1.4.4
-django-extensions==3.1.3
-django-bootstrap4==3.0.1
+django-extensions==3.2.0
+django-bootstrap4==22.1
 libsasscompiler==0.1.9
-django-debug-toolbar==3.2.4
-django-admin-numeric-filter==0.1.6
+django-debug-toolbar==3.5.0
+django-admin-numeric-filter @ git+https://github.com/lukasvinclav/django-admin-numeric-filter.git@83853dfcc8d354c7aea8020a075bbd83dc8ca171
 djangorestframework==3.13.1
-django-filter==21.1
+django-filter==22.1
 
-sentry-sdk==0.12.2
+sentry-sdk==1.8.0
index 580a2c1..f061380 100644 (file)
@@ -1,13 +1,13 @@
 # This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
-from django.conf.urls import url
+from django.urls import path
 from . import views
 
 
 urlpatterns = [
-    url(r'^oauth/$', views.oauth, name='apiclient_oauth'),
-    url(r'^oauth_callback/$', views.oauth_callback, name='apiclient_oauth_callback'),
-    url(r'^oauth-beta/$', views.oauth, kwargs={'beta': True}, name='apiclient_beta_oauth'),
-    url(r'^oauth_callback-beta/$', views.oauth_callback, kwargs={'beta': True}, name='apiclient_beta_callback'),
+    path('oauth/', views.oauth, name='apiclient_oauth'),
+    path('oauth_callback/', views.oauth_callback, name='apiclient_oauth_callback'),
+    path('oauth-beta/', views.oauth, kwargs={'beta': True}, name='apiclient_beta_oauth'),
+    path('oauth_callback-beta/', views.oauth_callback, kwargs={'beta': True}, name='apiclient_beta_callback'),
 ]
index ee82a5a..7a85594 100644 (file)
@@ -5,7 +5,7 @@ from io import BytesIO
 
 from django import forms
 from django.conf import settings
-from django.utils.translation import ugettext_lazy as _, ugettext
+from django.utils.translation import gettext_lazy as _, gettext
 from cover.models import Image
 from django.utils.safestring import mark_safe
 from PIL import Image as PILImage
@@ -36,7 +36,7 @@ class ImageAddForm(forms.ModelForm):
                 pass
             else:
                 raise forms.ValidationError(mark_safe(
-                    ugettext('Image <a href="%(url)s">already in repository</a>.')
+                    gettext('Image <a href="%(url)s">already in repository</a>.')
                     % {'url': img.get_absolute_url()}))
         return cl
 
@@ -46,7 +46,7 @@ class ImageAddForm(forms.ModelForm):
             same_source = Image.objects.filter(source_url=source_url)
             if same_source:
                 raise forms.ValidationError(mark_safe(
-                    ugettext('Image <a href="%(url)s">already in repository</a>.')
+                    gettext('Image <a href="%(url)s">already in repository</a>.')
                     % {'url': same_source.first().get_absolute_url()}))
         return source_url
 
@@ -60,7 +60,7 @@ class ImageAddForm(forms.ModelForm):
         download_url = cleaned_data.get('download_url', None)
         uploaded_file = cleaned_data.get('file', None)
         if not download_url and not uploaded_file:
-            raise forms.ValidationError(ugettext('No image specified'))
+            raise forms.ValidationError(gettext('No image specified'))
         if download_url:
             image_data = URLOpener().open(download_url).read()
             width, height = PILImage.open(BytesIO(image_data)).size
@@ -68,7 +68,7 @@ class ImageAddForm(forms.ModelForm):
             width, height = PILImage.open(uploaded_file.file).size
         min_width, min_height = settings.MIN_COVER_SIZE
         if width < min_width or height < min_height:
-            raise forms.ValidationError(ugettext('Image too small: %sx%s, minimal dimensions %sx%s') %
+            raise forms.ValidationError(gettext('Image too small: %sx%s, minimal dimensions %sx%s') %
                                         (width, height, min_width, min_height))
         return cleaned_data
 
@@ -85,7 +85,7 @@ class ImageEditForm(forms.ModelForm):
         width, height = PILImage.open(uploaded_file.file).size
         min_width, min_height = settings.MIN_COVER_SIZE
         if width < min_width or height < min_height:
-            raise forms.ValidationError(ugettext('Image too small: %sx%s, minimal dimensions %sx%s') %
+            raise forms.ValidationError(gettext('Image too small: %sx%s, minimal dimensions %sx%s') %
                                         (width, height, min_width, min_height))
 
 
index 33c5e73..04c2a6b 100644 (file)
@@ -8,7 +8,7 @@ from django.db import models
 from django.db.models.signals import post_save
 from django.dispatch import receiver
 from django.urls import reverse
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
 from django.contrib.sites.models import Site
 from PIL import Image as PILImage
 from cover.utils import URLOpener
index 8278835..20cd7d6 100644 (file)
@@ -1,22 +1,21 @@
 # This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
-from django.conf.urls import url
 from django.urls import path
 from . import views
 
 
 urlpatterns = [
-    url(r'^preview/$', views.preview_from_xml, name='cover_preview'),
-    url(r'^preview/(?P<book>[^/]+)/$', views.preview, name='cover_preview'),
-    url(r'^preview/(?P<book>[^/]+)/(?P<chunk>[^/]+)/$',
+    path('preview/', views.preview_from_xml, name='cover_preview'),
+    path('preview/<slug:book>/', views.preview, name='cover_preview'),
+    path('preview/<slug:book>/<slug:chunk>/',
             views.preview, name='cover_preview'),
-    url(r'^preview/(?P<book>[^/]+)/(?P<chunk>[^/]+)/(?P<rev>\d+)/$',
+    path('preview/<slug:book>/<slug:chunk>/<int:rev>/',
             views.preview, name='cover_preview'),
 
-    url(r'^image/$', views.image_list, name='cover_image_list'),
-    url(r'^image/(?P<pk>\d+)/?$', views.image, name='cover_image'),
-    url(r'^image/(?P<pk>\d+)/file/', views.image_file, name='cover_file'),
-    url(r'^add_image/$', views.add_image, name='cover_add_image'),
+    path('image/', views.image_list, name='cover_image_list'),
+    path('image/<int:pk>/', views.image, name='cover_image'),
+    path('image/<int:pk>/file/', views.image_file, name='cover_file'),
+    path('add_image/', views.add_image, name='cover_add_image'),
     path('quick-import/<int:pk>/', views.quick_import, name='cover_quick_import'),
 ]
index 418ae4a..6598e75 100644 (file)
@@ -3,7 +3,7 @@
 #
 from django.db.models import Count
 from django import forms
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
 from django.conf import settings
 from slugify import slugify
 from .constants import MASTERS
index 1580f74..23d3344 100644 (file)
@@ -6,7 +6,7 @@ from django.contrib.sites.models import Site
 from django.db import connection, models, transaction
 from django.template.loader import render_to_string
 from django.urls import reverse
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
 from django.conf import settings
 from slugify import slugify
 
index 2698b58..4d8f6d2 100644 (file)
@@ -6,7 +6,7 @@ from django.db import models
 from django.db.utils import IntegrityError
 from django.template.loader import render_to_string
 from django.urls import reverse
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
 from documents.helpers import cached_in_field
 from documents.managers import VisibleManager
 from dvcs import models as dvcs_models
index b05c928..fd3d8c4 100644 (file)
@@ -6,7 +6,7 @@ from django.contrib.sites.models import Site
 from django.db import models
 from django.template.loader import render_to_string
 from django.urls import reverse
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
 from documents.helpers import cached_in_field
 from documents.models import Project
 from dvcs import models as dvcs_models
index f0ac752..cc78ba5 100644 (file)
@@ -2,7 +2,7 @@
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 from django.db import models
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
 
 
 class Project(models.Model):
index 5322bb6..2073a95 100644 (file)
@@ -3,7 +3,7 @@
 #
 from django.contrib.auth.models import User
 from django.db import models
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
 from documents.models import Chunk, Image
 
 
index 88120d2..2261f5d 100644 (file)
@@ -4,7 +4,7 @@
 import re
 from django.db.models import Q, Count, F, Max
 from django import template
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
 from django.contrib.auth.models import User
 from documents.models import Book, Chunk, Image, Project
 
index 5c3b1eb..b0a34bc 100644 (file)
@@ -3,7 +3,7 @@
 #
 from django.urls import reverse
 from django import template
-from django.utils.translation import ugettext as _
+from django.utils.translation import gettext as _
 
 register = template.Library()
 
index 4a6795b..486a2d6 100644 (file)
@@ -5,7 +5,7 @@ from datetime import timedelta
 from django.db.models import Q
 from django.urls import reverse
 from django import template
-from django.utils.translation import ugettext as _
+from django.utils.translation import gettext as _
 
 from documents.models import Chunk, BookPublishRecord, Image, ImagePublishRecord
 
index 602d4f2..1a1f185 100644 (file)
@@ -1,7 +1,7 @@
 # This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
-from django.conf.urls import url
+from django.urls import path, re_path
 from django.contrib.auth.decorators import permission_required
 from django.views.generic import RedirectView
 from .feeds import PublishTrackFeed
@@ -9,58 +9,56 @@ from . import views
 
 
 urlpatterns = [
-    url(r'^$', RedirectView.as_view(url='catalogue/', permanent=False)),
+    path('', RedirectView.as_view(url='catalogue/', permanent=False)),
 
-    url(r'^images/$', views.image_list, name='documents_image_list'),
-    url(r'^image/(?P<slug>[^/]+)/$', views.image, name="documents_image"),
-    url(r'^image/(?P<slug>[^/]+)/publish$', views.publish_image,
+    path('images/', views.image_list, name='documents_image_list'),
+    path('image/<slug:slug>/', views.image, name="documents_image"),
+    path('image/<slug:slug>/publish', views.publish_image,
             name="documents_publish_image"),
 
-    url(r'^catalogue/$', views.document_list, name='documents_document_list'),
-    url(r'^user/$', views.my, name='documents_user'),
-    url(r'^user/(?P<username>[^/]+)/$', views.user, name='documents_user'),
-    url(r'^users/$', views.users, name='documents_users'),
-    url(r'^activity/$', views.activity, name='documents_activity'),
-    url(r'^activity/(?P<isodate>\d{4}-\d{2}-\d{2})/$', 
+    path('catalogue/', views.document_list, name='documents_document_list'),
+    path('user/', views.my, name='documents_user'),
+    path('user/<username>/', views.user, name='documents_user'),
+    path('users/', views.users, name='documents_users'),
+    path('activity/', views.activity, name='documents_activity'),
+    re_path(r'^activity/(?P<isodate>\d{4}-\d{2}-\d{2})/$', 
         views.activity, name='documents_activity'),
 
-    url(r'^upload/$',
-        views.upload, name='documents_upload'),
+    path('upload/', views.upload, name='documents_upload'),
 
-    url(r'^create/(?P<slug>[^/]*)/',
-        views.create_missing, name='documents_create_missing'),
-    url(r'^create/',
+    path('create/<slug:slug>/',
         views.create_missing, name='documents_create_missing'),
+    path('create/', views.create_missing, name='documents_create_missing'),
 
-    url(r'^book/(?P<slug>[^/]+)/publish$', views.publish, name="documents_publish"),
+    path('book/<slug:slug>/publish', views.publish, name="documents_publish"),
 
-    url(r'^book/(?P<slug>[^/]+)/$', views.book, name="documents_book"),
-    url(r'^book/(?P<slug>[^/]+)/gallery/$',
+    path('book/<slug:slug>/', views.book, name="documents_book"),
+    path('book/<slug:slug>/gallery/',
             permission_required('documents.change_book')(views.GalleryView.as_view()),
             name="documents_book_gallery"),
-    url(r'^book/(?P<slug>[^/]+)/xml$', views.book_xml, name="documents_book_xml"),
-    url(r'^book/dc/(?P<slug>[^/]+)/xml$', views.book_xml_dc, name="documents_book_xml_dc"),
-    url(r'^book/(?P<slug>[^/]+)/txt$', views.book_txt, name="documents_book_txt"),
-    url(r'^book/(?P<slug>[^/]+)/html$', views.book_html, name="documents_book_html"),
-    url(r'^book/(?P<slug>[^/]+)/epub$', views.book_epub, name="documents_book_epub"),
-    url(r'^book/(?P<slug>[^/]+)/mobi$', views.book_mobi, name="documents_book_mobi"),
-    url(r'^book/(?P<slug>[^/]+)/pdf$', views.book_pdf, name="documents_book_pdf"),
-    url(r'^book/(?P<slug>[^/]+)/pdf-mobile$', views.book_pdf, kwargs={'mobile': True}, name="documents_book_pdf_mobile"),
+    path('book/<slug:slug>/xml', views.book_xml, name="documents_book_xml"),
+    path('book/dc/<slug:slug>/xml', views.book_xml_dc, name="documents_book_xml_dc"),
+    path('book/<slug:slug>/txt', views.book_txt, name="documents_book_txt"),
+    path('book/<slug:slug>/html', views.book_html, name="documents_book_html"),
+    path('book/<slug:slug>/epub', views.book_epub, name="documents_book_epub"),
+    path('book/<slug:slug>/mobi', views.book_mobi, name="documents_book_mobi"),
+    path('book/<slug:slug>/pdf', views.book_pdf, name="documents_book_pdf"),
+    path('book/<slug:slug>/pdf-mobile', views.book_pdf, kwargs={'mobile': True}, name="documents_book_pdf_mobile"),
 
-    url(r'^chunk_add/(?P<slug>[^/]+)/(?P<chunk>[^/]+)/$',
+    path('chunk_add/<slug:slug>/<slug:chunk>/',
         views.chunk_add, name="documents_chunk_add"),
-    url(r'^chunk_edit/(?P<slug>[^/]+)/(?P<chunk>[^/]+)/$',
+    path('chunk_edit/<slug:slug>/<slug:chunk>/',
         views.chunk_edit, name="documents_chunk_edit"),
-    url(r'^book_append/(?P<slug>[^/]+)/$',
+    path('book_append/<slug:slug>/',
         views.book_append, name="documents_book_append"),
-    url(r'^chunk_mass_edit',
+    path('chunk_mass_edit',
         views.chunk_mass_edit, name='documents_chunk_mass_edit'),
-    url(r'^image_mass_edit',
+    path('image_mass_edit',
         views.image_mass_edit, name='documents_image_mass_edit'),
 
-    url(r'^track/(?P<slug>[^/]*)/$', PublishTrackFeed()),
-    url(r'^active/$', views.active_users_list, name='active_users_list'),
+    path('track/<slug:slug>/', PublishTrackFeed()),
+    path('active/', views.active_users_list, name='active_users_list'),
 
-    url(r'^mark-final/$', views.mark_final, name='mark_final'),
-    url(r'^mark-final-completed/$', views.mark_final_completed, name='mark_final_completed'),
+    path('mark-final/', views.mark_final, name='mark_final'),
+    path('mark-final-completed/', views.mark_final_completed, name='mark_final_completed'),
 ]
index 38e69c1..6c9f29e 100644 (file)
@@ -5,7 +5,7 @@ from collections import defaultdict
 from datetime import datetime, date, timedelta
 import logging
 import os
-from urllib.parse import unquote, urlsplit, urlunsplit
+from urllib.parse import quote_plus, unquote, urlsplit, urlunsplit
 
 from django.conf import settings
 from django.contrib import auth
@@ -19,8 +19,7 @@ from django.http import Http404, HttpResponse, HttpResponseForbidden
 from django.http.response import HttpResponseRedirect
 from django.shortcuts import get_object_or_404, render
 from django.utils.encoding import iri_to_uri
-from django.utils.http import urlquote_plus
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
 from django.views.decorators.http import require_POST
 from django_cas_ng.decorators import user_passes_test
 
index 978f072..5d465ca 100644 (file)
@@ -11,7 +11,7 @@ from django.core.files.storage import FileSystemStorage
 from django.db import models, transaction
 from django.db.models.base import ModelBase
 from django.utils.text import format_lazy
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
 import merge3
 
 from django.conf import settings
index 14f37f4..d129cf9 100644 (file)
@@ -4,4 +4,4 @@
 from django.dispatch import Signal
 
 post_commit = Signal()
-post_publishable = Signal(providing_args=['publishable'])
+post_publishable = Signal()
index dbf2939..c0503ec 100644 (file)
@@ -4,7 +4,7 @@
 import codecs
 from django.utils.html import escape
 from django.utils.safestring import mark_safe
-from django.utils.translation import ugettext as _
+from django.utils.translation import gettext as _
 from django import template
 
 register = template.Library()
index 2f36af1..e407885 100644 (file)
@@ -1,7 +1,6 @@
 # This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
-from django.conf.urls import url
 from django.urls import include, path
 from django.contrib import admin
 from django.conf import settings
@@ -17,17 +16,17 @@ urlpatterns = [
     #url(r'^admin/logout/$', django_cas_ng.views.logout, name='logout'),
 
     # Admin panel
-    url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
-    url(r'^admin/', admin.site.urls),
+    path('admin/doc/', include('django.contrib.admindocs.urls')),
+    path('admin/', admin.site.urls),
     path('catalogue/', include('catalogue.urls')),
-    url(r'^$', RedirectView.as_view(url='/documents/', permanent=False)),
-    url(r'^documents/', include('documents.urls')),
-    url(r'^apiclient/', include('apiclient.urls')),
-    url(r'^editor/', include('wiki.urls')),
-    url(r'^images/', include('wiki_img.urls')),
-    url(r'^cover/', include('cover.urls')),
-    url(r'^depot/', include('depot.urls')),
-    url(r'^wlxml/', include('wlxml.urls')),
+    path('', RedirectView.as_view(url='/documents/', permanent=False)),
+    path('documents/', include('documents.urls')),
+    path('apiclient/', include('apiclient.urls')),
+    path('editor/', include('wiki.urls')),
+    path('images/', include('wiki_img.urls')),
+    path('cover/', include('cover.urls')),
+    path('depot/', include('depot.urls')),
+    path('wlxml/', include('wlxml.urls')),
 
     path('api/', include('redakcja.api.urls')),
 ]
@@ -35,14 +34,14 @@ urlpatterns = [
 
 if settings.CAS_SERVER_URL:
     urlpatterns += [
-        url(r'^accounts/login/$', django_cas_ng.views.LoginView.as_view(), name='cas_ng_login'),
-        url(r'^accounts/logout/$', django_cas_ng.views.LogoutView.as_view(), name='logout'),
+        path('accounts/login/', django_cas_ng.views.LoginView.as_view(), name='cas_ng_login'),
+        path('accounts/logout/', django_cas_ng.views.LogoutView.as_view(), name='logout'),
     ]
 else:
     import django.contrib.auth.views
     urlpatterns += [
-        url(r'^accounts/login/$', django.contrib.auth.views.LoginView.as_view(), name='cas_ng_login'),
-        url(r'^accounts/', include('django.contrib.auth.urls')),
+        path('accounts/login/', django.contrib.auth.views.LoginView.as_view(), name='cas_ng_login'),
+        path('accounts/', include('django.contrib.auth.urls')),
     ]
 
 
@@ -51,4 +50,4 @@ if settings.DEBUG:
     urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
 
     import debug_toolbar
-    urlpatterns += [url(r'^__debug__/', include(debug_toolbar.urls))]
+    urlpatterns += [path('__debug__/', include(debug_toolbar.urls))]
index 1fa695b..cb6de45 100644 (file)
@@ -2,7 +2,7 @@
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 from django.contrib import admin
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
 from django import forms
 import json
 
index 02567fa..a221e04 100644 (file)
@@ -2,7 +2,7 @@
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 from django.db import models
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
 
 
 class ButtonGroup(models.Model):
index 084ae46..4619467 100644 (file)
@@ -2,7 +2,7 @@
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 from django import forms
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
 
 from documents.models import Chunk
 
index 456e219..b3cb9d8 100644 (file)
@@ -2,7 +2,7 @@
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 from django.db import models
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
 
 import logging
 logger = logging.getLogger("fnp.wiki")
index f1a4508..f2fa3f5 100644 (file)
@@ -1,37 +1,27 @@
 # This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
-from django.conf.urls import url
+from django.urls import path
 from . import views
 
 
 urlpatterns = [
-    url(r'^edit/(?P<slug>[^/]+)/(?:(?P<chunk>[^/]+)/)?$',
-        views.editor, name="wiki_editor"),
-
-    url(r'^readonly/(?P<slug>[^/]+)/(?:(?P<chunk>[^/]+)/)?$',
-        views.editor_readonly, name="wiki_editor_readonly"),
-
-    url(r'^gallery/(?P<directory>[^/]+)/$',
-        views.gallery, name="wiki_gallery"),
-
-    url(r'^history/(?P<chunk_id>\d+)/$',
-        views.history, name="wiki_history"),
-
-    url(r'^rev/(?P<chunk_id>\d+)/$',
-        views.revision, name="wiki_revision"),
-
-    url(r'^text/(?P<chunk_id>\d+)/$',
-        views.text, name="wiki_text"),
-
-    url(r'^revert/(?P<chunk_id>\d+)/$',
-        views.revert, name='wiki_revert'),
-
-    url(r'^diff/(?P<chunk_id>\d+)/$', views.diff, name="wiki_diff"),
-    url(r'^pubmark/(?P<chunk_id>\d+)/$', views.pubmark, name="wiki_pubmark"),
-
-    url(r'^themes$', views.themes, name="themes"),
-
-    url(r'^back/$', views.back),
-    url(r'^editor-user-area/$', views.editor_user_area),
+    path('edit/<slug:slug>/<slug:chunk>/', views.editor, name="wiki_editor"),
+    path('edit/<slug:slug>/', views.editor, name="wiki_editor"),
+
+    path('readonly/<slug:slug>/<slug:chunk>/',
+         views.editor_readonly, name="wiki_editor_readonly"),
+    path('readonly/<slug:slug>/',
+         views.editor_readonly, name="wiki_editor_readonly"),
+
+    path('gallery/<directory>/', views.gallery, name="wiki_gallery"),
+    path('history/<int:chunk_id>/', views.history, name="wiki_history"),
+    path('rev/<int:chunk_id>/', views.revision, name="wiki_revision"),
+    path('text/<int:chunk_id>/', views.text, name="wiki_text"),
+    path('revert/<int:chunk_id>/', views.revert, name='wiki_revert'),
+    path('diff/<int:chunk_id>/', views.diff, name="wiki_diff"),
+    path('pubmark/<int:chunk_id>/', views.pubmark, name="wiki_pubmark"),
+    path('themes', views.themes, name="themes"),
+    path('back/', views.back),
+    path('editor-user-area/', views.editor_user_area),
 ]
index 7bcea51..cf67abb 100644 (file)
@@ -14,7 +14,7 @@ from django.http import Http404, HttpResponseForbidden
 from django.middleware.gzip import GZipMiddleware
 from django.utils.decorators import decorator_from_middleware
 from django.utils.formats import localize
-from django.utils.translation import ugettext as _
+from django.utils.translation import gettext as _
 from django.views.decorators.http import require_POST, require_GET
 from django.shortcuts import get_object_or_404, render
 
index 43b1a25..49d7845 100644 (file)
@@ -2,7 +2,7 @@
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 from django import forms
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
 from wiki.forms import DocumentTextSaveForm
 from documents.models import Image
 
index 8224484..0c9e848 100644 (file)
@@ -1,26 +1,26 @@
 # This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
-from django.conf.urls import url
+from django.urls import path
 from . import views
 
 
 urlpatterns = [
-    url(r'^edit/(?P<slug>[^/]+)/$',
+    path('edit/<slug:slug>/',
         views.editor, name="wiki_img_editor"),
 
-    url(r'^readonly/(?P<slug>[^/]+)/$',
+    path('readonly/<slug:slug>/',
         views.editor_readonly, name="wiki_img_editor_readonly"),
 
-    url(r'^text/(?P<image_id>\d+)/$',
+    path('text/<int:image_id>/',
         views.text, name="wiki_img_text"),
 
-    url(r'^history/(?P<object_id>\d+)/$',
+    path('history/<int:object_id>/',
         views.history, name="wiki_img_history"),
 
-    url(r'^revert/(?P<object_id>\d+)/$',
+    path('revert/<int:object_id>/',
         views.revert, name='wiki_img_revert'),
 
-    url(r'^diff/(?P<object_id>\d+)/$', views.diff, name="wiki_img_diff"),
-    url(r'^pubmark/(?P<object_id>\d+)/$', views.pubmark, name="wiki_img_pubmark"),
+    path('diff/<int:object_id>/', views.diff, name="wiki_img_diff"),
+    path('pubmark/<int:object_id>/', views.pubmark, name="wiki_img_pubmark"),
 ]
index 7fc5c70..a313528 100644 (file)
@@ -15,7 +15,7 @@ from django.shortcuts import get_object_or_404, render
 from django.views.decorators.http import require_GET, require_POST
 from django.conf import settings
 from django.utils.formats import localize
-from django.utils.translation import ugettext as _
+from django.utils.translation import gettext as _
 
 from documents.models import Image
 from wiki import forms