diff --git a/app/adapters/blizzard/parsers/hero.py b/app/adapters/blizzard/parsers/hero.py index 76fb89f3..3b0fa82d 100644 --- a/app/adapters/blizzard/parsers/hero.py +++ b/app/adapters/blizzard/parsers/hero.py @@ -99,9 +99,19 @@ def _parse_hero_summary(overview_section: LexborNode, locale: Locale) -> dict: icon_element = extra_list_items[0].css_first("blz-icon") icon_url = safe_get_attribute(icon_element, "src") + backgrounds = [ + { + "url": img.attributes["src"], + "sizes": (img.attributes.get("bp") or "").split(), + } + for img in overview_section.css("blz-image[slot=background]") + if img.attributes.get("src") + ] + return { "name": safe_get_text(header_section.css_first("h2")), "description": safe_get_text(header_section.css_first("p")), + "backgrounds": backgrounds, "role": get_role_from_icon_url(icon_url or ""), "location": safe_get_text(extra_list_items[1]), "birthday": birthday, diff --git a/app/heroes/enums.py b/app/heroes/enums.py index 0661f3a7..0a4cc602 100644 --- a/app/heroes/enums.py +++ b/app/heroes/enums.py @@ -3,6 +3,17 @@ from app.helpers import read_csv_data_file +class BackgroundImageSize(StrEnum): + """Responsive breakpoint sizes for hero background images""" + + MIN = "min" + XS = "xs" + SM = "sm" + MD = "md" + LG = "lg" + XL_PLUS = "xl+" + + class MediaType(StrEnum): """Media types for heroes pages""" diff --git a/app/heroes/models.py b/app/heroes/models.py index d724d0bd..bf02aff4 100644 --- a/app/heroes/models.py +++ b/app/heroes/models.py @@ -4,7 +4,22 @@ from app.roles.enums import Role -from .enums import HeroGamemode, HeroKey, MediaType +from .enums import BackgroundImageSize, HeroGamemode, HeroKey, MediaType + + +class HeroBackground(BaseModel): + url: HttpUrl = Field( + ..., + description="URL of the background image", + examples=[ + "https://blz-contentstack-images.akamaized.net/v3/assets/blt2477dcaf4ebd440c/blt242e79efb1e27251/631a8b791566e20e82f30288/1600_Cassidy.jpg", + ], + ) + sizes: list[BackgroundImageSize] = Field( + ..., + description="Responsive breakpoint sizes for which this image is used", + examples=[["md", "lg"]], + ) class HitPoints(BaseModel): @@ -167,6 +182,26 @@ class Hero(BaseModel): "https://d15f34w2p8l1cc.cloudfront.net/overwatch/6cfb48b5597b657c2eafb1277dc5eef4a07eae90c265fcd37ed798189619f0a5.png", ], ) + backgrounds: list[HeroBackground] = Field( + ..., + description="List of background images for the hero, one per responsive breakpoint group.", + examples=[ + [ + { + "url": "https://blz-contentstack-images.akamaized.net/v3/assets/blt2477dcaf4ebd440c/bltadb0bb2e726bee08/631a8b79be2fcf0db5eea4c8/960_Cassidy.jpg", + "sizes": ["min", "xs", "sm"], + }, + { + "url": "https://blz-contentstack-images.akamaized.net/v3/assets/blt2477dcaf4ebd440c/blt242e79efb1e27251/631a8b791566e20e82f30288/1600_Cassidy.jpg", + "sizes": ["md", "lg"], + }, + { + "url": "https://blz-contentstack-images.akamaized.net/v3/assets/blt2477dcaf4ebd440c/blt4bb4c31f6849c25b/631a8b781613910e6926bfd4/2600_Cassidy.jpg", + "sizes": ["xl+"], + }, + ], + ], + ) role: Role = Field( ..., description="Role of the hero", diff --git a/uv.lock b/uv.lock index 1458e4bb..5a6c718e 100644 --- a/uv.lock +++ b/uv.lock @@ -604,7 +604,7 @@ wheels = [ [[package]] name = "overfast-api" -version = "3.41.8" +version = "3.42.1" source = { virtual = "." } dependencies = [ { name = "aiosqlite" },