Пример #1
0
async def setParam(ctx: discord.ext.commands.Context, param: str, *value: str):
	if (param == "channel"):
		if ctx.author.guild_permissions.administrator or ctx.author.id == 437296242817761292:
			if len(value) < 1:
				raise commands.MissingRequiredArgument(inspect.Parameter(name="chat",kind=inspect._ParameterKind.VAR_POSITIONAL))
			if len(value) < 2:
				raise commands.MissingRequiredArgument(inspect.Parameter(name="room",kind=inspect._ParameterKind.VAR_POSITIONAL))
			channel = ctx.channel
			try:
				chan_id = int(value[1][2:-1])
				channel = ctx.guild.get_channel(chan_id)
			except ValueError:
				if value[1] == "here":
					if servers[f'{ctx.guild.id}'].get("channels") == None:
						servers[f'{ctx.guild.id}']["channels"] = {}
					servers[f'{ctx.guild.id}']["channels"][value[0]] = channel.id
					message = await ctx.send(f"Channel {value[0]} has been set to #{channel} for this guild.")
					await asyncio.sleep(3)
					await asyncio.gather(message.delete(),ctx.message.delete())
					print(f"Channel {value[0]} has been set to #{channel} for guild {ctx.guild}.")
					logger.info(f"Channel {value[0]} has been set to #{channel} for guild {ctx.guild}.")
				elif value[1] == "unset":
					if servers[f'{ctx.guild.id}'].get("channels") == None:
						message = await ctx.send("No channels are set for this guild.")
						await asyncio.sleep(3)
						await asyncio.gather(message.delete(),ctx.message.delete())
						return
					elif servers[f'{ctx.guild.id}']["channels"].get(value[0]) == None:
						message = await ctx.send("This channel is not set for this guild.")
						await asyncio.sleep(3)
						await asyncio.gather(message.delete(),ctx.message.delete())
						return
					else:
						servers[f'{ctx.guild.id}']["channels"][value[0]] = None
						message = await ctx.send(f"Channel {value[0]} has successfully unset for this guild.")
						await asyncio.sleep(3)
						await asyncio.gather(message.delete(),ctx.message.delete())
						print(f"Channel {value[0]} has been unset for guild {ctx.guild}.")
						logger.info(f"Channel {value[0]} has been unset for guild {ctx.guild}.")
				else:
					print(f'not setting chat {chat} to anywhere as invalid parameters are passed in.')
			else:
				if servers[f'{ctx.guild.id}'].get("channels") == None:
					servers[f'{ctx.guild.id}']["channels"] = {}
				servers[f'{ctx.guild.id}']["channels"][value[0]] = chan_id
				message = await ctx.send(f"Channel {value[0]} has been set to #{channel} for this guild.")
				await asyncio.sleep(3)
				await asyncio.gather(message.delete(),ctx.message.delete())
				print(f"Channel {value[0]} has been set to #{channel} for guild {ctx.guild}.")
				logger.info(f"Channel {value[0]} has been set to #{channel} for guild {ctx.guild}.")
			with open(f'{rundir}/private/servers.json', 'w') as f:
				json.dump(servers, f, indent=2)

		else:
			commands.MissingPermissions(discord.permissions.Permissions(permissions=8))
	else:
		print(param)
Пример #2
0
    async def activity(self, ctx, activity_type: str.lower, *, message: str = ""):
        """
        Set an activity status for the bot.

        Possible activity types:
            - `playing`
            - `streaming`
            - `listening`
            - `watching`

        When activity type is set to `listening`,
        it must be followed by a "to": "listening to..."

        When activity type is set to `streaming`, you can set
        the linked twitch page:
        - `{prefix}config set twitch_url https://www.twitch.tv/somechannel/`

        To remove the current activity status:
        - `{prefix}activity clear`
        """
        if activity_type == "clear":
            self.bot.config["activity_type"] = None
            self.bot.config["activity_message"] = None
            await self.bot.config.update()
            await self.set_presence()
            embed = Embed(title="Activity Removed", color=self.bot.main_color)
            return await ctx.send(embed=embed)

        if not message:
            raise commands.MissingRequiredArgument(param(name="message"))

        activity, msg = (
            await self.set_presence(
                activity_identifier=activity_type,
                activity_by_key=True,
                activity_message=message,
            )
        )["activity"]
        if activity is None:
            raise commands.MissingRequiredArgument(param(name="activity"))

        self.bot.config["activity_type"] = activity.type.value
        self.bot.config["activity_message"] = message
        await self.bot.config.update()

        embed = Embed(
            title="Activity Changed", description=msg, color=self.bot.main_color
        )
        return await ctx.send(embed=embed)
Пример #3
0
def admin_dash_o(ctx, args, perms):
    if len(
            args
    ) == 0:  # todo: make the part up to line 26 a function since it's the exact same in all commands
        raise commands.MissingRequiredArgument(
            inspect.Parameter("args", inspect.Parameter.VAR_POSITIONAL))

    if args[0] == "-o" and ctx.message.author.id in devs:
        if len(args) == 1:
            raise commands.MissingRequiredArgument(
                inspect.Parameter("args", inspect.Parameter.VAR_POSITIONAL))
        return 2

    return 1 if (p := ctx.message.author.permissions_in(ctx.message.channel)).manage_messages and perms == 0 or perms \
     == 1 and p.kick_members or perms == 2 and p.ban_members else 0 # DO NOT QUESTION THIS CODE
Пример #4
0
    async def iamn(self, ctx, *, role: discord.Role = None):
        """
		Remove a self-assigned role
		Usage:
			{command_prefix}iamn [role]
		Example:
			.iamn OverwatchPing
		"""
        settings = gs.get(ctx.guild)

        if role is None:
            from inspect import Parameter
            raise commands.MissingRequiredArgument(Parameter("role", False))

        if not settings.self_assign["enabled"]:
            embed = discord.Embed(
                colour=roxbot.EmbedColours.pink,
                description=
                "SelfAssignable roles are not enabled on this server")
            return await ctx.send(embed=embed)

        member = ctx.author

        if role in member.roles and role.id in settings.self_assign["roles"]:
            await member.remove_roles(role, reason="'iamn' command triggered.")
            return await ctx.send("{} has been successfully removed.".format(
                role.name))
        elif role not in member.roles and role.id in settings.self_assign[
                "roles"]:
            return await ctx.send("You do not have {}.".format(role.name))
        else:
            return await ctx.send("That role is not self-assignable.")
Пример #5
0
    async def iam(self, ctx, *, role: discord.Role = None):
        """
		Self-assign yourself a role. Only one role at a time.
		Usage:
			{command_prefix}iam [role]
		Example:
			.iam OverwatchPing
		"""
        settings = gs.get(ctx.guild)

        if role is None:
            # Hacky way to get the error I want
            from inspect import Parameter
            raise commands.MissingRequiredArgument(Parameter("Role", False))

        if not settings.self_assign["enabled"]:
            embed = discord.Embed(
                colour=roxbot.EmbedColours.pink,
                description=
                "SelfAssignable roles are not enabled on this server")
            return await ctx.send(embed=embed)

        member = ctx.author

        if role in member.roles:
            return await ctx.send("You already have that role.")

        if role.id in settings.self_assign["roles"]:
            await member.add_roles(role, reason="'iam' command triggered.")
            return await ctx.send("Yay {}! You now have the {} role!".format(
                member.mention, role.name))
        else:
            return await ctx.send("That role is not self-assignable.")
Пример #6
0
    async def cmd_add(self, ctx, cmd_name, *args):
        if not "".join(args):
            await ctx.message.add_reaction(Lang.CMDERROR)
            raise commands.MissingRequiredArgument(
                inspect.signature(self.cmd_add).parameters['args'])
        cmd_name = cmd_name.lower()

        # TODO Process multiple output texts
        cmd_texts = [" ".join(args)]

        # Process special discord /cmd
        for i in range(0, len(cmd_texts)):
            contains_me = cmd_texts[i].lower().startswith("/me")

            if contains_me:
                cmd_texts[i] = "_{}_".format(cmd_texts[i][3:])

        if cmd_name in self.commands:
            self.commands[cmd_name].texts.extend(cmd_texts)
            self.save()
            await ctx.message.add_reaction(Lang.CMDSUCCESS)
            await ctx.send(Lang.lang(self, "add_exists", cmd_name))
        else:
            self.commands[cmd_name] = Cmd(cmd_name, ctx.author.id, cmd_texts)
            self.save()
            # await utils.log_to_admin_channel(ctx)
            await ctx.message.add_reaction(Lang.CMDSUCCESS)
            await utils.write_debug_channel(
                self.bot,
                Lang.lang(self, 'cmd_added',
                          self.commands[cmd_name].get_raw_texts()))
Пример #7
0
async def remove(ctx, arg):
    server = get_server(ctx)

    if arg == 'all':
        server.playlist.deleteAll()
        if server.voice: server.voice.stop()
        await ctx.send(embed=MsgEmbed.info('Удалил весь плейлист :fire:'))
        return

    if not arg.isdigit(): raise commands.MissingRequiredArgument()
    else: pos = int(arg)

    if not 0 <= pos < server.playlist.getLength():
        await ctx.send(embed=MsgEmbed.warning(
            'Как может в казино быть колода разложена в другом порядке?! Ты чё, бредишь, что ли?! Ёбаный твой рот, а!..'
        ))
        return

    mi = server.playlist.getByPosition(pos)
    playlist, voice = server.playlist, server.voice
    if pos == playlist.getPosition() and voice: voice.stop()
    if playlist.deleteByPosition(pos):
        await ctx.send(
            embed=MsgEmbed.info(f'Удалил: {mi.artist} - {mi.title} :fire:'))
    else:
        await ctx.send(embed=MsgEmbed.error('Ошибка удаления'))
Пример #8
0
 async def dev(self, ctx, command, branch_name=None):
     """Developer commands.
     branch - find out which branch I'm on
     evolve - get updates from current branch and restart
     evolve <branch_name> - change to a different branch, update and restart"""
     if command == 'branch':
         shell = await asyncio.create_subprocess_shell(
             "git rev-parse --abbrev-ref HEAD",
             stdout=asyncio.subprocess.PIPE)
         stdout, stderr = await shell.communicate()
         bname = stdout.decode().strip()
         await ctx.bot.send_message(ctx.message.channel,
                                    "Current branch: {}".format(bname))
     elif command == 'evolve':
         msg = "Grabbing the latest updates."
         if branch_name:
             shell = await asyncio.create_subprocess_shell("git fetch")
             await shell.wait()
             shell = await asyncio.create_subprocess_shell(
                 "git checkout {}".format(shlex.quote(branch_name)))
             code = await shell.wait()
             if code != 0:
                 await ctx.bot.send_message(
                     ctx.message.channel,
                     "Couldn't change to branch: {}".format(branch_name))
                 return
             else:
                 msg = "Changed to branch: {}. {}".format(branch_name, msg)
         await ctx.bot.send_message(ctx.message.channel, msg)
         await ctx.bot.close()
     else:
         raise commands.MissingRequiredArgument()
Пример #9
0
    async def whothisis(self,
                        ctx,
                        author: typing.Optional[discord.Member] = None,
                        *,
                        name: str = None):
        if name == None and author != None:
            name = author.name
            author = ctx.author
        elif name != None:
            name = name
        else:
            raise commands.MissingRequiredArgument(
                type("testù" + ("ù" * 100), (object, ), {"name": "name"})())

        if author == None:
            author = ctx.author

        await ctx.message.add_reaction("⏳")

        image = f"{author.avatar_url}"
        if ctx.message.attachments:
            url = ctx.message.attachments[0].url
            if url.endswith("png"):
                image = f"{ctx.message.attachments[0].url}"

        file = await self.bot.imgen.whothisis(avatars=[image], text=name)

        await ctx.message.remove_reaction("⏳", ctx.me)
        await ctx.message.add_reaction("⌛")

        await ctx.send(file=file)

        await ctx.message.remove_reaction("⌛", ctx.me)
        await ctx.message.add_reaction("🤔")
Пример #10
0
    async def voice_mute(self, ctx, users: commands.Greedy[discord.Member], *,
                         reason: str):
        """ Voice mute multiple members permanently """

        if len(users) == 0:
            raise commands.MissingRequiredArgument(
                self.general_mute.params["users"])

        if len(reason) >= 450:
            return await ctx.send("Reason too long!")

        mute_role = ctx.guild.get_role(873198321580245032)
        modlogs = ctx.guild.get_channel(827971859667746838)
        muted = 0
        muted_list = []
        for user in users:
            if mute_role in user.roles or ctx.author.top_role.position < user.top_role.position or user.bot:
                continue
            await user.add_roles(
                mute_role,
                reason=f"[Staff: {ctx.author} - {ctx.author.id}] - {reason}")
            muted_list.append(f"{user.mention} ({user.id})\n")
            muted += 1

        e = discord.Embed(color=14301754, title=f"Voice muted {muted} members")
        members = ''.join(muted_list[:30]) + f"\n(+{muted - 30} more)"
        e.description = f"**Staff:** {ctx.author} ({ctx.author.id})\n**Reason:** {reason}\n**Members:**\n{members}"
        await modlogs.send(embed=e)
        await ctx.send(f"Voice muted {muted} members")
Пример #11
0
    async def command_eightball(self, context, *phrase):
        """
        Predicts the outcome of a question

        Bot uses its fortune-telling powers to answer your question.
        Ask a question and get one of the classic magic 8 ball answers.

        ex:
        `<prefix>8ball` is it going to be sunny today?
        `<prefix>8b` are you going to answer correctly?
        """
        if len(phrase) == 0:  # at least one argument
            param = collections.namedtuple('param', 'name')
            raise commands.MissingRequiredArgument(param('phrase'))

        answer = random.randint(0, len(self.eightball_answers) - 1)
        if answer <= 9:  # Affirmative answer
            emoji = self.eightball_emojis[0]
        elif answer <= 14:  # Meh answer
            emoji = self.eightball_emojis[1]
        else:  # Negative answer
            emoji = self.eightball_emojis[2]

        message_without_command = context.message.clean_content.split(
            maxsplit=1)[1]
        await context.send(
            f'`{message_without_command}`: {self.eightball_answers[answer]} {emoji}'
        )
Пример #12
0
 async def remind(self, ctx, *, arg):
     session = self.Session()
     try:
         arg = arg[1:]
         d = dict(x.split('=', 1) for x in arg.split(' -'))
         if "msg" not in d or "date" not in d:
             raise commands.MissingRequiredArgument("Message or DateTime")
         date = parser.parse(timestr=d.get("date")).replace(tzinfo=tz.gettz(d.get("tz", "GMT")))
         date = date.astimezone(tz.UTC)
         print(date)
         if "u" in d:
             u = await discordstaff(d.get("u"), ctx)
         else:
             u = ctx.author
         r = timer.Reminder(ctx.author.id, d.get("msg"), date, u.id)
         def check(message: discord.Message) -> bool:
             return message.author == ctx.author
         try:
             await ctx.send(f"Do you really want to add this reminder on {date.strftime('`%Y-%b-%d` | `%H:%M` `TZ: %Z`')}. Type Y/y/Yes/yes in chat to confirm, N/n/No/no to cancel.")
             self.message = await self.bot.wait_for('message', timeout=30.5, check=check)
         except asyncio.TimeoutError:
             await ctx.send("The author didn't respond.")
         if self.message.content in("yes", "Yes", "y", "Y"):
             await ctx.message.add_reaction("👍")
             session.add(r)
             print("commited")
             session.commit()
         else:
             await ctx.send("Reminder wasn't added.")
     except Exception as e:
         print(e)
         session.rollback()
     finally:
         session.close()
Пример #13
0
    async def command_gamedeal(self, context, *game_name):
        """
        Displays game pricing info

        Info pertains to all stores in which the game is available for purchase

        ex:
        `<prefix>gamedeal` Assassin's Creed Odyssey
        `<prefix>gameprice` Cyberpunk 2077
        """
        if len(game_name) == 0:  # at least one argument
            param = collections.namedtuple('param', 'name')
            raise commands.MissingRequiredArgument(param('game_name'))

        game_name = ' '.join(game_name)
        game_name_quoted = urllib.parse.quote(game_name)

        game = await self.isthereanydeal_identifier_api.call_api(f'&title={game_name_quoted}')

        if game.plain:
            game_info = await self.isthereanydeal_game_info_api.call_api(
                f'&plains={game.plain}')
            game_prices = await self.isthereanydeal_game_prices_api.call_api(
                f'&plains={game.plain}')
            game_historical_low_price = await self.isthereanydeal_historical_price_api.call_api(
                f'&plains={game.plain}')

            embed = await self.create_gamedeal_embed(
                game_info, game_prices, game_historical_low_price)
            await context.send(embed=embed)

        else:
            await context.send(f'Could not find game `{game_name}`')
Пример #14
0
 async def role_give(self, ctx, *args: typing.Union[discord.Role,
                                                    discord.Member, str]):
     """
     Used to create roles and assign roles.
     If new roles are passed in, they will be created. If new or existing roles and guild members are passed in, they will be created if applicable and assigned
     `-role give [roles] [users]`
     """
     users = list(filter(lambda x: isinstance(x, discord.Member), args))
     roles = list(filter(lambda x: isinstance(x, discord.Role), args))
     new_roles = list(filter(lambda x: isinstance(x, str), args))
     if len(roles) + len(new_roles) is 0:
         raise commands.MissingRequiredArgument(discord.Role)
     for new in new_roles:
         new = await ctx.guild.create_role(name=new)
         roles.append(new)
     if len(new_roles) is not 0:
         await ctx.send(embed=await Macro.send(
             f"Created the roles {', '.join(new_roles)}"))
     if len(users) is 0:
         return
     for user in users:
         await user.add_roles(*roles)
     users = map(str, users)
     roles = map(str, roles)
     await ctx.send(embed=await Macro.send(
         f"Gave {', '.join(users)} the roles {', '.join(roles)}"))
Пример #15
0
    async def _role_take(self, ctx, members, roles):
        if len(roles) is 0 or len(members) is 0:
            raise commands.MissingRequiredArgument(
                discord.Role if len(roles) is 0 else discord.Member)

        for member in members:
            await member.remove_roles(*roles)
Пример #16
0
async def _get_art(ctx, set, *card_name):
    if len(card_name) < 1:
        raise commands.MissingRequiredArgument(_get_art.params["card_name"])

    card_name = " ".join(card_name)
    set_id = set.lower()

    card = scryfall_api.get_cards([{
        "card_name": card_name,
        "set": set_id,
    }])

    if len(card) > 0:
        name = card[0][0]["name"]

        if card[0][0].get("image_uris").get("art_crop"):
            art_uri = card[0][0]["image_uris"]["art_crop"]
            artist_name = card[0][0]["artist"]
            flavor_text = card[0][0].get("flavor_text")

            embed = discord.Embed(type="rich")
            embed.title = name + f" ({set_id.upper()})"
            embed.set_image(url=art_uri)
            embed.description = f"*{flavor_text}*" if flavor_text else None
            embed.set_footer(
                text=f"{artist_name} — ™ and © Wizards of the Coast")

            await ctx.send(embed=embed)

        else:
            await ctx.send(f"No art found for card with name `{name}`.")
    else:
        await ctx.send(
            f"Art for card `{name}` from set `{set_id.upper()}` not found.")
Пример #17
0
    async def status(self, ctx, *, status_type: str.lower):
        """
        Set a status for the bot.

        Possible status types:
            - `online`
            - `idle`
            - `dnd`
            - `do_not_disturb` or `do not disturb`
            - `invisible` or `offline`

        To remove the current status:
        - `{prefix}status clear`
        """
        if status_type == "clear":
            self.bot.config["status"] = None
            await self.bot.config.update()
            await self.set_presence()
            embed = Embed(title="Status Removed", color=self.bot.main_color)
            return await ctx.send(embed=embed)
        status_type = status_type.replace(" ", "_")

        status, msg = (
            await self.set_presence(status_identifier=status_type, status_by_key=True)
        )["status"]
        if status is None:
            raise commands.MissingRequiredArgument(param(name="status"))

        self.bot.config["status"] = status.value
        await self.bot.config.update()

        embed = Embed(
            title="Status Changed", description=msg, color=self.bot.main_color
        )
        return await ctx.send(embed=embed)
Пример #18
0
    async def purge(
        self,
        ctx,
        n: typing.Optional[int] = 0,
        users: commands.Greedy[Member] = [],
        n2: typing.Optional[int] = 0,
        # This allows the command to be used with either order of [num] [user]
    ):
        if not users and not n:
            param = Parameter('number_of_messages', Parameter.POSITIONAL_ONLY)
            raise commands.MissingRequiredArgument(param)
        channel = ctx.message.channel
        if not users:
            msg_limit = n + 1 if n else 100
            await channel.purge(limit=msg_limit, check=None, before=None)
        else:
            if n2:
                n = n2

            userids = [user.id for user in users]

            def check(m):
                return any(m.author.id == userid for userid in userids)

            msg_limit = n if n else 100
            await ctx.message.delete()
            await channel.purge(limit=msg_limit, check=check, before=None)
        return True
Пример #19
0
 async def starboard(self, ctx, channel_or_remove, stars: int = None):
     """
     Sets given channel as starboard channel for server
     <example>
     <cmd>#starboard 5</cmd>
     <res>Sets `#starboard` as this server's starboard channel with 5 stars required</res>
     <cmd>remove</cmd>
     <res>Removes starboard from server</res>
     </example>
     """
     if channel_or_remove.lower() == 'remove':
         self.delete_guild_starboard(ctx.guild.id)
         await ctx.send('Removed starboard from this server')
         return
     if stars is None:
         raise commands.MissingRequiredArgument(
             Parameter('stars', Parameter.POSITIONAL_ONLY))
     channel = await commands.TextChannelConverter().convert(
         ctx, channel_or_remove)
     if channel.guild != ctx.guild:
         return await ctx.send(f'Channel must be in this guild')
     if stars <= 0:
         return await ctx.send(f'Invalid star amount')
     self.set_guild_starboard(ctx.guild.id, channel.id, stars)
     await ctx.send(f'Added channel {channel} as a starboard channel')
Пример #20
0
    async def privatechannel(self, ctx, *members: discord.Member):
        if len(members) == 0:
            raise commands.MissingRequiredArgument(inspect.Parameter("member", inspect.Parameter.POSITIONAL_ONLY))
        overwrites = {ctx.guild.default_role: discord.PermissionOverwrite(view_channel=False),
                      ctx.author: discord.PermissionOverwrite(view_channel=True)}
        for member in members:
            overwrites[member] = discord.PermissionOverwrite(view_channel=True)
        channel_name = f"{ctx.author.nick}'s private channel"
        for p in string.punctuation:
            channel_name = channel_name.replace(p, "")
        channel_name = channel_name.replace(" ", "-").lower()
        if channel_name in [c.name for c in ctx.guild.text_channels]:
            await ctx.message.reply(error_str("You already have a private channel!"))
            return
        new_channel = await ctx.guild.create_text_channel(channel_name, overwrites=overwrites)
        welcome_message = await new_channel.send(f"Welcome to <@{ctx.author.id}>'s private channel with "
                                                 f"{','.join([f'<@{m.id}>' for m in members])}!\nYou have 5 minutes!")
        await welcome_message.add_reaction("✅")

        def check(reaction, user):
            return user == ctx.author and str(reaction.emoji) == "✅"

        try:
            reaction, user = await bot.wait_for('reaction_add', timeout=300.0, check=check)
        except asyncio.TimeoutError:
            await new_channel.delete()
        else:
            await new_channel.delete()
Пример #21
0
    async def transform(self, ctx, param):
        """Because Danny literally only allow commands.converter._Greedy class to be pass here using
           'is' comparison, I have to override it to allow any other Greedy subclass.
           
           It's obvious that Danny doesn't want people to subclass it smh."""

        required = param.default is param.empty
        converter = commands.converter.get_converter(param)
        optional_converter = self._is_typing_optional(param.annotation)

        if optional_converter:
            converter = self.get_optional_converter(converter)

        if isinstance(converter, commands.converter.Greedy):
            if param.kind == param.POSITIONAL_OR_KEYWORD or param.kind == param.POSITIONAL_ONLY:
                if self.is_greedy_required(converter) and ctx.view.eof:
                    if required:
                        if optional_converter:
                            return None
                        raise commands.MissingRequiredArgument(param)
                    else:
                        return param.default
                return await self._transform_greedy_pos(ctx, param, required, converter, converter.converter)

        return await super().transform(ctx, param)
Пример #22
0
    async def logs(self, ctx, *, member: User = None):
        """Shows a list of previous Modmail thread logs of a member."""

        await ctx.trigger_typing()

        if not member:
            thread = ctx.thread
            if not thread:
                raise commands.MissingRequiredArgument(param(name='member'))
            user = thread.recipient
        else:
            user = member

        default_avatar = 'https://cdn.discordapp.com/embed/avatars/0.png'
        icon_url = getattr(user, 'avatar_url', default_avatar)

        logs = await self.bot.api.get_user_logs(user.id)

        if not any(not log['open'] for log in logs):
            embed = discord.Embed(color=discord.Color.red(),
                                  description='This user does not '
                                  'have any previous logs.')
            return await ctx.send(embed=embed)

        logs = reversed([e for e in logs if not e['open']])

        embeds = self.format_log_embeds(logs, avatar_url=icon_url)

        session = PaginatorSession(ctx, *embeds)
        await session.run()
Пример #23
0
 async def crabmeme(self, ctx, *, text: str):
     '''Limited to owner only (for now, it may return) due to this command using like 90% CPU'''
     if not await self.bot.is_team_owner(ctx.author):
         return
     if not '|' in text:
         raise commands.ArgumentParsingError(
             'Text should be separated by |')
     if not text:
         raise commands.MissingRequiredArgument(
             'You need to provide text for the meme')
     filename = str(ctx.author.id) + '.mp4'
     t = text.upper().replace('| ', '|').split('|')
     if len(t) != 2:
         raise commands.ArgumentParsingError(
             'Text should have 2 sections, separated by |')
     if (not t[0] and not t[0].strip()) or (not t[1] and not t[1].strip()):
         raise commands.ArgumentParsingError('Cannot use an empty string')
     msg = await ctx.send('🦀 Generating Crab Rave 🦀')
     await self.loop.run_in_executor(None,
                                     func=functools.partial(
                                         self.gencrabrave, t, filename))
     meme = discord.File(filename, 'crab.mp4')
     await msg.delete()
     await ctx.send(file=meme)
     os.remove(filename)
Пример #24
0
    async def convert(self, ctx, argstr):
        converted = {}

        for raw_arg in shlex.split(argstr or ""):
            if "=" not in raw_arg:
                continue
            name, *values = raw_arg.split("=")
            value = "=".join(values)

            argument = self.arguments.get(name.lower())
            if not argument:
                raise UnknownArgumentError(name)

            try:
                converted_value = await self._convert_value(
                    ctx, argument.converter, value)
                converted[name] = converted_value
            except commands.ConversionError as e:
                e = getattr(e, "original", e)
                raise InvalidArgumentValueError(name, value, e) from e
            except Exception as e:
                raise commands.ConversionError(self, e) from e

        for name, argument in self.arguments.items():
            if isinstance(argument,
                          RequiredArgument) and name not in converted:
                param = inspect.Parameter(name, inspect.Parameter.KEYWORD_ONLY)
                raise commands.MissingRequiredArgument(param)

            if argument.default is not None and name not in converted:
                converted[name] = argument.default

        return converted
        async def wrapper(*args, **kwargs):
            ctx = args[1]
            print(
                f"{ctx.author}({ctx.author.id}) in {ctx.channel}: {ctx.message.content}"
            )
            if type(ctx) is not commands.Context:
                print("ERROR: Missing ctx variable in @custom_check() call in",
                      cmd.__name__, " command!")
                raise commands.MissingRequiredArgument(ctx)
            if isinstance(ctx.channel, discord.channel.DMChannel):
                if not allowed_in_dm:
                    await ctx.channel.send("Command not allowed in DM")
                    return False
            else:
                if not ctx.channel.name in allowed_channels + [
                        'glug-bot-test', 'bot-commands', 'bot-testing'
                ]:
                    print(
                        f"Command used in {ctx.channel.name} channel while allowed channels were {str(allowed_channels)}"
                    )
                    return False

            if len(req_roles) > 0:
                role_found = False
                user = get_member(ctx, ctx.author.id)
                for role in user.roles:
                    if role.id in req_roles:
                        role_found = True
                        break
                if not role_found:
                    await ctx.channel.send("You don't have required role(s)")
                    return False

            return await cmd(*args, **kwargs)
Пример #26
0
    async def add(
            self, name: str, ctx: Context, url: str,
            whitelist: List[int]=None, target_album_id: str=None
    ) -> None:
        obj = discord.utils.get(self.list_objs, name=name)

        # Try to remove it, but fail silently if it's NoneType (meaning we might have passed in an embed)
        try:
            url = url.strip("<>")
        except AttributeError:
            pass

        if url is None:
            if ctx.message.attachments:
                url = ctx.message.attachments[0]
                if url.endswith(":large"):
                    url = url[:-6]
                elif url.endswith("large"):  # Twitter images suck
                    url = url[:-5]
            else:
                raise commands.MissingRequiredArgument("url")
        elif url == "^":
            async for msg in ctx.message.channel.history(limit=1, before=ctx.message):
                try:
                    url = msg.attachments[0].url
                except IndexError:
                    url = check_urls(msg.clean_content)
                    if not url:
                        raise commands.BadArgument("Previous message contains no actionable data.")

        await obj.add_to_list(ctx, url, whitelist, target_album_id)
Пример #27
0
    async def logs(self, ctx, *, user: User = None):
        """
        Get previous Modmail thread logs of a member.

        Leave `user` blank when this command is used within a
        thread channel to show logs for the current recipient.
        `user` may be a user ID, mention, or name.
        """

        await ctx.trigger_typing()

        if not user:
            thread = ctx.thread
            if not thread:
                raise commands.MissingRequiredArgument(SimpleNamespace(name="member"))
            user = thread.recipient

        default_avatar = "https://cdn.discordapp.com/embed/avatars/0.png"
        icon_url = getattr(user, "avatar_url", default_avatar)

        logs = await self.bot.api.get_user_logs(user.id)

        if not any(not log["open"] for log in logs):
            embed = discord.Embed(
                color=discord.Color.red(),
                description="This user does not " "have any previous logs.",
            )
            return await ctx.send(embed=embed)

        logs = reversed([e for e in logs if not e["open"]])

        embeds = self.format_log_embeds(logs, avatar_url=icon_url)

        session = EmbedPaginatorSession(ctx, *embeds)
        await session.run()
Пример #28
0
    async def automod_mass_caps(self,
                                ctx,
                                value: AutomodValues,
                                percentage: int = None):
        """" Set the automod value for anti mass caps and set the caps percentege limit """

        automod = cm.get(self.bot, 'automod', ctx.guild.id)

        if not automod:
            raise commands.BadArgument(
                _("Automod is disabled in this server, enable it by using `{0}automod toggle` command"
                  ).format(ctx.prefix))

        if value['action'] != 0:
            raise commands.MissingRequiredArgument(
                self.automod_mass_caps.params['percentage'])

        if percentage and not 25 < percentage < 100:
            raise commands.BadArgument(
                _("Percentage limit must be between 25 and 100"))

        anticaps = cm.get(self.bot, 'masscaps', ctx.guild.id)
        if not anticaps and value['action'] != 0:
            await self.bot.db.execute(
                "INSERT INTO masscaps(guild_id, level, percentage, time) VALUES($1, $2, $3, $4)",
                ctx.guild.id, value['action'], percentage, value['time'])
            self.bot.masscaps[ctx.guild.id] = {
                'level': value['action'],
                'time': value['time'],
                'percentage': percentage
            }
        elif anticaps and value['action'] != 0:
            await self.bot.db.execute(
                "UPDATE masscaps SET level = $1, time = $2, percentage = $3 WHERE guild_id = $4",
                value['action'], value['time'], percentage, ctx.guild.id)
            self.bot.masscaps[ctx.guild.id] = {
                'level': value['action'],
                'time': value['time'],
                'percentage': percentage
            }
        elif anticaps and value['action'] == 0:
            await self.bot.db.execute(
                "DELETE FROM masscaps WHERE guild_id = $1", ctx.guild.id)
            self.bot.masscaps.pop(ctx.guild.id)
            return await ctx.send(
                _("{0} Successfuly disabled anti mass caps in this server").
                format(self.bot.settings['emojis']['misc']['white-mark']))
        elif not anticaps and value['action'] == 0:
            raise commands.BadArgument(
                _("Anti caps are already disabled in this server."))

        the_value = value['action']
        await ctx.send(
            _("{0} Successfully set anti mass caps punishment type to **{1}** members. Percentage set to - `{2}`.{3}"
              ).format(
                  self.bot.settings['emojis']['misc']['white-mark'],
                  automod_values(the_value), percentage,
                  _(" They will be muted/banned for 12 hours by default.")
                  if value['action'] in [5, 2] else ''))
Пример #29
0
    async def default(self, ctx: commands.Context, param: str) -> Image:
        url = await super().default(ctx, param)

        try:
            return await url_to_image(url)

        except (FileTooLarge, InvalidImageType):
            raise commands.MissingRequiredArgument(param)
Пример #30
0
    async def remind(self, ctx: commands.Context, *, when: str):
        """Remind yourself about something in the future

        - The time goes first and it has to be some sort of human readable offset
        - For example: "1h 5m", "3.4 days", "4:13"
        - Then put `to` and what you want to be reminded about
        - e.g. `remindme 4 hours to do X and Y`
        """
        try:
            future_time, text = when.split(" to ", 1)
        except ValueError:
            raise commands.MissingRequiredArgument(
                Parameter("to", Parameter.POSITIONAL_ONLY))
        else:
            future_time = future_time.strip()
            text = text.strip()
            if not text:
                raise commands.MissingRequiredArgument(
                    Parameter("text", Parameter.POSITIONAL_ONLY))
            if len(text) > 1000:
                raise commands.BadArgument("Reminder text is too long.")

        parsed_time = timeparse(future_time)
        if not parsed_time:
            raise commands.BadArgument(
                "Unable to parse given time. Check if there are typos.")
        parsed_offset = timedelta(seconds=parsed_time)
        remind_offset = datetime.utcnow() + parsed_offset
        new_reminder = Reminder(reminder_text=text,
                                reminder_time=remind_offset,
                                user_id=ctx.author.id,
                                channel_id=ctx.channel.id)
        await new_reminder.create()
        if parsed_offset < timedelta(
                minutes=30
        ) and new_reminder.reminder_id not in Auto.QUEUED_REMINDERS:
            Auto.QUEUED_REMINDERS[
                new_reminder.reminder_id] = self.bot.loop.create_task(
                    self.setup_reminder(new_reminder))

        readable_offset = naturaldelta(remind_offset)
        embed = self.bot.create_embed(
            description=
            f"{Icons.ALERT} {ctx.author.mention}, you will be reminded about this in {readable_offset}"
        )
        await ctx.send(embed=embed)