Esempio n. 1
0
def destructionEmbed(member):
    return Embed(
        description=
        f"тЭЧ {member.mention} Your lab has exploded ЁЯТе due to overload, you lost everything."
    )
Esempio n. 2
0
    async def info(self, ctx):
        """
        send an embed containing info in format
        Server_id           Owner

        Channels
        text | voice
        Total:

        Members
        online | idle | dnd | streaming | offline
        Total:
        """

        status = {}
        for member in ctx.guild.members:
            status[member.status.name] = status.get(member.status.name, 0) + 1

        online = core.utils.get(self.bot.emojis, name="status_online")
        idle = core.utils.get(self.bot.emojis, name="status_idle")
        dnd = core.utils.get(self.bot.emojis, name="status_dnd")
        streaming = core.utils.get(self.bot.emojis, name="status_streaming")
        offline = core.utils.get(self.bot.emojis, name="status_offline")

        text = core.utils.get(self.bot.emojis, name="text_channel")
        voice = core.utils.get(self.bot.emojis, name="voice_channel")

        embed = Embed(
            title=f"{ctx.guild.name}",
            description=
            f"{ctx.guild.description if ctx.guild.description else ''}",
            color=Color.from_rgb(0, 0, 0))
        embed.add_field(name="ID", value=(f"{ctx.guild.id}"))
        embed.add_field(name="Owner", value=(f"{ctx.guild.owner}"))
        embed.add_field(
            name="Channels",
            value=("{text} {text_count} " + "{voice} {voice_count}").format(
                text=text,
                text_count=len(ctx.guild.text_channels),
                voice=voice,
                voice_count=len(ctx.guild.voice_channels)) +
            f"\n**Total:** {len(ctx.guild.channels)}",
            inline=False)
        embed.add_field(
            name="Members",
            value=("{online} {online_count} " + "{idle} {idle_count} " +
                   "{dnd} {dnd_count} " + "{streaming} {streaming_count} " +
                   "{offline} {offline_count}").format(
                       online=online,
                       online_count=status.get("online", 0),
                       idle=idle,
                       idle_count=status.get("idle", 0),
                       dnd=dnd,
                       dnd_count=status.get("dnd", 0),
                       streaming=streaming,
                       streaming_count=status.get("streaming", 0),
                       offline=offline,
                       offline_count=status.get("offline", 0)) +
            f"\n**Total:** {len(ctx.guild.members)}",
            inline=False)

        await ctx.send(embed=embed)
Esempio n. 3
0
            elif l in [
                    "| **Name** | **Usage** | **Description** | **Aliases** |",
                    "|:-:|:-:|:-:|:-:|"
            ]:
                pass
            elif l.startswith("|") and l.endswith("|"):
                cmd = list(
                    map(lambda x: x.replace('`', ""),
                        l.strip("|").split("|")))
                helpvals[lastheader].append("< " + cmd[1] + " >\n[ AKA " +
                                            cmd[3].ljust(15) + " ]( " +
                                            cmd[2] + " )")
            else:
                helpvals[lastheader].append('> ' + l.replace('`', ''))

helpembed = Embed(colour=0x9542f4)

desc = "```markdown"

first = True
for key, value in helpvals.items():
    if first:
        helpembed.title = key
        helpembed.description = '\n'.join(
            map(lambda x: x.lstrip(">").strip(), value)
        ) + '\n\nTo display another page, do `cow help {page number}`. For more help, take a look at [the Readme](https://github.com/UnsignedByte/discow/blob/master/README.md) on our [github repository](https://github.com/UnsignedByte/discow)!'
        first = False
    else:
        stoadd = "\n\n# " + key + '\n\n' + '\n'.join(value)
        if len(desc) + len(stoadd) >= 1000:
            helpembed.add_field(name='\a', value=desc + '```')
    async def anime(self, args, mobj):
        """
        Does a AniList search to find requested Anime
        
        If there are multiple options, will ask you which one to choose. You will have 10 seconds to respond.
        
        Will not return any adult series.
        """
        args = " ".join(args)

        result = await self.ani_get_options(args, mobj, 'ANIME')

        if result:
            anime = self.anilist.getAnimeDetailsById(result)
        else:
            anime = self.anilist.getAnimeDetails(args)
        if not anime:
            await self.error(mobj.channel, "Could not find anything")
            return

        if not anime:
            await self.error(mobj.channel, "Could not find anything")
            return

        embed = Embed(
            title=anime['title_english']
            if anime['title_english'] else anime['title_romaji']
            if anime['title_romaji'] else anime['title_japanese'],
            colour=Color(0x7289da),
            url=f"https://anilist.co/anime/{anime['id']}/{anime['title_romaji']}"
            .replace(" ", "%20"))
        embed.set_image(url=anime['img'])
        embed.add_field(name="Episode Count",
                        value=str(anime['total_episodes']))
        embed.add_field(name="Type", value=anime['type'])
        embed.add_field(name="Status", value=anime['airing_status'])

        embed.add_field(
            name="Dates",
            value=
            f'{anime["start_date"]} through {anime["end_date"] if anime["end_date"] != "None-None-None" else "present"}'
            if anime["start_date"] != anime["end_date"] else
            f'{anime["start_date"]}')

        if anime["synonyms"]:
            embed.add_field(name="Synonyms",
                            value=", ".join(anime["synonyms"]))
        if anime["description"] is None:
            anime["description"] = "Could not pull synopsis"
        anime["description"] = re.sub(
            r'\n\s*\n', '\n\n',
            unescape(anime["description"]).replace("<br>", "\n"))
        if len(anime["description"]) > 1000:
            if "\n" in anime["description"][:965]:
                anime["description"] = anime[
                    "description"][:anime["description"][:965].rfind("\n")]
            else:
                anime["description"] = anime["description"][:965]
            anime["description"] += "\nIncomplete synopsis due to length."

        embed.add_field(name="Synopsis", value=anime["description"])
        try:
            await self.embed(mobj.channel, embed)
        except BaseException:
            await self.error(
                mobj.channel,
                "Something when trying to format the object. Here is a link to the anime: "
                + "https://myanimelist.net/anime/{0.id}/{0.title}".format(
                    anime).replace(" ", "%20"))
Esempio n. 5
0
    async def status(self, ctx): #既に存在する関数名だったらERROR出るのでもし今後コマンドを追加するならコマンド名と同じ関数名にして下さい。
        f"""
        ステータスの表示。
        今後アイテム追加した場合に備えてページ分けを自動でさせてます。
        f"""
        try: # ERRORが起きるか起きないか。起きたらexceptに飛ばされる
          # sqlite_listの中からデータベースに接続したというオブジェクトを取得
            _, conn, cur = [sql for sql in self.bot.sqlite_list if ctx.author.id == sql[0]][0]
            user = ctx.author
            user_id = ctx.author.id
            user_name = ctx.author.nick if ctx.author.nick else ctx.author.name

          # ユーザーの総経験値を取得
            player_exp = await database.get_player_exp(ctx, user_id, conn, cur)

          # 戦闘チャンネルの確認
            await cur.execute("select distinct channel_id FROM in_battle WHERE user_id=?", (user_id,))
            in_battle = await cur.fetchone()
            battle_str = f"{self.bot.get_channel(in_battle[0]).guild.name}の{self.bot.get_channel(in_battle[0]).mention}" if in_battle and self.bot.get_channel(in_battle[0]) else "現在休戦中or認識出来ないチャンネル"

          # アイテムを所持してるかの確認。アイテムはitem_idで登録してるので名前をall_dataファイルのitem_lists変数から引っ張ってきます。
            await cur.execute("select distinct item_id,count FROM item WHERE user_id=? ORDER BY item_id;", (user_id,))
            i_list = ''.join(f'{item_lists[i[0]]} : {i[1]}個\n' for i in await cur.fetchall())
          # 今後アイテムが増えた場合に25個のデータ(重複なし)でページ分け
            msgs = list(filter(lambda a: a != "", ["\n".join(i_list.split("\n")[i:i + 25]) for i in range(0, len(i_list), 25)] if i_list != "" else ["無し"]))

          # 現在のユーザのランキングlistで返しindexで順位を取得する方法にしています。
            await cur.execute("select distinct user_id FROM player ORDER BY exp DESC;")
            user_rank = [r[0] for r in await cur.fetchall()]

          # 経験値をmath.sqrt(平方根の計算)を使用し求めます。整数を返すためにint()を使用しています。
            player_level = int(math.sqrt(player_exp))
            embeds = []
            embed = Embed()
            embed.add_field(name="Lv", value=str(player_level))
            embed.add_field(name="HP", value=str(player_level*5+50))
            embed.add_field(name="ATK", value=str(int(player_level*5+50)))
            embed.add_field(name="EXP", value=str(player_exp))
          # レベル+1の必要経験値数(2乗)-現在の経験値数で計算しています。
            embed.add_field(name="次のLvまで", value=str((player_level+1)**2-player_exp)+"exp")
            embed.add_field(name="戦闘状況:", value=battle_str)
            embed.add_field(name="順位:", value=f"{user_rank.index(user_id) + 1}位")
          # ユーザーのアイコン表示
            embed.set_thumbnail(url=user.avatar_url_as())
            embed.set_author(name=f"{user_name}のステータス:")
            embeds.append(embed)

            [embeds.append(Embed(description=f"```{i if i else 'アイテムを所持していません。'}```").set_thumbnail(url=user.avatar_url_as()).set_author(name=f"{user_name}のステータス:")) for i in msgs]

            msg = await ctx.send(content=f"```diff\n1ページ/{len(embeds)}ページ目を表示中\n見たいページを発言してください。\n30秒経ったら処理は止まります。\n0と発言したら強制的に処理は止まります。```", embed=embeds[0])
            while True: # 処理が終わる(return)まで無限ループ
                try: # ERRORが起きるか起きないか。起きたらexceptに飛ばされる
                    msg_react = await self.bot.wait_for('message', check=lambda m: m.author == ctx.author and m.content.isdigit() and 0 <= int(m.content) <= len(embeds), timeout=30)
                  # await self.bot.wait_for('message')で返ってくるのは文字列型
                    if msg_react.content == "0":
                      # このcontentの中にはゼロ幅スペースが入っています。Noneでもいいのですが編集者はこっちの方が分かりやすいからこうしています。
                        return await msg.edit(content="‌")
                    await msg.edit(content=f"```diff\n{int(msg_react.content)}ページ/{len(embeds)}ページ目を表示中\n見たいページを発言してください。\n30秒経ったら処理は止まります。\n0と発言したら強制的に処理は止まります。```", embed=embeds[int(msg_react.content)-1])
                except asyncio.TimeoutError: # wait_forの時間制限を超過した場合
                  # このcontentの中にはゼロ幅スペースが入っています。Noneでもいいのですが編集者はこっちの方が分かりやすいからこうしています。
                    return await msg.edit(content="‌", embed=Embed(title=f"時間切れです..."))

        except (NotFound, asyncio.TimeoutError, Forbidden): # 編集した際に文字が見つからなかった, wait_forの時間制限を超過した場合, メッセージに接続できなかった
            return
        except: # 上のERROR以外のERROR出た場合はtracebackで表示するようにしています。 上手くコマンドが反応しない場合はコンソールを見てね!
            return print("エラー情報\n" + traceback.format_exc())
Esempio n. 6
0
    async def superstarify(
        self,
        ctx: Context,
        member: Member,
        duration: Expiry,
        *,
        reason: str = '',
    ) -> None:
        """
        Temporarily force a random superstar name (like Taylor Swift) to be the user's nickname.

        A unit of time should be appended to the duration.
        Units (∗case-sensitive):
        \u2003`y` - years
        \u2003`m` - months∗
        \u2003`w` - weeks
        \u2003`d` - days
        \u2003`h` - hours
        \u2003`M` - minutes∗
        \u2003`s` - seconds

        Alternatively, an ISO 8601 timestamp can be provided for the duration.

        An optional reason can be provided, which would be added to a message stating their old nickname
        and linking to the nickname policy.
        """
        if await _utils.get_active_infraction(ctx, member, "superstar"):
            return

        # Post the infraction to the API
        old_nick = member.display_name
        infraction_reason = f'Old nickname: {old_nick}. {reason}'
        infraction = await _utils.post_infraction(ctx, member, "superstar", infraction_reason, duration, active=True)
        id_ = infraction["id"]

        forced_nick = self.get_nick(id_, member.id)
        expiry_str = format_infraction(infraction["expires_at"])

        # Apply the infraction
        async def action() -> None:
            log.debug(f"Changing nickname of {member} to {forced_nick}.")
            self.mod_log.ignore(constants.Event.member_update, member.id)
            await member.edit(nick=forced_nick, reason=reason)

        old_nick = escape_markdown(old_nick)
        forced_nick = escape_markdown(forced_nick)

        nickname_info = textwrap.dedent(f"""
            Old nickname: `{old_nick}`
            New nickname: `{forced_nick}`
        """).strip()

        user_message = (
            f"Your previous nickname, **{old_nick}**, "
            f"was so bad that we have decided to change it. "
            f"Your new nickname will be **{forced_nick}**.\n\n"
            "{reason}"
            f"You will be unable to change your nickname until **{expiry_str}**. "
            "If you're confused by this, please read our "
            f"[official nickname policy]({NICKNAME_POLICY_URL})."
        ).format

        successful = await self.apply_infraction(
            ctx, infraction, member, action(),
            user_reason=user_message(reason=f'**Additional details:** {reason}\n\n' if reason else ''),
            additional_info=nickname_info
        )

        # Send an embed with to the invoking context if superstar was successful.
        if successful:
            log.trace(f"Sending superstar #{id_} embed.")
            embed = Embed(
                title="Superstarified!",
                colour=constants.Colours.soft_orange,
                description=user_message(reason='')
            )
            await ctx.send(embed=embed)
Esempio n. 7
0
async def draw(command, msg, user, channel, *args, **kwargs):
    full_msg = kwargs['full_msg']
    char_num = 7
    client = kwargs['client']
    unicode_reactions = ["1⃣", "2⃣", "3⃣", "4⃣", "5⃣", "6⃣", "7⃣"]
    player1 = user

    if len(msg.split(' ')) > 2:
        raise Exception(
            bold("Draw") + ": Too many arguments. " +
            await help_lizard('', '', '', ''))
    # No mention or too many, Raise exception
    elif not full_msg.mentions or len(full_msg.mentions) > 1:
        raise Exception(
            bold("Draw") +
            ": You must mention exactly one user to draw against.")

    player2 = full_msg.mentions[0]

    if player1 == player2:
        raise Exception(
            bold("Draw") + ": You are not allowed to draw against yourself.")

    # Start with randomselect basis to get characters
    try:
        game = msg.split(' ')[1].lower()
    except:
        # No game to be found so default to sfv
        game = 'sfv'

    chars, games = get_randomselect_data(game)
    if not chars:
        raise Exception(
            bold("Draw") + ": Invalid game: {0}. Valid games are: {1}".format(
                bold(game), bold(', '.join(games))))

    if len(chars) < char_num:
        # If we have a game with an amount of characters less than the number of cards drawn, it will never create a list
        raise Exception(
            bold("Draw") +
            ": Invalid game: {0}. The game selected has too few characters to function with this command."
            .format(bold(game)))

    # Initial accept embed
    accept_embed = Embed(title="Card Draw", colour=Colour(0x0fa1dc))
    accept_embed.set_footer(
        text="Do you agree to a draw, {0}?".format(player2.display_name))
    try:
        accept_msg = await channel.send(embed=accept_embed)
    except:
        raise Exception(
            bold("Draw") +
            ": Error sending embed to chat. Give Lizard-BOT the permission: " +
            bold("Embed Links"))
    await accept_msg.add_reaction('❌')
    await accept_msg.add_reaction('✅')

    try:
        # Wait for the reaction from the correct user
        # lambda function check for the correct reaction and the correct user
        reaction, user = await client.wait_for(
            'reaction_add',
            timeout=60.0,
            check=lambda reaction, user: user == player2 and
            (str(reaction.emoji) == '✅' or str(reaction.emoji) == '❌'
             ) and reaction.message == accept_msg)
        if str(reaction.emoji) == '❌':
            raise Exception()
    except:
        await accept_msg.delete()
        raise Exception(bold("Draw") + ": The draw was not accepted.")

    # if we got here, draw was accepted

    # randomly choose player order
    order = random_choice(
        [[player1, player2, player1, player2, player2, player1],
         [player2, player1, player2, player1, player1, player2]])
    # declare an Array of 0s to mark all cards as not picked
    # -1 means a card ban, 1 means a card draw
    picks = [0] * char_num

    #create new embed
    card_embed = Embed(title="Card Draw", colour=Colour(0x0fa1dc))

    # Declare list and fill with the amount of random characters
    # Make it so that it has to be all different characters
    characters_list = []
    while len(characters_list) < char_num:
        new_char = random_choice(chars)
        # Only add to the list if it is a new character
        if not new_char in characters_list:
            characters_list.append(new_char)
    # Add characters to ban
    for i, c in enumerate(characters_list):
        card_embed.add_field(name="Char {0}".format(i + 1),
                             value=c,
                             inline=True)

    await accept_msg.delete()
    try:
        game_msg = await channel.send(embed=card_embed)
    except:
        raise Exception(
            bold("Draw") +
            ": Error sending embed to chat. Give Lizard-BOT the permission: " +
            bold("Embed Links"))

    # Add reactions for pick/ban purposes
    for reaction in unicode_reactions:
        await game_msg.add_reaction(reaction)

    # Create lists for the picked characters
    p1_chars = []
    p2_chars = []

    for it, player in enumerate(order):
        user_to_check = None
        msg_to_check = None
        reaction_read = None
        reaction_read_emoji = None
        number = None

        # first two are bans
        if it < 2:
            card_embed.set_footer(text="{0}, select a character to ban.".
                                  format(player.display_name))
            await game_msg.edit(embed=card_embed)

            while not (user_to_check == player) or not (
                    msg_to_check == game_msg
            ) or reaction_read_emoji not in unicode_reactions:
                try:
                    reaction_read, user_to_check = await client.wait_for(
                        'reaction_add', timeout=60.0)
                    msg_to_check = reaction_read.message
                    if not (msg_to_check == game_msg
                            and user_to_check == player):
                        continue
                    reaction_read_emoji = reaction_read.emoji
                    number = unicode_reactions.index(reaction_read_emoji)
                    if picks[number] != 0:
                        # already banned, set as None to make it fail
                        reaction_read_emoji = None
                        card_embed.set_footer(
                            text=
                            "{0}, that character is already banned, please choose another."
                            .format(player.display_name))
                        await game_msg.edit(embed=card_embed)
                except Exception as ex:
                    if type(ex).__name__ == "TimeoutError":
                        await game_msg.delete()
                        raise Exception(
                            bold("Draw") +
                            ": {0} failed to ban a character.".format(
                                player.display_name))
                    else:
                        # As of right now, if something else goes wrong its because a reaction its not expecting was sent, go to the next loop
                        continue
            # mark character as banned
            picks[number] = -1
            # Strikethrough char on embed
            card_embed.set_field_at(number,
                                    name="Char {0}".format(number + 1),
                                    value="~~{0}~~".format(
                                        characters_list[number]))

        else:
            card_embed.set_footer(text="{0}, select a character to pick.".
                                  format(player.display_name))
            if it == 4:
                # Remind them gently they get to pick another character in a row if they are the 2nd player
                card_embed.set_footer(
                    text="{0}, select another character to pick.".format(
                        player.display_name))
            await game_msg.edit(embed=card_embed)

            while not (user_to_check == player) or not (
                    msg_to_check == game_msg
            ) or reaction_read_emoji not in unicode_reactions:
                try:
                    reaction_read, user_to_check = await client.wait_for(
                        'reaction_add', timeout=60.0)
                    msg_to_check = reaction_read.message
                    if not (msg_to_check == game_msg
                            and user_to_check == player):
                        continue
                    reaction_read_emoji = reaction_read.emoji
                    number = unicode_reactions.index(reaction_read_emoji)
                    if picks[number] == -1:
                        # already banned, set as None to make it fail
                        reaction_read_emoji = None
                        card_embed.set_footer(
                            text=
                            "{0}, that character is already banned, please choose another."
                            .format(player.display_name))
                        await game_msg.edit(embed=card_embed)
                    elif picks[number] == 1:
                        # already banned, set as None to make it fail
                        reaction_read_emoji = None
                        card_embed.set_footer(
                            text=
                            "{0}, that character is already chosen, please choose another."
                            .format(player.display_name))
                        await game_msg.edit(embed=card_embed)
                except Exception as ex:
                    if type(ex).__name__ == "TimeoutError":
                        await game_msg.delete()
                        raise Exception(
                            bold("Draw") +
                            ": {0} failed to choose a character.".format(
                                player.display_name))
                    else:
                        # As of right now, if something else goes wrong its because a reaction its not expecting was sent, go to the next loop
                        continue
            # mark character as picked
            picks[number] = 1
            # edit embed to bold character
            card_embed.set_field_at(number,
                                    name="Char {0}".format(number + 1),
                                    value="__" +
                                    bold(characters_list[number]) + "__")
            # assign character chosen to
            if player == player1:
                p1_chars.append(characters_list[number])
            else:
                p2_chars.append(characters_list[number])
    # create new embed
    chosen_embed = Embed(title="Final Picks", colour=Colour(0x0fa1dc))
    chosen_embed.add_field(name=player1.display_name,
                           value=", ".join(p1_chars))
    chosen_embed.add_field(name=player2.display_name,
                           value=", ".join(p2_chars))
    await game_msg.delete()
    await channel.send(embed=chosen_embed)
    return "Card draw finished"
Esempio n. 8
0
def write(word, isPic=False):
    if isPic == False:
        embed = Embed(description=word)
        UserObject.embed_send_list.append(embed)
    else:
        UserObject.embed_send_list.append(word)
Esempio n. 9
0
    async def hanukkah_festival(self, ctx):
        """Tells you about the Hanukkah Festivaltime of festival, festival day, etc)."""
        hanukkah_dates = await self.get_hanukkah_dates()
        self.hanukkah_dates_split(hanukkah_dates)
        hanukkah_start_day = int(self.hanukkah_days[0])
        hanukkah_start_month = int(self.hanukkah_months[0])
        hanukkah_start_year = int(self.hanukkah_years[0])
        hanukkah_end_day = int(self.hanukkah_days[8])
        hanukkah_end_month = int(self.hanukkah_months[8])
        hanukkah_end_year = int(self.hanukkah_years[8])

        hanukkah_start = datetime.date(hanukkah_start_year,
                                       hanukkah_start_month,
                                       hanukkah_start_day)
        hanukkah_end = datetime.date(hanukkah_end_year, hanukkah_end_month,
                                     hanukkah_end_day)
        today = datetime.date.today()
        # today = datetime.date(2019, 12, 24) (for testing)
        day = str(today.day)
        month = str(today.month)
        year = str(today.year)
        embed = Embed()
        embed.title = 'Hanukkah'
        embed.colour = Colours.blue
        if day in self.hanukkah_days and month in self.hanukkah_months and year in self.hanukkah_years:
            if int(day) == hanukkah_start_day:
                now = datetime.datetime.utcnow()
                now = str(now)
                hours = int(now[11:13]) + 4  # using only hours
                hanukkah_start_hour = 18
                if hours < hanukkah_start_hour:
                    embed.description = (
                        f"Hanukkah hasnt started yet, "
                        f"it will start in about {hanukkah_start_hour-hours} hour/s."
                    )
                    return await ctx.send(embed=embed)
                elif hours > hanukkah_start_hour:
                    embed.description = (
                        f'It is the starting day of Hanukkah ! '
                        f'Its been {hours-hanukkah_start_hour} hours hanukkah started !'
                    )
                    return await ctx.send(embed=embed)
            festival_day = self.hanukkah_days.index(day)
            number_suffixes = ['st', 'nd', 'rd', 'th']
            suffix = ''
            if int(festival_day) == 1:
                suffix = number_suffixes[0]
            if int(festival_day) == 2:
                suffix = number_suffixes[1]
            if int(festival_day) == 3:
                suffix = number_suffixes[2]
            if int(festival_day) > 3:
                suffix = number_suffixes[3]
            message = ''
            for _ in range(1, festival_day + 1):
                message += ':menorah:'
            embed.description = f'It is the {festival_day}{suffix} day of Hanukkah ! \n {message}'
            await ctx.send(embed=embed)
        else:
            if today < hanukkah_start:
                festival_starting_month = hanukkah_start.strftime('%B')
                embed.description = (
                    f"Hanukkah has not started yet. "
                    f"Hanukkah will start at sundown on {hanukkah_start_day}th "
                    f"of {festival_starting_month}.")
            else:
                festival_end_month = hanukkah_end.strftime('%B')
                embed.description = (
                    f"Looks like you missed Hanukkah !"
                    f"Hanukkah ended on {hanukkah_end_day}th of {festival_end_month}."
                )

            await ctx.send(embed=embed)
Esempio n. 10
0
    async def _item(self, ctx, user_id, channel_id, item_name, mentions, conn,
                    cur, bot):  # アイテム関連の関数。
        try:  # ERRORが起きるか起きないか。起きたらexceptに飛ばされる
            if not item_name:  # item_nameが空だった場合
                # アイテムを所持してるかの確認。アイテムはitem_idで登録してるので名前をall_dataファイルのitem_lists変数から引っ張ってきます。
                await cur.execute(
                    "select distinct item_id,count FROM item WHERE user_id=? ORDER BY item_id;",
                    (user_id, ))
                i_list = ''.join(f'{item_lists[i[0]]} : {i[1]}個\n'
                                 for i in await cur.fetchall())
                msgs = list(
                    filter(lambda a: a != "", [
                        "\n".join(i_list.split("\n")[i:i + 25])
                        for i in range(0, len(i_list), 25)
                    ]))  # 今後アイテムが増えた場合に25個のデータ(重複なし)でページ分け

                embeds = [
                    Embed(description=f"```{i if i else 'アイテムを所持していません。'}```").
                    set_thumbnail(url=ctx.author.avatar_url_as()).set_author(
                        name=f"{ctx.author}のステータス:") for i in msgs
                ]
                msg = await ctx.send(
                    content=
                    f"```diff\n1ページ/{len(embeds)}ページ目を表示中\n見たいページを発言してください。\n30秒経ったら処理は止まります。\n0と発言したら強制的に処理は止まります。```",
                    embed=embeds[0])
                while True:  # 処理が終わる(return)まで無限ループ
                    try:  # ERRORが起きるか起きないか。起きたらexceptに飛ばされる
                        msg_react = await bot.wait_for(
                            'message',
                            check=lambda m: m.author == ctx.author and m.
                            content.isdigit() and 0 <= int(m.content) <= len(
                                embeds),
                            timeout=30)
                        # await self.bot.wait_for('message')で返ってくるのは文字列型
                        if msg_react.content == "0":
                            # このcontentの中にはゼロ幅スペースが入っています。Noneでもいいのですが編集者はこっちの方が分かりやすいからこうしています。
                            return await msg.edit(content="‌")
                        await msg.edit(
                            content=
                            f"```diff\n{int(msg_react.content)}ページ/{len(embeds)}ページ目を表示中\n見たいページを発言してください。\n30秒経ったら処理は止まります。\n0と発言したら強制的に処理は止まります。```",
                            embed=embeds[int(msg_react.content) - 1])
                    except asyncio.TimeoutError:  # wait_forの時間制限を超過した場合
                        # このcontentの中にはゼロ幅スペースが入っています。Noneでもいいのですが編集者はこっちの方が分かりやすいからこうしています。
                        return await msg.edit(content="‌",
                                              embed=Embed(title=f"時間切れです..."))

            if item_name in ["e", "elixir", "エリクサー"
                             ]:  # item_nameが["e", "elixir", "エリクサー"]の中のどれかだったら
                return await ctx.send(await elixir(user_id, channel_id, conn,
                                                   cur))
            elif item_name in [
                    "f", "fire", "ファイアボールの書"
            ]:  # item_nameが["f", "fire", "ファイアボールの書"]の中のどれかだったら
                return await Database().fireball(ctx, user_id, channel_id,
                                                 conn, cur, bot)
            elif item_name in ["p", "pray", "祈りの書"
                               ]:  # item_nameが["p", "pray", "祈りの書"]の中のどれかだったら
                return await ctx.send(await pray(ctx, user_id, channel_id,
                                                 mentions, conn, cur, bot))
            else:  # item_nameでアイテムが存在してなかった場合
                return await ctx.send(
                    embed=Embed(title=f"!?", description="そのアイテムは存在しません。"))

        except (NotFound, asyncio.TimeoutError, Forbidden
                ):  # 編集した際に文字が見つからなかった, wait_forの時間制限を超過した場合, メッセージに接続できなかった
            return
        except:  # 上のERROR以外のERROR出た場合はtracebackで表示するようにしています。 上手くコマンドが反応しない場合はコンソールを見てね!
            return print("エラー情報\n" + traceback.format_exc())
Esempio n. 11
0
 def _get_error_embed(self, title: str, body: str) -> Embed:
     """Return an embed that contains the exception."""
     return Embed(title=title, colour=Colours.soft_red, description=body)
Esempio n. 12
0
    async def maps(self, ctx, searches="", rotation_maps=True):
        """
        Lists all maps  in rotation when no searches are provided
        Searches for maps when searches are given
        """
        await ctx.defer()
        with open("utils/maps.json") as file:
            maps = load(file)
        map_str = list()
        args = list(map(lambda x: x.strip(), filter(None, searches.lower().split(","))))

        if not rotation_maps: #Merg
            with open("utils/all_maps.json") as file:
                all_maps = load(file)
                maps = {**maps, **all_maps}

        list_maps = None
        if not searches:
            list_maps = list(maps.items())
        else:
            list_maps = []
            for search in args:
                for k, v in maps.items():
                    if search in k.lower() or search in str(v):
                        if [k, v] not in list_maps: #Only adds new elements so no dupes
                            list_maps.append([k, v])

        amount = len(list_maps) #Amount of maps found

        if not list_maps: #No results
            return await error_embed(ctx,"No maps found. Did you forget to separate maps with commas (blackout, pagodas III)?")

        if len(list_maps) == 1: #Image for single search result
            map_id = list_maps[0][1]
            map_name = list_maps[0][0]

            if os.path.exists(f"assets/map_screenshots/{map_id}.jpg"):
                file = File(f"assets/map_screenshots/{map_id}.jpg", filename=f"{map_id}.png")
                embed = Embed(title="Maps Found:", description=f"[{map_name}](https://www.brawl.com/games/ctf/maps/{map_id}) ({map_id})",
                  color=Colour.dark_purple())
                embed.set_image(url=f"attachment://{map_id}.png")
                response = await ctx.send("Fetching maps...")
                await response.edit(content="Done!")
                await ctx.channel.send(embed=embed, file=file)
            else: #Handling single search results without an image
                embed = Embed(title="Maps Found:",
                              description=f"[{map_name}](https://www.brawl.com/games/ctf/maps/{map_id}) ({map_id})",
                              color=Colour.dark_purple())
                embed.set_footer(text="This map has no image yet :(")
                response = await ctx.send("Fetching maps...")
                await response.edit(content="Done!")
                await ctx.channel.send(embed=embed)
            return
        
        for (map_name, map_id) in list_maps:
            map_str.append(f"[{map_name}](https://www.brawl.com/games/ctf/maps/{map_id}) ({map_id})")
        if len(list_maps)>5: #Sort maps by name but only for >5 results otherwise match string gets scuffed
            map_str = sorted(map_str)
        if len(list_maps) <= 5 and len(list_maps) != 0:  # Shows map ids only if there are 3 results
            map_str.append(f"\n*For match server:*\n`{' '.join(str(item[1]) for item in list_maps)}`")

        await create_list_pages(self.bot, ctx, f"Maps Found ({amount}):", map_str, "No Maps were found", random_item=True)
Esempio n. 13
0
class VerificationCog(Cog, name="Verification"):
    def __init__(self, bot: Bot):
        self.bot = bot

    @commands.command()
    @private_only
    async def verify(self, ctx: Context, *, password: str):
        correct_password: str = await Settings.get(str,
                                                   "verification_password")
        if correct_password is None:
            raise CommandError(translations.verification_disabled)

        if password != correct_password:
            raise CommandError(translations.password_incorrect)

        guild: Guild = self.bot.guilds[0]
        member: Member = guild.get_member(ctx.author.id)

        delay: int = await Settings.get(int, "verification_delay", -1)
        if delay != -1 and (datetime.utcnow() -
                            member.joined_at).total_seconds() < delay:
            raise CommandError(translations.password_incorrect)

        add: List[Role] = []
        remove: List[Role] = []
        fail = False
        for vrole in await db_thread(
                db.all, VerificationRole):  # type: VerificationRole
            role: Optional[Role] = guild.get_role(vrole.role_id)
            if role is None:
                continue

            if vrole.reverse:
                if role in member.roles:
                    remove.append(role)
                else:
                    fail = True
            elif not vrole.reverse and role not in member.roles:
                add.append(role)
        if not add and not remove:
            raise CommandError(translations.already_verified)
        if fail:
            raise CommandError(
                translations.verification_reverse_role_not_assigned)

        await member.add_roles(*add)
        await member.remove_roles(*remove)
        embed = Embed(title=translations.verification,
                      description=translations.verified,
                      colour=Colours.Verification)
        await ctx.send(embed=embed)

    @commands.group(aliases=["vf"])
    @Permission.manage_verification.check
    @guild_only()
    async def verification(self, ctx: Context):
        """
        configure verify command
        """

        if ctx.subcommand_passed is not None:
            if ctx.invoked_subcommand is None:
                raise UserInputError
            return

        password: str = await Settings.get(str, "verification_password")

        normal: List[Role] = []
        reverse: List[Role] = []
        for vrole in await db_thread(
                db.all, VerificationRole):  # type: VerificationRole
            role: Optional[Role] = ctx.guild.get_role(vrole.role_id)
            if role is None:
                await db_thread(db.delete, vrole)
            else:
                [normal, reverse][vrole.reverse].append(role)

        embed = Embed(title=translations.verification, colour=Colours.error)
        if password is None or not normal + reverse:
            embed.add_field(name=translations.status,
                            value=translations.verification_disabled,
                            inline=False)
            await ctx.send(embed=embed)
            return

        embed.colour = Colours.Verification
        embed.add_field(name=translations.status,
                        value=translations.verification_enabled,
                        inline=False)
        embed.add_field(name=translations.password,
                        value=f"`{password}`",
                        inline=False)

        delay: int = await Settings.get(int, "verification_delay", -1)
        val = translations.f_x_seconds(
            delay) if delay != -1 else translations.disabled
        embed.add_field(name=translations.delay, value=val, inline=False)

        if normal:
            embed.add_field(
                name=translations.roles_normal,
                value="\n".join(f":small_orange_diamond: {role.mention}"
                                for role in normal),
            )
        if reverse:
            embed.add_field(
                name=translations.roles_reverse,
                value="\n".join(f":small_blue_diamond: {role.mention}"
                                for role in reverse),
            )

        await ctx.send(embed=embed)

    @verification.command(name="add", aliases=["a", "+"])
    async def verification_add(self,
                               ctx: Context,
                               role: Role,
                               reverse: bool = False):
        """
        add verification role
        if `reverse` is set to `true`, the role is not added but removed during verification.
        the `verify` command will fail if the user does not have the role.
        """

        if role >= ctx.me.top_role:
            raise CommandError(
                translations.f_role_not_set_too_high(role, ctx.me.top_role))
        if role.managed:
            raise CommandError(translations.f_role_not_set_managed_role(role))

        if await db_thread(db.get, VerificationRole, role.id) is not None:
            raise CommandError(translations.verification_role_already_set)

        await db_thread(VerificationRole.create, role.id, reverse)
        embed = Embed(
            title=translations.verification,
            description=translations.verification_role_added,
            colour=Colours.Verification,
        )
        await ctx.send(embed=embed)
        if reverse:
            await send_to_changelog(
                ctx.guild,
                translations.f_log_verification_role_added_reverse(
                    role.name, role.id))
        else:
            await send_to_changelog(
                ctx.guild,
                translations.f_log_verification_role_added(role.name, role.id))

    @verification.command(name="remove", aliases=["r", "-"])
    async def verification_remove(self, ctx: Context, *, role: Role):
        """
        remove verification role
        """

        if (row := await db_thread(db.get, VerificationRole, role.id)) is None:
            raise CommandError(translations.verification_role_not_set)

        await db_thread(db.delete, row)
        embed = Embed(
            title=translations.verification,
            description=translations.verification_role_removed,
            colour=Colours.Verification,
        )
        await ctx.send(embed=embed)
        await send_to_changelog(
            ctx.guild,
            translations.f_log_verification_role_removed(role.name, role.id))
Esempio n. 14
0
def redEmbed(descr):
    return Embed(description=descr,
                 colour=discord.Colour.from_rgb(255, 25, 25))
Esempio n. 15
0
async def main(client):
    with db:
        top_members_limit = ClubUser.top_members_limit()
        pin_reactions_by_members = [
            pin_reaction for pin_reaction in ClubPinReaction.listing()
            if pin_reaction.user.is_member
        ]

    log.info(
        f'Found {len(pin_reactions_by_members)} pin reactions by people who are currently members'
    )
    for pin_reaction in pin_reactions_by_members:
        member = await client.juniorguru_guild.fetch_member(
            pin_reaction.user.id)

        if member.dm_channel:
            channel = member.dm_channel
        else:
            channel = await member.create_dm()

        log.info(
            f"Checking DM if already pinned for {member.display_name} #{member.id}"
        )
        if await is_pinned(pin_reaction.message.url, channel):
            log.info(f"Already pinned for {member.display_name} #{member.id}")
            continue

        log.info(
            f"Not pinned for {member.display_name} #{member.id}, sending a message to DM"
        )
        if DISCORD_MUTATIONS_ENABLED:
            content = (
                '📌 Vidím špendlík! Ukládám ti příspěvek sem, do soukromé zprávy. '
                f'Když bude mít ~{top_members_limit} špendlíků, připnu jej v původním kanálu pro všechny.'
            )
            embed_description = [
                f"{pin_reaction.message.author.mention} v {pin_reaction.message.channel_mention}:",
                f"> {textwrap.shorten(pin_reaction.message.content, 500, placeholder='…')}",
                f"[Hop na příspěvek]({pin_reaction.message.url})",
                "",
            ]
            await channel.send(
                content=content,
                embed=Embed(description="\n".join(embed_description)))
        else:
            log.warning(
                "Skipping Discord mutations, DISCORD_MUTATIONS_ENABLED not set"
            )

    log.info(
        f"Going through messages pinned by reactions, minimum is {top_members_limit} pin reactions"
    )
    with db:
        messages = ClubMessage.pinned_by_reactions_listing(top_members_limit)
    log.info(f'Found {len(messages)} messages')
    for message in messages:
        log.info(
            f"Message {message.url} {'PINNED' if message.is_pinned else 'NOT PINNED'}"
        )
        if not message.is_pinned:
            log.info(f"Pinning {message.url}")
            channel = await client.fetch_channel(message.channel_id)
            discord_message = await channel.fetch_message(message.id)
            await discord_message.pin(
                reason=
                f"The message has {message.pin_reactions_count} pin reactions, minimum is {top_members_limit}"
            )
Esempio n. 16
0
    def response_embed(self, response, success=True):
        embed = Embed(description=response,
                      color=0x00ff00 if success else 0xff0000)
        embed.set_author(name='UoM Esports Bot', icon_url=self.user.avatar_url)

        return embed
Esempio n. 17
0
 def embed(self):
     return Embed(title="Error", description=self.msg, color=Color.red())
Esempio n. 18
0
    async def on_ready(self):
        # output information about the bot's login
        log('Logged in as {0}, {0.id}'.format(self.user))

        # command prefix
        self.command_prefix = self.config.get('general', 'command_prefix')

        # read guild variable ids from the config file and intialise them as global variables
        self.guild = self.get_guild(int(self.config.get('general', 'guild')))

        # bot name
        await self.guild.me.edit(nick=self.config.get('general', 'name'))

        # channels
        self.bot_channel = self.guild.get_channel(
            int(self.config.get('channels', 'bot')))
        self.admin_channel = self.guild.get_channel(
            int(self.config.get('channels', 'admin')))
        self.stream_channel = self.guild.get_channel(
            int(self.config.get('channels', 'stream')))

        self.streaming = None

        # roles
        self.admin_role = find(
            lambda role: role.id == int(self.config.get('roles', 'admin')),
            self.guild.roles)
        self.member_role = find(
            lambda role: role.id == int(self.config.get('roles', 'member')),
            self.guild.roles)
        self.guest_role = find(
            lambda role: role.id == int(self.config.get('roles', 'guest')),
            self.guild.roles)
        self.first_strike_role = find(
            lambda role: role.id == int(
                self.config.get('roles', 'first_strike')), self.guild.roles)
        self.second_strike_role = find(
            lambda role: role.id == int(
                self.config.get('roles', 'second_strike')), self.guild.roles)

        with open('roles.txt', 'w') as f:
            for role in self.guild.roles:
                f.write('{0.name} {0.id}\n'.format(role))

        # produce the list of commands
        self.commands = {}
        for att in dir(self):
            attr = getattr(self, att, None)
            if hasattr(attr, 'bot_command'):
                self.commands[att] = {
                    'cmd': attr,
                    'admin_only': attr.admin_only,
                    'embed': self.cmd_embed(attr)
                }

        # maintain the bots presence
        asyncio.ensure_future(self.maintain_presence())

        # check the unbans
        asyncio.ensure_future(self.check_unbans())

        # generate the help embeds
        self.help_embed = Embed(title='Commands',
                                color=self.member_role.colour)
        self.help_embed.set_author(name='UoM Esports Bot',
                                   icon_url=self.user.avatar_url)
        for category in ['General', 'Games', 'Roles']:
            self.help_embed.add_field(
                name=category,
                value='\n'.join([
                    '{}{}'.format(self.command_prefix, command)
                    for command in self.commands
                    if not self.commands[command]['admin_only']
                    and self.commands[command]['cmd'].category == category
                ]),
            )
        self.help_embed.set_footer(
            text='Type "{}help command" to get its usage.'.format(
                self.command_prefix))
        self.admin_embed = Embed(title='Admin Commands',
                                 color=self.admin_role.colour)
        self.admin_embed.set_author(name='UoM Esports Bot',
                                    icon_url=self.user.avatar_url)
        for category in ['General', 'Games', 'Roles']:
            self.admin_embed.add_field(
                name=category,
                value='\n'.join([
                    '{0}{1}{2}{0}'.format(
                        '**' if self.commands[command]['admin_only'] else '',
                        self.command_prefix, command)
                    for command in self.commands
                    if self.commands[command]['cmd'].category == category
                ]))
        self.admin_embed.set_footer(
            text=
            'Type "{}help command" to get its usage. Admin-only commands have bold formattng.'
            .format(self.command_prefix))

        # generate the game roles
        self.games = []
        for sid in self.config.get('roles', 'games').split():
            try:
                role = find(lambda role: role.id == int(sid), self.guild.roles)

                # check if role exists
                if role:
                    self.games.append(role)
                else:
                    # role doesn't exist
                    log('Couldn\'t find role with ID {}'.format(sid))
            except Exception as ex:
                log('Unhandled {} while reading in role ID {}: {}'.format(
                    ex.__class__.__name__, sid, ex))

        # write out working game roles to the config file
        self.config.set('roles', 'games',
                        ' '.join([str(role.id) for role in self.games]))
        self.write_config()

        # ready to go!
        log('------')
        self.ready.set()
Esempio n. 19
0
def help_embed() -> Embed:
    return Embed(title="MiniMaid Help",
                 description=HELP_MESSAGE,
                 colour=Colour.blue())
Esempio n. 20
0
    async def _clean_messages(
        self,
        amount: int,
        ctx: Context,
        channels: Iterable[TextChannel],
        bots_only: bool = False,
        user: User = None,
        regex: Optional[str] = None,
        until_message: Optional[Message] = None,
    ) -> None:
        """A helper function that does the actual message cleaning."""
        def predicate_bots_only(message: Message) -> bool:
            """Return True if the message was sent by a bot."""
            return message.author.bot

        def predicate_specific_user(message: Message) -> bool:
            """Return True if the message was sent by the user provided in the _clean_messages call."""
            return message.author == user

        def predicate_regex(message: Message) -> bool:
            """Check if the regex provided in _clean_messages matches the message content or any embed attributes."""
            content = [message.content]

            # Add the content for all embed attributes
            for embed in message.embeds:
                content.append(embed.title)
                content.append(embed.description)
                content.append(embed.footer.text)
                content.append(embed.author.name)
                for field in embed.fields:
                    content.append(field.name)
                    content.append(field.value)

            # Get rid of empty attributes and turn it into a string
            content = [attr for attr in content if attr]
            content = "\n".join(content)

            # Now let's see if there's a regex match
            if not content:
                return False
            else:
                return bool(re.search(regex.lower(), content.lower()))

        # Is this an acceptable amount of messages to clean?
        if amount > CleanMessages.message_limit:
            embed = Embed(
                color=Colour(Colours.soft_red),
                title=random.choice(NEGATIVE_REPLIES),
                description=f"You cannot clean more than {CleanMessages.message_limit} messages."
            )
            await ctx.send(embed=embed)
            return

        # Are we already performing a clean?
        if self.cleaning:
            embed = Embed(
                color=Colour(Colours.soft_red),
                title=random.choice(NEGATIVE_REPLIES),
                description="Please wait for the currently ongoing clean operation to complete."
            )
            await ctx.send(embed=embed)
            return

        # Set up the correct predicate
        if bots_only:
            predicate = predicate_bots_only      # Delete messages from bots
        elif user:
            predicate = predicate_specific_user  # Delete messages from specific user
        elif regex:
            predicate = predicate_regex          # Delete messages that match regex
        else:
            predicate = None                     # Delete all messages

        # Default to using the invoking context's channel
        if not channels:
            channels = [ctx.channel]

        # Delete the invocation first
        self.mod_log.ignore(Event.message_delete, ctx.message.id)
        await ctx.message.delete()

        messages = []
        message_ids = []
        self.cleaning = True

        # Find the IDs of the messages to delete. IDs are needed in order to ignore mod log events.
        for channel in channels:
            async for message in channel.history(limit=amount):

                # If at any point the cancel command is invoked, we should stop.
                if not self.cleaning:
                    return

                # If we are looking for specific message.
                if until_message:

                    # we could use ID's here however in case if the message we are looking for gets deleted,
                    # we won't have a way to figure that out thus checking for datetime should be more reliable
                    if message.created_at < until_message.created_at:
                        # means we have found the message until which we were supposed to be deleting.
                        break

                    # Since we will be using `delete_messages` method of a TextChannel and we need message objects to
                    # use it as well as to send logs we will start appending messages here instead adding them from
                    # purge.
                    messages.append(message)

                # If the message passes predicate, let's save it.
                if predicate is None or predicate(message):
                    message_ids.append(message.id)

        self.cleaning = False

        # Now let's delete the actual messages with purge.
        self.mod_log.ignore(Event.message_delete, *message_ids)
        for channel in channels:
            if until_message:
                for i in range(0, len(messages), 100):
                    # while purge automatically handles the amount of messages
                    # delete_messages only allows for up to 100 messages at once
                    # thus we need to paginate the amount to always be <= 100
                    await channel.delete_messages(messages[i:i + 100])
            else:
                messages += await channel.purge(limit=amount, check=predicate)

        # Reverse the list to restore chronological order
        if messages:
            messages = reversed(messages)
            log_url = await self.mod_log.upload_log(messages, ctx.author.id)
        else:
            # Can't build an embed, nothing to clean!
            embed = Embed(
                color=Colour(Colours.soft_red),
                description="No matching messages could be found."
            )
            await ctx.send(embed=embed, delete_after=10)
            return

        # Build the embed and send it
        target_channels = ", ".join(channel.mention for channel in channels)

        message = (
            f"**{len(message_ids)}** messages deleted in {target_channels} by "
            f"{ctx.author.mention}\n\n"
            f"A log of the deleted messages can be found [here]({log_url})."
        )

        await self.mod_log.send_log_message(
            icon_url=Icons.message_bulk_delete,
            colour=Colour(Colours.soft_red),
            title="Bulk message delete",
            text=message,
            channel_id=Channels.mod_log,
        )
Esempio n. 21
0
async def _inspire(ctx: Context):
    embed = Embed()
    embed.set_image(
        url=requests.get("https://inspirobot.me/api?generate=true").text)
    return await ctx.send(embed=embed)
Esempio n. 22
0
File: asahi.py Progetto: cmyui/Asahi
        if user.priv & Privileges.Disallowed:
            return await ctx.send('This user is banned/restricted!')

        m = 0

        if '-m' in args:
            m = int(args[args.index('-m') + 1])

        if '-rx' in args: rx = Mods.RELAX
        elif '-ap' in args: rx = Mods.AUTOPILOT
        else: rx = Mods.NOMOD

        mode = lbModes(m, rx)
        stats = user.stats[mode.value]

        embed = Embed(title='')
        embed.set_author(
            name=
            f'{mode!r} profile for {user.full_name} - {stats.pp}pp (#{stats.rank} // {user.country_iso.upper()}#{stats.country_rank})',
            url=f'https://{glob.config.domain}/u/{user.id}',
            icon_url=f'https://countryflags.io/{user.country_iso}/flat/64.png')
        embed.set_thumbnail(url=f'https://a.{glob.config.domain}/{user.id}')

        # TODO: finish embed lol
        return await ctx.send(embed=embed)


def setup(bot) -> None:
    bot.add_cog(asahiBot(bot))
    async def ln(self, args, mobj):
        try:
            """
            Does a AniList search to find requested Light Novel.
            
            If there are multiple options, will ask you which one to choose. You will have 10 seconds to respond.
            
            Will not return any adult series.
            """
            args = " ".join(args)
            result = await self.ani_get_options(args, mobj, 'LN')
            if result:
                manga = self.anilist.getMangaDetailsById(result)
            else:
                manga = self.anilist.getMangaDetails(args)

            if not manga:
                await self.error(mobj.channel, "Could not find anything")
                return
            embed = Embed(
                title=manga['title_english']
                if manga['title_english'] else manga['title_romaji']
                if manga['title_romaji'] else manga['title_japanese'],
                colour=Color(0x7289da),
                url=
                f"https://anilist.co/manga/{manga['id']}/{manga['title_romaji']}"
                .replace(" ", "%20"))
            # embed.set_author(name=author.display_name, icon_url=avatar)
            embed.set_image(url=manga['img'])
            embed.add_field(
                name="Length",
                value=
                f'{manga["total_chapters"] if manga["total_chapters"] else 0} Chapters, {manga["total_volumes"] if manga["total_volumes"] else 0} Volumes'
            )
            embed.add_field(name="Type", value=manga["type"])
            embed.add_field(name="Status", value=manga["airing_status"])
            embed.add_field(
                name="Dates",
                value=
                f'{manga["start_date"]} through {manga["end_date"] if manga["end_date"] != "None-None-None" else "present"}'
                if manga["start_date"] != manga["end_date"] else
                f'{manga["start_date"]}')

            if manga["synonyms"]:
                embed.add_field(name="Synonyms",
                                value=", ".join(manga["synonyms"]))

            if manga["description"] is None:
                manga["description"] = "Could not pull synopsis"
            manga["description"] = re.sub(
                r'\n\s*\n', '\n\n',
                unescape(manga["description"]).replace("<br>", "\n"))
            if len(manga["description"]) > 1000:
                if "\n" in manga["description"][:965]:
                    manga["description"] = manga[
                        "description"][:manga["description"][:965].rfind("\n")]
                else:
                    manga["description"] = manga["description"][:965]
                manga["description"] += "\nIncomplete synopsis due to length."

            embed.add_field(name="Synopsis", value=manga["description"])

            try:
                await self.embed(mobj.channel, embed)
            except BaseException:
                await self.error(
                    mobj.channel,
                    "Something when trying to format the object. Here is a link to the manga: "
                    + "https://myanimelist.net/manga/{0.id}/{0.title}".format(
                        manga).replace(" ", "%20"))
        except Exception as e:
            exc_type, exc_obj, exc_tb = sys.exc_info()
            fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
            print(exc_type, fname, exc_tb.tb_lineno)
async def action(**kwargs):
    event_type = kwargs['event_type']
    config = kwargs['config']
    client = kwargs['client']

    if event_type == 'member.unban':
        # Grab configuration values
        admin_server_id = config.getint('banpool', 'admin_server_id')
        admin_chan_name = config.get('banpool', 'admin_chan')
        admin_server = discord.utils.get(client.guilds, id=admin_server_id)
        admin_chan = discord.utils.get(admin_server.channels, name=admin_chan_name)

        user = kwargs['user']
        guild = kwargs['guild']

        try:
            result = banpool_manager.is_user_banned(user.id)

            # User is in banpool, so we need to add an exception
            if result[1]:
                logger.debug("member_unban event was caught for banpool ID: {}".format(user.id))
                banpool_manager.add_user_to_exceptions(user.id, guild.id)

                unban_embed = Embed(title="User Exception Added", color=Color.orange())
                unban_embed.add_field(name="User Name", value=user.name + "#" + str(user.discriminator), inline=False)
                unban_embed.add_field(name="Server ID", value=guild.id, inline=True)
                unban_embed.add_field(name="User ID", value=user.id, inline=True)
                unban_embed.set_footer(icon_url=guild.icon_url, text=guild.name)

                await admin_chan.send(embed=unban_embed)

                # check if the server has an announce channel set, if so, announce the ban
                announce_chan_id = banpool_config.get_announce_chan(guild.id)

                if announce_chan_id:
                    announce_chan = discord.utils.get(guild.channels, id=announce_chan_id)
                    announce_embed = Embed(title="User Exception Added", color=Color.orange())
                    announce_embed.add_field(name="User Name", value=user.name + "#" + str(user.discriminator), inline=True)
                    announce_embed.add_field(name="User Profile", value=f"<@{user.id}>", inline=False)
                    announce_embed.add_field(name="User ID", value=user.id, inline=False)
                    await announce_chan.send(embed=announce_embed)
        except:
            logger.error(traceback.format_exc())

    if event_type == 'member.join':
        # Grab configuration values
        admin_server_id = config.getint('banpool', 'admin_server_id')
        admin_chan_name = config.get('banpool', 'admin_chan')

        admin_server = discord.utils.get(client.guilds, id=admin_server_id)
        admin_chan = discord.utils.get(admin_server.channels, name=admin_chan_name)
        member = kwargs['member']
        guild = member.guild

        try:
            result = banpool_manager.is_user_banned(member.id)

            # The member is banpooled and we might need to ban them
            if result[1]:
                # check if the guild is subscribed to any banpool the user is in
                banpool_list = [p for p in result[0]]

                is_subscribed = False
                for pool in banpool_list:
                    check_subscription = banpool_config.is_guild_subscribed(guild.id, pool)

                    if check_subscription:
                        is_subscribed = True
                        target_pool = pool

                if is_subscribed:
                    banpool_name = target_pool
                    reason = result[0][target_pool].reason
                    logger.debug('member_join was caught for banpool ID: {}'.format(member.id))
                    user_id = member.id
                    user_name = member.name
                    user_discriminator = member.discriminator
                    server_id = member.guild.id

                    is_exception = banpool_manager.is_user_in_exceptions(user_id, server_id)

                    bot_perms = admin_chan.permissions_for(member.guild.me)

                    if not is_exception and bot_perms.ban_members:
                        logger.debug('member joined is in the banpool and has no exceptions: {}'.format(member.id))
                        banpool_manager.set_last_knowns(user_id, user_name, user_discriminator)

                        ban_embed = Embed(title="User Banned on Join", color=Color.green())
                        ban_embed.add_field(name="User Name", value=user_name + "#" + str(user_discriminator), inline=False)
                        ban_embed.add_field(name="Server ID", value=guild.id, inline=True)
                        ban_embed.add_field(name="User ID", value=user_id, inline=True)
                        ban_embed.add_field(name="Banpool Name", value=banpool_name, inline=False)
                        ban_embed.add_field(name="Ban Reason", value=reason, inline=False)
                        ban_embed.set_footer(icon_url=guild.icon_url, text=guild.name)
                        await admin_chan.send(embed=ban_embed)

                        # check if the server has an announce channel set, if so, announce the ban
                        announce_chan_id = banpool_config.get_announce_chan(guild.id)

                        if announce_chan_id:
                            announce_chan = discord.utils.get(guild.channels, id=announce_chan_id)
                            announce_embed = Embed(title="User Banned on Join", color=Color.green())
                            announce_embed.add_field(name="User Name", value=member.name + "#" + str(member.discriminator), inline=True)
                            announce_embed.add_field(name="Nickname", value=member.nick, inline=True)
                            announce_embed.add_field(name="User Profile", value=f"<@{member.id}>", inline=False)
                            announce_embed.add_field(name="User ID", value=user_id, inline=False)
                            announce_embed.set_footer(icon_url=guild.icon_url, text="See Admin Mains for more details")
                            await announce_chan.send(embed=announce_embed)

                        await guild.ban(member, reason="Banpool Bot [{}] - {}".format(banpool_name, reason))
        except:
            logger.error(traceback.format_exc())
Esempio n. 25
0
    async def ranking(self, ctx): #既に存在する関数名だったらERROR出るのでもし今後コマンドを追加するならコマンド名と同じ関数名にして下さい。
        f"""
        各種ランキングの表示
        各種100位まで表示するようにしております。
        10位ごとに勝手にページが分けられます。
        f"""
        try: # ERRORが起きるか起きないか。起きたらexceptに飛ばされる
            bot = self.bot
            r_dict = {'0⃣': "プレイヤーランキング", '1⃣': "BOTランキング",  '2⃣': "鯖ランキング"}
          # sqlite_listの中からデータベースに接続したというオブジェクトを取得
            _, conn, cur = [sql for sql in self.bot.sqlite_list if ctx.author.id == sql[0]][0]
            msg = await ctx.send(embed=Embed(description="\n".join([f"{r[0]}:`{r[1]}`" for r in list(r_dict.items())]) + "\n見たい番号を発言してください。").set_author(name="Ranking一覧:"))
            msg_react = await self.bot.wait_for('message', check=lambda message: message.author == ctx.author and message.content.isdigit() and 0 <= int(message.content) <= len(list(r_dict.keys())) - 1, timeout=10)
          # await self.bot.wait_for('message')で返ってくるのは文字列型
            if msg_react.content == "0":
              # ユーザーはisbotの中身を0で登録してるのでそこで判断して全データを取得させます。
                await cur.execute("select distinct user_id, exp FROM player WHERE isbot =0 ORDER BY exp DESC;")
                players_rank = "\n".join(["{0}位:[`{1}`] (Lv{2})".format(k, bot.get_user(member[0]), int(math.sqrt(member[1]))) for member, k in zip(await cur.fetchall(), range(1, 101))])
              # データ10個ごとにページ分け
                ranking_msgs = ["\n".join(players_rank.split("\n")[i:i + 10]) for i in range(0, 100, 10)]
                author = "世界Top100プレイヤー"
            elif msg_react.content == "1":
              # BOTはisbotの中身を1で登録してるのでそこで判断して全データを取得させます。
                await cur.execute("select distinct user_id, exp FROM player WHERE isbot=1 ORDER BY exp DESC;")
                players_rank = "\n".join(["{0}位:[`{1}`] (Lv{2})".format(k, bot.get_user(member[0]), int(math.sqrt(member[1]))) for member, k in zip(await cur.fetchall(), range(1, 101))])
              # データ10個ごとにページ分け
                ranking_msgs = ["\n".join(players_rank.split("\n")[i:i + 10]) for i in range(0, 100, 10)]
                author = "世界Top100ボット"
            else:
                server_id = []
              # チャンネルのレベル(昇順)にリストを取得します
              # if not [cc for cc in server_id if c[0] in cc] => 既に鯖がリストに入ってる場合は無視するための処理です
              # bot.get_guild(c[0]) => その鯖をBOTが取得できるかの処理です。取得できなかった場合はその鯖の情報は無視されます。
                await cur.execute('select distinct server_id, boss_level FROM channel_status ORDER BY boss_level DESC;')
                [server_id.append(c) for c in await cur.fetchall() if not [cc for cc in server_id if c[0] in cc] and bot.get_guild(c[0])]
                players_rank = "".join(["{0}位:[`{1}`] (Lv{2})\n".format(k, bot.get_guild(c[0]), c[1]) for c, k in zip(server_id, range(1, 101))])
              # データ10個ごとにページ分け
                ranking_msgs = ["\n".join(players_rank.split("\n")[i:i + 10]) for i in range(0, 100, 10)]
                author = "世界Top100サーバー"

            if not list(filter(lambda a: a != '', ranking_msgs)):
                return await ctx.send(embed=Embed(description="まだデータはないようだ..."))

            embeds = []
            for embed in list(filter(lambda a: a != '', ranking_msgs)):
                embeds.append(Embed(description=embed).set_author(name=author))

            await msg.edit(content=f"```diff\n1ページ/{len(embeds)}ページ目を表示中\n見たいページを発言してください。\n30秒経ったら処理は止まります。\n0と発言したら強制的に処理は止まります。```", embed=embeds[0])
            while True: # 処理が終わる(return)まで無限ループ
                try: # ERRORが起きるか起きないか。起きたらexceptに飛ばされる
                    msg_react = await self.bot.wait_for('message', check=lambda m: m.author == ctx.author and m.content.isdigit() and 0 <= int(m.content) <= len(embeds), timeout=30)
                  # await self.bot.wait_for('message')で返ってくるのは文字列型
                    if msg_react.content == "0":
                      # このcontentの中にはゼロ幅スペースが入っています。Noneでもいいのですが編集者はこっちの方が分かりやすいからこうしています。
                        return await msg.edit(content="‌")
                    await msg.edit(content=f"```diff\n{int(msg_react.content)}ページ/{len(embeds)}ページ目を表示中\n見たいページを発言してください。\n30秒経ったら処理は止まります。\n0と発言したら強制的に処理は止まります。```", embed=embeds[int(msg_react.content)-1])
                except asyncio.TimeoutError: # wait_forの時間制限を超過した場合
                  # このcontentの中にはゼロ幅スペースが入っています。Noneでもいいのですが編集者はこっちの方が分かりやすいからこうしています。
                    return await msg.edit(content="‌", embed=Embed(title=f"時間切れです..."))

        except (NotFound, asyncio.TimeoutError, Forbidden): # 編集した際に文字が見つからなかった, wait_forの時間制限を超過した場合, メッセージに接続できなかった
            return
        except: # 上のERROR以外のERROR出た場合はtracebackで表示するようにしています。 上手くコマンドが反応しない場合はコンソールを見てね!
            return print("エラー情報\n" + traceback.format_exc())
Esempio n. 26
0
    async def server(self, ctx: Context) -> None:
        """
        Returns information about the guild the command was run in.
        Information included:
        - A brief server description
        - Server icon
        - Date server was created (and how long ago that was)
        - Human member count
        - Bot count
        - How many members are online/offline
        - Current server owner
        - Boost information
        """
        # Save guild to variable instead of using `ctx.message.guild` each time
        guild: Guild = ctx.message.guild

        # Calculate when the guild was created and how long ago that was and present it in a human-friendly format
        now: datetime = datetime.utcnow()
        delta: relativedelta = abs(relativedelta(now, guild.created_at))
        humanized: str = humanize_delta(delta)
        created_at: str = guild.created_at.strftime('%d %B %Y')
        created_ago: str = f'{humanized} ago'

        # Get guild's icon
        icon: str = guild.icon_url

        # Get information about the current members of the guild
        humans: int = len(
            [x for x in filter(lambda member: not member.bot, guild.members)])
        bots: int = guild.member_count - humans
        total: int = humans + bots
        invite: Invite = await self.bot.fetch_invite('discord.gg/RqPtwNxd8h')
        online: int = invite.approximate_presence_count
        offline: int = invite.approximate_member_count - invite.approximate_presence_count

        # Get owner information
        owner: str = guild.owner.mention

        # Get server boost information
        number_of_boosts: int = guild.premium_subscription_count
        boost_level: int = guild.premium_tier

        # Declare embed with all fields added
        embed = Embed(
            title='Server information',
            description='SMETCH is a community that helps those in need!',
            colour=0x00d166).add_field(
                name='Server was created on:',
                value=f'{created_at}\n{created_ago}',
                inline=False
            ).add_field(
                name='Member count:',
                value=f'👥 {humans} humans\n🤖 {bots} bots\nTotal: {total}\
                  \n<:online:832185731845062716> {online} <:offline:832185762618671164> {offline}',
                inline=False).add_field(
                    name='Current owner:', value=owner, inline=False
                ).add_field(
                    name='Current boosts:',
                    value=f'{number_of_boosts} boosts at Level {boost_level}',
                    inline=True).set_thumbnail(url=icon)

        await ctx.send(embed=embed)
        return
Esempio n. 27
0
    async def pep_command(self, ctx: Context, pep_number: str):
        """
        Fetches information about a PEP and sends it to the channel.
        """

        if pep_number.isdigit():
            pep_number = int(pep_number)
        else:
            return await ctx.invoke(self.bot.get_command("help"), "pep")

        # Newer PEPs are written in RST instead of txt
        if pep_number > 542:
            pep_url = f"{self.base_github_pep_url}{pep_number:04}.rst"
        else:
            pep_url = f"{self.base_github_pep_url}{pep_number:04}.txt"

        # Attempt to fetch the PEP
        log.trace(f"Requesting PEP {pep_number} with {pep_url}")
        response = await self.bot.http_session.get(pep_url)

        if response.status == 200:
            log.trace("PEP found")

            pep_content = await response.text()

            # Taken from https://github.com/python/peps/blob/master/pep0/pep.py#L179
            pep_header = HeaderParser().parse(StringIO(pep_content))

            # Assemble the embed
            pep_embed = Embed(
                title=f"**PEP {pep_number} - {pep_header['Title']}**",
                description=f"[Link]({self.base_pep_url}{pep_number:04})",
            )

            pep_embed.set_thumbnail(
                url="https://www.python.org/static/opengraph-icon-200x200.png")

            # Add the interesting information
            if "Status" in pep_header:
                pep_embed.add_field(name="Status", value=pep_header["Status"])
            if "Python-Version" in pep_header:
                pep_embed.add_field(name="Python-Version",
                                    value=pep_header["Python-Version"])
            if "Created" in pep_header:
                pep_embed.add_field(name="Created",
                                    value=pep_header["Created"])
            if "Type" in pep_header:
                pep_embed.add_field(name="Type", value=pep_header["Type"])

        elif response.status == 404:
            log.trace("PEP was not found")
            not_found = f"PEP {pep_number} does not exist."
            pep_embed = Embed(title="PEP not found", description=not_found)
            pep_embed.colour = Colour.red()

        else:
            log.trace(
                f"The user requested PEP {pep_number}, but the response had an unexpected status code: "
                f"{response.status}.\n{response.text}")

            error_message = "Unexpected HTTP error during PEP search. Please let us know."
            pep_embed = Embed(title="Unexpected error",
                              description=error_message)
            pep_embed.colour = Colour.red()

        await ctx.message.channel.send(embed=pep_embed)
Esempio n. 28
0
async def on_message(message):
    # if message.guild.id != 202845295158099980: return  # Testing guild
    # if message.author.id != 174406433603846145: return  # Testing stuff, stop spamming

    # check if it's even a user
    if message.author.bot:
        return

    #TEMPORARY
    if message.guild and message.guild.id == 442952794480050177:
        if message.channel.id == 693792405882929173:  # verification
            try:
                await message.delete()
            except:
                pass
            if message.content.lower() == 'i agree to the rules':
                r = discord.utils.get(message.guild.roles, id=693790666249207808)
                try:
                    await message.author.add_roles(r)
                except:
                    pass

    is_mod = await moderator_check_no_ctx(message.author, message.guild, bot)
    ck = 'censor_list'
    was_deleted = False
    if not is_mod:
        if message.guild and message.guild.id in bot.from_serversetup and bot.from_serversetup[message.guild.id][ck]:
            if any(w.lower() in bot.from_serversetup[message.guild.id][ck] for w in message.content.lower().split()):
                await message.delete()
                was_deleted = True
            if any(c in message.content.lower() for c in
                   bot.from_serversetup[message.guild.id][ck]) and not was_deleted:
                await message.delete()
                was_deleted = True

    arl = 0
    # get anti raid level
    if message.guild and message.guild.id in bot.anti_raid:
        arl = bot.anti_raid[message.guild.id]['anti_raid_level']
        if arl > 1:  # check ping count during raid levels 2 and 3
            mention_count = sum(not m.bot and m.id != message.author.id for m in message.mentions)
            if mention_count > bot.anti_raid[message.guild.id]['max_allowed_mentions']:
                return await dutils.punish_based_on_arl(arl, message, bot, mentions=True)

    # it was a dm
    if not message.guild and message.author.id != bot.config['CLIENT_ID']:
        arl = -1
        # print(f'DM LOG: {str(message.author)} (id: {message.author.id}) sent me this: {message.content}')
        if not bot.is_ready():
            return await message.channel.send("Bot is still starting up, hold on a few seconds.")
        is_setup = await dutils.dm_log_try_setup(bot)
        if is_setup:
            await dutils.dm_log(bot, message)

    pfx = str(get_pre(bot, message))
    if message.content in [f'<@!{bot.config["CLIENT_ID"]}>', f'<@{bot.config["CLIENT_ID"]}>']:
        return await message.channel.send(
            embed=(Embed(title='My prefix here is', description=pfx).set_footer(text='You can change it with '
                                                                                     f'{pfx}prefix')))

    # is_prefix = message.content.startswith(pfx) or message.content.split(' ')[0] in [f'<@!{bot.config["CLIENT_ID"]}>',
    #                                                                                  f'<@{bot.config["CLIENT_ID"]}>']

    #  Check if it's actually a cmd or custom cmd
    possible_cmd = ""
    is_actually_cmd = False
    ctype = -1  # 1 possible_cmd | 2 mutli word | 3 same as 0 but inh | 4 same as 1 but inh
    if message.content.startswith(f'<@{bot.config["CLIENT_ID"]}>'):
        pfx_len = len(f'<@{bot.config["CLIENT_ID"]}>') + 1
    elif message.content.startswith(f'<@!{bot.config["CLIENT_ID"]}>'):
        pfx_len = len(f'<@!{bot.config["CLIENT_ID"]}>') + 1
    elif message.content.startswith(pfx):
        pfx_len = len(pfx)
    else:
        pfx_len = -1
    if pfx_len > 0:
        possible_cmd = message.content[pfx_len:].split(' ')[0]
        if possible_cmd in bot.all_commands:
            is_actually_cmd = True
        if not is_actually_cmd:
            if message.guild and message.guild.id in bot.all_cmds:
                if possible_cmd in bot.all_cmds[message.guild.id]['cmds_name_list']:
                    ctype = 1
                elif message.content[pfx_len:] in bot.all_cmds[message.guild.id]['cmds_name_list']:
                    ctype = 2
                elif possible_cmd in bot.all_cmds[message.guild.id]['inh_cmds_name_list']:
                    ctype = 3
                elif message.content[pfx_len:] in bot.all_cmds[message.guild.id]['inh_cmds_name_list']:
                    ctype = 4

    # if it was a command
    if (is_actually_cmd or ctype > 0) or arl > 1:  # catch messages here for anti spam on arl > 1 regardless of cmd
        if arl in [0, 1]:  # If not checking for message spamming and user is blacklisted return
            if message.author.id in bot.banlist:
                return

        if arl in [0, 1]:  # user can unblacklist themselves here
            if (message.author.id in bot.blacklist) and ('unblacklistme' in message.content):
                if possible_cmd and possible_cmd == 'unblacklistme':
                    if not bot.is_ready():
                        return await message.channel.send("Bot is still starting up, hold on a few seconds.")
                    if was_deleted: return
                    return await bot.process_commands(message)

        if arl in [0, 1]:  # the journey for the blacklisted end shere
            if message.author.id in bot.blacklist:
                return

        bucket = bot.spam_control[arl].get_bucket(message)
        current = message.created_at.replace(tzinfo=datetime.timezone.utc).timestamp()
        retry_after = bucket.update_rate_limit(current)
        author_id = message.author.id

        # spamming has started (but ignore moderators though)
        if retry_after and not is_mod:
            bot._auto_spam_count[author_id] += 1
            d_max = 4  # max number of times they can spam again after bucket triggers
            if arl > 1: d_max = 2
            if bot._auto_spam_count[author_id] >= d_max:

                #  SPAMMER DETECTED HERE!
                if arl > 1:
                    return await dutils.punish_based_on_arl(arl, message, bot)

                if possible_cmd != 'unblacklistme' and arl in [0, 1]:
                    del bot._auto_spam_count[author_id]
                    # await self.log_spammer(ctx, message, retry_after, autoblock=True)
                    out = f'[{retry_after} | {message.content}]({message.jump_url})'
                    # print(out)
                    gid = 0
                    if message.guild: gid = message.guild.id
                    await dutils.blacklist_from_bot(bot, message.author, out, gid,
                                                    ch_to_reply_at=message.channel, arl=arl)
                else:
                    out2 = f"{str(message.author)} {datetime.datetime.utcnow().strftime('%c')}" \
                           f" source: {message.jump_url}"
                    out = f'[{author_id} | {retry_after} |' \
                          f' {message.content}]({message.jump_url})'
                    if message.author.id not in bot.banlist:
                        await dutils.ban_from_bot(bot, message.author, out2, message.guild.id, message.channel)
            else:
                out = f'almost SPAMMER: {author_id} | {retry_after} | {message.content} | {message.jump_url}'
            bot.logger.info(out)
            if bot._auto_spam_count[author_id] == d_max - 1: return
        else:
            bot._auto_spam_count.pop(author_id, None)

        arl1_ret = ("The server has set it's raid protection to level 1.\n"
                    f"{message.author.mention} stop using/spamming bot commands "
                    f"for now or else you will get banned from the bot.")

        sup = None
        kk = 'disabled_onlyEnabled_cmds_and_chs'
        if message.guild and message.guild.id in bot.from_serversetup and bot.from_serversetup[message.guild.id][kk]:
            sup = bot.from_serversetup[message.guild.id][kk]

        if not is_mod and (is_actually_cmd or ctype > 0) and arl > 1:
            return  # we don't want non mods triggering commands during a raid
        if was_deleted:
            return
        if is_actually_cmd:
            if arl == 1 and not is_mod:  # well, during a lvl 1 raid, we can warn them
                return await message.channel.send(arl1_ret)
            if sup and possible_cmd in sup and not is_mod:
                if message.channel.id in sup[possible_cmd]['dis']:
                    return await message.channel.send("❌ This command is disabled in the following channels:\n"
                                                      f"{', '.join((message.guild.get_channel(c)).mention for c in sup[possible_cmd]['dis'])}")
                if sup[possible_cmd]['only_e'] and message.channel.id not in sup[possible_cmd]['only_e']:
                    return await message.channel.send("❌ This command is enabled only in the following channels:\n"
                                                      f"{', '.join((message.guild.get_channel(c)).mention for c in sup[possible_cmd]['only_e'])}")

            if not bot.is_ready():
                return await message.channel.send("Bot is still starting up, hold on a few seconds.")
            return await bot.process_commands(message)

        if ctype != -1:
            if not bot.is_ready():
                return await message.channel.send("Bot is still starting up, hold on a few seconds.")
            if arl == 1 and not is_mod:
                return await message.channel.send(arl1_ret)

            pos_c = '"custom cmds"'
            if sup and pos_c in sup:
                if message.channel.id in sup[pos_c]['dis'] and not is_mod:
                    return await message.channel.send("❌ Custom commands are disabled in the following channels:\n"
                                                      f"{', '.join((message.guild.get_channel(c)).mention for c in sup[pos_c]['dis'])}")
                if sup[pos_c]['only_e'] and message.channel.id not in sup[pos_c]['only_e']:
                    return await message.channel.send("❌ Custom commands are enabled only in the following channels:\n"
                                                      f"{', '.join((message.guild.get_channel(c)).mention for c in sup[pos_c]['only_e'])}")

            if ctype == 1:
                c = bot.all_cmds[message.guild.id]['cmds'][possible_cmd]
            elif ctype == 2:
                c = bot.all_cmds[message.guild.id]['cmds'][message.content[pfx_len:]]
            elif ctype == 3:
                for cc in bot.all_cmds[message.guild.id]['inh_cmd_list']:
                    if possible_cmd in cc: c = cc[possible_cmd]
            elif ctype == 4:
                for cc in bot.all_cmds[message.guild.id]['inh_cmd_list']:
                    if message.content[pfx_len:] in cc: c = cc[message.content[pfx_len:]]

            if bool(c['raw']): return await message.channel.send(c['content'])
            if bool(c['image']):
                em = Embed(color=int(f'0x{c["color"][-6:]}', 16))
                em.set_image(url=c['content'])
            else:
                em = Embed(color=int(f'0x{c["color"][-6:]}', 16), description=c['content'])
                pic = str(c['content']).find('http')
                if pic > -1:
                    urls = re.findall(r'https?:[/.\w\s-]*\.(?:jpg|gif|png|jpeg)', str(c['content']))
                    if len(urls) > 0: em.set_image(url=urls[0])
            return await message.channel.send(embed=em)
Esempio n. 29
0
    def search_talents_and_feats(self, class_name, query):
        # Check if cache is populated for this class
        if not self.class_list[class_name].get("feats", None):
            self.refresh_class_details(class_name)

        talents = list(
            filter(
                lambda x: str(query).lower() in x.get("name", "").lower(),
                self.class_list[class_name]["feats"],
            ))

        if len(talents) == 1 or query.lower() in list(
                map(lambda x: x["name"].lower(), talents)):
            # Only a single talent found, so return all details about it
            talent = (talents[0] if len(talents) == 1 else list(
                filter(lambda x: x["name"].lower() == str(query).lower(),
                       talents))[0])

            res = Embed(
                title=
                f"{talent['name']} -- Level {talent['level']} {class_name.capitalize()} {talent['talentType'].capitalize()}",
                color=ClassColors(class_name.upper()).value,
            )
            res.add_field(name="Cast Type",
                          value=talent["castTime"],
                          inline=True)
            res.add_field(name="Duration",
                          value=talent["duration"],
                          inline=True)
            res.add_field(
                name="Description",
                value=html2text(talent["description"]).strip(),
                inline=False,
            )
            res.add_field(
                name="Requirements",
                value="\n".join(talent["requirements"])
                if talent["requirements"] else "None",
                inline=False,
            )
            res.add_field(name="Prerequisite",
                          value=talent["requiredFeat"],
                          inline=False)
        elif len(talents) >= 1:
            # User is searching based on a query, so return a list of talents
            res = Embed(title=f'Features Matching "{query}":',
                        color=Color.dark_gold())
            talent_map = {
                feat_name: []
                for feat_name in list(
                    map(lambda x: x["talentType"].capitalize(), talents))
            }
            for talent in list(
                    map(
                        lambda x: {
                            "name": x["name"],
                            "type": x["talentType"].capitalize()
                        },
                        talents,
                    )):
                talent_map[talent["type"]].append(talent["name"])

            for type, names in talent_map.items():
                res.add_field(name=type, value="\n".join(names), inline=False)

        else:
            res = Embed(
                title=
                f'Feature/ talent not found for class {class_name.capitalize()}: "{query}"',
                color=Color.red(),
            )

        return res
Esempio n. 30
0
def noStorageEmbed(member):
    return Embed(description=f"{member.mention} {no_storage_warning}")