migrate to black 24

This commit is contained in:
Your Name 2024-06-02 14:50:07 -04:00 committed by Henri Dickson
parent a71283e6d5
commit 55b1f1b365
29 changed files with 176 additions and 76 deletions

View file

@ -1,12 +1,15 @@
exclude: ^test_data/
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
rev: v4.6.0
hooks:
- id: check-yaml
- id: check-json
- id: check-xml
- id: check-toml
- id: check-ast
- id: check-docstring-first
- id: check-executables-have-shebangs
- id: check-symlinks
- id: check-added-large-files
args: [--maxkb=1024]
@ -21,7 +24,7 @@ repos:
- id: mixed-line-ending
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.3.5
rev: v0.4.7
hooks:
- id: ruff
# - id: ruff-format
@ -33,7 +36,7 @@ repos:
args: ["--profile=black"]
- repo: https://github.com/psf/black
rev: 22.12.0
rev: 24.4.2
hooks:
- id: black

View file

@ -13,6 +13,7 @@ Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.conf import settings
from django.contrib import admin
from django.urls import include, path

View file

@ -279,7 +279,8 @@ class BooksTWTestCase(TestCase):
self.assertEqual(site.resource.id_value, "0010947886")
self.assertEqual(site.resource.item.isbn, "9786263152236")
self.assertEqual(
site.resource.item.title, "阿拉伯人三千年:從民族、部落、語言、文化、宗教到帝國,綜覽阿拉伯世界的崛起、衰落與再興"
site.resource.item.title,
"阿拉伯人三千年:從民族、部落、語言、文化、宗教到帝國,綜覽阿拉伯世界的崛起、衰落與再興",
)

View file

@ -6,6 +6,7 @@ a Site should map to a unique set of url patterns.
a Site may scrape a url and store result in ResourceContent
ResourceContent persists as an ExternalResource which may link to an Item
"""
import json
import re
from dataclasses import dataclass, field

View file

@ -71,7 +71,8 @@ class SteamTestCase(TestCase):
self.assertEqual(site.ready, True)
self.assertEqual(site.resource.metadata["title"], "Portal 2")
self.assertEqual(
site.resource.metadata["brief"], "“终身测试计划”现已升级,您可以为您自己或您的好友设计合作谜题!"
site.resource.metadata["brief"],
"“终身测试计划”现已升级,您可以为您自己或您的好友设计合作谜题!",
)
self.assertIsInstance(site.resource.item, Game)
self.assertEqual(site.resource.item.steam, "620")
@ -102,7 +103,9 @@ class DoubanGameTestCase(TestCase):
self.assertEqual(site.resource.metadata["title"], "传送门2 Portal 2")
self.assertIsInstance(site.resource.item, Game)
self.assertEqual(site.resource.item.douban_game, "10734307")
self.assertEqual(site.resource.item.genre, ["第一人称射击", "益智", "射击", "动作"])
self.assertEqual(
site.resource.item.genre, ["第一人称射击", "益智", "射击", "动作"]
)
self.assertEqual(site.resource.item.other_title, [])

View file

@ -118,14 +118,21 @@ class Migration(migrations.Migration):
"title",
models.CharField(default="", max_length=1000, verbose_name="标题"),
),
("brief", models.TextField(blank=True, default="", verbose_name="简介")),
(
"brief",
models.TextField(blank=True, default="", verbose_name="简介"),
),
(
"primary_lookup_id_type",
models.CharField(max_length=50, null=True, verbose_name="主要标识类型"),
models.CharField(
max_length=50, null=True, verbose_name="主要标识类型"
),
),
(
"primary_lookup_id_value",
models.CharField(max_length=1000, null=True, verbose_name="主要标识数值"),
models.CharField(
max_length=1000, null=True, verbose_name="主要标识数值"
),
),
(
"metadata",
@ -184,14 +191,21 @@ class Migration(migrations.Migration):
"title",
models.CharField(default="", max_length=1000, verbose_name="标题"),
),
("brief", models.TextField(blank=True, default="", verbose_name="简介")),
(
"brief",
models.TextField(blank=True, default="", verbose_name="简介"),
),
(
"primary_lookup_id_type",
models.CharField(max_length=50, null=True, verbose_name="主要标识类型"),
models.CharField(
max_length=50, null=True, verbose_name="主要标识类型"
),
),
(
"primary_lookup_id_value",
models.CharField(max_length=1000, null=True, verbose_name="主要标识数值"),
models.CharField(
max_length=1000, null=True, verbose_name="主要标识数值"
),
),
(
"metadata",
@ -505,12 +519,17 @@ class Migration(migrations.Migration):
),
(
"id_value",
models.CharField(blank=True, max_length=1000, verbose_name="源网站ID"),
models.CharField(
blank=True, max_length=1000, verbose_name="源网站ID"
),
),
(
"raw_url",
models.CharField(
blank=True, max_length=1000, unique=True, verbose_name="源网站ID"
blank=True,
max_length=1000,
unique=True,
verbose_name="源网站ID",
),
),
(

View file

@ -1,8 +1,9 @@
# Generated by Django 4.2.13 on 2024-06-02 16:17
import catalog.common.utils
from django.db import migrations, models
import catalog.common.utils
class Migration(migrations.Migration):

View file

@ -396,9 +396,7 @@ class PerformanceProduction(Item):
return (
self.cover.url # type:ignore
if self.cover and self.cover != DEFAULT_ITEM_COVER
else self.show.cover_image_url
if self.show
else None
else self.show.cover_image_url if self.show else None
)
def update_linked_items_from_external_resource(self, resource: ExternalResource):

View file

@ -30,7 +30,9 @@ class DoubanDramaTestCase(TestCase):
resource = site.get_resource_ready()
item = site.get_item()
self.assertEqual(item.title, "不眠之人·拿破仑")
self.assertEqual(item.other_title, ["眠らない男・ナポレオン ―愛と栄光の涯(はて)に―"])
self.assertEqual(
item.other_title, ["眠らない男・ナポレオン ―愛と栄光の涯(はて)に―"]
)
self.assertEqual(item.genre, ["音乐剧"])
self.assertEqual(item.troupe, ["宝塚歌剧团"])
self.assertEqual(item.composer, ["ジェラール・プレスギュルヴィック"])
@ -74,7 +76,9 @@ class DoubanDramaTestCase(TestCase):
# item.version, ["08星组公演版", "10年月組公演版", "17年星組公演版", "ュージカル2017年版"]
# )
self.assertEqual(item.director, ["小池修一郎", "小池 修一郎", "石丸さち子"])
self.assertEqual(item.playwright, ["小池修一郎", "Baroness Orczy原作", "小池 修一郎"])
self.assertEqual(
item.playwright, ["小池修一郎", "Baroness Orczy原作", "小池 修一郎"]
)
self.assertEqual(
item.actor,
[

View file

@ -354,7 +354,7 @@ class Indexer:
"query_by": ",".join(SEARCHABLE_ATTRIBUTES),
"filter_by": filters,
# "facet_by": "category",
"sort_by": "_text_match:desc,rating_count:desc"
"sort_by": "_text_match:desc,rating_count:desc",
# 'facetsDistribution': ['_class'],
# 'sort_by': None,
}

View file

@ -7,6 +7,7 @@ Scraping the website directly.
- It requires Apple Developer Membership ($99 per year) to obtain a token.
"""
import json
import logging

View file

@ -43,7 +43,9 @@ class Bangumi(AbstractSite):
model = "TVSeason" if is_series else "Movie"
if dt:
year = dt.split("-")[0]
showtime = [{"time": dt, "region": "首播日期" if is_series else "发布日期"}]
showtime = [
{"time": dt, "region": "首播日期" if is_series else "发布日期"}
]
case 3:
model = "Album"
case 4:

View file

@ -3,6 +3,7 @@ BoardGameGeek
ref: https://boardgamegeek.com/wiki/page/BGG_XML_API2
"""
import html
from langdetect import detect

View file

@ -55,7 +55,9 @@ class BooksTW(AbstractSite):
)
translators = [s.strip() for s in translators]
language_elem = content.xpath("//div/ul/li[starts-with(text(),'語言:')]/text()")
language_elem = content.xpath(
"//div/ul/li[starts-with(text(),'語言:')]/text()"
)
language = (
language_elem[0].strip().split("")[1].strip() if language_elem else None # type: ignore
)
@ -70,9 +72,11 @@ class BooksTW(AbstractSite):
pub_date = content.xpath("string(//div/ul/li[contains(text(),'出版日期:')])")
pub_date = re.match(
r"(\d+)/(\d+)/(\d+)\s*$",
pub_date.strip().split("", 1)[1].strip().split(" ", 1)[0] # type: ignore
if pub_date
else "",
(
pub_date.strip().split("", 1)[1].strip().split(" ", 1)[0] # type: ignore
if pub_date
else ""
),
)
if pub_date:
pub_year = int(pub_date[1])

View file

@ -1,6 +1,7 @@
"""
Discogs.
"""
import json
import logging

View file

@ -139,10 +139,11 @@ class IGDB(AbstractSite):
"brief": brief,
"official_site": official_site,
"igdb_id": r["id"],
"cover_image_url": "https:"
+ r["cover"]["url"].replace("t_thumb", "t_cover_big")
if r.get("cover")
else None,
"cover_image_url": (
"https:" + r["cover"]["url"].replace("t_thumb", "t_cover_big")
if r.get("cover")
else None
),
}
)
if steam_url:

View file

@ -83,13 +83,13 @@ class IMDB(AbstractSite):
"year": d["releaseYear"]["year"] if d.get("releaseYear") else None,
"is_series": d["titleType"]["isSeries"],
"is_episode": d["titleType"]["isEpisode"],
"genre": [x["text"] for x in d["genres"]["genres"]]
if d.get("genres")
else [],
"genre": (
[x["text"] for x in d["genres"]["genres"]] if d.get("genres") else []
),
"brief": d["plot"].get("plotText") if d.get("plot") else None,
"cover_image_url": d["primaryImage"].get("url")
if d.get("primaryImage")
else None,
"cover_image_url": (
d["primaryImage"].get("url") if d.get("primaryImage") else None
),
}
if d.get("series"):
episode_info = d["series"].get("episodeNumber")

View file

@ -90,9 +90,9 @@ class RSS(AbstractSite):
metadata={
"title": feed["title"],
"brief": bleach.clean(feed["description"], strip=True),
"hosts": [feed.get("itunes_author")]
if feed.get("itunes_author")
else [],
"hosts": (
[feed.get("itunes_author")] if feed.get("itunes_author") else []
),
"official_site": feed.get("link"),
"cover_image_url": feed.get("cover_url"),
"genre": feed.get("itunes_categories", [None])[0],
@ -126,9 +126,11 @@ class RSS(AbstractSite):
"brief": bleach.clean(episode.get("description"), strip=True),
"description_html": episode.get("description_html"),
"cover_url": episode.get("episode_art_url"),
"media_url": episode.get("enclosures")[0].get("url")
if episode.get("enclosures")
else None,
"media_url": (
episode.get("enclosures")[0].get("url")
if episode.get("enclosures")
else None
),
"pub_date": make_aware(
datetime.fromtimestamp(episode.get("published"))
),

View file

@ -1,6 +1,7 @@
"""
Spotify
"""
import datetime
import logging
import time

View file

@ -24,6 +24,7 @@ tv specials are are shown as movies
For now, we follow Douban convention, but keep an eye on it in case it breaks its own rules...
"""
import re
from functools import cached_property
from typing import TYPE_CHECKING, overload

View file

@ -37,7 +37,18 @@ def export_marks_task(user):
)
if not os.path.exists(os.path.dirname(filename)):
os.makedirs(os.path.dirname(filename))
heading = ["标题", "简介", "豆瓣评分", "链接", "创建时间", "我的评分", "标签", "评论", "NeoDB链接", "其它ID"]
heading = [
"标题",
"简介",
"豆瓣评分",
"链接",
"创建时间",
"我的评分",
"标签",
"评论",
"NeoDB链接",
"其它ID",
]
wb = Workbook()
# adding write_only=True will speed up but corrupt the xlsx and won't be importable
for status, label in [

View file

@ -207,7 +207,10 @@ class DoubanImporter:
f"豆瓣标记和评论导入完成,共处理{self.total}篇,已存在{self.skipped}篇,新增{self.imported}篇。",
)
if len(self.failed):
msg.error(self.user, f'豆瓣评论导入时未能处理以下网址:\n{" , ".join(self.failed)}')
msg.error(
self.user,
f'豆瓣评论导入时未能处理以下网址:\n{" , ".join(self.failed)}',
)
def import_mark_sheet(self, worksheet, shelf_type, sheet_name):
prefix = f"{self.user} {sheet_name}|"

View file

@ -71,7 +71,10 @@ class Migration(migrations.Migration):
"title",
models.CharField(default="", max_length=1000, verbose_name="标题"),
),
("brief", models.TextField(blank=True, default="", verbose_name="简介")),
(
"brief",
models.TextField(blank=True, default="", verbose_name="简介"),
),
(
"cover",
models.ImageField(

View file

@ -32,27 +32,51 @@ def user_stats_of(collection: Collection, identity: APIdentity):
def prural_items(count: int, category: str):
match category:
case "book":
return ngettext("%(count)d book", "%(count)d books", count,) % {
return ngettext(
"%(count)d book",
"%(count)d books",
count,
) % {
"count": count,
}
case "movie":
return ngettext("%(count)d movie", "%(count)d movies", count,) % {
return ngettext(
"%(count)d movie",
"%(count)d movies",
count,
) % {
"count": count,
}
case "tv":
return ngettext("%(count)d tv show", "%(count)d tv shows", count,) % {
return ngettext(
"%(count)d tv show",
"%(count)d tv shows",
count,
) % {
"count": count,
}
case "music":
return ngettext("%(count)d album", "%(count)d albums", count,) % {
return ngettext(
"%(count)d album",
"%(count)d albums",
count,
) % {
"count": count,
}
case "game":
return ngettext("%(count)d game", "%(count)d games", count,) % {
return ngettext(
"%(count)d game",
"%(count)d games",
count,
) % {
"count": count,
}
case "podcast":
return ngettext("%(count)d podcast", "%(count)d podcasts", count,) % {
return ngettext(
"%(count)d podcast",
"%(count)d podcasts",
count,
) % {
"count": count,
}
case "performance":
@ -64,6 +88,10 @@ def prural_items(count: int, category: str):
"count": count,
}
case _:
return ngettext("%(count)d item", "%(count)d items", count,) % {
return ngettext(
"%(count)d item",
"%(count)d items",
count,
) % {
"count": count,
}

View file

@ -294,13 +294,15 @@ def get_related_acct_list(site, token, api):
r: list[dict[str, str]] = response.json()
results.extend(
map(
lambda u: ( # type: ignore
u["acct"]
if u["acct"].find("@") != -1
else u["acct"] + "@" + site
)
if "acct" in u
else u,
lambda u: (
( # type: ignore
u["acct"]
if u["acct"].find("@") != -1
else u["acct"] + "@" + site
)
if "acct" in u
else u
),
r,
)
)
@ -684,9 +686,11 @@ def share_collection(collection, comment, user, visibility_no, link):
if user == collection.owner.user
else (
_("shared {username}'s collection").format(
username=" @" + collection.owner.user.mastodon_acct + " "
if collection.owner.user.mastodon_acct
else " " + collection.owner.username + " "
username=(
" @" + collection.owner.user.mastodon_acct + " "
if collection.owner.user.mastodon_acct
else " " + collection.owner.username + " "
)
)
)
)

View file

@ -1,8 +1,8 @@
black~=22.12.0
black~=24.4.2
coverage
django-debug-toolbar
django-stubs
djlint~=1.34.0
djlint~=1.34.1
isort~=5.13.2
lxml-stubs
pre-commit

View file

@ -206,9 +206,9 @@ def connect_redirect_back(request):
)
return register_new_user(
request,
username=None
if settings.MASTODON_ALLOW_ANY_SITE
else user_data["username"],
username=(
None if settings.MASTODON_ALLOW_ANY_SITE else user_data["username"]
),
mastodon_username=user_data["username"],
mastodon_id=user_data["id"],
mastodon_site=site,

View file

@ -86,9 +86,11 @@ def init_identity(apps, schema_editor):
local=True,
username=username,
domain_name=domain,
deleted=None
if user.is_active
else user.mastodon_last_reachable + timedelta(days=90),
deleted=(
None
if user.is_active
else user.mastodon_last_reachable + timedelta(days=90)
),
)
takahe_user = TakaheUser.objects.create(
pk=user.pk, email=handler, admin=user.is_superuser, password=user.password

View file

@ -427,12 +427,16 @@ class User(AbstractUser):
sp = name.split("@")
if len(sp) == 2:
query_kwargs = {
"mastodon_username__iexact"
if case_sensitive
else "mastodon_username": sp[0],
"mastodon_site__iexact"
if case_sensitive
else "mastodon_site": sp[1],
(
"mastodon_username__iexact"
if case_sensitive
else "mastodon_username"
): sp[0],
(
"mastodon_site__iexact"
if case_sensitive
else "mastodon_site"
): sp[1],
}
else:
return None