-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathirc.py
115 lines (93 loc) · 3.38 KB
/
irc.py
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
__author__ = 'tobiewarburton'
import socket
import re
class RawMessage:
def __init__(self, command, prefix, params, trail):
self.command = command
self.prefix = prefix
self.params = params
self.trail = trail
def handle(self, bot):
if self.command == 'PING':
bot.send_raw('PONG ' + self.trail)
print self
def __str__(self):
return 'RAW %s %s %s %s' % (self.command, self.prefix, self.params,
self.trail)
@staticmethod
def parse(data):
if data['command'].isdigit():
return NumericMessage(int(data['command']), data['prefix'],
data['params'], data['trail'])
elif data['command'] == 'PRIVMSG':
return PrivMessage(data['prefix'], data['params'], data['trail'])
else:
return RawMessage(data['command'], data['prefix'], data['params'],
data['trail'])
class NumericMessage:
def __init__(self, numeric, prefix, params, trail):
self.numeric = numeric
self.prefix = prefix
self.params = params
self.trail = trail
def handle(self, bot):
pass
def __str__(self):
return 'NUMERIC (%d) %s %s %s' % (self.numeric, self.prefix,
self.params, self.trail)
class PrivMessage:
def __init__(self, sender, destination, msg):
self.nick, self.user, self.host = re.search(r'(.*)!(.*)@(.*)',
sender).groups()
self.destination = destination
self.msg = msg
def is_channel(self):
return self.destination.startswith('#')
def is_private(self):
return not is_channel()
def __str__(self):
if self.is_channel():
return '[ %s ] <%s> %s' % (self.destination, self.nick, self.msg)
else:
return '<%s> %s' % (self.nick, self.msg)
class Bot:
def __init__(self, server, port, nick, channels):
self.server = server
self.port = port
self.channels = channels
self.nick = nick
self.socket = socket.socket()
def send_raw(self, raw):
self.socket.send('%s\r\n' % raw)
def connect(self):
self.socket.connect((self.server, self.port))
self.file = self.socket.makefile('r')
self.send_raw('NICK %s' % self.nick)
self.send_raw('USER %s %s %s :warb0' %
(self.nick, self.nick, self.nick))
for channel in self.channels:
self.send_raw('JOIN %s' % channel)
def listen(self):
while True:
line = self.file.readline().replace('\r', '').strip()
if not line:
break
# we have a line!
self.handle(line)
def handle(self, line):
irc_regex = re.compile(
r'^(:(?P<prefix>\S+) )?(?P<command>\S+)( (?!:)(?P<params>.+?))?( :(?P<trail>.+))?$'
)
matched = irc_regex.match(line)
data = matched.groupdict()
msg = RawMessage.parse(data)
if isinstance(msg, PrivMessage):
print msg
elif isinstance(msg, NumericMessage):
msg.handle(self)
else:
msg.handle(self)
if __name__ == '__main__':
bot = Bot('irc.rizon.net', 6667, 'warb0t', ['#aurora-rs'])
bot.connect()
bot.listen()