Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wiseplat
GitHub Repository: wiseplat/python-code
Path: blob/master/ invest-robot-contest_TinkoffBotTwitch-main/venv/lib/python3.8/site-packages/twitchio/user.py
7771 views
1
"""
2
The MIT License (MIT)
3
4
Copyright (c) 2017-2021 TwitchIO
5
6
Permission is hereby granted, free of charge, to any person obtaining a
7
copy of this software and associated documentation files (the "Software"),
8
to deal in the Software without restriction, including without limitation
9
the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
and/or sell copies of the Software, and to permit persons to whom the
11
Software is furnished to do so, subject to the following conditions:
12
13
The above copyright notice and this permission notice shall be included in
14
all copies or substantial portions of the Software.
15
16
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
DEALINGS IN THE SOFTWARE.
23
"""
24
25
import datetime
26
import time
27
from typing import TYPE_CHECKING, List, Optional, Union, Tuple
28
29
from .enums import BroadcasterTypeEnum, UserTypeEnum
30
from .errors import HTTPException, Unauthorized
31
from .rewards import CustomReward
32
from .utils import parse_timestamp
33
34
35
if TYPE_CHECKING:
36
from .http import TwitchHTTP
37
from .channel import Channel
38
from .models import BitsLeaderboard, Clip, ExtensionBuilder, Tag, FollowEvent, Prediction
39
40
41
__all__ = (
42
"PartialUser",
43
"BitLeaderboardUser",
44
"UserBan",
45
"SearchUser",
46
"User",
47
)
48
49
50
class PartialUser:
51
52
__slots__ = "id", "name", "_http", "_cached_rewards"
53
54
def __init__(self, http: "TwitchHTTP", id: Union[int, str], name: Optional[str]):
55
self.id = int(id)
56
self.name = name
57
self._http = http
58
59
self._cached_rewards = None
60
61
def __repr__(self):
62
return f"<PartialUser id={self.id}, name={self.name}>"
63
64
@property
65
def channel(self) -> Optional["Channel"]:
66
"""
67
Returns the :class:`twitchio.Channel` associated with this user. Could be None if you are not part of the channel's chat
68
69
Returns
70
--------
71
Optional[:class:`twitchio.Channel`]
72
"""
73
from .channel import Channel
74
75
if self.name in self._http.client._connection._cache:
76
return Channel(self.name, self._http.client._connection)
77
78
async def fetch(self, token: str = None, force=False) -> "User":
79
"""|coro|
80
81
Fetches the full user from the api or cache
82
83
Parameters
84
-----------
85
token : :class:`str`
86
Optional OAuth token to be used instead of the bot-wide OAuth token
87
force : :class:`bool`
88
Whether to force a fetch from the api or try to get from the cache first. Defaults to False
89
90
Returns
91
--------
92
:class:`twitchio.User` The full user associated with this PartialUser
93
"""
94
data = await self._http.client.fetch_users(ids=[self.id], force=force, token=token)
95
return data[0]
96
97
async def edit(self, token: str, description: str) -> None:
98
"""|coro|
99
100
Edits a channels description
101
102
Parameters
103
-----------
104
token: :class:`str`
105
An oauth token for the user with the user:edit scope
106
description: :class:`str`
107
The new description for the user
108
"""
109
await self._http.put_update_user(token, description)
110
111
async def fetch_tags(self):
112
"""|coro|
113
114
Fetches tags the user currently has active.
115
116
Returns
117
--------
118
List[:class:`twitchio.Tag`]
119
"""
120
from .models import Tag
121
122
data = await self._http.get_channel_tags(str(self.id))
123
return [Tag(x) for x in data]
124
125
async def replace_tags(self, token: str, tags: List[Union[str, "Tag"]]):
126
"""|coro|
127
128
Replaces the channels active tags. Tags expire 72 hours after being applied,
129
unless the stream is live during that time period.
130
131
Parameters
132
-----------
133
token: :class:`str`
134
An oauth token with the user:edit:broadcast scope
135
tags: List[Union[:class:`twitchio.Tag`, :class:`str`]]
136
A list of :class:`twitchio.Tag` or tag ids to put on the channel. Max 100
137
"""
138
tags = [x if isinstance(x, str) else x.id for x in tags]
139
await self._http.put_replace_channel_tags(token, str(self.id), tags)
140
141
async def get_custom_rewards(
142
self, token: str, *, only_manageable=False, ids: List[int] = None, force=False
143
) -> List["CustomReward"]:
144
"""|coro|
145
146
Fetches the channels custom rewards (aka channel points) from the api.
147
Parameters
148
----------
149
token : :class:`str`
150
The users oauth token.
151
only_manageable : :class:`bool`
152
Whether to fetch all rewards or only ones you can manage. Defaults to false.
153
ids : List[:class:`int`]
154
An optional list of reward ids
155
force : :class:`bool`
156
Whether to force a fetch or try to get from cache. Defaults to False
157
158
Returns
159
-------
160
161
"""
162
if not force and self._cached_rewards and self._cached_rewards[0] + 300 > time.monotonic():
163
return self._cached_rewards[1]
164
165
try:
166
data = await self._http.get_rewards(token, self.id, only_manageable, ids)
167
except Unauthorized as error:
168
raise Unauthorized("The given token is invalid", "", 401) from error
169
except HTTPException as error:
170
status = error.args[2]
171
if status == 403:
172
raise HTTPException(
173
"The custom reward was created by a different application, or channel points are "
174
"not available for the broadcaster (403)",
175
error.args[1],
176
403,
177
) from error
178
raise
179
else:
180
values = [CustomReward(self._http, x, self) for x in data]
181
self._cached_rewards = time.monotonic(), values
182
return values
183
184
async def fetch_bits_leaderboard(
185
self, token: str, period: str = "all", user_id: int = None, started_at: datetime.datetime = None
186
) -> "BitsLeaderboard":
187
"""|coro|
188
189
Fetches the bits leaderboard for the channel. This requires an OAuth token with the bits:read scope.
190
191
Parameters
192
-----------
193
token: :class:`str`
194
the OAuth token with the bits:read scope
195
period: Optional[:class:`str`]
196
one of `day`, `week`, `month`, `year`, or `all`, defaults to `all`
197
started_at: Optional[:class:`datetime.datetime`]
198
the timestamp to start the period at. This is ignored if the period is `all`
199
user_id: Optional[:class:`int`]
200
the id of the user to fetch for
201
"""
202
from .models import BitsLeaderboard
203
204
data = await self._http.get_bits_board(token, period, user_id, started_at)
205
return BitsLeaderboard(self._http, data)
206
207
async def start_commercial(self, token: str, length: int) -> dict:
208
"""|coro|
209
210
Starts a commercial on the channel. Requires an OAuth token with the `channel:edit:commercial` scope.
211
212
Parameters
213
-----------
214
token: :class:`str`
215
the OAuth token
216
length: :class:`int`
217
the length of the commercial. Should be one of `30`, `60`, `90`, `120`, `150`, `180`
218
219
Returns
220
--------
221
:class:`dict` a dictionary with `length`, `message`, and `retry_after`
222
"""
223
data = await self._http.post_commercial(token, str(self.id), length)
224
return data[0]
225
226
async def create_clip(self, token: str, has_delay=False) -> dict:
227
"""|coro|
228
229
Creates a clip on the channel. Note that clips are not created instantly, so you will have to query
230
:meth:`~get_clips` to confirm the clip was created. Requires an OAuth token with the `clips:edit` scope
231
232
Parameters
233
-----------
234
token: :class:`str`
235
the OAuth token
236
has_delay: :class:`bool`
237
Whether the clip should have a delay to match that of a viewer. Defaults to False
238
239
Returns
240
--------
241
:class:`dict` a dictionary with `id` and `edit_url`
242
"""
243
data = await self._http.post_create_clip(token, self.id, has_delay)
244
return data[0]
245
246
async def fetch_clips(self) -> List["Clip"]:
247
"""|coro|
248
249
Fetches clips from the api. This will only return clips from the specified user.
250
Use :class:`Client.fetch_clips` to fetch clips by id
251
252
Returns
253
--------
254
List[:class:`twitchio.Clip`]
255
"""
256
from .models import Clip
257
258
data = await self._http.get_clips(self.id)
259
260
return [Clip(self._http, x) for x in data]
261
262
async def fetch_hypetrain_events(self, id: str = None, token: str = None):
263
"""|coro|
264
265
Fetches hypetrain event from the api. Needs a token with the channel:read:hype_train scope.
266
267
Parameters
268
-----------
269
id: Optional[:class:`str`]
270
The hypetrain id, if known, to fetch for
271
token: Optional[:class:`str`]
272
The oauth token to use. Will default to the one passed to the bot/client.
273
274
Returns
275
--------
276
List[:class:`twitchio.HypeTrainEvent`]
277
A list of hypetrain events
278
"""
279
from .models import HypeTrainEvent
280
281
data = await self._http.get_hype_train(self.id, id=id, token=token)
282
return [HypeTrainEvent(self._http, d) for d in data]
283
284
async def fetch_bans(self, token: str, userids: List[Union[str, int]] = None) -> List["UserBan"]:
285
"""|coro|
286
287
Fetches a list of people the User has banned from their channel.
288
289
Parameters
290
-----------
291
token: :class:`str`
292
The oauth token with the moderation:read scope.
293
userids: List[Union[:class:`str`, :class:`int`]]
294
An optional list of userids to fetch. Will fetch all bans if this is not passed
295
"""
296
data = await self._http.get_channel_bans(token, str(self.id), user_ids=userids)
297
return [UserBan(self._http, d) for d in data]
298
299
async def fetch_ban_events(self, token: str, userids: List[int] = None):
300
"""|coro|
301
302
Fetches ban/unban events from the User's channel.
303
304
Parameters
305
-----------
306
token: :class:`str`
307
The oauth token with the moderation:read scope.
308
userids: List[:class:`int`]
309
An optional list of users to fetch ban/unban events for
310
311
Returns
312
--------
313
List[:class:`twitchio.BanEvent`]
314
"""
315
from .models import BanEvent
316
317
data = await self._http.get_channel_ban_unban_events(token, str(self.id), userids)
318
return [BanEvent(self._http, x, self) for x in data]
319
320
async def fetch_moderators(self, token: str, userids: List[int] = None):
321
"""|coro|
322
323
Fetches the moderators for this channel.
324
325
Parameters
326
-----------
327
token: :class:`str`
328
The oauth token with the moderation:read scope.
329
userids: List[:class:`int`]
330
An optional list of users to check mod status of
331
332
Returns
333
--------
334
List[:class:`twitchio.PartialUser`]
335
"""
336
data = await self._http.get_channel_moderators(token, str(self.id), user_ids=userids)
337
return [PartialUser(self._http, d["user_id"], d["user_name"]) for d in data]
338
339
async def fetch_mod_events(self, token: str):
340
"""|coro|
341
342
Fetches mod events (moderators being added and removed) for this channel.
343
344
Parameters
345
-----------
346
token: :class:`str`
347
The oauth token with the moderation:read scope.
348
349
Returns
350
--------
351
List[:class:`twitchio.ModEvent`]
352
"""
353
from .models import ModEvent
354
355
data = await self._http.get_channel_mod_events(token, str(self.id))
356
return [ModEvent(self._http, d, self) for d in data]
357
358
async def automod_check(self, token: str, query: list):
359
"""|coro|
360
361
Checks if a string passes the automod filter
362
363
Parameters
364
-----------
365
token: :class:`str`
366
The oauth token with the moderation:read scope.
367
query: List[:class:`AutomodCheckMessage`]
368
A list of :class:`twitchio.AutomodCheckMessage`
369
370
Returns
371
--------
372
List[:class:`twitchio.AutomodCheckResponse`]
373
"""
374
from .models import AutomodCheckResponse
375
376
data = await self._http.post_automod_check(token, str(self.id), *[x._to_dict() for x in query])
377
return [AutomodCheckResponse(d) for d in data]
378
379
async def fetch_stream_key(self, token: str):
380
"""|coro|
381
382
Fetches the users stream key
383
384
Parameters
385
-----------
386
token: :class:`str`
387
The oauth token with the channel:read:stream_key scope
388
389
Returns
390
--------
391
:class:`str`
392
"""
393
data = await self._http.get_stream_key(token, str(self.id))
394
return data
395
396
async def fetch_following(self, token: str = None) -> List["FollowEvent"]:
397
"""|coro|
398
399
Fetches a list of users that this user is following.
400
401
Parameters
402
-----------
403
token: Optional[:class:`str`]
404
An oauth token to use instead of the bots token
405
406
Returns
407
--------
408
List[:class:`twitchio.FollowEvent`]
409
"""
410
from .models import FollowEvent
411
412
data = await self._http.get_user_follows(token=token, from_id=str(self.id))
413
return [FollowEvent(self._http, d, from_=self) for d in data]
414
415
async def fetch_followers(self, token: str = None):
416
"""|coro|
417
418
Fetches a list of users that are following this user.
419
420
Parameters
421
-----------
422
token: Optional[:class:`str`]
423
An oauth token to use instead of the bots token
424
425
Returns
426
--------
427
List[:class:`twitchio.FollowEvent`]
428
"""
429
from .models import FollowEvent
430
431
data = await self._http.get_user_follows(to_id=str(self.id))
432
return [FollowEvent(self._http, d, to=self) for d in data]
433
434
async def fetch_follow(self, to_user: "PartialUser", token: str = None):
435
"""|coro|
436
437
Check if a user follows another user or when they followed a user.
438
439
Parameters
440
-----------
441
to_user: :class:`PartialUser`
442
token: Optional[:class:`str`]
443
An oauth token to use instead of the bots token
444
445
Returns
446
--------
447
:class:`twitchio.FollowEvent`
448
"""
449
if not isinstance(to_user, PartialUser):
450
raise TypeError(f"to_user must be a PartialUser not {type(to_user)}")
451
452
from .models import FollowEvent
453
454
data = await self._http.get_user_follows(from_id=str(self.id), to_id=str(to_user.id))
455
return FollowEvent(self._http, data[0]) if data else None
456
457
async def follow(self, userid: int, token: str, *, notifications=False):
458
"""|coro|
459
460
Follows the user
461
462
Parameters
463
-----------
464
userid: :class:`int`
465
The user id to follow this user with
466
token: :class:`str`
467
An oauth token with the user:edit:follows scope
468
notifications: :class:`bool`
469
Whether to allow push notifications when this user goes live. Defaults to False
470
"""
471
await self._http.post_follow_channel(
472
token, from_id=str(userid), to_id=str(self.id), notifications=notifications
473
)
474
475
async def unfollow(self, userid: int, token: str):
476
"""|coro|
477
478
Unfollows the user
479
480
Parameters
481
-----------
482
userid: :class:`int`
483
The user id to unfollow this user with
484
token: :class:`str`
485
An oauth token with the user:edit:follows scope
486
"""
487
await self._http.delete_unfollow_channel(token, from_id=str(userid), to_id=str(self.id))
488
489
async def fetch_subscriptions(self, token: str, userids: List[int] = None):
490
"""|coro|
491
492
Fetches the subscriptions for this channel.
493
494
Parameters
495
-----------
496
token: :class:`str`
497
An oauth token with the channel:read:subscriptions scope
498
userids: Optional[List[:class:`int`]]
499
An optional list of userids to look for
500
501
Returns
502
--------
503
List[:class:`twitchio.SubscriptionEvent`]
504
"""
505
from .models import SubscriptionEvent
506
507
data = await self._http.get_channel_subscriptions(token, str(self.id), user_ids=userids)
508
return [SubscriptionEvent(self._http, d, broadcaster=self) for d in data]
509
510
async def create_marker(self, token: str, description: str = None):
511
"""|coro|
512
513
Creates a marker on the stream. This only works if the channel is live (among other conditions)
514
515
Parameters
516
-----------
517
token: :class:`str`
518
An oauth token with the user:edit:broadcast scope
519
description: :class:`str`
520
An optional description of the marker
521
522
Returns
523
--------
524
:class:`twitchio.Marker`
525
"""
526
from .models import Marker
527
528
data = await self._http.post_stream_marker(token, user_id=str(self.id), description=description)
529
return Marker(data[0])
530
531
async def fetch_markers(self, token: str, video_id: str = None):
532
"""|coro|
533
534
Fetches markers from the given video id, or the most recent video.
535
The Twitch api will only return markers created by the user of the authorized token
536
537
Parameters
538
-----------
539
token: :class:`str`
540
An oauth token with the user:edit:broadcast scope
541
video_id: :class:`str`
542
A specific video o fetch from. Defaults to the most recent stream if not passed
543
544
Returns
545
--------
546
Optional[:class:`twitchio.VideoMarkers`]
547
"""
548
from .models import VideoMarkers
549
550
data = await self._http.get_stream_markers(token, user_id=str(self.id), video_id=video_id)
551
if data:
552
return VideoMarkers(data[0]["videos"])
553
554
async def fetch_extensions(self, token: str):
555
"""|coro|
556
557
Fetches extensions the user has (active and inactive)
558
559
Parameters
560
-----------
561
token: :class:`str`
562
An oauth token with the user:read:broadcast scope
563
564
Returns
565
--------
566
List[:class:`twitchio.Extension`]
567
"""
568
from .models import Extension
569
570
data = await self._http.get_channel_extensions(token)
571
return [Extension(d) for d in data]
572
573
async def fetch_active_extensions(self, token: str = None):
574
"""|coro|
575
576
Fetches active extensions the user has.
577
Returns a dictionary containing the following keys: `panel`, `overlay`, `component`.
578
579
Parameters
580
-----------
581
token: Optional[:class:`str`]
582
An oauth token with the user:read:broadcast *or* user:edit:broadcast scope
583
584
Returns
585
--------
586
Dict[:class:`str`, Dict[:class:`int`, :class:`twitchio.ActiveExtension`]]
587
"""
588
from .models import ActiveExtension
589
590
data = await self._http.get_user_active_extensions(token, str(self.id))
591
return {typ: {int(n): ActiveExtension(d) for n, d in vals.items()} for typ, vals in data.items()}
592
593
async def update_extensions(self, token: str, extensions: "ExtensionBuilder"):
594
"""|coro|
595
596
Updates a users extensions. See the :class:`twitchio.ExtensionBuilder`
597
598
Parameters
599
-----------
600
token: :class:`str`
601
An oauth token with user:edit:broadcast scope
602
extensions: :class:`twitchio.ExtensionBuilder`
603
A :class:`twitchio.ExtensionBuilder` to be given to the twitch api
604
605
Returns
606
--------
607
Dict[:class:`str`, Dict[:class:`int`, :class:`twitchio.ActiveExtension`]]
608
"""
609
from .models import ActiveExtension
610
611
data = await self._http.put_user_extensions(token, extensions._to_dict())
612
return {typ: {int(n): ActiveExtension(d) for n, d in vals.items()} for typ, vals in data.items()}
613
614
async def fetch_videos(self, period="all", sort="time", type="all", language=None):
615
"""|coro|
616
617
Fetches videos that belong to the user. If you have specific video ids use :func:`Client.fetch_videos`
618
619
Parameters
620
-----------
621
period: :class:`str`
622
The period for which to fetch videos. Valid values are `all`, `day`, `week`, `month`. Defaults to `all`
623
sort: :class:`str`
624
Sort orders of the videos. Valid values are `time`, `trending`, `views`, Defaults to `time`
625
type: Optional[:class:`str`]
626
Type of the videos to fetch. Valid values are `upload`, `archive`, `highlight`. Defaults to `all`
627
language: Optional[:class:`str`]
628
Language of the videos to fetch. Must be an `ISO-639-1 <https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes>`_ two letter code.
629
630
Returns
631
--------
632
List[:class:`twitchio.Video`]
633
"""
634
from .models import Video
635
636
data = await self._http.get_videos(user_id=str(self.id), period=period, sort=sort, type=type, language=language)
637
return [Video(self._http, x, self) for x in data]
638
639
async def end_prediction(
640
self, token: str, prediction_id: str, status: str, winning_outcome_id: str = None
641
) -> "Prediction":
642
"""|coro|
643
644
End a prediction with an outcome.
645
646
Parameters
647
-----------
648
token: :class:`str`
649
An oauth token with the channel:manage:predictions scope
650
prediction_id: :class:`str`
651
ID of the prediction to end.
652
653
Returns
654
--------
655
:class:`twitchio.Prediction`
656
"""
657
from .models import Prediction
658
659
data = await self._http.patch_prediction(
660
token,
661
broadcaster_id=str(self.id),
662
prediction_id=prediction_id,
663
status=status,
664
winning_outcome_id=winning_outcome_id,
665
)
666
return Prediction(self._http, data[0])
667
668
async def get_predictions(self, token: str, prediction_id: str = None) -> List["Prediction"]:
669
"""|coro|
670
671
Gets information on a prediction or the list of predictions
672
if none is provided.
673
674
Parameters
675
-----------
676
token: :class:`str`
677
An oauth token with the channel:manage:predictions scope
678
prediction_id: :class:`str`
679
ID of the prediction to receive information about.
680
681
Returns
682
--------
683
:class:`twitchio.Prediction`
684
"""
685
from .models import Prediction
686
687
data = await self._http.get_predictions(token, broadcaster_id=str(self.id), prediction_id=prediction_id)
688
return [Prediction(self._http, d) for d in data]
689
690
async def create_prediction(
691
self, token: str, title: str, blue_outcome: str, pink_outcome: str, prediction_window: int
692
) -> "Prediction":
693
"""|coro|
694
695
Creates a prediction for the channel.
696
697
Parameters
698
-----------
699
token: :class:`str`
700
An oauth token with the channel:manage:predictions scope
701
title: :class:`str`
702
Title for the prediction (max of 45 characters)
703
blue_outcome: :class:`str`
704
Text for the first outcome people can vote for. (max 25 characters)
705
pink_outcome: :class:`str`
706
Text for the second outcome people can vote for. (max 25 characters)
707
prediction_window: :class:`int`
708
Total duration for the prediction (in seconds)
709
710
Returns
711
--------
712
:class:`twitchio.Prediction`
713
"""
714
from .models import Prediction
715
716
data = await self._http.post_prediction(
717
token,
718
broadcaster_id=str(self.id),
719
title=title,
720
blue_outcome=blue_outcome,
721
pink_outcome=pink_outcome,
722
prediction_window=prediction_window,
723
)
724
return Prediction(self._http, data[0])
725
726
async def modify_stream(self, token: str, game_id: int = None, language: str = None, title: str = None):
727
"""|coro|
728
729
Modify stream information
730
Parameters
731
-----------
732
token: :class:`str`
733
An oauth token with the channel:manage:broadcast scope
734
game_id: :class:`int`
735
Optional game ID being played on the channel. Use 0 to unset the game.
736
language: :class:`str`
737
Optional language of the channel. A language value must be either the ISO 639-1 two-letter code for a supported stream language or “other”.
738
title: :class:`str`
739
Optional title of the stream.
740
"""
741
if game_id is not None:
742
game_id = str(game_id)
743
744
await self._http.patch_channel(
745
token,
746
broadcaster_id=str(self.id),
747
game_id=game_id,
748
language=language,
749
title=title,
750
)
751
752
async def fetch_schedule(
753
self,
754
segment_ids: List[str] = None,
755
start_time: datetime.datetime = None,
756
utc_offset: int = None,
757
first: int = 20,
758
):
759
"""|coro|
760
761
Fetches the schedule of a streamer
762
Parameters
763
-----------
764
segment_ids: Optional[List[:class:`str`]]
765
List of segment IDs of the stream schedule to return. Maximum: 100
766
start_time: Optional[:class:`datetime.datetime`]
767
A datetime object to start returning stream segments from. If not specified, the current date and time is used.
768
utc_offset: Optional[:class:`int`]
769
A timezone offset for the requester specified in minutes. +4 hours from GMT would be `240`
770
first: Optional[:class:`int`]
771
Maximum number of stream segments to return. Maximum: 25. Default: 20.
772
Returns
773
--------
774
:class:`twitchio.Schedule`
775
"""
776
from .models import Schedule
777
778
data = await self._http.get_channel_schedule(
779
broadcaster_id=str(self.id),
780
segment_ids=segment_ids,
781
start_time=start_time,
782
utc_offset=utc_offset,
783
first=first,
784
)
785
786
return Schedule(self._http, data)
787
788
async def fetch_channel_teams(self):
789
"""|coro|
790
791
Fetches a list of Twitch Teams of which the specified channel/broadcaster is a member.
792
793
Returns
794
--------
795
List[:class:`twitchio.ChannelTeams`]
796
"""
797
from .models import ChannelTeams
798
799
data = await self._http.get_channel_teams(
800
broadcaster_id=str(self.id),
801
)
802
803
return [ChannelTeams(self._http, x) for x in data]
804
805
806
class BitLeaderboardUser(PartialUser):
807
808
__slots__ = "rank", "score"
809
810
def __init__(self, http: "TwitchHTTP", data: dict):
811
super(BitLeaderboardUser, self).__init__(http, id=data["user_id"], name=data["user_name"])
812
self.rank: int = data["rank"]
813
self.score: int = data["score"]
814
815
816
class UserBan(PartialUser):
817
818
__slots__ = ("expires_at",)
819
820
def __init__(self, http: "TwitchHTTP", data: dict):
821
super(UserBan, self).__init__(http, name=data["user_login"], id=data["user_id"])
822
self.expires_at = (
823
datetime.datetime.strptime(data["expires_at"], "%Y-%m-%dT%H:%M:%SZ") if data["expires_at"] else None
824
)
825
826
827
class SearchUser(PartialUser):
828
829
__slots__ = "game_id", "name", "display_name", "language", "title", "thumbnail_url", "live", "started_at", "tag_ids"
830
831
def __init__(self, http: "TwitchHTTP", data: dict):
832
self._http = http
833
self.display_name: str = data["display_name"]
834
self.name: str = data["broadcaster_login"]
835
self.id: int = int(data["id"])
836
self.game_id: str = data["game_id"]
837
self.title: str = data["title"]
838
self.thumbnail_url: str = data["thumbnail_url"]
839
self.language: str = data["broadcaster_language"]
840
self.live: bool = data["is_live"]
841
self.started_at = datetime.datetime.strptime(data["started_at"], "%Y-%m-%dT%H:%M:%SZ") if self.live else None
842
self.tag_ids: List[str] = data["tag_ids"]
843
844
845
class User(PartialUser):
846
847
__slots__ = (
848
"_http",
849
"id",
850
"name",
851
"display_name",
852
"type",
853
"broadcaster_type",
854
"description",
855
"profile_image",
856
"offline_image",
857
"view_count",
858
"created_at",
859
"email",
860
"_cached_rewards",
861
)
862
863
def __init__(self, http: "TwitchHTTP", data: dict):
864
self._http = http
865
self.id = int(data["id"])
866
self.name: str = data["login"]
867
self.display_name: str = data["display_name"]
868
self.type = UserTypeEnum(data["type"])
869
self.broadcaster_type = BroadcasterTypeEnum(data["broadcaster_type"])
870
self.description: str = data["description"]
871
self.profile_image: str = data["profile_image_url"]
872
self.offline_image: str = data["offline_image_url"]
873
self.view_count: Tuple[int] = (data["view_count"],) # this isn't supposed to be a tuple but too late to fix it!
874
self.created_at = parse_timestamp(data["created_at"])
875
self.email: Optional[str] = data.get("email")
876
self._cached_rewards = None
877
878
def __repr__(self):
879
return f"<User id={self.id} name={self.name} display_name={self.display_name} type={self.type}>"
880
881