Пример #1
0
    async def star_leaderboard(self, ctx: Context):
        """Retrieve the star leaderboard for the current server"""
        data = await stats.leaderboard(ctx.guild, top=8)

        def fmt_data(dct: dict, emoji: str = "\N{WHITE MEDIUM STAR}"):
            items = []
            keys = list(dct.keys())
            for x, y in dct.items():
                medal = medals[min(len(medals) - 1,
                                   keys.index(x))].format(index(keys, x))
                items.append(
                    f"{medal} {x.mention} \N{EM DASH} **{y:,}** {emoji}")
            return "\n".join(items) or inline(
                i18n("There's nothing here yet..."))

        await ctx.send(embed=(discord.Embed(colour=ctx.me.colour).set_author(
            name=i18n("Server Leaderboard"), icon_url=ctx.guild.icon_url
        ).add_field(name=i18n("Stars Given"), value=fmt_data(
            data["given"])).add_field(
                name=i18n("Stars Received"), value=fmt_data(data["received"])
            ).add_field(name="\N{ZERO WIDTH JOINER}",
                        value="\N{ZERO WIDTH JOINER}",
                        inline=False).add_field(
                            name=i18n("Max Stars Received"),
                            value=fmt_data(data["max_received"])).add_field(
                                name=i18n("Starboard Messages"),
                                value=fmt_data(data["messages"],
                                               emoji="\N{ENVELOPE}"),
                            )))
Пример #2
0
    async def stars_unignore(self,
                             ctx: Context,
                             name: str,
                             *,
                             reason: str = None):
        """Remove a channel or member from the server's ignore list

        `reason` is only used if unignoring a member
        """
        item = await resolve_any(ctx, name, commands.TextChannelConverter,
                                 commands.MemberConverter)

        if isinstance(item, discord.Member) and not await hierarchy_allows(
                self.bot, ctx.author, item):
            await ctx.send(
                error(
                    i18n(
                        "You aren't allowed to remove that member from the ignore list"
                    )))
            return
        elif (isinstance(item, discord.TextChannel)
              and item == await ctx.starboard.resolve_starboard()):
            await ctx.send(
                warning(
                    i18n(
                        "The starboard channel is always ignored and cannot be manually "
                        "ignored nor unignored.")))
            return

        if not await ctx.starboard.is_ignored(item):
            await ctx.send(
                warning(
                    i18n(
                        "That user is not already ignored from using this server's starboard"
                    ) if isinstance(item, discord.Member) else i18n(
                        "That channel is not already being ignored")))
            return

        await ctx.starboard.unignore(item)
        await ctx.send(
            tick(
                i18n("**{}** is no longer ignored from this server's starboard"
                     )).format(item))

        if isinstance(item, discord.Member):
            try:
                await modlog.create_case(
                    bot=self.bot,
                    guild=ctx.guild,
                    created_at=ctx.message.created_at,
                    action_type="starboardunblock",
                    user=item,
                    moderator=ctx.author,
                    reason=reason,
                    until=None,
                    channel=None,
                )
            except RuntimeError:
                pass
Пример #3
0
 async def stars_unhide(self, ctx: Context, message: StarboardMessage):
     """Unhide a previously hidden message"""
     if message.hidden is False:
         return await ctx.send(
             error(i18n("That message hasn't been hidden")))
     message.hidden = False
     await ctx.send(
         tick(
             i18n("The message sent by **{}** is no longer hidden.").format(
                 message.author)))
Пример #4
0
 async def stars_hide(self, ctx: Context, message: StarboardMessage):
     """Hide a message from the starboard"""
     if message.hidden:
         return await ctx.send(error(i18n("That message is already hidden"))
                               )
     message.hidden = True
     await ctx.send(
         tick(
             i18n("The message sent by **{}** is now hidden.").format(
                 message.author)))
Пример #5
0
    async def starboard_selfstar(self, ctx: Context, toggle: bool = None):
        """Toggles if members can star their own messages

        Member statistics do not respect this setting, and always ignore self-stars.
        """
        toggle = (
            not await ctx.starboard.selfstar()) if toggle is None else toggle
        await ctx.starboard.selfstar.set(toggle)
        await ctx.send(
            tick(
                i18n("Members can now star their own messages") if toggle else
                i18n("Members can no longer star their own messages")))
Пример #6
0
    async def starboardset_v2_import(self, ctx: Context, mongo_uri: str):
        """Import Red v2 instance data

        Please note that this is not officially supported, and this import tool
        is provided as-is.

        Only messages are imported currently; server settings are not imported,
        and must be setup again.

        In most cases, `mongodb://localhost:27017` will work just fine
        if you're importing a local v2 instance.
        """
        if not await confirm(
                ctx,
                timeout=90.0,
                content=i18n(
                    "**PLEASE READ THIS! UNEXPECTED BAD THINGS MAY HAPPEN IF YOU DON'T!**"
                    "\n"
                    "Importing from v2 instances is not officially supported, due to the vast"
                    " differences in backend data storage schemas. This command is provided as-is,"
                    " with no guarantee of maintenance nor stability."
                    "\n\n"
                    "Server settings will not be imported and must be setup again."
                    "\n"
                    "Starred messages data will be imported, but if a message is present in"
                    " my current data set, **it will be overwritten** with the imported data."
                    "\n\n\n"
                    "Please react with \N{WHITE HEAVY CHECK MARK} to confirm that you wish to continue."
                ),
        ):
            await ctx.send(i18n("Import cancelled."), delete_after=30)
            return

        tmp = await ctx.send(
            i18n("Importing data... (this could take a while)"))
        try:
            async with ctx.typing():
                await v2_migration.import_data(self.bot, mongo_uri)
        except v2_migration.NoMotorError:
            await fmt(
                ctx,
                error(
                    i18n(
                        "Motor is not installed; cannot import v2 data.\n\n"
                        "Please do `{prefix}pipinstall motor` and re-attempt the import."
                    )),
            )
        else:
            await ctx.send(tick(i18n("Imported successfully.")))
        finally:
            await tmp.delete()
Пример #7
0
 async def cmd_starboard(self, ctx: Context):
     """Manage the server starboard"""
     if not ctx.invoked_subcommand:
         await ctx.send_help()
         await ctx.send(
             box(
                 i18n("Starboard channel: {channel}\n"
                      "Min stars: {min_stars}\n"
                      "Cached messages: {cache_len}").format(
                          channel=await ctx.starboard.resolve_starboard()
                          or i18n("No channel setup"),
                          min_stars=await ctx.starboard.min_stars(),
                          cache_len=len(ctx.starboard.message_cache),
                      )))
Пример #8
0
 async def starboard_channel(self,
                             ctx: Context,
                             channel: discord.TextChannel = None):
     """Set or clear the server's starboard channel"""
     if channel and channel.guild.id != ctx.guild.id:
         await ctx.send(error(i18n("That channel isn't in this server")))
         return
     await ctx.starboard.channel.set(getattr(channel, "id", None))
     if channel is None:
         await ctx.send(tick(i18n("Cleared the current starboard channel")))
     else:
         await ctx.send(
             tick(
                 i18n("Set the starboard channel to {}").format(
                     channel.mention)))
Пример #9
0
 async def starboard_minstars(self, ctx: Context, stars: int):
     """Set the amount of stars required for a message to be sent to this server's starboard"""
     if stars < 1:
         await ctx.send(
             warning(i18n("The amount of stars must be a non-zero number")))
         return
     if stars > len([x for x in ctx.guild.members if not x.bot]):
         await ctx.send(
             warning(
                 i18n(
                     "There aren't enough members in this server to reach"
                     " the given amount of stars. Maybe try a lower number?"
                 )))
         return
     await ctx.starboard.min_stars.set(stars)
     await ctx.tick()
Пример #10
0
    async def star_remove(self, ctx: Context, message: StarboardMessage):
        """Remove a previously added star"""
        if not message.has_starred(ctx.author):
            await fmt(
                ctx,
                warning(
                    i18n("You haven't starred that message\n\n"
                         "(you can use `{prefix}star` to star it)")),
                delete_after=15,
            )
            return

        try:
            await message.remove_star(ctx.author)
        except StarboardException:
            await ctx.send(warning(i18n("Failed to remove star")))
        else:
            await ctx.tick()
Пример #11
0
 def fmt_data(dct: dict, emoji: str = "\N{WHITE MEDIUM STAR}"):
     items = []
     keys = list(dct.keys())
     for x, y in dct.items():
         medal = medals[min(len(medals) - 1,
                            keys.index(x))].format(index(keys, x))
         items.append(
             f"{medal} {x.mention} \N{EM DASH} **{y:,}** {emoji}")
     return "\n".join(items) or inline(
         i18n("There's nothing here yet..."))
Пример #12
0
    async def star(self, ctx: Context, message: AutoStarboardMessage):
        """Star a message by it's ID"""
        if message.has_starred(ctx.author):
            await ctx.send(
                warning(
                    i18n("You've already starred that message\n\n"
                         "(you can use `{}star remove` to remove your star)").
                    format(ctx.prefix)),
                delete_after=15,
            )
            return

        try:
            await message.add_star(ctx.author)
        except SelfStarException:
            await ctx.send(warning(i18n("You cannot star your own messages")))
        except StarboardException:
            await ctx.send(warning(i18n("Failed to add star")))
        else:
            await ctx.tick()
Пример #13
0
 async def star_stats(self, ctx: Context, *, member: discord.Member = None):
     """Get your or a specified member's stats"""
     member = member or ctx.author
     data = {
         k: f"{v:,}"
         for k, v in (await stats.user_stats(member)).items()
     }
     await ctx.send(
         info(
             i18n(
                 "{member} has given **{given}** star(s), received **{received}**"
                 " star(s) with a max of **{max_received}** star(s) on a single message,"
                 " and have **{messages}** total message(s) on this server's starboard."
             ).format(member=bold(str(member)), **data)))
Пример #14
0
 async def stars_update(self, ctx: Context, message: StarboardMessage):
     """Forcefully update a starboard message"""
     await message.update_cached_message()
     await message.update_starboard_message()
     await ctx.send(tick(i18n("Message has been updated.")))