Exemple #1
0
def dice_em(result: list, sep: str = ', ') -> Embed:
    sep = f'**{sep}**'
    if len(result) == 1:
        return Embed(title=':game_die: Rzut kością',
                     description=f'Wynik: **{result[0]}**.',
                     color=Color.dark_red())
    else:
        return Embed(title=':game_die: Rzut kośćmi',
                     description=f'Wyniki: **{sep.join(result)}**.',
                     color=Color.dark_red())
Exemple #2
0
def black_jack_embed(user: User,
                     player,
                     outcome: str = None,
                     hidden: bool = True) -> Embed:
    """
    Creates embed based on set of constraints for blackjack
    :param user:  discord.User
    :param player: player object for blackjack
    :param outcome: blackjack game outcome
    :param hidden: dealer card value
    :return: discord.Embed
    """
    embed = black_jack_template(user, player, "", Color.gold())
    embed.add_field(name="Dealer hand",
                    value=player.game.get_emote_string(hidden=hidden))
    if outcome == "win":
        embed.colour = Color.dark_green()
        embed.description = "**Outcome:** You won!"
    elif outcome == "lose":
        embed.colour = Color.dark_red()
        embed.description = "**Outcome:** You lost!"
    elif outcome == "tie":
        embed.colour = Color.dark_grey()
        embed.description = "**Outcome:** It's a tie!"
    return embed
Exemple #3
0
def goodbye(message: str) -> Embed:
    """
    Constructs goodbye embed with fixed title 'Goodbye' and red color.
    :param message: embed description
    :return: Embed object
    """
    return simple_embed(message, "Goodbye", color=Color.dark_red())
Exemple #4
0
 async def play(self) -> None:
     """Start the main game loop."""
     await self.send_status()
     HangmanGame.players[self.guild][self.channel].append(self.player)
     while self.player in HangmanGame.players[self.guild][self.channel]:
         guess = await self.get_guess()
         guess_status = await self.apply_guess(guess)
         if guess_status is False:
             embed = Embed(
                 title="Game aborted",
                 description="You aborted the game.",
                 color=Color.dark_red()
             )
             await self.channel.send(embed=embed)
             return
         await self.send_status(guess, guess_status)
         if state := self.is_finished():
             if state == 1:
                 embed = Embed(
                     title="You won",
                     description=":tada: You won the game!",
                     color=Color.green()
                 )
                 await self.channel.send(embed=embed)
             elif state == 2:
                 embed = Embed(
                     title="You lost",
                     description="You ran out of guesses.",
                     color=Color.green()
                 )
                 await self.channel.send(embed=embed)
             return
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)]
Exemple #6
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 #7
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 #8
0
    async def on_member_ban(self, guild: Guild, user: t.Union[User,
                                                              Member]) -> None:
        if self.bot.log_is_ignored(Event.member_ban, (guild.id, user.id)):
            return

        unban_log_entry = await last_audit_log_with_fail_embed(
            guild,
            actions=[AuditLogAction.ban],
            send_callback=partial(self.send_log, guild),
            target=user)
        if unban_log_entry is None:
            return

        embed = Embed(title="User banned",
                      description=textwrap.dedent(f"""
                **User:** {user.mention}
                **Author:** {unban_log_entry.user.mention}
                **Reason:** {unban_log_entry.reason if unban_log_entry.reason else "N/A"}
                """),
                      color=Color.dark_red())
        embed.set_thumbnail(url=user.avatar_url)
        embed.set_footer(text=f"User ID: {user.id}")
        embed.timestamp = unban_log_entry.created_at

        await self.send_log(guild, embed=embed)
Exemple #9
0
    async def send_wordle_embed(self, ctx, wordle, guesses, header_str):
        """
    Generates the wordle image, host it on imgur and send the it as an interaction response
    --
    input:
      ctx: interactions.CommandContext
      wordle: wordle.Wordle
      guesses: List[str]
      header_str: str
    """
        img_path = "wordle_tmp.png"
        wordle.generate_image(guesses, img_path)
        link = utils.upload_image_to_imgur(img_path)
        os.remove(img_path)

        color = Color.gold()
        if len(guesses) > 0 and guesses[-1] == wordle.solution:
            color = Color.dark_green()
        elif len(guesses
                 ) == wordle.nb_trials and guesses[-1] != wordle.solution:
            color = Color.dark_red()

        embed = Embed(title="Wordle",
                      description=header_str,
                      color=color.value,
                      image=EmbedImageStruct(url=link)._json)
        await ctx.send(embeds=embed, ephemeral=True)
Exemple #10
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 #11
0
 async def send_status(self, guess: t.Optional[str] = None, guess_status: t.Optional[t.Literal[0, 1, 2, 3]] = None) -> None:
     """Get current game status as embed."""
     embed = Embed(
         title="Hangman",
         color=Color.dark_green(),
     )
     embed.add_field(
         name="**❯❯ Status**",
         value=f"```\n{HangmanGame.stages[self.tries]}```",
         inline=False
     )
     embed.add_field(
         name="**❯❯ Word**",
         value=f"**{self.display_word}**",
         inline=False
     )
     if guess:
         description = f"Letter {guess}"
         if guess_status == 0:
             description += " isn't in the word"
             color = Color.red()
         elif guess_status == 1:
             description += " is in the word"
             color = Color.green()
         elif guess_status == 2:
             description += " isn't valid"
             color = Color.dark_red()
         elif guess_status == 3:
             description += " was already guessed."
             color = Color.dark_red()
         guess_embed = Embed(
             description=description,
             color=color
         )
         await self.channel.send(embed=guess_embed, delete_after=5)
     embed.set_footer(
         text=f"{config.COMMAND_PREFIX}hangexit to exit the game! | Powered By HotWired."
     )
     if hasattr(self, "message"):
         await self.message.edit(embed=embed)
     else:
         self.message = await self.channel.send(embed=embed)
Exemple #12
0
 def __init__(self, webhook):
     self.webhook = webhook
     self.level_color = {
         "INFO": Color.light_grey(),
         "WARNING": Color.gold(),
         "ERROR": Color.dark_red(),
         "CRITICAL": Color.red(),
         "DEBUG": Color.dark_green(),
         "NOTSET": Color.dark_grey(),
     }
     super(DiscordHandler, self).__init__()
Exemple #13
0
    async def treset(self, ctx):
        if self.tournament.status in (2, 3, 4):
            raise commands.BadArgument(
                f"The tournament is ongoing and cannot be reset. Please try to use `;cancel` instead."
            )

        self.tournament = Tournament()
        await ctx.send(
            f"{Emote.check} The tournament has succesfully been reset.")

        Log("Tournament Reset",
            description=
            f"{ctx.author.mention} has reset the tournament to default values.",
            color=Color.dark_red())
Exemple #14
0
 async def ninerr(self, ctx, errcode: str):
     """Parses Nintendo 3DS error codes."""
     err = errcode[0:8]
     if re.match('[0-1][0-9][0-9]\-[0-9][0-9][0-9][0-9]', err) == None:
         await self.bot.say(
             "Wrong format. Error codes use the format `###-####`.")
         return
     embed = discord.Embed(
         title=err + (": Nintendo 3DS" if err[0] == "0" else ": Wii U"))
     embed.url = "http://www.nintendo.com/consumer/wfc/en_na/ds/results.jsp?error_code={}&system={}&locale=en_US".format(
         err, "3DS" if err[0] == "0" else "Wiiu")
     if err not in self.errcodes:
         embed.description = "I don't know this one! Click the error code for details on Nintendo Support.\n\nIf you keep getting this issue and Nintendo Support does not help, or know how to fix it, you should report relevant details to <@78465448093417472> so it can be added to the bot."
     else:
         embed.description = self.errcodes[err]
         embed.color = (Color.dark_red() if err[0] == "0" else Color.blue())
     await self.bot.say("", embed=embed)
Exemple #15
0
    async def on_message_delete(self, msg):
        if msg.author.bot:
            return

        if isinstance(msg.channel, DMChannel):
            return  # ignore, this is handled in modmail for dm's

        user = msg.author

        if msg.content is None or msg.content == "":
            return

        emb = Embed(title="Message Deleted", color=Color.dark_red())
        emb.add_field(name="Message:", value=msg.content, inline=True)
        emb.add_field(name="User:"******"{user.name}#{user.discriminator}\n<{user.id}>")
        emb.set_thumbnail(url=user.avatar_url)
        await self.bot.msglogs_channel.send("", embed=emb)
Exemple #16
0
def bot_info_em(bot: Bot) -> Embed:
    return Embed(
        title=bot.user.name,
        description='\u200b',
        color=Color.dark_red()
    ).add_field(
        name='Właściciel',
        value=bot.get_user(bot.owner_id)
    ).add_field(
        name='Wersja',
        value=bot.version or 'Nieznana'
    ).add_field(
        name='Kod źródłowy',
        value='GitHub: <https://github.com/AnonymousX86/poland-bot>',
        inline=False
    ).set_thumbnail(
        url=bot.user.avatar_url
    )
Exemple #17
0
 async def on_member_remove(self, member):
     if member.guild.id == 497097726400528394:
         em = Embed(
             title=f"{member.name} left the guild.",
             description=
             f":wave:  -  Sorry to see you go {member.name}#{member.discriminator}, return again soon!",
             timestamp=datetime.utcnow(),
             color=Color.dark_red(),
         )
         em.set_author(
             name="Aurora",
             icon_url=
             "https://cdn.discordapp.com/icons/497097726400528394/00453191715921c03ca41dbe8b1a0569.png?size=128",
         )
         em.set_image(
             url=
             "https://cdn.discordapp.com/attachments/663351785293086720/718843903561695282/Aurora_Farewell_Banner.jpg"
         )
         await member.guild.get_channel(718798993852727317).send(embed=em)
Exemple #18
0
    async def on_raw_message_delete(self,
                                    payload: RawMessageDeleteEvent) -> None:
        """
        Send an embed whenever uncached message got deleted, we do not have the
        previous contents of this message, so we can only send the the fact that
        it was actually deleted, and channel it happened in.

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

        In case this wasn't the case, we may log the embed (with some further
        checks which are also present in `on_message_edit`, such as DM check).
        """
        guild = self.bot.get_guild(payload.guild_id)

        if not guild:
            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 (payload.guild_id, payload.message_id) in self._handled_cached:
            return

        if self.bot.log_is_ignored(Event.message_delete,
                                   (guild.id, payload.message_id)):
            return

        channel = self.bot.get_channel(payload.channel_id)
        embed = Embed(title="Uncached message deleted",
                      description=textwrap.dedent(f"""
                **Channel:** {channel.mention if channel else 'Unable to get channel'}
                **Content:** This message is an uncached message, content can't be displayed
                """),
                      color=Color.dark_red())
        embed.timestamp = datetime.datetime.utcnow()
        embed.set_footer(text=f"Message ID: {payload.message_id}")

        await self.send_log(guild, embed=embed)
Exemple #19
0
async def on_command_error(ctx, error):
    """Triggered when a command send an error

    Decorators:
        BOT.event

    Arguments:
        ctx {Context} -- Context of the message
        error {Exception} -- Discord error
    """
    content = dict(colour=Color.dark_red())
    critical(ctx.command, error)
    field = dict(name="Error", inline=False)
    if isinstance(error, errors.NoPrivateMessage):
        field["value"] = ":warning: This command cannot be used in private messages."
    elif isinstance(error, errors.CommandOnCooldown):
        field["value"] = ":stopwatch: This command is on cooldown, \
retry after {:.2f} seconds".format(error.retry_after)
    elif isinstance(error, errors.DisabledCommand):
        field["value"] = "This command is disabled and cannot be used."
    elif isinstance(error, errors.CommandNotFound):
        field["value"] = ":grey_question: Unknown command. \
Use `{}help` to get commands".format(ctx.prefix)
    elif isinstance(error, errors.MissingPermissions):
        field["value"] = ":no_entry_sign: {}".format(error.message)
    elif isinstance(error, errors.MissingRequiredArgument):
        field["value"] = "An argument is missing"
    elif isinstance(error, errors.CheckFailure):
        field["value"] = ":no_entry_sign: At least 1 check has failed"
    elif isinstance(error, errors.NotOwner):
        field["value"] = ":no_entry_sign: You are not the owner of the bot"
    elif isinstance(error, errors.CommandInvokeError):
        field["value"] = ":stop_sign: The command {} has thrown an error.".format(ctx.command)
        critical('In {0.command.qualified_name}:'.format(ctx))
        print_tb(error.original.__traceback__)
        critical('{0.__class__.__name__}: {0}'.format(error.original))
    content["fields"] = field
    message = create_embed(content)
    await ctx.author.send(embed=message)
Exemple #20
0
def create_embed(lang="de"):
    embed = Embed(title=f'Willkommen!',
                  color=Color.dark_red(),
                  url="https://github.com/bundestagsBot/bundestagsBot")
    embed.timestamp = datetime.utcnow()
    try:
        if lang == "de":
            embed.description = welcome_de.format(
                cfg.options["channel_ids"]["roles"][0],
                cfg.options["channel_ids"]["welcome"][0],
                cfg.options["channel_ids"]["bot"][0],
                cfg.options["channel_ids"]["suggestions"][0])
    except KeyError:
        SHL.output(
            f"{red}Could not send full Embed. Please check if you applied all needed configuration.{white}"
        )
        embed.description = "__**Welcome**__"
    except IndexError:
        SHL.output(
            f"{red}Could not send full Embed. Please check if you applied all needed configuration.{white}"
        )
        embed.description = "__**Welcome**__"
    return embed
Exemple #21
0
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):
    await victim.guild.kick(victim, reason=reason)
Exemple #22
0
    async def on_message_delete(self, message: Message) -> None:
        """
        Send a log message whenever any sent message is removed.

        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((message.guild.id, message.id))

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

        # Add message to ignore list, to prevent raw event on executing
        self.bot.log_ignore(Event.message_delete,
                            (message.guild.id, message.id))

        response = (
            f"**Author:** {message.author.mention}\n"
            f"**Channel:** {message.channel.mention}\n"
            f"**Initially created: ** {time_elapsed(message.created_at, max_units=3)}"
        )

        if message.attachments:
            readable_attachments = ', '.join(
                attachment.filename for attachment in message.attachments)
            response += f"\n**Attachment file-name{'s' if len(message.attachments) > 1 else ''}:** {readable_attachments}"

        # Limit log embed to avoid huge messages cluttering the log,
        # if message is longer, upload it instead.
        if len(message.clean_content) > MAX_LOGGED_MESSAGE_SIZE:
            # NOTE; Text uploading might be happening too often, and might have to be removed
            # in the future
            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 removed discrod message."
            )
            if url:
                response += f"\n**Content:** Message too long, check [message upload]({url})"
            else:
                response += "\n**Contet:** Message too long (WARNING: Automatic upload failed)"
        else:
            response += f"\n**Content:** {message.content}"

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

        embed = Embed(title="Message deleted",
                      description=response,
                      color=Color.dark_red())
        embed.timestamp = datetime.datetime.utcnow()
        embed.set_footer(text=f"Message ID: {message.id}")

        await self.send_log(message.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.")
Exemple #24
0
 async def shutdown(self, ctx):
     """Shut down the bot and whole script Lol"""
     await ctx.channel.send("Ok")
     await ctx.bot.config.channels.status.send(
         embed=Embed(title="<:offline:708886391672537139> shutting Down.....", color=Color.dark_red())
     )
     exit()
Exemple #25
0
 async def on_guild_remove(self, guild: Guild):
     embed = Embed(
         title=f"Left guild: {guild}", description=f"ID: {guild.id}", color=Color.dark_red()
     ).set_thumbnail(url=guild.icon.url if guild.icon else None)
     await self.bot.status_channels.Guilds.send(embed=embed)
Exemple #26
0
 async def on_member_ban(self, guild, user):
     await self.logembed(user, "Banned", Color.dark_red())
Exemple #27
0
    async def check_expired_roles(self):
        """
        Function checks for expired users on community nad removes them if necessary
        """
        print(Fore.GREEN +
              f"{get_time()} --> CHECKING FOR USERS WITH EXPIRED ROLES ")
        now = datetime.utcnow().timestamp(
        )  # Gets current time of the system in unix format
        merchant_manager = self.backoffice.merchant_manager
        overdue_members = merchant_manager.get_over_due_users(
            timestamp=int(now))  # Gets all overdue members from database
        bot = self.bot
        if overdue_members:
            bot_guilds = [guild for guild in bot.guilds
                          ]  # get all guilds bot has access to
            for mem in overdue_members:
                mem_id = mem['userId']
                mem_role_id = mem['roleId']
                mem_role_community_id = mem['communityId']

                # Check if community where role was created still has bot
                if [
                        guild.id for guild in bot_guilds
                        if mem_role_community_id == guild.id
                ]:
                    # get guild and member
                    guild = bot.get_guild(id=mem_role_community_id)
                    member = guild.get_member(mem_id)
                    # Check if member still exists
                    if member in guild.members:
                        role = guild.get_role(
                            role_id=mem_role_id)  # Get the role
                        if role:
                            if role in member.roles:
                                await member.remove_roles(
                                    role,
                                    reason=
                                    'Merchant notification -> Role expired')
                                if merchant_manager.remove_overdue_user_role(
                                        community_id=mem_role_community_id,
                                        role_id=mem_role_id,
                                        user_id=mem_id):
                                    expired = discord.Embed(
                                        name=':timer: Expired Role :timer: ',
                                        title=
                                        '__Role Expiration Notification__',
                                        description=
                                        'Your membership has expired. Please check '
                                        'details below.',
                                        color=Color.dark_red())

                                    expired.set_thumbnail(
                                        url=bot.user.avatar_url)
                                    expired.add_field(
                                        name=
                                        ':bank: Origin of role expiration:bank: ',
                                        value=guild.name,
                                        inline=False)
                                    expired.add_field(
                                        name=
                                        ":man_juggling: Expired Role :man_juggling: ",
                                        value=f'```{role.name}```')
                                    expired.add_field(
                                        name=
                                        ":information_source: Information :information_source: ",
                                        value=
                                        " In order to obtain back all privileges please re-purchase"
                                        " the role directly from the community."
                                    )
                                    await member.send(embed=expired)
                                else:
                                    channel_sys = channels["merchant"]
                                    # send notification to merchant for system if user could not be removed from database
                                    expired_sys = discord.Embed(
                                        title=
                                        '__Expired user could not be removed from system__',
                                        colour=discord.Color.red())
                                    expired_sys.set_thumbnail(
                                        url=bot.user.avatar_url)
                                    expired_sys.add_field(name='Community',
                                                          value=guild.name,
                                                          inline=False)
                                    expired_sys.add_field(name="Expired Role",
                                                          value=role.name)
                                    expired_sys.add_field(
                                        name="User details",
                                        value=f'Role ID: {mem_role_id}\n'
                                        f'Community ID: {mem_role_community_id}\n'
                                        f'Member ID: {mem_id}')
                                    merch_channel = bot.get_channel(
                                        id=int(channel_sys))
                                    await merch_channel.send(embed=expired_sys)
                            else:
                                merchant_manager.remove_overdue_user_role(
                                    community_id=mem_role_community_id,
                                    user_id=mem_id,
                                    role_id=mem_role_id)
                        else:
                            merchant_manager.remove_monetized_role_from_system(
                                role_id=mem_role_id,
                                community_id=mem_role_community_id)
                            merchant_manager.bulk_user_clear(
                                community_id=mem_role_community_id,
                                role_id=mem_role_id)
                    else:
                        merchant_manager.delete_user_from_applied(
                            community_id=mem_role_community_id, user_id=mem_id)
                else:
                    merchant_manager.bulk_user_clear(
                        community_id=mem_role_community_id,
                        role_id=mem_role_id)
                    merchant_manager.remove_all_monetized_roles(
                        guild_id=mem_role_community_id)

        else:
            print(Fore.GREEN +
                  'There are no overdue members in the system going to sleep!')
            print(
                '===========================================================')
Exemple #28
0
async def commands(message, client):
    if message.content.startswith('>help'):
        txt = ""
        txt += "**FONCTIONS D\'ANIMATION DU DISCORD**\n"
        txt += "-----------------------------------\n"
        txt += ':dog2: | **>ordre** : Donne un ordre à Ohana.\n'
        txt += '> Paramètres :\n'
        txt += '> *assis*, *couché* ou *patte* | Liste non exhaustive.A toi de trouver les autres :upside_down:.\n'
        txt += '> Exemple : **>ordre patte chien**\n'
        txt += ':frame_photo: | **>race** : affiche une race d\`une espèce aléatoire.\n'
        txt += '> Paramètres :\n'
        txt += '> *chien* :dog:, *chat* :cat: ou *cheval* :horse: | Permet de préciser l\'espèce dont la race tirée au sort est associée.\n'
        txt += '> Exemple : **>race chien**\n'
        txt += ':teacher: | **>anecdote** : affiche une anecdote sur les animaux.\n'
        txt += "\n"
        txt += "**FONCTIONS POUR LES QUIZ**\n"
        txt += "-----------------------------------\n"
        txt += ':question: | **>quiz** : commande globale pour toutes les commandes liées aux quiz.\n'
        txt += '> Paramètres :\n'
        txt += '> *planning* :calendar: | Affiche la liste des quiz avec leur date.\n'
        txt += '> *classement* :crown: | Affiche le classement en cours (mois courant).\n'
        txt += '> *rappel* :notepad_spiral: | Gestion de la liste des joueurs de quiz qui veulent un rappel 10 minutes avant les quiz.\n'
        txt += "\n"
        txt += "**FONCTIONS DE GESTION DU DISCORD**\n"
        txt += "-----------------------------------\n"
        # txt += ':bar_chart: **>utilisateurs** : affiche des statistiques sur les utilisateurs du Discord.\n'
        # txt += ':bar_chart: **>messages** : affiche des statistiques sur les messages postés sur le Discord.\n'
        # txt += ':calendar: **>algo** : affiche le lien vers le flowchart du bot.\n'
        txt += ':calendar: **>code** : affiche le lien vers la roadmap du bot.\n'
        txt += ':computer: **>data** : regénère les fichiers de données pour mettre à jour les statistiques.\n'
        await message.channel.send(txt)

    if message.content.startswith('>test'):
        commands = [
            '>help', '>race', '>race chat', '>race chien', '>race cheval',
            '>anecdote', '>ordre assis', '>ordre couché', '>ordre patte',
            '>ordre high five', '>ordre belle', '>utilisateur', '>messages',
            '>code', '>data'
        ]
        for command in commands:
            await message.channel.send(command)
            await asyncio.sleep(1)

    # INTERACTIONS COMMANDS
    if message.content.startswith('>ordre'):
        await functions.apply_order(message)

    if message.content.startswith('>anecdote'):
        await functions.anecdote(message)

    if message.content.startswith('>race'):
        await functions.race(message)

    # QUIZ COMMANDS
    if message.content.startswith('>quiz planning'):
        import pandas as pd
        df = pd.read_excel("inputs/xlsx/planning.xlsx")

        def category(cat):
            if "Chien" in cat:
                return ":dog2:"
            if "Chat" in cat:
                return ":cat2:"
            if "Cheval" in cat:
                return ":racehorse:"
            if "Oiseau" in cat:
                return ":bird:"
            if "NAC" in cat:
                return ":rabbit2:"
            if "?" in cat:
                return ":interrobang:"
            return ":feet:"

        txt = "**QUIZ PASSÉS**\n"
        separator_added = False
        for id, row in df.iterrows():
            # Date	Titre	Catégorie
            ts = pd.to_datetime(str(row['Date']))
            date = ts.strftime('%d/%m/%Y')
            d, m, y = date.split("/")
            d = functions.rank_to_emote(d, type="date")
            m = functions.rank_to_emote(m, type="date")
            y = functions.rank_to_emote(y, type="date")

            import datetime
            if (ts > datetime.datetime.now() and not separator_added):
                txt += "**QUIZ FUTURS**\n"
                separator_added = True
            # txt += "{}/{}/{} : {} {}\n".format(d,m,y, row['Titre'], category(row['Catégorie']))
            txt += ":arrow_forward: {} {} : {}\n".format(
                category(row['Catégorie']), date, row['Titre'])
            if len(txt) > 1000:
                am = discord.AllowedMentions(everyone=False,
                                             users=False,
                                             roles=False,
                                             replied_user=False)
                await message.channel.send(txt, allowed_mentions=am)
                txt = ""
        am = discord.AllowedMentions(everyone=False,
                                     users=False,
                                     roles=False,
                                     replied_user=False)
        await message.channel.send(txt, allowed_mentions=am)

    if message.content.startswith('>question'):
        import pandas as pd
        df = pd.read_csv("inputs/csv/fci.csv", delimiter="\t")
        l = list()
        for key, row in df.sample().iterrows():
            r = row
        while r['id'] in l:
            for key, row in df.sample().iterrows():
                r = row
        l.append(r['id'])
        id_b = r['id']
        name_b = r['name_fr']
        country_b = r['country']

        propositions = list()
        propositions.append(country_b)

        await message.channel.send("De quel pays provient la race : " +
                                   name_b.title())

        rows_same_country = df[df['country'] == country_b]
        rows_diff_country = df.merge(
            rows_same_country, how='outer',
            indicator=True).loc[lambda x: x['_merge'] == 'left_only']
        other_responses = rows_diff_country.sample(3)
        for key, row in other_responses.iterrows():
            propositions.append(row['country'].title())
        for p in propositions:
            await message.channel.send("- {}".format(p.title()))
        await message.channel.send(":star: Réponse : ||" + country_b.title() +
                                   "||")

    if message.content.startswith('>quiz classement'):
        quiz.prepare_csv()
        functions.create_podium()
        df_members = pd.read_csv("outputs/members.csv")

        def get_discriminator(author):
            return author.split("#")[-1]

        df_quizz = pd.read_csv("outputs/charts/classement.csv")
        df_quizz['discriminator'] = df_quizz.apply(
            lambda x: get_discriminator(x['Username']), axis=1)
        df_members['discriminator'] = df_members['discriminator'].astype(int)
        df_quizz['discriminator'] = df_quizz['discriminator'].astype(int)
        df = df_quizz.merge(df_members,
                            how="left",
                            suffixes=('_quizz', '_data'))
        await message.channel.send(file=discord.File('outputs/podium.png'))
        txt = "Classement du mois :\n"
        for key, row in df.head(10).iterrows():
            print(row['id' ''])
            txt += "{}\n{} [<@{}>]\n:homes: {} |:1234: {}pts\n".format(
                functions.rank_to_emote(key + 1),
                row['display_name'].split("-")[0].strip(), row['id'],
                row['refuge'], row['Points'])
            if len(txt) > 1000:
                am = discord.AllowedMentions(everyone=False,
                                             users=False,
                                             roles=False,
                                             replied_user=False)
                await message.channel.send(txt, allowed_mentions=am)
                txt = ""
        am = discord.AllowedMentions(everyone=False,
                                     users=False,
                                     roles=False,
                                     replied_user=False)
        await message.channel.send(txt, allowed_mentions=am)

        # await functions.order_not_available(message);

    if message.content.startswith('>bug'):
        from discord.utils import get
        user = get(message.guild.members, name="Cédric")
        if user:
            await user.send(content=message.author.name)
            await user.send(content=message.content)
        else:
            print("NON")

    if message.content.startswith('>quiz rappel'):
        await functions.order_not_available(message)

    # ADMIN COMMANDS
    if message.content.startswith('>algo'):
        await functions.order_not_available(message)

    if message.content.startswith('>utilisateurs'):
        # await functions.order_not_available(message);
        # return
        df = pd.read_csv("outputs/members.csv")
        cjs = df['refuge'].unique()
        cjs = sorted(cjs)
        roles = [
            'Administrateurs', 'Modérateurs', 'Responsables de refuge',
            'Agents animaliers', 'Référents', 'Encadrants', 'Jeunes'
        ]
        colors = dict()
        colors['Administrateurs'] = Color.red()
        colors['Modérateurs'] = Color.orange()
        colors['Responsables de refuge'] = Color.green()
        colors['Agents animaliers'] = Color.teal()
        colors['Référents'] = Color.purple()
        colors['Encadrants'] = Color.blue()
        colors['Jeunes'] = Color.gold()
        colors['Non présentés'] = Color.dark_red()
        for cj in cjs:
            await message.channel.send(":map: **{}** :map:".format(cj))
            df_temp = df[df['refuge'] == cj]
            for role in roles:
                l = list()
                for key, row in df_temp[df_temp['top_role'] ==
                                        role].iterrows():
                    l.append(row['display_name'])
                if len(l) > 0:
                    l = sorted(l)
                    emeb = discord.Embed(title=role,
                                         description="\n".join(l),
                                         color=colors[role])
                    await message.channel.send(embed=emeb)

    if message.content.startswith('>messages'):
        import time
        start_time = time.time()

        await message.channel.send('Bien reçu ! Je vais compter les messages.')
        await message.channel.send('Je reviens dans quelques secondes ...')

        df = pd.read_csv("outputs/csv/messages.csv")

        import seaborn as sns
        top_five = df['channel'].value_counts().keys()[:5]
        df_temp = df[df['channel'].isin(top_five)]
        sns_plot = sns.catplot(y="channel",
                               kind="count",
                               palette="pastel",
                               edgecolor=".6",
                               data=df_temp)
        sns_plot.savefig("outputs/images/output.png")

        await message.channel.send('En tout, il y a {} messages.'.format(
            len(list(df['content']))))
        await message.channel.send(
            'Répartition dans les salons :',
            file=discord.File('outputs/images/output.png'))
        await message.channel.send("J'ai trouvé ce résultat en %d secondes." %
                                   int(time.time() - start_time))
        return

    if message.content.startswith('>code'):
        await message.channel.send(
            'Tu veux connaître les prochaines améliorations du bot ? Ca se passe ici !'
        )
        await message.channel.send(
            'https://github.com/cedricmaigrot/Discord_laSPA/projects/1')
        await message.channel.send(
            'Tu veux faire ton propre bot comme <@818564026237452350> ? Le code est en open source !'
        )
        await message.channel.send(file=discord.File('inputs/images/work.gif'))

    if message.content.startswith('>data'):
        import time
        start_time = time.time()
        await message.channel.send('Bien reçu ! Je vais mémoriser les données.'
                                   )
        await message.channel.send('Je reviens dans quelques secondes ...')
        for guild in client.guilds:
            if guild.name in "Clubs Jeunes SPA":
                # lst = list()
                # for channel in guild.channels:
                #     print("Channel : " + channel.name)
                #     try:
                #         hist = await channel.history(limit=20000).flatten()
                #         for h in hist:
                #             lst.append([h.activity, h.application, h.attachments, h.author, h.call, h.channel,
                #                         h.channel_mentions, h.clean_content, h.content, h.created_at, h.edited_at,
                #                         h.embeds, h.flags, h.guild, h.id, h.jump_url, h.mention_everyone, h.mentions,
                #                         h.nonce, h.pinned, h.raw_channel_mentions, h.raw_mentions, h.raw_role_mentions,
                #                         h.reactions, h.reference, h.role_mentions, h.stickers, h.system_content, h.tts,
                #                         h.type, h.webhook_id])
                #     except:
                #         pass
                # df_messages = pd.DataFrame(lst, columns=["activity", "application", "attachments", "author", "call",
                #                                          "channel", "channel_mentions", "clean_content", "content",
                #                                          "created_at", "edited_at", "embeds", "flags", "guild", "id",
                #                                          "jump_url", "mention_everyone", "mentions", "nonce", "pinned",
                #                                          "raw_channel_mentions", "raw_mentions", "raw_role_mentions",
                #                                          "reactions", "reference", "role_mentions", "stickers",
                #                                          "system_content", "tts", "type", "webhook_id"])
                # df_messages.to_csv("outputs/messages.csv")
                # df_messages.to_excel("outputs/messages.xlsx")
                # df_messages.to_html("outputs/messages.html")

                df_messages = pd.read_excel("outputs/messages.xlsx")

                lst = list()
                for member in guild.members:
                    print("Member : " + member.name)
                    lst.append([
                        member.activities, member.activity, member.avatar,
                        member.avatar_url, member.bot, member.color,
                        member.colour, member.created_at,
                        member.default_avatar, member.default_avatar_url,
                        member.desktop_status, member.discriminator,
                        member.display_name, member.guild,
                        member.guild_permissions, member.id, member.joined_at,
                        member.mention, member.mobile_status, member.name,
                        member.nick, member.pending, member.premium_since,
                        member.public_flags, member.raw_status, member.roles,
                        member.status, member.system, member.top_role,
                        member.voice, member.web_status
                    ])
                df_members = pd.DataFrame(
                    lst,
                    columns=[
                        "activities", "activity", "avatar", "avatar_url",
                        "bot", "color", "colour", "created_at",
                        "default_avatar", "default_avatar_url",
                        "desktop_status", "discriminator", "display_name",
                        "guild", "guild_permissions", "id", "joined_at",
                        "mention", "mobile_status", "name", "nick", "pending",
                        "premium_since", "public_flags", "raw_status", "roles",
                        "status", "system", "top_role", "voice", "web_status"
                    ])

                def get_shelter(roles):
                    shelter = "Inconnu"
                    for role in roles:
                        r = discord.utils.get(guild.roles, id=role.id)
                        if "Club Jeunes" in r.name:
                            shelter = r.name
                            print(r.name)
                    return shelter

                df_members['refuge'] = df_members.apply(
                    lambda x: get_shelter(x['roles']), axis=1)

                df_members.to_csv("outputs/members.csv")
                df_members.to_excel("outputs/members.xlsx")
                df_members.to_html("outputs/members.html")

                lst = list()
                for role in guild.roles:
                    print("Role : " + role.name)
                    lst.append([
                        role.color, role.colour, role.created_at, role.guild,
                        role.hoist, role.id, role.managed, role.members,
                        role.mention, role.mentionable, role.name,
                        role.permissions, role.position, role.tags
                    ])
                df_roles = pd.DataFrame(lst,
                                        columns=[
                                            "color", "colour", "created_at",
                                            "guild", "hoist", "id", "managed",
                                            "members", "mention",
                                            "mentionable", "name",
                                            "permissions", "position", "tags"
                                        ])
                df_roles.to_csv("outputs/roles.csv")
                df_roles.to_excel("outputs/roles.xlsx")
                df_roles.to_html("outputs/roles.html")

                df_members['discriminator'] = df_members[
                    'discriminator'].astype(str)

                def get_discriminator(author):
                    name = "{}".format(author)
                    return name.split("#")[-1]

                df_messages['author_discriminator'] = df_messages.apply(
                    lambda x: get_discriminator(x['author']), axis=1)
                df_messages['author_discriminator'] = df_messages[
                    'author_discriminator'].astype(str)

                df_merge = df_messages.merge(df_members,
                                             left_on='author_discriminator',
                                             right_on='discriminator',
                                             suffixes=('_messages',
                                                       '_members'))
                df_merge = df_merge.merge(df_roles,
                                          left_on='top_role',
                                          right_on='name',
                                          suffixes=('', '_role'))

                # df_messages[(~df_messages['id'].isin(df_merge['id_messages']))]['author']
                df_merge.to_html("outputs/merge.html")
                df_merge.to_csv("outputs/merge.csv")
                df_merge.to_excel("outputs/merge.xlsx")

        await message.channel.send('C\'est fait !')
        await message.channel.send("J'ai fait cela en %d secondes." %
                                   int(time.time() - start_time))
        return
Exemple #29
0
async def begin_verification(member: Member):
    main_guild = await get_main_guild()

    # Create new channel
    channel_name = f"verification-{generate_id(4)}"

    # Find the correct category
    category = find_category_by_id(main_guild,
                                   VERIFICATION_CHANNEL_CATEGORY_ID)
    if not category:
        raise Exception(
            f"Could not find category with ID {VERIFICATION_CHANNEL_CATEGORY_ID}"
        )

    permission_overwrites = {
        main_guild.me:
        PermissionOverwrite(read_messages=True,
                            send_messages=True,
                            read_message_history=True),
        member:
        PermissionOverwrite(read_messages=True,
                            send_messages=True,
                            read_message_history=True),
        main_guild.default_role:
        PermissionOverwrite(read_messages=False, send_messages=False)
    }

    auth_channel = await main_guild.create_text_channel(
        channel_name,
        category=category,
        overwrites=permission_overwrites,
        reason=f"Authenticating user {member.id}#{member.discriminator}")

    random_code = generate_code(4)
    random_emoji_text, random_emoji_unicode = choice(
        gets(String.VERIFY_RANDOM_EMOJI_LIST))

    await auth_channel.send(
        gets(String.ON_VERIFICATION_BEGIN).format(user_mention=member.mention))
    await auth_channel.send(
        gets(String.VERIFICATION_HOW).format(
            code=random_code,
            random_emoji=random_emoji_text.strip(":"),
        ))

    responses = []
    embed = None

    try:
        failed_tries = 0

        def is_correct_response(message: Message):
            if message.author.id != member.id:
                return False
            if message.channel.id != auth_channel.id:
                return False

            responses.append(message)

            content = str(message.content).strip().lower()
            # Should begin with the code and end with the emoji
            if random_code.lower() not in content:
                return False
            if random_emoji_unicode not in content:
                return False

            return True

        response: Message = await bot.wait_for("message",
                                               check=is_correct_response,
                                               timeout=120)
    except TimeoutError:
        # Tell the user they were too slow and delete the verification channel
        await member.send(gets(String.VERIFY_FAILED_TIMEOUT))
        await auth_channel.delete(
            reason=
            f"Verification for {member.name}#{member.discriminator} ({member.id}) "
            f"failed: timeout")

        if len(responses) == 0:
            if LOG_VERIFICATIONS_CONSOLE:
                log.info(
                    f"Member failed to verify (timeout): {member.name}#{member.discriminator} ({member.id}), "
                    f"expected '{random_code} {random_emoji_unicode}', no responses"
                )

            embed = Embed(
                title="User failed to verify (timeout)",
                description=
                f"*Expected \"{random_code} {random_emoji_unicode}\"*\n"
                f"*No response*",
                color=Color.dark_red(),
                timestamp=datetime.now())
        else:
            last_message = responses[-1]

            trimmed = last_message.clean_content
            if len(trimmed) > 1000:
                trimmed = f"{trimmed[:1000]}[...]"

            if LOG_VERIFICATIONS_CONSOLE:
                log.info(
                    f"Member not verified (timeout): {member.name}#{member.discriminator} ({member.id}), "
                    f"expected '{random_code} {random_emoji_unicode}', last response '{trimmed}'"
                )

            embed = Embed(
                title="Member failed to verify (timeout)",
                description=
                f"*Expected \"{random_code} {random_emoji_unicode}\"*\n"
                f"Last response:\n```{trimmed}```",
                color=Color.red(),
                timestamp=datetime.now())
    else:
        await response.add_reaction("✅")

        # Assign the full member role
        full_role = await get_verified_role()
        await member.add_roles(full_role, reason=f"Verification finished")

        await member.send(
            gets(String.VERIFY_SUCCESS).format(user_mention=member.mention))
        await auth_channel.delete(
            reason=
            f"Verification for {member.name}#{member.discriminator} ({member.id}) "
            f"finished")

        trimmed = response.clean_content
        if len(trimmed) > 1000:
            trimmed = f"{trimmed[:1000]}[...]"

        if LOG_VERIFICATIONS_CONSOLE:
            log.info(
                f"Member verified: {member.name}#{member.discriminator} ({member.id}) with message '{trimmed}' "
                f"(expected \"{random_code} {random_emoji_unicode}\")")

        embed = Embed(
            title="Member verified",
            description=f"*Expected \"{random_code} {random_emoji_unicode}\"*\n"
            f"```{trimmed}```",
            color=Color.green(),
            timestamp=datetime.now())
    finally:
        # Remove the reaction on the main message
        trigger_messsage = await get_verify_trigger_message()
        await trigger_messsage.remove_reaction(VERIFICATION_TRIGGER_EMOJI,
                                               member)

        # Send the log embed if enabled
        log_channel = await get_logging_channel()
        if log_channel is not None:
            embed.set_footer(
                text=
                f"Member: {member.name}#{member.discriminator} ({member.id})",
                icon_url=member.avatar_url)

            await log_channel.send(embed=embed)