-i https://py.mdrn.pl/simple/
# django
-Django==2.2.6
+Django==2.2.8
fnpdjango==0.4
docutils
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()
# 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):
"""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):
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.
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:
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)
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."""
class BannerAdmin(TranslationAdmin):
list_display = ['place', 'text', 'priority', 'since', 'until', 'show_members', 'staff_preview']
-
+
admin.site.register(models.Banner, BannerAdmin)
fields = ['text', 'image', 'own_colors', 'background_color', 'text_color']
extra = 0
min_num = 1
-
+
class DynamicTextInsertAdmin(admin.ModelAdmin):
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(
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)
+++ /dev/null
-from django.test import TestCase
-
-# Create your tests here.
fields = ('text',)
-
translator.register(models.Banner, BannerTranslationOptions)
-
-
+++ /dev/null
-from django.shortcuts import render
-
-# Create your views here.
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:
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', [])
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)
instance.complete = state == 'complete'
instance.save()
return instance
-from django.conf import settings
KEY_SIZE = 18
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)
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):
item_tag_name = 'resource'
root_tag_name = 'response'
-
#
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
# 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(
# 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))
# 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
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<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
- 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')),
]
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
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(
response.status_code = 401
response['WWW-Authenticate'] = 'Basic realm="%s"' % realm
return response
-
+
#
def logged_in_or_basicauth(realm=""):
# 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
# 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'}
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
# 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
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',)
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:
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')
# 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
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"),
]
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']
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)
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)
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:
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)
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(
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):
longMessage = True
-class PersonStub(object):
+class PersonStub:
def __init__(self, first_names, last_name):
self.first_names = first_names
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 = {
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())
)
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()
"""
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 """
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()
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.")
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,
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.'
)
</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')
# 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
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<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
- 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'),
- 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<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
- 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.
- 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.
- 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'),
- 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'),
- 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'),
+
]
})
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]
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':
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')
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))
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:
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
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)
# 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<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'),
]
# 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'),
]
# 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<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')),
]
# 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<slug>[a-zA-Z0-9_-]+)/$', views.infopage, name='infopage'),
+ path('<slug>/', views.infopage, name='infopage'),
]
# 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<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'),
)
# 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<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'),
]
# 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<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'),
]
# 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
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
# 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<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'),
- 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'),
]
# 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')
]
# 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<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"),
]
# 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'),
)
# 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()),
]
# 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<slug>[^/]+)$', views.poll, name='poll'),
+ path('<slug:slug>', views.poll, name='poll'),
]
# 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'),
]
# 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'),
]
# 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'),
]
# 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<slug>[a-z0-9-]+)/$',
+ path('like/<slug:slug>/',
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'),
]
# 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<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'),
]
# 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'),
]
# 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<path>.*)$', views.wait, name='waiter'),
+ path('<path:path>', views.wait, name='waiter'),
]
{% 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>
{% 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 %}
{% 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 %}
{% spaceless %}
- {% load static from staticfiles %}
+ {% load static %}
{% load pipeline %}
<!DOCTYPE html>
# 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
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<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}),
- url(r'^%s(?P<path>.*)$' % settings.STATIC_URL[1:], django.views.static.serve,
- {'document_root': settings.STATIC_ROOT, 'show_indexes': True}),
]