From f2a1a33c28c4a386b84a2cd39403c125de6fd820 Mon Sep 17 00:00:00 2001 From: NotSoToothless <67082114+FURRO404@users.noreply.github.com> Date: Sat, 20 Jun 2026 21:56:03 -0700 Subject: [PATCH] add tss tournament stuff (#1349) --- BOT/tss_tournaments.py | 21 +++++++++++++++++++++ tests/test_tss_tournaments.py | 16 ++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/BOT/tss_tournaments.py b/BOT/tss_tournaments.py index e5cebb3..346bd1c 100644 --- a/BOT/tss_tournaments.py +++ b/BOT/tss_tournaments.py @@ -190,6 +190,25 @@ def normalize_side(type_bracket: Optional[str]) -> str: return t or "match" +def apply_tournament_side_context(matches: List[Dict[str, Any]]) -> None: + """Fix stage labels whose side depends on tournament format. + + In double-elim data, TSS puts ``Semifinal`` under the loser bracket tree. In + single-elim data, ``Semifinal`` is just an elimination stage. Use presence of + Looser/Loser rows to disambiguate. + """ + has_loser_side = any( + "looser" in str(m.get("type_bracket") or "").lower() + or "loser" in str(m.get("type_bracket") or "").lower() + for m in matches + ) + if not has_loser_side: + return + for match in matches: + if "semifinal" in str(match.get("type_bracket") or "").lower(): + match["side"] = "loser" + + def derive_format( type_brackets: Any, type_tournament: Optional[str] = None ) -> str: @@ -566,6 +585,8 @@ def build_scan_sync( standings = parse_standings(data.get("GroupStage")) break + apply_tournament_side_context(matches) + # Battles per match → session links. Dedupe match_ids (same id can repeat # across sources); fetch once per (match_id, type_bracket). battle_targets: List[Dict[str, Any]] = [] diff --git a/tests/test_tss_tournaments.py b/tests/test_tss_tournaments.py index c52d931..02fd50a 100644 --- a/tests/test_tss_tournaments.py +++ b/tests/test_tss_tournaments.py @@ -79,6 +79,22 @@ def test_normalize_side(): assert tt.normalize_side("Group") == "group" +def test_apply_tournament_side_context_moves_double_elim_semifinal_to_loser(): + matches = [ + {"type_bracket": "Winner", "side": "winner"}, + {"type_bracket": "Looser", "side": "loser"}, + {"type_bracket": "Semifinal", "side": "final"}, + {"type_bracket": "Final", "side": "final"}, + ] + tt.apply_tournament_side_context(matches) + assert matches[2]["side"] == "loser" + assert matches[3]["side"] == "final" + + single_elim = [{"type_bracket": "Semifinal", "side": "final"}] + tt.apply_tournament_side_context(single_elim) + assert single_elim[0]["side"] == "final" + + def test_derive_format(): assert tt.derive_format([], "double-elumination") == "double-elim" assert tt.derive_format([], "single-elumination") == "single-elim"