1 import socket
, time
, random
6 def do_nothing(*arguments
):
13 last_index
= len(input) - 1
14 while i
<= last_index
:
15 current_char
= input[i
]
16 if ord(current_char
) < ord(' '):
17 if current_char
== '\x03' and last_index
- i
>= 2:
18 next_char
= input[i
+ 1]
19 next_char_value
= ord(next_char
)
22 second_digit
= ord(input[i
+ 1])
23 if second_digit
>= ord('0') and second_digit
<= ord('5'):
25 elif next_char
== '0':
27 elif next_char_value
>= ord('2') and next_char_value
<= ord('9'):
30 output
+= current_char
35 def __init__(self
, input):
39 tokens
= input[1 : ].split('!')
46 tokens
= tokens
[1].split('@')
51 self
.ident
= tokens
[0]
52 self
.address
= tokens
[1]
56 self
.on_raw_packet
= do_nothing
57 self
.on_failed_connect
= do_nothing
58 self
.on_connect
= do_nothing
59 self
.on_disconnect
= do_nothing
60 self
.on_entry
= do_nothing
61 self
.on_notice
= do_nothing
62 self
.on_join
= do_nothing
63 self
.on_invite
= do_nothing
64 self
.on_channel_message
= do_nothing
65 self
.on_private_message
= do_nothing
66 self
.on_nick_name_in_use
= self
.change_nick
67 self
.on_quit
= do_nothing
69 self
.auto_reconnect
= True
70 self
.auto_reconnect_delay
= 5
73 def connect(self
, server
, port
, nick
, user
, local_host
, real_name
):
78 self
.local_host
= local_host
79 self
.real_name
= real_name
82 self
.socket
= socket
.socket(socket
.AF_INET
, socket
.SOCK_STREAM
, socket
.IPPROTO_TCP
)
84 self
.socket
.connect((server
, port
))
88 self
.on_failed_connect()
89 if self
.auto_reconnect
:
90 time
.sleep(self
.auto_reconnect_delay
)
94 self
.send_line('NICK %s' % nick
)
95 self
.send_line('USER %s "%s" "%s" :%s' % (user
, local_host
, server
, real_name
))
99 self
.connect(self
.server
, self
.port
, self
.nick
, self
.user
, self
.local_host
, self
.real_name
)
101 def send_line(self
, line
):
102 self
.socket
.send('%s\r\n' % line
)
104 def join(self
, channel
):
105 self
.send_line('JOIN %s' % channel
)
107 def message(self
, target
, message
):
108 self
.send_line('PRIVMSG %s :%s' % (target
, message
))
110 def got_disconnected(self
):
112 time
.sleep(self
.auto_reconnect_delay
)
115 def receive_data(self
):
118 new_data
= self
.socket
.recv(self
.read_size
)
119 if len(new_data
) == 0:
120 self
.got_disconnected()
122 self
.buffer += new_data
123 self
.process_new_data()
125 def process_new_data(self
):
127 offset
= self
.buffer.find('\n')
130 line
= self
.buffer[0 : offset
].replace('\r', '')
131 self
.buffer = self
.buffer[offset
+ 1 : ]
132 self
.process_line(line
)
134 def process_line(self
, line
):
135 self
.on_raw_packet(line
)
139 offset
= line
.find(colon
, 1)
141 tokens
= line
.split(delimiter
)
143 tokens
= line
[0 : offset
- 1].split(delimiter
)
144 tokens
.append(line
[offset
+ 1 : ])
146 self
.process_command(tokens
)
148 def process_command(self
, tokens
):
150 ('376', self
.event_end_of_motd
),
151 ('422', self
.event_end_of_motd
),
152 ('433', self
.event_nick_name_in_use
),
153 ('NOTICE', self
.event_notice
),
154 ('INVITE', self
.event_invite
),
155 ('JOIN', self
.event_join
),
156 ('PRIVMSG', self
.event_message
),
157 ('MODE', self
.event_mode
),
158 ('QUIT', self
.event_quit
)
161 if tokens
[0] == 'PING' and len(tokens
) == 2:
162 self
.send_line('PONG %s' % tokens
[1])
168 for command
, function
in commands
:
169 if command
== tokens
[1]:
173 def change_nick(self
):
174 new_nick
= '%s%d' % (self
.nick
, random
.randint(10, 99))
175 self
.send_line('NICK %s' % new_nick
)
177 def event_end_of_motd(self
, tokens
):
178 self
.nick
= tokens
[2]
181 def event_nick_name_in_use(self
, tokens
):
182 self
.on_nick_name_in_use()
184 def event_notice(self
, tokens
):
185 user
= irc_user(tokens
[0])
189 self
.on_notice(user
, text
)
191 def event_invite(self
, tokens
):
192 user
= irc_user(tokens
[0])
196 self
.on_invite(user
, channel
)
198 def event_join(self
, tokens
):
199 user
= irc_user(tokens
[0])
202 own_join
= (user
.nick
== self
.nick
)
204 self
.on_join(channel
, user
, own_join
)
206 def event_message(self
, tokens
):
207 user
= irc_user(tokens
[0])
212 if target
== self
.nick
:
213 self
.on_private_message(user
, message
)
215 self
.on_channel_message(target
, user
, message
)
217 def event_mode(self
, tokens
):
220 def event_quit(self
, tokens
):
221 user
= irc_user(tokens
[0])
225 self
.on_quit(user
, message
)