コード例 #1
0
ファイル: logging.py プロジェクト: monkeyboy2805/adambot
    async def avatar_handler(before: discord.Member,
                             after: discord.Member) -> dict:
        """
        Handler that returns the old avatar for thumbnail usage and the new avatar for the embed image
        """

        return {
            "thumbnail_url": get_user_avatar_url(before)[0],
            "image": get_user_avatar_url(after)[0],
            "description": ":arrow_right: Old Avatar\n:arrow_down: New Avatar"
        }  # todo: guild avatar listener if it exists
コード例 #2
0
ファイル: reputation.py プロジェクト: monkeyboy2805/adambot
    async def check(self, ctx: commands.Context, *, args: str = "") -> None:
        """
        Checks a specific person reps, or your own if user is left blank
        """

        if not args:
            user = ctx.author
        else:
            user = await self.bot.get_spaced_member(ctx, self.bot, args=args)
            if user is None:
                await self.bot.DefaultEmbedResponses.error_embed(
                    self.bot, ctx, "We could not find that user!")
                return

        rep = None
        lb_pos = None
        async with self.bot.pool.acquire() as connection:
            all_rep = await connection.fetch(
                "SELECT member_id, reps FROM rep WHERE guild_id = $1 ORDER by reps DESC;",
                ctx.guild.id)
            all_rep = [
                x for x in all_rep
                if ctx.channel.guild.get_member(x[0]) is not None
            ]
            member_record = next((x for x in all_rep if x[0] == user.id), None)
            if member_record:  # If the user actually has reps
                rep = member_record[1]  # Check member ID and then get reps
                prev = 0
                lb_pos = 0
                for record in all_rep:
                    if record[1] != prev:
                        lb_pos += 1
                        prev = record[1]  # Else, increase the rank
                    if record[0] == user.id:
                        break  # End loop if reached the user

        if not rep:
            rep = 0
        embed = Embed(title=f"Rep info for {user.display_name} ({user})",
                      color=Colour.from_rgb(139, 0, 139))
        # could change to user.colour at some point, I prefer the purple for now though
        embed.add_field(name="Rep points", value=rep)
        embed.add_field(
            name="Leaderboard position",
            value=self.bot.ordinal(lb_pos) if lb_pos else "Nowhere :(")
        embed.set_footer(
            text=f"Requested by {ctx.author.display_name} ({ctx.author})\n" +
            self.bot.correct_time().strftime(self.bot.ts_format),
            icon_url=get_user_avatar_url(ctx.author, mode=1)[0])
        embed.set_thumbnail(url=get_user_avatar_url(user, mode=1)[0])
        await ctx.send(embed=embed)
コード例 #3
0
    async def _warnlist_member(self,
                               ctx: commands.Context,
                               member: discord.Member,
                               page_num: int = 1) -> None:
        """
        Handles getting the warns for a specific member
        """

        async with self.bot.pool.acquire() as connection:
            warns = await connection.fetch(
                "SELECT * FROM warn WHERE member_id = ($1) AND guild_id = $2 ORDER BY id;",
                member.id, ctx.guild.id)

        if len(warns) > 0:
            embed = self.bot.EmbedPages(
                self.bot.PageTypes.WARN,
                warns,
                f"{member.display_name}'s warnings",
                Colour.from_rgb(177, 252, 129),
                self.bot,
                ctx.author,
                ctx.channel,
                thumbnail_url=get_guild_icon_url(ctx.guild),
                icon_url=get_user_avatar_url(ctx.author, mode=1)[0],
                footer=
                f"Requested by: {ctx.author.display_name} ({ctx.author})\n" +
                self.bot.correct_time().strftime(self.bot.ts_format))

            await embed.set_page(int(page_num))
            await embed.send()
        else:
            await ctx.send("No warnings recorded!")
コード例 #4
0
ファイル: starboard.py プロジェクト: adampy/adambot
    async def make_starboard_embed(self, message: discord.Message, stars: int, emoji: discord.Emoji, color: discord.Color) -> discord.Embed:
        """
        Turns the message into an Embed that can be sent in the starboard channel
        """

        embed = discord.Embed(title=f"{stars} {emoji} (in #{message.channel.name})", color=color if color else self.bot.GOLDEN_YELLOW, description=message.content)
        embed.set_author(name=message.author.display_name, icon_url=get_user_avatar_url(message.author, mode=1)[0])
        if message.embeds:
            embedded_data = message.embeds[0]
            if embedded_data.type == "image" and not self.is_url_spoiler(message.content, embedded_data.url):
                embed.set_image(url=embedded_data.url)
            else:
                embed.add_field(name="Message is an embed", value="Press the message link to view", inline=False)

        if message.reference:
            embed.add_field(name="In response to...", value=f"{message.reference.resolved.author.display_name}#{message.reference.resolved.author.discriminator}", inline=False)

        if message.attachments:
            attatched = message.attachments[0]
            is_spoiler = attatched.is_spoiler()
            if not is_spoiler and attatched.url.lower().endswith(("png", "jpeg", "jpg", "gif", "webp")):
                embed.set_image(url=attatched.url)
            elif is_spoiler:
                embed.add_field(name="Attachment", value=f"||[{attatched.filename}]({attatched.url})||", inline=False)
            else:
                embed.add_field(name="Attachment", value=f"[{attatched.filename}]({attatched.url})", inline=False)

        embed.add_field(name="Message link", value=f"[Click me!]({message.jump_url})")
        embed.set_footer(text=self.bot.correct_time().strftime("%H:%M on %m/%d/%Y"))
        return embed
コード例 #5
0
ファイル: reputation.py プロジェクト: monkeyboy2805/adambot
    async def set(self, ctx: commands.Context,
                  user: discord.Member | discord.User, rep: str) -> None:
        """
        Sets a specific members reps to a given value.
        """

        if not rep.isdigit():
            await self.bot.DefaultEmbedResponses.error_embed(
                self.bot, ctx, "The reputation points must be a number!")
            return
        new_reps = await self.set_rep(user.id, ctx.guild.id, int(rep))
        await self.bot.DefaultEmbedResponses.success_embed(
            self.bot,
            ctx,
            f"{user.display_name}'s reputation points have been changed!",
            desc=f"{user.display_name} now has {new_reps} reputation points!",
            thumbnail_url=get_user_avatar_url(user)[0])

        channel_id = await self.bot.get_config_key(ctx, "log_channel")
        if channel_id is None:
            return
        channel = self.bot.get_channel(channel_id)
        embed = Embed(title="Reputation Points Set",
                      color=Colour.from_rgb(177, 252, 129))
        embed.add_field(name="Member", value=str(user))
        embed.add_field(name="Staff", value=str(ctx.author))
        embed.add_field(name="New Rep", value=new_reps)
        embed.set_footer(
            text=self.bot.correct_time().strftime(self.bot.ts_format))
        await channel.send(embed=embed)
コード例 #6
0
    async def info(self, ctx: commands.Context, *,
                   role: discord.Role | str) -> None:
        """
        Displays various details about a specified role.
        Works with a role mention, role name or role ID.
        """

        if type(role) is not discord.Role:
            role = await self.find_closest_role(ctx,
                                                role,
                                                verbosity=Verbosity.ALL)
            if len(role) > 1:
                return

            role = role[0]

        embed = Embed(title=f"Role info ~ {role.name}", colour=role.colour)
        embed.add_field(name="Created at",
                        value=self.bot.correct_time(role.created_at))
        embed.add_field(name="Members", value=len(role.members))
        embed.add_field(name="Position", value=role.position)
        embed.add_field(name="Displays separately", value=role.hoist)
        embed.add_field(name="Mentionable", value=role.mentionable)
        embed.add_field(name="Colour", value=role.colour)
        embed.add_field(name="Role ID", value=role.id)
        icon_url = get_guild_icon_url(ctx.guild)
        if icon_url:
            embed.set_thumbnail(url=icon_url)
        embed.set_footer(
            text=f"Requested by: {ctx.author.display_name} ({ctx.author})\n" +
            self.bot.correct_time().strftime(self.bot.ts_format),
            icon_url=get_user_avatar_url(ctx.author, mode=1)[0])

        await ctx.send(embed=embed)
コード例 #7
0
ファイル: reputation.py プロジェクト: monkeyboy2805/adambot
    async def get_leaderboard(self, ctx: commands.Context) -> None:
        async with self.bot.pool.acquire() as connection:
            leaderboard = await connection.fetch(
                "SELECT member_id, reps FROM rep WHERE guild_id = $1 ORDER BY reps DESC",
                ctx.guild.id)

        if len(leaderboard) == 0:
            await self.bot.DefaultEmbedResponses.error_embed(
                self.bot, ctx,
                f"There aren't any reputation points in {ctx.guild.name} yet! "
            )
            return

        embed = self.bot.EmbedPages(
            self.bot.PageTypes.REP,
            leaderboard,
            f"{ctx.guild.name}'s Reputation Leaderboard",
            Colour.from_rgb(177, 252, 129),
            self.bot,
            ctx.author,
            ctx.channel,
            thumbnail_url=get_guild_icon_url(ctx.guild),
            icon_url=get_user_avatar_url(ctx.author, mode=1)[0],
            footer=f"Requested by: {ctx.author.display_name} ({ctx.author})\n"
            + self.bot.correct_time().strftime(self.bot.ts_format))
        await embed.set_page(1)  # Default first page
        await embed.send()
コード例 #8
0
    async def handle_unban(self,
                           data: dict,
                           reason: str = "",
                           author: str = "",
                           ctx: commands.Context = None) -> None:
        try:
            user = self.bot.get_user(data["member_id"])
            if not user and ctx:
                user, in_guild = await self.get_member_obj(
                    ctx, data["member_id"])
                if not user:
                    return
            guild = self.bot.get_guild(data["guild_id"])
            await guild.unban(user, reason=reason)
            channel_id = await self.bot.get_config_key(ctx, "log_channel")
            if channel_id is None:
                return
            channel = self.bot.get_channel(channel_id)

            embed = Embed(title="Unban", color=Colour.from_rgb(76, 176, 80))
            embed.add_field(name="User", value=f"{user.mention} ({user.id})")
            embed.add_field(name="Moderator",
                            value=str(self.bot.user if not author else author))
            embed.add_field(name="Reason", value=reason)
            embed.set_thumbnail(url=get_user_avatar_url(user)[0])
            embed.set_footer(
                text=self.bot.correct_time().strftime(self.bot.ts_format))
            await channel.send(embed=embed)
        except Exception as e:
            print(e)
            pass  # go away!
コード例 #9
0
ファイル: spotify.py プロジェクト: monkeyboy2805/adambot
    async def spotify_info(self, ctx: commands.Context, *, args: discord.Member | discord.User | str = "") -> None:
        if len(args) == 0:
            user = ctx.message.author
        else:
            if type(args) is not discord.Member:
                user = await self.bot.get_spaced_member(ctx, self.bot, args=args)
            else:
                user = args
            if user is None:
                fail_embed = Embed(title="Spotify info", description=f":x:  **Sorry {ctx.author.display_name} we could not find that user!**", color=Colour.from_rgb(255, 7, 58))
                fail_embed.set_footer(text=f"Requested by: {ctx.author.display_name} ({ctx.author})\n" + (
                        self.bot.correct_time()).strftime(self.bot.ts_format), icon_url=get_user_avatar_url(ctx.author, mode=1)[0])
                await ctx.send(embed=fail_embed)
                return

        spotify_activity = None
        for i in range(0, len(user.activities)):
            if type(user.activities[i]).__name__ == "Spotify":
                spotify_activity = user.activities[i]
                break
        if spotify_activity is None:
            fail_embed = Embed(title=f"Spotify info for {user}", description="The user isn't currently listening to Spotify\n*(note that this can't be detected unless Spotify is visible on the status)*", colour=user.colour)
            fail_embed.set_footer(text=f"Requested by: {ctx.author.display_name} ({ctx.author})\n" + (
                    self.bot.correct_time()).strftime(self.bot.ts_format), icon_url=get_user_avatar_url(ctx.author, mode=1)[0])
            await ctx.message.channel.send(embed=fail_embed)
            return
        duration = spotify_activity.duration.seconds
        minutes = duration//60
        seconds = duration % 60
        if seconds < 10:
            seconds = "0" + str(seconds)
        song_start = self.bot.correct_time(spotify_activity.start).strftime("%H:%M:%S")
        song_end = self.bot.correct_time(spotify_activity.end).strftime("%H:%M:%S")
        embed = Embed(title=f"Spotify info", colour=user.colour)
        embed.add_field(name="Track", value=f"{spotify_activity.title}")
        embed.add_field(name="Artist(s)", value=f"{spotify_activity.artist}")
        embed.add_field(name="Album", value=f"{spotify_activity.album}")
        embed.add_field(name="Track Length", value=f"{minutes}:{seconds}")
        embed.add_field(name="Time This Song Started", value=f"{song_start}")
        embed.add_field(name="Time This Song Will End", value=f"{song_end}")
        embed.add_field(name="Party ID (Premium Only)", value=f"{spotify_activity.party_id}")
        embed.add_field(name="Song's Spotify Link", value=f"https://open.spotify.com/track/{spotify_activity.track_id}", inline=False)
        embed.set_thumbnail(url=spotify_activity.album_cover_url)
        embed.set_author(name=f"{user}", icon_url=get_user_avatar_url(user, mode=1)[0])
        embed.set_footer(text=f"Requested by: {ctx.author.display_name} ({ctx.author})\n" + (
                    self.bot.correct_time()).strftime(self.bot.ts_format), icon_url=get_user_avatar_url(ctx.author, mode=1)[0])
        await ctx.message.channel.send(embed=embed)
コード例 #10
0
ファイル: member.py プロジェクト: monkeyboy2805/adambot
    async def serverinfo(self, ctx: commands.Context) -> None:
        """
        Information about the server.
        """

        guild = ctx.message.guild
        time_ = guild.created_at
        time_since = discord.utils.utcnow() - time_

        join = Embed(
            title=f"**__{str(guild)}__**",
            description=
            f"Created at {self.bot.correct_time(time_).strftime(self.bot.ts_format)}. That's {time_since.days} days ago!",
            color=Colour.from_rgb(21, 125, 224))
        icon_url = get_guild_icon_url(guild)
        if icon_url:
            join.set_thumbnail(url=icon_url)

        join.add_field(
            name="Users Online",
            value=
            f"{len([x for x in guild.members if x.status != Status.offline])}/{len(guild.members)}"
        )
        if ctx.guild.rules_channel:  # only community
            join.add_field(name="Rules Channel",
                           value=f"{ctx.guild.rules_channel.mention}")
        join.add_field(name="Text Channels",
                       value=f"{len(guild.text_channels)}")
        join.add_field(name="Voice Channels",
                       value=f"{len(guild.voice_channels)}")

        join.add_field(name="Roles", value=f"{len(guild.roles)}")
        join.add_field(name="Owner", value=f"{str(guild.owner)}")
        join.add_field(name="Server ID", value=f"{guild.id}")

        join.add_field(
            name="Emoji slots filled",
            value=f"{len(ctx.guild.emojis)}/{ctx.guild.emoji_limit}")
        join.add_field(
            name="Sticker slots filled",
            value=f"{len(ctx.guild.stickers)}/{ctx.guild.sticker_limit}")
        join.add_field(name="Upload size limit",
                       value=f"{guild.filesize_limit/1048576} MB")

        join.add_field(
            name="Boost level",
            value=
            f"{ctx.guild.premium_tier} ({ctx.guild.premium_subscription_count} boosts, {len(ctx.guild.premium_subscribers)} boosters)"
        )
        join.add_field(
            name="Default Notification Level",
            value=f"{self.bot.make_readable(guild.default_notifications.name)}"
        )
        join.set_footer(
            text=f"Requested by: {ctx.author.display_name} ({ctx.author})\n" +
            (self.bot.correct_time()).strftime(self.bot.ts_format),
            icon_url=get_user_avatar_url(ctx.author, mode=1)[0])

        await ctx.send(embed=join)
コード例 #11
0
ファイル: member.py プロジェクト: monkeyboy2805/adambot
    async def avatar(self,
                     ctx: commands.Context,
                     member: discord.Member | discord.User = None) -> None:
        if not member:
            member = ctx.author

        avatar_urls = get_user_avatar_url(member, mode=2)

        if len(avatar_urls) == 1 or avatar_urls[0] == avatar_urls[1]:
            await ctx.send(avatar_urls[0])
        else:
            await ctx.send(f"**ACCOUNT AVATAR:**\n{avatar_urls[0]}")
            await ctx.send(f"**SERVER AVATAR:**\n{avatar_urls[1]}")
コード例 #12
0
    async def kick(self,
                   ctx: commands.Context,
                   member: discord.Member,
                   *,
                   args: str = "") -> None:
        """
        Kicks a given user.
        Kick members perm needed
        """

        if ctx.me.top_role < member.top_role:
            await ctx.send(
                f"Can't ban {member.mention}, they have a higher role than the bot!"
            )
            return

        reason = None
        if args:
            parsed_args = self.bot.flag_handler.separate_args(
                args, fetch=["reason"], blank_as_flag="reason")
            reason = parsed_args["reason"]

        if not reason:
            reason = f"No reason provided"

        try:  # perhaps add some like `attempt_dm` thing in utils instead of this?
            await member.send(
                f"You have been kicked from {ctx.guild} ({reason})")
        except (discord.Forbidden, discord.HTTPException):
            await ctx.send(
                f"Could not DM {member.display_name} about their kick!")

        await member.kick(reason=reason)
        await ctx.send(f"{member.mention} has been kicked :boot:")

        channel_id = await self.bot.get_config_key(ctx, "log_channel")
        if channel_id is None:
            return
        channel = self.bot.get_channel(channel_id)

        embed = Embed(title="Kick", color=Colour.from_rgb(220, 123, 28))
        embed.add_field(name="Member", value=f"{member.mention} ({member.id})")
        embed.add_field(name="Reason",
                        value=reason + f" (kicked by {ctx.author.name})")
        embed.set_thumbnail(url=get_user_avatar_url(member, mode=1)[0])
        embed.set_footer(
            text=self.bot.correct_time().strftime(self.bot.ts_format))
        await channel.send(embed=embed)
コード例 #13
0
ファイル: logging.py プロジェクト: monkeyboy2805/adambot
    async def on_member_remove(self, member: discord.Member) -> None:
        channel = await self.get_log_channel(member.guild, "join_leave")
        if channel is None:
            return

        member_left = Embed(title=":information_source: User Left",
                            color=Colour.from_rgb(218, 118, 39))
        member_left.add_field(
            name="User", value=f"{member} ({member.id})\n {member.mention}")

        joined_at = member.joined_at
        if joined_at is not None:
            rn = discord.utils.utcnow()

            a = self.bot.correct_time(joined_at, timezone_="UTC")

            since_joined = (rn - a)
            since_str = ""
            props = [
                "weeks", "days", "hours", "minutes", "seconds", "milliseconds",
                "microseconds"
            ]
            for prop in props:
                if prop in dir(
                        since_joined
                ):  # datetime delta objects have no standard get method :(
                    since_str += f"{since_joined.__getattribute__(prop)} {prop} " if since_joined.__getattribute__(
                        prop) else ""
            user_joined = a.strftime(self.bot.ts_format)
            member_left.add_field(name="Joined",
                                  value=f"{user_joined} ({since_str} ago)"
                                  if joined_at else "Undetected")

        roles = [f"{role.mention}"
                 for role in member.roles][1:]  # 1: eliminates @@everyone
        roles_str = ""
        for role_ in roles:
            roles_str += f"{role_}, "
        roles_str = roles_str[:len(roles_str) - 2]

        member_left.add_field(name="Roles",
                              value=roles_str if member.roles[1:] else "None",
                              inline=False)
        member_left.set_thumbnail(url=get_user_avatar_url(member, mode=1)[0])
        member_left.set_footer(
            text=self.bot.correct_time().strftime(self.bot.ts_format))
        await channel.send(embed=member_left)
コード例 #14
0
ファイル: warnings.py プロジェクト: monkeyboy2805/adambot
    async def warns(self,
                    ctx: commands.Context,
                    member: discord.Member = None) -> None:
        """
        Shows a user their warnings, or shows staff members all/a single persons warnings
        """

        is_staff = await self.bot.is_staff(ctx)
        if is_staff:
            if not member:
                # Show all warns
                async with self.bot.pool.acquire() as connection:
                    warns = await connection.fetch(
                        "SELECT * FROM warn WHERE guild_id = $1 ORDER BY id;",
                        ctx.guild.id)

                if len(warns) > 0:
                    embed = self.bot.EmbedPages(
                        self.bot.PageTypes.WARN,
                        warns,
                        f"{ctx.guild.name if not member else member.display_name}'s warnings",
                        Colour.from_rgb(177, 252, 129),
                        self.bot,
                        ctx.author,
                        ctx.channel,
                        thumbnail_url=get_guild_icon_url(ctx.guild),
                        icon_url=get_user_avatar_url(ctx.author, mode=1)[0],
                        footer=
                        f"Requested by: {ctx.author.display_name} ({ctx.author})\n"
                        + self.bot.correct_time().strftime(self.bot.ts_format))

                    await embed.set_page(1)
                    await embed.send()
                else:
                    await ctx.send("No warnings recorded!")
            else:
                # Show member's warns
                await self._warnlist_member(
                    ctx, member,
                    1)  # Last parameter is the page number to start on
        else:
            if not member or member.id == ctx.author.id:
                # Show ctx.author warns
                await self._warnlist_member(ctx, ctx.author, 1)
            else:
                await ctx.send(
                    "You don't have permission to view other people's warns.")
コード例 #15
0
ファイル: bot.py プロジェクト: monkeyboy2805/adambot
    async def botinfo(self, ctx: commands.Context) -> None:
        app_info = await self.bot.application_info()
        embed = Embed(
            title=f"Bot info for ({self.bot.user})",
            description=app_info.description if app_info.description else "",
            colour=0x87CEEB)
        embed.add_field(name="Uptime",
                        value=self.bot.time_str(
                            round(time.time() - self.bot.start_time)))
        embed.add_field(name="Discord.py version",
                        value=discord.__version__,
                        inline=False)
        embed.add_field(name="Python version",
                        value=f"{platform.python_version()}",
                        inline=False)
        embed.add_field(name="Commit in use",
                        value=f"{self.commit_name} ({self.commit_hash})"
                        if self.commit_hash else "Unknown",
                        inline=False)
        if self.commit_url:
            embed.add_field(name="Commit link",
                            value=self.commit_url,
                            inline=False)
        if self.branch_name:
            embed.add_field(name="Currently checked out branch",
                            value=self.branch_name,
                            inline=False)
        embed.add_field(name="Host OS",
                        value=f"{platform.system()}",
                        inline=False)
        embed.add_field(name="Bot owner",
                        value=f"{app_info.owner}",
                        inline=False)
        embed.add_field(name="Public bot",
                        value=f"{app_info.bot_public}",
                        inline=False)

        if hasattr(app_info, "icon"):
            embed.set_thumbnail(url=app_info.icon.url)
        embed.set_footer(
            text=f"Requested by: {ctx.author.display_name} ({ctx.author})\n" +
            (self.bot.correct_time()).strftime(self.bot.ts_format),
            icon_url=get_user_avatar_url(ctx.author, mode=1)[0])
        await ctx.send(embed=embed)
コード例 #16
0
ファイル: member.py プロジェクト: monkeyboy2805/adambot
    async def gcses(self, ctx: commands.Context) -> None:
        embed = Embed(title="Information on UK exams",
                      color=Colour.from_rgb(148, 0, 211))
        now = self.bot.correct_time()
        time_ = self.bot.correct_time(
            datetime(year=2022, month=5, day=16, hour=9, minute=0, second=0))
        if now > time_:
            embed.description = "Exams have already started!"
        else:
            time_ = time_ - now
            m, s = divmod(time_.seconds, 60)
            h, m = divmod(m, 60)
            embed.description = f"{time_.days} days {h} hours {m} minutes {s} seconds remaining until the first exam (RS Paper 1)"

        embed.set_footer(
            text=f"Requested by: {ctx.author.display_name} ({ctx.author})\n" +
            (self.bot.correct_time()).strftime(self.bot.ts_format),
            icon_url=get_user_avatar_url(ctx.author, mode=1)[0])
        await ctx.send(embed=embed)
コード例 #17
0
    async def showreactionroles(self, ctx: commands.Context) -> None:
        """
        Shows all the current reaction roles in the guild
        """

        async with self.bot.pool.acquire() as connection:
            data = await connection.fetch(
                "SELECT * FROM reaction_roles WHERE guild_id = $1;",
                ctx.guild.id)

        embed = discord.Embed(
            title=f":information_source: {ctx.guild.name} reaction roles",
            color=self.bot.INFORMATION_BLUE)
        embed.set_footer(
            text=f"Requested by: {ctx.author.display_name} ({ctx.author})\n" +
            self.bot.correct_time().strftime(self.bot.ts_format),
            icon_url=get_user_avatar_url(ctx.author, mode=1)[0])

        message_reactions = {}  # ID -> str (to put in embed)
        message_channels = {}  # ID -> discord.TextChannel
        for rr in data:
            role = ctx.guild.get_role(rr["role_id"])
            emoji = rr["emoji"] or [
                x for x in ctx.guild.emojis if x.id == rr["emoji_id"]
            ][0]
            if rr["message_id"] not in message_reactions.keys():
                message_reactions[rr[
                    "message_id"]] = f"{emoji} -> {role.mention} {'(inverse)' if rr['inverse'] else ''}"
            else:
                message_reactions[rr[
                    "message_id"]] += f"\n{emoji} -> {role.mention} {'(inverse)' if rr['inverse'] else ''}"

            if rr["message_id"] not in message_channels.keys():
                message_channels[rr["message_id"]] = self.bot.get_channel(
                    rr["channel_id"])

        for message_id in message_reactions:
            embed.add_field(
                name=f"{message_id} (in #{message_channels[message_id]})",
                value=message_reactions[message_id])

        await ctx.reply(embed=embed)
コード例 #18
0
    async def list_server_roles(self, ctx: commands.Context) -> None:
        """
        Lists all the roles on the server.
        """

        embed = self.bot.EmbedPages(
            self.bot.PageTypes.ROLE_LIST,
            ctx.guild.roles[1:][::-1],
            f":information_source: Roles in {ctx.guild.name}",
            ctx.author.colour,
            self.bot,
            ctx.author,
            ctx.channel,
            thumbnail_url=get_guild_icon_url(ctx.guild),
            icon_url=get_user_avatar_url(ctx.author, mode=1)[0],
            footer=f"Requested by: {ctx.author.display_name} ({ctx.author})\n"
            + self.bot.correct_time().strftime(self.bot.ts_format))

        await embed.set_page(1)
        await embed.send()
コード例 #19
0
ファイル: starboard.py プロジェクト: adampy/adambot
    async def view(self, ctx: commands.Context) -> None:
        """
        View all of the starboards in the current guild
        """
        
        starboards = await self._get_starboards(ctx.guild.id)
        embed = self.bot.EmbedPages(
            self.bot.PageTypes.STARBOARD_LIST,
            starboards,
            f":information_source: {ctx.guild.name}'s starboards",
            self.bot.GOLDEN_YELLOW,
            self.bot,
            ctx.author,
            ctx.channel,
            thumbnail_url=get_guild_icon_url(ctx.guild),
            icon_url=get_user_avatar_url(ctx.author, mode=1)[0],
            footer=f"Requested by: {ctx.author.display_name} ({ctx.author})\n" + self.bot.correct_time().strftime(self.bot.ts_format),
        )

        await embed.set_page(1)
        await embed.send()
コード例 #20
0
ファイル: member.py プロジェクト: monkeyboy2805/adambot
    async def quote(self, ctx: commands.Context, messageid: int,
                    channel: discord.TextChannel | discord.Thread) -> None:
        """
        Quote a message to remember it.
        """

        try:
            msg = await channel.fetch_message(messageid)
        except Exception:
            await ctx.send(f"```{ctx.prefix}quote <message_id> [channel_id]```"
                           )
            return

        user = msg.author
        image = None
        repl = re.compile(r"/(\[.+?)(\(.+?\))/")
        edited = f" (edited at {msg.edited_at.isoformat(' ', 'seconds')})" if msg.edited_at else ""

        content = re.sub(repl, r"\1​\2", msg.content)

        if msg.attachments:
            image = msg.attachments[0].url

        embed = Embed(
            title="Quote link",
            url=f"https://discordapp.com/channels/{channel.id}/{messageid}",
            color=user.color,
            timestamp=msg.created_at)

        if image:
            embed.set_image(url=image)
        embed.set_footer(text=f"Sent by {user.name}#{user.discriminator}",
                         icon_url=get_user_avatar_url(user, mode=1)[0])
        embed.description = f"❝ {content} ❞" + edited
        await ctx.send(embed=embed)

        try:
            await ctx.message.delete()
        except Exception as e:
            print(e)
コード例 #21
0
ファイル: qotd.py プロジェクト: monkeyboy2805/adambot
    async def list(self, ctx: commands.Context, page_num: int = 1) -> None:
        async with self.bot.pool.acquire() as connection:
            qotds = await connection.fetch(
                "SELECT * FROM qotd WHERE guild_id = $1 ORDER BY id",
                ctx.guild.id)

        if len(qotds) > 0:
            embed = self.bot.EmbedPages(
                self.bot.PageTypes.QOTD,
                qotds,
                f"{ctx.guild.name}'s QOTDs",
                Colour.from_rgb(177, 252, 129),
                self.bot,
                ctx.author,
                ctx.channel,
                thumbnail_url=get_guild_icon_url(ctx.guild),
                icon_url=get_user_avatar_url(ctx.author, mode=1)[0],
                footer=
                f"Requested by: {ctx.author.display_name} ({ctx.author})\n" +
                self.bot.correct_time().strftime(self.bot.ts_format))
            await embed.set_page(int(page_num))
            await embed.send()
        else:
            await ctx.send("No QOTD have been submitted in this guild before.")
コード例 #22
0
ファイル: member.py プロジェクト: monkeyboy2805/adambot
    async def userinfo(self, ctx: commands.Context, *, args: str = "") -> None:
        """
        Information about you or a user
        """

        author = ctx.author
        guild = ctx.guild

        if len(args) == 0:
            user = author
        else:
            user = await self.bot.get_spaced_member(ctx, self.bot, args=args)
            args = args.replace("<",
                                "").replace(">",
                                            "").replace("@",
                                                        "").replace("!", "")
            if user is None and args.isdigit():
                user = await self.bot.fetch_user(
                    int(args)
                )  # allows getting some limited info about a user that isn't a member of the guild
            if user is None:
                await ctx.send(embed=Embed(
                    title="Userinfo",
                    description=
                    f":x:  **Sorry {ctx.author.display_name} we could not find that user!**",
                    color=Colour.from_rgb(255, 7, 58)))
                return

        is_member = isinstance(user, discord.Member)
        if is_member:
            statuses = ""
            if user.desktop_status != discord.Status.offline:
                statuses += f"{getattr(self.bot.EmojiEnum, str(user.desktop_status).upper())} Desktop "
            if user.web_status != discord.Status.offline:
                statuses += f"{getattr(self.bot.EmojiEnum, str(user.web_status).upper())} Web "
            if user.mobile_status != discord.Status.offline:
                statuses += f"{getattr(self.bot.EmojiEnum, str(user.mobile_status).upper())} Mobile"
            if not statuses:
                statuses = "in offline status"
            else:
                statuses = f"using {statuses}"

            data = Embed(
                description=f"Chilling {statuses}" if is_member else "",
                colour=user.colour)
        else:
            data = Embed(colour=user.colour)

        data.add_field(name="User ID", value=f"{user.id}")
        user_created = self.bot.correct_time(user.created_at).strftime(
            self.bot.ts_format)
        since_created = (ctx.message.created_at - user.created_at).days
        created_on = f"{user_created}\n({since_created} days ago)"
        data.add_field(name="Joined Discord on", value=created_on)

        if is_member:
            roles = user.roles[-1:0:-1]

            joined_at = user.joined_at

            if joined_at is not None:
                since_joined = (ctx.message.created_at - joined_at).days
                user_joined = self.bot.correct_time(joined_at).strftime(
                    self.bot.ts_format)

            else:
                since_joined = "?"
                user_joined = "Unknown"

            voice_state = user.voice

            member_number = (sorted(guild.members,
                                    key=lambda m: m.joined_at or ctx.message.
                                    created_at).index(user) + 1)

            joined_on = f"{user_joined}\n({since_joined} days ago)"

            data.add_field(name="Joined this server on", value=joined_on)
            data.add_field(name="Position",
                           value=f"#{member_number}/{len(guild.members)}")
            for activity in user.activities:
                if isinstance(activity, discord.Spotify):
                    diff = discord.utils.utcnow(
                    ) - activity.start  # timedeltas have stupid normalisation of days, seconds, milliseconds because that make sense
                    data.add_field(
                        name="Listening to Spotify",
                        value=
                        f"{activity.title} by {activity.artist} on {activity.album} ({self.bot.time_str(diff.seconds + diff.days * 86400)} elapsed)",
                        inline=False)

                elif isinstance(activity, discord.CustomActivity):
                    data.add_field(name="Custom Status",
                                   value=f"{activity.name}",
                                   inline=False)

                else:
                    """
                    It's worth noting that all activities normally have details attached, but Game objects do NOT have details
                    Rationale: memory optimisation
                    """
                    if activity.start:
                        diff = discord.utils.utcnow() - activity.start
                        diff = f"({self.bot.time_str(diff.seconds + diff.days * 86400)} elapsed)"
                    else:
                        diff = ""
                    data.add_field(
                        name=f"{type(activity).__name__}",
                        value=
                        f"{activity.name} {diff}\n{'' if not hasattr(activity, 'details') else activity.details}",
                        inline=False)

            if roles:
                disp_roles = ", ".join([role.name for role in roles[:10]])
                if len(roles) > 10:
                    disp_roles += f" (+{len(roles) - 10} roles)"
                data.add_field(name="Roles", value=disp_roles, inline=False)

            else:
                data.add_field(name="Roles", value="No roles currently!")

            if voice_state and voice_state.channel:
                data.add_field(
                    name="Current voice channel",
                    value=
                    f"{voice_state.channel.mention} ID: {voice_state.channel.id}",
                    inline=False,
                )

        data.set_footer(
            text=f"Requested by: {ctx.author.display_name} ({ctx.author})\n" +
            (self.bot.correct_time()).strftime(self.bot.ts_format),
            icon_url=get_user_avatar_url(ctx.author, mode=1)[0])
        flags = user.public_flags.all()  # e.g. hypesquad stuff
        if flags:
            desc = []
            for flag in flags:
                desc.append(
                    self.bot.make_readable(flag.name)
                )  # PyCharm likes to complain about this but it's an enum so... it's perfectly valid
            desc = ", ".join(desc)
            data.add_field(name="Special flags", value=desc, inline=False)

        name = f"{user} ~ {user.display_name}"

        avatar = get_user_avatar_url(user, mode=1)[0]
        data.set_author(name=name, icon_url=avatar)
        data.set_thumbnail(url=avatar)

        await ctx.send(embed=data)
コード例 #23
0
    async def mute(self,
                   ctx: commands.Context,
                   member: discord.Member,
                   *,
                   args: str = "") -> None:
        """
        Gives a given user the Muted role.
        Manage roles perm needed.
        """

        role = get(member.guild.roles,
                   id=await self.bot.get_config_key(member, "muted_role"))
        if not role:
            await ctx.send(":x: No muted role has been set!")
            return
        if role in member.roles:
            await ctx.send(
                f":x: **{member}** is already muted! Unmute them and mute them again to change their mute"
            )
            return
        reason, timeperiod = None, None
        if args:
            parsed_args = self.bot.flag_handler.separate_args(
                args, fetch=["time", "reason"], blank_as_flag="reason")
            timeperiod = parsed_args["time"]
            reason = parsed_args["reason"]

            if timeperiod:
                await self.bot.tasks.submit_task(
                    "unmute",
                    datetime.utcnow() + timedelta(seconds=timeperiod),
                    extra_columns={
                        "member_id": member.id,
                        "guild_id": member.guild.id
                    })
        await member.add_roles(role,
                               reason=reason if reason else
                               f"No reason - muted by {ctx.author.name}")
        await ctx.send(f":ok_hand: **{member}** has been muted")
        # "you are muted " + timestring
        if not timeperiod:
            timestring = "indefinitely"
        else:
            time = (self.bot.correct_time() + timedelta(seconds=timeperiod)
                    )  # + timedelta(hours = 1)
            timestring = "until " + time.strftime("%H:%M on %d/%m/%y")

        if not reason or reason is None:
            reasonstring = "an unknown reason (the staff member did not give a reason)"
        else:
            reasonstring = reason
        try:
            await member.send(
                f"You have been muted {timestring} for {reasonstring}.")
        except (discord.Forbidden, discord.HTTPException):
            await ctx.send(
                f"Could not DM {member.display_name} about their mute!")

        channel_id = await self.bot.get_config_key(ctx, "log_channel")
        if channel_id is None:
            return
        channel = self.bot.get_channel(channel_id)

        embed = Embed(title="Member Muted", color=Colour.from_rgb(172, 32, 31))
        embed.add_field(name="Member", value=f"{member.mention} ({member.id})")
        embed.add_field(name="Moderator", value=str(ctx.author))
        embed.add_field(name="Reason", value=reason)
        embed.add_field(name="Expires",
                        value=timestring.replace("until ", "")
                        if timestring != "indefinitely" else "Never")
        embed.set_thumbnail(url=get_user_avatar_url(member, mode=1)[0])
        embed.set_footer(
            text=self.bot.correct_time().strftime(self.bot.ts_format))
        await channel.send(embed=embed)
コード例 #24
0
    async def ban(self,
                  ctx: commands.Context,
                  member: discord.Member | str,
                  *,
                  args: str = "") -> None:
        """
        Bans a given user.
        Merged with previous command hackban
        Single bans work with user mention or user ID
        Mass bans work with user IDs currently, reason flag HAS to be specified if setting
        Ban members perm needed
        """

        if not ctx.me.guild_permissions.ban_members:
            await ctx.send("Can't do that sorry :(")
            return

        invites = await ctx.guild.invites()
        reason = "No reason provided"
        massban = (ctx.invoked_with == "massban")
        timeperiod = tracker = None

        if args:
            parsed_args = self.bot.flag_handler.separate_args(
                args,
                fetch=["time", "reason"],
                blank_as_flag="reason" if not massban else None)
            timeperiod = parsed_args["time"]
            reason = parsed_args["reason"]

        if massban:
            members = ctx.message.content[ctx.message.content.index(" ") +
                                          1:].split(" ")
            members = [
                member for member in members
                if len(member) == 18 and str(member).isnumeric()
            ]
            # possibly rearrange at some point to allow checking if the member/user object can be obtained?
            tracker = await ctx.send(
                f"Processed bans for 0/{len(members)} members")
        else:
            members = [member]
        already_banned = []
        not_found = []
        could_not_notify = []

        ban = 0
        for ban, member_ in enumerate(members, start=1):
            if massban:
                await tracker.edit(
                    content=f"Banning {ban}/{len(members)} users" +
                    (f", {len(not_found)} users not found"
                     if len(not_found) > 0 else "") +
                    (f", {len(already_banned)} users already banned"
                     if len(already_banned) > 0 else ""))

            if type(member_) is not discord.Member:
                member, in_guild = await self.get_member_obj(ctx, member_)
            else:
                member = member_
                in_guild = True

            if in_guild:
                if ctx.me.top_role < member.top_role:
                    await ctx.send(
                        f"Can't ban {member.mention}, they have a higher role than the bot!"
                    )
                    continue
            for invite in invites:
                if invite.inviter.id == member.id:
                    await ctx.invoke(self.bot.get_command("revokeinvite"),
                                     invite_code=invite.code)
            if timeperiod:
                await self.bot.tasks.submit_task("unban",
                                                 datetime.utcnow() +
                                                 timedelta(seconds=timeperiod),
                                                 extra_columns={
                                                     "member_id": member.id,
                                                     "guild_id": ctx.guild.id
                                                 })
            if not member:
                not_found.append(member_)
                if not massban:
                    await ctx.send(f"Couldn't find that user ({member_})!")
                    return
                else:
                    continue
            if await self.is_user_banned(ctx, member):
                already_banned.append(member.mention)
                if not massban:
                    await ctx.send(f"{member.mention} is already banned!")
                    return
                else:
                    continue
            try:
                await member.send(
                    f"You have been banned from {ctx.guild.name} ({reason})")
            except (discord.Forbidden, discord.HTTPException):
                if not massban:
                    await ctx.send(
                        f"Could not DM {member.mention} ({member.id}) about their ban!"
                    )
                else:
                    could_not_notify.append(member)

            await ctx.guild.ban(member, reason=reason, delete_message_days=0)
            if not massban:
                await ctx.send(f"{member.mention} has been banned.")

            channel_id = await self.bot.get_config_key(ctx, "log_channel")
            if channel_id is None:
                return
            channel = self.bot.get_channel(channel_id)

            embed = Embed(title="Ban" if in_guild else "Hackban",
                          color=Colour.from_rgb(255, 255, 255))
            embed.add_field(name="Member",
                            value=f"{member.mention} ({member.id})")
            embed.add_field(name="Moderator", value=str(ctx.author))
            embed.add_field(name="Reason", value=reason)
            embed.set_thumbnail(url=get_user_avatar_url(member, mode=1)[0])
            embed.set_footer(
                text=self.bot.correct_time().strftime(self.bot.ts_format))

            await channel.send(embed=embed)
        if massban:
            # chr(10) used for \n since you can't have backslash characters in f string fragments
            await tracker.edit(
                content=f"Processed bans for {ban}/{len(members)} users" +
                (f"\n__**These users weren't found**__:\n\n - {f'{chr(10)} - '.join(f'{a_not_found}' for a_not_found in not_found)}\n"
                 if len(not_found) > 0 else "") +
                (f"\n__**These users are already banned**__:\n\n - {f'{chr(10)} - '.join(f'{a_already_banned}' for a_already_banned in already_banned)}"
                 if len(already_banned) > 0 else "") +
                (f"\n__**These users couldn't be DMed about their ban**__:\n\n - {f'{chr(10)} - '.join(f'{a_unnotified}' for a_unnotified in could_not_notify)}"
                 if len(could_not_notify) > 0 else ""))
コード例 #25
0
    async def config(self, ctx: commands.Context) -> None:
        """
        View the current configuration settings of the guild
        """

        if not (ctx.author.guild_permissions.administrator
                or await self.is_staff(ctx)):
            await self.bot.DefaultEmbedResponses.invalid_perms(self.bot, ctx)
            return

        if ctx.invoked_subcommand is None:  # User is staff and no subcommand => send embed
            """
             To get the config options
             1. Copy self.CONFIG into a new variable
             2. Foreach config option, append the option to the list under the specific option's key (this is the embed value)
             3. Pass the dict into EmbedPages for formatting
            """

            data = copy.deepcopy(self.CONFIG)
            config_dict = self.bot.configs[ctx.guild.id]

            for key in config_dict.keys():
                if key not in data.keys():
                    continue  # This clause ensures that variables, e.g. "bruhs", that are in the DB but not in self.CONFIG, do not appear

                if not config_dict[key] or data[key][0] not in [
                        Validation.Channel, Validation.Role
                ]:
                    data[key].append(config_dict[key] if config_dict[key]
                                     is not None else "*N/A*")

                elif data[key][0] == Validation.Channel:
                    channel = ctx.guild.get_channel_or_thread(
                        config_dict[key]
                    )  # note that this is gonna have to be looked at again if any other types of channels are to be allowed
                    data[key].append(f"{channel.mention} ({config_dict[key]})"
                                     if channel else "*N/A*")

                elif data[key][0] == Validation.Role:
                    role = ctx.guild.get_role(config_dict[key])
                    data[key].append(f"{role.mention} ({config_dict[key]})"
                                     if role else "*N/A*")

            p = (
                await self.bot.get_used_prefixes(ctx)
            )[-1]  # guild will be last if set, if not it'll fall back to global
            desc = f"Below are the configurable options for {ctx.guild.name}. To change one, do `{p}config set <key> <value>` where <key> is the option you'd like to change, e.g. `{p}config set qotd_limit 2`"
            embed = self.bot.EmbedPages(
                self.bot.PageTypes.CONFIG,
                data,
                f":tools:  {ctx.guild.name} ({ctx.guild.id}) configuration",
                ctx.author.colour,
                self.bot,
                ctx.author,
                ctx.channel,
                desc=desc,
                thumbnail_url=get_guild_icon_url(ctx.guild),
                icon_url=get_user_avatar_url(ctx.author, mode=1)[0],
                footer=
                f"Requested by: {ctx.author.display_name} ({ctx.author})\n" +
                self.bot.correct_time().strftime(self.bot.ts_format))
            await embed.set_page(1)  # Default first page
            await embed.send()
コード例 #26
0
    async def lurker_kick(self,
                          ctx: commands.Context,
                          days: str = "7") -> None:
        # days is specifically "7" as default and not 7 since if you specify an integer it barfs if you supply a non-int value
        """
        Command that kicks people without a role, and joined 7 or more days ago.
        """
        def check(m: discord.Message) -> bool:
            return m.channel == ctx.channel and m.author == ctx.author

        if not days.isnumeric():
            await ctx.send("Specify a whole, non-zero number of days!")
            return

        days = int(days)
        time_ago = discord.utils.utcnow() - datetime.timedelta(days=days)
        members = [
            x for x in ctx.guild.members
            if len(x.roles) <= 1 and x.joined_at < time_ago
        ]  # Members with only the everyone role and more than 7 days ago
        if len(members) == 0:
            await ctx.send(
                f"There are no lurkers to kick that have been here {days} days or longer!"
            )
            return

        question = await ctx.send(
            f"Do you want me to kick all lurkers that have been here {days} days or longer ({len(members)} members)? (Type either 'yes' or 'no')"
        )
        try:
            response = await self.bot.wait_for("message",
                                               check=check,
                                               timeout=300)
        except asyncio.TimeoutError:
            await question.delete()
            return

        if response.content.lower() == "yes":
            for i in range(len(members)):
                member = members[i]

                await question.edit(
                    content=f"Kicked {i}/{len(members)} lurkers :ok_hand:")
                await member.kick(
                    reason="Auto-kicked following lurker kick command.")

            await question.edit(
                content=
                f"All {len(members)} lurkers that have been here more than {days} days have been kicked :ok_hand:"
            )

        elif response.content.lower() == "no":
            await question.edit(content="No lurkers have been kicked :ok_hand:"
                                )

        else:
            await question.edit(
                content=
                "Unknown response, therefore no lurkers have been kicked :ok_hand:"
            )

        channel_id = await self.bot.get_config_key(ctx, "log_channel")
        if channel_id is None:
            return
        channel = self.bot.get_channel(channel_id)

        embed = Embed(title="Lurker-kick", color=Colour.from_rgb(220, 123, 28))
        embed.add_field(name="Members", value=str(len(members)))
        embed.add_field(name="Reason",
                        value="Auto-kicked from the -lurkers kick command")
        embed.add_field(name="Initiator", value=ctx.author.mention)
        embed.set_thumbnail(url=get_user_avatar_url(ctx.author, mode=1)[0])
        embed.set_footer(
            text=self.bot.correct_time().strftime(self.bot.ts_format))
        await channel.send(embed=embed)
コード例 #27
0
ファイル: logging.py プロジェクト: monkeyboy2805/adambot
    async def prop_change_handler(self, before: discord.Member,
                                  after: discord.Member) -> dict:
        """
        God handler which handles all the default logging embed behaviour
        Works for both member and user objects
        """
        """
        Property definitions
        """

        user_updated_colour = Colour.from_rgb(
            214, 174, 50)  # Storing as var quicker than initialising each time
        watched_props = [{
            "name": "display_name",
            "display_name": "Nickname",
            "colour": user_updated_colour,
            "custom_handler": self.disp_name_handler
        }, {
            "name": "roles",
            "display_name": "Roles",
            "colour": user_updated_colour,
            "custom_handler": self.embed_role_comparison
        }, {
            "name": "avatar",
            "display_name": "Avatar",
            "colour": user_updated_colour,
            "custom_handler": self.avatar_handler
        }, {
            "name": "name",
            "display_name": "Username",
            "colour": user_updated_colour,
            "custom_handler": None
        }, {
            "name": "discriminator",
            "display_name": "Discriminator",
            "colour": user_updated_colour,
            "custom_handler": None
        }]

        for prop in watched_props:
            thumbnail_set = False

            if hasattr(before, prop["name"]) and hasattr(
                    after, prop["name"]
            ):  # user objects don't have all the same properties as member objects

                if (getattr(before, prop["name"]) != getattr(
                        after, prop["name"])) or (
                            prop["name"] == "avatar"
                            and get_user_avatar_url(before)[0] !=
                            get_user_avatar_url(after)[0]
                        ):  # TODO: Fix up the edge case with avatars?
                    log = Embed(
                        title=
                        f":information_source: {prop['display_name']} Updated",
                        color=prop["colour"])
                    log.add_field(name="User",
                                  value=f"{after} ({after.id})",
                                  inline=True)

                    if not prop["custom_handler"]:
                        log.add_field(
                            name=f"Old {prop['display_name'].lower()}",
                            value=getattr(before, prop["name"]))
                        log.add_field(
                            name=f"New {prop['display_name'].lower()}",
                            value=getattr(after, prop["name"]))

                    else:
                        """
                        Calls the custom embed handler as defined
                        Custom embed handlers are expected to return dict type objects to be handled below
                        """

                        result = await prop["custom_handler"](before, after)
                        if result:  # return None for no result
                            if "fields" in result:
                                for field in result["fields"]:
                                    log.add_field(name=field["name"],
                                                  value=field["value"])
                            if "description" in result:
                                log.description = result["description"]
                            if "image" in result:
                                log.set_image(url=f"{result['image']}")
                            if "thumbnail_url" in result:
                                log.set_thumbnail(
                                    url=f"{result['thumbnail_url']}")
                                thumbnail_set = True
                        else:
                            continue

                    if not thumbnail_set:
                        log.set_thumbnail(
                            url=get_user_avatar_url(after, mode=1)[0])
                    log.set_footer(text=self.bot.correct_time().strftime(
                        self.bot.ts_format))

                    # Send `log` embed to all servers the user is part of, unless its a nickname change or role change (which are server specific)
                    if prop["display_name"] in ["Nickname", "Roles"]:
                        channel = await self.get_log_channel(
                            before.guild, "member_update")
                        if channel:
                            await channel.send(embed=log)

                    else:
                        shared_guilds = [
                            x for x in self.bot.guilds if after in x.members
                        ]
                        for guild in shared_guilds:
                            channel = await self.get_log_channel(
                                guild, "member_update")
                            if channel:
                                await channel.send(embed=log)
コード例 #28
0
ファイル: reputation.py プロジェクト: monkeyboy2805/adambot
    async def award(self, ctx: commands.Context, *,
                    args: discord.Member | discord.User | str) -> None:
        """
        Gives the member a reputation point. Aliases are give and point
        """

        if type(args) == discord.Member:
            user = args
        elif type(args) == discord.User:
            user = ctx.guild.get_member(args.id)
        else:
            # todo: sort this mess out
            user = await self.bot.get_spaced_member(
                ctx, self.bot, args=args
            ) if args else None  # check so rep award doesn't silently fail when no string given

        if not user:
            failed = Embed(title=f":x:  Sorry we could not find the user!"
                           if args else "Rep Help",
                           color=self.bot.ERROR_RED)
            if args:
                failed.add_field(name="Requested user", value=args)

            failed.add_field(
                name="Information",
                value=
                f"\nTo award rep to someone, type \n`{ctx.prefix}rep Member_Name`\nor\n`{ctx.prefix}rep @Member`\n"
                f"Pro tip: If e.g. fred roberto was recently active you can type `{ctx.prefix}rep fred`\n\nTo see the other available rep commands type `{ctx.prefix}help rep`",
                inline=False)
            failed.set_footer(
                text=f"Requested by: {ctx.author.display_name} ({ctx.author})\n"
                + (self.bot.correct_time()).strftime(self.bot.ts_format),
                icon_url=get_user_avatar_url(ctx.author, mode=1)[0])

            await ctx.send(embed=failed)
            return
        nick = user.display_name

        if ctx.author != user and not user.bot:  # Check prevents self-rep and that receiver is not a bot
            award_banned_role = ctx.guild.get_role(
                await self.bot.get_config_key(ctx, "rep_award_banned"))
            receive_banned_role = ctx.guild.get_role(
                await self.bot.get_config_key(ctx, "rep_receive_banned"))
            award_banned = award_banned_role in ctx.author.roles
            receive_banned = receive_banned_role in user.roles
            award = not award_banned and not receive_banned
            title = f"You have been blocked from awarding reputation points" if award_banned else ""
            title += " and " if award_banned and receive_banned else "!" if award_banned and not receive_banned else ""
            title += f"{nick} has been blocked from receiving reputation points!" if receive_banned else ""
            title += f"\n\n{nick} did not receive a reputation point!" if not award else ""

            if award:
                reps = await self.modify_rep(user, 1)
                await self.bot.DefaultEmbedResponses.success_embed(
                    self.bot,
                    ctx,
                    f"{nick} received a reputation point!",
                    desc=f"{user.mention} now has {reps} reputation points!",
                    thumbnail_url=get_user_avatar_url(user, mode=1)[0])

                # Log rep
                channel_id = await self.bot.get_config_key(ctx, "log_channel")
                if channel_id is None:
                    return
                channel = self.bot.get_channel(channel_id)
                embed = Embed(title="Reputation Points",
                              color=Colour.from_rgb(177, 252, 129))
                embed.add_field(name="From",
                                value=f"{str(ctx.author)} ({ctx.author.id})")
                embed.add_field(name="To", value=f"{str(user)} ({user.id})")
                embed.add_field(name="New Rep", value=reps)
                embed.add_field(name="Awarded in", value=ctx.channel.mention)
                embed.set_footer(
                    text=self.bot.correct_time().strftime(self.bot.ts_format))
                await channel.send(embed=embed)

            else:  # Rep cannot be given
                await self.bot.DefaultEmbedResponses.error_embed(
                    self.bot,
                    ctx,
                    title,
                    desc=
                    "Contact a member of staff if you think you are seeing this by mistake.",
                    thumbnail_url=get_user_avatar_url(user, mode=1)[0])

        else:
            desc = "The bot overlords do not accept puny humans' rewards" if user.bot else "You cannot rep yourself, cheating bugger."
            await self.bot.DefaultEmbedResponses.error_embed(
                self.bot,
                ctx,
                f"Failed to award a reputation point to {nick}",
                desc=desc,
                thumbnail_url=get_user_avatar_url(user, mode=1)[0])
コード例 #29
0
ファイル: member.py プロジェクト: monkeyboy2805/adambot
    async def resultsday(self, ctx: commands.Context, hour: str = "") -> None:
        if ctx.invoked_with in ["resultsday", "gcseresults", "results", None]:
            which = "GCSE"
        else:
            which = "A-Level"
        if not hour:
            hour = 10
        else:
            try:
                hour = int(hour)
            except ValueError:
                await ctx.send(
                    "You must choose an integer between 0 and 23 for the command to work!"
                )

        if not 0 <= hour < 24:
            await ctx.send("The hour must be between 0 and 23!")
            return

        if hour == 12:
            string = "noon"
        elif hour == 0:
            string = "0:00AM"
        elif hour >= 12:
            string = f"{hour - 12}PM"
        else:
            string = f"{hour}AM"
        rn = self.bot.correct_time()
        if which == "GCSE":
            time_ = self.bot.correct_time(
                datetime(year=2022,
                         month=8,
                         day=18,
                         hour=hour,
                         minute=0,
                         second=0))
        else:
            time_ = self.bot.correct_time(
                datetime(year=2022,
                         month=8,
                         day=11,
                         hour=hour,
                         minute=0,
                         second=0))
        embed = Embed(
            title=
            f"Countdown until {which} results day at {string} (on {time_.day}/{time_.month}/{time_.year})",
            color=Colour.from_rgb(148, 0, 211))

        if rn > time_:
            embed.description = "Results have already been released!"
        else:
            time_ = time_ - rn
            m, s = divmod(time_.seconds, 60)
            h, m = divmod(m, 60)
            embed.description = f"{time_.days} days {h} hours {m} minutes {s} seconds remaining"
        embed.set_footer(
            text=f"Requested by: {ctx.author.display_name} ({ctx.author})\n" +
            (self.bot.correct_time()).strftime(self.bot.ts_format),
            icon_url=get_user_avatar_url(ctx.author, mode=1)[0])
        icon_url = get_guild_icon_url(ctx.guild)
        if icon_url:
            embed.set_thumbnail(url=icon_url)
        await ctx.send(embed=embed)
コード例 #30
0
ファイル: logging.py プロジェクト: monkeyboy2805/adambot
    async def on_member_join(self, member: discord.Member) -> None:
        guild = member.guild

        ichannel = await self.get_log_channel(guild, "join_leave")
        if ichannel is None:  # If invite channel not set
            return

        old_invites = self.invites[guild.id]
        new_invites = await self.get_all_invites(guild)

        updated_invites = []
        possible_joins_missed = False
        for invite in new_invites:
            found = False
            for old_invite in old_invites:
                if old_invite.code == invite.code:
                    found = True
                    if invite.uses > old_invite.uses:
                        updated_invites.append(invite)
                        if invite.uses - old_invite.uses != 1:
                            possible_joins_missed = True

            if not found and invite.uses != 0:  # else 0-use invites will be logged
                updated_invites.append(invite)  # new invites

        self.invites[guild.id] = new_invites
        if ichannel:  # still check & update invites in case channel is configured later
            invite_log = Embed(title="Invite data",
                               color=Colour.from_rgb(0, 0, 255))
            if len(updated_invites) == 1:
                invite_log.set_author(
                    name=
                    f"{updated_invites[0].inviter} ~ {updated_invites[0].inviter.display_name}"
                    if updated_invites[0].inviter else
                    f"{guild.name} ~ Vanity URL",
                    icon_url=get_user_avatar_url(updated_invites[0].inviter,
                                                 mode=1)[0])

                invite_log.description = ":arrow_up: Inviter Avatar\n:arrow_right: Member Avatar"
            else:
                invite_log.description = ":arrow_right: Member Avatar"

            invite_log.add_field(
                name="Member",
                value=f"{member.mention} [{member.name}] ({member.id})")

            for x, invite in enumerate(updated_invites):
                invite_log.add_field(
                    name=f"\nPossible Invite #{x + 1}\n\nInviter"
                    if len(updated_invites) != 1 else "Inviter",
                    value=invite.inviter.mention
                    if invite.inviter else "Server (Vanity)",
                    inline=len(updated_invites) == 1)

                invite_log.add_field(name="Code", value=invite.code)
                invite_log.add_field(name="Channel",
                                     value=invite.channel.mention)
                invite_log.add_field(name="Expires",
                                     value=self.bot.time_str(invite.max_age)
                                     if invite.max_age != 0 else "Never")
                invite_log.add_field(
                    name="Uses",
                    value=str(invite.uses) +
                    (f"/{invite.max_uses}" if invite.max_uses != 0 else ""))
                invite_log.add_field(name="Invite Created",
                                     value=self.bot.correct_time(
                                         invite.created_at).strftime(
                                             self.bot.ts_format),
                                     inline=False)

            invite_log.add_field(name="Account created",
                                 value=self.bot.correct_time(
                                     member.created_at).strftime(
                                         self.bot.ts_format),
                                 inline=False)

            if not updated_invites:
                invite_log.add_field(name="Invite used",
                                     value="Server Discovery")

            invite_log.set_thumbnail(
                url=get_user_avatar_url(member, mode=1)[0])
            invite_log.set_footer(
                text=self.bot.correct_time().strftime(self.bot.ts_format))
            if (
                    invite_log.to_dict() not in self.previous_inv_log_embeds
            ) or not updated_invites:  # limits log spam e.g. if connection drops

                #if possible_joins_missed or len(updated_invites) != 1:
                #    await get(guild.text_channels, name="invite-logs").send("*WARNING: Due to a bot glitch or other reason, the below data may be inaccurate due to potentially missed previous joins.*")

                self.previous_inv_log_embeds.append(invite_log.to_dict())
                await ichannel.send(embed=invite_log)