Cleaning.
authorRadek Czajka <rczajka@rczajka.pl>
Mon, 16 Dec 2019 23:13:51 +0000 (00:13 +0100)
committerRadek Czajka <rczajka@rczajka.pl>
Mon, 16 Dec 2019 23:13:51 +0000 (00:13 +0100)
54 files changed:
requirements/requirements.txt
src/ajaxable/templatetags/ajaxable_tags.py
src/ajaxable/utils.py
src/annoy/admin.py
src/annoy/models.py
src/annoy/tests.py [deleted file]
src/annoy/translation.py
src/annoy/views.py [deleted file]
src/api/fields.py
src/api/models.py
src/api/renderers.py
src/api/serializers.py
src/api/tests/tests.py
src/api/urls.py
src/api/views.py
src/basicauth.py
src/catalogue/__init__.py
src/catalogue/admin.py
src/catalogue/api/fields.py
src/catalogue/api/helpers.py
src/catalogue/api/urls.py
src/catalogue/api/views.py
src/catalogue/fields.py
src/catalogue/test_utils.py
src/catalogue/tests/test_book_import.py
src/catalogue/tests/test_tags.py
src/catalogue/urls.py
src/catalogue/views.py
src/club/urls.py
src/dictionary/urls.py
src/funding/urls.py
src/infopages/urls.py
src/isbn/urls.py
src/lesmianator/urls.py
src/libraries/urls.py
src/newsletter/admin.py
src/newsletter/urls.py
src/oai/urls.py
src/opds/urls.py
src/paypal/urls.py
src/picture/api/urls.py
src/polls/urls.py
src/push/urls.py
src/reporting/urls.py
src/search/urls.py
src/social/api/urls.py
src/social/urls.py
src/suggest/urls.py
src/waiter/urls.py
src/wolnelektury/templates/base/app.html
src/wolnelektury/templates/base/superbase.html
src/wolnelektury/templates/main_page.html
src/wolnelektury/templates/widget.html
src/wolnelektury/urls.py

index b0c3c8e..f217cca 100644 (file)
@@ -1,7 +1,7 @@
 -i https://py.mdrn.pl/simple/
 
 # django
 -i https://py.mdrn.pl/simple/
 
 # django
-Django==2.2.6
+Django==2.2.8
 fnpdjango==0.4
 docutils
 
 fnpdjango==0.4
 docutils
 
index 9406481..2d980f2 100644 (file)
@@ -4,8 +4,9 @@
 from django import template
 from django.utils.encoding import force_text
 from django.utils.safestring import mark_safe
 from django import template
 from django.utils.encoding import force_text
 from django.utils.safestring import mark_safe
-
 from ajaxable.utils import placeholdized
 from ajaxable.utils import placeholdized
+
+
 register = template.Library()
 
 
 register = template.Library()
 
 
index 164feac..f8e99ce 100755 (executable)
@@ -2,23 +2,23 @@
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 from functools import wraps
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 from functools import wraps
+import json
 
 from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden
 from django.shortcuts import render
 from django.utils.encoding import force_text
 from django.utils.functional import Promise
 from django.utils.http import urlquote_plus
 
 from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden
 from django.shortcuts import render
 from django.utils.encoding import force_text
 from django.utils.functional import Promise
 from django.utils.http import urlquote_plus
-import json
 from django.utils.translation import ugettext_lazy as _
 from django.views.decorators.vary import vary_on_headers
 from honeypot.decorators import verify_honeypot_value
 
 
 class LazyEncoder(json.JSONEncoder):
 from django.utils.translation import ugettext_lazy as _
 from django.views.decorators.vary import vary_on_headers
 from honeypot.decorators import verify_honeypot_value
 
 
 class LazyEncoder(json.JSONEncoder):
-    def default(self, obj):
-        if isinstance(obj, Promise):
-            return force_text(obj)
-        return obj
+    def default(self, o):
+        if isinstance(o, Promise):
+            return force_text(o)
+        return o
 
 
 def method_decorator(function_decorator):
 
 
 def method_decorator(function_decorator):
@@ -40,8 +40,7 @@ def require_login(request):
     """Return 403 if request is AJAX. Redirect to login page if not."""
     if request.is_ajax():
         return HttpResponseForbidden('Not logged in')
     """Return 403 if request is AJAX. Redirect to login page if not."""
     if request.is_ajax():
         return HttpResponseForbidden('Not logged in')
-    else:
-        return HttpResponseRedirect('/uzytkownicy/zaloguj')  # next?=request.build_full_path())
+    return HttpResponseRedirect('/uzytkownicy/zaloguj')  # next?=request.build_full_path())
 
 
 def placeholdized(form):
 
 
 def placeholdized(form):
@@ -50,7 +49,7 @@ def placeholdized(form):
     return form
 
 
     return form
 
 
-class AjaxableFormView(object):
+class AjaxableFormView:
     """Subclass this to create an ajaxable view for any form.
 
     In the subclass, provide at least form_class.
     """Subclass this to create an ajaxable view for any form.
 
     In the subclass, provide at least form_class.
@@ -107,7 +106,7 @@ class AjaxableFormView(object):
                     response_data.update(add_args)
                 if not request.is_ajax() and response_data['redirect']:
                     return HttpResponseRedirect(urlquote_plus(
                     response_data.update(add_args)
                 if not request.is_ajax() and response_data['redirect']:
                     return HttpResponseRedirect(urlquote_plus(
-                            response_data['redirect'], safe='/?=&'))
+                        response_data['redirect'], safe='/?=&'))
             elif request.is_ajax():
                 # Form was sent with errors. Send them back.
                 if self.form_prefix:
             elif request.is_ajax():
                 # Form was sent with errors. Send them back.
                 if self.form_prefix:
@@ -139,17 +138,17 @@ class AjaxableFormView(object):
         if self.placeholdize:
             form = placeholdized(form)
         context = {
         if self.placeholdize:
             form = placeholdized(form)
         context = {
-                self.formname: form,
-                "title": title,
-                "honeypot": self.honeypot,
-                "placeholdize": self.placeholdize,
-                "submit": self.submit,
-                "action": self.action,
-                "response_data": response_data,
-                "ajax_template": self.template,
-                "view_args": args,
-                "view_kwargs": kwargs,
-            }
+            self.formname: form,
+            "title": title,
+            "honeypot": self.honeypot,
+            "placeholdize": self.placeholdize,
+            "submit": self.submit,
+            "action": self.action,
+            "response_data": response_data,
+            "ajax_template": self.template,
+            "view_args": args,
+            "view_kwargs": kwargs,
+        }
         context.update(self.extra_context(request, obj))
         return render(request, template, context)
 
         context.update(self.extra_context(request, obj))
         return render(request, template, context)
 
@@ -163,8 +162,7 @@ class AjaxableFormView(object):
             if message:
                 output = "<div class='normal-text'>" + message + "</div>" + output
             return HttpResponse(output)
             if message:
                 output = "<div class='normal-text'>" + message + "</div>" + output
             return HttpResponse(output)
-        else:
-            return HttpResponseRedirect(path)
+        return HttpResponseRedirect(path)
 
     def get_object(self, request, *args, **kwargs):
         """Override to parse view args and get some associated data."""
 
     def get_object(self, request, *args, **kwargs):
         """Override to parse view args and get some associated data."""
index 3f2bd3d..24e977e 100644 (file)
@@ -7,7 +7,7 @@ from . import models
 class BannerAdmin(TranslationAdmin):
     list_display = ['place', 'text', 'priority', 'since', 'until', 'show_members', 'staff_preview']
 
 class BannerAdmin(TranslationAdmin):
     list_display = ['place', 'text', 'priority', 'since', 'until', 'show_members', 'staff_preview']
 
-    
+
 admin.site.register(models.Banner, BannerAdmin)
 
 
 admin.site.register(models.Banner, BannerAdmin)
 
 
@@ -27,7 +27,7 @@ class DynamicTextInsertTextInline(admin.TabularInline):
     fields = ['text', 'image', 'own_colors', 'background_color', 'text_color']
     extra = 0
     min_num = 1
     fields = ['text', 'image', 'own_colors', 'background_color', 'text_color']
     extra = 0
     min_num = 1
-    
+
 
 
 class DynamicTextInsertAdmin(admin.ModelAdmin):
 
 
 class DynamicTextInsertAdmin(admin.ModelAdmin):
index 5b9009b..9ed724c 100644 (file)
@@ -40,9 +40,9 @@ class Banner(models.Model):
 
         if hasattr(request, 'annoy_banner_exempt'):
             return cls.objects.none()
 
         if hasattr(request, 'annoy_banner_exempt'):
             return cls.objects.none()
-        
+
         if settings.DEBUG:
         if settings.DEBUG:
-            assert place in PLACES, "Banner place `{}` must be defined in annoy.places.".format(place)
+            assert place in PLACES, f"Banner place `{place}` must be defined in annoy.places."
 
         n = now()
         banners = cls.objects.filter(
 
         n = now()
         banners = cls.objects.filter(
@@ -60,8 +60,8 @@ class Banner(models.Model):
             if Membership.is_active_for(request.user):
                 banners = banners.filter(show_members=True)
         return banners
             if Membership.is_active_for(request.user):
                 banners = banners.filter(show_members=True)
         return banners
-        
-        
+
+
 class DynamicTextInsert(models.Model):
     paragraphs = models.IntegerField(_('pararaphs'))
     url = models.CharField(max_length=1024)
 class DynamicTextInsert(models.Model):
     paragraphs = models.IntegerField(_('pararaphs'))
     url = models.CharField(max_length=1024)
diff --git a/src/annoy/tests.py b/src/annoy/tests.py
deleted file mode 100644 (file)
index 7ce503c..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-from django.test import TestCase
-
-# Create your tests here.
index eb17ada..2d8055a 100644 (file)
@@ -9,7 +9,4 @@ class BannerTranslationOptions(TranslationOptions):
     fields = ('text',)
 
 
     fields = ('text',)
 
 
-
 translator.register(models.Banner, BannerTranslationOptions)
 translator.register(models.Banner, BannerTranslationOptions)
-
-
diff --git a/src/annoy/views.py b/src/annoy/views.py
deleted file mode 100644 (file)
index 91ea44a..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-from django.shortcuts import render
-
-# Create your views here.
index b6269da..d1f9da4 100644 (file)
@@ -17,7 +17,7 @@ class AbsoluteURLField(serializers.ReadOnlyField):
         if view_args:
             for v in view_args:
                 fields = v.split(':', 1)
         if view_args:
             for v in view_args:
                 fields = v.split(':', 1)
-                self.view_args[fields[0]] = fields[1] if len(fields)>1 else fields[0]
+                self.view_args[fields[0]] = fields[1] if len(fields) > 1 else fields[0]
 
     def to_representation(self, value):
         if self.view_name is not None:
 
     def to_representation(self, value):
         if self.view_name is not None:
@@ -29,7 +29,7 @@ class AbsoluteURLField(serializers.ReadOnlyField):
         return self.context['request'].build_absolute_uri(value)
 
 
         return self.context['request'].build_absolute_uri(value)
 
 
-class LegacyMixin(object):
+class LegacyMixin:
     def to_representation(self, value):
         value = super(LegacyMixin, self).to_representation(value)
         non_null_fields = getattr(getattr(self, 'Meta', None), 'legacy_non_null_fields', [])
     def to_representation(self, value):
         value = super(LegacyMixin, self).to_representation(value)
         non_null_fields = getattr(getattr(self, 'Meta', None), 'legacy_non_null_fields', [])
index e72aaff..28bc880 100644 (file)
@@ -30,14 +30,17 @@ def _pre_delete_handler(sender, instance, **kwargs):
         if sender == Tag:
             if instance.category in ('book', 'set'):
                 return
         if sender == Tag:
             if instance.category in ('book', 'set'):
                 return
-            else:
-                category = instance.category
+            category = instance.category
         else:
             category = None
         content_type = ContentType.objects.get_for_model(sender)
         Deleted.objects.create(
         else:
             category = None
         content_type = ContentType.objects.get_for_model(sender)
         Deleted.objects.create(
-            content_type=content_type, object_id=instance.id, created_at=instance.created_at, category=category,
-            slug=instance.slug)
+            content_type=content_type,
+            object_id=instance.id,
+            created_at=instance.created_at,
+            category=category,
+            slug=instance.slug
+        )
 pre_delete.connect(_pre_delete_handler)
 
 
 pre_delete.connect(_pre_delete_handler)
 
 
@@ -57,7 +60,6 @@ class BookUserData(models.Model):
         instance.complete = state == 'complete'
         instance.save()
         return instance
         instance.complete = state == 'complete'
         instance.save()
         return instance
-from django.conf import settings
 
 
 KEY_SIZE = 18
 
 
 KEY_SIZE = 18
@@ -85,7 +87,10 @@ class Consumer(models.Model):
     key = models.CharField(max_length=KEY_SIZE)
     secret = models.CharField(max_length=SECRET_SIZE)
     status = models.CharField(max_length=16, choices=CONSUMER_STATES, default='pending')
     key = models.CharField(max_length=KEY_SIZE)
     secret = models.CharField(max_length=SECRET_SIZE)
     status = models.CharField(max_length=16, choices=CONSUMER_STATES, default='pending')
-    user = models.ForeignKey(settings.AUTH_USER_MODEL, models.CASCADE, null=True, blank=True, related_name='consumers')
+    user = models.ForeignKey(
+        settings.AUTH_USER_MODEL, models.CASCADE,
+        null=True, blank=True, related_name='consumers'
+    )
 
     def __str__(self):
         return "Consumer %s with key %s" % (self.name, self.key)
 
     def __str__(self):
         return "Consumer %s with key %s" % (self.name, self.key)
@@ -101,7 +106,10 @@ class Token(models.Model):
     token_type = models.IntegerField(choices=TOKEN_TYPES)
     timestamp = models.IntegerField()
     is_approved = models.BooleanField(default=False)
     token_type = models.IntegerField(choices=TOKEN_TYPES)
     timestamp = models.IntegerField()
     is_approved = models.BooleanField(default=False)
-    user = models.ForeignKey(settings.AUTH_USER_MODEL, models.CASCADE, null=True, blank=True, related_name='tokens')
+    user = models.ForeignKey(
+        settings.AUTH_USER_MODEL, models.CASCADE,
+        null=True, blank=True, related_name='tokens'
+    )
     consumer = models.ForeignKey(Consumer, models.CASCADE)
 
     def __str__(self):
     consumer = models.ForeignKey(Consumer, models.CASCADE)
 
     def __str__(self):
index 57edec3..3f742db 100644 (file)
@@ -11,4 +11,3 @@ class LegacyXMLRenderer(XMLRenderer):
 
     item_tag_name = 'resource'
     root_tag_name = 'response'
 
     item_tag_name = 'resource'
     root_tag_name = 'response'
-
index 237a155..eb6994c 100644 (file)
@@ -3,7 +3,7 @@
 #
 from django.contrib.auth.models import User
 from rest_framework import serializers
 #
 from django.contrib.auth.models import User
 from rest_framework import serializers
-from .fields import UserPremiumField, AbsoluteURLField, ThumbnailField
+from .fields import UserPremiumField
 from .models import BookUserData
 
 
 from .models import BookUserData
 
 
index e17db29..f85a061 100644 (file)
@@ -2,25 +2,25 @@
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 from base64 import b64encode
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 from base64 import b64encode
-from os import path
 import hashlib
 import hmac
 import hashlib
 import hmac
-import json
 from io import BytesIO
 from io import BytesIO
+import json
+from os import path
 from time import time
 from time import time
+from unittest.mock import patch
 from urllib.parse import quote, urlencode, parse_qs
 
 from django.contrib.auth.models import User
 from django.core.files.uploadedfile import SimpleUploadedFile
 from django.test import TestCase
 from django.test.utils import override_settings
 from urllib.parse import quote, urlencode, parse_qs
 
 from django.contrib.auth.models import User
 from django.core.files.uploadedfile import SimpleUploadedFile
 from django.test import TestCase
 from django.test.utils import override_settings
-from unittest.mock import patch
-from api.models import Consumer, Token
 
 from catalogue.models import Book, Tag
 from picture.forms import PictureImportForm
 from picture.models import Picture
 import picture.tests
 
 from catalogue.models import Book, Tag
 from picture.forms import PictureImportForm
 from picture.models import Picture
 import picture.tests
+from api.models import Consumer, Token
 
 
 @override_settings(
 
 
 @override_settings(
@@ -275,7 +275,11 @@ class OAuth1Tests(ApiTest):
 
         # Request token authorization.
         self.client.login(username='test', password='test')
 
         # Request token authorization.
         self.client.login(username='test', password='test')
-        response = self.client.get('/api/oauth/authorize/?oauth_token=%s&oauth_callback=test://oauth.callback/' % request_token)
+        response = self.client.get(
+            '/api/oauth/authorize/?oauth_token=%s&oauth_callback=test://oauth.callback/' % (
+                request_token,
+            )
+        )
         post_data = response.context['form'].initial
 
         response = self.client.post('/api/oauth/authorize/?' + urlencode(post_data))
         post_data = response.context['form'].initial
 
         response = self.client.post('/api/oauth/authorize/?' + urlencode(post_data))
index 536d3fe..4fb321a 100644 (file)
@@ -1,7 +1,7 @@
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
-from django.conf.urls import url, include
+from django.urls import path, include
 from django.views.decorators.csrf import csrf_exempt
 from django.views.generic import TemplateView
 import catalogue.views
 from django.views.decorators.csrf import csrf_exempt
 from django.views.generic import TemplateView
 import catalogue.views
@@ -10,31 +10,31 @@ from . import views
 
 
 urlpatterns = [
 
 
 urlpatterns = [
-    url(r'^oauth/request_token/$', csrf_exempt(views.OAuth1RequestTokenView.as_view())),
-    url(r'^oauth/authorize/$', views.oauth_user_auth, name='oauth_user_auth'),
-    url(r'^oauth/access_token/$', csrf_exempt(views.OAuth1AccessTokenView.as_view())),
+    path('oauth/request_token/', csrf_exempt(views.OAuth1RequestTokenView.as_view())),
+    path('oauth/authorize/', views.oauth_user_auth, name='oauth_user_auth'),
+    path('oauth/access_token/', csrf_exempt(views.OAuth1AccessTokenView.as_view())),
 
 
-    url(r'^$', TemplateView.as_view(template_name='api/main.html'), name='api'),
+    path('', TemplateView.as_view(template_name='api/main.html'), name='api'),
 
     # info boxes (used by mobile app)
 
     # info boxes (used by mobile app)
-    url(r'book/(?P<book_id>\d*?)/info\.html$', catalogue.views.book_info),
-    url(r'tag/(?P<tag_id>\d*?)/info\.html$', catalogue.views.tag_info),
+    path('book/<int:book_id>/info.html', catalogue.views.book_info),
+    path('tag/<int:tag_id>/info.html', catalogue.views.tag_info),
 
     # reading data
 
     # reading data
-    url(r'^reading/(?P<slug>[a-z0-9-]+)/$',
-        piwik_track_view(views.BookUserDataView.as_view()),
-        name='api_reading'),
-    url(r'^reading/(?P<slug>[a-z0-9-]+)/(?P<state>[a-z]+)/$',
-        piwik_track_view(views.BookUserDataView.as_view()),
-        name='api_reading'),
-    url(r'^username/$',
-        piwik_track_view(views.UserView.as_view()),
-        name='api_username'),
+    path('reading/<slug:slug>/',
+         piwik_track_view(views.BookUserDataView.as_view()),
+         name='api_reading'),
+    path('reading/<slug:slug>/<slug:state>/',
+         piwik_track_view(views.BookUserDataView.as_view()),
+         name='api_reading'),
+    path('username/',
+         piwik_track_view(views.UserView.as_view()),
+         name='api_username'),
 
 
-    url(r'^blog$',
-        piwik_track_view(views.BlogView.as_view())),
+    path('blog',
+         piwik_track_view(views.BlogView.as_view())),
 
 
-    url(r'^pictures/', include('picture.api.urls')),
-    url(r'^', include('social.api.urls')),
-    url(r'^', include('catalogue.api.urls')),
+    path('pictures/', include('picture.api.urls')),
+    path('', include('social.api.urls')),
+    path('', include('catalogue.api.urls')),
 ]
 ]
index 69f9b8b..6762fb1 100644 (file)
@@ -10,13 +10,12 @@ from django.views.generic.base import View
 from oauthlib.common import urlencode
 from oauthlib.oauth1 import RequestTokenEndpoint, AccessTokenEndpoint
 from oauthlib.oauth1 import AuthorizationEndpoint, OAuth1Error
 from oauthlib.common import urlencode
 from oauthlib.oauth1 import RequestTokenEndpoint, AccessTokenEndpoint
 from oauthlib.oauth1 import AuthorizationEndpoint, OAuth1Error
-from api.models import KEY_SIZE, SECRET_SIZE
 from rest_framework.permissions import IsAuthenticated
 from rest_framework.response import Response
 from rest_framework.views import APIView
 from rest_framework.permissions import IsAuthenticated
 from rest_framework.response import Response
 from rest_framework.views import APIView
-from rest_framework.generics import ListAPIView, RetrieveAPIView, get_object_or_404
+from rest_framework.generics import RetrieveAPIView, get_object_or_404
 from catalogue.models import Book
 from catalogue.models import Book
-from .models import BookUserData
+from .models import BookUserData, KEY_SIZE, SECRET_SIZE
 from . import serializers
 from .request_validator import PistonRequestValidator
 from .utils import oauthlib_request, oauthlib_response, vary_on_auth
 from . import serializers
 from .request_validator import PistonRequestValidator
 from .utils import oauthlib_request, oauthlib_response, vary_on_auth
@@ -86,7 +85,7 @@ def oauth_user_auth(request):
 
         return render(request, 'oauth/authorize_token.html', {'form': form})
 
 
         return render(request, 'oauth/authorize_token.html', {'form': form})
 
-    elif request.method == "POST":
+    if request.method == "POST":
         try:
             response = oauthlib_response(
                 endpoint.create_authorization_response(
         try:
             response = oauthlib_response(
                 endpoint.create_authorization_response(
index 1275390..b4acb46 100644 (file)
@@ -44,7 +44,7 @@ def view_or_basicauth(view, request, test_func, realm="", *args, **kwargs):
     response.status_code = 401
     response['WWW-Authenticate'] = 'Basic realm="%s"' % realm
     return response
     response.status_code = 401
     response['WWW-Authenticate'] = 'Basic realm="%s"' % realm
     return response
-    
+
 
 #
 def logged_in_or_basicauth(realm=""):
 
 #
 def logged_in_or_basicauth(realm=""):
index 1290f81..da120b5 100644 (file)
@@ -2,7 +2,7 @@
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 import logging
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 import logging
-from django.conf import settings as settings
+from django.conf import settings
 from django.utils.module_loading import import_string
 from catalogue.utils import AppSettings
 
 from django.utils.module_loading import import_string
 from catalogue.utils import AppSettings
 
@@ -16,11 +16,11 @@ class Settings(AppSettings):
     # PDF needs TeXML + XeLaTeX, MOBI needs Calibre.
     DONT_BUILD = {'pdf', 'mobi'}
     FORMAT_ZIPS = {
     # PDF needs TeXML + XeLaTeX, MOBI needs Calibre.
     DONT_BUILD = {'pdf', 'mobi'}
     FORMAT_ZIPS = {
-            'epub': 'wolnelektury_pl_epub',
-            'pdf': 'wolnelektury_pl_pdf',
-            'mobi': 'wolnelektury_pl_mobi',
-            'fb2': 'wolnelektury_pl_fb2',
-        }
+        'epub': 'wolnelektury_pl_epub',
+        'pdf': 'wolnelektury_pl_pdf',
+        'mobi': 'wolnelektury_pl_mobi',
+        'fb2': 'wolnelektury_pl_fb2',
+    }
 
     REDAKCJA_URL = "http://redakcja.wolnelektury.pl"
     GOOD_LICENSES = {r'CC BY \d\.\d', r'CC BY-SA \d\.\d'}
 
     REDAKCJA_URL = "http://redakcja.wolnelektury.pl"
     GOOD_LICENSES = {r'CC BY \d\.\d', r'CC BY-SA \d\.\d'}
@@ -42,7 +42,10 @@ class Settings(AppSettings):
         for format_ in ['epub', 'pdf', 'mobi', 'fb2']:
             attname = 'ALL_%s_ZIP' % format_.upper()
             if hasattr(settings, attname):
         for format_ in ['epub', 'pdf', 'mobi', 'fb2']:
             attname = 'ALL_%s_ZIP' % format_.upper()
             if hasattr(settings, attname):
-                logging.warn("%s is deprecated, use CATALOGUE_FORMAT_ZIPS[%s] instead", attname, format_)
+                logging.warn(
+                    "%s is deprecated, use CATALOGUE_FORMAT_ZIPS[%s] instead",
+                    attname, format_
+                )
                 value[format_] = getattr(settings, attname)
         return value
 
                 value[format_] = getattr(settings, attname)
         return value
 
index 9008df1..88377e7 100644 (file)
@@ -2,8 +2,6 @@
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 from django.contrib import admin
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 from django.contrib import admin
-from django import forms
-
 from catalogue.models import Tag, Book, Fragment, BookMedia, Collection, Source
 
 
 from catalogue.models import Tag, Book, Fragment, BookMedia, Collection, Source
 
 
@@ -29,7 +27,9 @@ class MediaInline(admin.TabularInline):
 
 
 class BookAdmin(admin.ModelAdmin):
 
 
 class BookAdmin(admin.ModelAdmin):
-    list_display = ('title', 'slug', 'created_at', 'has_epub_file', 'has_html_file', 'has_description',)
+    list_display = (
+        'title', 'slug', 'created_at', 'has_epub_file', 'has_html_file', 'has_description',
+    )
     search_fields = ('title',)
     ordering = ('title',)
 
     search_fields = ('title',)
     ordering = ('title',)
 
index 80de4ab..d95c3a8 100644 (file)
@@ -15,7 +15,9 @@ class BookLiked(serializers.ReadOnlyField):
         request = self.context['request']
         if not hasattr(request, 'liked_books'):
             if request.user.is_authenticated:
         request = self.context['request']
         if not hasattr(request, 'liked_books'):
             if request.user.is_authenticated:
-                request.liked_books = set(Book.tagged.with_any(request.user.tag_set.all()).values_list('id', flat=True))
+                request.liked_books = set(
+                    Book.tagged.with_any(request.user.tag_set.all()).values_list('id', flat=True)
+                )
             else:
                 request.liked_books = None
         if request.liked_books is not None:
             else:
                 request.liked_books = None
         if request.liked_books is not None:
index 6813e03..7971268 100644 (file)
@@ -20,6 +20,4 @@ def books_after(books, after, new_api):
 def order_books(books, new_api):
     if new_api:
         return books.order_by('sort_key_author', 'sort_key', 'id')
 def order_books(books, new_api):
     if new_api:
         return books.order_by('sort_key_author', 'sort_key', 'id')
-    else:
-        return books.order_by('slug')
-
+    return books.order_by('slug')
index 0f2343d..2e5a9be 100644 (file)
@@ -1,7 +1,7 @@
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
-from django.conf.urls import include, url
+from django.urls import path, re_path
 from stats.utils import piwik_track_view
 from . import views
 
 from stats.utils import piwik_track_view
 from . import views
 
@@ -12,67 +12,67 @@ paginate_re = r'(?:after/(?P<after>[a-z0-9-]+)/)?(?:count/(?P<count>[0-9]+)/)?$'
 
 urlpatterns = [
     # books by collections
 
 urlpatterns = [
     # books by collections
-    url(r'^collections/$',
-        piwik_track_view(views.CollectionList.as_view()),
-        name="catalogue_api_collections"),
-    url(r'^collections/(?P<slug>[^/]+)/$',
-        piwik_track_view(views.CollectionDetail.as_view()),
-        name="collection-detail"),
+    path('collections/',
+         piwik_track_view(views.CollectionList.as_view()),
+         name="catalogue_api_collections"),
+    path('collections/<slug:slug>/',
+         piwik_track_view(views.CollectionDetail.as_view()),
+         name="collection-detail"),
 
 
-    url(tags_re + r'books/' + paginate_re,
-        piwik_track_view(views.BookList.as_view()),
-        name='catalogue_api_book_list'),
-    url(tags_re + r'parent_books/' + paginate_re,
-        piwik_track_view(views.BookList.as_view()),
-        {"top_level": True}, name='catalogue_api_parent_book_list'),
-    url(tags_re + r'audiobooks/' + paginate_re,
-        piwik_track_view(views.BookList.as_view()),
-        {"audiobooks": True}, name='catalogue_api_audiobook_list'),
-    url(tags_re + r'daisy/' + paginate_re,
-        piwik_track_view(views.BookList.as_view()),
-        {"daisy": True}, name='catalogue_api_daisy_list'),
-    url(r'^recommended/' + paginate_re,
-        piwik_track_view(views.BookList.as_view()),
-        {"recommended": True}, name='catalogue_api_recommended_list'),
-    url(r'^newest/$',
-        piwik_track_view(views.BookList.as_view()),
-        {"newest": True, "top_level": True, "count": 20},
-        name='catalogue_api_newest_list'),
+    re_path(tags_re + r'books/' + paginate_re,
+            piwik_track_view(views.BookList.as_view()),
+            name='catalogue_api_book_list'),
+    re_path(tags_re + r'parent_books/' + paginate_re,
+            piwik_track_view(views.BookList.as_view()),
+            {"top_level": True}, name='catalogue_api_parent_book_list'),
+    re_path(tags_re + r'audiobooks/' + paginate_re,
+            piwik_track_view(views.BookList.as_view()),
+            {"audiobooks": True}, name='catalogue_api_audiobook_list'),
+    re_path(tags_re + r'daisy/' + paginate_re,
+            piwik_track_view(views.BookList.as_view()),
+            {"daisy": True}, name='catalogue_api_daisy_list'),
+    re_path(r'^recommended/' + paginate_re,
+            piwik_track_view(views.BookList.as_view()),
+            {"recommended": True}, name='catalogue_api_recommended_list'),
+    path('newest/',
+         piwik_track_view(views.BookList.as_view()),
+         {"newest": True, "top_level": True, "count": 20},
+         name='catalogue_api_newest_list'),
 
 
-    url(r'^books/(?P<slug>[^/]+)/$',
-        piwik_track_view(views.BookDetail.as_view()),
-        name='catalogue_api_book'),
+    path('books/<slug:slug>/',
+         piwik_track_view(views.BookDetail.as_view()),
+         name='catalogue_api_book'),
 
 
-    url(tags_re + r'ebooks/' + paginate_re,
-        piwik_track_view(views.EbookList.as_view()),
-        name='catalogue_api_ebook_list'),
-    url(tags_re + r'parent_ebooks/' + paginate_re,
-        piwik_track_view(views.EbookList.as_view()),
-        {"top_level": True},
-        name='catalogue_api_parent_ebook_list'),
+    re_path(tags_re + r'ebooks/' + paginate_re,
+            piwik_track_view(views.EbookList.as_view()),
+            name='catalogue_api_ebook_list'),
+    re_path(tags_re + r'parent_ebooks/' + paginate_re,
+            piwik_track_view(views.EbookList.as_view()),
+            {"top_level": True},
+            name='catalogue_api_parent_ebook_list'),
 
 
-    url(r'^filter-books/$',
-        piwik_track_view(views.FilterBookList.as_view()),
-        name='catalogue_api_filter_books'),
+    path('filter-books/',
+         piwik_track_view(views.FilterBookList.as_view()),
+         name='catalogue_api_filter_books'),
 
 
-    url(r'^epub/(?P<slug>[a-z0-9-]+)/$',
-        piwik_track_view(views.EpubView.as_view()),
-        name='catalogue_api_epub'),
+    path('epub/<slug:slug>/',
+         piwik_track_view(views.EpubView.as_view()),
+         name='catalogue_api_epub'),
 
 
-    url(r'^preview/$',
-        piwik_track_view(views.Preview.as_view()),
-        name='catalogue_api_preview'),
+    path('preview/',
+         piwik_track_view(views.Preview.as_view()),
+         name='catalogue_api_preview'),
 
 
-    url(r'^(?P<tags>(?:(?:[a-z0-9-]+/){2}){1,6})fragments/$',
-        piwik_track_view(views.FragmentList.as_view())),
-    url(r'^books/(?P<book>[a-z0-9-]+)/fragments/(?P<anchor>[a-z0-9-]+)/$',
-        piwik_track_view(views.FragmentView.as_view()),
-        name="catalogue_api_fragment"),
+    re_path(r'^(?P<tags>(?:(?:[a-z0-9-]+/){2}){1,6})fragments/$',
+            piwik_track_view(views.FragmentList.as_view())),
+    path('books/<slug:book>/fragments/<slug:anchor>/',
+         piwik_track_view(views.FragmentView.as_view()),
+         name="catalogue_api_fragment"),
 
 
-    url(r'^(?P<category>[a-z]+)s/$',
-        piwik_track_view(views.TagCategoryView.as_view()),
-        name='catalogue_api_tag_list'),
-    url(r'^(?P<category>[a-z]+)s/(?P<slug>[a-z0-9-]+)/$',
-        piwik_track_view(views.TagView.as_view()),
-        name="catalogue_api_tag"),
+    path('<slug:category>s/',
+         piwik_track_view(views.TagCategoryView.as_view()),
+         name='catalogue_api_tag_list'),
+    path('<slug:category>s/<slug:slug>/',
+         piwik_track_view(views.TagView.as_view()),
+         name="catalogue_api_tag"),
 ]
 ]
index 34971c4..c70a73e 100644 (file)
@@ -11,14 +11,14 @@ from rest_framework.response import Response
 from rest_framework import status
 from api.handlers import read_tags
 from api.utils import vary_on_auth
 from rest_framework import status
 from api.handlers import read_tags
 from api.utils import vary_on_auth
-from club.models import Membership
-from .helpers import books_after, order_books
-from . import serializers
 from catalogue.forms import BookImportForm
 from catalogue.models import Book, Collection, Tag, Fragment, BookMedia
 from catalogue.models.tag import prefetch_relations
 from catalogue.forms import BookImportForm
 from catalogue.models import Book, Collection, Tag, Fragment, BookMedia
 from catalogue.models.tag import prefetch_relations
+from club.models import Membership
 from club.permissions import IsClubMember
 from wolnelektury.utils import re_escape
 from club.permissions import IsClubMember
 from wolnelektury.utils import re_escape
+from .helpers import books_after, order_books
+from . import serializers
 
 
 book_tag_categories = ['author', 'epoch', 'kind', 'genre']
 
 
 book_tag_categories = ['author', 'epoch', 'kind', 'genre']
index 46cde23..be4ce8a 100644 (file)
@@ -133,8 +133,9 @@ class BuildTxt(BuildEbook):
 class BuildPdf(BuildEbook):
     @staticmethod
     def transform(wldoc, fieldfile):
 class BuildPdf(BuildEbook):
     @staticmethod
     def transform(wldoc, fieldfile):
-        return wldoc.as_pdf(morefloats=settings.LIBRARIAN_PDF_MOREFLOATS, cover=True,
-                            ilustr_path=gallery_path(wldoc.book_info.url.slug), customizations=['notoc'])
+        return wldoc.as_pdf(
+            morefloats=settings.LIBRARIAN_PDF_MOREFLOATS, cover=True,
+            ilustr_path=gallery_path(wldoc.book_info.url.slug), customizations=['notoc'])
 
     def build(self, fieldfile):
         BuildEbook.build(self, fieldfile)
 
     def build(self, fieldfile):
         BuildEbook.build(self, fieldfile)
@@ -203,8 +204,9 @@ class BuildHtml(BuildEbook):
                     if lang == settings.LANGUAGE_CODE:
                         # Allow creating themes if book in default language.
                         tag, created = Tag.objects.get_or_create(
                     if lang == settings.LANGUAGE_CODE:
                         # Allow creating themes if book in default language.
                         tag, created = Tag.objects.get_or_create(
-                                            slug=slugify(theme_name),
-                                            category='theme')
+                            slug=slugify(theme_name),
+                            category='theme'
+                        )
                         if created:
                             tag.name = theme_name
                             setattr(tag, "name_%s" % lang, theme_name)
                         if created:
                             tag.name = theme_name
                             setattr(tag, "name_%s" % lang, theme_name)
@@ -215,7 +217,10 @@ class BuildHtml(BuildEbook):
                     elif lang is not None:
                         # Don't create unknown themes in non-default languages.
                         try:
                     elif lang is not None:
                         # Don't create unknown themes in non-default languages.
                         try:
-                            tag = Tag.objects.get(category='theme', **{"name_%s" % lang: theme_name})
+                            tag = Tag.objects.get(
+                                category='theme',
+                                **{"name_%s" % lang: theme_name}
+                            )
                         except Tag.DoesNotExist:
                             pass
                         else:
                         except Tag.DoesNotExist:
                             pass
                         else:
@@ -227,7 +232,12 @@ class BuildHtml(BuildEbook):
                 short_text = truncate_html_words(text, 15)
                 if text == short_text:
                     short_text = ''
                 short_text = truncate_html_words(text, 15)
                 if text == short_text:
                     short_text = ''
-                new_fragment = Fragment.objects.create(anchor=fragment.id, book=book, text=text, short_text=short_text)
+                new_fragment = Fragment.objects.create(
+                    anchor=fragment.id,
+                    book=book,
+                    text=text,
+                    short_text=short_text
+                )
 
                 new_fragment.save()
                 new_fragment.tags = set(meta_tags + themes)
 
                 new_fragment.save()
                 new_fragment.tags = set(meta_tags + themes)
index a6e69db..6bc5569 100644 (file)
@@ -4,11 +4,11 @@
 from os.path import abspath, dirname, join
 import tempfile
 from traceback import extract_stack
 from os.path import abspath, dirname, join
 import tempfile
 from traceback import extract_stack
+from django.conf import settings
 from django.test import TestCase
 from django.test.utils import override_settings
 from slugify import slugify
 from librarian import WLURI
 from django.test import TestCase
 from django.test.utils import override_settings
 from slugify import slugify
 from librarian import WLURI
-from django.conf import settings
 
 
 @override_settings(
 
 
 @override_settings(
@@ -17,8 +17,8 @@ from django.conf import settings
     NO_SEARCH_INDEX=True,
     CELERY_TASK_ALWAYS_EAGER=True,
     CACHES={
     NO_SEARCH_INDEX=True,
     CELERY_TASK_ALWAYS_EAGER=True,
     CACHES={
-            'default': {'BACKEND': 'django.core.cache.backends.dummy.DummyCache'},
-        },
+        'default': {'BACKEND': 'django.core.cache.backends.dummy.DummyCache'},
+    },
     SOLR=settings.SOLR_TEST,
 )
 class WLTestCase(TestCase):
     SOLR=settings.SOLR_TEST,
 )
 class WLTestCase(TestCase):
@@ -28,7 +28,7 @@ class WLTestCase(TestCase):
     longMessage = True
 
 
     longMessage = True
 
 
-class PersonStub(object):
+class PersonStub:
 
     def __init__(self, first_names, last_name):
         self.first_names = first_names
 
     def __init__(self, first_names, last_name):
         self.first_names = first_names
@@ -38,7 +38,7 @@ class PersonStub(object):
         return " ".join(self.first_names + (self.last_name,))
 
 
         return " ".join(self.first_names + (self.last_name,))
 
 
-class BookInfoStub(object):
+class BookInfoStub:
     _empty_fields = ['cover_url', 'variant_of']
     # allow single definition for multiple-value fields
     _salias = {
     _empty_fields = ['cover_url', 'variant_of']
     # allow single definition for multiple-value fields
     _salias = {
@@ -59,10 +59,9 @@ class BookInfoStub(object):
         except KeyError as e:
             if key in self._empty_fields:
                 return None
         except KeyError as e:
             if key in self._empty_fields:
                 return None
-            elif key in self._salias:
+            if key in self._salias:
                 return [getattr(self, self._salias[key])]
                 return [getattr(self, self._salias[key])]
-            else:
-                raise AttributeError(e)
+            raise AttributeError(e)
 
     def to_dict(self):
         return dict((key, str(value)) for key, value in self.__dict.items())
 
     def to_dict(self):
         return dict((key, str(value)) for key, value in self.__dict.items())
index 9ad22a4..f8900c8 100644 (file)
@@ -25,10 +25,10 @@ class BookImportLogicTests(WLTestCase):
         )
 
         self.expected_tags = [
         )
 
         self.expected_tags = [
-           ('author', 'jim-lazy'),
-           ('genre', 'x-genre'),
-           ('epoch', 'x-epoch'),
-           ('kind', 'x-kind'),
+            ('author', 'jim-lazy'),
+            ('genre', 'x-genre'),
+            ('epoch', 'x-epoch'),
+            ('kind', 'x-kind'),
         ]
         self.expected_tags.sort()
 
         ]
         self.expected_tags.sort()
 
@@ -97,8 +97,14 @@ class BookImportLogicTests(WLTestCase):
         """
 
         book = models.Book.from_text_and_meta(ContentFile(book_text), self.book_info)
         """
 
         book = models.Book.from_text_and_meta(ContentFile(book_text), self.book_info)
-        self.assertTrue([('theme', 'love')],
-                     book.fragments.all()[0].tags.filter(category='theme').values_list('category', 'slug'))
+        self.assertEqual(
+            [('theme', 'love')],
+            list(
+                book.fragments.all()[0].tags.filter(
+                    category='theme'
+                ).values_list('category', 'slug')
+            )
+        )
 
     def test_book_with_no_theme(self):
         """ fragments with no themes shouldn't be created at all """
 
     def test_book_with_no_theme(self):
         """ fragments with no themes shouldn't be created at all """
@@ -180,10 +186,10 @@ class BookImportLogicTests(WLTestCase):
         self.book_info.epochs = self.book_info.epoch, 'Y-Epoch',
 
         self.expected_tags.extend([
         self.book_info.epochs = self.book_info.epoch, 'Y-Epoch',
 
         self.expected_tags.extend([
-           ('author', 'joe-dilligent'),
-           ('genre', 'y-genre'),
-           ('epoch', 'y-epoch'),
-           ('kind', 'y-kind'),
+            ('author', 'joe-dilligent'),
+            ('genre', 'y-genre'),
+            ('epoch', 'y-epoch'),
+            ('kind', 'y-kind'),
         ])
         self.expected_tags.sort()
 
         ])
         self.expected_tags.sort()
 
@@ -287,10 +293,10 @@ class TreeImportTest(WLTestCase):
 
     def test_ok(self):
         self.assertEqual(
 
     def test_ok(self):
         self.assertEqual(
-                list(self.client.get('/katalog/gatunek/x-genre/').context['object_list']),
-                [self.parent],
-                "There should be only parent on common tag page."
-            )
+            list(self.client.get('/katalog/gatunek/x-genre/').context['object_list']),
+            [self.parent],
+            "There should be only parent on common tag page."
+        )
         # pies = models.Tag.objects.get(slug='pies')
         themes = self.parent.related_themes()
         self.assertEqual(len(themes), 1, "There should be child theme in parent theme counter.")
         # pies = models.Tag.objects.get(slug='pies')
         themes = self.parent.related_themes()
         self.assertEqual(len(themes), 1, "There should be child theme in parent theme counter.")
@@ -308,10 +314,10 @@ class TreeImportTest(WLTestCase):
         models.Book.from_text_and_meta(
             ContentFile(child_text), self.child_info, overwrite=True)
         self.assertEqual(
         models.Book.from_text_and_meta(
             ContentFile(child_text), self.child_info, overwrite=True)
         self.assertEqual(
-                list(self.client.get('/katalog/gatunek/x-genre/').context['object_list']),
-                [self.parent],
-                "There should only be parent on common tag page."
-            )
+            list(self.client.get('/katalog/gatunek/x-genre/').context['object_list']),
+            [self.parent],
+            "There should only be parent on common tag page."
+        )
         # pies = models.Tag.objects.get(slug='pies')
         # kot = models.Tag.objects.get(slug='kot')
         self.assertEqual(len(self.parent.related_themes()), 2,
         # pies = models.Tag.objects.get(slug='pies')
         # kot = models.Tag.objects.get(slug='kot')
         self.assertEqual(len(self.parent.related_themes()), 2,
@@ -396,7 +402,7 @@ class MultilingualBookImportTest(WLTestCase):
         models.Book.from_text_and_meta(ContentFile(book_text), self.eng_info)
 
         self.assertEqual(
         models.Book.from_text_and_meta(ContentFile(book_text), self.eng_info)
 
         self.assertEqual(
-            set([b.language for b in models.Book.objects.all()]),
+            {b.language for b in models.Book.objects.all()},
             {'pol', 'eng'},
             'Books imported in wrong languages.'
         )
             {'pol', 'eng'},
             'Books imported in wrong languages.'
         )
index 29acd4a..92845e2 100644 (file)
@@ -96,8 +96,9 @@ class TagRelatedTagsTests(WLTestCase):
                 </akap></opowiadanie></utwor>
                 """ % info.title
             book = models.Book.from_text_and_meta(
                 </akap></opowiadanie></utwor>
                 """ % info.title
             book = models.Book.from_text_and_meta(
-                    ContentFile(book_text.encode('utf-8')),
-                    info)
+                ContentFile(book_text.encode('utf-8')),
+                info
+            )
             book.save()
 
         tag_empty = models.Tag(name='Empty tag', slug='empty', category='author')
             book.save()
 
         tag_empty = models.Tag(name='Empty tag', slug='empty', category='author')
index ac551b9..27fddc2 100644 (file)
@@ -1,7 +1,7 @@
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of Wolnelektury, 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.db.models import Max
 from django.views.generic import ListView, RedirectView
 from catalogue.feeds import AudiobookFeed
 from django.db.models import Max
 from django.views.generic import ListView, RedirectView
 from catalogue.feeds import AudiobookFeed
@@ -10,72 +10,71 @@ from catalogue import views
 import picture.views
 
 
 import picture.views
 
 
-SLUG = r'[a-z0-9-]*'
-
 urlpatterns = [
 urlpatterns = [
-    url(r'^obraz/strona/$', picture.views.picture_page, name='picture_page'),
+    path('obraz/strona/', picture.views.picture_page, name='picture_page'),
     # pictures - currently pictures are coupled with catalogue, hence the url is here
     # pictures - currently pictures are coupled with catalogue, hence the url is here
-    url(r'^obraz/$', picture.views.picture_list_thumb, name='picture_list_thumb'),
-    url(r'^obraz/(?P<slug>%s).html$' % SLUG, picture.views.picture_viewer, name='picture_viewer'),
-    url(r'^obraz/(?P<slug>%s)/$' % SLUG, picture.views.picture_detail, name='picture_detail'),
+    path('obraz/', picture.views.picture_list_thumb, name='picture_list_thumb'),
+    path('obraz/<slug:slug>.html', picture.views.picture_viewer, name='picture_viewer'),
+    path('obraz/<slug:slug>/', picture.views.picture_detail, name='picture_detail'),
 
     # old search page - redirected
 
     # old search page - redirected
-    url(r'^szukaj/$', RedirectView.as_view(
-            url='/szukaj/', query_string=True, permanent=True)),
+    path('szukaj/', RedirectView.as_view(
+        url='/szukaj/', query_string=True, permanent=True)),
 
 
-    url(r'^$', views.catalogue, name='catalogue'),
+    path('', views.catalogue, name='catalogue'),
 
 
-    url(r'^autor/$', views.tag_catalogue, {'category': 'author'}, name='author_catalogue'),
-    url(r'^epoka/$', views.tag_catalogue, {'category': 'epoch'}, name='epoch_catalogue'),
-    url(r'^gatunek/$', views.tag_catalogue, {'category': 'genre'}, name='genre_catalogue'),
-    url(r'^rodzaj/$', views.tag_catalogue, {'category': 'kind'}, name='kind_catalogue'),
-    url(r'^motyw/$', views.tag_catalogue, {'category': 'theme'}, name='theme_catalogue'),
+    path('autor/', views.tag_catalogue, {'category': 'author'}, name='author_catalogue'),
+    path('epoka/', views.tag_catalogue, {'category': 'epoch'}, name='epoch_catalogue'),
+    path('gatunek/', views.tag_catalogue, {'category': 'genre'}, name='genre_catalogue'),
+    path('rodzaj/', views.tag_catalogue, {'category': 'kind'}, name='kind_catalogue'),
+    path('motyw/', views.tag_catalogue, {'category': 'theme'}, name='theme_catalogue'),
 
 
-    url(r'^galeria/$', views.gallery, name='gallery'),
-    url(r'^kolekcje/$', views.collections, name='catalogue_collections'),
+    path('galeria/', views.gallery, name='gallery'),
+    path('kolekcje/', views.collections, name='catalogue_collections'),
 
 
-    url(r'^lektury/$', views.literature, name='book_list'),
-    url(r'^lektury/(?P<slug>[a-zA-Z0-9-]+)/$', views.collection, name='collection'),
-    url(r'^audiobooki/$', views.audiobooks, name='audiobook_list'),
-    url(r'^daisy/$', views.daisy_list, name='daisy_list'),
-    url(r'^nowe/$', ListView.as_view(
+    path('lektury/', views.literature, name='book_list'),
+    path('lektury/<slug:slug>/', views.collection, name='collection'),
+    path('audiobooki/', views.audiobooks, name='audiobook_list'),
+    path('daisy/', views.daisy_list, name='daisy_list'),
+    path('nowe/', ListView.as_view(
         queryset=Book.objects.filter(parent=None).order_by('-created_at'),
         template_name='catalogue/recent_list.html'), name='recent_list'),
         queryset=Book.objects.filter(parent=None).order_by('-created_at'),
         template_name='catalogue/recent_list.html'), name='recent_list'),
-    url(r'^nowe/audiobooki/$', ListView.as_view(
+    path('nowe/audiobooki/', ListView.as_view(
         queryset=Book.objects.filter(media__type='ogg').annotate(m=Max('media__uploaded_at')).order_by('-m'),
         template_name='catalogue/recent_audiobooks_list.html'), name='recent_audiobooks_list'),
         queryset=Book.objects.filter(media__type='ogg').annotate(m=Max('media__uploaded_at')).order_by('-m'),
         template_name='catalogue/recent_audiobooks_list.html'), name='recent_audiobooks_list'),
-    url(r'^nowe/daisy/$', ListView.as_view(
+    path('nowe/daisy/', ListView.as_view(
         queryset=Book.objects.filter(media__type='daisy').annotate(m=Max('media__uploaded_at')).order_by('-m'),
         template_name='catalogue/recent_daisy_list.html'), name='recent_daisy_list'),
 
         queryset=Book.objects.filter(media__type='daisy').annotate(m=Max('media__uploaded_at')).order_by('-m'),
         template_name='catalogue/recent_daisy_list.html'), name='recent_daisy_list'),
 
-    url(r'^custompdf/(?P<slug>%s)/$' % SLUG, views.CustomPDFFormView(), name='custom_pdf_form'),
+    path('custompdf/<slug:slug>/', views.CustomPDFFormView(), name='custom_pdf_form'),
 
 
-    url(r'^audiobooki/(?P<type>mp3|ogg|daisy|all).xml$', AudiobookFeed(), name='audiobook_feed'),
+    re_path(r'^audiobooki/(?P<type>mp3|ogg|daisy|all).xml$', AudiobookFeed(), name='audiobook_feed'),
 
 
-    url(r'^pobierz/(?P<key>.*)/(?P<slug>%s).(?P<format_>[a-z0-9]*)$' % SLUG, views.embargo_link, name='embargo_link'),
+    path('pobierz/<key>/<slug:slug>.<slug:format_>', views.embargo_link, name='embargo_link'),
 
     # zip
 
     # zip
-    url(r'^zip/pdf\.zip$', views.download_zip, {'format': 'pdf', 'slug': None}, 'download_zip_pdf'),
-    url(r'^zip/epub\.zip$', views.download_zip, {'format': 'epub', 'slug': None}, 'download_zip_epub'),
-    url(r'^zip/mobi\.zip$', views.download_zip, {'format': 'mobi', 'slug': None}, 'download_zip_mobi'),
-    url(r'^zip/mp3/(?P<slug>%s)\.zip' % SLUG, views.download_zip, {'format': 'mp3'}, 'download_zip_mp3'),
-    url(r'^zip/ogg/(?P<slug>%s)\.zip' % SLUG, views.download_zip, {'format': 'ogg'}, 'download_zip_ogg'),
+    path('zip/pdf.zip', views.download_zip, {'format': 'pdf', 'slug': None}, 'download_zip_pdf'),
+    path('zip/epub.zip', views.download_zip, {'format': 'epub', 'slug': None}, 'download_zip_epub'),
+    path('zip/mobi.zip', views.download_zip, {'format': 'mobi', 'slug': None}, 'download_zip_mobi'),
+    path('zip/mp3/<slug:slug>.zip', views.download_zip, {'format': 'mp3'}, 'download_zip_mp3'),
+    path('zip/ogg/<slug:slug>.zip', views.download_zip, {'format': 'ogg'}, 'download_zip_ogg'),
 
     # Public interface. Do not change this URLs.
 
     # Public interface. Do not change this URLs.
-    url(r'^lektura/(?P<slug>%s)\.html$' % SLUG, views.book_text, name='book_text'),
-    url(r'^lektura/(?P<slug>%s)/audiobook/$' % SLUG, views.player, name='book_player'),
-    url(r'^lektura/(?P<slug>%s)/$' % SLUG, views.book_detail, name='book_detail'),
-    url(r'^lektura/(?P<slug>%s)/motyw/(?P<theme_slug>[a-zA-Z0-9-]+)/$' % SLUG,
-        views.book_fragments, name='book_fragments'),
+    path('lektura/<slug:slug>.html', views.book_text, name='book_text'),
+    path('lektura/<slug:slug>/audiobook/', views.player, name='book_player'),
+    path('lektura/<slug:slug>/', views.book_detail, name='book_detail'),
+    path('lektura/<slug:slug>/motyw/<slug:theme_slug>/',
+         views.book_fragments, name='book_fragments'),
 
 
-    url(r'^okladka-ridero/(?P<slug>%s).png$' % SLUG, views.ridero_cover),
-    url(r'^isbn/(?P<book_format>(pdf|epub|mobi|txt|html))/(?P<slug>%s)/' % SLUG, views.get_isbn),
+    path('okladka-ridero/<slug:slug>.png', views.ridero_cover),
+    path('isbn/<slug:book_format>/<slug:slug>/', views.get_isbn),
 
     # This should be the last pattern.
 
     # This should be the last pattern.
-    url(r'^galeria/(?P<tags>[a-zA-Z0-9-/]*)/$', views.tagged_object_list, {'list_type': 'gallery'},
+    re_path(r'^galeria/(?P<tags>[a-zA-Z0-9-/]*)/$', views.tagged_object_list, {'list_type': 'gallery'},
         name='tagged_object_list_gallery'),
         name='tagged_object_list_gallery'),
-    url(r'^audiobooki/(?P<tags>[a-zA-Z0-9-/]*)/$', views.tagged_object_list, {'list_type': 'audiobooks'},
+    re_path(r'^audiobooki/(?P<tags>[a-zA-Z0-9-/]*)/$', views.tagged_object_list, {'list_type': 'audiobooks'},
         name='tagged_object_list_audiobooks'),
         name='tagged_object_list_audiobooks'),
-    url(r'^(?P<tags>[a-zA-Z0-9-/]*)/$', views.tagged_object_list, {'list_type': 'books'},
+    re_path(r'^(?P<tags>[a-zA-Z0-9-/]*)/$', views.tagged_object_list, {'list_type': 'books'},
         name='tagged_object_list'),
         name='tagged_object_list'),
+
 ]
 ]
index 66a2b91..2c6692f 100644 (file)
@@ -81,10 +81,13 @@ def differentiate_tags(request, tags, ambiguous_slugs):
         })
     return render(
         request,
         })
     return render(
         request,
-        'catalogue/differentiate_tags.html', {'tags': tags, 'options': options, 'unparsed': ambiguous_slugs[1:]})
+        'catalogue/differentiate_tags.html',
+        {'tags': tags, 'options': options, 'unparsed': ambiguous_slugs[1:]}
+    )
 
 
 
 
-def object_list(request, objects, fragments=None, related_tags=None, tags=None, list_type='books', extra=None):
+def object_list(request, objects, fragments=None, related_tags=None, tags=None,
+                list_type='books', extra=None):
     if not tags:
         tags = []
     tag_ids = [tag.pk for tag in tags]
     if not tags:
         tags = []
     tag_ids = [tag.pk for tag in tags]
@@ -94,7 +97,9 @@ def object_list(request, objects, fragments=None, related_tags=None, tags=None,
         related_tag_lists.append(related_tags)
     else:
         related_tag_lists.append(
         related_tag_lists.append(related_tags)
     else:
         related_tag_lists.append(
-            Tag.objects.usage_for_queryset(objects, counts=True).exclude(category='set').exclude(pk__in=tag_ids))
+            Tag.objects.usage_for_queryset(
+                objects, counts=True
+            ).exclude(category='set').exclude(pk__in=tag_ids))
     if not (extra and extra.get('theme_is_set')):
         if fragments is None:
             if list_type == 'gallery':
     if not (extra and extra.get('theme_is_set')):
         if fragments is None:
             if list_type == 'gallery':
@@ -102,7 +107,9 @@ def object_list(request, objects, fragments=None, related_tags=None, tags=None,
             else:
                 fragments = Fragment.objects.filter(book__in=objects)
         related_tag_lists.append(
             else:
                 fragments = Fragment.objects.filter(book__in=objects)
         related_tag_lists.append(
-            Tag.objects.usage_for_queryset(fragments, counts=True).filter(category='theme').exclude(pk__in=tag_ids)
+            Tag.objects.usage_for_queryset(
+                fragments, counts=True
+            ).filter(category='theme').exclude(pk__in=tag_ids)
             .only('name', 'sort_key', 'category', 'slug'))
         if isinstance(objects, QuerySet):
             objects = prefetch_relations(objects, 'author')
             .only('name', 'sort_key', 'category', 'slug'))
         if isinstance(objects, QuerySet):
             objects = prefetch_relations(objects, 'author')
@@ -169,8 +176,7 @@ def analyse_tags(request, tag_str):
         chunks = tag_str.split('/')
         if len(chunks) == 2 and chunks[0] == 'autor':
             raise ResponseInstead(pdcounter_views.author_detail(request, chunks[1]))
         chunks = tag_str.split('/')
         if len(chunks) == 2 and chunks[0] == 'autor':
             raise ResponseInstead(pdcounter_views.author_detail(request, chunks[1]))
-        else:
-            raise Http404
+        raise Http404
     except Tag.MultipleObjectsReturned as e:
         # Ask the user to disambiguate
         raise ResponseInstead(differentiate_tags(request, e.tags, e.ambiguous_slugs))
     except Tag.MultipleObjectsReturned as e:
         # Ask the user to disambiguate
         raise ResponseInstead(differentiate_tags(request, e.tags, e.ambiguous_slugs))
@@ -243,7 +249,9 @@ def tagged_object_list(request, tags, list_type):
         params = {
             'objects': Book.tagged.with_all(tags, audiobooks),
             'extra': {
         params = {
             'objects': Book.tagged.with_all(tags, audiobooks),
             'extra': {
-                'daisy': Book.tagged.with_all(tags, audiobooks.filter(media__type='daisy').distinct()),
+                'daisy': Book.tagged.with_all(
+                    tags, audiobooks.filter(media__type='daisy').distinct()
+                ),
             }
         }
     else:
             }
         }
     else:
@@ -342,11 +350,13 @@ def import_book(request):
             exception = pprint.pformat(info[1])
             tb = '\n'.join(traceback.format_tb(info[2]))
             return HttpResponse(
             exception = pprint.pformat(info[1])
             tb = '\n'.join(traceback.format_tb(info[2]))
             return HttpResponse(
-                    _("An error occurred: %(exception)s\n\n%(tb)s") % {'exception': exception, 'tb': tb},
-                    mimetype='text/plain')
+                _("An error occurred: %(exception)s\n\n%(tb)s") % {
+                    'exception': exception, 'tb': tb
+                },
+                mimetype='text/plain'
+            )
         return HttpResponse(_("Book imported successfully"))
         return HttpResponse(_("Book imported successfully"))
-    else:
-        return HttpResponse(_("Error importing file: %r") % book_import_form.errors)
+    return HttpResponse(_("Error importing file: %r") % book_import_form.errors)
 
 
 # info views for API
 
 
 # info views for API
@@ -405,7 +415,7 @@ class CustomPDFFormView(AjaxableFormView):
 
     def validate_object(self, obj, request):
         book = obj
 
     def validate_object(self, obj, request):
         book = obj
-        if book.preview and not Membership_is_active_for(request.user):
+        if book.preview and not Membership.is_active_for(request.user):
             return HttpResponseRedirect(book.get_absolute_url())
         return super(CustomPDFFormView, self).validate_object(obj, request)
 
             return HttpResponseRedirect(book.get_absolute_url())
         return super(CustomPDFFormView, self).validate_object(obj, request)
 
index a2dfbb9..7a3795a 100644 (file)
@@ -1,26 +1,26 @@
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of Wolnelektury, 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 annoy.utils import banner_exempt
 from . import views
 
 
 urlpatterns = [
 from annoy.utils import banner_exempt
 from . import views
 
 
 urlpatterns = [
-    url(r'^$', banner_exempt(views.JoinView.as_view()), name='club_join'),
-    url(r'^info/$', banner_exempt(views.ClubView.as_view()), name='club'),
+    path('', banner_exempt(views.JoinView.as_view()), name='club_join'),
+    path('info/', banner_exempt(views.ClubView.as_view()), name='club'),
 
 
-    url(r'^plan/(?P<key>[-a-z0-9]+)/$', banner_exempt(views.ScheduleView.as_view()), name='club_schedule'),
-    url(r'^plan/(?P<key>[-a-z0-9]+)/dziekujemy/$', banner_exempt(views.ScheduleThanksView.as_view()), name='club_thanks'),
+    path('plan/<key>/', banner_exempt(views.ScheduleView.as_view()), name='club_schedule'),
+    path('plan/<key>/dziekujemy/', banner_exempt(views.ScheduleThanksView.as_view()), name='club_thanks'),
 
 
-    url(r'^przylacz/(?P<key>[-a-z0-9]+)/$', views.claim, name='club_claim'),
-    url(r'^anuluj/(?P<key>[-a-z0-9]+)/$', views.cancel, name='club_cancel'),
-    url(r'^testowa-platnosc/(?P<key>[-a-z0-9]+)/$', views.DummyPaymentView.as_view(), name='club_dummy_payment'),
+    path('przylacz/<key>/', views.claim, name='club_claim'),
+    path('anuluj/<key>/', views.cancel, name='club_cancel'),
+    path('testowa-platnosc/<key>/', views.DummyPaymentView.as_view(), name='club_dummy_payment'),
 
 
-    url(r'platnosc/payu/cykl/(?P<key>.+)/', banner_exempt(views.PayURecPayment.as_view()), name='club_payu_rec_payment'),
-    url(r'platnosc/payu/(?P<key>.+)/', banner_exempt(views.PayUPayment.as_view()), name='club_payu_payment'),
+    path('platnosc/payu/cykl/<key>/', banner_exempt(views.PayURecPayment.as_view()), name='club_payu_rec_payment'),
+    path('platnosc/payu/<key>/', banner_exempt(views.PayUPayment.as_view()), name='club_payu_payment'),
 
 
-    url(r'notify/(?P<pk>\d+)/', views.PayUNotifyView.as_view(), name='club_payu_notify'),
+    path('notify/<int:pk>/', views.PayUNotifyView.as_view(), name='club_payu_notify'),
 
 
-    url(r'czlonek/', views.MembershipView.as_view(), name='club_membership'),
+    path('czlonek/', views.MembershipView.as_view(), name='club_membership'),
 ]
 ]
index 2baf628..3ab98fc 100755 (executable)
@@ -1,9 +1,9 @@
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of Wolnelektury, 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 dictionary.views import NotesView
 
 urlpatterns = [
 from dictionary.views import NotesView
 
 urlpatterns = [
-    url(r'^$', NotesView.as_view(), name='dictionary_notes'),
+    path('', NotesView.as_view(), name='dictionary_notes'),
 ]
 ]
index 986c4f0..3aae4ea 100644 (file)
@@ -1,22 +1,22 @@
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
-from django.conf.urls import url, include
+from django.urls import path, include
 from . import views
 
 
 urlpatterns = [
 from . import views
 
 
 urlpatterns = [
-    url(r'^$', views.CurrentView.as_view(), name='funding_current'),
-    url(r'^teraz/$', views.CurrentView.as_view()),
-    url(r'^teraz/(?P<slug>[^/]+)/$', views.CurrentView.as_view(), name='funding_current'),
-    url(r'^lektura/$', views.OfferListView.as_view(), name='funding'),
-    url(r'^lektura/(?P<slug>[^/]+)/$', views.OfferDetailView.as_view(), name='funding_offer'),
-    url(r'^pozostale/$', views.WLFundView.as_view(), name='funding_wlfund'),
+    path('', views.CurrentView.as_view(), name='funding_current'),
+    path('teraz/', views.CurrentView.as_view()),
+    path('teraz/<slug:slug>/', views.CurrentView.as_view(), name='funding_current'),
+    path('lektura/', views.OfferListView.as_view(), name='funding'),
+    path('lektura/<slug:slug>/', views.OfferDetailView.as_view(), name='funding_offer'),
+    path('pozostale/', views.WLFundView.as_view(), name='funding_wlfund'),
 
 
-    url(r'^dziekujemy/$', views.ThanksView.as_view(), name='funding_thanks'),
-    url(r'^niepowodzenie/$', views.NoThanksView.as_view(), name='funding_nothanks'),
+    path('dziekujemy/', views.ThanksView.as_view(), name='funding_thanks'),
+    path('niepowodzenie/', views.NoThanksView.as_view(), name='funding_nothanks'),
 
 
-    url(r'^wylacz_email/$', views.DisableNotifications.as_view(), name='funding_disable_notifications'),
+    path('wylacz_email/', views.DisableNotifications.as_view(), name='funding_disable_notifications'),
 
 
-    url(r'^getpaid/', include('getpaid.urls')),
+    path('getpaid/', include('getpaid.urls')),
 ]
 ]
index 9d82335..233345a 100755 (executable)
@@ -1,10 +1,10 @@
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of Wolnelektury, 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 = [
 from . import views
 
 
 urlpatterns = [
-    url(r'^(?P<slug>[a-zA-Z0-9_-]+)/$', views.infopage, name='infopage'),
+    path('<slug>/', views.infopage, name='infopage'),
 ]
 ]
index 2a977e5..893831e 100644 (file)
@@ -1,15 +1,15 @@
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of Wolnelektury, 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 = (
 from . import views
 
 urlpatterns = (
-    url(r'^dodaj/$', views.add_isbn_wl, name='add_isbn_wl'),
-    url(r'^potwierdzenie/$', views.confirm_isbn_wl, name='confirm_isbn_wl'),
-    url(r'^save-wl-onix/$', views.save_wl_onix, name='save_wl_onix'),
-    url(r'^tagi-isbn/(?P<slug>[a-z0-9-]*)/$', views.wl_dc_tags, name='wl_dc_tags'),
+    path('dodaj/', views.add_isbn_wl, name='add_isbn_wl'),
+    path('potwierdzenie/', views.confirm_isbn_wl, name='confirm_isbn_wl'),
+    path('save-wl-onix/', views.save_wl_onix, name='save_wl_onix'),
+    path('tagi-isbn/<slug:slug>/', views.wl_dc_tags, name='wl_dc_tags'),
 
 
-    url(r'^dodaj-fnp/$', views.add_isbn_fnp, name='add_isbn_fnp'),
-    url(r'^przypisane/(?P<slug>[a-z0-9-]*)/$', views.assigned_isbn, name='assigned_isbn'),
+    path('dodaj-fnp/', views.add_isbn_fnp, name='add_isbn_fnp'),
+    path('przypisane/<slug:slug>/', views.assigned_isbn, name='assigned_isbn'),
 )
 )
index 15d6f25..dbee5f8 100644 (file)
@@ -1,14 +1,14 @@
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of Wolnelektury, 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 = [
 from . import views
 
 
 urlpatterns = [
-    url(r'^$', views.main_page, name='lesmianator'),
-    url(r'^wiersz/$', views.new_poem, name='new_poem'),
-    url(r'^lektura/(?P<slug>[a-z0-9-]+)/$', views.poem_from_book, name='poem_from_book'),
-    url(r'^polka/(?P<shelf>[a-zA-Z0-9-]+)/$', views.poem_from_set, name='poem_from_set'),
-    url(r'^wiersz/(?P<poem>[a-zA-Z0-9-]+)/$', views.get_poem, name='get_poem'),
+    path('', views.main_page, name='lesmianator'),
+    path('wiersz/', views.new_poem, name='new_poem'),
+    path('lektura/<slug:slug>/', views.poem_from_book, name='poem_from_book'),
+    path('polka/<shelf>/', views.poem_from_set, name='poem_from_set'),
+    path('wiersz/<poem>/', views.get_poem, name='get_poem'),
 ]
 ]
index 3e3d78e..9753b77 100644 (file)
@@ -1,12 +1,12 @@
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of Wolnelektury, 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 = [
 from . import views
 
 
 urlpatterns = [
-    url(r'^$', views.main_view, name='libraries_main_view'),
-    url(r'^(?P<slug>[a-zA-Z0-9_-]+)$', views.catalog_view, name='libraries_catalog_view'),
-    url(r'^(?P<catalog_slug>[a-zA-Z0-9_-]+)/(?P<slug>[a-zA-Z0-9_-]+)$', views.library_view, name='libraries_library_view'),
+    path('', views.main_view, name='libraries_main_view'),
+    path('<slug:slug>', views.catalog_view, name='libraries_catalog_view'),
+    path('<slug:catalog_slug>/<slug:slug>', views.library_view, name='libraries_library_view'),
 ]
 ]
index 530eeca..48134b1 100644 (file)
@@ -1,7 +1,7 @@
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of Wolnelektury, 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 django.contrib import admin
 from django.http.response import HttpResponse
 from django.views.decorators.cache import never_cache
 from django.contrib import admin
 from django.http.response import HttpResponse
 from django.views.decorators.cache import never_cache
@@ -16,7 +16,7 @@ class SubscriptionAdmin(admin.ModelAdmin):
     def get_urls(self):
         urls = super(SubscriptionAdmin, self).get_urls()
         my_urls = [
     def get_urls(self):
         urls = super(SubscriptionAdmin, self).get_urls()
         my_urls = [
-            url(r'^extract/$', self.extract_subscribers, name='extract_subscribers'),
+            path('extract/', self.extract_subscribers, name='extract_subscribers'),
         ]
         return my_urls + urls
 
         ]
         return my_urls + urls
 
index c99b47a..bfae579 100644 (file)
@@ -1,14 +1,14 @@
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of Wolnelektury, 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 = [
 from . import views
 
 urlpatterns = [
-    url(r'^zapisz-sie/$', views.subscribe_form, name='subscribe'),
-    url(r'^zapis/$', views.subscribed, name='subscribed'),
-    url(r'^potwierdzenie/(?P<subscription_id>[0-9]+)/(?P<hashcode>[0-9a-f]+)/$',
+    path('zapisz-sie/', views.subscribe_form, name='subscribe'),
+    path('zapis/', views.subscribed, name='subscribed'),
+    path('potwierdzenie/<int:subscription_id>/<slug:hashcode>/',
         views.confirm_subscription, name='confirm_subscription'),
         views.confirm_subscription, name='confirm_subscription'),
-    url(r'^wypisz-sie/$', views.unsubscribe_form, name='unsubscribe'),
-    url(r'^wypisano/$', views.unsubscribed, name='unsubscribed'),
+    path('wypisz-sie/', views.unsubscribe_form, name='unsubscribe'),
+    path('wypisano/', views.unsubscribed, name='unsubscribed'),
 ]
 ]
index 2088a8a..85c31af 100644 (file)
@@ -1,10 +1,10 @@
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of Wolnelektury, 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 = [
 from . import views
 
 
 urlpatterns = [
-    url(r'^$', views.oaipmh, name='oaipmh')
+    path('', views.oaipmh, name='oaipmh')
 ]
 ]
index 213c55a..1d68199 100644 (file)
@@ -1,15 +1,15 @@
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of Wolnelektury, 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 opds.views import RootFeed, ByCategoryFeed, ByTagFeed, UserFeed, UserSetFeed, SearchFeed
 
 
 urlpatterns = [
 from opds.views import RootFeed, ByCategoryFeed, ByTagFeed, UserFeed, UserSetFeed, SearchFeed
 
 
 urlpatterns = [
-    url(r'^$', RootFeed(), name="opds_authors"),
-    url(r'^search/$', SearchFeed(), name="opds_search"),
-    url(r'^user/$', UserFeed(), name="opds_user"),
-    url(r'^set/(?P<slug>[a-zA-Z0-9-]+)/$', UserSetFeed(), name="opds_user_set"),
-    url(r'^(?P<category>[a-zA-Z0-9-]+)/$', ByCategoryFeed(), name="opds_by_category"),
-    url(r'^(?P<category>[a-zA-Z0-9-]+)/(?P<slug>[a-zA-Z0-9-]+)/$', ByTagFeed(), name="opds_by_tag"),
+    path('', RootFeed(), name="opds_authors"),
+    path('search/', SearchFeed(), name="opds_search"),
+    path('user/', UserFeed(), name="opds_user"),
+    path('set/<slug>/', UserSetFeed(), name="opds_user_set"),
+    path('<category>/', ByCategoryFeed(), name="opds_by_category"),
+    path('<category>/<slug>/', ByTagFeed(), name="opds_by_tag"),
 ]
 ]
index bd26993..aca8918 100644 (file)
@@ -1,15 +1,15 @@
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of Wolnelektury, 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 django.views.generic import RedirectView
 from . import views
 
 urlpatterns = (
 from django.views.generic import RedirectView
 from . import views
 
 urlpatterns = (
-    url(r'^form/$', RedirectView.as_view(url='/towarzystwo/dolacz/')),
-    url(r'^app-form/$', RedirectView.as_view(url='/towarzystwo/dolacz/app/')),
+    path('form/', RedirectView.as_view(url='/towarzystwo/dolacz/')),
+    path('app-form/', RedirectView.as_view(url='/towarzystwo/dolacz/app/')),
 
 
-    url(r'^return/$', views.paypal_return, name='paypal_return'),
-    url(r'^app-return/$', views.paypal_return, kwargs={'app': True}, name='paypal_app_return'),
-    url(r'^cancel/$', views.paypal_cancel, name='paypal_cancel'),
+    path('return/', views.paypal_return, name='paypal_return'),
+    path('app-return/', views.paypal_return, kwargs={'app': True}, name='paypal_app_return'),
+    path('cancel/', views.paypal_cancel, name='paypal_cancel'),
 )
 )
index cb457f5..95fd103 100644 (file)
@@ -1,10 +1,10 @@
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of Wolnelektury, 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 = [
 from . import views
 
 
 urlpatterns = [
-    url(r'^$', views.PicturesView.as_view()),
+    path('', views.PicturesView.as_view()),
 ]
 ]
index 897686b..f2d3a02 100644 (file)
@@ -1,10 +1,10 @@
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of Wolnelektury, 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 = [
 from . import views
 
 
 urlpatterns = [
-    url(r'^(?P<slug>[^/]+)$', views.poll, name='poll'),
+    path('<slug:slug>', views.poll, name='poll'),
 ]
 ]
index c7f64d9..a92a55f 100644 (file)
@@ -1,11 +1,11 @@
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of Wolnelektury, 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 push import views
 
 
 urlpatterns = [
 from push import views
 
 
 urlpatterns = [
-    url(r'^wyslij/$', views.notification_form, name='notification_form'),
-    url(r'^wyslane/$', views.notification_sent, name='notification_sent'),
+    path('wyslij/', views.notification_form, name='notification_form'),
+    path('wyslane/', views.notification_sent, name='notification_sent'),
 ]
 ]
index fa7ceb2..a9ae44a 100755 (executable)
@@ -1,12 +1,12 @@
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of Wolnelektury, 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 = [
 from . import views
 
 
 urlpatterns = [
-    url(r'^$', views.stats_page, name='reporting_stats'),
-    url(r'^katalog.pdf$', views.catalogue_pdf, name='reporting_catalogue_pdf'),
-    url(r'^katalog.csv$', views.catalogue_csv, name='reporting_catalogue_csv'),
+    path('', views.stats_page, name='reporting_stats'),
+    path('katalog.pdf', views.catalogue_pdf, name='reporting_catalogue_pdf'),
+    path('katalog.csv', views.catalogue_csv, name='reporting_catalogue_csv'),
 ]
 ]
index 980f5e8..46e73c5 100644 (file)
@@ -1,11 +1,11 @@
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of Wolnelektury, 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 = [
 from . import views
 
 
 urlpatterns = [
-    url(r'^$', views.main, name='wlsearch'),
-    url(r'^hint/$', views.hint, name='search_hint'),
+    path('', views.main, name='wlsearch'),
+    path('hint/', views.hint, name='search_hint'),
 ]
 ]
index 2ed2d66..2b20ab8 100644 (file)
@@ -1,16 +1,16 @@
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
-from django.conf.urls import include, url
+from django.urls import path
 from stats.utils import piwik_track_view
 from . import views
 
 
 urlpatterns = [
 from stats.utils import piwik_track_view
 from . import views
 
 
 urlpatterns = [
-    url(r'^like/(?P<slug>[a-z0-9-]+)/$',
+    path('like/<slug:slug>/',
         piwik_track_view(views.LikeView.as_view()),
         name='social_api_like'),
         piwik_track_view(views.LikeView.as_view()),
         name='social_api_like'),
-    url(r'^shelf/(?P<state>[a-z]+)/$',
+    path('shelf/<slug:state>/',
         piwik_track_view(views.ShelfView.as_view()),
         name='social_api_shelf'),
 ]
         piwik_track_view(views.ShelfView.as_view()),
         name='social_api_shelf'),
 ]
index 6b78950..e092ff0 100644 (file)
@@ -1,14 +1,14 @@
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of Wolnelektury, 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 django.views.decorators.cache import never_cache
 from . import views
 
 
 urlpatterns = [
 from django.views.decorators.cache import never_cache
 from . import views
 
 
 urlpatterns = [
-    url(r'^lektura/(?P<slug>[a-z0-9-]+)/lubie/$', views.like_book, name='social_like_book'),
-    url(r'^lektura/(?P<slug>[a-z0-9-]+)/nie_lubie/$', views.unlike_book, name='social_unlike_book'),
-    url(r'^lektura/(?P<slug>[a-z0-9-]+)/polki/$', never_cache(views.ObjectSetsFormView()), name='social_book_sets'),
-    url(r'^polka/$', views.my_shelf, name='social_my_shelf'),
+    path('lektura/<slug:slug>/lubie/', views.like_book, name='social_like_book'),
+    path('lektura/<slug:slug>/nie_lubie/', views.unlike_book, name='social_unlike_book'),
+    path('lektura/<slug:slug>/polki/', never_cache(views.ObjectSetsFormView()), name='social_book_sets'),
+    path('polka/', views.my_shelf, name='social_my_shelf'),
 ]
 ]
index 4a03a0d..7f15ac5 100644 (file)
@@ -1,10 +1,10 @@
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of Wolnelektury, 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 suggest import views
 
 urlpatterns = [
 from suggest import views
 
 urlpatterns = [
-    url(r'^$', views.SuggestionFormView(), name='suggest'),
-    url(r'^plan/$', views.PublishingSuggestionFormView(), name='suggest_publishing'),
+    path('', views.SuggestionFormView(), name='suggest'),
+    path('plan/', views.PublishingSuggestionFormView(), name='suggest_publishing'),
 ]
 ]
index ffe9805..1c8b17f 100644 (file)
@@ -1,9 +1,9 @@
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of Wolnelektury, 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 waiter import views
 
 urlpatterns = [
 from waiter import views
 
 urlpatterns = [
-    url(r'^(?P<path>.*)$', views.wait, name='waiter'),
+    path('<path:path>', views.wait, name='waiter'),
 ]
 ]
index 43b6d95..b215081 100644 (file)
@@ -2,7 +2,7 @@
 {% spaceless %}
   <html lang="{{ LANGUAGE_CODE }}" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">
     {% load pipeline i18n %}
 {% spaceless %}
   <html lang="{{ LANGUAGE_CODE }}" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">
     {% load pipeline i18n %}
-    {% load static from staticfiles %}
+    {% load static %}
     {% load piwik_tags %}
     {% get_current_language as LANGUAGE_CODE %}
     <head>
     {% load piwik_tags %}
     {% get_current_language as LANGUAGE_CODE %}
     <head>
index bd7de37..cdbdb69 100644 (file)
@@ -2,7 +2,7 @@
 {% spaceless %}
   <html lang="{{ LANGUAGE_CODE }}" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">
     {% load pipeline i18n %}
 {% spaceless %}
   <html lang="{{ LANGUAGE_CODE }}" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">
     {% load pipeline i18n %}
-    {% load static from staticfiles %}
+    {% load static %}
     {% load catalogue_tags funding_tags reporting_stats %}
     {% load piwik_tags %}
     {% load cache %}
     {% load catalogue_tags funding_tags reporting_stats %}
     {% load piwik_tags %}
     {% load cache %}
index 71731b9..9d5b1fb 100644 (file)
@@ -1,7 +1,7 @@
 {% extends "base/base.html" %}
 {% load latest_blog_posts from blog %}
 {% load carousel from social_tags %}
 {% extends "base/base.html" %}
 {% load latest_blog_posts from blog %}
 {% load carousel from social_tags %}
-{% load static from staticfiles %}
+{% load static %}
 {% load i18n catalogue_tags infopages_tags %}
 {% load cache %}
 {% load funding_tags %}
 {% load i18n catalogue_tags infopages_tags %}
 {% load cache %}
 {% load funding_tags %}
index de79b56..3eb3422 100644 (file)
@@ -1,5 +1,5 @@
 {% spaceless %}
 {% spaceless %}
-  {% load static from staticfiles %}
+  {% load static %}
   {% load pipeline %}
   <!DOCTYPE html>
 
   {% load pipeline %}
   <!DOCTYPE html>
 
index c328c83..af6244c 100644 (file)
@@ -1,9 +1,9 @@
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
-from django.conf.urls import include, url
 from django.conf import settings
 from django.contrib import admin
 from django.conf import settings
 from django.contrib import admin
+from django.urls import include, path
 from django.views.generic import RedirectView
 import django.views.static
 import catalogue.views
 from django.views.generic import RedirectView
 import django.views.static
 import catalogue.views
@@ -12,100 +12,97 @@ from . import views
 
 
 urlpatterns = [
 
 
 urlpatterns = [
-    url(r'^$', views.main_page, name='main_page'),
-    url(r'^planowane/$', views.publish_plan, name='publish_plan'),
-    url(r'^widget\.html$', views.widget, name='widget'),
+    path('', views.main_page, name='main_page'),
+    path('planowane/', views.publish_plan, name='publish_plan'),
+    path('widget.html', views.widget, name='widget'),
 
 
-    url(r'^zegar/$', views.clock, name='clock'),
+    path('zegar/', views.clock, name='clock'),
 
     # Authentication
 
     # Authentication
-    url(r'^uzytkownik/$', views.user_settings, name='user_settings'),
-    url(r'^uzytkownik/login/$', views.LoginFormView(), name='login'),
-    url(r'^uzytkownik/signup/$', views.RegisterFormView(), name='register'),
-    url(r'^uzytkownik/logout/$', views.logout_then_redirect, name='logout'),
-    url(r'^uzytkownik/zaloguj-utworz/$', views.LoginRegisterFormView(), name='login_register'),
-    url(r'^uzytkownik/social/signup/$', views.SocialSignupView.as_view(), name='socialaccount_signup'),
+    path('uzytkownik/', views.user_settings, name='user_settings'),
+    path('uzytkownik/login/', views.LoginFormView(), name='login'),
+    path('uzytkownik/signup/', views.RegisterFormView(), name='register'),
+    path('uzytkownik/logout/', views.logout_then_redirect, name='logout'),
+    path('uzytkownik/zaloguj-utworz/', views.LoginRegisterFormView(), name='login_register'),
+    path('uzytkownik/social/signup/', views.SocialSignupView.as_view(), name='socialaccount_signup'),
 ]
 
 urlpatterns += [
 ]
 
 urlpatterns += [
-    url(r'^katalog/', include('catalogue.urls')),
-    url(r'^opds/', include('opds.urls')),
-    url(r'^sugestia/', include('suggest.urls')),
-    url(r'^lesmianator/', include('lesmianator.urls')),
-    url(r'^przypisy/', include('dictionary.urls')),
-    url(r'^raporty/', include('reporting.urls')),
-    url(r'^info/', include('infopages.urls')),
-    url(r'^ludzie/', include('social.urls')),
-    url(r'^uzytkownik/', include('allauth.urls')),
-    url(r'^czekaj/', include('waiter.urls')),
-    url(r'^wesprzyj/', include('funding.urls')),
-    url(r'^ankieta/', include('polls.urls')),
-    url(r'^biblioteki/', include('libraries.urls')),
-    url(r'^newsletter/', include('newsletter.urls')),
-    url(r'^formularz/', include('forms_builder.forms.urls')),
-    url(r'^isbn/', include('isbn.urls')),
-    url(r'^messaging/', include('messaging.urls')),
-
-    url(r'^paypal/app-form/$', RedirectView.as_view(
+    path('katalog/', include('catalogue.urls')),
+    path('opds/', include('opds.urls')),
+    path('sugestia/', include('suggest.urls')),
+    path('lesmianator/', include('lesmianator.urls')),
+    path('przypisy/', include('dictionary.urls')),
+    path('raporty/', include('reporting.urls')),
+    path('info/', include('infopages.urls')),
+    path('ludzie/', include('social.urls')),
+    path('uzytkownik/', include('allauth.urls')),
+    path('czekaj/', include('waiter.urls')),
+    path('wesprzyj/', include('funding.urls')),
+    path('ankieta/', include('polls.urls')),
+    path('biblioteki/', include('libraries.urls')),
+    path('newsletter/', include('newsletter.urls')),
+    path('formularz/', include('forms_builder.forms.urls')),
+    path('isbn/', include('isbn.urls')),
+    path('messaging/', include('messaging.urls')),
+
+    path('paypal/app-form/', RedirectView.as_view(
         url='/towarzystwo/?app=1', permanent=False)),
         url='/towarzystwo/?app=1', permanent=False)),
-    url(r'^towarzystwo/dolacz/$', RedirectView.as_view(
+    path('towarzystwo/dolacz/', RedirectView.as_view(
         url='/towarzystwo/', permanent=False)),
 
         url='/towarzystwo/', permanent=False)),
 
-
-    url(r'^paypal/', include('paypal.urls')),
-    url(r'^powiadomienie/', include('push.urls')),
-    url(r'^towarzystwo/', include('club.urls')),
+    path('paypal/', include('paypal.urls')),
+    path('powiadomienie/', include('push.urls')),
+    path('towarzystwo/', include('club.urls')),
 
     # Admin panel
 
     # Admin panel
-    url(r'^admin/catalogue/book/import$', catalogue.views.import_book, name='import_book'),
-    url(r'^admin/catalogue/picture/import$', picture.views.import_picture, name='import_picture'),
-    url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
-    url(r'^admin/', admin.site.urls),
+    path('admin/catalogue/book/import', catalogue.views.import_book, name='import_book'),
+    path('admin/catalogue/picture/import', picture.views.import_picture, name='import_picture'),
+    path('admin/doc/', include('django.contrib.admindocs.urls')),
+    path('admin/', admin.site.urls),
 
     # API
 
     # API
-    url(r'^api/', include('api.urls')),
+    path('api/', include('api.urls')),
     # OAIPMH
     # OAIPMH
-    url(r'^oaipmh/', include('oai.urls')),
+    path('oaipmh/', include('oai.urls')),
 
 
-    url(r'^szukaj/', include('search.urls')),
+    path('szukaj/', include('search.urls')),
 
 
-    url(r'^i18n/', include('django.conf.urls.i18n')),
-    url(r'^forum/', include('machina.urls')),
+    path('i18n/', include('django.conf.urls.i18n')),
+    path('forum/', include('machina.urls')),
 ]
 
 urlpatterns += [
     # old static pages - redirected
 ]
 
 urlpatterns += [
     # old static pages - redirected
-    url(r'^1procent/$', RedirectView.as_view(
+    path('1procent/', RedirectView.as_view(
         url='http://nowoczesnapolska.org.pl/wesprzyj_nas/', permanent=True)),
         url='http://nowoczesnapolska.org.pl/wesprzyj_nas/', permanent=True)),
-    url(r'^epub/$', RedirectView.as_view(
+    path('epub/', RedirectView.as_view(
         url='/katalog/lektury/', permanent=False)),
         url='/katalog/lektury/', permanent=False)),
-    url(r'^mozesz-nam-pomoc/$', RedirectView.as_view(
+    path('mozesz-nam-pomoc/', RedirectView.as_view(
         url='/info/wlacz-sie-w-prace/', permanent=True)),
         url='/info/wlacz-sie-w-prace/', permanent=True)),
-    url(r'^o-projekcie/$', RedirectView.as_view(
+    path('o-projekcie/', RedirectView.as_view(
         url='/info/o-projekcie/', permanent=True)),
         url='/info/o-projekcie/', permanent=True)),
-    url(r'^widget/$', RedirectView.as_view(
+    path('widget/', RedirectView.as_view(
         url='/info/widget/', permanent=True)),
         url='/info/widget/', permanent=True)),
-    url(r'^wolontariat/$', RedirectView.as_view(
+    path('wolontariat/', RedirectView.as_view(
         url='/info/wlacz-sie-w-prace/', permanent=False)),
 ]
 
 urlpatterns += [
         url='/info/wlacz-sie-w-prace/', permanent=False)),
 ]
 
 urlpatterns += [
-    url(r'^error-test/$', views.exception_test),
-    # url(r'^post-test/$', views.post_test),
+    # path('error-test/', views.exception_test),
+    # path('post-test/', views.post_test),
 ]
 
 
 if settings.DEBUG:
     import debug_toolbar
     urlpatterns = [
 ]
 
 
 if settings.DEBUG:
     import debug_toolbar
     urlpatterns = [
-        url(r'^__debug__/', include(debug_toolbar.urls)),
+        path('__debug__/', include(debug_toolbar.urls)),
     ] + urlpatterns
 
 if settings.DEBUG:
     urlpatterns += [
         # Static files
     ] + urlpatterns
 
 if settings.DEBUG:
     urlpatterns += [
         # Static files
-        url(r'^%s(?P<path>.*)$' % settings.MEDIA_URL[1:], django.views.static.serve,
+        path('%s<path:path>' % settings.MEDIA_URL[1:], django.views.static.serve,
            {'document_root': settings.MEDIA_ROOT, 'show_indexes': True}),
            {'document_root': settings.MEDIA_ROOT, 'show_indexes': True}),
-        url(r'^%s(?P<path>.*)$' % settings.STATIC_URL[1:], django.views.static.serve,
-            {'document_root': settings.STATIC_ROOT, 'show_indexes': True}),
     ]
     ]