-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmodels.py
More file actions
162 lines (135 loc) · 5.33 KB
/
Copy pathmodels.py
File metadata and controls
162 lines (135 loc) · 5.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
"""
Alertle-V2 — Data models
"""
from __future__ import annotations
from dataclasses import dataclass, field
from datetime import datetime
from typing import Optional
# ── ESPN models ───────────────────────────────────────────────────────────────
@dataclass
class ESPNTeam:
id: str
name: str # "Toronto Maple Leafs"
abbreviation: str # "TOR"
short_name: str # "Maple Leafs"
location: str # "Toronto"
logo_url: str = ""
@dataclass
class ESPNLeague:
sport: str # "hockey"
league: str # "nhl"
label: str # "NHL"
is_event_series: bool = False # True for golf, F1, UFC, tennis
@dataclass
class ESPNGame:
id: str
sport: str
league: str
home_team: ESPNTeam
away_team: ESPNTeam
start_time: datetime # UTC
venue: str = ""
venue_city: str = ""
status: str = "scheduled" # scheduled | in_progress | final
home_score: Optional[int] = None
away_score: Optional[int] = None
broadcast_networks: list[str] = field(default_factory=list)
odds_spread: str = ""
odds_home_spread: str = ""
odds_away_spread: str = ""
odds_over_under: str = ""
odds_home_ml: str = ""
odds_away_ml: str = ""
series_summary: str = "" # "Series tied 2-2"
season_context: str = "" # "Week 14" / "Matchday 22"
winner_abbrev: str = "" # set when status == final
# ── EPG models ────────────────────────────────────────────────────────────────
@dataclass
class EPGChannel:
id: str
name: str
channel_number: str = ""
tvg_id: str = ""
@dataclass
class EPGProgram:
channel_id: str
channel_name: str
title: str
subtitle: str
description: str
start: datetime # UTC
stop: datetime # UTC
channel_number: str = ""
is_live: bool = False # True when XMLTV <live/> element is present
# ── Match — ESPN game + EPG channels it was found on ─────────────────────────
@dataclass
class GameMatch:
game: ESPNGame
channels: list[str] = field(default_factory=list) # channel names from EPG
program_description: str = "" # first EPG program description
schedule: list[dict] = field(default_factory=list)
# schedule: [{"start": "<ISO datetime UTC>", "channels": [...]}, ...]
# populated for event_series; empty for regular team/league games
# ── Config models ─────────────────────────────────────────────────────────────
@dataclass
class GameThumbsEndpointConfig:
type: str = "thumb" # thumb | logo | cover
style: int = 1
aspect: str = "16-9" # thumb only: 4-3 | 16-9 | 1-1
show_logo: bool = True
badge: Optional[str] = None # HD | FHD | 4K | UHD | ALT | None
fallback: bool = True
@dataclass
class ContentDefaults:
show_venue: bool = True
show_broadcast: bool = True
show_odds: bool = False
show_series: bool = True
show_week_context: bool = True
show_key_stats: bool = False
@dataclass
class Endpoint:
id: str
type: str # discord | telegram | pushover | ntfy
modes: list[str] = field(default_factory=list) # digest | lead_time | game_start | game_summary
lead_time_minutes: int = 30
precision_minutes: int = 0 # 0 = exact
digest_time: str = "08:00"
digest_team_days: int = 1
digest_event_days: int = 7
digest_show_channels: bool = True
weekly_digest_time: str = "08:00"
weekly_digest_day: str = "monday"
weekly_digest_team_days: int = 7
weekly_digest_event_days: int = 7
weekly_digest_show_channels: bool = True
bundle_window_minutes: int = 10
auto_record: bool = False
content_defaults: ContentDefaults = field(default_factory=ContentDefaults)
game_thumbs: GameThumbsEndpointConfig = field(default_factory=GameThumbsEndpointConfig)
# notifier-specific fields stored in raw dict
_raw: dict = field(default_factory=dict, repr=False)
@dataclass
class Subscription:
label: str
espn_sport: str
espn_league: str
scope: str # "team" | "league" | "event_series"
espn_team_id: Optional[str] = None
espn_team_name: Optional[str] = None
espn_team_abbrev: Optional[str] = None
game_thumbs_league: str = ""
content_overrides: dict = field(default_factory=dict)
endpoints: list[str] = field(default_factory=list)
standings_alert: bool = False # event_series only: send daily leaderboard
# ── Scheduled alert state (persisted to SQLite) ───────────────────────────────
@dataclass
class ScheduledAlert:
id: str # "{game_id}:{endpoint_id}:{mode}"
game_id: str
endpoint_id: str
mode: str # digest | lead_time | game_start | game_summary
fire_at: datetime # UTC — when to send
game_match_json: str # serialised GameMatch
sent: bool = False
retry_count: int = 0