Miscellaneous fixes/changes incl. loadingscreen fix (v2.4.1)

This commit is contained in:
Dpeta 2022-07-05 21:45:16 +02:00
parent 66e838ebf4
commit b90c258604
12 changed files with 224 additions and 174 deletions

View file

@ -1,6 +1,24 @@
# Changelog
(This document uses YYYY-MM-DD)
## [v2.4.1] - 2022-07-05
### Added
- Support for more IRC replies/commands that imply a (forced) nick/handle change.
### Fixed
- Connecting dialog not disappearing when theme was changed.
- Client not sending QUIT on manual reconnect or exit via tray.
- Manual reconnect occasionally failing.
### Changed
- LoadingScreen/connecting dialog is no longer blocking.
- Console output is less verbose.
### Deprecated
- Removed the weird metadata support timeout thingy, I think ought to just get the full 005 before we try to get moods.
- Replaced instances of socket.error excepts with OSError, since it's depreciated.
## [v2.4] - 2022-06-30
### Added

141
irc.py
View file

@ -46,16 +46,14 @@ class PesterIRC(QtCore.QThread):
self.NickServ = services.NickServ()
self.ChanServ = services.ChanServ()
def IRCConnect(self):
server = self.config.server()
port = self.config.port()
ssl = self.config.ssl()
self.cli = IRCClient(PesterHandler,
host=server,
port=port,
host=self.config.server(),
port=self.config.port(),
ssl=self.config.ssl(),
nick=self.mainwindow.profile().handle,
real_name='pcc31',
timeout=120,
ssl=ssl)
username='pcc31',
realname='pcc31',
timeout=120)
self.cli.command_handler.parent = self
self.cli.command_handler.mainwindow = self.mainwindow
self.cli.connect()
@ -90,8 +88,8 @@ class PesterIRC(QtCore.QThread):
self.connected.emit()
def setConnectionBroken(self):
PchumLog.critical("setconnection broken")
self.reconnectIRC()
#self.brokenConnection = True
self.disconnectIRC()
#self.brokenConnection = True # Unused
@QtCore.pyqtSlot()
def updateIRC(self):
try:
@ -101,19 +99,17 @@ class PesterIRC(QtCore.QThread):
return True
else:
raise se
except socket.error as se:
except OSError as se:
raise se
except (OSError, IndexError) as se:
except (OSError,
ValueError,
IndexError) as se:
raise se
except StopIteration:
self.conn = self.cli.conn()
return True
else:
return res
@QtCore.pyqtSlot()
def reconnectIRC(self):
PchumLog.warning("reconnectIRC() from thread %s" % (self))
self.cli.close()
@QtCore.pyqtSlot(PesterProfile)
def getMood(self, *chums):
@ -127,7 +123,7 @@ class PesterIRC(QtCore.QThread):
t = str(text)
try:
helpers.notice(self.cli, h, t)
except socket.error as e:
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
@QtCore.pyqtSlot(QString, QString)
@ -174,7 +170,7 @@ class PesterIRC(QtCore.QThread):
try:
for t in textl:
helpers.msg(self.cli, h, t)
except socket.error as e:
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
@QtCore.pyqtSlot(QString, QString,)
@ -184,7 +180,7 @@ class PesterIRC(QtCore.QThread):
#msg = msg.replace(cmd, '')
try:
helpers.ctcp(self.cli, handle, text)
except socket.error as e:
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
@QtCore.pyqtSlot(QString, bool)
@ -194,7 +190,7 @@ class PesterIRC(QtCore.QThread):
helpers.msg(self.cli, h, "COLOR >%s" % (self.mainwindow.profile().colorcmd()))
if initiated:
helpers.msg(self.cli, h, "PESTERCHUM:BEGIN")
except socket.error as e:
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
@QtCore.pyqtSlot(QString)
@ -202,7 +198,7 @@ class PesterIRC(QtCore.QThread):
h = str(handle)
try:
helpers.msg(self.cli, h, "PESTERCHUM:CEASE")
except socket.error as e:
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
@QtCore.pyqtSlot()
@ -211,7 +207,7 @@ class PesterIRC(QtCore.QThread):
handle = me.handle
try:
helpers.nick(self.cli, handle)
except socket.error as e:
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
self.mainwindow.closeConversations(True)
@ -225,13 +221,13 @@ class PesterIRC(QtCore.QThread):
# Moods via metadata
try:
helpers.metadata(self.cli, '*', "set", "mood", str(me.mood.value()))
except socket.error as e:
except OSError 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:
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
@QtCore.pyqtSlot()
@ -241,7 +237,7 @@ class PesterIRC(QtCore.QThread):
for h in list(self.mainwindow.convos.keys()):
try:
helpers.msg(self.cli, h, "COLOR >%s" % (self.mainwindow.profile().colorcmd()))
except socket.error as e:
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
@QtCore.pyqtSlot(QString)
@ -249,7 +245,7 @@ class PesterIRC(QtCore.QThread):
h = str(handle)
try:
helpers.msg(self.cli, h, "PESTERCHUM:BLOCK")
except socket.error as e:
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
@QtCore.pyqtSlot(QString)
@ -257,7 +253,7 @@ class PesterIRC(QtCore.QThread):
h = str(handle)
try:
helpers.msg(self.cli, h, "PESTERCHUM:UNBLOCK")
except socket.error as e:
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
@QtCore.pyqtSlot(QString)
@ -265,14 +261,14 @@ class PesterIRC(QtCore.QThread):
c = str(channel)
try:
helpers.names(self.cli, c)
except socket.error as e:
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
@QtCore.pyqtSlot()
def requestChannelList(self):
try:
helpers.channel_list(self.cli)
except socket.error as e:
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
@QtCore.pyqtSlot(QString)
@ -281,7 +277,7 @@ class PesterIRC(QtCore.QThread):
try:
helpers.join(self.cli, c)
helpers.mode(self.cli, c, "", None)
except socket.error as e:
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
@QtCore.pyqtSlot(QString)
@ -290,7 +286,7 @@ class PesterIRC(QtCore.QThread):
try:
helpers.part(self.cli, c)
self.cli.command_handler.joined = False
except socket.error as e:
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
@QtCore.pyqtSlot(QString, QString)
@ -307,7 +303,7 @@ class PesterIRC(QtCore.QThread):
reason = ""
try:
helpers.kick(self.cli, h, c, reason)
except socket.error as e:
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
@QtCore.pyqtSlot(QString, QString, QString)
@ -320,7 +316,7 @@ class PesterIRC(QtCore.QThread):
cmd = None
try:
helpers.mode(self.cli, c, m, cmd)
except socket.error as e:
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
@QtCore.pyqtSlot(QString)
@ -328,7 +324,7 @@ class PesterIRC(QtCore.QThread):
c = str(channel)
try:
helpers.names(self.cli, c)
except socket.error as e:
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
@QtCore.pyqtSlot(QString, QString)
@ -337,7 +333,7 @@ class PesterIRC(QtCore.QThread):
c = str(channel)
try:
helpers.invite(self.cli, h, c)
except socket.error as e:
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
@ -345,7 +341,7 @@ class PesterIRC(QtCore.QThread):
def pingServer(self):
try:
self.cli.send("PING %s" % int(time.time()))
except socket.error as e:
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
@ -356,7 +352,7 @@ class PesterIRC(QtCore.QThread):
self.cli.send("AWAY Idle")
else:
self.cli.send("AWAY")
except socket.error as e:
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
@ -366,12 +362,16 @@ class PesterIRC(QtCore.QThread):
h = str(handle)
try:
helpers.ctcp(self.cli, c, "NOQUIRKS", h)
except socket.error as e:
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
def quit_dc(self):
helpers.quit(self.cli, _pcVersion + " <3")
@QtCore.pyqtSlot()
def disconnectIRC(self):
if hasattr(self, 'cli'):
helpers.quit(self.cli, _pcVersion + " <3")
self.cli._end = True
self.cli.close()
moodUpdated = QtCore.pyqtSignal('QString', Mood)
colorUpdated = QtCore.pyqtSignal('QString', QtGui.QColor)
@ -383,6 +383,7 @@ class PesterIRC(QtCore.QThread):
namesReceived = QtCore.pyqtSignal('QString', PesterList)
channelListReceived = QtCore.pyqtSignal(PesterList)
nickCollision = QtCore.pyqtSignal('QString', 'QString')
getSvsnickedOn = QtCore.pyqtSignal('QString', 'QString')
myHandleChanged = QtCore.pyqtSignal('QString')
chanInviteOnly = QtCore.pyqtSignal('QString')
modesUpdated = QtCore.pyqtSignal('QString', 'QString')
@ -450,7 +451,7 @@ class PesterHandler(DefaultCommandHandler):
if (x != None) and (x != ''):
reason += x + ' '
self.parent.stopIRC = reason.strip()
self.parent.reconnectIRC()
self.parent.disconnectIRC()
def privmsg(self, nick, chan, msg):
handle = nick[0:nick.find("!")]
@ -559,7 +560,7 @@ class PesterHandler(DefaultCommandHandler):
if (x != None) and (x != ''):
reason += x + ' '
self.parent.stopIRC = reason.strip()
self.parent.reconnectIRC()
self.parent.disconnectIRC()
def keyvalue(self, target, handle_us, handle_owner, key, visibility, *value):
# The format of the METADATA server notication is:
@ -577,7 +578,7 @@ class PesterHandler(DefaultCommandHandler):
chumglub = "GETMOOD "
try:
helpers.msg(self.client, "#pesterchum", chumglub + failed_handle)
except socket.error as e:
except OSError as e:
PchumLog.warning(e)
self.parent.setConnectionBroken()
@ -587,7 +588,7 @@ class PesterHandler(DefaultCommandHandler):
chumglub = "GETMOOD "
try:
helpers.msg(self.client, "#pesterchum", chumglub + failed_handle)
except socket.error as e:
except OSError as e:
PchumLog.warning(e)
self.parent.setConnectionBroken()
@ -597,11 +598,12 @@ class PesterHandler(DefaultCommandHandler):
chumglub = "GETMOOD "
try:
helpers.msg(self.client, "#pesterchum", chumglub + failed_handle)
except socket.error as e:
except OSError as e:
PchumLog.warning(e)
self.parent.setConnectionBroken()
def featurelist(self, target, handle, *params):
# Better to do this via CAP ACK/CAP NEK
# RPL_ISUPPORT
features = params[:-1]
PchumLog.info("Server featurelist: " + str(features))
@ -610,11 +612,22 @@ class PesterHandler(DefaultCommandHandler):
PchumLog.info("Server supports metadata.")
self.parent.metadata_supported = True
def cap(self, server, nick, subcommand, tag):
PchumLog.info("CAP %s %s %s %s" % (server, nick, subcommand, tag))
#if tag == "message-tags":
# if subcommand == "ACK":
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 nickcollision(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))
@ -730,7 +743,13 @@ class PesterHandler(DefaultCommandHandler):
#except IndexError:
#self.parent.userPresentUpdate.emit("", channel, m+":%s" % (op))
def nick(self, oldnick, newnick):
def nick(self, oldnick, newnick, hopcount=0):
# NICK from/to us
if oldnick == self.mainwindow.profile().handle:
# Server changed our handle, svsnick?
self.parent.getSvsnickedOn.emit(oldnick, newnick)
# NICK from/to someone else
oldhandle = oldnick[0:oldnick.find("!")]
if oldhandle == self.mainwindow.profile().handle:
self.parent.myHandleChanged.emit(newnick)
@ -824,25 +843,7 @@ class PesterHandler(DefaultCommandHandler):
self.client.send('PONG', server)
def getMood(self, *chums):
# Try to get mood via metadata get.
# If it fails the old code is excecuted.
# If services/bot, assume mood 18.
# * This doesn't actually seem to work.
#for c in chums:
# if c.handle.upper() in BOTNAMES:
# print("True")
# print(c.handle)
# PchumLog.info("%s is a bot, setting mood to 18." % (c.handle))
# self.parent.moodUpdated.emit(c.handle, Mood(18))
# Wait for server to send welcome to verify RPL_ISUPPORT has been send.
# Apparently 005 is send after 001 so nvm we gotta wait longer :"3
timeout = 0
while ((self.parent.registeredIRC == False)
or ((timeout < 15)
and (self.parent.metadata_supported == False))):
time.sleep(0.1)
timeout += 1
"""Get mood via metadata if supported"""
# Get via metadata or via legacy method
if self.parent.metadata_supported == True:
@ -851,7 +852,7 @@ class PesterHandler(DefaultCommandHandler):
chandle = c.handle
try:
helpers.metadata(self.client, chandle, "get", "mood")
except socket.error as e:
except OSError as e:
PchumLog.warning(e)
self.parent.setConnectionBroken()
else:
@ -863,7 +864,7 @@ class PesterHandler(DefaultCommandHandler):
if len(chumglub+chandle) >= 350:
try:
helpers.msg(self.client, "#pesterchum", chumglub)
except socket.error as e:
except OSError as e:
PchumLog.warning(e)
self.parent.setConnectionBroken()
chumglub = "GETMOOD "
@ -871,7 +872,7 @@ class PesterHandler(DefaultCommandHandler):
if chumglub != "GETMOOD ":
try:
helpers.msg(self.client, "#pesterchum", chumglub)
except socket.error as e:
except OSError as e:
PchumLog.warning(e)
self.parent.setConnectionBroken()
@ -883,12 +884,12 @@ class PesterHandler(DefaultCommandHandler):
# if len(chandle) >= 200:
# try:
# self.client.send("ISON", ":%s" % (isonNicks))
# except socket.error:
# except OSError:
# self.parent.setConnectionBroken()
# isonNicks = ""
# isonNicks += " " + chandle
# if isonNicks != "":
# try:
# self.client.send("ISON", ":%s" % (isonNicks))
# except socket.error:
# except OSError:
# self.parent.setConnectionBroken()

View file

@ -791,7 +791,7 @@ class PesterChooseTheme(QtWidgets.QDialog):
self.rejected.connect(parent.closeTheme)
class PesterChooseProfile(QtWidgets.QDialog):
def __init__(self, userprofile, config, theme, parent, collision=None):
def __init__(self, userprofile, config, theme, parent, collision=None, svsnick=None):
QtWidgets.QDialog.__init__(self, parent)
self.userprofile = userprofile
self.theme = theme
@ -848,6 +848,9 @@ class PesterChooseProfile(QtWidgets.QDialog):
if collision:
collision_warning = QtWidgets.QLabel("%s is taken already! Pick a new profile." % (collision))
layout_0.addWidget(collision_warning)
elif svsnick != None:
svsnick_warning = QtWidgets.QLabel("Your handle got changed from %s to %s! Pick a new profile." % svsnick)
layout_0.addWidget(svsnick_warning)
else:
layout_0.addWidget(self.currentHandle, alignment=QtCore.Qt.AlignmentFlag.AlignHCenter)
layout_0.addLayout(layout_1)
@ -1753,6 +1756,8 @@ class LoadingScreen(QtWidgets.QDialog):
self.mainwindow = parent
self.setStyleSheet(self.mainwindow.theme["main/defaultwindow/style"])
#self.setWindowModality(QtCore.Qt.WindowModality.NonModal) # useless
#self.setAttribute(QtCore.Qt.WidgetAttribute.WA_DeleteOnClose) # useless
self.loadinglabel = QtWidgets.QLabel("CONN3CT1NG", self)
self.cancel = QtWidgets.QPushButton("QU1T >:?", self)
self.ok = QtWidgets.QPushButton("R3CONN3CT >:]", self)
@ -1761,6 +1766,7 @@ class LoadingScreen(QtWidgets.QDialog):
self.ok.setAutoDefault(True)
self.cancel.clicked.connect(self.reject)
self.ok.clicked.connect(self.tryAgain)
#self.finished.connect(self.finishedEvent)
self.layout = QtWidgets.QVBoxLayout()
self.layout.addWidget(self.loadinglabel)
@ -1775,6 +1781,9 @@ class LoadingScreen(QtWidgets.QDialog):
self.ok.setFocus()
self.timer = None
#def finishedEvent(self, result):
# self.close()
def hideReconnect(self, safe=True):
self.ok.hide()
if safe:
@ -1792,8 +1801,6 @@ class LoadingScreen(QtWidgets.QDialog):
def enableQuit(self):
self.cancel.setEnabled(True)
tryAgain = QtCore.pyqtSignal()
class AboutPesterchum(QtWidgets.QDialog):
def __init__(self, parent=None):
QtWidgets.QDialog.__init__(self, parent)

View file

@ -82,7 +82,8 @@ class IRCClient:
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.nick = None
self.real_name = None
self.realname = None
self.username = None
self.host = None
self.port = None
self.connect_cb = None
@ -131,6 +132,12 @@ class IRCClient:
try:
tries = 1
while tries < 10:
# Check if alive
if self._end == True:
break
if self.socket.fileno() == -1:
self._end = True
break
try:
ready_to_read, ready_to_write, in_error = select.select([], [self.socket], [])
for x in ready_to_write:
@ -156,9 +163,8 @@ class IRCClient:
raise socket.timeout
except (OSError,
IndexError,
ValueError) as e:
# Unknown error, might as well retry?
# index/value can happen if the socket breaks.
ValueError,
Exception) as e:
PchumLog.warning("Unkown error on send, " + str(e))
if tries >= 9:
raise e
@ -168,7 +174,7 @@ class IRCClient:
PchumLog.debug("ready_to_write (len %s): " % str(len(ready_to_write)) + str(ready_to_write))
except Exception as se:
PchumLog.warning("socket.error %s" % str(se))
PchumLog.warning("Send Exception %s" % str(se))
try:
if not self.blocking and se.errno == 11:
pass
@ -190,7 +196,7 @@ class IRCClient:
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
bare_sock = socket.create_connection(("%s" % self.host, self.port))
bare_sock = socket.create_connection((self.host, self.port))
self.socket = context.wrap_socket(bare_sock,
server_hostname=self.host,
do_handshake_on_connect=False)
@ -206,7 +212,7 @@ class IRCClient:
PchumLog.info("secure sockets version is %s" % self.socket.version())
else:
self.socket = socket.create_connection(("%s" % self.host, self.port))
self.socket = socket.create_connection((self.host, self.port))
# setblocking is a shorthand for timeout,
# we shouldn't use both.
@ -218,7 +224,7 @@ class IRCClient:
self.socket.setblocking(True)
helpers.nick(self, self.nick)
helpers.user(self, self.nick, self.real_name)
helpers.user(self, self.username, self.realname)
if self.connect_cb:
self.connect_cb(self)
@ -231,6 +237,12 @@ class IRCClient:
try:
tries = 1
while tries < 10:
# Check if alive
if self._end == True:
break
if self.socket.fileno() == -1:
self._end = True
break
try:
ready_to_read, ready_to_write, in_error = select.select([self.socket], [], [])
for x in ready_to_read:
@ -249,14 +261,16 @@ class IRCClient:
except ssl.SSLEOFError as e:
# ssl.SSLEOFError guarantees a broken connection.
PchumLog.warning("ssl.SSLEOFError in on send, " + str(e))
raise ssl.SSLEOFError
raise e
except (socket.timeout, TimeoutError) as e:
# socket.timeout is deprecated in 3.10
PchumLog.warning("TimeoutError in on send, " + str(e))
raise socket.timeout
except (OSError, IndexError) as e:
# Unknown error, might as well retry?
PchumLog.warning("Unkown error, " + str(e))
except (OSError,
IndexError,
ValueError,
Exception) as e:
PchumLog.warning("Unkown error in conn, " + str(e))
if tries >= 9:
raise e
tries += 1
@ -268,8 +282,8 @@ class IRCClient:
if self._end:
break
raise e
except ssl.SSLEOFError:
raise ssl.SSLEOFError
except ssl.SSLEOFError as e:
raise e
except OSError as e:
PchumLog.warning("conn exception %s in %s" % (e, self))
if self._end:
@ -287,7 +301,7 @@ class IRCClient:
break
if len(buffer) == 0 and self.blocking:
PchumLog.debug("len(buffer) = 0")
raise socket.error("Connection closed")
raise OSError("Connection closed")
data = buffer.split(bytes("\n", "UTF-8"))
buffer = data.pop()
@ -303,13 +317,13 @@ class IRCClient:
else:
self.command_handler.run(command, prefix, *args)
except CommandError as e:
PchumLog.debug("CommandError %s" % str(e))
PchumLog.warning("CommandError %s" % str(e))
yield True
except socket.timeout as se:
PchumLog.debug("passing timeout")
raise se
except (socket.error, ssl.SSLEOFError) as se:
except (OSError, ssl.SSLEOFError) as se:
PchumLog.debug("problem: %s" % (str(se)))
if self.socket:
PchumLog.info('error: closing socket')
@ -333,15 +347,11 @@ class IRCClient:
try:
self.socket.shutdown(socket.SHUT_RDWR)
except OSError as e:
PchumLog.warning("Error while shutting down socket, already broken? %s" % str(e))
PchumLog.debug("Error while shutting down socket, already broken? %s" % str(e))
try:
self.socket.close()
except OSError as e:
PchumLog.warning("Error while closing socket, already broken? %s" % str(e))
def quit(self, msg):
PchumLog.info("QUIT")
self.socket.sendall(bytes(msg + "\n", "UTF-8"))
PchumLog.debug("Error while closing socket, already broken? %s" % str(e))
class IRCApp:
""" This class manages several IRCClient instances without the use of threads.

View file

@ -97,7 +97,8 @@ class CommandHandler(object):
try:
f = self.get(command)
except NoSuchCommandError:
except NoSuchCommandError as e:
PchumLog.info(e)
self.__unhandled__(command, *args)
return
@ -106,7 +107,9 @@ class CommandHandler(object):
try:
f(*args)
except TypeError as e:
logging.exception("Failed to pass command, did the server pass an unsupported paramater?\n%s" % str(e))
logging.warning("Failed to pass command, did the server pass an unsupported paramater? " + str(e))
except Exception as e:
logging.warning("Failed to pass command, %s" % str(e))
@protected
def __unhandled__(self, cmd, *args):

View file

@ -101,14 +101,14 @@ def identify(cli, passwd, authuser="NickServ"):
msg(cli, authuser, "IDENTIFY %s" % passwd)
def quit(cli, msg):
msg = "QUIT :%s" % msg
cli.quit(msg)
cli.close()
cli._end = 1
cli.send("QUIT %s" % (msg))
def user(cli, username, realname=None):
cli.send("USER", realname or username, cli.host, cli.host,
realname or username)
def user(cli, username, realname):
cli.send("USER",
username,
'0',
'*',
':' + realname)
_simple = (
'join',
@ -140,4 +140,3 @@ def _addNumerics():
setattr(m, name, numericcmd(num, name))
_addNumerics()

View file

@ -223,8 +223,10 @@ protocol_events = [
"quit",
"invite",
"pong",
"metadata", # Metadata specification
"tagmsg", # IRCv3 message tags extension
"nick", # We can get svsnicked
"metadata", # Metadata specification
"tagmsg", # IRCv3 message tags extension
"cap" # IRCv3 Client Capability Negotiation
]
all_events = (generated_events

View file

@ -26,7 +26,6 @@ logging.config.fileConfig(_datadir + "logging.ini")
PchumLog = logging.getLogger('pchumLogger')
def parse_raw_irc_command(element):
print(element)
"""
This function parses a raw irc command and returns a tuple
of (prefix, command, args).

View file

@ -704,14 +704,7 @@ def kxhandleInput(ctx, text=None, flavor=None):
msgbox.exec()
return
# Debug output.
try:
# Turns out that Windows consoles can't handle unicode, heh...who'da
# thunk. We have to repr() this, as such.
print(repr(msg))
except Exception as err:
print("(Couldn't print processed message: {!s})".format(err))
PchumLog.info("--> recv \"%s\"" % msg)
# karxi: We have a list...but I'm not sure if we ever get anything else, so
# best to play it safe. I may remove this during later refactoring.
if isinstance(msg, list):
@ -728,10 +721,10 @@ def kxhandleInput(ctx, text=None, flavor=None):
msg = kxlexMsg(msg)
# Debug output.
try:
print(repr(msg))
except Exception as err:
print("(Couldn't print lexed message: {!s})".format(err))
#try:
# print(repr(msg))
#except Exception as err:
# print("(Couldn't print lexed message: {!s})".format(err))
# Remove coloring if this is a /me!
if is_action:

View file

@ -1171,7 +1171,7 @@ class TrollSlumWindow(QtWidgets.QFrame):
unblockChumSignal = QtCore.pyqtSignal('QString')
class PesterWindow(MovingWindow):
reconnectIRC = QtCore.pyqtSignal()
disconnectIRC = QtCore.pyqtSignal()
sendMessage = QtCore.pyqtSignal('QString', 'QString')
def __init__(self, options, parent=None, app=None):
@ -1292,7 +1292,7 @@ class PesterWindow(MovingWindow):
opts.triggered.connect(self.openOpts)
exitaction = QtGui.QAction(self.theme["main/menus/client/exit"], self)
self.exitaction = exitaction
exitaction.triggered.connect(self.quit)
exitaction.triggered.connect(self.killApp, QtCore.Qt.ConnectionType.QueuedConnection)
userlistaction = QtGui.QAction(self.theme["main/menus/client/userlist"], self)
self.userlistaction = userlistaction
userlistaction.triggered.connect(self.showAllUsers)
@ -1305,7 +1305,7 @@ class PesterWindow(MovingWindow):
self.idleaction.setCheckable(True)
self.idleaction.toggled[bool].connect(self.toggleIdle)
self.reconnectAction = QtGui.QAction(self.theme["main/menus/client/reconnect"], self)
self.reconnectAction.triggered.connect(self.reconnectIRC)
self.reconnectAction.triggered.connect(self.disconnectIRC)
self.menu = QtWidgets.QMenuBar(self)
self.menu.setNativeMenuBar(False)
@ -1583,7 +1583,6 @@ class PesterWindow(MovingWindow):
self.hide()
self.closeToTraySignal.emit()
def closeEvent(self, event):
# This gets called directly if Pesterchum is closed from the taskbar, annoyingly enough.
if hasattr(self, 'trollslum') and self.trollslum:
self.trollslum.close()
try:
@ -1597,8 +1596,7 @@ class PesterWindow(MovingWindow):
self.closeToTray()
elif setting == 2: # quit
self.closeConversations()
self.quit() # Shut down IRC & Pesterchum fully.
self.closeSignal.emit() # <-- A close signal here on it's own shuts down QT but not the Python and the IRC connection :(
self.closeSignal.emit()
event.accept()
def newMessage(self, handle, msg):
if handle in self.config.getBlocklist():
@ -1863,11 +1861,16 @@ class PesterWindow(MovingWindow):
self.chumList.showOnlineNumbers()
def changeProfile(self, collision=None):
def changeProfile(self, collision=None, svsnick=None):
if not hasattr(self, 'chooseprofile'):
self.chooseprofile = None
if not self.chooseprofile:
self.chooseprofile = PesterChooseProfile(self.userprofile, self.config, self.theme, self, collision=collision)
self.chooseprofile = PesterChooseProfile(self.userprofile,
self.config,
self.theme,
self,
collision=collision,
svsnick=svsnick)
self.chooseprofile.exec()
def themePicker(self):
@ -2338,7 +2341,7 @@ class PesterWindow(MovingWindow):
def userPresentUpdate(self, handle, channel, update):
c = str(channel)
n = str(handle)
print("c=%s\nn=%s\nupdate=%s\n" % (c, n, update))
#print("c=%s\nn=%s\nupdate=%s\n" % (c, n, update))
if update == "nick":
l = n.split(":")
oldnick = l[0]
@ -3180,6 +3183,11 @@ class PesterWindow(MovingWindow):
@QtCore.pyqtSlot(QString, QString)
def nickCollision(self, handle, tmphandle):
if hasattr(self, 'loadingscreen'):
if self.loadingscreen != None:
self.loadingscreen.done(QtWidgets.QDialog.DialogCode.Accepted)
self.loadingscreen = None
self.mychumhandle.setText(tmphandle)
self.userprofile = userProfile(PesterProfile("pesterClient%d" % (random.randint(100,999)), QtGui.QColor("black"), Mood(0)))
self.changeTheme(self.userprofile.getTheme())
@ -3189,6 +3197,24 @@ class PesterWindow(MovingWindow):
if not self.chooseprofile:
h = str(handle)
self.changeProfile(collision=h)
@QtCore.pyqtSlot(QString, QString)
def getSvsnickedOn(self, oldhandle, newhandle):
if hasattr(self, 'loadingscreen'):
if self.loadingscreen != None:
self.loadingscreen.done(QtWidgets.QDialog.DialogCode.Accepted)
self.loadingscreen = None
self.mychumhandle.setText(newhandle)
self.userprofile = userProfile(PesterProfile(newhandle,
QtGui.QColor("black"),
Mood(0)))
self.changeTheme(self.userprofile.getTheme())
if not hasattr(self, 'chooseprofile'):
self.chooseprofile = None
if not self.chooseprofile:
self.changeProfile(svsnick=(oldhandle, newhandle))
@QtCore.pyqtSlot(QString)
def myHandleChanged(self, handle):
if self.profile().handle == handle:
@ -3223,28 +3249,17 @@ class PesterWindow(MovingWindow):
self.forbiddenChan.emit(channel, reason)
@QtCore.pyqtSlot()
def quit(self):
try:
self.irc.quit_dc() # Actually send QUIT to server
except Exception as e:
# Not connected?
PchumLog.warning("QUIT failed: " + str(e))
try:
self.parent.trayicon.hide() #
self.app.quit()
except AttributeError as e:
# Called from outside main Window?
PchumLog.warning("Unelegant quit: " + str(e))
sys.exit()
def killApp(self):
self.disconnectIRC.emit()
self.parent.trayicon.hide()
self.app.quit()
def passIRC(self, irc):
self.irc = irc
def updateServerJson(self):
PchumLog.info(self.customServerPrompt_qline.text() + " chosen")
server_and_port = self.customServerPrompt_qline.text().split(':')
try:
server = {
"server": server_and_port[0],
@ -3539,7 +3554,7 @@ class PesterWindow(MovingWindow):
# Connect
self.chooseServerWidged.accepted.connect(self.setServer)
self.chooseServerWidged.rejected.connect(self.quit)
self.chooseServerWidged.rejected.connect(self.killApp, QtCore.Qt.ConnectionType.QueuedConnection)
# Show
self.chooseServerWidged.show()
@ -3575,7 +3590,7 @@ class PesterWindow(MovingWindow):
inviteOnlyChan = QtCore.pyqtSignal('QString')
forbiddenChan = QtCore.pyqtSignal('QString', 'QString')
closeSignal = QtCore.pyqtSignal()
reconnectIRC = QtCore.pyqtSignal()
disconnectIRC = QtCore.pyqtSignal()
gainAttention = QtCore.pyqtSignal(QtWidgets.QWidget)
pingServer = QtCore.pyqtSignal()
setAway = QtCore.pyqtSignal(bool)
@ -3627,7 +3642,7 @@ class MainProgram(QtCore.QObject):
self.app = QtWidgets.QApplication(sys.argv)
self.app.setApplicationName("Pesterchum")
self.app.setQuitOnLastWindowClosed(False)
#self.app.setQuitOnLastWindowClosed(False)
options = self.oppts(sys.argv[1:])
@ -3678,7 +3693,7 @@ class MainProgram(QtCore.QObject):
miniAction = QtGui.QAction("MINIMIZE", self)
miniAction.triggered.connect(self.widget.showMinimized)
exitAction = QtGui.QAction("EXIT", self)
exitAction.triggered.connect(PesterWindow.quit)
exitAction.triggered.connect(self.widget.killApp, QtCore.Qt.ConnectionType.QueuedConnection)
self.traymenu.addAction(miniAction)
self.traymenu.addAction(exitAction)
@ -3699,6 +3714,19 @@ class MainProgram(QtCore.QObject):
self.widget.passIRC(self.irc) # Maybe this is absolutely terrible in practice, but screw it.
self.widget.gainAttention[QtWidgets.QWidget].connect(self.alertWindow)
#self.app.lastWindowClosed.connect(self.lastWindow)
self.app.aboutToQuit.connect(self.death)
def death(self):
# app murder in progress
#print("death inbound")
if hasattr(self, 'widget'):
self.widget.killApp()
#def lastWindow(self):
# print("all windows closed")
# if hasattr(self, 'widget'):
# self.widget.killApp()
@QtCore.pyqtSlot(QtWidgets.QWidget)
def alertWindow(self, widget):
@ -3708,9 +3736,8 @@ class MainProgram(QtCore.QObject):
def trayiconShow(self):
self.trayicon.show()
if self.widget.config.trayMessage():
self.trayicon.showMessage("Pesterchum", "Pesterchum is still running in the system tray.\n\
Right click to close it.\n\
Click this message to never see this again.")
self.trayicon.showMessage("Pesterchum", ("Pesterchum is still running in the system tray."
+ '\n' + "Right click to close it."))
@QtCore.pyqtSlot()
def trayMessageClick(self):
@ -3752,7 +3779,7 @@ Click this message to never see this again.")
('setAway(bool)', 'setAway(bool)'),
('killSomeQuirks(QString, QString)',
'killSomeQuirks(QString, QString)'),
('reconnectIRC()', 'reconnectIRC()')
('disconnectIRC()', 'disconnectIRC()')
]
# IRC --> Main window
irc2widget = [('connected()', 'connected()'),
@ -3770,6 +3797,8 @@ Click this message to never see this again.")
'deliverInvite(QString, QString)'),
('nickCollision(QString, QString)',
'nickCollision(QString, QString)'),
('getSvsnickedOn(QString, QString)',
'getSvsnickedOn(QString, QString)'),
('myHandleChanged(QString)',
'myHandleChanged(QString)'),
('namesReceived(QString, PyQt_PyObject)',
@ -3818,7 +3847,7 @@ Click this message to never see this again.")
(widget.pingServer, irc.pingServer),
(widget.setAway, irc.setAway),
(widget.killSomeQuirks, irc.killSomeQuirks),
(widget.reconnectIRC, irc.reconnectIRC),
(widget.disconnectIRC, irc.disconnectIRC),
# Main window --> IRC
(irc.connected, widget.connected),
(irc.moodUpdated, widget.updateMoodSlot),
@ -3828,6 +3857,7 @@ Click this message to never see this again.")
(irc.noticeReceived, widget.deliverNotice),
(irc.inviteReceived, widget.deliverInvite),
(irc.nickCollision, widget.nickCollision),
(irc.getSvsnickedOn, widget.getSvsnickedOn),
(irc.myHandleChanged, widget.myHandleChanged),
(irc.namesReceived, widget.updateNames),
(irc.userPresentUpdate, widget.userPresentUpdate),
@ -3887,17 +3917,7 @@ Click this message to never see this again.")
widget.loadingscreen.showReconnect()
else:
widget.loadingscreen.hideReconnect()
status = widget.loadingscreen.exec()
if status == QtWidgets.QDialog.DialogCode.Rejected:
sys.exit(0)
else:
if self.widget.tabmemo:
for c in self.widget.tabmemo.convos:
self.irc.joinChannel(c)
else:
for c in list(self.widget.memos.values()):
self.irc.joinChannel(c.channel)
return True
widget.loadingscreen.open()
@QtCore.pyqtSlot()
def connected(self):
@ -3911,8 +3931,7 @@ Click this message to never see this again.")
self.widget.loadingscreen = None
self.attempts += 1
if hasattr(self, 'irc') and self.irc:
self.irc.reconnectIRC()
self.irc.quit()
self.irc.disconnectIRC()
else:
self.restartIRC()
@QtCore.pyqtSlot()

View file

@ -189,7 +189,6 @@ class ToastMachine(object):
class PesterToast(QtWidgets.QWidget, DefaultToast):
def __init__(self, machine, title, msg, icon, time=3000, parent=None):
PchumLog.info(isinstance(parent, QtWidgets.QWidget))
kwds = dict(machine=machine, title=title, msg=msg, icon=icon)
super().__init__(parent, **kwds)

View file

@ -1,2 +1,2 @@
_pcVersion = "Alt. v2.4"
buildVersion = "v2.4"
_pcVersion = "Alt. v2.4.1"
buildVersion = "v2.4.1"