Exemple #1
0
def random():
    # type: () -> Color

    chilipepper = Color(0x9B1B30)
    tan = Color(0xBEAA3E)
    icedcoffee = Color(0xB18F6A)

    return choice([
        Color.teal(),
        Color.dark_teal(),
        Color.green(),
        Color.dark_green(),
        Color.blue(),
        Color.dark_blue(),
        Color.purple(),
        Color.dark_purple(),
        Color.magenta(),
        Color.dark_magenta(),
        Color.gold(),
        Color.dark_gold(),
        Color.orange(),
        Color.dark_orange(),
        Color.red(),
        Color.dark_red(),
        Color.lighter_grey(),
        Color.darker_grey(),
        Color.blurple(),
        tan,
        icedcoffee,
        chilipepper,
    ])
Exemple #2
0
 def __init__(self, client):
     self.client = client
     self.client_color = Color.red()
     self.color_dict = {
         1: [Color.teal(), 'teal'],
         2: [Color.dark_teal(), 'dark_teal'],
         3: [Color.green(), 'green'],
         4: [Color.dark_green(), 'dark_green'],
         5: [Color.blue(), 'blue'],
         6: [Color.dark_blue(), 'dark_blue'],
         7: [Color.purple(), 'purple'],
         8: [Color.dark_purple(), 'dark_purple'],
         9: [Color.magenta(), 'magenta'],
         10: [Color.dark_magenta(), 'dark_magenta'],
         11: [Color.gold(), 'gold'],
         12: [Color.dark_gold(), 'dark_gold'],
         13: [Color.orange(), 'orange'],
         14: [Color.dark_orange(), 'dark_orange'],
         15: [Color.red(), 'red'],
         16: [Color.dark_red(), 'dark_red'],
         17: [Color.lighter_grey(), 'lighter_grey'],
         18: [Color.dark_grey(), 'grey'],
         19: [Color.light_grey(), 'light_grey'],
         20: [Color.darker_grey(), 'darker_grey']
     }
Exemple #3
0
    async def begin(self, ctx):
        if self.tournament.status != Status.Opened:
            raise commands.BadArgument(
                "The tournament cannot be closed right now.")
        if len(self.tournament.get_participants()) < 1:
            raise commands.BadArgument(
                "There are no participants in the tournament.")

        no_ign = ""
        for player in self.tournament.get_participants():
            user = User.fetch_by_id(ctx, player.id)
            if user.ign is None: no_ign += f"**{player.name}**\n"

        if no_ign != "":
            raise commands.BadArgument(
                "Some players do not have an IGN set: \n" + no_ign)

        await ctx.send(
            f"{Emote.check} The tournament has been closed. Players can no longer join!"
        )
        self.tournament.status = Status.Closed
        Log("Tournament Closed",
            description=
            f"{ctx.author.mention} closed **{self.tournament.name}**.",
            color=Color.dark_orange())

        await self.tournament.msg.clear_reactions()
        embed = UpdatedEmbed(self.tournament)
        await self.tournament.msg.edit(embed=embed)
Exemple #4
0
def random():
    # type: () -> Color

    tan = Color(0xBEAA3E)

    return choice([
        Color.teal(),
        Color.dark_teal(),
        Color.green(),
        Color.dark_green(),
        Color.blue(),
        Color.dark_blue(),
        Color.purple(),
        Color.dark_purple(),
        Color.magenta(),
        Color.dark_magenta(),
        Color.gold(),
        Color.dark_gold(),
        Color.orange(),
        Color.dark_orange(),
        Color.red(),
        Color.dark_red(),
        Color.lighter_grey(),
        Color.darker_grey(),
        Color.blurple(),
        tan,
    ])
Exemple #5
0
def random():
    c = [
        Color.teal(),
        Color.dark_teal(),
        Color.green(),
        Color.dark_green(),
        Color.blue(),
        Color.dark_blue(),
        Color.purple(),
        Color.dark_purple(),
        Color.magenta(),
        Color.dark_magenta(),
        Color.gold(),
        Color.dark_gold(),
        Color.orange(),
        Color.dark_orange(),
        Color.red(),
        Color.dark_red(),
        Color.lighter_grey(),
        Color.darker_grey(),
        Color.blurple(),
        tan,
        icedcoffee,
        chilipepper
    ]
    return c[randint(0, len(c) - 1)]
 async def pypi(self, ctx: CommandContext, search, *, text=''):
     message: Message = ctx.message
     proc = Popen(['pip', 'search', search], stdout=PIPE, stderr=PIPE)
     if proc.wait() != 0:
         await message.edit(
             embed=Embed(
                 color=Color.red(),
                 description='Failed to search for `{search}` on pypi.'))
     stdout, _ = proc.communicate()
     stdout = stdout.decode(encoding='utf-8')
     lines: List[str] = stdout.split('\n')
     content = lines[0] + ' '.join(line.strip() for line in lines[1:] if line.startswith('    '))
     match = matcher.match(content)
     if not match:
         await message.edit(
             embed=Embed(
                 color=Color.dark_orange(),
                 description=f"Weird response format:```\n{stdout[:512]}```"))
     name = match.group("name")
     version = match.group("version")
     description = match.group("description")
     await message.edit(
         content=text,
         embed=Embed(
             title=name,
             url=f"https://pypi.org/project/{name}/",
             description=description
         ).set_footer(text=version))
Exemple #7
0
 async def random(self, ctx):
     reference = await get_random_verse()
     verses = await get_verse(reference)
     embed = Embed(title=verses["heading"],
                   description=verses["text"],
                   url=verses["url"],
                   color=Color.dark_orange())
     await ctx.channel.send(embed=embed)
Exemple #8
0
 async def bible_verse(self, ctx, *, reference):
     """returns a bible verse or passage from the format 'book chapter:verse(s)'"""
     verses = await get_verse(reference)
     embed = Embed(title=verses["heading"],
                   description=verses["text"],
                   url=verses["url"],
                   color=Color.dark_orange())
     await ctx.channel.send(embed=embed)
Exemple #9
0
    async def getinfo(self, ctx: Context, *, sentence: str) -> None:
        detection = await translator.detect(sentence)

        embed = Embed(title="Sentence Info", color=Color.dark_orange())
        embed.add_field(name="Language Code",
                        value=detection.lang,
                        inline=False)
        embed.add_field(name="Confidence",
                        value=detection.confidence,
                        inline=False)
        await ctx.send(embed=embed)
Exemple #10
0
    async def on_voice_state_update(self, member: Member, before: VoiceState,
                                    after: VoiceState) -> None:
        if before.afk != after.afk:
            embed = Embed(title="User went AFK"
                          if after.afk else "User is no longer AFK",
                          description=f"**User:** {member.mention}",
                          color=Color.blue())
        elif before.channel != after.channel:
            description_lines = [f"**User:** {member.mention}"]
            if before.channel:
                description_lines.append(
                    f"**Previous Channel:** {before.channel}")
            if after.channel:
                description_lines.append(f"**New Channel:** {after.channel}")

            embed = Embed(title="User changed channels"
                          if after.channel else "User left voice channel",
                          description="\n".join(description_lines),
                          color=Color.blue())
        elif before.deaf != after.deaf:
            embed = Embed(
                title="User deafened" if after.deaf else "User undeafened",
                description=f"**User:** {member.mention}",
                color=Color.dark_orange())
        elif before.mute != after.mute:
            embed = Embed(
                title="User silenced" if after.mute else "User unsilenced",
                description=f"**User:** {member.mention}",
                color=Color.dark_orange())
        # Client actions cal also happen here, i.e. self mute/deaf/stream/video
        # we don't need to log those, so we can return early in that case
        else:
            return

        embed.set_thumbnail(url=member.avatar_url)

        await self.send_log(member.guild, embed=embed)
Exemple #11
0
    async def delegate_ranks(self):
        all_delegates = self.bot.dpops_queries.delegates.get_delegates()
        print("getting delegates")
        if isinstance(all_delegates, list):
            for delegate in all_delegates:
                delegate["total_vote_count"] = int(
                    delegate["total_vote_count"])

            newlist = sorted(all_delegates,
                             key=itemgetter('total_vote_count'),
                             reverse=True)

            top_10 = newlist[0:10]

            stats_chn = self.bot.get_channel(id=self.bot.stats_channel_id)
            await top_delegates(destination=stats_chn,
                                c=Color.dark_orange(),
                                data=top_10)
        else:
            error = all_delegates["error"]
            print(error)
Exemple #12
0
    async def on_member_remove(self, member: Member) -> None:
        if self.bot.log_is_ignored(Event.member_remove,
                                   (member.guild.id, member.id)):
            return

        description = (
            f"**Mention:** {member.mention}\n"
            f"**Joined:** {time_elapsed(member.joined_at, max_units=3)}\n")
        roles = ", ".join(role.mention for role in member.roles[1:])
        description += f"**Roles:** {roles}\n" if roles else ''
        description += f"**Members:** Server is now at {member.guild.member_count} members."

        embed = Embed(
            title="Member left",
            description=description,
            color=Color.dark_orange(),
        )
        embed.timestamp = datetime.datetime.now()
        embed.set_thumbnail(url=member.avatar_url)
        embed.set_footer(text=f"Member ID: {member.id}")

        await self.send_log(member.guild, embed=embed)
Exemple #13
0
def new_event_em(text: str) -> Embed:
    return Embed(title=':dolls: Nowy event!',
                 color=Color.dark_orange()).add_field(
                     name='Temat', value=text).add_field(
                         name='\u200b',
                         value='Szczegóły zaraz zostaną podane.')
Exemple #14
0
    async def hangman(self, ctx: Context) -> None:
        def display_hangman(tries: int) -> str:
            stages = [
                # final state: head, torso, both arms, and both legs
                r"""```
--------
|      |
|      O
|     \|/
|      |
|     / \
-
                    ```""",
                # head, torso, both arms, and one leg
                r"""```
--------
|      |
|      O
|     \|/
|      |
|     /
-
                    ```""",
                # head, torso, and both arms
                r"""```
--------
|      |
|      O
|     \|/
|      |
|
-
                    ```""",
                # head, torso, and one arm
                r"""```
--------
|      |
|      O
|     \|
|      |
|
-
                    ```""",
                # head and torso
                r"""```
--------
|      |
|      O
|      |
|      |
|
-
                    ```""",
                # head
                r"""```
--------
|      |
|      O
|
|
|
-
                    ```""",
                # initial empty state
                r"""```
--------
|      |
|
|
|
|
-
                    ```""",
            ]
            return stages[tries]

        def check(message: Message) -> bool:
            return message.author == ctx.author and message.channel == ctx.channel

        word = random.choice(word_list).upper()
        word_completion = "#" * len(word)
        guessed = False
        guessed_letters = []
        guessed_words = []
        tries = 6

        await ctx.send(
            embed=Embed(title="Let's play Hangman!", color=Color.dark_green()))
        embed = Embed(title="Hangman Status", color=Color.dark_teal())
        embed.add_field(name="**❯❯ Hang Status**",
                        value=display_hangman(tries),
                        inline=False)
        embed.add_field(name="**❯❯ Word Completion Status**",
                        value=f"**{word_completion}**",
                        inline=False)
        embed.set_footer(text="Powered By HotWired.")
        await ctx.send(embed=embed)

        while not guessed and tries > 0:
            await ctx.send(
                embed=Embed(description="Please guess a letter or word: ",
                            color=Color.gold()))
            input = await self.bot.wait_for("message", check=check)
            guess = input.content.upper()

            if len(guess) == 1 and guess.isalpha():
                if guess in guessed_letters:
                    await ctx.send(embed=Embed(
                        description=f"You already guessed the letter {guess}",
                        color=Color.red()))
                elif guess not in word:
                    await ctx.send(
                        embed=Embed(description=f"{guess} is not in the word.",
                                    color=Color.dark_magenta()))
                    tries -= 1
                    guessed_letters.append(guess)
                else:
                    await ctx.send(embed=Embed(
                        description=f"Good job, {guess} is in the word!",
                        color=Color.dark_green()))
                    guessed_letters.append(guess)
                    word_as_list = list(word_completion)
                    indices = [
                        i for i, letter in enumerate(word) if letter == guess
                    ]

                    for index in indices:
                        word_as_list[index] = guess
                    word_completion = "".join(word_as_list)
                    if "#" not in word_completion:
                        guessed = True

            elif len(guess) == len(word) and guess.isalpha():
                if guess in guessed_words:
                    await ctx.send(embed=Embed(
                        description=f"You already guessed the word {guess}",
                        color=Color.red()))
                elif guess != word:
                    await ctx.send(
                        embed=Embed(description=f"{guess} is not the word.",
                                    color=Color.dark_orange()))
                    tries -= 1
                    guessed_words.append(guess)
                else:
                    guessed = True
                    word_completion = word
            else:
                await ctx.send(embed=Embed(description="Not a valid guess.",
                                           color=Color.blurple()))

            embed = Embed(title="Hangman Status", color=Color.dark_teal())
            embed.add_field(name="**❯❯ Hang Status**",
                            value=display_hangman(tries),
                            inline=False)
            embed.add_field(name="**❯❯ Word Completion Status**",
                            value=f"**{word_completion}**",
                            inline=False)
            embed.set_footer(text="Powered By HotWired.")
            await ctx.send(embed=embed)

        if guessed:
            await ctx.send(embed=Embed(
                description=
                "Congrats, you guessed the word! You win! :partying_face: ",
                color=Color.dark_green()))
        else:
            await ctx.send(embed=Embed(
                description=
                f"Sorry, you ran out of tries. The word was {word}. Maybe next time! :frowning: ",
                color=Color.red()))
Exemple #15
0
    async def on_raw_message_edit(self,
                                  payload: RawMessageUpdateEvent) -> None:
        """
        Send an embed whenever uncached message got edited, we do not have the
        previous contents of this message, so we can only send the current (edited)
        content, and the fact that it was actually edited.

        This listener trigers whenever a message is edited, this includes the messages
        that are cached and trigger `on_message_edit` directly, which means we have to
        ignore these.

        Disocrd's API also triggers this listener whenever an embed is sent. This is quite
        unexpected behavior for this event, and we should ignore it as it isn't an actual
        message edit event.

        In case neither of these cases are true, we may log the embed (with some further
        checks which are also present in `on_message_edit`, such as DM check).
        """
        # Try to fetch the message before it may get removed, if we don't manage that
        # we can ignore this event
        try:
            channel = self.bot.get_channel(int(payload.channel_id))
            message = await channel.fetch_message(payload.message_id)
        except NotFound:
            return

        # As described in docstring, this even also triggers on embed sending, if that's
        # the case, we can simply ignore that
        if "embeds" in payload.data and len(payload.data["embeds"]) > 0:
            return

        # Sleep for a while to leave enough time for normal event to execute, which will add this
        # channel into the handled cached set, to avoid double logging
        await asyncio.sleep(1)
        if (message.guild.id, message.id) in self._handled_cached:
            return

        if self.is_ignored(message, Event.message_edit):
            return

        response = (
            f"**Author:** {message.author.mention}\n"
            f"**Channel:** {message.channel.mention}\n"
            f"**Before:** This message is an uncached message, content can't be displayed"
        )

        if len(message.clean_content) > MAX_LOGGED_MESSAGE_SIZE:
            url = await upload_text(
                self.bot.http_session,
                message.content,
                file_name="message.md",
                paste_name="Automatic message upload.",
                paste_description=
                "This paste was automatically generated from edited discrod message."
            )
            if url:
                response += f"\n**After:** Message too long, check [message upload]({url})"
            else:
                response += "\n**After:** Message too long (WARNING: Automatic upload failed"
        else:
            response += f"\n**After:** {message.content}"

        response += f"\n[Jump url]({message.jump_url})"

        embed = Embed(title="Uncached message edited",
                      description=response,
                      color=Color.dark_orange())
        embed.timestamp = datetime.datetime.utcnow()
        embed.set_footer(text=f"Message ID: {message.id}\n")

        await self.send_log(message.guild, embed=embed)
    async def doctor(self, ctx: 'CustomContext'):
        waiting_message = await ctx.send(
            "<a:loading:393852367751086090> Please wait, running `doctor` checks"
        )  # <a:loading:393852367751086090> is a loading emoji
        t_1 = time.perf_counter()
        await ctx.trigger_typing(
        )  # tell Discord that the bot is "typing", which is a very simple request
        t_2 = time.perf_counter()
        time_delta = round(
            (t_2 - t_1) * 1000)  # calculate the time needed to trigger typing
        del self.bot.settings.settings_cache[ctx.guild]
        messages = {}
        message = []
        # Permissions
        wanted_permissions = discord.permissions.Permissions.none()
        wanted_permissions.update(kick_members=True,
                                  ban_members=True,
                                  read_messages=True,
                                  send_messages=True,
                                  manage_messages=True,
                                  embed_links=True,
                                  attach_files=True,
                                  read_message_history=True,
                                  external_emojis=True,
                                  change_nickname=True,
                                  add_reactions=True)

        message.append("```diff")

        errored_in = []
        for channel in ctx.guild.channels:
            my_permissions = ctx.message.guild.me.permissions_in(channel)
            if not my_permissions.is_strict_superset(wanted_permissions):
                errored_in.append(channel)

        if len(errored_in) == 0:
            message.append("+ Everything checks out! No permissions problems")
        else:
            message.append(
                f"= The following channels have permissions problems, use the {ctx.prefix}bot_permissions_check command in them to see what's missing"
            )
            message.extend(["- #" + channel.name for channel in errored_in])

        top_role = ctx.message.guild.me.top_role

        # Position isn't guaranteed to not have gaps
        # Discord pls

        message.append(
            f"= Bot top role is at position {top_role.position}/{ctx.guild.roles[-1].position} [higher is better] - "
            f"Any user that have a role equal or higher to <{top_role.name}> can't be kicked/banned"
        )
        message.append("```")

        messages["Bot Permissions"] = discord.Embed(
            description="\n".join(message),
            color=Color.green() if len(errored_in) == 0 else Color.red())

        # Settings

        message = [
            "If a setting is enabled, the line will be in green. If it's disabled, the line will be red ```diff"
        ]

        settings_char = {True: "+ ", False: "- "}

        guild = ctx.guild
        settings_to_check = {
            "automod_enable": "Automod",
            "autotrigger_enable":
            "AutoTriggers (special automod rules to fight a specific kind of spam message — Require automod to be enabled too)",
            "thresholds_enable":
            "Thresholds (automatic action when a users received X strikes)",
            "logs_enable": "Logs",
            "autoinspect_enable":
            "AutoInspect (Verification of new members that join your server)",
            "rolepersist_enable": "RolePersist (VIP)"
        }

        for setting, display_name in settings_to_check.items():
            setting_enabled = await self.bot.settings.get(guild, setting)

            message.append(settings_char[setting_enabled] + display_name)

        message.append(
            f"```\n To edit your settings, and see more of them, use the `{ctx.prefix}urls` command to see your server webpage, "
            "then edit settings there (You may need to login first)\n")

        messages["Bot Settings"] = discord.Embed(
            description="\n".join(message), color=Color.dark_green())

        # Logs

        logs_enabled = await self.bot.settings.get(guild, "logs_enable")

        if logs_enabled:
            logs = {
                "logs_moderation_channel_id": "Moderation acts",
                "logs_joins_channel_id": "Users joining/leaving",
                "logs_rolepersist_channel_id": "Roles persist",
                "logs_member_edits_channel_id": "Users edits",
                "logs_edits_channel_id": "Message edits",
                "logs_delete_channel_id": "Message deletions",
                "logs_autoinspect_channel_id": "AutoInspect logs"
            }
            everything_good = True
            message = [
                "Logs are globally enabled on this server. The following specific logs are activated and configured: \n```diff"
            ]
            for setting, display_name in logs.items():
                try:
                    setting_value = int(await
                                        self.bot.settings.get(guild, setting))
                except ValueError:
                    message.append(
                        f"= {display_name} log (enabled but there is text in the ID field, I can't parse it)"
                    )
                else:
                    if setting_value == 0:
                        message.append(f"- {display_name} log")
                        everything_good = False
                    else:
                        channel_logged = discord.utils.get(guild.channels,
                                                           id=setting_value)
                        if channel_logged:
                            message.append(
                                f"+ {display_name} log (in #{channel_logged.name})"
                            )
                        else:
                            message.append(
                                f"= {display_name} log (enabled but couldn't find the channel that goes by ID {setting_value})"
                            )
                            everything_good = False

            message.append("```")

            messages["Logs"] = discord.Embed(
                description="\n".join(message),
                color=Color.green()
                if everything_good else Color.dark_orange())

        message = []

        # Staff

        l = await get_level(ctx, ctx.author)

        levels_names = {
            10: "Bot owner",
            9: "Reserved for future use",
            8: "Bot global-moderators",
            7: "Reserved for future use",
            6: "Reserved for future use",
            5: "Server owner",
            4: "Server administrator",
            3: "Server moderator",
            2: "Server trusted user",
            1: "Member",
            0: "Bot-banned"
        }

        message.append(
            f"Your current access level is `{l}` ({levels_names[l]}).")

        embed = discord.Embed(
            description="\n".join(message),
            color=Color.green() if l >= 3 else Color.orange())

        ids = await self.bot.settings.get(guild, 'permissions_admins')
        if len(ids) > 0:

            message = [
                "The following user(s) have been granted server **admin** (4) here "
                "(This is not a complete list since it does **not** include people with the `administrator` permission) \n```diff"
            ]
            for admin_id in ids:
                admin = discord.utils.get(guild.members, id=admin_id)
                if admin:
                    message.append(
                        f"+ {admin.name}#{admin.discriminator} ({admin_id})")
                else:
                    role = discord.utils.get(guild.roles, id=admin_id)
                    if role:
                        message.append(f"+ (Role) {role.name} ({admin_id})")
                    else:
                        message.append(f"- User left the server ({admin_id})")
            message.append("```")

            embed.add_field(name="Server administrators",
                            value="\n".join(message),
                            inline=False)

        ids = await self.bot.settings.get(guild, 'permissions_moderators')
        if len(ids) > 0:
            message = [
                "The following user(s) have been granted server **moderator** (3) here "
                "(This is not a complete list since it does **not** include people with the `ban_members` permission) \n```diff"
            ]
            for mod_id in ids:
                mod = discord.utils.get(guild.members, id=mod_id)
                if mod:
                    message.append(
                        f"+ {mod.name}#{mod.discriminator} ({mod_id})")
                else:
                    role = discord.utils.get(guild.roles, id=mod_id)
                    if role:
                        message.append(f"+ (Role) {role.name} ({mod_id})")
                    else:
                        message.append(f"- User left the server ({mod_id})")
            message.append("```")

            embed.add_field(name="Server moderators",
                            value="\n".join(message),
                            inline=False)

        ids = await self.bot.settings.get(guild, 'permissions_trusted')
        if len(ids) > 0:
            message = [
                "The following user(s) have been granted server **trusted** (2) here "
                "(This is not a complete list since it does **not** include people with the `kick_members` permission) \n```diff"
            ]
            for trusted_id in ids:
                trusted = discord.utils.get(guild.members, id=trusted_id)
                if trusted:
                    message.append(
                        f"+ {trusted.name}#{trusted.discriminator} ({trusted_id})"
                    )
                else:
                    role = discord.utils.get(guild.roles, id=trusted_id)
                    if role:
                        message.append(f"+ (Role) {role.name} ({trusted_id})")
                    else:
                        message.append(
                            f"- User left the server ({trusted_id})")
            message.append("```")

            embed.add_field(name="Trusted users",
                            value="\n".join(message),
                            inline=False)

        messages["Staff"] = embed

        embed = discord.Embed(
            description=
            "This is stuff you can't do much about it, but just wait for the problems to go away if there are some. \n"
            "You might want to check https://status.discordapp.com for more information",
            color=Color.green() if time_delta < 200 else Color.red())

        embed.add_field(name="Bot ping", value=f"{time_delta}ms")
        embed.add_field(name="Bot latency",
                        value=f"{round(self.bot.latency * 1000)}ms")

        messages["Connexion"] = embed

        ok = True

        try:
            widget = await guild.widget()
        except discord.HTTPException:
            widget = None
            ok = False

        invite_code = await self.bot.settings.get(guild, 'invite_code')

        invite_error = False

        if not invite_code:
            ok = False
            invite_error = "No invite is set in your server settings. Please add it on the dashboard!"
        else:
            try:
                await self.bot.fetch_invite(invite_code)
            except discord.NotFound:
                invite_error = "The invite code was provided but is not working correctly. Please check that the invite is valid."
                ok = False
            except discord.HTTPException:
                invite_error = "There was an error reading your invite code. Please check that the invite is valid."
                ok = False

        embed = discord.Embed(
            description="Checking discord server settings since 1990",
            color=Color.green() if ok else Color.red())

        embed.add_field(
            name="Widget enabled",
            value=f"Yes" if widget else
            "You should enable the server widget for it to show up properly on your server webpage."
        )
        embed.add_field(name="Invite provided",
                        value=f"Yes" if not invite_error else invite_error)

        messages["Server Settings"] = embed

        # Send everything
        for message_title, embed in messages.items():
            embed.title = message_title
            await ctx.send(embed=embed)
            # await ctx.trigger_typing()
            await asyncio.sleep(.8)

        await waiting_message.delete()
Exemple #17
0
import datetime
import typing
import pytz

import discord
from discord import Color

from cogs.misc import LikeUser, FakeMember

colours = {
    'unban': Color.green(),
    'unmute': Color.dark_green(),
    'note': Color.light_grey(),
    'warn': Color.orange(),
    'mute': Color.dark_purple(),
    'kick': Color.dark_orange(),
    'softban': Color.red(),
    'ban': Color.dark_red()
}


async def ban(victim: discord.Member, reason: str = None):
    await victim.guild.ban(victim, reason=reason)


async def softban(victim: discord.Member, reason: str = None):
    await victim.guild.ban(victim, reason=reason)
    await victim.guild.unban(victim, reason=reason)


async def kick(victim: discord.Member, reason: str = None):
Exemple #18
0
    async def on_message_edit(self, before: Message, after: Message) -> None:
        """
        Send a log message whenever any sent message is edited.

        This is useful for moderation purposes, because users often try to hide what
        they send, to avoid getting caught breaking some rules, logging the content of
        these messages will prevent that.

        Messages can sometimes get quite long, and we don't want to clutter the log with them,
        if this is the case, we upload this message to a paste service and only provide a link.
        """
        # Add this message to set of ignored messages for raw events, these trigger even if
        # the message was cached, and to prevent double logging, we need to ignore them
        self._handled_cached.add((after.guild.id, after.id))

        if self.is_ignored(message=after, event=Event.message_edit):
            return

        response = (f"**Author:** {after.author.mention}\n"
                    f"**Channel:** {after.channel.mention}")
        if before.edited_at:
            response += f"\n**Last edited:** {time_elapsed(before.edited_at, after.edited_at, max_units=3)}"
        else:
            response += f"\n**Initially created:** {time_elapsed(before.created_at, after.edited_at, max_units=3)}"

        # Limit log embed to avoid huge messages cluttering the log,
        # if message is longer, upload it instead.
        if len(before.clean_content +
               after.clean_content) > MAX_LOGGED_MESSAGE_SIZE:
            # NOTE; Text uploading might be happening too often, and might have to be removed
            # in the future
            payload = [
                {
                    "name": "before",
                    "content": {
                        "format": "text",
                        "value": before.content
                    }
                },
                {
                    "name": "after",
                    "content": {
                        "format": "text",
                        "value": after.content
                    }
                },
            ]

            url = await upload_files(
                self.bot.http_session,
                payload,
                paste_name="Automatic message upload.",
                paste_description=
                "This paste was automatically generated from edited discord message."
            )
            if url:
                response += f"\n**Changes:** Message too long, check [message upload]({url})"
            else:
                response += "\n**Changes:** Message too long (WARNING: Automatic upload failed)"
        else:
            response += f"\n**Before:** {before.content}"
            response += f"\n**After:** {after.content}"

        response += f"\n[Jump link]({after.jump_url})"

        embed = Embed(title="Message edited",
                      description=response,
                      color=Color.dark_orange())
        embed.timestamp = after.edited_at
        embed.set_footer(text=f"Message ID: {after.id}")

        await self.send_log(after.guild, embed=embed)
    async def fetch_track(self):
        """Task for fetching warzone matches of tracked users."""
        logging.info("Starting warzone tracking...")
        tracked = session.query(wz_model).filter_by(track=True).all()

        if not len(tracked):
            return

        embed_color = [
            Color.gold(),
            Color.light_grey(),
            Color.dark_orange(),
            Color.dark_red()
        ]

        matches = dict()

        async with aiohttp.ClientSession() as aiosession:
            try:
                await aiosession.get("https://profile.callofduty.com/cod/login"
                                     )

                cookies = aiosession.cookie_jar.filter_cookies(
                    "https://callofduty.com")

                params = {
                    "username": getenv("COD_USERNAME"),
                    "password": getenv("COD_PASSWORD"),
                    "remember_me": "true",
                    "_csrf": cookies["XSRF-TOKEN"].value,
                }

                await aiosession.post(
                    "https://profile.callofduty.com/do_login?new_SiteId=cod",
                    params=params,
                    allow_redirects=False)

            except Exception as e:
                logging.error("Could not acquire session for warzone tracking")
                return

            for t in tracked:
                try:
                    battletag = requests.utils.quote(t.battletag)

                    url = f"https://my.callofduty.com/api/papi-client/crm/cod/v2/title/mw/platform/battle/gamer/{battletag}/matches/wz/start/0/end/0/details?limit=1"

                    async with aiosession.get(url) as resp:
                        response = await resp.json()

                    player_match = response["data"]["matches"][0]
                    player_match["channel_id"] = t.channel_id

                    now = int(datetime.utcnow().strftime("%s"))

                    if t.last_match == player_match[
                            "matchID"] or now - player_match[
                                "utcEndSeconds"] > 30 * 60:
                        continue

                    matches.setdefault(player_match["matchID"],
                                       dict()).setdefault(
                                           player_match["player"]["team"],
                                           list()).append(player_match)

                    t.last_match = player_match["matchID"]

                except Exception as e:
                    logging.error(
                        f"Could not retrieve warzone history for {t.battletag}",
                        exc_info=e)

        for match in matches.values():
            for team in match.values():
                p0 = team[0]

                channel = self.bot.get_channel(p0["channel_id"])

                ordinal = lambda n: f'{n}{"tsnrhtdd"[(n//10%10!=1)*(n%10<4)*n%10::4]}'

                placement = int(p0["playerStats"]["teamPlacement"])
                placement_color = placement - 1 if placement < 4 else -1

                embed = Embed(
                    title=
                    f"{p0['player']['username']}'s team finished in __{ordinal(placement)}__ against {p0['teamCount']} teams.",
                    color=embed_color[placement_color],
                    timestamp=datetime.fromtimestamp(p0["utcStartSeconds"]),
                )

                embed.add_field(
                    name="Match duration",
                    value=f"{int(p0['duration'] // 60000)} minutes",
                    inline=True)
                embed.add_field(
                    name="Team survived",
                    value=
                    f"{int(p0['playerStats']['teamSurvivalTime']) // 60000} minutes",
                    inline=True,
                )
                embed.add_field(name=chr(173), value=chr(173),
                                inline=True)  # field skip

                for player in team:
                    stats = f"""**KDA:** {round(player["playerStats"]["kdRatio"], 2)}
                    **Kills:** {int(player["playerStats"]["kills"])} **Deaths:** {int(player["playerStats"]["deaths"])}
                    **Damage:** {int(player["playerStats"]["damageDone"])}
                    """
                    embed.add_field(name=player["player"]["username"],
                                    value=inspect.cleandoc(stats),
                                    inline=True)

                await channel.send(embed=embed)
        session.commit()
        logging.info("Warzone tracking finished.")