From d02877bdce71aefb921239a024a70bf2b6120cda Mon Sep 17 00:00:00 2001 From: Gabriel Augendre Date: Fri, 23 Sep 2022 20:47:19 +0100 Subject: [PATCH] Fix type annotations --- poetry.lock | 116 ++++++++++++++++------------- pyproject.toml | 1 + src/articles/admin.py | 15 ++-- src/articles/context_processors.py | 14 ++-- src/articles/utils.py | 4 +- src/articles/views/api.py | 6 +- src/articles/views/feeds.py | 4 +- src/articles/views/html.py | 6 +- src/attachments/admin.py | 6 +- src/attachments/models.py | 4 +- src/blog/settings.py | 1 + 11 files changed, 99 insertions(+), 78 deletions(-) diff --git a/poetry.lock b/poetry.lock index 78379b5..302e863 100644 --- a/poetry.lock +++ b/poetry.lock @@ -54,6 +54,14 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "cerberus" +version = "1.3.4" +description = "Lightweight, extensible schema and data validation tool for Python dictionaries." +category = "dev" +optional = false +python-versions = ">=2.7" + [[package]] name = "certifi" version = "2021.10.8" @@ -81,6 +89,17 @@ python-versions = ">=3.5.0" [package.extras] unicode_backport = ["unicodedata2"] +[[package]] +name = "click" +version = "8.1.3" +description = "Composable command line interface toolkit" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + [[package]] name = "colorama" version = "0.4.4" @@ -91,14 +110,14 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "coverage" -version = "6.3.2" +version = "6.4.4" description = "Code coverage measurement for Python" category = "dev" optional = false python-versions = ">=3.7" [package.dependencies] -tomli = {version = "*", optional = true, markers = "extra == \"toml\""} +tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} [package.extras] toml = ["tomli"] @@ -138,8 +157,8 @@ bcrypt = ["bcrypt"] [[package]] name = "django-anymail" -version = "8.5" -description = "Django email integration for Amazon SES, Mailgun, Mailjet, Postmark, SendGrid, SendinBlue, SparkPost and other transactional ESPs" +version = "8.6" +description = "Django email backends and webhooks for Amazon SES, Mailgun, Mailjet, Mandrill, Postal, Postmark, SendGrid, SendinBlue, and SparkPost" category = "main" optional = false python-versions = ">=3.5" @@ -332,6 +351,24 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "kolo" +version = "2.0.3" +description = "See everything happening in your running Django app" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +cerberus = ">=1.3.4" +click = ">=7.1.2" +tomli = {version = ">=2.0.0", markers = "python_version < \"3.11\""} +toolz = ">=0.11.1" +ulid-py = ">=1.1.0" + +[package.extras] +test_generation = ["jinja2 (>=3.0.0)"] + [[package]] name = "lxml" version = "4.8.0" @@ -763,6 +800,14 @@ category = "dev" optional = false python-versions = ">=3.7" +[[package]] +name = "toolz" +version = "0.12.0" +description = "List processing tools and functional utilities" +category = "dev" +optional = false +python-versions = ">=3.5" + [[package]] name = "types-beautifulsoup4" version = "4.10.19" @@ -838,6 +883,14 @@ category = "main" optional = false python-versions = ">=2" +[[package]] +name = "ulid-py" +version = "1.1.0" +description = "Universally Unique Lexicographically Sortable Identifier" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "urllib3" version = "1.26.9" @@ -920,7 +973,7 @@ multidict = ">=4.0" [metadata] lock-version = "1.1" python-versions = "^3.10" -content-hash = "c028a335a533ac4671836cf273e5026afa6b7324634116653f3d7631d030bbcc" +content-hash = "7940617ffd193623a91d63618c413a52c334673b2cf47d1749a9ff25e1693dc6" [metadata.files] asgiref = [ @@ -1003,6 +1056,7 @@ brotli = [ {file = "Brotli-1.0.9-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:76ffebb907bec09ff511bb3acc077695e2c32bc2142819491579a695f77ffd4d"}, {file = "Brotli-1.0.9.zip", hash = "sha256:4d1b810aa0ed773f81dceda2cc7b403d01057458730e309856356d4ef4188438"}, ] +cerberus = [] certifi = [ {file = "certifi-2021.10.8-py2.py3-none-any.whl", hash = "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"}, {file = "certifi-2021.10.8.tar.gz", hash = "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872"}, @@ -1015,53 +1069,12 @@ charset-normalizer = [ {file = "charset-normalizer-2.0.12.tar.gz", hash = "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597"}, {file = "charset_normalizer-2.0.12-py3-none-any.whl", hash = "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df"}, ] +click = [] colorama = [ {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, ] -coverage = [ - {file = "coverage-6.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9b27d894748475fa858f9597c0ee1d4829f44683f3813633aaf94b19cb5453cf"}, - {file = "coverage-6.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:37d1141ad6b2466a7b53a22e08fe76994c2d35a5b6b469590424a9953155afac"}, - {file = "coverage-6.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9987b0354b06d4df0f4d3e0ec1ae76d7ce7cbca9a2f98c25041eb79eec766f1"}, - {file = "coverage-6.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:26e2deacd414fc2f97dd9f7676ee3eaecd299ca751412d89f40bc01557a6b1b4"}, - {file = "coverage-6.3.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4dd8bafa458b5c7d061540f1ee9f18025a68e2d8471b3e858a9dad47c8d41903"}, - {file = "coverage-6.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:46191097ebc381fbf89bdce207a6c107ac4ec0890d8d20f3360345ff5976155c"}, - {file = "coverage-6.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6f89d05e028d274ce4fa1a86887b071ae1755082ef94a6740238cd7a8178804f"}, - {file = "coverage-6.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:58303469e9a272b4abdb9e302a780072c0633cdcc0165db7eec0f9e32f901e05"}, - {file = "coverage-6.3.2-cp310-cp310-win32.whl", hash = "sha256:2fea046bfb455510e05be95e879f0e768d45c10c11509e20e06d8fcaa31d9e39"}, - {file = "coverage-6.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:a2a8b8bcc399edb4347a5ca8b9b87e7524c0967b335fbb08a83c8421489ddee1"}, - {file = "coverage-6.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:f1555ea6d6da108e1999b2463ea1003fe03f29213e459145e70edbaf3e004aaa"}, - {file = "coverage-6.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5f4e1edcf57ce94e5475fe09e5afa3e3145081318e5fd1a43a6b4539a97e518"}, - {file = "coverage-6.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7a15dc0a14008f1da3d1ebd44bdda3e357dbabdf5a0b5034d38fcde0b5c234b7"}, - {file = "coverage-6.3.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21b7745788866028adeb1e0eca3bf1101109e2dc58456cb49d2d9b99a8c516e6"}, - {file = "coverage-6.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:8ce257cac556cb03be4a248d92ed36904a59a4a5ff55a994e92214cde15c5bad"}, - {file = "coverage-6.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b0be84e5a6209858a1d3e8d1806c46214e867ce1b0fd32e4ea03f4bd8b2e3359"}, - {file = "coverage-6.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:acf53bc2cf7282ab9b8ba346746afe703474004d9e566ad164c91a7a59f188a4"}, - {file = "coverage-6.3.2-cp37-cp37m-win32.whl", hash = "sha256:8bdde1177f2311ee552f47ae6e5aa7750c0e3291ca6b75f71f7ffe1f1dab3dca"}, - {file = "coverage-6.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:b31651d018b23ec463e95cf10070d0b2c548aa950a03d0b559eaa11c7e5a6fa3"}, - {file = "coverage-6.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:07e6db90cd9686c767dcc593dff16c8c09f9814f5e9c51034066cad3373b914d"}, - {file = "coverage-6.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2c6dbb42f3ad25760010c45191e9757e7dce981cbfb90e42feef301d71540059"}, - {file = "coverage-6.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c76aeef1b95aff3905fb2ae2d96e319caca5b76fa41d3470b19d4e4a3a313512"}, - {file = "coverage-6.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8cf5cfcb1521dc3255d845d9dca3ff204b3229401994ef8d1984b32746bb45ca"}, - {file = "coverage-6.3.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8fbbdc8d55990eac1b0919ca69eb5a988a802b854488c34b8f37f3e2025fa90d"}, - {file = "coverage-6.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ec6bc7fe73a938933d4178c9b23c4e0568e43e220aef9472c4f6044bfc6dd0f0"}, - {file = "coverage-6.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9baff2a45ae1f17c8078452e9e5962e518eab705e50a0aa8083733ea7d45f3a6"}, - {file = "coverage-6.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fd9e830e9d8d89b20ab1e5af09b32d33e1a08ef4c4e14411e559556fd788e6b2"}, - {file = "coverage-6.3.2-cp38-cp38-win32.whl", hash = "sha256:f7331dbf301b7289013175087636bbaf5b2405e57259dd2c42fdcc9fcc47325e"}, - {file = "coverage-6.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:68353fe7cdf91f109fc7d474461b46e7f1f14e533e911a2a2cbb8b0fc8613cf1"}, - {file = "coverage-6.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b78e5afb39941572209f71866aa0b206c12f0109835aa0d601e41552f9b3e620"}, - {file = "coverage-6.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4e21876082ed887baed0146fe222f861b5815455ada3b33b890f4105d806128d"}, - {file = "coverage-6.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34626a7eee2a3da12af0507780bb51eb52dca0e1751fd1471d0810539cefb536"}, - {file = "coverage-6.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1ebf730d2381158ecf3dfd4453fbca0613e16eaa547b4170e2450c9707665ce7"}, - {file = "coverage-6.3.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd6fe30bd519694b356cbfcaca9bd5c1737cddd20778c6a581ae20dc8c04def2"}, - {file = "coverage-6.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:96f8a1cb43ca1422f36492bebe63312d396491a9165ed3b9231e778d43a7fca4"}, - {file = "coverage-6.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:dd035edafefee4d573140a76fdc785dc38829fe5a455c4bb12bac8c20cfc3d69"}, - {file = "coverage-6.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5ca5aeb4344b30d0bec47481536b8ba1181d50dbe783b0e4ad03c95dc1296684"}, - {file = "coverage-6.3.2-cp39-cp39-win32.whl", hash = "sha256:f5fa5803f47e095d7ad8443d28b01d48c0359484fec1b9d8606d0e3282084bc4"}, - {file = "coverage-6.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:9548f10d8be799551eb3a9c74bbf2b4934ddb330e08a73320123c07f95cc2d92"}, - {file = "coverage-6.3.2-pp36.pp37.pp38-none-any.whl", hash = "sha256:18d520c6860515a771708937d2f78f63cc47ab3b80cb78e86573b0a760161faf"}, - {file = "coverage-6.3.2.tar.gz", hash = "sha256:03e2a7826086b91ef345ff18742ee9fc47a6839ccd517061ef8fa1976e652ce9"}, -] +coverage = [] cssselect = [ {file = "cssselect-1.1.0-py2.py3-none-any.whl", hash = "sha256:f612ee47b749c877ebae5bb77035d8f4202c6ad0f0fc1271b3c18ad6c4468ecf"}, {file = "cssselect-1.1.0.tar.gz", hash = "sha256:f95f8dedd925fd8f54edb3d2dfb44c190d9d18512377d3c1e2388d16126879bc"}, @@ -1075,8 +1088,8 @@ django = [ {file = "Django-4.0.4.tar.gz", hash = "sha256:4e8177858524417563cc0430f29ea249946d831eacb0068a1455686587df40b5"}, ] django-anymail = [ - {file = "django-anymail-8.5.tar.gz", hash = "sha256:677e937dc9e2671ca7631abb1d94ddc6b840beb3d53c0fbf699e866a6a9ba92f"}, - {file = "django_anymail-8.5-py3-none-any.whl", hash = "sha256:2325932f56f914d96e0a54db850f2b246ed2277b753f75319620d051a51551e2"}, + {file = "django-anymail-8.6.tar.gz", hash = "sha256:783342d49dd07d68778b81dd12a94c86e1d217463a68a85450a0513fabe31345"}, + {file = "django_anymail-8.6-py3-none-any.whl", hash = "sha256:49d83d7c16316ca86a624097496881d59b7d71b16bf1c5211cffa5b19ef98d0c"}, ] django-cleanup = [ {file = "django-cleanup-5.2.0.tar.gz", hash = "sha256:909d10ff574f5ce1a40fa63bd5c94c9ed866fd7ae770994c46cdf66c3db3e846"}, @@ -1131,6 +1144,7 @@ invoke = [ {file = "invoke-1.7.0-py3-none-any.whl", hash = "sha256:a5159fc63dba6ca2a87a1e33d282b99cea69711b03c64a35bb4e1c53c6c4afa0"}, {file = "invoke-1.7.0.tar.gz", hash = "sha256:e332e49de40463f2016315f51df42313855772be86435686156bc18f45b5cc6c"}, ] +kolo = [] lxml = [ {file = "lxml-4.8.0-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:e1ab2fac607842ac36864e358c42feb0960ae62c34aa4caaf12ada0a1fb5d99b"}, {file = "lxml-4.8.0-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28d1af847786f68bec57961f31221125c29d6f52d9187c01cd34dc14e2b29430"}, @@ -1503,6 +1517,7 @@ tomli = [ {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] +toolz = [] types-beautifulsoup4 = [ {file = "types-beautifulsoup4-4.10.19.tar.gz", hash = "sha256:dfbee0b788fdd0e59c2a62594b3152abff639bba5ad01e55628bd5e39adc8010"}, {file = "types_beautifulsoup4-4.10.19-py3-none-any.whl", hash = "sha256:209030fecc9770ebed79e94a308aa29009d53c81fe08f0b5dff1d837cd00bdd7"}, @@ -1539,6 +1554,7 @@ tzdata = [ {file = "tzdata-2022.1-py2.py3-none-any.whl", hash = "sha256:238e70234214138ed7b4e8a0fab0e5e13872edab3be586ab8198c407620e2ab9"}, {file = "tzdata-2022.1.tar.gz", hash = "sha256:8b536a8ec63dc0751342b3984193a3118f8fca2afe25752bb9b7fffd398552d3"}, ] +ulid-py = [] urllib3 = [ {file = "urllib3-1.26.9-py2.py3-none-any.whl", hash = "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14"}, {file = "urllib3-1.26.9.tar.gz", hash = "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e"}, diff --git a/pyproject.toml b/pyproject.toml index 14201c2..9d275f5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,6 +42,7 @@ types-setuptools = "^57.4.5" types-toml = "^0.10.1" types-beautifulsoup4 = "^4.10.7" types-Pillow = "^8.3.11" +kolo = "^2.0.3" [tool.black] target-version = ['py310'] diff --git a/src/articles/admin.py b/src/articles/admin.py index 7264dde..6cb40f4 100644 --- a/src/articles/admin.py +++ b/src/articles/admin.py @@ -3,8 +3,9 @@ from typing import cast from django.contrib import admin, messages from django.contrib.admin import register from django.contrib.auth.admin import UserAdmin +from django.core.handlers.wsgi import WSGIRequest from django.db.models import QuerySet -from django.http import HttpRequest, HttpResponse, HttpResponseRedirect +from django.http import HttpResponse, HttpResponseRedirect from django.shortcuts import redirect from .models import Article, Tag, User @@ -77,13 +78,13 @@ class ArticleAdmin(admin.ModelAdmin): autocomplete_fields = ["tags"] show_full_result_count = False - def get_queryset(self, request: HttpRequest) -> QuerySet: + def get_queryset(self, request: WSGIRequest) -> QuerySet: queryset = super().get_queryset(request) queryset = queryset.prefetch_related("tags") return queryset @admin.action(description="Publish selected articles") - def publish(self, request: HttpRequest, queryset: QuerySet) -> None: + def publish(self, request: WSGIRequest, queryset: QuerySet) -> None: if not request.user.has_perm("articles.change_article"): messages.warning(request, "You're not allowed to do this.") return @@ -92,7 +93,7 @@ class ArticleAdmin(admin.ModelAdmin): messages.success(request, f"{len(queryset)} articles published.") @admin.action(description="Unpublish selected articles") - def unpublish(self, request: HttpRequest, queryset: QuerySet) -> None: + def unpublish(self, request: WSGIRequest, queryset: QuerySet) -> None: if not request.user.has_perm("articles.change_article"): messages.warning(request, "You're not allowed to do this.") return @@ -101,7 +102,7 @@ class ArticleAdmin(admin.ModelAdmin): messages.success(request, f"{len(queryset)} articles unpublished.") @admin.action(description="Refresh draft key of selected articles") - def refresh_draft_key(self, request: HttpRequest, queryset: QuerySet) -> None: + def refresh_draft_key(self, request: WSGIRequest, queryset: QuerySet) -> None: if not request.user.has_perm("articles.change_article"): messages.warning(request, "You're not allowed to do this.") return @@ -120,13 +121,13 @@ class ArticleAdmin(admin.ModelAdmin): } def response_post_save_add( - self, request: HttpRequest, obj: Article + self, request: WSGIRequest, obj: Article ) -> HttpResponseRedirect: if "_preview" in request.POST: return cast(HttpResponseRedirect, redirect("article-detail", slug=obj.slug)) return super().response_post_save_add(request, obj) - def response_change(self, request: HttpRequest, obj: Article) -> HttpResponse: + def response_change(self, request: WSGIRequest, obj: Article) -> HttpResponse: if "_preview" in request.POST: obj.save() return redirect("article-detail", slug=obj.slug) diff --git a/src/articles/context_processors.py b/src/articles/context_processors.py index f567618..3236ff4 100644 --- a/src/articles/context_processors.py +++ b/src/articles/context_processors.py @@ -2,7 +2,7 @@ import copy from typing import Any from django.conf import settings -from django.http import HttpRequest +from django.core.handlers.wsgi import WSGIRequest from articles.models import Article from attachments.models import Attachment @@ -12,7 +12,7 @@ IGNORED_PATHS = [ ] -def drafts_count(request: HttpRequest) -> dict[str, Any]: +def drafts_count(request: WSGIRequest) -> dict[str, Any]: if request.path in IGNORED_PATHS: return {} if not request.user.is_authenticated: @@ -20,13 +20,13 @@ def drafts_count(request: HttpRequest) -> dict[str, Any]: return {"drafts_count": Article.objects.filter(status=Article.DRAFT).count()} -def date_format(request: HttpRequest) -> dict[str, Any]: +def date_format(request: WSGIRequest) -> dict[str, Any]: if request.path in IGNORED_PATHS: return {} return {"CUSTOM_ISO": r"Y-m-d\TH:i:sO", "ISO_DATE": "Y-m-d"} -def git_version(request: HttpRequest) -> dict[str, Any]: +def git_version(request: WSGIRequest) -> dict[str, Any]: if request.path in IGNORED_PATHS: return {} try: @@ -40,13 +40,13 @@ def git_version(request: HttpRequest) -> dict[str, Any]: return {"git_version": version, "git_version_url": url} -def analytics(request: HttpRequest) -> dict[str, Any]: +def analytics(request: WSGIRequest) -> dict[str, Any]: return { "goatcounter_domain": settings.GOATCOUNTER_DOMAIN, } -def open_graph_image_url(request: HttpRequest) -> dict[str, Any]: +def open_graph_image_url(request: WSGIRequest) -> dict[str, Any]: if request.path in IGNORED_PATHS: return {} open_graph_image = Attachment.objects.get_open_graph_image() @@ -56,7 +56,7 @@ def open_graph_image_url(request: HttpRequest) -> dict[str, Any]: return {"open_graph_image_url": url} -def blog_metadata(request: HttpRequest) -> dict[str, Any]: +def blog_metadata(request: WSGIRequest) -> dict[str, Any]: blog_settings = copy.deepcopy(settings.BLOG) return { "blog": blog_settings, diff --git a/src/articles/utils.py b/src/articles/utils.py index 033e9bf..ee00254 100644 --- a/src/articles/utils.py +++ b/src/articles/utils.py @@ -3,14 +3,14 @@ import re import markdown from bs4 import BeautifulSoup from django.conf import settings -from django.http import HttpRequest +from django.core.handlers.wsgi import WSGIRequest from markdown.extensions.codehilite import CodeHiliteExtension from markdown.extensions.toc import TocExtension from articles.markdown import LazyLoadingImageExtension -def build_full_absolute_url(request: HttpRequest | None, url: str) -> str: +def build_full_absolute_url(request: WSGIRequest | None, url: str) -> str: if request: return request.build_absolute_uri(url) else: diff --git a/src/articles/views/api.py b/src/articles/views/api.py index a6d41c8..1b6f3f1 100644 --- a/src/articles/views/api.py +++ b/src/articles/views/api.py @@ -1,7 +1,8 @@ from typing import Any from django.contrib.auth.decorators import login_required -from django.http import HttpRequest, HttpResponse +from django.core.handlers.wsgi import WSGIRequest +from django.http import HttpResponse from django.shortcuts import render from django.views.decorators.http import require_POST @@ -10,7 +11,8 @@ from articles.models import Article, Tag @login_required @require_POST -def render_article(request: HttpRequest, article_pk: int) -> HttpResponse: +def render_article(request: WSGIRequest, article_pk: int) -> HttpResponse: + print(f"{type(request)=}") template = "articles/article_detail.html" article = Article.objects.get(pk=article_pk) article.content = request.POST.get("content", article.content) diff --git a/src/articles/views/feeds.py b/src/articles/views/feeds.py index eaa507a..41c1ead 100644 --- a/src/articles/views/feeds.py +++ b/src/articles/views/feeds.py @@ -2,8 +2,8 @@ from datetime import datetime from typing import Any, Iterable from django.contrib.syndication.views import Feed +from django.core.handlers.wsgi import WSGIRequest from django.db.models import QuerySet -from django.http import HttpRequest from articles.models import Article, Tag from blog import settings @@ -34,7 +34,7 @@ class CompleteFeed(BaseFeed): class TagFeed(BaseFeed): - def get_object(self, request: HttpRequest, *args: Any, **kwargs: Any) -> Tag: + def get_object(self, request: WSGIRequest, *args: Any, **kwargs: Any) -> Tag: return Tag.objects.get(slug=kwargs.get("slug")) def title(self, tag: Tag) -> str: diff --git a/src/articles/views/html.py b/src/articles/views/html.py index d08c980..caef2fd 100644 --- a/src/articles/views/html.py +++ b/src/articles/views/html.py @@ -4,10 +4,10 @@ from typing import Any from django.conf import settings from django.contrib.auth.mixins import LoginRequiredMixin +from django.core.handlers.wsgi import WSGIRequest from django.core.paginator import Page from django.db.models import F, Q, QuerySet -from django.http import HttpRequest -from django.http.response import HttpResponseBase +from django.http.response import HttpResponse, HttpResponseBase from django.shortcuts import get_object_or_404 from django.views import generic from django.views.generic import DetailView @@ -101,7 +101,7 @@ class TagArticlesListView(PublicArticleListView): html_title = "" def dispatch( - self, request: HttpRequest, *args: Any, **kwargs: Any + self, request: WSGIRequest, *args: Any, **kwargs: Any ) -> HttpResponseBase: self.tag = get_object_or_404(Tag, slug=self.kwargs.get("slug")) self.main_title = self.html_title = f"{self.tag.name} articles" diff --git a/src/attachments/admin.py b/src/attachments/admin.py index 0eb3ccb..14672a7 100644 --- a/src/attachments/admin.py +++ b/src/attachments/admin.py @@ -1,7 +1,7 @@ from django.contrib import admin, messages from django.contrib.admin import register +from django.core.handlers.wsgi import WSGIRequest from django.db.models import QuerySet -from django.http import HttpRequest from django.utils.html import format_html from attachments.models import Attachment @@ -59,7 +59,7 @@ class AttachmentAdmin(admin.ModelAdmin): return "" @admin.action(description="Set as open graph image") - def set_as_open_graph_image(self, request: HttpRequest, queryset: QuerySet) -> None: + def set_as_open_graph_image(self, request: WSGIRequest, queryset: QuerySet) -> None: if len(queryset) != 1: messages.error(request, "You must select only one attachment") return @@ -69,7 +69,7 @@ class AttachmentAdmin(admin.ModelAdmin): @admin.action(description="Reprocess selected attachments") def reprocess_selected_attachments( - self, request: HttpRequest, queryset: QuerySet + self, request: WSGIRequest, queryset: QuerySet ) -> None: if len(queryset) == 0: messages.error(request, "You must select at least one attachment") diff --git a/src/attachments/models.py b/src/attachments/models.py index 8758d6a..24a8ff5 100644 --- a/src/attachments/models.py +++ b/src/attachments/models.py @@ -8,16 +8,16 @@ from typing import Any import requests from django.conf import settings from django.core.files import File +from django.core.handlers.wsgi import WSGIRequest from django.db import models from django.db.models.fields.files import FieldFile -from django.http import HttpRequest from PIL import Image from articles.utils import build_full_absolute_url class AbsoluteUrlFieldFile(FieldFile): - def get_full_absolute_url(self, request: HttpRequest) -> str: + def get_full_absolute_url(self, request: WSGIRequest) -> str: return build_full_absolute_url(request, self.url) diff --git a/src/blog/settings.py b/src/blog/settings.py index 529e1fd..a57f4cd 100644 --- a/src/blog/settings.py +++ b/src/blog/settings.py @@ -96,6 +96,7 @@ INSTALLED_APPS = [ ] MIDDLEWARE = [ + "kolo.middleware.KoloMiddleware", "django.middleware.security.SecurityMiddleware", "whitenoise.middleware.WhiteNoiseMiddleware", "django.middleware.gzip.GZipMiddleware",