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 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 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 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 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
def remove(self, key: str) -> typing.Any: key = key.lower() logger.info("Removing %s.", key) if key not in self.all_keys: raise InvalidConfigError(f'Configuration "{key}" is invalid.') self._cache[key] = deepcopy(self.defaults[key]) return self._cache[key]
def __getitem__(self, key: str) -> typing.Any: key = key.lower() if key not in self.all_keys: raise InvalidConfigError(f'Configuration "{key}" is invalid.') if key not in self._cache: self._cache[key] = deepcopy(self.defaults[key]) return self._cache[key]
def __setitem__(self, key: str, item: typing.Any) -> None: key = key.lower() logger.info("Setting %s.", key) if key not in self.all_keys: raise InvalidConfigError( f'Clave de configuración "{key}" es inválida.') self._cache[key] = item
def remove(self, key: str) -> typing.Any: key = key.lower() logger.info("Removing %s.", key) if key not in self.all_keys: raise InvalidConfigError(f'La configurazione "{key}" non è valida.') if key in self._cache: del self._cache[key] self._cache[key] = deepcopy(self.defaults[key]) return self._cache[key]
def get(self, key: str, default: typing.Any = Default) -> typing.Any: key = key.lower() if key not in self.all_keys: raise InvalidConfigError(f'Configuration "{key}" is invalid.') if key not in self._cache: if default is Default: self._cache[key] = deepcopy(self.defaults[key]) if default is not Default and self._cache[key] == self.defaults[key]: self._cache[key] = default return self._cache[key]
def remove(self, key: str) -> typing.Any: key = key.lower() logger.info("Removiendo %s.", key) if key not in self.all_keys: raise InvalidConfigError( f'Clave de configuración "{key}" es inválida.') if key in self._cache: del self._cache[key] self._cache[key] = deepcopy(self.defaults[key]) return self._cache[key]
async def login(cls, bot) -> "GitHub": """ Logs in to GitHub with configuration variable information. Parameters ---------- bot : Bot The Modmail bot. Returns ------- GitHub The newly created `GitHub` object. """ self = cls(bot, bot.config.get("github_token")) resp: dict = await self.request("https://api.github.com/user") if resp.get("login"): self.username = resp["login"] self.avatar_url = resp["avatar_url"] self.url = resp["html_url"] logger.info(f"GitHub logged in to: {self.username}") return self else: raise InvalidConfigError("Invalid github token")
def set(self, key: str, item: typing.Any) -> None: key = key.lower() logger.info("Setting %s.", key) if key not in self.all_keys: raise InvalidConfigError(f'Configuration "{key}" is invalid.') self._cache[key] = item
def get(self, key: str, convert=True) -> typing.Any: key = key.lower() if key not in self.all_keys: raise InvalidConfigError(f'Configuration "{key}" is invalid.') if key not in self._cache: self._cache[key] = deepcopy(self.defaults[key]) value = self._cache[key] if not convert: return value if key in self.colors: try: return int(value.lstrip("#"), base=16) except ValueError: logger.error("Invalid %s provided.", key) value = int(self.remove(key).lstrip("#"), base=16) elif key in self.time_deltas: if not isinstance(value, isodate.Duration): try: value = isodate.parse_duration(value) except isodate.ISO8601Error: logger.warning( "The {account} age limit needs to be a " 'ISO-8601 duration formatted duration, not "%s".', value, ) value = self.remove(key) elif key in self.booleans: try: value = strtobool(value) except ValueError: value = self.remove(key) elif key in self.enums: if value is None: return None try: value = self.enums[key](value) except ValueError: logger.warning("Invalid %s %s.", key, value) value = self.remove(key) elif key in self.force_str: # Temporary: as we saved in int previously, leading to int32 overflow, # this is transitioning IDs to strings new_value = {} changed = False for k, v in value.items(): new_v = v if isinstance(v, list): new_v = [] for n in v: if n != -1 and not isinstance(n, str): changed = True n = str(n) new_v.append(n) new_value[k] = new_v if changed: # transition the database as well self.set(key, new_value) value = new_value return value
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
def __setitem__(self, key: str, item: typing.Any) -> None: key = key.lower() logger.info("Setting %s.", key) if key not in self.all_keys: raise InvalidConfigError(f'La configurazione "{key}" non è valida.') self._cache[key] = item