refactoring
This commit is contained in:
116
crawler/lineup_builder.py
Normal file
116
crawler/lineup_builder.py
Normal file
@@ -0,0 +1,116 @@
|
||||
"""
|
||||
crawler/lineup_builder.py — 라인업 데이터 구성
|
||||
|
||||
relay 데이터와 preview 데이터에서 라인업 정보를 추출합니다.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from crawler.naver_api import get_team_names
|
||||
|
||||
|
||||
def get_starting_pitcher(pitchers: list[dict[str, Any]]) -> dict[str, Any] | None:
|
||||
"""투수 리스트에서 선발투수 추출"""
|
||||
if not pitchers:
|
||||
return None
|
||||
return min(pitchers, key=lambda p: p.get("seqno", 999))
|
||||
|
||||
|
||||
def get_starting_batters(batters: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
||||
"""타자 리스트에서 선발 라인업 추출"""
|
||||
starters_by_order: dict[int, dict[str, Any]] = {}
|
||||
for batter in sorted(batters, key=lambda b: (b.get("batOrder", 999), b.get("seqno", 999))):
|
||||
bat_order = batter.get("batOrder")
|
||||
if bat_order is None or bat_order in starters_by_order:
|
||||
continue
|
||||
starters_by_order[bat_order] = batter
|
||||
return [starters_by_order[order] for order in sorted(starters_by_order)]
|
||||
|
||||
|
||||
def build_lineup_team(team_name: str, lineup: dict[str, Any]) -> dict[str, Any]:
|
||||
"""relay 데이터의 라인업 → 정규화된 팀 라인업 dict"""
|
||||
starter_pitcher = get_starting_pitcher(lineup.get("pitcher", []))
|
||||
starting_batters = get_starting_batters(lineup.get("batter", []))
|
||||
return {
|
||||
"team_name": team_name,
|
||||
"starter_pitcher": {
|
||||
"name": starter_pitcher.get("name"),
|
||||
"position": "투수",
|
||||
"number": starter_pitcher.get("backnum"),
|
||||
}
|
||||
if starter_pitcher
|
||||
else None,
|
||||
"players": [
|
||||
{
|
||||
"bat_order": batter.get("batOrder"),
|
||||
"name": batter.get("name"),
|
||||
"position": batter.get("posName"),
|
||||
"number": batter.get("backnum"),
|
||||
}
|
||||
for batter in starting_batters
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def build_preview_lineup_team(
|
||||
team_name: str, preview_lineup: dict[str, Any] | None,
|
||||
) -> dict[str, Any] | None:
|
||||
"""preview 데이터의 라인업 → 정규화된 팀 라인업 dict"""
|
||||
if not preview_lineup:
|
||||
return None
|
||||
|
||||
full_lineup = preview_lineup.get("fullLineUp") or []
|
||||
starter_pitcher = next(
|
||||
(
|
||||
player
|
||||
for player in full_lineup
|
||||
if player.get("positionName") == "선발투수"
|
||||
or int(player.get("batorder", 0) or 0) == 0
|
||||
),
|
||||
None,
|
||||
)
|
||||
batters = sorted(
|
||||
(player for player in full_lineup if int(player.get("batorder", 0) or 0) > 0),
|
||||
key=lambda p: int(p.get("batorder", 99) or 99),
|
||||
)
|
||||
|
||||
return {
|
||||
"team_name": team_name,
|
||||
"starter_pitcher": {
|
||||
"name": starter_pitcher.get("playerName"),
|
||||
"position": "투수",
|
||||
"number": starter_pitcher.get("backnum"),
|
||||
}
|
||||
if starter_pitcher
|
||||
else None,
|
||||
"players": [
|
||||
{
|
||||
"bat_order": int(player.get("batorder")),
|
||||
"name": player.get("playerName"),
|
||||
"position": player.get("positionName"),
|
||||
"number": player.get("backnum"),
|
||||
}
|
||||
for player in batters
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def build_lineup_summary(
|
||||
game_id: str,
|
||||
game_info: dict[str, Any],
|
||||
relay_data: dict[str, Any],
|
||||
preview_data: dict[str, Any] | None = None,
|
||||
) -> dict[str, Any]:
|
||||
"""전체 라인업 요약 생성 (preview 우선, relay 폴백)"""
|
||||
away_name, home_name = get_team_names(game_id, game_info)
|
||||
away_preview = build_preview_lineup_team(
|
||||
away_name, (preview_data or {}).get("awayTeamLineUp"),
|
||||
)
|
||||
home_preview = build_preview_lineup_team(
|
||||
home_name, (preview_data or {}).get("homeTeamLineUp"),
|
||||
)
|
||||
return {
|
||||
"away_team": away_preview or build_lineup_team(away_name, relay_data["awayLineup"]),
|
||||
"home_team": home_preview or build_lineup_team(home_name, relay_data["homeLineup"]),
|
||||
}
|
||||
Reference in New Issue
Block a user