comparison irclib.py @ 17:32a35f7eff70

Rewrote/modified many things, multiple bridges should now work and are preferred over multiple bots. Signed-off-by: Charly COSTE <changaco@changaco.net>
author Charly COSTE <changaco@changaco.net>
date Thu, 20 Aug 2009 01:00:54 +0200
parents 1a1f2a0d35c7
children abdb7a2b6c6d
comparison
equal deleted inserted replaced
16:0c4a7452d66c 17:32a35f7eff70
159 self.handlers = {} 159 self.handlers = {}
160 self.delayed_commands = [] # list of tuples in the format (time, function, arguments) 160 self.delayed_commands = [] # list of tuples in the format (time, function, arguments)
161 161
162 self.add_global_handler("ping", _ping_ponger, -42) 162 self.add_global_handler("ping", _ping_ponger, -42)
163 163
164 def server(self): 164 def server(self, server, port, nickname):
165 """Creates and returns a ServerConnection object.""" 165 """Creates or returns an existing ServerConnection object for nickname at server:port.
166 166
167 c = ServerConnection(self) 167 server -- Server name.
168
169 port -- Port number.
170
171 nickname -- The nickname."""
172
173 for c in self.connections:
174 if c.server == server and c.port == port and c.real_nickname == nickname:
175 return c
176 c = ServerConnection(self, server, port, nickname)
168 self.connections.append(c) 177 self.connections.append(c)
169 return c 178 return c
170 179
171 def process_data(self, sockets): 180 def process_data(self, sockets):
172 """Called when there is more data to read on connection sockets. 181 """Called when there is more data to read on connection sockets.
370 379
371 ServerConnection objects are instantiated by calling the server 380 ServerConnection objects are instantiated by calling the server
372 method on an IRC object. 381 method on an IRC object.
373 """ 382 """
374 383
375 def __init__(self, irclibobj): 384 def __init__(self, irclibobj, server, port, nickname):
376 Connection.__init__(self, irclibobj) 385 Connection.__init__(self, irclibobj)
377 self.connected = 0 # Not connected yet. 386 self.connected = False # Not connected yet.
378 self.really_connected = False 387 self.really_connected = False
388 self.used_by = 1
379 self.socket = None 389 self.socket = None
380 self.ssl = None 390 self.ssl = None
381 391 self.server = server
382 def connect(self, server, port, nickname, password=None, username=None, 392 self.port = port
383 ircname=None, localaddress="", localport=0, ssl=False, ipv6=False): 393 self.nickname = nickname
384 """Connect/reconnect to a server. 394
395
396 def __str__(self):
397 return self.real_nickname+' at '+self.server+':'+str(self.port)
398
399
400 def connect(self, password=None, username=None,
401 ircname=None, localaddress="", localport=0, ssl=False, ipv6=False, nick_callback=None):
402 """Connect to the server.
385 403
386 Arguments: 404 Arguments:
387 405
388 server -- Server name.
389
390 port -- Port number.
391
392 nickname -- The nickname.
393
394 password -- Password (if any). 406 password -- Password (if any).
395 407
396 username -- The username. 408 username -- The username.
397 409
398 ircname -- The IRC name ("realname"). 410 ircname -- The IRC name ("realname").
407 419
408 This function can be called to reconnect a closed connection. 420 This function can be called to reconnect a closed connection.
409 421
410 Returns the ServerConnection object. 422 Returns the ServerConnection object.
411 """ 423 """
412 if self.connected: 424 if self.connected == True:
413 self.disconnect("Changing servers") 425 self.used_by += 1
414 426 self.irclibobj.bot.error('===> Debug: using existing IRC connection for '+str(self)+', this connection is now used by '+str(self.used_by)+' bridges', debug=True)
415 self.closing = False 427 self.nick(self.real_nickname, callback=nick_callback)
428 return
429
430
431 self.nick_callbacks = []
416 self.previous_buffer = "" 432 self.previous_buffer = ""
417 self.handlers = {} 433 self.handlers = {}
418 self.real_server_name = "" 434 self.real_server_name = ""
419 self.real_nickname = nickname 435 self.real_nickname = self.nickname
420 self.server = server 436 self.username = username or self.nickname
421 self.port = port 437 self.ircname = ircname or self.nickname
422 self.nickname = nickname
423 self.username = username or nickname
424 self.ircname = ircname or nickname
425 self.password = password 438 self.password = password
426 self.localaddress = localaddress 439 self.localaddress = localaddress
427 self.localport = localport 440 self.localport = localport
428 self.localhost = socket.gethostname() 441 self.localhost = socket.gethostname()
442
443 self.irclibobj.bot.error('===> Debug: opening new IRC connection for '+str(self), debug=True)
444
429 if ipv6: 445 if ipv6:
430 self.socket = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) 446 self.socket = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
431 else: 447 else:
432 self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 448 self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
433 try: 449 try:
437 self.ssl = socket.ssl(self.socket) 453 self.ssl = socket.ssl(self.socket)
438 except socket.error, x: 454 except socket.error, x:
439 self.socket.close() 455 self.socket.close()
440 self.socket = None 456 self.socket = None
441 raise ServerConnectionError, "Couldn't connect to socket: %s" % x 457 raise ServerConnectionError, "Couldn't connect to socket: %s" % x
442 self.connected = 1 458 self.connected = True
443 if self.irclibobj.fn_to_add_socket: 459 if self.irclibobj.fn_to_add_socket:
444 self.irclibobj.fn_to_add_socket(self.socket) 460 self.irclibobj.fn_to_add_socket(self.socket)
445 461
446 # Log on... 462 # Log on...
447 if self.password: 463 if self.password:
448 self.pass_(self.password) 464 self.pass_(self.password)
449 self.nick(self.nickname) 465 self.nick(self.nickname, callback=nick_callback)
450 self.user(self.username, self.ircname) 466 self.user(self.username, self.ircname)
451 return self 467 return self
452 468
453 def close(self): 469
470 def _call_nick_callbacks(self, error, arguments=[]):
471 i = 0
472 for f in self.nick_callbacks:
473 i += 1
474 f(error, arguments=arguments)
475 self.nick_callbacks = []
476 if i == 0:
477 self.irclibobj.bot.error('=> Debug: no nick callback for "'+str(self)+'"', debug=True)
478 else:
479 self.irclibobj.bot.error('=> Debug: called '+str(i)+' callback(s) for "'+str(self)+'"', debug=True)
480
481
482 def add_nick_callback(self, callback):
483 self.nick_callbacks.append(callback)
484
485
486 def close(self, message):
454 """Close the connection. 487 """Close the connection.
455 488
456 This method closes the connection permanently; after it has 489 This method closes the connection permanently; after it has
457 been called, the object is unusable. 490 been called, the object is unusable.
458 """ 491 """
459 492
460 self.disconnect("Closing object") 493 self.disconnect(message)
461 self.irclibobj._remove_connection(self) 494 self.irclibobj._remove_connection(self)
462 495
463 def _get_socket(self): 496 def _get_socket(self):
464 """[Internal]""" 497 """[Internal]"""
465 return self.socket 498 return self.socket
654 message -- Quit message. 687 message -- Quit message.
655 """ 688 """
656 if not self.connected: 689 if not self.connected:
657 return 690 return
658 691
659 self.connected = 0 692 self.connected = False
660 693
661 self.quit(message) 694 self.quit(message)
662 695
663 try: 696 try:
664 self.socket.close() 697 self.socket.close()
665 except socket.error, x: 698 except socket.error, x:
666 pass 699 pass
667 self.socket = None 700 self.socket = None
701 self.irclibobj
668 self._handle_event(Event("disconnect", self.server, "", [message])) 702 self._handle_event(Event("disconnect", self.server, "", [message]))
669 703
670 def globops(self, text): 704 def globops(self, text):
671 """Send a GLOBOPS command.""" 705 """Send a GLOBOPS command."""
672 self.send_raw("GLOBOPS :" + text) 706 self.send_raw("GLOBOPS :" + text)
728 762
729 def names(self, channels=None): 763 def names(self, channels=None):
730 """Send a NAMES command.""" 764 """Send a NAMES command."""
731 self.send_raw("NAMES" + (channels and (" " + ",".join(channels)) or "")) 765 self.send_raw("NAMES" + (channels and (" " + ",".join(channels)) or ""))
732 766
733 def nick(self, newnick): 767 def nick(self, newnick, callback=None):
734 """Send a NICK command.""" 768 """Send a NICK command."""
769 if callback != None:
770 self.add_nick_callback(callback)
771 if ' ' in newnick:
772 self._call_nick_callbacks('erroneusnickname')
773 return
735 self.send_raw("NICK " + newnick) 774 self.send_raw("NICK " + newnick)
736 775
737 def notice(self, target, text): 776 def notice(self, target, text):
738 """Send a NOTICE command.""" 777 """Send a NOTICE command."""
739 # Should limit len(text) here! 778 # Should limit len(text) here!
866 DCCConnection objects are instantiated by calling the dcc 905 DCCConnection objects are instantiated by calling the dcc
867 method on an IRC object. 906 method on an IRC object.
868 """ 907 """
869 def __init__(self, irclibobj, dcctype): 908 def __init__(self, irclibobj, dcctype):
870 Connection.__init__(self, irclibobj) 909 Connection.__init__(self, irclibobj)
871 self.connected = 0 910 self.connected = False
872 self.passive = 0 911 self.passive = 0
873 self.dcctype = dcctype 912 self.dcctype = dcctype
874 self.peeraddress = None 913 self.peeraddress = None
875 self.peerport = None 914 self.peerport = None
876 915
893 self.passive = 0 932 self.passive = 0
894 try: 933 try:
895 self.socket.connect((self.peeraddress, self.peerport)) 934 self.socket.connect((self.peeraddress, self.peerport))
896 except socket.error, x: 935 except socket.error, x:
897 raise DCCConnectionError, "Couldn't connect to socket: %s" % x 936 raise DCCConnectionError, "Couldn't connect to socket: %s" % x
898 self.connected = 1 937 self.connected = True
899 if self.irclibobj.fn_to_add_socket: 938 if self.irclibobj.fn_to_add_socket:
900 self.irclibobj.fn_to_add_socket(self.socket) 939 self.irclibobj.fn_to_add_socket(self.socket)
901 return self 940 return self
902 941
903 def listen(self): 942 def listen(self):
930 message -- Quit message. 969 message -- Quit message.
931 """ 970 """
932 if not self.connected: 971 if not self.connected:
933 return 972 return
934 973
935 self.connected = 0 974 self.connected = False
936 try: 975 try:
937 self.socket.close() 976 self.socket.close()
938 except socket.error, x: 977 except socket.error, x:
939 pass 978 pass
940 self.socket = None 979 self.socket = None
948 987
949 if self.passive and not self.connected: 988 if self.passive and not self.connected:
950 conn, (self.peeraddress, self.peerport) = self.socket.accept() 989 conn, (self.peeraddress, self.peerport) = self.socket.accept()
951 self.socket.close() 990 self.socket.close()
952 self.socket = conn 991 self.socket = conn
953 self.connected = 1 992 self.connected = True
954 if DEBUG: 993 if DEBUG:
955 print "DCC connection from %s:%d" % ( 994 print "DCC connection from %s:%d" % (
956 self.peeraddress, self.peerport) 995 self.peeraddress, self.peerport)
957 self.irclibobj._handle_event( 996 self.irclibobj._handle_event(
958 self, 997 self,