Exemplo n.º 1
0
import re
from beastbot.core.commands import Converter, BadArgument
from beastbot.core.i18n import Translator

_ = Translator("Mod", __file__)

_id_regex = re.compile(r"([0-9]{15,21})$")
_mention_regex = re.compile(r"<@!?([0-9]{15,21})>$")


class RawUserIds(Converter):
    async def convert(self, ctx, argument):
        # This is for the hackban and unban commands, where we receive IDs that
        # are most likely not in the guild.
        # Mentions are supported, but most likely won't ever be in cache.

        if match := _id_regex.match(argument) or _mention_regex.match(
                argument):
            return int(match.group(1))

        raise BadArgument(
            _("{} doesn't look like a valid user ID.").format(argument))
Exemplo n.º 2
0
from typing import NewType, TYPE_CHECKING

from beastbot.core.commands import BadArgument, Context, Converter
from beastbot.core.i18n import Translator
from beastbot.core.utils.chat_formatting import inline

_ = Translator("Cleanup", __file__)


class RawMessageIds(Converter):
    async def convert(self, ctx: Context, argument: str) -> int:
        if argument.isnumeric() and len(argument) >= 17:
            return int(argument)

        raise BadArgument(
            _("{} doesn't look like a valid message ID.").format(argument))


PositiveInt = NewType("PositiveInt", int)
if TYPE_CHECKING:
    positive_int = PositiveInt
else:

    def positive_int(arg: str) -> int:
        try:
            ret = int(arg)
        except ValueError:
            raise BadArgument(
                _("{arg} is not an integer.").format(arg=inline(arg)))
        if ret <= 0:
            raise BadArgument(
Exemplo n.º 3
0
from beastbot.core.i18n import Translator
from beastbot.core.utils import AsyncIter
from beastbot.core.utils.chat_formatting import box
from beastbot.core.utils.menus import start_adding_reactions
from beastbot.core.utils.predicates import ReactionPredicate

from ...apis.playlist_interface import Playlist, create_playlist
from ...audio_dataclasses import _PARTIALLY_SUPPORTED_MUSIC_EXT, Query
from ...audio_logging import debug_exc_log
from ...errors import TooManyMatches, TrackEnqueueError
from ...utils import Notifier, PlaylistScope
from ..abc import MixinMeta
from ..cog_utils import CompositeMetaClass

log = logging.getLogger("red.cogs.Audio.cog.Utilities.playlists")
_ = Translator("Audio", Path(__file__))


class PlaylistUtilities(MixinMeta, metaclass=CompositeMetaClass):
    async def can_manage_playlist(self, scope: str, playlist: Playlist,
                                  ctx: commands.Context, user, guild) -> bool:
        is_owner = await self.bot.is_owner(ctx.author)
        has_perms = False
        user_to_query = user
        guild_to_query = guild
        dj_enabled = None
        playlist_author = (guild.get_member(playlist.author) if guild else
                           self.bot.get_user(playlist.author) or user)

        is_different_user = len(
            {playlist.author, user_to_query.id, ctx.author.id}) != 1
Exemplo n.º 4
0
from copy import copy
import asyncio
import discord

from beastbot.core import Config, checks, commands
from beastbot.core.commands.requires import PrivilegeLevel
from beastbot.core.i18n import Translator
from beastbot.core.utils.predicates import MessagePredicate

_ = Translator("Warnings", __file__)


async def warning_points_add_check(
    config: Config, ctx: commands.Context, user: discord.Member, points: int
):
    """Handles any action that needs to be taken or not based on the points"""
    guild = ctx.guild
    guild_settings = config.guild(guild)
    act = {}
    async with guild_settings.actions() as registered_actions:
        for a in registered_actions:
            # Actions are sorted in decreasing order of points.
            # The first action we find where the user is above the threshold will be the
            # highest action we can take.
            if points >= a["points"]:
                act = a
                break
    if act and act["exceed_command"] is not None:  # some action needs to be taken
        await create_and_invoke_context(ctx, act["exceed_command"], user)

Exemplo n.º 5
0
from beastbot.core.i18n import Translator, cog_i18n
from beastbot.core.utils import AsyncIter
from beastbot.core.utils.chat_formatting import box, pagify, bold
from beastbot.core.utils.menus import start_adding_reactions
from beastbot.core.utils.predicates import MessagePredicate, ReactionPredicate

from .checks import trivia_stop_check
from .converters import finite_float
from .log import LOG
from .session import TriviaSession

__all__ = ["Trivia", "UNIQUE_ID", "get_core_lists"]

UNIQUE_ID = 0xB3C0E453

_ = Translator("Trivia", __file__)


class InvalidListError(Exception):
    """A Trivia list file is in invalid format."""

    pass


@cog_i18n(_)
class Trivia(commands.Cog):
    """Play trivia with friends!"""
    def __init__(self):
        super().__init__()
        self.trivia_sessions = []
        self.config = Config.get_conf(self,
Exemplo n.º 6
0
import datetime
import itertools
import textwrap
from io import BytesIO
from typing import Iterator, List, Optional, Sequence, SupportsInt, Union

import discord
from babel.lists import format_list as babel_list
from babel.numbers import format_decimal

from beastbot.core.i18n import Translator, get_babel_locale, get_babel_regional_format

_ = Translator("UtilsChatFormatting", __file__)


def error(text: str) -> str:
    """Get text prefixed with an error emoji.

    Returns
    -------
    str
        The new message.

    """
    return "\N{NO ENTRY SIGN} {}".format(text)


def warning(text: str) -> str:
    """Get text prefixed with a warning emoji.

    Returns
Exemplo n.º 7
0
from datetime import timedelta
from copy import copy
import contextlib
import discord

from beastbot.core import Config, checks, commands
from beastbot.core.utils import AsyncIter
from beastbot.core.utils.chat_formatting import pagify, box
from beastbot.core.utils.antispam import AntiSpam
from beastbot.core.bot import Red
from beastbot.core.i18n import Translator, cog_i18n, set_contextual_locales_from_guild
from beastbot.core.utils.predicates import MessagePredicate
from beastbot.core.utils.tunnel import Tunnel


_ = Translator("Reports", __file__)

log = logging.getLogger("red.reports")


@cog_i18n(_)
class Reports(commands.Cog):
    """Create user reports that server staff can respond to.

    Users can open reports using `[p]report`. These are then sent
    to a channel in the server for staff, and the report creator
    gets a DM. Both can be used to communicate.
    """

    default_guild_settings = {"output_channel": None, "active": False, "next_ticket": 1}
Exemplo n.º 8
0
import asyncio
from typing import Optional

import discord
from beastbot.core import commands
from beastbot.core.i18n import Translator
from beastbot.core.utils import AsyncIter
from beastbot.core.utils.chat_formatting import humanize_list, inline

_ = Translator("Announcer", __file__)


class Announcer:
    def __init__(self, ctx: commands.Context, message: str, config=None):
        """
        :param ctx:
        :param message:
        :param config: Used to determine channel overrides
        """
        self.ctx = ctx
        self.message = message
        self.config = config

        self.active = None

    def start(self):
        """
        Starts an announcement.
        :return:
        """
        if self.active is None: