Rewrote some aspects of channel mode management

This commit is contained in:
Dpeta 2021-08-24 15:49:50 +02:00
parent 1fd62ef404
commit 5b4673e0dd
9 changed files with 346 additions and 27 deletions

View file

@ -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

View file

@ -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 "<c=%s><c=%s>%s</c> %s %s %s.</c>" % \
(syscolor.name(), self.colorhtml(), initials, timetext, verb, channel[1:].upper().replace("_", " "))
def memobanmsg(self, opchum, opgrammar, syscolor, initials, reason):

88
irc.py
View file

@ -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:

225
memos.py
View file

@ -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:

View file

@ -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:

View file

@ -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]

View file

@ -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)

View file

@ -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()

View file

@ -1,2 +1,2 @@
_pcVersion = "Alt. v2.1.3"
buildVersion = "v2.1.3"
_pcVersion = "Alt. v2.1.3.1"
buildVersion = "v2.1.3.1"