Fix types
This commit is contained in:
parent
6f6116c3c7
commit
c092d3089f
13 changed files with 48 additions and 18 deletions
|
|
@ -12,7 +12,6 @@ from config import settings
|
|||
if TYPE_CHECKING:
|
||||
from collections.abc import Callable
|
||||
from collections.abc import Generator
|
||||
from collections.abc import Iterator
|
||||
from pathlib import Path
|
||||
from types import ModuleType
|
||||
|
||||
|
|
@ -28,7 +27,7 @@ def reload_settings_module() -> Generator[Callable[..., ModuleType]]:
|
|||
original_env: dict[str, str] = os.environ.copy()
|
||||
|
||||
@contextmanager
|
||||
def temporary_env(env: dict[str, str]) -> Iterator[None]:
|
||||
def temporary_env(env: dict[str, str]) -> Generator[None]:
|
||||
previous_env: dict[str, str] = os.environ.copy()
|
||||
os.environ.clear()
|
||||
os.environ.update(env)
|
||||
|
|
|
|||
|
|
@ -53,9 +53,9 @@ if TYPE_CHECKING:
|
|||
from os import stat_result
|
||||
from pathlib import Path
|
||||
|
||||
from debug_toolbar.utils import QueryDict
|
||||
from django.db.models import QuerySet
|
||||
from django.http import HttpRequest
|
||||
from django.http.request import QueryDict
|
||||
|
||||
|
||||
logger: logging.Logger = logging.getLogger("ttvdrops.views")
|
||||
|
|
@ -309,7 +309,7 @@ def docs_rss_view(request: HttpRequest) -> HttpResponse:
|
|||
# Add limit=1 to GET parameters
|
||||
get_data: QueryDict = request.GET.copy()
|
||||
get_data["limit"] = "1"
|
||||
limited_request.GET = get_data # pyright: ignore[reportAttributeAccessIssue]
|
||||
limited_request.GET = get_data
|
||||
|
||||
response: HttpResponse = feed_view(limited_request, *args)
|
||||
return _pretty_example(response.content.decode("utf-8"))
|
||||
|
|
|
|||
|
|
@ -289,7 +289,7 @@ class KickDropCampaign(auto_prefetch.Model):
|
|||
"""Return the image URL for the campaign."""
|
||||
# Image from first drop
|
||||
if self.rewards.exists(): # pyright: ignore[reportAttributeAccessIssue]
|
||||
first_reward: KickReward = self.rewards.first() # pyright: ignore[reportAttributeAccessIssue]
|
||||
first_reward: KickReward | None = self.rewards.first() # pyright: ignore[reportAttributeAccessIssue]
|
||||
if first_reward and first_reward.image_url:
|
||||
return first_reward.full_image_url
|
||||
|
||||
|
|
|
|||
|
|
@ -442,6 +442,8 @@ class ImportKickDropsCommandTest(TestCase):
|
|||
campaign: KickDropCampaign = KickDropCampaign.objects.get()
|
||||
assert campaign.name == "PUBG 9th Anniversary"
|
||||
assert campaign.status == "active"
|
||||
assert campaign.organization is not None
|
||||
assert campaign.category is not None
|
||||
assert campaign.organization.name == "KRAFTON"
|
||||
assert campaign.category.name == "PUBG: Battlegrounds"
|
||||
|
||||
|
|
|
|||
|
|
@ -177,7 +177,9 @@ class TTVDropsAtomBaseFeed(TTVDropsBaseFeed):
|
|||
feed_type = BrowserFriendlyAtom1Feed
|
||||
|
||||
|
||||
def _with_campaign_related(queryset: QuerySet[DropCampaign]) -> QuerySet[DropCampaign]:
|
||||
def _with_campaign_related(
|
||||
queryset: QuerySet[DropCampaign, DropCampaign],
|
||||
) -> QuerySet[DropCampaign, DropCampaign]:
|
||||
"""Apply related-selects/prefetches needed by feed rendering to avoid N+1 queries.
|
||||
|
||||
Returns:
|
||||
|
|
|
|||
|
|
@ -631,6 +631,9 @@ class Command(BaseCommand):
|
|||
)
|
||||
return
|
||||
|
||||
if game_obj.box_art_file is None:
|
||||
return
|
||||
|
||||
game_obj.box_art_file.save(file_name, ContentFile(response.content), save=True)
|
||||
|
||||
def _get_or_create_channel(self, channel_info: ChannelInfoSchema) -> Channel:
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ from twitch.models import Game
|
|||
from twitch.models import Organization
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from debug_toolbar.panels.templates.panel import QuerySet
|
||||
from django.core.management.base import CommandParser
|
||||
from django.db.models import QuerySet
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ class Command(BaseCommand):
|
|||
help="Re-download even if a local box art file already exists.",
|
||||
)
|
||||
|
||||
def handle(self, *_args: object, **options: object) -> None:
|
||||
def handle(self, *_args: object, **options: object) -> None: # noqa: PLR0914
|
||||
"""Download Twitch box art images for all games."""
|
||||
limit_value: object | None = options.get("limit")
|
||||
limit: int | None = limit_value if isinstance(limit_value, int) else None
|
||||
|
|
@ -92,6 +92,10 @@ class Command(BaseCommand):
|
|||
skipped += 1
|
||||
continue
|
||||
|
||||
if game.box_art_file is None:
|
||||
failed += 1
|
||||
continue
|
||||
|
||||
game.box_art_file.save(
|
||||
file_name,
|
||||
ContentFile(response.content),
|
||||
|
|
@ -99,7 +103,9 @@ class Command(BaseCommand):
|
|||
)
|
||||
|
||||
# Auto-convert to WebP and AVIF
|
||||
self._convert_to_modern_formats(game.box_art_file.path)
|
||||
box_art_path: str | None = getattr(game.box_art_file, "path", None)
|
||||
if box_art_path:
|
||||
self._convert_to_modern_formats(box_art_path)
|
||||
|
||||
downloaded += 1
|
||||
|
||||
|
|
|
|||
|
|
@ -264,7 +264,7 @@ class Command(BaseCommand):
|
|||
client: httpx.Client,
|
||||
image_url: str,
|
||||
twitch_id: str,
|
||||
file_field: FieldFile,
|
||||
file_field: FieldFile | None,
|
||||
) -> str:
|
||||
"""Download a single image and save it to the file field.
|
||||
|
||||
|
|
@ -281,6 +281,9 @@ class Command(BaseCommand):
|
|||
suffix: str = Path(parsed_url.path).suffix or ".jpg"
|
||||
file_name: str = f"{twitch_id}{suffix}"
|
||||
|
||||
if file_field is None:
|
||||
return "failed"
|
||||
|
||||
try:
|
||||
response: httpx.Response = client.get(image_url)
|
||||
response.raise_for_status()
|
||||
|
|
@ -299,7 +302,9 @@ class Command(BaseCommand):
|
|||
file_field.save(file_name, ContentFile(response.content), save=True)
|
||||
|
||||
# Auto-convert to WebP and AVIF
|
||||
self._convert_to_modern_formats(file_field.path)
|
||||
image_path: str | None = getattr(file_field, "path", None)
|
||||
if image_path:
|
||||
self._convert_to_modern_formats(image_path)
|
||||
|
||||
return "downloaded"
|
||||
|
||||
|
|
|
|||
|
|
@ -279,6 +279,7 @@ class RSSFeedTestCase(TestCase):
|
|||
def test_campaign_and_game_feeds_use_absolute_media_enclosure_urls(self) -> None:
|
||||
"""Campaign/game RSS+Atom enclosures should use absolute URLs for local media files."""
|
||||
self.game.box_art = ""
|
||||
assert self.game.box_art_file is not None
|
||||
self.game.box_art_file.save(
|
||||
"box.png",
|
||||
ContentFile(b"game-image-bytes"),
|
||||
|
|
@ -289,6 +290,7 @@ class RSSFeedTestCase(TestCase):
|
|||
self.game.save()
|
||||
|
||||
self.campaign.image_url = ""
|
||||
assert self.campaign.image_file is not None
|
||||
self.campaign.image_file.save(
|
||||
"campaign.png",
|
||||
ContentFile(b"campaign-image-bytes"),
|
||||
|
|
@ -712,6 +714,7 @@ class RSSFeedTestCase(TestCase):
|
|||
name="File Game",
|
||||
display_name="File Game",
|
||||
)
|
||||
assert game2.box_art_file is not None
|
||||
game2.box_art_file.save("sample.png", ContentFile(b"hello"))
|
||||
game2.save()
|
||||
|
||||
|
|
@ -723,6 +726,7 @@ class RSSFeedTestCase(TestCase):
|
|||
end_at=timezone.now() + timedelta(days=1),
|
||||
operation_names=["DropCampaignDetails"],
|
||||
)
|
||||
assert campaign2.image_file is not None
|
||||
campaign2.image_file.save("camp.jpg", ContentFile(b"world"))
|
||||
campaign2.save()
|
||||
|
||||
|
|
|
|||
|
|
@ -1067,9 +1067,18 @@ class TestSEOHelperFunctions:
|
|||
def test_build_seo_context_with_all_parameters(self) -> None:
|
||||
"""Test _build_seo_context with all parameters."""
|
||||
now: datetime.datetime = timezone.now()
|
||||
breadcrumb: list[dict[str, int | str]] = [
|
||||
{"position": 1, "name": "Home", "url": "/"},
|
||||
]
|
||||
breadcrumb: dict[str, Any] = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "BreadcrumbList",
|
||||
"itemListElement": [
|
||||
{
|
||||
"@type": "ListItem",
|
||||
"position": 1,
|
||||
"name": "Home",
|
||||
"item": "/",
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
context: dict[str, Any] = _build_seo_context(
|
||||
page_title="Test",
|
||||
|
|
@ -1077,7 +1086,7 @@ class TestSEOHelperFunctions:
|
|||
page_image="https://example.com/img.jpg",
|
||||
og_type="article",
|
||||
schema_data={},
|
||||
breadcrumb_schema=breadcrumb, # pyright: ignore[reportArgumentType]
|
||||
breadcrumb_schema=breadcrumb,
|
||||
pagination_info=[{"rel": "next", "url": "/page/2/"}],
|
||||
published_date=now.isoformat(),
|
||||
modified_date=now.isoformat(),
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ def normalize_twitch_box_art_url(url: str) -> str:
|
|||
return url
|
||||
|
||||
normalized_path: str = TWITCH_BOX_ART_SIZE_PATTERN.sub("", parsed.path)
|
||||
return urlunparse(parsed._replace(path=normalized_path))
|
||||
return str(urlunparse(parsed._replace(path=normalized_path)))
|
||||
|
||||
|
||||
@lru_cache(maxsize=40 * 40 * 1024)
|
||||
|
|
|
|||
|
|
@ -1396,7 +1396,7 @@ def reward_campaign_detail_view(request: HttpRequest, twitch_id: str) -> HttpRes
|
|||
class GamesListView(GamesGridView):
|
||||
"""List view for games in simple list format."""
|
||||
|
||||
template_name: str = "twitch/games_list.html"
|
||||
template_name: str | None = "twitch/games_list.html"
|
||||
|
||||
|
||||
# MARK: /channels/
|
||||
|
|
@ -1748,7 +1748,7 @@ def badge_set_detail_view(request: HttpRequest, set_id: str) -> HttpResponse:
|
|||
)
|
||||
return ChatBadge.objects.filter(pk__in=badge_ids).order_by(preserved_order)
|
||||
|
||||
badges = get_sorted_badges(badge_set)
|
||||
badges: QuerySet[ChatBadge, ChatBadge] = get_sorted_badges(badge_set)
|
||||
|
||||
# Attach award_campaigns attribute to each badge for template use
|
||||
for badge in badges:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue