Mercurial > xib
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, |