|
24 | 24 |
|
25 | 25 | from __future__ import annotations |
26 | 26 |
|
27 | | -from typing import TYPE_CHECKING, Literal |
| 27 | +from typing import TYPE_CHECKING, Literal, NamedTuple |
28 | 28 |
|
29 | 29 | from twitchio.user import PartialUser |
30 | 30 | from twitchio.utils import parse_timestamp |
|
34 | 34 | import datetime |
35 | 35 |
|
36 | 36 | from twitchio.http import HTTPClient |
37 | | - from twitchio.types_.responses import HypeTrainEventsResponseContributions, HypeTrainEventsResponseData |
| 37 | + from twitchio.types_.responses import ( |
| 38 | + HypeTrainEventsResponseContributions, |
| 39 | + HypeTrainEventsResponseData, |
| 40 | + HypeTrainStatusResponseData, |
| 41 | + HypeTrainStatusTopContributions, |
| 42 | + ) |
| 43 | + |
| 44 | + CombinedContributionType = Literal["BITS", "SUBS", "OTHER", "bits", "subscriptions", "other"] |
38 | 45 |
|
39 | | -__all__ = ("HypeTrainContribution", "HypeTrainEvent") |
| 46 | +__all__ = ("HypeTrainAllTimeHigh", "HypeTrainContribution", "HypeTrainEvent", "HypeTrainStatus") |
40 | 47 |
|
41 | 48 |
|
42 | 49 | class HypeTrainEvent: |
@@ -119,18 +126,157 @@ class HypeTrainContribution: |
119 | 126 | total: int |
120 | 127 | The total amount contributed. If type is ``BITS``, total represents the amount of Bits used. |
121 | 128 | If type is ``SUBS``, total is 500, 1000, or 2500 to represent tier 1, 2, or 3 subscriptions, respectively. |
122 | | - type: typing.Literal["BITS", "SUBS", "OTHER"] |
123 | | - Identifies the contribution method, either BITS, SUBS or OTHER. |
| 129 | + type: typing.Literal["BITS", "SUBS", "OTHER", "bits", "subscription", "other"] |
| 130 | + Identifies the contribution method. |
| 131 | +
|
| 132 | + **HypeTrainEvent:** |
| 133 | +
|
| 134 | + - **BITS**: cheering with Bits. |
| 135 | + - **SUBS**: subscription activity like subscribing or gifting subscriptions. |
| 136 | + - **OTHER**: covers other contribution methods not listed. |
| 137 | +
|
| 138 | + **HypeTrainStatus:** |
| 139 | +
|
| 140 | + - **bits**: cheering with Bits. |
| 141 | + - **subscription**: subscription activity like subscribing or gifting subscriptions. |
| 142 | + - **other**: covers other contribution methods not listed. |
| 143 | +
|
124 | 144 | user: PartialUser |
125 | 145 | The user making the contribution. |
126 | 146 | """ |
127 | 147 |
|
128 | | - __slots__ = "total", "type", "user" |
| 148 | + __slots__ = ("total", "type", "user") |
129 | 149 |
|
130 | | - def __init__(self, data: HypeTrainEventsResponseContributions, *, http: HTTPClient) -> None: |
| 150 | + def __init__( |
| 151 | + self, data: HypeTrainEventsResponseContributions | HypeTrainStatusTopContributions, *, http: HTTPClient |
| 152 | + ) -> None: |
131 | 153 | self.total: int = int(data["total"]) |
132 | | - self.type: Literal["BITS", "SUBS", "OTHER"] = data["type"] |
133 | | - self.user = PartialUser(data["user"], None, http=http) |
| 154 | + self.type: CombinedContributionType = data["type"] |
| 155 | + |
| 156 | + if "user" in data: |
| 157 | + self.user = PartialUser(data["user"], http=http) |
| 158 | + else: |
| 159 | + self.user = PartialUser(data["user_id"], data["user_login"], data["user_name"], http=http) |
134 | 160 |
|
135 | 161 | def __repr__(self) -> str: |
136 | 162 | return f"<HypeTrainContribution total={self.total} type={self.type} user={self.user}>" |
| 163 | + |
| 164 | + |
| 165 | +class HypeTrainAllTimeHigh(NamedTuple): |
| 166 | + """The all time high data for a Hype Train. |
| 167 | +
|
| 168 | + Attributes |
| 169 | + ----------- |
| 170 | + level: int |
| 171 | + The level of the record Hype Train. |
| 172 | + total: int |
| 173 | + The total amount contributed to the record Hype Train. |
| 174 | + achieved_at: datetime.datetime |
| 175 | + The datetime when the record was achieved. |
| 176 | + """ |
| 177 | + |
| 178 | + level: int |
| 179 | + total: int |
| 180 | + achieved_at: datetime.datetime |
| 181 | + |
| 182 | + |
| 183 | +class HypeTrainStatus: |
| 184 | + """Represents the current status of a Hype Train. |
| 185 | +
|
| 186 | + Attributes |
| 187 | + ----------- |
| 188 | + id: str |
| 189 | + The ID of the Hype Train. |
| 190 | + broadcaster: PartialUser |
| 191 | + The user whose channel the Hype Train is occurring on. |
| 192 | + level: int |
| 193 | + The current level of the Hype Train. |
| 194 | + total: int1 |
| 195 | + The total amount contributed to the Hype Train. |
| 196 | + progress: int |
| 197 | + The number of points contributed to the Hype Train at the current level. |
| 198 | + goal: int |
| 199 | + The value needed to reach the next level. |
| 200 | + top_contributions: list[HypeTrainContribution] |
| 201 | + The contributors with the most points contributed. |
| 202 | + started_at: datetime.datetime |
| 203 | + The time the Hype Train started. |
| 204 | + expires_at: datetime.datetime |
| 205 | + The time the Hype Train expires. |
| 206 | + type: Literal["treasure", "golden_kappa", "regular"] |
| 207 | + The type of Hype Train. Can be one of `treasure`, `golden_kappa`, or `regular`. |
| 208 | + all_time_high: HypeTrainAllTimeHigh | None |
| 209 | + Information about the channel's hype train records. |
| 210 | + shared_train: bool |
| 211 | + Whether this Hype Train is a shared train. |
| 212 | + shared_train_participants: list[PartialUser] |
| 213 | + A list containing the broadcasters participating in the shared hype train. |
| 214 | + shared_all_time_high: HypeTrainAllTimeHigh | None |
| 215 | + Information about the channel's shared hype train records. |
| 216 | + """ |
| 217 | + |
| 218 | + __slots__ = ( |
| 219 | + "all_time_high", |
| 220 | + "broadcaster", |
| 221 | + "expires_at", |
| 222 | + "goal", |
| 223 | + "id", |
| 224 | + "level", |
| 225 | + "progress", |
| 226 | + "shared_all_time_high", |
| 227 | + "shared_train", |
| 228 | + "shared_train_participants", |
| 229 | + "started_at", |
| 230 | + "top_contributions", |
| 231 | + "total", |
| 232 | + "type", |
| 233 | + ) |
| 234 | + |
| 235 | + def __init__(self, data: HypeTrainStatusResponseData, *, http: HTTPClient) -> None: |
| 236 | + current = data.get("current") |
| 237 | + if current is None: |
| 238 | + raise ValueError("HypeTrainStatus requires 'current'") |
| 239 | + all_time_high = data.get("all_time_high") |
| 240 | + shared_all_time_high = data.get("shared_all_time_high") |
| 241 | + |
| 242 | + self.id: str = current["id"] |
| 243 | + self.broadcaster = PartialUser( |
| 244 | + current["broadcaster_user_id"], current["broadcaster_user_id"], current["broadcaster_user_name"], http=http |
| 245 | + ) |
| 246 | + self.level: int = current["level"] |
| 247 | + self.total: int = current["total"] |
| 248 | + self.progress: int = current["progress"] |
| 249 | + self.goal: int = current["goal"] |
| 250 | + self.started_at: datetime.datetime = parse_timestamp(current["started_at"]) |
| 251 | + self.expires_at: datetime.datetime = parse_timestamp(current["expires_at"]) |
| 252 | + self.type: Literal["treasure", "golden_kappa", "regular"] = current["type"] |
| 253 | + self.top_contributions: list[HypeTrainContribution] = [ |
| 254 | + HypeTrainContribution(c, http=http) for c in current["top_contributions"] |
| 255 | + ] |
| 256 | + self.all_time_high: HypeTrainAllTimeHigh | None = ( |
| 257 | + HypeTrainAllTimeHigh( |
| 258 | + level=all_time_high["level"], |
| 259 | + total=all_time_high["total"], |
| 260 | + achieved_at=parse_timestamp(all_time_high["achieved_at"]), |
| 261 | + ) |
| 262 | + if all_time_high is not None |
| 263 | + else None |
| 264 | + ) |
| 265 | + self.shared_train: bool = current["is_shared_train"] |
| 266 | + self.shared_train_participants: list[PartialUser] = ( |
| 267 | + [ |
| 268 | + PartialUser(u["broadcaster_user_id"], u["broadcaster_user_login"], u["broadcaster_user_name"], http=http) |
| 269 | + for u in current["shared_train_participants"] |
| 270 | + ] |
| 271 | + if self.shared_train |
| 272 | + else [] |
| 273 | + ) |
| 274 | + self.shared_all_time_high: HypeTrainAllTimeHigh | None = ( |
| 275 | + HypeTrainAllTimeHigh( |
| 276 | + level=shared_all_time_high["level"], |
| 277 | + total=shared_all_time_high["total"], |
| 278 | + achieved_at=parse_timestamp(shared_all_time_high["achieved_at"]), |
| 279 | + ) |
| 280 | + if shared_all_time_high is not None |
| 281 | + else None |
| 282 | + ) |
0 commit comments