From 8952b9530d943655e552ea660c47e850123c5105 Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Tue, 17 Dec 2019 00:13:51 +0100 Subject: [PATCH] Cleaning. --- requirements/requirements.txt | 2 +- src/ajaxable/templatetags/ajaxable_tags.py | 3 +- src/ajaxable/utils.py | 42 ++++--- src/annoy/admin.py | 4 +- src/annoy/models.py | 8 +- src/annoy/tests.py | 3 - src/annoy/translation.py | 3 - src/annoy/views.py | 3 - src/api/fields.py | 4 +- src/api/models.py | 22 ++-- src/api/renderers.py | 1 - src/api/serializers.py | 2 +- src/api/tests/tests.py | 14 ++- src/api/urls.py | 42 +++---- src/api/views.py | 7 +- src/basicauth.py | 2 +- src/catalogue/__init__.py | 17 +-- src/catalogue/admin.py | 6 +- src/catalogue/api/fields.py | 4 +- src/catalogue/api/helpers.py | 4 +- src/catalogue/api/urls.py | 112 +++++++++--------- src/catalogue/api/views.py | 6 +- src/catalogue/fields.py | 22 +++- src/catalogue/test_utils.py | 15 ++- src/catalogue/tests/test_book_import.py | 44 ++++--- src/catalogue/tests/test_tags.py | 5 +- src/catalogue/urls.py | 83 +++++++------ src/catalogue/views.py | 34 ++++-- src/club/urls.py | 24 ++-- src/dictionary/urls.py | 4 +- src/funding/urls.py | 22 ++-- src/infopages/urls.py | 4 +- src/isbn/urls.py | 14 +-- src/lesmianator/urls.py | 12 +- src/libraries/urls.py | 8 +- src/newsletter/admin.py | 4 +- src/newsletter/urls.py | 12 +- src/oai/urls.py | 4 +- src/opds/urls.py | 14 +-- src/paypal/urls.py | 12 +- src/picture/api/urls.py | 4 +- src/polls/urls.py | 4 +- src/push/urls.py | 6 +- src/reporting/urls.py | 8 +- src/search/urls.py | 6 +- src/social/api/urls.py | 6 +- src/social/urls.py | 10 +- src/suggest/urls.py | 6 +- src/waiter/urls.py | 4 +- src/wolnelektury/templates/base/app.html | 2 +- .../templates/base/superbase.html | 2 +- src/wolnelektury/templates/main_page.html | 2 +- src/wolnelektury/templates/widget.html | 2 +- src/wolnelektury/urls.py | 109 +++++++++-------- 54 files changed, 422 insertions(+), 397 deletions(-) delete mode 100644 src/annoy/tests.py delete mode 100644 src/annoy/views.py diff --git a/requirements/requirements.txt b/requirements/requirements.txt index b0c3c8e86..f217ccaff 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -1,7 +1,7 @@ -i https://py.mdrn.pl/simple/ # django -Django==2.2.6 +Django==2.2.8 fnpdjango==0.4 docutils diff --git a/src/ajaxable/templatetags/ajaxable_tags.py b/src/ajaxable/templatetags/ajaxable_tags.py index 940648143..2d980f278 100644 --- a/src/ajaxable/templatetags/ajaxable_tags.py +++ b/src/ajaxable/templatetags/ajaxable_tags.py @@ -4,8 +4,9 @@ from django import template from django.utils.encoding import force_text from django.utils.safestring import mark_safe - from ajaxable.utils import placeholdized + + register = template.Library() diff --git a/src/ajaxable/utils.py b/src/ajaxable/utils.py index 164feac34..f8e99cece 100755 --- a/src/ajaxable/utils.py +++ b/src/ajaxable/utils.py @@ -2,23 +2,23 @@ # 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 -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): - 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): @@ -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') - else: - return HttpResponseRedirect('/uzytkownicy/zaloguj') # next?=request.build_full_path()) + return HttpResponseRedirect('/uzytkownicy/zaloguj') # next?=request.build_full_path()) def placeholdized(form): @@ -50,7 +49,7 @@ def placeholdized(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. @@ -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['redirect'], safe='/?=&')) + response_data['redirect'], safe='/?=&')) 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 = { - 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) @@ -163,8 +162,7 @@ class AjaxableFormView(object): if message: output = "
" + message + "
" + 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.""" diff --git a/src/annoy/admin.py b/src/annoy/admin.py index 3f2bd3dd8..24e977e2b 100644 --- a/src/annoy/admin.py +++ b/src/annoy/admin.py @@ -7,7 +7,7 @@ from . import models class BannerAdmin(TranslationAdmin): list_display = ['place', 'text', 'priority', 'since', 'until', 'show_members', 'staff_preview'] - + 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 - + class DynamicTextInsertAdmin(admin.ModelAdmin): diff --git a/src/annoy/models.py b/src/annoy/models.py index 5b9009b0c..9ed724c0e 100644 --- a/src/annoy/models.py +++ b/src/annoy/models.py @@ -40,9 +40,9 @@ class Banner(models.Model): if hasattr(request, 'annoy_banner_exempt'): return cls.objects.none() - + 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( @@ -60,8 +60,8 @@ class Banner(models.Model): 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) diff --git a/src/annoy/tests.py b/src/annoy/tests.py deleted file mode 100644 index 7ce503c2d..000000000 --- a/src/annoy/tests.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.test import TestCase - -# Create your tests here. diff --git a/src/annoy/translation.py b/src/annoy/translation.py index eb17ada17..2d8055a9c 100644 --- a/src/annoy/translation.py +++ b/src/annoy/translation.py @@ -9,7 +9,4 @@ class BannerTranslationOptions(TranslationOptions): fields = ('text',) - translator.register(models.Banner, BannerTranslationOptions) - - diff --git a/src/annoy/views.py b/src/annoy/views.py deleted file mode 100644 index 91ea44a21..000000000 --- a/src/annoy/views.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.shortcuts import render - -# Create your views here. diff --git a/src/api/fields.py b/src/api/fields.py index b6269da16..d1f9da4bf 100644 --- a/src/api/fields.py +++ b/src/api/fields.py @@ -17,7 +17,7 @@ class AbsoluteURLField(serializers.ReadOnlyField): 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: @@ -29,7 +29,7 @@ class AbsoluteURLField(serializers.ReadOnlyField): 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', []) diff --git a/src/api/models.py b/src/api/models.py index e72aaff20..28bc8807d 100644 --- a/src/api/models.py +++ b/src/api/models.py @@ -30,14 +30,17 @@ def _pre_delete_handler(sender, instance, **kwargs): 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( - 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) @@ -57,7 +60,6 @@ class BookUserData(models.Model): instance.complete = state == 'complete' instance.save() return instance -from django.conf import settings 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') - 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) @@ -101,7 +106,10 @@ class Token(models.Model): 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): diff --git a/src/api/renderers.py b/src/api/renderers.py index 57edec3fb..3f742db27 100644 --- a/src/api/renderers.py +++ b/src/api/renderers.py @@ -11,4 +11,3 @@ class LegacyXMLRenderer(XMLRenderer): item_tag_name = 'resource' root_tag_name = 'response' - diff --git a/src/api/serializers.py b/src/api/serializers.py index 237a155c3..eb6994c73 100644 --- a/src/api/serializers.py +++ b/src/api/serializers.py @@ -3,7 +3,7 @@ # 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 diff --git a/src/api/tests/tests.py b/src/api/tests/tests.py index e17db29c7..f85a061b0 100644 --- a/src/api/tests/tests.py +++ b/src/api/tests/tests.py @@ -2,25 +2,25 @@ # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. # from base64 import b64encode -from os import path import hashlib import hmac -import json from io import BytesIO +import json +from os import path 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 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 api.models import Consumer, Token @override_settings( @@ -275,7 +275,11 @@ class OAuth1Tests(ApiTest): # 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)) diff --git a/src/api/urls.py b/src/api/urls.py index 536d3fe49..4fb321a32 100644 --- a/src/api/urls.py +++ b/src/api/urls.py @@ -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. # -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 @@ -10,31 +10,31 @@ from . import views 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) - url(r'book/(?P\d*?)/info\.html$', catalogue.views.book_info), - url(r'tag/(?P\d*?)/info\.html$', catalogue.views.tag_info), + path('book//info.html', catalogue.views.book_info), + path('tag//info.html', catalogue.views.tag_info), # reading data - url(r'^reading/(?P[a-z0-9-]+)/$', - piwik_track_view(views.BookUserDataView.as_view()), - name='api_reading'), - url(r'^reading/(?P[a-z0-9-]+)/(?P[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//', + piwik_track_view(views.BookUserDataView.as_view()), + name='api_reading'), + path('reading///', + 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')), ] diff --git a/src/api/views.py b/src/api/views.py index 69f9b8b03..6762fb1da 100644 --- a/src/api/views.py +++ b/src/api/views.py @@ -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 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.generics import ListAPIView, RetrieveAPIView, get_object_or_404 +from rest_framework.generics import RetrieveAPIView, get_object_or_404 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 @@ -86,7 +85,7 @@ def oauth_user_auth(request): 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( diff --git a/src/basicauth.py b/src/basicauth.py index 1275390ed..b4acb46db 100644 --- a/src/basicauth.py +++ b/src/basicauth.py @@ -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 - + # def logged_in_or_basicauth(realm=""): diff --git a/src/catalogue/__init__.py b/src/catalogue/__init__.py index 1290f81d6..da120b574 100644 --- a/src/catalogue/__init__.py +++ b/src/catalogue/__init__.py @@ -2,7 +2,7 @@ # 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 @@ -16,11 +16,11 @@ class Settings(AppSettings): # 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'} @@ -42,7 +42,10 @@ class Settings(AppSettings): 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 diff --git a/src/catalogue/admin.py b/src/catalogue/admin.py index 9008df14a..88377e79d 100644 --- a/src/catalogue/admin.py +++ b/src/catalogue/admin.py @@ -2,8 +2,6 @@ # 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 @@ -29,7 +27,9 @@ class MediaInline(admin.TabularInline): 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',) diff --git a/src/catalogue/api/fields.py b/src/catalogue/api/fields.py index 80de4ab34..d95c3a857 100644 --- a/src/catalogue/api/fields.py +++ b/src/catalogue/api/fields.py @@ -15,7 +15,9 @@ class BookLiked(serializers.ReadOnlyField): 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: diff --git a/src/catalogue/api/helpers.py b/src/catalogue/api/helpers.py index 6813e03d4..7971268b0 100644 --- a/src/catalogue/api/helpers.py +++ b/src/catalogue/api/helpers.py @@ -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') - else: - return books.order_by('slug') - + return books.order_by('slug') diff --git a/src/catalogue/api/urls.py b/src/catalogue/api/urls.py index 0f2343df9..2e5a9beb4 100644 --- a/src/catalogue/api/urls.py +++ b/src/catalogue/api/urls.py @@ -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. # -from django.conf.urls import include, url +from django.urls import path, re_path from stats.utils import piwik_track_view from . import views @@ -12,67 +12,67 @@ paginate_re = r'(?:after/(?P[a-z0-9-]+)/)?(?:count/(?P[0-9]+)/)?$' urlpatterns = [ # books by collections - url(r'^collections/$', - piwik_track_view(views.CollectionList.as_view()), - name="catalogue_api_collections"), - url(r'^collections/(?P[^/]+)/$', - 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//', + 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[^/]+)/$', - piwik_track_view(views.BookDetail.as_view()), - name='catalogue_api_book'), + path('books//', + 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[a-z0-9-]+)/$', - piwik_track_view(views.EpubView.as_view()), - name='catalogue_api_epub'), + path('epub//', + 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(?:(?:[a-z0-9-]+/){2}){1,6})fragments/$', - piwik_track_view(views.FragmentList.as_view())), - url(r'^books/(?P[a-z0-9-]+)/fragments/(?P[a-z0-9-]+)/$', - piwik_track_view(views.FragmentView.as_view()), - name="catalogue_api_fragment"), + re_path(r'^(?P(?:(?:[a-z0-9-]+/){2}){1,6})fragments/$', + piwik_track_view(views.FragmentList.as_view())), + path('books//fragments//', + piwik_track_view(views.FragmentView.as_view()), + name="catalogue_api_fragment"), - url(r'^(?P[a-z]+)s/$', - piwik_track_view(views.TagCategoryView.as_view()), - name='catalogue_api_tag_list'), - url(r'^(?P[a-z]+)s/(?P[a-z0-9-]+)/$', - piwik_track_view(views.TagView.as_view()), - name="catalogue_api_tag"), + path('s/', + piwik_track_view(views.TagCategoryView.as_view()), + name='catalogue_api_tag_list'), + path('s//', + piwik_track_view(views.TagView.as_view()), + name="catalogue_api_tag"), ] diff --git a/src/catalogue/api/views.py b/src/catalogue/api/views.py index 34971c45f..c70a73ed0 100644 --- a/src/catalogue/api/views.py +++ b/src/catalogue/api/views.py @@ -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 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 club.models import Membership 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'] diff --git a/src/catalogue/fields.py b/src/catalogue/fields.py index 46cde2379..be4ce8a41 100644 --- a/src/catalogue/fields.py +++ b/src/catalogue/fields.py @@ -133,8 +133,9 @@ class BuildTxt(BuildEbook): 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) @@ -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( - 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) @@ -215,7 +217,10 @@ class BuildHtml(BuildEbook): 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: @@ -227,7 +232,12 @@ class BuildHtml(BuildEbook): 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) diff --git a/src/catalogue/test_utils.py b/src/catalogue/test_utils.py index a6e69db74..6bc5569c6 100644 --- a/src/catalogue/test_utils.py +++ b/src/catalogue/test_utils.py @@ -4,11 +4,11 @@ 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.conf import settings @override_settings( @@ -17,8 +17,8 @@ from django.conf import settings 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): @@ -28,7 +28,7 @@ class WLTestCase(TestCase): longMessage = True -class PersonStub(object): +class PersonStub: 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,)) -class BookInfoStub(object): +class BookInfoStub: _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 - elif key in self._salias: + if key in self._salias: 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()) diff --git a/src/catalogue/tests/test_book_import.py b/src/catalogue/tests/test_book_import.py index 9ad22a4d0..f8900c8a3 100644 --- a/src/catalogue/tests/test_book_import.py +++ b/src/catalogue/tests/test_book_import.py @@ -25,10 +25,10 @@ class BookImportLogicTests(WLTestCase): ) 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() @@ -97,8 +97,14 @@ class BookImportLogicTests(WLTestCase): """ 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 """ @@ -180,10 +186,10 @@ class BookImportLogicTests(WLTestCase): 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() @@ -287,10 +293,10 @@ class TreeImportTest(WLTestCase): 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.") @@ -308,10 +314,10 @@ class TreeImportTest(WLTestCase): 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, @@ -396,7 +402,7 @@ class MultilingualBookImportTest(WLTestCase): 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.' ) diff --git a/src/catalogue/tests/test_tags.py b/src/catalogue/tests/test_tags.py index 29acd4aa1..92845e228 100644 --- a/src/catalogue/tests/test_tags.py +++ b/src/catalogue/tests/test_tags.py @@ -96,8 +96,9 @@ class TagRelatedTagsTests(WLTestCase): """ % 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') diff --git a/src/catalogue/urls.py b/src/catalogue/urls.py index ac551b99c..27fddc2f0 100644 --- a/src/catalogue/urls.py +++ b/src/catalogue/urls.py @@ -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. # -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 @@ -10,72 +10,71 @@ from catalogue import views import picture.views -SLUG = r'[a-z0-9-]*' - 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 - url(r'^obraz/$', picture.views.picture_list_thumb, name='picture_list_thumb'), - url(r'^obraz/(?P%s).html$' % SLUG, picture.views.picture_viewer, name='picture_viewer'), - url(r'^obraz/(?P%s)/$' % SLUG, picture.views.picture_detail, name='picture_detail'), + path('obraz/', picture.views.picture_list_thumb, name='picture_list_thumb'), + path('obraz/.html', picture.views.picture_viewer, name='picture_viewer'), + path('obraz//', picture.views.picture_detail, name='picture_detail'), # 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[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//', 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'), - 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'), - 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'), - url(r'^custompdf/(?P%s)/$' % SLUG, views.CustomPDFFormView(), name='custom_pdf_form'), + path('custompdf//', views.CustomPDFFormView(), name='custom_pdf_form'), - url(r'^audiobooki/(?Pmp3|ogg|daisy|all).xml$', AudiobookFeed(), name='audiobook_feed'), + re_path(r'^audiobooki/(?Pmp3|ogg|daisy|all).xml$', AudiobookFeed(), name='audiobook_feed'), - url(r'^pobierz/(?P.*)/(?P%s).(?P[a-z0-9]*)$' % SLUG, views.embargo_link, name='embargo_link'), + path('pobierz//.', views.embargo_link, name='embargo_link'), # 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%s)\.zip' % SLUG, views.download_zip, {'format': 'mp3'}, 'download_zip_mp3'), - url(r'^zip/ogg/(?P%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/.zip', views.download_zip, {'format': 'mp3'}, 'download_zip_mp3'), + path('zip/ogg/.zip', views.download_zip, {'format': 'ogg'}, 'download_zip_ogg'), # Public interface. Do not change this URLs. - url(r'^lektura/(?P%s)\.html$' % SLUG, views.book_text, name='book_text'), - url(r'^lektura/(?P%s)/audiobook/$' % SLUG, views.player, name='book_player'), - url(r'^lektura/(?P%s)/$' % SLUG, views.book_detail, name='book_detail'), - url(r'^lektura/(?P%s)/motyw/(?P[a-zA-Z0-9-]+)/$' % SLUG, - views.book_fragments, name='book_fragments'), + path('lektura/.html', views.book_text, name='book_text'), + path('lektura//audiobook/', views.player, name='book_player'), + path('lektura//', views.book_detail, name='book_detail'), + path('lektura//motyw//', + views.book_fragments, name='book_fragments'), - url(r'^okladka-ridero/(?P%s).png$' % SLUG, views.ridero_cover), - url(r'^isbn/(?P(pdf|epub|mobi|txt|html))/(?P%s)/' % SLUG, views.get_isbn), + path('okladka-ridero/.png', views.ridero_cover), + path('isbn///', views.get_isbn), # This should be the last pattern. - url(r'^galeria/(?P[a-zA-Z0-9-/]*)/$', views.tagged_object_list, {'list_type': 'gallery'}, + re_path(r'^galeria/(?P[a-zA-Z0-9-/]*)/$', views.tagged_object_list, {'list_type': 'gallery'}, name='tagged_object_list_gallery'), - url(r'^audiobooki/(?P[a-zA-Z0-9-/]*)/$', views.tagged_object_list, {'list_type': 'audiobooks'}, + re_path(r'^audiobooki/(?P[a-zA-Z0-9-/]*)/$', views.tagged_object_list, {'list_type': 'audiobooks'}, name='tagged_object_list_audiobooks'), - url(r'^(?P[a-zA-Z0-9-/]*)/$', views.tagged_object_list, {'list_type': 'books'}, + re_path(r'^(?P[a-zA-Z0-9-/]*)/$', views.tagged_object_list, {'list_type': 'books'}, name='tagged_object_list'), + ] diff --git a/src/catalogue/views.py b/src/catalogue/views.py index 66a2b91b0..2c6692f19 100644 --- a/src/catalogue/views.py +++ b/src/catalogue/views.py @@ -81,10 +81,13 @@ def differentiate_tags(request, tags, ambiguous_slugs): }) 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] @@ -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( - 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': @@ -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( - 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') @@ -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])) - 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)) @@ -243,7 +249,9 @@ def tagged_object_list(request, tags, list_type): 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: @@ -342,11 +350,13 @@ def import_book(request): 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")) - 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 @@ -405,7 +415,7 @@ class CustomPDFFormView(AjaxableFormView): 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) diff --git a/src/club/urls.py b/src/club/urls.py index a2dfbb966..7a3795a8b 100644 --- a/src/club/urls.py +++ b/src/club/urls.py @@ -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. # -from django.conf.urls import url +from django.urls import path 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[-a-z0-9]+)/$', banner_exempt(views.ScheduleView.as_view()), name='club_schedule'), - url(r'^plan/(?P[-a-z0-9]+)/dziekujemy/$', banner_exempt(views.ScheduleThanksView.as_view()), name='club_thanks'), + path('plan//', banner_exempt(views.ScheduleView.as_view()), name='club_schedule'), + path('plan//dziekujemy/', banner_exempt(views.ScheduleThanksView.as_view()), name='club_thanks'), - url(r'^przylacz/(?P[-a-z0-9]+)/$', views.claim, name='club_claim'), - url(r'^anuluj/(?P[-a-z0-9]+)/$', views.cancel, name='club_cancel'), - url(r'^testowa-platnosc/(?P[-a-z0-9]+)/$', views.DummyPaymentView.as_view(), name='club_dummy_payment'), + path('przylacz//', views.claim, name='club_claim'), + path('anuluj//', views.cancel, name='club_cancel'), + path('testowa-platnosc//', views.DummyPaymentView.as_view(), name='club_dummy_payment'), - url(r'platnosc/payu/cykl/(?P.+)/', banner_exempt(views.PayURecPayment.as_view()), name='club_payu_rec_payment'), - url(r'platnosc/payu/(?P.+)/', banner_exempt(views.PayUPayment.as_view()), name='club_payu_payment'), + path('platnosc/payu/cykl//', banner_exempt(views.PayURecPayment.as_view()), name='club_payu_rec_payment'), + path('platnosc/payu//', banner_exempt(views.PayUPayment.as_view()), name='club_payu_payment'), - url(r'notify/(?P\d+)/', views.PayUNotifyView.as_view(), name='club_payu_notify'), + path('notify//', 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'), ] diff --git a/src/dictionary/urls.py b/src/dictionary/urls.py index 2baf62852..3ab98fc9b 100755 --- a/src/dictionary/urls.py +++ b/src/dictionary/urls.py @@ -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. # -from django.conf.urls import url +from django.urls import path from dictionary.views import NotesView urlpatterns = [ - url(r'^$', NotesView.as_view(), name='dictionary_notes'), + path('', NotesView.as_view(), name='dictionary_notes'), ] diff --git a/src/funding/urls.py b/src/funding/urls.py index 986c4f039..3aae4eae1 100644 --- a/src/funding/urls.py +++ b/src/funding/urls.py @@ -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. # -from django.conf.urls import url, include +from django.urls import path, include from . import views urlpatterns = [ - url(r'^$', views.CurrentView.as_view(), name='funding_current'), - url(r'^teraz/$', views.CurrentView.as_view()), - url(r'^teraz/(?P[^/]+)/$', views.CurrentView.as_view(), name='funding_current'), - url(r'^lektura/$', views.OfferListView.as_view(), name='funding'), - url(r'^lektura/(?P[^/]+)/$', 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//', views.CurrentView.as_view(), name='funding_current'), + path('lektura/', views.OfferListView.as_view(), name='funding'), + path('lektura//', 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')), ] diff --git a/src/infopages/urls.py b/src/infopages/urls.py index 9d8233541..233345a5f 100755 --- a/src/infopages/urls.py +++ b/src/infopages/urls.py @@ -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. # -from django.conf.urls import url +from django.urls import path from . import views urlpatterns = [ - url(r'^(?P[a-zA-Z0-9_-]+)/$', views.infopage, name='infopage'), + path('/', views.infopage, name='infopage'), ] diff --git a/src/isbn/urls.py b/src/isbn/urls.py index 2a977e530..893831e74 100644 --- a/src/isbn/urls.py +++ b/src/isbn/urls.py @@ -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. # -from django.conf.urls import url +from django.urls import path 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[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//', views.wl_dc_tags, name='wl_dc_tags'), - url(r'^dodaj-fnp/$', views.add_isbn_fnp, name='add_isbn_fnp'), - url(r'^przypisane/(?P[a-z0-9-]*)/$', views.assigned_isbn, name='assigned_isbn'), + path('dodaj-fnp/', views.add_isbn_fnp, name='add_isbn_fnp'), + path('przypisane//', views.assigned_isbn, name='assigned_isbn'), ) diff --git a/src/lesmianator/urls.py b/src/lesmianator/urls.py index 15d6f252d..dbee5f808 100644 --- a/src/lesmianator/urls.py +++ b/src/lesmianator/urls.py @@ -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. # -from django.conf.urls import url +from django.urls import path from . import views urlpatterns = [ - url(r'^$', views.main_page, name='lesmianator'), - url(r'^wiersz/$', views.new_poem, name='new_poem'), - url(r'^lektura/(?P[a-z0-9-]+)/$', views.poem_from_book, name='poem_from_book'), - url(r'^polka/(?P[a-zA-Z0-9-]+)/$', views.poem_from_set, name='poem_from_set'), - url(r'^wiersz/(?P[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//', views.poem_from_book, name='poem_from_book'), + path('polka//', views.poem_from_set, name='poem_from_set'), + path('wiersz//', views.get_poem, name='get_poem'), ] diff --git a/src/libraries/urls.py b/src/libraries/urls.py index 3e3d78e76..9753b77fb 100644 --- a/src/libraries/urls.py +++ b/src/libraries/urls.py @@ -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. # -from django.conf.urls import url +from django.urls import path from . import views urlpatterns = [ - url(r'^$', views.main_view, name='libraries_main_view'), - url(r'^(?P[a-zA-Z0-9_-]+)$', views.catalog_view, name='libraries_catalog_view'), - url(r'^(?P[a-zA-Z0-9_-]+)/(?P[a-zA-Z0-9_-]+)$', views.library_view, name='libraries_library_view'), + path('', views.main_view, name='libraries_main_view'), + path('', views.catalog_view, name='libraries_catalog_view'), + path('/', views.library_view, name='libraries_library_view'), ] diff --git a/src/newsletter/admin.py b/src/newsletter/admin.py index 530eeca85..48134b173 100644 --- a/src/newsletter/admin.py +++ b/src/newsletter/admin.py @@ -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. # -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 @@ -16,7 +16,7 @@ class SubscriptionAdmin(admin.ModelAdmin): 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 diff --git a/src/newsletter/urls.py b/src/newsletter/urls.py index c99b47a43..bfae579a4 100644 --- a/src/newsletter/urls.py +++ b/src/newsletter/urls.py @@ -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. # -from django.conf.urls import url +from django.urls import path from . import views urlpatterns = [ - url(r'^zapisz-sie/$', views.subscribe_form, name='subscribe'), - url(r'^zapis/$', views.subscribed, name='subscribed'), - url(r'^potwierdzenie/(?P[0-9]+)/(?P[0-9a-f]+)/$', + path('zapisz-sie/', views.subscribe_form, name='subscribe'), + path('zapis/', views.subscribed, name='subscribed'), + path('potwierdzenie///', 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'), ] diff --git a/src/oai/urls.py b/src/oai/urls.py index 2088a8aad..85c31afe2 100644 --- a/src/oai/urls.py +++ b/src/oai/urls.py @@ -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. # -from django.conf.urls import url +from django.urls import path from . import views urlpatterns = [ - url(r'^$', views.oaipmh, name='oaipmh') + path('', views.oaipmh, name='oaipmh') ] diff --git a/src/opds/urls.py b/src/opds/urls.py index 213c55af8..1d681992c 100644 --- a/src/opds/urls.py +++ b/src/opds/urls.py @@ -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. # -from django.conf.urls import url +from django.urls import path 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[a-zA-Z0-9-]+)/$', UserSetFeed(), name="opds_user_set"), - url(r'^(?P[a-zA-Z0-9-]+)/$', ByCategoryFeed(), name="opds_by_category"), - url(r'^(?P[a-zA-Z0-9-]+)/(?P[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//', UserSetFeed(), name="opds_user_set"), + path('/', ByCategoryFeed(), name="opds_by_category"), + path('//', ByTagFeed(), name="opds_by_tag"), ] diff --git a/src/paypal/urls.py b/src/paypal/urls.py index bd2699398..aca891850 100644 --- a/src/paypal/urls.py +++ b/src/paypal/urls.py @@ -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. # -from django.conf.urls import url +from django.urls import path 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'), ) diff --git a/src/picture/api/urls.py b/src/picture/api/urls.py index cb457f501..95fd10356 100644 --- a/src/picture/api/urls.py +++ b/src/picture/api/urls.py @@ -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. # -from django.conf.urls import url +from django.urls import path from . import views urlpatterns = [ - url(r'^$', views.PicturesView.as_view()), + path('', views.PicturesView.as_view()), ] diff --git a/src/polls/urls.py b/src/polls/urls.py index 897686b8a..f2d3a023a 100644 --- a/src/polls/urls.py +++ b/src/polls/urls.py @@ -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. # -from django.conf.urls import url +from django.urls import path from . import views urlpatterns = [ - url(r'^(?P[^/]+)$', views.poll, name='poll'), + path('', views.poll, name='poll'), ] diff --git a/src/push/urls.py b/src/push/urls.py index c7f64d966..a92a55ff1 100644 --- a/src/push/urls.py +++ b/src/push/urls.py @@ -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. # -from django.conf.urls import url +from django.urls import path 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'), ] diff --git a/src/reporting/urls.py b/src/reporting/urls.py index fa7ceb28d..a9ae44a3a 100755 --- a/src/reporting/urls.py +++ b/src/reporting/urls.py @@ -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. # -from django.conf.urls import url +from django.urls import path 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'), ] diff --git a/src/search/urls.py b/src/search/urls.py index 980f5e865..46e73c5bc 100644 --- a/src/search/urls.py +++ b/src/search/urls.py @@ -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. # -from django.conf.urls import url +from django.urls import path 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'), ] diff --git a/src/social/api/urls.py b/src/social/api/urls.py index 2ed2d66d1..2b20ab8a1 100644 --- a/src/social/api/urls.py +++ b/src/social/api/urls.py @@ -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. # -from django.conf.urls import include, url +from django.urls import path from stats.utils import piwik_track_view from . import views urlpatterns = [ - url(r'^like/(?P[a-z0-9-]+)/$', + path('like//', piwik_track_view(views.LikeView.as_view()), name='social_api_like'), - url(r'^shelf/(?P[a-z]+)/$', + path('shelf//', piwik_track_view(views.ShelfView.as_view()), name='social_api_shelf'), ] diff --git a/src/social/urls.py b/src/social/urls.py index 6b7895084..e092ff0bf 100644 --- a/src/social/urls.py +++ b/src/social/urls.py @@ -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. # -from django.conf.urls import url +from django.urls import path from django.views.decorators.cache import never_cache from . import views urlpatterns = [ - url(r'^lektura/(?P[a-z0-9-]+)/lubie/$', views.like_book, name='social_like_book'), - url(r'^lektura/(?P[a-z0-9-]+)/nie_lubie/$', views.unlike_book, name='social_unlike_book'), - url(r'^lektura/(?P[a-z0-9-]+)/polki/$', never_cache(views.ObjectSetsFormView()), name='social_book_sets'), - url(r'^polka/$', views.my_shelf, name='social_my_shelf'), + path('lektura//lubie/', views.like_book, name='social_like_book'), + path('lektura//nie_lubie/', views.unlike_book, name='social_unlike_book'), + path('lektura//polki/', never_cache(views.ObjectSetsFormView()), name='social_book_sets'), + path('polka/', views.my_shelf, name='social_my_shelf'), ] diff --git a/src/suggest/urls.py b/src/suggest/urls.py index 4a03a0d35..7f15ac56d 100644 --- a/src/suggest/urls.py +++ b/src/suggest/urls.py @@ -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. # -from django.conf.urls import url +from django.urls import path 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'), ] diff --git a/src/waiter/urls.py b/src/waiter/urls.py index ffe9805f4..1c8b17f2c 100644 --- a/src/waiter/urls.py +++ b/src/waiter/urls.py @@ -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. # -from django.conf.urls import url +from django.urls import path from waiter import views urlpatterns = [ - url(r'^(?P.*)$', views.wait, name='waiter'), + path('', views.wait, name='waiter'), ] diff --git a/src/wolnelektury/templates/base/app.html b/src/wolnelektury/templates/base/app.html index 43b6d954a..b2150817f 100644 --- a/src/wolnelektury/templates/base/app.html +++ b/src/wolnelektury/templates/base/app.html @@ -2,7 +2,7 @@ {% spaceless %} {% load pipeline i18n %} - {% load static from staticfiles %} + {% load static %} {% load piwik_tags %} {% get_current_language as LANGUAGE_CODE %} diff --git a/src/wolnelektury/templates/base/superbase.html b/src/wolnelektury/templates/base/superbase.html index bd7de37e0..cdbdb69a0 100644 --- a/src/wolnelektury/templates/base/superbase.html +++ b/src/wolnelektury/templates/base/superbase.html @@ -2,7 +2,7 @@ {% spaceless %} {% load pipeline i18n %} - {% load static from staticfiles %} + {% load static %} {% load catalogue_tags funding_tags reporting_stats %} {% load piwik_tags %} {% load cache %} diff --git a/src/wolnelektury/templates/main_page.html b/src/wolnelektury/templates/main_page.html index 71731b98d..9d5b1fbb3 100644 --- a/src/wolnelektury/templates/main_page.html +++ b/src/wolnelektury/templates/main_page.html @@ -1,7 +1,7 @@ {% 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 %} diff --git a/src/wolnelektury/templates/widget.html b/src/wolnelektury/templates/widget.html index de79b5632..3eb3422da 100644 --- a/src/wolnelektury/templates/widget.html +++ b/src/wolnelektury/templates/widget.html @@ -1,5 +1,5 @@ {% spaceless %} - {% load static from staticfiles %} + {% load static %} {% load pipeline %} diff --git a/src/wolnelektury/urls.py b/src/wolnelektury/urls.py index c328c83f5..af6244ccc 100644 --- a/src/wolnelektury/urls.py +++ b/src/wolnelektury/urls.py @@ -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. # -from django.conf.urls import include, url 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 @@ -12,100 +12,97 @@ from . import views 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 - 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 += [ - 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(r'^towarzystwo/dolacz/$', RedirectView.as_view( + path('towarzystwo/dolacz/', RedirectView.as_view( 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 - 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 - url(r'^api/', include('api.urls')), + path('api/', include('api.urls')), # 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 - url(r'^1procent/$', RedirectView.as_view( + path('1procent/', RedirectView.as_view( 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(r'^mozesz-nam-pomoc/$', RedirectView.as_view( + path('mozesz-nam-pomoc/', RedirectView.as_view( 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(r'^widget/$', RedirectView.as_view( + path('widget/', RedirectView.as_view( 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(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 = [ - url(r'^__debug__/', include(debug_toolbar.urls)), + path('__debug__/', include(debug_toolbar.urls)), ] + urlpatterns if settings.DEBUG: urlpatterns += [ # Static files - url(r'^%s(?P.*)$' % settings.MEDIA_URL[1:], django.views.static.serve, + path('%s' % settings.MEDIA_URL[1:], django.views.static.serve, {'document_root': settings.MEDIA_ROOT, 'show_indexes': True}), - url(r'^%s(?P.*)$' % settings.STATIC_URL[1:], django.views.static.serve, - {'document_root': settings.STATIC_ROOT, 'show_indexes': True}), ] -- 2.20.1