def restore_cooldown(cld_dict): """Assume we already checked it exists (is not None).""" rate = cld_dict['rate'] per = cld_dict['per'] cdtype = BucketType[cld_dict['type']] cooldown = Cooldown(rate, per, cdtype) cooldown._window = cld_dict['_window'] cooldown._tokens = cld_dict['_tokens'] cooldown._last = cld_dict['_last'] return cooldown
async def krab(self, ctx, top: str, bottom: str = None): """:crab: HAAN IS HOOG :crab:""" x = await ctx.send(':crab: MEEM AAN HET MAKEN, EVEN GEDULD AUB :crab:') if not bottom: text = top else: text = ','.join([top, bottom]) params = {"text": text} auth = {"Authorization": self.token} async with self.bot.web.get('https://dankmemer.services/api/crab', params=params, headers=auth) as r: if r.status == 429: raise CommandOnCooldown(cooldown=Cooldown( 1, 30, BucketType.default), retry_after=30.0) elif r.status != 200: raise CommandError resp = await r.content.read() b = BytesIO(resp) f = File(b, filename='krab.mp4') await x.delete() return await ctx.send(content=':crab: {} :crab:'.format( text.replace(",", " ").upper()), file=f)
def __init__(self, **kwargs): super().__init__(**kwargs) self.command_attrs = { "cooldown": Cooldown(3, 5.0, BucketType.user), "name": "help", "aliases": ["h"] }
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 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 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): super().__init__(command_attrs={ 'cooldown': Cooldown(1, 3.0, BucketType.member), 'help': 'Показывает эту плашку'} )
def __init__(self): super().__init__(command_attrs={ 'help': 'Shows help about the bot, a command or a category', 'cooldown': Cooldown(1, 15, BucketType.channel)})
class Roles: def __init__(self, bot): self.bot = bot self.rules_channel = 434836251766423564 self.req_channel = 442045140261928960 self.msg_id = 434842027692130304 self.emoji_server_id = 417804713413836830 async def cmdcheck(ctx): return ctx.author.id == 111158853839654912 or ctx.author.guild_permissions.manage_roles @commands.check(cmdcheck) @commands.command(hidden=True) async def addrole(self, ctx, role: discord.Role, emoji_name, url=None): """Adds a new role to the reaction role manager.""" c = self.bot.get_channel(self.rules_channel) msg = await c.get_message(self.msg_id) if emoji_name in self.bot.reaction_manager: return await ctx.send("Role has already been added!") if len(msg.reactions) == 20: return await ctx.send("Cannot add role! Too many roles exist. [Reaction reached 20 Emoji]") if url is None: if len(ctx.message.attachments) > 0: url = ctx.message.attachments[0].url resp = await self.bot.session.get(url) img = await resp.read() try: guild = self.bot.get_guild(self.emoji_server_id) emoji = await guild.create_custom_emoji(name=emoji_name, image=img) except: # noqa return await ctx.send("Could not create emoji!") await msg.add_reaction(emoji) self.bot.reaction_manager[emoji_name] = role.id query = """ INSERT INTO reaction_roles (emoji_name, role_id) VALUES ($1, $2) """ await self.bot.pool.execute(query, emoji_name, role.id) await ctx.send(f"Added `{emoji_name}` as an assignable role!") @restricted() @commands.group() async def request(self, ctx): """Request a special role. More info on each role is in the rules. """ async def request_body(ctx): channel = ctx.guild.get_channel(ctx.bot.get_cog('Roles').req_channel) if channel is None: return role = discord.utils.get(ctx.guild.roles, name=ctx.command.name) if role.name not in ('Parasites', 'Verified'): return await ctx.send("You can't request that role, Darling!") if role in ctx.author.roles: return await ctx.send("You already have that role, Darling!") embed = discord.Embed(title="Role requested!", timestamp=datetime.now(), color=discord.Color.purple()) \ .add_field(name='Role', value=role.name) \ .add_field(name="Joined at", value=ctx.author.joined_at.strftime("%Y-%m-%d %H:%M")) \ .add_field(name="Account Created", value=ctx.author.created_at.strftime("%Y-%m-%d %H:%M")) \ .set_author(name=f"{ctx.author} / {ctx.author.id}", icon_url=ctx.author.avatar_url) \ .set_footer(text=ctx.author.id) msg = await channel.send(embed=embed) await msg.add_reaction('✅') await msg.add_reaction('❌') await ctx.send("Request sent!") for r_name in ['Parasites', 'Verified']: request_body.__commands_cooldown__ = Cooldown(1, 86400, BucketType.user) request.command(r_name, aliases=[r_name.lower()])(request_body) async def handle_request(self, author, guild, msg_id, emoji): emojis = ('✅', '❌') perms = author.guild_permissions if not (perms.kick_members and perms.ban_members): if author.id != self.bot.owner_id: return channel = guild.get_channel(self.req_channel) if channel is None: return if emoji.name not in emojis: return msg = await channel.get_message(msg_id) if msg is None: return if sum(1 for r in msg.reactions if r.emoji in emojis and r.count > 1) == 0: return r_name = msg.embeds[0].fields[0].value role = discord.utils.get(guild.roles, name=r_name) embed = msg.embeds[0] requester = guild.get_member(int(embed.footer.text)) if emoji.name == '✅': embed.color = discord.Color.green() await requester.add_roles(role) await msg.edit(embed=embed) try: await requester.send(f"Your request has been accepted! You now have `{role.name}`") except: # give up if we cant send # noqa pass elif emoji.name == '❌': embed.color = discord.Color.red() await msg.edit(embed=embed) try: await requester.send(f"Your request for `{role.name}` was denied. Please try again later.") except: # rip # noqa pass await msg.clear_reactions() async def on_raw_reaction_add(self, event): guild = self.bot.get_guild(event.guild_id) member = guild.get_member(event.user_id) await self.handle_request(member, guild, event.message_id, event.emoji) if event.message_id != self.msg_id: return role = guild.get_role(self.bot.reaction_manager[event.emoji.name]) if role in member.roles: return await member.add_roles(role) async def on_raw_reaction_remove(self, event): guild = self.bot.get_guild(event.guild_id) member = guild.get_member(event.user_id) if event.message_id != self.msg_id: return role = guild.get_role(self.bot.reaction_manager[event.emoji.name]) if role not in member.roles: return await member.remove_roles(role)
await channel.delete(reason=translator.translate( "support room is not needed anymore")) class CustomCooldownMapping(CooldownMapping): def _bucket_key(self, member): bucket_type = self._cooldown.type if bucket_type is BucketType.user: return member.id elif bucket_type is BucketType.guild: return member.guild.id elif bucket_type is BucketType.channel: return member.voice.channel.id cooldown = Cooldown(1, 300, BucketType.user) buckets = CustomCooldownMapping(cooldown) def setup_voice_state_update_handler(bot): async def on_voice_state_update(member, before, after): guild = Guild.from_discord_guild(member.guild) translator = Translator(Bot._string_translations, guild.language_enum) if after.channel is not None: channel = after.channel category = channel.category if category is not None: if before.channel != channel and category.id == guild.voice_category: