Path: blob/master/ invest-robot-contest_TinkoffBotTwitch-main/venv/lib/python3.8/site-packages/twitchio/abcs.py
7783 views
"""1The MIT License (MIT)23Copyright (c) 2017-2021 TwitchIO45Permission is hereby granted, free of charge, to any person obtaining a6copy of this software and associated documentation files (the "Software"),7to deal in the Software without restriction, including without limitation8the rights to use, copy, modify, merge, publish, distribute, sublicense,9and/or sell copies of the Software, and to permit persons to whom the10Software is furnished to do so, subject to the following conditions:1112The above copyright notice and this permission notice shall be included in13all copies or substantial portions of the Software.1415THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS16OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE18AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING20FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER21DEALINGS IN THE SOFTWARE.22"""2324import abc25import time2627from .cooldowns import RateBucket28from .errors import *293031class IRCLimiterMapping:32def __init__(self):33self.buckets = {}3435def get_bucket(self, channel: str, method: str) -> RateBucket:36try:37bucket = self.buckets[channel]38except KeyError:39bucket = RateBucket(method=method)40self.buckets[channel] = bucket4142if bucket.method != method:43bucket.method = method44bucket.limit = bucket.MODLIMIT if method == "mod" else bucket.IRCLIMIT45self.buckets[channel] = bucket4647return bucket484950limiter = IRCLimiterMapping()515253class Messageable(abc.ABC):5455__slots__ = ()5657@abc.abstractmethod58def _fetch_channel(self):59raise NotImplementedError6061@abc.abstractmethod62def _fetch_websocket(self):63raise NotImplementedError6465@abc.abstractmethod66def _fetch_message(self):67raise NotImplementedError6869@abc.abstractmethod70def _bot_is_mod(self):71raise NotImplementedError7273def check_bucket(self, channel):74mod = self._bot_is_mod()7576if mod:77bucket = limiter.get_bucket(channel=channel, method="mod")78else:79bucket = limiter.get_bucket(channel=channel, method="irc")8081now = time.time()82bucket.update()8384if bucket.limited:85raise IRCCooldownError(86f"IRC Message rate limit reached for channel <{channel}>."87f" Please try again in {bucket._reset - now:.2f}s"88)8990def check_content(self, content: str):91if len(content) > 500:92raise InvalidContent("Content must not exceed 500 characters.")9394async def send(self, content: str):95"""|coro|969798Send a message to the destination associated with the dataclass.99100Destination will either be a channel or user.101102Parameters103------------104content: str105The content you wish to send as a message. The content must be a string.106107Raises108--------109InvalidContent110Invalid content.111"""112entity = self._fetch_channel()113ws = self._fetch_websocket()114115self.check_content(content)116self.check_bucket(channel=entity.name)117118try:119name = entity.channel.name120except AttributeError:121name = entity.name122123if entity.__messageable_channel__:124await ws.send(f"PRIVMSG #{name} :{content}\r\n")125else:126await ws.send(f"PRIVMSG #jtv :/w {entity.name} {content}\r\n")127128async def reply(self, content: str):129"""|coro|130131132Send a message in reply to the user who sent a message in the destination133associated with the dataclass.134135Destination will be the context of which the message/command was sent.136137Parameters138------------139content: str140The content you wish to send as a message. The content must be a string.141142Raises143--------144InvalidContent145Invalid content.146"""147entity = self._fetch_channel()148ws = self._fetch_websocket()149message = self._fetch_message()150151self.check_content(content)152self.check_bucket(channel=entity.name)153154try:155name = entity.channel.name156except AttributeError:157name = entity.name158159if entity.__messageable_channel__:160await ws.reply(message.id, f"PRIVMSG #{name} :{content}\r\n")161else:162await ws.send(f"PRIVMSG #jtv :/w {name} {content}\r\n")163164165