Ejemplo n.º 1
0
    async def colour(
        self,
        ctx: vbu.Context,
        *,
        colour: typing.Union[vbu.converters.ColourConverter, discord.Colour,
                             discord.Role, discord.Member],
    ):
        """
        Get you a colour.
        """

        # https://www.htmlcsscolor.com/preview/gallery/5dadec.png
        if isinstance(colour, discord.Role):
            colour = colour.colour
        elif isinstance(colour, discord.Member):
            try:
                colour = [i for i in colour.roles
                          if i.colour.value > 0][-1].colour
            except IndexError:
                colour = discord.Colour(0)
        hex_colour = colour.value
        with vbu.Embed(colour=hex_colour,
                       title=f"#{hex_colour:0>6X}") as embed:
            embed.set_image(
                url=
                f"https://www.htmlcsscolor.com/preview/gallery/{hex_colour:0>6X}.png"
            )
        await ctx.send(embed=embed)
Ejemplo n.º 2
0
    async def rtdm_js(self, ctx, *, obj: str):
        """
        Gives you a documentation link for a Javascript entity.
        """

        url = "https://developer.mozilla.org/api/v1/search"
        params = {
            'q': obj,
            'local': 'en-US',
        }
        headers = {
            'User-Agent': self.bot.user_agent,
        }
        async with self.bot.session.get(url, params=params, headers=headers) as r:
            data = await r.json()
        if not data['documents']:
            return await ctx.send("I couldn't find anything. Sorry.")
        embed = vbu.Embed(use_random_colour=True, description="")
        for i in data['documents']:
            if 'web/javascript' not in i['slug']:
                continue
            embed.description += f"[`{i['title']}`](https://developer.mozilla.org{i['mdn_url']})\n"
            if embed.description.count("\n") >= 8:
                break
        return await ctx.send(embed=embed)
Ejemplo n.º 3
0
    async def rtdm_dotnet(self, ctx, *, obj: str):
        """
        Gives you a documentation link for a .NET entity.
        """

        url = "https://docs.microsoft.com/api/apibrowser/dotnet/search"
        params = {
            'api-version': '0.2',
            'search': obj,
            'locale': 'en-us',
            '$filter': "monikers/any(t: t eq 'net-5.0')",
        }
        headers = {
            'User-Agent': self.bot.user_agent,
        }
        async with self.bot.session.get(url, params=params, headers=headers) as r:
            data = await r.json()
        if not data['results']:
            return await ctx.send("I couldn't find anything. Sorry.")
        embed = vbu.Embed(use_random_colour=True, description="")
        for i in data['results']:
            embed.description += f"[`{i['displayName']}`]({i['url']})\n"
            if embed.description.count("\n") >= 8:
                break
        return await ctx.send(embed=embed)
Ejemplo n.º 4
0
    async def wolfram(self, ctx: vbu.Context, *, search: str):
        """
        Send a query to WolframAlpha.
        """

        # Build our request
        params = {
            "input": search,
            "appid": self.bot.config['api_keys']['wolfram'],
            "format": "image",
            "output": "json",
        }
        headers = {
            "User-Agent": self.bot.user_agent,
        }

        # Send our request
        async with self.bot.session.get(
            "https://api.wolframalpha.com/v2/query",
            params=params,
            headers=headers) as r:
            data = json.loads(await r.text())

        # Send output
        try:
            pod = data['queryresult']['pods'][1]
            embed = vbu.Embed(
                title=pod['title'],
                use_random_colour=True,
            ).set_image(url=pod['subpods'][0]['img']['src'], )
            return await ctx.send(embed=embed)
        except (KeyError, IndexError):
            return await ctx.send("No results for that query!")
Ejemplo n.º 5
0
    async def dnd_class(self, ctx: commands.Context, *, class_name: str):
        """
        Gives you information on a D&D class.
        """

        # Get our data
        async with ctx.typing():
            data = await self.send_web_request("classes", class_name)
        if not data:
            return await ctx.send(
                "I couldn't find any information for that class.")

        # Make embed
        embed = vbu.Embed(
            use_random_colour=True,
            title=data['name'],
        ).add_field(
            "Proficiencies",
            ", ".join([i['name'] for i in data['proficiencies']]),
        ).add_field(
            "Saving Throws",
            ", ".join([i['name'] for i in data['saving_throws']]),
        ).add_field(
            "Starting Equipment",
            "\n".join([
                f"{i['quantity']}x {i['equipment']['name']}"
                for i in data['starting_equipment']
            ]),
        )

        # And send
        return await ctx.send(embed=embed)
Ejemplo n.º 6
0
    async def points_leaderboard_show(self, ctx: vbu.Context):
        """
        Show the points leaderboard without creating a new one.
        """

        # Make some assertions
        assert ctx.guild

        # See if they're running a subcommand
        if ctx.invoked_subcommand is not None:
            return

        # Get data
        async with vbu.Database() as db:
            rows = await db(
                "SELECT * FROM user_points WHERE guild_id=$1 AND points > 0 ORDER BY points DESC",
                ctx.guild.id)

        # Format it into an embed
        valid_users = []
        for i in rows:
            member = ctx.guild.get_member(i['user_id'])
            if member is None:
                continue
            valid_users.append(f"{member.mention}: {i['points']:,}")
            if len(valid_users) >= 30:
                break
        with vbu.Embed(use_random_colour=True) as embed:
            embed.description = '\n'.join(
                valid_users) or 'Nobody is on here :c'

        # Output
        await ctx.send(embed=embed)
Ejemplo n.º 7
0
    async def whois(self, ctx: vbu.Context, user: discord.Member = None):
        """
        Give you some information about a user.
        """

        # Set up our intial vars
        user = user or ctx.author
        embed = vbu.Embed(use_random_colour=True)
        embed.set_author_to_user(user)

        # Get the user account creation time
        create_value = f"{discord.utils.format_dt(user.created_at)}\n{discord.utils.format_dt(user.created_at, 'R')}"
        embed.add_field("Account Creation Time", create_value, inline=False)

        # Get the user guild join time
        if ctx.guild:
            join_value = f"{discord.utils.format_dt(user.joined_at)}\n{discord.utils.format_dt(user.joined_at, 'R')}"
            embed.add_field("Guild Join Time", join_value, inline=False)

        # Set the embed thumbnail
        embed.set_thumbnail(user.display_avatar.with_size(1024).url)

        # Sick
        if isinstance(ctx, commands.SlashContext):
            return await ctx.interaction.response.send_message(embed=embed)
        else:
            return await ctx.send(embed=embed)
Ejemplo n.º 8
0
    def get_embed_from_cache(self, cache, obj) -> dict:
        """
        Build up some kwargs from the cache and a given input object.
        """

        item_casefold = obj.casefold()
        item_underscore_casefold = item_casefold.replace(" ", "_")
        split = item_casefold.split('.')
        split_underscore = [i.replace(" ", "_") for i in split]
        outputs = []

        for key, link in cache.items():

            # Key would be something like 'TextChannel.fetch', now 'textchannel.fetch'
            key_casefold = key.casefold()

            # See if we got an exact match
            if item_casefold in key_casefold or item_underscore_casefold in key_casefold:
                if item_casefold == key_casefold or item_underscore_casefold == key_casefold:
                    outputs.append((key, link, 20,))
                else:
                    outputs.append((key, link, 15,))

            # See if we're looking for a method
            if len(split) == 1:
                continue

            # Search by method
            if split[1] and split[1] in key_casefold or split_underscore[1] in key_casefold:
                if split[1] == key_casefold or split_underscore[1] == key_casefold:
                    outputs.append((key, link, 12,))
                else:
                    outputs.append((key, link, 10,))

            # Search by class
            if split[0] and split[0] in key_casefold or split_underscore[0] in key_casefold:
                if split[0] == key_casefold or split_underscore[0] == key_casefold:
                    outputs.append((key, link, 7,))
                else:
                    outputs.append((key, link, 5,))

        # Hey maybe they didn't say anything useful
        if len(outputs) == 0:
            return {"content": "I couldn't find anything. Sorry."}

        # Yo there's a result. Let's embed that.
        embed = vbu.Embed(use_random_colour=True)
        outputs.sort(key=lambda i: (i[2], i[0]), reverse=True)
        embed.description = ""
        for key, url, weight in outputs:
            v = f"[`{key}`]({url})\n"
            if v in embed.description:
                continue
            embed.description += v
            if embed.description.count("\n") >= 8:
                break
        return {"embed": embed}
Ejemplo n.º 9
0
    async def pypi(self, ctx: vbu.Context, package_name: str):
        """
        Grab data from PyPi.
        """

        # Get data
        async with self.bot.session.get(f"https://pypi.org/pypi/{package_name}/json") as r:
            if r.status != 200:
                with vbu.Embed(use_random_colour=True) as embed:
                    embed.title = f"Module `{package_name}` not found"
                    embed.description = f"[Search Results](https://pypi.org/search/?q={package_name})"
                return await ctx.send(embed=embed)
            data = await r.json()

        # Format into an embed
        with vbu.Embed(use_random_colour=True) as embed:
            embed.set_author(name=data['info']['name'], url=f"https://pypi.org/project/{package_name}")
            embed.description = data['info']['summary']
        return await ctx.send(embed=embed)
Ejemplo n.º 10
0
        def formatter(menu, items):
            # Create the embed
            commands_embed = vbu.Embed(title="Command Data (times run)")
            # Add the total count footer
            commands_embed.set_footer(text=f"Total: {total_count}")
            # Add the command list to the emebd
            commands_embed.description = "\n".join(items)

            # Return the embed
            return commands_embed
Ejemplo n.º 11
0
    async def fox(self, ctx: commands.Context):
        """
        Give you a foxxo picture!
        """

        await ctx.trigger_typing()
        headers = {"User-Agent": self.bot.user_agent}
        async with self.bot.session.get("https://randomfox.ca/floof/",
                                        headers=headers) as r:
            data = await r.json()
        with vbu.Embed(use_random_colour=True) as embed:
            embed.set_image(url=data['image'])
        await ctx.send(embed=embed)
Ejemplo n.º 12
0
    def default_ranked_list_formatter(m: "Paginator", d: typing.List[str]):
        """
        The default list formatter for embeds. Takes the paginator instance and the list of strings to be displayed,
        and returns a dictionary of kwargs for a `Message.edit`.
        """

        return vbu.Embed(
            use_random_colour=True,
            description="\n".join([
                f"{i}. {o}"
                for i, o in enumerate(d,
                                      start=(m.current_page * m.per_page) + 1)
            ]),
        ).set_footer(f"Page {m.current_page + 1}/{m.max_pages}", )
Ejemplo n.º 13
0
    async def dog(self, ctx: commands.Context):
        """
        Give you a doggo picture!
        """

        await ctx.trigger_typing()
        headers = {"User-Agent": self.bot.user_agent}
        url = "https://dog.ceo/api/breeds/image/random"
        async with self.bot.session.get(url, headers=headers) as r:
            data = await r.json()
        if data['status'] == "error":
            return await ctx.send("No dogs were found :(")
        with vbu.Embed(use_random_colour=True) as embed:
            embed.set_image(url=data['message'])
        await ctx.send(embed=embed)
Ejemplo n.º 14
0
    async def enlarge(
            self,
            ctx: vbu.Context,
            target: typing.Union[discord.Member, discord.User, discord.Emoji, discord.PartialEmoji] = None,
            ):
        """
        Enlarges the avatar or given emoji.
        """

        target = target or ctx.author
        if isinstance(target, (discord.User, discord.Member, discord.ClientUser)):
            url = target.display_avatar.url
        elif isinstance(target, (discord.Emoji, discord.PartialEmoji)):
            url = target.url
        with vbu.Embed(color=0x1) as embed:
            embed.set_image(url=str(url))
        await ctx.send(embed=embed)
Ejemplo n.º 15
0
    async def on_leaderboard_update(self, guild: discord.Guild):
        """
        Update the leaderboard message.
        """

        # See if we can get the leaderboard message
        class FakeContext:
            bot = self.bot

        leaderboard_message_url = self.bot.guild_settings[
            guild.id]['leaderboard_message_url']
        if not leaderboard_message_url:
            return
        try:
            message = await commands.MessageConverter().convert(
                FakeContext, leaderboard_message_url)
        except commands.BadArgument:
            return
        if message is None:
            return

        # Get data
        async with vbu.Database() as db:
            rows = await db(
                "SELECT * FROM user_points WHERE guild_id=$1 AND points > 0 ORDER BY points DESC",
                guild.id)

        # Format it into an embed
        valid_users = []
        for i in rows:
            member = guild.get_member(i['user_id'])
            if member is None:
                continue
            valid_users.append(f"{member.mention}: {i['points']:,}")
            if len(valid_users) >= 30:
                break
        with vbu.Embed(use_random_colour=True) as embed:
            embed.description = '\n'.join(
                valid_users) or 'Nobody is on here :c'

        # Output
        await message.edit(content=None, embed=embed)
Ejemplo n.º 16
0
 async def _show_pp(self, ctx: commands.SlashContext) -> None:
     async with vbu.DatabaseConnection() as db:
         cache: utils.CachedUser = await utils.get_user_cache(
             ctx.author.id,
             db=db,
             bot=self.bot,
             logger=self.logger,
         )
         with vbu.Embed() as embed:
             embed.colour = utils.BLUE
             embed.set_author(
                 name=f"{ctx.author.display_name}'s PP",
                 icon_url=ctx.author.avatar.url,
             )
             embed.description = f"8{('='*(cache.pp.size // 50))[:1000]}D"
             embed.add_field(
                 "Stats",
                 f"Size - {cache.pp.size}\nMultiplier - {cache.pp.multiplier}",
             )
         await ctx.interaction.response.send_message(embed=embed)
Ejemplo n.º 17
0
    async def npm(self, ctx: vbu.Context, package_name: str):
        """
        Check NPM for a package.
        """

        # Get our data
        async with self.bot.session.get(f"http://registry.npmjs.com/{package_name}/") as e:
            if e.status == 404:
                await ctx.send(f"I could not find anything about `{package_name}` :c")
                return
            if e.status != 200:
                await ctx.send("Something went wrong, try again later...")
                return
            data = await e.json()

        # make a lil embed
        with vbu.Embed(use_random_colour=True) as embed:
            embed.set_author(name=data['name'], url=f"https://www.npmjs.com/package/{package_name}")
            embed.description = data['description']
        await ctx.send(embed=embed)
Ejemplo n.º 18
0
    async def cat(self, ctx: commands.Context):
        """
        Give you a cat picture!
        """

        await ctx.trigger_typing()
        headers = {
            "User-Agent": self.bot.user_agent,
            "x-api-key": self.bot.config['api_keys']['cat_api']
        }
        params = {"limit": 1}
        async with self.bot.session.get(
                "https://api.thecatapi.com/v1/images/search",
                params=params,
                headers=headers) as r:
            data = await r.json()
        if not data:
            return await ctx.send("I couldn't find that breed of cat.")
        with vbu.Embed(use_random_colour=True) as embed:
            embed.set_image(url=data[0]['url'])
        await ctx.send(embed=embed)
Ejemplo n.º 19
0
 def formatter(
         menu: utils.Paginator,
         items: typing.List[utils.LootableItem]) -> vbu.Embed:
     with vbu.Embed() as embed:
         output = []
         for item in items:
             output.append(
                 f"2x {item.emoji} **{item.name}** ─ {item.type.replace('_', ' ').title()}"
                 +
                 f"\n **{item.rarity.replace('_', ' ').title()}**"
                 + f"  ─ `{item.id}` {item.description}")
         embed.set_author(
             name=f"{ctx.author.display_name}'s inventory",
             icon_url=ctx.author.avatar.url,
         )
         embed.description = (
             f"use [/item-info [item]]({self.bot.hyperlink}) for more information.\n\n"
             + "\n\n".join(output))
         embed.set_footer(
             f"Page {menu.current_page + 1}/{menu.max_pages}")
     return embed
Ejemplo n.º 20
0
    async def nuget(self, ctx: vbu.Context, package_name: str):
        """
        Check nuget for a package.
        """

        # Get our data
        async with self.bot.session.get(f"https://azuresearch-usnc.nuget.org/query?q={package_name}") as e:
            if e.status != 200:
                await ctx.send("Something went wrong, try again later...")
                return
            data = await e.json()

        # make a lil embed
        with vbu.Embed(use_random_colour=True) as embed:
            if data['data']:
                embed.set_author(name=data['data'][0]['title'], url=f"https://www.nuget.org/packages/{data['data'][0]['id']}")
                embed.description = data['data'][0]['description']
            else:
                await ctx.send(f"I could not find anything for `{package_name}` :c")
                return
        await ctx.send(embed=embed)
Ejemplo n.º 21
0
    async def dnd_condition(self, ctx: commands.Context, *,
                            condition_name: str):
        """
        Gives you information on a D&D condition.
        """

        # Get our data
        async with ctx.typing():
            data = await self.send_web_request("conditions", condition_name)
        if not data:
            return await ctx.send(
                "I couldn't find any information for that condition.")

        # Make an embed
        embed = vbu.Embed(
            use_random_colour=True,
            title=data['name'],
            description="\n".join(data['desc']),
        )

        # And send
        return await ctx.send(embed=embed)
Ejemplo n.º 22
0
    async def grandexchange(self, ctx: vbu.Context, *, item: str):
        """
        Get the value of an item on the grand exchange (OSRS).
        """

        async with ctx.typing():
            if item.lower() in ['random']:
                item_id = random.choice(list(self.item_ids.values()))
            else:
                item = item.capitalize()
                item_id = self.item_ids.get(item)

            if item_id:
                item_dict = await self.get_item_details_by_id(item_id)
                item_value = await self.parse_item_value(item_dict,
                                                         return_int=False)

                name = item_dict['name']
                item_page_url = API_BASE_URL + f"a=373/{name.replace(' ', '+')}/viewitem?obj={item_id}"

                with vbu.Embed() as embed:
                    embed.set_author(name=name,
                                     url=item_page_url,
                                     icon_url=item_dict['icon'])
                    embed.set_thumbnail(url=item_dict['icon_large'])
                    embed.add_field('Value',
                                    f'{item_value} coins',
                                    inline=False)
                    embed.add_field(f'Examine {name}',
                                    item_dict['description'],
                                    inline=False)
                    embed.add_field('Members',
                                    MEMBERS_MAPPING[item_dict['members']],
                                    inline=False)

                return await ctx.send(embed=embed)
            else:
                return await ctx.send('Item not found')
Ejemplo n.º 23
0
    def default_list_formatter(
            m: "Paginator",
            d: _EmbedOrStringList) -> typing.Union[_EmbedsDict, discord.Embed]:
        """
        The default list formatter for embeds. Takes the paginator instance and the list of data
        to be displayed, and returns a dictionary of kwargs for a `Message.edit`.
        """

        if all(isinstance(i, discord.Embed) for i in d):
            if typing.TYPE_CHECKING:
                typed_embeds_d = typing.cast(_EmbedsDict, {"embeds": d})
            else:
                typed_embeds_d = {"embeds": d}
            return typed_embeds_d
        else:
            if typing.TYPE_CHECKING:
                typed_str_d = typing.cast(typing.List[str], d)
            else:
                typed_str_d = d
            return vbu.Embed(
                use_random_colour=True,
                description="\n".join(typed_str_d),
            ).set_footer(f"Page {m.current_page + 1}/{m.max_pages}", )
Ejemplo n.º 24
0
    async def upgrades(self, ctx: commands.Context):
        """
        Show you your upgrades and the price of the next level.
        """

        # The output that we want to build
        message = []  # A list of text to send
        emote_string_list = []  # Their emoji progress bar

        # Grab their upgrades from the database
        if not await utils.check_registered(self.bot, ctx.author.id):
            return await ctx.send("Please use the `register` command before using this bot!")
        async with vbu.Database() as db:
            upgrades = await db(
                """SELECT rod_upgrade, bait_upgrade, line_upgrade, lure_upgrade, crate_chance_upgrade, weight_upgrade,
                crate_tier_upgrade, bleach_upgrade, toys_upgrade, amazement_upgrade, mutation_upgrade,
                big_servings_upgrade, hygienic_upgrade, feeding_upgrade
                FROM user_upgrades WHERE user_id = $1""",
                ctx.author.id,
            )

        # Find the positions for the different upgrades
        positions = [(2140, 910), (1300, 1070), (1310, 1260), (1710, 1080), (2200, 1470),
                     (1760, 1290), (2180, 1450), (2670,
                                                  170), (240, 210), (840, 110),
                     (550, 1460), (840, 750), (1930, 190), (1020, 1290)]

        # Makes a list of the upgrades names
        list_of_upgrades = [single for single in upgrades[0].keys()]

        # Create an id for the image
        id = "".join(
            random.choice(string.ascii_uppercase + string.digits)
            for _ in range(10)
        )

        # Set the file prefix, shadow path, and file name
        file_prefix = "C:/Users/JT/Pictures/Aqua/assets/images"
        shadow = f"{file_prefix}/background/Room Walls/shadow-export.png"
        file_name = f"{file_prefix}/background/Room Walls/Upgrades_Wall/User Walls/{id}user_upgrade_room.png"

        # Open the shadow and background, make a copy of background
        shadow = Image.open(shadow).convert("RGBA")
        background = Image.open(
            f"{file_prefix}/background/Room Walls/Upgrade_Wall-export.png"
        ).convert("RGBA")
        new_background = background.copy()

        # For each upgrade open the upgrade at it's tier and paste it to the background
        for i, upgrade in enumerate(upgrades[0]):
            added_upgrade = Image.open(
                f"{file_prefix}/background/Room Walls/Upgrades_Wall/{list_of_upgrades[i]}_tier_{upgrades[0][list_of_upgrades[i]]+1}-export.png").convert("RGBA")
            new_background.paste(added_upgrade, positions[i], added_upgrade)

        # Paste the shadow on top finally
        new_background.paste(shadow, (0, 0), shadow)

        # Save the background as a png with the file name and send it
        new_background.save(file_name, format="PNG")
        await ctx.send(file=discord.File(file_name))

        # Set up variables
        tier = 0
        tree_number = 0
        unknown_str = "???"

        # For each upgrade...
        for upgrade, level in upgrades[0].items():

            # If it isnt the user id
            if upgrade != "user_id":

                # Set the tier to 1 more than it was, set the description and name
                tier += 1
                description = self.UPGRADE_DESCRIPTIONS[upgrade]
                name = " ".join(upgrade.split("_")).title()

                # Get the cost of an upgrade
                cost_string = f"{self.UPGRADE_COST_LIST[int(level)]:,} {EMOJIS['sand_dollar']}"

                # If its the first tier its also the parent upgrade
                if tier == 1:
                    parent_one = upgrade

                # Set up variables upgrade specific
                left_bar = EMOJIS["bar_L"]
                start = ""
                start_two = ""
                emote = EMOJIS["bar_1"]

                # If the tier is 2 or 5 it's in the second tier of upgrades
                if tier in (2, 5):

                    # Set the cost with the second list and set it to the second parent upgrade
                    cost_string = f"{self.UPGRADE_COST_LIST_TWO[int(level)]:,} {EMOJIS['sand_dollar']}"
                    parent_two = upgrade

                    # If they don't have the full upgrade of the previous one, make them unknown
                    if upgrades[0][parent_one] != 5:
                        description = unknown_str
                        name = unknown_str
                        cost_string = unknown_str

                    # Set the start emotes to the correct emojis
                    start = EMOJIS["straight_branch"]
                    start_two = EMOJIS["straight"]
                    emote = EMOJIS["bar_2"]
                    left_bar = EMOJIS["bar_L_branch"]

                    # If its tier 5 set some more emojis
                    if tier == 5:
                        start = EMOJIS["branch"]
                        start_two = EMOJIS["straight"]

                # If its in tiers 3 or 6 (the first set of tier 3)
                elif tier in (3, 6):

                    # Set the cost of upgrade to cost list three
                    cost_string = f"{self.UPGRADE_COST_LIST_THREE[int(level)]:,} {EMOJIS['sand_dollar']}"

                    # If the parent isnt fully upgraded, set these to unknown
                    if upgrades[0][parent_two] != 5:
                        description = unknown_str
                        name = unknown_str
                        cost_string = unknown_str

                    # Set variables to the correct emotes
                    start = f"{EMOJIS['bar_empty']}{EMOJIS['straight_branch']}"
                    emote = EMOJIS["bar_3"]
                    left_bar = EMOJIS["bar_L_straight"]

                    # If the tier is 3 set some other correct emotes
                    if tier == 3:
                        start_two = f"{EMOJIS['straight']}{EMOJIS['straight']}"
                        start = (
                            f"{EMOJIS['straight']}{EMOJIS['straight_branch']}"
                        )

                    # If not set another correct emote
                    else:
                        start_two = f"{EMOJIS['bar_empty']}{EMOJIS['straight']}"

                # Else if its in tier 4 or 7 (in the second set of tier 3 upgrades)
                elif tier in (4, 7):

                    # Set the cost of upgrade to cost list three
                    cost_string = f"{self.UPGRADE_COST_LIST_THREE[int(level)]:,} {EMOJIS['sand_dollar']}"

                    # If the parent isnt fully upgraded, set these to unknown
                    if upgrades[0][parent_two] != 5:
                        description = unknown_str
                        name = unknown_str
                        cost_string = unknown_str

                    # Set variables to the correct emotes
                    emote = EMOJIS["bar_3"]
                    left_bar = EMOJIS["bar_L_straight"]

                    # If the tier is 4 set some other correct emotes
                    if tier == 4:
                        start_two = f"{EMOJIS['straight']}{EMOJIS['straight']}"
                        start = f"{EMOJIS['straight']}{EMOJIS['branch']}"

                    # If not set other correct emotes
                    else:
                        start_two = f"{EMOJIS['bar_empty']}{EMOJIS['straight']}"
                        start = f"{EMOJIS['bar_empty']}{EMOJIS['branch']}"

                # If they're fully upgraded
                if level == 5:
                    cost_string = "Fully upgraded."

                # Each level they have is a full bar emoji, up to 5 characters long
                emote_string_list.clear()  # Clear our emoji list first
                for _ in range(level):

                    emote_string_list.append(emote)

                while len(emote_string_list) < 5:
                    emote_string_list.append(EMOJIS["bar_e"])

                # Set up the progress bar
                progress_bar = (
                    f"{left_bar}{''.join(emote_string_list)}{EMOJIS['bar_R']}"
                )

                # New line for f strings
                new_line = "\n"

                # Set up the message for the upgrade
                message.append(
                    (
                        f"{start}{progress_bar}",
                        f"{start_two}**{name}: (Lvl. {level}.): {cost_string}**{new_line}{start_two}*{description}*",
                    )
                )

                # If its the last tier of the tree
                if tier == 7:
                    # Append some empty spaces
                    message.append(("** **", "** **"))

                    # Set tree to 2 and tier back to 0
                    tree_number += 1
                    tier = 0

        # Set up the embed with titles for each field
        for time, message_data in enumerate(message):
            if time <= 7:
                if time == 0:
                    embed = vbu.Embed()
                    embed.add_field(
                        name="The Way of the Fish",
                        value="These upgrades have to do with fishing",
                        inline=False,
                    )
                embed.add_field(
                    name=message_data[1], value=message_data[0], inline=False
                )
            if time > 7:
                if time == 8:
                    embed_2 = vbu.Embed()
                    embed_2.add_field(
                        name="The Way of the Tank",
                        value="These upgrades have to do with owning fish in aquariums",
                        inline=False,
                    )
                embed_2.add_field(
                    name=message_data[1], value=message_data[0], inline=False
                )
        # Send the embed
        await ctx.send(embed=embed)
        await ctx.send(embed=embed_2)
Ejemplo n.º 25
0
    async def _blackjack_command(self, ctx: commands.SlashContext,
                                 amount: int):
        with utils.UsingCommand(ctx):
            async with vbu.DatabaseConnection() as db:
                cache: utils.CachedUser = await utils.get_user_cache(
                    ctx.author.id,
                    db=db,
                    bot=self.bot,
                    logger=self.logger,
                )

                if amount < 25:
                    return await ctx.interaction.response.send_message(
                        content=
                        f"No can do, you need to gamble atleast **25 inches**")

                if amount > cache.pp.size:
                    return await ctx.interaction.response.send_message(
                        content=
                        f"How you gamble that amount when you dont even have that many inches LMAO. You're missing {utils.format_rewards(inches=amount - cache.pp.size)}"
                    )

                game = utils.BlackjackGame(utils.Deck())
                cache.pp.size -= amount

                with vbu.Embed() as embed:
                    embed.colour = 0x2C82C9
                    kwargs = {"name": f"{ctx.author.name}'s game of Blackjack"}
                    if ctx.author.avatar:
                        kwargs["icon_url"] = ctx.author.avatar.url
                    embed.set_author(**kwargs)
                    embed.add_field(
                        name=f"{ctx.author.name} 🎮",
                        value=
                        f"Hand - {game.player}\nTotal - `{game.player.total_value()}`",
                    )
                    embed.add_field(
                        name="Pp bot <:ppevil:871396299830861884>",
                        value=f"Hand - {game.dealer.hidden()}\nTotal - `?`",
                    )

                components = discord.ui.MessageComponents(
                    discord.ui.ActionRow(
                        discord.ui.Button(
                            label="Hit",
                            custom_id="HIT",
                            style=discord.ui.ButtonStyle.success,
                        ),
                        discord.ui.Button(
                            label="Stand",
                            custom_id="STAND",
                            style=discord.ui.ButtonStyle.danger,
                        ),
                    ))

                if game.state == utils.BlackjackState.PLAYER_BLACKJACK:
                    reward = int(amount * 2.5)
                    cache.pp.size += reward
                    with embed:
                        embed.colour = utils.GREEN
                        embed.description = f"**BLACKJACK!**\n{ctx.author.name} walks away with {utils.format_rewards(inches=reward)} (50% bonus)"
                        embed.edit_field_by_index(
                            1,
                            name="Pp bot <:ppevil:871396299830861884>",
                            value=
                            f"Hand - {game.dealer}\nTotal - `{game.dealer.total_value()}`",
                        )
                    return await ctx.interaction.response.send_message(
                        embed=embed,
                        components=components.disable_components())

                elif game.state == utils.BlackjackState.DEALER_BLACKJACK:
                    with embed:
                        embed.colour = utils.RED
                        embed.description = f"**DEALER BLACKJACK!**\n{ctx.author.name} loses {utils.format_rewards(inches=-amount)}"
                        embed.edit_field_by_index(
                            1,
                            name="Pp bot <:ppevil:871396299830861884>",
                            value=
                            f"Hand - {game.dealer}\nTotal - `{game.dealer.total_value()}`",
                        )
                    return await ctx.interaction.response.send_message(
                        embed=embed,
                        components=components.disable_components())

                elif game.state == utils.BlackjackState.PUSH:
                    cache.pp.size += amount
                    with embed:
                        embed.colour = utils.YELLOW
                        embed.description = f"**PUSH!**\nSomehow you both got a blackjack LMAO, it's a tie"
                    return await ctx.interaction.response.send_message(
                        embed=embed,
                        components=components.disable_components())

                await ctx.interaction.response.send_message(
                    embed=embed, components=components)

                original_message: discord.InteractionMessage = (
                    await ctx.interaction.original_message())

                actions: typing.List[str] = []

                def formatted_actions() -> str:
                    if not actions:
                        return ""
                    reversed_actions = list(reversed(actions))
                    if len(actions) > 2:
                        return "```diff\n{}\n{} previous {}...```".format(
                            "\n".join(reversed_actions[:2]),
                            len(reversed_actions) - 2,
                            "actions" if len(reversed_actions) -
                            3 else "action",
                        )
                    return "```diff\n{}```".format("\n".join(reversed_actions))

                def action_check(
                        action_interaction: discord.Interaction) -> bool:
                    if (action_interaction.message is not None
                            and action_interaction.message.id !=
                            original_message.id
                            or action_interaction.user != ctx.author):
                        return False

                    if action_interaction.user != ctx.author:
                        self.bot.loop.create_task(
                            action_interaction.response.send_message(
                                content="Bro this is not meant for you LMAO",
                                ephemeral=True,
                            ))
                        return False

                    if (action_interaction.data is not None
                            and not utils.BlackjackAction.get(
                                typing.cast(
                                    str,
                                    action_interaction.data.get(
                                        "custom_id", "")))):
                        x = action_interaction.data["custom_id"]
                        self.bot.loop.create_task(
                            action_interaction.response.send_message(
                                content=
                                "Something went wrong lmao try using this command again with different button",
                                ephemeral=True,
                            ))
                        raise asyncio.TimeoutError()
                        return

                    return True

                while game.state == utils.BlackjackState.PLAYER_TURN:
                    try:
                        action_interaction: discord.Interaction = (
                            await self.bot.wait_for("component_interaction",
                                                    check=action_check,
                                                    timeout=15))

                    except asyncio.TimeoutError:
                        game.state = utils.BlackjackState.TIMEOUT
                        break

                    assert action_interaction.data is not None
                    action = getattr(utils.BlackjackAction,
                                     action_interaction.data["custom_id"])

                    game.player_action(action)

                    if action == utils.BlackjackAction.HIT:
                        actions.append(
                            f"+ {ctx.author.name} hits and received a {game.player.cards[-1]}."
                        )
                    elif action == utils.BlackjackAction.STAND:
                        actions.append(f"! {ctx.author.name} stands.")
                    else:
                        actions.append(
                            f"? {ctx.author.name} {action.name.lower()}s.")

                    with embed:
                        embed.edit_field_by_index(
                            0,
                            name=f"{ctx.author.name} 🎮",
                            value=
                            f"Hand - {game.player}\nTotal - `{game.player.total_value()}`",
                        )
                        embed.edit_field_by_index(
                            1,
                            name="Pp bot <:ppevil:871396299830861884>",
                            value=f"Hand - {game.dealer.hidden()}\nTotal - `?`",
                        )
                        embed.description = formatted_actions() or None

                    await action_interaction.response.edit_message(embed=embed)

                if game.state == utils.BlackjackState.TIMEOUT:
                    actions.append(f"- {ctx.author.name} doesn't respond.")
                    with embed:
                        embed.colour = utils.YELLOW
                        embed.description = f"**TIMED OUT!**\nWhile {ctx.author.name} was AFK, the dealer ran away with his {utils.format_rewards(inches=-amount)}"
                        embed.edit_field_by_index(
                            1,
                            name="Pp bot <:ppevil:871396299830861884>",
                            value=
                            f"Hand - {game.dealer}\nTotal - `{game.dealer.total_value()}`",
                        )
                        if actions:
                            embed.description += formatted_actions()

                elif game.state == utils.BlackjackState.PLAYER_BUST:
                    actions.append(f"- {ctx.author.name} busts.")
                    with embed:
                        embed.colour = utils.RED
                        embed.description = f"**BUST!**\n{ctx.author.name} got a bit to greedy, and busted. You lose {utils.format_rewards(inches=-amount)}"
                        embed.edit_field_by_index(
                            1,
                            name="Pp bot <:ppevil:871396299830861884>",
                            value=
                            f"Hand - {game.dealer}\nTotal - `{game.dealer.total_value()}`",
                        )
                        if actions:
                            embed.description += formatted_actions()

                else:
                    while game.state == utils.BlackjackState.DEALER_TURN:

                        with embed:
                            embed.edit_field_by_index(
                                1,
                                name="Pp bot <:ppevil:871396299830861884>",
                                value=
                                f"Hand - {game.dealer}\nTotal - `{game.dealer.total_value()}`",
                            )
                            embed.description = formatted_actions() or None

                        await original_message.edit(
                            embed=embed,
                            components=components.disable_components())

                        await asyncio.sleep(1)
                        game.dealer_action()
                        actions.append(
                            f"+ pp bot hits and received a {game.dealer.cards[-1]}."
                        )

                    if game.state == utils.BlackjackState.DEALER_BUST:
                        actions.append(f"- pp bot busts.")
                        reward = amount * 2
                        cache.pp.size += reward
                        with embed:
                            embed.colour = utils.GREEN
                            embed.description = f"**DEALER BUST!**\npp bot got absolutely destroyed by {ctx.author.name}. You win {utils.format_rewards(inches=reward)}"
                            embed.edit_field_by_index(
                                1,
                                name="Pp bot <:ppevil:871396299830861884>",
                                value=
                                f"Hand - {game.dealer}\nTotal - `{game.dealer.total_value()}`",
                            )
                            if actions:
                                embed.description += formatted_actions()
                        await original_message.edit(
                            embed=embed,
                            components=components.disable_components())

                    elif game.state == utils.BlackjackState.DEALER_WIN:
                        actions.append(f"+ pp bot wins.")
                        with embed:
                            embed.colour = utils.RED
                            embed.description = f"**DEALER WIN!**\n{ctx.author.name} got dunked on by pp bot. You lose {utils.format_rewards(inches=-amount)}"
                            embed.edit_field_by_index(
                                1,
                                name="Pp bot <:ppevil:871396299830861884>",
                                value=
                                f"Hand - {game.dealer}\nTotal - `{game.dealer.total_value()}`",
                            )
                            if actions:
                                embed.description += formatted_actions()

                    elif game.state == utils.BlackjackState.PLAYER_WIN:
                        actions.append(f"+ {ctx.author.name} wins.")
                        reward = amount * 2
                        cache.pp.size += reward
                        with embed:
                            embed.colour = utils.GREEN
                            embed.description = f"**YOU WIN!**\n{ctx.author.name} has proved their extreme gambling skill against pp bot. You win {utils.format_rewards(inches=reward)}"
                            embed.edit_field_by_index(
                                1,
                                name="Pp bot <:ppevil:871396299830861884>",
                                value=
                                f"Hand - {game.dealer}\nTotal - `{game.dealer.total_value()}`",
                            )
                            if actions:
                                embed.description += formatted_actions()

                    else:
                        actions.append(f"+ {ctx.author.name} and pp bot push.")
                        with embed:
                            cache.pp.size += amount
                            embed.colour = utils.YELLOW
                            embed.description = f"**PUSH!**\n{ctx.author.name} and pp bot ended up in a tie. You win {utils.format_rewards(inches=0)}"
                            embed.edit_field_by_index(
                                1,
                                name="Pp bot <:ppevil:871396299830861884>",
                                value=
                                f"Hand - {game.dealer}\nTotal - `{game.dealer.total_value()}`",
                            )
                            if actions:
                                embed.description += formatted_actions()

                await original_message.edit(
                    embed=embed, components=components.disable_components())
Ejemplo n.º 26
0
    async def issue_create(self, ctx: vbu.Context, repo: GitRepo, *, title: str, body: str = ""):
        """
        Create a Github issue on a given repo.
        """

        # Get the database because whatever why not
        async with vbu.Database() as db:
            user_rows = await db("SELECT * FROM user_settings WHERE user_id=$1", ctx.author.id)
            if not user_rows or not user_rows[0][f'{repo.host.lower()}_username']:
                return await ctx.send(
                    (
                        f"You need to link your {repo.host} account to Discord to run this "
                        f"command - see the website at `{ctx.clean_prefix}info`."
                    ),
                )

        # Work out what components we want to use
        embed = vbu.Embed(title=title, description=body, use_random_colour=True).set_footer(text=str(repo))
        components = discord.ui.MessageComponents.boolean_buttons()
        components.components[0].components.append(discord.ui.Button(label="Set title", custom_id="TITLE"))
        components.components[0].components.append(discord.ui.Button(label="Set body", custom_id="BODY"))
        components.components[0].components.append(discord.ui.Button(label="Set repo", custom_id="REPO"))
        options = [
            discord.ui.SelectOption(label=i.name, value=i.name, description=i.description)
            for i in await repo.get_labels(user_rows[0])
        ]
        components.add_component(discord.ui.ActionRow(
            discord.ui.SelectMenu(
                custom_id="LABELS",
                min_values=0,
                max_values=len(options),
                options=options,
            )
        ))
        labels = []

        # Ask if we want to do this
        m = None
        while True:

            # See if we want to update the body
            embed = vbu.Embed(
                title=title,
                description=body or "...",
                use_random_colour=True,
            ).set_footer(
                text=str(repo),
            ).add_field(
                "Labels",
                ", ".join([f"`{i}`" for i in labels]) or "...",
            )
            if m is None:
                m = await ctx.send("Are you sure you want to create this issue?", embed=embed, components=components)
            else:
                await m.edit(embed=embed, components=components.enable_components())
            try:
                payload = await self.bot.wait_for("component_interaction", check=vbu.component_check(ctx.author, m), timeout=120)
            except asyncio.TimeoutError:
                return await ctx.send("Timed out asking for issue create confirmation.")

            # Disable components
            if payload.component.custom_id not in ["LABELS"]:
                await payload.response.edit_message(components=components.disable_components())

            # Get the body
            if payload.component.custom_id == "BODY":

                # Wait for their body message
                n = await payload.followup.send("What body content do you want to be added to your issue?")
                try:
                    check = lambda n: n.author.id == ctx.author.id and n.channel.id == ctx.channel.id
                    body_message = await self.bot.wait_for("message", check=check, timeout=60 * 5)
                except asyncio.TimeoutError:
                    return await payload.followup.send("Timed out asking for issue body text.")

                # Grab the attachments
                attachment_urls = []
                for i in body_message.attachments:
                    try:
                        async with self.bot.session.get(i.url) as r:
                            data = await r.read()
                        file = discord.File(io.BytesIO(data), filename=i.filename)
                        cache_message = await ctx.author.send(file=file)
                        attachment_urls.append((file.filename, cache_message.attachments[0].url))
                    except discord.HTTPException:
                        break

                # Delete their body message and our asking message
                try:
                    await n.delete()
                    await body_message.delete()
                except discord.HTTPException:
                    pass

                # Fix up the body
                body = body.strip() + "\n\n" + body_message.content + "\n\n"
                for name, url in attachment_urls:
                    body += f"![{name}]({url})\n"

            # Get the title
            elif payload.component.custom_id == "TITLE":

                # Wait for their body message
                n = await payload.followup.send("What do you want to set the issue title to?")
                try:
                    check = lambda n: n.author.id == ctx.author.id and n.channel.id == ctx.channel.id
                    title_message = await self.bot.wait_for("message", check=check, timeout=60 * 5)
                except asyncio.TimeoutError:
                    return await payload.followup.send("Timed out asking for issue title text.")

                # Delete their body message and our asking message
                try:
                    await n.delete()
                    await title_message.delete()
                except discord.HTTPException:
                    pass
                title = title_message.content

            # Get the repo
            elif payload.component.custom_id == "REPO":

                # Wait for their body message
                n = await payload.followup.send("What do you want to set the repo to?")
                try:
                    check = lambda n: n.author.id == ctx.author.id and n.channel.id == ctx.channel.id
                    repo_message = await self.bot.wait_for("message", check=check, timeout=60 * 5)
                except asyncio.TimeoutError:
                    return await payload.followup.send("Timed out asking for issue title text.")

                # Delete their body message and our asking message
                try:
                    await n.delete()
                    await repo_message.delete()
                except discord.HTTPException:
                    pass

                # Edit the message
                try:
                    repo = await GitRepo.convert(ctx, repo_message.content)
                except Exception:
                    await ctx.send(f"That repo isn't valid, {ctx.author.mention}", delete_after=3)

            # Get the labels
            elif payload.component.custom_id == "LABELS":
                await payload.response.defer_update()
                labels = payload.values

            # Check for exiting
            elif payload.component.custom_id == "NO":
                return await payload.followup.send("Alright, cancelling issue add.")
            elif payload.component.custom_id == "YES":
                break

        # Work out our args
        headers = {}
        if repo.host == "Github":
            json = {'title': title, 'body': body.strip(), 'labels': labels}
            headers = {'Accept': 'application/vnd.github.v3+json', 'Authorization': f"token {user_rows[0]['github_access_token']}"}
        elif repo.host == "Gitlab":
            json = {'title': title, 'description': body.strip(), 'labels': ",".join(labels)}
            headers = {'Authorization': f"Bearer {user_rows[0]['gitlab_bearer_token']}"}
        else:
            raise Exception("Invalid host")
        headers.update({'User-Agent': self.bot.user_agent})

        # Make the post request
        async with self.bot.session.post(repo.issue_api_url, json=json, headers=headers) as r:
            data = await r.json()
            self.logger.info(f"Received data from git {r.url!s} - {data!s}")
            if not r.ok:
                return await ctx.send(f"I was unable to create an issue on that repository - `{data}`.",)
        await ctx.send(f"Your issue has been created - <{data.get('html_url') or data.get('web_url')}>.",)
        await self.increase_repo_usage_counter(ctx.author, repo)
Ejemplo n.º 27
0
    async def dnd_monster(self, ctx: commands.Context, *, monster_name: str):
        """
        Gives you information on a D&D monster.
        """

        # Get our data
        data = await self.send_web_request("monsters", monster_name)
        if not data:
            return await ctx.send(
                "I couldn't find any information for that monster.")

        # Make an embed
        embed = vbu.Embed(
            use_random_colour=True,
            title=data['name'],
            description="\n".join([
                f"{data['size'].capitalize()} | {data['type']} | {data['hit_points']:,} ({data['hit_dice']}) HP | {data['xp']:,} XP",
                ", ".join(
                    [f"{o} {data[i]}" for i, o in self.ATTRIBUTES.items()]),
            ])).add_field(
                name="Proficiencies",
                value=", ".join([
                    f"{i['proficiency']['name']} {i['value']}"
                    for i in data['proficiencies']
                ]) or "None",
            ).add_field(
                name="Damage Vulnerabilities",
                value="\n".join(data['damage_vulnerabilities']).capitalize()
                or "None",
            ).add_field(
                name="Damage Resistances",
                value="\n".join(data['damage_resistances']).capitalize()
                or "None",
            ).add_field(
                name="Damage Immunities",
                value="\n".join(data['damage_immunities']).capitalize()
                or "None",
            ).add_field(
                name="Condition Immunities",
                value="\n".join(
                    [i['name']
                     for i in data['condition_immunities']]).capitalize()
                or "None",
            ).add_field(
                name="Senses",
                value="\n".join([
                    f"{i.replace('_', ' ').capitalize()} {o}"
                    for i, o in data['senses'].items()
                ]) or "None",
            )
        self.group_field_descriptions(embed, "Actions", data['actions'])
        self.group_field_descriptions(embed, "Legendary Actions",
                                      data.get('legendary_actions', list()))
        if data.get('special_abilities'):
            embed.add_field(
                name="Special Abilities",
                value="\n".join([
                    f"**{i['name']}**\n{i['desc']}"
                    for i in data['special_abilities']
                    if i['name'] != 'Spellcasting'
                ]) or "None",
                inline=False,
            )
        spellcasting = [
            i for i in data.get('special_abilities', list())
            if i['name'] == 'Spellcasting'
        ]
        if spellcasting:
            spellcasting = spellcasting[0]
            embed.add_field(
                name="Spellcasting",
                value=spellcasting['desc'].replace('\n\n', '\n'),
                inline=False,
            )

        # And send
        return await ctx.send(embed=embed)
Ejemplo n.º 28
0
    async def commit_poster_loop(self, embed_title: str, api_url: str,
                                 repo_url: str):
        """
        Grab the data from the Discord datamining repo and post it to the coding channel of VFL.
        """

        # Grab the data
        self.logger.info(f"Grabbing repo data from {api_url}")
        async with self.bot.session.get(api_url) as r:
            data = await r.json()

        # Let's work out the new data
        new_commits = []
        if self.last_posted_commit[repo_url] is None:
            self.last_posted_commit[repo_url] = data[0]['sha']
            self.logger.info("Setting to last commit - no commits cached")
            return
        for index, i in enumerate(data):
            if i['sha'] == self.last_posted_commit[repo_url]:
                new_commits = data[:index]
                break

        # See if we have anything to talk about
        if not new_commits:
            self.logger.info("No new commits found")
            return
        self.logger.info(f"Logging info of {len(new_commits)} commits")

        # Work out which of our new commits have comments
        comment_urls = [
            i['comments_url'] for i in new_commits
            if i['commit']['comment_count'] > 0
        ]
        comment_text = []
        for url in comment_urls:
            async with self.bot.session.get(url) as r:
                data = await r.json()
            comment_text.extend([(i['commit_id'],
                                  re.sub(r"^## (.+)", r"**\1**", i['body']))
                                 for i in data])
        self.logger.info(f"Logging info of {len(comment_text)} comments")

        # Get the full description
        description_unsplit = '\n'.join([
            f"{i['commit']['message']} - [Link]({repo_url}commit/{i['sha']})"
            for i in new_commits
        ])

        # Inform the bot owner that the description is larger than allowed by discord
        if len(description_unsplit) > 2048:
            self.logger.info(
                f"Our description is longer than 2048 characters and this isnt really poggers, "
                f"we need to make it in multiple embeds. It was {len(description_unsplit)} characters."
            )

        # Split the description into a list of descriptions each 2048 or less
        description_array = [
            description_unsplit[i:i + 2048]
            for i in range(0, len(description_unsplit), 2048)
        ]

        # Format one into an embed
        with vbu.Embed(use_random_colour=True) as embed:
            embed.title = embed_title
            embed.description = description_array.pop(0)
            for sha, body in comment_text:
                embed.add_field(sha, body, inline=False)

        # And send the first one
        channel = self.bot.get_channel(self.VFL_CODING_CHANNEL_ID)
        assert isinstance(channel, discord.TextChannel)
        m = await channel.send(embed=embed)
        await m.publish()

        # If there are more than 2048 characters send the other parts
        for description in description_array:
            with vbu.Embed(use_random_colour=True) as embed:
                embed.title = "Continuation of " + embed_title
                embed.description = description
            m = await channel.send(embed=embed)
            await m.publish()

        # We are done PogChamp
        self.logger.info("Sent data to channel")
        self.last_posted_commit[repo_url] = new_commits[0]['sha']
Ejemplo n.º 29
0
    async def steam(self, ctx: vbu.Context, *, app_name: str):
        """
        Search Steam for an item.
        """

        # Load cache
        if not self.game_cache:
            await self.load_game_cache()

        # Get app
        app_object = None
        appid = None
        await ctx.trigger_typing()

        # By url
        match = self.GAME_URL_REGEX.search(app_name)
        if match is not None:
            app_name = match.group(1)

        # By app id
        if app_name.isdigit():
            appid = int(app_name)
            try:
                app_object = [i for i in self.game_cache if i['appid'] == int(app_name)][0]
            except IndexError:
                pass

        # By app name
        if app_object is None and appid is None:
            app_name = self.get_valid_name(app_name)
            valid_items = [i for i in self.game_cache if app_name.lower() in self.get_valid_name(i['name']).lower()]
            full_title_match = [i for i in valid_items if app_name.lower() == self.get_valid_name(i['name']).lower()]
            if full_title_match:
                valid_items = [full_title_match[0]]
            if len(valid_items) > 1:
                output_items = valid_items[:10]
                output_ids = [f"`{i['appid']}` - {i['name']}" for i in output_items]
                return await ctx.send("There are multiple results with that name:\n" + "\n".join(output_ids))  # TODO
            elif len(valid_items) == 0:
                return await ctx.send("There are no results with that name.")
            app_object = valid_items[0]
            appid = app_object['appid']

        # Get info
        params = {
            "appids": appid
        }
        headers = {
            "User-Agent": self.bot.user_agent
        }
        async with self.bot.session.get(self.GAME_DATA_URL, params=params, headers=headers) as r:
            game_data = await r.json()
        if game_data[str(appid)]['success'] is False:
            return await ctx.send(f"I couldn't find an application with ID `{appid}`.")
        game_object = game_data[str(appid)]['data']

        # See if it's NSFW
        if int(game_object.get('required_age', '0')) >= 18 and ctx.channel.nsfw is False:
            return await ctx.send("That game is marked as an 18+, so can't be sent in a non-NSFW channel.")

        # Embed it babey
        with vbu.Embed(use_random_colour=True) as embed:
            embed.title = game_object['name']
            embed.set_footer(text=f"AppID: {appid}")
            embed.description = game_object['short_description']
            embed.add_field("Developer", ', '.join(game_object.get('developers', list())) or 'None', inline=True)
            embed.add_field("Publisher", ', '.join(game_object.get('publishers', list())) or 'None', inline=True)
            embed.add_field("Genre", ', '.join(i['description'] for i in game_object['genres']) or 'None', inline=True)
            if game_object.get('price_overview') is not None:
                initial_price = game_object['price_overview']['initial_formatted']
                final_price = game_object['price_overview']['final_formatted']
                embed.add_field("Price", f"~~{initial_price}~~ {final_price}" if initial_price else final_price, inline=True)
            embed.add_field("Link", f"Open with Steam - steam://store/{appid}\nOpen in browser - [Link](https://store.steampowered.com/app/{appid}/)", inline=False)
            screenshots = [i['path_full'] for i in game_object['screenshots']]
            embed.set_image(url=screenshots[0])

        # Send
        m = await ctx.send(embed=embed)
Ejemplo n.º 30
0
    def generate_embed(self, data) -> typing.Optional[vbu.Embed]:
        """
        Make an embed based on some OMDB data.
        """

        search = data.get('Title') is None
        if search and data.get('Search') is None:
            return None

        embed = vbu.Embed(use_random_colour=True)
        if not search:
            embed.title = f"{data['Title']} ({data['Year']})"

        valid_info = lambda v: v not in [None, 'N/A', 'n/a']

        # List short details of up to 10 results
        if search:
            description_list = []
            for index, row in enumerate(data['Search'][:10], start=1):
                if valid_info(row.get('Poster')):
                    description_list.append(
                        f"{index}. **{row['Title']}** ({row['Year']}) - [Poster]({row['Poster']})"
                    )
                else:
                    description_list.append(
                        f"{index}. **{row['Title']}** ({row['Year']})")
            embed.description = '\n'.join(description_list)
            return embed

        # List full details
        if data.get('Plot'):
            embed.description = data['Plot']
        if data.get('Released'):
            embed.add_field("Release Date", data['Released'])
        if data.get('Rated'):
            embed.add_field("Age Rating", data['Rated'])
        if data.get('Runtime'):
            embed.add_field("Runtime", data['Runtime'])
        if data.get('Genre'):
            embed.add_field(f"Genre{'s' if ',' in data['Genre'] else ''}",
                            data['Genre'])
        if data.get('imdbRating'):
            embed.add_field("IMDB Rating", data['imdbRating'])
        if data.get('Production'):
            embed.add_field(
                f"Production Compan{'ies' if ',' in data['Production'] else 'y'}",
                data['Production'])
        if data.get('Director'):
            embed.add_field(
                f"Director{'s' if ',' in data['Director'] else ''}",
                data['Director'])
        if data.get('Writer'):
            embed.add_field(f"Writer{'s' if ',' in data['Writer'] else ''}",
                            data['Writer'],
                            inline=False)
        if data.get('imdbID'):
            embed.add_field(
                "IMDB Page",
                f"[Direct Link](https://www.imdb.com/title/{data['imdbID']}/) - IMDB ID `{data['imdbID']}`",
                inline=False)
        if valid_info(data.get('Poster')):
            embed.set_thumbnail(data['Poster'])
        return embed