diff --git a/classes.py b/classes.py index 58e3a05..9b5dde5 100644 --- a/classes.py +++ b/classes.py @@ -505,6 +505,38 @@ class PyLinkNetworkCoreWithUtils(PyLinkNetworkCore): casemapping (rfc1459 or ascii).""" return self._to_lower_core(text, casemapping=self.casemapping) + _NICK_REGEX = r'^[A-Za-z\|\\_\[\]\{\}\^\`][A-Z0-9a-z\-\|\\_\[\]\{\}\^\`]*$' + @classmethod + def is_nick(cls, s, nicklen=None): + """Returns whether the string given is a valid IRC nick.""" + + if nicklen and len(s) > nicklen: + return False + return bool(re.match(cls._NICK_REGEX, s)) + + @staticmethod + def is_channel(s): + """Returns whether the string given is a valid IRC channel name.""" + return str(s).startswith('#') + + @staticmethod + def _isASCII(s): + """Returns whether the given string only contains non-whitespace ASCII characters.""" + chars = string.ascii_letters + string.digits + string.punctuation + return all(char in chars for char in s) + + @classmethod + def is_server_name(cls, s): + """Returns whether the string given is a valid IRC server name.""" + return cls._isASCII(s) and '.' in s and not s.startswith('.') + + _HOSTMASK_RE = re.compile(r'^\S+!\S+@\S+$') + @classmethod + def is_hostmask(cls, text): + """Returns whether the given text is a valid IRC hostmask (nick!user@host).""" + # Band-aid patch here to prevent bad bans set by Janus forwarding people into invalid channels. + return bool(cls._HOSTMASK_RE.match(text) and '#' not in text) + def parse_modes(self, target, args): """Parses a modestring list into a list of (mode, argument) tuples. ['+mitl-o', '3', 'person'] => [('+m', None), ('+i', None), ('+t', None), ('+l', '3'), ('-o', 'person')] @@ -1178,6 +1210,8 @@ class PyLinkNetworkCoreWithUtils(PyLinkNetworkCore): uid, nick) self.call_hooks([self.sid, 'SAVE', {'target': uid}]) +utils._proto_utils_class = PyLinkNetworkCoreWithUtils # Used by compatibility wrappers + class IRCNetwork(PyLinkNetworkCoreWithUtils): S2S_BUFSIZE = 510 diff --git a/utils.py b/utils.py index 9db2dbf..b6ba882 100644 --- a/utils.py +++ b/utils.py @@ -21,6 +21,7 @@ from pylinkirc import protocols, plugins PLUGIN_PREFIX = plugins.__name__ + '.' PROTOCOL_PREFIX = protocols.__name__ + '.' NORMALIZEWHITESPACE_RE = re.compile(r'\s+') +_proto_utils_class = None # Set by classes.py when loaded class NotAuthorizedError(Exception): """ @@ -49,31 +50,40 @@ def add_hook(func, command): world.hooks[command].append(func) return func -_nickregex = r'^[A-Za-z\|\\_\[\]\{\}\^\`][A-Z0-9a-z\-\|\\_\[\]\{\}\^\`]*$' +# DEPRECATED def isNick(s, nicklen=None): - """Returns whether the string given is a valid nick.""" - if nicklen and len(s) > nicklen: - return False - return bool(re.match(_nickregex, s)) + """Returns whether the string given is a valid nick. + Deprecated since 2.0: use irc.is_nick() instead.""" + + log.warning('utils.isNick() is deprecated since PyLink 2.0, use irc.is_nick() instead.') + return _proto_utils_class.is_nick(s, nicklen=nicklen) + +# DEPRECATED def isChannel(s): - """Returns whether the string given is a valid channel name.""" - return str(s).startswith('#') + """Returns whether the string given is a valid channel name. -def _isASCII(s): - """Returns whether the string given is valid ASCII.""" - chars = string.ascii_letters + string.digits + string.punctuation - return all(char in chars for char in s) + Deprecated since 2.0: use irc.is_channel() instead.""" + log.warning('utils.isChannel() is deprecated since PyLink 2.0, use irc.is_channel() instead.') + return _proto_utils_class.is_channel(s) + +# DEPRECATED def isServerName(s): - """Returns whether the string given is a valid IRC server name.""" - return _isASCII(s) and '.' in s and not s.startswith('.') + """Returns whether the string given is a valid server name. -hostmaskRe = re.compile(r'^\S+!\S+@\S+$') + Deprecated since 2.0: use irc.is_server_name() instead.""" + + log.warning('utils.isServerName() is deprecated since PyLink 2.0, use irc.is_server_name() instead.') + return _proto_utils_class.is_server_name(s) + +# DEPRECATED def isHostmask(text): - """Returns whether the given text is a valid hostmask.""" - # Band-aid patch here to prevent bad bans set by Janus forwarding people into invalid channels. - return hostmaskRe.match(text) and '#' not in text + """Returns whether the given text is a valid hostmask. + + Deprecated since 2.0: use irc.is_hostmask() instead.""" + log.warning('utils.isHostmask() is deprecated since PyLink 2.0, use irc.is_hostmask() instead.') + return _proto_utils_class.is_hostmask(text) def expandpath(path): """ @@ -134,9 +144,6 @@ class ServiceBot(): self.name = name self.default_nick = default_nick - # TODO: validate nick, ident, etc. on runtime as well - assert isNick(name), "Invalid service name %r" % name - # Tracks whether the bot should be manipulatable by the 'bots' plugin and other commands. self.manipulatable = manipulatable