コード例 #1
0
    def __init__(self, conf):
        '''Starts the irc client library and XMLRPC Server.'''
        self.remote_irc_servers = {}
        self.events = EventList()

        # Makes sure files exist
        #TODO: Reference documentation on how to generate these files.
        if conf.cert_file and not os.path.exists(conf.cert_file):
            raise RuntimeError('cert_file "%s" not found!' % conf.cert_file)
        if conf.key_file and conf.key_file and not os.path.exists(conf.key_file):
            raise RuntimeError('key_file "%s" not found!' % conf.key_file)
        if not conf.accepted_certs_file:
            certs_required = ssl.CERT_NONE
        elif not os.path.exists(conf.accepted_certs_file):
            raise RuntimeError('accepted_certs_file "%s" not found!' % conf.accepted_certs_file)
        else:
            certs_required = ssl.CERT_REQUIRED

        self.irc_client = irclib.IRC()
        self.irc_client.add_global_handler("all_events", self._handle_irc_event)

        # Start xmlrpc server
        self.xmlrpc_server = securexmlrpc.SecureXMLRPCServer(
            (conf.bind_address, conf.bind_port),
            certfile = conf.cert_file,
            keyfile = conf.key_file,
            ca_certs = conf.accepted_certs_file,
            cert_reqs = certs_required,
        )
        self.xmlrpc_server.register_instance(self)
        self.xmlrpc_server.timeout = 0.1 # Make handle_request() non-blocking
コード例 #2
0
ファイル: proxy.py プロジェクト: mbrown1413/pirc
    def __init__(self, conf):
        """Starts the irc client library and XMLRPC Server."""
        self.remote_irc_servers = {}
        self.events = EventList()

        # Makes sure files exist
        # TODO: Reference documentation on how to generate these files.
        if conf.cert_file and not os.path.exists(conf.cert_file):
            raise RuntimeError('cert_file "%s" not found!' % conf.cert_file)
        if conf.key_file and conf.key_file and not os.path.exists(conf.key_file):
            raise RuntimeError('key_file "%s" not found!' % conf.key_file)
        if not conf.accepted_certs_file:
            certs_required = ssl.CERT_NONE
        elif not os.path.exists(conf.accepted_certs_file):
            raise RuntimeError('accepted_certs_file "%s" not found!' % conf.accepted_certs_file)
        else:
            certs_required = ssl.CERT_REQUIRED

        self.irc_client = irclib.IRC()
        self.irc_client.add_global_handler("all_events", self._handle_irc_event)

        # Start xmlrpc server
        self.xmlrpc_server = securexmlrpc.SecureXMLRPCServer(
            (conf.bind_address, conf.bind_port),
            certfile=conf.cert_file,
            keyfile=conf.key_file,
            ca_certs=conf.accepted_certs_file,
            cert_reqs=certs_required,
        )
        self.xmlrpc_server.register_instance(self)
        self.xmlrpc_server.timeout = 0.1  # Make handle_request() non-blocking
コード例 #3
0
ファイル: mm1.py プロジェクト: jedrzejowski/mops-project
    def __init__(self, queueSize, mi):
        self.queueSize = queueSize
        self.mi = mi

        self.pkgInQ = 0
        self.eventList = EventList()
        self.__onArrival = None
        self.__onService = None
        self.__onDrop = None

        self.statPkgArrives = 0
        self.statPkgArrived = 0
        self.statPkgServiced = 0
        self.statPkgDropped = 0
        self.statServiceTime = 0
        self.statPkgDelays = []
コード例 #4
0
ファイル: rootview.py プロジェクト: cyberixae/kunquat
    def _perform_updates(self, signals):
        visibility_manager = self._ui_model.get_visibility_manager()
        visibility_update = visibility_manager.get_visible()

        opened = visibility_update - self._visible
        closed = self._visible - visibility_update

        for ui in opened:
            # Check settings for UI visibility
            is_show_allowed = visibility_manager.is_show_allowed()

            if ui == UI_MAIN:
                if is_show_allowed:
                    self._main_window.show()
            elif ui == UI_ABOUT:
                self._about_window = AboutWindow()
                self._about_window.set_ui_model(self._ui_model)
                if is_show_allowed:
                    self._about_window.show()
            elif ui == UI_EVENT_LOG:
                self._event_log = EventList()
                self._event_log.set_ui_model(self._ui_model)
                if is_show_allowed:
                    self._event_log.show()

        for ui in closed:
            if ui == UI_MAIN:
                visibility_manager.hide_all()
                self._main_window.hide()
            elif ui == UI_ABOUT:
                self._about_window.unregister_updaters()
                self._about_window.deleteLater()
                self._about_window = None
            elif ui == UI_EVENT_LOG:
                self._event_log.unregister_updaters()
                self._event_log.deleteLater()
                self._event_log = None

        self._visible = set(visibility_update)

        if self._visible:
            if 'signal_start_save_module' in signals:
                self._start_save_module()
            if 'signal_save_module_finished' in signals:
                self._on_save_module_finished()
        else:
            QApplication.quit()

        self._ui_model.clock()
コード例 #5
0
ファイル: server.py プロジェクト: itucsdb1603/itucsdb1603
def create_app():
    app = Flask(__name__)
    app.register_blueprint(site)
    app.register_blueprint(mods)
    app.register_blueprint(imgPosts)
    app.register_blueprint(places)
    app.register_blueprint(events)
    app.register_blueprint(TextPosts)
    app.register_blueprint(hashtags)
    app.register_blueprint(hashtagContents)
    app.register_blueprint(Topics)
    app.topiclist = TopicList()
    app.moderatorlist = ModeratorList()
    app.imgpostlist = ImgPostList()
    app.textpostlist = TextPostList()
    app.hashtags = Hashtags()
    app.hashtagContents = HashtagContents()
    app.eventlist = EventList()
    app.placelist = PlaceList()
    app.secret_key = "secret key"
    login_manager.init_app(app)
    login_manager.login_view = 'site.signup_page'
    return app
コード例 #6
0
ファイル: rootview.py プロジェクト: cyberixae/kunquat
class RootView():

    def __init__(self):
        self._ui_model = None
        self._task_executer = None
        self._updater = None
        self._visible = set()
        self._main_window = MainWindow()
        self._about_window = None
        self._event_log = None
        self._module = None

    def set_ui_model(self, ui_model):
        self._ui_model = ui_model
        self._main_window.set_ui_model(ui_model)
        self._updater = self._ui_model.get_updater()
        self._updater.register_updater(self._perform_updates)
        self._module = self._ui_model.get_module()

    def show_main_window(self):
        visibility_manager = self._ui_model.get_visibility_manager()
        visibility_manager.show_main()

    def setup_module(self):
        module = self._ui_model.get_module()
        module_path = cmdline.get_kqt_file()
        if module_path:
            module.set_path(module_path)
            module.execute_load(self._task_executer)
        else:
            module.execute_create_sandbox(self._task_executer)

    def set_task_executer(self, task_executer):
        self._task_executer = task_executer

    def _perform_updates(self, signals):
        visibility_manager = self._ui_model.get_visibility_manager()
        visibility_update = visibility_manager.get_visible()

        opened = visibility_update - self._visible
        closed = self._visible - visibility_update

        for ui in opened:
            # Check settings for UI visibility
            is_show_allowed = visibility_manager.is_show_allowed()

            if ui == UI_MAIN:
                if is_show_allowed:
                    self._main_window.show()
            elif ui == UI_ABOUT:
                self._about_window = AboutWindow()
                self._about_window.set_ui_model(self._ui_model)
                if is_show_allowed:
                    self._about_window.show()
            elif ui == UI_EVENT_LOG:
                self._event_log = EventList()
                self._event_log.set_ui_model(self._ui_model)
                if is_show_allowed:
                    self._event_log.show()

        for ui in closed:
            if ui == UI_MAIN:
                visibility_manager.hide_all()
                self._main_window.hide()
            elif ui == UI_ABOUT:
                self._about_window.unregister_updaters()
                self._about_window.deleteLater()
                self._about_window = None
            elif ui == UI_EVENT_LOG:
                self._event_log.unregister_updaters()
                self._event_log.deleteLater()
                self._event_log = None

        self._visible = set(visibility_update)

        if self._visible:
            if 'signal_start_save_module' in signals:
                self._start_save_module()
            if 'signal_save_module_finished' in signals:
                self._on_save_module_finished()
        else:
            QApplication.quit()

        self._ui_model.clock()

    def unregister_updaters(self):
        self._updater.unregister_updater(self._perform_updates)
        self._main_window.unregister_updaters()

    def _start_save_module(self):
        self._main_window.setEnabled(False)
        self._module.flush(self._execute_save_module)

    def _execute_save_module(self):
        task = self._module.execute_save(self._task_executer)

    def _on_save_module_finished(self):
        self._module.finish_save()
        self._main_window.setEnabled(True)
コード例 #7
0
ファイル: proxy.py プロジェクト: mbrown1413/pirc
class IRCProxyServer(object):
    """The XMLRPC interface that proxy clients use.

    An instance of this class is served via XMLRPC.  Proxy clients use it to
    get events and send events to IRC servers.  This means that any functions
    that don't start with an underscore is served directly via XMLRPC.

    When an event is received from an IRC server, _handle_irc_event is called.

    """

    def __init__(self, conf):
        """Starts the irc client library and XMLRPC Server."""
        self.remote_irc_servers = {}
        self.events = EventList()

        # Makes sure files exist
        # TODO: Reference documentation on how to generate these files.
        if conf.cert_file and not os.path.exists(conf.cert_file):
            raise RuntimeError('cert_file "%s" not found!' % conf.cert_file)
        if conf.key_file and conf.key_file and not os.path.exists(conf.key_file):
            raise RuntimeError('key_file "%s" not found!' % conf.key_file)
        if not conf.accepted_certs_file:
            certs_required = ssl.CERT_NONE
        elif not os.path.exists(conf.accepted_certs_file):
            raise RuntimeError('accepted_certs_file "%s" not found!' % conf.accepted_certs_file)
        else:
            certs_required = ssl.CERT_REQUIRED

        self.irc_client = irclib.IRC()
        self.irc_client.add_global_handler("all_events", self._handle_irc_event)

        # Start xmlrpc server
        self.xmlrpc_server = securexmlrpc.SecureXMLRPCServer(
            (conf.bind_address, conf.bind_port),
            certfile=conf.cert_file,
            keyfile=conf.key_file,
            ca_certs=conf.accepted_certs_file,
            cert_reqs=certs_required,
        )
        self.xmlrpc_server.register_instance(self)
        self.xmlrpc_server.timeout = 0.1  # Make handle_request() non-blocking

    def _run(self):
        """Run proxy server forever in a loop."""
        while True:
            self._loop_iteration()

    def _loop_iteration(self):
        """A single iteration of the _run()'s main loop.

        Handles one xmlrpc request if available and pending IRC events.

        """
        self.xmlrpc_server.handle_request()
        self.irc_client.process_once(0.1)

    def _dispatch(self, method, params):
        """Delegate XMLRPC requests to the appropriate method.

        The method could be in a few different places.  Here are the places
        that are checked, in order:
            # IRCProxyServer.<method>
            # If the method name starts with "server_", that prefix is taken
              off and RemoteIRCServer.<method_stripped> is searched.  The first
              argument is assumed to be the server name, and the method inside
              the appropriate server is called.
            # If the method name starts with "channel_", that prefix is taken
              off and RemoteIRCChannel.<method_stripped> is searched.  The
              first two arguments are assumed to be server name and channel
              name, and server._dispatch_channel_method is called for the
              appropriate server.

        :param method:
            Name of the XMLRPC method requested.

        :param params:
            A tuple of the parameters given in the XMLRPC call.

        :returns:
            The return value of the method that was called.  An XMLRPC Fault is
            returned for any errors.

        """
        # TODO: Double check typechecking in all _dispatch methods.

        try:

            # Method inside IRCProxyServer (this instance)
            func = getattr(self, method, None)
            if func != None and callable(func):
                return func(*params)

            # Look for method inside a RemoteIRCServer instance
            # Prefix of server_
            elif method.startswith("server_"):
                return self._dispatch_server(method, params)

            # Look for method inside a RemoteIRCChannel instance
            # Prefix of channel_
            elif method.startswith("channel_") and len(params) > 0:
                return self._dispatch_channel(method, params)

            # Method not found!
            raise ServerError('Method "%s" not found.' % method)

        except ServerError as e:
            # TODO: Log
            raise Fault(2, " ".join(e.args))

        except Exception as e:
            # TODO: Log
            traceback.print_exc()
            raise Fault(3, "Proxy server received an unexpected error.  See log file for details.")

    def _dispatch_server(self, method, params):
        """Dispatch for xmlrpc methods starting with _server."""

        # Check for method existence and callability
        server_method = method[len("server_") :]
        if not server_method.startswith("_") and callable(getattr(RemoteIRCServer, server_method, None)):

            # Get server
            if len(params) <= 0:
                raise ServerError('Not enough arguments for method "%s".' % method)
            server_name = params[0]
            type_check("server_name", server_name, basestring)
            if server_name not in self.remote_irc_servers:
                raise ServerError('Server with name "%s" was not found' % server_name)
            server = self.remote_irc_servers[server_name]

            # Call server method
            func = getattr(server, server_method)
            return func(*params[1:])

        raise ServerError('Method "%s" not found.' % method)

    def _dispatch_channel(self, method, params):
        """Dispatch for xmlrpc methods starting with _channel."""

        # Checks for methods existance an non-privacy are done in
        # RemoteIRCServer._dispatch_channel_method

        # Get server
        if len(params) <= 0:
            raise ServerError('Not enough arguments for method "%s".' % method)
        server_name = params[0]
        type_check("server_name", server_name, basestring)
        if server_name not in self.remote_irc_servers:
            raise ServerError('Server with name "%s" was not found' % server_name)
        server = self.remote_irc_servers[server_name]

        # Dispatch to corresponding server
        return server._dispatch_channel_method(method, params[1:])

    def _handle_irc_event(self, connection, irc_event):
        """Callback for any events from irclib.

        Converts the irc_event object into a dictionary, then gives the
        dictionary to the server it belongs to.

        :param connection:
            Connection that caused this event.  See irclib for details.

        :param irc_event:
            A small storage object for the incoming event provided by irclib.

        """

        try:

            # Ignore raw messages and pings
            if irc_event._eventtype == "all_raw_messages" or irc_event._eventtype == "ping":

                return

            irc_event.connection = connection
            event = format_irc_event(irc_event, self)
            if not event:
                return
            server = self.remote_irc_servers[event["server"]]
            server._handle_irc_event(event)

        except ServerError as e:
            # TODO: Log
            traceback.print_exc()

        except Exception as e:
            # TODO: Log
            traceback.print_exc()

    def get_events_since(self, start_time):
        type_check("start_time", start_time, int, float)
        if start_time < 0:
            raise ServerError("start_time must be a positive number.")

        events = self.events.get_events_since(start_time)
        for server in self.remote_irc_servers.itervalues():
            events.extend(server._get_events_since(start_time))
        return events

    def server_list(self):
        return self.remote_irc_servers.keys()

    def server_connect(self, server_name, nick_name, uri, port=6667, password="", ssl=False, ipv6=False):
        type_check("server_name", server_name, basestring)
        type_check("nick_name", nick_name, basestring)
        type_check("uri", uri, basestring)
        type_check("port", port, int)
        type_check("password", password, basestring)
        type_check("ssl", ssl, bool)
        type_check("ipv6", ipv6, bool)
        if port < 0 or port > 65535:
            raise ServerError("port must be between 0 and 65535 inclusive.")

        if not password:
            password = None
        if server_name in self.server_list():
            raise ServerError("Server with that name is already connected!")

        connection = self.irc_client.server()
        remote_server = RemoteIRCServer(connection, server_name, nick_name, uri, port, password, ssl, ipv6)
        self.remote_irc_servers[server_name] = remote_server
        self.events.append(type="server_connect", server=server_name)
        return True

    def server_disconnect(self, server_name, part_message=""):
        type_check("server_name", server_name, basestring)
        type_check("part_message", part_message, basestring)
        if server_name not in self.remote_irc_servers:
            raise ServerError('Server with name="%s" does not exist' % server_name)

        server = self.remote_irc_servers[server_name]
        server._disconnect(part_message)
        del self.remote_irc_servers[server_name]
        self.events.append(type="server_disconnect", server=server_name)
        return True
コード例 #8
0
ファイル: mm1.py プロジェクト: jedrzejowski/mops-project
class MM1:
    def __init__(self, queueSize, mi):
        self.queueSize = queueSize
        self.mi = mi

        self.pkgInQ = 0
        self.eventList = EventList()
        self.__onArrival = None
        self.__onService = None
        self.__onDrop = None

        self.statPkgArrives = 0
        self.statPkgArrived = 0
        self.statPkgServiced = 0
        self.statPkgDropped = 0
        self.statServiceTime = 0
        self.statPkgDelays = []

    def step2next(self):
        event = self.eventList.popEvent()

        if event is None:
            return

        if event.name == 'arrival':
            self.__arrival(event)
        if event.name == 'service':
            self.__service(event)

    def newArrival(self, delay):
        self.eventList.addEvent(delay, 'arrival')

    def __arrival(self, event):

        if self.pkgInQ == self.queueSize:
            self.statPkgDropped += 1
            if self.__onDrop is not None:
                self.__onDrop(event)
            return

        self.pkgInQ += 1
        self.statPkgArrived += 1
        self.statPkgDelays.append(event.time)

        if self.pkgInQ == 1:
            self.__genService()

        if self.__onArrival is not None:
            self.__onArrival(event)

    def __service(self, event):
        self.pkgInQ -= 1
        self.statPkgServiced += 1
        self.statServiceTime += event.delay

        i = self.statPkgServiced - 1
        self.statPkgDelays[i] = event.time - self.statPkgDelays[i]

        if self.pkgInQ > 0:
            self.__genService()

        if self.__onService is not None:
            self.__onService(event)

    def __genService(self):
        self.eventList.addEvent(numpy.random.poisson(self.mi), 'service')

    def onArrival(self, func):
        self.__onArrival = func

    def onService(self, func):
        self.__onService = func

    def onDrop(self, func):
        self.__onDrop = func

    def printStatus(self):

        pkgPerSec = self.statPkgServiced / self.eventList.getTime() * 1000
        servicePrec = self.statServiceTime / self.eventList.getTime() * 100

        pkgDropRate = self.statPkgDropped / (self.statPkgArrived + self.statPkgDropped) * 100

        print(f"    statPkgArrived  = {self.statPkgArrived:14.0f}")
        print(f"    statPkgServiced = {self.statPkgServiced:14.0f}")
        print(f"    statPkgDropped  = {self.statPkgDropped:14.0f}")
        print(f"    pkgDropRate     = {pkgDropRate:14.1f} [%]")
        print(f"    pkgPerSec       = {pkgPerSec:14.3f} [s]")
        print(f"    servicePrec     = {servicePrec:14.1f} [%]")
        print(f"    pkgDelayMean    = {numpy.mean(self.statPkgDelays):14.1f} ")
コード例 #9
0
class IRCProxyServer(object):
    '''The XMLRPC interface that proxy clients use.

    An instance of this class is served via XMLRPC.  Proxy clients use it to
    get events and send events to IRC servers.  This means that any functions
    that don't start with an underscore is served directly via XMLRPC.

    When an event is received from an IRC server, _handle_irc_event is called.

    '''

    def __init__(self, conf):
        '''Starts the irc client library and XMLRPC Server.'''
        self.remote_irc_servers = {}
        self.events = EventList()

        # Makes sure files exist
        #TODO: Reference documentation on how to generate these files.
        if conf.cert_file and not os.path.exists(conf.cert_file):
            raise RuntimeError('cert_file "%s" not found!' % conf.cert_file)
        if conf.key_file and conf.key_file and not os.path.exists(conf.key_file):
            raise RuntimeError('key_file "%s" not found!' % conf.key_file)
        if not conf.accepted_certs_file:
            certs_required = ssl.CERT_NONE
        elif not os.path.exists(conf.accepted_certs_file):
            raise RuntimeError('accepted_certs_file "%s" not found!' % conf.accepted_certs_file)
        else:
            certs_required = ssl.CERT_REQUIRED

        self.irc_client = irclib.IRC()
        self.irc_client.add_global_handler("all_events", self._handle_irc_event)

        # Start xmlrpc server
        self.xmlrpc_server = securexmlrpc.SecureXMLRPCServer(
            (conf.bind_address, conf.bind_port),
            certfile = conf.cert_file,
            keyfile = conf.key_file,
            ca_certs = conf.accepted_certs_file,
            cert_reqs = certs_required,
        )
        self.xmlrpc_server.register_instance(self)
        self.xmlrpc_server.timeout = 0.1 # Make handle_request() non-blocking

    def _run(self):
        '''Run proxy server forever in a loop.'''
        while True:
            self._loop_iteration()

    def _loop_iteration(self):
        '''A single iteration of the _run()'s main loop.

        Handles one xmlrpc request if available and pending IRC events.

        '''
        self.xmlrpc_server.handle_request()
        self.irc_client.process_once(0.1)

    def _dispatch(self, method, params):
        '''Delegate XMLRPC requests to the appropriate method.

        The method could be in a few different places.  Here are the places
        that are checked, in order:
            # IRCProxyServer.<method>
            # If the method name starts with "server_", that prefix is taken
              off and RemoteIRCServer.<method_stripped> is searched.  The first
              argument is assumed to be the server name, and the method inside
              the appropriate server is called.
            # If the method name starts with "channel_", that prefix is taken
              off and RemoteIRCChannel.<method_stripped> is searched.  The
              first two arguments are assumed to be server name and channel
              name, and server._dispatch_channel_method is called for the
              appropriate server.

        :param method:
            Name of the XMLRPC method requested.

        :param params:
            A tuple of the parameters given in the XMLRPC call.

        :returns:
            The return value of the method that was called.  An XMLRPC Fault is
            returned for any errors.

        '''
        #TODO: Double check typechecking in all _dispatch methods.

        try:

            # Method inside IRCProxyServer (this instance)
            func = getattr(self, method, None)
            if func != None and callable(func):
                return func(*params)

            # Look for method inside a RemoteIRCServer instance
            # Prefix of server_
            elif method.startswith("server_"):
                return self._dispatch_server(method, params)

            # Look for method inside a RemoteIRCChannel instance
            # Prefix of channel_
            elif method.startswith("channel_") and len(params) > 0:
                return self._dispatch_channel(method, params)

            # Method not found!
            raise ServerError('Method "%s" not found.' % method)

        except ServerError as e:
            #TODO: Log
            raise Fault(2, ' '.join(e.args))

        except Exception as e:
            #TODO: Log
            traceback.print_exc()
            raise Fault(3, "Proxy server received an unexpected error.  See log file for details.")

    def _dispatch_server(self, method, params):
        '''Dispatch for xmlrpc methods starting with _server.'''

        # Check for method existence and callability
        server_method = method[len("server_"):]
        if not server_method.startswith("_") and \
                callable(getattr(RemoteIRCServer, server_method, None)):

            # Get server
            if len(params) <= 0:
                raise ServerError('Not enough arguments for method "%s".' % method)
            server_name = params[0]
            type_check("server_name", server_name, basestring)
            if server_name not in self.remote_irc_servers:
                raise ServerError('Server with name "%s" was not found' % server_name)
            server = self.remote_irc_servers[server_name]

            # Call server method
            func = getattr(server, server_method)
            return func(*params[1:])

        raise ServerError('Method "%s" not found.' % method)

    def _dispatch_channel(self, method, params):
        '''Dispatch for xmlrpc methods starting with _channel.'''

        # Checks for methods existance an non-privacy are done in
        # RemoteIRCServer._dispatch_channel_method

        # Get server
        if len(params) <= 0:
            raise ServerError('Not enough arguments for method "%s".' % method)
        server_name = params[0]
        type_check("server_name", server_name, basestring)
        if server_name not in self.remote_irc_servers:
            raise ServerError('Server with name "%s" was not found' % server_name)
        server = self.remote_irc_servers[server_name]

        # Dispatch to corresponding server
        return server._dispatch_channel_method(method, params[1:])

    def _handle_irc_event(self, connection, irc_event):
        '''Callback for any events from irclib.

        Converts the irc_event object into a dictionary, then gives the
        dictionary to the server it belongs to.

        :param connection:
            Connection that caused this event.  See irclib for details.

        :param irc_event:
            A small storage object for the incoming event provided by irclib.

        '''

        try:

            # Ignore raw messages and pings
            if irc_event._eventtype == "all_raw_messages" or \
                irc_event._eventtype == "ping":

                return

            irc_event.connection = connection
            event = format_irc_event(irc_event, self)
            if not event: return
            server = self.remote_irc_servers[event['server']]
            server._handle_irc_event(event)

        except ServerError as e:
            #TODO: Log
            traceback.print_exc()

        except Exception as e:
            #TODO: Log
            traceback.print_exc()

    def get_events_since(self, start_time):
        type_check("start_time", start_time, int, float)
        if start_time < 0:
            raise ServerError("start_time must be a positive number.")

        events = self.events.get_events_since(start_time)
        for server in self.remote_irc_servers.itervalues():
            events.extend(server._get_events_since(start_time))
        return events

    def server_list(self):
        return self.remote_irc_servers.keys()

    def server_connect(self, server_name, nick_name, uri, port=6667,
                       password="", ssl=False, ipv6=False):
        type_check("server_name", server_name, basestring)
        type_check("nick_name", nick_name, basestring)
        type_check("uri", uri, basestring)
        type_check("port", port, int)
        type_check("password", password, basestring)
        type_check("ssl", ssl, bool)
        type_check("ipv6", ipv6, bool)
        if port < 0 or port > 65535:
            raise ServerError("port must be between 0 and 65535 inclusive.")

        if not password:
            password = None
        if server_name in self.server_list():
            raise ServerError("Server with that name is already connected!")

        connection = self.irc_client.server()
        remote_server = RemoteIRCServer(connection, server_name, nick_name,
                                        uri, port, password, ssl, ipv6)
        self.remote_irc_servers[server_name] = remote_server
        self.events.append(type="server_connect", server=server_name)
        return True

    def server_disconnect(self, server_name, part_message=""):
        type_check("server_name", server_name, basestring)
        type_check("part_message", part_message, basestring)
        if server_name not in self.remote_irc_servers:
            raise ServerError('Server with name="%s" does not exist' % server_name)

        server = self.remote_irc_servers[server_name]
        server._disconnect(part_message)
        del self.remote_irc_servers[server_name]
        self.events.append(type="server_disconnect", server=server_name)
        return True