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/chatter.py
7790 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
from typing import Optional, TYPE_CHECKING, Dict
26
27
from .abcs import Messageable
28
from .enums import PredictionEnum
29
30
if TYPE_CHECKING:
31
from .user import User
32
from .websocket import WSConnection
33
34
35
__all__ = ("PartialChatter", "Chatter")
36
37
38
class PartialChatter(Messageable):
39
40
__messageable_channel__ = False
41
42
def __init__(self, websocket, **kwargs):
43
self._name = kwargs.get("name")
44
self._ws = websocket
45
self._channel = kwargs.get("channel", self._name)
46
self._message = kwargs.get("message")
47
48
def __repr__(self):
49
return f"<PartialChatter name: {self._name}, channel: {self._channel}>"
50
51
def __eq__(self, other):
52
return other.name == self.name and other.channel.name == other.channel.name
53
54
def __hash__(self):
55
return hash(self.name + self.channel.name)
56
57
async def user(self) -> "User":
58
"""|coro|
59
60
Fetches a :class:`twitchio.User` object based off the chatters channel name
61
62
Returns
63
--------
64
:class:`twitchio.User`
65
"""
66
return (await self._ws._client.fetch_users(names=[self.name]))[0]
67
68
@property
69
def name(self):
70
"""The users name"""
71
return self._name
72
73
@property
74
def channel(self):
75
"""The channel associated with the user."""
76
return self._channel
77
78
def _fetch_channel(self):
79
return self # Abstract method
80
81
def _fetch_websocket(self):
82
return self._ws # Abstract method
83
84
def _fetch_message(self):
85
return self._message # Abstract method
86
87
def _bot_is_mod(self):
88
return False
89
90
91
class Chatter(PartialChatter):
92
93
__slots__ = (
94
"_name",
95
"_channel",
96
"_tags",
97
"_badges",
98
"_cached_badges",
99
"_ws",
100
"id",
101
"_turbo",
102
"_sub",
103
"_mod",
104
"_display_name",
105
"_colour",
106
)
107
108
__messageable_channel__ = False
109
110
def __init__(self, websocket: "WSConnection", **kwargs):
111
super(Chatter, self).__init__(websocket, **kwargs)
112
self._tags = kwargs.get("tags", None)
113
self._ws = websocket
114
115
self._cached_badges: Optional[Dict[str, str]] = None
116
117
if not self._tags:
118
self.id = None
119
self._badges = None
120
self._turbo = None
121
self._sub = None
122
self._mod = None
123
self._display_name = None
124
self._colour = None
125
return
126
127
self.id = self._tags.get("user-id")
128
self._badges = self._tags.get("badges")
129
self._turbo = self._tags.get("turbo")
130
self._sub = int(self._tags["subscriber"])
131
self._mod = int(self._tags["mod"])
132
self._display_name = self._tags["display-name"]
133
self._colour = self._tags["color"]
134
135
if self._badges:
136
self._cached_badges = {k: v for k, v in [badge.split("/") for badge in self._badges.split(",")]}
137
138
def _bot_is_mod(self):
139
cache = self._ws._cache[self._channel.name] # noqa
140
for user in cache:
141
if user.name == self._ws.nick:
142
try:
143
mod = user.is_mod
144
except AttributeError:
145
return False
146
147
return mod
148
149
@property
150
def name(self) -> str:
151
"""The users name. This may be formatted differently than display name."""
152
return self._name or (self.display_name and self.display_name.lower())
153
154
@property
155
def badges(self) -> dict:
156
"""The users badges."""
157
if self._cached_badges:
158
return self._cached_badges.copy()
159
160
return {}
161
162
@property
163
def display_name(self) -> str:
164
"""The users display name."""
165
return self._display_name
166
167
@property
168
def mention(self) -> str:
169
"""Mentions the users display name by prefixing it with '@'"""
170
return f"@{self._display_name}"
171
172
@property
173
def colour(self) -> str:
174
"""The users colour. Alias to color."""
175
return self._colour
176
177
@property
178
def color(self) -> str:
179
"""The users color."""
180
return self.colour
181
182
@property
183
def is_broadcaster(self) -> bool:
184
"""A boolean indicating whether the User is the broadcaster of the current channel."""
185
186
return "broadcaster" in self.badges
187
188
@property
189
def is_mod(self) -> bool:
190
"""A boolean indicating whether the User is a moderator of the current channel."""
191
if self._mod == 1:
192
return True
193
194
return self.channel.name == self.name.lower()
195
196
@property
197
def is_turbo(self) -> Optional[bool]:
198
"""A boolean indicating whether the User is Turbo.
199
200
Could be None if no Tags were received.
201
"""
202
return self._turbo
203
204
@property
205
def is_subscriber(self) -> bool:
206
"""A boolean indicating whether the User is a subscriber of the current channel.
207
208
.. note::
209
210
changed in 2.1.0: return value is no longer optional. founders will now appear as subscribers
211
"""
212
return bool(self._sub) or "founder" in self.badges
213
214
@property
215
def prediction(self) -> Optional[PredictionEnum]:
216
"""
217
The users current prediction, if one exists.
218
219
Returns
220
--------
221
Optional[:class:`twitchio.enums.PredictionEnum`]
222
"""
223
if "blue-1" in self.badges:
224
return PredictionEnum("blue-1")
225
226
elif "pink-2" in self.badges:
227
return PredictionEnum("pink-2")
228
229
return None
230
231
232
class WhisperChatter(PartialChatter):
233
234
__messageable_channel__ = False
235
236
def __init__(self, websocket: "WSConnection", **kwargs):
237
super().__init__(websocket, **kwargs)
238
239
def __repr__(self):
240
return f"<WhisperChatter name: {self._name}>"
241
242
@property
243
def channel(self):
244
return None
245
246
def _fetch_channel(self):
247
return self # Abstract method
248
249
def _fetch_websocket(self):
250
return self._ws # Abstract method
251
252
def _bot_is_mod(self):
253
return False
254
255