Mercurial > xib
comparison irclib.py @ 260:9a2302e8382b
(irclib) created a "Channel" class
Signed-off-by: Charly COSTE <changaco@changaco.net>
author | Charly COSTE <changaco@changaco.net> |
---|---|
date | Sat, 13 Mar 2010 17:38:47 +0100 |
parents | e64b574afa8f |
children | 53f4d9aa2b52 |
comparison
equal
deleted
inserted
replaced
259:3b318108e9e0 | 260:9a2302e8382b |
---|---|
408 if connection in self.connections: | 408 if connection in self.connections: |
409 self.connections.remove(connection) | 409 self.connections.remove(connection) |
410 if self.fn_to_remove_socket: | 410 if self.fn_to_remove_socket: |
411 self.fn_to_remove_socket(connection._get_socket()) | 411 self.fn_to_remove_socket(connection._get_socket()) |
412 | 412 |
413 | |
414 LEFT, LEAVING, NOT_IN, JOINING, JOINED = range(5) | |
415 | |
416 class Channel: | |
417 | |
418 def __init__(self, connection, channel_name): | |
419 self.connection = connection | |
420 self.channel_name = channel_name | |
421 self.callbacks = [] | |
422 self.state = NOT_IN | |
423 | |
424 def _callback(self, error): | |
425 if not error: | |
426 self.state = JOINED | |
427 else: | |
428 self.state = NOT_IN | |
429 m = 'channel "'+self.channel_name+'" on connection "'+str(self.connection)+'"' | |
430 if len(self.callbacks) == 0: | |
431 self.connection.irclibobj.bot.error(1, 'no join callback for '+m, debug=True) | |
432 else: | |
433 self.connection.irclibobj.bot.error(1, 'calling '+str(len(self.callbacks))+' join callback(s) for '+m, debug=True) | |
434 for f in self.callbacks: | |
435 f(self.channel_name, error) | |
436 | |
437 def add_callback(self, callback): | |
438 if callback and not callback in self.callbacks: | |
439 self.callbacks.append(callback) | |
440 | |
441 def join(self, key=None, callback=None): | |
442 self.state = JOINING | |
443 self.key = key | |
444 self.add_callback(callback) | |
445 self.connection.send_raw("JOIN %s%s" % (self.channel_name, (key and (" " + key)))) | |
446 | |
447 def part(self, message=None): | |
448 if self.state <= NOT_IN: | |
449 return | |
450 self.state = LEAVING | |
451 self.connection.send_raw("PART " + self.channel_name + (message and (" " + message))) | |
452 | |
453 def rejoin(self): | |
454 self.join(key=self.key) | |
455 | |
456 def remove_callback(self, callback): | |
457 try: | |
458 self.callbacks.remove(callback) | |
459 except ValueError: | |
460 pass | |
461 | |
462 | |
413 _rfc_1459_command_regexp = re.compile("^(:(?P<prefix>[^ ]+) +)?(?P<command>[^ ]+)( *(?P<argument> .+))?") | 463 _rfc_1459_command_regexp = re.compile("^(:(?P<prefix>[^ ]+) +)?(?P<command>[^ ]+)( *(?P<argument> .+))?") |
414 | 464 |
415 class Connection: | 465 class Connection: |
416 """Base class for IRC connections. | 466 """Base class for IRC connections. |
417 | 467 |
462 self.port = port | 512 self.port = port |
463 self.nickname = nickname | 513 self.nickname = nickname |
464 self.nick_callbacks = [] | 514 self.nick_callbacks = [] |
465 self.join_callbacks = {} | 515 self.join_callbacks = {} |
466 self.lock = threading.RLock() | 516 self.lock = threading.RLock() |
467 self.left_channels = [] | 517 self.channels = {} |
468 self.channels = [] | |
469 self.channels_keys = {} | |
470 self.irc_id = None | 518 self.irc_id = None |
471 self.previous_buffer = "" | 519 self.previous_buffer = "" |
472 self.handlers = {} | 520 self.handlers = {} |
473 self.real_server_name = "" | 521 self.real_server_name = "" |
474 self.new_nickname = None | 522 self.new_nickname = None |
592 if self.nick(self.nickname): | 640 if self.nick(self.nickname): |
593 self.user(self.username, self.ircname) | 641 self.user(self.username, self.ircname) |
594 | 642 |
595 # Rejoin channels | 643 # Rejoin channels |
596 if len(self.channels) > 0: | 644 if len(self.channels) > 0: |
597 for channel in self.channels: | 645 for channel in self.channels.itervalues(): |
598 if self.channels_keys.has_key(channel): | 646 channel.rejoin() |
599 key = self.channels_keys[channel] | |
600 else: | |
601 key = '' | |
602 self.join(channel, key=key) | |
603 | 647 |
604 self.lock.release() | 648 self.lock.release() |
605 return self | 649 return self |
606 | 650 |
607 | 651 |
611 else: | 655 else: |
612 self.irclibobj.bot.error(1, 'calling '+str(len(self.nick_callbacks))+' nick callback(s) for "'+self.__str__()+'"', debug=True) | 656 self.irclibobj.bot.error(1, 'calling '+str(len(self.nick_callbacks))+' nick callback(s) for "'+self.__str__()+'"', debug=True) |
613 for f in self.nick_callbacks: | 657 for f in self.nick_callbacks: |
614 f(error, arguments=arguments) | 658 f(error, arguments=arguments) |
615 self.nick_callbacks = [] | 659 self.nick_callbacks = [] |
616 | |
617 | |
618 def _call_join_callbacks(self, channel, error): | |
619 self.lock.acquire() | |
620 m = 'channel "'+channel+'" on connection "'+str(self)+'"' | |
621 if not self.join_callbacks.has_key(channel) or len(self.join_callbacks[channel]) == 0: | |
622 self.irclibobj.bot.error(1, 'no join callback for '+m, debug=True) | |
623 else: | |
624 self.irclibobj.bot.error(1, 'calling '+str(len(self.join_callbacks[channel]))+' join callback(s) for '+m, debug=True) | |
625 for f in self.join_callbacks[channel]: | |
626 f(channel, error) | |
627 self.join_callbacks.pop(channel, None) | |
628 self.lock.release() | |
629 | 660 |
630 | 661 |
631 def add_nick_callback(self, callback): | 662 def add_nick_callback(self, callback): |
632 self.nick_callbacks.append(callback) | 663 self.nick_callbacks.append(callback) |
633 | 664 |
795 if self.irc_id != prefix: | 826 if self.irc_id != prefix: |
796 self.irc_id = prefix | 827 self.irc_id = prefix |
797 if DEBUG: | 828 if DEBUG: |
798 print "irc_id: %s" % (prefix) | 829 print "irc_id: %s" % (prefix) |
799 channel = target.lower() | 830 channel = target.lower() |
800 if not channel in self.channels: | 831 if self.channels[channel].state != JOINED: |
801 self.channels.append(channel) | 832 self.channels[channel]._callback(None) |
802 if channel in self.left_channels: | |
803 self.left_channels.remove(channel) | |
804 self._call_join_callbacks(channel, None) | |
805 | 833 |
806 if command in ['inviteonlychan', 'bannedfromchan', 'channelisfull', 'badchannelkey']: | 834 if command in ['inviteonlychan', 'bannedfromchan', 'channelisfull', 'badchannelkey']: |
807 self._call_join_callbacks(arguments[0].lower(), command) | 835 self.channels[arguments[0].lower()]._callback(command) |
808 | 836 |
809 if DEBUG: | 837 if DEBUG: |
810 print "command: %s, source: %s, target: %s, arguments: %s" % ( | 838 print "command: %s, source: %s, target: %s, arguments: %s" % ( |
811 command, prefix, target, arguments) | 839 command, prefix, target, arguments) |
812 | 840 |
912 | 940 |
913 nicks -- List of nicks. | 941 nicks -- List of nicks. |
914 """ | 942 """ |
915 self.send_raw("ISON " + " ".join(nicks)) | 943 self.send_raw("ISON " + " ".join(nicks)) |
916 | 944 |
917 def join(self, channel, callback=None, key=""): | 945 def join(self, channel_name, callback=None, key=""): |
918 """Send a JOIN command.""" | 946 """Send a JOIN command.""" |
919 if callback: | 947 if not self.channels.has_key(channel_name): |
920 self.add_join_callback(channel, callback) | 948 self.channels[channel_name] = Channel(self, channel_name) |
921 if key: | 949 self.channels[channel_name].join(key=key, callback=callback) |
922 self.channels_keys[channel] = key | |
923 self.send_raw("JOIN %s%s" % (channel, (key and (" " + key)))) | |
924 | 950 |
925 def kick(self, channel, nick, comment=""): | 951 def kick(self, channel, nick, comment=""): |
926 """Send a KICK command.""" | 952 """Send a KICK command.""" |
927 self.send_raw("KICK %s %s%s" % (channel, nick, (comment and (" :" + comment)))) | 953 self.send_raw("KICK %s %s%s" % (channel, nick, (comment and (" :" + comment)))) |
928 | 954 |
982 self.send_raw("NOTICE %s :%s" % (target, text)) | 1008 self.send_raw("NOTICE %s :%s" % (target, text)) |
983 | 1009 |
984 def oper(self, nick, password): | 1010 def oper(self, nick, password): |
985 """Send an OPER command.""" | 1011 """Send an OPER command.""" |
986 self.send_raw("OPER %s %s" % (nick, password)) | 1012 self.send_raw("OPER %s %s" % (nick, password)) |
987 | |
988 def _remove_channel(self, channel): | |
989 if channel in self.channels: | |
990 self.channels.remove(channel) | |
991 if not channel in self.left_channels: | |
992 self.left_channels.append(channel) | |
993 | 1013 |
994 def part(self, channels, message=""): | 1014 def part(self, channels, message=""): |
995 """Send a PART command.""" | 1015 """Send a PART command.""" |
996 try: | 1016 try: |
997 if isinstance(channels, basestring): | 1017 if isinstance(channels, basestring): |
998 self._remove_channel(channels) | 1018 self.channels[channels].part(message=message) |
999 self.send_raw("PART " + channels + (message and (" " + message))) | |
1000 else: | 1019 else: |
1001 for channel in channels: | 1020 for channel in channels: |
1002 self._remove_channel(channel) | 1021 self.channels[channel].part(message=message) |
1003 self.send_raw("PART " + ",".join(channels) + (message and (" " + message))) | |
1004 except ServerNotConnectedError: | 1022 except ServerNotConnectedError: |
1005 self.disconnect(volontary=True) | 1023 self.disconnect(volontary=True) |
1006 self.connect() | 1024 self.connect() |
1007 | 1025 |
1008 def pass_(self, password): | 1026 def pass_(self, password): |