示例#1
0
 async def _build_queue_search_page(
         self, ctx: commands.Context, page_num: int,
         search_list: List[Tuple[int, str]]) -> discord.Embed:
     search_num_pages = math.ceil(len(search_list) / 10)
     search_idx_start = (page_num - 1) * 10
     search_idx_end = search_idx_start + 10
     track_match = ""
     async for i, track in AsyncIter(
             search_list[search_idx_start:search_idx_end]).enumerate(
                 start=search_idx_start):
         track_idx = i + 1
         if type(track) is str:
             track_location = LocalPath(
                 track, self.local_folder_current_path).to_string_user()
             track_match += "`{}.` **{}**\n".format(track_idx,
                                                    track_location)
         else:
             track_match += "`{}.` **{}**\n".format(track[0], track[1])
     embed = discord.Embed(colour=await ctx.embed_colour(),
                           title=_("Matching Tracks:"),
                           description=track_match)
     embed.set_footer(text=_(
         "Page {page_num}/{total_pages} | {num_tracks} tracks").format(
             page_num=humanize_number(page_num),
             total_pages=humanize_number(search_num_pages),
             num_tracks=len(search_list),
         ))
     return embed
示例#2
0
    async def slotmax(self, ctx: commands.Context, bid: positive_int):
        """Set the maximum slot machine bid.

        Example:
            - `[p]economyset slotmax 50`

        **Arguments**

        - `<bid>` The new maximum bid for using the slot machine. Default is 100.
        """
        guild = ctx.guild
        is_global = await bank.is_global()
        if is_global:
            slot_min = await self.config.SLOT_MIN()
        else:
            slot_min = await self.config.guild(guild).SLOT_MIN()
        if bid < slot_min:
            await ctx.send(
                _("Warning: Maximum bid is less than the minimum bid ({min_bid}). "
                  "Slots will not work.").format(
                      min_bid=humanize_number(slot_min)))
        credits_name = await bank.get_currency_name(guild)
        if is_global:
            await self.config.SLOT_MAX.set(bid)
        else:
            await self.config.guild(guild).SLOT_MAX.set(bid)
        await ctx.send(
            _("Maximum bid is now {bid} {currency}.").format(
                bid=humanize_number(bid), currency=credits_name))
示例#3
0
 def make_embed(self, data):
     is_rerun = data["type"] == "rerun"
     url = f"https://www.twitch.tv/{data['login']}" if data[
         "login"] is not None else None
     logo = data["profile_image_url"]
     if logo is None:
         logo = "https://static-cdn.jtvnw.net/jtv_user_pictures/xarth/404_user_70x70.png"
     status = data["title"]
     if not status:
         status = _("Untitled broadcast")
     if is_rerun:
         status += _(" - Rerun")
     embed = discord.Embed(title=status, url=url, color=0x6441A4)
     embed.set_author(name=data["user_name"])
     embed.add_field(name=_("Followers"),
                     value=humanize_number(data["followers"]))
     embed.add_field(name=_("Total views"),
                     value=humanize_number(data["view_count"]))
     embed.set_thumbnail(url=logo)
     if data["thumbnail_url"]:
         embed.set_image(
             url=rnd(data["thumbnail_url"].format(width=320, height=180)))
     if data["game_name"]:
         embed.set_footer(text=_("Playing: ") + data["game_name"])
     return embed
示例#4
0
    async def bankset_showsettings(self, ctx: commands.Context):
        """Show the current bank settings."""
        cur_setting = await bank.is_global()
        if cur_setting:
            group = bank._config
        else:
            if not ctx.guild:
                return
            group = bank._config.guild(ctx.guild)
        group_data = await group.all()
        bank_name = group_data["bank_name"]
        bank_scope = _("Global") if cur_setting else _("Server")
        currency_name = group_data["currency"]
        default_balance = group_data["default_balance"]
        max_balance = group_data["max_balance"]

        settings = _(
            "Bank settings:\n\nBank name: {bank_name}\nBank scope: {bank_scope}\n"
            "Currency: {currency_name}\nDefault balance: {default_balance}\n"
            "Maximum allowed balance: {maximum_bal}\n").format(
                bank_name=bank_name,
                bank_scope=bank_scope,
                currency_name=currency_name,
                default_balance=humanize_number(default_balance),
                maximum_bal=humanize_number(max_balance),
            )
        await ctx.send(box(settings))
示例#5
0
    def make_embed(self, data):
        avatar = rnd(
            "https://picarto.tv/user_data/usrimg/{}/dsdefault.jpg".format(
                data["name"].lower()))
        url = "https://picarto.tv/" + data["name"]
        thumbnail = data["thumbnails"]["web"]
        embed = discord.Embed(title=data["title"], url=url, color=0x4C90F3)
        embed.set_author(name=data["name"])
        embed.set_image(url=rnd(thumbnail))
        embed.add_field(name=_("Followers"),
                        value=humanize_number(data["followers"]))
        embed.add_field(name=_("Total views"),
                        value=humanize_number(data["viewers_total"]))
        embed.set_thumbnail(url=avatar)
        data["tags"] = ", ".join(data["tags"])

        if not data["tags"]:
            data["tags"] = _("None")

        if data["adult"]:
            data["adult"] = _("NSFW | ")
        else:
            data["adult"] = ""

        embed.set_footer(
            text=_("{adult}Category: {category} | Tags: {tags}").format(
                **data))
        return embed
示例#6
0
    async def _set(self, ctx: commands.Context, to: discord.Member,
                   creds: SetParser):
        """Set the balance of a user's bank account.

        Putting + or - signs before the amount will add/remove currency on the user's bank account instead.

        Examples:
            - `[p]bank set @Twentysix 26` - Sets balance to 26
            - `[p]bank set @Twentysix +2` - Increases balance by 2
            - `[p]bank set @Twentysix -6` - Decreases balance by 6

        **Arguments**

        - `<to>` The user to set the currency of.
        - `<creds>` The amount of currency to set their balance to.
        """
        author = ctx.author
        currency = await bank.get_currency_name(ctx.guild)

        try:
            if creds.operation == "deposit":
                await bank.deposit_credits(to, creds.sum)
                msg = _("{author} added {num} {currency} to {user}'s account."
                        ).format(
                            author=author.display_name,
                            num=humanize_number(creds.sum),
                            currency=currency,
                            user=to.display_name,
                        )
            elif creds.operation == "withdraw":
                await bank.withdraw_credits(to, creds.sum)
                msg = _(
                    "{author} removed {num} {currency} from {user}'s account."
                ).format(
                    author=author.display_name,
                    num=humanize_number(creds.sum),
                    currency=currency,
                    user=to.display_name,
                )
            else:
                await bank.set_balance(to, creds.sum)
                msg = _(
                    "{author} set {user}'s account balance to {num} {currency}."
                ).format(
                    author=author.display_name,
                    num=humanize_number(creds.sum),
                    currency=currency,
                    user=to.display_name,
                )
        except (ValueError, errors.BalanceTooHigh) as e:
            await ctx.send(str(e))
        else:
            await ctx.send(msg)
示例#7
0
 async def bankset_maxbal(self, ctx: commands.Context, *, amount: int):
     """Set the maximum balance a user can get."""
     try:
         await bank.set_max_balance(amount, ctx.guild)
     except ValueError:
         # noinspection PyProtectedMember
         return await ctx.send(
             _("Amount must be greater than zero and less than {max}.").
             format(max=humanize_number(bank._MAX_BALANCE)))
     await ctx.send(
         _("Maximum balance has been set to: {amount}").format(
             amount=humanize_number(amount)))
示例#8
0
    async def balance(self,
                      ctx: commands.Context,
                      user: discord.Member = None):
        """Show the user's account balance.

        Example:
            - `[p]bank balance`
            - `[p]bank balance @Twentysix`

        **Arguments**

        - `<user>` The user to check the balance of. If omitted, defaults to your own balance.
        """
        if user is None:
            user = ctx.author

        bal = await bank.get_balance(user)
        currency = await bank.get_currency_name(ctx.guild)
        max_bal = await bank.get_max_balance(ctx.guild)
        if bal > max_bal:
            bal = max_bal
            await bank.set_balance(user, bal)
        await ctx.send(
            _("{user}'s balance is {num} {currency}").format(
                user=user.display_name,
                num=humanize_number(bal),
                currency=currency))
示例#9
0
async def deposit_credits(member: discord.Member, amount: int) -> int:
    """Add a given amount of credits to an account.

    Parameters
    ----------
    member : discord.Member
        The member to deposit credits to.
    amount : int
        The amount to deposit.

    Returns
    -------
    int
        The new balance.

    Raises
    ------
    ValueError
        If the deposit amount is invalid.
    TypeError
        If the deposit amount is not an `int`.

    """
    if not isinstance(amount, int):
        raise TypeError("Deposit amount must be of type int, not {}.".format(
            type(amount)))
    if _invalid_amount(amount):
        raise ValueError("Invalid deposit amount {} <= 0".format(
            humanize_number(amount, override_locale="en_US")))

    bal = await get_balance(member)
    return await set_balance(member, amount + bal)
示例#10
0
        async def wrapped(*args, **kwargs):
            context: commands.Context = None
            for arg in args:
                if isinstance(arg, commands.Context):
                    context = arg
                    break

            if not context.guild and not await is_global():
                raise commands.UserFeedbackCheckFailure(
                    _("Can't pay for this command in DM without a global bank."
                      ))
            try:
                await withdraw_credits(context.author, amount)
            except Exception:
                credits_name = await get_currency_name(context.guild)
                raise commands.UserFeedbackCheckFailure(
                    _("You need at least {cost} {currency} to use this command."
                      ).format(cost=humanize_number(amount),
                               currency=credits_name))
            else:
                try:
                    return await coro(*args, **kwargs)
                except AbortPurchase:
                    await deposit_credits(context.author, amount)
                except Exception:
                    await deposit_credits(context.author, amount)
                    raise
示例#11
0
    async def transfer(self, ctx: commands.Context, to: discord.Member,
                       amount: int):
        """Transfer currency to other users.

        This will come out of your balance, so make sure you have enough.

        Example:
            - `[p]bank transfer @Twentysix 500`

        **Arguments**

        - `<to>` The user to give currency to.
        - `<amount>` The amount of currency to give.
        """
        from_ = ctx.author
        currency = await bank.get_currency_name(ctx.guild)

        try:
            await bank.transfer_credits(from_, to, amount)
        except (ValueError, errors.BalanceTooHigh) as e:
            return await ctx.send(str(e))

        await ctx.send(
            _("{user} transferred {num} {currency} to {other_user}").format(
                user=from_.display_name,
                num=humanize_number(amount),
                currency=currency,
                other_user=to.display_name,
            ))
示例#12
0
 async def economyset_showsettings(self, ctx: commands.Context):
     """
     Shows the current economy settings
     """
     guild = ctx.guild
     if await bank.is_global():
         conf = self.config
     else:
         conf = self.config.guild(guild)
     await ctx.send(
         box(
             _("----Economy Settings---\n"
               "Minimum slot bid: {slot_min}\n"
               "Maximum slot bid: {slot_max}\n"
               "Slot cooldown: {slot_time}\n"
               "Payday amount: {payday_amount}\n"
               "Payday cooldown: {payday_time}\n"
               "Amount given at account registration: {register_amount}\n"
               "Maximum allowed balance: {maximum_bal}").format(
                   slot_min=humanize_number(await conf.SLOT_MIN()),
                   slot_max=humanize_number(await conf.SLOT_MAX()),
                   slot_time=humanize_number(await conf.SLOT_TIME()),
                   payday_time=humanize_number(await conf.PAYDAY_TIME()),
                   payday_amount=humanize_number(await
                                                 conf.PAYDAY_CREDITS()),
                   register_amount=humanize_number(
                       await bank.get_default_balance(guild)),
                   maximum_bal=humanize_number(await
                                               bank.get_max_balance(guild)),
               )))
示例#13
0
    async def rolepaydayamount(self, ctx: commands.Context, role: discord.Role,
                               creds: int):
        """Set the amount earned each payday for a role.
        Set to `0` to remove the payday amount you set for that role.

        Only available when not using a global bank.

        Example:
            - `[p]economyset rolepaydayamount @Members 400`

        **Arguments**

        - `<role>` The role to assign a custom payday amount to.
        - `<creds>` The new amount to give when using the payday command.
        """
        guild = ctx.guild
        max_balance = await bank.get_max_balance(ctx.guild)
        if creds >= max_balance:
            return await ctx.send(
                _("The bank requires that you set the payday to be less than"
                  " its maximum balance of {maxbal}.").format(
                      maxbal=humanize_number(max_balance)))
        credits_name = await bank.get_currency_name(guild)
        if await bank.is_global():
            await ctx.send(
                _("The bank must be per-server for per-role paydays to work."))
        else:
            if creds <= 0:  # Because I may as well...
                default_creds = await self.config.guild(guild).PAYDAY_CREDITS()
                await self.config.role(role).clear()
                await ctx.send(
                    _("The payday value attached to role has been removed. "
                      "Users with this role will now receive the default pay "
                      "of {num} {currency}.").format(
                          num=humanize_number(default_creds),
                          currency=credits_name))
            else:
                await self.config.role(role).PAYDAY_CREDITS.set(creds)
                await ctx.send(
                    _("Every payday will now give {num} {currency} "
                      "to people with the role {role_name}.").format(
                          num=humanize_number(creds),
                          currency=credits_name,
                          role_name=role.name))
示例#14
0
    async def command_audiostats(self, ctx: commands.Context):
        """Audio stats."""
        server_num = len(lavalink.active_players())
        total_num = len(lavalink.all_players())

        msg = ""
        async for p in AsyncIter(lavalink.all_players()):
            connect_start = p.fetch("connect")
            connect_dur = self.get_time_string(
                int((datetime.datetime.utcnow() -
                     connect_start).total_seconds()))
            try:
                if not p.current:
                    raise AttributeError
                current_title = await self.get_track_description(
                    p.current, self.local_folder_current_path)
                msg += "{} [`{}`]: {}\n".format(p.channel.guild.name,
                                                connect_dur, current_title)
            except AttributeError:
                msg += "{} [`{}`]: **{}**\n".format(p.channel.guild.name,
                                                    connect_dur,
                                                    _("Nothing playing."))

        if total_num == 0:
            return await self.send_embed_msg(
                ctx, title=_("Not connected anywhere."))
        servers_embed = []
        pages = 1
        for page in pagify(msg, delims=["\n"], page_length=1500):
            em = discord.Embed(
                colour=await ctx.embed_colour(),
                title=_("Playing in {num}/{total} servers:").format(
                    num=humanize_number(server_num),
                    total=humanize_number(total_num)),
                description=page,
            )
            em.set_footer(text=_("Page {}/{}").format(
                humanize_number(pages),
                humanize_number((math.ceil(len(msg) / 1500)))))
            pages += 1
            servers_embed.append(em)

        await menu(ctx, servers_embed, DEFAULT_CONTROLS)
示例#15
0
    async def roll(self, ctx, number: int = 100):
        """Roll a random number.

        The result will be between 1 and `<number>`.

        `<number>` defaults to 100.
        """
        author = ctx.author
        if 1 < number <= MAX_ROLL:
            n = randint(1, number)
            await ctx.send("{author.mention} :game_die: {n} :game_die:".format(
                author=author, n=humanize_number(n)))
        elif number <= 1:
            await ctx.send(
                _("{author.mention} Maybe higher than 1? ;P").format(
                    author=author))
        else:
            await ctx.send(
                _("{author.mention} Max allowed number is {maxamount}.").
                format(author=author, maxamount=humanize_number(MAX_ROLL)))
示例#16
0
async def withdraw_credits(member: discord.Member, amount: int) -> int:
    """Remove a certain amount of credits from an account.

    Parameters
    ----------
    member : discord.Member
        The member to withdraw credits from.
    amount : int
        The amount to withdraw.

    Returns
    -------
    int
        New account balance.

    Raises
    ------
    ValueError
        If the withdrawal amount is invalid or if the account has insufficient
        funds.
    TypeError
        If the withdrawal amount is not an `int`.

    """
    if not isinstance(amount, int):
        raise TypeError(
            "Withdrawal amount must be of type int, not {}.".format(
                type(amount)))
    if _invalid_amount(amount):
        raise ValueError("Invalid withdrawal amount {} < 0".format(
            humanize_number(amount, override_locale="en_US")))

    bal = await get_balance(member)
    if amount > bal:
        raise ValueError("Insufficient funds {} > {}".format(
            humanize_number(amount, override_locale="en_US"),
            humanize_number(bal, override_locale="en_US"),
        ))

    return await set_balance(member, bal - amount)
示例#17
0
    async def registeramount(self, ctx: commands.Context, creds: int):
        """Set the initial balance for new bank accounts.

        Example:
            - `[p]economyset registeramount 5000`

        **Arguments**

        - `<creds>` The new initial balance amount. Default is 0.
        """
        guild = ctx.guild
        max_balance = await bank.get_max_balance(ctx.guild)
        credits_name = await bank.get_currency_name(guild)
        try:
            await bank.set_default_balance(creds, guild)
        except ValueError:
            return await ctx.send(
                _("Amount must be greater than or equal to zero and less than {maxbal}."
                  ).format(maxbal=humanize_number(max_balance)))
        await ctx.send(
            _("Registering an account will now give {num} {currency}.").format(
                num=humanize_number(creds), currency=credits_name))
示例#18
0
async def transfer_credits(
    from_: Union[discord.Member, discord.User],
    to: Union[discord.Member, discord.User],
    amount: int,
):
    """Transfer a given amount of credits from one account to another.

    Parameters
    ----------
    from_: Union[discord.Member, discord.User]
        The member to transfer from.
    to : Union[discord.Member, discord.User]
        The member to transfer to.
    amount : int
        The amount to transfer.

    Returns
    -------
    int
        The new balance of the member gaining credits.

    Raises
    ------
    ValueError
        If the amount is invalid or if ``from_`` has insufficient funds.
    TypeError
        If the amount is not an `int`.
    RuntimeError
        If the bank is guild-specific and a discord.User object is provided.
    BalanceTooHigh
        If the balance after the transfer would be greater than
        ``bank._MAX_BALANCE``.
    """
    if not isinstance(amount, int):
        raise TypeError("Transfer amount must be of type int, not {}.".format(
            type(amount)))
    if _invalid_amount(amount):
        raise ValueError("Invalid transfer amount {} <= 0".format(
            humanize_number(amount, override_locale="en_US")))
    guild = getattr(to, "guild", None)
    max_bal = await get_max_balance(guild)

    if await get_balance(to) + amount > max_bal:
        currency = await get_currency_name(guild)
        raise errors.BalanceTooHigh(user=to.display_name,
                                    max_balance=max_bal,
                                    currency_name=currency)

    await withdraw_credits(from_, amount)
    return await deposit_credits(to, amount)
示例#19
0
 async def maybe_charge_requester(self, ctx: commands.Context, jukebox_price: int) -> bool:
     jukebox = await self.config.guild(ctx.guild).jukebox()
     if jukebox and not await self._can_instaskip(ctx, ctx.author):
         can_spend = await bank.can_spend(ctx.author, jukebox_price)
         if can_spend:
             await bank.withdraw_credits(ctx.author, jukebox_price)
         else:
             credits_name = await bank.get_currency_name(ctx.guild)
             bal = await bank.get_balance(ctx.author)
             await self.send_embed_msg(
                 ctx,
                 title=_("Not enough {currency}").format(currency=credits_name),
                 description=_(
                     "{required_credits} {currency} required, but you have {bal}."
                 ).format(
                     currency=credits_name,
                     required_credits=humanize_number(jukebox_price),
                     bal=humanize_number(bal),
                 ),
             )
         return can_spend
     else:
         return True
示例#20
0
    async def paydayamount(self, ctx: commands.Context, creds: int):
        """Set the amount earned each payday.

        Example:
            - `[p]economyset paydayamount 400`

        **Arguments**

        - `<creds>` The new amount to give when using the payday command. Default is 120.
        """
        guild = ctx.guild
        max_balance = await bank.get_max_balance(ctx.guild)
        if creds <= 0 or creds > max_balance:
            return await ctx.send(
                _("Amount must be greater than zero and less than {maxbal}.").
                format(maxbal=humanize_number(max_balance)))
        credits_name = await bank.get_currency_name(guild)
        if await bank.is_global():
            await self.config.PAYDAY_CREDITS.set(creds)
        else:
            await self.config.guild(guild).PAYDAY_CREDITS.set(creds)
        await ctx.send(
            _("Every payday will now give {num} {currency}.").format(
                num=humanize_number(creds), currency=credits_name))
示例#21
0
async def set_default_balance(amount: int, guild: discord.Guild = None) -> int:
    """Set the default balance amount.

    Parameters
    ----------
    amount : int
        The new default balance.
    guild : `discord.Guild`, optional
        The guild to set the default balance for (required if bank is
        guild-specific).

    Returns
    -------
    int
        The new default balance.

    Raises
    ------
    RuntimeError
        If the bank is guild-specific and guild was not provided.
    ValueError
        If the amount is less than 0 or higher than the max allowed balance.
    TypeError
        If the amount is not an `int`.

    """
    if not isinstance(amount, int):
        raise TypeError("Amount must be of type int, not {}.".format(
            type(amount)))
    max_bal = await get_max_balance(guild)

    if not (0 <= amount <= max_bal):
        raise ValueError(
            "Amount must be greater than or equal zero and less than or equal {max}."
            .format(max=humanize_number(max_bal, override_locale="en_US")))

    if await is_global():
        await _config.default_balance.set(amount)
        global _cache
        _cache["default_balance"] = amount
    elif guild is not None:
        await _config.guild(guild).default_balance.set(amount)
    else:
        raise RuntimeError("Guild is missing and required.")

    return amount
示例#22
0
    def make_embed(self, data):
        base_url = "https://edge.sf.hitbox.tv"
        livestream = data["livestream"][0]
        channel = livestream["channel"]
        url = channel["channel_link"]
        embed = discord.Embed(title=livestream["media_status"],
                              url=url,
                              color=0x98CB00)
        embed.set_author(name=livestream["media_name"])
        embed.add_field(name=_("Followers"),
                        value=humanize_number(channel["followers"]))
        embed.set_thumbnail(url=base_url + channel["user_logo"])
        if livestream["media_thumbnail"]:
            embed.set_image(url=rnd(base_url + livestream["media_thumbnail"]))
        embed.set_footer(text=_("Playing: ") + livestream["category_name"])

        return embed
示例#23
0
async def set_max_balance(amount: int, guild: discord.Guild = None) -> int:
    """Set the maximum balance for the bank.

    Parameters
    ----------
    amount : int
        The new maximum balance.
    guild : `discord.Guild`, optional
        The guild to set the max balance for (required if bank is
        guild-specific).

    Returns
    -------
    int
        The new maximum balance.

    Raises
    ------
    RuntimeError
        If the bank is guild-specific and guild was not provided.
    ValueError
        If the amount is less than 0 or higher than 2 ** 63 - 1.
    TypeError
        If the amount is not an `int`.

    """
    if not isinstance(amount, int):
        raise TypeError("Amount must be of type int, not {}.".format(
            type(amount)))
    if not (0 < amount <= _MAX_BALANCE):
        raise ValueError(
            "Amount must be greater than zero and less than {max}.".format(
                max=humanize_number(_MAX_BALANCE, override_locale="en_US")))

    if await is_global():
        await _config.max_balance.set(amount)
        global _cache
        _cache["max_balance"] = amount
    elif guild is not None:
        await _config.guild(guild).max_balance.set(amount)
    else:
        raise RuntimeError(
            "Guild must be provided if setting the maximum balance of a guild-specific bank."
        )
    return amount
示例#24
0
    async def command_equalizer_list(self, ctx: commands.Context):
        """List saved eq presets."""
        eq_presets = await self.config.custom("EQUALIZER",
                                              ctx.guild.id).eq_presets()
        if not eq_presets.keys():
            return await self.send_embed_msg(
                ctx, title=_("No saved equalizer presets."))

        space = "\N{EN SPACE}"
        header_name = _("Preset Name")
        header_author = _("Author")
        header = box(
            "[{header_name}]{space}[{header_author}]\n".format(
                header_name=header_name,
                space=space * 9,
                header_author=header_author),
            lang="ini",
        )
        preset_list = ""
        for preset, bands in eq_presets.items():
            try:
                author = self.bot.get_user(bands["author"])
            except TypeError:
                author = "None"
            msg = f"{preset}{space * (22 - len(preset))}{author}\n"
            preset_list += msg

        page_list = []
        colour = await ctx.embed_colour()
        for page in pagify(preset_list, delims=[", "], page_length=1000):
            formatted_page = box(page, lang="ini")
            embed = discord.Embed(colour=colour,
                                  description=f"{header}\n{formatted_page}")
            embed.set_footer(text=_("{num} preset(s)").format(
                num=humanize_number(len(list(eq_presets.keys())))))
            page_list.append(embed)
        await menu(ctx, page_list, DEFAULT_CONTROLS)
示例#25
0
    async def _build_queue_page(
        self,
        ctx: commands.Context,
        queue: list,
        player: lavalink.player_manager.Player,
        page_num: int,
    ) -> discord.Embed:
        shuffle = await self.config.guild(ctx.guild).shuffle()
        repeat = await self.config.guild(ctx.guild).repeat()
        autoplay = await self.config.guild(ctx.guild).auto_play()

        queue_num_pages = math.ceil(len(queue) / 10)
        queue_idx_start = (page_num - 1) * 10
        queue_idx_end = queue_idx_start + 10
        if len(player.queue) > 500:
            queue_list = _(
                "__Too many songs in the queue, only showing the first 500__.\n\n"
            )
        else:
            queue_list = ""

        arrow = await self.draw_time(ctx)
        pos = self.format_time(player.position)

        if player.current.is_stream:
            dur = "LIVE"
        else:
            dur = self.format_time(player.current.length)

        query = Query.process_input(player.current,
                                    self.local_folder_current_path)
        current_track_description = await self.get_track_description(
            player.current, self.local_folder_current_path)
        if query.is_stream:
            queue_list += _("**Currently livestreaming:**\n")
            queue_list += f"{current_track_description}\n"
            queue_list += _("Requested by: **{user}**").format(
                user=player.current.requester)
            queue_list += f"\n\n{arrow}`{pos}`/`{dur}`\n\n"
        else:
            queue_list += _("Playing: ")
            queue_list += f"{current_track_description}\n"
            queue_list += _("Requested by: **{user}**").format(
                user=player.current.requester)
            queue_list += f"\n\n{arrow}`{pos}`/`{dur}`\n\n"

        async for i, track in AsyncIter(
                queue[queue_idx_start:queue_idx_end]).enumerate(
                    start=queue_idx_start):
            req_user = track.requester
            track_idx = i + 1
            track_description = await self.get_track_description(
                track, self.local_folder_current_path, shorten=True)
            queue_list += f"`{track_idx}.` {track_description}, "
            queue_list += _("requested by **{user}**\n").format(user=req_user)

        embed = discord.Embed(
            colour=await ctx.embed_colour(),
            title=_("Queue for __{guild_name}__").format(
                guild_name=ctx.guild.name),
            description=queue_list,
        )

        if await self.config.guild(ctx.guild
                                   ).thumbnail() and player.current.thumbnail:
            embed.set_thumbnail(url=player.current.thumbnail)
        queue_dur = await self.queue_duration(ctx)
        queue_total_duration = self.format_time(queue_dur)
        text = _(
            "Page {page_num}/{total_pages} | {num_tracks} tracks, {num_remaining} remaining\n"
        ).format(
            page_num=humanize_number(page_num),
            total_pages=humanize_number(queue_num_pages),
            num_tracks=len(player.queue),
            num_remaining=queue_total_duration,
        )
        text += (
            _("Auto-Play") + ": " +
            ("\N{WHITE HEAVY CHECK MARK}" if autoplay else "\N{CROSS MARK}"))
        text += (
            (" | " if text else "") + _("Shuffle") + ": " +
            ("\N{WHITE HEAVY CHECK MARK}" if shuffle else "\N{CROSS MARK}"))
        text += (
            (" | " if text else "") + _("Repeat") + ": " +
            ("\N{WHITE HEAVY CHECK MARK}" if repeat else "\N{CROSS MARK}"))
        embed.set_footer(text=text)
        return embed
示例#26
0
    async def command_skip(self,
                           ctx: commands.Context,
                           skip_to_track: int = None):
        """Skip to the next track, or to a given track number."""
        if not self._player_check(ctx):
            return await self.send_embed_msg(ctx, title=_("Nothing playing."))
        player = lavalink.get_player(ctx.guild.id)
        can_skip = await self._can_instaskip(ctx, ctx.author)
        if (not ctx.author.voice or
                ctx.author.voice.channel != player.channel) and not can_skip:
            return await self.send_embed_msg(
                ctx,
                title=_("Unable To Skip Tracks"),
                description=_(
                    "You must be in the voice channel to skip the music."),
            )
        if not player.current:
            return await self.send_embed_msg(ctx, title=_("Nothing playing."))
        dj_enabled = self._dj_status_cache.setdefault(
            ctx.guild.id, await self.config.guild(ctx.guild).dj_enabled())
        vote_enabled = await self.config.guild(ctx.guild).vote_enabled()
        is_alone = await self.is_requester_alone(ctx)
        is_requester = await self.is_requester(ctx, ctx.author)
        if dj_enabled and not vote_enabled:
            if not (can_skip or is_requester) and not is_alone:
                return await self.send_embed_msg(
                    ctx,
                    title=_("Unable To Skip Tracks"),
                    description=
                    _("You need the DJ role or be the track requester to skip tracks."
                      ),
                )
            if (is_requester and not can_skip
                    and isinstance(skip_to_track, int) and skip_to_track > 1):
                return await self.send_embed_msg(
                    ctx,
                    title=_("Unable To Skip Tracks"),
                    description=_("You can only skip the current track."),
                )

        if vote_enabled:
            if not can_skip:
                if skip_to_track is not None:
                    return await self.send_embed_msg(
                        ctx,
                        title=_("Unable To Skip Tracks"),
                        description=
                        _("Can't skip to a specific track in vote mode without the DJ role."
                          ),
                    )
                if ctx.author.id in self.skip_votes[ctx.message.guild]:
                    self.skip_votes[ctx.message.guild].remove(ctx.author.id)
                    reply = _("I removed your vote to skip.")
                else:
                    self.skip_votes[ctx.message.guild].append(ctx.author.id)
                    reply = _("You voted to skip.")

                num_votes = len(self.skip_votes[ctx.message.guild])
                vote_mods = []
                for member in player.channel.members:
                    can_skip = await self._can_instaskip(ctx, member)
                    if can_skip:
                        vote_mods.append(member)
                num_members = len(player.channel.members) - len(vote_mods)
                vote = int(100 * num_votes / num_members)
                percent = await self.config.guild(ctx.guild).vote_percent()
                if vote >= percent:
                    self.skip_votes[ctx.message.guild] = []
                    await self.send_embed_msg(ctx,
                                              title=_("Vote threshold met."))
                    return await self._skip_action(ctx)
                else:
                    reply += _(
                        " Votes: {num_votes}/{num_members}"
                        " ({cur_percent}% out of {required_percent}% needed)"
                    ).format(
                        num_votes=humanize_number(num_votes),
                        num_members=humanize_number(num_members),
                        cur_percent=vote,
                        required_percent=percent,
                    )
                    return await self.send_embed_msg(ctx, title=reply)
            else:
                return await self._skip_action(ctx, skip_to_track)
        else:
            return await self._skip_action(ctx, skip_to_track)
示例#27
0
 def __str__(self) -> str:
     return _(
         "{user}'s balance cannot rise above {max} {currency}.").format(
             user=self.user,
             max=humanize_number(self.max_balance),
             currency=self.currency_name)
示例#28
0
    async def leaderboard(self,
                          ctx: commands.Context,
                          top: int = 10,
                          show_global: bool = False):
        """Print the leaderboard.

        Defaults to top 10.

        Examples:
            - `[p]leaderboard`
            - `[p]leaderboard 50` - Shows the top 50 instead of top 10.
            - `[p]leaderboard 100 yes` - Shows the top 100 from all servers.

        **Arguments**

        - `<top>` How many positions on the leaderboard to show. Defaults to 10 if omitted.
        - `<show_global>` Whether to include results from all servers. This will default to false unless specified.
        """
        guild = ctx.guild
        author = ctx.author
        embed_requested = await ctx.embed_requested()
        footer_message = _("Page {page_num}/{page_len}.")
        max_bal = await bank.get_max_balance(ctx.guild)

        if top < 1:
            top = 10

        base_embed = discord.Embed(title=_("Economy Leaderboard"))
        if await bank.is_global() and show_global:
            # show_global is only applicable if bank is global
            bank_sorted = await bank.get_leaderboard(positions=top, guild=None)
            base_embed.set_author(name=ctx.bot.user.name,
                                  icon_url=ctx.bot.user.avatar_url)
        else:
            bank_sorted = await bank.get_leaderboard(positions=top,
                                                     guild=guild)
            if guild:
                base_embed.set_author(name=guild.name, icon_url=guild.icon_url)

        try:
            bal_len = len(humanize_number(bank_sorted[0][1]["balance"]))
            bal_len_max = len(humanize_number(max_bal))
            if bal_len > bal_len_max:
                bal_len = bal_len_max
            # first user is the largest we'll see
        except IndexError:
            return await ctx.send(_("There are no accounts in the bank."))
        pound_len = len(str(len(bank_sorted)))
        header = "{pound:{pound_len}}{score:{bal_len}}{name:2}\n".format(
            pound="#",
            name=_("Name"),
            score=_("Score"),
            bal_len=bal_len + 6,
            pound_len=pound_len + 3,
        )
        highscores = []
        pos = 1
        temp_msg = header
        for acc in bank_sorted:
            try:
                name = guild.get_member(acc[0]).display_name
            except AttributeError:
                user_id = ""
                if await ctx.bot.is_owner(ctx.author):
                    user_id = f"({str(acc[0])})"
                name = f"{acc[1]['name']} {user_id}"

            balance = acc[1]["balance"]
            if balance > max_bal:
                balance = max_bal
                await bank.set_balance(MOCK_MEMBER(acc[0], guild), balance)
            balance = humanize_number(balance)
            if acc[0] != author.id:
                temp_msg += (f"{f'{humanize_number(pos)}.': <{pound_len+2}} "
                             f"{balance: <{bal_len + 5}} {name}\n")

            else:
                temp_msg += (f"{f'{humanize_number(pos)}.': <{pound_len+2}} "
                             f"{balance: <{bal_len + 5}} "
                             f"<<{author.display_name}>>\n")
            if pos % 10 == 0:
                if embed_requested:
                    embed = base_embed.copy()
                    embed.description = box(temp_msg, lang="md")
                    embed.set_footer(text=footer_message.format(
                        page_num=len(highscores) + 1,
                        page_len=ceil(len(bank_sorted) / 10),
                    ))
                    highscores.append(embed)
                else:
                    highscores.append(box(temp_msg, lang="md"))
                temp_msg = header
            pos += 1

        if temp_msg != header:
            if embed_requested:
                embed = base_embed.copy()
                embed.description = box(temp_msg, lang="md")
                embed.set_footer(text=footer_message.format(
                    page_num=len(highscores) + 1,
                    page_len=ceil(len(bank_sorted) / 10),
                ))
                highscores.append(embed)
            else:
                highscores.append(box(temp_msg, lang="md"))

        if highscores:
            await menu(
                ctx,
                highscores,
                DEFAULT_CONTROLS
                if len(highscores) > 1 else {"\N{CROSS MARK}": close_menu},
            )
        else:
            await ctx.send(_("No balances found."))
示例#29
0
    async def serverinfo(self, ctx, details: bool = False):
        """
        Show server information.

        `details`: Shows more information when set to `True`.
        Default to False.
        """
        guild = ctx.guild
        passed = (ctx.message.created_at - guild.created_at).days
        created_at = _(
            "Created on {date}. That's over {num} days ago!").format(
                date=guild.created_at.strftime("%d %b %Y %H:%M"),
                num=humanize_number(passed),
            )
        online = humanize_number(
            len([
                m.status for m in guild.members
                if m.status != discord.Status.offline
            ]))
        total_users = humanize_number(guild.member_count)
        text_channels = humanize_number(len(guild.text_channels))
        voice_channels = humanize_number(len(guild.voice_channels))
        if not details:
            data = discord.Embed(description=created_at,
                                 colour=await ctx.embed_colour())
            data.add_field(name=_("Region"), value=str(guild.region))
            data.add_field(name=_("Users online"),
                           value=f"{online}/{total_users}")
            data.add_field(name=_("Text Channels"), value=text_channels)
            data.add_field(name=_("Voice Channels"), value=voice_channels)
            data.add_field(name=_("Roles"),
                           value=humanize_number(len(guild.roles)))
            data.add_field(name=_("Owner"), value=str(guild.owner))
            data.set_footer(
                text=_("Server ID: ") + str(guild.id) +
                _("  •  Use {command} for more info on the server.").format(
                    command=f"{ctx.clean_prefix}serverinfo 1"))
            if guild.icon_url:
                data.set_author(name=guild.name, url=guild.icon_url)
                data.set_thumbnail(url=guild.icon_url)
            else:
                data.set_author(name=guild.name)
        else:

            def _size(num: int):
                for unit in ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB"]:
                    if abs(num) < 1024.0:
                        return "{0:.1f}{1}".format(num, unit)
                    num /= 1024.0
                return "{0:.1f}{1}".format(num, "YB")

            def _bitsize(num: int):
                for unit in ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB"]:
                    if abs(num) < 1000.0:
                        return "{0:.1f}{1}".format(num, unit)
                    num /= 1000.0
                return "{0:.1f}{1}".format(num, "YB")

            shard_info = (_("\nShard ID: **{shard_id}/{shard_count}**").format(
                shard_id=humanize_number(guild.shard_id + 1),
                shard_count=humanize_number(ctx.bot.shard_count),
            ) if ctx.bot.shard_count > 1 else "")
            # Logic from: https://github.com/TrustyJAID/Trusty-cogs/blob/master/serverstats/serverstats.py#L159
            online_stats = {
                _("Humans: "):
                lambda x: not x.bot,
                _(" • Bots: "):
                lambda x: x.bot,
                "\N{LARGE GREEN CIRCLE}":
                lambda x: x.status is discord.Status.online,
                "\N{LARGE ORANGE CIRCLE}":
                lambda x: x.status is discord.Status.idle,
                "\N{LARGE RED CIRCLE}":
                lambda x: x.status is discord.Status.do_not_disturb,
                "\N{MEDIUM WHITE CIRCLE}\N{VARIATION SELECTOR-16}":
                lambda x: (x.status is discord.Status.offline),
                "\N{LARGE PURPLE CIRCLE}":
                lambda x: any(a.type is discord.ActivityType.streaming
                              for a in x.activities),
                "\N{MOBILE PHONE}":
                lambda x: x.is_on_mobile(),
            }
            member_msg = _(
                "Users online: **{online}/{total_users}**\n").format(
                    online=online, total_users=total_users)
            count = 1
            for emoji, value in online_stats.items():
                try:
                    num = len([m for m in guild.members if value(m)])
                except Exception as error:
                    print(error)
                    continue
                else:
                    member_msg += f"{emoji} {bold(humanize_number(num))} " + (
                        "\n" if count % 2 == 0 else "")
                count += 1

            vc_regions = {
                "vip-us-east": _("__VIP__ US East ") + "\U0001F1FA\U0001F1F8",
                "vip-us-west": _("__VIP__ US West ") + "\U0001F1FA\U0001F1F8",
                "vip-amsterdam":
                _("__VIP__ Amsterdam ") + "\U0001F1F3\U0001F1F1",
                "eu-west": _("EU West ") + "\U0001F1EA\U0001F1FA",
                "eu-central": _("EU Central ") + "\U0001F1EA\U0001F1FA",
                "europe": _("Europe ") + "\U0001F1EA\U0001F1FA",
                "london": _("London ") + "\U0001F1EC\U0001F1E7",
                "frankfurt": _("Frankfurt ") + "\U0001F1E9\U0001F1EA",
                "amsterdam": _("Amsterdam ") + "\U0001F1F3\U0001F1F1",
                "us-west": _("US West ") + "\U0001F1FA\U0001F1F8",
                "us-east": _("US East ") + "\U0001F1FA\U0001F1F8",
                "us-south": _("US South ") + "\U0001F1FA\U0001F1F8",
                "us-central": _("US Central ") + "\U0001F1FA\U0001F1F8",
                "singapore": _("Singapore ") + "\U0001F1F8\U0001F1EC",
                "sydney": _("Sydney ") + "\U0001F1E6\U0001F1FA",
                "brazil": _("Brazil ") + "\U0001F1E7\U0001F1F7",
                "hongkong": _("Hong Kong ") + "\U0001F1ED\U0001F1F0",
                "russia": _("Russia ") + "\U0001F1F7\U0001F1FA",
                "japan": _("Japan ") + "\U0001F1EF\U0001F1F5",
                "southafrica": _("South Africa ") + "\U0001F1FF\U0001F1E6",
                "india": _("India ") + "\U0001F1EE\U0001F1F3",
                "dubai": _("Dubai ") + "\U0001F1E6\U0001F1EA",
                "south-korea": _("South Korea ") + "\U0001f1f0\U0001f1f7",
            }
            verif = {
                "none": _("0 - None"),
                "low": _("1 - Low"),
                "medium": _("2 - Medium"),
                "high": _("3 - High"),
                "extreme": _("4 - Extreme"),
            }

            features = {
                "ANIMATED_ICON":
                _("Animated Icon"),
                "BANNER":
                _("Banner Image"),
                "COMMERCE":
                _("Commerce"),
                "COMMUNITY":
                _("Community"),
                "DISCOVERABLE":
                _("Server Discovery"),
                "FEATURABLE":
                _("Featurable"),
                "INVITE_SPLASH":
                _("Splash Invite"),
                "MEMBER_LIST_DISABLED":
                _("Member list disabled"),
                "MEMBER_VERIFICATION_GATE_ENABLED":
                _("Membership Screening enabled"),
                "MORE_EMOJI":
                _("More Emojis"),
                "NEWS":
                _("News Channels"),
                "PARTNERED":
                _("Partnered"),
                "PREVIEW_ENABLED":
                _("Preview enabled"),
                "PUBLIC_DISABLED":
                _("Public disabled"),
                "VANITY_URL":
                _("Vanity URL"),
                "VERIFIED":
                _("Verified"),
                "VIP_REGIONS":
                _("VIP Voice Servers"),
                "WELCOME_SCREEN_ENABLED":
                _("Welcome Screen enabled"),
            }
            guild_features_list = [
                f"\N{WHITE HEAVY CHECK MARK} {name}"
                for feature, name in features.items()
                if feature in guild.features
            ]

            joined_on = _(
                "{bot_name} joined this server on {bot_join}. That's over {since_join} days ago!"
            ).format(
                bot_name=ctx.bot.user.name,
                bot_join=guild.me.joined_at.strftime("%d %b %Y %H:%M:%S"),
                since_join=humanize_number(
                    (ctx.message.created_at - guild.me.joined_at).days),
            )

            data = discord.Embed(
                description=(f"{guild.description}\n\n"
                             if guild.description else "") + created_at,
                colour=await ctx.embed_colour(),
            )
            data.set_author(
                name=guild.name,
                icon_url=
                "https://cdn.discordapp.com/emojis/457879292152381443.png"
                if "VERIFIED" in guild.features else
                "https://cdn.discordapp.com/emojis/508929941610430464.png"
                if "PARTNERED" in guild.features else discord.Embed.Empty,
            )
            if guild.icon_url:
                data.set_thumbnail(url=guild.icon_url)
            data.add_field(name=_("Members:"), value=member_msg)
            data.add_field(
                name=_("Channels:"),
                value=_("\N{SPEECH BALLOON} Text: {text}\n"
                        "\N{SPEAKER WITH THREE SOUND WAVES} Voice: {voice}").
                format(text=bold(text_channels), voice=bold(voice_channels)),
            )
            data.add_field(
                name=_("Utility:"),
                value=_(
                    "Owner: {owner}\nVoice region: {region}\nVerif. level: {verif}\nServer ID: {id}{shard_info}"
                ).format(
                    owner=bold(str(guild.owner)),
                    region=
                    f"**{vc_regions.get(str(guild.region)) or str(guild.region)}**",
                    verif=bold(verif[str(guild.verification_level)]),
                    id=bold(str(guild.id)),
                    shard_info=shard_info,
                ),
                inline=False,
            )
            data.add_field(
                name=_("Misc:"),
                value=
                _("AFK channel: {afk_chan}\nAFK timeout: {afk_timeout}\nCustom emojis: {emoji_count}\nRoles: {role_count}"
                  ).format(
                      afk_chan=bold(str(guild.afk_channel))
                      if guild.afk_channel else bold(_("Not set")),
                      afk_timeout=bold(
                          humanize_timedelta(seconds=guild.afk_timeout)),
                      emoji_count=bold(humanize_number(len(guild.emojis))),
                      role_count=bold(humanize_number(len(guild.roles))),
                  ),
                inline=False,
            )
            if guild_features_list:
                data.add_field(name=_("Server features:"),
                               value="\n".join(guild_features_list))
            if guild.premium_tier != 0:
                nitro_boost = _(
                    "Tier {boostlevel} with {nitroboosters} boosts\n"
                    "File size limit: {filelimit}\n"
                    "Emoji limit: {emojis_limit}\n"
                    "VCs max bitrate: {bitrate}").format(
                        boostlevel=bold(str(guild.premium_tier)),
                        nitroboosters=bold(
                            humanize_number(guild.premium_subscription_count)),
                        filelimit=bold(_size(guild.filesize_limit)),
                        emojis_limit=bold(str(guild.emoji_limit)),
                        bitrate=bold(_bitsize(guild.bitrate_limit)),
                    )
                data.add_field(name=_("Nitro Boost:"), value=nitro_boost)
            if guild.splash:
                data.set_image(url=guild.splash_url_as(format="png"))
            data.set_footer(text=joined_on)

        await ctx.send(embed=data)
示例#30
0
    async def slot_machine(author, channel, bid):
        default_reel = deque(cast(Iterable, SMReel))
        reels = []
        for i in range(3):
            default_reel.rotate(random.randint(-999, 999))  # weeeeee
            new_reel = deque(default_reel, maxlen=3)  # we need only 3 symbols
            reels.append(new_reel)  # for each reel
        rows = (
            (reels[0][0], reels[1][0], reels[2][0]),
            (reels[0][1], reels[1][1], reels[2][1]),
            (reels[0][2], reels[1][2], reels[2][2]),
        )

        slot = "~~\n~~"  # Mobile friendly
        for i, row in enumerate(rows):  # Let's build the slot to show
            sign = "  "
            if i == 1:
                sign = ">"
            slot += "{}{} {} {}\n".format(
                sign,
                *[c.value for c in row]  # pylint: disable=no-member
            )

        payout = PAYOUTS.get(rows[1])
        if not payout:
            # Checks for two-consecutive-symbols special rewards
            payout = PAYOUTS.get((rows[1][0], rows[1][1]),
                                 PAYOUTS.get((rows[1][1], rows[1][2])))
        if not payout:
            # Still nothing. Let's check for 3 generic same symbols
            # or 2 consecutive symbols
            has_three = rows[1][0] == rows[1][1] == rows[1][2]
            has_two = (rows[1][0] == rows[1][1]) or (rows[1][1] == rows[1][2])
            if has_three:
                payout = PAYOUTS["3 symbols"]
            elif has_two:
                payout = PAYOUTS["2 symbols"]

        pay = 0
        if payout:
            then = await bank.get_balance(author)
            pay = payout["payout"](bid)
            now = then - bid + pay
            try:
                await bank.set_balance(author, now)
            except errors.BalanceTooHigh as exc:
                await bank.set_balance(author, exc.max_balance)
                await channel.send(
                    _("You've reached the maximum amount of {currency}! "
                      "Please spend some more \N{GRIMACING FACE}\n{old_balance} -> {new_balance}!"
                      ).format(
                          currency=await bank.get_currency_name(
                              getattr(channel, "guild", None)),
                          old_balance=humanize_number(then),
                          new_balance=humanize_number(exc.max_balance),
                      ))
                return
            phrase = T_(payout["phrase"])
        else:
            then = await bank.get_balance(author)
            await bank.withdraw_credits(author, bid)
            now = then - bid
            phrase = _("Nothing!")
        await channel.send(("{slot}\n{author.mention} {phrase}\n\n" + _(
            "Your bid: {bid}"
        ) + _(
            "\n{old_balance} - {bid} (Your bid) + {pay} (Winnings) → {new_balance}!"
        )).format(
            slot=slot,
            author=author,
            phrase=phrase,
            bid=humanize_number(bid),
            old_balance=humanize_number(then),
            new_balance=humanize_number(now),
            pay=humanize_number(pay),
        ))