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