Update deps
This commit is contained in:
parent
d02877bdce
commit
5b5f03afaf
14 changed files with 348 additions and 629 deletions
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"env": {
|
"env": {
|
||||||
"browser": true,
|
"browser": true,
|
||||||
"es6": true,
|
"es2019": true,
|
||||||
"jquery": true
|
"jquery": true
|
||||||
},
|
},
|
||||||
"extends": [
|
"extends": [
|
||||||
|
@ -45,7 +45,6 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"ecmaVersion": 6,
|
|
||||||
"sourceType": "module"
|
"sourceType": "module"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
2
.kolo/config.toml
Normal file
2
.kolo/config.toml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[filters]
|
||||||
|
ignore_request_paths = ["/static/"]
|
|
@ -1,7 +1,7 @@
|
||||||
exclude: (\.min\.(js|css)(\.map)?$|/vendor/)
|
exclude: (\.min\.(js|css)(\.map)?$|/vendor/)
|
||||||
repos:
|
repos:
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
rev: v4.1.0
|
rev: v4.3.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: check-ast
|
- id: check-ast
|
||||||
- id: check-json
|
- id: check-json
|
||||||
|
@ -24,27 +24,32 @@ repos:
|
||||||
rev: 5.10.1
|
rev: 5.10.1
|
||||||
hooks:
|
hooks:
|
||||||
- id: isort
|
- id: isort
|
||||||
|
args:
|
||||||
|
- --profile=black
|
||||||
- repo: https://github.com/psf/black
|
- repo: https://github.com/psf/black
|
||||||
rev: 22.1.0
|
rev: 22.8.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: black
|
- id: black
|
||||||
|
args:
|
||||||
|
- -t
|
||||||
|
- py310
|
||||||
- repo: https://github.com/asottile/pyupgrade
|
- repo: https://github.com/asottile/pyupgrade
|
||||||
rev: v2.31.0
|
rev: v2.38.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: pyupgrade
|
- id: pyupgrade
|
||||||
args:
|
args:
|
||||||
- --py310-plus
|
- --py310-plus
|
||||||
- repo: https://github.com/adamchainz/django-upgrade
|
- repo: https://github.com/adamchainz/django-upgrade
|
||||||
rev: 1.4.0
|
rev: 1.10.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: django-upgrade
|
- id: django-upgrade
|
||||||
args: [--target-version, "4.0"]
|
args: [--target-version, "4.1"]
|
||||||
- repo: https://github.com/rtts/djhtml
|
- repo: https://github.com/rtts/djhtml
|
||||||
rev: v1.5.0
|
rev: v1.5.2
|
||||||
hooks:
|
hooks:
|
||||||
- id: djhtml
|
- id: djhtml
|
||||||
- repo: https://github.com/flakeheaven/flakeheaven
|
- repo: https://github.com/flakeheaven/flakeheaven
|
||||||
rev: 0.11.0
|
rev: 3.0.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: flakeheaven
|
- id: flakeheaven
|
||||||
additional_dependencies:
|
additional_dependencies:
|
||||||
|
@ -58,19 +63,19 @@ repos:
|
||||||
- flake8-pyi
|
- flake8-pyi
|
||||||
- wemake-python-styleguide
|
- wemake-python-styleguide
|
||||||
- repo: https://github.com/pre-commit/mirrors-prettier
|
- repo: https://github.com/pre-commit/mirrors-prettier
|
||||||
rev: v2.5.1
|
rev: v3.0.0-alpha.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: prettier
|
- id: prettier
|
||||||
types_or: [javascript, css]
|
types_or: [javascript, css]
|
||||||
- repo: https://github.com/pre-commit/mirrors-eslint
|
- repo: https://github.com/pre-commit/mirrors-eslint
|
||||||
rev: v8.9.0
|
rev: v8.23.1
|
||||||
hooks:
|
hooks:
|
||||||
- id: eslint
|
- id: eslint
|
||||||
args: [--fix]
|
args: [--fix]
|
||||||
types_or: [javascript, css]
|
types_or: [javascript, css]
|
||||||
additional_dependencies:
|
additional_dependencies:
|
||||||
- eslint@^7.29.0
|
- eslint
|
||||||
- eslint-config-prettier@^8.3.0
|
- eslint-config-prettier
|
||||||
- repo: local
|
- repo: local
|
||||||
hooks:
|
hooks:
|
||||||
- id: mypy
|
- id: mypy
|
||||||
|
|
862
poetry.lock
generated
862
poetry.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -7,45 +7,43 @@ license = "GPLv3"
|
||||||
|
|
||||||
[tool.poetry.dependencies]
|
[tool.poetry.dependencies]
|
||||||
python = "^3.10"
|
python = "^3.10"
|
||||||
django = "^4.0"
|
django = "^4.1"
|
||||||
markdown = "^3.2"
|
markdown = "^3.2"
|
||||||
gunicorn = "^20.0"
|
gunicorn = "^20.0"
|
||||||
Pygments = "^2.6"
|
Pygments = "^2.6"
|
||||||
django-anymail = {version = "^8.4", extras = ["mailgun"]}
|
django-anymail = {version = "^8.4", extras = ["mailgun"]}
|
||||||
pillow = "^8.4"
|
pillow = "^9.2"
|
||||||
django-cleanup = "^5.0"
|
django-cleanup = "^6.0"
|
||||||
requests = "^2.24"
|
requests = "^2.24"
|
||||||
readtime = "^1.1.1"
|
readtime = "^2.0.0"
|
||||||
django-debug-toolbar = "^3.2"
|
django-debug-toolbar = "^3.2"
|
||||||
whitenoise = {extras = ["brotli"], version = "^5.2.0"}
|
whitenoise = {extras = ["brotli"], version = "^6.0"}
|
||||||
rcssmin = "^1.0.6"
|
rcssmin = "^1.0.6"
|
||||||
django-csp = "^3.7"
|
django-csp = "^3.7"
|
||||||
django-two-factor-auth = {extras = ["phonenumberslite"], git = "https://github.com/Bouke/django-two-factor-auth.git", rev = "ffe4422e"}
|
django-two-factor-auth = {extras = ["phonenumberslite"], version = "^1.14"}
|
||||||
beautifulsoup4 = "^4.10.0"
|
beautifulsoup4 = "^4.10.0"
|
||||||
django-environ = "^0.8.1"
|
django-environ = "^0.9.0"
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
pre-commit = "^2.7"
|
pre-commit = "^2.7"
|
||||||
pytest = "^6.0"
|
pytest = "^7.0"
|
||||||
pytest-django = "^4.5"
|
pytest-django = "^4.5"
|
||||||
model-bakery = "^1.1"
|
model-bakery = "^1.1"
|
||||||
pytest-cov = "^3.0"
|
pytest-cov = "^3.0"
|
||||||
pytest-recording = "^0.12.0"
|
pytest-recording = "^0.12.0"
|
||||||
pytest-rerunfailures = "^10.2"
|
pytest-rerunfailures = "^10.2"
|
||||||
pytest-env = "^0.6.2"
|
pytest-env = "^0.6.2"
|
||||||
poetry-deps-scanner = "^1.0.1"
|
poetry-deps-scanner = "^2.0"
|
||||||
invoke = "^1.6.0"
|
invoke = "^1.6.0"
|
||||||
mypy = "^0.930"
|
mypy = "^0.971"
|
||||||
types-Markdown = "^3.3.10"
|
types-Markdown = "^3.3.10"
|
||||||
types-requests = "^2.26.3"
|
types-requests = "^2.26.3"
|
||||||
types-setuptools = "^57.4.5"
|
types-setuptools = "^65"
|
||||||
types-toml = "^0.10.1"
|
types-toml = "^0.10.1"
|
||||||
types-beautifulsoup4 = "^4.10.7"
|
types-beautifulsoup4 = "^4.10.7"
|
||||||
types-Pillow = "^8.3.11"
|
types-Pillow = "^9.2"
|
||||||
kolo = "^2.0.3"
|
kolo = "^2.0.3"
|
||||||
|
lxml-stubs = "^0.4.0"
|
||||||
[tool.black]
|
|
||||||
target-version = ['py310']
|
|
||||||
|
|
||||||
[tool.isort]
|
[tool.isort]
|
||||||
profile = "black"
|
profile = "black"
|
||||||
|
@ -62,7 +60,7 @@ env = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[tool.mypy]
|
[tool.mypy]
|
||||||
mypy_path = "$MYPY_CONFIG_FILE_DIR/stubs:$MYPY_CONFIG_FILE_DIR/src"
|
mypy_path = "$MYPY_CONFIG_FILE_DIR/stubs"
|
||||||
disallow_untyped_defs = true
|
disallow_untyped_defs = true
|
||||||
warn_redundant_casts = true
|
warn_redundant_casts = true
|
||||||
strict_equality = true
|
strict_equality = true
|
||||||
|
@ -79,14 +77,15 @@ module = [
|
||||||
"django_otp.plugins.otp_totp.models",
|
"django_otp.plugins.otp_totp.models",
|
||||||
"model_bakery",
|
"model_bakery",
|
||||||
"invoke",
|
"invoke",
|
||||||
|
"kolo",
|
||||||
]
|
]
|
||||||
ignore_missing_imports = true
|
ignore_missing_imports = true
|
||||||
|
|
||||||
[tool.flakehell]
|
[tool.flakeheaven]
|
||||||
max_complexity = 10
|
max_complexity = 10
|
||||||
format = "grouped"
|
format = "grouped"
|
||||||
|
|
||||||
[tool.flakehell.plugins]
|
[tool.flakeheaven.plugins]
|
||||||
"flake8-*" = [
|
"flake8-*" = [
|
||||||
"+*",
|
"+*",
|
||||||
# long lines
|
# long lines
|
||||||
|
@ -101,10 +100,11 @@ flake8-quotes = ["-Q000"] # found double quotes, conflict with black
|
||||||
flake8-commas = ["-C812"] # missing trailing comma, conflict with black
|
flake8-commas = ["-C812"] # missing trailing comma, conflict with black
|
||||||
flake8-docstrings = ["-D1??"] # missing docstring
|
flake8-docstrings = ["-D1??"] # missing docstring
|
||||||
flake8-rst-docstrings = ["-*"]
|
flake8-rst-docstrings = ["-*"]
|
||||||
|
flake8-isort = ["-*"]
|
||||||
|
|
||||||
[tool.flakehell.exceptions."**/migrations/*"]
|
[tool.flakeheaven.exceptions."**/migrations/*"]
|
||||||
|
|
||||||
[tool.flakehell.exceptions."**/tests/*"]
|
[tool.flakeheaven.exceptions."**/tests/*"]
|
||||||
flake8-bandit = ["-S101"] # Use of assert detected.
|
flake8-bandit = ["-S101"] # Use of assert detected.
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
|
|
|
@ -46,7 +46,7 @@ class ArticleAdmin(admin.ModelAdmin):
|
||||||
("author", "tags"),
|
("author", "tags"),
|
||||||
("status", "published_at"),
|
("status", "published_at"),
|
||||||
("created_at", "updated_at"),
|
("created_at", "updated_at"),
|
||||||
("views_count", "read_time"),
|
("views_count",),
|
||||||
("has_code", "has_custom_css"),
|
("has_code", "has_custom_css"),
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
@ -13,7 +13,7 @@ def forwards(apps: Apps, schema_editor: BaseDatabaseSchemaEditor) -> None:
|
||||||
tags = []
|
tags = []
|
||||||
keyword: str
|
keyword: str
|
||||||
for keyword in list(
|
for keyword in list(
|
||||||
filter(None, map(lambda k: k.strip(), article.keywords.split(",")))
|
filter(None, (keyword.strip() for keyword in article.keywords.split(",")))
|
||||||
):
|
):
|
||||||
tag = Tag.objects.using(db_alias).filter(name__iexact=keyword).first()
|
tag = Tag.objects.using(db_alias).filter(name__iexact=keyword).first()
|
||||||
if tag is None:
|
if tag is None:
|
||||||
|
@ -29,7 +29,7 @@ def backwards(apps: Apps, schema_editor: BaseDatabaseSchemaEditor) -> None:
|
||||||
db_alias = schema_editor.connection.alias
|
db_alias = schema_editor.connection.alias
|
||||||
articles = Article.objects.using(db_alias).all()
|
articles = Article.objects.using(db_alias).all()
|
||||||
for article in articles:
|
for article in articles:
|
||||||
article.keywords = ",".join(map(lambda tag: tag.name, article.tags.all()))
|
article.keywords = ",".join(tag.name for tag in article.tags.all())
|
||||||
Article.objects.bulk_update(articles, ["keywords"])
|
Article.objects.bulk_update(articles, ["keywords"])
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,9 @@ from __future__ import annotations
|
||||||
|
|
||||||
import random
|
import random
|
||||||
import uuid
|
import uuid
|
||||||
|
from collections.abc import Sequence
|
||||||
from functools import cached_property
|
from functools import cached_property
|
||||||
from typing import Any, Sequence
|
from typing import Any
|
||||||
|
|
||||||
import rcssmin
|
import rcssmin
|
||||||
import readtime
|
import readtime
|
||||||
|
@ -15,6 +16,7 @@ from django.db.models import Prefetch
|
||||||
from django.template.defaultfilters import slugify
|
from django.template.defaultfilters import slugify
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
from lxml.etree import ParseError # noqa: S410
|
||||||
|
|
||||||
from articles.utils import (
|
from articles.utils import (
|
||||||
build_full_absolute_url,
|
build_full_absolute_url,
|
||||||
|
@ -130,9 +132,13 @@ class Article(models.Model):
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
def get_read_time(self) -> int:
|
def get_read_time(self) -> int:
|
||||||
content = self.get_formatted_content
|
try:
|
||||||
if content:
|
content = self.get_formatted_content
|
||||||
return readtime.of_html(content).minutes
|
if content:
|
||||||
|
return readtime.of_html(content).minutes
|
||||||
|
except ParseError:
|
||||||
|
print(f"minutes failed for pk {self.pk}")
|
||||||
|
return 0
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
|
@ -150,7 +156,7 @@ class Article(models.Model):
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def keywords(self) -> str:
|
def keywords(self) -> str:
|
||||||
return ", ".join(map(lambda tag: tag.name, self.tags.all()))
|
return ", ".join(tag.name for tag in self.tags.all())
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def get_minified_custom_css(self) -> str:
|
def get_minified_custom_css(self) -> str:
|
||||||
|
|
|
@ -10,7 +10,7 @@ function addCopyCode() {
|
||||||
pre.querySelector("code").firstChild,
|
pre.querySelector("code").firstChild,
|
||||||
0,
|
0,
|
||||||
pre.querySelector("code").lastChild,
|
pre.querySelector("code").lastChild,
|
||||||
1
|
1,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -7,7 +7,7 @@ from articles.models import User
|
||||||
|
|
||||||
@pytest.mark.django_db()
|
@pytest.mark.django_db()
|
||||||
# @pytest.mark.skip("Fails for no apparent reason")
|
# @pytest.mark.skip("Fails for no apparent reason")
|
||||||
@pytest.mark.flaky(reruns=5, reruns_delay=3)
|
# @pytest.mark.flaky(reruns=5, reruns_delay=3)
|
||||||
def test_can_access_add_article(client: Client, author: User) -> None:
|
def test_can_access_add_article(client: Client, author: User) -> None:
|
||||||
client.force_login(author)
|
client.force_login(author)
|
||||||
url = reverse("admin:articles_article_add")
|
url = reverse("admin:articles_article_add")
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
from collections.abc import Iterable
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Any, Iterable
|
from typing import Any
|
||||||
|
|
||||||
from django.contrib.syndication.views import Feed
|
from django.contrib.syndication.views import Feed
|
||||||
from django.core.handlers.wsgi import WSGIRequest
|
from django.core.handlers.wsgi import WSGIRequest
|
||||||
|
|
|
@ -45,7 +45,7 @@ class BaseArticleListView(generic.ListView):
|
||||||
**initial_queryparams,
|
**initial_queryparams,
|
||||||
**self.get_additional_querystring_params(),
|
**self.get_additional_querystring_params(),
|
||||||
}
|
}
|
||||||
return "&".join(map(lambda item: f"{item[0]}={item[1]}", querystring.items()))
|
return "&".join(f"{item[0]}={item[1]}" for item in querystring.items())
|
||||||
|
|
||||||
|
|
||||||
class PublicArticleListView(BaseArticleListView):
|
class PublicArticleListView(BaseArticleListView):
|
||||||
|
|
|
@ -46,7 +46,7 @@ SECRET_KEY = env("SECRET_KEY")
|
||||||
|
|
||||||
admins = env("ADMINS")
|
admins = env("ADMINS")
|
||||||
if admins:
|
if admins:
|
||||||
ADMINS = list(map(lambda x: tuple(x.split("|")), admins))
|
ADMINS = [tuple(admin.split("|")) for admin in admins]
|
||||||
|
|
||||||
DEFAULT_FROM_EMAIL = "Gab's Notes <blog@mg.gabnotes.org>"
|
DEFAULT_FROM_EMAIL = "Gab's Notes <blog@mg.gabnotes.org>"
|
||||||
SERVER_EMAIL = "Gab's Notes <blog@mg.gabnotes.org>"
|
SERVER_EMAIL = "Gab's Notes <blog@mg.gabnotes.org>"
|
||||||
|
@ -96,7 +96,6 @@ INSTALLED_APPS = [
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
"kolo.middleware.KoloMiddleware",
|
|
||||||
"django.middleware.security.SecurityMiddleware",
|
"django.middleware.security.SecurityMiddleware",
|
||||||
"whitenoise.middleware.WhiteNoiseMiddleware",
|
"whitenoise.middleware.WhiteNoiseMiddleware",
|
||||||
"django.middleware.gzip.GZipMiddleware",
|
"django.middleware.gzip.GZipMiddleware",
|
||||||
|
@ -111,6 +110,13 @@ MIDDLEWARE = [
|
||||||
"csp.middleware.CSPMiddleware",
|
"csp.middleware.CSPMiddleware",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
try:
|
||||||
|
import kolo
|
||||||
|
|
||||||
|
MIDDLEWARE = ["kolo.middleware.KoloMiddleware"] + MIDDLEWARE
|
||||||
|
except ImportError:
|
||||||
|
pass # do nothing
|
||||||
|
|
||||||
ROOT_URLCONF = "blog.urls"
|
ROOT_URLCONF = "blog.urls"
|
||||||
|
|
||||||
TEMPLATES = [
|
TEMPLATES = [
|
||||||
|
|
2
tasks.py
2
tasks.py
|
@ -2,7 +2,7 @@
|
||||||
Invoke management tasks for the project.
|
Invoke management tasks for the project.
|
||||||
|
|
||||||
The current implementation with type annotations is not compatible
|
The current implementation with type annotations is not compatible
|
||||||
with invoke 1.6.0 and requires manual patching.
|
with invoke 1.7.1 and requires manual patching.
|
||||||
|
|
||||||
See https://github.com/pyinvoke/invoke/pull/458/files
|
See https://github.com/pyinvoke/invoke/pull/458/files
|
||||||
"""
|
"""
|
||||||
|
|
Reference in a new issue