From 5b4673e0dd6c1996b506be42bf090cdcc27e866a Mon Sep 17 00:00:00 2001 From: Dpeta Date: Tue, 24 Aug 2021 15:49:50 +0200 Subject: [PATCH] Rewrote some aspects of channel mode management --- CHANGELOG.md | 12 +++ dataobjs.py | 17 +++- irc.py | 88 +++++++++++++---- memos.py | 225 ++++++++++++++++++++++++++++++++++++++++++++ oyoyo/client.py | 6 ++ oyoyo/cmdhandler.py | 14 ++- oyoyo/helpers.py | 5 + pesterchum.py | 2 + version.py | 4 +- 9 files changed, 346 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b0ed68..90ff979 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,17 @@ # Changelog (This document uses YYYY-MM-DD) +## [v2.1.3.1] - 2021-8-24 + +### Added + - Memo messages for the following channel modes: zMQNRODGPCrR (see https://www.unrealircd.org/docs/Channel_Modes for info) + - (Memo messages for registration is pretty much the only useful one out of these.) + - More comprehensive logging for DEBUG (Might be a bit obtuse so I'll probably make it more consistent later). + +### Fixed + - Rewrote channel mode function to fix crash when user and channel modes were set in a single command, this also fixes: + - Crash when being the only person in a non-persistent memo you own while having autoop enabled (with nickServ). + ## [v2.1.3] - 2021-8-09 ### Added @@ -18,6 +29,7 @@ ### Changed - Honk emote now only triggers when typing ':honk:' instead of on every 'honk'. +- Logging is now configured in logging.conf and logs are also writen to pesterchum.log by default. ## [v2.1.2] - 2021-4-16 diff --git a/dataobjs.py b/dataobjs.py index f459126..e40075a 100644 --- a/dataobjs.py +++ b/dataobjs.py @@ -1,3 +1,6 @@ +import logging, logging.config +logging.config.fileConfig('logging.conf') +PchumLog = logging.getLogger('pchumLogger') from PyQt5 import QtCore, QtGui from datetime import * import re @@ -167,7 +170,15 @@ class PesterProfile(object): caps = [l for l in handle if l.isupper()] if not caps: caps = [""] - initials = (handle[0]+caps[0]).upper() + PchumLog.debug("handle = " + str(handle)) + PchumLog.debug("caps = " + str(caps)) + # Fallback for invalid string + try: + initials = (handle[0]+caps[0]).upper() + except: + PchumLog.exception('') + initials = "XX" + PchumLog.debug("initials = " + str(initials)) if hasattr(self, 'time') and time: if self.time > time: return "F"+initials @@ -176,7 +187,7 @@ class PesterProfile(object): else: return "C"+initials else: - return (handle[0]+caps[0]).upper() + return initials def colorhtml(self): if self.color: return self.color.name() @@ -227,7 +238,9 @@ class PesterProfile(object): def memoopenmsg(self, syscolor, td, timeGrammar, verb, channel): (temporal, pcf, when) = (timeGrammar.temporal, timeGrammar.pcf, timeGrammar.when) timetext = timeDifference(td) + PchumLog.debug("pre pcf+self.initials()") initials = pcf+self.initials() + PchumLog.debug("post pcf+self.initials()") return "%s %s %s %s." % \ (syscolor.name(), self.colorhtml(), initials, timetext, verb, channel[1:].upper().replace("_", " ")) def memobanmsg(self, opchum, opgrammar, syscolor, initials, reason): diff --git a/irc.py b/irc.py index 4eec52f..0fdac69 100644 --- a/irc.py +++ b/irc.py @@ -269,6 +269,7 @@ class PesterIRC(QtCore.QThread): c = str(channel) m = str(mode) cmd = str(command) + PchumLog.debug("c=%s\nm=%s\ncmd=%s" % (c,m,cmd)) if cmd == "": cmd = None try: @@ -469,36 +470,87 @@ class PesterHandler(DefaultCommandHandler): self.parent.mainwindow.randhandler.setRunning(True) self.parent.moodUpdated.emit(handle, Mood("chummy")) def mode(self, op, channel, mode, *handles): - #channel = channel.decode('utf-8') + PchumLog.debug("op=" + str(op)) + PchumLog.debug("channel=" + str(channel)) + PchumLog.debug("mode=" + str(mode)) + PchumLog.debug("*handles=" + str(handles)) + if len(handles) <= 0: handles = [""] - #opnick = op.decode('utf-8')[0:op.decode('utf-8').find("!")] opnick = op[0:op.find("!")] - if op == channel or channel == self.parent.mainwindow.profile().handle: + PchumLog.debug("opnick=" + opnick) + + # Channel section + # Okay so, as I understand it channel modes will always be applied to a channel even if the commands also sets a mode to a user. + # So "MODE #channel +ro handleHandle" will set +r to channel #channel as well as set +o to handleHandle + # Therefore the bellow method causes a crash if both user and channel mode are being set in one command. + + #if op == channel or channel == self.parent.mainwindow.profile().handle: + # modes = list(self.parent.mainwindow.modes) + # if modes and modes[0] == "+": modes = modes[1:] + # if mode[0] == "+": + # for m in mode[1:]: + # if m not in modes: + # modes.extend(m) + # elif mode[0] == "-": + # for i in mode[1:]: + # try: + # modes.remove(i) + # except ValueError: + # pass + # modes.sort() + # self.parent.mainwindow.modes = "+" + "".join(modes) + + + # EXPIRIMENTAL FIX + # No clue how stable this is but since it doens't seem to cause a crash it's probably an improvement. + # This might be clunky with non-unrealircd IRC servers + channel_mode = "" + unrealircd_channel_modes = ['c', 'C', 'd', 'f', 'G', 'H', 'i', 'k', 'K', 'L', 'l', 'm', 'M', 'N', 'n', 'O', 'P', 'p', 'Q', 'R', 'r', 's', 'S', 'T', 't', 'V', 'z', 'Z'] + if any(md in mode for md in unrealircd_channel_modes): + PchumLog.debug("Channel mode in string.") modes = list(self.parent.mainwindow.modes) - if modes and modes[0] == "+": modes = modes[1:] - if mode[0] == "+": - for m in mode[1:]: - if m not in modes: - modes.extend(m) - elif mode[0] == "-": - for i in mode[1:]: - try: - modes.remove(i) - except ValueError: - pass + for md in unrealircd_channel_modes: + if mode.find(md)!= -1: # -1 means not found + PchumLog.debug("md=" + md) + if mode[0] == "+": + modes.extend(md) + channel_mode = "+" + md + elif mode[0] == "-": + try: + modes.remove(md) + channel_mode = "-" + md + except ValueError: + PchumLog.warning("Can't remove channel mode that isn't set.") + pass + self.parent.userPresentUpdate.emit("", channel, channel_mode+":%s" % (op)) + PchumLog.debug("pre-mode=" + str(mode)) + mode = mode.replace(md, "") + PchumLog.debug("post-mode=" + str(mode)) modes.sort() self.parent.mainwindow.modes = "+" + "".join(modes) + modes = [] cur = "+" for l in mode: if l in ["+","-"]: cur = l else: modes.append("%s%s" % (cur, l)) + PchumLog.debug("handles=" + str(handles)) + PchumLog.debug("enumerate(modes) = " + str(list(enumerate(modes)))) for (i,m) in enumerate(modes): - try: - self.parent.userPresentUpdate.emit(handles[i], channel, m+":%s" % (op)) - except IndexError: - self.parent.userPresentUpdate.emit("", channel, m+":%s" % (op)) + + # Server-set usermodes don't need to be passed. + if (handles == "") & ( ('x' in m) | ('z' in m) | ('o' in m) )!=True: + try: + self.parent.userPresentUpdate.emit(handles[i], channel, m+":%s" % (op)) + except: + PchumLog.exception('') + + #self.parent.userPresentUpdate.emit(handles[i], channel, m+":%s" % (op)) + # Passing an empty handle here might cause a crash. + #except IndexError: + #self.parent.userPresentUpdate.emit("", channel, m+":%s" % (op)) + def nick(self, oldnick, newnick): oldhandle = oldnick[0:oldnick.find("!")] if oldhandle == self.mainwindow.profile().handle: diff --git a/memos.py b/memos.py index 7b6f604..7f1a3ae 100644 --- a/memos.py +++ b/memos.py @@ -788,6 +788,116 @@ class PesterMemo(PesterConvo): msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Muted", True) self.textArea.append(convertTags(msg)) self.mainwindow.chatlog.log(self.channel, msg) + + #New + if modes.find("C") >= 0: + self.chanMod.setChecked(True) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "No-CTCP", True) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) + if modes.find("D") >= 0: + self.chanMod.setChecked(True) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Join Delayed", True) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) + if modes.find("f") >= 0: + self.chanMod.setChecked(True) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Flood Protected", True) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) + if modes.find("G") >= 0: + self.chanMod.setChecked(True) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Censored", True) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) + if modes.find("H") >= 0: + self.chanMod.setChecked(True) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Remembering Chat History", True) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) + if modes.find("k") >= 0: + self.chanMod.setChecked(True) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Key-only", True) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) + if modes.find("K") >= 0: + self.chanMod.setChecked(True) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "No-Knock", True) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) + if modes.find("L") >= 0: + self.chanMod.setChecked(True) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Redirecting", True) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) + if modes.find("K") >= 0: + self.chanMod.setChecked(True) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "No-Knock", True) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) + if modes.find("l") >= 0: + self.chanMod.setChecked(True) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Limiting maximum amount of users", True) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) + if modes.find("M") >= 0: + self.chanMod.setChecked(True) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Non-Auth muted", True) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) + if modes.find("N") >= 0: + self.chanMod.setChecked(True) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Handle-locked", True) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) + if modes.find("O") >= 0: + self.chanMod.setChecked(True) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "An Oper-Only channel", True) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) + if modes.find("P") >= 0: + self.chanMod.setChecked(True) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Permanent", True) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) + if modes.find("Q") >= 0: + self.chanMod.setChecked(True) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "No-kick", True) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) + if modes.find("R") >= 0: + self.chanMod.setChecked(True) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Registered users only", True) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) + if modes.find("r") >= 0: + self.chanMod.setChecked(True) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Registered", True) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) + if modes.find("z") >= 0: + self.chanMod.setChecked(True) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Secure-only", True) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) elif modes[0] == "-": for i in modes[1:]: try: @@ -818,6 +928,116 @@ class PesterMemo(PesterConvo): msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Muted", False) self.textArea.append(convertTags(msg)) self.mainwindow.chatlog.log(self.channel, msg) + + #New + if modes.find("C") >= 0: + self.chanMod.setChecked(False) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "No-CTCP", False) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) + if modes.find("D") >= 0: + self.chanMod.setChecked(False) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Join Delayed", False) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) + if modes.find("f") >= 0: + self.chanMod.setChecked(False) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Flood Protected", False) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) + if modes.find("G") >= 0: + self.chanMod.setChecked(False) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Censored", False) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) + if modes.find("H") >= 0: + self.chanMod.setChecked(False) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Remembering Chat History", False) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) + if modes.find("k") >= 0: + self.chanMod.setChecked(False) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Key-only", False) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) + if modes.find("K") >= 0: + self.chanMod.setChecked(False) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "No-Knock", False) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) + if modes.find("L") >= 0: + self.chanMod.setChecked(False) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Redirecting", False) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) + if modes.find("K") >= 0: + self.chanMod.setChecked(False) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "No-Knock", False) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) + if modes.find("l") >= 0: + self.chanMod.setChecked(False) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Limiting maximum amount of users", False) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) + if modes.find("M") >= 0: + self.chanMod.setChecked(False) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Non-Auth muted", False) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) + if modes.find("N") >= 0: + self.chanMod.setChecked(False) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Handle-locked", False) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) + if modes.find("O") >= 0: + self.chanMod.setChecked(False) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "An Oper-Only channel", False) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) + if modes.find("P") >= 0: + self.chanMod.setChecked(False) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Permanent", False) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) + if modes.find("Q") >= 0: + self.chanMod.setChecked(False) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "No-kick", False) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) + if modes.find("R") >= 0: + self.chanMod.setChecked(False) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Registered users only", False) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) + if modes.find("r") >= 0: + self.chanMod.setChecked(False) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Registered", False) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) + if modes.find("z") >= 0: + self.chanMod.setChecked(False) + if op: + msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Secure-only", False) + self.textArea.append(convertTags(msg)) + self.mainwindow.chatlog.log(self.channel, msg) chanmodes.sort() self.modes = "+" + "".join(chanmodes) if self.mainwindow.advanced: @@ -935,6 +1155,8 @@ class PesterMemo(PesterConvo): else: ttracker = TimeTracker(timedelta(0)) opchum = PesterProfile(op) + PchumLog.debug("op = " + op) + PchumLog.debug("opchum = " + opchum.handle) if op in self.times: opgrammar = self.times[op].getGrammar() elif op == self.mainwindow.profile().handle: @@ -969,6 +1191,7 @@ class PesterMemo(PesterConvo): h = str(handle) c = str(channel) update = str(update) + PchumLog.debug("h=%s\nc=%s\nupdate=%s" % (h,c,update)) if update[0:4] == "kick": # yeah, i'm lazy. l = update.split(":") update = l[0] @@ -1108,7 +1331,9 @@ class PesterMemo(PesterConvo): elif update == "+o": if self.mainwindow.config.opvoiceMessages(): (chum, opchum, opgrammar) = self.chumOPstuff(h, op) + PchumLog.debug("chum.handle = %s\nopchum.handle = %s\nopgrammar = %s\n systemColor = %s\n" % (chum.handle, opchum.handle, opgrammar, systemColor)) msg = chum.memoopmsg(opchum, opgrammar, systemColor) + PchumLog.debug("post memoopmsg") self.textArea.append(convertTags(msg)) self.mainwindow.chatlog.log(self.channel, msg) for c in chums: diff --git a/oyoyo/client.py b/oyoyo/client.py index c7fb82f..11a1606 100644 --- a/oyoyo/client.py +++ b/oyoyo/client.py @@ -15,6 +15,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. +import logging, logging.config +logging.config.fileConfig('logging.conf') +PchumLog = logging.getLogger('pchumLogger') + import logging import socket import sys @@ -216,6 +220,8 @@ class IRCClient: data = buffer.split(bytes("\n", "UTF-8")) buffer = data.pop() + PchumLog.debug("data = " + str(data)) + for el in data: prefix, command, args = parse_raw_irc_command(el) try: diff --git a/oyoyo/cmdhandler.py b/oyoyo/cmdhandler.py index 4d7fb42..263c969 100644 --- a/oyoyo/cmdhandler.py +++ b/oyoyo/cmdhandler.py @@ -14,6 +14,9 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. +import logging, logging.config +logging.config.fileConfig('logging.conf') +PchumLog = logging.getLogger('pchumLogger') import inspect import logging @@ -105,11 +108,12 @@ class CommandHandler(object): # Because more than 5 arguments can be passed by channelmodeis try: - if str(command) == 'channelmodeis': + #if str(command) == 'channelmodeis': # This might be stupid :) - f(*args[0:4]) - else: - f(*args) + # Update: This was very stupid + #f(*args[0:4]) + #else: + f(*args) except Exception as e: #logging.error('command raised '+ command + str()) logging.error('command args: ' + str([*args])) @@ -188,7 +192,7 @@ class BotCommandHandler(DefaultCommandHandler): and calls self.processBotCommand(cmd, sender) if its is. """ - logging.debug("tryBotCommand('%s' '%s' '%s')" % (prefix, dest, msg)) + PchumLog.debug("tryBotCommand('%s' '%s' '%s')" % (prefix, dest, msg)) if dest == self.client.nick: dest = parse_nick(prefix)[0] diff --git a/oyoyo/helpers.py b/oyoyo/helpers.py index d12b929..30a16dc 100644 --- a/oyoyo/helpers.py +++ b/oyoyo/helpers.py @@ -17,6 +17,9 @@ """ contains helper functions for common irc commands """ +import logging, logging.config +logging.config.fileConfig('logging.conf') +PchumLog = logging.getLogger('pchumLogger') import random def msg(cli, user, msg): @@ -42,6 +45,8 @@ def kick(cli, handle, channel, reason=""): cli.send("KICK %s %s %s" % (channel, handle, reason)) def mode(cli, channel, mode, options=None): + PchumLog.debug("mode = " + str(mode)) + PchumLog.debug("options = " + str(options)) cmd = "MODE %s %s" % (channel, mode) if options: cmd += " %s" % (options) diff --git a/pesterchum.py b/pesterchum.py index 4090c3e..a6b8c6b 100644 --- a/pesterchum.py +++ b/pesterchum.py @@ -2258,6 +2258,7 @@ class PesterWindow(MovingWindow): def userPresentUpdate(self, handle, channel, update): c = str(channel) n = str(handle) + PchumLog.debug("c=%s\nn=%s\nupdate=%s\n" % (c, n, update)) if update == "nick": l = n.split(":") oldnick = l[0] @@ -2297,6 +2298,7 @@ class PesterWindow(MovingWindow): except KeyError: self.namesdb[c] = [n] + PchumLog.debug("handle=%s\nchannel=%s\nupdate=%s\n" % (handle, channel, update)) self.userPresentSignal.emit(handle, channel, update) @QtCore.pyqtSlot() diff --git a/version.py b/version.py index 4202432..d65837d 100644 --- a/version.py +++ b/version.py @@ -1,2 +1,2 @@ -_pcVersion = "Alt. v2.1.3" -buildVersion = "v2.1.3" +_pcVersion = "Alt. v2.1.3.1" +buildVersion = "v2.1.3.1"