def __init__(self, prem: tuple, reg: tuple): self.types = { "user": BucketType.user, "channel": BucketType.channel, "guild": BucketType.guild, } self.premium_mapping = CooldownMapping.from_cooldown(*self.clean(prem)) self.regular_mapping = CooldownMapping.from_cooldown(*self.clean(reg))
def decorator(func): try: cooldown_obj = Cooldown(rate, per, type) # type: ignore except Exception: cooldown_obj = Cooldown(rate, per) try: mapping = CooldownMapping(cooldown_obj) # type: ignore except Exception: mapping = CooldownMapping(cooldown_obj, type) if isinstance(func, InvokableApplicationCommand): func._buckets = mapping else: func.__slash_cooldown__ = mapping return func
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.db = None # pylint: disable=invalid-name self.session = ClientSession() self.xp_cooldown = CooldownMapping.from_cooldown(1, 60, BucketType.member) self.players = {} self.prefixes = [] self.welcome_message = None
def __init__(self, bot) -> None: self.bot = bot self.bot.check(is_not_excluded) self.bot.before_invoke(self.before_invoke) self.spam_counter = {} self.spam_cooldown = CooldownMapping.from_cooldown( rate=10, per=7.5, type=BucketType.user) self.exclusion_watch = None
def __init__(self, func: Callable[..., Awaitable], *, name: str = None, **kwargs): self.func = func self.name = name or func.__name__ self._error_handler: Optional[Callable[..., Any]] = None self.auto_sync: bool = True # Extract checks if hasattr(func, "__slash_checks__"): self.checks: List[Callable[..., Any]] = func.__slash_checks__ else: self.checks: List[Callable[..., Any]] = [] # Cooldown try: cooldown = func.__slash_cooldown__ except AttributeError: cooldown = None if cooldown is None: try: # Assuming that it's discord.py 1.7.0+ self._buckets = CooldownMapping(cooldown, BucketType.default) except Exception: # discord.py <= 1.6.x try: self._buckets = CooldownMapping(cooldown) # type: ignore except Exception: # Hopefully we never reach this self._buckets: CooldownMapping = None # type: ignore else: self._buckets = cooldown # Add custom kwargs for kw, value in kwargs.items(): if not hasattr(self, kw): setattr(self, kw, value)
def cooldown_with_role_bypass(rate: int, per: float, type: BucketType = BucketType.default, *, bypass_roles: Iterable[int]) -> Callable: """ Applies a cooldown to a command, but allows members with certain roles to be ignored. NOTE: this replaces the `Command.before_invoke` callback, which *might* introduce problems in the future. """ # Make it a set so lookup is hash based. bypass = set(bypass_roles) # This handles the actual cooldown logic. buckets = CooldownMapping(Cooldown(rate, per, type)) # Will be called after the command has been parse but before it has been invoked, ensures that # the cooldown won't be updated if the user screws up their input to the command. async def predicate(cog: Cog, ctx: Context) -> None: nonlocal bypass, buckets if any(role.id in bypass for role in ctx.author.roles): return # Cooldown logic, taken from discord.py internals. current = ctx.message.created_at.replace( tzinfo=datetime.timezone.utc).timestamp() bucket = buckets.get_bucket(ctx.message) retry_after = bucket.update_rate_limit(current) if retry_after: raise CommandOnCooldown(bucket, retry_after) def wrapper(command: Command) -> Command: # NOTE: this could be changed if a subclass of Command were to be used. I didn't see the need for it # so I just made it raise an error when the decorator is applied before the actual command object exists. # # If the `before_invoke` detail is ever a problem then I can quickly just swap over. if not isinstance(command, Command): raise TypeError( 'Decorator `cooldown_with_role_bypass` must be applied after the command decorator. ' 'This means it has to be above the command decorator in the code.' ) command._before_invoke = predicate return command return wrapper
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) print('-' * 50) self.session = AioClientSession(loop=self.loop) for attr in ('_command_cd', '_error_cd', '_clock_cd', '_warn_cd'): setattr( self, attr, CooldownMapping.from_cooldown(1, GLOBAL_USER_COOLDOWN, BucketType.member)) for env in ('JISHAKU_NO_UNDERSCORE', 'JISHAKU_NO_UNDERSCORE'): environ[env] = 'true' for ext in ('jishaku', EXTENSION_LOADER_PATH): self.load_extension(ext)
def decorator(func): if isinstance(func, Command): nonlocal rate, per, type db_name = (f"Cooldowns") make_db_if_not_exists(path=f"{DBPATH}\\{db_name}.json") cooldowns = db_receive(db_name) if not rate: rate = 1 if not per: if str(func) not in cooldowns: cooldowns[str(func)] = default_cooldown db_update(db_name, cooldowns) per = cooldowns[str(func)] func._buckets = CooldownMapping(Cooldown(rate, per, type)) else: func.__commands_cooldown__ = Cooldown(rate, per, type) return func
def __init__(self, bot: Eris): self.bot = bot self.cooldown = CooldownMapping.from_cooldown(1, 60, BucketType.member)
def __init__(self, bot): self.bot = bot self.mem_update = CooldownMapping.from_cooldown( 1, 1, BucketType.member)
from dataclasses import dataclass from functools import partial as funct_partial from typing import List, Tuple, Union from discord.ext.commands import BucketType, CooldownMapping from discord.ext.menus import ListPageSource from jikanpy import AioJikan from utils.converters import to_human_datetime, try_unpack_class from utils.formatters import BetterEmbed global_cd = BucketType.default ApiCooldown = namedtuple('ApiCooldown', ['long', 'short']) API_COOLDOWNS = ApiCooldown( long=CooldownMapping.from_cooldown(30, 60, global_cd), short=CooldownMapping.from_cooldown(2, 1, global_cd), ) NSFW_MANGA = {'doujinshi', 'ecchi', 'hentai'} TIME_TEMPLATE = "%Y-%m-%dT%H:%M:%S%z" # iso 8601 #* Base classes @dataclass class Response: request_hash: str request_cached: bool request_cache_expiry: int results: list
class InvokableApplicationCommand: def __init__(self, func: Callable[..., Awaitable], *, name: str = None, **kwargs): self.func = func self.name = name or func.__name__ self._error_handler: Optional[Callable[..., Any]] = None self.auto_sync: bool = True # Extract checks if hasattr(func, "__slash_checks__"): self.checks: List[Callable[..., Any]] = func.__slash_checks__ else: self.checks: List[Callable[..., Any]] = [] # Cooldown try: cooldown = func.__slash_cooldown__ except AttributeError: cooldown = None if cooldown is None: try: # Assuming that it's discord.py 1.7.0+ self._buckets = CooldownMapping(cooldown, BucketType.default) except Exception: # discord.py <= 1.6.x try: self._buckets = CooldownMapping(cooldown) # type: ignore except Exception: # Hopefully we never reach this self._buckets: CooldownMapping = None # type: ignore else: self._buckets = cooldown # Add custom kwargs for kw, value in kwargs.items(): if not hasattr(self, kw): setattr(self, kw, value) async def __call__(self, *args, **kwargs): return await self.func(*args, **kwargs) @staticmethod def _isinstance(obj: Any, typ: type) -> bool: if not isinstance(typ, type) or isinstance( typ, EnumMeta): # special annotation return True if issubclass(typ, discord.User): return isinstance( obj, (discord.User, discord.Member, discord.ClientUser)) else: return isinstance(obj, typ) def _prepare_cooldowns(self, inter: Any): if self._buckets.valid: dt = inter.created_at current = dt.replace(tzinfo=datetime.timezone.utc).timestamp() bucket = self._buckets.get_bucket(inter, current) retry_after = bucket.update_rate_limit(current) if retry_after: raise CommandOnCooldown(bucket, retry_after) def _dispatch_error(self, cog: Any, inter: BaseInteraction, error: Exception): asyncio.create_task(self._invoke_error_handler(cog, inter, error)) async def _run_checks(self, inter: BaseInteraction): for _check in self.checks: if not await _check(inter): raise InteractionCheckFailure( f"command <{self.name}> has failed") async def _maybe_cog_call(self, cog: Any, inter: BaseInteraction): if cog: return await self(cog, inter) else: return await self(inter) async def _invoke_error_handler(self, cog: Any, inter: BaseInteraction, error: Exception): if self._error_handler is None: return if cog: await self._error_handler(cog, inter, error) else: await self._error_handler(inter, error) def error(self, func: Callable[..., Awaitable]): """ A decorator that makes the function below work as error handler for this command. """ if not asyncio.iscoroutinefunction(func): raise TypeError( "The local error handler must be an async function") self._error_handler = func return func def is_on_cooldown(self, inter: Any): """ Checks whether the slash command is currently on cooldown. Parameters ----------- inter: :class:`SlashInteraction` The interaction to use when checking the commands cooldown status. Returns -------- :class:`bool` A boolean indicating if the slash command is on cooldown. """ if not self._buckets.valid: return False bucket = self._buckets.get_bucket(inter) dt = inter.created_at current = dt.replace(tzinfo=datetime.timezone.utc).timestamp() return bucket.get_tokens(current) == 0 def reset_cooldown(self, inter: Any): """ Resets the cooldown on this slash command. Parameters ----------- inter: :class:`SlashInteraction` The interaction to reset the cooldown under. """ if self._buckets.valid: bucket = self._buckets.get_bucket(inter) bucket.reset() def get_cooldown_retry_after(self, inter: Any): """ Retrieves the amount of seconds before this slash command can be tried again. Parameters ----------- inter: :class:`SlashInteraction` The interaction to retrieve the cooldown from. Returns -------- :class:`float` The amount of time left on this slash command's cooldown in seconds. If this is ``0.0`` then the slash command isn't on cooldown. """ if self._buckets.valid: bucket = self._buckets.get_bucket(inter) dt = inter.created_at current = dt.replace(tzinfo=datetime.timezone.utc).timestamp() return bucket.get_retry_after(current) return 0.0
def __init__(self, bot): self.bot = bot self._cooldown = CooldownMapping.from_cooldown( rate=5, per=20, type=BucketType.user )
def __init__(self, bot): self.bot = bot self.cb_client = ac.Cleverbot(TRAVITIA_TOKEN) self.cb_client.set_context(ac.DictContext(self.cb_client)) self.cb_emotions = tuple(ac.Emotion) self._cd = CooldownMapping.from_cooldown(1.0, 5.0, BucketType.member)