Ejemplo n.º 1
0
 def __init__(self, configuration):
     global connection
     """ initialise connection object. """
 
     self.configuration = configuration
     self.__conn_hooks__ = configuration.get_value('main', 'onconnect').split(',')
     self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     self._setupdone, self._connected, self._registered, self._passrequired, self.debug = (False, False, False, False, False)
     self.log = logging.getLogger('ashiema')
     self.basic = Basic(self)
     self._queue = Queue()
     self._evh = EventHandler()
     self.pluginloader = PluginLoader((self, self._evh))
     self.scheduler = Scheduler()
     self.tasks = {}
Ejemplo n.º 2
0
class Connection(object):
    """ Connection object to manage the connection 
        to the uplink """
        
    def __init__(self, configuration):
        global connection
        """ initialise connection object. """
    
        self.configuration = configuration
        self.__conn_hooks__ = configuration.get_value('main', 'onconnect').split(',')
        self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self._setupdone, self._connected, self._registered, self._passrequired, self.debug = (False, False, False, False, False)
        self.log = logging.getLogger('ashiema')
        self.basic = Basic(self)
        self._queue = Queue()
        self._evh = EventHandler()
        self.pluginloader = PluginLoader((self, self._evh))
        self.scheduler = Scheduler()
        self.tasks = {}

    """ information setup """
    def setup_info(self, nick = '', ident = '', real = ''):
        """ set up post connection info. """
        
        self.nick = nick
        self.ident = ident
        self.real = real
        self._setupdone = True
    
        return self

    def set_debug(self, debug = True):
        """ set connection debug logging. """
        
        self.debug = debug
        
        return self
    
    """ flag management """
    def shutdown(self):
        """ change the self._connection flag to shut down the bot """
        
        # unload all plugins
        self.pluginloader.unload()
        # shut down all leftover apscheduler tasks
        for task in self.tasks:
            self.scheduler.unschedule_job(task)
        # shut down the scheduler
        self.scheduler.shutdown()
        # change the value that controls the connection loop
        self._connected = False
        
    """ socket manipulation and management """
    def connect(self, address = '', port = '', _ssl = None, password = None):
        """ complete the connection process. """

        assert self._setupdone is True, 'Information setup has not been completed.'
        assert address and port, 'Parameters for connection have not been provided.'
        
        _ssl = True if _ssl == True or _ssl == "True" or _ssl == "true" else False
        if _ssl is True:
            self.connection = ssl.wrap_socket(self._socket)
            self.log.info("connection type: SSL")
        elif _ssl is False:
            self.connection = self._socket
            self.log.info("connection type: plain")
        else:
            self.connection = self._socket
            self.log.warning("connection type not specified, assuming plain.")
        if password is not None:
            self._passrequired, self._password = (True, password)
        self._evh.load_default_events()
        self.connection.connect((address, int(port)))
        # we're connected!
        self._connected = True
        
        return self
    
    def send(self, data):
        """ function to add a line to the sendqueue to be sent. """
        
        assert self._setupdone is True, 'Information setup has not been completed.'
        assert self._connected is True, 'Connection to the uplink has not yet been established.'

        self._queue.append(data.encode("UTF-8") + '\r\n')
    
    def _raw_send(self, data):
        """ allows sending of raw data directly to the uplink 
            assumes +data+ has received all necessary formatting to actually be read and processed by the uplink """
        
        assert self._setupdone is True, 'Information setup has not been completed.'
        assert self._connected is True, 'Connection to the uplink has not yet been established.'

        data = data.decode('UTF-8', 'ignore')
        self.connection.send(data.encode('UTF-8'))
   
    def run(self):
        """ runs the polling loop. 
            this should run off of two assertions:
            self._connected is true, and self._setupdone is true."""
        
        assert self._setupdone is True, 'Information setup has not been completed.'
        assert self._connected is True, 'Connection to the uplink has not yet been established.'
        
        # start the scheduler
        self.scheduler.start()
        # cycle counter
        _cc = 1
        while self._connected is True:
            try:
                # first, sleep so we don't slurp up CPU time like no tomorrow
                time.sleep(0.005)
                # send user registration if we're not already registered and about 35 cycles have passed
                if not self._registered and _cc is 20:
                    if self._passrequired: 
                        self.send("PASS :%s" % (self._password))
                        self._password = None
                    self.send("NICK %s" % (self.nick))
                    self.send("USER %s +iw %s :%s" % (self.nick, self.ident, self.real))
                    self._registered = True
                # now, select.
                r, w, e = select.select([self.connection], [], [self.connection], .025)
                # now GO!
                if self.connection in r:
                    self.parse(self.connection.recv(35000))
                # check if im in the errors
                if self.connection in e:
                    self._connected = False
                    self.log.severe("error during poll; aborting")
                    break
                # process the data thats in the queue
                try:
                    [self._raw_send(data) for data in [self._queue.pop() for count in xrange(0, 1)]]
                except (AssertionError, QueueError) as e:
                    pass
                except (KeyboardInterrupt, SystemExit) as e:
                    self.shutdown()
                _cc += 1
            except (KeyboardInterrupt, SystemExit) as e:
                self.shutdown()
        # what are we going to do after the loop closes?
        self.log.info("shutting down.")
        self.connection.close()
        self._socket.close()
        exit()
    
    """ data parsing and event dispatch """
    def parse(self, data):
        
        assert self._connected is True, 'Connection to the uplink has not yet been established.'
        
        data = data.split('\r\n')
        for line in data:
             # serialisation.
             line = Serialise(line, (self, self._evh))
             # fire off all events that match the data.
             self._evh.map_events(line)