Anonymous avatar Anonymous committed 84a707f

Version 0.2.0.

Comments (0)

Files changed (6)

+1999-08-21  Joel Rosdahl  <joel@rosdahl.net>
+
+	* Released version 0.2.0.
+
+	* servermap: Updated to work with irclib 0.2.0.
+
+	* irccat: Updated to work with irclib 0.2.0.
+
+	* ircbot.py: Updated to work with irclib 0.2.0.  The bot now
+ 	checks every minute that it is connected.  If it's not, it
+ 	reconnects.
+
+	* irclib.py: Changes in how to create a ServerConnection object.
+  	Made the code for handling disconnection hopefully more robust.
+  	Renamed connect() to sconnect().
+
 1999-06-19  Joel Rosdahl  <joel@rosdahl.net>
 
 	* irclib.py: Released 0.1.0.
 VERSION := $(shell sed -n -e '/VERSION = /{s/VERSION = \(.*\), \(.*\), \(.*\)/\1.\2.\3/;p;}' <irclib.py)
 
 main:
-	echo "Nothing to be made."
+	@echo "Nothing to be made."
 
 dist:
 	mkdir irclib-$(VERSION)
 
 from irclib import *
 
+# Every RECONNECT_INTERVAL seconds, check if the bot is connected and
+# reconnect it if it isn't.
+RECONNECT_INTERVAL = 60
+
 class SingleServerIRCBot:
     def __init__(self, server_list, nickname, realname, channels_file="bot.channels"):
         self.channels = {}
 
         self.nickname = nickname
         self.realname = realname
-        self.connect()
+        self.connection = self.irc.server()
         for numeric in all_events:
             self.connection.add_global_handler(numeric, self.event_dispatcher)
+        self.connection.execute_delayed(RECONNECT_INTERVAL, self.__connected_checker, ())
+        self.connect()
+
+    def __connected_checker(self):
+        self.connection.execute_delayed(RECONNECT_INTERVAL, self.__connected_checker, ())
+        if not self.connection.is_connected():
+            self.jump_server()
 
     def connect(self):
         password = None
         if len(self.server_list[self.current_server]) > 2:
             password = self.server_list[self.current_server][2]
-        self.connection = self.irc.server_connect(self.server_list[self.current_server][0],
-                                                  self.server_list[self.current_server][1],
-                                                  self.nickname,
-                                                  self.nickname,
-                                                  self.realname,
-                                                  password)
+        try:
+            self.connection.connect(self.server_list[self.current_server][0],
+                                    self.server_list[self.current_server][1],
+                                    self.nickname,
+                                    self.nickname,
+                                    self.realname,
+                                    password)
+        except ServerConnectionError:
+            pass
 
     def jump_server(self):
-        self.get_connection().quit("Jumping servers")
+        if self.connection.is_connected():
+            self.get_connection().quit("Jumping servers")
         self.current_server = (self.current_server + 1) % len(self.server_list)
         self.connect()
 
                 c.ctcp_reply(nick_from_nickmask(e.source()), "PING " + e.arguments()[1])
     
     def on_error(self, c, e):
-        self.jump_server()
         # XXX join channels here, etc.
+        pass
         
     def on_join(self, c, e):
         self.channels[lower_irc_string(e.target())].add_nick(e.source())
             return self.modes["k"]
         else:
             return None
-
-    def is_(self):
-        return self.has_mode("")
-
-    def is_(self):
-        return self.has_mode("")
 
 irc = irclib.IRC()
 try:
-    c = irc.server_connect(server, port, nickname, nickname, nickname)
+    c = irc.server().connect(server, port, nickname, nickname, nickname)
 except irclib.ServerConnectionError, x:
     print x
     sys.exit(1)
 import time
 import types
 
-VERSION = 0, 1, 0
+VERSION = 0, 2, 0
 DEBUG = 0
 
 # TODO
 # (maybe) color parser convenience functions
 # documentation (including all event types)
 # (maybe) add awareness of different types of ircds
+# send data asynchronously to the server
 
 # NOTES
 # -----
         self.fn_to_add_timeout = fn_to_add_timeout
         self.connections = []
         self.handlers = {}
-        self.delayed_commands = [] # list of (time, function, arguments)
+        self.delayed_commands = [] # list of tuples in the format (time, function, arguments)
 
         self.add_global_handler("ping", _ping_ponger, -42)
 
-    def server_connect(self, server, port, nick, username, ircname, password=None):
-        """Connect to an IRC server.
+    def server(self):
+        """Creates and returns an IRC server object."""
 
-        Returns a ServerConnection object.
-        """
-
-        c = ServerConnection(self, server, port, nick, username, ircname, password)
+        c = ServerConnection(self)
         self.connections.append(c)
-        if self.fn_to_add_socket:
-            self.fn_to_add_socket(c._get_socket())
         return c
 
     def DCC_connect(self, host, port):
         Timeouts will be processed every second.
         """
         while 1:
-            (i, o, e) = select.select(map(lambda x: x._get_socket(),
-                                          self.connections),
-                                      [],
-                                      [],
-                                      1)
+            sockets = map(lambda x: x._get_socket(), self.connections)
+            sockets = filter(lambda x: x != None, sockets)
+            (i, o, e) = select.select(sockets, [], [], 1)
             self.process_data(i)
             self.process_timeout()
 
 
 class ServerConnection(Connection):
     # Creates a ServerConnection object.
-    def __init__(self, irclibobj, server, port, nickname, username, ircname, password):
+    def __init__(self, irclibobj):
         Connection.__init__(self, irclibobj)
+        self.connected = 0  # Not connected yet.
+
+    def connect(self, server, port, nickname, username, ircname, password=None):
+        """(Re)connect to a server.
+
+        This function can be called to reconnect a closed connection.
+
+        Returns the ServerConnection object.
+        """
+        if self.connected:
+            self.quit("Changing server")
+
+        self.socket = None
+        self.previous_buffer = ""
+        self.handlers = {}
+        self.real_server_name = ""
+        self.real_nickname = nickname
         self.server = server
         self.port = port
         self.nickname = nickname
         self.username = username
         self.ircname = ircname
         self.password = password
-        self.connected = 0  # Not connected yet.
-        self.socket = None
-        self.previous_buffer = ""
-        self.handlers = {}
-        self.real_server_name = ""
-        self.real_nickname = nickname
-
-        self.connect_to_server()
-
-    def connect_to_server(self):
-        """(Re)connect to server.
-
-        This function can be called to reconnect a closed connection.
-        """
-        if self.connected:
-            self.quit("Changing server")
         self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
         try:
             self.socket.connect(self.server, self.port)
         except socket.error, x:
             raise ServerConnectionError, "Couldn't connect to socket: %s" % x
         self.connected = 1
+        if self.irclibobj.fn_to_add_socket:
+            self.irclibobj.fn_to_add_socket(self.socket)
 
         # Log on...
         if self.password:
             self.pass_(self.password)
         self.nick(self.nickname)
         self.user(self.username, self.ircname)
+        return self
 
+    def close(self):
+        """This method closes the connection permanently; after it is
+        called the object is unusable."""
+
+        self.disconnect("Closing object")
+        self.irclibobj._remove_connection(self)
+        
     def _get_socket(self):
         return self.socket
 
             new_data = self.socket.recv(2**14)
         except socket.error, x:
             # The server hung up.
-            self._handle_event(Event("disconnect",
-                                     self.get_server_name(),
-                                     None,
-                                     []))
+            self.disconnect("Connection reset by peer")
             return
         if not new_data:
             # Read nothing: connection must be down.
             for fn in self.handlers[event.eventtype()]:
                 fn(self, event)
 
+    def is_connected(self):
+        return self.connected
+
     def add_global_handler(self, *args):
         """See documentation for IRC.add_global_handler."""
         apply(self.irclibobj.add_global_handler, args)
     def admin(self, server=""):
         self.send_raw(string.strip(string.join(["ADMIN", server])))
 
-    def connect(self, target, port="", server=""):
-        self.send_raw("CONNECT %s%s%s" % (target,
-                                          port and (" " + port),
-                                          server and (" " + server)))
-
     def ctcp(self, ctcptype, target, parameter=""):
         ctcptype = string.upper(ctcptype)
         self.privmsg(target, "\001%s%s\001" % (ctcptype, parameter and (" " + parameter) or ""))
     def disconnect(self, message=""):
         """Hang up the connection."""
         self.connected = 0
-        self.irclibobj._remove_connection(self)
         try:
             self.socket.close()
         except socket.error, x:
             pass
+        self.socket = None
         self._handle_event(Event("disconnect", self.server, "", [message]))
 
     def exit(self, message=""):
     def quit(self, message=""):
         self.send_raw("QUIT" + (message and (" :" + message)))
 
+    def sconnect(self, target, port="", server=""):
+        self.send_raw("CONNECT %s%s%s" % (target,
+                                          port and (" " + port),
+                                          server and (" " + server)))
+
     def send_raw(self, string):
         """Send raw string to server.
 
 sys.stdout.write("Connecting to server...")
 sys.stdout.flush()
 try:
-    c = irc.server_connect(server, port, nickname, nickname, nickname)
+    c = irc.server().connect(server, port, nickname, nickname, nickname)
 except irclib.ServerConnectionError, x:
     print x
     sys.exit(1)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.