def set(self, key: str, item: typing.Any, convert=True) -> None: if not convert: return self.__setitem__(key, item) if key in self.colors: try: hex_ = str(item) if hex_.startswith("#"): hex_ = hex_[1:] if len(hex_) == 3: hex_ = "".join(s for s in hex_ for _ in range(2)) if len(hex_) != 6: raise InvalidConfigError( "Nombre de color o HEX inválido.") try: int(hex_, 16) except ValueError: raise InvalidConfigError( "Nombre de color o HEX inválido.") except InvalidConfigError: name = str(item).lower() name = re.sub(r"[\-+|. ]+", " ", name) hex_ = ALL_COLORS.get(name) if hex_ is None: name = re.sub(r"[\-+|. ]+", "", name) hex_ = ALL_COLORS.get(name) if hex_ is None: raise return self.__setitem__(key, "#" + hex_) if key in self.time_deltas: try: isodate.parse_duration(item) except isodate.ISO8601Error: try: converter = UserFriendlyTimeSync() time = converter.convert(None, item) if time.arg: raise ValueError except BadArgument as exc: raise InvalidConfigError(*exc.args) except Exception as e: logger.debug(e) raise InvalidConfigError( "Tiempo no reconocido, por favor use el formato de duración ISO-8601 " 'o un tiempo de "lectura humana" más simple.') item = isodate.duration_isoformat(time.dt - converter.now) return self.__setitem__(key, item) if key in self.booleans: try: return self.__setitem__(key, strtobool(item)) except ValueError: raise InvalidConfigError("Debe ser un valor de SÃ/No.") # elif key in self.special_types: # if key == "status": return self.__setitem__(key, item)
def set(self, key: str, item: typing.Any, convert=True) -> None: if not convert: return self.__setitem__(key, item) if key in self.colors: try: hex_ = str(item) if hex_.startswith("#"): hex_ = hex_[1:] if len(hex_) == 3: hex_ = "".join(s for s in hex_ for _ in range(2)) if len(hex_) != 6: raise InvalidConfigError("Invalid color name or hex.") try: int(hex_, 16) except ValueError: raise InvalidConfigError("Invalid color name or hex.") except InvalidConfigError: name = str(item).lower() name = re.sub(r"[\-+|. ]+", " ", name) hex_ = ALL_COLORS.get(name) if hex_ is None: name = re.sub(r"[\-+|. ]+", "", name) hex_ = ALL_COLORS.get(name) if hex_ is None: raise return self.__setitem__(key, "#" + hex_) if key in self.time_deltas: try: isodate.parse_duration(item) except isodate.ISO8601Error: try: converter = UserFriendlyTime() time = self.bot.loop.run_until_complete( converter.convert(None, item) ) if time.arg: raise ValueError except BadArgument as exc: raise InvalidConfigError(*exc.args) except Exception: raise InvalidConfigError( "Unrecognized time, please use ISO-8601 duration format " 'string or a simpler "human readable" time.' ) item = isodate.duration_isoformat(time.dt - converter.now) return self.__setitem__(key, item) if key in self.booleans: try: return self.__setitem__(key, strtobool(item)) except ValueError: raise InvalidConfigError("Must be a yes/no value.") # elif key in self.special_types: # if key == "status": return self.__setitem__(key, item)
def clean_data(self, key, val): value_text = val clean_value = val # when setting a color if key in self.colors: hex_ = ALL_COLORS.get(val) if hex_ is None: if not isinstance(val, str): raise InvalidConfigError('Invalid color name or hex.') if val.startswith('#'): val = val[1:] if len(val) != 6: raise InvalidConfigError('Invalid color name or hex.') for v in val: if v not in { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }: raise InvalidConfigError('Invalid color name or hex.') clean_value = '#' + val value_text = clean_value else: clean_value = hex_ value_text = f'{val} ({clean_value})' return clean_value, value_text
async def rgb(self, ctx, *, rgb_value): """ Find the closest color name corresponding to the RGB value, if any. """ rgb_value_match = re.match(r'^(\d{,3})\D+(\d{,3})\D+(\d{,3})$', rgb_value) if not rgb_value_match: return await ctx.send( f'"{escape_mentions(rgb_value)}" is not a valid RGB value.') r, g, b = map(int, rgb_value_match.groups()) if not 0 <= r <= 255 or not 0 <= g <= 255 or not 0 <= b <= 255: return await ctx.send(f'`{rgb_value}` is not a valid RGB value.') hex_code = '{0:02x}{1:02x}{2:02x}'.format(r, g, b) if self.bot.version >= parse_version('3.3.0-dev0'): possibilities = { v: k for k, v in ALL_COLORS.items() if v[::2] == hex_code[::2] } else: possibilities = { v: k for k, v in ALL_COLORS.items() if v[1::2] == hex_code[::2] } closest_hex = difflib.get_close_matches(hex_code, possibilities, n=1) if not closest_hex: return await ctx.send( f'RGB values `{r}, {g}, {b}` does not have an known color name.' ) closest_hex = closest_hex[0] clean_name = re.match(r'^(?:[^:]+:)?([^:]+)$', possibilities[closest_hex]).group(1) embed = Embed( title=f'RGB {r}, {g}, {b}', description=f'Closest color name: "{clean_name.title()}".') if self.bot.version >= parse_version('3.3.0-dev0'): embed.set_thumbnail( url=f'https://placehold.it/100/{closest_hex}?text=+') else: embed.set_thumbnail( url=f'https://placehold.it/100/{closest_hex[1:]}?text=+') return await ctx.send(embed=embed)
async def rgb(self, ctx, *, rgb_value): """ Trova il tuo nome di colore più vicino corrispondente al valore RGB, se c'è uno. """ rgb_value_match = re.match(r'^(\d{,3})\D+(\d{,3})\D+(\d{,3})$', rgb_value) if not rgb_value_match: return await ctx.send( f'"{escape_mentions(rgb_value)}" non è un valore RGB valido.') r, g, b = map(int, rgb_value_match.groups()) if not 0 <= r <= 255 or not 0 <= g <= 255 or not 0 <= b <= 255: return await ctx.send(f'`{rgb_value}` non è un valore RGB valido.') hex_code = '{0:02x}{1:02x}{2:02x}'.format(r, g, b) if self.bot.version >= parse_version('3.3.0-dev0'): possibilities = { v: k for k, v in ALL_COLORS.items() if v[::2] == hex_code[::2] } else: possibilities = { v: k for k, v in ALL_COLORS.items() if v[1::2] == hex_code[::2] } closest_hex = difflib.get_close_matches(hex_code, possibilities, n=1) if not closest_hex: return await ctx.send( f'I valori RGB `{r}, {g}, {b}` non hanno un nome di colore conosciuto.' ) closest_hex = closest_hex[0] clean_name = re.match(r'^(?:[^:]+:)?([^:]+)$', possibilities[closest_hex]).group(1) embed = Embed( title=f'RGB {r}, {g}, {b}', description=f'Nome di colore più vicino: "{clean_name.title()}".') if self.bot.version >= parse_version('3.3.0-dev0'): embed.set_thumbnail( url=f'https://placehold.it/100/{closest_hex}?text=+') else: embed.set_thumbnail( url=f'https://placehold.it/100/{closest_hex[1:]}?text=+') return await ctx.send(embed=embed)
async def hex(self, ctx, *, hex_code: str.lower): """ Trova il tuo nome di colore più vicino corrispondente al codice hex. """ hex_code_match = re.match(r'^#?([a-f0-9]{6}|[a-f0-9]{3})$', hex_code) if hex_code_match is None: return await ctx.send( f'"{escape_mentions(hex_code)}" non è un codice hex valido.') hex_code = hex_code_match.group(1) if len(hex_code) == 3: hex_code = ''.join(s for s in hex_code for _ in range(2)) if self.bot.version >= parse_version('3.3.0-dev0'): possibilities = { v: k for k, v in ALL_COLORS.items() if v[::2] == hex_code[::2] } else: possibilities = { v: k for k, v in ALL_COLORS.items() if v[1::2] == hex_code[::2] } closest_hex = difflib.get_close_matches(hex_code, possibilities, n=1) if not closest_hex: return await ctx.send( f'Il codice hex `#{hex_code}` non ha un nome di colore conosciuto.' ) closest_hex = closest_hex[0] clean_name = re.match(r'^(?:[^:]+:)?([^:]+)$', possibilities[closest_hex]).group(1) embed = Embed( title=f'#{hex_code}', description=f'Nome di colore più vicino: "{clean_name.title()}".') if self.bot.version >= parse_version('3.3.0-dev0'): embed.set_thumbnail( url=f'https://placehold.it/100/{closest_hex}?text=+') else: embed.set_thumbnail( url=f'https://placehold.it/100/{closest_hex[1:]}?text=+') return await ctx.send(embed=embed)
async def clean_data(self, key: str, val: typing.Any) -> typing.Tuple[str, str]: value_text = val clean_value = val # when setting a color if key in self.colors: hex_ = ALL_COLORS.get(val) if hex_ is None: hex_ = str(hex_) if hex_.startswith("#"): hex_ = hex_[1:] if len(hex_) == 3: hex_ = "".join(s for s in hex_ for _ in range(2)) if len(hex_) != 6: raise InvalidConfigError("Invalid color name or hex.") try: int(val, 16) except ValueError: raise InvalidConfigError("Invalid color name or hex.") clean_value = "#" + val value_text = clean_value else: clean_value = hex_ value_text = f"{val} ({clean_value})" elif key in self.time_deltas: try: isodate.parse_duration(val) except isodate.ISO8601Error: try: converter = UserFriendlyTime() time = await converter.convert(None, val) if time.arg: raise ValueError except BadArgument as exc: raise InvalidConfigError(*exc.args) except Exception: raise InvalidConfigError( "Unrecognized time, please use ISO-8601 duration format " 'string or a simpler "human readable" time.') clean_value = isodate.duration_isoformat(time.dt - converter.now) value_text = f"{val} ({clean_value})" elif key in self.booleans: try: clean_value = value_text = strtobool(val) except ValueError: raise InvalidConfigError("Must be a yes/no value.") return clean_value, value_text
async def hex(self, ctx, *, hex_code: str.lower): """ Find the closest color name corresponding to the hex code, if any. """ hex_code_match = re.match(r'^#?([a-f0-9]{6}|[a-f0-9]{3})$', hex_code) if hex_code_match is None: return await ctx.send( f'"{escape_mentions(hex_code)}" is not a valid hex code.') hex_code = hex_code_match.group(1) if len(hex_code) == 3: hex_code = ''.join(s for s in hex_code for _ in range(2)) if self.bot.version >= parse_version('3.3.0-dev0'): possibilities = { v: k for k, v in ALL_COLORS.items() if v[::2] == hex_code[::2] } else: possibilities = { v: k for k, v in ALL_COLORS.items() if v[1::2] == hex_code[::2] } closest_hex = difflib.get_close_matches(hex_code, possibilities, n=1) if not closest_hex: return await ctx.send( f'Hex code `#{hex_code}` does not have an known color name.') closest_hex = closest_hex[0] clean_name = re.match(r'^(?:[^:]+:)?([^:]+)$', possibilities[closest_hex]).group(1) embed = Embed( title=f'#{hex_code}', description=f'Closest color name: "{clean_name.title()}".') if self.bot.version >= parse_version('3.3.0-dev0'): embed.set_thumbnail( url=f'https://placehold.it/100/{closest_hex}?text=+') else: embed.set_thumbnail( url=f'https://placehold.it/100/{closest_hex[1:]}?text=+') return await ctx.send(embed=embed)
async def clean_data(self, key: str, val: typing.Any) -> typing.Tuple[str, str]: value_text = val clean_value = val # when setting a color if key in self.colors: hex_ = ALL_COLORS.get(val) if hex_ is None: if not isinstance(val, str): raise InvalidConfigError('Invalid color name or hex.') if val.startswith('#'): val = val[1:] if len(val) != 6: raise InvalidConfigError('Invalid color name or hex.') for letter in val: if letter not in { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }: raise InvalidConfigError('Invalid color name or hex.') clean_value = '#' + val value_text = clean_value else: clean_value = hex_ value_text = f'{val} ({clean_value})' elif key in self.time_deltas: try: isodate.parse_duration(val) except isodate.ISO8601Error: try: converter = UserFriendlyTime() time = await converter.convert(None, val) if time.arg: raise ValueError except BadArgument as exc: raise InvalidConfigError(*exc.args) except Exception: raise InvalidConfigError( 'Unrecognized time, please use ISO-8601 duration format ' 'string or a simpler "human readable" time.') clean_value = isodate.duration_isoformat(time.dt - converter.now) value_text = f'{val} ({clean_value})' return clean_value, value_text
async def color(self, ctx, *, name: str.lower): """ Convert a known color name to RGB and hex representations. """ hex_code = ALL_COLORS.get(name) if hex_code is None: return await ctx.send( f'Color "{escape_mentions(name)}" is not a known color name.') if self.bot.version < parse_version('3.3.0-dev0'): hex_code = hex_code[1:] r, g, b = tuple(int(hex_code[i:i + 2], 16) for i in (0, 2, 4)) embed = Embed(title=name.title(), description=f'Hex: `#{hex_code}`, RGB: `{r}, {g}, {b}`.') embed.set_thumbnail(url=f'https://placehold.it/100/{hex_code}?text=+') return await ctx.send(embed=embed)
async def clean_data(self, key: str, val: typing.Any) -> typing.Tuple[str, str]: value_text = val clean_value = val # when setting a color if key in self.colors: hex_ = ALL_COLORS.get(val) if hex_ is None: if not isinstance(val, str): raise InvalidConfigError("Invalid color name or hex.") if val.startswith("#"): val = val[1:] if len(val) != 6: raise InvalidConfigError("Invalid color name or hex.") for letter in val: if letter not in { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", }: raise InvalidConfigError("Invalid color name or hex.") clean_value = "#" + val value_text = clean_value else: clean_value = hex_ value_text = f"{val} ({clean_value})" elif key in self.time_deltas: try: isodate.parse_duration(val) except isodate.ISO8601Error: try: converter = UserFriendlyTime() time = await converter.convert(None, val) if time.arg: raise ValueError except BadArgument as exc: raise InvalidConfigError(*exc.args) except Exception: raise InvalidConfigError( "Unrecognized time, please use ISO-8601 duration format " 'string or a simpler "human readable" time.') clean_value = isodate.duration_isoformat(time.dt - converter.now) value_text = f"{val} ({clean_value})" return clean_value, value_text