mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-11-30 06:49:24 +01:00
Add support for message tags.
This commit is contained in:
parent
ed37fb6646
commit
ba495f5719
@ -50,6 +50,37 @@ from .utils.iter import all
|
|||||||
class MalformedIrcMsg(ValueError):
|
class MalformedIrcMsg(ValueError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# http://ircv3.net/specs/core/message-tags-3.2.html#escaping-values
|
||||||
|
SERVER_TAG_ESCAPE = [
|
||||||
|
('\\', '\\\\'), # \ -> \\
|
||||||
|
(' ', r'\s'),
|
||||||
|
(';', r'\:'),
|
||||||
|
('\r', r'\r'),
|
||||||
|
('\n', r'\n'),
|
||||||
|
]
|
||||||
|
escape_server_tag_value = utils.str.MultipleReplacer(
|
||||||
|
dict(SERVER_TAG_ESCAPE))
|
||||||
|
unescape_server_tag_value = utils.str.MultipleReplacer(
|
||||||
|
dict(map(lambda x:(x[1],x[0]), SERVER_TAG_ESCAPE)))
|
||||||
|
|
||||||
|
def parse_server_tags(s):
|
||||||
|
server_tags = {}
|
||||||
|
for tag in s.split(';'):
|
||||||
|
if '=' not in tag:
|
||||||
|
server_tags[tag] = None
|
||||||
|
else:
|
||||||
|
(key, value) = tag.split('=', 1)
|
||||||
|
server_tags[key] = unescape_server_tag_value(value)
|
||||||
|
return server_tags
|
||||||
|
def format_server_tags(server_tags):
|
||||||
|
parts = []
|
||||||
|
for (key, value) in server_tags.items():
|
||||||
|
if value is None:
|
||||||
|
parts.append(key)
|
||||||
|
else:
|
||||||
|
parts.append('%s=%s' % (key, escape_server_tag_value(value)))
|
||||||
|
return '@' + ';'.join(parts)
|
||||||
|
|
||||||
class IrcMsg(object):
|
class IrcMsg(object):
|
||||||
"""Class to represent an IRC message.
|
"""Class to represent an IRC message.
|
||||||
|
|
||||||
@ -81,7 +112,8 @@ class IrcMsg(object):
|
|||||||
# data. Goodbye, __slots__.
|
# data. Goodbye, __slots__.
|
||||||
# On second thought, let's use methods for tagging.
|
# On second thought, let's use methods for tagging.
|
||||||
__slots__ = ('args', 'command', 'host', 'nick', 'prefix', 'user',
|
__slots__ = ('args', 'command', 'host', 'nick', 'prefix', 'user',
|
||||||
'_hash', '_str', '_repr', '_len', 'tags', 'reply_env')
|
'_hash', '_str', '_repr', '_len', 'tags', 'reply_env',
|
||||||
|
'server_tags')
|
||||||
def __init__(self, s='', command='', args=(), prefix='', msg=None,
|
def __init__(self, s='', command='', args=(), prefix='', msg=None,
|
||||||
reply_env=None):
|
reply_env=None):
|
||||||
assert not (msg and s), 'IrcMsg.__init__ cannot accept both s and msg'
|
assert not (msg and s), 'IrcMsg.__init__ cannot accept both s and msg'
|
||||||
@ -99,6 +131,11 @@ class IrcMsg(object):
|
|||||||
if not s.endswith('\n'):
|
if not s.endswith('\n'):
|
||||||
s += '\n'
|
s += '\n'
|
||||||
self._str = s
|
self._str = s
|
||||||
|
if s[0] == '@':
|
||||||
|
(server_tags, s) = s.split(' ', 1)
|
||||||
|
self.server_tags = parse_server_tags(server_tags[1:])
|
||||||
|
else:
|
||||||
|
self.server_tags = {}
|
||||||
if s[0] == ':':
|
if s[0] == ':':
|
||||||
self.prefix, s = s[1:].split(None, 1)
|
self.prefix, s = s[1:].split(None, 1)
|
||||||
else:
|
else:
|
||||||
|
@ -128,6 +128,19 @@ class IrcMsgTestCase(SupyTestCase):
|
|||||||
m.tag('repliedTo', 12)
|
m.tag('repliedTo', 12)
|
||||||
self.assertEqual(m.repliedTo, 12)
|
self.assertEqual(m.repliedTo, 12)
|
||||||
|
|
||||||
|
def testServerTags(self):
|
||||||
|
s = '@aaa=b\\:bb;ccc;example.com/ddd=ee\\\\se ' \
|
||||||
|
':nick!ident@host.com PRIVMSG me :Hello'
|
||||||
|
m = ircmsgs.IrcMsg(s)
|
||||||
|
self.assertEqual(m.server_tags, {
|
||||||
|
'aaa': 'b;bb',
|
||||||
|
'ccc': None,
|
||||||
|
'example.com/ddd': 'ee\\se'})
|
||||||
|
self.assertEqual(m.prefix, 'nick!ident@host.com')
|
||||||
|
self.assertEqual(m.command, 'PRIVMSG')
|
||||||
|
self.assertEqual(m.args, ('me', 'Hello'))
|
||||||
|
self.assertEqual(str(m), s + '\n')
|
||||||
|
|
||||||
class FunctionsTestCase(SupyTestCase):
|
class FunctionsTestCase(SupyTestCase):
|
||||||
def testIsAction(self):
|
def testIsAction(self):
|
||||||
L = [':jemfinch!~jfincher@ts26-2.homenet.ohio-state.edu PRIVMSG'
|
L = [':jemfinch!~jfincher@ts26-2.homenet.ohio-state.edu PRIVMSG'
|
||||||
|
Loading…
Reference in New Issue
Block a user