def _color(self, clr: str): if len(clr) == 3: clr = f"{clr[0]}{clr[0]}{clr[1]}{clr[1]}{clr[2]}{clr[2]}" if len(clr) == 6: try: c = tuple(int(clr[i:i + 2], 16) for i in range(0, len(clr), 2)) return c except: raise commands.ConversionError("Oops! There's an invalid color ): Colors must be formatted " "`rgb` or `rrggbb`", original=None) raise commands.ConversionError("Oops! There's an invalid color ): Colors must be formatted " "`rgb` or `rrggbb`", original=None)
def MessageID(argument): try: return int(argument, base=10) except ValueError: raise commands.ConversionError( f'"{argument}" is not a valid message ID. Use Developer Mode to get the Copy ID option.' )
async def convert(self, ctx, argstr): converted = {} for raw_arg in shlex.split(argstr or ""): if "=" not in raw_arg: continue name, *values = raw_arg.split("=") value = "=".join(values) argument = self.arguments.get(name.lower()) if not argument: raise UnknownArgumentError(name) try: converted_value = await self._convert_value( ctx, argument.converter, value) converted[name] = converted_value except commands.ConversionError as e: e = getattr(e, "original", e) raise InvalidArgumentValueError(name, value, e) from e except Exception as e: raise commands.ConversionError(self, e) from e for name, argument in self.arguments.items(): if isinstance(argument, RequiredArgument) and name not in converted: param = inspect.Parameter(name, inspect.Parameter.KEYWORD_ONLY) raise commands.MissingRequiredArgument(param) if argument.default is not None and name not in converted: converted[name] = argument.default return converted
def _convert_to_bool(self, value): """ Converts a string value to bool. Raises :class:`discord.ext.commands.ConversionError` if the conversion fails. """ lowered = value.lower() if lowered in ("ja", "yes", "y", "true", "t", "1", "enable", "on"): return True elif lowered in ("nein", "no", "false", "f", "0", "disable", "off"): return False raise commands.ConversionError(value, None)
async def _convert_value(self, ctx, converter, value): """ Converts the given value with the supplied converter. Raises a :class:`discord.commands.ConversionError` if the conversion fails. """ # This essentially is a rip-off of the _actual_conversion() method in # discord.py's ext/commands/core.py file if converter is bool: return self._convert_to_bool(value) try: module = converter.__module__ except ValueError: ... else: if module is not None: if module.startswith( "discord.") and not module.endswith("converter"): converter = getattr(converters, converter.__name__ + "Converter") try: if inspect.isclass(converter): if issubclass(converter, commands.Converter): instance = converter() ret = await instance.convert(ctx, value) return ret method = getattr(converter, "convert", None) if method is not None and inspect.ismethod(method): ret = await method(ctx, value) elif isinstance(converter, commands.Converter): ret = await converter.convert(ctx, value) return ret except Exception as e: raise commands.ConversionError(converter, e) from e try: return converter(value) except Exception as e: raise commands.ConversionError(converter, e) from e
async def _resolve_default(self, ctx, param): try: if inspect.isclass(param.default) and issubclass( param.default, ParamDefault): instance = param.default() return await instance.default(ctx) elif isinstance(param.default, ParamDefault): return await param.default.default(ctx) except commands.CommandError: raise except Exception as e: raise commands.ConversionError(param.default, e) from e return None if param.default is param.empty else param.default
async def convert_flag_type(self, flag: Flag, ctx: commands.Context, argument: Optional[str], passed_flag: str): converter = flag.converter if argument is None or argument.strip() == "": if flag.default is None: raise MissingRequiredFlagArgument(passed_flag) else: argument = flag.default argument = argument.strip() if converter is bool: return _convert_to_bool(argument) try: module = converter.__module__ except AttributeError: pass else: if module is not None and (module.startswith('discord.') and not module.endswith('converter')): converter = CONVERTER_MAPPING.get(converter, converter) try: if inspect.isclass(converter) and issubclass(converter, Converter): if inspect.ismethod(converter.convert): return await converter.convert(ctx, argument) else: return await converter().convert(ctx, argument) elif isinstance(converter, Converter): return await converter.convert(ctx, argument) except commands.CommandError: raise except Exception as exc: raise commands.ConversionError(converter, exc) from exc try: return converter(argument) except commands.CommandError: raise except Exception as exc: try: name = converter.__name__ except AttributeError: name = converter.__class__.__name__ raise commands.BadArgument( f'Converting to "{name}" failed for flag "{passed_flag}".' ) from exc
def _convert_poll_args(cls, ctx: Context, args: List[Tuple[str, Optional[str]]]): valid_args = {('anon', 'a', 'anonymous'): cls._convert_bool_arg} found_args = {} args = dict(args) for keys, converter in valid_args.items(): for option in keys: if option in args: if isinstance(converter, commands.Converter): found_args[keys[0]] = converter.convert( ctx, args[option]) elif callable(converter): found_args[keys[0]] = converter(args[option]) else: raise commands.ConversionError(None, None) break return found_args
async def _actual_conversion(self, ctx, converter, argument, param): if converter is bool: return _convert_to_bool(argument) try: module = converter.__module__ except AttributeError: pass else: if not isinstance(converter, FlagParser) and \ module is not None and (module.startswith('discord.') and not module.endswith('converter')): converter = getattr(commands, converter.__name__ + 'Converter') try: if inspect.isclass(converter): if issubclass(converter, commands.Converter): instance = converter() ret = await instance.convert(ctx, argument) return ret else: method = getattr(converter, 'convert', None) if method is not None and inspect.ismethod(method): ret = await method(ctx, argument) return ret elif isinstance(converter, commands.Converter): ret = await converter.convert(ctx, argument) return ret except commands.CommandError: raise except Exception as exc: raise commands.ConversionError(converter, exc) from exc try: return converter(argument) except commands.CommandError: raise except Exception as exc: try: name = converter.__name__ except AttributeError: name = converter.__class__.__name__ raise commands.BadArgument( 'Converting to "{}" failed for parameter "{}".'.format( name, param.name)) from exc
async def _process_commands(self, command: str, path: str): # noqa c901 ar = [x.split(" ") for x in [a.strip(" ") for a in command.split(',')]] im: Image = PIL.Image.open(path) # im.load() im = im.convert("RGBA") print(ar) fmt = "png" for e in ar: for i in range(3): e.append(None) if e[0] == "convert": mode = e[1] if not mode or mode not in "bw,rgb,rgba,luma,web,adaptive": raise commands.ConversionError("Unknown conversion mode", original=None) if mode == "bw": im = im.convert("1") if mode in ["rgb", "rgba"]: im = im.convert(mode.upper()) if mode == "luma": im = im.convert("L") if mode == "web": im = im.convert("P") if mode == "adaptive": im = im.convert( "P", palette=ADAPTIVE, colors=min(int(e[2]), 256) if e[2] else 256) if e[0] == "format": if not e[1] or e[1] not in "png,jpg,gif".split(","): raise commands.ConversionError( f"Invalid output format {e[1]}", original=None) fmt = e[1] if e[0] == "bw": im = im.convert("1").convert("RGBA") if e[0] == "luma": im = im.convert("L").convert("RGBA") if e[0] == "autocontrast": im = im.convert("RGB") im = ImageOps.autocontrast(im, int(e[1]) if e[1] else 0) im = im.convert("RGBA") if e[0] == "rotate": im = im.rotate(int(e[1])) if e[0] == "invert": im = ImageOps.invert(im) if e[0] == "grayscale": im = ImageOps.grayscale(im) if e[0] == "equalize": im = ImageOps.equalize(im) if e[0] == "sepia": im = ImageOps.colorize(ImageOps.grayscale(im), (0, 0, 0), (255, 255, 255), mid=(112, 66, 20)) if e[0] == "colorize": im = ImageOps.colorize(ImageOps.grayscale(im), (0, 0, 0), (255, 255, 255), mid=self._color(e[1])) if e[0] == "posterize": im = ImageOps.posterize(im, int(e[1]) if e[1] else 128) if e[0] == "solarize": im = im.convert("RGB") if len(e) > 1: a = int(e[1]) else: a = 128 im = ImageOps.solarize(im, a) im = im.convert("RGBA") if e[0] == "flip": im = ImageOps.flip(im) if e[0] == "mirror": im = ImageOps.mirror(im) if e[0] == "blur": if len(e) > 1: a = int(e[1]) else: a = 2 im = im.filter(ImageFilter.GaussianBlur(a)) if e[0] == "boxblur": if len(e) > 1: a = int(e[1]) else: a = 2 im = im.filter(ImageFilter.BoxBlur(a)) if e[0] == "sharpen": im = im.filter( ImageFilter.UnsharpMask( int(e[1]) if e[1] else 2, int(e[2]) if e[2] else 150, int(e[3]) if e[3] else 3)) if e[0] == "scale": im = ImageOps.scale(im, float(e[1])) if e[0] == "pscale": im = ImageOps.scale(im, float(e[1]), PIL.Image.NEAREST) if e[0] == "scalexy": im = im.resize((int(im.width * float(e[1])), int(im.height * float(e[2])))) if e[0] == "pscalexy": im = im.resize((int( im.width * float(e[1])), int(im.height * float(e[2]))), PIL.Image.NEAREST) if e[0] == "scaleto": im = im.resize((int(e[1]), int(e[2])), PIL.Image.BICUBIC) if e[0] == "pscaleto": im = im.resize((int(e[1]), int(e[2])), PIL.Image.NEAREST) if e[0] == "potografy": im = im.resize((int(im.width / 20), int(im.height / 4)), PIL.Image.NEAREST) im = im.resize((int(im.width * 20), int(im.height * 4)), PIL.Image.NEAREST) im = ImageOps.posterize(im, 2) im = ImageOps.colorize(ImageOps.grayscale(im), (0, 0, 0), (255, 255, 255), mid=(112, 66, 20)) im = im.rotate(25) if e[0] == "matrix": size = (im.width, im.height) im = im.resize((int(e[1]), int(e[2])), PIL.Image.NEAREST) im = im.resize(size, PIL.Image.NEAREST) a = path.split(".") async with self.lock: self.counter += 1 b = str(self.counter) + "." + fmt # + a[-1] im.save(b) return True, b, os.path.getsize(b)
async def test__on_command_error(self): """Unit tests for bot._on_command_error function.""" # async def _on_command_error(bot, ctx, exc) _on_command_error = bot._on_command_error # mauvais serveur ctx = mock.NonCallableMock(commands.Context, guild=10) await _on_command_error(config.bot, ctx, None) ctx.send.assert_not_called() # STOP ctx = mock_discord.get_ctx() exc = commands.CommandInvokeError(blocs.tools.CommandExit()) await _on_command_error(config.bot, ctx, exc) ctx.assert_sent("Mission aborted") # STOP custom message ctx = mock_discord.get_ctx() exc = commands.CommandInvokeError(blocs.tools.CommandExit("cust0m")) await _on_command_error(config.bot, ctx, exc) ctx.assert_sent("cust0m") # BDD error - MJ ctx = mock_discord.get_ctx() ctx.author.top_role = mock.MagicMock(discord.Role, __ge__=lambda s, o: True) # >= MJ exc = commands.CommandInvokeError(bdd.SQLAlchemyError("bzzt")) try: raise exc.original # creating traceback except bdd.SQLAlchemyError: pass await _on_command_error(config.bot, ctx, exc) mock_discord.assert_sent(config.Channel.logs, "Rollback session") config.Channel.logs.send.reset_mock() config.session.rollback.assert_called_once() config.session.rollback.reset_mock() ctx.assert_sent(["Un problème est survenu", "Traceback", "SQLAlchemyError", "bzzt"]) # BDD error - not MJ ctx = mock_discord.get_ctx() ctx.author.top_role = mock.MagicMock(discord.Role, __ge__=lambda s, o: False) # < MJ exc = commands.CommandInvokeError(bdd.DriverOperationalError("bzoozt")) try: raise exc.original # creating traceback except bdd.DriverOperationalError: pass await _on_command_error(config.bot, ctx, exc) mock_discord.assert_sent(config.Channel.logs, "Rollback session") config.Channel.logs.send.reset_mock() config.session.rollback.assert_called_once() config.session.rollback.reset_mock() ctx.assert_sent(["Un problème est survenu", bdd.DriverOperationalError.__name__, "bzoozt"]) ctx.assert_not_sent("Traceback") # BDD error - session not ready : on vérifie juste que pas d'erreur ctx = mock_discord.get_ctx() _session = config.session del config.session ctx.author.top_role = mock.MagicMock(discord.Role, __ge__=lambda s, o: True) # >= MJ exc = commands.CommandInvokeError(bdd.SQLAlchemyError("bzzt")) await _on_command_error(config.bot, ctx, exc) mock_discord.assert_sent(config.Channel.logs) # nothing config.Channel.logs.send.reset_mock() ctx.assert_sent(["Un problème est survenu", "SQLAlchemyError", "bzzt"]) config.session = _session # CommandNotFound ctx = mock_discord.get_ctx() await _on_command_error(config.bot, ctx, commands.CommandNotFound()) ctx.assert_sent("je ne connais pas cette commande") # DisabledCommand ctx = mock_discord.get_ctx() await _on_command_error(config.bot, ctx, commands.DisabledCommand()) ctx.assert_sent("Cette commande est désactivée") # ConversionError command = mock.Mock() ctx = mock_discord.get_ctx(command) exc = commands.ConversionError("bkrkr", "kak") await _on_command_error(config.bot, ctx, exc) ctx.assert_sent(["ce n'est pas comme ça qu'on utilise cette commande", "ConversionError", "bkrkr", "kak"]) config.bot.get_context.assert_called_with(ctx.message) self.assertEqual(ctx.message.content, f"!help {command.name}") config.bot.get_context.return_value.reinvoke.assert_called() # UserInputError command = mock.Mock() ctx = mock_discord.get_ctx(command) exc = commands.UserInputError("bakaka") await _on_command_error(config.bot, ctx, exc) ctx.assert_sent(["ce n'est pas comme ça qu'on utilise cette commande", "UserInputError", "bakaka"]) config.bot.get_context.assert_called_with(ctx.message) self.assertEqual(ctx.message.content, f"!help {command.name}") config.bot.get_context.return_value.reinvoke.assert_called() # UserInputError derivate command = mock.Mock() ctx = mock_discord.get_ctx(command) exc = commands.BadArgument("bakaka") await _on_command_error(config.bot, ctx, exc) ctx.assert_sent(["ce n'est pas comme ça qu'on utilise cette commande", "BadArgument", "bakaka"]) config.bot.get_context.assert_called_with(ctx.message) self.assertEqual(ctx.message.content, f"!help {command.name}") config.bot.get_context.return_value.reinvoke.assert_called() # CheckAnyFailure ctx = mock_discord.get_ctx() exc = commands.CheckAnyFailure(mock.ANY, mock.ANY) await _on_command_error(config.bot, ctx, exc) ctx.assert_sent("cette commande est réservée aux MJs") # MissingAnyRole ctx = mock_discord.get_ctx() exc = commands.MissingAnyRole([mock.ANY]) await _on_command_error(config.bot, ctx, exc) ctx.assert_sent("Cette commande est réservée aux joueurs") # MissingRole ctx = mock_discord.get_ctx() exc = commands.MissingRole(mock.ANY) await _on_command_error(config.bot, ctx, exc) ctx.assert_sent("cette commande est réservée aux joueurs en vie") # one_command.AlreadyInCommand, not addIA/modifIA command = mock.Mock() command.configure_mock(name="blabla") ctx = mock_discord.get_ctx(command) exc = blocs.one_command.AlreadyInCommand() await _on_command_error(config.bot, ctx, exc) ctx.assert_sent("Impossible d'utiliser une commande pendant") # one_command.AlreadyInCommand, addIA command = mock.Mock() command.configure_mock(name="addIA") ctx = mock_discord.get_ctx(command) exc = blocs.one_command.AlreadyInCommand() await _on_command_error(config.bot, ctx, exc) ctx.assert_sent() # one_command.AlreadyInCommand, modifIA command = mock.Mock() command.configure_mock(name="modifIA") ctx = mock_discord.get_ctx(command) exc = blocs.one_command.AlreadyInCommand() await _on_command_error(config.bot, ctx, exc) ctx.assert_sent() # CheckFailure (autre check erreur) ctx = mock_discord.get_ctx() exc = commands.CheckFailure("jojo") with mock.patch("lgrez.blocs.tools.mention_MJ") as mmj_patch: await _on_command_error(config.bot, ctx, exc) mmj_patch.assert_called_once_with(ctx) ctx.assert_sent(["cette commande ne puisse pas être exécutée", "CheckFailure", "jojo"]) # other exception ctx = mock_discord.get_ctx() exc = AttributeError("oh") with mock.patch("lgrez.blocs.tools.mention_MJ") as mmj_patch: await _on_command_error(config.bot, ctx, exc) mmj_patch.assert_called_once_with(ctx) ctx.assert_sent(["Une erreur inattendue est survenue", "AttributeError", "oh"]) # other exception ctx = mock_discord.get_ctx() class SomeException(Exception): pass exc = SomeException("p!wet") with mock.patch("lgrez.blocs.tools.mention_MJ") as mmj_patch: await _on_command_error(config.bot, ctx, exc) mmj_patch.assert_called_once_with(ctx) ctx.assert_sent(["Une erreur inattendue est survenue", "SomeException", "p!wet"])