"""Small administrative command-line tools for framework operators.""" import argparse import uuid import psycopg2 from core import identity def _discordID(value): value = value.strip() if not value or not value.isdigit(): raise argparse.ArgumentTypeError("Discord ID must contain only digits") return value def _userUUID(value): try: return str(uuid.UUID(value)) except (AttributeError, TypeError, ValueError) as error: raise argparse.ArgumentTypeError("user UUID must be a valid UUID") from error def _username(value): value = value.strip() if not value: raise argparse.ArgumentTypeError("username cannot be empty") return value def _linkDiscord(args): try: linked = identity.linkDiscordUser( args.discord_id, userUUID=args.user_uuid, username=args.username, ) except ValueError as error: args.command_parser.error(str(error)) except psycopg2.Error: args.command_parser.exit( 1, "link-discord failed: database operation failed\n", ) print( "linked Discord user " f"{linked['provider_user_id']} to user {linked['user_uuid']}" ) return 0 def buildParser(): parser = argparse.ArgumentParser(description="Manage framework data") commands = parser.add_subparsers(dest="command", required=True) linkParser = commands.add_parser( "link-discord", help="link an existing user to a Discord account", ) linkParser.add_argument("--discord-id", required=True, type=_discordID) userSelector = linkParser.add_mutually_exclusive_group(required=True) userSelector.add_argument("--user-uuid", type=_userUUID) userSelector.add_argument("--username", type=_username) linkParser.set_defaults(handler=_linkDiscord, command_parser=linkParser) return parser def main(argv=None): args = buildParser().parse_args(argv) return args.handler(args) if __name__ == "__main__": raise SystemExit(main())