Esempio n. 1
0
        await ctx.send(embed=embed)

    @commands.group(name='google', invoke_without_command=True)
    @commands.cooldown(1, 15, commands.BucketType.user)
    async def google(self, ctx: NewCtx, *, query: str):
        """Searches something on google"""
        is_nsfw = ctx.channel.is_nsfw()
        ctx.cache_key += [is_nsfw]

        if not (source := ctx.cached_data):

            source = await self.aiogoogle.do_search(ctx,
                                                    query=query,
                                                    is_nsfw=is_nsfw)

        menu = menus.MenuPages(source, clear_reactions_after=True)
        await menu.start(ctx)

    @google.command(name='image', aliases=['-i'])
    @commands.cooldown(1, 15, commands.BucketType.user)
    async def google_image(self, ctx, *, query: str):
        """Searches an image on google"""
        is_nsfw = ctx.channel.is_nsfw()
        ctx.cache_key += [is_nsfw]

        if not (source := ctx.cached_data):
            source = await self.aiogoogle.do_search(ctx,
                                                    query=query,
                                                    is_nsfw=is_nsfw,
                                                    image_search=True)
Esempio n. 2
0
                upvotes = post_data['score']
                comment_count = post_data['num_comments']
                subreddit = post_data['subreddit']

                _post = PostObj(nsfw=nsfw,
                                title=title,
                                self_text=self_text,
                                url=url,
                                author=author,
                                image_link=image_link,
                                video_link=video_link,
                                upvotes=upvotes,
                                comment_count=comment_count,
                                subreddit=subreddit)

                posts.add(_post)
            except Exception as err:
                await ctx.webhook_send(
                    f"{err} in {ctx.channel.mention} trying item {counter} of {amount}",
                    webhook=self.webhook,
                    skip_ctx=True)
        embeds = self._gen_embeds(ctx.author, list(posts),
                                  ctx.channel.is_nsfw())
        pages = menus.MenuPages(PagedEmbedMenu(embeds))
        await pages.start(ctx)


def setup(bot):
    """ Cog Entrypoint. """
    bot.add_cog(Memes(bot))
Esempio n. 3
0
        await ctx.send(embed=embed)

    @commands.group(name="google", invoke_without_command=True)
    @commands.cooldown(1, 15, commands.BucketType.user)
    async def google(self, ctx: main.NewCtx, *, query: str):
        """Searches something on google"""
        is_nsfw = ctx.channel.is_nsfw()
        ctx.cache_key += [is_nsfw]

        if not (source := ctx.cached_data):

            source = await self.aiogoogle.do_search(ctx,
                                                    query=query,
                                                    is_nsfw=is_nsfw)

        menu = menus.MenuPages(source, delete_message_after=True)
        await menu.start(ctx)

    @google.command(name="image", aliases=["-i"])
    @commands.cooldown(1, 15, commands.BucketType.user)
    async def google_image(self, ctx: main.NewCtx, *, query: str):
        """Searches an image on google"""
        is_nsfw = ctx.channel.is_nsfw()
        ctx.cache_key += [is_nsfw]

        if not (source := ctx.cached_data):
            source = await self.aiogoogle.do_search(ctx,
                                                    query=query,
                                                    is_nsfw=is_nsfw,
                                                    image_search=True)
 async def source(self, ctx: Context, source: Optional[str] = None):
     """
     Tries to find the source of an image through the image url or the image as attachment.
     """
     async with ctx.channel.typing():
         url = None
         if source is None:
             if ctx.message.attachments:
                 url = ctx.message.attachments[0].url
             else:
                 embed = discord.Embed(
                     title='No image to look for the source.',
                     color=ERROR_EMBED_COLOR)
                 await ctx.channel.send(embed=embed)
                 ctx.command.reset_cooldown(ctx)
         else:
             url = source
         if url:
             if not url.lower().endswith(
                 ('.jpg', '.png', '.bmp', '.jpeg', '.gif')):
                 embed = discord.Embed(
                     title=
                     'No correct url specified (`.jpg`, `.png`, `.bmp`, `.jpeg`, `.gif`).',
                     color=ERROR_EMBED_COLOR)
                 await ctx.channel.send(embed=embed)
                 ctx.command.reset_cooldown(ctx)
             else:
                 try:
                     data = await self.bot.saucenao.search(url)
                 except Exception as e:
                     log.exception(e)
                     embed = discord.Embed(
                         title=
                         f'An error occurred while looking for the source, the link is invalid, or the '
                         f'daily limit has been reached.',
                         color=ERROR_EMBED_COLOR)
                     return await ctx.channel.send(embed=embed)
                 if data:
                     embeds = []
                     for page, entry in enumerate(data):
                         try:
                             embed = await self.get_source_embed(
                                 entry, page + 1, len(data))
                         except Exception as e:
                             log.exception(e)
                             embed = discord.Embed(
                                 title='Error',
                                 color=ERROR_EMBED_COLOR,
                                 description=
                                 'An error occurred while loading the embed.'
                             )
                             embed.set_footer(
                                 text=
                                 f'Provided by https://saucenao.com/ • Page {page + 1}/{len(data)}'
                             )
                         embeds.append(embed)
                     menu = menus.MenuPages(source=EmbedListMenu(embeds),
                                            clear_reactions_after=True,
                                            timeout=30)
                     await menu.start(ctx)
                 else:
                     embed = discord.Embed(title='No source found.',
                                           color=ERROR_EMBED_COLOR)
                     await ctx.channel.send(embed=embed)
Esempio n. 5
0
    async def reddit(self, ctx: NewCtx, sub: str = 'memes', sort: str = 'hot'):
        """Gets the <sub>reddits <amount> of posts sorted by <method>"""
        if sort.lower() not in ("top", "hot", "best", "controversial", "new",
                                "rising"):
            return await ctx.send("Not a valid sort-by type.")

        PostObj = namedtuple('PostObj', [
            'title', 'self_text', 'url', 'author', 'image_link', 'video_link',
            'upvotes', 'comment_count', 'subreddit'
        ])

        posts = set()

        subr_url = f"https://www.reddit.com/r/{sub}/about.json"
        base_url = f"https://www.reddit.com/r/{sub}/{sort}.json"

        async with self.bot.session.get(
                subr_url, headers={"User-Agent":
                                   "Yoink discord bot"}) as subr_resp:
            subr_deets = await subr_resp.json()

        if 'data' not in subr_deets:
            raise commands.BadArgument("Subreddit does not exist.")
        if subr_deets['data'].get('over18',
                                  None) and not ctx.channel.is_nsfw():
            raise commands.NSFWChannelRequired(ctx.channel)

        async with self.bot.session.get(base_url) as res:
            page_json = await res.json()

        idx = 0
        for post_data in page_json['data']['children']:
            image_url = None
            video_url = None

            if idx == 20:
                break

            post = post_data['data']
            if post['stickied'] or (post['over_18']
                                    and not ctx.channel.is_nsfw()):
                idx += 1
                continue

            title = shorten(post['title'], width=250)
            self_text = shorten(post['selftext'], width=1500)
            url = f"https://www.reddit.com{post['permalink']}"
            author = post['author']
            image_url = post['url'] if post['url'].endswith(
                (".jpg", ".png", ".jpeg", ".gif", ".webp")) else None
            if "v.redd.it" in post['url']:
                image_url = post['thumbnail']
                if post.get("media", None):
                    video_url = post['url']
                else:
                    continue
            upvotes = post['score']
            comment_count = post['num_comments']
            subreddit = post['subreddit']

            _post = PostObj(title=title,
                            self_text=self_text,
                            url=url,
                            author=author,
                            image_link=image_url,
                            video_link=video_url,
                            upvotes=upvotes,
                            comment_count=comment_count,
                            subreddit=subreddit)

            posts.add(_post)
        embeds = self._gen_embeds(ctx.author, list(posts))
        pages = menus.MenuPages(PagedEmbedMenu(embeds))
        await pages.start(ctx)
Esempio n. 6
0
    async def send_bot_help(self, mapping):
        e = discord.Embed(title='Command Help',
                          color=discord.Color.from_rgb(123, 47, 181))
        e.set_author(name=self.context.author,
                     icon_url=self.context.author.avatar_url)

        # Separate Page
        e_command = e.copy()

        e.set_thumbnail(
            url='https://avatars2.githubusercontent.com/u/31901301?s=280&v=4')

        e.add_field(
            name='Download 1.8.9',
            value=
            '[1.0.0 RC4 Beta](https://github.com/ChatTriggers/ct.js/releases/download/1.0.0RC4/ctjs-1.0'
            '.0-RC4-1.8.9.jar)\n '
            '[0.18.4 Stable](https://github.com/ChatTriggers/ct.js/releases/download/0.18.4/ctjs-0.18.4'
            '-SNAPSHOT-1.8.9.jar)\n '
            '[0.16.6 Legacy](https://github.com/ChatTriggers/ct.js/releases/download/0.16.6/ctjs-0.16.6'
            '-SNAPSHOT-1.8.9.jar)')

        e.add_field(
            name='Download 1.12.2',
            value=
            '[0.18.4 Stable](https://github.com/ChatTriggers/ct.js/releases/download/0.18.4/ctjs-0.18.4'
            '-SNAPSHOT-1.12.2.jar)\n '
            '[0.16.6 Legacy](https://github.com/ChatTriggers/ct.js/releases/download/0.16.6/ctjs-0.16.6'
            '-SNAPSHOT-1.12.2.jar)')

        e.add_field(name='Developers',
                    value='[kerbybit](https://github.com/kerbybit)\n'
                    '[FalseHonesty](https://github.com/FalseHonesty)\n'
                    '[Matt](https://github.com/mattco98)',
                    inline=True)

        e.add_field(
            name='What is ChatTriggers?',
            value=
            'ChatTriggers is a framework for Minecraft that allows for live scripting and client '
            'modification using JavaScript. We provide libraries, wrappers, objects and more to make '
            'your life as a modder as easy as possible. Even without the proper wrapper, you can still '
            'use exposed Minecraft methods and variables but you will need knowledge of FML mappings',
            inline=False)

        # Iterate over Cogs & Command to add to the 2nd embed
        # Built for only one Cog
        for cog, _commands in self.get_bot_mapping().items():
            _commands = await self.filter_commands(_commands)

            command_string = '```asciidoc\n'

            for _command in _commands:
                command_string += self.get_command_signature(_command) + '\n'

            # Remove last `\n`
            command_string = command_string[:-2]
            command_string += '```'

            if cog:
                e_command.description = command_string

        pages = menus.MenuPages(source=HelpPaginator([e, e_command]),
                                clear_reactions_after=True,
                                delete_message_after=True)
        await pages.start(self.context)
Esempio n. 7
0
async def show_translators_menu(ctx, translators):
    pages = menus.MenuPages(source=TranslatorsMenusSource(ctx, translators), clear_reactions_after=True)
    await pages.start(ctx)
Esempio n. 8
0
async def weeklyChallenge(ctx, **flags):
    challenge_weeks = {}
    week = flags["week"]
    if week < 1 or week > len(weekly_levels.levels):
        week = weekly_levels.levels[-1].week
    error = {"occurred": False, "detail": ""}
    #flags["position"] += -1
    if flags["position"] < 0 or flags["position"] > 1000 - NUMBER_TO_SHOW_TOP:
        flags["position"] = 0
    offset = flags["position"]
    level_obj = weekly_levels.getByWeek(week)

    if level_obj != None:  # Top command

        lb = get_top(level_obj, flags["unbreaking"])
        if flags["user"] != None and flags["price"] == None and flags[
                "position"] == 0:  # Position Command
            found_user = False
            search_for_id = re.search(r"@\w+", flags["user"])
            for pos, score in enumerate(lb):
                if not search_for_id:
                    if score['display_name'].lower() == flags["user"].lower():
                        offset = pos
                        found_user = True
                        break
                else:
                    if score['owner']['id'] == flags["user"][1:]:
                        offset = pos
                        found_user = True
                        break
            if not found_user:
                embed = discord.Embed(
                    title=f"User Not found",
                    description=
                    "The user you are looking for is not in the top 1000 for this level or you might have mistyped their username.",
                    colour=discord.Colour(0xf93a2f),
                )
                await ctx.send(embed=embed)
        elif flags["price"] != None and flags["position"] == 0 and flags[
                "user"] == None:
            price = parse_price_input(flags["price"])
            offset = 0
            prev = 0
            found_price = False
            for c, entry in enumerate(lb):
                if prev <= price and entry["value"] >= price:
                    offset = c
                    found_price = True
                    break
                prev = entry["value"]
            if not found_price:
                embed = discord.Embed(
                    title=f"Price Out of top 1000",
                    description=
                    "There are no scores at that price in the top 1000.",
                    colour=discord.Colour(0xf93a2f),
                )
                await ctx.send(embed=embed)
        else:  # Calculate offset based on passed position and ties
            prev = 0
            for c, entry in enumerate(lb):
                if prev <= offset and entry["rank"] >= offset:
                    offset = c
                    break
                if entry["rank"] != prev:
                    prev = entry["rank"]
        pages = menus.MenuPages(source=GeneralLeaderboardViewer(
            lb,
            level_obj.name,
            offset,
            flags["unbreaking"],
            level_obj.last_reloaded(),
            mobile_view=flags["mobile"],
            is_weekly_challenge=True,
            thumbnail_url=level_obj.preview),
                                clear_reactions_after=True)
        await pages.start(ctx)
    else:
        error["occurred"] = True
        error["detail"] = INVALID_LEVEL_TEXT
    if error["occurred"]:
        embed = discord.Embed(
            title=f"An Error Occurred.",
            description=error["detail"],
            colour=discord.Colour(0xf93a2f),
        )
        await ctx.send(embed=embed)
 async def test_command(self, ctx: commands.Context):
     pages = menus.MenuPages(source=Source(data, key=lambda t: t.key, per_page=5), clear_reactions_after=True)
     await pages.start(ctx)
Esempio n. 10
0
async def show_items_menu(ctx, items, title: str):
    pages = menus.MenuPages(source=ItemsMenusSource(ctx, items, title),
                            clear_reactions_after=True)
    await pages.start(ctx)
Esempio n. 11
0
async def globaltop(ctx, **flags):
    offset = 0
    level_type = flags["type"]
    nobreaks = flags["unbreaking"]
    level_type = level_type.lower()
    if level_type not in [
            "all", "regular", "challenge", "weekly"
    ] or (flags["moneyspent"] and level_type == "weekly"):
        level_type = "all"
    message = await ctx.send(embed=discord.Embed(
        title=f"Processing Data...", colour=discord.Colour(0x3586ff)))
    global_leaderboard, id_to_display_names, worlds = get_global_leaderboard(
        nobreaks, level_type, flags["moneyspent"], flags["worlds"])

    if flags["user"] != None and flags["score"] == None and flags[
            "position"] == 0:  # Position Command
        found_user = False
        search_for_id = re.search(r"@\w+", flags["user"])
        for pos, itm in enumerate(list(global_leaderboard.items())):
            if not search_for_id:
                if id_to_display_names[
                        itm[0]].lower() == flags["user"].lower():
                    offset = pos
                    found_user = True
                    break
            else:
                if itm[0] == flags["user"][1:]:
                    offset = pos
                    found_user = True
                    break
        if not found_user:
            embed = discord.Embed(
                title=f"User Not found",
                description=
                "The user you are looking for is not on the global leaderboard or you might have mistyped their username.",
                colour=discord.Colour(0xf93a2f),
            )
            await ctx.send(embed=embed)
    elif flags["score"] != None and flags["position"] == 0 and flags[
            "user"] == None:
        price = parse_price_input(flags["score"])
        offset = 0
        prev = 0
        found_price = False
        for c, itm in enumerate(list(global_leaderboard.items())):
            entry = itm[1]
            if prev <= price and entry["score"] >= price:
                offset = c
                found_price = True
                break
            prev = entry["score"]
        if not found_price:
            embed = discord.Embed(
                title=f"Score not found",
                description=
                "There are no at that value in the global leaderboard.",
                colour=discord.Colour(0xf93a2f),
            )
            await ctx.send(embed=embed)
    else:  # Calculate offset based on passed position and ties
        offset = flags["position"]
        prev = 0
        for c, itm in enumerate(list(global_leaderboard.items())):
            entry = itm[1]
            if prev <= offset and entry["rank"] >= offset:
                offset = c
                break
            if entry["rank"] != prev:
                prev = entry["rank"]

    embed = discord.Embed(title=f"Global Leaderboard:",
                          colour=discord.Colour(0x3586ff))
    embed.set_author(
        name="PB2 Leaderboards Bot",
        icon_url=
        "https://cdn.discordapp.com/app-assets/720364938908008568/758752385244987423.png"
    )
    lb = []
    for c, itm in enumerate(list(global_leaderboard.items())):
        lb.append({
            "name":
            f"{'🥇🥈🥉'[itm[1]['rank']] if itm[1]['rank']+1 <= 3 else itm[1]['rank']+1}: {id_to_display_names[itm[0]]}",
            "value":
            f"Spent: {'${:,}'.format(int(itm[1]['score']))}"
            if flags["moneyspent"] else f"Score: {itm[1]['score']}",
            "inline":
            True
        })
        #print(c,id_to_display_names[itm[0]], itm[1])
    await message.delete()
    pages = menus.MenuPages(source=GlobalLeaderboardViewer(
        lb, offset, level_type, nobreaks, worlds, mobile_view=flags["mobile"]),
                            clear_reactions_after=True)
    await pages.start(ctx)
Esempio n. 12
0
    async def help(self, ctx, command: str = None):
        global prefix
        prefix = await get_prefix(self.bot, ctx)
        prefix = prefix[2]
        global CTX
        CTX = ctx
        usginfo = " (When using commands, <> indicates a required argument and [] indicates an optional argument.) do **NOT** include them when using commands."
        error = f'```css\nThat command, "{command}", does not exist!\n```'
        if command:
            embed = discord.Embed(title="Help", colour=0xED791D)
            cmd = self.bot.get_command(command)

            if not cmd:
                await ctx.send(error)

                return

            if not cmd.hidden:

                if cmd.parent:

                    embed.add_field(
                        name="Usage:",
                        value=
                        f'{usginfo}\n{prefix}{cmd.parent} {cmd.name} {cmd.signature}',
                        inline=False)
                else:

                    embed.add_field(
                        name="Usage:",
                        value=f'{usginfo}\n{prefix}{cmd.name} {cmd.signature}',
                        inline=False)

                if cmd.aliases:

                    aliases = ""

                    for a in cmd.aliases:
                        aliases += f"\n`{a}`"

                    embed.add_field(name='Aliases',
                                    value=aliases,
                                    inline=False)

                try:

                    commands = ""

                    for a in cmd.commands:
                        commands += f"`{prefix}{cmd.name} {a.name} {a.signature}`\n"

                    embed.add_field(name="Subcommands",
                                    value=commands,
                                    inline=False)

                except:

                    pass

            else:

                await ctx.send(error)
                return

            await ctx.send(embed=embed)
            return

        fun = ""
        for a in self.bot.commands:
            print(a.cog_name)
            if a.cog_name == "Fun":
                if not a.hidden:
                    fun += f"`{prefix}{a.name}` ◍ "
                    try:
                        for b in a.commands:
                            fun += f"`{prefix}{a.name} {b.name}` ◍ "
                    except:
                        pass

        economy = ""
        for a in self.bot.commands:
            print(a.cog_name)
            if a.cog_name == "Economy":
                if not a.hidden:
                    economy += f"`{prefix}{a.name}` ◍ "
                    try:
                        for b in a.commands:
                            economy += f"`{prefix}{a.name} {b.name}` ◍ "
                    except:
                        pass

        music = ""

        for a in self.bot.commands:
            if a.cog_name == "Music":
                if not a.hidden:
                    music += f"`{prefix}{a.name}` ◍ "
                    try:
                        for b in a.commands:
                            music += f"`{prefix}{a.name} {b.name}` ◍ "
                    except:
                        pass

        userinfo = ""

        for a in self.bot.commands:
            if a.cog_name == "UserInfo":
                if not a.hidden:
                    userinfo += f"`{prefix}{a.name}` ◍ "
                    try:
                        for b in a.commands:
                            userinfo += f"`{prefix}{a.name} {b.name}` ◍ "
                    except:
                        pass

        meta = ""

        for a in self.bot.commands:
            if a.cog_name == "Meta":
                if not a.hidden:
                    meta += f"`{prefix}{a.name}` ◍ "
                    try:
                        for b in a.commands:
                            meta += f"`{prefix}{a.name} {b.name}` ◍ "
                    except:
                        pass

        moderation = ""

        for a in self.bot.commands:
            if a.cog_name == "Moderation":
                if not a.hidden:
                    moderation += f"`{prefix}{a.name}` ◍ "
                    try:
                        for b in a.commands:
                            moderation += f"`{prefix}{a.name} {b.name}` ◍ "
                    except:
                        pass

        custom = ""

        for a in self.bot.commands:
            if a.cog_name == "Custom":
                if not a.hidden:
                    custom += f"`{prefix}{a.name}` ◍ "
                    try:
                        for b in a.commands:
                            custom += f"`{prefix}{a.name} {b.name}` ◍ "
                    except:
                        pass

        image = ""

        for a in self.bot.commands:
            if a.cog_name == "Images":
                if not a.hidden:
                    image += f"`{a.name}` ◍ "
                    try:
                        for b in a.commands:
                            image += f"`{prefix}{a.name} {b.name}` ◍ "
                    except:
                        pass

        lockdown = ""

        for a in self.bot.commands:
            if a.cog_name == "Lockdown":
                if not a.hidden:
                    lockdown += f"`{prefix}{a.name}` ◍ "
                    try:
                        for b in a.commands:
                            lockdown += f"`{prefix}{a.name} {b.name}` ◍ "
                    except:
                        pass

        translator = ""

        for a in self.bot.commands:
            if a.cog_name == "Translate":
                if not a.hidden:
                    translator += f"`{prefix}{a.name}` ◍ "
                    try:
                        for b in a.commands:
                            translator += f"`{prefix}{a.name} {b.name}` ◍ "
                    except:
                        pass

        leveling = ""

        for a in self.bot.commands:
            if a.cog_name == "Leveling":
                if not a.hidden:
                    leveling += f"`{prefix}{a.name}` ◍ "
                    try:
                        for b in a.commands:
                            leveling += f"`{prefix}{a.name} {b.name}` ◍ "
                    except:
                        pass

        fdescriptions = [
            f"""
            **FUN**
            {fun}

            """, f"""
            **ECONOMY**
            {economy}

            """, f"""
            **MUSIC**
            {music}

            """, f"""
            **USERINFO**
            {userinfo}

            """, f"""
            **META**
            {meta}

            """, f"""
            **MODERATION**
            {moderation}

            """, f"""
            **IMAGE**
            {image}

            """, f"""
            **LOCKDOWN**
            {lockdown}

            """, f"""
            **TRANSLATION**
            {translator}

            """, f"""
            **LEVELING**
            {leveling}

            """, f"""
            **CUSTOM**
            {custom}

        """
        ]

        source = HelpSource(fdescriptions, per_page=2)
        menu = menus.MenuPages(source)
        await menu.start(ctx)
Esempio n. 13
0
    async def help(self, ctx, command: str = None):
        prefix = "arc!"
        error = f'```css\nThat command, "{command}", does not exist!\n```'
        if command:  # check if the command exists
            embed = discord.Embed(title="Help",
                                  colour=0x2F3136)  #  create a new embed
            cmd = self.bot.get_command(command)  # get the command description.

            if not cmd:
                if command == "ttt":  # tic tac toe is in js, so the python side doesn't know it exists.
                    # this means we have to add it manually.
                    embed.add_field(
                        name="Usage:",
                        value=f"{prefix}ttt [member]",
                        inline=False,
                    )
                    return await ctx.send(embed=embed
                                          )  # send the help for tic tac toe
                else:
                    return await ctx.send(
                        error
                    )  # if its not tic tac toe, tell the user that the command does not exist.

            # check that the command is not hidden
            if not cmd.hidden:

                # this whole block below is for sub-commands,
                # aliases and such. to save myself time, im not gonna go through this.
                if cmd.parent:

                    embed.add_field(
                        name="Usage:",
                        value=
                        f"{prefix}{cmd.parent} {cmd.name} {cmd.signature}",
                        inline=False,
                    )
                else:

                    embed.add_field(
                        name="Usage:",
                        value=f"{prefix}{cmd.name} {cmd.signature}",
                        inline=False,
                    )

                if cmd.aliases:

                    aliases = ""

                    for a in cmd.aliases:
                        aliases += f"\n`{a}`"

                    embed.add_field(name="Aliases",
                                    value=aliases,
                                    inline=False)

                try:

                    commands = ""

                    for a in cmd.commands:
                        commands += f"`{prefix}{cmd.name} {a.name} {a.signature}`\n"

                    embed.add_field(name="Subcommands",
                                    value=commands,
                                    inline=False)

                except:

                    pass

            else:

                await ctx.send(error)
                return

            await ctx.send(embed=embed)
            return

        # these chunks below set up the default help command for the bot.
        con4 = ""
        for a in self.bot.commands:
            if a.cog_name == "Connect4":
                if not a.hidden:
                    con4 += f"`{prefix}{a.name}` ◍ "
                    try:
                        for b in a.commands:
                            con4 += f"`{prefix}{a.name} {b.name}` ◍ "
                    except:
                        pass

        slot = ""
        for a in self.bot.commands:
            if a.cog_name == "SlotMachine":
                if not a.hidden:
                    slot += f"`{prefix}{a.name}` ◍ "
                    try:
                        for b in a.commands:
                            slot += f"`{prefix}{a.name} {b.name}` ◍ "
                    except:
                        pass

        economy = ""
        for a in self.bot.commands:
            if a.cog_name == "Economy":
                if not a.hidden:
                    economy += f"`{prefix}{a.name}` ◍ "
                    try:
                        for b in a.commands:
                            economy += f"`{prefix}{a.name} {b.name}` ◍ "
                    except:
                        pass

        candy = ""
        for a in self.bot.commands:
            if a.cog_name == "Candy":
                if not a.hidden:
                    candy += f"`{prefix}{a.name}` ◍ "
                    try:
                        for b in a.commands:
                            candy += f"`{prefix}{a.name} {b.name}` ◍ "
                    except:
                        pass

        profs = ""
        for a in self.bot.commands:
            if a.cog_name == "Profiles":
                if not a.hidden:
                    profs += f"`{prefix}{a.name}` ◍ "
                    try:
                        for b in a.commands:
                            profs += f"`{prefix}{a.name} {b.name}` ◍ "
                    except:
                        pass

        fdescriptions = [
            f"""
            **Connect Four**
            {con4}
            """, f"""
            **Slot Machine**
            {slot}
            """, f"""
            **Economy**
            {economy}
            """, f"""
            **Candy**
            {candy}
            """, f"""
            **Profiles**
            {profs}
            """, f"""
            **Tic Tac Toe**
            `{prefix}ttt` ◍ 
            """
        ]  # format the help command into a list

        source = HelpSource(fdescriptions, per_page=2)  # paginate it
        menu = menus.MenuPages(source)
        await menu.start(ctx)  # send the paginator
Esempio n. 14
0
    async def google(self, ctx, *, query):
        async with ctx.typing():
            params = {"safe": "on", "lr": "lang_en", "hl": "en", "q": query}
            headers = {
                "User-Agent":
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0"
            }

            async with self.bot.session.get(f"https://google.com/search",
                                            params=params,
                                            headers=headers) as resp:
                if resp.status != 200:
                    return await ctx.send(
                        f":x: Failed to search google (status code {resp.status_code})"
                    )

                html = await resp.text("utf-8")

                # Debugging
                with open("google.html", "w", encoding="utf-8") as file:
                    file.write(html)

                root = etree.fromstring(html, etree.HTMLParser())

            # Search results
            results = [
                g.find(".//div[@class='yuRUbf']/a")
                for g in root.findall(".//div[@class='g']")
            ]
            entries = []

            # Results formatting
            for result in results:
                if result:
                    href = result.get("href")
                    h3 = result.find(".//h3[@class='LC20lb DKV0Md']")

                    cite = result.find(".//div/cite")
                    site = f"`{cite.text}`" if cite is not None else ""
                    entries.append({
                        "title": h3.text,
                        "description": f"`{site}`",
                        "url": href
                    })

            search_results = "\n".join([
                f"[{result['title']}]({result['url']})"
                for result in entries[:5]
            ])

            # Calculation card
            calculator = root.find(".//div[@class='tyYmIf']")
            if calculator is not None:
                equation = calculator.find(".//span[@class='vUGUtc']")
                result = calculator.find(".//span[@class='qv3Wpe']")

                em = discord.Embed(title="Calculator",
                                   description=f"{equation.text}{result.text}",
                                   color=0x4285F3)

                if search_results:
                    em.add_field(name="Search Results",
                                 value=search_results,
                                 inline=False)

                return await ctx.send(embed=em)

            # Conversion card
            converter = root.find(
                ".//div[@class='vk_c card obcontainer card-section']")
            if converter is not None:
                src, dest = converter.findall(".//input[@class='vXQmIe gsrt']")
                units = converter.findall(".//option[@selected='1']")
                formula = converter.find(".//div[@class='bjhkR']")

                em = discord.Embed(title=f"{units[0].text} Converter",
                                   color=0x4285F3)
                em.add_field(name=units[1].text.title(),
                             value=src.get("value"))
                em.add_field(name=units[2].text.title(),
                             value=dest.get("value"))
                em.add_field(name="Formula", value=formula.text.capitalize())

                if search_results:
                    em.add_field(name="Search Results",
                                 value=search_results,
                                 inline=False)

                return await ctx.send(embed=em)

            # Currency card
            currency_converter = root.find(".//table[@class='qzNNJ']")
            if currency_converter is not None:
                src_name, dest_name = currency_converter.findall(
                    ".//option[@selected='1']")
                src = currency_converter.find(
                    ".//input[@class='ZEB7Fb vk_gy vk_sh Hg3mWc']")
                dest = currency_converter.find(
                    ".//input[@class='a61j6 vk_gy vk_sh Hg3mWc']")
                time = root.find(".//div[@class='hqAUc']/span")

                em = discord.Embed(title="Currency Converter",
                                   description=time.text.replace("·", ""),
                                   color=0x4285F3)
                em.add_field(name=f"{src_name.text} ({src_name.get('value')})",
                             value=src.get("value"))
                em.add_field(
                    name=f"{dest_name.text} ({dest_name.get('value')})",
                    value=dest.get("value"))

                if search_results:
                    em.add_field(name="Search Results",
                                 value=search_results,
                                 inline=False)

                return await ctx.send(embed=em)

            # Generic information card
            information = root.find(".//div[@class='IZ6rdc']")
            if information is not None:
                em = discord.Embed(title="Information",
                                   description=f"{information.text}",
                                   color=0x4285F3)

                if search_results:
                    em.add_field(name="Search Results",
                                 value=search_results,
                                 inline=False)

                return await ctx.send(embed=em)

            # Translation card
            translator = root.find(".//div[@class='tw-src-ltr']")
            if translator is not None:
                src_lang = root.find(".//span[@class='source-language']")
                dest_lang = root.find(".//span[@class='target-language']")

                src = translator.find(".//pre[@id='tw-source-text']/span")
                dest = translator.find(".//pre[@id='tw-target-text']/span")

                em = discord.Embed(title="Translator", color=0x4285F3)
                em.add_field(name=src_lang.text.title(), value=src.text)
                em.add_field(name=dest_lang.text.title(), value=dest.text)

                if search_results:
                    em.add_field(name="Search Results",
                                 value=search_results,
                                 inline=False)

                return await ctx.send(embed=em)

            # Time in card
            time_in = root.find(
                ".//div[@class='gsrt vk_bk dDoNo FzvWSb XcVN5d DjWnwf']")
            if time_in is not None:
                date = root.find(".//div[@class='vk_gy vk_sh']")
                location = root.find(".//span[@class='vk_gy vk_sh']")

                em = discord.Embed(
                    title=location.text,
                    description=f"{time_in.text} — {''.join(date.itertext())}",
                    color=0x4285F3)

                if search_results:
                    em.add_field(name="Search Results",
                                 value=search_results,
                                 inline=False)

                return await ctx.send(embed=em)

            # Generic time card
            generic_time = root.find(
                ".//div[@class='vk_c vk_gy vk_sh card-section sL6Rbf R36Kq']")
            if generic_time is not None:
                info = generic_time.find(".//div")

                em = discord.Embed(title="Time",
                                   description="".join(info.itertext()),
                                   color=0x4285F3)

                if search_results:
                    em.add_field(name="Search Results",
                                 value=search_results,
                                 inline=False)

                return await ctx.send(embed=em)

            # Definition card
            definer = root.find(".//div[@class='WI9k4c']")
            if definer is not None:
                word = definer.find(
                    ".//div[@class='RjReFf jY7QFf']/div[@class='DgZBFd XcVN5d frCXef']/span"
                )
                pronounciation = definer.find(".//div[@class='S23sjd g30o5d']")
                conjunction = root.find(
                    ".//div[@class='pgRvse vdBwhd ePtbIe']/i/span")

                raw_examples = [
                    raw_example for raw_example in root.findall(
                        ".//div[@class='L1jWkf h3TRxf']/div/span")
                    if raw_example.text
                ]
                examples = [
                    f"{counter+1}. {example.text}"
                    for counter, example in enumerate(raw_examples)
                ]

                em = discord.Embed(
                    title="Definition",
                    description=
                    f"{word.text} `{''.join(pronounciation.itertext())}`\n\n*{conjunction.text}*",
                    color=0x4285F3)
                em.add_field(name="Examples", value="\n".join(examples))

                if search_results:
                    em.add_field(name="Search Results",
                                 value=search_results,
                                 inline=False)

                return await ctx.send(embed=em)

            # Weather card
            weather = root.find(".//div[@class='nawv0d']")
            if weather is not None:
                image = weather.find(".//img[@class='wob_tci']")
                temperature_f = weather.find(".//span[@class='wob_t TVtOme']")
                temperature_c = weather.find(".//span[@class='wob_t']")

                location = weather.find(".//div[@class='wob_loc mfMhoc']")
                time = weather.find(".//div[@class='wob_dts']")

                details = weather.find(".//div[@class='wtsRwe']")
                precipitation = details.find(".//span[@id='wob_pp']")
                humidity = details.find(".//span[@id='wob_hm']")
                wind = details.find(".//span[@class='wob_t']")

                em = discord.Embed(
                    title=f"Weather in {location.text}",
                    description=f"{time.text} — {image.get('alt')}",
                    color=0x4285F3)
                em.set_thumbnail(url=f"https:{image.get('src')}")
                em.add_field(
                    name="Temperature",
                    value=f"{temperature_f.text}°F | {temperature_c.text}°C",
                    inline=False)
                em.add_field(name="Precipitation", value=precipitation.text)
                em.add_field(name="Humidity", value=humidity.text)
                em.add_field(name="Wind", value=wind.text)

                if search_results:
                    em.add_field(name="Search Results",
                                 value=search_results,
                                 inline=False)

                return await ctx.send(embed=em)

            if not results:
                return await ctx.send(":x: I couldn't find any results")

        pages = menus.MenuPages(GoogleResultPages(entries, query),
                                clear_reactions_after=True)
        await pages.start(ctx)
Esempio n. 15
0
 async def wares(self, ctx: MyContext):
     """Show the selection of items available"""
     shop_items = await self.shop_items
     page_source = ShopInventoryPageSource(shop_items, per_page=9)
     menu = menus.MenuPages(page_source, delete_message_after=True, clear_reactions_after=True)
     await menu.start(ctx, wait=True)
Esempio n. 16
0
 async def mafia_roles(self, ctx):
     """Displays the available custom roles"""
     menu = menus.MenuPages(source=RolesSource(ctx.bot.__special_roles__),
                            clear_reactions_after=True)
     await menu.start(ctx)
Esempio n. 17
0
 async def send_group_help(self, group):
     entries = await self.filter_commands(group.commands, sort=True)
     menu = menus.MenuPages(HelpGroupPaginator(self, group, entries))
     await menu.start(self.context)
Esempio n. 18
0
    async def tutorial(self, ctx):
        """Learn the game."""
        p = ctx.prefix

        embed1 = discord.Embed(color=self.client.ayesha_blue)
        embed1.set_author(name='Ayesha Tutorial: Introduction',
                          icon_url=self.client.user.avatar_url)
        embed1.set_thumbnail(url=ctx.author.avatar_url)

        embed1.add_field(
            name='Welcome to Ayesha, a new Gacha RPG for Discord!',
            value=
            (f"**∘ |** **Create a character** by doing `{p}create <your name>`.\n"
             f"**∘ |** **Customize** your playstyle with `{p}class` and `{p}origin`.\n"
             f"**∘ |** View your **profile** with the `{p}profile` command!\n"
             f"**∘ |** View your **weapons** with the `{p}inventory` command.\n"
             f"**∘ |** View your **acolytes** with `{p}tavern`.\n"
             f"**∘ |** Do `{p}pve <1-25>` to fight **bosses** and earn **rewards**!\n"
             f"**∘ |** Get passive **resources** from `{p}travel` and `{p}expedition`.\n"
             f"**∘ |** Make friends in `{p}brotherhood`s, `{p}college`s, or `{p}guild`s.\n\n"
             f"Hit the ▶️ for a quick walkthrough!\n"
             f"Still stuck? Use the `{p}help` command!"))

        embed2 = discord.Embed(color=self.client.ayesha_blue)
        embed2.set_author(name='Ayesha Tutorial: Introduction',
                          icon_url=self.client.user.avatar_url)
        embed2.set_thumbnail(url=ctx.author.avatar_url)

        embed2.add_field(
            name="Ayesha's Stat System",
            value=
            (f"**You will be seeing a bunch of terms thrown all over the game. "
             f"Here's a quick overview:**\n"
             f"**∘ | Gold:** the base currency for Ayesha, used for most anything in the game.\n"
             f"**∘ | Rubidics:** rubidics are the **gacha** currency for Ayesha. "
             f"That means it is entirely separate from gameplay, and used only for `{p}summon`ing.\n"
             f"**∘ | Level:** your character's level, which can be increased by a few important commands.\n"
             f"**∘ | Attack:** your character's attack. It can be increased based"
             f"off your weapon, acolytes, class, origin, and association.\n"
             f"**∘ | Crit:** like Attack, but denoting your critical strike chance.\n"
             f"**∘ | HP:** your hit points, used in `{p}pvp` and `{p}pve`.\n"
             f"**∘ | Gravitas:** Your **reputation** or **influence** in the bot, "
             f"an alternative stat to raise for those not interested by combat.\n\n"
             f"Hit the ▶️ for your first steps!\n"
             f"Still stuck? Join the `{p}support` server for help!"))

        embed3 = discord.Embed(color=self.client.ayesha_blue)
        embed3.set_author(name='Ayesha Tutorial: Introduction',
                          icon_url=self.client.user.avatar_url)
        embed3.set_thumbnail(url=ctx.author.avatar_url)

        embed3.add_field(
            name='Quick-Start Guide',
            value=
            (f"**∘ |** Fighting bosses is the fastest way to level up. Try doing `{p}pve 1`.\n"
             f"**∘ |** You will notice that you had set Attack, Crit, and HP stats. "
             f"There are multiple factors affecting these. The fastest way to increase "
             f"your attack is with a better weapon. Do `{p}inventory` and equip "
             f"your **Wooden Spear** by doing `{p}equip <ID>`. The ID is the number "
             f"listed next to the weapon's name in your inventory."))

        embed3.add_field(
            name='Introduction to Class and Origin',
            value=
            (f"**∘ |** Now do `{p}class` and `{p}origin`. There are 10 classes "
             f"and 9 origins, each with their own niche. Read their effects "
             f"carefully, then do `{p}class <Name>` and `{p}origin <Name>` "
             f"to take on whichever are your favorites! You can change them "
             f"again later."),
            inline=False)

        embed4 = discord.Embed(color=self.client.ayesha_blue)
        embed4.set_author(name='Ayesha Tutorial: Introduction',
                          icon_url=self.client.user.avatar_url)
        embed4.set_thumbnail(url=ctx.author.avatar_url)

        embed4.add_field(
            name='The Gacha System!',
            value=
            (f"**∘ |** To get stronger weapons and acolytes, use the `{p}roll` "
             f"command. You can roll up to 10 times at once with `{p}roll 10`.\n"
             f"**∘ |** Each summon from the gacha costs **1 rubidic**, Ayesha's "
             f"gacha currency. You start off with 10 rolls, but can gain more:\n"
             f"**  -** By levelling up (do more `{p}pve`!)\n"
             f"**  -** Doing `{p}daily` every 12 hours, for **2** rubidics.\n"
             f"**  -** And voting for the bot on the bot list! This will net you "
             f"**1** rubidic, but we are listed on two sites (do `{p}vote`). "
             f"Voting has the same cooldown as `{p}daily`, so you can do it at the "
             f"the same time everyday, twice a day, for **8** rubidics/day!"))

        embed4.add_field(
            name='Your Friendly Neighborhood Acolyte',
            value=
            (f"**∘ |** Acolytes are the most effective way to increase your ATK, "
             f"Crit, and HP, and some give other powerful effects!\n"
             f"**∘ |** Acolytes are obtained through gacha. If you've already "
             f"pulled some, you can see your list with `{p}tavern`.\n"
             f"**∘ |** Like your inventory, acolytes have an ID number, and they "
             f"are equipped with the `{p}hire` command. You can have up to 2 "
             f"acolytes equipped at any time, hence the slot being '1 or 2.'"),
            inline=False)

        embed5 = self.ty_embed(p, ctx.author.avatar_url)

        pages = PageMaker.number_pages(
            [embed1, embed2, embed3, embed4, embed5])
        tutorial_pages = menus.MenuPages(
            source=PageSourceMaker.PageMaker(pages),
            clear_reactions_after=True,
            delete_message_after=True)
        await tutorial_pages.start(ctx)
Esempio n. 19
0
 async def _error(self, ctx):
     first_step = list(self.bot.error_cache)
     errors = first_step[::-1]
     pages = menus.MenuPages(source=AllErrorsSource(errors), clear_reactions_after=True,)
     await pages.start(ctx)
Esempio n. 20
0
    async def Acolytes(self, ctx):
        """Learn the game."""
        p = ctx.prefix

        embed1 = discord.Embed(color=self.client.ayesha_blue)
        embed1.set_author(name='Ayesha Tutorial: Acolytes',
                          icon_url=self.client.user.avatar_url)
        embed1.set_thumbnail(url=ctx.author.avatar_url)

        embed1.add_field(
            name='What are Acolytes?',
            value=
            (f"Acolytes are your friends, teammates who fight alongside you in battle. "
             f"They boost your ATK, Crit, and HP, and may have another effect that "
             f"enhances your gameplay.\n\n"
             f"Acolytes are obtained from the `{p}roll` command. There are five "
             f"rarities, from 1⭐ to 5⭐. You have a base 1% chance of rolling "
             f"5⭐ on any roll, but are guaranteed to get one on your 80th "
             f"summon since your 5⭐ or legendary roll."))

        embed2 = discord.Embed(color=self.client.ayesha_blue)
        embed2.set_author(name='Ayesha Tutorial: Acolytes',
                          icon_url=self.client.user.avatar_url)
        embed2.set_thumbnail(url=ctx.author.avatar_url)

        embed2.add_field(
            name='How do I equip my acolytes?',
            value=
            (f"You can view all your acolytes with the `{p}tavern` command.\n\n"
             f"It lists each acolyte, its level and stats, and effect if it has one."
             f"Next to its name is its ID. To add an acolyte to your team, do"
             f"`{p}recruit <ID> <1-2>` to equip it in your 1st or 2nd slot.\n\n"
             f"You only have 2 slots for acolytes, so make sure you choose wisely!"
             ))

        embed3 = discord.Embed(color=self.client.ayesha_blue)
        embed3.set_author(name='Ayesha Tutorial: Acolytes',
                          icon_url=self.client.user.avatar_url)
        embed3.set_thumbnail(url=ctx.author.avatar_url)

        embed3.add_field(
            name='How do I strengthen my acolytes?',
            value=
            (f"The first way to level up your acolytes is passively. For every "
             f"10 xp you earn, your equipped acolytes will earn 1.\n\n"))

        embed3.add_field(
            name='The Second Way: Adventure Awaits!',
            value=
            (f"The second, faster way is with the `{p}train` command. But wait! "
             f"This will require a long and arduous adventure!\n"
             f"If you do `{p}acolyte <Acolyte Name>`, you can see expanded "
             f"information about that acolyte."
             f"Try `{p}acolyte Ayesha`. You will notice that under the 'Details' "
             f"category, it says 'Upgrade Material: Oat'. If you have Ayesha "
             f"and want to level her, that means you have to obtain and use oats."
             f"In order to do that, there are three commands at your service:\n"
             f"**  -** `{p}travel`\n"
             f"**  -** `{p}forage`\n"
             f"**  -** `{p}expedition`\n"),
            inline=False)

        embed4 = discord.Embed(color=self.client.ayesha_blue)
        embed4.set_author(name='Ayesha Tutorial: Acolytes',
                          icon_url=self.client.user.avatar_url)
        embed4.set_thumbnail(url=ctx.author.avatar_url)

        embed4.add_field(
            name='Gathering resources for your acolyte',
            value=
            (f"You now must follow six steps: \n"
             f"**  -** Do `{p}travel` and find which location lists oats. Glakelys "
             f"has oats, so do `{p}travel Glakelys` and wait a few hours to get "
             f"to that location.\n"
             f"**  -** Once there, do `{p}arrive` to officially set your location "
             f"to Glakelys. You can see it change on your `{p}profile`.\n"
             f"**  -** `{p}forage` will actively gain you materials. Alternatively...\n"
             f"**  -** `{p}expedition` will place you on a passive adventure "
             f"in which you collect these materials over the course of a week. "
             f"You can go on expedition for as long as you want. You will gain more "
             f"rewards the longer you're gone, but only for up to a week. You can "
             f"view the length of your expedition with `{p}cooldowns`. Once finished, "
             f"do `{p}arrive` to get all your booty.\n"
             f"**  -** `{p}pack` will show you all the resources you hold. Look at "
             f"how much oat you have now!\n\n"))

        embed4.add_field(
            name='And now I can train!',
            value=
            (f"And now, finally, now that you have all the resources you need, NOW "
             f"you can `{p}train <Acolyte ID>`. Each training costs you `50` material "
             f"and `250` gold, and will net your acolyte 5,000 experience.\n"
             f"Seem slow? You can train multiple times at once. For example, "
             f"`{p}train 1 100` will train the acolyte with ID:1 100 times!"),
            inline=False)

        embed5 = self.ty_embed(p, ctx.author.avatar_url)

        pages = PageMaker.number_pages(
            [embed1, embed2, embed3, embed4, embed5])
        tutorial_pages = menus.MenuPages(
            source=PageSourceMaker.PageMaker(pages),
            clear_reactions_after=True,
            delete_message_after=True)
        await tutorial_pages.start(ctx)
 async def trace(self, ctx: Context, trace: Optional[str] = None):
     """
     Tries to find the anime the image is from through the image url or the image as attachment.
     """
     async with ctx.channel.typing():
         url = None
         if trace is None:
             if ctx.message.attachments:
                 url = ctx.message.attachments[0].url
             else:
                 embed = discord.Embed(
                     title='No image to look for the anime.',
                     color=ERROR_EMBED_COLOR)
                 await ctx.channel.send(embed=embed)
                 ctx.command.reset_cooldown(ctx)
         else:
             url = trace
         if url:
             if not url.lower().endswith(
                 ('.jpg', '.png', '.bmp', '.jpeg', '.gif')):
                 embed = discord.Embed(
                     title=
                     'No correct url specified (`.jpg`, `.png`, `.bmp`, `.jpeg`, `.gif`).',
                     color=ERROR_EMBED_COLOR)
                 await ctx.channel.send(embed=embed)
                 ctx.command.reset_cooldown(ctx)
             else:
                 try:
                     data = await self.bot.tracemoe.search(url)
                 except Exception as e:
                     log.exception(e)
                     embed = discord.Embed(
                         title=
                         f'An error occurred while searching for the anime or the link is invalid.',
                         color=ERROR_EMBED_COLOR)
                     return await ctx.channel.send(embed=embed)
                 if data:
                     embeds = []
                     for page, anime in enumerate(data):
                         try:
                             embed = await self.get_trace_embed(
                                 anime, page + 1, len(data))
                             if is_adult(anime):
                                 if not ctx.channel.is_nsfw():
                                     embed = discord.Embed(
                                         title='Error',
                                         color=ERROR_EMBED_COLOR,
                                         description=
                                         f'Adult content. No NSFW channel.')
                                     embed.set_footer(
                                         text=
                                         f'Provided by https://trace.moe/ • Page {page + 1}/{len(data)}'
                                     )
                         except Exception as e:
                             log.exception(e)
                             embed = discord.Embed(
                                 title='Error',
                                 color=DEFAULT_EMBED_COLOR,
                                 description=
                                 'An error occurred while loading the embed.'
                             )
                             embed.set_footer(
                                 text=
                                 f'Provided by https://trace.moe/ • Page {page + 1}/{len(data.get("docs"))}'
                             )
                         embeds.append(embed)
                     menu = menus.MenuPages(source=EmbedListMenu(embeds),
                                            clear_reactions_after=True,
                                            timeout=30)
                     await menu.start(ctx)
                 else:
                     embed = discord.Embed(title='No anime found.',
                                           color=ERROR_EMBED_COLOR)
                     await ctx.channel.send(embed=embed)
Esempio n. 22
0
    async def Items(self, ctx):
        """Learn the game."""
        p = ctx.prefix

        embed1 = discord.Embed(color=self.client.ayesha_blue)
        embed1.set_author(name='Ayesha Tutorial: Items',
                          icon_url=self.client.user.avatar_url)
        embed1.set_thumbnail(url=ctx.author.avatar_url)

        embed1.add_field(
            name=f"Item Overview",
            value=
            (f"You can have one weapon equipped at any time and are the "
             f"easiest way to increase your ATK and Crit stats.\n\n"
             f"You can view all your owned weapons with the `{p}inventory` command. "
             f"Alongside its Attack, and Crit, each item has an ID, the number "
             f"next to its name, which you use when you want to use other "
             f"commands on an item."))
        embed1.add_field(
            name=f"Weapontype and Rarity",
            value=
            (f"Each weapon also has one of 13 types and one of 5 rarities.\n\n"
             f"Equipping a weapon of a certain type might give you a 20 ATK bonus, "
             f"depending on your class. The weapontypes associated with your class "
             f"can be found in the `{p}class` menu.\n\n"
             f"Your weapontype might also affect your rewards from `{p}mine`, "
             f"`{p}hunt`, and `{p}forage`.\n\n"
             f"You can filter through your inventory by weapontype and rarity. "
             f"To see all your maces, do `{p}inventory mace`, and to see all "
             f"your epic items, do `{p}inventory epic`. To see all of your "
             f"epic maces, do `{p}inventory epic mace`."),
            inline=False)

        embed2 = discord.Embed(color=self.client.ayesha_blue)
        embed2.set_author(name='Ayesha Tutorial: Items',
                          icon_url=self.client.user.avatar_url)
        embed2.set_thumbnail(url=ctx.author.avatar_url)

        embed2.add_field(
            name=f"Upgrading Items",
            value=
            (f"Items have a certain range of ATK and Crit based off its rarity, "
             f"but the ATK value can be increased up to a point. The first way "
             f"is via the `{p}upgrade` command. Upgrading can only be done in "
             f"urban areas, and costs you gold and iron. There is also a limit "
             f"to the ATK you can upgrade to depending on the item's rarity.\n\n"
             f"The `{p}merge` command can boost an item's attack past the limit "
             f"of `{p}upgrade`. Merging, however, requires a weaker weapon of "
             f"the same weapontype to be destroyed. Blacksmiths can use the "
             f"`{p}forge` command, which costs more than `{p}merge`, but "
             f"raise the weapon's attack more."))
        embed2.add_field(
            name=f"Selling Items",
            value=
            (f"You can sell items you no longer want for gold. "
             f"The `{p}sell` command will let you sell any single item. You can "
             f"also list multiple IDs with `{p}sellmultiple` or sell all your items "
             f"of a specific rarity with `{p}sellall`. None of these commands will "
             f"net you more gold per weapon and exist for convenience.\n\n"
             f"Alternatively, you can `{p}offer` your unwanted strong weapons "
             f"to other players for a price."),
            inline=False)

        embed3 = self.ty_embed(p, ctx.author.avatar_url)

        pages = PageMaker.number_pages([embed1, embed2, embed3])
        tutorial_pages = menus.MenuPages(
            source=PageSourceMaker.PageMaker(pages),
            clear_reactions_after=True,
            delete_message_after=True)
        await tutorial_pages.start(ctx)
Esempio n. 23
0
    async def importsona(self, ctx: utils.Context):
        """
        Get your sona from another server.
        """

        # See if they're setting one up already
        if ctx.author.id in self.currently_setting_sonas:
            return await ctx.send(
                "You're already setting up a sona! Please finish that one off first!"
            )

        # Try and send them an initial DM
        try:
            await ctx.author.send(
                f"Now taking you through importing your sona to **{ctx.guild.name}**!"
            )
        except discord.Forbidden:
            return await ctx.send(
                "I couldn't send you a DM! Please open your DMs for this server and try again."
            )
        self.currently_setting_sonas.add(ctx.author.id)
        await ctx.send("Sent you a DM!")

        # Get sona data
        async with self.bot.database() as db:
            database_rows = await db("SELECT * FROM fursonas WHERE user_id=$1",
                                     ctx.author.id)

        # Format that into a list
        all_user_sonas = []
        for row in database_rows:
            try:
                guild = self.bot.get_guild(
                    row['guild_id']) or await self.bot.fetch_guild(
                        row['guild_id'])
            except discord.Forbidden:
                guild = None

            # Add to the all sona list
            menu_data = dict(row)
            if guild:
                menu_data.update({"guild_name": guild.name})
            else:
                menu_data.update({"guild_name": "Unknown Guild Name"})
            all_user_sonas.append(menu_data)

        # Let's add our other servers via their APIs
        for api_data in self.OTHER_FURRY_GUILD_DATA[::-1]:

            # Format data
            url = api_data['url']
            params = {
                i: o.format(user=ctx.author, guild=ctx.guild, bot=self.bot)
                for i, o in api_data.get('params', dict()).copy().items()
            }
            headers = {
                i: o.format(user=ctx.author, guild=ctx.guild, bot=self.bot)
                for i, o in api_data.get('headers', dict()).copy().items()
            }

            # Run request
            try:
                async with self.bot.session.get(url,
                                                params=params,
                                                headers=headers) as r:
                    grabbed_sona_data = await r.json()
            except Exception:
                grabbed_sona_data = {'data': []}

            # Add to lists
            if grabbed_sona_data['data']:
                guild_id = api_data['guild_id']
                guild_name = api_data['name']

                # Add to the all sona list
                for sona in grabbed_sona_data['data']:
                    menu_data = sona.copy()
                    menu_data.update({
                        "guild_name": guild_name,
                        "guild_id": guild_id
                    })
                    all_user_sonas.append(menu_data)

        # Filter the list
        all_user_sonas = [
            i for i in all_user_sonas if i['guild_id'] != ctx.guild.id
        ]
        if not self.bot.guild_settings[ctx.guild.id]["nsfw_is_allowed"]:
            all_user_sonas = [i for i in all_user_sonas if i['nsfw'] is False]
        if not all_user_sonas:
            self.currently_setting_sonas.remove(ctx.author.id)
            return await ctx.send(
                "You have no sonas available to import from other servers.")

        # Send it off to the user
        pages = menus.MenuPages(
            source=FursonaPageSource(all_user_sonas, per_page=1))
        await pages.start(ctx, channel=ctx.author, wait=True)

        # Ask if the user wants to import the sona they stopped on
        sona_data = pages.raw_sona_data
        ask_import_message = await ctx.author.send(
            f"Do you want to import your sona from **{sona_data['guild_name']}**?"
        )
        await ask_import_message.add_reaction(self.CHECK_MARK_EMOJI)
        await ask_import_message.add_reaction(self.CROSS_MARK_EMOJI)
        try:
            check = lambda r, u: r.message.id == ask_import_message.id and u.id == ctx.author.id
            reaction, _ = await self.bot.wait_for("reaction_add",
                                                  check=check,
                                                  timeout=120)
        except asyncio.TimeoutError:
            self.currently_setting_sonas.remove(ctx.author.id)
            return await ctx.author.send("Timed out asking about sona import.")

        # Import data
        self.currently_setting_sonas.remove(ctx.author.id)
        emoji = str(reaction.emoji)
        if emoji == self.CROSS_MARK_EMOJI:
            return await ctx.author.send(
                "Alright, cancelled importing your sona.")
        command = self.bot.get_command("setsonabyjson")
        ctx.information = sona_data
        return await command.invoke(ctx)
Esempio n. 24
0
def menuobj(inp):
	a = ['.']
	for i in range(9):
		a.append('.')
	return menus.MenuPages(source=MySource(a, inp), clear_reactions_after=True)
Esempio n. 25
0
async def show_tagslist_embed(ctx: MyContext, tags: List[Tag]):
    pages = menus.MenuPages(source=TagsListMenuSource(ctx, tags),
                            clear_reactions_after=True)
    await pages.start(ctx)
Esempio n. 26
0
    async def inventory(self, ctx, *, query=''):
        """`query`: the way you want to sort your items. Put a weapontype, rarity, and order by attack or crit.

        View your inventory of items. Each item has an ID listed netx to its name that can be referenced for related commands.
        You can also sort specifically by weapontype, rarity, and order by attack or crit. Simply add the things you want to sort by in the command to get a smaller inventory.
        For example, to get all common swords in your inventory, do `%inventory common sword`. You can also do `%inventory crit` to sort all your weapons by crit.
        """
        #Create a list of all the queries for individual filtering
        sort = [term.title() for term in query.split()]

        #These functions will see how the items are sorted
        def filter_weapontypes(query):
            weapontypes = self.client.weapontypes
            if query in weapontypes:
                return True
            else:
                return False

        def filter_rarity(query):
            rarities = ['Common', 'Uncommon', 'Rare', 'Epic', 'Legendary']
            if query in rarities:
                return True
            else:
                return False

        def filter_metric(query):
            stats = ['Attack', 'Crit']
            if query in stats:
                return True
            else:
                return False

        filtered_type = filter(filter_weapontypes, sort)
        filtered_rarity = filter(filter_rarity, sort)
        filtered_stat = filter(filter_metric, sort)

        try:
            weapontype = list(filtered_type)[0]
        except IndexError:
            weapontype = None

        try:
            rarity = list(filtered_rarity)[0]
        except IndexError:
            rarity = None

        try:
            stat = list(filtered_stat)[0]
        except IndexError:
            stat = 'attack'

        #Retrieve the player's inventory based off the queries, but put equipped item first always
        inventory = []
        equipped_item = await self.client.pg_con.fetchrow(
            'SELECT item_id, weapontype, attack, crit, weapon_name, rarity, is_equipped FROM items WHERE owner_id = $1 AND is_equipped = True',
            ctx.author.id)
        if equipped_item is not None:
            inventory.append(equipped_item)

        psql = 'SELECT item_id, weapontype, attack, crit, weapon_name, rarity, is_equipped FROM items WHERE owner_id = $1 AND is_equipped = False '

        if stat == 'attack':
            psql2 = ' ORDER BY attack DESC'
        else:
            psql2 = ' ORDER BY crit DESC'

        if weapontype is not None and rarity is not None:
            psql += 'AND weapontype = $2 AND rarity = $3 ' + psql2
            inv = await self.client.pg_con.fetch(psql, ctx.author.id,
                                                 weapontype, rarity)

        elif weapontype is None and rarity is not None:
            psql += 'AND rarity = $2 ' + psql2
            inv = await self.client.pg_con.fetch(psql, ctx.author.id, rarity)

        elif weapontype is not None and rarity is None:
            psql += 'AND weapontype = $2 ' + psql2
            inv = await self.client.pg_con.fetch(psql, ctx.author.id,
                                                 weapontype)

        else:
            psql += psql2
            inv = await self.client.pg_con.fetch(psql, ctx.author.id)

        for item in inv:
            inventory.append(item)

        invpages = []
        for i in range(0, len(inv), 5):  #list 5 entries at a time
            invpages.append(self.write(
                i, inventory,
                ctx.author.display_name))  # Write will create the embeds
        if len(invpages) == 0:
            await ctx.reply('Your inventory is empty!')
        else:
            invpages = PageSourceMaker.PageMaker.number_pages(invpages)
            inventory = menus.MenuPages(
                source=PageSourceMaker.PageMaker(invpages),
                clear_reactions_after=True,
                delete_message_after=True)
            await inventory.start(ctx)
Esempio n. 27
0
def MakeMenu(name, data, embedcolor, perPage):
    return menus.MenuPages(source=MenuList(name, data, embedcolor, perPage),
                           clear_reactions_after=True)
Esempio n. 28
0
    async def leaderboard(self, ctx: utils.Context, days: int = None):
        """
        Gives you the leaderboard users for the server.
        """

        if days is None:
            days = self.bot.guild_settings[
                ctx.guild.id]['activity_window_days']
        elif days <= 0:
            days = 7
        elif days > 365:
            days = 365

        # This takes a while
        async with ctx.typing():

            # Get all their valid user IDs
            async with self.bot.database() as db:
                message_rows = await db(
                    """SELECT user_id, COUNT(timestamp) FROM user_messages WHERE guild_id=$1 AND
                    timestamp > TIMEZONE('UTC', NOW()) - MAKE_INTERVAL(days => $2) GROUP BY user_id
                    ORDER BY COUNT(timestamp) DESC LIMIT 30;""",
                    ctx.guild.id,
                    days,
                )
                point_rows = await db(
                    """SELECT user_id, SUM(points) FROM user_messages WHERE guild_id=$1 AND
                    timestamp > TIMEZONE('UTC', NOW()) - MAKE_INTERVAL(days => $2) GROUP BY user_id
                    ORDER BY SUM(points) DESC LIMIT 30;""",
                    ctx.guild.id,
                    days,
                )
                vc_rows = await db(
                    """SELECT user_id, COUNT(timestamp) FROM user_vc_activity WHERE guild_id=$1 AND
                    timestamp > TIMEZONE('UTC', NOW()) - MAKE_INTERVAL(days => $2) GROUP BY user_id
                    ORDER BY COUNT(timestamp) DESC LIMIT 30;""",
                    ctx.guild.id,
                    days,
                )

            # Sort that into more formattable data
            user_data_dict = collections.defaultdict({
                'points': 0,
                'message_count': 0,
                'vc_minute_count': 0
            }.copy)  # uid: {message_count: int, vc_minute_count: int}
            for row in point_rows:
                user_data_dict[row['user_id']]['points'] = row['sum']
            for row in message_rows:
                user_data_dict[row['user_id']]['message_count'] = row['count']
            for row in vc_rows:
                user_data_dict[
                    row['user_id']]['vc_minute_count'] = row['count']

            # And now make it into something we can sort
            guild_user_data = [(uid, d['points'], d['message_count'],
                                d['vc_minute_count'])
                               for uid, d in user_data_dict.items()]
            valid_guild_user_data = []
            for i in guild_user_data:
                try:
                    if ctx.guild.get_member(
                            i[0]) or await ctx.guild.fetch_member(i[0]):
                        valid_guild_user_data.append(i)
                except discord.HTTPException:
                    pass
            ordered_guild_user_data = sorted(valid_guild_user_data,
                                             key=lambda k: k[1] + (k[3] // 5),
                                             reverse=True)

        # Make menu
        pages = menus.MenuPages(source=LeaderboardSource(
            self.bot, ctx.guild.id, ordered_guild_user_data,
            f"Tracked Points over {days} days"),
                                clear_reactions_after=True)
        return await pages.start(ctx)
Esempio n. 29
0
 async def dice(self, ctx, *dice: converters.Dice):
     """Takes the typical die+/-mod format to output the results"""
     results = [die.print() for die in dice]
     die_menu = menus.MenuPages(source=DiceListMenu(results),
                                clear_reactions_after=True)
     await die_menu.start(ctx)
Esempio n. 30
0
 async def fun(self, ctx):
     source = self.FunSource(self.bot.get_cog("Fun").get_commands())
     p1 = menus.MenuPages(source)
     await p1.start(ctx)