comparison irclib.py @ 174:c158ad24ef3c

moved irc connection interval handling to irclib Signed-off-by: Charly COSTE <changaco@changaco.net>
author Charly COSTE <changaco@changaco.net>
date Thu, 04 Feb 2010 21:02:36 +0100
parents 64a0e9636ae6
children 102f895347ff
comparison
equal deleted inserted replaced
173:6c4aaf8f3733 174:c158ad24ef3c
162 self.fn_to_add_timeout = fn_to_add_timeout 162 self.fn_to_add_timeout = fn_to_add_timeout
163 self.connections = [] 163 self.connections = []
164 self.handlers = {} 164 self.handlers = {}
165 self.delayed_commands = [] # list of tuples in the format (time, function, arguments) 165 self.delayed_commands = [] # list of tuples in the format (time, function, arguments)
166 self.charsets = {'': ['utf-8']} 166 self.charsets = {'': ['utf-8']}
167 self.connection_intervals = {'': 1}
168 self.connection_stacks = {}
167 169
168 self.add_global_handler("ping", _ping_ponger, -42) 170 self.add_global_handler("ping", _ping_ponger, -42)
171
172
173 def _connection_loop(self, server_str):
174 stack = self.connection_stacks[server_str]
175 if len(stack) > 0:
176 stack[0][0](*stack[0][1])
177 stack.pop(0)
178 delay = self.connection_interval(server=server_str)
179 self.bot.error('==> Debug: waiting '+str(delay)+' seconds before next connection on '+server_str, debug=True)
180 self.execute_delayed(delay, self._connection_loop, (server_str,))
181 else:
182 self.connection_stacks.pop(server_str)
183
184
185 def connection_interval(self, server='', seconds=None):
186 if seconds:
187 self.connection_intervals[server] = seconds
188 return seconds
189 elif self.connection_intervals.has_key(server):
190 return self.connection_intervals[server]
191 else:
192 return self.connection_intervals['']
193
169 194
170 def get_connection(self, server, port, nickname): 195 def get_connection(self, server, port, nickname):
171 for c in self.connections: 196 for c in self.connections:
172 if c.server == server and c.port == port and c.real_nickname == nickname: 197 if c.server == server and c.port == port and c.real_nickname == nickname:
173 return c 198 return c
176 def has_connection(self, server, port, nickname): 201 def has_connection(self, server, port, nickname):
177 if self.get_connection(server, port, nickname): 202 if self.get_connection(server, port, nickname):
178 return True 203 return True
179 return False 204 return False
180 205
181 def open_connection(self, server, port, nickname): 206 def open_connection(self, server, port, nickname, delay=None):
182 """Creates or returns an existing ServerConnection object for nickname at server:port. 207 """Creates or returns an existing ServerConnection object for nickname at server:port.
183 208
184 server -- Server name. 209 server -- Server name.
185 210
186 port -- Port number. 211 port -- Port number.
189 214
190 c = self.get_connection(server, port, nickname) 215 c = self.get_connection(server, port, nickname)
191 if c: 216 if c:
192 return c 217 return c
193 c = ServerConnection(self, server, port, nickname) 218 c = ServerConnection(self, server, port, nickname)
219 server_str = c._server_str()
220 if not self.connection_stacks.has_key(server_str):
221 self.connection_stacks[server_str] = []
222 delay = self.connection_interval(server=server_str, seconds=delay)
223 self.execute_delayed(delay, self._connection_loop, (server_str,))
194 self.connections.append(c) 224 self.connections.append(c)
195 return c 225 return c
196 226
197 def process_data(self, sockets): 227 def process_data(self, sockets):
198 """Called when there is more data to read on connection sockets. 228 """Called when there is more data to read on connection sockets.
412 442
413 def __init__(self, irclibobj, server, port, nickname): 443 def __init__(self, irclibobj, server, port, nickname):
414 Connection.__init__(self, irclibobj) 444 Connection.__init__(self, irclibobj)
415 self.connected = False # Not connected yet. 445 self.connected = False # Not connected yet.
416 self.really_connected = False 446 self.really_connected = False
417 self.used_by = 1 447 self.used_by = 0
418 self.socket = None 448 self.socket = None
419 self.ssl = None 449 self.ssl = None
420 self.server = server 450 self.server = server
421 self.port = port 451 self.port = port
422 self.nickname = nickname 452 self.nickname = nickname
453 self.nick_callbacks = []
423 self.lock = threading.RLock() 454 self.lock = threading.RLock()
424 self.left_channels = [] 455 self.left_channels = []
425 456
426 457
427 def __str__(self): 458 def __str__(self):
475 Returns the ServerConnection object. 506 Returns the ServerConnection object.
476 """ 507 """
477 508
478 self.lock.acquire() 509 self.lock.acquire()
479 510
480 if self.connected == True: 511 if nick_callback:
512 self.add_nick_callback(nick_callback)
513
514 if self.used_by > 0:
481 self.used_by += 1 515 self.used_by += 1
482 self.irclibobj.bot.error('===> Debug: using existing IRC connection for '+self.__str__()+', this connection is now used by '+str(self.used_by)+' bridges', debug=True) 516 self.irclibobj.bot.error('===> Debug: using existing IRC connection for '+self.__str__()+', this connection is now used by '+str(self.used_by)+' bridges', debug=True)
483 if nick_callback != None:
484 self.add_nick_callback(nick_callback)
485 if self.really_connected: 517 if self.really_connected:
486 self._call_nick_callbacks(None) 518 self._call_nick_callbacks(None)
487 self.lock.release() 519 self.lock.release()
488 return self 520 return self
489 521
490 if self.socket != 'closed': 522 if self.socket != 'closed':
523 self.used_by = 1
491 if charsets or not self.irclibobj.charsets.has_key(self._server_str()): 524 if charsets or not self.irclibobj.charsets.has_key(self._server_str()):
492 self.irclibobj.charsets[self._server_str()] = charsets 525 self.irclibobj.charsets[self._server_str()] = charsets
493 self.nick_callbacks = []
494 self.irc_id = None 526 self.irc_id = None
495 self.previous_buffer = "" 527 self.previous_buffer = ""
496 self.handlers = {} 528 self.handlers = {}
497 self.real_server_name = "" 529 self.real_server_name = ""
498 self.real_nickname = self.nickname 530 self.real_nickname = self.nickname
500 self.ircname = ircname or self.nickname 532 self.ircname = ircname or self.nickname
501 self.password = password 533 self.password = password
502 self.localaddress = localaddress 534 self.localaddress = localaddress
503 self.localport = localport 535 self.localport = localport
504 self.localhost = socket.gethostname() 536 self.localhost = socket.gethostname()
505 537 self.ssl = ssl
538 self.ipv6 = ipv6
539
540 self.irclibobj.connection_stacks[self._server_str()].append( (self._connect, ()) )
541
542 self.lock.release()
543 return self
544
545
546 def _connect(self):
547
548 self._ping()
549
550 self.lock.acquire()
551
552 if self.socket != 'closed':
506 self.irclibobj.bot.error('===> Debug: opening new IRC connection for '+self.__str__(), debug=True) 553 self.irclibobj.bot.error('===> Debug: opening new IRC connection for '+self.__str__(), debug=True)
507 else: 554 else:
508 self.irclibobj.bot.error('===> Debug: reopening IRC connection for '+self.__str__(), debug=True) 555 self.irclibobj.bot.error('===> Debug: reopening IRC connection for '+self.__str__(), debug=True)
509 556
510 self._ping() 557 if self.ipv6:
511
512 if ipv6:
513 self.socket = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) 558 self.socket = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
514 else: 559 else:
515 self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 560 self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
516 try: 561 try:
517 self.socket.bind((self.localaddress, self.localport)) 562 self.socket.bind((self.localaddress, self.localport))
518 self.socket.connect((self.server, self.port)) 563 self.socket.connect((self.server, self.port))
519 if ssl: 564 if self.ssl:
520 self.ssl = socket.ssl(self.socket) 565 self.ssl = socket.ssl(self.socket)
521 except socket.error, x: 566 except socket.error, x:
522 self.socket.close() 567 self.socket.close()
523 self.socket = 'closed' 568 self.socket = 'closed'
524 raise ServerConnectionError, "Couldn't connect to socket: %s" % x 569 raise ServerConnectionError, "Couldn't connect to socket: %s" % x
527 self.irclibobj.fn_to_add_socket(self.socket) 572 self.irclibobj.fn_to_add_socket(self.socket)
528 573
529 # Log on... 574 # Log on...
530 if self.password: 575 if self.password:
531 self.pass_(self.password) 576 self.pass_(self.password)
532 if self.nick(self.nickname, callback=nick_callback) == True: 577 if self.nick(self.nickname):
533 self.user(self.username, self.ircname) 578 self.user(self.username, self.ircname)
579
534 self.lock.release() 580 self.lock.release()
535 return self 581 return self
536 582
537 583
538 def _call_nick_callbacks(self, error, arguments=[]): 584 def _call_nick_callbacks(self, error, arguments=[]):