diff --git a/README.md b/README.md index 8dc013f..e775227 100644 --- a/README.md +++ b/README.md @@ -99,9 +99,12 @@ cancels. Completed match results flash in place; the logos and card header are drawn once and stay stationary during the animation. -The WWF.com logo remains at top left. The centered logo follows the show name: -SmackDown shows use the SmackDown logo, Raw shows use the Raw logo, and other -shows display no centered show logo. +The WWF.com logo remains at top left on shows run by the World Wrestling +Federation (any card from the built-in games, clones of them, or a BYOG +federation named WWF/"World Wrestling Federation"). Federations with any other +name get no corner logo, and their centered show logo is truly centered. The +centered logo follows the show name: SmackDown shows use the SmackDown logo, Raw +shows use the Raw logo, and other shows display no centered show logo. In the card view, use ↑/↓ (or `j`/`k`) to highlight a promo, press Enter to expand or collapse it, and use Page Up/Page Down to scroll while the header diff --git a/smackdown_card_maker.py b/smackdown_card_maker.py index 4eb4873..592541b 100644 --- a/smackdown_card_maker.py +++ b/smackdown_card_maker.py @@ -272,6 +272,11 @@ def game_display_name(game_id: str) -> str: return GAMES[game_id]["title"] +def is_wwf_federation(name: str | None) -> bool: + folded = str(name or "").strip().casefold() + return folded in ("world wrestling federation", "wwf") + + def title_definitions_for_game(game_id: str, profile: dict[str, Any] | None = None) -> list[dict[str, str]]: if profile and isinstance(profile.get("championships"), list): @@ -1661,7 +1666,13 @@ def show_logo_path(show_name: str) -> Path | None: def header_lines(card: dict[str, Any], width: int) -> list[str]: - left, left_width = _render_image(ROOT / "wwfcomlogo.gif", 23, 6) + card_federation = str(card.get("federation_name") + or federation_name(card["game_id"])) + is_wwf = is_wwf_federation(card_federation) + if is_wwf: + left, left_width = _render_image(ROOT / "wwfcomlogo.gif", 23, 6) + else: + left, left_width = [], 0 logo_path = show_logo_path(card["show"]) if logo_path: center, center_width = _render_image(logo_path, 38, 6) @@ -1671,16 +1682,21 @@ def header_lines(card: dict[str, Any], width: int) -> list[str]: center_width = len(brand) else: center, center_width = [], 0 - if not left: + if is_wwf and not left: left = [color("WWF.com", RED)] left_width = 7 row_count = max(len(left), len(center), 2) if width < 62: title = card.get("game_title", game_title(card["game_id"])) - return [f"{color('WWF.com', RED)} {color(title, CYAN)}", + heading = f"{color('WWF.com', RED)} {color(title, CYAN)}" if is_wwf \ + else color(title, CYAN) + return [heading, f"{card['date']} · {show_location_text(card)}", ""] left_x = 1 - center_x = max(left_x + left_width + 3, (width - center_width) // 2) + if left: + center_x = max(left_x + left_width + 3, (width - center_width) // 2) + else: + center_x = (width - center_width) // 2 date_text = card["date"] date_x = width - len(date_text) - 2 output: list[str] = [] diff --git a/test_smackdown_card_maker.py b/test_smackdown_card_maker.py index 6f54575..a09f5f4 100644 --- a/test_smackdown_card_maker.py +++ b/test_smackdown_card_maker.py @@ -1132,6 +1132,70 @@ class HeaderLogoTests(unittest.TestCase): header = "\n".join(app.header_lines(card, 100)) self.assertIn("RAW IS WAR", header) + def custom_card(self) -> dict: + card = MarkdownTests().make_card(Path("card.md")) + card["federation_name"] = "Fantasy Fed" + card["game_title"] = "Rumble Royale" + return card + + def test_is_wwf_federation_matches_canonical_name_and_alias(self): + for name in ("World Wrestling Federation", "world wrestling federation", + "WWF", " wwf "): + self.assertTrue(app.is_wwf_federation(name), name) + for name in ("Fantasy Fed", "WWE", "WCW", ""): + self.assertFalse(app.is_wwf_federation(name), name) + + def test_corner_logo_only_renders_for_wwf_federations(self): + def image_mock(path, _columns, _rows): + if path.name == "wwfcomlogo.gif": + return ["IMG1"], 3 + return ["C1"], 3 + + wwf_card = MarkdownTests().make_card(Path("card.md")) + wwf_card["show"] = "Monday Night Raw" + custom_card = self.custom_card() + custom_card["show"] = "Monday Night Raw" + with patch.object(app, "_render_image", side_effect=image_mock): + wwf_header = app.header_lines(wwf_card, 100) + custom_header = app.header_lines(custom_card, 100) + self.assertIn("IMG1", wwf_header[0]) + self.assertFalse(any("IMG1" in line for line in custom_header)) + # With no corner logo the centered show logo is truly centered (48 = (100-3)//2). + # With no corner logo the centered show logo is truly centered (48 = (100-3)//2) + # and the date still sits at the top-right of the same row. + self.assertTrue(custom_header[0].startswith(" " * 48 + "C1"), custom_header[0]) + self.assertIn("2026-10-25", custom_header[0]) + self.assertNotIn("WWF.com", "\n".join(app.header_lines(custom_card, 100))) + + def test_wwf_alias_federations_render_the_corner_logo(self): + image_mock = lambda path, _columns, _rows: (["IMG1"], 3) + for federation in ("WWF", "world wrestling federation"): + card = self.custom_card() + card["federation_name"] = federation + with patch.object(app, "_render_image", side_effect=image_mock): + header = app.header_lines(card, 100) + self.assertIn("IMG1", header[0], federation) + + def test_corner_logo_text_fallback_only_for_wwf_federations(self): + wwf_card = MarkdownTests().make_card(Path("card.md")) + custom_card = self.custom_card() + with patch.object(app, "_render_image", return_value=([], 0)): + wwf_header = "\n".join(app.header_lines(wwf_card, 100)) + custom_header = "\n".join(app.header_lines(custom_card, 100)) + self.assertIn("WWF.com", wwf_header) + self.assertNotIn("WWF.com", custom_header) + + def test_narrow_custom_federation_header_drops_wwf_branding(self): + wwf_card = MarkdownTests().make_card(Path("card.md")) + custom_card = self.custom_card() + wwf_header = "\n".join(app.header_lines(wwf_card, 60)) + custom_header = "\n".join(app.header_lines(custom_card, 60)) + self.assertIn("WWF.com", wwf_header) + self.assertNotIn("WWF.com", custom_header) + self.assertIn("Rumble Royale", custom_header) + for header in (wwf_header, custom_header): + self.assertIn("2026-10-25", header) + class PromoFoldingTests(unittest.TestCase): def card_with_promos(self) -> dict: