Brandon209-Red-bot-Cogs/rolemanagement/converters.py
2020-01-30 03:15:53 -05:00

214 lines
8.1 KiB
Python

import argparse
import shlex
from typing import Optional, List, NamedTuple, Dict
from redbot.core.commands import RoleConverter, Context, BadArgument
import discord
_RoleConverter = RoleConverter()
class NoExitParser(argparse.ArgumentParser):
def error(self, message):
raise BadArgument()
class RoleSyntaxConverter(NamedTuple):
parsed: Dict[str, List[discord.Role]]
@classmethod
async def convert(cls, ctx: Context, argument: str):
parser = NoExitParser(description="Role management syntax help", add_help=False, allow_abbrev=True)
parser.add_argument("--add", nargs="*", dest="add", default=[])
parser.add_argument("--remove", nargs="*", dest="remove", default=[])
try:
vals = vars(parser.parse_args(shlex.split(argument)))
except Exception:
raise BadArgument()
if not vals["add"] and not vals["remove"]:
raise BadArgument("Must provide at least one action")
for attr in ("add", "remove"):
vals[attr] = [await _RoleConverter.convert(ctx, r) for r in vals[attr]]
return cls(vals)
class ComplexActionConverter(NamedTuple):
"""
--has-all roles
--has-none roles
--has-any roles
--has-no-roles
--has-exactly-nroles
--has-more-than-nroles
--has-less-than-nroles
--has-perm permissions
--any-perm permissions
--not-perm permissions
--above role
--below role
--add roles
--remove roles
--only-humans
--only-bots
--everyone
"""
parsed: dict
@classmethod
async def convert(cls, ctx: Context, argument: str):
parser = NoExitParser(description="Role management syntax help", add_help=False)
parser.add_argument("--has-any", nargs="*", dest="any", default=[])
parser.add_argument("--has-all", nargs="*", dest="all", default=[])
parser.add_argument("--has-none", nargs="*", dest="none", default=[])
parser.add_argument("--has-no-roles", action="store_true", default=False, dest="noroles")
parser.add_argument("--has-perms", nargs="*", dest="hasperm", default=[])
parser.add_argument("--any-perm", nargs="*", dest="anyperm", default=[])
parser.add_argument("--not-perm", nargs="*", dest="notperm", default=[])
parser.add_argument("--add", nargs="*", dest="add", default=[])
parser.add_argument("--remove", nargs="*", dest="remove", default=[])
parser.add_argument("--has-exactly-nroles", dest="quantity", type=int)
parser.add_argument("--has-more-than-nroles", dest="gt", type=int, default=None)
parser.add_argument("--has-less-than-nroles", dest="lt", type=int, default=None)
parser.add_argument("--above", dest="above", type=str, default=None)
parser.add_argument("--below", dest="below", type=str, default=None)
hum_or_bot = parser.add_mutually_exclusive_group()
hum_or_bot.add_argument("--only-humans", action="store_true", default=False, dest="humans")
hum_or_bot.add_argument("--only-bots", action="store_true", default=False, dest="bots")
hum_or_bot.add_argument("--everyone", action="store_true", default=False, dest="everyone")
try:
vals = vars(parser.parse_args(shlex.split(argument)))
except Exception:
raise BadArgument()
if not vals["add"] and not vals["remove"]:
raise BadArgument("Must provide at least one action")
if not any(
(
vals["humans"],
vals["everyone"],
vals["bots"],
vals["any"],
vals["all"],
vals["none"],
vals["hasperm"],
vals["notperm"],
vals["anyperm"],
vals["noroles"],
bool(vals["quantity"] is not None),
bool(vals["gt"] is not None),
bool(vals["lt"] is not None),
vals["above"],
vals["below"],
)
):
raise BadArgument("You need to provide at least 1 search criterion")
for attr in ("any", "all", "none", "add", "remove"):
vals[attr] = [await _RoleConverter.convert(ctx, r) for r in vals[attr]]
for attr in ("below", "above"):
if vals[attr] is None:
continue
vals[attr] = await _RoleConverter.convert(ctx, vals[attr])
for attr in ("hasperm", "anyperm", "notperm"):
vals[attr] = [i.replace("_", " ").lower().replace(" ", "_").replace("server", "guild") for i in vals[attr]]
if any(perm not in dir(discord.Permissions) for perm in vals[attr]):
raise BadArgument("You gave an invalid permission")
return cls(vals)
class ComplexSearchConverter(NamedTuple):
"""
--has-all roles
--has-none roles
--has-any roles
--has-no-roles
--has-exactly-nroles
--has-more-than-nroles
--has-less-than-nroles
--only-humans
--only-bots
--above role
--below role
--has-perm permissions
--any-perm permissions
--not-perm permissions
--everyone
--csv
"""
parsed: dict
@classmethod
async def convert(cls, ctx: Context, argument: str):
parser = NoExitParser(description="Role management syntax help", add_help=False)
parser.add_argument("--has-any", nargs="*", dest="any", default=[])
parser.add_argument("--has-all", nargs="*", dest="all", default=[])
parser.add_argument("--has-none", nargs="*", dest="none", default=[])
parser.add_argument("--has-no-roles", action="store_true", default=False, dest="noroles")
parser.add_argument("--has-perms", nargs="*", dest="hasperm", default=[])
parser.add_argument("--any-perm", nargs="*", dest="anyperm", default=[])
parser.add_argument("--not-perm", nargs="*", dest="notperm", default=[])
parser.add_argument("--csv", action="store_true", default=False)
parser.add_argument("--has-exactly-nroles", dest="quantity", type=int, default=None)
parser.add_argument("--has-more-than-nroles", dest="gt", type=int, default=None)
parser.add_argument("--has-less-than-nroles", dest="lt", type=int, default=None)
parser.add_argument("--above", dest="above", type=str, default=None)
parser.add_argument("--below", dest="below", type=str, default=None)
hum_or_bot = parser.add_mutually_exclusive_group()
hum_or_bot.add_argument("--only-humans", action="store_true", default=False, dest="humans")
hum_or_bot.add_argument("--only-bots", action="store_true", default=False, dest="bots")
hum_or_bot.add_argument("--everyone", action="store_true", default=False, dest="everyone")
try:
vals = vars(parser.parse_args(shlex.split(argument)))
except Exception:
raise BadArgument()
if not any(
(
vals["humans"],
vals["everyone"],
vals["bots"],
vals["any"],
vals["all"],
vals["none"],
vals["hasperm"],
vals["notperm"],
vals["anyperm"],
vals["noroles"],
bool(vals["quantity"] is not None),
bool(vals["gt"] is not None),
bool(vals["lt"] is not None),
vals["above"],
vals["below"],
)
):
raise BadArgument("You need to provide at least 1 search criterion")
for attr in ("any", "all", "none"):
vals[attr] = [await _RoleConverter.convert(ctx, r) for r in vals[attr]]
for attr in ("below", "above"):
if vals[attr] is None:
continue
vals[attr] = await _RoleConverter.convert(ctx, vals[attr])
for attr in ("hasperm", "anyperm", "notperm"):
vals[attr] = [i.replace("_", " ").lower().replace(" ", "_").replace("server", "guild") for i in vals[attr]]
if any(perm not in dir(discord.Permissions) for perm in vals[attr]):
raise BadArgument("You gave an invalid permission")
return cls(vals)