Prechádzať zdrojové kódy

ircd/meetbot: Use try/except to reconnect if needed.

Luther Blissett 3 rokov pred
rodič
commit
73ffece558
2 zmenil súbory, kde vykonal 133 pridanie a 118 odobranie
  1. 132 117
      bin/ircd/script/meetbot.py
  2. 1 1
      bin/ircd/src/main.rs

+ 132 - 117
bin/ircd/script/meetbot.py

@@ -18,150 +18,165 @@ PICKLE_DB = "meetbot.pickle"
 # TODO: while this is nice to support, it would perhaps be better to do it
 # all over the same connection rather than opening a socket for each channel.
 async def channel_listen(host, port, nick, chan):
-    logging.info("%s: Connecting to %s:%s", chan, host, port)
-    reader, writer = await asyncio.open_connection(host, port)
-
-    logging.debug("%s: Send CAP msg", chan)
-    msg = "CAP REQ : no-history\r\n"
-    writer.write(msg.encode("utf-8"))
-
-    logging.debug("%s: Send NICK msg", chan)
-    msg = f"NICK {nick}\r\n"
-    writer.write(msg.encode("utf-8"))
-
-    logging.debug("%s: Send CAP END msg", chan)
-    msg = "CAP END\r\n"
-    writer.write(msg.encode("utf-8"))
-
-    logging.debug("%s: Send JOIN msg", chan)
-    msg = f"JOIN {chan}\r\n"
-    writer.write(msg.encode("utf-8"))
-
-    logging.info("%s: Listening to channel", chan)
-    while True:
-        msg = await reader.readline()
-        msg = msg.decode("utf8")
-        if not msg:
-            continue
-
-        split_msg = msg.split(" ")
-        command = split_msg[1]
-        nick = split_msg[0][1:].rsplit("!", 1)[0]
-        logging.debug("%s: Recv: %s", chan, msg.rstrip())
-
-        if command == "PRIVMSG":
-            msg_title = msg.split(" ")[3][1:].rstrip()
-            if not msg_title:
-                logging.info("%s: Recv empty PRIVMSG, ignoring", chan)
+    try:
+        logging.info("%s: Connecting to %s:%s", chan, host, port)
+        reader, writer = await asyncio.open_connection(host, port)
+
+        logging.debug("%s: Send CAP msg", chan)
+        msg = "CAP REQ : no-history\r\n"
+        writer.write(msg.encode("utf-8"))
+
+        logging.debug("%s: Send NICK msg", chan)
+        msg = f"NICK {nick}\r\n"
+        writer.write(msg.encode("utf-8"))
+
+        logging.debug("%s: Send CAP END msg", chan)
+        msg = "CAP END\r\n"
+        writer.write(msg.encode("utf-8"))
+
+        logging.debug("%s: Send JOIN msg", chan)
+        msg = f"JOIN {chan}\r\n"
+        writer.write(msg.encode("utf-8"))
+
+        logging.info("%s: Listening to channel", chan)
+        while True:
+            msg = await reader.readline()
+            msg = msg.decode("utf8")
+            if not msg:
                 continue
 
-            if msg_title == "!start":
-                logging.info("%s: Got !start", chan)
-                topics = CHANS[chan]["topics"]
-                reply = f"PRIVMSG {chan} :Meeting started"
-                logging.info("%s: Send: %s", chan, reply)
-                writer.write((reply + "\r\n").encode("utf-8"))
-                await writer.drain()
+            split_msg = msg.split(" ")
+            command = split_msg[1]
+            nick_c = split_msg[0][1:].rsplit("!", 1)[0]
+            logging.debug("%s: Recv: %s", chan, msg.rstrip())
+
+            if command == "PRIVMSG":
+                msg_title = msg.split(" ")[3][1:].rstrip()
+                if not msg_title:
+                    logging.info("%s: Recv empty PRIVMSG, ignoring", chan)
+                    continue
 
-                if len(topics) == 0:
-                    reply = f"PRIVMSG {chan} :No topics"
+                if msg_title == "!start":
+                    logging.info("%s: Got !start", chan)
+                    topics = CHANS[chan]["topics"]
+                    reply = f"PRIVMSG {chan} :Meeting started"
                     logging.info("%s: Send: %s", chan, reply)
                     writer.write((reply + "\r\n").encode("utf-8"))
                     await writer.drain()
-                    continue
 
-                reply = f"PRIVMSG {chan} :Topics:"
-                logging.info("%s: Send: %s", chan, reply)
-                writer.write((reply + "\r\n").encode("utf-8"))
-                await writer.drain()
+                    if len(topics) == 0:
+                        reply = f"PRIVMSG {chan} :No topics"
+                        logging.info("%s: Send: %s", chan, reply)
+                        writer.write((reply + "\r\n").encode("utf-8"))
+                        await writer.drain()
+                        continue
 
-                for i, topic in enumerate(topics):
-                    reply = f"PRIVMSG {chan} :{i+1}. {topic}"
+                    reply = f"PRIVMSG {chan} :Topics:"
                     logging.info("%s: Send: %s", chan, reply)
                     writer.write((reply + "\r\n").encode("utf-8"))
                     await writer.drain()
 
-                cur_topic = topics.pop(0)
-                reply = f"PRIVMSG {chan} :Current topic: {cur_topic}\r\n"
-                CHANS[chan]["topics"] = topics
-                writer.write(reply.encode("utf-8"))
-                await writer.drain()
-                continue
-
-            if msg_title == "!end":
-                logging.info("%s: Got !end", chan)
-                reply = f"PRIVMSG {chan} :Meeting ended"
-                logging.info("%s: Send: %s", chan, reply)
-                writer.write((reply + "\r\n").encode("utf-8"))
-                await writer.drain()
-                continue
+                    for i, topic in enumerate(topics):
+                        reply = f"PRIVMSG {chan} :{i+1}. {topic}"
+                        logging.info("%s: Send: %s", chan, reply)
+                        writer.write((reply + "\r\n").encode("utf-8"))
+                        await writer.drain()
 
-            if msg_title == "!topic":
-                logging.info("%s: Got !topic", chan)
-                topic = msg.split(" ", 4)
+                    cur_topic = topics.pop(0)
+                    reply = f"PRIVMSG {chan} :Current topic: {cur_topic}\r\n"
+                    CHANS[chan]["topics"] = topics
+                    writer.write(reply.encode("utf-8"))
+                    await writer.drain()
+                    continue
 
-                if len(topic) != 5:
-                    logging.debug("%s: Topic msg len not 5, skipping", chan)
+                if msg_title == "!end":
+                    logging.info("%s: Got !end", chan)
+                    reply = f"PRIVMSG {chan} :Meeting ended"
+                    logging.info("%s: Send: %s", chan, reply)
+                    writer.write((reply + "\r\n").encode("utf-8"))
+                    await writer.drain()
                     continue
 
-                topic = topic[4].rstrip() + f" (by {nick})"
+                if msg_title == "!topic":
+                    logging.info("%s: Got !topic", chan)
+                    topic = msg.split(" ", 4)
+
+                    if len(topic) != 5:
+                        logging.debug("%s: Topic msg len not 5, skipping",
+                                      chan)
+                        continue
+
+                    topic = topic[4].rstrip() + f" (by {nick_c})"
+
+                    if topic == "":
+                        logging.debug("%s: Topic message empty, skipping",
+                                      chan)
+                        continue
+
+                    topics = CHANS[chan]["topics"]
+                    if topic not in topics:
+                        topics.append(topic)
+                        CHANS[chan]["topics"] = topics
+                        logging.debug("%s: Appended topic to channel topics",
+                                      chan)
+                        reply = f"PRIVMSG {chan} :Added topic: {topic}"
+                        logging.info("%s: Send: %s", chan, reply)
+                    else:
+                        logging.debug("%s: Topic already in list of topics",
+                                      chan)
+                        reply = f"PRIVMSG {chan} :Topic already in list"
+                        logging.info("%s: Send: %s", chan, reply)
 
-                if topic == "":
-                    logging.debug("%s: Topic message empty, skipping", chan)
+                    writer.write((reply + "\r\n").encode("utf-8"))
+                    await writer.drain()
                     continue
 
-                topics = CHANS[chan]["topics"]
-                if topic not in topics:
-                    topics.append(topic)
-                    CHANS[chan]["topics"] = topics
-                    logging.debug("%s: Appended topic to channel topics", chan)
-                    reply = f"PRIVMSG {chan} :Added topic: {topic}"
-                    logging.info("%s: Send: %s", chan, reply)
-                else:
-                    logging.debug("%s: Topic already in list of topics", chan)
-                    reply = f"PRIVMSG {chan} :Topic already in list"
+                if msg_title == "!list":
+                    logging.info("%s: Got !list", chan)
+                    topics = CHANS[chan]["topics"]
+                    if len(topics) == 0:
+                        reply = f"PRIVMSG {chan} :No topics"
+                    else:
+                        reply = f"PRIVMSG {chan} :Topics:"
+
                     logging.info("%s: Send: %s", chan, reply)
+                    writer.write((reply + "\r\n").encode("utf-8"))
+                    await writer.drain()
 
-                writer.write((reply + "\r\n").encode("utf-8"))
-                await writer.drain()
-                continue
+                    for i, topic in enumerate(topics):
+                        reply = f"PRIVMSG {chan} :{i+1}. {topic}"
+                        logging.info("%s: Send: %s", chan, reply)
+                        writer.write((reply + "\r\n").encode("utf-8"))
+                        await writer.drain()
 
-            if msg_title == "!list":
-                logging.info("%s: Got !list", chan)
-                topics = CHANS[chan]["topics"]
-                if len(topics) == 0:
-                    reply = f"PRIVMSG {chan} :No topics"
-                else:
-                    reply = f"PRIVMSG {chan} :Topics:"
+                    continue
 
-                logging.info("%s: Send: %s", chan, reply)
-                writer.write((reply + "\r\n").encode("utf-8"))
-                await writer.drain()
+                if msg_title == "!next":
+                    logging.info("%s: Got !next", chan)
+                    topics = CHANS[chan]["topics"]
+                    if len(topics) == 0:
+                        reply = f"PRIVMSG {chan} :No further topics"
+                    else:
+                        cur_topic = topics.pop(0)
+                        CHANS[chan]["topics"] = topics
+                        reply = f"PRIVMSG {chan} :Current topic: {cur_topic}"
 
-                for i, topic in enumerate(topics):
-                    reply = f"PRIVMSG {chan} :{i+1}. {topic}"
                     logging.info("%s: Send: %s", chan, reply)
                     writer.write((reply + "\r\n").encode("utf-8"))
                     await writer.drain()
+                    continue
 
-                continue
-
-            if msg_title == "!next":
-                logging.info("%s: Got !next", chan)
-                topics = CHANS[chan]["topics"]
-                if len(topics) == 0:
-                    reply = f"PRIVMSG {chan} :No further topics"
-                else:
-                    cur_topic = topics.pop(0)
-                    CHANS[chan]["topics"] = topics
-                    reply = f"PRIVMSG {chan} :Current topic: {cur_topic}"
-
-                logging.info("%s: Send: %s", chan, reply)
-                writer.write((reply + "\r\n").encode("utf-8"))
-                await writer.drain()
-                continue
-
-    return
+    except KeyboardInterrupt:
+        pass
+    except ConnectionRefusedError:
+        logging.warning("%s: Connection refused, trying again in 3s...", chan)
+        await asyncio.sleep(3)
+        await channel_listen(host, port, nick, chan)
+    except Exception as e:
+        logging.error("EXCEPTION: %s", e)
+        logging.warn("%s: Connection interrupted. Reconnecting in 3s...", chan)
+        await asyncio.sleep(3)
+        await channel_listen(host, port, nick, chan)
 
 
 async def main(debug=False):
@@ -223,7 +238,7 @@ if __name__ == "__main__":
 
     try:
         asyncio.run(main(debug=DBG))
-    except:
+    except KeyboardInterrupt:
         print("\rCaught ^C, saving pickle and exiting")
 
     with open(PICKLE_DB, "wb") as fdesc:

+ 1 - 1
bin/ircd/src/main.rs

@@ -1,7 +1,7 @@
-use std::fmt;
 use async_channel::Receiver;
 use async_executor::Executor;
 use async_std::sync::{Arc, Mutex};
+use std::fmt;
 
 use log::{info, warn};
 use rand::rngs::OsRng;