Beispiel #1
0
    def __init__(self,
                 command: str,
                 *,
                 flag: Optional[str] = None,
                 owner_only: bool = False,
                 chan: bool = True,
                 pm: bool = False,
                 playing: bool = False,
                 silenced: bool = False,
                 phases: Iterable[str] = (),
                 roles: Iterable[str] = (),
                 users: Iterable[User] = None):

        # the "d" flag indicates it should only be enabled in debug mode
        if flag == "d" and not botconfig.DEBUG_MODE:
            return

        # handle command localizations
        commands = messages.raw("_commands")[command]

        self.commands = frozenset(commands)
        self.flag = flag
        self.owner_only = owner_only
        self.chan = chan
        self.pm = pm
        self.playing = playing
        self.silenced = silenced
        self.phases = phases
        self.roles = roles
        self.users = users  # iterable of users that can use the command at any time (should be a mutable object)
        self.func = None
        self.aftergame = False
        self.name = commands[0]
        self.key = "{0}_{1}".format(command, id(self))
        self.alt_allowed = bool(flag or owner_only)

        alias = False
        self.aliases = []

        if var.DISABLED_COMMANDS.intersection(commands):
            return  # command is disabled, do not add to COMMANDS

        for name in commands:
            for func in COMMANDS[name]:
                if func.owner_only != owner_only or func.flag != flag:
                    raise ValueError("unmatching access levels for {0}".format(
                        func.name))

            COMMANDS[name].append(self)
            if name in botconfig.ALLOWED_ALT_CHANNELS_COMMANDS:
                self.alt_allowed = True
            if name in getattr(botconfig, "OWNERS_ONLY_COMMANDS", ()):
                self.owner_only = True
            if alias:
                self.aliases.append(name)
            alias = True

        if playing:  # Don't restrict to owners or allow in alt channels
            self.owner_only = False
            self.alt_allowed = False
Beispiel #2
0
 def _join_simple(self, value, arg, sort=False):
     from src.messages import messages
     # join using only a comma (in English), regardless of the number of list items
     normal_chars = messages.raw("_metadata", "list")
     simple = normal_chars[1]
     return self._join(value,
                       arg,
                       join_chars=[simple, simple, simple],
                       sort=sort)
Beispiel #3
0
    def _article(self, value, arg):
        from src.messages import messages

        for rule in messages.raw("_metadata", "articles"):
            if rule["pattern"] is None or fnmatch.fnmatch(
                    value, rule["pattern"]):
                return rule["article"]

        raise ValueError(
            "No article rules matched the value {0!r} in language metadata!".
            format(value))
Beispiel #4
0
    def convert_field(self, value, conversion):
        from src.messages import messages, LocalRole, LocalMode, LocalTotem

        if conversion == "role":
            if isinstance(value, LocalRole):
                # FIXME: this doesn't necessarily match the roles metadata (which can have lists of arbitrary length)
                return [value.singular, value.plural]
            return messages.raw("_roles", value)
        if conversion == "mode":
            if isinstance(value, LocalMode):
                return value.local
            return messages.raw("_gamemodes", value)
        if conversion == "command":
            return messages.raw("_commands", value)[0]
        if conversion == "totem":
            if isinstance(value, LocalTotem):
                return value.local
            return messages.raw("_totems", value)
        if conversion == "cat":
            return messages.raw("_role_categories", value)
        if conversion == "phase":
            return messages.raw("_phases", value)

        # not one of our custom things
        return super().convert_field(value, conversion)
Beispiel #5
0
def _parse_expires(expires: str,
                   base: Optional[str] = None) -> Optional[datetime]:
    if expires in messages.raw("never_aliases"):
        return None

    try:
        # if passed a raw int, treat it as days
        amount = int(expires)
        suffix = messages.raw("day_suffix")
    except ValueError:
        amount = int(expires[:-1])
        suffix = expires[-1]

    if amount <= 0:
        raise ValueError("amount cannot be negative")

    if not base:
        base = datetime.utcnow()
    else:
        base = datetime.strptime(base, "%Y-%m-%d %H:%M:%S")

    if suffix == messages.raw("day_suffix"):
        expires = base + timedelta(days=amount)
    elif suffix == messages.raw("hour_suffix"):
        expires = base + timedelta(hours=amount)
    elif suffix == messages.raw("minute_suffix"):
        expires = base + timedelta(minutes=amount)
    else:
        raise ValueError("unrecognized time suffix")

    round_add = 0
    if expires.second >= 30:
        round_add = 1
    expires -= timedelta(seconds=expires.second,
                         microseconds=expires.microsecond)
    expires += timedelta(minutes=round_add)
    return expires
Beispiel #6
0
    def _plural(self, value, arg):
        from src.messages import messages

        if not arg:
            num = None
        else:
            try:
                num = int(arg)
            except TypeError:
                num = len(arg)
        for rule in messages.raw("_metadata", "plural"):
            if rule["number"] is None or rule["number"] == num:
                return value[rule["index"]]

        raise ValueError(
            "No plural rules matched the number {0!r} in language metadata!".
            format(num))
Beispiel #7
0
    def _join(self, value, arg, join_chars=None, sort=False):
        from src.messages import messages

        spec = None
        conv = None
        if arg:
            if arg[0] == "!":
                parts = arg[1:].split(":", maxsplit=1)
                conv = parts[0]
                if len(parts) > 1:
                    spec = parts[1]
            elif arg[0] == ":":
                spec = arg[1:]
            else:
                spec = arg

        if not join_chars:
            join_chars = messages.raw("_metadata", "list")

        value = list(value)  # make sure we can index it

        def fmt(s):
            if conv:
                s = self.convert_field(s, conv)
            return self.format_field(s, spec)

        value = [fmt(v) for v in value]
        if sort:
            # FIXME make this transport-agnostic
            value = sorted(value,
                           key=lambda v: v.replace("\u0002", "").lower())

        if not value:
            return ""
        elif len(value) == 1:
            return value[0]
        elif len(value) == 2:
            return join_chars[0].join(value)
        else:
            return (join_chars[1].join(value[:-1]) + join_chars[2] + value[-1])
Beispiel #8
0
    def _join(self, value, arg, join_chars=None):
        from src.messages import messages

        spec = None
        if arg:
            spec = arg

        if not join_chars:
            join_chars = messages.raw("_metadata", "list")

        value = list(value)  # make sure we can index it

        if not value:
            return ""
        elif len(value) == 1:
            return self.format_field(value[0], spec)
        elif len(value) == 2:
            return join_chars[0].join(
                self.format_field(v, spec) for v in value)
        else:
            return (join_chars[1].join(
                self.format_field(v, spec) for v in value[:-1]) +
                    join_chars[2] + self.format_field(value[-1], spec))
Beispiel #9
0
    def convert_field(self, value, conversion):
        from src.messages import messages

        if conversion == "role":
            return messages.raw("_roles", value)
        if conversion == "mode":
            return messages.raw("_gamemodes", value)
        if conversion == "command":
            return messages.raw("_commands", value)[0]
        if conversion == "totem":
            return messages.raw("_totems", value)
        if conversion == "cat":
            return messages.raw("_role_categories", value)
        if conversion == "phase":
            return messages.raw("_phases", value)

        # not one of our custom things
        return super().convert_field(value, conversion)
Beispiel #10
0
        if "stasis" in warning["sanctions"]:
            sanctions.append(messages["warn_view_stasis"].format(
                warning["sanctions"]["stasis"]))
        if "deny" in warning["sanctions"]:
            sanctions.append(messages["warn_view_deny"].format(
                warning["sanctions"]["deny"]))
        if "tempban" in warning["sanctions"]:
            sanctions.append(messages["warn_view_tempban"].format(
                warning["sanctions"]["tempban"]))
    if sanctions:
        wrapper.pm(messages["warn_view_sanctions"].format(sanctions))


warn_parser = LineParser(prog="warn")
warn_subparsers = warn_parser.add_subparsers()
_waccount = messages.raw("_commands", "warn opt account")  # type: List[str]
_wall = messages.raw("_commands", "warn opt all")  # type: List[str]
_wban = messages.raw("_commands", "warn opt ban")  # type: List[str]
_wdeny = messages.raw("_commands", "warn opt deny")  # type: List[str]
_wexpires = messages.raw("_commands", "warn opt expires")  # type: List[str]
_whelp = messages.raw("_commands", "warn opt help")  # type: List[str]
_wnotes = messages.raw("_commands", "warn opt notes")  # type: List[str]
_wreason = messages.raw("_commands", "warn opt reason")  # type: List[str]
_wstasis = messages.raw("_commands", "warn opt stasis")  # type: List[str]

_wl = messages.raw("_commands", "warn list")  # type: List[str]
_warn_list = warn_subparsers.add_parser(_wl[0], aliases=_wl[1:])
_warn_list.add_argument(*_wall, dest="all", action="store_true")
_warn_list.add_argument(*_whelp, dest="help", action="help")
_warn_list.add_argument("page", type=int, nargs="?", default=1)
_warn_list.set_defaults(func=warn_list)