From 298dd8eb5d89e9e65b6a35c2bf80d1e9ac337dfc Mon Sep 17 00:00:00 2001 From: Dpeta Date: Sun, 5 Jun 2022 01:08:38 +0200 Subject: [PATCH] IRC Metadata draft support for moods --- irc.py | 55 ++++++++++++++++++++++++++++++++++++---------- oyoyo/helpers.py | 5 +++++ oyoyo/ircevents.py | 11 ++++++++++ 3 files changed, 60 insertions(+), 11 deletions(-) diff --git a/irc.py b/irc.py index 066d659..da3a8fd 100644 --- a/irc.py +++ b/irc.py @@ -209,6 +209,13 @@ class PesterIRC(QtCore.QThread): @QtCore.pyqtSlot() def updateMood(self): me = self.mainwindow.profile() + # Moods via metadata + try: + helpers.metadata(self.cli, '*', "set", "mood", str(me.mood.value())) + except socket.error as e: + PchumLog.warning(e) + self.setConnectionBroken() + # Backwards compatibility try: helpers.msg(self.cli, "#pesterchum", "MOOD >%d" % (me.mood.value())) except socket.error as e: @@ -385,6 +392,13 @@ class PesterHandler(DefaultCommandHandler): self.parent.memoReceived.emit(msg[1:msg.index("]")], handle, msg) else: self.parent.noticeReceived.emit(handle, msg) + def metadata(self, target, nick, key, visibility, value): + # The format of the METADATA server notication is: + # METADATA + if key == "mood": + mood = Mood(int(value)) + self.parent.moodUpdated.emit(nick, mood) + def privmsg(self, nick, chan, msg): handle = nick[0:nick.find("!")] if len(msg) == 0: @@ -477,12 +491,38 @@ class PesterHandler(DefaultCommandHandler): from time import sleep sleep(0.5) # To prevent TLS from dying %d" % (mymood)) + + def keyvalue(self, target, handle_us, handle_owner, key, visibility, *value): + # The format of the METADATA server notication is: + # METADATA + if key == "mood": + mood = Mood(int(value[0])) + self.parent.moodUpdated.emit(handle_owner, mood) + def metadatasubok(self, *params): + PchumLog.info("metadatasubok: " + str(params)) + + def nomatchingkey(self, target, our_handle, failed_handle, key, *error): + # Try to get moods the old way if metadata fails. + PchumLog.info("nomatchingkey: " + failed_handle) + chumglub = "GETMOOD " + try: + helpers.msg(self.client, "#pesterchum", chumglub + failed_handle) + except socket.error as e: + PchumLog.warning(e) + self.parent.setConnectionBroken() + + def nicknameinuse(self, server, cmd, nick, msg): newnick = "pesterClient%d" % (random.randint(100,999)) helpers.nick(self.client, newnick) self.parent.nickCollision.emit(nick, newnick) + def quit(self, nick, reason): handle = nick[0:nick.find("!")] PchumLog.info("---> recv \"QUIT %s: %s\"" % (handle, reason)) @@ -513,6 +553,7 @@ class PesterHandler(DefaultCommandHandler): if handle == self.parent.mainwindow.randhandler.randNick: self.parent.mainwindow.randhandler.setRunning(True) self.parent.moodUpdated.emit(handle, Mood("chummy")) + def mode(self, op, channel, mode, *handles): PchumLog.debug("op=" + str(op)) PchumLog.debug("channel=" + str(channel)) @@ -683,20 +724,12 @@ class PesterHandler(DefaultCommandHandler): self.client.send('PONG', server) def getMood(self, *chums): - chumglub = "GETMOOD " + # Try to get mood via metadata get. + # If it fails the old code is excecuted. for c in chums: chandle = c.handle - if len(chumglub+chandle) >= 350: - try: - helpers.msg(self.client, "#pesterchum", chumglub) - except socket.error as e: - PchumLog.warning(e) - self.parent.setConnectionBroken() - chumglub = "GETMOOD " - chumglub += chandle - if chumglub != "GETMOOD ": try: - helpers.msg(self.client, "#pesterchum", chumglub) + helpers.metadata(self.client, chandle, "get", "mood") except socket.error as e: PchumLog.warning(e) self.parent.setConnectionBroken() diff --git a/oyoyo/helpers.py b/oyoyo/helpers.py index b30f7da..e991b6f 100644 --- a/oyoyo/helpers.py +++ b/oyoyo/helpers.py @@ -66,6 +66,11 @@ def ctcp(cli, handle, cmd, msg=""): def ctcp_reply(cli, handle, cmd, msg=""): notice(cli, str(handle), "\x01%s %s\x01" % (cmd.upper(), msg)) +def metadata(cli, target, subcommand, *params): + # IRC metadata draft specification + # https://gist.github.com/k4bek4be/92c2937cefd49990fbebd001faf2b237 + cli.send("METADATA", target, subcommand, *params) + def msgrandom(cli, choices, dest, user=None): o = "%s: " % user if user else "" o += random.choice(choices) diff --git a/oyoyo/ircevents.py b/oyoyo/ircevents.py index fc59887..10dabd0 100644 --- a/oyoyo/ircevents.py +++ b/oyoyo/ircevents.py @@ -180,6 +180,16 @@ numeric_events = { "502": "usersdontmatch", } +# IRC metadata draft specification +# https://gist.github.com/k4bek4be/92c2937cefd49990fbebd001faf2b237 +metadata_numeric_events = { + "761": "keyvalue", + "762": "metadataend", + "766": "nomatchingkey", + "770": "metadatasubok", + } +numeric_events.update(metadata_numeric_events) + generated_events = [ # Generated events "dcc_connect", @@ -205,6 +215,7 @@ protocol_events = [ "quit", "invite", "pong", + "metadata" # Metadata specification ] all_events = generated_events + protocol_events + list(numeric_events.values())