1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
#!/usr/bin/env python3
#
# This is very horrible and quickly written
# But it works
#
import datetime, miniirc, re
assert miniirc.ver >= (1,8,1)
_LEADING_COLON = '' if miniirc.ver[0] > 2 else ':'
_esc_re = re.compile(r'\\(.)|\t')
idc_to_irc = {
#'MESSAGE': 'PRIVMSG',
'RPL_LOGIN_GOOD': '001',
}
class IDC(miniirc.IRC):
def idc_message_parser(self, msg):
args = _esc_re.sub(lambda m: m.group(1) or '\udeff', msg).split('\udeff')
command = args.pop(0).upper()
tags = {}
if command == 'PRIVMSG':
dt = datetime.datetime.utcfromtimestamp(float(args[0]))
tags['time'] = dt.isoformat() + 'Z'
hostmask = (args[1], args[1], f'idc/{args[1]}')
args = [self.current_nick, args[2]]
else:
hostmask = ('', '', '')
if args and _LEADING_COLON:
args[-1] = _LEADING_COLON + args[-1]
return idc_to_irc.get(command, command), hostmask, tags, args
# Send raw messages
def idc_send(self, *args):
line = '\t'.join(arg.replace('\\', '\\\\').replace('\t', '\\\t')
for arg in args)
super().quote(line, force=True)
if miniirc.ver < (2, 0, 0):
@property
def _sock(self):
return self.sock
def quote(self, *msg, force=None, tags=None) -> None:
cmd, _, tags2, args = miniirc.ircv3_message_parser(' '.join(msg))
if miniirc.ver[0] < 2 and args and args[-1].startswith(':'):
args[-1] = args[-1][1:]
self.send(cmd, *args, force=force, tags=tags or tags2)
def _get_idc_account(self):
if isinstance(self.ns_identity, tuple):
return self.ns_identity
else:
return self.ns_identity.split(' ', 1)
@property
def current_nick(self):
return self._get_idc_account()[0]
def send(self, cmd, *args, force=None, tags=None) -> None:
cmd = cmd.upper()
if cmd in ('PRIVMSG', 'NOTICE'):
target = args[0]
# TODO: Make miniirc think that SASL worked PMs to NickServ don't
# have to be blocked.
if target == 'NickServ':
return
self.idc_send('CHANMSG' if target.startswith('#') else 'PRIVMSG',
*args)
elif cmd in ('PING', 'QUIT'):
self.idc_send(cmd, *args)
elif cmd == 'USER':
user, password = self._get_idc_account()
self.idc_send('USER', user, password)
# Override the message parser to change the default parser.
def change_parser(self, parser=None):
super().change_parser(parser or self.idc_message_parser)
|