Exemple #1
0
def cmd_hello(data, server, witem):
    if not server or not server.connected:
        irssi.prnt("Not connected to server")

    if data:
        server.command("MSG %s Hello!" % data)
    elif isinstance(witem, irssi.Channel) or isinstance(witem, irssi.Query):
        witem.command("MSG %s Hello!" % witem.name)
    else:
        irssi.prnt("Nick not given, and no active channel/query in window")
def cmd_insult(data, server, witem):
    if not server or not server.connected:
        irssi.prnt("Not connected to server")
    insult = "thou %s %s %s!" % (random.choice(c1), random.choice(c2),
                                 random.choice(c3))
    if data:
        server.command("MSG %s %s %s" % (witem.name, data, insult))
    elif isinstance(witem, irssi.Channel) or isinstance(witem, irssi.Query):
        witem.command("MSG %s %s" % (witem.name, insult))
    else:
        irssi.prnt("Nick not given, and no active channel/query in window")
    def update(self, info):
        if not self.filter_event(info):
            return

        if self.debug:
            irssi.prnt("RStatus update: " + pprint.pformat(info))

        for conn, client_info in self.clients.items():
            if info["type"] == "message" and not client_info["send_messages"]:
                continue

            self.client_send(conn, info)
    def status(self, data, server, window):
        irssi.prnt("RStatus: Current Status: ")
        irssi.prnt("Connected clients: {0}".format(len(self.clients)))
        irssi.prnt("Server Socket OK? {0}".format(self.socket != False))

        for key, (info, etime) in self.lasts.items():
            etime = time.strftime("%Y/%m/%d %H:%M:%S", time.localtime(etime))
            irssi.prnt("Last {0}: {1} at {2}".format(key, info, etime))
    def client_try_send(self, fd, condition, conn, init=False):
        if conn not in self.clients or (not init and conn.fileno() != fd):
            return False

        try:
            sent = conn.send(self.clients[conn]["send_queue"])
            if not init:
                assert sent > 0
        except Exception, e:
            if isinstance(e, socket.error) and e.errno == errno.EAGAIN and \
               init:
                sent = 0
            else:
                if self.debug:
                    irssi.prnt("RStatus: Client send failed")
                    irssi.prnt(traceback.format_exc())

                self.client_drop(conn, "SEND IO Error")
                return False
    def __init__(self, debug=False):
        self.debug = debug
        self.lasts = {}
        self.create_settings()
        self.load_settings()
        self.create_socket()

        if self.debug:
            irssi.prnt("RStatus loaded. Windows:")
            irssi.prnt(pprint.pformat(self.window_all()))

        irssi.signal_add("setup changed", self.load_settings)
        irssi.signal_add("setup reread", self.load_settings)

        irssi.signal_add("window hilight", self.windowhilight)
        irssi.signal_add("message private", self.privmsg)
        irssi.signal_add("message public", self.pubmsg)

        irssi.signal_add("channel destroyed", self.channeldestroyed)
        irssi.signal_add("query destroyed", self.querydestroyed)

        irssi.command_bind("rstatus", self.status)
    def client_drop(self, conn, reason, notify=False):
        if self.debug:
            irssi.prnt("RStatus: Dropping client: '{0}'".format(reason))
        self.last_set("drop", reason)

        clientinfo = self.clients[conn]
        del self.clients[conn]

        tags = clientinfo["watches"].values() + clientinfo["timeouts"].values()
        for tag in tags:
            irssi.get_script().source_remove(tag)

        if notify and len(clientinfo["send_queue"]) == 0:
            try:
                conn.send(json.dumps({"type": "disconnect_notice"}) + "\n")
            except:
                self.client_conn_close(conn)
            else:
                irssi.get_script().timeout_add(self.timeout_drop_notify * 1000,
                                               self.client_conn_close, conn)
        else:
            self.client_conn_close(conn)
    def load_settings(self, *args):
        nikeys = ["default_channels", "default_queries"]
        setkeys = ["override_notify", "override_ignore"]
        keys = nikeys + setkeys + ["socket"]

        settings = {}

        for key in keys:
            settings[key] = irssi.settings_get_str(key)

        for key in setkeys:
            settings[key] = set([i.lower() for i in settings[key].split()])

        for key in nikeys:
            if settings[key] not in ["notify", "ignore"]:
                irssi.prnt("RStatus: Warning: option " + key + " is invalid")

            settings[key] = (settings[key] == "notify")

        settings["socket"] = os.path.expanduser(settings["socket"])

        self.settings = settings
    def socket_activity(self, fd, condition, sock):
        if sock != self.socket or sock.fileno() != fd:
            return False

        try:
            (conn, address) = self.socket.accept()
        except:
            irssi.prnt("RStatus: Socket error:")
            irssi.prnt(traceback.format_exc())

            self.socket.close()
            self.socket = None
            return False

        if self.debug:
            irssi.prnt("RStatus: new client connected")

        if address == '':
            address = 'UNIX Socket'
        self.last_set("connect", address)

        conn.setblocking(False)

        clientinfo = {
            "send_queue": "",
            "recv_buffer": "",
            "send_messages": False,
            "watches": {},
            "timeouts": {}
        }

        clientinfo["watches"]["recv"] = \
            irssi.get_script().io_add_watch(conn, self.client_try_recv,
                                            conn, irssi.IO_IN)
        clientinfo["watches"]["err"] = \
            irssi.get_script().io_add_watch(conn, self.client_drop_ioerror,
                                            conn, irssi.IO_ERR)
        clientinfo["watches"]["hup"] = \
            irssi.get_script().io_add_watch(conn, self.client_drop_ioerror,
                                            conn, irssi.IO_HUP)

        self.clients[conn] = clientinfo

        self.client_timeout_set(conn, "recv", self.timeout_heartbeat,
                self.client_drop_timeout, (conn, "RECV Timeout (HB, F)"))
        self.client_new(conn)

        return True
    def client_try_recv(self, fd, condition, conn):
        if conn not in self.clients or conn.fileno() != fd:
            return False

        try:
            data = conn.recv(1024)
        except:
            if self.debug:
                irssi.prnt("RStatus: Client IO error:")
                irssi.prnt(traceback.format_exc())

            self.client_drop(conn, "RECV IO Error")
            return False

        if not data:
            if self.debug:
                irssi.prnt("RStatus: Client read failed")

            self.client_drop(conn, "RECV failed (EOF)")
            return False

        self.clients[conn]["recv_buffer"] += data

        if len(self.clients[conn]["recv_buffer"]) > self.cbuffer_limit:
            self.client_drop(conn, "RECV Buffer Overflow", notify=True)
            return False

        if "\n" in self.clients[conn]["recv_buffer"]:
            data_parts = self.clients[conn]["recv_buffer"].split("\n")
            self.clients[conn]["recv_buffer"] = data_parts[-1]
            data_parts = data_parts[:-1]

            for data in data_parts:
                if data == "":
                    continue

                try:
                    data = json.loads(data)
                    assert isinstance(data, dict)
                    self.client_recv(conn, data)

                    # Happens when we receive a disconnect request
                    if conn not in self.clients:
                        return False
                except:
                    if self.debug:
                        irssi.prnt("RStatus: Client parse failed")
                        irssi.prnt(traceback.format_exc())

                    self.client_drop(conn, "RECV BAD JSON", notify=True)
                    return False

        if len(self.clients[conn]["recv_buffer"]) > 0:
            timeout = self.timeout_txrx
            reason = "RX"
        else:
            timeout = self.timeout_heartbeat
            reason = "HB"
        reason = "RECV Timeout ({0})".format(reason)

        self.client_timeout_set(conn, "recv", timeout,
                                self.client_drop_timeout, (conn, reason))

        return True