Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds mypy annotations for templatetags #3422

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions bookwyrm/models/author.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,22 +53,22 @@ def save(self, *args: Any, **kwargs: Any) -> None:
super().save(*args, **kwargs)

@property
def isni_link(self):
def isni_link(self) -> str:
"""generate the url from the isni id"""
clean_isni = re.sub(r"\s", "", self.isni)
return f"https://isni.org/isni/{clean_isni}"

@property
def openlibrary_link(self):
def openlibrary_link(self) -> str:
"""generate the url from the openlibrary id"""
return f"https://openlibrary.org/authors/{self.openlibrary_key}"

@property
def isfdb_link(self):
def isfdb_link(self) -> str:
"""generate the url from the isni id"""
return f"https://www.isfdb.org/cgi-bin/ea.cgi?{self.isfdb}"

def get_remote_id(self):
def get_remote_id(self) -> str:
"""editions and works both use "book" instead of model_name"""
return f"{BASE_URL}/author/{self.id}"

Expand Down
8 changes: 6 additions & 2 deletions bookwyrm/models/book.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
""" database schema for books and shelves """
from __future__ import annotations

from itertools import chain
import re
from typing import Any, Dict, Optional, Iterable
from typing import Any, Dict, Optional, Iterable, TYPE_CHECKING
from typing_extensions import Self

from django.contrib.postgres.search import SearchVectorField
Expand Down Expand Up @@ -33,6 +34,9 @@
from .base_model import BookWyrmModel
from . import fields

if TYPE_CHECKING:
from bookwyrm.models import Author


class BookDataModel(ObjectMixin, BookWyrmModel):
"""fields shared between editable book data (books, works, authors)"""
Expand Down Expand Up @@ -415,7 +419,7 @@ def default_edition(self):
"""in case the default edition is not set"""
return self.editions.order_by("-edition_rank").first()

def author_edition(self, author):
def author_edition(self, author: Author) -> Any:
"""in case the default edition doesn't have the required author"""
return self.editions.filter(authors=author).order_by("-edition_rank").first()

Expand Down
10 changes: 6 additions & 4 deletions bookwyrm/templatetags/book_display_tags.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
""" template filters """
from typing import Any
from django import template
from django.db.models import QuerySet
from bookwyrm import models


register = template.Library()


@register.filter(name="review_count")
def get_review_count(book):
def get_review_count(book: models.Edition) -> int:
"""how many reviews?"""
return models.Review.objects.filter(deleted=False, book=book).count()


@register.filter(name="book_description")
def get_book_description(book):
def get_book_description(book: models.Edition) -> Any:
"""use the work's text if the book doesn't have it"""
if book.description:
return book.description
Expand All @@ -24,12 +26,12 @@ def get_book_description(book):


@register.simple_tag(takes_context=False)
def get_book_file_links(book):
def get_book_file_links(book: models.Edition) -> QuerySet[models.FileLink]:
"""links for a book"""
return book.file_links.filter(domain__status="approved")


@register.filter(name="author_edition")
def get_author_edition(book, author):
def get_author_edition(book: models.Work, author: models.Author) -> Any:
"""default edition for a book on the author page"""
return book.author_edition(author)
6 changes: 3 additions & 3 deletions bookwyrm/templatetags/celery_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@


@register.filter(name="uptime")
def uptime(seconds):
def uptime(seconds: float) -> str:
"""Seconds uptime to a readable format"""
return str(datetime.timedelta(seconds=seconds))


@register.filter(name="runtime")
def runtime(timestamp):
def runtime(timestamp: float) -> datetime.timedelta:
"""How long has it been?"""
return datetime.datetime.now() - datetime.datetime.fromtimestamp(timestamp)


@register.filter(name="shortname")
def shortname(name):
def shortname(name: str) -> str:
"""removes bookwyrm.celery..."""
return ".".join(name.split(".")[-2:])
4 changes: 3 additions & 1 deletion bookwyrm/templatetags/date_ext.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
""" additional formatting of dates """
from typing import Any

from django import template
from django.template import defaultfilters
from django.contrib.humanize.templatetags.humanize import naturalday
Expand All @@ -9,7 +11,7 @@


@register.filter(expects_localtime=True)
def naturalday_partial(date, arg=None):
def naturalday_partial(date: Any, arg: Any = None) -> str | None:
"""chooses appropriate precision if date is a PartialDate object

If arg is a Django-defined format such as "DATE_FORMAT", it will be adjusted
Expand Down
6 changes: 4 additions & 2 deletions bookwyrm/templatetags/feed_page_tags.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
""" tags used on the feed pages """
from typing import Any
from django import template
from bookwyrm.views.feed import get_suggested_books
from bookwyrm import models


register = template.Library()


@register.filter(name="load_subclass")
def load_subclass(status):
def load_subclass(status: models.Status) -> models.Status:
"""sometimes you didn't select_subclass"""
if hasattr(status, "quotation"):
return status.quotation
Expand All @@ -21,7 +23,7 @@ def load_subclass(status):


@register.simple_tag(takes_context=True)
def suggested_books(context):
def suggested_books(context: dict[str, Any]) -> Any:
"""get books for suggested books panel"""
# this happens here instead of in the view so that the template snippet can
# be cached in the template
Expand Down
6 changes: 3 additions & 3 deletions bookwyrm/templatetags/group_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,21 @@


@register.filter(name="has_groups")
def has_groups(user):
def has_groups(user: models.User) -> bool:
"""whether or not the user has a pending invitation to join this group"""

return models.GroupMember.objects.filter(user=user).exists()


@register.filter(name="is_member")
def is_member(group, user):
def is_member(group: models.Group, user: models.User) -> bool:
"""whether or not the user is a member of this group"""

return models.GroupMember.objects.filter(group=group, user=user).exists()


@register.filter(name="is_invited")
def is_invited(group, user):
def is_invited(group: models.Group, user: models.User) -> bool:
"""whether or not the user has a pending invitation to join this group"""

return models.GroupMemberInvitation.objects.filter(group=group, user=user).exists()
13 changes: 8 additions & 5 deletions bookwyrm/templatetags/interaction.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
""" template filters for status interaction buttons """
from typing import Any
from django import template

from bookwyrm import models
Expand All @@ -9,7 +10,7 @@


@register.filter(name="liked")
def get_user_liked(user, status):
def get_user_liked(user: models.User, status: models.Status) -> Any:
"""did the given user fav a status?"""
return get_or_set(
f"fav-{user.id}-{status.id}",
Expand All @@ -21,7 +22,7 @@ def get_user_liked(user, status):


@register.filter(name="boosted")
def get_user_boosted(user, status):
def get_user_boosted(user: models.User, status: models.Status) -> Any:
"""did the given user fav a status?"""
return get_or_set(
f"boost-{user.id}-{status.id}",
Expand All @@ -32,13 +33,13 @@ def get_user_boosted(user, status):


@register.filter(name="saved")
def get_user_saved_lists(user, book_list):
def get_user_saved_lists(user: models.User, book_list: models.List) -> bool:
"""did the user save a list"""
return user.saved_lists.filter(id=book_list.id).exists()


@register.simple_tag(takes_context=True)
def get_relationship(context, user_object):
def get_relationship(context: dict[str, Any], user_object: models.User) -> Any:
"""caches the relationship between the logged in user and another user"""
user = context["request"].user
return get_or_set(
Expand All @@ -50,7 +51,9 @@ def get_relationship(context, user_object):
)


def get_relationship_name(user, user_object):
def get_relationship_name(
user: models.User, user_object: models.User
) -> dict[str, bool]:
"""returns the relationship type"""
types = {
"is_following": False,
Expand Down
7 changes: 4 additions & 3 deletions bookwyrm/templatetags/landing_page_tags.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
""" template filters """
from typing import Optional
from django import template
from django.db.models import Avg, StdDev, Count, F, Q
from django.db.models import Avg, StdDev, Count, F, Q, QuerySet

from bookwyrm import models

register = template.Library()


@register.simple_tag(takes_context=False)
def get_book_superlatives():
def get_book_superlatives() -> dict[str, Optional[models.Work]]:
"""get book stats for the about page"""
total_ratings = models.Review.objects.filter(local=True, deleted=False).count()
data = {}
Expand Down Expand Up @@ -67,7 +68,7 @@ def get_book_superlatives():


@register.simple_tag(takes_context=False)
def get_landing_books():
def get_landing_books() -> list[QuerySet[models.Edition]]:
"""list of books for the landing page"""
return list(
set(
Expand Down
2 changes: 1 addition & 1 deletion bookwyrm/templatetags/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@


@register.simple_tag(takes_context=False)
def get_lang():
def get_lang() -> str:
"""get current language, strip to the first two letters"""
language = utils.translation.get_language()
return language[0 : language.find("-")]
3 changes: 2 additions & 1 deletion bookwyrm/templatetags/markdown.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
""" template filters """
from typing import Any
from django import template
from bookwyrm.views.status import to_markdown

Expand All @@ -7,7 +8,7 @@


@register.filter(name="to_markdown")
def get_markdown(content):
def get_markdown(content: str) -> Any:
"""convert markdown to html"""
if content:
return to_markdown(content)
Expand Down
6 changes: 4 additions & 2 deletions bookwyrm/templatetags/notification_page_tags.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
""" tags used on the feed pages """
from typing import Optional
from django import template
from bookwyrm import models
from bookwyrm.templatetags.feed_page_tags import load_subclass


register = template.Library()


@register.simple_tag(takes_context=False)
def related_status(notification):
def related_status(notification: models.Notification) -> Optional[models.Status]:
"""for notifications"""
if not notification.related_status:
return None
return load_subclass(notification.related_status)


@register.simple_tag(takes_context=False)
def get_related_users(notification):
def get_related_users(notification: models.Notification) -> list[models.User]:
"""Who actually was it who liked your post"""
return list(reversed(list(notification.related_users.distinct())))[:10]
5 changes: 3 additions & 2 deletions bookwyrm/templatetags/rating_tags.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
""" template filters """
from typing import Any
from django import template
from django.db.models import Avg

Expand All @@ -10,7 +11,7 @@


@register.filter(name="rating")
def get_rating(book, user):
def get_rating(book: models.Edition, user: models.User) -> Any:
"""get the overall rating of a book"""
# this shouldn't happen, but it CAN
if not book.parent_work:
Expand All @@ -29,7 +30,7 @@ def get_rating(book, user):


@register.filter(name="user_rating")
def get_user_rating(book, user):
def get_user_rating(book: models.Edition, user: models.User) -> Any:
"""get a user's rating of a book"""
rating = (
models.Review.objects.filter(
Expand Down
12 changes: 7 additions & 5 deletions bookwyrm/templatetags/shelf_tags.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
""" Filters and tags related to shelving books """
from typing import Any
from django import template
from django.utils.translation import gettext_lazy as _
from django_stubs_ext import StrPromise

from bookwyrm import models
from bookwyrm.utils import cache
Expand All @@ -19,7 +21,7 @@


@register.filter(name="is_book_on_shelf")
def get_is_book_on_shelf(book, shelf):
def get_is_book_on_shelf(book: models.Edition, shelf: models.Shelf) -> Any:
"""is a book on a shelf"""
return cache.get_or_set(
f"book-on-shelf-{book.id}-{shelf.id}",
Expand All @@ -31,7 +33,7 @@ def get_is_book_on_shelf(book, shelf):


@register.filter(name="next_shelf")
def get_next_shelf(current_shelf):
def get_next_shelf(current_shelf: str) -> str:
"""shelf you'd use to update reading progress"""
if current_shelf == "to-read":
return "reading"
Expand All @@ -45,7 +47,7 @@ def get_next_shelf(current_shelf):


@register.filter(name="translate_shelf_name")
def get_translated_shelf_name(shelf):
def get_translated_shelf_name(shelf: models.Shelf | dict[str, str]) -> str | StrPromise:
"""produce translated shelf identifiername"""
if not shelf:
return ""
Expand All @@ -59,7 +61,7 @@ def get_translated_shelf_name(shelf):


@register.simple_tag(takes_context=True)
def active_shelf(context, book):
def active_shelf(context: dict[str, Any], book: models.Edition) -> Any:
"""check what shelf a user has a book on, if any"""
user = context["request"].user
return cache.get_or_set(
Expand All @@ -78,7 +80,7 @@ def active_shelf(context, book):


@register.simple_tag(takes_context=False)
def latest_read_through(book, user):
def latest_read_through(book: models.Edition, user: models.User) -> Any:
"""the most recent read activity"""
return cache.get_or_set(
f"latest_read_through-{user.id}-{book.id}",
Expand Down
2 changes: 1 addition & 1 deletion bookwyrm/templatetags/stars.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@


@register.filter(name="half_star")
def get_half_star(value):
def get_half_star(value: str) -> str:
"""one of those things that's weirdly hard with templates"""
return f"{value}.5"
Loading
Loading