From 43cae42f577c3734ebcfd6d968d35d4602cd3a0b Mon Sep 17 00:00:00 2001 From: Eragon Date: Tue, 15 Mar 2022 22:56:48 +0100 Subject: [PATCH] Add Ctrl-C clean shutdown and ignore v43 connexions errors --- bridge.py | 11 +++++-- shoutbox.py | 83 ++++++++++++++++++++++++++++++++--------------------- 2 files changed, 60 insertions(+), 34 deletions(-) diff --git a/bridge.py b/bridge.py index 909e0b6..f777926 100644 --- a/bridge.py +++ b/bridge.py @@ -1,4 +1,5 @@ import logging +import sys from irc import IRC @@ -32,5 +33,11 @@ irc.start("Shoutbox[darks]", password, nick) for c in channels: irc.join(f"#{c}") -shoutbox.run() -irc.run() +try: + shoutbox.run() + irc.run() + +except KeyboardInterrupt: + irc.stop() + shoutbox.stop() + sys.exit(0) diff --git a/shoutbox.py b/shoutbox.py index a953691..7d7068d 100644 --- a/shoutbox.py +++ b/shoutbox.py @@ -17,6 +17,8 @@ class Shoutbox(object): self.cookies = cookies self._callbacks = [] self.irc_clients = {} # pseudo: [IRC(), date] + self.running = False + self._handler = Thread(target=self._handle) for channel, last_id in self.channels.items(): messages = json.loads(r.get(f"https://www.planet-casio.com/Fr/shoutbox/api/read?since={last_id}&channel={channel}&format=text").text)['messages'] @@ -24,39 +26,17 @@ class Shoutbox(object): self.channels[channel] = m['id'] def run(self): - def handler(): - while True: - for channel, last_id in self.channels.items(): - messages = json.loads(r.get(f"https://www.planet-casio.com/Fr/shoutbox/api/read?since={last_id}&channel={channel}&format=text").text)['messages'] - for m in messages: - logging.debug(m) - self.channels[channel] = m['id'] - message = SBMessage(m, channel) - for event, callback in self._callbacks: - author = Shoutbox.normalize(message.author) - # client is not known or is disconnected - if author not in self.irc_clients.keys() \ - or self.irc_clients[author][0].running == False: - self.irc_clients[author] = [ - IRC('irc.planet-casio.com', 6697), - datetime.datetime.now() - ] - self.irc_clients[author][0].start(f"{author}[s]", password, nick) - logging.debug(f"{author} has joined IRC") - # client is known but AFK - else: - self.irc_clients[author][1] = datetime.datetime.now() - logging.debug(f"{author} has updated IRC") + self.running = True + self._handler.start() - if event(message): - logging.info(f"matched {event.__name__}") - callback(message) - # kill afk clients - for c in self.irc_clients.values(): - if datetime.datetime.now() - c[1] > datetime.timedelta(hours=1): - c[0].stop() - time.sleep(1) - Thread(target=handler).start() + def stop(self): + logging.debug("STOP: Stop requests to planet-casio.com") + self.running = False + logging.debug("STOP: Halt all irc user threads") + for client in self.irc_clients: + self.irc_clients[client][0].stop() + self._handler.join() + logging.debug("STOP: Shoutbox thread closed") def on(self, event): """ Adds a callback to the IRC handler @@ -92,6 +72,45 @@ class Shoutbox(object): return [u[1] for u in USERS if u[0].lower() == pseudo.lower()][0] return pseudo.replace(' ', '_') + def _handle(self): + while self.running: + try: + for channel, last_id in self.channels.items(): + messages = json.loads(r.get(f"https://www.planet-casio.com/Fr/shoutbox/api/read?since={last_id}&channel={channel}&format=text").text)['messages'] + for m in messages: + logging.debug(m) + self.channels[channel] = m['id'] + message = SBMessage(m, channel) + if not self.running: + break + for event, callback in self._callbacks: + author = Shoutbox.normalize(message.author) + # client is not known or is disconnected + if author not in self.irc_clients.keys() \ + or self.irc_clients[author][0].running == False: + self.irc_clients[author] = [ + IRC('irc.planet-casio.com', 6697), + datetime.datetime.now() + ] + self.irc_clients[author][0].start(f"{author}[s]", password, nick) + logging.debug(f"{author} has joined IRC") + # client is known but AFK + else: + self.irc_clients[author][1] = datetime.datetime.now() + logging.debug(f"{author} has updated IRC") + + if event(message): + logging.info(f"matched {event.__name__}") + callback(message) + # kill afk clients + for c in self.irc_clients.values(): + if datetime.datetime.now() - c[1] > datetime.timedelta(hours=1): + c[0].stop() + except Exception as e: + logging.error(f"Faillure in Shoutbox thread {e}") + finally: + time.sleep(1) + class SBMessage(object): def __init__(self, raw, channel):