diff --git a/.github/workflows/black.yml b/.github/workflows/black.yml
new file mode 100644
index 0000000..a9be522
--- /dev/null
+++ b/.github/workflows/black.yml
@@ -0,0 +1,10 @@
+name: Black
+
+on: [push, pull_request]
+
+jobs:
+ black:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: psf/black@stable
diff --git a/README.md b/README.md
index 72d17dc..c5157aa 100644
--- a/README.md
+++ b/README.md
@@ -8,6 +8,7 @@
+
diff --git a/__main__.py b/__main__.py
index 21f8383..2fee9c7 100644
--- a/__main__.py
+++ b/__main__.py
@@ -5,6 +5,6 @@ import sys
try:
from .run_as_subprocess import main
except (ImportError, ModuleNotFoundError):
- from run_as_subprocess import main
-
+ from run_as_subprocess import main
+
main(sys.argv)
diff --git a/console.py b/console.py
index 4a8fd4e..b9f8d1d 100644
--- a/console.py
+++ b/console.py
@@ -1,7 +1,7 @@
# vim: set autoindent ts=4 sts=4 sw=4 textwidth=79 expandtab:
# -*- coding=UTF-8; tab-width: 4 -*-
-#import os
-#from os import remove
+# import os
+# from os import remove
import sys
import traceback
import time
@@ -17,17 +17,20 @@ except ImportError:
from PyQt5.QtWidgets import QAction
import dataobjs
-#import generic
-#import memos
-#import parsetools
+
+# import generic
+# import memos
+# import parsetools
import ostools
-#from version import _pcVersion
+
+# from version import _pcVersion
from pnc.dep.attrdict import AttrDict
-PchumLog = logging.getLogger('pchumLogger')
+PchumLog = logging.getLogger("pchumLogger")
+
class ConsoleWindow(QtWidgets.QDialog):
-#~class ConsoleWindow(styler.PesterBaseWindow):
+ # ~class ConsoleWindow(styler.PesterBaseWindow):
# A simple console class, cobbled together from the corpse of another.
stylesheet_path = "main/defaultwindow/style"
@@ -127,7 +130,7 @@ class ConsoleWindow(QtWidgets.QDialog):
def initTheme(self, theme):
# Set up our style/window specifics
self.changeTheme(theme)
- self.resize(400,600)
+ self.resize(400, 600)
def changeTheme(self, theme):
self.setStyleSheet(theme[self.stylesheet_path])
@@ -150,18 +153,23 @@ class ConsoleWindow(QtWidgets.QDialog):
wgt = QtWidgets.QApplication.widgetAt(pos)
if wgt is None:
# Don't set None, for now. May change this later.
- self.addMessage("You need to have your cursor over something " + \
- "in Pesterchum to use that.",
- direction=direction)
+ self.addMessage(
+ "You need to have your cursor over something "
+ + "in Pesterchum to use that.",
+ direction=direction,
+ )
return
self.selected_widget = wgt
nchild = len(wgt.children())
output = []
output.append("CONSOLE.selected_widget = {0!r}".format(wgt))
- output.append("{0: <4}Parent: {1!r}".format('', wgt.parent()))
- output.append("{0: <4}{1:4d} child{2}".format('',
- nchild, ("ren" if abs(nchild) != 1 else "") ))
+ output.append("{0: <4}Parent: {1!r}".format("", wgt.parent()))
+ output.append(
+ "{0: <4}{1:4d} child{2}".format(
+ "", nchild, ("ren" if abs(nchild) != 1 else "")
+ )
+ )
if self.show_info_on_select:
qtss = None
uses_ss = None
@@ -211,12 +219,13 @@ class ConsoleWindow(QtWidgets.QDialog):
else:
# We got a stylesheet out of this!
uses_ss, ss_msg = True, "Yes"
- #~ss_par_msg = "{0: <4}...on parent ↑{1:d}: {2!r}".format('',
- ss_par_msg = "{0: <4}...on parent #{1:d}: {2!r}".format('',
- i, ss_par)
+ # ~ss_par_msg = "{0: <4}...on parent ↑{1:d}: {2!r}".format('',
+ ss_par_msg = "{0: <4}...on parent #{1:d}: {2!r}".format(
+ "", i, ss_par
+ )
msg = []
- msg.append("{0: <4}QtSS?: {1}".format('', ss_msg))
+ msg.append("{0: <4}QtSS?: {1}".format("", ss_msg))
# A stylesheet analyzer would be wonderful here. Perhaps something
# that tells us how many parent classes define stylesheets?
if uses_ss:
@@ -224,16 +233,15 @@ class ConsoleWindow(QtWidgets.QDialog):
# We got this stylesheet from a parent object somewhere.
msg.append(ss_par_msg)
msg.append("{0: <4}".format("Stylesheet:"))
- for ln in qtss.split('\n'):
+ for ln in qtss.split("\n"):
msg.append("{0: <8}".format(ln))
# Actually add this stuff to the result we're constructing
output.extend(msg)
- output = '\n'.join(output)
+ output = "\n".join(output)
self.addMessage(output, direction=direction)
-
# Actual console stuff.
def execInConsole(self, scriptstr, env=None):
# Since that's what imports *us*, this should be okay
@@ -247,16 +255,16 @@ class ConsoleWindow(QtWidgets.QDialog):
# Fetch from the class/instance first.
_CUSTOM_ENV = self._CUSTOM_ENV.copy()
# Modify with some hard-coded environmental additions.
- _CUSTOM_ENV.update({
+ _CUSTOM_ENV.update(
+ {
"CONSOLE": self,
"MAINWIN": self.mainwindow,
"PCONFIG": self.mainwindow.config,
- "exit": lambda: self.mainwindow.exitaction.trigger()
- })
+ "exit": lambda: self.mainwindow.exitaction.trigger(),
+ }
+ )
# Aliases.
- _CUSTOM_ENV.update({
- "quit": _CUSTOM_ENV["exit"]
- })
+ _CUSTOM_ENV.update({"quit": _CUSTOM_ENV["exit"]})
# Add whatever additions were set in the main pesterchum file.
_CUSTOM_ENV.update(pchum._CONSOLE_ENV)
@@ -284,7 +292,7 @@ class ConsoleWindow(QtWidgets.QDialog):
# Replace the old writer (for now)
sysout, sys.stdout = sys.stdout, self
try:
- code = compile(scriptstr + '\n', "", "single")
+ code = compile(scriptstr + "\n", "", "single")
# Will using cenv instead of env cause problems?...
result = eval(code, cenv)
except:
@@ -309,7 +317,7 @@ class ConsoleWindow(QtWidgets.QDialog):
# We only ever use this for receiving, so it's safe to assume the
# direction is always -1.
if not isinstance(data, list):
- data = data.split('\n')
+ data = data.split("\n")
for line in data:
if len(line):
self.addMessage(line, -1)
@@ -332,7 +340,7 @@ class ConsoleText(QtWidgets.QTextEdit):
def __init__(self, theme, parent=None):
super(ConsoleText, self).__init__(parent)
- if hasattr(self.window(), 'mainwindow'):
+ if hasattr(self.window(), "mainwindow"):
self.mainwindow = self.window().mainwindow
else:
self.mainwindow = self.window()
@@ -362,7 +370,7 @@ class ConsoleText(QtWidgets.QTextEdit):
# be too hard - it's what dicts are for.
# Add the rest.
- stylesheet += '\n' + self.stylesheet_template
+ stylesheet += "\n" + self.stylesheet_template
stylesheet = stylesheet.format(style=theme)
self.setStyleSheet(stylesheet)
@@ -371,12 +379,12 @@ class ConsoleText(QtWidgets.QTextEdit):
# Direction > 0 == out (sent by us); < 0 == in (sent by script).
if len(msg) == 0:
return
- #~color = chum.colorcmd()
- #~initials = chum.initials()
+ # ~color = chum.colorcmd()
+ # ~initials = chum.initials()
parent = self.window()
mwindow = parent.mainwindow
- #systemColor = QtGui.QColor(mwindow.theme["convo/systemMsgColor"])
+ # systemColor = QtGui.QColor(mwindow.theme["convo/systemMsgColor"])
if mwindow.config.showTimeStamps():
if mwindow.config.time12Format():
@@ -406,7 +414,7 @@ class ConsoleText(QtWidgets.QTextEdit):
# Later, this will have to escape things so we don't parse them,
# likely...hm.
- #~result = "{} {} {!r}"
+ # ~result = "{} {} {!r}"
# The input we get is already repr'd...we pass it via print, and thus
# do that there.
result = "{}{} {}\n"
@@ -442,8 +450,12 @@ class ConsoleText(QtWidgets.QTextEdit):
# should.
# karxi: Test for tab changing?
if self.window().text.input:
- if event.key() not in (QtCore.Qt.Key.Key_PageUp, QtCore.Qt.Key.Key_PageDown,
- QtCore.Qt.Key.Key_Up, QtCore.Qt.Key.Key_Down):
+ if event.key() not in (
+ QtCore.Qt.Key.Key_PageUp,
+ QtCore.Qt.Key.Key_PageDown,
+ QtCore.Qt.Key.Key_Up,
+ QtCore.Qt.Key.Key_Down,
+ ):
self.window().text.input.keyPressEvent(event)
super(ConsoleText, self).keyPressEvent(event)
@@ -463,7 +475,9 @@ class ConsoleText(QtWidgets.QTextEdit):
QtWidgets.QApplication.clipboard().setText(url)
else:
# This'll probably be removed. May change the lexer out.
- QtGui.QDesktopServices.openUrl(QtCore.QUrl(url, QtCore.QUrl.ParsingMode.TolerantMode))
+ QtGui.QDesktopServices.openUrl(
+ QtCore.QUrl(url, QtCore.QUrl.ParsingMode.TolerantMode)
+ )
super(ConsoleText, self).mousePressEvent(event)
@@ -477,8 +491,13 @@ class ConsoleText(QtWidgets.QTextEdit):
# PyQt5
pos = event.pos()
if self.anchorAt(pos):
- if self.viewport().cursor().shape != QtCore.Qt.CursorShape.PointingHandCursor:
- self.viewport().setCursor(QtGui.QCursor(QtCore.Qt.CursorShape.PointingHandCursor))
+ if (
+ self.viewport().cursor().shape
+ != QtCore.Qt.CursorShape.PointingHandCursor
+ ):
+ self.viewport().setCursor(
+ QtGui.QCursor(QtCore.Qt.CursorShape.PointingHandCursor)
+ )
else:
self.viewport().setCursor(QtGui.QCursor(QtCore.Qt.CursorShape.IBeamCursor))
@@ -489,6 +508,7 @@ class ConsoleText(QtWidgets.QTextEdit):
class ConsoleInput(QtWidgets.QLineEdit):
"""The actual text entry box on a ConsoleWindow."""
+
# I honestly feel like this could just be made a private class of
# ConsoleWindow, but...best not to overcomplicate things.
stylesheet_path = "convo/input/style"
@@ -516,7 +536,7 @@ class ConsoleInput(QtWidgets.QLineEdit):
# NOTE: Do we really want everyone knowing we're around if we're
# messing around in the console? Hm.
parent.mainwindow.idler.time = 0
-
+
if evtkey == QtCore.Qt.Key.Key_Up:
text = str(self.text())
next = parent.text.history.next(text)
diff --git a/convo.py b/convo.py
index e356c9a..c7c0f84 100644
--- a/convo.py
+++ b/convo.py
@@ -14,16 +14,12 @@ except ImportError:
import ostools
from dataobjs import PesterHistory
-from parsetools import (convertTags,
- lexMessage,
- mecmd,
- colorBegin,
- colorEnd,
- smiledict)
+from parsetools import convertTags, lexMessage, mecmd, colorBegin, colorEnd, smiledict
import parsetools
from pnc.dep.attrdict import AttrDict
-PchumLog = logging.getLogger('pchumLogger')
+PchumLog = logging.getLogger("pchumLogger")
+
class PesterTabWindow(QtWidgets.QFrame):
def __init__(self, mainwindow, parent=None, convo="convo"):
@@ -41,18 +37,26 @@ class PesterTabWindow(QtWidgets.QFrame):
self.shortcuts = AttrDict()
self.shortcuts.tabNext = QShortcut(
- QtGui.QKeySequence('Ctrl+j'), self,
- context=QtCore.Qt.ShortcutContext.WidgetWithChildrenShortcut)
+ QtGui.QKeySequence("Ctrl+j"),
+ self,
+ context=QtCore.Qt.ShortcutContext.WidgetWithChildrenShortcut,
+ )
self.shortcuts.tabLast = QShortcut(
- QtGui.QKeySequence('Ctrl+k'), self,
- context=QtCore.Qt.ShortcutContext.WidgetWithChildrenShortcut)
+ QtGui.QKeySequence("Ctrl+k"),
+ self,
+ context=QtCore.Qt.ShortcutContext.WidgetWithChildrenShortcut,
+ )
# Note that we use reversed keys here.
self.shortcuts.tabUp = QShortcut(
- QtGui.QKeySequence('Ctrl+PgDown'), self,
- context=QtCore.Qt.ShortcutContext.WidgetWithChildrenShortcut)
+ QtGui.QKeySequence("Ctrl+PgDown"),
+ self,
+ context=QtCore.Qt.ShortcutContext.WidgetWithChildrenShortcut,
+ )
self.shortcuts.tabDn = QShortcut(
- QtGui.QKeySequence('Ctrl+PgUp'), self,
- context=QtCore.Qt.ShortcutContext.WidgetWithChildrenShortcut)
+ QtGui.QKeySequence("Ctrl+PgUp"),
+ self,
+ context=QtCore.Qt.ShortcutContext.WidgetWithChildrenShortcut,
+ )
self.shortcuts.tabNext.activated.connect(self.nudgeTabNext)
self.shortcuts.tabUp.activated.connect(self.nudgeTabNext)
@@ -61,7 +65,7 @@ class PesterTabWindow(QtWidgets.QFrame):
self.initTheme(self.mainwindow.theme)
self.layout = QtWidgets.QVBoxLayout()
- self.layout.setContentsMargins(0,0,0,0)
+ self.layout.setContentsMargins(0, 0, 0, 0)
self.layout.addWidget(self.tabs)
self.setLayout(self.layout)
self.convos = {}
@@ -83,6 +87,7 @@ class PesterTabWindow(QtWidgets.QFrame):
self.tabs.removeTab(i)
self.changedTab = False
return c
+
def addChat(self, convo):
self.convos[convo.title()] = convo
# either addTab or setCurrentIndex will trigger changed()
@@ -90,6 +95,7 @@ class PesterTabWindow(QtWidgets.QFrame):
self.tabIndices[convo.title()] = newindex
self.tabs.setCurrentIndex(newindex)
self.tabs.setTabIcon(newindex, convo.icon())
+
def showChat(self, handle):
tabi = self.tabIndices[handle]
if self.tabs.currentIndex() == tabi:
@@ -98,6 +104,7 @@ class PesterTabWindow(QtWidgets.QFrame):
self.convos[handle].raiseChat()
else:
self.tabs.setCurrentIndex(tabi)
+
"""
There are two instances of "convoHasFocus" for some reason?
This one seems to just get redefined.
@@ -107,7 +114,7 @@ class PesterTabWindow(QtWidgets.QFrame):
self.tabs.tabText(self.tabs.currentIndex()) == convo.title()):
return True
"""
-
+
def isBot(self, *args, **kwargs):
return self.mainwindow.isBot(*args, **kwargs)
@@ -115,29 +122,35 @@ class PesterTabWindow(QtWidgets.QFrame):
# TODO: Clean this up. Our text areas now call this.
keypress = event.key()
mods = event.modifiers()
- if ((mods & QtCore.Qt.KeyboardModifier.ControlModifier) and
- keypress == QtCore.Qt.Key.Key_Tab):
+ if (
+ mods & QtCore.Qt.KeyboardModifier.ControlModifier
+ ) and keypress == QtCore.Qt.Key.Key_Tab:
handles = list(self.convos.keys())
waiting = self.mainwindow.waitingMessages.waitingHandles()
waitinghandles = list(set(handles) & set(waiting))
if len(waitinghandles) > 0:
nexti = self.tabIndices[waitinghandles[0]]
else:
- nexti = (self.tabIndices[self.currentConvo.title()] + 1) % self.tabs.count()
+ nexti = (
+ self.tabIndices[self.currentConvo.title()] + 1
+ ) % self.tabs.count()
self.tabs.setCurrentIndex(nexti)
@QtCore.pyqtSlot()
- def nudgeTabNext(self): return self.nudgeTabIndex(+1)
+ def nudgeTabNext(self):
+ return self.nudgeTabIndex(+1)
+
@QtCore.pyqtSlot()
- def nudgeTabLast(self): return self.nudgeTabIndex(-1)
+ def nudgeTabLast(self):
+ return self.nudgeTabIndex(-1)
def nudgeTabIndex(self, direction):
# Inverted controls. Might add an option for this if people want
# it.
- #~if keypress == QtCore.Qt.Key.Key_PageDown:
- #~ direction = 1
- #~elif keypress == QtCore.Qt.Key.Key_PageUp:
- #~ direction = -1
+ # ~if keypress == QtCore.Qt.Key.Key_PageDown:
+ # ~ direction = 1
+ # ~elif keypress == QtCore.Qt.Key.Key_PageUp:
+ # ~ direction = -1
# ...Processing...
tabs = self.tabs
# Pick our new index by sliding up or down the tab range.
@@ -161,7 +174,7 @@ class PesterTabWindow(QtWidgets.QFrame):
tabs.setCurrentIndex(nind)
def contextMenuEvent(self, event):
- #~if event.reason() == QtGui.QContextMenuEvent.Reason.Mouse:
+ # ~if event.reason() == QtGui.QContextMenuEvent.Reason.Mouse:
tabi = self.tabs.tabAt(event.pos())
if tabi < 0:
tabi = self.tabs.currentIndex()
@@ -179,12 +192,14 @@ class PesterTabWindow(QtWidgets.QFrame):
def closeSoft(self):
self.softclose = True
self.close()
+
def updateBlocked(self, handle):
i = self.tabIndices[handle]
icon = QtGui.QIcon(self.mainwindow.theme["main/chums/moods/blocked/icon"])
self.tabs.setTabIcon(i, icon)
if self.tabs.currentIndex() == i:
self.setWindowIcon(icon)
+
def updateMood(self, handle, mood, unblocked=False):
i = self.tabIndices[handle]
if handle in self.mainwindow.config.getBlocklist() and not unblocked:
@@ -194,37 +209,42 @@ class PesterTabWindow(QtWidgets.QFrame):
self.tabs.setTabIcon(i, icon)
if self.tabs.currentIndex() == i:
self.setWindowIcon(icon)
+
def closeEvent(self, event):
if not self.softclose:
while self.tabs.count() > 0:
self.tabClose(0)
self.windowClosed.emit()
+
def focusInEvent(self, event):
# make sure we're not switching tabs!
i = self.tabs.tabAt(self.mapFromGlobal(QtGui.QCursor.pos()))
if i == -1:
- i = self.tabs.currentIndex()
+ i = self.tabs.currentIndex()
handle = str(self.tabs.tabText(i))
self.clearNewMessage(handle)
+
def convoHasFocus(self, handle):
i = self.tabIndices[handle]
- if (self.tabs.currentIndex() == i and
- (self.hasFocus() or self.tabs.hasFocus())):
+ if self.tabs.currentIndex() == i and (self.hasFocus() or self.tabs.hasFocus()):
return True
else:
return False
+
def notifyNewMessage(self, handle):
i = self.tabIndices[handle]
- self.tabs.setTabTextColor(i,
- QtGui.QColor(self.mainwindow.theme["%s/tabs/newmsgcolor"
- % (self.type)]))
+ self.tabs.setTabTextColor(
+ i, QtGui.QColor(self.mainwindow.theme["%s/tabs/newmsgcolor" % (self.type)])
+ )
convo = self.convos[handle]
# Create a function for the icon to use
# TODO: Let us disable this.
def func():
convo.showChat()
+
self.mainwindow.waitingMessages.addMessage(handle, func)
# set system tray
+
def clearNewMessage(self, handle):
try:
i = self.tabIndices[handle]
@@ -232,13 +252,15 @@ class PesterTabWindow(QtWidgets.QFrame):
except KeyError:
pass
self.mainwindow.waitingMessages.messageAnswered(handle)
+
def initTheme(self, theme):
self.resize(*theme["convo/size"])
self.setStyleSheet(theme["convo/tabwindow/style"])
self.tabs.setShape(QtWidgets.QTabBar.Shape(theme["convo/tabs/tabstyle"]))
- self.tabs.setStyleSheet("QTabBar::tab{ %s } QTabBar::tab:selected { %s }"
- % (theme["convo/tabs/style"],
- theme["convo/tabs/selectedstyle"]))
+ self.tabs.setStyleSheet(
+ "QTabBar::tab{ %s } QTabBar::tab:selected { %s }"
+ % (theme["convo/tabs/style"], theme["convo/tabs/selectedstyle"])
+ )
def changeTheme(self, theme):
self.initTheme(theme)
@@ -255,20 +277,20 @@ class PesterTabWindow(QtWidgets.QFrame):
def tabClose(self, i):
handle = str(self.tabs.tabText(i))
self.mainwindow.waitingMessages.messageAnswered(handle)
- #print(self.convos.keys())
+ # print(self.convos.keys())
# I, legit don' t know why this is an issue, but, uh, yeah-
try:
convo = self.convos[handle]
except:
- #handle = handle.replace("&","")
- handle = ''.join(handle.split('&', 1))
+ # handle = handle.replace("&","")
+ handle = "".join(handle.split("&", 1))
convo = self.convos[handle]
del self.convos[handle]
del self.tabIndices[handle]
self.tabs.removeTab(i)
for (h, j) in self.tabIndices.items():
if j > i:
- self.tabIndices[h] = j-1
+ self.tabIndices[h] = j - 1
self.layout.removeWidget(convo)
convo.close()
if self.tabs.count() == 0:
@@ -312,10 +334,12 @@ class PesterTabWindow(QtWidgets.QFrame):
windowClosed = QtCore.pyqtSignal()
+
class PesterMovie(QtGui.QMovie):
def __init__(self, parent):
super(PesterMovie, self).__init__(parent)
self.textwindow = parent
+
@QtCore.pyqtSlot(int)
def animate(self, frame):
text = self.textwindow
@@ -327,20 +351,25 @@ class PesterMovie(QtGui.QMovie):
if text.hasTabs:
i = text.tabobject.tabIndices[text.parent().title()]
if text.tabobject.tabs.currentIndex() == i:
- text.document().addResource(QtGui.QTextDocument.ResourceType.ImageResource.value,
- text.urls[movie], movie.currentPixmap())
+ text.document().addResource(
+ QtGui.QTextDocument.ResourceType.ImageResource.value,
+ text.urls[movie],
+ movie.currentPixmap(),
+ )
text.setLineWrapColumnOrWidth(text.lineWrapColumnOrWidth())
else:
- text.document().addResource(QtGui.QTextDocument.ResourceType.ImageResource.value,
- text.urls[movie],
- movie.currentPixmap())
+ text.document().addResource(
+ QtGui.QTextDocument.ResourceType.ImageResource.value,
+ text.urls[movie],
+ movie.currentPixmap(),
+ )
text.setLineWrapColumnOrWidth(text.lineWrapColumnOrWidth())
-
+
class PesterText(QtWidgets.QTextEdit):
def __init__(self, theme, parent=None):
super(PesterText, self).__init__(parent)
- if hasattr(self.parent(), 'mainwindow'):
+ if hasattr(self.parent(), "mainwindow"):
self.mainwindow = self.parent().mainwindow
else:
self.mainwindow = self.parent()
@@ -356,8 +385,12 @@ class PesterText(QtWidgets.QTextEdit):
self.copyAvailable[bool].connect(self.textReady)
self.urls = {}
for k in smiledict:
- self.addAnimation(QtCore.QUrl("smilies/%s" % (smiledict[k])), "smilies/%s" % (smiledict[k]))
- #self.mainwindow.animationSetting[bool].connect(self.animateChanged)
+ self.addAnimation(
+ QtCore.QUrl("smilies/%s" % (smiledict[k])),
+ "smilies/%s" % (smiledict[k]),
+ )
+ # self.mainwindow.animationSetting[bool].connect(self.animateChanged)
+
def addAnimation(self, url, fileName):
# We don't need to treat images formats like .png as animation,
# this always opens a file handler otherwise, "movie.frameCount() > 1" isn't sufficient.
@@ -365,12 +398,12 @@ class PesterText(QtWidgets.QTextEdit):
# As long as we're only using gifs there's no advantage to that though.
if not fileName.endswith(".gif"):
return
-
+
movie = PesterMovie(self)
movie.setFileName(fileName)
self.urls[movie] = url
movie.frameChanged[int].connect(movie.animate)
-
+
"""
@QtCore.pyqtSlot(bool)
def animateChanged(self, animate):
@@ -393,29 +426,37 @@ class PesterText(QtWidgets.QTextEdit):
@QtCore.pyqtSlot(bool)
def textReady(self, ready):
self.textSelected = ready
+
def initTheme(self, theme):
if "convo/scrollbar" in theme:
- self.setStyleSheet("QTextEdit { %s }"
- "QScrollBar:vertical { %s }"
- "QScrollBar::handle:vertical { %s }"
- "QScrollBar::add-line:vertical { %s }"
- "QScrollBar::sub-line:vertical { %s }"
- "QScrollBar:up-arrow:vertical { %s }"
- "QScrollBar:down-arrow:vertical { %s }"
- % (theme["convo/textarea/style"],
- theme["convo/scrollbar/style"],
- theme["convo/scrollbar/handle"],
- theme["convo/scrollbar/downarrow"],
- theme["convo/scrollbar/uparrow"],
- theme["convo/scrollbar/uarrowstyle"],
- theme["convo/scrollbar/darrowstyle"]))
+ self.setStyleSheet(
+ "QTextEdit { %s }"
+ "QScrollBar:vertical { %s }"
+ "QScrollBar::handle:vertical { %s }"
+ "QScrollBar::add-line:vertical { %s }"
+ "QScrollBar::sub-line:vertical { %s }"
+ "QScrollBar:up-arrow:vertical { %s }"
+ "QScrollBar:down-arrow:vertical { %s }"
+ % (
+ theme["convo/textarea/style"],
+ theme["convo/scrollbar/style"],
+ theme["convo/scrollbar/handle"],
+ theme["convo/scrollbar/downarrow"],
+ theme["convo/scrollbar/uparrow"],
+ theme["convo/scrollbar/uarrowstyle"],
+ theme["convo/scrollbar/darrowstyle"],
+ )
+ )
else:
self.setStyleSheet("QTextEdit { %s }" % (theme["convo/textarea/style"]))
+
def addMessage(self, lexmsg, chum):
if len(lexmsg) == 0:
return
color = chum.colorcmd()
- systemColor = QtGui.QColor(self.parent().mainwindow.theme["convo/systemMsgColor"])
+ systemColor = QtGui.QColor(
+ self.parent().mainwindow.theme["convo/systemMsgColor"]
+ )
initials = chum.initials()
parent = self.parent()
window = parent.mainwindow
@@ -438,28 +479,34 @@ class PesterText(QtWidgets.QTextEdit):
time = ""
if lexmsg[0] == "PESTERCHUM:BEGIN":
parent.setChumOpen(True)
- pmsg = chum.pestermsg(me, systemColor, window.theme["convo/text/beganpester"])
+ pmsg = chum.pestermsg(
+ me, systemColor, window.theme["convo/text/beganpester"]
+ )
window.chatlog.log(chum.handle, pmsg)
self.append(convertTags(pmsg))
elif lexmsg[0] == "PESTERCHUM:CEASE":
parent.setChumOpen(False)
- pmsg = chum.pestermsg(me, systemColor, window.theme["convo/text/ceasepester"])
+ pmsg = chum.pestermsg(
+ me, systemColor, window.theme["convo/text/ceasepester"]
+ )
window.chatlog.log(chum.handle, pmsg)
self.append(convertTags(pmsg))
elif lexmsg[0] == "PESTERCHUM:BLOCK":
- pmsg = chum.pestermsg(me, systemColor, window.theme['convo/text/blocked'])
+ pmsg = chum.pestermsg(me, systemColor, window.theme["convo/text/blocked"])
window.chatlog.log(chum.handle, pmsg)
self.append(convertTags(pmsg))
elif lexmsg[0] == "PESTERCHUM:UNBLOCK":
- pmsg = chum.pestermsg(me, systemColor, window.theme['convo/text/unblocked'])
+ pmsg = chum.pestermsg(me, systemColor, window.theme["convo/text/unblocked"])
window.chatlog.log(chum.handle, pmsg)
self.append(convertTags(pmsg))
elif lexmsg[0] == "PESTERCHUM:BLOCKED":
- pmsg = chum.pestermsg(me, systemColor, window.theme['convo/text/blockedmsg'])
+ pmsg = chum.pestermsg(
+ me, systemColor, window.theme["convo/text/blockedmsg"]
+ )
window.chatlog.log(chum.handle, pmsg)
self.append(convertTags(pmsg))
elif lexmsg[0] == "PESTERCHUM:IDLE":
- imsg = chum.idlemsg(systemColor, window.theme['convo/text/idle'])
+ imsg = chum.idlemsg(systemColor, window.theme["convo/text/idle"])
window.chatlog.log(chum.handle, imsg)
self.append(convertTags(imsg))
elif type(lexmsg[0]) is mecmd:
@@ -471,30 +518,34 @@ class PesterText(QtWidgets.QTextEdit):
self.append(time + convertTags(memsg))
else:
if not parent.chumopen and chum is not me:
- beginmsg = chum.pestermsg(me, systemColor, window.theme["convo/text/beganpester"])
+ beginmsg = chum.pestermsg(
+ me, systemColor, window.theme["convo/text/beganpester"]
+ )
parent.setChumOpen(True)
window.chatlog.log(chum.handle, beginmsg)
self.append(convertTags(beginmsg))
- lexmsg[0:0] = [colorBegin("" % (color), color),
- "%s: " % (initials)]
+ lexmsg[0:0] = [colorBegin("" % (color), color), "%s: " % (initials)]
lexmsg.append(colorEnd(""))
- self.append(""
- + time
- + convertTags(lexmsg)
- + "")
- #self.append(''
+ self.append(
+ '' + time + convertTags(lexmsg) + ""
+ )
+ # self.append(''
# + ''
# + ''
# + '');
if chum is me:
window.chatlog.log(parent.chum.handle, lexmsg)
else:
- if ((window.idler.auto or window.idler.manual) and parent.chumopen
- and not parent.isBot(chum.handle)):
+ if (
+ (window.idler.auto or window.idler.manual)
+ and parent.chumopen
+ and not parent.isBot(chum.handle)
+ ):
idlethreshhold = 60
- if (not hasattr(self, 'lastmsg')) or \
- datetime.now() - self.lastmsg > timedelta(0,idlethreshhold):
+ if (
+ not hasattr(self, "lastmsg")
+ ) or datetime.now() - self.lastmsg > timedelta(0, idlethreshhold):
verb = window.theme["convo/text/idle"]
idlemsg = me.idlemsg(systemColor, verb)
parent.textArea.append(convertTags(idlemsg))
@@ -502,10 +553,12 @@ class PesterText(QtWidgets.QTextEdit):
parent.messageSent.emit("PESTERCHUM:IDLE", parent.title())
self.lastmsg = datetime.now()
window.chatlog.log(chum.handle, lexmsg)
+
def changeTheme(self, theme):
self.initTheme(theme)
sb = self.verticalScrollBar()
sb.setValue(sb.maximum())
+
def focusInEvent(self, event):
self.parent().clearNewMessage()
QtWidgets.QTextEdit.focusInEvent(self, event)
@@ -516,12 +569,16 @@ class PesterText(QtWidgets.QTextEdit):
def keyPressEvent(self, event):
# First parent is the PesterConvo containing this.
# Second parent is the PesterTabWindow containing *it*.
- pass_to_super = (QtCore.Qt.Key.Key_PageUp, QtCore.Qt.Key.Key_PageDown,
- QtCore.Qt.Key.Key_Up, QtCore.Qt.Key.Key_Down)
+ pass_to_super = (
+ QtCore.Qt.Key.Key_PageUp,
+ QtCore.Qt.Key.Key_PageDown,
+ QtCore.Qt.Key.Key_Up,
+ QtCore.Qt.Key.Key_Down,
+ )
parent = self.parent()
key = event.key()
- #keymods = event.modifiers()
- if hasattr(parent, 'textInput') and key not in pass_to_super:
+ # keymods = event.modifiers()
+ if hasattr(parent, "textInput") and key not in pass_to_super:
# TODO: Shift focus here on bare (no modifiers) alphanumerics.
parent.textInput.keyPressEvent(event)
@@ -546,9 +603,11 @@ class PesterText(QtWidgets.QTextEdit):
if event.modifiers() == QtCore.Qt.KeyboardModifier.ControlModifier:
QtWidgets.QApplication.clipboard().setText(url)
else:
- QtGui.QDesktopServices.openUrl(QtCore.QUrl(url,
- QtCore.QUrl.ParsingMode.TolerantMode))
+ QtGui.QDesktopServices.openUrl(
+ QtCore.QUrl(url, QtCore.QUrl.ParsingMode.TolerantMode)
+ )
QtWidgets.QTextEdit.mousePressEvent(self, event)
+
def mouseMoveEvent(self, event):
QtWidgets.QTextEdit.mouseMoveEvent(self, event)
try:
@@ -558,8 +617,13 @@ class PesterText(QtWidgets.QTextEdit):
# PyQt5
pos = event.pos()
if self.anchorAt(pos):
- if self.viewport().cursor().shape != QtCore.Qt.CursorShape.PointingHandCursor:
- self.viewport().setCursor(QtGui.QCursor(QtCore.Qt.CursorShape.PointingHandCursor))
+ if (
+ self.viewport().cursor().shape
+ != QtCore.Qt.CursorShape.PointingHandCursor
+ ):
+ self.viewport().setCursor(
+ QtGui.QCursor(QtCore.Qt.CursorShape.PointingHandCursor)
+ )
else:
self.viewport().setCursor(QtGui.QCursor(QtCore.Qt.CursorShape.IBeamCursor))
@@ -567,24 +631,28 @@ class PesterText(QtWidgets.QTextEdit):
textMenu = self.createStandardContextMenu()
textMenu.exec(event.globalPos())
+
class PesterInput(QtWidgets.QLineEdit):
stylesheet_path = "convo/input/style"
+
def __init__(self, theme, parent=None):
super(PesterInput, self).__init__(parent)
self.changeTheme(theme)
+
def changeTheme(self, theme):
# Explicitly set color if not already set.
# (Some platforms seem to default to white instead of black.)
-
- StyleSheet = theme[self.stylesheet_path]
- if "color:" not in theme[self.stylesheet_path].replace(' ', ''):
+
+ StyleSheet = theme[self.stylesheet_path]
+ if "color:" not in theme[self.stylesheet_path].replace(" ", ""):
StyleSheet = "color: black; " + StyleSheet
self.setStyleSheet(StyleSheet)
-
+
def focusInEvent(self, event):
self.parent().clearNewMessage()
self.parent().textArea.textCursor().clearSelection()
super(PesterInput, self).focusInEvent(event)
+
def keyPressEvent(self, event):
if event.key() == QtCore.Qt.Key.Key_Up:
text = str(self.text())
@@ -600,6 +668,7 @@ class PesterInput(QtWidgets.QLineEdit):
self.parent().mainwindow.idler.time = 0
super(PesterInput, self).keyPressEvent(event)
+
class PesterConvo(QtWidgets.QFrame):
def __init__(self, chum, initiated, mainwindow, parent=None):
super(PesterConvo, self).__init__(parent)
@@ -610,9 +679,9 @@ class PesterConvo(QtWidgets.QFrame):
self.mainwindow = mainwindow
theme = self.mainwindow.theme
self.resize(*theme["convo/size"])
- self.setStyleSheet("QtWidgets.QFrame#%s { %s }"
- % (chum.handle,
- theme["convo/style"]))
+ self.setStyleSheet(
+ "QtWidgets.QFrame#%s { %s }" % (chum.handle, theme["convo/style"])
+ )
self.setWindowIcon(self.icon())
self.setWindowTitle(self.title())
@@ -620,12 +689,22 @@ class PesterConvo(QtWidgets.QFrame):
self.chumLabel = QtWidgets.QLabel(t.safe_substitute(handle=chum.handle), self)
self.chumLabel.setStyleSheet(self.mainwindow.theme["convo/chumlabel/style"])
- self.chumLabel.setAlignment(self.aligndict["h"][self.mainwindow.theme["convo/chumlabel/align/h"]]
- | self.aligndict["v"][self.mainwindow.theme["convo/chumlabel/align/v"]])
- self.chumLabel.setMaximumHeight(self.mainwindow.theme["convo/chumlabel/maxheight"])
- self.chumLabel.setMinimumHeight(self.mainwindow.theme["convo/chumlabel/minheight"])
- self.chumLabel.setSizePolicy(QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.MinimumExpanding,
- QtWidgets.QSizePolicy.Policy.MinimumExpanding))
+ self.chumLabel.setAlignment(
+ self.aligndict["h"][self.mainwindow.theme["convo/chumlabel/align/h"]]
+ | self.aligndict["v"][self.mainwindow.theme["convo/chumlabel/align/v"]]
+ )
+ self.chumLabel.setMaximumHeight(
+ self.mainwindow.theme["convo/chumlabel/maxheight"]
+ )
+ self.chumLabel.setMinimumHeight(
+ self.mainwindow.theme["convo/chumlabel/minheight"]
+ )
+ self.chumLabel.setSizePolicy(
+ QtWidgets.QSizePolicy(
+ QtWidgets.QSizePolicy.Policy.MinimumExpanding,
+ QtWidgets.QSizePolicy.Policy.MinimumExpanding,
+ )
+ )
self.textArea = PesterText(self.mainwindow.theme, self)
self.textInput = PesterInput(self.mainwindow.theme, self)
self.textInput.setFocus()
@@ -638,28 +717,45 @@ class PesterConvo(QtWidgets.QFrame):
self.layout.addWidget(self.textInput)
self.layout.setSpacing(0)
margins = self.mainwindow.theme["convo/margins"]
- self.layout.setContentsMargins(margins["left"], margins["top"],
- margins["right"], margins["bottom"])
+ self.layout.setContentsMargins(
+ margins["left"], margins["top"], margins["right"], margins["bottom"]
+ )
self.setLayout(self.layout)
self.optionsMenu = QtWidgets.QMenu(self)
- self.optionsMenu.setStyleSheet(self.mainwindow.theme["main/defaultwindow/style"])
- self.addChumAction = QAction(self.mainwindow.theme["main/menus/rclickchumlist/addchum"], self)
+ self.optionsMenu.setStyleSheet(
+ self.mainwindow.theme["main/defaultwindow/style"]
+ )
+ self.addChumAction = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/addchum"], self
+ )
self.addChumAction.triggered.connect(self.addThisChum)
- self.blockAction = QAction(self.mainwindow.theme["main/menus/rclickchumlist/blockchum"], self)
+ self.blockAction = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/blockchum"], self
+ )
self.blockAction.triggered.connect(self.blockThisChum)
- self.quirksOff = QAction(self.mainwindow.theme["main/menus/rclickchumlist/quirksoff"], self)
+ self.quirksOff = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/quirksoff"], self
+ )
self.quirksOff.setCheckable(True)
self.quirksOff.toggled[bool].connect(self.toggleQuirks)
- self.oocToggle = QAction(self.mainwindow.theme["main/menus/rclickchumlist/ooc"], self)
+ self.oocToggle = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/ooc"], self
+ )
self.oocToggle.setCheckable(True)
self.oocToggle.toggled[bool].connect(self.toggleOOC)
- self.unblockchum = QAction(self.mainwindow.theme["main/menus/rclickchumlist/unblockchum"], self)
+ self.unblockchum = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/unblockchum"], self
+ )
self.unblockchum.triggered.connect(self.unblockChumSlot)
- self.reportchum = QAction(self.mainwindow.theme["main/menus/rclickchumlist/report"], self)
+ self.reportchum = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/report"], self
+ )
self.reportchum.triggered.connect(self.reportThisChum)
- self.logchum = QAction(self.mainwindow.theme["main/menus/rclickchumlist/viewlog"], self)
+ self.logchum = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/viewlog"], self
+ )
self.logchum.triggered.connect(self.openChumLogs)
# For this, we'll want to use setChecked to toggle these so they match
@@ -670,25 +766,32 @@ class PesterConvo(QtWidgets.QFrame):
# TODO: Look into setting up theme support here.
# Theme support :3c
- #if self.mainwindow.theme.has_key("main/menus/rclickchumlist/beeponmessage"):
+ # if self.mainwindow.theme.has_key("main/menus/rclickchumlist/beeponmessage"):
try:
- self._beepToggle = QAction(self.mainwindow.theme["main/menus/rclickchumlist/beeponmessage"], self)
+ self._beepToggle = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/beeponmessage"], self
+ )
except:
self._beepToggle = QAction("BEEP ON MESSAGE", self)
self._beepToggle.setCheckable(True)
self._beepToggle.toggled[bool].connect(self.toggleBeep)
- #if self.mainwindow.theme.has_key("main/menus/rclickchumlist/flashonmessage"):
+ # if self.mainwindow.theme.has_key("main/menus/rclickchumlist/flashonmessage"):
try:
- self._flashToggle = QAction(self.mainwindow.theme["main/menus/rclickchumlist/flashonmessage"], self)
+ self._flashToggle = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/flashonmessage"], self
+ )
except:
self._flashToggle = QAction("FLASH ON MESSAGE", self)
self._flashToggle.setCheckable(True)
self._flashToggle.toggled[bool].connect(self.toggleFlash)
- #if self.mainwindow.theme.has_key("main/menus/rclickchumlist/mutenotifications"):
+ # if self.mainwindow.theme.has_key("main/menus/rclickchumlist/mutenotifications"):
try:
- self._muteToggle = QAction(self.mainwindow.theme["main/menus/rclickchumlist/mutenotifications"], self)
+ self._muteToggle = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/mutenotifications"],
+ self,
+ )
except:
self._muteToggle = QAction("MUTE NOTIFICATIONS", self)
self._muteToggle.setCheckable(True)
@@ -717,7 +820,11 @@ class PesterConvo(QtWidgets.QFrame):
if parent:
parent.addChat(self)
if initiated:
- msg = self.mainwindow.profile().pestermsg(self.chum, QtGui.QColor(self.mainwindow.theme["convo/systemMsgColor"]), self.mainwindow.theme["convo/text/beganpester"])
+ msg = self.mainwindow.profile().pestermsg(
+ self.chum,
+ QtGui.QColor(self.mainwindow.theme["convo/systemMsgColor"]),
+ self.mainwindow.theme["convo/text/beganpester"],
+ )
self.setChumOpen(True)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.title(), msg)
@@ -726,8 +833,10 @@ class PesterConvo(QtWidgets.QFrame):
def title(self):
return self.chum.handle
+
def icon(self):
return self.chum.mood.icon(self.mainwindow.theme)
+
def myUpdateMood(self, mood):
chum = self.mainwindow.profile()
syscolor = QtGui.QColor(self.mainwindow.theme["convo/systemMsgColor"])
@@ -740,12 +849,12 @@ class PesterConvo(QtWidgets.QFrame):
def updateMood(self, mood, unblocked=False, old=None):
syscolor = QtGui.QColor(self.mainwindow.theme["convo/systemMsgColor"])
- #~ if mood.name() == "offline" and self.chumopen == True and not unblocked:
- #~ self.mainwindow.ceasesound.play()
- #~ msg = self.chum.pestermsg(self.mainwindow.profile(), syscolor, self.mainwindow.theme["convo/text/ceasepester"])
- #~ self.textArea.append(convertTags(msg))
- #~ self.mainwindow.chatlog.log(self.title(), msg)
- #~ self.chumopen = False
+ # ~ if mood.name() == "offline" and self.chumopen == True and not unblocked:
+ # ~ self.mainwindow.ceasesound.play()
+ # ~ msg = self.chum.pestermsg(self.mainwindow.profile(), syscolor, self.mainwindow.theme["convo/text/ceasepester"])
+ # ~ self.textArea.append(convertTags(msg))
+ # ~ self.mainwindow.chatlog.log(self.title(), msg)
+ # ~ self.chumopen = False
if old and old.name() != mood.name():
msg = self.chum.moodmsg(mood, syscolor, self.mainwindow.theme)
self.textArea.append(convertTags(msg))
@@ -754,7 +863,9 @@ class PesterConvo(QtWidgets.QFrame):
self.parent().updateMood(self.title(), mood, unblocked)
else:
if self.chum.blocked(self.mainwindow.config) and not unblocked:
- self.setWindowIcon(QtGui.QIcon(self.mainwindow.theme["main/chums/moods/blocked/icon"]))
+ self.setWindowIcon(
+ QtGui.QIcon(self.mainwindow.theme["main/chums/moods/blocked/icon"])
+ )
self.optionsMenu.addAction(self.unblockchum)
self.optionsMenu.removeAction(self.blockAction)
else:
@@ -762,17 +873,21 @@ class PesterConvo(QtWidgets.QFrame):
self.optionsMenu.removeAction(self.unblockchum)
self.optionsMenu.addAction(self.blockAction)
# print mood update?
+
def updateBlocked(self):
if self.parent():
self.parent().updateBlocked(self.title())
else:
- self.setWindowIcon(QtGui.QIcon(self.mainwindow.theme["main/chums/moods/blocked/icon"]))
+ self.setWindowIcon(
+ QtGui.QIcon(self.mainwindow.theme["main/chums/moods/blocked/icon"])
+ )
self.optionsMenu.addAction(self.unblockchum)
self.optionsMenu.removeAction(self.blockAction)
def updateColor(self, color):
PchumLog.debug("convo updateColor: " + str(color))
self.chum.color = color
+
def addMessage(self, msg, me=True):
if type(msg) in [str, str]:
lexmsg = lexMessage(msg)
@@ -796,16 +911,19 @@ class PesterConvo(QtWidgets.QFrame):
memoblink &= self.mainwindow.config.MBLINK
pesterblink &= self.mainwindow.config.PBLINK
mutednots = self.notifications_muted
- #mtsrc = self
+ # mtsrc = self
if parent:
try:
mutednots = parent.notifications_muted
- #mtsrc = parent
+ # mtsrc = parent
except:
pass
- if not (self.hasFocus() or self.textArea.hasFocus() or
- self.textInput.hasFocus() or
- (parent and parent.convoHasFocus(title))):
+ if not (
+ self.hasFocus()
+ or self.textArea.hasFocus()
+ or self.textInput.hasFocus()
+ or (parent and parent.convoHasFocus(title))
+ ):
# ok if it has a tabconvo parent, send that the notify.
if parent:
# Just let the icon highlight normally.
@@ -818,11 +936,11 @@ class PesterConvo(QtWidgets.QFrame):
# the checks there.
# PesterTabWindow -> MemoTabWindow
if isinstance(parent, MemoTabWindow):
- if self.always_flash or memoblink:
- self.mainwindow.gainAttention.emit(parent)
+ if self.always_flash or memoblink:
+ self.mainwindow.gainAttention.emit(parent)
elif isinstance(parent, PesterTabWindow):
- if self.always_flash or pesterblink:
- self.mainwindow.gainAttention.emit(parent)
+ if self.always_flash or pesterblink:
+ self.mainwindow.gainAttention.emit(parent)
# if not change the window title and update system tray
else:
self.newmessage = True
@@ -831,15 +949,16 @@ class PesterConvo(QtWidgets.QFrame):
# entirely sure how much of this directly affects what we see.
def func():
self.showChat()
+
self.mainwindow.waitingMessages.addMessage(title, func)
if not mutednots:
# Once again, PesterMemo inherits from PesterConvo.
if isinstance(self, PesterMemo):
- if self.always_flash or memoblink:
- self.mainwindow.gainAttention.emit(self)
+ if self.always_flash or memoblink:
+ self.mainwindow.gainAttention.emit(self)
elif isinstance(self, PesterConvo):
- if self.always_flash or pesterblink:
- self.mainwindow.gainAttention.emit(self)
+ if self.always_flash or pesterblink:
+ self.mainwindow.gainAttention.emit(self)
def clearNewMessage(self):
if self.parent():
@@ -849,6 +968,7 @@ class PesterConvo(QtWidgets.QFrame):
self.setWindowTitle(self.title())
self.mainwindow.waitingMessages.messageAnswered(self.title())
# reset system tray
+
def focusInEvent(self, event):
self.clearNewMessage()
self.textInput.setFocus()
@@ -862,68 +982,101 @@ class PesterConvo(QtWidgets.QFrame):
if self.parent():
self.parent().showChat(self.title())
self.raiseChat()
+
def contextMenuEvent(self, event):
if event.reason() == QtGui.QContextMenuEvent.Reason.Mouse:
self.optionsMenu.popup(event.globalPos())
+
def closeEvent(self, event):
self.mainwindow.waitingMessages.messageAnswered(self.title())
for movie in self.textArea.urls:
- movie.setFileName("") # Required, sometimes, for some reason. . .
+ movie.setFileName("") # Required, sometimes, for some reason. . .
movie.stop()
del movie
self.windowClosed.emit(self.title())
def setChumOpen(self, o):
self.chumopen = o
+
def changeTheme(self, theme):
self.resize(*theme["convo/size"])
- self.setStyleSheet("QtWidgets.QFrame#%s { %s }" % (self.chum.handle, theme["convo/style"]))
+ self.setStyleSheet(
+ "QtWidgets.QFrame#%s { %s }" % (self.chum.handle, theme["convo/style"])
+ )
margins = theme["convo/margins"]
- self.layout.setContentsMargins(margins["left"], margins["top"],
- margins["right"], margins["bottom"])
+ self.layout.setContentsMargins(
+ margins["left"], margins["top"], margins["right"], margins["bottom"]
+ )
self.setWindowIcon(self.icon())
t = Template(self.mainwindow.theme["convo/chumlabel/text"])
self.chumLabel.setText(t.safe_substitute(handle=self.title()))
self.chumLabel.setStyleSheet(theme["convo/chumlabel/style"])
- self.chumLabel.setAlignment(self.aligndict["h"][self.mainwindow.theme["convo/chumlabel/align/h"]] | self.aligndict["v"][self.mainwindow.theme["convo/chumlabel/align/v"]])
- self.chumLabel.setMaximumHeight(self.mainwindow.theme["convo/chumlabel/maxheight"])
- self.chumLabel.setMinimumHeight(self.mainwindow.theme["convo/chumlabel/minheight"])
- self.chumLabel.setSizePolicy(QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.MinimumExpanding, QtWidgets.QSizePolicy.Policy.Expanding))
- self.quirksOff.setText(self.mainwindow.theme["main/menus/rclickchumlist/quirksoff"])
- self.addChumAction.setText(self.mainwindow.theme["main/menus/rclickchumlist/addchum"])
- self.blockAction.setText(self.mainwindow.theme["main/menus/rclickchumlist/blockchum"])
- self.unblockchum.setText(self.mainwindow.theme["main/menus/rclickchumlist/unblockchum"])
+ self.chumLabel.setAlignment(
+ self.aligndict["h"][self.mainwindow.theme["convo/chumlabel/align/h"]]
+ | self.aligndict["v"][self.mainwindow.theme["convo/chumlabel/align/v"]]
+ )
+ self.chumLabel.setMaximumHeight(
+ self.mainwindow.theme["convo/chumlabel/maxheight"]
+ )
+ self.chumLabel.setMinimumHeight(
+ self.mainwindow.theme["convo/chumlabel/minheight"]
+ )
+ self.chumLabel.setSizePolicy(
+ QtWidgets.QSizePolicy(
+ QtWidgets.QSizePolicy.Policy.MinimumExpanding,
+ QtWidgets.QSizePolicy.Policy.Expanding,
+ )
+ )
+ self.quirksOff.setText(
+ self.mainwindow.theme["main/menus/rclickchumlist/quirksoff"]
+ )
+ self.addChumAction.setText(
+ self.mainwindow.theme["main/menus/rclickchumlist/addchum"]
+ )
+ self.blockAction.setText(
+ self.mainwindow.theme["main/menus/rclickchumlist/blockchum"]
+ )
+ self.unblockchum.setText(
+ self.mainwindow.theme["main/menus/rclickchumlist/unblockchum"]
+ )
self.logchum.setText(self.mainwindow.theme["main/menus/rclickchumlist/viewlog"])
- #if self.mainwindow.theme.has_key("main/menus/rclickchumlist/beeponmessage"):
+ # if self.mainwindow.theme.has_key("main/menus/rclickchumlist/beeponmessage"):
try:
- self._beepToggle.setText(self.mainwindow.theme["main/menus/rclickchumlist/beeponmessage"])
+ self._beepToggle.setText(
+ self.mainwindow.theme["main/menus/rclickchumlist/beeponmessage"]
+ )
except:
self._beepToggle.setText("BEEP ON MESSAGE")
- #if self.mainwindow.theme.has_key("main/menus/rclickchumlist/flashonmessage"):
+ # if self.mainwindow.theme.has_key("main/menus/rclickchumlist/flashonmessage"):
try:
- self._flashToggle.setText(self.mainwindow.theme["main/menus/rclickchumlist/flashonmessage"])
+ self._flashToggle.setText(
+ self.mainwindow.theme["main/menus/rclickchumlist/flashonmessage"]
+ )
except:
self._flashToggle.setText("FLASH ON MESSAGE", self)
- #if self.mainwindow.theme.has_key("main/menus/rclickchumlist/mutenotifications"):
+ # if self.mainwindow.theme.has_key("main/menus/rclickchumlist/mutenotifications"):
try:
- self._muteToggle.setText(self.mainwindow.theme["main/menus/rclickchumlist/mutenotifications"])
+ self._muteToggle.setText(
+ self.mainwindow.theme["main/menus/rclickchumlist/mutenotifications"]
+ )
except:
self._muteToggle.setText("MUTE NOTIFICATIONS")
- #if self.mainwindow.theme.has_key("main/menus/rclickchumlist/report"):
+ # if self.mainwindow.theme.has_key("main/menus/rclickchumlist/report"):
try:
- self.reportchum.setText(self.mainwindow.theme["main/menus/rclickchumlist/report"])
+ self.reportchum.setText(
+ self.mainwindow.theme["main/menus/rclickchumlist/report"]
+ )
except:
pass
self.textArea.changeTheme(theme)
self.textInput.changeTheme(theme)
-
@QtCore.pyqtSlot()
def sentMessage(self):
# Offloaded to another function, like its sisters.
@@ -936,29 +1089,36 @@ class PesterConvo(QtWidgets.QFrame):
@QtCore.pyqtSlot()
def addThisChum(self):
self.mainwindow.addChum(self.chum)
+
@QtCore.pyqtSlot()
def blockThisChum(self):
self.mainwindow.blockChum(self.chum.handle)
+
@QtCore.pyqtSlot()
def reportThisChum(self):
self.mainwindow.reportChum(self.chum.handle)
+
@QtCore.pyqtSlot()
def unblockChumSlot(self):
self.mainwindow.unblockChum(self.chum.handle)
+
@QtCore.pyqtSlot(bool)
def toggleQuirks(self, toggled):
self.applyquirks = not toggled
+
@QtCore.pyqtSlot(bool)
def toggleOOC(self, toggled):
self.ooc = toggled
+
@QtCore.pyqtSlot()
def openChumLogs(self):
currentChum = self.chum.handle
- self.mainwindow.chumList.pesterlogviewer = PesterLogViewer(currentChum,
- self.mainwindow.config,
- self.mainwindow.theme,
- self.mainwindow)
- self.mainwindow.chumList.pesterlogviewer.rejected.connect(self.mainwindow.chumList.closeActiveLog)
+ self.mainwindow.chumList.pesterlogviewer = PesterLogViewer(
+ currentChum, self.mainwindow.config, self.mainwindow.theme, self.mainwindow
+ )
+ self.mainwindow.chumList.pesterlogviewer.rejected.connect(
+ self.mainwindow.chumList.closeActiveLog
+ )
self.mainwindow.chumList.pesterlogviewer.show()
self.mainwindow.chumList.pesterlogviewer.raise_()
self.mainwindow.chumList.pesterlogviewer.activateWindow()
@@ -975,15 +1135,22 @@ class PesterConvo(QtWidgets.QFrame):
def toggleMute(self, toggled):
self.notifications_muted = toggled
- messageSent = QtCore.pyqtSignal('QString', 'QString')
- windowClosed = QtCore.pyqtSignal('QString')
+ messageSent = QtCore.pyqtSignal("QString", "QString")
+ windowClosed = QtCore.pyqtSignal("QString")
+
+ aligndict = {
+ "h": {
+ "center": QtCore.Qt.AlignmentFlag.AlignHCenter,
+ "left": QtCore.Qt.AlignmentFlag.AlignLeft,
+ "right": QtCore.Qt.AlignmentFlag.AlignRight,
+ },
+ "v": {
+ "center": QtCore.Qt.AlignmentFlag.AlignVCenter,
+ "top": QtCore.Qt.AlignmentFlag.AlignTop,
+ "bottom": QtCore.Qt.AlignmentFlag.AlignBottom,
+ },
+ }
- aligndict = {"h": {"center": QtCore.Qt.AlignmentFlag.AlignHCenter,
- "left": QtCore.Qt.AlignmentFlag.AlignLeft,
- "right": QtCore.Qt.AlignmentFlag.AlignRight },
- "v": {"center": QtCore.Qt.AlignmentFlag.AlignVCenter,
- "top": QtCore.Qt.AlignmentFlag.AlignTop,
- "bottom": QtCore.Qt.AlignmentFlag.AlignBottom } }
# the import is way down here to avoid recursive imports
from logviewer import PesterLogViewer
diff --git a/dataobjs.py b/dataobjs.py
index 112acee..b9b485a 100644
--- a/dataobjs.py
+++ b/dataobjs.py
@@ -1,6 +1,7 @@
import logging
import ostools
-PchumLog = logging.getLogger('pchumLogger')
+
+PchumLog = logging.getLogger("pchumLogger")
try:
from PyQt6 import QtGui
except ImportError:
@@ -11,15 +12,17 @@ import re
import random
from mood import Mood
-from parsetools import (timeDifference,
- convertTags,
- lexMessage,
- parseRegexpFunctions,
- smiledict)
+from parsetools import (
+ timeDifference,
+ convertTags,
+ lexMessage,
+ parseRegexpFunctions,
+ smiledict,
+)
from mispeller import mispeller
_urlre = re.compile(r"(?i)(?:^|(?<=\s))(?:(?:https?|ftp)://|magnet:)[^\s]+")
-#_url2re = re.compile(r"(?i)(?\\]+)\)")
_lowerre = re.compile(r"lower\(([\w<>\\]+)\)")
@@ -30,6 +33,7 @@ _smilere = re.compile("|".join(list(smiledict.keys())))
_memore = re.compile(r"(\s|^)(#[A-Za-z0-9_]+)")
_handlere = re.compile(r"(\s|^)(@[A-Za-z0-9_]+)")
+
class pesterQuirk(object):
def __init__(self, quirk):
if type(quirk) != dict:
@@ -46,7 +50,7 @@ class pesterQuirk(object):
self.checkstate = self.quirk["checkstate"]
except KeyError:
pass
-
+
def apply(self, string, first=False, last=False):
if not self.on:
return string
@@ -60,7 +64,7 @@ class pesterQuirk(object):
fr = self.quirk["from"]
if not first and len(fr) > 0 and fr[0] == "^":
return string
- if not last and len(fr) > 0 and fr[len(fr)-1] == "$":
+ if not last and len(fr) > 0 and fr[len(fr) - 1] == "$":
return string
to = self.quirk["to"]
pt = parseRegexpFunctions(to)
@@ -71,15 +75,17 @@ class pesterQuirk(object):
fr = self.quirk["from"]
if not first and len(fr) > 0 and fr[0] == "^":
return string
- if not last and len(fr) > 0 and fr[len(fr)-1] == "$":
+ if not last and len(fr) > 0 and fr[len(fr) - 1] == "$":
return string
+
def randomrep(mo):
choice = random.choice(self.quirk["randomlist"])
pt = parseRegexpFunctions(choice)
return pt.expand(mo)
+
return re.sub(self.quirk["from"], randomrep, string)
elif self.type == "spelling":
- percentage = self.quirk["percentage"]/100.0
+ percentage = self.quirk["percentage"] / 100.0
words = string.split(" ")
newl = []
ctag = re.compile("(?c=?.*?>)", re.I)
@@ -99,7 +105,7 @@ class pesterQuirk(object):
else:
newl.append(w)
return " ".join(newl)
-
+
def __str__(self):
if self.type == "prefix":
return "BEGIN WITH: %s" % (self.quirk["value"])
@@ -108,28 +114,38 @@ class pesterQuirk(object):
elif self.type == "replace":
return "REPLACE %s WITH %s" % (self.quirk["from"], self.quirk["to"])
elif self.type == "regexp":
- return "REGEXP: %s REPLACED WITH %s" % (self.quirk["from"], self.quirk["to"])
+ return "REGEXP: %s REPLACED WITH %s" % (
+ self.quirk["from"],
+ self.quirk["to"],
+ )
elif self.type == "random":
- return "REGEXP: %s RANDOMLY REPLACED WITH %s" % (self.quirk["from"], [r for r in self.quirk["randomlist"]])
+ return "REGEXP: %s RANDOMLY REPLACED WITH %s" % (
+ self.quirk["from"],
+ [r for r in self.quirk["randomlist"]],
+ )
elif self.type == "spelling":
return "MISPELLER: %d%%" % (self.quirk["percentage"])
+
class pesterQuirks(object):
def __init__(self, quirklist):
self.quirklist = []
for q in quirklist:
self.addQuirk(q)
+
def plainList(self):
return [q.quirk for q in self.quirklist]
+
def addQuirk(self, q):
if type(q) == dict:
self.quirklist.append(pesterQuirk(q))
elif type(q) == pesterQuirk:
self.quirklist.append(q)
+
def apply(self, lexed, first=False, last=False):
- prefix = [q for q in self.quirklist if q.type=='prefix']
- suffix = [q for q in self.quirklist if q.type=='suffix']
-
+ prefix = [q for q in self.quirklist if q.type == "prefix"]
+ suffix = [q for q in self.quirklist if q.type == "suffix"]
+
newlist = []
for (i, o) in enumerate(lexed):
if type(o) not in [str, str]:
@@ -140,7 +156,7 @@ class pesterQuirks(object):
newlist.append(string)
newlist.append(o)
continue
- lastStr = (i == len(lexed)-1)
+ lastStr = i == len(lexed) - 1
string = o
for q in self.quirklist:
try:
@@ -170,17 +186,17 @@ class pesterQuirks(object):
excludes.sort(key=lambda exclude: exclude.start())
# Recursion check.
# Strings like http://:3: require this.
- for n in range(0, len(excludes)-1):
- if excludes[n].end() > excludes[n+1].start():
+ for n in range(0, len(excludes) - 1):
+ if excludes[n].end() > excludes[n + 1].start():
excludes.pop(n)
# Seperate parts to be quirked.
sendparts = list()
# Add string until start of exclude at index 0.
until = excludes[0].start()
- sendparts.append(string[:until])
+ sendparts.append(string[:until])
# Add strings between excludes.
for part in range(1, len(excludes)):
- after = excludes[part-1].end()
+ after = excludes[part - 1].end()
until = excludes[part].start()
sendparts.append(string[after:until])
# Add string after exclude at last index.
@@ -191,50 +207,46 @@ class pesterQuirks(object):
recvparts = list()
for part in sendparts:
# No split, apply like normal.
- if q.type == 'regexp' or q.type == 'random':
- recvparts.append(q.apply(part,
- first=(i==0),
- last=lastStr))
- elif q.type == 'prefix' and i == 0:
+ if q.type == "regexp" or q.type == "random":
+ recvparts.append(
+ q.apply(part, first=(i == 0), last=lastStr)
+ )
+ elif q.type == "prefix" and i == 0:
recvparts.append(q.apply(part))
- elif q.type == 'suffix' and lastStr:
+ elif q.type == "suffix" and lastStr:
recvparts.append(q.apply(part))
else:
recvparts.append(q.apply(part))
# Reconstruct and update string.
- string = ''
- #print("excludes: " + str(excludes))
- #print("sendparts: " + str(sendparts))
- #print("recvparts: " + str(recvparts))
+ string = ""
+ # print("excludes: " + str(excludes))
+ # print("sendparts: " + str(sendparts))
+ # print("recvparts: " + str(recvparts))
for part in range(0, len(excludes)):
string += recvparts[part]
string += excludes[part].group()
string += recvparts[-1]
else:
# No split, apply like normal.
- if q.type != 'prefix' and q.type != 'suffix':
- if q.type == 'regexp' or q.type == 'random':
- string = q.apply(string,
- first=(i==0),
- last=lastStr)
+ if q.type != "prefix" and q.type != "suffix":
+ if q.type == "regexp" or q.type == "random":
+ string = q.apply(string, first=(i == 0), last=lastStr)
else:
string = q.apply(string)
- elif q.type == 'prefix' and i == 0:
+ elif q.type == "prefix" and i == 0:
string = q.apply(string)
- elif q.type == 'suffix' and lastStr:
+ elif q.type == "suffix" and lastStr:
string = q.apply(string)
else:
# No split, apply like normal.
- if q.type != 'prefix' and q.type != 'suffix':
- if q.type == 'regexp' or q.type == 'random':
- string = q.apply(string,
- first=(i==0),
- last=lastStr)
+ if q.type != "prefix" and q.type != "suffix":
+ if q.type == "regexp" or q.type == "random":
+ string = q.apply(string, first=(i == 0), last=lastStr)
else:
string = q.apply(string)
- elif q.type == 'prefix' and i == 0:
+ elif q.type == "prefix" and i == 0:
string = q.apply(string)
- elif q.type == 'suffix' and lastStr:
+ elif q.type == "suffix" and lastStr:
string = q.apply(string)
newlist.append(string)
final = []
@@ -249,8 +261,17 @@ class pesterQuirks(object):
for q in self.quirklist:
yield q
+
class PesterProfile(object):
- def __init__(self, handle, color=None, mood=Mood("offline"), group=None, notes="", chumdb=None):
+ def __init__(
+ self,
+ handle,
+ color=None,
+ mood=Mood("offline"),
+ group=None,
+ notes="",
+ chumdb=None,
+ ):
self.handle = handle
if color is None:
if chumdb:
@@ -266,6 +287,7 @@ class PesterProfile(object):
group = "Chums"
self.group = group
self.notes = notes
+
def initials(self, time=None):
handle = self.handle
caps = [l for l in handle if l.isupper()]
@@ -275,37 +297,46 @@ class PesterProfile(object):
PchumLog.debug("caps = " + str(caps))
# Fallback for invalid string
try:
- initials = (handle[0]+caps[0]).upper()
+ initials = (handle[0] + caps[0]).upper()
except:
- PchumLog.exception('')
+ PchumLog.exception("")
initials = "XX"
PchumLog.debug("initials = " + str(initials))
- if hasattr(self, 'time') and time:
+ if hasattr(self, "time") and time:
if self.time > time:
- return "F"+initials
+ return "F" + initials
elif self.time < time:
- return "P"+initials
+ return "P" + initials
else:
- return "C"+initials
+ return "C" + initials
else:
return initials
+
def colorhtml(self):
if self.color:
return self.color.name()
else:
return "#000000"
+
def colorcmd(self):
if self.color:
(r, g, b, a) = self.color.getRgb()
- return "%d,%d,%d" % (r,g,b)
+ return "%d,%d,%d" % (r, g, b)
else:
return "0,0,0"
+
def plaindict(self):
- return (self.handle, {"handle": self.handle,
- "mood": self.mood.name(),
- "color": str(self.color.name()),
- "group": str(self.group),
- "notes": str(self.notes)})
+ return (
+ self.handle,
+ {
+ "handle": self.handle,
+ "mood": self.mood.name(),
+ "color": str(self.color.name()),
+ "group": str(self.group),
+ "notes": str(self.notes),
+ },
+ )
+
def blocked(self, config):
return self.handle in config.getBlocklist()
@@ -315,112 +346,248 @@ class PesterProfile(object):
uppersuffix = suffix.upper()
if time is not None:
handle = "%s %s" % (time.temporal, self.handle)
- initials = time.pcf+self.initials()+time.number+uppersuffix
+ initials = time.pcf + self.initials() + time.number + uppersuffix
else:
handle = self.handle
- initials = self.initials()+uppersuffix
- return "-- %s%s [%s] %s --" % (syscolor.name(), handle, suffix, self.colorhtml(), initials, msg)
+ initials = self.initials() + uppersuffix
+ return "-- %s%s [%s] %s --" % (
+ syscolor.name(),
+ handle,
+ suffix,
+ self.colorhtml(),
+ initials,
+ msg,
+ )
+
def pestermsg(self, otherchum, syscolor, verb):
- return "-- %s [%s] %s %s [%s] at %s --" % (syscolor.name(), self.handle, self.colorhtml(), self.initials(), verb, otherchum.handle, otherchum.colorhtml(), otherchum.initials(), datetime.now().strftime("%H:%M"))
+ return "-- %s [%s] %s %s [%s] at %s --" % (
+ syscolor.name(),
+ self.handle,
+ self.colorhtml(),
+ self.initials(),
+ verb,
+ otherchum.handle,
+ otherchum.colorhtml(),
+ otherchum.initials(),
+ datetime.now().strftime("%H:%M"),
+ )
+
def moodmsg(self, mood, syscolor, theme):
- return "-- %s [%s] changed their mood to %s --" % (syscolor.name(), self.handle, self.colorhtml(), self.initials(), mood.name().upper(), theme["main/chums/moods"][mood.name()]["icon"])
+ return (
+ "-- %s [%s] changed their mood to %s --"
+ % (
+ syscolor.name(),
+ self.handle,
+ self.colorhtml(),
+ self.initials(),
+ mood.name().upper(),
+ theme["main/chums/moods"][mood.name()]["icon"],
+ )
+ )
+
def idlemsg(self, syscolor, verb):
- return "-- %s [%s] %s --" % (syscolor.name(), self.handle, self.colorhtml(), self.initials(), verb)
+ return "-- %s [%s] %s --" % (
+ syscolor.name(),
+ self.handle,
+ self.colorhtml(),
+ self.initials(),
+ verb,
+ )
+
def memoclosemsg(self, syscolor, initials, verb):
if type(initials) == type(list()):
- return "%s %s." % (syscolor.name(), self.colorhtml(), ", ".join(initials), verb)
+ return "%s %s." % (
+ syscolor.name(),
+ self.colorhtml(),
+ ", ".join(initials),
+ verb,
+ )
else:
- return "%s%s%s %s." % (syscolor.name(), self.colorhtml(), initials.pcf, self.initials(), initials.number, verb)
+ return "%s%s%s %s." % (
+ syscolor.name(),
+ self.colorhtml(),
+ initials.pcf,
+ self.initials(),
+ initials.number,
+ verb,
+ )
+
def memonetsplitmsg(self, syscolor, initials):
if len(initials) <= 0:
return "Netsplit quits: None" % (syscolor.name())
else:
- return "Netsplit quits: %s" % (syscolor.name(), ", ".join(initials))
+ return "Netsplit quits: %s" % (
+ syscolor.name(),
+ ", ".join(initials),
+ )
+
def memoopenmsg(self, syscolor, td, timeGrammar, verb, channel):
- (temporal, pcf, when) = (timeGrammar.temporal, timeGrammar.pcf, timeGrammar.when)
+ (temporal, pcf, when) = (
+ timeGrammar.temporal,
+ timeGrammar.pcf,
+ timeGrammar.when,
+ )
timetext = timeDifference(td)
PchumLog.debug("pre pcf+self.initials()")
- initials = 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("_", " "))
+ return "%s %s %s %s." % (
+ syscolor.name(),
+ self.colorhtml(),
+ initials,
+ timetext,
+ verb,
+ channel[1:].upper().replace("_", " "),
+ )
+
def memobanmsg(self, opchum, opgrammar, syscolor, initials, reason):
- opinit = opgrammar.pcf+opchum.initials()+opgrammar.number
+ opinit = opgrammar.pcf + opchum.initials() + opgrammar.number
if type(initials) == type(list()):
if opchum.handle == reason:
- return "%s banned %s from responding to memo." % \
- (opchum.colorhtml(), opinit, self.colorhtml(), ", ".join(initials))
+ return "%s banned %s from responding to memo." % (
+ opchum.colorhtml(),
+ opinit,
+ self.colorhtml(),
+ ", ".join(initials),
+ )
else:
- return "%s banned %s from responding to memo: [%s]." % \
- (opchum.colorhtml(), opinit, self.colorhtml(), ", ".join(initials), str(reason))
+ return (
+ "%s banned %s from responding to memo: [%s]."
+ % (
+ opchum.colorhtml(),
+ opinit,
+ self.colorhtml(),
+ ", ".join(initials),
+ str(reason),
+ )
+ )
else:
# Is timeGrammar defined? Not sure if this works as intented, added try except block to be safe.
try:
- initials = timeGrammar.pcf+self.initials()+timeGrammar.number
+ initials = timeGrammar.pcf + self.initials() + timeGrammar.number
if opchum.handle == reason:
- return "%s banned %s from responding to memo." % \
- (opchum.colorhtml(), opinit, self.colorhtml(), initials)
+ return (
+ "%s banned %s from responding to memo."
+ % (opchum.colorhtml(), opinit, self.colorhtml(), initials)
+ )
else:
- return "%s banned %s from responding to memo: [%s]." % \
- (opchum.colorhtml(), opinit, self.colorhtml(), initials, str(reason))
+ return (
+ "%s banned %s from responding to memo: [%s]."
+ % (
+ opchum.colorhtml(),
+ opinit,
+ self.colorhtml(),
+ initials,
+ str(reason),
+ )
+ )
except:
- PchumLog.exception('')
+ PchumLog.exception("")
initials = self.initials()
if opchum.handle == reason:
- return "%s banned %s from responding to memo." % \
- (opchum.colorhtml(), opinit, self.colorhtml(), initials)
+ return (
+ "%s banned %s from responding to memo."
+ % (opchum.colorhtml(), opinit, self.colorhtml(), initials)
+ )
else:
- return "%s banned %s from responding to memo: [%s]." % \
- (opchum.colorhtml(), opinit, self.colorhtml(), initials, str(reason))
+ return (
+ "%s banned %s from responding to memo: [%s]."
+ % (
+ opchum.colorhtml(),
+ opinit,
+ self.colorhtml(),
+ initials,
+ str(reason),
+ )
+ )
# As far as I'm aware, there's no IRC reply for this, this seems impossible to check for in practice.
def memopermabanmsg(self, opchum, opgrammar, syscolor, timeGrammar):
- initials = (timeGrammar.pcf
- + self.initials()
- + timeGrammar.number)
- opinit = (opgrammar.pcf
- + opchum.initials()
- + opgrammar.number)
- return "%s permabanned %s from the memo." % \
- (opchum.colorhtml(), opinit, self.colorhtml(), initials)
-
+ initials = timeGrammar.pcf + self.initials() + timeGrammar.number
+ opinit = opgrammar.pcf + opchum.initials() + opgrammar.number
+ return "%s permabanned %s from the memo." % (
+ opchum.colorhtml(),
+ opinit,
+ self.colorhtml(),
+ initials,
+ )
+
def memojoinmsg(self, syscolor, td, timeGrammar, verb):
- #(temporal, pcf, when) = (timeGrammar.temporal, timeGrammar.pcf, timeGrammar.when)
+ # (temporal, pcf, when) = (timeGrammar.temporal, timeGrammar.pcf, timeGrammar.when)
timetext = timeDifference(td)
- initials = timeGrammar.pcf+self.initials()+timeGrammar.number
- return "%s %s [%s] %s %s." % \
- (syscolor.name(), self.colorhtml(), timeGrammar.temporal, self.handle,
- initials, timetext, verb)
+ initials = timeGrammar.pcf + self.initials() + timeGrammar.number
+ return "%s %s [%s] %s %s." % (
+ syscolor.name(),
+ self.colorhtml(),
+ timeGrammar.temporal,
+ self.handle,
+ initials,
+ timetext,
+ verb,
+ )
+
def memoopmsg(self, opchum, opgrammar, syscolor):
- opinit = opgrammar.pcf+opchum.initials()+opgrammar.number
- return "%s made %s an OP." % \
- (opchum.colorhtml(), opinit, self.colorhtml(), self.initials())
+ opinit = opgrammar.pcf + opchum.initials() + opgrammar.number
+ return "%s made %s an OP." % (
+ opchum.colorhtml(),
+ opinit,
+ self.colorhtml(),
+ self.initials(),
+ )
+
def memodeopmsg(self, opchum, opgrammar, syscolor):
- opinit = opgrammar.pcf+opchum.initials()+opgrammar.number
- return "%s took away %s's OP powers." % \
- (opchum.colorhtml(), opinit, self.colorhtml(), self.initials())
+ opinit = opgrammar.pcf + opchum.initials() + opgrammar.number
+ return "%s took away %s's OP powers." % (
+ opchum.colorhtml(),
+ opinit,
+ self.colorhtml(),
+ self.initials(),
+ )
+
def memovoicemsg(self, opchum, opgrammar, syscolor):
- opinit = opgrammar.pcf+opchum.initials()+opgrammar.number
- return "%s gave %s voice." % \
- (opchum.colorhtml(), opinit, self.colorhtml(), self.initials())
+ opinit = opgrammar.pcf + opchum.initials() + opgrammar.number
+ return "%s gave %s voice." % (
+ opchum.colorhtml(),
+ opinit,
+ self.colorhtml(),
+ self.initials(),
+ )
+
def memodevoicemsg(self, opchum, opgrammar, syscolor):
- opinit = opgrammar.pcf+opchum.initials()+opgrammar.number
- return "%s took away %s's voice." % \
- (opchum.colorhtml(), opinit, self.colorhtml(), self.initials())
+ opinit = opgrammar.pcf + opchum.initials() + opgrammar.number
+ return "%s took away %s's voice." % (
+ opchum.colorhtml(),
+ opinit,
+ self.colorhtml(),
+ self.initials(),
+ )
+
def memomodemsg(self, opchum, opgrammar, syscolor, modeverb, modeon):
- opinit = opgrammar.pcf+opchum.initials()+opgrammar.number
- if modeon: modeon = "now"
- else: modeon = "no longer"
- return "Memo is %s %s by %s" % \
- (syscolor.name(), modeon, modeverb, opchum.colorhtml(), opinit)
+ opinit = opgrammar.pcf + opchum.initials() + opgrammar.number
+ if modeon:
+ modeon = "now"
+ else:
+ modeon = "no longer"
+ return "Memo is %s %s by %s" % (
+ syscolor.name(),
+ modeon,
+ modeverb,
+ opchum.colorhtml(),
+ opinit,
+ )
+
def memoquirkkillmsg(self, opchum, opgrammar, syscolor):
- opinit = opgrammar.pcf+opchum.initials()+opgrammar.number
- return "%s turned off your quirk." % \
- (syscolor.name(), opchum.colorhtml(), opinit)
+ opinit = opgrammar.pcf + opchum.initials() + opgrammar.number
+ return "%s turned off your quirk." % (
+ syscolor.name(),
+ opchum.colorhtml(),
+ opinit,
+ )
@staticmethod
def checkLength(handle):
return len(handle) <= 256
+
@staticmethod
def checkValid(handle):
caps = [l for l in handle if l.isupper()]
@@ -432,11 +599,13 @@ class PesterProfile(object):
return (False, "Only alphanumeric characters allowed")
return (True,)
+
class PesterHistory(object):
def __init__(self):
self.history = []
self.current = 0
self.saved = None
+
def next(self, text):
if self.current == 0:
return None
@@ -445,20 +614,25 @@ class PesterHistory(object):
self.current -= 1
text = self.history[self.current]
return text
+
def prev(self):
self.current += 1
if self.current >= len(self.history):
self.current = len(self.history)
return self.retrieve()
return self.history[self.current]
+
def reset(self):
self.current = len(self.history)
self.saved = None
+
def save(self, text):
self.saved = text
+
def retrieve(self):
return self.saved
+
def add(self, text):
- if len(self.history) == 0 or text != self.history[len(self.history)-1]:
+ if len(self.history) == 0 or text != self.history[len(self.history) - 1]:
self.history.append(text)
self.reset()
diff --git a/generic.py b/generic.py
index f8d79f4..0f06980 100644
--- a/generic.py
+++ b/generic.py
@@ -5,30 +5,40 @@ except ImportError:
from PyQt5 import QtGui, QtWidgets
from datetime import timedelta
+
class mysteryTime(timedelta):
def __sub__(self, other):
return self
+
def __eq__(self, other):
- return (type(other) is mysteryTime)
+ return type(other) is mysteryTime
+
def __neq__(self, other):
- return (type(other) is not mysteryTime)
+ return type(other) is not mysteryTime
+
class CaseInsensitiveDict(dict):
def __setitem__(self, key, value):
super(CaseInsensitiveDict, self).__setitem__(key.lower(), value)
+
def __getitem__(self, key):
return super(CaseInsensitiveDict, self).__getitem__(key.lower())
+
def __contains__(self, key):
return super(CaseInsensitiveDict, self).__contains__(key.lower())
+
def has_key(self, key):
return key.lower() in super(CaseInsensitiveDict, self)
+
def __delitem__(self, key):
super(CaseInsensitiveDict, self).__delitem__(key.lower())
+
class PesterList(list):
def __init__(self, l):
self.extend(l)
+
class PesterIcon(QtGui.QIcon):
def __init__(self, *x):
super(PesterIcon, self).__init__(x[0])
@@ -36,6 +46,7 @@ class PesterIcon(QtGui.QIcon):
self.icon_pixmap = QtGui.QPixmap(x[0])
else:
self.icon_pixmap = None
+
def realsize(self):
if self.icon_pixmap:
return self.icon_pixmap.size()
@@ -45,18 +56,21 @@ class PesterIcon(QtGui.QIcon):
except IndexError:
return None
+
class RightClickList(QtWidgets.QListWidget):
def contextMenuEvent(self, event):
- #fuckin Qt <--- I feel that 3
+ # fuckin Qt <--- I feel that 3
if event.reason() == QtGui.QContextMenuEvent.Reason.Mouse:
listing = self.itemAt(event.pos())
self.setCurrentItem(listing)
optionsMenu = self.getOptionsMenu()
if optionsMenu:
optionsMenu.popup(event.globalPos())
+
def getOptionsMenu(self):
return self.optionsMenu
+
class RightClickTree(QtWidgets.QTreeWidget):
def contextMenuEvent(self, event):
if event.reason() == QtGui.QContextMenuEvent.Reason.Mouse:
@@ -65,9 +79,11 @@ class RightClickTree(QtWidgets.QTreeWidget):
optionsMenu = self.getOptionsMenu()
if optionsMenu:
optionsMenu.popup(event.globalPos())
+
def getOptionsMenu(self):
return self.optionsMenu
+
class MultiTextDialog(QtWidgets.QDialog):
def __init__(self, title, parent, *queries):
super(MultiTextDialog, self).__init__(parent)
@@ -98,6 +114,7 @@ class MultiTextDialog(QtWidgets.QDialog):
layout_0.addLayout(layout_ok)
self.setLayout(layout_0)
+
def getText(self):
r = self.exec()
if r == QtWidgets.QDialog.DialogCode.Accepted:
@@ -108,6 +125,7 @@ class MultiTextDialog(QtWidgets.QDialog):
else:
return None
+
class MovingWindow(QtWidgets.QFrame):
# Qt supports starting a system-specific move operation since 5.15, so we shouldn't need to manually set position like this anymore.
# https://doc.qt.io/qt-5/qwindow.html#startSystemMove
@@ -116,6 +134,7 @@ class MovingWindow(QtWidgets.QFrame):
super(MovingWindow, self).__init__(*x, **y)
self.moving = None
self.moveupdate = 0
+
def mouseMoveEvent(self, event):
if self.moving:
move = event.globalPos() - self.moving
@@ -124,6 +143,7 @@ class MovingWindow(QtWidgets.QFrame):
if self.moveupdate > 5:
self.moveupdate = 0
self.update()
+
def mousePressEvent(self, event):
# Assuming everything is supported, we only need this function to call "self.windowHandle().startSystemMove()".
# If not supported, startSystemMove() returns False and the legacy code runs anyway.
@@ -135,18 +155,27 @@ class MovingWindow(QtWidgets.QFrame):
print("PyQt <= 5.14?")
print(str(e))
if event.button() == 1:
- self.moving = event.globalPos() - self.pos()
+ self.moving = event.globalPos() - self.pos()
+
def mouseReleaseEvent(self, event):
if event.button() == 1:
self.update()
self.moving = None
+
class NoneSound(object):
def __init__(self, *args, **kwargs):
pass
- def play(self): pass
- def setVolume(self, v): pass
- def set_volume(self, v): pass
+
+ def play(self):
+ pass
+
+ def setVolume(self, v):
+ pass
+
+ def set_volume(self, v):
+ pass
+
class WMButton(QtWidgets.QPushButton):
def __init__(self, icon, parent=None):
diff --git a/irc.py b/irc.py
index 5553540..a321b0d 100644
--- a/irc.py
+++ b/irc.py
@@ -21,22 +21,23 @@ from oyoyo.client import IRCClient
from oyoyo.cmdhandler import DefaultCommandHandler
from oyoyo import helpers, services
-PchumLog = logging.getLogger('pchumLogger')
+PchumLog = logging.getLogger("pchumLogger")
# Python 3
QString = str
# Copied from pesterchum.py
-#CUSTOMBOTS = ["CALSPRITE", "RANDOMENCOUNTER"]
-#BOTNAMES = ["NICKSERV", "CHANSERV", "MEMOSERV", "OPERSERV", "HELPSERV", "HOSTSERV", "BOTSERV"]
-#BOTNAMES.extend(CUSTOMBOTS)
+# CUSTOMBOTS = ["CALSPRITE", "RANDOMENCOUNTER"]
+# BOTNAMES = ["NICKSERV", "CHANSERV", "MEMOSERV", "OPERSERV", "HELPSERV", "HOSTSERV", "BOTSERV"]
+# BOTNAMES.extend(CUSTOMBOTS)
-#if ostools.isOSXBundle():
+# if ostools.isOSXBundle():
# logging.basicConfig(level=logging.WARNING)
-#else:
+# else:
# # karxi; We do NOT need this set to INFO; it's very, very spammy.
# logging.basicConfig(level=logging.WARNING)
+
class PesterIRC(QtCore.QThread):
def __init__(self, config, window, verify_hostname=True):
QtCore.QThread.__init__(self)
@@ -49,15 +50,18 @@ class PesterIRC(QtCore.QThread):
self.stopIRC = None
self.NickServ = services.NickServ()
self.ChanServ = services.ChanServ()
+
def IRCConnect(self):
- self.cli = IRCClient(PesterHandler,
- host=self.config.server(),
- port=self.config.port(),
- ssl=self.config.ssl(),
- nick=self.mainwindow.profile().handle,
- username='pcc31',
- realname='pcc31',
- timeout=120)
+ self.cli = IRCClient(
+ PesterHandler,
+ host=self.config.server(),
+ port=self.config.port(),
+ ssl=self.config.ssl(),
+ nick=self.mainwindow.profile().handle,
+ username="pcc31",
+ realname="pcc31",
+ timeout=120,
+ )
self.cli.command_handler.parent = self
self.cli.command_handler.mainwindow = self.mainwindow
try:
@@ -67,6 +71,7 @@ class PesterIRC(QtCore.QThread):
self.askToConnect.emit(e)
raise e
self.conn = self.cli.conn()
+
def run(self):
try:
self.IRCConnect()
@@ -96,10 +101,12 @@ class PesterIRC(QtCore.QThread):
def setConnected(self):
self.registeredIRC = True
self.connected.emit()
+
def setConnectionBroken(self):
PchumLog.critical("setconnection broken")
self.disconnectIRC()
- #self.brokenConnection = True # Unused
+ # self.brokenConnection = True # Unused
+
@QtCore.pyqtSlot()
def updateIRC(self):
try:
@@ -111,9 +118,7 @@ class PesterIRC(QtCore.QThread):
raise se
except OSError as se:
raise se
- except (OSError,
- ValueError,
- IndexError) as se:
+ except (OSError, ValueError, IndexError) as se:
raise se
except StopIteration:
self.conn = self.cli.conn()
@@ -123,15 +128,17 @@ class PesterIRC(QtCore.QThread):
@QtCore.pyqtSlot(PesterProfile)
def getMood(self, *chums):
- if hasattr(self, 'cli'):
+ if hasattr(self, "cli"):
self.cli.command_handler.getMood(*chums)
+
@QtCore.pyqtSlot(PesterList)
def getMoods(self, chums):
- if hasattr(self, 'cli'):
+ if hasattr(self, "cli"):
self.cli.command_handler.getMood(*chums)
+
@QtCore.pyqtSlot(QString, QString)
def sendNotice(self, text, handle):
- if hasattr(self, 'cli'):
+ if hasattr(self, "cli"):
h = str(handle)
t = str(text)
try:
@@ -139,20 +146,22 @@ class PesterIRC(QtCore.QThread):
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
+
@QtCore.pyqtSlot(QString, QString)
def sendMessage(self, text, handle):
- if hasattr(self, 'cli'):
+ if hasattr(self, "cli"):
h = str(handle)
textl = [str(text)]
+
def splittext(l):
if len(l[0]) > 450:
- space = l[0].rfind(" ", 0,430)
+ space = l[0].rfind(" ", 0, 430)
if space == -1:
space = 450
- elif l[0][space+1:space+5] == "":
- space = space+4
- a = l[0][0:space+1]
- b = l[0][space+1:]
+ elif l[0][space + 1 : space + 5] == "":
+ space = space + 4
+ a = l[0][0 : space + 1]
+ b = l[0][space + 1 :]
if a.count(" a.count(""):
# oh god ctags will break!! D=
hanging = []
@@ -161,17 +170,18 @@ class PesterIRC(QtCore.QThread):
while c != -1:
d = a.find("", c)
while d in usedends:
- d = a.find("", d+1)
- if d != -1: usedends.append(d)
+ d = a.find("", d + 1)
+ if d != -1:
+ usedends.append(d)
else:
- f = a.find(">", c)+1
+ f = a.find(">", c) + 1
hanging.append(a[c:f])
- c = a.rfind("")):
+ for i in range(a.count("")):
a = a + ""
- #start them up again in the second part
+ # start them up again in the second part
for c in hanging:
b = c + b
if len(b) > 0:
@@ -180,6 +190,7 @@ class PesterIRC(QtCore.QThread):
return [a]
else:
return l
+
textl = splittext(textl)
try:
for t in textl:
@@ -187,37 +198,46 @@ class PesterIRC(QtCore.QThread):
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
- @QtCore.pyqtSlot(QString, QString,)
+
+ @QtCore.pyqtSlot(
+ QString,
+ QString,
+ )
def sendCTCP(self, handle, text):
- if hasattr(self, 'cli'):
+ if hasattr(self, "cli"):
try:
helpers.ctcp(self.cli, handle, text)
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
+
@QtCore.pyqtSlot(QString, bool)
def startConvo(self, handle, initiated):
- if hasattr(self, 'cli'):
+ if hasattr(self, "cli"):
h = str(handle)
try:
- helpers.msg(self.cli, h, "COLOR >%s" % (self.mainwindow.profile().colorcmd()))
+ helpers.msg(
+ self.cli, h, "COLOR >%s" % (self.mainwindow.profile().colorcmd())
+ )
if initiated:
helpers.msg(self.cli, h, "PESTERCHUM:BEGIN")
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
+
@QtCore.pyqtSlot(QString)
def endConvo(self, handle):
- if hasattr(self, 'cli'):
+ if hasattr(self, "cli"):
h = str(handle)
try:
helpers.msg(self.cli, h, "PESTERCHUM:CEASE")
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
+
@QtCore.pyqtSlot()
def updateProfile(self):
- if hasattr(self, 'cli'):
+ if hasattr(self, "cli"):
me = self.mainwindow.profile()
handle = me.handle
try:
@@ -230,13 +250,14 @@ class PesterIRC(QtCore.QThread):
self.mainwindow.autoJoinDone = False
self.mainwindow.doAutoJoins()
self.updateMood()
+
@QtCore.pyqtSlot()
def updateMood(self):
- if hasattr(self, 'cli'):
+ if hasattr(self, "cli"):
me = self.mainwindow.profile()
# Moods via metadata
try:
- helpers.metadata(self.cli, '*', "set", "mood", str(me.mood.value()))
+ helpers.metadata(self.cli, "*", "set", "mood", str(me.mood.value()))
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
@@ -246,63 +267,73 @@ class PesterIRC(QtCore.QThread):
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
+
@QtCore.pyqtSlot()
def updateColor(self):
- if hasattr(self, 'cli'):
- #PchumLog.debug("irc updateColor (outgoing)")
- #me = self.mainwindow.profile()
+ if hasattr(self, "cli"):
+ # PchumLog.debug("irc updateColor (outgoing)")
+ # me = self.mainwindow.profile()
# Update color metadata field
try:
color = self.mainwindow.profile().color
- helpers.metadata(self.cli, '*', "set", "color", str(color.name()))
+ helpers.metadata(self.cli, "*", "set", "color", str(color.name()))
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
# Send color messages
for h in list(self.mainwindow.convos.keys()):
try:
- helpers.msg(self.cli, h, "COLOR >%s" % (self.mainwindow.profile().colorcmd()))
+ helpers.msg(
+ self.cli,
+ h,
+ "COLOR >%s" % (self.mainwindow.profile().colorcmd()),
+ )
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
+
@QtCore.pyqtSlot(QString)
def blockedChum(self, handle):
- if hasattr(self, 'cli'):
+ if hasattr(self, "cli"):
h = str(handle)
try:
helpers.msg(self.cli, h, "PESTERCHUM:BLOCK")
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
+
@QtCore.pyqtSlot(QString)
def unblockedChum(self, handle):
- if hasattr(self, 'cli'):
+ if hasattr(self, "cli"):
h = str(handle)
try:
helpers.msg(self.cli, h, "PESTERCHUM:UNBLOCK")
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
+
@QtCore.pyqtSlot(QString)
def requestNames(self, channel):
- if hasattr(self, 'cli'):
+ if hasattr(self, "cli"):
c = str(channel)
try:
helpers.names(self.cli, c)
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
+
@QtCore.pyqtSlot()
def requestChannelList(self):
- if hasattr(self, 'cli'):
+ if hasattr(self, "cli"):
try:
helpers.channel_list(self.cli)
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
+
@QtCore.pyqtSlot(QString)
def joinChannel(self, channel):
- if hasattr(self, 'cli'):
+ if hasattr(self, "cli"):
c = str(channel)
try:
helpers.join(self.cli, c)
@@ -310,9 +341,10 @@ class PesterIRC(QtCore.QThread):
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
+
@QtCore.pyqtSlot(QString)
def leftChannel(self, channel):
- if hasattr(self, 'cli'):
+ if hasattr(self, "cli"):
c = str(channel)
try:
helpers.part(self.cli, c)
@@ -320,17 +352,18 @@ class PesterIRC(QtCore.QThread):
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
+
@QtCore.pyqtSlot(QString, QString)
def kickUser(self, handle, channel):
- if hasattr(self, 'cli'):
+ if hasattr(self, "cli"):
l = handle.split(":")
c = str(channel)
h = str(l[0])
if len(l) > 1:
reason = str(l[1])
if len(l) > 2:
- for x in l[2:]:
- reason += str(":") + str(x)
+ for x in l[2:]:
+ reason += str(":") + str(x)
else:
reason = ""
try:
@@ -338,13 +371,14 @@ class PesterIRC(QtCore.QThread):
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
+
@QtCore.pyqtSlot(QString, QString, QString)
def setChannelMode(self, channel, mode, command):
- if hasattr(self, 'cli'):
+ if hasattr(self, "cli"):
c = str(channel)
m = str(mode)
cmd = str(command)
- PchumLog.debug("c=%s\nm=%s\ncmd=%s" % (c,m,cmd))
+ PchumLog.debug("c=%s\nm=%s\ncmd=%s" % (c, m, cmd))
if cmd == "":
cmd = None
try:
@@ -352,18 +386,20 @@ class PesterIRC(QtCore.QThread):
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
+
@QtCore.pyqtSlot(QString)
def channelNames(self, channel):
- if hasattr(self, 'cli'):
+ if hasattr(self, "cli"):
c = str(channel)
try:
helpers.names(self.cli, c)
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
+
@QtCore.pyqtSlot(QString, QString)
def inviteChum(self, handle, channel):
- if hasattr(self, 'cli'):
+ if hasattr(self, "cli"):
h = str(handle)
c = str(channel)
try:
@@ -374,9 +410,9 @@ class PesterIRC(QtCore.QThread):
@QtCore.pyqtSlot()
def pingServer(self):
- if hasattr(self, 'cli'):
+ if hasattr(self, "cli"):
try:
- if hasattr(self, 'cli'):
+ if hasattr(self, "cli"):
self.cli.send("PING :B33")
except OSError as e:
PchumLog.warning(e)
@@ -384,7 +420,7 @@ class PesterIRC(QtCore.QThread):
@QtCore.pyqtSlot(bool)
def setAway(self, away=True):
- if hasattr(self, 'cli'):
+ if hasattr(self, "cli"):
try:
if away:
self.cli.send("AWAY Idle")
@@ -396,7 +432,7 @@ class PesterIRC(QtCore.QThread):
@QtCore.pyqtSlot(QString, QString)
def killSomeQuirks(self, channel, handle):
- if hasattr(self, 'cli'):
+ if hasattr(self, "cli"):
c = str(channel)
h = str(handle)
try:
@@ -407,42 +443,47 @@ class PesterIRC(QtCore.QThread):
@QtCore.pyqtSlot()
def disconnectIRC(self):
- if hasattr(self, 'cli'):
+ 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)
- messageReceived = QtCore.pyqtSignal('QString', 'QString')
- memoReceived = QtCore.pyqtSignal('QString', 'QString', 'QString')
- noticeReceived = QtCore.pyqtSignal('QString', 'QString')
- inviteReceived = QtCore.pyqtSignal('QString', 'QString')
- timeCommand = QtCore.pyqtSignal('QString', 'QString', 'QString')
- namesReceived = QtCore.pyqtSignal('QString', PesterList)
+ moodUpdated = QtCore.pyqtSignal("QString", Mood)
+ colorUpdated = QtCore.pyqtSignal("QString", QtGui.QColor)
+ messageReceived = QtCore.pyqtSignal("QString", "QString")
+ memoReceived = QtCore.pyqtSignal("QString", "QString", "QString")
+ noticeReceived = QtCore.pyqtSignal("QString", "QString")
+ inviteReceived = QtCore.pyqtSignal("QString", "QString")
+ timeCommand = QtCore.pyqtSignal("QString", "QString", "QString")
+ 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')
+ nickCollision = QtCore.pyqtSignal("QString", "QString")
+ getSvsnickedOn = QtCore.pyqtSignal("QString", "QString")
+ myHandleChanged = QtCore.pyqtSignal("QString")
+ chanInviteOnly = QtCore.pyqtSignal("QString")
+ modesUpdated = QtCore.pyqtSignal("QString", "QString")
connected = QtCore.pyqtSignal()
askToConnect = QtCore.pyqtSignal(Exception)
- userPresentUpdate = QtCore.pyqtSignal('QString', 'QString',
- 'QString')
- cannotSendToChan = QtCore.pyqtSignal('QString', 'QString')
+ userPresentUpdate = QtCore.pyqtSignal("QString", "QString", "QString")
+ cannotSendToChan = QtCore.pyqtSignal("QString", "QString")
tooManyPeeps = QtCore.pyqtSignal()
- quirkDisable = QtCore.pyqtSignal('QString', 'QString', 'QString')
- forbiddenchannel = QtCore.pyqtSignal('QString', 'QString')
+ quirkDisable = QtCore.pyqtSignal("QString", "QString", "QString")
+ forbiddenchannel = QtCore.pyqtSignal("QString", "QString")
+
class PesterHandler(DefaultCommandHandler):
def notice(self, nick, chan, msg):
- handle = nick[0:nick.find("!")]
- PchumLog.info("---> recv \"NOTICE %s :%s\"" % (handle, msg))
- if handle == "ChanServ" and chan == self.parent.mainwindow.profile().handle and msg[0:2] == "[#":
- self.parent.memoReceived.emit(msg[1:msg.index("]")], handle, msg)
+ handle = nick[0 : nick.find("!")]
+ PchumLog.info('---> recv "NOTICE %s :%s"' % (handle, msg))
+ if (
+ handle == "ChanServ"
+ and chan == self.parent.mainwindow.profile().handle
+ and msg[0:2] == "[#"
+ ):
+ 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
@@ -453,35 +494,37 @@ class PesterHandler(DefaultCommandHandler):
except ValueError:
PchumLog.warning("Invalid mood value, %s, %s" % (nick, mood))
elif key.lower() == "color":
- color = QtGui.QColor(value) # Invalid color becomes rgb 0,0,0
+ color = QtGui.QColor(value) # Invalid color becomes rgb 0,0,0
self.parent.colorUpdated.emit(nick, color)
def tagmsg(self, prefix, tags, *args):
- PchumLog.info('TAGMSG: %s %s %s' % (prefix, tags, str(args)))
- message_tags = tags[1:].split(';')
+ PchumLog.info("TAGMSG: %s %s %s" % (prefix, tags, str(args)))
+ message_tags = tags[1:].split(";")
for m in message_tags:
if m.startswith("+pesterchum"):
# Pesterchum tag
try:
- key, value = m.split('=')
+ key, value = m.split("=")
except ValueError:
return
- PchumLog.info('Pesterchum tag: %s=%s' % (key, value))
+ PchumLog.info("Pesterchum tag: %s=%s" % (key, value))
# PESTERCHUM: syntax check
- if ((value == "BEGIN")
+ if (
+ (value == "BEGIN")
or (value == "BLOCK")
or (value == "CEASE")
or (value == "BLOCK")
or (value == "BLOCKED")
or (value == "UNBLOCK")
or (value == "IDLE")
- or (value == "ME")):
+ or (value == "ME")
+ ):
# Process like it's a PESTERCHUM: PRIVMSG
msg = "PESTERCHUM:" + value
self.privmsg(prefix, args[0], msg)
elif value.startswith("COLOR>"):
# Process like it's a COLOR >0,0,0 PRIVMSG
- msg = value.replace('>', " >")
+ msg = value.replace(">", " >")
self.privmsg(prefix, args[0], msg)
elif value.startswith("TIME>"):
# Process like it's a PESTERCHUM:TIME> PRIVMSG
@@ -490,46 +533,60 @@ class PesterHandler(DefaultCommandHandler):
else:
# Invalid syntax
PchumLog.warning("TAGMSG with invalid syntax.")
+
def error(self, *params):
# Server is ending connection.
- reason = ''
+ reason = ""
for x in params:
- if (x != None) and (x != ''):
- reason += x + ' '
+ if (x != None) and (x != ""):
+ reason += x + " "
self.parent.stopIRC = reason.strip()
self.parent.disconnectIRC()
-
+
def privmsg(self, nick, chan, msg):
- handle = nick[0:nick.find("!")]
+ handle = nick[0 : nick.find("!")]
if len(msg) == 0:
return
# CTCP
# ACTION, IRC /me (The CTCP kind)
- if msg[0:8] == '\x01ACTION ':
- msg = '/me' + msg[7:-1]
+ if msg[0:8] == "\x01ACTION ":
+ msg = "/me" + msg[7:-1]
# CTCPs that don't need to be shown
- elif msg[0] == '\x01':
- PchumLog.info("---> recv \"CTCP %s :%s\"" % (handle, msg[1:-1]))
+ elif msg[0] == "\x01":
+ PchumLog.info('---> recv "CTCP %s :%s"' % (handle, msg[1:-1]))
# VERSION, return version
if msg[1:-1].startswith("VERSION"):
- helpers.ctcp_reply(self.parent.cli, handle, "VERSION", "Pesterchum %s" % (_pcVersion))
- # CLIENTINFO, return supported CTCP commands.
+ helpers.ctcp_reply(
+ self.parent.cli, handle, "VERSION", "Pesterchum %s" % (_pcVersion)
+ )
+ # CLIENTINFO, return supported CTCP commands.
elif msg[1:-1].startswith("CLIENTINFO"):
- helpers.ctcp_reply(self.parent.cli, handle, "CLIENTINFO",
- "ACTION VERSION CLIENTINFO PING SOURCE NOQUIRKS GETMOOD")
+ helpers.ctcp_reply(
+ self.parent.cli,
+ handle,
+ "CLIENTINFO",
+ "ACTION VERSION CLIENTINFO PING SOURCE NOQUIRKS GETMOOD",
+ )
# PING, return pong
elif msg[1:-1].startswith("PING"):
if len(msg[1:-1].split("PING ")) > 1:
- helpers.ctcp_reply(self.parent.cli, handle, "PING", msg[1:-1].split("PING ")[1])
+ helpers.ctcp_reply(
+ self.parent.cli, handle, "PING", msg[1:-1].split("PING ")[1]
+ )
else:
helpers.ctcp_reply(self.parent.cli, handle, "PING")
# SOURCE, return source
elif msg[1:-1].startswith("SOURCE"):
- helpers.ctcp_reply(self.parent.cli, handle, "SOURCE", "https://github.com/Dpeta/pesterchum-alt-servers")
+ helpers.ctcp_reply(
+ self.parent.cli,
+ handle,
+ "SOURCE",
+ "https://github.com/Dpeta/pesterchum-alt-servers",
+ )
# ???
elif msg[1:-1].startswith("NOQUIRKS") and chan[0] == "#":
- op = nick[0:nick.find("!")]
+ op = nick[0 : nick.find("!")]
self.parent.quirkDisable.emit(chan, msg[10:-1], op)
# GETMOOD via CTCP
elif msg[1:-1].startswith("GETMOOD"):
@@ -543,7 +600,7 @@ class PesterHandler(DefaultCommandHandler):
if chan != "#pesterchum":
# We don't need anywhere near that much spam.
- PchumLog.info("---> recv \"PRIVMSG %s :%s\"" % (handle, msg))
+ PchumLog.info('---> recv "PRIVMSG %s :%s"' % (handle, msg))
if chan == "#pesterchum":
# follow instructions
@@ -557,9 +614,8 @@ class PesterHandler(DefaultCommandHandler):
mychumhandle = self.mainwindow.profile().handle
mymood = self.mainwindow.profile().mood.value()
if msg.find(mychumhandle, 8) != -1:
- helpers.msg(self.client, "#pesterchum",
- "MOOD >%d" % (mymood))
- elif chan[0] == '#':
+ helpers.msg(self.client, "#pesterchum", "MOOD >%d" % (mymood))
+ elif chan[0] == "#":
if msg[0:16] == "PESTERCHUM:TIME>":
self.parent.timeCommand.emit(chan, handle, msg[16:])
else:
@@ -575,39 +631,42 @@ class PesterHandler(DefaultCommandHandler):
colors = [int(d) for d in colors]
except ValueError as e:
PchumLog.warning(e)
- colors = [0,0,0]
+ colors = [0, 0, 0]
PchumLog.debug("colors: " + str(colors))
color = QtGui.QColor(*colors)
self.parent.colorUpdated.emit(handle, color)
else:
self.parent.messageReceived.emit(handle, msg)
-
def pong(self, *args):
# source, server, token
- #print("PONG", source, server, token)
- #self.parent.mainwindow.lastrecv = time.time()
- #print("PONG TIME: %s" % self.parent.mainwindow.lastpong)
+ # print("PONG", source, server, token)
+ # self.parent.mainwindow.lastrecv = time.time()
+ # print("PONG TIME: %s" % self.parent.mainwindow.lastpong)
pass
-
+
def welcome(self, server, nick, msg):
self.parent.setConnected()
- #mychumhandle = self.mainwindow.profile().handle
+ # mychumhandle = self.mainwindow.profile().handle
mymood = self.mainwindow.profile().mood.value()
color = self.mainwindow.profile().color
if not self.mainwindow.config.lowBandwidth():
# Negotiate capabilities
helpers.cap(self.client, "REQ", "message-tags")
- helpers.cap(self.client, "REQ", "draft/metadata-notify-2") # <--- Not required in the unreal5 module implementation
- helpers.cap(self.client, "REQ", "pesterchum-tag") # <--- Currently not using this
- time.sleep(0.413 + 0.097) # <--- somehow, this actually helps.
+ helpers.cap(
+ self.client, "REQ", "draft/metadata-notify-2"
+ ) # <--- Not required in the unreal5 module implementation
+ helpers.cap(
+ self.client, "REQ", "pesterchum-tag"
+ ) # <--- Currently not using this
+ time.sleep(0.413 + 0.097) # <--- somehow, this actually helps.
helpers.join(self.client, "#pesterchum")
# Moods via metadata
- helpers.metadata(self.client, '*', 'sub', 'mood')
- helpers.metadata(self.client, '*', "set", "mood", str(mymood))
+ helpers.metadata(self.client, "*", "sub", "mood")
+ helpers.metadata(self.client, "*", "set", "mood", str(mymood))
# Color via metadata
- helpers.metadata(self.client, '*', 'sub', 'color')
- helpers.metadata(self.client, '*', "set", "color", str(color.name()))
+ helpers.metadata(self.client, "*", "sub", "color")
+ helpers.metadata(self.client, "*", "set", "color", str(color.name()))
# Backwards compatible moods
helpers.msg(self.client, "#pesterchum", "MOOD >%d" % (mymood))
@@ -615,8 +674,8 @@ class PesterHandler(DefaultCommandHandler):
# Server is not allowing us to connect.
reason = "Handle is not allowed on this server.\n"
for x in args:
- if (x != None) and (x != ''):
- reason += x + ' '
+ if (x != None) and (x != ""):
+ reason += x + " "
self.parent.stopIRC = reason.strip()
self.parent.disconnectIRC()
@@ -626,7 +685,7 @@ class PesterHandler(DefaultCommandHandler):
if key == "mood":
mood = Mood(int(value[0]))
self.parent.moodUpdated.emit(handle_owner, mood)
-
+
def metadatasubok(self, *params):
PchumLog.info("metadatasubok: " + str(params))
@@ -672,59 +731,62 @@ class PesterHandler(DefaultCommandHandler):
def cap(self, server, nick, subcommand, tag):
PchumLog.info("CAP %s %s %s %s" % (server, nick, subcommand, tag))
- #if tag == "message-tags":
+ # if tag == "message-tags":
# if subcommand == "ACK":
-
-
+
def nicknameinuse(self, server, cmd, nick, msg):
- newnick = "pesterClient%d" % (random.randint(100,999))
+ 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))
+ 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))
+ handle = nick[0 : nick.find("!")]
+ PchumLog.info('---> recv "QUIT %s: %s"' % (handle, reason))
if handle == self.parent.mainwindow.randhandler.randNick:
self.parent.mainwindow.randhandler.setRunning(False)
server = self.parent.mainwindow.config.server()
- baseserver = server[server.rfind(".", 0, server.rfind(".")):]
+ baseserver = server[server.rfind(".", 0, server.rfind(".")) :]
if reason.count(baseserver) == 2:
self.parent.userPresentUpdate.emit(handle, "", "netsplit")
else:
self.parent.userPresentUpdate.emit(handle, "", "quit")
self.parent.moodUpdated.emit(handle, Mood("offline"))
+
def kick(self, opnick, channel, handle, reason):
- op = opnick[0:opnick.find("!")]
+ op = opnick[0 : opnick.find("!")]
self.parent.userPresentUpdate.emit(handle, channel, "kick:%s:%s" % (op, reason))
# ok i shouldnt be overloading that but am lazy
+
def part(self, nick, channel, reason="nanchos"):
- handle = nick[0:nick.find("!")]
- PchumLog.info("---> recv \"PART %s: %s\"" % (handle, channel))
+ handle = nick[0 : nick.find("!")]
+ PchumLog.info('---> recv "PART %s: %s"' % (handle, channel))
self.parent.userPresentUpdate.emit(handle, channel, "left")
if channel == "#pesterchum":
self.parent.moodUpdated.emit(handle, Mood("offline"))
+
def join(self, nick, channel):
- handle = nick[0:nick.find("!")]
- PchumLog.info("---> recv \"JOIN %s: %s\"" % (handle, channel))
+ handle = nick[0 : nick.find("!")]
+ PchumLog.info('---> recv "JOIN %s: %s"' % (handle, channel))
self.parent.userPresentUpdate.emit(handle, channel, "join")
if channel == "#pesterchum":
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))
PchumLog.debug("mode=" + str(mode))
PchumLog.debug("*handles=" + str(handles))
- if len(handles) <= 0: handles = [""]
- opnick = op[0:op.find("!")]
+ if len(handles) <= 0:
+ handles = [""]
+ opnick = op[0 : op.find("!")]
PchumLog.debug("opnick=" + opnick)
# Channel section
@@ -732,7 +794,7 @@ class PesterHandler(DefaultCommandHandler):
# 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:
+ # 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] == "+":
@@ -748,59 +810,96 @@ class PesterHandler(DefaultCommandHandler):
# modes.sort()
# self.parent.mainwindow.modes = "+" + "".join(modes)
-
# EXPIRIMENTAL FIX
# No clue how stable this is but since it doesn'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']
+ 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)
for md in unrealircd_channel_modes:
- if mode.find(md)!= -1: # -1 means not found
+ if mode.find(md) != -1: # -1 means not found
PchumLog.debug("md=" + md)
if mode[0] == "+":
modes.extend(md)
- channel_mode = "+" + 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.")
+ PchumLog.warning(
+ "Can't remove channel mode that isn't set."
+ )
pass
- self.parent.userPresentUpdate.emit("", channel, channel_mode+":%s" % (op))
+ 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
+ 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):
+ for (i, m) in enumerate(modes):
# Server-set usermodes don't need to be passed.
- if (handles == ['']) & ( ('x' in m) | ('z' in m) | ('o' in m) | ('x' in m) )!=True:
+ if (handles == [""]) & (
+ ("x" in m) | ("z" in m) | ("o" in m) | ("x" in m)
+ ) != True:
try:
- self.parent.userPresentUpdate.emit(handles[i], channel, m+":%s" % (op))
+ self.parent.userPresentUpdate.emit(
+ handles[i], channel, m + ":%s" % (op)
+ )
except IndexError as e:
PchumLog.exception("modeSetIndexError: %s" % e)
- #print("i = " + i)
- #print("m = " + m)
- #self.parent.userPresentUpdate.emit(handles[i], channel, m+":%s" % (op))
- #self.parent.userPresentUpdate.emit(handles[i], channel, m+":%s" % (op))
+ # print("i = " + i)
+ # print("m = " + m)
+ # self.parent.userPresentUpdate.emit(handles[i], channel, m+":%s" % (op))
+ # 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))
-
+ # except IndexError:
+ # self.parent.userPresentUpdate.emit("", channel, m+":%s" % (op))
+
def nick(self, oldnick, newnick, hopcount=0):
PchumLog.info("%s, %s" % (oldnick, newnick))
# svsnick
@@ -809,10 +908,11 @@ class PesterHandler(DefaultCommandHandler):
self.parent.getSvsnickedOn.emit(oldnick, newnick)
# etc.
- oldhandle = oldnick[0:oldnick.find("!")]
- if ((oldhandle == self.mainwindow.profile().handle)
- or (newnick == self.mainwindow.profile().handle)):
- #print('hewwo')
+ oldhandle = oldnick[0 : oldnick.find("!")]
+ if (oldhandle == self.mainwindow.profile().handle) or (
+ newnick == self.mainwindow.profile().handle
+ ):
+ # print('hewwo')
self.parent.myHandleChanged.emit(newnick)
newchum = PesterProfile(newnick, chumdb=self.mainwindow.chumdb)
self.parent.moodUpdated.emit(oldhandle, Mood("offline"))
@@ -820,18 +920,20 @@ class PesterHandler(DefaultCommandHandler):
if newnick in self.mainwindow.chumList.chums:
self.getMood(newchum)
if oldhandle == self.parent.mainwindow.randhandler.randNick:
- self.parent.mainwindow.randhandler.setRunning(False)
+ self.parent.mainwindow.randhandler.setRunning(False)
elif newnick == self.parent.mainwindow.randhandler.randNick:
- self.parent.mainwindow.randhandler.setRunning(True)
+ self.parent.mainwindow.randhandler.setRunning(True)
+
def namreply(self, server, nick, op, channel, names):
namelist = names.split(" ")
- PchumLog.info("---> recv \"NAMES %s: %d names\"" % (channel, len(namelist)))
- if not hasattr(self, 'channelnames'):
+ PchumLog.info('---> recv "NAMES %s: %d names"' % (channel, len(namelist)))
+ if not hasattr(self, "channelnames"):
self.channelnames = {}
if channel not in self.channelnames:
self.channelnames[channel] = []
self.channelnames[channel].extend(namelist)
- #def ison(self, server, nick, nicks):
+
+ # def ison(self, server, nick, nicks):
# nicklist = nicks.split(" ")
# getglub = "GETMOOD "
# PchumLog.info("---> recv \"ISON :%s\"" % nicks)
@@ -841,7 +943,7 @@ class PesterHandler(DefaultCommandHandler):
# getglub += nick_it
# if getglub != "GETMOOD ":
# helpers.msg(self.client, "#pesterchum", getglub)
-
+
def endofnames(self, server, nick, channel, msg):
try:
namelist = self.channelnames[channel]
@@ -854,50 +956,62 @@ class PesterHandler(DefaultCommandHandler):
pl = PesterList(namelist)
del self.channelnames[channel]
self.parent.namesReceived.emit(channel, pl)
- if channel == "#pesterchum" and (not hasattr(self, "joined") or not self.joined):
+ if channel == "#pesterchum" and (
+ not hasattr(self, "joined") or not self.joined
+ ):
self.joined = True
- self.parent.mainwindow.randhandler.setRunning(self.parent.mainwindow.randhandler.randNick in namelist)
+ self.parent.mainwindow.randhandler.setRunning(
+ self.parent.mainwindow.randhandler.randNick in namelist
+ )
chums = self.mainwindow.chumList.chums
- #self.isOn(*chums)
+ # self.isOn(*chums)
lesschums = []
for c in chums:
chandle = c.handle
if chandle in namelist:
lesschums.append(c)
self.getMood(*lesschums)
-
+
def liststart(self, server, handle, *info):
self.channel_list = []
info = list(info)
- self.channel_field = info.index("Channel") # dunno if this is protocol
- PchumLog.info("---> recv \"CHANNELS: %s " % (self.channel_field))
+ self.channel_field = info.index("Channel") # dunno if this is protocol
+ PchumLog.info('---> recv "CHANNELS: %s ' % (self.channel_field))
+
def list(self, server, handle, *info):
channel = info[self.channel_field]
usercount = info[1]
if channel not in self.channel_list and channel != "#pesterchum":
self.channel_list.append((channel, usercount))
- PchumLog.info("---> recv \"CHANNELS: %s " % (channel))
+ PchumLog.info('---> recv "CHANNELS: %s ' % (channel))
+
def listend(self, server, handle, msg):
pl = PesterList(self.channel_list)
- PchumLog.info("---> recv \"CHANNELS END\"")
+ PchumLog.info('---> recv "CHANNELS END"')
self.parent.channelListReceived.emit(pl)
self.channel_list = []
def umodeis(self, server, handle, modes):
self.parent.mainwindow.modes = modes
+
def invite(self, sender, you, channel):
- handle = sender.split('!')[0]
+ handle = sender.split("!")[0]
self.parent.inviteReceived.emit(handle, channel)
+
def inviteonlychan(self, server, handle, channel, msg):
self.parent.chanInviteOnly.emit(channel)
+
# channelmodeis can have six arguments.
def channelmodeis(self, server, handle, channel, modes, mode_params=""):
self.parent.modesUpdated.emit(channel, modes)
+
def cannotsendtochan(self, server, handle, channel, msg):
self.parent.cannotSendToChan.emit(channel, msg)
+
def toomanypeeps(self, *stuff):
self.parent.tooManyPeeps.emit()
- #def badchanmask(channel, *args):
+
+ # def badchanmask(channel, *args):
# # Channel name is not valid.
# msg = ' '.join(args)
# self.parent.forbiddenchannel.emit(channel, msg)
@@ -905,10 +1019,10 @@ class PesterHandler(DefaultCommandHandler):
# Channel is forbidden.
self.parent.forbiddenchannel.emit(channel, msg)
self.parent.userPresentUpdate.emit(handle, channel, "left")
-
+
def ping(self, prefix, server):
- #self.parent.mainwindow.lastping = time.time()
- self.client.send('PONG', server)
+ # self.parent.mainwindow.lastping = time.time()
+ self.client.send("PONG", server)
def getMood(self, *chums):
"""Get mood via metadata if supported"""
@@ -925,11 +1039,13 @@ class PesterHandler(DefaultCommandHandler):
self.parent.setConnectionBroken()
else:
# Legacy
- PchumLog.warning("Server doesn't seem to support metadata, using legacy GETMOOD.")
+ PchumLog.warning(
+ "Server doesn't seem to support metadata, using legacy GETMOOD."
+ )
chumglub = "GETMOOD "
for c in chums:
chandle = c.handle
- if len(chumglub+chandle) >= 350:
+ if len(chumglub + chandle) >= 350:
try:
helpers.msg(self.client, "#pesterchum", chumglub)
except OSError as e:
@@ -943,9 +1059,8 @@ class PesterHandler(DefaultCommandHandler):
except OSError as e:
PchumLog.warning(e)
self.parent.setConnectionBroken()
-
- #def isOn(self, *chums):
+ # def isOn(self, *chums):
# isonNicks = ""
# for c in chums:
# chandle = c.handle
diff --git a/logviewer.py b/logviewer.py
index e26c586..b079fde 100644
--- a/logviewer.py
+++ b/logviewer.py
@@ -4,6 +4,7 @@ import codecs
import re
import ostools
from time import strftime, strptime
+
try:
from PyQt6 import QtCore, QtGui, QtWidgets
except ImportError:
@@ -15,13 +16,15 @@ from convo import PesterText
_datadir = ostools.getDataDir()
+
class PesterLogSearchInput(QtWidgets.QLineEdit):
def __init__(self, theme, parent=None):
QtWidgets.QLineEdit.__init__(self, parent)
self.setStyleSheet(theme["convo/input/style"] + "; margin-right:0px;")
+
def keyPressEvent(self, event):
QtWidgets.QLineEdit.keyPressEvent(self, event)
- if hasattr(self.parent(), 'textArea'):
+ if hasattr(self.parent(), "textArea"):
if event.key() == QtCore.Qt.Key.Key_Return:
self.parent().logSearch(self.text())
if self.parent().textArea.find(self.text()):
@@ -29,6 +32,7 @@ class PesterLogSearchInput(QtWidgets.QLineEdit):
else:
self.parent().logSearch(self.text())
+
class PesterLogHighlighter(QtGui.QSyntaxHighlighter):
def __init__(self, parent):
QtGui.QSyntaxHighlighter.__init__(self, parent)
@@ -36,11 +40,16 @@ class PesterLogHighlighter(QtGui.QSyntaxHighlighter):
self.hilightstyle = QtGui.QTextCharFormat()
self.hilightstyle.setBackground(QtGui.QBrush(QtCore.Qt.GlobalColor.green))
self.hilightstyle.setForeground(QtGui.QBrush(QtCore.Qt.GlobalColor.black))
+
def highlightBlock(self, text):
- for i in range(0, len(text)-(len(self.searchTerm)-1)):
- if str(text[i:i+len(self.searchTerm)]).lower() == str(self.searchTerm).lower():
+ for i in range(0, len(text) - (len(self.searchTerm) - 1)):
+ if (
+ str(text[i : i + len(self.searchTerm)]).lower()
+ == str(self.searchTerm).lower()
+ ):
self.setFormat(i, len(self.searchTerm), self.hilightstyle)
+
class PesterLogUserSelect(QtWidgets.QDialog):
def __init__(self, config, theme, parent):
QtWidgets.QDialog.__init__(self, parent)
@@ -49,7 +58,7 @@ class PesterLogUserSelect(QtWidgets.QDialog):
self.theme = theme
self.parent = parent
self.handle = parent.profile().handle
- self.logpath = _datadir+"logs"
+ self.logpath = _datadir + "logs"
self.setStyleSheet(self.theme["main/defaultwindow/style"])
self.setWindowTitle("Pesterlogs")
@@ -72,7 +81,9 @@ class PesterLogUserSelect(QtWidgets.QDialog):
for (i, t) in enumerate(chumMemoList):
item = QtWidgets.QListWidgetItem(t)
- item.setForeground(QtGui.QBrush(QtGui.QColor(self.theme["main/chums/userlistcolor"])))
+ item.setForeground(
+ QtGui.QBrush(QtGui.QColor(self.theme["main/chums/userlistcolor"]))
+ )
self.chumsBox.addItem(item)
self.search = PesterLogSearchInput(theme, self)
@@ -109,10 +120,12 @@ class PesterLogUserSelect(QtWidgets.QDialog):
@QtCore.pyqtSlot()
def viewActivatedLog(self):
selectedchum = self.selectedchum().text()
- if not hasattr(self, 'pesterlogviewer'):
+ if not hasattr(self, "pesterlogviewer"):
self.pesterlogviewer = None
if not self.pesterlogviewer:
- self.pesterlogviewer = PesterLogViewer(selectedchum, self.config, self.theme, self.parent)
+ self.pesterlogviewer = PesterLogViewer(
+ selectedchum, self.config, self.theme, self.parent
+ )
self.pesterlogviewer.rejected.connect(self.closeActiveLog)
self.pesterlogviewer.show()
self.pesterlogviewer.raise_()
@@ -126,7 +139,13 @@ class PesterLogUserSelect(QtWidgets.QDialog):
@QtCore.pyqtSlot()
def openDir(self):
- QtGui.QDesktopServices.openUrl(QtCore.QUrl("file:///" + os.path.join(_datadir, "logs"), QtCore.QUrl.ParsingMode.TolerantMode))
+ QtGui.QDesktopServices.openUrl(
+ QtCore.QUrl(
+ "file:///" + os.path.join(_datadir, "logs"),
+ QtCore.QUrl.ParsingMode.TolerantMode,
+ )
+ )
+
class PesterLogViewer(QtWidgets.QDialog):
def __init__(self, chum, config, theme, parent):
@@ -140,18 +159,27 @@ class PesterLogViewer(QtWidgets.QDialog):
self.handle = parent.profile().handle
self.chum = chum
self.convos = {}
- self.logpath = _datadir+"logs"
+ self.logpath = _datadir + "logs"
self.setStyleSheet(self.theme["main/defaultwindow/style"])
self.setWindowTitle("Pesterlogs with " + self.chum)
self.format = "bbcode"
- if os.path.exists("%s/%s/%s/%s" % (self.logpath, self.handle, chum, self.format)):
- self.logList = os.listdir("%s/%s/%s/%s/" % (self.logpath, self.handle, self.chum, self.format))
+ if os.path.exists(
+ "%s/%s/%s/%s" % (self.logpath, self.handle, chum, self.format)
+ ):
+ self.logList = os.listdir(
+ "%s/%s/%s/%s/" % (self.logpath, self.handle, self.chum, self.format)
+ )
else:
self.logList = []
- if not os.path.exists("%s/%s/%s/%s" % (self.logpath, self.handle, chum, self.format)) or len(self.logList) == 0:
+ if (
+ not os.path.exists(
+ "%s/%s/%s/%s" % (self.logpath, self.handle, chum, self.format)
+ )
+ or len(self.logList) == 0
+ ):
instructions = QtWidgets.QLabel("No Pesterlogs were found")
self.ok = QtWidgets.QPushButton("CLOSE", self)
@@ -166,15 +194,28 @@ class PesterLogViewer(QtWidgets.QDialog):
self.setLayout(layout_0)
else:
- self.instructions = QtWidgets.QLabel("Pesterlog with " +self.chum+ " on")
+ self.instructions = QtWidgets.QLabel("Pesterlog with " + self.chum + " on")
self.textArea = PesterLogText(theme, self.parent)
self.textArea.setReadOnly(True)
self.textArea.setFixedWidth(600)
if "convo/scrollbar" in theme:
- self.textArea.setStyleSheet("QTextEdit { width:500px; %s } QScrollBar:vertical { %s } QScrollBar::handle:vertical { %s } QScrollBar::add-line:vertical { %s } QScrollBar::sub-line:vertical { %s } QScrollBar:up-arrow:vertical { %s } QScrollBar:down-arrow:vertical { %s }" % (theme["convo/textarea/style"], theme["convo/scrollbar/style"], theme["convo/scrollbar/handle"], theme["convo/scrollbar/downarrow"], theme["convo/scrollbar/uparrow"], theme["convo/scrollbar/uarrowstyle"], theme["convo/scrollbar/darrowstyle"] ))
+ self.textArea.setStyleSheet(
+ "QTextEdit { width:500px; %s } QScrollBar:vertical { %s } QScrollBar::handle:vertical { %s } QScrollBar::add-line:vertical { %s } QScrollBar::sub-line:vertical { %s } QScrollBar:up-arrow:vertical { %s } QScrollBar:down-arrow:vertical { %s }"
+ % (
+ theme["convo/textarea/style"],
+ theme["convo/scrollbar/style"],
+ theme["convo/scrollbar/handle"],
+ theme["convo/scrollbar/downarrow"],
+ theme["convo/scrollbar/uparrow"],
+ theme["convo/scrollbar/uarrowstyle"],
+ theme["convo/scrollbar/darrowstyle"],
+ )
+ )
else:
- self.textArea.setStyleSheet("QTextEdit { width:500px; %s }" % (theme["convo/textarea/style"]))
+ self.textArea.setStyleSheet(
+ "QTextEdit { width:500px; %s }" % (theme["convo/textarea/style"])
+ )
self.logList.sort()
self.logList.reverse()
@@ -184,20 +225,31 @@ class PesterLogViewer(QtWidgets.QDialog):
self.tree.setFixedSize(260, 300)
self.tree.header().hide()
if "convo/scrollbar" in theme:
- self.tree.setStyleSheet("QTreeWidget { %s } QScrollBar:vertical { %s } QScrollBar::handle:vertical { %s } QScrollBar::add-line:vertical { %s } QScrollBar::sub-line:vertical { %s } QScrollBar:up-arrow:vertical { %s } QScrollBar:down-arrow:vertical { %s }" % (theme["convo/textarea/style"], theme["convo/scrollbar/style"], theme["convo/scrollbar/handle"], theme["convo/scrollbar/downarrow"], theme["convo/scrollbar/uparrow"], theme["convo/scrollbar/uarrowstyle"], theme["convo/scrollbar/darrowstyle"] ))
+ self.tree.setStyleSheet(
+ "QTreeWidget { %s } QScrollBar:vertical { %s } QScrollBar::handle:vertical { %s } QScrollBar::add-line:vertical { %s } QScrollBar::sub-line:vertical { %s } QScrollBar:up-arrow:vertical { %s } QScrollBar:down-arrow:vertical { %s }"
+ % (
+ theme["convo/textarea/style"],
+ theme["convo/scrollbar/style"],
+ theme["convo/scrollbar/handle"],
+ theme["convo/scrollbar/downarrow"],
+ theme["convo/scrollbar/uparrow"],
+ theme["convo/scrollbar/uarrowstyle"],
+ theme["convo/scrollbar/darrowstyle"],
+ )
+ )
else:
self.tree.setStyleSheet("%s" % (theme["convo/textarea/style"]))
self.tree.itemSelectionChanged.connect(self.loadSelectedLog)
self.tree.setSortingEnabled(False)
child_1 = None
- last = ["",""]
- #blackbrush = QtGui.QBrush(QtCore.Qt.GlobalColor.black)
- for (i,l) in enumerate(self.logList):
+ last = ["", ""]
+ # blackbrush = QtGui.QBrush(QtCore.Qt.GlobalColor.black)
+ for (i, l) in enumerate(self.logList):
my = self.fileToMonthYear(l)
if my[0] != last[0]:
child_1 = QtWidgets.QTreeWidgetItem(["%s %s" % (my[0], my[1])])
- #child_1.setForeground(0, blackbrush)
+ # child_1.setForeground(0, blackbrush)
self.tree.addTopLevelItem(child_1)
if i == 0:
child_1.setExpanded(True)
@@ -205,7 +257,8 @@ class PesterLogViewer(QtWidgets.QDialog):
last = self.fileToMonthYear(l)
self.hilight = PesterLogHighlighter(self.textArea)
- if len(self.logList) > 0: self.loadLog(self.logList[0])
+ if len(self.logList) > 0:
+ self.loadLog(self.logList[0])
self.search = PesterLogSearchInput(theme, self)
self.search.setFocus()
@@ -246,29 +299,48 @@ class PesterLogViewer(QtWidgets.QDialog):
self.loadLog(self.timeToFile(self.tree.currentItem().text(0)))
def loadLog(self, fname):
- fp = codecs.open("%s/%s/%s/%s/%s" % (self.logpath, self.handle, self.chum, self.format, fname), encoding='utf-8', mode='r')
+ fp = codecs.open(
+ "%s/%s/%s/%s/%s"
+ % (self.logpath, self.handle, self.chum, self.format, fname),
+ encoding="utf-8",
+ mode="r",
+ )
self.textArea.clear()
for line in fp:
- cline = line.replace("\r\n", "").replace("[/color]","").replace("[url]","").replace("[/url]","")
+ cline = (
+ line.replace("\r\n", "")
+ .replace("[/color]", "")
+ .replace("[url]", "")
+ .replace("[/url]", "")
+ )
cline = re.sub("\[color=(#.{6})]", r"", cline)
self.textArea.append(convertTags(cline))
textCur = self.textArea.textCursor()
- #textCur.movePosition(1)
+ # textCur.movePosition(1)
self.textArea.setTextCursor(textCur)
- self.instructions.setText("Pesterlog with " +self.chum+ " on " + self.fileToTime(str(fname)))
+ self.instructions.setText(
+ "Pesterlog with " + self.chum + " on " + self.fileToTime(str(fname))
+ )
def logSearch(self, search):
self.hilight.searchTerm = search
self.hilight.rehighlight()
def fileToMonthYear(self, fname):
- time = strptime(fname[(fname.index(".")+1):fname.index(".txt")], "%Y-%m-%d.%H.%M")
+ time = strptime(
+ fname[(fname.index(".") + 1) : fname.index(".txt")], "%Y-%m-%d.%H.%M"
+ )
return [strftime("%B", time), strftime("%Y", time)]
+
def fileToTime(self, fname):
- timestr = fname[(fname.index(".")+1):fname.index(".txt")]
+ timestr = fname[(fname.index(".") + 1) : fname.index(".txt")]
return strftime("%a %d %b %Y %H %M", strptime(timestr, "%Y-%m-%d.%H.%M"))
+
def timeToFile(self, time):
- return self.chum + strftime(".%Y-%m-%d.%H.%M.txt", strptime(str(time), "%a %d %b %Y %H %M"))
+ return self.chum + strftime(
+ ".%Y-%m-%d.%H.%M.txt", strptime(str(time), "%a %d %b %Y %H %M")
+ )
+
class PesterLogText(PesterText):
def __init__(self, theme, parent=None):
@@ -276,6 +348,7 @@ class PesterLogText(PesterText):
def focusInEvent(self, event):
QtWidgets.QTextEdit.focusInEvent(self, event)
+
def mousePressEvent(self, event):
try:
# PyQt6
@@ -290,8 +363,11 @@ class PesterLogText(PesterText):
handle = str(url[1:])
self.parent().parent.newConversation(handle)
else:
- QtGui.QDesktopServices.openUrl(QtCore.QUrl(url, QtCore.QUrl.ParsingMode.TolerantMode))
+ QtGui.QDesktopServices.openUrl(
+ QtCore.QUrl(url, QtCore.QUrl.ParsingMode.TolerantMode)
+ )
QtWidgets.QTextEdit.mousePressEvent(self, event)
+
def mouseMoveEvent(self, event):
QtWidgets.QTextEdit.mouseMoveEvent(self, event)
try:
@@ -301,8 +377,13 @@ class PesterLogText(PesterText):
# PyQt5
pos = event.pos()
if self.anchorAt(pos):
- if self.viewport().cursor().shape != QtCore.Qt.CursorShape.PointingHandCursor:
- self.viewport().setCursor(QtGui.QCursor(QtCore.Qt.CursorShape.PointingHandCursor))
+ if (
+ self.viewport().cursor().shape
+ != QtCore.Qt.CursorShape.PointingHandCursor
+ ):
+ self.viewport().setCursor(
+ QtGui.QCursor(QtCore.Qt.CursorShape.PointingHandCursor)
+ )
else:
self.viewport().setCursor(QtGui.QCursor(QtCore.Qt.CursorShape.IBeamCursor))
diff --git a/memos.py b/memos.py
index 2884ae3..30e8be5 100644
--- a/memos.py
+++ b/memos.py
@@ -16,15 +16,22 @@ import parsetools
from dataobjs import PesterProfile, PesterHistory
from generic import PesterIcon, RightClickList, mysteryTime
from convo import PesterConvo, PesterInput, PesterText, PesterTabWindow
-from parsetools import (convertTags, timeProtocol, lexMessage, colorBegin,
- mecmd, smiledict)
+from parsetools import (
+ convertTags,
+ timeProtocol,
+ lexMessage,
+ colorBegin,
+ mecmd,
+ smiledict,
+)
from logviewer import PesterLogViewer
-PchumLog = logging.getLogger('pchumLogger')
+PchumLog = logging.getLogger("pchumLogger")
# Python 3
QString = str
+
def delta2txt(d, format="pc"):
if type(d) is mysteryTime:
return "?"
@@ -35,7 +42,7 @@ def delta2txt(d, format="pc"):
return "i"
sign = "F" if d >= timedelta(0) else "P"
d = abs(d)
- totalminutes = (d.days*86400 + d.seconds) // 60
+ totalminutes = (d.days * 86400 + d.seconds) // 60
hours = totalminutes // 60
leftovermins = totalminutes % 60
if hours < 100:
@@ -49,13 +56,14 @@ def delta2txt(d, format="pc"):
else:
return "%s%02d:%02d" % (sign, hours, leftovermins)
+
def txt2delta(txt):
sign = 1
- if txt[0] == '?':
+ if txt[0] == "?":
return mysteryTime()
- if txt[0] == '+':
+ if txt[0] == "+":
txt = txt[1:]
- elif txt[0] == '-':
+ elif txt[0] == "-":
sign = -1
txt = txt[1:]
l = txt.split(":")
@@ -64,7 +72,7 @@ def txt2delta(txt):
m = 0
if len(l) > 1:
m = int(l[1])
- timed = timedelta(0, h*3600+m*60)
+ timed = timedelta(0, h * 3600 + m * 60)
except ValueError:
timed = timedelta(0)
except OverflowError:
@@ -72,10 +80,11 @@ def txt2delta(txt):
return timedelta.min
else:
return timedelta.max
- return sign*timed
+ return sign * timed
+
def pcfGrammar(td):
- if td == timedelta(microseconds=1): # Replacement for mysteryTime 3
+ if td == timedelta(microseconds=1): # Replacement for mysteryTime 3
when = "???"
temporal = "???"
pcf = "?"
@@ -93,6 +102,7 @@ def pcfGrammar(td):
pcf = "C"
return (temporal, pcf, when)
+
class TimeGrammar(object):
def __init__(self, temporal, pcf, when, number="0"):
self.temporal = temporal
@@ -103,24 +113,26 @@ class TimeGrammar(object):
else:
self.number = str(number)
+
class TimeTracker(list):
def __init__(self, time=None):
# mysteryTime breaks stuff now, so, uh
# I'm replacing it with 1 day...
- if type(time)==mysteryTime:
+ if type(time) == mysteryTime:
time = timedelta(microseconds=1)
self.timerecord = {"P": [], "F": []}
self.open = {}
if time is not None:
self.append(time)
- self.current=0
+ self.current = 0
self.addRecord(time)
self.open[time] = False
else:
- self.current=-1
+ self.current = -1
+
def addTime(self, timed):
# mysteryTime 3
- if type(timed)==mysteryTime:
+ if type(timed) == mysteryTime:
timed = timedelta(microseconds=1)
try:
i = self.index(timed)
@@ -132,16 +144,20 @@ class TimeTracker(list):
self.open[timed] = False
self.addRecord(timed)
return False
+
def prevTime(self):
i = self.current
i = (i - 1) % len(self)
return self[i]
+
def nextTime(self):
i = self.current
i = (i + 1) % len(self)
return self[i]
+
def setCurrent(self, timed):
self.current = self.index(timed)
+
def addRecord(self, timed):
try:
(temporal, pcf, when) = pcfGrammar(timed - timedelta(0))
@@ -152,6 +168,7 @@ class TimeTracker(list):
if timed in self.timerecord[pcf]:
return
self.timerecord[pcf].append(timed)
+
def getRecord(self, timed):
try:
(temporal, pcf, when) = pcfGrammar(timed - timedelta(0))
@@ -160,34 +177,41 @@ class TimeTracker(list):
if pcf == "C" or pcf == "?":
return 0
if len(self.timerecord[pcf]) > 1:
- return self.timerecord[pcf].index(timed)+1
+ return self.timerecord[pcf].index(timed) + 1
else:
return 0
+
def removeTime(self, timed):
try:
self.pop(self.index(timed))
- self.current = len(self)-1
+ self.current = len(self) - 1
del self.open[timed]
return True
except ValueError:
return None
+
def openTime(self, time):
if time in self.open:
self.open[time] = True
+
def openCurrentTime(self):
timed = self.getTime()
self.openTime(timed)
+
def isFirstTime(self):
timed = self.getTime()
return not self.open[timed]
+
def getTime(self):
if self.current >= 0:
return self[self.current]
else:
return None
+
def getGrammar(self):
timed = self.getTime()
return self.getGrammarTime(timed)
+
def getGrammarTime(self, timed):
mytime = timedelta(0)
try:
@@ -198,6 +222,7 @@ class TimeTracker(list):
return TimeGrammar(temporal, pcf, when, 0)
return TimeGrammar(temporal, pcf, when, self.getRecord(timed))
+
class TimeInput(QtWidgets.QLineEdit):
def __init__(self, timeslider, parent):
super(TimeInput, self).__init__(parent)
@@ -205,9 +230,11 @@ class TimeInput(QtWidgets.QLineEdit):
self.setText("+0:00")
self.timeslider.valueChanged[int].connect(self.setTime)
self.editingFinished.connect(self.setSlider)
+
@QtCore.pyqtSlot(int)
def setTime(self, sliderval):
self.setText(self.timeslider.getTime())
+
@QtCore.pyqtSlot()
def setSlider(self):
value = str(self.text())
@@ -221,12 +248,13 @@ class TimeInput(QtWidgets.QLineEdit):
index = 50
for i, td in enumerate(timedlist):
if abstimed < td:
- index = i-1
+ index = i - 1
break
- self.timeslider.setValue(sign*index)
+ self.timeslider.setValue(sign * index)
text = delta2txt(timed)
self.setText(text)
+
class TimeSlider(QtWidgets.QSlider):
def __init__(self, orientation, parent):
super(TimeSlider, self).__init__(orientation, parent)
@@ -235,35 +263,44 @@ class TimeSlider(QtWidgets.QSlider):
self.setMaximum(50)
self.setValue(0)
self.setPageStep(1)
+
def getTime(self):
time = timelist[abs(self.value())]
sign = "+" if self.value() >= 0 else "-"
- return sign+time
+ return sign + time
+
def mouseDoubleClickEvent(self, event):
self.setValue(0)
+
class MemoTabWindow(PesterTabWindow):
def __init__(self, mainwindow, parent=None):
super(MemoTabWindow, self).__init__(mainwindow, parent, "memos")
+
def addChat(self, convo):
self.convos[convo.channel] = convo
# either addTab or setCurrentIndex will trigger changed()
newindex = self.tabs.addTab(convo.channel)
self.tabIndices[convo.channel] = newindex
self.tabs.setCurrentIndex(newindex)
- self.tabs.setTabIcon(newindex,
- PesterIcon(self.mainwindow.theme["memos/memoicon"]))
+ self.tabs.setTabIcon(
+ newindex, PesterIcon(self.mainwindow.theme["memos/memoicon"])
+ )
+
def updateBlocked(self):
pass
+
def updateMood(self):
pass
-_ctag_begin = re.compile(r'')
+
+_ctag_begin = re.compile(r"")
+
class MemoText(PesterText):
def __init__(self, theme, parent=None):
super(MemoText, self).__init__(theme, parent)
- if hasattr(self.parent(), 'mainwindow'):
+ if hasattr(self.parent(), "mainwindow"):
self.mainwindow = self.parent().mainwindow
else:
self.mainwindow = self.parent()
@@ -279,35 +316,41 @@ class MemoText(PesterText):
self.copyAvailable[bool].connect(self.textReady)
self.urls = {}
for k in smiledict:
- self.addAnimation(QtCore.QUrl("smilies/%s" % (smiledict[k])),
- "smilies/%s" % (smiledict[k]))
- #self.mainwindow.animationSetting[bool].connect(self.animateChanged)
+ self.addAnimation(
+ QtCore.QUrl("smilies/%s" % (smiledict[k])),
+ "smilies/%s" % (smiledict[k]),
+ )
+ # self.mainwindow.animationSetting[bool].connect(self.animateChanged)
def initTheme(self, theme):
if "memos/scrollbar" in theme:
- self.setStyleSheet("QTextEdit { %s }"
- "QScrollBar:vertical { %s }"
- "QScrollBar::handle:vertical { %s }"
- "QScrollBar::add-line:vertical { %s }"
- "QScrollBar::sub-line:vertical { %s }"
- "QScrollBar:up-arrow:vertical { %s }"
- "QScrollBar:down-arrow:vertical { %s }"
- % (theme["memos/textarea/style"],
- theme["memos/scrollbar/style"],
- theme["memos/scrollbar/handle"],
- theme["memos/scrollbar/downarrow"],
- theme["memos/scrollbar/uparrow"],
- theme["memos/scrollbar/uarrowstyle"],
- theme["memos/scrollbar/darrowstyle"] ))
+ self.setStyleSheet(
+ "QTextEdit { %s }"
+ "QScrollBar:vertical { %s }"
+ "QScrollBar::handle:vertical { %s }"
+ "QScrollBar::add-line:vertical { %s }"
+ "QScrollBar::sub-line:vertical { %s }"
+ "QScrollBar:up-arrow:vertical { %s }"
+ "QScrollBar:down-arrow:vertical { %s }"
+ % (
+ theme["memos/textarea/style"],
+ theme["memos/scrollbar/style"],
+ theme["memos/scrollbar/handle"],
+ theme["memos/scrollbar/downarrow"],
+ theme["memos/scrollbar/uparrow"],
+ theme["memos/scrollbar/uarrowstyle"],
+ theme["memos/scrollbar/darrowstyle"],
+ )
+ )
else:
self.setStyleSheet("QTextEdit { %s }" % theme["memos/textarea/style"])
# So it doesn't inherit the memo's background image.
# Fixes floating "PESTERLOG:"
try:
- self.setStyleSheet(self.styleSheet()
- + ("QMenu{ %s }"
- % theme["main/defaultwindow/style"]))
+ self.setStyleSheet(
+ self.styleSheet() + ("QMenu{ %s }" % theme["main/defaultwindow/style"])
+ )
except:
pass
@@ -325,8 +368,8 @@ class MemoText(PesterText):
if m.state() == QtGui.QMovie.MovieState.NotRunning:
m.start()
chumdb = window.chumdb
- if chum is not me: # SO MUCH WH1T3SP4C3 >:]
- if type(lexmsg[0]) is colorBegin: # get color tag
+ if chum is not me: # SO MUCH WH1T3SP4C3 >:]
+ if type(lexmsg[0]) is colorBegin: # get color tag
colortag = lexmsg[0]
try:
color = QtGui.QColor(*[int(c) for c in colortag.color.split(",")])
@@ -363,10 +406,12 @@ class MemoText(PesterText):
if time.isFirstTime():
grammar = time.getGrammar()
- joinmsg = chum.memojoinmsg(systemColor,
- time.getTime(),
- grammar,
- window.theme["convo/text/joinmemo"])
+ joinmsg = chum.memojoinmsg(
+ systemColor,
+ time.getTime(),
+ grammar,
+ window.theme["convo/text/joinmemo"],
+ )
self.append(convertTags(joinmsg))
parent.mainwindow.chatlog.log(parent.channel, joinmsg)
time.openCurrentTime()
@@ -375,7 +420,8 @@ class MemoText(PesterText):
if msg.count(" msg.count(""):
for i in range(msg.count("")):
msg = msg + ""
- return "" + msg + ""
+ return '' + msg + ""
+
if type(lexmsg[0]) is mecmd:
memsg = chum.memsg(systemColor, lexmsg, time=time.getGrammar())
window.chatlog.log(parent.channel, memsg)
@@ -387,12 +433,14 @@ class MemoText(PesterText):
def changeTheme(self, theme):
self.initTheme(theme)
+
class MemoInput(PesterInput):
stylesheet_path = "memos/input/style"
# karxi: Because of the use of stylesheet_path, we don't have to rewrite
# this code.
# Neat, huh?
+
class PesterMemo(PesterConvo):
# TODO: Clean up inheritance between these!! The inits are ugly.
def __init__(self, channel, timestr, mainwindow, parent=None):
@@ -404,71 +452,107 @@ class PesterMemo(PesterConvo):
self.time = TimeTracker(txt2delta(timestr))
self.setWindowTitle(channel)
self.channelLabel = QtWidgets.QLabel(self)
- self.channelLabel.setSizePolicy(QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.MinimumExpanding,
- QtWidgets.QSizePolicy.Policy.Expanding))
+ self.channelLabel.setSizePolicy(
+ QtWidgets.QSizePolicy(
+ QtWidgets.QSizePolicy.Policy.MinimumExpanding,
+ QtWidgets.QSizePolicy.Policy.Expanding,
+ )
+ )
self.textArea = MemoText(self.mainwindow.theme, self)
self.textInput = MemoInput(self.mainwindow.theme, self)
self.textInput.setFocus()
self.miniUserlist = QtWidgets.QPushButton(">\n>", self)
- #self.miniUserlist.setStyleSheet("border:1px solid #a68168; border-width: 2px 0px 2px 2px; height: 90px; width: 10px; color: #cd8f9d; font-family: 'Arial'; background: white; margin-left: 2px;")
+ # self.miniUserlist.setStyleSheet("border:1px solid #a68168; border-width: 2px 0px 2px 2px; height: 90px; width: 10px; color: #cd8f9d; font-family: 'Arial'; background: white; margin-left: 2px;")
self.miniUserlist.clicked.connect(self.toggleUserlist)
-
self.userlist = RightClickList(self)
- self.userlist.setSizePolicy(QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed,
- QtWidgets.QSizePolicy.Policy.Expanding))
+ self.userlist.setSizePolicy(
+ QtWidgets.QSizePolicy(
+ QtWidgets.QSizePolicy.Policy.Fixed,
+ QtWidgets.QSizePolicy.Policy.Expanding,
+ )
+ )
self.userlist.optionsMenu = QtWidgets.QMenu(self)
- self.pesterChumAction = QAction(self.mainwindow.theme["main/menus/rclickchumlist/pester"], self)
+ self.pesterChumAction = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/pester"], self
+ )
self.pesterChumAction.triggered.connect(self.newPesterSlot)
- self.addchumAction = QAction(self.mainwindow.theme["main/menus/rclickchumlist/addchum"], self)
+ self.addchumAction = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/addchum"], self
+ )
self.addchumAction.triggered.connect(self.addChumSlot)
- self.banuserAction = QAction(self.mainwindow.theme["main/menus/rclickchumlist/banuser"], self)
+ self.banuserAction = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/banuser"], self
+ )
self.banuserAction.triggered.connect(self.banSelectedUser)
- self.opAction = QAction(self.mainwindow.theme["main/menus/rclickchumlist/opuser"], self)
+ self.opAction = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/opuser"], self
+ )
self.opAction.triggered.connect(self.opSelectedUser)
- self.voiceAction = QAction(self.mainwindow.theme["main/menus/rclickchumlist/voiceuser"], self)
+ self.voiceAction = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/voiceuser"], self
+ )
self.voiceAction.triggered.connect(self.voiceSelectedUser)
- self.quirkDisableAction = QAction(self.mainwindow.theme["main/menus/rclickchumlist/quirkkill"], self)
+ self.quirkDisableAction = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/quirkkill"], self
+ )
self.quirkDisableAction.triggered.connect(self.killQuirkUser)
self.userlist.optionsMenu.addAction(self.pesterChumAction)
self.userlist.optionsMenu.addAction(self.addchumAction)
# ban & op list added if we are op
self.optionsMenu = QtWidgets.QMenu(self)
- self.optionsMenu.setStyleSheet(self.mainwindow.theme["main/defaultwindow/style"]) # So it doesn't inherit the memo's background image.
- # Fixes floating "PESTERLOG:"
- self.oocToggle = QAction(self.mainwindow.theme["main/menus/rclickchumlist/ooc"], self)
+ self.optionsMenu.setStyleSheet(
+ self.mainwindow.theme["main/defaultwindow/style"]
+ ) # So it doesn't inherit the memo's background image.
+ # Fixes floating "PESTERLOG:"
+ self.oocToggle = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/ooc"], self
+ )
self.oocToggle.setCheckable(True)
self.oocToggle.toggled[bool].connect(self.toggleOOC)
- self.quirksOff = QAction(self.mainwindow.theme["main/menus/rclickchumlist/quirksoff"], self)
+ self.quirksOff = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/quirksoff"], self
+ )
self.quirksOff.setCheckable(True)
self.quirksOff.toggled[bool].connect(self.toggleQuirks)
- self.logchum = QAction(self.mainwindow.theme["main/menus/rclickchumlist/viewlog"], self)
+ self.logchum = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/viewlog"], self
+ )
self.logchum.triggered.connect(self.openChumLogs)
- self.invitechum = QAction(self.mainwindow.theme["main/menus/rclickchumlist/invitechum"], self)
+ self.invitechum = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/invitechum"], self
+ )
self.invitechum.triggered.connect(self.inviteChums)
- #if self.mainwindow.theme.has_key("main/menus/rclickchumlist/beeponmessage"):
+ # if self.mainwindow.theme.has_key("main/menus/rclickchumlist/beeponmessage"):
try:
- self._beepToggle = QAction(self.mainwindow.theme["main/menus/rclickchumlist/beeponmessage"], self)
+ self._beepToggle = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/beeponmessage"], self
+ )
except:
self._beepToggle = QAction("BEEP ON MESSAGE", self)
self._beepToggle.setCheckable(True)
self._beepToggle.toggled[bool].connect(self.toggleBeep)
- #if self.mainwindow.theme.has_key("main/menus/rclickchumlist/flashonmessage"):
+ # if self.mainwindow.theme.has_key("main/menus/rclickchumlist/flashonmessage"):
try:
- self._flashToggle = QAction(self.mainwindow.theme["main/menus/rclickchumlist/flashonmessage"], self)
+ self._flashToggle = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/flashonmessage"], self
+ )
except:
self._flashToggle = QAction("FLASH ON MESSAGE", self)
self._flashToggle.setCheckable(True)
self._flashToggle.toggled[bool].connect(self.toggleFlash)
- #if self.mainwindow.theme.has_key("main/menus/rclickchumlist/mutenotifications"):
+ # if self.mainwindow.theme.has_key("main/menus/rclickchumlist/mutenotifications"):
try:
- self._muteToggle = QAction(self.mainwindow.theme["main/menus/rclickchumlist/mutenotifications"], self)
+ self._muteToggle = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/mutenotifications"],
+ self,
+ )
except:
self._muteToggle = QAction("MUTE NOTIFICATIONS", self)
self._muteToggle.setCheckable(True)
@@ -484,24 +568,36 @@ class PesterMemo(PesterConvo):
self.optionsMenu.addAction(self.logchum)
self.optionsMenu.addAction(self.invitechum)
- self.chanModeMenu = QtWidgets.QMenu(self.mainwindow.theme["main/menus/rclickchumlist/memosetting"], self)
- self.chanNoquirks = QAction(self.mainwindow.theme["main/menus/rclickchumlist/memonoquirk"], self)
+ self.chanModeMenu = QtWidgets.QMenu(
+ self.mainwindow.theme["main/menus/rclickchumlist/memosetting"], self
+ )
+ self.chanNoquirks = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/memonoquirk"], self
+ )
self.chanNoquirks.setCheckable(True)
self.chanNoquirks.toggled[bool].connect(self.noquirksChan)
- self.chanHide = QAction(self.mainwindow.theme["main/menus/rclickchumlist/memohidden"], self)
+ self.chanHide = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/memohidden"], self
+ )
self.chanHide.setCheckable(True)
self.chanHide.toggled[bool].connect(self.hideChan)
- self.chanInvite = QAction(self.mainwindow.theme["main/menus/rclickchumlist/memoinvite"], self)
+ self.chanInvite = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/memoinvite"], self
+ )
self.chanInvite.setCheckable(True)
self.chanInvite.toggled[bool].connect(self.inviteChan)
- self.chanMod = QAction(self.mainwindow.theme["main/menus/rclickchumlist/memomute"], self)
+ self.chanMod = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/memomute"], self
+ )
self.chanMod.setCheckable(True)
self.chanMod.toggled[bool].connect(self.modChan)
self.chanModeMenu.addAction(self.chanNoquirks)
self.chanModeMenu.addAction(self.chanHide)
self.chanModeMenu.addAction(self.chanInvite)
self.chanModeMenu.addAction(self.chanMod)
- self.chanModeMenu.setStyleSheet(self.mainwindow.theme["main/defaultwindow/style"]) # BWAH BWAH FLOATING "PESTERLOG:"
+ self.chanModeMenu.setStyleSheet(
+ self.mainwindow.theme["main/defaultwindow/style"]
+ ) # BWAH BWAH FLOATING "PESTERLOG:"
self.timeslider = TimeSlider(QtCore.Qt.Orientation.Horizontal, self)
self.timeinput = TimeInput(self.timeslider, self)
@@ -533,9 +629,9 @@ class PesterMemo(PesterConvo):
layout_1.addWidget(self.miniUserlist)
layout_1.addWidget(self.userlist)
-# layout_1 = QtGui.QGridLayout()
-# layout_1.addWidget(self.timeslider, 0, 1, QtCore.Qt.AlignmentFlag.AlignHCenter)
-# layout_1.addWidget(self.timeinput, 1, 0, 1, 3)
+ # layout_1 = QtGui.QGridLayout()
+ # layout_1.addWidget(self.timeslider, 0, 1, QtCore.Qt.AlignmentFlag.AlignHCenter)
+ # layout_1.addWidget(self.timeinput, 1, 0, 1, 3)
layout_2 = QtWidgets.QHBoxLayout()
layout_2.addWidget(self.timeslider)
layout_2.addWidget(self.timeinput)
@@ -550,8 +646,9 @@ class PesterMemo(PesterConvo):
self.layout.addLayout(layout_2)
self.layout.setSpacing(0)
margins = self.mainwindow.theme["memos/margins"]
- self.layout.setContentsMargins(margins["left"], margins["top"],
- margins["right"], margins["bottom"])
+ self.layout.setContentsMargins(
+ margins["left"], margins["top"], margins["right"], margins["bottom"]
+ )
self.setLayout(self.layout)
@@ -561,11 +658,13 @@ class PesterMemo(PesterConvo):
p = self.mainwindow.profile()
timeGrammar = self.time.getGrammar()
systemColor = QtGui.QColor(self.mainwindow.theme["memos/systemMsgColor"])
- msg = p.memoopenmsg(systemColor,
- self.time.getTime(),
- timeGrammar,
- self.mainwindow.theme["convo/text/openmemo"],
- self.channel)
+ msg = p.memoopenmsg(
+ systemColor,
+ self.time.getTime(),
+ timeGrammar,
+ self.mainwindow.theme["convo/text/openmemo"],
+ self.channel,
+ )
self.time.openCurrentTime()
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
@@ -585,35 +684,45 @@ class PesterMemo(PesterConvo):
if self.userlist.isHidden():
self.userlist.show()
self.miniUserlist.setText(">\n>")
- self.miniUserlist.setStyleSheet("%s border-width: 2px 0px 2px 2px;"
- % self.miniUserlist.styleSheet())
+ self.miniUserlist.setStyleSheet(
+ "%s border-width: 2px 0px 2px 2px;" % self.miniUserlist.styleSheet()
+ )
else:
self.userlist.hide()
self.miniUserlist.setText("<\n<")
- self.miniUserlist.setStyleSheet("%s border-width: 2px;"
- % self.miniUserlist.styleSheet())
+ self.miniUserlist.setStyleSheet(
+ "%s border-width: 2px;" % self.miniUserlist.styleSheet()
+ )
def title(self):
return self.channel
+
def icon(self):
return PesterIcon(self.mainwindow.theme["memos/memoicon"])
def sendTimeInfo(self, newChum=False):
if newChum:
- self.messageSent.emit("PESTERCHUM:TIME>%s" % (delta2txt(self.time.getTime(), "server")+"i"),
- self.title())
+ self.messageSent.emit(
+ "PESTERCHUM:TIME>%s" % (delta2txt(self.time.getTime(), "server") + "i"),
+ self.title(),
+ )
else:
- self.messageSent.emit("PESTERCHUM:TIME>%s" % (delta2txt(self.time.getTime(), "server")),
- self.title())
+ self.messageSent.emit(
+ "PESTERCHUM:TIME>%s" % (delta2txt(self.time.getTime(), "server")),
+ self.title(),
+ )
def updateMood(self):
pass
+
def updateBlocked(self):
pass
+
def updateColor(self, handle, color):
chums = self.userlist.findItems(handle, QtCore.Qt.MatchFlag.MatchExactly)
for c in chums:
c.setForeground(QtGui.QBrush(color))
+
def addMessage(self, text, handle):
if type(handle) is bool:
chum = self.mainwindow.profile()
@@ -627,68 +736,80 @@ class PesterMemo(PesterConvo):
self.setStyleSheet("QtWidgets.QFrame { %s };" % (theme["memos/style"]))
self.setWindowIcon(PesterIcon(theme["memos/memoicon"]))
t = Template(theme["memos/label/text"])
- if self.mainwindow.advanced and hasattr(self, 'modes'):
- self.channelLabel.setText(t.safe_substitute(channel=self.channel) + "(%s)" % (self.modes))
+ if self.mainwindow.advanced and hasattr(self, "modes"):
+ self.channelLabel.setText(
+ t.safe_substitute(channel=self.channel) + "(%s)" % (self.modes)
+ )
else:
self.channelLabel.setText(t.safe_substitute(channel=self.channel))
self.channelLabel.setStyleSheet(theme["memos/label/style"])
- self.channelLabel.setAlignment(self.aligndict["h"][theme["memos/label/align/h"]]
- | self.aligndict["v"][theme["memos/label/align/v"]])
+ self.channelLabel.setAlignment(
+ self.aligndict["h"][theme["memos/label/align/h"]]
+ | self.aligndict["v"][theme["memos/label/align/v"]]
+ )
self.channelLabel.setMaximumHeight(theme["memos/label/maxheight"])
self.channelLabel.setMinimumHeight(theme["memos/label/minheight"])
self.userlist.optionsMenu.setStyleSheet(theme["main/defaultwindow/style"])
scrolls = "width: 12px; height: 12px; border: 0; padding: 0;"
if "main/chums/scrollbar" in theme:
- self.userlist.setStyleSheet("QListWidget { %s }"
- "QScrollBar { %s }"
- "QScrollBar::handle { %s }"
- "QScrollBar::add-line { %s }"
- "QScrollBar::sub-line { %s }"
- "QScrollBar:up-arrow { %s }"
- "QScrollBar:down-arrow { %s }"
- % (theme["memos/userlist/style"],
- theme["main/chums/scrollbar/style"] + scrolls,
- theme["main/chums/scrollbar/handle"],
- theme["main/chums/scrollbar/downarrow"],
- theme["main/chums/scrollbar/uparrow"],
- theme["main/chums/scrollbar/uarrowstyle"],
- theme["main/chums/scrollbar/darrowstyle"]))
+ self.userlist.setStyleSheet(
+ "QListWidget { %s }"
+ "QScrollBar { %s }"
+ "QScrollBar::handle { %s }"
+ "QScrollBar::add-line { %s }"
+ "QScrollBar::sub-line { %s }"
+ "QScrollBar:up-arrow { %s }"
+ "QScrollBar:down-arrow { %s }"
+ % (
+ theme["memos/userlist/style"],
+ theme["main/chums/scrollbar/style"] + scrolls,
+ theme["main/chums/scrollbar/handle"],
+ theme["main/chums/scrollbar/downarrow"],
+ theme["main/chums/scrollbar/uparrow"],
+ theme["main/chums/scrollbar/uarrowstyle"],
+ theme["main/chums/scrollbar/darrowstyle"],
+ )
+ )
elif "convo/scrollbar" in theme:
- self.userlist.setStyleSheet("QListWidget { %s }"
- "QScrollBar { %s }"
- "QScrollBar::handle { %s }"
- "QScrollBar::add-line { %s }"
- "QScrollBar::sub-line { %s }"
- "QScrollBar:up-arrow { %s }"
- "QScrollBar:down-arrow { %s }"
- % (theme["memos/userlist/style"],
- theme["convo/scrollbar/style"] + scrolls,
- theme["convo/scrollbar/handle"],
- "display: none;",
- "display: none;",
- "display: none;",
- "display: none;"))
+ self.userlist.setStyleSheet(
+ "QListWidget { %s }"
+ "QScrollBar { %s }"
+ "QScrollBar::handle { %s }"
+ "QScrollBar::add-line { %s }"
+ "QScrollBar::sub-line { %s }"
+ "QScrollBar:up-arrow { %s }"
+ "QScrollBar:down-arrow { %s }"
+ % (
+ theme["memos/userlist/style"],
+ theme["convo/scrollbar/style"] + scrolls,
+ theme["convo/scrollbar/handle"],
+ "display: none;",
+ "display: none;",
+ "display: none;",
+ "display: none;",
+ )
+ )
else:
- self.userlist.setStyleSheet("QListWidget { %s }"
- "QScrollBar { %s }"
- "QScrollBar::handle { %s }"
- % (theme["memos/userlist/style"],
- scrolls,
- "background-color: black;"))
+ self.userlist.setStyleSheet(
+ "QListWidget { %s }"
+ "QScrollBar { %s }"
+ "QScrollBar::handle { %s }"
+ % (theme["memos/userlist/style"], scrolls, "background-color: black;")
+ )
self.userlist.setFixedWidth(theme["memos/userlist/width"])
if self.userlist.isHidden():
borders = "border-width: 2px;"
else:
borders = "border-width: 2px 0px 2px 2px;"
- self.miniUserlist.setStyleSheet("padding: 0px;"
- "margin: 0px;"
- "margin-left: 5px;"
- "width: 10px;"
- "height: 90px;"
- + borders
- + theme["memos/userlist/style"])
+ self.miniUserlist.setStyleSheet(
+ "padding: 0px;"
+ "margin: 0px;"
+ "margin-left: 5px;"
+ "width: 10px;"
+ "height: 90px;" + borders + theme["memos/userlist/style"]
+ )
self.addchumAction.setText(theme["main/menus/rclickchumlist/addchum"])
self.banuserAction.setText(theme["main/menus/rclickchumlist/banuser"])
@@ -706,12 +827,16 @@ class PesterMemo(PesterConvo):
self.timeinput.setFixedWidth(theme["memos/time/text/width"])
self.timeinput.setStyleSheet(theme["memos/time/text/style"])
- slidercss = ("QSlider { %s }"
- "Slider::groove { %s }"
- "QSlider::handle { %s }"
- % (theme["memos/time/slider/style"],
- theme["memos/time/slider/groove"],
- theme["memos/time/slider/handle"]))
+ slidercss = (
+ "QSlider { %s }"
+ "Slider::groove { %s }"
+ "QSlider::handle { %s }"
+ % (
+ theme["memos/time/slider/style"],
+ theme["memos/time/slider/groove"],
+ theme["memos/time/slider/handle"],
+ )
+ )
self.timeslider.setStyleSheet(slidercss)
larrow = PesterIcon(self.mainwindow.theme["memos/time/arrows/left"])
@@ -726,27 +851,35 @@ class PesterMemo(PesterConvo):
self.timeswitchr.setIconSize(rarrow.realsize())
self.timeswitchr.setStyleSheet(self.mainwindow.theme["memos/time/arrows/style"])
- #if self.mainwindow.theme.has_key("main/menus/rclickchumlist/beeponmessage"):
+ # if self.mainwindow.theme.has_key("main/menus/rclickchumlist/beeponmessage"):
try:
- self._beepToggle.setText(self.mainwindow.theme["main/menus/rclickchumlist/beeponmessage"])
+ self._beepToggle.setText(
+ self.mainwindow.theme["main/menus/rclickchumlist/beeponmessage"]
+ )
except:
self._beepToggle.setText("BEEP ON MESSAGE")
- #if self.mainwindow.theme.has_key("main/menus/rclickchumlist/flashonmessage"):
+ # if self.mainwindow.theme.has_key("main/menus/rclickchumlist/flashonmessage"):
try:
- self._flashToggle.setText(self.mainwindow.theme["main/menus/rclickchumlist/flashonmessage"])
+ self._flashToggle.setText(
+ self.mainwindow.theme["main/menus/rclickchumlist/flashonmessage"]
+ )
except:
self._flashToggle.setText("FLASH ON MESSAGE")
- #if self.mainwindow.theme.has_key("main/menus/rclickchumlist/mutenotifications"):
+ # if self.mainwindow.theme.has_key("main/menus/rclickchumlist/mutenotifications"):
try:
- self._muteToggle.setText(self.mainwindow.theme["main/menus/rclickchumlist/mutenotifications"])
+ self._muteToggle.setText(
+ self.mainwindow.theme["main/menus/rclickchumlist/mutenotifications"]
+ )
except:
self._muteToggle.setText("MUTE NOTIFICATIONS")
- #if self.mainwindow.theme.has_key("main/menus/rclickchumlist/pester"):
+ # if self.mainwindow.theme.has_key("main/menus/rclickchumlist/pester"):
try:
- self.pesterChumAction.setText(self.mainwindow.theme["main/menus/rclickchumlist/pester"])
+ self.pesterChumAction.setText(
+ self.mainwindow.theme["main/menus/rclickchumlist/pester"]
+ )
except:
pass
@@ -755,20 +888,21 @@ class PesterMemo(PesterConvo):
self.textArea.changeTheme(theme)
self.textInput.changeTheme(theme)
margins = theme["memos/margins"]
- self.layout.setContentsMargins(margins["left"], margins["top"],
- margins["right"], margins["bottom"])
- for item in [self.userlist.item(i) for i in range(0,self.userlist.count())]:
+ self.layout.setContentsMargins(
+ margins["left"], margins["top"], margins["right"], margins["bottom"]
+ )
+ for item in [self.userlist.item(i) for i in range(0, self.userlist.count())]:
self.iconCrap(item)
def addUser(self, handle):
chumdb = self.mainwindow.chumdb
defaultcolor = QtGui.QColor("black")
founder = False
- op = False
- halfop = False
- admin = False
- voice = False
- if handle[0] == '@':
+ op = False
+ halfop = False
+ admin = False
+ voice = False
+ if handle[0] == "@":
op = True
handle = handle[1:]
if handle == self.mainwindow.profile().handle:
@@ -776,7 +910,7 @@ class PesterMemo(PesterConvo):
self.userlist.optionsMenu.addAction(self.banuserAction)
self.optionsMenu.addMenu(self.chanModeMenu)
self.op = True
- elif handle[0] == '%':
+ elif handle[0] == "%":
halfop = True
handle = handle[1:]
if handle == self.mainwindow.profile().handle:
@@ -784,13 +918,13 @@ class PesterMemo(PesterConvo):
self.userlist.optionsMenu.addAction(self.banuserAction)
self.optionsMenu.addMenu(self.chanModeMenu)
self.halfop = True
- elif handle[0] == '+':
+ elif handle[0] == "+":
voice = True
handle = handle[1:]
- elif handle[0] == '~':
+ elif handle[0] == "~":
founder = True
handle = handle[1:]
- elif handle[0] == '&':
+ elif handle[0] == "&":
admin = True
handle = handle[1:]
item = QtWidgets.QListWidgetItem(handle)
@@ -798,7 +932,7 @@ class PesterMemo(PesterConvo):
color = self.mainwindow.profile().color
else:
color = chumdb.getColor(handle, defaultcolor)
- item.box = (handle == "evacipatedBox")
+ item.box = handle == "evacipatedBox"
item.setForeground(QtGui.QBrush(color))
item.founder = founder
item.op = op
@@ -816,14 +950,37 @@ class PesterMemo(PesterConvo):
while listing is not None:
users.append(self.userlist.takeItem(0))
listing = self.userlist.item(0)
- users.sort(key=lambda x: ((-1 if x.box else (0 if x.founder else (1 if x.admin else (2 if x.op else (3 if x.halfop else (4 if x.voice else 5)))))), x.text()))
+ users.sort(
+ key=lambda x: (
+ (
+ -1
+ if x.box
+ else (
+ 0
+ if x.founder
+ else (
+ 1
+ if x.admin
+ else (
+ 2
+ if x.op
+ else (3 if x.halfop else (4 if x.voice else 5))
+ )
+ )
+ )
+ ),
+ x.text(),
+ )
+ )
for u in users:
self.userlist.addItem(u)
def updateChanModes(self, modes, op):
- if not hasattr(self, 'modes'): self.modes = ""
+ if not hasattr(self, "modes"):
+ self.modes = ""
chanmodes = list(str(self.modes))
- if chanmodes and chanmodes[0] == "+": chanmodes = chanmodes[1:]
+ if chanmodes and chanmodes[0] == "+":
+ chanmodes = chanmodes[1:]
modes = str(modes)
if op:
systemColor = QtGui.QColor(self.mainwindow.theme["memos/systemMsgColor"])
@@ -845,117 +1002,165 @@ class PesterMemo(PesterConvo):
self.quirksOff.setChecked(True)
self.applyquirks = False
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "A No-Quirk zone", True)
+ msg = chum.memomodemsg(
+ opchum, opgrammar, systemColor, "A No-Quirk zone", True
+ )
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("s") >= 0:
self.chanHide.setChecked(True)
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Secret", True)
+ msg = chum.memomodemsg(
+ opchum, opgrammar, systemColor, "Secret", True
+ )
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("i") >= 0:
self.chanInvite.setChecked(True)
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Invite-Only", True)
+ msg = chum.memomodemsg(
+ opchum, opgrammar, systemColor, "Invite-Only", 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, "Muted", True)
+ msg = chum.memomodemsg(
+ opchum, opgrammar, systemColor, "Muted", True
+ )
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
- #New
+ # New
if modes.find("C") >= 0:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "No-CTCP", True)
+ 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:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Join Delayed", True)
+ 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:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Flood Protected", True)
+ 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:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Censored", True)
+ 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:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Remembering Chat History", True)
+ 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:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Key-only", True)
+ 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:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "No-Knock", True)
+ 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:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Redirecting", True)
+ 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:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "No-Knock", True)
+ 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:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Limiting maximum amount of users", True)
+ 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:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Non-Auth muted", True)
+ 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:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Handle-locked", True)
+ 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:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "An Oper-Only channel", True)
+ 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:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Permanent", True)
+ 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:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "No-kick", True)
+ 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:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Registered users only", True)
+ 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:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Registered", True)
+ 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:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Secure-only", True)
+ msg = chum.memomodemsg(
+ opchum, opgrammar, systemColor, "Secure-only", True
+ )
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
elif modes[0] == "-":
@@ -967,125 +1172,178 @@ class PesterMemo(PesterConvo):
if modes.find("c") >= 0:
self.chanNoquirks.setChecked(False)
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "A No-Quirk zone", False)
+ msg = chum.memomodemsg(
+ opchum, opgrammar, systemColor, "A No-Quirk zone", False
+ )
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("s") >= 0:
self.chanHide.setChecked(False)
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Secret", False)
+ msg = chum.memomodemsg(
+ opchum, opgrammar, systemColor, "Secret", False
+ )
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if modes.find("i") >= 0:
self.chanInvite.setChecked(False)
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Invite-Only", False)
+ msg = chum.memomodemsg(
+ opchum, opgrammar, systemColor, "Invite-Only", 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, "Muted", False)
+ msg = chum.memomodemsg(
+ opchum, opgrammar, systemColor, "Muted", False
+ )
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
- #New
+ # New
if modes.find("C") >= 0:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "No-CTCP", False)
+ 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:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Join Delayed", False)
+ 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:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Flood Protected", False)
+ 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:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Censored", False)
+ 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:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Remembering Chat History", False)
+ 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:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Key-only", False)
+ 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:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "No-Knock", False)
+ 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:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Redirecting", False)
+ 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:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "No-Knock", False)
+ 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:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Limiting maximum amount of users", False)
+ 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:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Non-Auth muted", False)
+ 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:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Handle-locked", False)
+ 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:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "An Oper-Only channel", False)
+ 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:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Permanent", False)
+ 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:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "No-kick", False)
+ 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:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Registered users only", False)
+ 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:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Registered", False)
+ 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:
if op:
- msg = chum.memomodemsg(opchum, opgrammar, systemColor, "Secure-only", False)
+ 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:
t = Template(self.mainwindow.theme["memos/label/text"])
- self.channelLabel.setText(t.safe_substitute(channel=self.channel)
- + "(%s)" % (self.modes))
+ self.channelLabel.setText(
+ t.safe_substitute(channel=self.channel) + "(%s)" % (self.modes)
+ )
def timeUpdate(self, handle, cmd):
window = self.mainwindow
@@ -1097,7 +1355,7 @@ class PesterMemo(PesterConvo):
secs = int(cmd)
time = datetime.fromtimestamp(secs)
timed = time - datetime.now()
- s = (timed.seconds // 60)*60
+ s = (timed.seconds // 60) * 60
timed = timedelta(timed.days, s)
except OverflowError:
if secs < 0:
@@ -1109,7 +1367,7 @@ class PesterMemo(PesterConvo):
if cmd == "i":
timed = timedelta(0)
else:
- if cmd[len(cmd)-1] == 'c':
+ if cmd[len(cmd) - 1] == "c":
close = timeProtocol(cmd)
timed = None
else:
@@ -1124,9 +1382,9 @@ class PesterMemo(PesterConvo):
self.times[handle].setCurrent(close)
grammar = self.times[handle].getGrammar()
self.times[handle].removeTime(close)
- msg = chum.memoclosemsg(systemColor,
- grammar,
- window.theme["convo/text/closememo"])
+ msg = chum.memoclosemsg(
+ systemColor, grammar, window.theme["convo/text/closememo"]
+ )
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
elif timed not in self.times[handle]:
@@ -1141,19 +1399,21 @@ class PesterMemo(PesterConvo):
@QtCore.pyqtSlot()
def sentMessage(self):
text = str(self.textInput.text())
-
+
return parsetools.kxhandleInput(self, text, flavor="memos")
-
+
@QtCore.pyqtSlot(QString)
def namesUpdated(self, channel):
c = str(channel)
- if c.lower() != self.channel.lower(): return
+ if c.lower() != self.channel.lower():
+ return
# get namesdb (unused)
- #namesdb = self.mainwindow.namesdb
+ # namesdb = self.mainwindow.namesdb
# reload names
self.userlist.clear()
for n in self.mainwindow.namesdb[self.channel]:
self.addUser(n)
+
@QtCore.pyqtSlot(QString, QString)
def modesUpdated(self, channel, modes):
c = str(channel)
@@ -1164,7 +1424,7 @@ class PesterMemo(PesterConvo):
def closeInviteOnly(self, channel):
c = str(channel)
if c.lower() == self.channel.lower():
- self.mainwindow.inviteOnlyChan['QString'].disconnect(self.closeInviteOnly)
+ self.mainwindow.inviteOnlyChan["QString"].disconnect(self.closeInviteOnly)
if self.parent():
PchumLog.info(self.channel)
i = self.parent().tabIndices[self.channel]
@@ -1172,11 +1432,14 @@ class PesterMemo(PesterConvo):
else:
self.close()
msgbox = QtWidgets.QMessageBox()
- msgbox.setStyleSheet("QMessageBox{ %s }"
- % self.mainwindow.theme["main/defaultwindow/style"])
+ msgbox.setStyleSheet(
+ "QMessageBox{ %s }" % self.mainwindow.theme["main/defaultwindow/style"]
+ )
msgbox.setText("%s: Invites only!" % (c))
- msgbox.setInformativeText("This channel is invite-only. "
- "You must get an invitation from someone on the inside before entering.")
+ msgbox.setInformativeText(
+ "This channel is invite-only. "
+ "You must get an invitation from someone on the inside before entering."
+ )
msgbox.setStandardButtons(QtWidgets.QMessageBox.StandardButton.Ok)
msgbox.exec()
@@ -1184,7 +1447,9 @@ class PesterMemo(PesterConvo):
def closeForbidden(self, channel, reason):
c = str(channel)
if c.lower() == self.channel.lower():
- self.mainwindow.forbiddenChan['QString', 'QString'].disconnect(self.closeForbidden)
+ self.mainwindow.forbiddenChan["QString", "QString"].disconnect(
+ self.closeForbidden
+ )
if self.parent():
PchumLog.info(self.channel)
i = self.parent().tabIndices[self.channel]
@@ -1192,21 +1457,24 @@ class PesterMemo(PesterConvo):
else:
self.close()
msgbox = QtWidgets.QMessageBox()
- msgbox.setStyleSheet("QMessageBox{ %s }"
- % self.mainwindow.theme["main/defaultwindow/style"])
+ msgbox.setStyleSheet(
+ "QMessageBox{ %s }" % self.mainwindow.theme["main/defaultwindow/style"]
+ )
msgbox.setText("%s: D: CANT JOIN MEMO!!!" % (c))
msgbox.setInformativeText(reason)
msgbox.setStandardButtons(QtWidgets.QMessageBox.StandardButton.Ok)
msgbox.exec()
def quirkDisable(self, op, msg):
- chums = self.userlist.findItems(op, QtCore.Qt.MatchFlag.MatchExactly)
+ chums = self.userlist.findItems(op, QtCore.Qt.MatchFlag.MatchExactly)
for c in chums:
if c.op:
if msg == self.mainwindow.profile().handle:
self.quirksOff.setChecked(True)
self.applyquirks = False
- systemColor = QtGui.QColor(self.mainwindow.theme["memos/systemMsgColor"])
+ systemColor = QtGui.QColor(
+ self.mainwindow.theme["memos/systemMsgColor"]
+ )
chum = self.mainwindow.profile()
opchum = PesterProfile(op)
if op in self.times:
@@ -1223,11 +1491,11 @@ class PesterMemo(PesterConvo):
chum = PesterProfile(h)
if h == self.mainwindow.profile().handle:
chum = self.mainwindow.profile()
- #ttracker = self.time
- #curtime = self.time.getTime()
- #elif h in self.times:
+ # ttracker = self.time
+ # curtime = self.time.getTime()
+ # elif h in self.times:
# ttracker = self.times[h]
- #else:
+ # else:
# ttracker = TimeTracker(timedelta(0))
opchum = PesterProfile(op)
PchumLog.debug("op = " + op)
@@ -1239,13 +1507,14 @@ class PesterMemo(PesterConvo):
else:
opgrammar = TimeGrammar("CURRENT", "C", "RIGHT NOW")
return (chum, opchum, opgrammar)
+
def iconCrap(self, c, down=True):
- for m in (self.umodes if down else reversed(self.umodes)):
- if eval("c."+m):
+ for m in self.umodes if down else reversed(self.umodes):
+ if eval("c." + m):
if m == "box":
icon = PesterIcon("smilies/box.png")
else:
- icon = PesterIcon(self.mainwindow.theme["memos/"+m+"/icon"])
+ icon = PesterIcon(self.mainwindow.theme["memos/" + m + "/icon"])
c.setIcon(icon)
return
icon = QtGui.QIcon()
@@ -1253,7 +1522,7 @@ class PesterMemo(PesterConvo):
@QtCore.pyqtSlot()
def dumpNetsplit(self):
- if (len(self.netsplit) > 0):
+ if len(self.netsplit) > 0:
chum = self.mainwindow.profile()
systemColor = QtGui.QColor(self.mainwindow.theme["memos/systemMsgColor"])
msg = chum.memonetsplitmsg(systemColor, self.netsplit)
@@ -1263,12 +1532,12 @@ class PesterMemo(PesterConvo):
@QtCore.pyqtSlot(QString, QString, QString)
def userPresentChange(self, handle, channel, update):
- #print("handle: %s, channel: %s, update: %s" % (handle, channel, update))
+ # print("handle: %s, channel: %s, update: %s" % (handle, channel, update))
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.
+ # 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]
op = l[1]
@@ -1282,21 +1551,33 @@ class PesterMemo(PesterConvo):
l = update.split(":")
update = l[0]
op = l[1]
- if (update in ["join","left", "kick", \
- "+q", "-q", "+o", "-o", "+h", "-h", \
- "+a", "-a", "+v", "-v"]) \
- and c.lower() != self.channel.lower():
+ if (
+ update
+ in [
+ "join",
+ "left",
+ "kick",
+ "+q",
+ "-q",
+ "+o",
+ "-o",
+ "+h",
+ "-h",
+ "+a",
+ "-a",
+ "+v",
+ "-v",
+ ]
+ ) and c.lower() != self.channel.lower():
return
- chums = self.userlist.findItems(h, QtCore.Qt.MatchFlag.MatchExactly)
+ chums = self.userlist.findItems(h, QtCore.Qt.MatchFlag.MatchExactly)
systemColor = QtGui.QColor(self.mainwindow.theme["memos/systemMsgColor"])
# print exit
if update in ("quit", "left", "nick", "netsplit"):
if update == "netsplit":
if not hasattr(self, "netsplit"):
self.netsplit = []
- QtCore.QTimer.singleShot(1500,
- self,
- QtCore.SLOT('dumpNetsplit()'))
+ QtCore.QTimer.singleShot(1500, self, QtCore.SLOT("dumpNetsplit()"))
for c in chums:
chum = PesterProfile(h)
self.userlist.takeItem(self.userlist.row(c))
@@ -1306,28 +1587,31 @@ class PesterMemo(PesterConvo):
while self.times[h].getTime() is not None:
t = self.times[h]
grammar = t.getGrammar()
- allinitials.append("%s%s%s" % (grammar.pcf,
- chum.initials(),
- grammar.number))
+ allinitials.append(
+ "%s%s%s" % (grammar.pcf, chum.initials(), grammar.number)
+ )
self.times[h].removeTime(t.getTime())
if update == "netsplit":
self.netsplit.extend(allinitials)
else:
- msg = chum.memoclosemsg(systemColor,
- allinitials,
- self.mainwindow.theme["convo/text/closememo"])
+ msg = chum.memoclosemsg(
+ systemColor,
+ allinitials,
+ self.mainwindow.theme["convo/text/closememo"],
+ )
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
if update == "nick":
self.addUser(newnick)
- newchums = self.userlist.findItems(newnick,
- QtCore.Qt.MatchFlag.MatchExactly)
+ newchums = self.userlist.findItems(
+ newnick, QtCore.Qt.MatchFlag.MatchExactly
+ )
for nc in newchums:
for c in chums:
nc.founder = c.founder
- nc.op = c.op
- nc.halfop = c.halfop
- nc.admin = c.admin
+ nc.op = c.op
+ nc.halfop = c.halfop
+ nc.admin = c.admin
self.iconCrap(nc)
self.sortUsers()
elif update == "kick":
@@ -1353,7 +1637,9 @@ class PesterMemo(PesterConvo):
opgrammar = TimeGrammar("CURRENT", "C", "RIGHT NOW")
while ttracker.getTime() is not None:
grammar = ttracker.getGrammar()
- allinitials.append("%s%s%s" % (grammar.pcf, chum.initials(), grammar.number))
+ allinitials.append(
+ "%s%s%s" % (grammar.pcf, chum.initials(), grammar.number)
+ )
ttracker.removeTime(ttracker.getTime())
msg = chum.memobanmsg(opchum, opgrammar, systemColor, allinitials, reason)
self.textArea.append(convertTags(msg))
@@ -1362,34 +1648,47 @@ class PesterMemo(PesterConvo):
if chum is self.mainwindow.profile():
# are you next?
msgbox = QtWidgets.QMessageBox()
- msgbox.setStyleSheet("QMessageBox{ %s }"
- % self.mainwindow.theme["main/defaultwindow/style"])
+ msgbox.setStyleSheet(
+ "QMessageBox{ %s }"
+ % self.mainwindow.theme["main/defaultwindow/style"]
+ )
msgbox.setText(self.mainwindow.theme["convo/text/kickedmemo"])
# Add ban(kick) reason
# l = split update
- kick_msg = ("press 0k to rec0nnect or cancel to absc0nd")
+ kick_msg = "press 0k to rec0nnect or cancel to absc0nd"
if len(l) >= 3:
try:
- if l[1] != l[2]: # If there's no reason then reason is set to handle
+ if (
+ l[1] != l[2]
+ ): # If there's no reason then reason is set to handle
# Process spare ':' characters (this might not be safe?)
aggrievocation = l[1] + ": " + l[2]
if len(l) > 3:
- aggrievocation += ':'
+ aggrievocation += ":"
for x in range(3, len(l)):
aggrievocation += l[x]
# Not for last slice
- if x != (len(l)-1):
- aggrievocation += ':'
- kick_msg = ("%s\n\npress 0k to rec0nnect or cancel to absc0nd" % aggrievocation)
+ if x != (len(l) - 1):
+ aggrievocation += ":"
+ kick_msg = (
+ "%s\n\npress 0k to rec0nnect or cancel to absc0nd"
+ % aggrievocation
+ )
except IndexError as e:
# This shouldn't happen
PchumLog.warning("kickmsg IndexError: %s" % e)
msgbox.setInformativeText(kick_msg)
- msgbox.setStandardButtons(QtWidgets.QMessageBox.StandardButton.Ok | QtWidgets.QMessageBox.StandardButton.Cancel)
+ msgbox.setStandardButtons(
+ QtWidgets.QMessageBox.StandardButton.Ok
+ | QtWidgets.QMessageBox.StandardButton.Cancel
+ )
# Find the OK button and make it default
for b in msgbox.buttons():
- if msgbox.buttonRole(b) == QtWidgets.QMessageBox.ButtonRole.AcceptRole:
+ if (
+ msgbox.buttonRole(b)
+ == QtWidgets.QMessageBox.ButtonRole.AcceptRole
+ ):
# We found the 'OK' button, set it as the default
b.setDefault(True)
b.setAutoDefault(True)
@@ -1405,11 +1704,13 @@ class PesterMemo(PesterConvo):
self.mainwindow.joinChannel.emit(self.channel)
me = self.mainwindow.profile()
self.time.openCurrentTime()
- msg = me.memoopenmsg(systemColor,
- self.time.getTime(),
- self.time.getGrammar(),
- self.mainwindow.theme["convo/text/openmemo"],
- self.channel)
+ msg = me.memoopenmsg(
+ systemColor,
+ self.time.getTime(),
+ self.time.getGrammar(),
+ self.mainwindow.theme["convo/text/openmemo"],
+ self.channel,
+ )
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
elif ret == QtWidgets.QMessageBox.StandardButton.Cancel:
@@ -1424,7 +1725,7 @@ class PesterMemo(PesterConvo):
elif update == "join":
self.addUser(h)
time = self.time.getTime()
- serverText = "PESTERCHUM:TIME>"+delta2txt(time, "server")
+ serverText = "PESTERCHUM:TIME>" + delta2txt(time, "server")
self.messageSent.emit(serverText, self.title())
elif update == "+q":
for c in chums:
@@ -1439,10 +1740,10 @@ 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"
+ # 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")
+ # PchumLog.debug("post memoopmsg")
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
for c in chums:
@@ -1515,7 +1816,7 @@ class PesterMemo(PesterConvo):
c.admin = False
self.iconCrap(c)
self.sortUsers()
- elif c.lower() == self.channel.lower() and h == "" and update[0] in ["+","-"]:
+ elif c.lower() == self.channel.lower() and h == "" and update[0] in ["+", "-"]:
self.updateChanModes(update, op)
elif update == "+v":
if self.mainwindow.config.opvoiceMessages():
@@ -1537,7 +1838,7 @@ class PesterMemo(PesterConvo):
c.voice = False
self.iconCrap(c)
self.sortUsers()
- elif c.lower() == self.channel.lower() and h == "" and update[0] in ["+","-"]:
+ elif c.lower() == self.channel.lower() and h == "" and update[0] in ["+", "-"]:
self.updateChanModes(update, op)
@QtCore.pyqtSlot()
@@ -1555,28 +1856,34 @@ class PesterMemo(PesterConvo):
return
currentChum = PesterProfile(str(self.userlist.currentItem().text()))
self.mainwindow.addChum(currentChum)
+
@QtCore.pyqtSlot()
def banSelectedUser(self):
if not self.userlist.currentItem():
return
currentHandle = str(self.userlist.currentItem().text())
- (reason, ok) = QtWidgets.QInputDialog.getText(self,
- "Ban User",
- "Enter the reason you are banning this user (optional):")
+ (reason, ok) = QtWidgets.QInputDialog.getText(
+ self, "Ban User", "Enter the reason you are banning this user (optional):"
+ )
if ok:
- self.mainwindow.kickUser.emit("%s:%s" % (currentHandle, reason), self.channel)
+ self.mainwindow.kickUser.emit(
+ "%s:%s" % (currentHandle, reason), self.channel
+ )
+
@QtCore.pyqtSlot()
def opSelectedUser(self):
if not self.userlist.currentItem():
return
currentHandle = str(self.userlist.currentItem().text())
self.mainwindow.setChannelMode.emit(self.channel, "+o", currentHandle)
+
@QtCore.pyqtSlot()
def voiceSelectedUser(self):
if not self.userlist.currentItem():
return
currentHandle = str(self.userlist.currentItem().text())
self.mainwindow.setChannelMode.emit(self.channel, "+v", currentHandle)
+
@QtCore.pyqtSlot()
def killQuirkUser(self):
if not self.userlist.currentItem():
@@ -1593,23 +1900,26 @@ class PesterMemo(PesterConvo):
@QtCore.pyqtSlot()
def openChumLogs(self):
currentChum = self.channel
- self.mainwindow.chumList.pesterlogviewer = PesterLogViewer(currentChum,
- self.mainwindow.config,
- self.mainwindow.theme,
- self.mainwindow)
- self.mainwindow.chumList.pesterlogviewer.rejected.connect(self.mainwindow.chumList.closeActiveLog)
+ self.mainwindow.chumList.pesterlogviewer = PesterLogViewer(
+ currentChum, self.mainwindow.config, self.mainwindow.theme, self.mainwindow
+ )
+ self.mainwindow.chumList.pesterlogviewer.rejected.connect(
+ self.mainwindow.chumList.closeActiveLog
+ )
self.mainwindow.chumList.pesterlogviewer.show()
self.mainwindow.chumList.pesterlogviewer.raise_()
self.mainwindow.chumList.pesterlogviewer.activateWindow()
@QtCore.pyqtSlot()
def inviteChums(self):
- if not hasattr(self, 'invitechums'):
+ if not hasattr(self, "invitechums"):
self.invitechums = None
if not self.invitechums:
- (chum, ok) = QtWidgets.QInputDialog.getText(self,
- "Invite to Chat",
- "Enter the chumhandle of the user you'd like to invite:")
+ (chum, ok) = QtWidgets.QInputDialog.getText(
+ self,
+ "Invite to Chat",
+ "Enter the chumhandle of the user you'd like to invite:",
+ )
if ok:
chum = str(chum)
self.mainwindow.inviteChum.emit(chum, self.channel)
@@ -1617,31 +1927,35 @@ class PesterMemo(PesterConvo):
@QtCore.pyqtSlot(bool)
def noquirksChan(self, on):
- x = ["-","+"][on]
- self.mainwindow.setChannelMode.emit(self.channel, x+"c", "")
+ x = ["-", "+"][on]
+ self.mainwindow.setChannelMode.emit(self.channel, x + "c", "")
+
@QtCore.pyqtSlot(bool)
def hideChan(self, on):
- x = ["-","+"][on]
- self.mainwindow.setChannelMode.emit(self.channel, x+"s", "")
+ x = ["-", "+"][on]
+ self.mainwindow.setChannelMode.emit(self.channel, x + "s", "")
+
@QtCore.pyqtSlot(bool)
def inviteChan(self, on):
- x = ["-","+"][on]
- self.mainwindow.setChannelMode.emit(self.channel, x+"i", "")
+ x = ["-", "+"][on]
+ self.mainwindow.setChannelMode.emit(self.channel, x + "i", "")
+
@QtCore.pyqtSlot(bool)
def modChan(self, on):
- x = ["-","+"][on]
- self.mainwindow.setChannelMode.emit(self.channel, x+"m", "")
+ x = ["-", "+"][on]
+ self.mainwindow.setChannelMode.emit(self.channel, x + "m", "")
@QtCore.pyqtSlot()
def sendtime(self):
- #me = self.mainwindow.profile()
- #systemColor = QtGui.QColor(self.mainwindow.theme["memos/systemMsgColor"])
+ # me = self.mainwindow.profile()
+ # systemColor = QtGui.QColor(self.mainwindow.theme["memos/systemMsgColor"])
time = txt2delta(self.timeinput.text())
- #present = self.time.addTime(time)
+ # present = self.time.addTime(time)
self.time.addTime(time)
- serverText = "PESTERCHUM:TIME>"+delta2txt(time, "server")
+ serverText = "PESTERCHUM:TIME>" + delta2txt(time, "server")
self.messageSent.emit(serverText, self.title())
+
@QtCore.pyqtSlot()
def smashclock(self):
me = self.mainwindow.profile()
@@ -1650,7 +1964,9 @@ class PesterMemo(PesterConvo):
if removed:
grammar = self.time.getGrammarTime(time)
systemColor = QtGui.QColor(self.mainwindow.theme["memos/systemMsgColor"])
- msg = me.memoclosemsg(systemColor, grammar, self.mainwindow.theme["convo/text/closememo"])
+ msg = me.memoclosemsg(
+ systemColor, grammar, self.mainwindow.theme["convo/text/closememo"]
+ )
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
@@ -1660,126 +1976,132 @@ class PesterMemo(PesterConvo):
self.resetSlider(newtime, send=False)
else:
self.resetSlider(newtime)
+
@QtCore.pyqtSlot()
def prevtime(self):
time = self.time.prevTime()
self.time.setCurrent(time)
self.resetSlider(time)
self.textInput.setFocus()
+
@QtCore.pyqtSlot()
def nexttime(self):
time = self.time.nextTime()
self.time.setCurrent(time)
self.resetSlider(time)
self.textInput.setFocus()
+
def closeEvent(self, event):
self.mainwindow.waitingMessages.messageAnswered(self.channel)
self.windowClosed.emit(self.title())
- windowClosed = QtCore.pyqtSignal('QString')
+ windowClosed = QtCore.pyqtSignal("QString")
-timelist = ["0:00",
- "0:01",
- "0:02",
- "0:04",
- "0:06",
- "0:10",
- "0:14",
- "0:22",
- "0:30",
- "0:41",
- "1:00",
- "1:34",
- "2:16",
- "3:14",
- "4:13",
- "4:20",
- "5:25",
- "6:12",
- "7:30",
- "8:44",
- "10:25",
- "11:34",
- "14:13",
- "16:12",
- "17:44",
- "22:22",
- "25:10",
- "33:33",
- "42:00",
- "43:14",
- "50:00",
- "62:12",
- "75:00",
- "88:44",
- "100",
- "133",
- "143",
- "188",
- "200",
- "222",
- "250",
- "314",
- "333",
- "413",
- "420",
- "500",
- "600",
- "612",
- "888",
- "1000",
- "1025"]
-
-timedlist = [timedelta(0),
- timedelta(0, 60),
- timedelta(0, 120),
- timedelta(0, 240),
- timedelta(0, 360),
- timedelta(0, 600),
- timedelta(0, 840),
- timedelta(0, 1320),
- timedelta(0, 1800),
- timedelta(0, 2460),
- timedelta(0, 3600),
- timedelta(0, 5640),
- timedelta(0, 8160),
- timedelta(0, 11640),
- timedelta(0, 15180),
- timedelta(0, 15600),
- timedelta(0, 19500),
- timedelta(0, 22320),
- timedelta(0, 27000),
- timedelta(0, 31440),
- timedelta(0, 37500),
- timedelta(0, 41640),
- timedelta(0, 51180),
- timedelta(0, 58320),
- timedelta(0, 63840),
- timedelta(0, 80520),
- timedelta(1, 4200),
- timedelta(1, 34380),
- timedelta(1, 64800),
- timedelta(1, 69240),
- timedelta(2, 7200),
- timedelta(2, 51120),
- timedelta(3, 10800),
- timedelta(3, 60240),
- timedelta(4, 14400),
- timedelta(5, 46800),
- timedelta(5, 82800),
- timedelta(7, 72000),
- timedelta(8, 28800),
- timedelta(9, 21600),
- timedelta(10, 36000),
- timedelta(13, 7200),
- timedelta(13, 75600),
- timedelta(17, 18000),
- timedelta(17, 43200),
- timedelta(20, 72000),
- timedelta(25),
- timedelta(25, 43200),
- timedelta(37),
- timedelta(41, 57600),
- timedelta(42, 61200)]
+timelist = [
+ "0:00",
+ "0:01",
+ "0:02",
+ "0:04",
+ "0:06",
+ "0:10",
+ "0:14",
+ "0:22",
+ "0:30",
+ "0:41",
+ "1:00",
+ "1:34",
+ "2:16",
+ "3:14",
+ "4:13",
+ "4:20",
+ "5:25",
+ "6:12",
+ "7:30",
+ "8:44",
+ "10:25",
+ "11:34",
+ "14:13",
+ "16:12",
+ "17:44",
+ "22:22",
+ "25:10",
+ "33:33",
+ "42:00",
+ "43:14",
+ "50:00",
+ "62:12",
+ "75:00",
+ "88:44",
+ "100",
+ "133",
+ "143",
+ "188",
+ "200",
+ "222",
+ "250",
+ "314",
+ "333",
+ "413",
+ "420",
+ "500",
+ "600",
+ "612",
+ "888",
+ "1000",
+ "1025",
+]
+timedlist = [
+ timedelta(0),
+ timedelta(0, 60),
+ timedelta(0, 120),
+ timedelta(0, 240),
+ timedelta(0, 360),
+ timedelta(0, 600),
+ timedelta(0, 840),
+ timedelta(0, 1320),
+ timedelta(0, 1800),
+ timedelta(0, 2460),
+ timedelta(0, 3600),
+ timedelta(0, 5640),
+ timedelta(0, 8160),
+ timedelta(0, 11640),
+ timedelta(0, 15180),
+ timedelta(0, 15600),
+ timedelta(0, 19500),
+ timedelta(0, 22320),
+ timedelta(0, 27000),
+ timedelta(0, 31440),
+ timedelta(0, 37500),
+ timedelta(0, 41640),
+ timedelta(0, 51180),
+ timedelta(0, 58320),
+ timedelta(0, 63840),
+ timedelta(0, 80520),
+ timedelta(1, 4200),
+ timedelta(1, 34380),
+ timedelta(1, 64800),
+ timedelta(1, 69240),
+ timedelta(2, 7200),
+ timedelta(2, 51120),
+ timedelta(3, 10800),
+ timedelta(3, 60240),
+ timedelta(4, 14400),
+ timedelta(5, 46800),
+ timedelta(5, 82800),
+ timedelta(7, 72000),
+ timedelta(8, 28800),
+ timedelta(9, 21600),
+ timedelta(10, 36000),
+ timedelta(13, 7200),
+ timedelta(13, 75600),
+ timedelta(17, 18000),
+ timedelta(17, 43200),
+ timedelta(20, 72000),
+ timedelta(25),
+ timedelta(25, 43200),
+ timedelta(37),
+ timedelta(41, 57600),
+ timedelta(42, 61200),
+]
diff --git a/menus.py b/menus.py
index 193d2b2..f88a476 100644
--- a/menus.py
+++ b/menus.py
@@ -22,24 +22,30 @@ from parsetools import lexMessage
QString = str
_datadir = ostools.getDataDir()
+
class PesterQuirkItem(QtWidgets.QTreeWidgetItem):
def __init__(self, quirk):
parent = None
QtWidgets.QTreeWidgetItem.__init__(self, parent)
self.quirk = quirk
self.setText(0, str(quirk))
+
def update(self, quirk):
self.quirk = quirk
self.setText(0, str(quirk))
+
def __lt__(self, quirkitem):
"""Sets the order of quirks if auto-sorted by Qt. Obsolete now."""
if self.quirk.type == "prefix":
return True
- elif (self.quirk.type == "replace" or self.quirk.type == "regexp") and \
- quirkitem.type == "suffix":
+ elif (
+ self.quirk.type == "replace" or self.quirk.type == "regexp"
+ ) and quirkitem.type == "suffix":
return True
else:
return False
+
+
class PesterQuirkList(QtWidgets.QTreeWidget):
def __init__(self, mainwindow, parent):
QtWidgets.QTreeWidget.__init__(self, parent)
@@ -54,18 +60,20 @@ class PesterQuirkList(QtWidgets.QTreeWidget):
item = PesterQuirkItem(q)
self.addItem(item, False)
self.changeCheckState()
- #self.setDragEnabled(True)
- #self.setDragDropMode(QtGui.QAbstractItemView.DragDropMode.InternalMove)
+ # self.setDragEnabled(True)
+ # self.setDragDropMode(QtGui.QAbstractItemView.DragDropMode.InternalMove)
self.setDropIndicatorShown(True)
self.setSortingEnabled(False)
self.setIndentation(15)
self.header().hide()
def addItem(self, item, new=True):
- item.setFlags(QtCore.Qt.ItemFlag.ItemIsSelectable
- | QtCore.Qt.ItemFlag.ItemIsDragEnabled
- | QtCore.Qt.ItemFlag.ItemIsUserCheckable
- | QtCore.Qt.ItemFlag.ItemIsEnabled)
+ item.setFlags(
+ QtCore.Qt.ItemFlag.ItemIsSelectable
+ | QtCore.Qt.ItemFlag.ItemIsDragEnabled
+ | QtCore.Qt.ItemFlag.ItemIsUserCheckable
+ | QtCore.Qt.ItemFlag.ItemIsEnabled
+ )
if item.quirk.on:
item.setCheckState(0, QtCore.Qt.CheckState.Checked)
else:
@@ -73,7 +81,8 @@ class PesterQuirkList(QtWidgets.QTreeWidget):
if new:
curgroup = self.currentItem()
if curgroup:
- if curgroup.parent(): curgroup = curgroup.parent()
+ if curgroup.parent():
+ curgroup = curgroup.parent()
item.quirk.quirk["group"] = item.quirk.group = curgroup.text(0)
found = self.findItems(item.quirk.group, QtCore.Qt.MatchFlag.MatchExactly)
if len(found) > 0:
@@ -81,10 +90,14 @@ class PesterQuirkList(QtWidgets.QTreeWidget):
else:
child_1 = QtWidgets.QTreeWidgetItem([item.quirk.group])
self.addTopLevelItem(child_1)
- child_1.setFlags(child_1.flags()
- | QtCore.Qt.ItemFlag.ItemIsUserCheckable
- | QtCore.Qt.ItemFlag.ItemIsEnabled)
- child_1.setChildIndicatorPolicy(QtWidgets.QTreeWidgetItem.ChildIndicatorPolicy.DontShowIndicatorWhenChildless)
+ child_1.setFlags(
+ child_1.flags()
+ | QtCore.Qt.ItemFlag.ItemIsUserCheckable
+ | QtCore.Qt.ItemFlag.ItemIsEnabled
+ )
+ child_1.setChildIndicatorPolicy(
+ QtWidgets.QTreeWidgetItem.ChildIndicatorPolicy.DontShowIndicatorWhenChildless
+ )
child_1.setCheckState(0, QtCore.Qt.CheckState.Unchecked)
child_1.setExpanded(True)
child_1.addChild(item)
@@ -93,93 +106,113 @@ class PesterQuirkList(QtWidgets.QTreeWidget):
def currentQuirk(self):
if type(self.currentItem()) is PesterQuirkItem:
return self.currentItem()
- else: return None
+ else:
+ return None
@QtCore.pyqtSlot()
def upShiftQuirk(self):
- found = self.findItems(self.currentItem().text(0),
- QtCore.Qt.MatchFlag.MatchExactly)
- if len(found): # group
+ found = self.findItems(
+ self.currentItem().text(0), QtCore.Qt.MatchFlag.MatchExactly
+ )
+ if len(found): # group
i = self.indexOfTopLevelItem(found[0])
if i > 0:
expand = found[0].isExpanded()
shifted_item = self.takeTopLevelItem(i)
- self.insertTopLevelItem(i-1, shifted_item)
+ self.insertTopLevelItem(i - 1, shifted_item)
shifted_item.setExpanded(expand)
self.setCurrentItem(shifted_item)
- else: # quirk
- found = self.findItems(self.currentItem().text(0),
- QtCore.Qt.MatchFlag.MatchExactly
- | QtCore.Qt.MatchFlag.MatchRecursive)
+ else: # quirk
+ found = self.findItems(
+ self.currentItem().text(0),
+ QtCore.Qt.MatchFlag.MatchExactly | QtCore.Qt.MatchFlag.MatchRecursive,
+ )
for f in found:
- if not f.isSelected(): continue
- if not f.parent(): continue
+ if not f.isSelected():
+ continue
+ if not f.parent():
+ continue
i = f.parent().indexOfChild(f)
- if i > 0: # keep in same group
+ if i > 0: # keep in same group
p = f.parent()
shifted_item = f.parent().takeChild(i)
- p.insertChild(i-1, shifted_item)
+ p.insertChild(i - 1, shifted_item)
self.setCurrentItem(shifted_item)
- else: # move to another group
+ else: # move to another group
j = self.indexOfTopLevelItem(f.parent())
- if j <= 0: continue
+ if j <= 0:
+ continue
shifted_item = f.parent().takeChild(i)
- self.topLevelItem(j-1).addChild(shifted_item)
+ self.topLevelItem(j - 1).addChild(shifted_item)
self.setCurrentItem(shifted_item)
self.changeCheckState()
@QtCore.pyqtSlot()
def downShiftQuirk(self):
- found = self.findItems(self.currentItem().text(0),
- QtCore.Qt.MatchFlag.MatchExactly)
- if len(found): # group
+ found = self.findItems(
+ self.currentItem().text(0), QtCore.Qt.MatchFlag.MatchExactly
+ )
+ if len(found): # group
i = self.indexOfTopLevelItem(found[0])
- if i < self.topLevelItemCount()-1 and i >= 0:
+ if i < self.topLevelItemCount() - 1 and i >= 0:
expand = found[0].isExpanded()
shifted_item = self.takeTopLevelItem(i)
- self.insertTopLevelItem(i+1, shifted_item)
+ self.insertTopLevelItem(i + 1, shifted_item)
shifted_item.setExpanded(expand)
self.setCurrentItem(shifted_item)
- else: # quirk
- found = self.findItems(self.currentItem().text(0),
- QtCore.Qt.MatchFlag.MatchExactly
- | QtCore.Qt.MatchFlag.MatchRecursive)
+ else: # quirk
+ found = self.findItems(
+ self.currentItem().text(0),
+ QtCore.Qt.MatchFlag.MatchExactly | QtCore.Qt.MatchFlag.MatchRecursive,
+ )
for f in found:
- if not f.isSelected(): continue
- if not f.parent(): continue
+ if not f.isSelected():
+ continue
+ if not f.parent():
+ continue
i = f.parent().indexOfChild(f)
- if i < f.parent().childCount()-1 and i >= 0:
+ if i < f.parent().childCount() - 1 and i >= 0:
p = f.parent()
shifted_item = f.parent().takeChild(i)
- p.insertChild(i+1, shifted_item)
+ p.insertChild(i + 1, shifted_item)
self.setCurrentItem(shifted_item)
else:
j = self.indexOfTopLevelItem(f.parent())
- if j >= self.topLevelItemCount()-1 or j < 0: continue
+ if j >= self.topLevelItemCount() - 1 or j < 0:
+ continue
shifted_item = f.parent().takeChild(i)
- self.topLevelItem(j+1).insertChild(0, shifted_item)
+ self.topLevelItem(j + 1).insertChild(0, shifted_item)
self.setCurrentItem(shifted_item)
self.changeCheckState()
@QtCore.pyqtSlot()
def removeCurrent(self):
i = self.currentItem()
- found = self.findItems(i.text(0),
- QtCore.Qt.MatchFlag.MatchExactly
- | QtCore.Qt.MatchFlag.MatchRecursive)
+ found = self.findItems(
+ i.text(0),
+ QtCore.Qt.MatchFlag.MatchExactly | QtCore.Qt.MatchFlag.MatchRecursive,
+ )
for f in found:
- if not f.isSelected(): continue
- if not f.parent(): # group
+ if not f.isSelected():
+ continue
+ if not f.parent(): # group
msgbox = QtWidgets.QMessageBox()
msgbox.setStyleSheet(self.mainwindow.theme["main/defaultwindow/style"])
msgbox.setObjectName("delquirkwarning")
msgbox.setWindowTitle("WARNING!")
- msgbox.setInformativeText("Are you sure you want to delete the quirk group: %s" % (f.text(0)))
- msgbox.setStandardButtons(QtWidgets.QMessageBox.StandardButton.Ok
- | QtWidgets.QMessageBox.StandardButton.Cancel)
+ msgbox.setInformativeText(
+ "Are you sure you want to delete the quirk group: %s" % (f.text(0))
+ )
+ msgbox.setStandardButtons(
+ QtWidgets.QMessageBox.StandardButton.Ok
+ | QtWidgets.QMessageBox.StandardButton.Cancel
+ )
# Find the Cancel button and make it default
for b in msgbox.buttons():
- if msgbox.buttonRole(b) == QtWidgets.QMessageBox.ButtonRole.RejectRole:
+ if (
+ msgbox.buttonRole(b)
+ == QtWidgets.QMessageBox.ButtonRole.RejectRole
+ ):
# We found the 'OK' button, set it as the default
b.setDefault(True)
b.setAutoDefault(True)
@@ -196,10 +229,12 @@ class PesterQuirkList(QtWidgets.QTreeWidget):
@QtCore.pyqtSlot()
def addQuirkGroup(self):
- if not hasattr(self, 'addgroupdialog'):
+ if not hasattr(self, "addgroupdialog"):
self.addgroupdialog = None
if not self.addgroupdialog:
- (gname, ok) = QtWidgets.QInputDialog.getText(self, "Add Group", "Enter a name for the new quirk group:")
+ (gname, ok) = QtWidgets.QInputDialog.getText(
+ self, "Add Group", "Enter a name for the new quirk group:"
+ )
if ok:
gname = str(gname)
if re.search("[^A-Za-z0-9_\s]", gname) is not None:
@@ -218,10 +253,14 @@ class PesterQuirkList(QtWidgets.QTreeWidget):
return
child_1 = QtWidgets.QTreeWidgetItem([gname])
self.addTopLevelItem(child_1)
- child_1.setFlags(child_1.flags()
- | QtCore.Qt.ItemFlag.ItemIsUserCheckable
- | QtCore.Qt.ItemFlag.ItemIsEnabled)
- child_1.setChildIndicatorPolicy(QtWidgets.QTreeWidgetItem.ChildIndicatorPolicy.DontShowIndicatorWhenChildless)
+ child_1.setFlags(
+ child_1.flags()
+ | QtCore.Qt.ItemFlag.ItemIsUserCheckable
+ | QtCore.Qt.ItemFlag.ItemIsEnabled
+ )
+ child_1.setChildIndicatorPolicy(
+ QtWidgets.QTreeWidgetItem.ChildIndicatorPolicy.DontShowIndicatorWhenChildless
+ )
child_1.setCheckState(0, QtCore.Qt.CheckState.Unchecked)
child_1.setExpanded(True)
@@ -239,14 +278,20 @@ class PesterQuirkList(QtWidgets.QTreeWidget):
noneChecked = False
else:
allChecked = False
- if allChecked: self.topLevelItem(i).setCheckState(0, QtCore.Qt.CheckState.Checked)
- elif noneChecked: self.topLevelItem(i).setCheckState(0, QtCore.Qt.CheckState.PartiallyChecked)
- else: self.topLevelItem(i).setCheckState(0, QtCore.Qt.CheckState.Checked)
+ if allChecked:
+ self.topLevelItem(i).setCheckState(0, QtCore.Qt.CheckState.Checked)
+ elif noneChecked:
+ self.topLevelItem(i).setCheckState(
+ 0, QtCore.Qt.CheckState.PartiallyChecked
+ )
+ else:
+ self.topLevelItem(i).setCheckState(0, QtCore.Qt.CheckState.Checked)
else:
state = self.topLevelItem(index).checkState(0)
for j in range(self.topLevelItem(index).childCount()):
self.topLevelItem(index).child(j).setCheckState(0, state)
+
class QuirkTesterWindow(QtWidgets.QDialog):
def __init__(self, parent):
QtWidgets.QDialog.__init__(self, parent)
@@ -254,7 +299,7 @@ class QuirkTesterWindow(QtWidgets.QDialog):
self.mainwindow = parent.mainwindow
self.setStyleSheet(self.mainwindow.theme["main/defaultwindow/style"])
self.setWindowTitle("Quirk Tester")
- self.resize(350,300)
+ self.resize(350, 300)
self.textArea = PesterText(self.mainwindow.theme, self)
self.textInput = PesterInput(self.mainwindow.theme, self)
@@ -276,6 +321,7 @@ class QuirkTesterWindow(QtWidgets.QDialog):
def clearNewMessage(self):
pass
+
@QtCore.pyqtSlot()
def sentMessage(self):
text = str(self.textInput.text())
@@ -296,13 +342,14 @@ class QuirkTesterWindow(QtWidgets.QDialog):
def closeEvent(self, event):
self.parent().quirktester = None
+
class PesterQuirkTypes(QtWidgets.QDialog):
def __init__(self, parent, quirk=None):
QtWidgets.QDialog.__init__(self, parent)
self.mainwindow = parent.mainwindow
self.setStyleSheet(self.mainwindow.theme["main/defaultwindow/style"])
self.setWindowTitle("Quirk Wizard")
- self.resize(500,310)
+ self.resize(500, 310)
self.quirk = quirk
self.pages = QtWidgets.QStackedWidget(self)
@@ -335,7 +382,8 @@ class PesterQuirkTypes(QtWidgets.QDialog):
self.funclist2.setStyleSheet("color: #000000; background-color: #FFFFFF;")
from parsetools import quirkloader
- funcs = [q+"()" for q in list(quirkloader.quirks.keys())]
+
+ funcs = [q + "()" for q in list(quirkloader.quirks.keys())]
funcs.sort()
self.funclist.addItems(funcs)
self.funclist2.addItems(funcs)
@@ -346,9 +394,9 @@ class PesterQuirkTypes(QtWidgets.QDialog):
self.reloadQuirkFuncButton2.clicked.connect(self.reloadQuirkFuncSlot)
self.funclist.setMaximumWidth(160)
- self.funclist.resize(160,50)
+ self.funclist.resize(160, 50)
self.funclist2.setMaximumWidth(160)
- self.funclist2.resize(160,50)
+ self.funclist2.resize(160, 50)
layout_f = QtWidgets.QVBoxLayout()
layout_f.addWidget(QtWidgets.QLabel("Available Regexp\nFunctions"))
layout_f.addWidget(self.funclist)
@@ -414,8 +462,10 @@ class PesterQuirkTypes(QtWidgets.QDialog):
layout_replace.addLayout(layout_3)
layout_3 = QtWidgets.QHBoxLayout()
excludeCheckbox = QtWidgets.QCheckBox("Exclude links and smilies")
- excludeCheckbox.setToolTip("Splits input to exclude smilies, weblinks, @handles, and #memos."
- + "\nThe replace is applied on every substring individually.")
+ excludeCheckbox.setToolTip(
+ "Splits input to exclude smilies, weblinks, @handles, and #memos."
+ + "\nThe replace is applied on every substring individually."
+ )
layout_3.addWidget(excludeCheckbox)
layout_replace.addLayout(layout_3)
@@ -436,9 +486,11 @@ class PesterQuirkTypes(QtWidgets.QDialog):
layout_regexp.addLayout(layout_3)
layout_3 = QtWidgets.QHBoxLayout()
excludeCheckbox = QtWidgets.QCheckBox("Exclude links and smilies")
- excludeCheckbox.setToolTip("Splits input to exclude smilies, weblinks, @handles, and #memos."
- + "\nSince the replace is applied on every substring individually,"
- + "\ncertain patterns or functions like gradients may not work correctly.")
+ excludeCheckbox.setToolTip(
+ "Splits input to exclude smilies, weblinks, @handles, and #memos."
+ + "\nSince the replace is applied on every substring individually,"
+ + "\ncertain patterns or functions like gradients may not work correctly."
+ )
layout_3.addWidget(excludeCheckbox)
layout_regexp.addLayout(layout_3)
layout_all.addLayout(layout_f)
@@ -480,9 +532,11 @@ class PesterQuirkTypes(QtWidgets.QDialog):
layout_random.addLayout(layout_6)
layout_9 = QtWidgets.QHBoxLayout()
excludeCheckbox = QtWidgets.QCheckBox("Exclude links and smilies")
- excludeCheckbox.setToolTip("Splits input to exclude smilies, weblinks, @handles, and #memos."
- + "\nSince the replace is applied on every substring individually,"
- + "\ncertain patterns or functions like gradients may not work correctly.")
+ excludeCheckbox.setToolTip(
+ "Splits input to exclude smilies, weblinks, @handles, and #memos."
+ + "\nSince the replace is applied on every substring individually,"
+ + "\ncertain patterns or functions like gradients may not work correctly."
+ )
layout_9.addWidget(excludeCheckbox)
layout_random.addLayout(layout_9)
@@ -514,33 +568,43 @@ class PesterQuirkTypes(QtWidgets.QDialog):
layout_3 = QtWidgets.QHBoxLayout()
excludeCheckbox = QtWidgets.QCheckBox("Exclude links and smilies")
- excludeCheckbox.setToolTip("Splits input to exclude smilies, weblinks, @handles, and #memos."
- + "\nThe replace is applied on every substring individually.")
+ excludeCheckbox.setToolTip(
+ "Splits input to exclude smilies, weblinks, @handles, and #memos."
+ + "\nThe replace is applied on every substring individually."
+ )
layout_3.addWidget(excludeCheckbox)
layout_mispeller.addLayout(layout_3)
if quirk:
- types = ["prefix","suffix","replace","regexp","random","spelling"]
- for (i,r) in enumerate(self.radios):
+ types = ["prefix", "suffix", "replace", "regexp", "random", "spelling"]
+ for (i, r) in enumerate(self.radios):
if i == types.index(quirk.quirk.type):
r.setChecked(True)
- self.changePage(types.index(quirk.quirk.type)+1)
+ self.changePage(types.index(quirk.quirk.type) + 1)
page = self.pages.currentWidget().layout()
q = quirk.quirk.quirk
- if q["type"] in ("prefix","suffix"):
+ if q["type"] in ("prefix", "suffix"):
page.itemAt(1).layout().itemAt(1).widget().setText(q["value"])
elif q["type"] == "replace":
page.itemAt(1).layout().itemAt(1).widget().setText(q["from"])
page.itemAt(2).layout().itemAt(1).widget().setText(q["to"])
try:
- page.itemAt(3).layout().itemAt(0).widget().setCheckState(QtCore.Qt.CheckState(int(q["checkstate"])))
+ page.itemAt(3).layout().itemAt(0).widget().setCheckState(
+ QtCore.Qt.CheckState(int(q["checkstate"]))
+ )
except (KeyError, ValueError) as e:
print("KeyError: %s" % str(e))
elif q["type"] == "regexp":
- page.itemAt(2).layout().itemAt(1).layout().itemAt(1).widget().setText(q["from"])
- page.itemAt(2).layout().itemAt(2).layout().itemAt(1).widget().setText(q["to"])
+ page.itemAt(2).layout().itemAt(1).layout().itemAt(1).widget().setText(
+ q["from"]
+ )
+ page.itemAt(2).layout().itemAt(2).layout().itemAt(1).widget().setText(
+ q["to"]
+ )
try:
- page.itemAt(2).layout().itemAt(3).layout().itemAt(0).widget().setCheckState(QtCore.Qt.CheckState(int(q["checkstate"])))
+ page.itemAt(2).layout().itemAt(3).layout().itemAt(
+ 0
+ ).widget().setCheckState(QtCore.Qt.CheckState(int(q["checkstate"])))
except (KeyError, ValueError) as e:
print("KeyError: %s" % str(e))
elif q["type"] == "random":
@@ -548,13 +612,17 @@ class PesterQuirkTypes(QtWidgets.QDialog):
for v in q["randomlist"]:
item = QtWidgets.QListWidgetItem(v, self.replacelist)
try:
- page.itemAt(2).layout().itemAt(2).layout().itemAt(0).widget().setCheckState(QtCore.Qt.CheckState(int(q["checkstate"])))
+ page.itemAt(2).layout().itemAt(2).layout().itemAt(
+ 0
+ ).widget().setCheckState(QtCore.Qt.CheckState(int(q["checkstate"])))
except (KeyError, ValueError) as e:
print("KeyError: %s" % str(e))
elif q["type"] == "spelling":
self.slider.setValue(q["percentage"])
try:
- page.itemAt(3).layout().itemAt(0).widget().setCheckState(QtCore.Qt.CheckState(int(q["checkstate"])))
+ page.itemAt(3).layout().itemAt(0).widget().setCheckState(
+ QtCore.Qt.CheckState(int(q["checkstate"]))
+ )
except (KeyError, ValueError) as e:
print("KeyError: %s" % str(e))
@@ -565,13 +633,15 @@ class PesterQuirkTypes(QtWidgets.QDialog):
def changePage(self, page):
c = self.pages.count()
- if page >= c or page < 0: return
+ if page >= c or page < 0:
+ return
self.back.setEnabled(page > 0)
if page >= 1 and page <= 6:
self.next.setText("Finish")
else:
self.next.setText("Next")
self.pages.setCurrentIndex(page)
+
@QtCore.pyqtSlot()
def nextPage(self):
if self.next.text() == "Finish":
@@ -579,11 +649,12 @@ class PesterQuirkTypes(QtWidgets.QDialog):
return
cur = self.pages.currentIndex()
if cur == 0:
- for (i,r) in enumerate(self.radios):
+ for (i, r) in enumerate(self.radios):
if r.isChecked():
- self.changePage(i+1)
+ self.changePage(i + 1)
else:
- self.changePage(cur+1)
+ self.changePage(cur + 1)
+
@QtCore.pyqtSlot()
def backPage(self):
cur = self.pages.currentIndex()
@@ -592,13 +663,15 @@ class PesterQuirkTypes(QtWidgets.QDialog):
@QtCore.pyqtSlot(int)
def printValue(self, value):
- self.current.setText(str(value)+"%")
+ self.current.setText(str(value) + "%")
+
@QtCore.pyqtSlot()
def addRandomString(self):
text = str(self.replaceinput.text())
item = QtWidgets.QListWidgetItem(text, self.replacelist)
self.replaceinput.setText("")
self.replaceinput.setFocus()
+
@QtCore.pyqtSlot()
def removeRandomString(self):
if not self.replacelist.currentItem():
@@ -610,14 +683,16 @@ class PesterQuirkTypes(QtWidgets.QDialog):
@QtCore.pyqtSlot()
def reloadQuirkFuncSlot(self):
from parsetools import reloadQuirkFunctions, quirkloader
+
reloadQuirkFunctions()
- funcs = [q+"()" for q in list(quirkloader.quirks.keys())]
+ funcs = [q + "()" for q in list(quirkloader.quirks.keys())]
funcs.sort()
self.funclist.clear()
self.funclist.addItems(funcs)
self.funclist2.clear()
self.funclist2.addItems(funcs)
+
class PesterChooseQuirks(QtWidgets.QDialog):
def __init__(self, config, theme, parent):
QtWidgets.QDialog.__init__(self, parent)
@@ -644,8 +719,8 @@ class PesterChooseQuirks(QtWidgets.QDialog):
self.newGroupButton.setToolTip("New Quirk Group")
self.newGroupButton.clicked.connect(self.quirkList.addQuirkGroup)
- layout_quirklist = QtWidgets.QHBoxLayout() #the nude layout quirklist
- layout_shiftbuttons = QtWidgets.QVBoxLayout() #the shift button layout
+ layout_quirklist = QtWidgets.QHBoxLayout() # the nude layout quirklist
+ layout_shiftbuttons = QtWidgets.QVBoxLayout() # the shift button layout
layout_shiftbuttons.addWidget(self.upShiftButton)
layout_shiftbuttons.addWidget(self.newGroupButton)
layout_shiftbuttons.addWidget(self.downShiftButton)
@@ -678,7 +753,7 @@ class PesterChooseQuirks(QtWidgets.QDialog):
layout_0 = QtWidgets.QVBoxLayout()
layout_0.addLayout(layout_quirklist)
layout_0.addLayout(layout_1)
- #layout_0.addLayout(layout_2)
+ # layout_0.addLayout(layout_2)
layout_0.addLayout(layout_3)
layout_0.addLayout(layout_ok)
@@ -690,19 +765,20 @@ class PesterChooseQuirks(QtWidgets.QDialog):
for j in range(self.quirkList.topLevelItem(i).childCount()):
u.append(self.quirkList.topLevelItem(i).child(j).quirk)
return u
- #return [self.quirkList.item(i).quirk for i in range(self.quirkList.count())]
+ # return [self.quirkList.item(i).quirk for i in range(self.quirkList.count())]
+
def testquirks(self):
u = []
for i in range(self.quirkList.topLevelItemCount()):
for j in range(self.quirkList.topLevelItem(i).childCount()):
item = self.quirkList.topLevelItem(i).child(j)
- if (item.checkState(0) == QtCore.Qt.CheckState.Checked):
+ if item.checkState(0) == QtCore.Qt.CheckState.Checked:
u.append(item.quirk)
return u
@QtCore.pyqtSlot()
def testQuirks(self):
- if not hasattr(self, 'quirktester'):
+ if not hasattr(self, "quirktester"):
self.quirktester = None
if self.quirktester:
return
@@ -712,13 +788,14 @@ class PesterChooseQuirks(QtWidgets.QDialog):
@QtCore.pyqtSlot()
def editSelected(self):
q = self.quirkList.currentQuirk()
- if not q: return
- #quirk = q.quirk
+ if not q:
+ return
+ # quirk = q.quirk
self.addQuirkDialog(q)
@QtCore.pyqtSlot()
def addQuirkDialog(self, quirk=None):
- if not hasattr(self, 'quirkadd'):
+ if not hasattr(self, "quirkadd"):
self.quirkadd = None
if self.quirkadd:
return
@@ -726,51 +803,100 @@ class PesterChooseQuirks(QtWidgets.QDialog):
self.quirkadd.accepted.connect(self.addQuirk)
self.quirkadd.rejected.connect(self.closeQuirk)
self.quirkadd.show()
+
@QtCore.pyqtSlot()
def addQuirk(self):
types = ["prefix", "suffix", "replace", "regexp", "random", "spelling"]
vdict = {}
- vdict["type"] = types[self.quirkadd.pages.currentIndex()-1]
+ vdict["type"] = types[self.quirkadd.pages.currentIndex() - 1]
page = self.quirkadd.pages.currentWidget().layout()
- if vdict["type"] in ("prefix","suffix"):
+ if vdict["type"] in ("prefix", "suffix"):
vdict["value"] = str(page.itemAt(1).layout().itemAt(1).widget().text())
elif vdict["type"] == "replace":
vdict["from"] = str(page.itemAt(1).layout().itemAt(1).widget().text())
vdict["to"] = str(page.itemAt(2).layout().itemAt(1).widget().text())
try:
# PyQt6
- vdict["checkstate"] = str(page.itemAt(3).layout().itemAt(0).widget().checkState().value)
+ vdict["checkstate"] = str(
+ page.itemAt(3).layout().itemAt(0).widget().checkState().value
+ )
except AttributeError:
# PyQt5
- vdict["checkstate"] = str(page.itemAt(3).layout().itemAt(0).widget().checkState())
+ vdict["checkstate"] = str(
+ page.itemAt(3).layout().itemAt(0).widget().checkState()
+ )
elif vdict["type"] == "regexp":
- vdict["from"] = str(page.itemAt(2).layout().itemAt(1).layout().itemAt(1).widget().text())
- vdict["to"] = str(page.itemAt(2).layout().itemAt(2).layout().itemAt(1).widget().text())
+ vdict["from"] = str(
+ page.itemAt(2).layout().itemAt(1).layout().itemAt(1).widget().text()
+ )
+ vdict["to"] = str(
+ page.itemAt(2).layout().itemAt(2).layout().itemAt(1).widget().text()
+ )
try:
# PyQt6
- vdict["checkstate"] = str(page.itemAt(2).layout().itemAt(3).layout().itemAt(0).widget().checkState().value)
+ vdict["checkstate"] = str(
+ page.itemAt(2)
+ .layout()
+ .itemAt(3)
+ .layout()
+ .itemAt(0)
+ .widget()
+ .checkState()
+ .value
+ )
except AttributeError:
# PyQt5
- vdict["checkstate"] = str(page.itemAt(2).layout().itemAt(3).layout().itemAt(0).widget().checkState())
+ vdict["checkstate"] = str(
+ page.itemAt(2)
+ .layout()
+ .itemAt(3)
+ .layout()
+ .itemAt(0)
+ .widget()
+ .checkState()
+ )
elif vdict["type"] == "random":
vdict["from"] = str(self.quirkadd.regexp.text())
try:
# PyQt6
- vdict["checkstate"] = str(page.itemAt(2).layout().itemAt(2).layout().itemAt(0).widget().checkState().value)
+ vdict["checkstate"] = str(
+ page.itemAt(2)
+ .layout()
+ .itemAt(2)
+ .layout()
+ .itemAt(0)
+ .widget()
+ .checkState()
+ .value
+ )
except AttributeError:
# PyQt5
- vdict["checkstate"] = str(page.itemAt(2).layout().itemAt(2).layout().itemAt(0).widget().checkState())
- randomlist = [str(self.quirkadd.replacelist.item(i).text())
- for i in range(0,self.quirkadd.replacelist.count())]
+ vdict["checkstate"] = str(
+ page.itemAt(2)
+ .layout()
+ .itemAt(2)
+ .layout()
+ .itemAt(0)
+ .widget()
+ .checkState()
+ )
+ randomlist = [
+ str(self.quirkadd.replacelist.item(i).text())
+ for i in range(0, self.quirkadd.replacelist.count())
+ ]
vdict["randomlist"] = randomlist
elif vdict["type"] == "spelling":
vdict["percentage"] = self.quirkadd.slider.value()
try:
# PyQt6
- vdict["checkstate"] = str(page.itemAt(3).layout().itemAt(0).widget().checkState().value)
+ vdict["checkstate"] = str(
+ page.itemAt(3).layout().itemAt(0).widget().checkState().value
+ )
except AttributeError:
# PyQt5
- vdict["checkstate"] = str(page.itemAt(3).layout().itemAt(0).widget().checkState())
+ vdict["checkstate"] = str(
+ page.itemAt(3).layout().itemAt(0).widget().checkState()
+ )
if vdict["type"] in ("regexp", "random"):
try:
re.compile(vdict["from"])
@@ -789,10 +915,12 @@ class PesterChooseQuirks(QtWidgets.QDialog):
else:
self.quirkadd.quirk.update(quirk)
self.quirkadd = None
+
@QtCore.pyqtSlot()
def closeQuirk(self):
self.quirkadd = None
+
class PesterChooseTheme(QtWidgets.QDialog):
def __init__(self, config, theme, parent):
QtWidgets.QDialog.__init__(self, parent)
@@ -830,8 +958,11 @@ class PesterChooseTheme(QtWidgets.QDialog):
self.accepted.connect(parent.themeSelected)
self.rejected.connect(parent.closeTheme)
+
class PesterChooseProfile(QtWidgets.QDialog):
- def __init__(self, userprofile, config, theme, parent, collision=None, svsnick=None):
+ def __init__(
+ self, userprofile, config, theme, parent, collision=None, svsnick=None
+ ):
QtWidgets.QDialog.__init__(self, parent)
self.userprofile = userprofile
self.theme = theme
@@ -839,15 +970,21 @@ class PesterChooseProfile(QtWidgets.QDialog):
self.parent = parent
self.setStyleSheet(self.theme["main/defaultwindow/style"])
- self.currentHandle = QtWidgets.QLabel("CHANGING FROM %s" % userprofile.chat.handle)
+ self.currentHandle = QtWidgets.QLabel(
+ "CHANGING FROM %s" % userprofile.chat.handle
+ )
self.chumHandle = QtWidgets.QLineEdit(self)
self.chumHandle.setMinimumWidth(200)
self.chumHandle.setObjectName("setprofilehandle")
- self.chumHandleLabel = QtWidgets.QLabel(self.theme["main/mychumhandle/label/text"], self)
+ self.chumHandleLabel = QtWidgets.QLabel(
+ self.theme["main/mychumhandle/label/text"], self
+ )
self.chumColorButton = QtWidgets.QPushButton(self)
self.chumColorButton.setObjectName("setprofilecolor")
self.chumColorButton.resize(50, 20)
- self.chumColorButton.setStyleSheet("background: %s" % (userprofile.chat.colorhtml()))
+ self.chumColorButton.setStyleSheet(
+ "background: %s" % (userprofile.chat.colorhtml())
+ )
self.chumcolor = userprofile.chat.color
self.chumColorButton.clicked.connect(self.openColorDialog)
layout_1 = QtWidgets.QHBoxLayout()
@@ -861,7 +998,7 @@ class PesterChooseProfile(QtWidgets.QDialog):
self.profileBox = QtWidgets.QComboBox(self)
self.profileBox.addItem("Choose a profile...")
for p in avail_profiles:
- #PchumLog.debug("Adding profile: %s" % p.chat.handle)
+ # PchumLog.debug("Adding profile: %s" % p.chat.handle)
self.profileBox.addItem(p.chat.handle)
else:
self.profileBox = None
@@ -886,13 +1023,19 @@ class PesterChooseProfile(QtWidgets.QDialog):
layout_0 = QtWidgets.QVBoxLayout()
if collision:
- collision_warning = QtWidgets.QLabel("%s is taken already! Pick a new profile." % (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)
+ 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.addWidget(
+ self.currentHandle, alignment=QtCore.Qt.AlignmentFlag.AlignHCenter
+ )
layout_0.addLayout(layout_1)
if avail_profiles:
profileLabel = QtWidgets.QLabel("Or choose an existing profile:", self)
@@ -927,7 +1070,10 @@ class PesterChooseProfile(QtWidgets.QDialog):
self.errorMsg.setText("PROFILE HANDLE IS TOO LONG")
return
if not PesterProfile.checkValid(handle)[0]:
- self.errorMsg.setText("NOT A VALID CHUMTAG. REASON:\n%s" % (PesterProfile.checkValid(handle)[1]))
+ self.errorMsg.setText(
+ "NOT A VALID CHUMTAG. REASON:\n%s"
+ % (PesterProfile.checkValid(handle)[1])
+ )
return
self.accept()
@@ -941,7 +1087,9 @@ class PesterChooseProfile(QtWidgets.QDialog):
problem.setObjectName("errmsg")
problem.setStyleSheet(self.theme["main/defaultwindow/style"])
problem.setWindowTitle("Problem!")
- problem.setInformativeText("You can't delete the profile you're currently using!")
+ problem.setInformativeText(
+ "You can't delete the profile you're currently using!"
+ )
problem.setStandardButtons(QtWidgets.QMessageBox.StandardButton.Ok)
problem.exec()
return
@@ -949,22 +1097,29 @@ class PesterChooseProfile(QtWidgets.QDialog):
msgbox = QtWidgets.QMessageBox()
msgbox.setStyleSheet(self.theme["main/defaultwindow/style"])
msgbox.setWindowTitle("WARNING!")
- msgbox.setInformativeText("Are you sure you want to delete the profile: %s" % (handle))
- msgbox.setStandardButtons(QtWidgets.QMessageBox.StandardButton.Ok
- | QtWidgets.QMessageBox.StandardButton.Cancel)
+ msgbox.setInformativeText(
+ "Are you sure you want to delete the profile: %s" % (handle)
+ )
+ msgbox.setStandardButtons(
+ QtWidgets.QMessageBox.StandardButton.Ok
+ | QtWidgets.QMessageBox.StandardButton.Cancel
+ )
ret = msgbox.exec()
if ret == QtWidgets.QMessageBox.StandardButton.Ok:
try:
- remove(_datadir+"profiles/%s.js" % (handle))
+ remove(_datadir + "profiles/%s.js" % (handle))
except OSError:
problem = QtWidgets.QMessageBox()
problem.setObjectName("errmsg")
problem.setStyleSheet(self.theme["main/defaultwindow/style"])
problem.setWindowTitle("Problem!")
- problem.setInformativeText("There was a problem deleting the profile: %s" % (handle))
+ problem.setInformativeText(
+ "There was a problem deleting the profile: %s" % (handle)
+ )
problem.setStandardButtons(QtWidgets.QMessageBox.StandardButton.Ok)
problem.exec()
+
class PesterMentions(QtWidgets.QDialog):
def __init__(self, window, theme, parent):
QtWidgets.QDialog.__init__(self, parent)
@@ -1014,7 +1169,7 @@ class PesterMentions(QtWidgets.QDialog):
@QtCore.pyqtSlot()
def addMention(self, mitem=None):
- d = {"label": "Mention:", "inputname": "value" }
+ d = {"label": "Mention:", "inputname": "value"}
if mitem is not None:
d["value"] = str(mitem.text())
pdict = MultiTextDialog("ENTER MENTION", self, d).getText()
@@ -1039,6 +1194,7 @@ class PesterMentions(QtWidgets.QDialog):
if i >= 0:
self.mentionlist.takeItem(i)
+
class PesterOptions(QtWidgets.QDialog):
def __init__(self, config, theme, parent):
QtWidgets.QDialog.__init__(self, parent)
@@ -1059,16 +1215,19 @@ class PesterOptions(QtWidgets.QDialog):
self.tabs = QtWidgets.QButtonGroup(self)
self.tabs.buttonClicked.connect(self.changePage) # Verify working
- self.tabNames = ["Chum List",
- "Conversations",
- "Interface",
- "Sound",
- "Notifications",
- "Logging",
- "Idle/Updates",
- "Theme",
- "Connection"]
- if parent.advanced: self.tabNames.append("Advanced")
+ self.tabNames = [
+ "Chum List",
+ "Conversations",
+ "Interface",
+ "Sound",
+ "Notifications",
+ "Logging",
+ "Idle/Updates",
+ "Theme",
+ "Connection",
+ ]
+ if parent.advanced:
+ self.tabNames.append("Advanced")
for t in self.tabNames:
button = QtWidgets.QPushButton(t)
self.tabs.addButton(button)
@@ -1080,8 +1239,10 @@ class PesterOptions(QtWidgets.QDialog):
self.bandwidthcheck = QtWidgets.QCheckBox("Low Bandwidth", self)
if self.config.lowBandwidth():
self.bandwidthcheck.setChecked(True)
- bandwidthLabel = QtWidgets.QLabel("(Stops you for receiving the flood of MOODS,\n"
- " though stops chumlist from working properly)")
+ bandwidthLabel = QtWidgets.QLabel(
+ "(Stops you for receiving the flood of MOODS,\n"
+ " though stops chumlist from working properly)"
+ )
font = bandwidthLabel.font()
font.setPointSize(8)
bandwidthLabel.setFont(font)
@@ -1144,18 +1305,17 @@ class PesterOptions(QtWidgets.QDialog):
# Disable the volume slider if we can't actually use it.
if parent.canSetVolume():
self.currentVol = QtWidgets.QLabel(
- "{0!s}%".format(self.config.volume()), self)
+ "{0!s}%".format(self.config.volume()), self
+ )
# We don't need to explicitly set this, but it helps drive the
# point home
self.volume.setEnabled(True)
else:
# We can't set the volume....
- self.currentVol = QtWidgets.QLabel(
- "(Disabled: Sound Mixer Error)", self)
+ self.currentVol = QtWidgets.QLabel("(Disabled: Sound Mixer Error)", self)
self.volume.setEnabled(False)
self.currentVol.setAlignment(QtCore.Qt.AlignmentFlag.AlignHCenter)
-
self.timestampcheck = QtWidgets.QCheckBox("Time Stamps", self)
if self.config.showTimeStamps():
self.timestampcheck.setChecked(True)
@@ -1171,7 +1331,9 @@ class PesterOptions(QtWidgets.QDialog):
if self.config.showSeconds():
self.secondscheck.setChecked(True)
- self.memomessagecheck = QtWidgets.QCheckBox("Show OP and Voice Messages in Memos", self)
+ self.memomessagecheck = QtWidgets.QCheckBox(
+ "Show OP and Voice Messages in Memos", self
+ )
if self.config.opvoiceMessages():
self.memomessagecheck.setChecked(True)
@@ -1179,7 +1341,9 @@ class PesterOptions(QtWidgets.QDialog):
self.animationscheck = QtWidgets.QCheckBox("Use animated smilies", self)
if self.config.animations():
self.animationscheck.setChecked(True)
- animateLabel = QtWidgets.QLabel("(Disable if you leave chats open for LOOOONG periods of time)")
+ animateLabel = QtWidgets.QLabel(
+ "(Disable if you leave chats open for LOOOONG periods of time)"
+ )
font = animateLabel.font()
font.setPointSize(8)
animateLabel.setFont(font)
@@ -1188,13 +1352,14 @@ class PesterOptions(QtWidgets.QDialog):
self.userlinkscheck.setChecked(self.config.disableUserLinks())
self.userlinkscheck.setVisible(False)
-
# Will add ability to turn off groups later
- #self.groupscheck = QtGui.QCheckBox("Use Groups", self)
- #self.groupscheck.setChecked(self.config.useGroups())
+ # self.groupscheck = QtGui.QCheckBox("Use Groups", self)
+ # self.groupscheck.setChecked(self.config.useGroups())
self.showemptycheck = QtWidgets.QCheckBox("Show Empty Groups", self)
self.showemptycheck.setChecked(self.config.showEmptyGroups())
- self.showonlinenumbers = QtWidgets.QCheckBox("Show Number of Online Chums", self)
+ self.showonlinenumbers = QtWidgets.QCheckBox(
+ "Show Number of Online Chums", self
+ )
self.showonlinenumbers.setChecked(self.config.showOnlineNumbers())
sortLabel = QtWidgets.QLabel("Sort Chums")
@@ -1230,19 +1395,19 @@ class PesterOptions(QtWidgets.QDialog):
layout_5.addWidget(QtWidgets.QLabel("Minutes before Idle:"))
layout_5.addWidget(self.idleBox)
- #self.updateBox = QtWidgets.QComboBox(self)
- #self.updateBox.addItem("Once a Day")
- #self.updateBox.addItem("Once a Week")
- #self.updateBox.addItem("Only on Start")
- #self.updateBox.addItem("Never")
- #check = self.config.checkForUpdates()
- #if check >= 0 and check < self.updateBox.count():
+ # self.updateBox = QtWidgets.QComboBox(self)
+ # self.updateBox.addItem("Once a Day")
+ # self.updateBox.addItem("Once a Week")
+ # self.updateBox.addItem("Only on Start")
+ # self.updateBox.addItem("Never")
+ # check = self.config.checkForUpdates()
+ # if check >= 0 and check < self.updateBox.count():
# self.updateBox.setCurrentIndex(check)
layout_6 = QtWidgets.QHBoxLayout()
- #layout_6.addWidget(QtWidgets.QLabel("Check for\nPesterchum Updates:"))
- #layout_6.addWidget(self.updateBox)
+ # layout_6.addWidget(QtWidgets.QLabel("Check for\nPesterchum Updates:"))
+ # layout_6.addWidget(self.updateBox)
- #if not ostools.isOSXLeopard():
+ # if not ostools.isOSXLeopard():
# self.mspaCheck = QtWidgets.QCheckBox("Check for MSPA Updates", self)
# self.mspaCheck.setChecked(self.config.checkMSPA())
@@ -1253,7 +1418,7 @@ class PesterOptions(QtWidgets.QDialog):
avail_themes = self.config.availableThemes()
self.themeBox = QtWidgets.QComboBox(self)
- notheme = (theme.name not in avail_themes)
+ notheme = theme.name not in avail_themes
for (i, t) in enumerate(avail_themes):
self.themeBox.addItem(t)
if (not notheme and t == theme.name) or (notheme and t == "pesterchum"):
@@ -1292,7 +1457,7 @@ class PesterOptions(QtWidgets.QDialog):
types = self.parent().tm.availableTypes()
cur = self.parent().tm.currentType()
self.notifyOptions.addItems(types)
- for (i,t) in enumerate(types):
+ for (i, t) in enumerate(types):
if t == cur:
self.notifyOptions.setCurrentIndex(i)
break
@@ -1300,13 +1465,13 @@ class PesterOptions(QtWidgets.QDialog):
layout_type = QtWidgets.QHBoxLayout()
layout_type.addWidget(self.notifyTypeLabel)
layout_type.addWidget(self.notifyOptions)
- self.notifySigninCheck = QtWidgets.QCheckBox("Chum signs in", self)
+ self.notifySigninCheck = QtWidgets.QCheckBox("Chum signs in", self)
if self.config.notifyOptions() & self.config.SIGNIN:
self.notifySigninCheck.setChecked(True)
- self.notifySignoutCheck = QtWidgets.QCheckBox("Chum signs out", self)
+ self.notifySignoutCheck = QtWidgets.QCheckBox("Chum signs out", self)
if self.config.notifyOptions() & self.config.SIGNOUT:
self.notifySignoutCheck.setChecked(True)
- self.notifyNewMsgCheck = QtWidgets.QCheckBox("New messages", self)
+ self.notifyNewMsgCheck = QtWidgets.QCheckBox("New messages", self)
if self.config.notifyOptions() & self.config.NEWMSG:
self.notifyNewMsgCheck.setChecked(True)
self.notifyNewConvoCheck = QtWidgets.QCheckBox("Only new conversations", self)
@@ -1339,7 +1504,7 @@ class PesterOptions(QtWidgets.QDialog):
layout_chumlist = QtWidgets.QVBoxLayout(widget)
layout_chumlist.setAlignment(QtCore.Qt.AlignmentFlag.AlignTop)
layout_chumlist.addWidget(self.hideOffline)
- #layout_chumlist.addWidget(self.groupscheck)
+ # layout_chumlist.addWidget(self.groupscheck)
layout_chumlist.addWidget(self.showemptycheck)
layout_chumlist.addWidget(self.showonlinenumbers)
layout_chumlist.addLayout(layout_3)
@@ -1358,9 +1523,9 @@ class PesterOptions(QtWidgets.QDialog):
layout_chat.addWidget(animateLabel)
layout_chat.addWidget(self.randomscheck)
# Re-enable these when it's possible to disable User and Memo links
- #layout_chat.addWidget(hr)
- #layout_chat.addWidget(QtGui.QLabel("User and Memo Links"))
- #layout_chat.addWidget(self.userlinkscheck)
+ # layout_chat.addWidget(hr)
+ # layout_chat.addWidget(QtGui.QLabel("User and Memo Links"))
+ # layout_chat.addWidget(self.userlinkscheck)
self.pages.addWidget(widget)
# Interface
@@ -1387,14 +1552,14 @@ class PesterOptions(QtWidgets.QDialog):
layout_doubleindent.addWidget(self.memopingcheck)
layout_doubleindent.addWidget(self.namesoundcheck)
layout_doubleindent.addWidget(self.editMentions)
- layout_doubleindent.setContentsMargins(22,0,0,0)
+ layout_doubleindent.setContentsMargins(22, 0, 0, 0)
layout_indent.addLayout(layout_doubleindent)
- layout_indent.setContentsMargins(22,0,0,0)
+ layout_indent.setContentsMargins(22, 0, 0, 0)
layout_sound.addLayout(layout_indent)
layout_sound.addSpacing(15)
mvol = QtWidgets.QLabel("Master Volume:", self)
# If we can't set the volume, grey this out as well
- #~mvol.setEnabled(parent.canSetVolume())
+ # ~mvol.setEnabled(parent.canSetVolume())
# Normally we'd grey this out, but that presently makes things
# rather unreadable
# Later we can look into changing the color to a theme[] entry
@@ -1410,13 +1575,13 @@ class PesterOptions(QtWidgets.QDialog):
layout_notify.addWidget(self.notifycheck)
layout_indent = QtWidgets.QVBoxLayout()
layout_indent.addLayout(layout_type)
- layout_indent.setContentsMargins(22,0,0,0)
+ layout_indent.setContentsMargins(22, 0, 0, 0)
layout_indent.addWidget(self.notifySigninCheck)
layout_indent.addWidget(self.notifySignoutCheck)
layout_indent.addWidget(self.notifyNewMsgCheck)
layout_doubleindent = QtWidgets.QVBoxLayout()
layout_doubleindent.addWidget(self.notifyNewConvoCheck)
- layout_doubleindent.setContentsMargins(22,0,0,0)
+ layout_doubleindent.setContentsMargins(22, 0, 0, 0)
layout_indent.addLayout(layout_doubleindent)
layout_indent.addWidget(self.notifyMentionsCheck)
layout_indent.addWidget(self.editMentions2)
@@ -1439,7 +1604,7 @@ class PesterOptions(QtWidgets.QDialog):
layout_idle.setAlignment(QtCore.Qt.AlignmentFlag.AlignTop)
layout_idle.addLayout(layout_5)
layout_idle.addLayout(layout_6)
- #if not ostools.isOSXLeopard():
+ # if not ostools.isOSXLeopard():
# layout_idle.addWidget(self.mspaCheck)
self.pages.addWidget(widget)
@@ -1462,7 +1627,7 @@ class PesterOptions(QtWidgets.QDialog):
layout_connect.addWidget(self.autonickserv)
layout_indent = QtWidgets.QVBoxLayout()
layout_indent.addWidget(self.nickservpass)
- layout_indent.setContentsMargins(22,0,0,0)
+ layout_indent.setContentsMargins(22, 0, 0, 0)
layout_connect.addLayout(layout_indent)
layout_connect.addWidget(QtWidgets.QLabel("Auto-Join Memos:"))
layout_connect.addWidget(self.autojoinlist)
@@ -1477,7 +1642,9 @@ class PesterOptions(QtWidgets.QDialog):
widget = QtWidgets.QWidget()
layout_advanced = QtWidgets.QVBoxLayout(widget)
layout_advanced.setAlignment(QtCore.Qt.AlignmentFlag.AlignTop)
- layout_advanced.addWidget(QtWidgets.QLabel("Current User Mode: %s" % parent.modes))
+ layout_advanced.addWidget(
+ QtWidgets.QLabel("Current User Mode: %s" % parent.modes)
+ )
layout_advanced.addLayout(layout_change)
self.pages.addWidget(widget)
@@ -1521,7 +1688,7 @@ class PesterOptions(QtWidgets.QDialog):
@QtCore.pyqtSlot()
def addAutoJoin(self, mitem=None):
- d = {"label": "Memo:", "inputname": "value" }
+ d = {"label": "Memo:", "inputname": "value"}
if mitem is not None:
d["value"] = str(mitem.text())
pdict = MultiTextDialog("ENTER MEMO", self, d).getText()
@@ -1529,8 +1696,9 @@ class PesterOptions(QtWidgets.QDialog):
return
pdict["value"] = "#" + pdict["value"]
if mitem is None:
- items = self.autojoinlist.findItems(pdict["value"],
- QtCore.Qt.MatchFlag.MatchFixedString)
+ items = self.autojoinlist.findItems(
+ pdict["value"], QtCore.Qt.MatchFlag.MatchFixedString
+ )
if len(items) == 0:
self.autojoinlist.addItem(pdict["value"])
else:
@@ -1553,6 +1721,7 @@ class PesterOptions(QtWidgets.QDialog):
self.memosoundcheck.setEnabled(True)
if self.memosoundcheck.isChecked():
self.memoSoundChange(1)
+
@QtCore.pyqtSlot(int)
def memoSoundChange(self, state):
if state == 0:
@@ -1561,13 +1730,14 @@ class PesterOptions(QtWidgets.QDialog):
else:
self.memopingcheck.setEnabled(True)
self.namesoundcheck.setEnabled(True)
+
@QtCore.pyqtSlot(int)
def printValue(self, v):
- self.currentVol.setText(str(v)+"%")
+ self.currentVol.setText(str(v) + "%")
@QtCore.pyqtSlot()
def openMentions(self):
- if not hasattr(self, 'mentionmenu'):
+ if not hasattr(self, "mentionmenu"):
self.mentionmenu = None
if not self.mentionmenu:
self.mentionmenu = PesterMentions(self.parent(), self.theme, self)
@@ -1576,10 +1746,12 @@ class PesterOptions(QtWidgets.QDialog):
self.mentionmenu.show()
self.mentionmenu.raise_()
self.mentionmenu.activateWindow()
+
@QtCore.pyqtSlot()
def closeMentions(self):
self.mentionmenu.close()
self.mentionmenu = None
+
@QtCore.pyqtSlot()
def updateMentions(self):
m = []
@@ -1588,6 +1760,7 @@ class PesterOptions(QtWidgets.QDialog):
self.parent().userprofile.setMentions(m)
self.mentionmenu = None
+
class PesterUserlist(QtWidgets.QDialog):
def __init__(self, config, theme, parent):
QtWidgets.QDialog.__init__(self, parent)
@@ -1599,18 +1772,22 @@ class PesterUserlist(QtWidgets.QDialog):
self.resize(200, 600)
self.searchbox = QtWidgets.QLineEdit(self)
- #self.searchbox.setStyleSheet(theme["convo/input/style"]) # which style is better?
+ # self.searchbox.setStyleSheet(theme["convo/input/style"]) # which style is better?
self.searchbox.setPlaceholderText("Search")
- self.searchbox.textChanged['QString'].connect(self.updateUsers)
+ self.searchbox.textChanged["QString"].connect(self.updateUsers)
self.label = QtWidgets.QLabel("USERLIST")
self.userarea = RightClickList(self)
self.userarea.setStyleSheet(self.theme["main/chums/style"])
self.userarea.optionsMenu = QtWidgets.QMenu(self)
- self.addChumAction = QAction(self.mainwindow.theme["main/menus/rclickchumlist/addchum"], self)
+ self.addChumAction = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/addchum"], self
+ )
self.addChumAction.triggered.connect(self.addChumSlot)
- self.pesterChumAction = QAction(self.mainwindow.theme["main/menus/rclickchumlist/pester"], self)
+ self.pesterChumAction = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/pester"], self
+ )
self.pesterChumAction.triggered.connect(self.pesterChumSlot)
self.userarea.optionsMenu.addAction(self.addChumAction)
self.userarea.optionsMenu.addAction(self.pesterChumAction)
@@ -1629,10 +1806,13 @@ class PesterUserlist(QtWidgets.QDialog):
self.mainwindow.namesUpdated.connect(self.updateUsers)
- self.mainwindow.userPresentSignal['QString', 'QString', 'QString'].connect(self.updateUserPresent)
+ self.mainwindow.userPresentSignal["QString", "QString", "QString"].connect(
+ self.updateUserPresent
+ )
self.updateUsers()
self.searchbox.setFocus()
+
@QtCore.pyqtSlot()
def updateUsers(self):
try:
@@ -1642,13 +1822,19 @@ class PesterUserlist(QtWidgets.QDialog):
return
self.userarea.clear()
for n in names:
- if str(self.searchbox.text()) == "" or n.lower().find(str(self.searchbox.text()).lower()) != -1:
+ if (
+ str(self.searchbox.text()) == ""
+ or n.lower().find(str(self.searchbox.text()).lower()) != -1
+ ):
# Strip channel membership prefixes
- n = n.strip('~').strip('@').strip('+').strip('&').strip('%')
+ n = n.strip("~").strip("@").strip("+").strip("&").strip("%")
item = QtWidgets.QListWidgetItem(n)
- item.setForeground(QtGui.QBrush(QtGui.QColor(self.theme["main/chums/userlistcolor"])))
+ item.setForeground(
+ QtGui.QBrush(QtGui.QColor(self.theme["main/chums/userlistcolor"]))
+ )
self.userarea.addItem(item)
self.userarea.sortItems()
+
@QtCore.pyqtSlot(QString, QString, QString)
def updateUserPresent(self, handle, channel, update):
h = str(handle)
@@ -1658,13 +1844,20 @@ class PesterUserlist(QtWidgets.QDialog):
elif update == "left" and c == "#pesterchum":
self.delUser(h)
elif update == "join" and c == "#pesterchum":
- if str(self.searchbox.text()) == "" or h.lower().find(str(self.searchbox.text()).lower()) != -1:
+ if (
+ str(self.searchbox.text()) == ""
+ or h.lower().find(str(self.searchbox.text()).lower()) != -1
+ ):
self.addUser(h)
+
def addUser(self, name):
item = QtWidgets.QListWidgetItem(name)
- item.setForeground(QtGui.QBrush(QtGui.QColor(self.theme["main/chums/userlistcolor"])))
+ item.setForeground(
+ QtGui.QBrush(QtGui.QColor(self.theme["main/chums/userlistcolor"]))
+ )
self.userarea.addItem(item)
self.userarea.sortItems()
+
def delUser(self, name):
matches = self.userarea.findItems(name, QtCore.Qt.MatchFlag.MatchExactly)
for m in matches:
@@ -1676,7 +1869,9 @@ class PesterUserlist(QtWidgets.QDialog):
self.userarea.setStyleSheet(theme["main/chums/style"])
self.addChumAction.setText(theme["main/menus/rclickchumlist/addchum"])
for item in [self.userarea.item(i) for i in range(0, self.userarea.count())]:
- item.setForeground(0, QtGui.QBrush(QtGui.QColor(theme["main/chums/userlistcolor"])))
+ item.setForeground(
+ 0, QtGui.QBrush(QtGui.QColor(theme["main/chums/userlistcolor"]))
+ )
@QtCore.pyqtSlot()
def addChumSlot(self):
@@ -1684,6 +1879,7 @@ class PesterUserlist(QtWidgets.QDialog):
if not cur:
return
self.addChum.emit(cur.text())
+
@QtCore.pyqtSlot()
def pesterChumSlot(self):
cur = self.userarea.currentItem()
@@ -1691,20 +1887,22 @@ class PesterUserlist(QtWidgets.QDialog):
return
self.pesterChum.emit(cur.text())
- addChum = QtCore.pyqtSignal('QString')
- pesterChum = QtCore.pyqtSignal('QString')
+ addChum = QtCore.pyqtSignal("QString")
+ pesterChum = QtCore.pyqtSignal("QString")
class MemoListItem(QtWidgets.QTreeWidgetItem):
def __init__(self, channel, usercount):
QtWidgets.QTreeWidgetItem.__init__(self, [channel, str(usercount)])
self.target = channel
+
def __lt__(self, other):
column = self.treeWidget().sortColumn()
if str(self.text(column)).isdigit() and str(other.text(column)).isdigit():
return int(self.text(column)) < int(other.text(column))
return self.text(column) < other.text(column)
+
class PesterMemoList(QtWidgets.QDialog):
def __init__(self, parent, channel=""):
QtWidgets.QDialog.__init__(self, parent)
@@ -1716,17 +1914,21 @@ class PesterMemoList(QtWidgets.QDialog):
self.label = QtWidgets.QLabel("MEMOS")
self.channelarea = RightClickTree(self)
- self.channelarea.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.ExtendedSelection)
+ self.channelarea.setSelectionMode(
+ QtWidgets.QAbstractItemView.SelectionMode.ExtendedSelection
+ )
self.channelarea.setStyleSheet(self.theme["main/chums/style"])
self.channelarea.optionsMenu = QtWidgets.QMenu(self)
self.channelarea.setColumnCount(2)
self.channelarea.setHeaderLabels(["Memo", "Users"])
self.channelarea.setIndentation(0)
- self.channelarea.setColumnWidth(0,200)
- self.channelarea.setColumnWidth(1,10)
+ self.channelarea.setColumnWidth(0, 200)
+ self.channelarea.setColumnWidth(1, 10)
self.channelarea.setSortingEnabled(True)
self.channelarea.sortByColumn(0, QtCore.Qt.SortOrder.AscendingOrder)
- self.channelarea.itemDoubleClicked[QtWidgets.QTreeWidgetItem, int].connect(self.AcceptSelection)
+ self.channelarea.itemDoubleClicked[QtWidgets.QTreeWidgetItem, int].connect(
+ self.AcceptSelection
+ )
self.orjoinlabel = QtWidgets.QLabel("OR MAKE A NEW MEMO:")
self.newmemo = QtWidgets.QLineEdit(channel, self)
@@ -1746,7 +1948,7 @@ class PesterMemoList(QtWidgets.QDialog):
layout_ok.addWidget(self.cancel)
layout_ok.addWidget(self.join)
- layout_left = QtWidgets.QVBoxLayout()
+ layout_left = QtWidgets.QVBoxLayout()
layout_right = QtWidgets.QVBoxLayout()
layout_right.setAlignment(QtCore.Qt.AlignmentFlag.AlignTop)
layout_0 = QtWidgets.QVBoxLayout()
@@ -1778,9 +1980,13 @@ class PesterMemoList(QtWidgets.QDialog):
def updateChannels(self, channels):
for c in channels:
- item = MemoListItem(c[0][1:],c[1])
- item.setForeground(0, QtGui.QBrush(QtGui.QColor(self.theme["main/chums/userlistcolor"])))
- item.setForeground(1, QtGui.QBrush(QtGui.QColor(self.theme["main/chums/userlistcolor"])))
+ item = MemoListItem(c[0][1:], c[1])
+ item.setForeground(
+ 0, QtGui.QBrush(QtGui.QColor(self.theme["main/chums/userlistcolor"]))
+ )
+ item.setForeground(
+ 1, QtGui.QBrush(QtGui.QColor(self.theme["main/chums/userlistcolor"]))
+ )
item.setIcon(0, QtGui.QIcon(self.theme["memos/memoicon"]))
self.channelarea.addTopLevelItem(item)
@@ -1788,7 +1994,9 @@ class PesterMemoList(QtWidgets.QDialog):
self.theme = theme
self.setStyleSheet(theme["main/defaultwindow/style"])
for item in [self.userarea.item(i) for i in range(0, self.channelarea.count())]:
- item.setForeground(0, QtGui.QBrush(QtGui.QColor(theme["main/chums/userlistcolor"])))
+ item.setForeground(
+ 0, QtGui.QBrush(QtGui.QColor(theme["main/chums/userlistcolor"]))
+ )
item.setIcon(QtGui.QIcon(theme["memos/memoicon"]))
@QtCore.pyqtSlot()
@@ -1805,18 +2013,20 @@ class LoadingScreen(QtWidgets.QDialog):
tryAgain = QtCore.pyqtSignal()
def __init__(self, parent=None):
- QtWidgets.QDialog.__init__(self,
- parent,
- QtCore.Qt.WindowType.CustomizeWindowHint
- | QtCore.Qt.WindowType.FramelessWindowHint)
+ QtWidgets.QDialog.__init__(
+ self,
+ parent,
+ QtCore.Qt.WindowType.CustomizeWindowHint
+ | QtCore.Qt.WindowType.FramelessWindowHint,
+ )
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.setWindowModality(QtCore.Qt.WindowModality.NonModal) # useless
+ # self.setAttribute(QtCore.Qt.WidgetAttribute.WA_DeleteOnClose) # useless
self.loadinglabel = QtWidgets.QLabel("CONN3CT1NG", self)
- #self.loadinglabel.setTextFormat(QtCore.Qt.TextFormat.RichText) # Clickable html links
- #self.loadinglabel.setWordWrap(True) # Unusable because of QT clipping bug (QTBUG-92381)
+ # self.loadinglabel.setTextFormat(QtCore.Qt.TextFormat.RichText) # Clickable html links
+ # self.loadinglabel.setWordWrap(True) # Unusable because of QT clipping bug (QTBUG-92381)
self.cancel = QtWidgets.QPushButton("QU1T >:?", self)
self.ok = QtWidgets.QPushButton("R3CONN3CT >:]", self)
# Help reduce the number of accidental Pesterchum closures... :|
@@ -1824,7 +2034,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.finished.connect(self.finishedEvent)
self.layout = QtWidgets.QVBoxLayout()
self.layout.addWidget(self.loadinglabel)
@@ -1838,8 +2048,8 @@ class LoadingScreen(QtWidgets.QDialog):
self.ok.setDefault(True)
self.ok.setFocus()
self.timer = None
-
- #def finishedEvent(self, result):
+
+ # def finishedEvent(self, result):
# self.close()
def hideReconnect(self, safe=True):
@@ -1859,6 +2069,7 @@ class LoadingScreen(QtWidgets.QDialog):
def enableQuit(self):
self.cancel.setEnabled(True)
+
class AboutPesterchum(QtWidgets.QDialog):
def __init__(self, parent=None):
QtWidgets.QDialog.__init__(self, parent)
@@ -1866,26 +2077,28 @@ class AboutPesterchum(QtWidgets.QDialog):
self.setStyleSheet(self.mainwindow.theme["main/defaultwindow/style"])
self.title = QtWidgets.QLabel("P3ST3RCHUM %s" % (_pcVersion))
- self.credits = QtWidgets.QLabel("Programming by:"
- "\n illuminatedwax (ghostDunk)"
- "\n Kiooeht (evacipatedBox)"
- "\n Lexi (lexicalNuance)"
- "\n oakwhiz"
- "\n alGore"
- "\n Cerxi (binaryCabalist)"
- "\n Arcane (arcaneAgilmente)"
- "\n karxi (Midna)"
- "\n Shou/Dpeta 🐱"
- "\n"
- "\nArt by:"
- "\n Grimlive (aquaMarinist)"
- "\n Cerxi (binaryCabalist)"
- "\n cubicSimulation"
- "\n"
- "\nSpecial Thanks:"
- "\n ABT"
- "\n gamblingGenocider"
- "\n Eco-Mono")
+ self.credits = QtWidgets.QLabel(
+ "Programming by:"
+ "\n illuminatedwax (ghostDunk)"
+ "\n Kiooeht (evacipatedBox)"
+ "\n Lexi (lexicalNuance)"
+ "\n oakwhiz"
+ "\n alGore"
+ "\n Cerxi (binaryCabalist)"
+ "\n Arcane (arcaneAgilmente)"
+ "\n karxi (Midna)"
+ "\n Shou/Dpeta 🐱"
+ "\n"
+ "\nArt by:"
+ "\n Grimlive (aquaMarinist)"
+ "\n Cerxi (binaryCabalist)"
+ "\n cubicSimulation"
+ "\n"
+ "\nSpecial Thanks:"
+ "\n ABT"
+ "\n gamblingGenocider"
+ "\n Eco-Mono"
+ )
self.ok = QtWidgets.QPushButton("OK", self)
self.ok.clicked.connect(self.reject)
@@ -1897,6 +2110,7 @@ class AboutPesterchum(QtWidgets.QDialog):
self.setLayout(layout_0)
+
class UpdatePesterchum(QtWidgets.QDialog):
def __init__(self, ver, url, parent=None):
QtWidgets.QDialog.__init__(self, parent)
@@ -1924,6 +2138,7 @@ class UpdatePesterchum(QtWidgets.QDialog):
self.setLayout(layout_0)
+
class AddChumDialog(QtWidgets.QDialog):
def __init__(self, avail_groups, parent=None):
QtWidgets.QDialog.__init__(self, parent)
diff --git a/mispeller.py b/mispeller.py
index 5b1cb28..5e38b2f 100644
--- a/mispeller.py
+++ b/mispeller.py
@@ -1,29 +1,55 @@
import random
-kbloc = [[x for x in "1234567890-="],
- [x for x in "qwertyuiop[]"],
- [x for x in "asdfghjkl:;'"],
- [x for x in "zxcvbnm,.>/?"]]
+kbloc = [
+ [x for x in "1234567890-="],
+ [x for x in "qwertyuiop[]"],
+ [x for x in "asdfghjkl:;'"],
+ [x for x in "zxcvbnm,.>/?"],
+]
kbdict = {}
for (i, l) in enumerate(kbloc):
for (j, k) in enumerate(l):
kbdict[k] = (i, j)
-sounddict = {"a": "e", "b": "d", "c": "k", "d": "g", "e": "eh",
- "f": "ph", "g": "j", "h": "h", "i": "ai", "j": "ge",
- "k": "c", "l": "ll", "m": "n", "n": "m", "o": "oa",
- "p": "b", "q": "kw", "r": "ar", "s": "ss", "t": "d",
- "u": "you", "v": "w", "w": "wn", "x": "cks", "y": "uy", "z": "s"}
-
+sounddict = {
+ "a": "e",
+ "b": "d",
+ "c": "k",
+ "d": "g",
+ "e": "eh",
+ "f": "ph",
+ "g": "j",
+ "h": "h",
+ "i": "ai",
+ "j": "ge",
+ "k": "c",
+ "l": "ll",
+ "m": "n",
+ "n": "m",
+ "o": "oa",
+ "p": "b",
+ "q": "kw",
+ "r": "ar",
+ "s": "ss",
+ "t": "d",
+ "u": "you",
+ "v": "w",
+ "w": "wn",
+ "x": "cks",
+ "y": "uy",
+ "z": "s",
+}
+
def mispeller(word):
if len(word) <= 6:
num = 1
else:
- num = random.choice([1,2])
+ num = random.choice([1, 2])
wordseq = list(range(0, len(word)))
random.shuffle(wordseq)
letters = wordseq[0:num]
+
def mistype(string, i):
l = string[i]
if l not in kbdict:
@@ -31,30 +57,42 @@ def mispeller(word):
lpos = kbdict[l]
newpos = lpos
while newpos == lpos:
- newpos = ((lpos[0] + random.choice([-1, 0, 1])) % len(kbloc),
- (lpos[1] + random.choice([-1,0,1])) % len(kbloc[0]))
- string = string[0:i]+kbloc[newpos[0]][newpos[1]]+string[i+1:]
+ newpos = (
+ (lpos[0] + random.choice([-1, 0, 1])) % len(kbloc),
+ (lpos[1] + random.choice([-1, 0, 1])) % len(kbloc[0]),
+ )
+ string = string[0:i] + kbloc[newpos[0]][newpos[1]] + string[i + 1 :]
return string
+
def transpose(string, i):
- j = (i + random.choice([-1,1])) % len(string)
+ j = (i + random.choice([-1, 1])) % len(string)
l = [c for c in string]
l[i], l[j] = l[j], l[i]
return "".join(l)
+
def randomletter(string, i):
- string = string[0:i+1]+random.choice("abcdefghijklmnopqrstuvwxyz")+string[i+1:]
+ string = (
+ string[0 : i + 1]
+ + random.choice("abcdefghijklmnopqrstuvwxyz")
+ + string[i + 1 :]
+ )
return string
+
def randomreplace(string, i):
- string = string[0:i]+random.choice("abcdefghijklmnopqrstuvwxyz")+string[i+1:]
+ string = (
+ string[0:i] + random.choice("abcdefghijklmnopqrstuvwxyz") + string[i + 1 :]
+ )
return string
+
def soundalike(string, i):
try:
c = sounddict[string[i]]
except:
return string
- string = string[0:i]+c+string[i+1:]
+ string = string[0:i] + c + string[i + 1 :]
return string
- func = random.choice([mistype, transpose, randomletter, randomreplace,
- soundalike])
+
+ func = random.choice([mistype, transpose, randomletter, randomreplace, soundalike])
for i in letters:
word = func(word, i)
return word
diff --git a/mood.py b/mood.py
index e5c05dc..e6de84d 100644
--- a/mood.py
+++ b/mood.py
@@ -6,28 +6,76 @@ except ImportError:
from generic import PesterIcon
+
class Mood(object):
- moods = ["chummy", "rancorous", "offline", "pleasant", "distraught",
- "pranky", "smooth", "ecstatic", "relaxed", "discontent",
- "devious", "sleek", "detestful", "mirthful", "manipulative",
- "vigorous", "perky", "acceptant", "protective", "mystified",
- "amazed", "insolent", "bemused" ]
+ moods = [
+ "chummy",
+ "rancorous",
+ "offline",
+ "pleasant",
+ "distraught",
+ "pranky",
+ "smooth",
+ "ecstatic",
+ "relaxed",
+ "discontent",
+ "devious",
+ "sleek",
+ "detestful",
+ "mirthful",
+ "manipulative",
+ "vigorous",
+ "perky",
+ "acceptant",
+ "protective",
+ "mystified",
+ "amazed",
+ "insolent",
+ "bemused",
+ ]
moodcats = ["chums", "trolls", "other"]
- revmoodcats = {'discontent': 'trolls', 'insolent': 'chums', 'rancorous': 'chums', 'sleek': 'trolls', 'bemused': 'chums', 'mystified': 'chums', 'pranky': 'chums', 'distraught': 'chums', 'offline': 'chums', 'chummy': 'chums', 'protective': 'other', 'vigorous': 'trolls', 'ecstatic': 'trolls', 'relaxed': 'trolls', 'pleasant': 'chums', 'manipulative': 'trolls', 'detestful': 'trolls', 'smooth': 'chums', 'mirthful': 'trolls', 'acceptant': 'trolls', 'perky': 'trolls', 'devious': 'trolls', 'amazed': 'chums'}
+ revmoodcats = {
+ "discontent": "trolls",
+ "insolent": "chums",
+ "rancorous": "chums",
+ "sleek": "trolls",
+ "bemused": "chums",
+ "mystified": "chums",
+ "pranky": "chums",
+ "distraught": "chums",
+ "offline": "chums",
+ "chummy": "chums",
+ "protective": "other",
+ "vigorous": "trolls",
+ "ecstatic": "trolls",
+ "relaxed": "trolls",
+ "pleasant": "chums",
+ "manipulative": "trolls",
+ "detestful": "trolls",
+ "smooth": "chums",
+ "mirthful": "trolls",
+ "acceptant": "trolls",
+ "perky": "trolls",
+ "devious": "trolls",
+ "amazed": "chums",
+ }
def __init__(self, mood):
if type(mood) is int:
self.mood = mood
else:
self.mood = self.moods.index(mood)
+
def value(self):
return self.mood
+
def name(self):
try:
name = self.moods[self.mood]
except IndexError:
name = "chummy"
return name
+
def icon(self, theme):
try:
f = theme["main/chums/moods"][self.name()]["icon"]
@@ -35,15 +83,18 @@ class Mood(object):
return PesterIcon(theme["main/chums/moods/chummy/icon"])
return PesterIcon(f)
+
class PesterMoodAction(QtCore.QObject):
def __init__(self, m, func):
QtCore.QObject.__init__(self)
self.mood = m
self.func = func
+
@QtCore.pyqtSlot()
def updateMood(self):
self.func(self.mood)
+
class PesterMoodHandler(QtCore.QObject):
def __init__(self, parent, *buttons):
QtCore.QObject.__init__(self)
@@ -55,13 +106,16 @@ class PesterMoodHandler(QtCore.QObject):
b.setSelected(True)
b.clicked.connect(b.updateMood)
b.moodUpdated[int].connect(self.updateMood)
+
def removeButtons(self):
for b in list(self.buttons.values()):
b.close()
+
def showButtons(self):
for b in list(self.buttons.values()):
b.show()
b.raise_()
+
@QtCore.pyqtSlot(int)
def updateMood(self, m):
# update MY mood
@@ -81,12 +135,15 @@ class PesterMoodHandler(QtCore.QObject):
self.mainwindow.userprofile.setLastMood(newmood)
if self.mainwindow.currentMoodIcon:
moodicon = newmood.icon(self.mainwindow.theme)
- self.mainwindow.currentMoodIcon.setPixmap(moodicon.pixmap(moodicon.realsize()))
+ self.mainwindow.currentMoodIcon.setPixmap(
+ moodicon.pixmap(moodicon.realsize())
+ )
if oldmood.name() != newmood.name():
for c in list(self.mainwindow.convos.values()):
c.myUpdateMood(newmood)
self.mainwindow.moodUpdated.emit()
+
class PesterMoodButton(QtWidgets.QPushButton):
def __init__(self, parent, **options):
icon = PesterIcon(options["icon"])
@@ -100,13 +157,16 @@ class PesterMoodButton(QtWidgets.QPushButton):
self.setStyleSheet(self.unselectedSheet)
self.mainwindow = parent
self.mood = Mood(options["mood"])
+
def setSelected(self, selected):
if selected:
self.setStyleSheet(self.selectedSheet)
else:
self.setStyleSheet(self.unselectedSheet)
+
@QtCore.pyqtSlot()
def updateMood(self):
# updates OUR mood
self.moodUpdated.emit(self.mood.value())
+
moodUpdated = QtCore.pyqtSignal(int)
diff --git a/nickservmsgs.py b/nickservmsgs.py
index f03709f..94ed4ab 100644
--- a/nickservmsgs.py
+++ b/nickservmsgs.py
@@ -1,16 +1,13 @@
# Hardcoded messages that NickServ sends and what to display to the user instead
messages = {
- "Your nick isn't registered.":
- "", # display the same
- "Password accepted - you are now recognized.":
- "", # display the same
- "If you do not change within one minute, I will change your nick.":
- "You have 1 minute to identify.",
- "If you do not change within 20 seconds, I will change your nick.":
- "You have 20 seconds to identify."
+ "Your nick isn't registered.": "", # display the same
+ "Password accepted - you are now recognized.": "", # display the same
+ "If you do not change within one minute, I will change your nick.": "You have 1 minute to identify.",
+ "If you do not change within 20 seconds, I will change your nick.": "You have 20 seconds to identify.",
}
+
def translate(msg):
if msg in messages:
if messages[msg] == "":
diff --git a/ostools.py b/ostools.py
index 1a2e5b3..73a3f52 100644
--- a/ostools.py
+++ b/ostools.py
@@ -1,37 +1,44 @@
import os
import sys
import platform
-
+
try:
from PyQt6.QtCore import QStandardPaths
except ImportError:
print("PyQt5 fallback (ostools.py)")
from PyQt5.QtCore import QStandardPaths
+
def isOSX():
return sys.platform == "darwin"
+
def isWin32():
return sys.platform == "win32"
+
def isLinux():
return sys.platform.startswith("linux")
+
def isOSXBundle():
- return isOSX() and (os.path.abspath('.').find(".app") != -1)
+ return isOSX() and (os.path.abspath(".").find(".app") != -1)
+
def isOSXLeopard():
return isOSX() and platform.mac_ver()[0].startswith("10.5")
+
def osVer():
if isWin32():
return " ".join(platform.win32_ver())
elif isOSX():
- ver = platform.mac_ver();
+ ver = platform.mac_ver()
return " ".join((ver[0], " (", ver[2], ")"))
elif isLinux():
return " ".join(platform.linux_distribution())
+
def validateDataDir():
"""Checks if data directory is present"""
# Define paths
@@ -42,7 +49,7 @@ def validateDataDir():
errorlogs = os.path.join(datadir, "errorlogs")
backup = os.path.join(datadir, "backup")
js_pchum = os.path.join(datadir, "pesterchum.js")
-
+
dirs = [datadir, profile, quirks, logs, errorlogs, backup]
for d in dirs:
if (os.path.isdir(d) == False) or (os.path.exists(d) == False):
@@ -50,20 +57,36 @@ def validateDataDir():
# pesterchum.js
if not os.path.exists(js_pchum):
- with open(js_pchum, 'w') as f:
+ with open(js_pchum, "w") as f:
f.write("{}")
+
def getDataDir():
# Temporary fix for non-ascii usernames
# If username has non-ascii characters, just store userdata
# in the Pesterchum install directory (like before)
try:
if isOSX():
- return os.path.join(QStandardPaths.writableLocation(QStandardPaths.StandardLocation.AppLocalDataLocation), "Pesterchum/")
+ return os.path.join(
+ QStandardPaths.writableLocation(
+ QStandardPaths.StandardLocation.AppLocalDataLocation
+ ),
+ "Pesterchum/",
+ )
elif isLinux():
- return os.path.join(QStandardPaths.writableLocation(QStandardPaths.StandardLocation.HomeLocation), ".pesterchum/")
+ return os.path.join(
+ QStandardPaths.writableLocation(
+ QStandardPaths.StandardLocation.HomeLocation
+ ),
+ ".pesterchum/",
+ )
else:
- return os.path.join(QStandardPaths.writableLocation(QStandardPaths.StandardLocation.AppLocalDataLocation), "pesterchum/")
+ return os.path.join(
+ QStandardPaths.writableLocation(
+ QStandardPaths.StandardLocation.AppLocalDataLocation
+ ),
+ "pesterchum/",
+ )
except UnicodeDecodeError as e:
print(e)
- return ''
+ return ""
diff --git a/oyoyo/client.py b/oyoyo/client.py
index d3406bb..f2e7387 100644
--- a/oyoyo/client.py
+++ b/oyoyo/client.py
@@ -16,7 +16,8 @@
# THE SOFTWARE.
import logging
-PchumLog = logging.getLogger('pchumLogger')
+
+PchumLog = logging.getLogger("pchumLogger")
import logging
import socket
@@ -29,32 +30,33 @@ from oyoyo.parse import parse_raw_irc_command
from oyoyo import helpers
from oyoyo.cmdhandler import CommandError
+
class IRCClientError(Exception):
pass
class IRCClient:
- """ IRC Client class. This handles one connection to a server.
+ """IRC Client class. This handles one connection to a server.
This can be used either with or without IRCApp ( see connect() docs )
"""
def __init__(self, cmd_handler, **kwargs):
- """ the first argument should be an object with attributes/methods named
- as the irc commands. You may subclass from one of the classes in
- oyoyo.cmdhandler for convenience but it is not required. The
- methods should have arguments (prefix, args). prefix is
+ """the first argument should be an object with attributes/methods named
+ as the irc commands. You may subclass from one of the classes in
+ oyoyo.cmdhandler for convenience but it is not required. The
+ methods should have arguments (prefix, args). prefix is
normally the sender of the command. args is a list of arguments.
- Its recommened you subclass oyoyo.cmdhandler.DefaultCommandHandler,
- this class provides defaults for callbacks that are required for
+ Its recommened you subclass oyoyo.cmdhandler.DefaultCommandHandler,
+ this class provides defaults for callbacks that are required for
normal IRC operation.
all other arguments should be keyword arguments. The most commonly
used will be nick, host and port. You can also specify an "on connect"
callback. ( check the source for others )
- Warning: By default this class will not block on socket operations, this
+ Warning: By default this class will not block on socket operations, this
means if you use a plain while loop your app will consume 100% cpu.
- To enable blocking pass blocking=True.
+ To enable blocking pass blocking=True.
>>> class My_Handler(DefaultCommandHandler):
... def privmsg(self, prefix, command, args):
@@ -76,7 +78,7 @@ class IRCClient:
"""
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-
+
self.nick = None
self.realname = None
self.username = None
@@ -93,9 +95,9 @@ class IRCClient:
self._end = False
def send(self, *args, **kwargs):
- """ send a message to the connected server. all arguments are joined
- with a space for convenience, for example the following are identical
-
+ """send a message to the connected server. all arguments are joined
+ with a space for convenience, for example the following are identical
+
>>> cli.send("JOIN %s" % some_room)
>>> cli.send("JOIN", some_room)
@@ -104,24 +106,29 @@ class IRCClient:
the 'encoding' keyword argument (default 'utf8').
In python 3, all args must be of type str or bytes, *BUT* if they are
str they will be converted to bytes with the encoding specified by the
- 'encoding' keyword argument (default 'utf8').
+ 'encoding' keyword argument (default 'utf8').
"""
if self._end == True:
return
# Convert all args to bytes if not already
- encoding = kwargs.get('encoding') or 'utf8'
+ encoding = kwargs.get("encoding") or "utf8"
bargs = []
for arg in args:
if isinstance(arg, str):
bargs.append(bytes(arg, encoding))
elif isinstance(arg, bytes):
bargs.append(arg)
- elif type(arg).__name__ == 'unicode':
+ elif type(arg).__name__ == "unicode":
bargs.append(arg.encode(encoding))
else:
- PchumLog.warning('Refusing to send one of the args from provided: %s'% repr([(type(arg), arg) for arg in args]))
- raise IRCClientError('Refusing to send one of the args from provided: %s'
- % repr([(type(arg), arg) for arg in args]))
+ PchumLog.warning(
+ "Refusing to send one of the args from provided: %s"
+ % repr([(type(arg), arg) for arg in args])
+ )
+ raise IRCClientError(
+ "Refusing to send one of the args from provided: %s"
+ % repr([(type(arg), arg) for arg in args])
+ )
msg = bytes(" ", "UTF-8").join(bargs)
PchumLog.info('---> send "%s"' % msg)
@@ -135,7 +142,9 @@ class IRCClient:
self._end = True
break
try:
- ready_to_read, ready_to_write, in_error = select.select([], [self.socket], [])
+ ready_to_read, ready_to_write, in_error = select.select(
+ [], [self.socket], []
+ )
for x in ready_to_write:
x.sendall(msg + bytes("\r\n", "UTF-8"))
break
@@ -157,35 +166,34 @@ class IRCClient:
# socket.timeout is deprecated in 3.10
PchumLog.warning("TimeoutError in on send, " + str(e))
raise socket.timeout
- except (OSError,
- IndexError,
- ValueError,
- Exception) as e:
+ except (OSError, IndexError, ValueError, Exception) as e:
PchumLog.warning("Unkown error on send, " + str(e))
if tries >= 9:
raise e
tries += 1
PchumLog.warning("Retrying send. (attempt %s)" % str(tries))
time.sleep(0.1)
-
- PchumLog.debug("ready_to_write (len %s): " % str(len(ready_to_write)) + str(ready_to_write))
+
+ PchumLog.debug(
+ "ready_to_write (len %s): " % str(len(ready_to_write))
+ + str(ready_to_write)
+ )
except Exception as se:
PchumLog.warning("Send Exception %s" % str(se))
try:
if not self.blocking and se.errno == 11:
pass
else:
- #raise se
+ # raise se
self._end = True # This ok?
except AttributeError:
- #raise se
+ # raise se
self._end = True # This ok?
def connect(self, verify_hostname=True):
- """ initiates the connection to the server set in self.host:self.port
- """
- PchumLog.info('connecting to %s:%s' % (self.host, self.port))
-
+ """initiates the connection to the server set in self.host:self.port"""
+ PchumLog.info("connecting to %s:%s" % (self.host, self.port))
+
if self.ssl == True:
context = ssl.create_default_context()
if verify_hostname == False:
@@ -193,9 +201,9 @@ class IRCClient:
context.verify_mode = ssl.CERT_NONE
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)
+ self.socket = context.wrap_socket(
+ bare_sock, server_hostname=self.host, do_handshake_on_connect=False
+ )
while True:
try:
self.socket.do_handshake()
@@ -208,8 +216,8 @@ class IRCClient:
# Disconnect for now
self.socket.close()
bare_sock.close()
- raise e
-
+ raise e
+
PchumLog.info("secure sockets version is %s" % self.socket.version())
else:
@@ -224,7 +232,7 @@ class IRCClient:
elif self.blocking:
self.socket.setblocking(True)
- #try:
+ # try:
# self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
# if hasattr(socket, "TCP_KEEPIDLE"):
# self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 1)
@@ -232,16 +240,16 @@ class IRCClient:
# self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 1)
# if hasattr(socket, "TCP_KEEPCNT"):
# self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 1)
- #except Exception as e:
+ # except Exception as e:
# print(e)
-
+
helpers.nick(self, self.nick)
helpers.user(self, self.username, self.realname)
if self.connect_cb:
self.connect_cb(self)
-
+
def conn(self):
- """returns a generator object. """
+ """returns a generator object."""
try:
buffer = bytes()
while not self._end:
@@ -256,7 +264,9 @@ class IRCClient:
self._end = True
break
try:
- ready_to_read, ready_to_write, in_error = select.select([self.socket], [], [])
+ ready_to_read, ready_to_write, in_error = select.select(
+ [self.socket], [], []
+ )
for x in ready_to_read:
buffer += x.recv(1024)
break
@@ -278,17 +288,16 @@ class IRCClient:
# socket.timeout is deprecated in 3.10
PchumLog.warning("TimeoutError in on send, " + str(e))
raise socket.timeout
- except (OSError,
- IndexError,
- ValueError,
- Exception) as e:
+ except (OSError, IndexError, ValueError, Exception) as e:
PchumLog.debug("Miscellaneous exception in conn, " + str(e))
if tries >= 9:
raise e
tries += 1
- PchumLog.debug("Possibly retrying recv. (attempt %s)" % str(tries))
+ PchumLog.debug(
+ "Possibly retrying recv. (attempt %s)" % str(tries)
+ )
time.sleep(0.1)
-
+
except socket.timeout as e:
PchumLog.warning("timeout in client.py, " + str(e))
if self._end:
@@ -303,7 +312,7 @@ class IRCClient:
try: # a little dance of compatibility to get the errno
errno = e.errno
except AttributeError:
- errno = e[0]
+ errno = e[0]
if not self.blocking and errno == 11:
pass
else:
@@ -322,7 +331,7 @@ class IRCClient:
for el in data:
tags, prefix, command, args = parse_raw_irc_command(el)
- #print(tags, prefix, command, args)
+ # print(tags, prefix, command, args)
try:
# Only need tags with tagmsg
if command.upper() == "TAGMSG":
@@ -339,7 +348,7 @@ class IRCClient:
except (OSError, ssl.SSLEOFError) as se:
PchumLog.debug("problem: %s" % (str(se)))
if self.socket:
- PchumLog.info('error: closing socket')
+ PchumLog.info("error: closing socket")
self.socket.close()
raise se
except Exception as e:
@@ -347,27 +356,33 @@ class IRCClient:
raise e
else:
PchumLog.debug("ending while, end is %s" % self._end)
- if self.socket:
- PchumLog.info('finished: closing socket')
+ if self.socket:
+ PchumLog.info("finished: closing socket")
self.socket.close()
yield False
+
def close(self):
# with extreme prejudice
if self.socket:
- PchumLog.info('shutdown socket')
- #print("shutdown socket")
+ PchumLog.info("shutdown socket")
+ # print("shutdown socket")
self._end = True
try:
self.socket.shutdown(socket.SHUT_RDWR)
except OSError as e:
- PchumLog.debug("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.debug("Error while closing socket, already broken? %s" % str(e))
-
+ PchumLog.debug(
+ "Error while closing socket, already broken? %s" % str(e)
+ )
+
+
class IRCApp:
- """ This class manages several IRCClient instances without the use of threads.
+ """This class manages several IRCClient instances without the use of threads.
(Non-threaded) Timer functionality is also included.
"""
@@ -384,27 +399,27 @@ class IRCApp:
self.sleep_time = 0.5
def addClient(self, client, autoreconnect=False):
- """ add a client object to the application. setting autoreconnect
+ """add a client object to the application. setting autoreconnect
to true will mean the application will attempt to reconnect the client
- after every disconnect. you can also set autoreconnect to a number
+ after every disconnect. you can also set autoreconnect to a number
to specify how many reconnects should happen.
warning: if you add a client that has blocking set to true,
- timers will no longer function properly """
- PchumLog.info('added client %s (ar=%s)' % (client, autoreconnect))
+ timers will no longer function properly"""
+ PchumLog.info("added client %s (ar=%s)" % (client, autoreconnect))
self._clients[client] = self._ClientDesc(autoreconnect=autoreconnect)
def addTimer(self, seconds, cb):
- """ add a timed callback. accuracy is not specified, you can only
+ """add a timed callback. accuracy is not specified, you can only
garuntee the callback will be called after seconds has passed.
( the only advantage to these timers is they dont use threads )
"""
assert callable(cb)
- PchumLog.info('added timer to call %s in %ss' % (cb, seconds))
+ PchumLog.info("added timer to call %s in %ss" % (cb, seconds))
self._timers.append((time.time() + seconds, cb))
def run(self):
- """ run the application. this will block until stop() is called """
+ """run the application. this will block until stop() is called"""
# TODO: convert this to use generators too?
self.running = True
while self.running:
@@ -413,42 +428,38 @@ class IRCApp:
for client, clientdesc in self._clients.items():
if clientdesc.con is None:
clientdesc.con = client.connect()
-
+
try:
next(clientdesc.con)
except Exception as e:
- PchumLog.error('client error %s' % str(e))
+ PchumLog.error("client error %s" % str(e))
PchumLog.error(traceback.format_exc())
if clientdesc.autoreconnect:
- clientdesc.con = None
+ clientdesc.con = None
if isinstance(clientdesc.autoreconnect, (int, float)):
clientdesc.autoreconnect -= 1
found_one_alive = True
else:
- clientdesc.con = False
+ clientdesc.con = False
else:
found_one_alive = True
-
+
if not found_one_alive:
- PchumLog.info('nothing left alive... quiting')
- self.stop()
+ PchumLog.info("nothing left alive... quiting")
+ self.stop()
now = time.time()
timers = self._timers[:]
self._timers = []
for target_time, cb in timers:
if now > target_time:
- PchumLog.info('calling timer cb %s' % cb)
+ PchumLog.info("calling timer cb %s" % cb)
cb()
- else:
+ else:
self._timers.append((target_time, cb))
time.sleep(self.sleep_time)
def stop(self):
- """ stop the application """
+ """stop the application"""
self.running = False
-
-
-
-
diff --git a/oyoyo/cmdhandler.py b/oyoyo/cmdhandler.py
index bb3526d..3ead782 100644
--- a/oyoyo/cmdhandler.py
+++ b/oyoyo/cmdhandler.py
@@ -20,10 +20,11 @@ import inspect
from oyoyo import helpers
from oyoyo.parse import parse_nick
-PchumLog = logging.getLogger('pchumLogger')
+PchumLog = logging.getLogger("pchumLogger")
+
def protected(func):
- """ decorator to protect functions from being called """
+ """decorator to protect functions from being called"""
func.protected = True
return func
@@ -32,17 +33,19 @@ class CommandError(Exception):
def __init__(self, cmd):
self.cmd = cmd
+
class NoSuchCommandError(CommandError):
def __str__(self):
return 'No such command "%s"' % ".".join(self.cmd)
+
class ProtectedCommandError(CommandError):
def __str__(self):
return 'Command "%s" is protected' % ".".join(self.cmd)
-
+
class CommandHandler(object):
- """ The most basic CommandHandler """
+ """The most basic CommandHandler"""
def __init__(self, client):
self.client = client
@@ -59,13 +62,13 @@ class CommandHandler(object):
["command", "sub", "func"].
"""
if isinstance(in_command_parts, (str, bytes)):
- in_command_parts = in_command_parts.split('.')
+ in_command_parts = in_command_parts.split(".")
command_parts = in_command_parts[:]
p = self
while command_parts:
cmd = command_parts.pop(0)
- if cmd.startswith('_'):
+ if cmd.startswith("_"):
raise ProtectedCommandError(in_command_parts)
try:
@@ -73,7 +76,7 @@ class CommandHandler(object):
except AttributeError:
raise NoSuchCommandError(in_command_parts)
- if hasattr(f, 'protected'):
+ if hasattr(f, "protected"):
raise ProtectedCommandError(in_command_parts)
if isinstance(f, CommandHandler) and command_parts:
@@ -84,10 +87,10 @@ class CommandHandler(object):
@protected
def run(self, command, *args):
- """ finds and runs a command """
- arguments_str = ''
+ """finds and runs a command"""
+ arguments_str = ""
for x in args:
- arguments_str += str(x) + ' '
+ arguments_str += str(x) + " "
PchumLog.debug("processCommand %s(%s)" % (command, arguments_str.strip()))
try:
@@ -97,14 +100,17 @@ class CommandHandler(object):
self.__unhandled__(command, *args)
return
- PchumLog.debug('f %s' % f)
+ PchumLog.debug("f %s" % f)
try:
f(*args)
except TypeError as e:
- PchumLog.info("Failed to pass command, did the server pass an unsupported paramater? " + str(e))
+ PchumLog.info(
+ "Failed to pass command, did the server pass an unsupported paramater? "
+ + str(e)
+ )
except Exception as e:
- #logging.info("Failed to pass command, %s" % str(e))
+ # logging.info("Failed to pass command, %s" % str(e))
PchumLog.exception("Failed to pass command")
@protected
@@ -112,46 +118,52 @@ class CommandHandler(object):
"""The default handler for commands. Override this method to
apply custom behavior (example, printing) unhandled commands.
"""
- PchumLog.debug('unhandled command %s(%s)' % (cmd, args))
+ PchumLog.debug("unhandled command %s(%s)" % (cmd, args))
class DefaultCommandHandler(CommandHandler):
- """ CommandHandler that provides methods for the normal operation of IRC.
+ """CommandHandler that provides methods for the normal operation of IRC.
If you want your bot to properly respond to pings, etc, you should subclass this.
"""
def ping(self, prefix, server):
- self.client.send('PONG', server)
+ self.client.send("PONG", server)
class DefaultBotCommandHandler(CommandHandler):
- """ default command handler for bots. methods/attributes are made
- available as commands """
+ """default command handler for bots. methods/attributes are made
+ available as commands"""
@protected
def getVisibleCommands(self, obj=None):
- test = (lambda x: isinstance(x, CommandHandler) or \
- inspect.ismethod(x) or inspect.isfunction(x))
- members = inspect.getmembers(obj or self, test)
- return [m for m, _ in members
- if (not m.startswith('_') and
- not hasattr(getattr(obj, m), 'protected'))]
+ test = (
+ lambda x: isinstance(x, CommandHandler)
+ or inspect.ismethod(x)
+ or inspect.isfunction(x)
+ )
+ members = inspect.getmembers(obj or self, test)
+ return [
+ m
+ for m, _ in members
+ if (not m.startswith("_") and not hasattr(getattr(obj, m), "protected"))
+ ]
def help(self, sender, dest, arg=None):
"""list all available commands or get help on a specific command"""
- PchumLog.info('help sender=%s dest=%s arg=%s' % (sender, dest, arg))
+ PchumLog.info("help sender=%s dest=%s arg=%s" % (sender, dest, arg))
if not arg:
commands = self.getVisibleCommands()
commands.sort()
- helpers.msg(self.client, dest,
- "available commands: %s" % " ".join(commands))
+ helpers.msg(
+ self.client, dest, "available commands: %s" % " ".join(commands)
+ )
else:
try:
f = self.get(arg)
except CommandError as e:
helpers.msg(self.client, dest, str(e))
return
-
+
doc = f.__doc__.strip() if f.__doc__ else "No help available"
if not inspect.ismethod(f):
@@ -159,11 +171,11 @@ class DefaultBotCommandHandler(CommandHandler):
if subcommands:
doc += " [sub commands: %s]" % " ".join(subcommands)
- helpers.msg(self.client, dest, "%s: %s" % (arg, doc))
+ helpers.msg(self.client, dest, "%s: %s" % (arg, doc))
class BotCommandHandler(DefaultCommandHandler):
- """ complete command handler for bots """
+ """complete command handler for bots"""
def __init__(self, client, command_handler):
DefaultCommandHandler.__init__(self, client)
@@ -174,22 +186,22 @@ class BotCommandHandler(DefaultCommandHandler):
@protected
def tryBotCommand(self, prefix, dest, msg):
- """ tests a command to see if its a command for the bot, returns True
+ """tests a command to see if its a command for the bot, returns True
and calls self.processBotCommand(cmd, sender) if its is.
"""
-
+
PchumLog.debug("tryBotCommand('%s' '%s' '%s')" % (prefix, dest, msg))
if dest == self.client.nick:
dest = parse_nick(prefix)[0]
elif msg.startswith(self.client.nick):
- msg = msg[len(self.client.nick)+1:]
- else:
+ msg = msg[len(self.client.nick) + 1 :]
+ else:
return False
msg = msg.strip()
- parts = msg.split(' ', 1)
+ parts = msg.split(" ", 1)
command = parts[0]
arg = parts[1:]
@@ -198,13 +210,3 @@ class BotCommandHandler(DefaultCommandHandler):
except CommandError as e:
helpers.msg(self.client, dest, str(e))
return True
-
-
-
-
-
-
-
-
-
-
diff --git a/oyoyo/helpers.py b/oyoyo/helpers.py
index 4513366..6dbb897 100644
--- a/oyoyo/helpers.py
+++ b/oyoyo/helpers.py
@@ -20,14 +20,16 @@
import logging
import random
-PchumLog = logging.getLogger('pchumLogger')
+PchumLog = logging.getLogger("pchumLogger")
+
def msg(cli, user, msg):
- for line in msg.split('\n'):
+ for line in msg.split("\n"):
cli.send("PRIVMSG", user, ":%s" % line)
+
def names(cli, *channels):
- tmp = __builtins__['list'](channels)
+ tmp = __builtins__["list"](channels)
msglist = []
while len(tmp) > 0:
msglist.append(tmp.pop())
@@ -38,12 +40,15 @@ def names(cli, *channels):
if len(msglist) > 0:
cli.send("NAMES %s" % (",".join(msglist)))
+
def channel_list(cli):
cli.send("LIST")
+
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))
@@ -52,9 +57,10 @@ def mode(cli, channel, mode, options=None):
cmd += " %s" % (options)
cli.send(cmd)
+
def ctcp(cli, handle, cmd, msg=""):
- # Space breaks protocol if msg is absent
- if msg=="":
+ # Space breaks protocol if msg is absent
+ if msg == "":
cli.send("PRIVMSG", handle, "\x01%s\x01" % (cmd))
else:
cli.send("PRIVMSG", handle, "\x01%s %s\x01" % (cmd, msg))
@@ -63,77 +69,96 @@ 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 cap(cli, subcommand, *params):
# Capability Negotiation
# https://ircv3.net/specs/extensions/capability-negotiation.html
cli.send("CAP", subcommand, *params)
+
def msgrandom(cli, choices, dest, user=None):
o = "%s: " % user if user else ""
o += random.choice(choices)
msg(cli, dest, o)
+
def _makeMsgRandomFunc(choices):
def func(cli, dest, user=None):
msgrandom(cli, choices, dest, user)
+
return func
-msgYes = _makeMsgRandomFunc(['yes', 'alright', 'ok'])
-msgOK = _makeMsgRandomFunc(['ok', 'done'])
-msgNo = _makeMsgRandomFunc(['no', 'no-way'])
+
+msgYes = _makeMsgRandomFunc(["yes", "alright", "ok"])
+msgOK = _makeMsgRandomFunc(["ok", "done"])
+msgNo = _makeMsgRandomFunc(["no", "no-way"])
def ns(cli, *args):
msg(cli, "NickServ", " ".join(args))
+
def cs(cli, *args):
msg(cli, "ChanServ", " ".join(args))
+
def identify(cli, passwd, authuser="NickServ"):
msg(cli, authuser, "IDENTIFY %s" % passwd)
+
def quit(cli, msg):
cli.send("QUIT %s" % (msg))
+
def user(cli, username, realname):
- cli.send("USER",
- username,
- '0',
- '*',
- ':' + realname)
+ cli.send("USER", username, "0", "*", ":" + realname)
+
_simple = (
- 'join',
- 'part',
- 'nick',
- 'notice',
- 'invite',
+ "join",
+ "part",
+ "nick",
+ "notice",
+ "invite",
)
+
+
def _addsimple():
import sys
+
def simplecmd(cmd_name):
def f(cli, *args):
cli.send(cmd_name, *args)
+
return f
+
m = sys.modules[__name__]
for t in _simple:
setattr(m, t, simplecmd(t.upper()))
+
+
_addsimple()
+
def _addNumerics():
import sys
from oyoyo import ircevents
+
def numericcmd(cmd_num, cmd_name):
def f(cli, *args):
cli.send(cmd_num, *args)
+
return f
+
m = sys.modules[__name__]
for num, name in ircevents.numeric_events.items():
setattr(m, name, numericcmd(num, name))
+
_addNumerics()
diff --git a/oyoyo/ircevents.py b/oyoyo/ircevents.py
index 9041f82..1ed1b85 100644
--- a/oyoyo/ircevents.py
+++ b/oyoyo/ircevents.py
@@ -116,7 +116,7 @@ numeric_events = {
"374": "endofinfo",
"375": "motdstart",
"376": "endofmotd",
- "377": "motd2", # 1997-10-16 -- tkil
+ "377": "motd2", # 1997-10-16 -- tkil
"381": "youreoper",
"382": "rehashing",
"384": "myportis",
@@ -143,7 +143,7 @@ numeric_events = {
"423": "noadmininfo",
"424": "fileerror",
"431": "nonicknamegiven",
- "432": "erroneusnickname", # Thiss iz how its speld in thee RFC.
+ "432": "erroneusnickname", # Thiss iz how its speld in thee RFC.
"433": "nicknameinuse",
"436": "nickcollision",
"437": "unavailresource", # "Nick temporally unavailable"
@@ -158,7 +158,7 @@ numeric_events = {
"462": "alreadyregistered",
"463": "nopermforhost",
"464": "passwdmismatch",
- "465": "yourebannedcreep", # I love this one...
+ "465": "yourebannedcreep", # I love this one...
"466": "youwillbebanned",
"467": "keyset",
"471": "channelisfull",
@@ -172,7 +172,7 @@ numeric_events = {
"481": "noprivileges",
"482": "chanoprivsneeded",
"483": "cantkillserver",
- "484": "restricted", # Connection is restricted
+ "484": "restricted", # Connection is restricted
"485": "uniqopprivsneeded",
"491": "nooperhost",
"492": "noservicehost",
@@ -195,7 +195,7 @@ metadata_numeric_events = {
"768": "keynotset",
"769": "keynopermission",
"770": "metadatasubok",
- }
+}
numeric_events.update(metadata_numeric_events)
generated_events = [
@@ -226,10 +226,7 @@ protocol_events = [
"nick", # We can get svsnicked
"metadata", # Metadata specification
"tagmsg", # IRCv3 message tags extension
- "cap" # IRCv3 Client Capability Negotiation
+ "cap", # IRCv3 Client Capability Negotiation
]
-all_events = (generated_events
- + protocol_events
- + list(numeric_events.values()))
-
+all_events = generated_events + protocol_events + list(numeric_events.values())
diff --git a/oyoyo/parse.py b/oyoyo/parse.py
index 8cdbaa3..e35c15c 100644
--- a/oyoyo/parse.py
+++ b/oyoyo/parse.py
@@ -19,7 +19,8 @@ import logging
from oyoyo.ircevents import numeric_events
-PchumLog = logging.getLogger('pchumLogger')
+PchumLog = logging.getLogger("pchumLogger")
+
def parse_raw_irc_command(element):
"""
@@ -55,20 +56,20 @@ def parse_raw_irc_command(element):
"""
-
+
try:
element = element.decode("utf-8")
except UnicodeDecodeError as e:
PchumLog.debug("utf-8 error %s" % str(e))
- element = element.decode("latin-1", 'replace')
-
+ element = element.decode("latin-1", "replace")
+
parts = element.strip().split(" ")
- if parts[0].startswith(':'):
+ if parts[0].startswith(":"):
tags = None
prefix = parts[0][1:]
command = parts[1]
args = parts[2:]
- elif parts[0].startswith('@'):
+ elif parts[0].startswith("@"):
# Message tag
tags = parts[0]
prefix = parts[1][1:]
@@ -84,14 +85,14 @@ def parse_raw_irc_command(element):
try:
command = numeric_events[command]
except KeyError:
- PchumLog.info('unknown numeric event %s' % command)
+ PchumLog.info("unknown numeric event %s" % command)
command = command.lower()
- if args[0].startswith(':'):
+ if args[0].startswith(":"):
args = [" ".join(args)[1:]]
else:
for idx, arg in enumerate(args):
- if arg.startswith(':'):
+ if arg.startswith(":"):
args = args[:idx] + [" ".join(args[idx:])[1:]]
break
@@ -99,23 +100,22 @@ def parse_raw_irc_command(element):
def parse_nick(name):
- """ parse a nickname and return a tuple of (nick, mode, user, host)
+ """parse a nickname and return a tuple of (nick, mode, user, host)
[ '!' [ = ] ] [ '@' ]
"""
try:
- nick, rest = name.split('!')
+ nick, rest = name.split("!")
except ValueError:
return (name, None, None, None)
try:
- mode, rest = rest.split('=')
+ mode, rest = rest.split("=")
except ValueError:
mode, rest = None, rest
try:
- user, host = rest.split('@')
+ user, host = rest.split("@")
except ValueError:
return (name, mode, rest, None)
return (name, mode, user, host)
-
diff --git a/oyoyo/services.py b/oyoyo/services.py
index c0fc5e6..c0c4848 100644
--- a/oyoyo/services.py
+++ b/oyoyo/services.py
@@ -1,117 +1,123 @@
# NickServ basic functions
_nickservfuncs = (
- 'register',
- 'group',
- 'glist',
- 'identify',
- 'access',
- 'drop',
- 'recover',
- 'release',
- 'sendpass',
- 'ghost',
- 'alist',
- 'info',
- 'list',
- 'logout',
- 'status',
- 'update'
+ "register",
+ "group",
+ "glist",
+ "identify",
+ "access",
+ "drop",
+ "recover",
+ "release",
+ "sendpass",
+ "ghost",
+ "alist",
+ "info",
+ "list",
+ "logout",
+ "status",
+ "update",
)
# NickServ SET functions
_nickservsetfuncs = (
- 'display',
- 'password',
- 'language',
- 'url',
- 'email',
- 'icq',
- 'greet',
- 'kill',
- 'secure',
- 'private',
- 'hide',
- 'msg',
- 'autoop'
+ "display",
+ "password",
+ "language",
+ "url",
+ "email",
+ "icq",
+ "greet",
+ "kill",
+ "secure",
+ "private",
+ "hide",
+ "msg",
+ "autoop",
)
# ChanServ basic functions
_chanservfuncs = (
- 'register',
- 'identify',
- 'sop',
- 'aop',
- 'hop',
- 'vop',
- 'access',
- 'levels',
- 'akick',
- 'drop',
- 'sendpass',
- 'ban',
- 'unban',
- 'clear',
- 'owner',
- 'deowner',
- 'protect',
- 'deprotect',
- 'op',
- 'deop',
- 'halfop',
- 'dehalfop',
- 'voice',
- 'devoice',
- 'getkey',
- 'invite',
- 'kick',
- 'list',
- 'logout',
- 'topic',
- 'info',
- 'appendtopic',
- 'enforce'
+ "register",
+ "identify",
+ "sop",
+ "aop",
+ "hop",
+ "vop",
+ "access",
+ "levels",
+ "akick",
+ "drop",
+ "sendpass",
+ "ban",
+ "unban",
+ "clear",
+ "owner",
+ "deowner",
+ "protect",
+ "deprotect",
+ "op",
+ "deop",
+ "halfop",
+ "dehalfop",
+ "voice",
+ "devoice",
+ "getkey",
+ "invite",
+ "kick",
+ "list",
+ "logout",
+ "topic",
+ "info",
+ "appendtopic",
+ "enforce",
)
_chanservsetfuncs = (
- 'founder',
- 'successor',
- 'password',
- 'desc',
- 'url',
- 'email',
- 'entrymsg',
- 'bantype',
- 'mlock',
- 'keeptopic',
- 'opnotice',
- 'peace',
- 'private',
- 'restricted',
- 'secure',
- 'secureops',
- 'securefounder',
- 'signkick',
- 'topiclock',
- 'xop'
+ "founder",
+ "successor",
+ "password",
+ "desc",
+ "url",
+ "email",
+ "entrymsg",
+ "bantype",
+ "mlock",
+ "keeptopic",
+ "opnotice",
+ "peace",
+ "private",
+ "restricted",
+ "secure",
+ "secureops",
+ "securefounder",
+ "signkick",
+ "topiclock",
+ "xop",
)
+
def _addServ(serv, funcs, prefix=""):
def simplecmd(cmd_name):
if prefix:
cmd_name = prefix.upper() + " " + cmd_name
+
def f(cli, *args):
print(cmd_name, " ".join(args))
- #cli.send(cmd_name, serv.name, *args)
+ # cli.send(cmd_name, serv.name, *args)
+
return f
+
for t in funcs:
setattr(serv, t, simplecmd(t.upper()))
+
class NickServ(object):
def __init__(self, nick="NickServ"):
self.name = nick
_addServ(self, _nickservfuncs)
_addServ(self, _nickservsetfuncs, "set")
+
class ChanServ(object):
def __init__(self, nick="ChanServ"):
self.name = nick
diff --git a/parsetools.py b/parsetools.py
index d7a46bd..bbc264f 100644
--- a/parsetools.py
+++ b/parsetools.py
@@ -12,51 +12,56 @@ except ImportError:
import dataobjs
import ostools
+
# karxi: My own contribution to this - a proper lexer.
import pnc.lexercon as lexercon
from generic import mysteryTime
from quirks import ScriptQuirks
from pyquirks import PythonQuirks
-#from luaquirks import LuaQuirks
-PchumLog = logging.getLogger('pchumLogger')
+# from luaquirks import LuaQuirks
+
+PchumLog = logging.getLogger("pchumLogger")
# I'll clean up the things that are no longer needed once the transition is
# actually finished.
QString = str
-_ctag_begin = re.compile(r'(?i)')
-_gtag_begin = re.compile(r'(?i)')
-_ctag_end = re.compile(r'(?i)')
-_ctag_rgb = re.compile(r'\d+,\d+,\d+')
+_ctag_begin = re.compile(r"(?i)")
+_gtag_begin = re.compile(r"(?i)")
+_ctag_end = re.compile(r"(?i)")
+_ctag_rgb = re.compile(r"\d+,\d+,\d+")
_urlre = re.compile(r"(?i)(?:^|(?<=\s))(?:(?:https?|ftp)://|magnet:)[^\s]+")
-#_url2re = re.compile(r"(?i)(?""")
_mecmdre = re.compile(r"^(/me|PESTERCHUM:ME)(\S*)")
_oocre = re.compile(r"([\[(\{])\1.*([\])\}])\2")
-_format_begin = re.compile(r'(?i)<([ibu])>')
-_format_end = re.compile(r'(?i)([ibu])>')
+_format_begin = re.compile(r"(?i)<([ibu])>")
+_format_end = re.compile(r"(?i)([ibu])>")
_honk = re.compile(r"(?i)\bhonk\b")
_groupre = re.compile(r"\\([0-9]+)")
quirkloader = ScriptQuirks()
_functionre = None
+
def loadQuirks():
global quirkloader, _functionre
quirkloader.add(PythonQuirks())
- #quirkloader.add(LuaQuirks())
+ # quirkloader.add(LuaQuirks())
quirkloader.loadAll()
quirkloader.funcre()
_functionre = re.compile(r"%s" % quirkloader.funcre())
+
def reloadQuirkFunctions():
quirkloader.loadAll()
global _functionre
_functionre = re.compile(r"%s" % quirkloader.funcre())
+
def lexer(string, objlist):
"""objlist is a list: [(objecttype, re),...] list is in order of preference"""
stringlist = [string]
@@ -80,6 +85,7 @@ def lexer(string, objlist):
stringlist = copy(newstringlist)
return stringlist
+
# karxi: All of these were derived from object before. I changed them to
# lexercon.Chunk so that I'd have an easier way to match against them until
# they're redone/removed.
@@ -87,12 +93,13 @@ class colorBegin(lexercon.Chunk):
def __init__(self, string, color):
self.string = string
self.color = color
+
def convert(self, format):
color = self.color
if format == "text":
return ""
if _ctag_rgb.match(color) is not None:
- if format=='ctag':
+ if format == "ctag":
return "" % (color)
try:
qc = QtGui.QColor(*[int(c) for c in color.split(",")])
@@ -105,14 +112,16 @@ class colorBegin(lexercon.Chunk):
if format == "html":
return '' % (qc.name())
elif format == "bbcode":
- return '[color=%s]' % (qc.name())
+ return "[color=%s]" % (qc.name())
elif format == "ctag":
- (r,g,b,a) = qc.getRgb()
- return '' % (r,g,b)
+ (r, g, b, a) = qc.getRgb()
+ return "" % (r, g, b)
+
class colorEnd(lexercon.Chunk):
def __init__(self, string):
self.string = string
+
def convert(self, format):
if format == "html":
return ""
@@ -123,10 +132,12 @@ class colorEnd(lexercon.Chunk):
else:
return self.string
+
class formatBegin(lexercon.Chunk):
def __init__(self, string, ftype):
self.string = string
self.ftype = ftype
+
def convert(self, format):
if format == "html":
return "<%s>" % (self.ftype)
@@ -137,10 +148,12 @@ class formatBegin(lexercon.Chunk):
else:
return self.string
+
class formatEnd(lexercon.Chunk):
def __init__(self, string, ftype):
self.string = string
self.ftype = ftype
+
def convert(self, format):
if format == "html":
return "%s>" % (self.ftype)
@@ -151,9 +164,11 @@ class formatEnd(lexercon.Chunk):
else:
return self.string
+
class hyperlink(lexercon.Chunk):
def __init__(self, string):
self.string = string
+
def convert(self, format):
if format == "html":
return "%s" % (self.string, self.string)
@@ -162,16 +177,20 @@ class hyperlink(lexercon.Chunk):
else:
return self.string
+
class hyperlink_lazy(hyperlink):
"""Deprecated since it doesn't seem to turn the full url into a link,
probably not required anyway, best to require a protocol prefix."""
+
def __init__(self, string):
self.string = "http://" + string
+
class imagelink(lexercon.Chunk):
def __init__(self, string, img):
self.string = string
self.img = img
+
def convert(self, format):
if format == "html":
return self.string
@@ -183,84 +202,104 @@ class imagelink(lexercon.Chunk):
else:
return ""
+
class memolex(lexercon.Chunk):
def __init__(self, string, space, channel):
self.string = string
self.space = space
self.channel = channel
+
def convert(self, format):
if format == "html":
return "%s%s" % (self.space, self.channel, self.channel)
else:
return self.string
+
class chumhandlelex(lexercon.Chunk):
def __init__(self, string, space, handle):
self.string = string
self.space = space
self.handle = handle
+
def convert(self, format):
if format == "html":
return "%s%s" % (self.space, self.handle, self.handle)
else:
return self.string
+
class smiley(lexercon.Chunk):
def __init__(self, string):
self.string = string
+
def convert(self, format):
if format == "html":
- return "" % (smiledict[self.string], self.string, self.string)
+ return "" % (
+ smiledict[self.string],
+ self.string,
+ self.string,
+ )
else:
return self.string
+
class honker(lexercon.Chunk):
def __init__(self, string):
self.string = string
+
def convert(self, format):
# No more 'honk' turning into an emote because everyone hated that :')
- #if format == "html":
+ # if format == "html":
# return ""
- #else:
+ # else:
return self.string
+
class mecmd(lexercon.Chunk):
def __init__(self, string, mecmd, suffix):
self.string = string
self.suffix = suffix
+
def convert(self, format):
return self.string
+
kxpclexer = lexercon.Pesterchum()
+
def kxlexMsg(string):
# Do a bit of sanitization.
msg = str(string)
# TODO: Let people paste line-by-line normally. Maybe have a mass-paste
# right-click option?
- msg = msg.replace('\n', ' ').replace('\r', ' ')
+ msg = msg.replace("\n", " ").replace("\r", " ")
# Something the original doesn't seem to have accounted for.
# Replace tabs with 4 spaces.
- msg = msg.replace('\t', ' ' * 4)
+ msg = msg.replace("\t", " " * 4)
# Begin lexing.
msg = kxpclexer.lex(msg)
# ...and that's it for this.
return msg
+
def lexMessage(string):
- lexlist = [(mecmd, _mecmdre),
- (colorBegin, _ctag_begin), (colorBegin, _gtag_begin),
- (colorEnd, _ctag_end),
- # karxi: Disabled this for now. No common versions of Pesterchum
- # actually use it, save for Chumdroid...which shouldn't.
- # When I change out parsers, I might add it back in.
- ##(formatBegin, _format_begin), (formatEnd, _format_end),
- (imagelink, _imgre),
- (hyperlink, _urlre),
- (memolex, _memore),
- (chumhandlelex, _handlere),
- (smiley, _smilere),
- (honker, _honk)]
+ lexlist = [
+ (mecmd, _mecmdre),
+ (colorBegin, _ctag_begin),
+ (colorBegin, _gtag_begin),
+ (colorEnd, _ctag_end),
+ # karxi: Disabled this for now. No common versions of Pesterchum
+ # actually use it, save for Chumdroid...which shouldn't.
+ # When I change out parsers, I might add it back in.
+ ##(formatBegin, _format_begin), (formatEnd, _format_end),
+ (imagelink, _imgre),
+ (hyperlink, _urlre),
+ (memolex, _memore),
+ (chumhandlelex, _handlere),
+ (smiley, _smilere),
+ (honker, _honk),
+ ]
string = str(string)
string = string.replace("\n", " ").replace("\r", " ")
@@ -282,14 +321,15 @@ def lexMessage(string):
else:
balanced.append(o)
if beginc > endc:
- for i in range(0, beginc-endc):
+ for i in range(0, beginc - endc):
balanced.append(colorEnd(""))
if len(balanced) == 0:
balanced.append("")
- if type(balanced[len(balanced)-1]) not in [str, str]:
+ if type(balanced[len(balanced) - 1]) not in [str, str]:
balanced.append("")
return balanced
+
def convertTags(lexed, format="html"):
if format not in ["html", "bbcode", "ctag", "text"]:
raise ValueError("Color format not recognized")
@@ -297,11 +337,13 @@ def convertTags(lexed, format="html"):
if type(lexed) in [str, str]:
lexed = lexMessage(lexed)
escaped = ""
- #firststr = True
+ # firststr = True
for (i, o) in enumerate(lexed):
if type(o) in [str, str]:
if format == "html":
- escaped += o.replace("&", "&").replace(">", ">").replace("<","<")
+ escaped += (
+ o.replace("&", "&").replace(">", ">").replace("<", "<")
+ )
else:
escaped += o
else:
@@ -309,6 +351,7 @@ def convertTags(lexed, format="html"):
return escaped
+
def _max_msg_len(mask=None, target=None, nick=None, ident=None):
# karxi: Copied from another file of mine, and modified to work with
# Pesterchum.
@@ -330,7 +373,7 @@ def _max_msg_len(mask=None, target=None, nick=None, ident=None):
# Since we should always be able to fetch this
# karxi: ... Which we can't, right now, unlike in the old script.
# TODO: Resolve this issue, give it the necessary information.
-
+
# If we CAN'T, stick with a length of 30, since that seems to be
# the average maximum nowadays
limit -= len(nick) if nick is not None else 30
@@ -339,7 +382,7 @@ def _max_msg_len(mask=None, target=None, nick=None, ident=None):
# ident length
limit -= len(ident) if nick is not None else 10
# Maximum (?) host length
- limit -= 63 # RFC 2812
+ limit -= 63 # RFC 2812
# The target is the place this is getting sent to - a channel or a nick
if target is not None:
limit -= len(target)
@@ -351,10 +394,11 @@ def _max_msg_len(mask=None, target=None, nick=None, ident=None):
return limit
+
def kxsplitMsg(lexed, ctx, fmt="pchum", maxlen=None, debug=False):
"""Split messages so that they don't go over the length limit.
Returns a list of the messages, neatly split.
-
+
Keep in mind that there's a little bit of magic involved in this at the
moment; some unsafe assumptions are made."""
@@ -384,11 +428,21 @@ def kxsplitMsg(lexed, ctx, fmt="pchum", maxlen=None, debug=False):
curlen = 0
# Maximum number of characters *to* use.
if not maxlen:
- maxlen = _max_msg_len(None, None, ctx.mainwindow.profile().handle, ctx.mainwindow.irc.cli.realname)
+ maxlen = _max_msg_len(
+ None, None, ctx.mainwindow.profile().handle, ctx.mainwindow.irc.cli.realname
+ )
elif maxlen < 0:
# Subtract the (negative) length, giving us less leeway in this
# function.
- maxlen = _max_msg_len(None, None, ctx.mainwindow.profile().handle, ctx.mainwindow.irc.cli.realname) + maxlen
+ maxlen = (
+ _max_msg_len(
+ None,
+ None,
+ ctx.mainwindow.profile().handle,
+ ctx.mainwindow.irc.cli.realname,
+ )
+ + maxlen
+ )
# Defined here, but modified in the loop.
msglen = 0
@@ -398,7 +452,7 @@ def kxsplitMsg(lexed, ctx, fmt="pchum", maxlen=None, debug=False):
tags that will be needed."""
return maxlen - curlen - (len(open_ctags) * 4)
- #safekeeping = lexed[:]
+ # safekeeping = lexed[:]
lexed = collections.deque(lexed)
rounds = 0
# NOTE: This entire mess is due for a rewrite. I'll start splitting it into
@@ -448,14 +502,14 @@ def kxsplitMsg(lexed, ctx, fmt="pchum", maxlen=None, debug=False):
# instead?
subround += 1
if debug:
- PchumLog.info("[Splitting round {}-{}...]".format(
- rounds, subround
- ))
- point = msg.rfind(' ', 0, lenl)
+ PchumLog.info(
+ "[Splitting round {}-{}...]".format(rounds, subround)
+ )
+ point = msg.rfind(" ", 0, lenl)
if point < 0:
# No spaces to break on...ugh. Break at the last space
# we can instead.
- point = lenl ## - 1
+ point = lenl ## - 1
# NOTE: The - 1 is for safety (but probably isn't
# actually necessary.)
# Split and push what we have.
@@ -509,16 +563,20 @@ def kxsplitMsg(lexed, ctx, fmt="pchum", maxlen=None, debug=False):
cte = lexercon.CTagEnd("", fmt, None)
working.extend([cte] * len(open_ctags))
if debug:
- print("\tRound {0} linebreak: Added {1} closing ctags".format(
+ print(
+ "\tRound {0} linebreak: Added {1} closing ctags".format(
rounds, len(open_ctags)
- ))
+ )
+ )
# Run it through the lexer again to render it.
- working = ''.join(kxpclexer.list_convert(working))
+ working = "".join(kxpclexer.list_convert(working))
if debug:
- print("\tRound {0} add: len == {1} (of {2})".format(
+ print(
+ "\tRound {0} add: len == {1} (of {2})".format(
rounds, len(working), maxlen
- ))
+ )
+ )
# Now that it's done the work for us, append and resume.
output.append(working)
@@ -598,22 +656,19 @@ def kxsplitMsg(lexed, ctx, fmt="pchum", maxlen=None, debug=False):
if len(working) > 0:
if debug:
print("Adding end trails: {!r}".format(working))
- working = ''.join(working)
+ working = "".join(working)
output.append(working)
# We're...done?
return output
+
def _is_ooc(msg, strict=True):
"""Check if a line is OOC. Note that Pesterchum *is* kind enough to strip
trailing spaces for us, even in the older versions, but we don't do that in
this function. (It's handled by the calling one.)"""
# Define the matching braces.
- braces = (
- ('(', ')'),
- ('[', ']'),
- ('{', '}')
- )
+ braces = (("(", ")"), ("[", "]"), ("{", "}"))
oocDetected = _oocre.match(msg)
# Somewhat-improved matching.
@@ -630,6 +685,7 @@ def _is_ooc(msg, strict=True):
return True
return False
+
def kxhandleInput(ctx, text=None, flavor=None):
"""The function that user input that should be sent to the server is routed
through. Handles lexing, splitting, and quirk application, as well as
@@ -680,7 +736,7 @@ def kxhandleInput(ctx, text=None, flavor=None):
# I'm pretty sure that putting a space before a /me *should* break the
# /me, but in practice, that's not the case.
is_action = msg.startswith("/me")
-
+
# Begin message processing.
# We use 'text' despite its lack of processing because it's simpler.
if should_quirk and not (is_action or is_ooc):
@@ -706,8 +762,8 @@ def kxhandleInput(ctx, text=None, flavor=None):
msgbox.setInformativeText(err_info)
msgbox.exec()
return
-
- PchumLog.info("--> recv \"%s\"" % msg)
+
+ 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):
@@ -718,23 +774,21 @@ def kxhandleInput(ctx, text=None, flavor=None):
# an object type I provided - just so I could pluck them out
# later.
msg[i] = m.convert(format="ctag")
- msg = ''.join(msg)
+ msg = "".join(msg)
# Quirks have been applied. Lex the messages (finally).
msg = kxlexMsg(msg)
# Debug output.
- #try:
+ # try:
# print(repr(msg))
- #except Exception as err:
+ # except Exception as err:
# print("(Couldn't print lexed message: {!s})".format(err))
# Remove coloring if this is a /me!
if is_action:
# Filter out formatting specifiers (just ctags, at the moment).
- msg = [m for m in msg if not isinstance(m,
- (lexercon.CTag, lexercon.CTagEnd)
- )]
+ msg = [m for m in msg if not isinstance(m, (lexercon.CTag, lexercon.CTagEnd))]
# We'll also add /me to the beginning of any new messages, later.
# Put what's necessary in before splitting.
@@ -752,9 +806,11 @@ def kxhandleInput(ctx, text=None, flavor=None):
# We'll use those later.
# Split the messages so we don't go over the buffer and lose text.
- maxlen = _max_msg_len(None, None, ctx.mainwindow.profile().handle, ctx.mainwindow.irc.cli.realname)
- # ctx.mainwindow.profile().handle ==> Get handle
- # ctx.mainwindow.irc.cli.realname ==> Get ident (Same as realname in this case.)
+ maxlen = _max_msg_len(
+ None, None, ctx.mainwindow.profile().handle, ctx.mainwindow.irc.cli.realname
+ )
+ # ctx.mainwindow.profile().handle ==> Get handle
+ # ctx.mainwindow.irc.cli.realname ==> Get ident (Same as realname in this case.)
# Since we have to do some post-processing, we need to adjust the maximum
# length we can use.
if flavor == "convo":
@@ -775,10 +831,8 @@ def kxhandleInput(ctx, text=None, flavor=None):
# Pester message handling.
if flavor == "convo":
# if ceased, rebegin
- if hasattr(ctx, 'chumopen') and not ctx.chumopen:
- ctx.mainwindow.newConvoStarted.emit(
- QString(ctx.title()), True
- )
+ if hasattr(ctx, "chumopen") and not ctx.chumopen:
+ ctx.mainwindow.newConvoStarted.emit(QString(ctx.title()), True)
ctx.setChumOpen(True)
# Post-process and send the messages.
@@ -804,11 +858,10 @@ def kxhandleInput(ctx, text=None, flavor=None):
# construct the messages.
clientMsg = "{2}{3}{4}: {0}".format(
- clientMsg, colorcmd, grammar.pcf, initials, grammar.number
- )
+ clientMsg, colorcmd, grammar.pcf, initials, grammar.number
+ )
# Not sure if this needs a space at the end...?
- serverMsg = "{2}: {0}".format(
- serverMsg, colorcmd, initials)
+ serverMsg = "{2}: {0}".format(serverMsg, colorcmd, initials)
ctx.addMessage(clientMsg, True)
if flavor != "menus":
@@ -825,7 +878,14 @@ def addTimeInitial(string, grammar):
# support Doc Scratch mode
if (endoftag < 0 or endoftag > 16) or (endofi < 0 or endofi > 17):
return string
- return string[0:endoftag+1]+grammar.pcf+string[endoftag+1:endofi]+grammar.number+string[endofi:]
+ return (
+ string[0 : endoftag + 1]
+ + grammar.pcf
+ + string[endoftag + 1 : endofi]
+ + grammar.number
+ + string[endofi:]
+ )
+
def timeProtocol(cmd):
dir = cmd[0]
@@ -836,31 +896,32 @@ def timeProtocol(cmd):
try:
l = [int(x) for x in cmd.split(":")]
except ValueError:
- l = [0,0]
- timed = timedelta(0, l[0]*3600+l[1]*60)
+ l = [0, 0]
+ timed = timedelta(0, l[0] * 3600 + l[1] * 60)
if dir == "P":
- timed = timed*-1
+ timed = timed * -1
return timed
+
def timeDifference(td):
- if td == timedelta(microseconds=1): # mysteryTime replacement :(
+ if td == timedelta(microseconds=1): # mysteryTime replacement :(
return "??:?? FROM ????"
if td < timedelta(0):
when = "AGO"
else:
when = "FROM NOW"
atd = abs(td)
- minutes = (atd.days*86400 + atd.seconds) // 60
+ minutes = (atd.days * 86400 + atd.seconds) // 60
hours = minutes // 60
leftoverminutes = minutes % 60
if atd == timedelta(0):
timetext = "RIGHT NOW"
- elif atd < timedelta(0,3600):
+ elif atd < timedelta(0, 3600):
if minutes == 1:
timetext = "%d MINUTE %s" % (minutes, when)
else:
timetext = "%d MINUTES %s" % (minutes, when)
- elif atd < timedelta(0,3600*100):
+ elif atd < timedelta(0, 3600 * 100):
if hours == 1 and leftoverminutes == 0:
timetext = "%d:%02d HOUR %s" % (hours, leftoverminutes, when)
else:
@@ -869,16 +930,20 @@ def timeDifference(td):
timetext = "%d HOURS %s" % (hours, when)
return timetext
+
def nonerep(text):
return text
+
class parseLeaf(object):
def __init__(self, function, parent):
self.nodes = []
self.function = function
self.parent = parent
+
def append(self, node):
self.nodes.append(node)
+
def expand(self, mo):
out = ""
for n in self.nodes:
@@ -891,12 +956,15 @@ class parseLeaf(object):
out = self.function(out)
return out
+
class backreference(object):
def __init__(self, number):
self.number = number
+
def __str__(self):
return self.number
+
def parseRegexpFunctions(to):
parsed = parseLeaf(nonerep, None)
current = parsed
@@ -907,7 +975,7 @@ def parseRegexpFunctions(to):
mo = _functionre.search(tmp)
if mo is not None:
if mo.start() > 0:
- current.append(to[curi:curi+mo.start()])
+ current.append(to[curi : curi + mo.start()])
backr = _groupre.search(mo.group())
if backr is not None:
current.append(backreference(backr.group(1)))
@@ -920,7 +988,7 @@ def parseRegexpFunctions(to):
current = current.parent
else:
current.append(")")
- curi = mo.end()+curi
+ curi = mo.end() + curi
else:
current.append(to[curi:])
curi = len(to)
@@ -929,11 +997,14 @@ def parseRegexpFunctions(to):
def img2smiley(string):
string = str(string)
+
def imagerep(mo):
return reverse_smiley[mo.group(1)]
+
string = re.sub(r'', imagerep, string)
return string
+
smiledict = {
":rancorous:": "pc_rancorous.png",
":apple:": "apple.png",
@@ -998,78 +1069,166 @@ smiledict = {
":scorpio:": "scorpio.gif",
":shades:": "shades.png",
":honk:": "honk.png",
- }
+}
-reverse_smiley = dict((v,k) for k, v in smiledict.items())
+reverse_smiley = dict((v, k) for k, v in smiledict.items())
_smilere = re.compile("|".join(list(smiledict.keys())))
+
class ThemeException(Exception):
def __init__(self, value):
self.parameter = value
+
def __str__(self):
return repr(self.parameter)
+
def themeChecker(theme):
- needs = ["main/size", "main/icon", "main/windowtitle", "main/style", \
- "main/background-image", "main/menubar/style", "main/menu/menuitem", \
- "main/menu/style", "main/menu/selected", "main/close/image", \
- "main/close/loc", "main/minimize/image", "main/minimize/loc", \
- "main/menu/loc", "main/menus/client/logviewer", \
- "main/menus/client/addgroup", "main/menus/client/options", \
- "main/menus/client/exit", "main/menus/client/userlist", \
- "main/menus/client/memos", "main/menus/client/import", \
- "main/menus/client/idle", "main/menus/client/reconnect", \
- "main/menus/client/_name", "main/menus/profile/quirks", \
- "main/menus/profile/block", "main/menus/profile/color", \
- "main/menus/profile/switch", "main/menus/profile/_name", \
- "main/menus/help/about", "main/menus/help/_name", "main/moodlabel/text", \
- "main/moodlabel/loc", "main/moodlabel/style", "main/moods", \
- "main/addchum/style", "main/addchum/text", "main/addchum/size", \
- "main/addchum/loc", "main/pester/text", "main/pester/size", \
- "main/pester/loc", "main/block/text", "main/block/size", "main/block/loc", \
- "main/mychumhandle/label/text", "main/mychumhandle/label/loc", \
- "main/mychumhandle/label/style", "main/mychumhandle/handle/loc", \
- "main/mychumhandle/handle/size", "main/mychumhandle/handle/style", \
- "main/mychumhandle/colorswatch/size", "main/mychumhandle/colorswatch/loc", \
- "main/defaultmood", "main/chums/size", "main/chums/loc", \
- "main/chums/style", "main/menus/rclickchumlist/pester", \
- "main/menus/rclickchumlist/removechum", \
- "main/menus/rclickchumlist/blockchum", "main/menus/rclickchumlist/viewlog", \
- "main/menus/rclickchumlist/removegroup", \
- "main/menus/rclickchumlist/renamegroup", \
- "main/menus/rclickchumlist/movechum", "convo/size", \
- "convo/tabwindow/style", "convo/tabs/tabstyle", "convo/tabs/style", \
- "convo/tabs/selectedstyle", "convo/style", "convo/margins", \
- "convo/chumlabel/text", "convo/chumlabel/style", "convo/chumlabel/align/h", \
- "convo/chumlabel/align/v", "convo/chumlabel/maxheight", \
- "convo/chumlabel/minheight", "main/menus/rclickchumlist/quirksoff", \
- "main/menus/rclickchumlist/addchum", "main/menus/rclickchumlist/blockchum", \
- "main/menus/rclickchumlist/unblockchum", \
- "main/menus/rclickchumlist/viewlog", "main/trollslum/size", \
- "main/trollslum/style", "main/trollslum/label/text", \
- "main/trollslum/label/style", "main/menus/profile/block", \
- "main/chums/moods/blocked/icon", "convo/systemMsgColor", \
- "convo/textarea/style", "convo/text/beganpester", "convo/text/ceasepester", \
- "convo/text/blocked", "convo/text/unblocked", "convo/text/blockedmsg", \
- "convo/text/idle", "convo/input/style", "memos/memoicon", \
- "memos/textarea/style", "memos/systemMsgColor", "convo/text/joinmemo", \
- "memos/input/style", "main/menus/rclickchumlist/banuser", \
- "main/menus/rclickchumlist/opuser", "main/menus/rclickchumlist/voiceuser", \
- "memos/margins", "convo/text/openmemo", "memos/size", "memos/style", \
- "memos/label/text", "memos/label/style", "memos/label/align/h", \
- "memos/label/align/v", "memos/label/maxheight", "memos/label/minheight", \
- "memos/userlist/style", "memos/userlist/width", "memos/time/text/width", \
- "memos/time/text/style", "memos/time/arrows/left", \
- "memos/time/arrows/style", "memos/time/buttons/style", \
- "memos/time/arrows/right", "memos/op/icon", "memos/voice/icon", \
- "convo/text/closememo", "convo/text/kickedmemo", \
- "main/chums/userlistcolor", "main/defaultwindow/style", \
- "main/chums/moods", "main/chums/moods/chummy/icon", "main/menus/help/help", \
- "main/menus/help/calsprite", "main/menus/help/nickserv", "main/menus/help/chanserv", \
- "main/menus/rclickchumlist/invitechum", "main/menus/client/randen", \
- "main/menus/rclickchumlist/memosetting", "main/menus/rclickchumlist/memonoquirk", \
- "main/menus/rclickchumlist/memohidden", "main/menus/rclickchumlist/memoinvite", \
- "main/menus/rclickchumlist/memomute", "main/menus/rclickchumlist/notes"]
+ needs = [
+ "main/size",
+ "main/icon",
+ "main/windowtitle",
+ "main/style",
+ "main/background-image",
+ "main/menubar/style",
+ "main/menu/menuitem",
+ "main/menu/style",
+ "main/menu/selected",
+ "main/close/image",
+ "main/close/loc",
+ "main/minimize/image",
+ "main/minimize/loc",
+ "main/menu/loc",
+ "main/menus/client/logviewer",
+ "main/menus/client/addgroup",
+ "main/menus/client/options",
+ "main/menus/client/exit",
+ "main/menus/client/userlist",
+ "main/menus/client/memos",
+ "main/menus/client/import",
+ "main/menus/client/idle",
+ "main/menus/client/reconnect",
+ "main/menus/client/_name",
+ "main/menus/profile/quirks",
+ "main/menus/profile/block",
+ "main/menus/profile/color",
+ "main/menus/profile/switch",
+ "main/menus/profile/_name",
+ "main/menus/help/about",
+ "main/menus/help/_name",
+ "main/moodlabel/text",
+ "main/moodlabel/loc",
+ "main/moodlabel/style",
+ "main/moods",
+ "main/addchum/style",
+ "main/addchum/text",
+ "main/addchum/size",
+ "main/addchum/loc",
+ "main/pester/text",
+ "main/pester/size",
+ "main/pester/loc",
+ "main/block/text",
+ "main/block/size",
+ "main/block/loc",
+ "main/mychumhandle/label/text",
+ "main/mychumhandle/label/loc",
+ "main/mychumhandle/label/style",
+ "main/mychumhandle/handle/loc",
+ "main/mychumhandle/handle/size",
+ "main/mychumhandle/handle/style",
+ "main/mychumhandle/colorswatch/size",
+ "main/mychumhandle/colorswatch/loc",
+ "main/defaultmood",
+ "main/chums/size",
+ "main/chums/loc",
+ "main/chums/style",
+ "main/menus/rclickchumlist/pester",
+ "main/menus/rclickchumlist/removechum",
+ "main/menus/rclickchumlist/blockchum",
+ "main/menus/rclickchumlist/viewlog",
+ "main/menus/rclickchumlist/removegroup",
+ "main/menus/rclickchumlist/renamegroup",
+ "main/menus/rclickchumlist/movechum",
+ "convo/size",
+ "convo/tabwindow/style",
+ "convo/tabs/tabstyle",
+ "convo/tabs/style",
+ "convo/tabs/selectedstyle",
+ "convo/style",
+ "convo/margins",
+ "convo/chumlabel/text",
+ "convo/chumlabel/style",
+ "convo/chumlabel/align/h",
+ "convo/chumlabel/align/v",
+ "convo/chumlabel/maxheight",
+ "convo/chumlabel/minheight",
+ "main/menus/rclickchumlist/quirksoff",
+ "main/menus/rclickchumlist/addchum",
+ "main/menus/rclickchumlist/blockchum",
+ "main/menus/rclickchumlist/unblockchum",
+ "main/menus/rclickchumlist/viewlog",
+ "main/trollslum/size",
+ "main/trollslum/style",
+ "main/trollslum/label/text",
+ "main/trollslum/label/style",
+ "main/menus/profile/block",
+ "main/chums/moods/blocked/icon",
+ "convo/systemMsgColor",
+ "convo/textarea/style",
+ "convo/text/beganpester",
+ "convo/text/ceasepester",
+ "convo/text/blocked",
+ "convo/text/unblocked",
+ "convo/text/blockedmsg",
+ "convo/text/idle",
+ "convo/input/style",
+ "memos/memoicon",
+ "memos/textarea/style",
+ "memos/systemMsgColor",
+ "convo/text/joinmemo",
+ "memos/input/style",
+ "main/menus/rclickchumlist/banuser",
+ "main/menus/rclickchumlist/opuser",
+ "main/menus/rclickchumlist/voiceuser",
+ "memos/margins",
+ "convo/text/openmemo",
+ "memos/size",
+ "memos/style",
+ "memos/label/text",
+ "memos/label/style",
+ "memos/label/align/h",
+ "memos/label/align/v",
+ "memos/label/maxheight",
+ "memos/label/minheight",
+ "memos/userlist/style",
+ "memos/userlist/width",
+ "memos/time/text/width",
+ "memos/time/text/style",
+ "memos/time/arrows/left",
+ "memos/time/arrows/style",
+ "memos/time/buttons/style",
+ "memos/time/arrows/right",
+ "memos/op/icon",
+ "memos/voice/icon",
+ "convo/text/closememo",
+ "convo/text/kickedmemo",
+ "main/chums/userlistcolor",
+ "main/defaultwindow/style",
+ "main/chums/moods",
+ "main/chums/moods/chummy/icon",
+ "main/menus/help/help",
+ "main/menus/help/calsprite",
+ "main/menus/help/nickserv",
+ "main/menus/help/chanserv",
+ "main/menus/rclickchumlist/invitechum",
+ "main/menus/client/randen",
+ "main/menus/rclickchumlist/memosetting",
+ "main/menus/rclickchumlist/memonoquirk",
+ "main/menus/rclickchumlist/memohidden",
+ "main/menus/rclickchumlist/memoinvite",
+ "main/menus/rclickchumlist/memomute",
+ "main/menus/rclickchumlist/notes",
+ ]
for n in needs:
try:
diff --git a/pesterchum.py b/pesterchum.py
index 30b301e..1c96e7d 100755
--- a/pesterchum.py
+++ b/pesterchum.py
@@ -18,42 +18,41 @@ if os.path.dirname(sys.argv[0]):
import ostools
import nickservmsgs
import pytwmn
-#import console
+
+# import console
from pnc.dep.attrdict import AttrDict
-from profile import (userConfig,
- userProfile,
- pesterTheme,
- PesterLog,
- PesterProfileDB)
-from menus import (PesterChooseQuirks,
- PesterChooseTheme,
- PesterChooseProfile,
- PesterOptions,
- PesterUserlist,
- PesterMemoList,
- LoadingScreen,
- AboutPesterchum,
- UpdatePesterchum,
- AddChumDialog)
-from mood import (Mood,
- PesterMoodAction,
- PesterMoodHandler,
- PesterMoodButton)
+from profile import userConfig, userProfile, pesterTheme, PesterLog, PesterProfileDB
+from menus import (
+ PesterChooseQuirks,
+ PesterChooseTheme,
+ PesterChooseProfile,
+ PesterOptions,
+ PesterUserlist,
+ PesterMemoList,
+ LoadingScreen,
+ AboutPesterchum,
+ UpdatePesterchum,
+ AddChumDialog,
+)
+from mood import Mood, PesterMoodAction, PesterMoodHandler, PesterMoodButton
from dataobjs import PesterProfile, pesterQuirk, pesterQuirks
-from generic import (PesterIcon,
- RightClickTree,
- PesterList,
- CaseInsensitiveDict,
- MovingWindow,
- NoneSound,
- WMButton)
-from convo import (PesterTabWindow,
- PesterConvo)
-from parsetools import (convertTags,
- addTimeInitial,
- themeChecker,
- ThemeException,
- loadQuirks)
+from generic import (
+ PesterIcon,
+ RightClickTree,
+ PesterList,
+ CaseInsensitiveDict,
+ MovingWindow,
+ NoneSound,
+ WMButton,
+)
+from convo import PesterTabWindow, PesterConvo
+from parsetools import (
+ convertTags,
+ addTimeInitial,
+ themeChecker,
+ ThemeException,
+ loadQuirks,
+)
from memos import PesterMemo, MemoTabWindow, TimeTracker
from irc import PesterIRC
from logviewer import PesterLogUserSelect, PesterLogViewer
@@ -77,39 +76,45 @@ loadQuirks()
# Command line options
parser = argparse.ArgumentParser()
-parser.add_argument("--server",
- "-s",
- metavar="ADDRESS",
- help="Specify server override. (legacy)")
-parser.add_argument("--port",
- "-p",
- metavar="PORT",
- help="Specify port override. (legacy)")
-parser.add_argument("--logging",
- "-l",
- metavar="LEVEL",
- default="WARNING",
- help=("Specify level of logging, possible values are:"
- " CRITICAL, ERROR, WARNING, INFO, DEBUG, NOTSET."
- " (https://docs.python.org/3/library/logging.html)"))
-parser.add_argument("--advanced",
- action="store_true",
- help=("Enable 'advanced' mode. Adds an 'advanced' tab"
- " to settings for setting user mode and adds"
- " channel modes in memo titles."
- " This feature is currently not maintained."))
-parser.add_argument("--nohonk",
- action="store_true",
- help="Disables the honk soundeffect 🤡📣")
+parser.add_argument(
+ "--server", "-s", metavar="ADDRESS", help="Specify server override. (legacy)"
+)
+parser.add_argument(
+ "--port", "-p", metavar="PORT", help="Specify port override. (legacy)"
+)
+parser.add_argument(
+ "--logging",
+ "-l",
+ metavar="LEVEL",
+ default="WARNING",
+ help=(
+ "Specify level of logging, possible values are:"
+ " CRITICAL, ERROR, WARNING, INFO, DEBUG, NOTSET."
+ " (https://docs.python.org/3/library/logging.html)"
+ ),
+)
+parser.add_argument(
+ "--advanced",
+ action="store_true",
+ help=(
+ "Enable 'advanced' mode. Adds an 'advanced' tab"
+ " to settings for setting user mode and adds"
+ " channel modes in memo titles."
+ " This feature is currently not maintained."
+ ),
+)
+parser.add_argument(
+ "--nohonk", action="store_true", help="Disables the honk soundeffect 🤡📣"
+)
# Set logging config section, log level is in oppts.
# Logger
-PchumLog = logging.getLogger('pchumLogger')
+PchumLog = logging.getLogger("pchumLogger")
# Handlers
-file_handler = logging.FileHandler(os.path.join(_datadir, 'pesterchum.log'))
+file_handler = logging.FileHandler(os.path.join(_datadir, "pesterchum.log"))
stream_handler = logging.StreamHandler()
# Format
-formatter = logging.Formatter('%(asctime)s - %(module)s - %(levelname)s - %(message)s')
+formatter = logging.Formatter("%(asctime)s - %(module)s - %(levelname)s - %(message)s")
file_handler.setFormatter(formatter)
stream_handler.setFormatter(formatter)
# Add handlers
@@ -119,7 +124,15 @@ PchumLog.addHandler(stream_handler)
# Global variables
BOTNAMES = []
CUSTOMBOTS = ["CALSPRITE", RANDNICK.upper()]
-SERVICES = ["NICKSERV", "CHANSERV", "MEMOSERV", "OPERSERV", "HELPSERV", "HOSTSERV", "BOTSERV"]
+SERVICES = [
+ "NICKSERV",
+ "CHANSERV",
+ "MEMOSERV",
+ "OPERSERV",
+ "HELPSERV",
+ "HOSTSERV",
+ "BOTSERV",
+]
BOTNAMES.extend(CUSTOMBOTS)
BOTNAMES.extend(SERVICES)
# Save the main app. From here, we should be able to get everything else in
@@ -137,44 +150,64 @@ _ARGUMENTS = parser.parse_args()
try:
# PyQt6, QtMultimedia is prefered.
from PyQt6 import QtMultimedia
- #print("Audio module is PyQt6 QtMultimedia.")
+
+ # print("Audio module is PyQt6 QtMultimedia.")
except ImportError:
if ostools.isWin32() or ostools.isOSX():
# PyQt5 QtMultimedia has native backends for MacOS and Windows
try:
from PyQt5 import QtMultimedia
- print("Using PyQt5 QtMultimedia as sound module. (fallback, PyQt6 QtMultimedia not availible)")
+
+ print(
+ "Using PyQt5 QtMultimedia as sound module. (fallback, PyQt6 QtMultimedia not availible)"
+ )
except ImportError:
try:
try:
# Mute pygame support print
- os.environ['PYGAME_HIDE_SUPPORT_PROMPT'] = "hide"
+ os.environ["PYGAME_HIDE_SUPPORT_PROMPT"] = "hide"
except:
pass
import pygame
- print("Using pygame as sound module. (fallback, PyQt6 QtMultimedia and PyQt5 QtMultimedia not availible)")
+
+ print(
+ "Using pygame as sound module. (fallback, PyQt6 QtMultimedia and PyQt5 QtMultimedia not availible)"
+ )
except ImportError:
- print("All possible audio modules failed to import."
- "\nPossible audio modules in order of preference (Windows/MacOS): PyQt6 QtMultimedia > PyQt5 QtMultimedia > pygame")
+ print(
+ "All possible audio modules failed to import."
+ "\nPossible audio modules in order of preference (Windows/MacOS): PyQt6 QtMultimedia > PyQt5 QtMultimedia > pygame"
+ )
elif ostools.isLinux() or True:
# PyQt5 QtMultimedia needs gstreamer on linux, so pygame is prefered.
try:
try:
# Mute pygame support print
- os.environ['PYGAME_HIDE_SUPPORT_PROMPT'] = "hide"
+ os.environ["PYGAME_HIDE_SUPPORT_PROMPT"] = "hide"
except:
pass
import pygame
- print("Using pygame as sound module. (fallback, PyQt6 QtMultimedia not availible)")
+
+ print(
+ "Using pygame as sound module. (fallback, PyQt6 QtMultimedia not availible)"
+ )
except ImportError:
try:
from PyQt5 import QtMultimedia
- print("Using PyQt5 QtMultimedia as sound module. (fallback, PyQt6 QtMultimedia and pygame not availible)")
- print("PyQt5 Multimedia will silently fail without GStreamer with relevant"
- " plugins on Linux, pygame is prefered when using PyQt5.")
+
+ print(
+ "Using PyQt5 QtMultimedia as sound module. (fallback, PyQt6 QtMultimedia and pygame not availible)"
+ )
+ print(
+ "PyQt5 Multimedia will silently fail without GStreamer with relevant"
+ " plugins on Linux, pygame is prefered when using PyQt5."
+ )
except ImportError:
- print("All possible audio modules failed to import."
- "\nLPossible audio modules in order of preference (Linux/Unknown): PyQt6 QtMultimedia > pygame > PyQt5 QtMultimedia")
+ print(
+ "All possible audio modules failed to import."
+ "\nLPossible audio modules in order of preference (Linux/Unknown): PyQt6 QtMultimedia > pygame > PyQt5 QtMultimedia"
+ )
+
class waitingMessageHolder(object):
def __init__(self, mainwindow, **msgfuncs):
@@ -183,11 +216,14 @@ class waitingMessageHolder(object):
self.queue = list(msgfuncs.keys())
if len(self.queue) > 0:
self.mainwindow.updateSystemTray()
+
def waitingHandles(self):
return self.queue
+
def answerMessage(self):
func = self.funcs[self.queue[0]]
func()
+
def messageAnswered(self, handle):
if handle not in self.queue:
return
@@ -195,15 +231,18 @@ class waitingMessageHolder(object):
del self.funcs[handle]
if len(self.queue) == 0:
self.mainwindow.updateSystemTray()
+
def addMessage(self, handle, func):
if handle not in self.funcs:
self.queue.append(handle)
self.funcs[handle] = func
if len(self.queue) > 0:
self.mainwindow.updateSystemTray()
+
def __len__(self):
return len(self.queue)
+
class chumListing(QtWidgets.QTreeWidgetItem):
def __init__(self, chum, window):
super(chumListing, self).__init__([chum.handle])
@@ -212,23 +251,34 @@ class chumListing(QtWidgets.QTreeWidgetItem):
self.handle = chum.handle
self.setMood(Mood("offline"))
self.status = None
- self.setToolTip(0, "%s: %s" % (chum.handle, window.chumdb.getNotes(chum.handle)))
+ self.setToolTip(
+ 0, "%s: %s" % (chum.handle, window.chumdb.getNotes(chum.handle))
+ )
+
def setMood(self, mood):
if hasattr(self.mainwindow, "chumList") and self.mainwindow.chumList.notify:
- #print "%s -> %s" % (self.chum.mood.name(), mood.name())
- if self.mainwindow.config.notifyOptions() & self.mainwindow.config.SIGNOUT and \
- mood.name() == "offline" and self.chum.mood.name() != "offline":
- #print "OFFLINE NOTIFY: " + self.handle
+ # print "%s -> %s" % (self.chum.mood.name(), mood.name())
+ if (
+ self.mainwindow.config.notifyOptions() & self.mainwindow.config.SIGNOUT
+ and mood.name() == "offline"
+ and self.chum.mood.name() != "offline"
+ ):
+ # print "OFFLINE NOTIFY: " + self.handle
uri = self.mainwindow.theme["toasts/icon/signout"]
- n = self.mainwindow.tm.Toast(self.mainwindow.tm.appName,
- "%s is Offline" % (self.handle), uri)
+ n = self.mainwindow.tm.Toast(
+ self.mainwindow.tm.appName, "%s is Offline" % (self.handle), uri
+ )
n.show()
- elif self.mainwindow.config.notifyOptions() & self.mainwindow.config.SIGNIN and \
- mood.name() != "offline" and self.chum.mood.name() == "offline":
- #print "ONLINE NOTIFY: " + self.handle
+ elif (
+ self.mainwindow.config.notifyOptions() & self.mainwindow.config.SIGNIN
+ and mood.name() != "offline"
+ and self.chum.mood.name() == "offline"
+ ):
+ # print "ONLINE NOTIFY: " + self.handle
uri = self.mainwindow.theme["toasts/icon/signin"]
- n = self.mainwindow.tm.Toast(self.mainwindow.tm.appName,
- "%s is Online" % (self.handle), uri)
+ n = self.mainwindow.tm.Toast(
+ self.mainwindow.tm.appName, "%s is Online" % (self.handle), uri
+ )
n.show()
login = False
logout = False
@@ -238,8 +288,10 @@ class chumListing(QtWidgets.QTreeWidgetItem):
login = True
self.chum.mood = mood
self.updateMood(login=login, logout=logout)
+
def setColor(self, color):
self.chum.color = color
+
def updateMood(self, unblock=False, login=False, logout=False):
mood = self.chum.mood
self.mood = mood
@@ -251,37 +303,76 @@ class chumListing(QtWidgets.QTreeWidgetItem):
else:
self.setIcon(0, icon)
try:
- self.setForeground(0, QtGui.QBrush(QtGui.QColor(self.mainwindow.theme["main/chums/moods"][self.mood.name()]["color"])))
+ self.setForeground(
+ 0,
+ QtGui.QBrush(
+ QtGui.QColor(
+ self.mainwindow.theme["main/chums/moods"][self.mood.name()][
+ "color"
+ ]
+ )
+ ),
+ )
except KeyError:
- self.setForeground(0, QtGui.QBrush(QtGui.QColor(self.mainwindow.theme["main/chums/moods/chummy/color"])))
+ self.setForeground(
+ 0,
+ QtGui.QBrush(
+ QtGui.QColor(self.mainwindow.theme["main/chums/moods/chummy/color"])
+ ),
+ )
+
def changeTheme(self, theme):
icon = self.mood.icon(theme)
self.setIcon(0, icon)
try:
- self.setForeground(0, QtGui.QBrush(QtGui.QColor((self.mainwindow.theme["main/chums/moods"][self.mood.name()]["color"]))))
+ self.setForeground(
+ 0,
+ QtGui.QBrush(
+ QtGui.QColor(
+ (
+ self.mainwindow.theme["main/chums/moods"][self.mood.name()][
+ "color"
+ ]
+ )
+ )
+ ),
+ )
except KeyError:
- self.setForeground(0, QtGui.QBrush(QtGui.QColor((self.mainwindow.theme["main/chums/moods/chummy/color"]))))
+ self.setForeground(
+ 0,
+ QtGui.QBrush(
+ QtGui.QColor(
+ (self.mainwindow.theme["main/chums/moods/chummy/color"])
+ )
+ ),
+ )
+
def login(self):
self.setIcon(0, PesterIcon("themes/arrow_right.png"))
self.status = "in"
QtCore.QTimer.singleShot(5000, self.doneLogin)
+
def doneLogin(self):
icon = self.mood.icon(self.mainwindow.theme)
self.setIcon(0, icon)
+
def logout(self):
self.setIcon(0, PesterIcon("themes/arrow_left.png"))
self.status = "out"
QtCore.QTimer.singleShot(5000, self.doneLogout)
+
def doneLogout(self):
hideoff = self.mainwindow.config.hideOfflineChums()
icon = self.mood.icon(self.mainwindow.theme)
self.setIcon(0, icon)
if hideoff and self.status and self.status == "out":
self.mainwindow.chumList.takeItem(self)
+
def __lt__(self, cl):
h1 = self.handle.lower()
h2 = cl.handle.lower()
- return (h1 < h2)
+ return h1 < h2
+
class chumArea(RightClickTree):
# This is the class that controls the actual main chumlist, I think.
@@ -304,23 +395,39 @@ class chumArea(RightClickTree):
self.groupMenu = QtWidgets.QMenu(self)
self.canonMenu = QtWidgets.QMenu(self)
self.optionsMenu = QtWidgets.QMenu(self)
- self.pester = QAction(self.mainwindow.theme["main/menus/rclickchumlist/pester"], self)
+ self.pester = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/pester"], self
+ )
self.pester.triggered.connect(self.activateChum)
- self.removechum = QAction(self.mainwindow.theme["main/menus/rclickchumlist/removechum"], self)
+ self.removechum = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/removechum"], self
+ )
self.removechum.triggered.connect(self.removeChum)
- self.blockchum = QAction(self.mainwindow.theme["main/menus/rclickchumlist/blockchum"], self)
+ self.blockchum = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/blockchum"], self
+ )
self.blockchum.triggered.connect(self.blockChum)
- self.logchum = QAction(self.mainwindow.theme["main/menus/rclickchumlist/viewlog"], self)
+ self.logchum = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/viewlog"], self
+ )
self.logchum.triggered.connect(self.openChumLogs)
- self.reportchum = QAction(self.mainwindow.theme["main/menus/rclickchumlist/report"], self)
+ self.reportchum = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/report"], self
+ )
self.reportchum.triggered.connect(self.reportChum)
self.findalts = QAction("Find Alts", self)
self.findalts.triggered.connect(self.findAlts)
- self.removegroup = QAction(self.mainwindow.theme["main/menus/rclickchumlist/removegroup"], self)
+ self.removegroup = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/removegroup"], self
+ )
self.removegroup.triggered.connect(self.removeGroup)
- self.renamegroup = QAction(self.mainwindow.theme["main/menus/rclickchumlist/renamegroup"], self)
+ self.renamegroup = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/renamegroup"], self
+ )
self.renamegroup.triggered.connect(self.renameGroup)
- self.notes = QAction(self.mainwindow.theme["main/menus/rclickchumlist/notes"], self)
+ self.notes = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/notes"], self
+ )
self.notes.triggered.connect(self.editNotes)
self.optionsMenu.addAction(self.pester)
@@ -328,7 +435,9 @@ class chumArea(RightClickTree):
self.optionsMenu.addAction(self.notes)
self.optionsMenu.addAction(self.blockchum)
self.optionsMenu.addAction(self.removechum)
- self.moveMenu = QtWidgets.QMenu(self.mainwindow.theme["main/menus/rclickchumlist/movechum"], self)
+ self.moveMenu = QtWidgets.QMenu(
+ self.mainwindow.theme["main/menus/rclickchumlist/movechum"], self
+ )
self.optionsMenu.addMenu(self.moveMenu)
self.optionsMenu.addAction(self.reportchum)
self.moveGroupMenu()
@@ -345,8 +454,8 @@ class chumArea(RightClickTree):
self.canonMenu.addAction(self.findalts)
self.initTheme(theme)
- #self.sortItems()
- #self.sortItems(1, QtCore.Qt.SortOrder.AscendingOrder)
+ # self.sortItems()
+ # self.sortItems(1, QtCore.Qt.SortOrder.AscendingOrder)
self.setSortingEnabled(False)
self.header().hide()
self.setDropIndicatorShown(True)
@@ -368,34 +477,36 @@ class chumArea(RightClickTree):
return None
text = str(self.currentItem().text(0))
if text.rfind(" (") != -1:
- text = text[0:text.rfind(" (")]
+ text = text[0 : text.rfind(" (")]
if text == "Chums":
return None
elif text in self.groups:
return self.groupMenu
else:
- #currenthandle = self.currentItem().chum.handle
-
- #if currenthandle in canon_handles:
+ # currenthandle = self.currentItem().chum.handle
+
+ # if currenthandle in canon_handles:
# return self.canonMenu
- #else:
+ # else:
return self.optionsMenu
def startDrag(self, dropAction):
-## Traceback (most recent call last):
-## File "pesterchum.py", line 355, in startDrag
-## mime.setData('application/x-item', '???')
-## TypeErroreError: setData(self, str, Union[QByteArray, bytes, bytearray]): argument 2 has unexpected type 'str'
+ ## Traceback (most recent call last):
+ ## File "pesterchum.py", line 355, in startDrag
+ ## mime.setData('application/x-item', '???')
+ ## TypeErroreError: setData(self, str, Union[QByteArray, bytes, bytearray]): argument 2 has unexpected type 'str'
try:
# create mime data object
mime = QtCore.QMimeData()
- mime.setData('application/x-item', QtCore.QByteArray()) # Voodoo programming :"3
+ mime.setData(
+ "application/x-item", QtCore.QByteArray()
+ ) # Voodoo programming :"3
# start drag
drag = QtGui.QDrag(self)
drag.setMimeData(mime)
drag.exec(QtCore.Qt.DropAction.MoveAction)
except:
- logging.exception('')
+ logging.exception("")
def dragMoveEvent(self, event):
if event.mimeData().hasFormat("application/x-item"):
@@ -405,24 +516,24 @@ class chumArea(RightClickTree):
event.ignore()
def dragEnterEvent(self, event):
- if (event.mimeData().hasFormat('application/x-item')):
+ if event.mimeData().hasFormat("application/x-item"):
event.accept()
else:
event.ignore()
def dropEvent(self, event):
- if (event.mimeData().hasFormat('application/x-item')):
+ if event.mimeData().hasFormat("application/x-item"):
event.acceptProposedAction()
else:
event.ignore()
return
thisitem = str(event.source().currentItem().text(0))
if thisitem.rfind(" (") != -1:
- thisitem = thisitem[0:thisitem.rfind(" (")]
+ thisitem = thisitem[0 : thisitem.rfind(" (")]
# Drop item is a group
thisitem = str(event.source().currentItem().text(0))
if thisitem.rfind(" (") != -1:
- thisitem = thisitem[0:thisitem.rfind(" (")]
+ thisitem = thisitem[0 : thisitem.rfind(" (")]
if thisitem == "Chums" or thisitem in self.groups:
try:
# PyQt6
@@ -430,10 +541,11 @@ class chumArea(RightClickTree):
except AttributeError:
# PyQt5
droppos = self.itemAt(event.pos())
- if not droppos: return
+ if not droppos:
+ return
droppos = str(droppos.text(0))
if droppos.rfind(" ") != -1:
- droppos = droppos[0:droppos.rfind(" ")]
+ droppos = droppos[0 : droppos.rfind(" ")]
if droppos == "Chums" or droppos in self.groups:
saveOpen = event.source().currentItem().isExpanded()
try:
@@ -442,8 +554,12 @@ class chumArea(RightClickTree):
except AttributeError:
# PyQt5
saveDrop = self.itemAt(event.pos())
- saveItem = self.takeTopLevelItem(self.indexOfTopLevelItem(event.source().currentItem()))
- self.insertTopLevelItems(self.indexOfTopLevelItem(saveDrop)+1, [saveItem])
+ saveItem = self.takeTopLevelItem(
+ self.indexOfTopLevelItem(event.source().currentItem())
+ )
+ self.insertTopLevelItems(
+ self.indexOfTopLevelItem(saveDrop) + 1, [saveItem]
+ )
if saveOpen:
saveItem.setExpanded(True)
@@ -451,7 +567,7 @@ class chumArea(RightClickTree):
for i in range(self.topLevelItemCount()):
text = str(self.topLevelItem(i).text(0))
if text.rfind(" (") != -1:
- text = text[0:text.rfind(" (")]
+ text = text[0 : text.rfind(" (")]
gTemp.append([str(text), self.topLevelItem(i).isExpanded()])
self.mainwindow.config.saveGroups(gTemp)
# Drop item is a chum
@@ -467,14 +583,14 @@ class chumArea(RightClickTree):
text = str(item.text(0))
# Figure out which group to drop into
if text.rfind(" (") != -1:
- text = text[0:text.rfind(" (")]
+ text = text[0 : text.rfind(" (")]
if text == "Chums" or text in self.groups:
group = text
gitem = item
else:
ptext = str(item.parent().text(0))
if ptext.rfind(" ") != -1:
- ptext = ptext[0:ptext.rfind(" ")]
+ ptext = ptext[0 : ptext.rfind(" ")]
group = ptext
gitem = item.parent()
@@ -511,7 +627,7 @@ class chumArea(RightClickTree):
else:
text = str(currentGroup.text(0))
if text.rfind(" (") != -1:
- text = text[0:text.rfind(" (")]
+ text = text[0 : text.rfind(" (")]
currentGroup = text
self.moveMenu.clear()
actGroup = QActionGroup(self)
@@ -528,28 +644,36 @@ class chumArea(RightClickTree):
if len([c for c in self.chums if c.handle == chum.handle]) != 0:
return
self.chums.append(chum)
- if not (self.mainwindow.config.hideOfflineChums() and
- chum.mood.name() == "offline"):
+ if not (
+ self.mainwindow.config.hideOfflineChums() and chum.mood.name() == "offline"
+ ):
chumLabel = chumListing(chum, self.mainwindow)
self.addItem(chumLabel)
- #self.topLevelItem(0).addChild(chumLabel)
- #self.topLevelItem(0).sortChildren(0, QtCore.Qt.SortOrder.AscendingOrder)
+ # self.topLevelItem(0).addChild(chumLabel)
+ # self.topLevelItem(0).sortChildren(0, QtCore.Qt.SortOrder.AscendingOrder)
def getChums(self, handle):
- chums = self.findItems(handle, QtCore.Qt.MatchFlag.MatchExactly
- | QtCore.Qt.MatchFlag.MatchRecursive)
+ chums = self.findItems(
+ handle,
+ QtCore.Qt.MatchFlag.MatchExactly | QtCore.Qt.MatchFlag.MatchRecursive,
+ )
return chums
def showAllChums(self):
for c in self.chums:
chandle = c.handle
- if not len(self.findItems(chandle,
- QtCore.Qt.MatchFlag.MatchExactly
- | QtCore.Qt.MatchFlag.MatchRecursive)):
- #if True:# For if it doesn't work at all :/
+ if not len(
+ self.findItems(
+ chandle,
+ QtCore.Qt.MatchFlag.MatchExactly
+ | QtCore.Qt.MatchFlag.MatchRecursive,
+ )
+ ):
+ # if True:# For if it doesn't work at all :/
chumLabel = chumListing(c, self.mainwindow)
self.addItem(chumLabel)
self.sort()
+
def hideOfflineChums(self):
for j in range(self.topLevelItemCount()):
i = 0
@@ -561,9 +685,10 @@ class chumArea(RightClickTree):
i += 1
listing = self.topLevelItem(j).child(i)
self.sort()
+
def showAllGroups(self, first=False):
if first:
- for i,g in enumerate(self.groups):
+ for i, g in enumerate(self.groups):
child_1 = QtWidgets.QTreeWidgetItem(["%s" % (g)])
self.addTopLevelItem(child_1)
if self.openGroups[i]:
@@ -573,9 +698,9 @@ class chumArea(RightClickTree):
for i in range(self.topLevelItemCount()):
text = str(self.topLevelItem(i).text(0))
if text.rfind(" (") != -1:
- text = text[0:text.rfind(" (")]
+ text = text[0 : text.rfind(" (")]
curgroups.append(text)
- for i,g in enumerate(self.groups):
+ for i, g in enumerate(self.groups):
if g not in curgroups:
child_1 = QtWidgets.QTreeWidgetItem(["%s" % (g)])
j = 0
@@ -589,40 +714,45 @@ class chumArea(RightClickTree):
child_1.setExpanded(True)
if self.mainwindow.config.showOnlineNumbers():
self.showOnlineNumbers()
+
def showOnlineNumbers(self):
- if hasattr(self, 'groups'):
+ if hasattr(self, "groups"):
self.hideOnlineNumbers()
- totals = {'Chums': 0}
- online = {'Chums': 0}
+ totals = {"Chums": 0}
+ online = {"Chums": 0}
for g in self.groups:
totals[str(g)] = 0
online[str(g)] = 0
for c in self.chums:
yes = c.mood.name() != "offline"
if c.group == "Chums":
- totals[str(c.group)] = totals[str(c.group)]+1
+ totals[str(c.group)] = totals[str(c.group)] + 1
if yes:
- online[str(c.group)] = online[str(c.group)]+1
+ online[str(c.group)] = online[str(c.group)] + 1
elif c.group in totals:
- totals[str(c.group)] = totals[str(c.group)]+1
+ totals[str(c.group)] = totals[str(c.group)] + 1
if yes:
- online[str(c.group)] = online[str(c.group)]+1
+ online[str(c.group)] = online[str(c.group)] + 1
else:
- totals["Chums"] = totals["Chums"]+1
+ totals["Chums"] = totals["Chums"] + 1
if yes:
- online["Chums"] = online["Chums"]+1
+ online["Chums"] = online["Chums"] + 1
for i in range(self.topLevelItemCount()):
text = str(self.topLevelItem(i).text(0))
if text.rfind(" (") != -1:
- text = text[0:text.rfind(" (")]
+ text = text[0 : text.rfind(" (")]
if text in online:
- self.topLevelItem(i).setText(0, "%s (%i/%i)" % (text, online[text], totals[text]))
+ self.topLevelItem(i).setText(
+ 0, "%s (%i/%i)" % (text, online[text], totals[text])
+ )
+
def hideOnlineNumbers(self):
for i in range(self.topLevelItemCount()):
text = str(self.topLevelItem(i).text(0))
if text.rfind(" (") != -1:
- text = text[0:text.rfind(" (")]
+ text = text[0 : text.rfind(" (")]
self.topLevelItem(i).setText(0, "%s" % (text))
+
def hideEmptyGroups(self):
i = 0
listing = self.topLevelItem(i)
@@ -632,18 +762,20 @@ class chumArea(RightClickTree):
else:
i += 1
listing = self.topLevelItem(i)
+
@QtCore.pyqtSlot()
def expandGroup(self):
item = self.currentItem()
text = str(item.text(0))
if text.rfind(" (") != -1:
- text = text[0:text.rfind(" (")]
+ text = text[0 : text.rfind(" (")]
if text in self.groups:
expand = item.isExpanded()
self.mainwindow.config.expandGroup(text, not expand)
+
def addItem(self, chumLabel):
- if hasattr(self, 'groups'):
+ if hasattr(self, "groups"):
if chumLabel.chum.group not in self.groups:
chumLabel.chum.group = "Chums"
if "Chums" not in self.groups:
@@ -652,12 +784,13 @@ class chumArea(RightClickTree):
for i in range(self.topLevelItemCount()):
text = str(self.topLevelItem(i).text(0))
if text.rfind(" (") != -1:
- text = text[0:text.rfind(" (")]
+ text = text[0 : text.rfind(" (")]
curgroups.append(text)
- if not self.findItems(chumLabel.handle,
- QtCore.Qt.MatchFlag.MatchExactly
- | QtCore.Qt.MatchFlag.MatchRecursive):
- #if True:# For if it doesn't work at all :/
+ if not self.findItems(
+ chumLabel.handle,
+ QtCore.Qt.MatchFlag.MatchExactly | QtCore.Qt.MatchFlag.MatchRecursive,
+ ):
+ # if True:# For if it doesn't work at all :/
if chumLabel.chum.group not in curgroups:
child_1 = QtWidgets.QTreeWidgetItem(["%s" % (chumLabel.chum.group)])
i = 0
@@ -667,12 +800,14 @@ class chumArea(RightClickTree):
break
if g in curgroups:
i += 1
- if self.openGroups[self.groups.index("%s" % (chumLabel.chum.group))]:
+ if self.openGroups[
+ self.groups.index("%s" % (chumLabel.chum.group))
+ ]:
child_1.setExpanded(True)
for i in range(self.topLevelItemCount()):
text = str(self.topLevelItem(i).text(0))
if text.rfind(" (") != -1:
- text = text[0:text.rfind(" (")]
+ text = text[0 : text.rfind(" (")]
if text == chumLabel.chum.group:
break
# Manual sorting
@@ -690,34 +825,38 @@ class chumArea(RightClickTree):
if fi > 0:
while not bestj:
for j in range(self.topLevelItem(i).childCount()):
- if chums[fi-c] == str(self.topLevelItem(i).child(j).text(0)):
+ if chums[fi - c] == str(
+ self.topLevelItem(i).child(j).text(0)
+ ):
bestj = j
- bestname = chums[fi-c]
+ bestname = chums[fi - c]
break
c += 1
- if fi-c < 0:
+ if fi - c < 0:
break
if bestname:
- self.topLevelItem(i).insertChild(bestj+1, chumLabel)
+ self.topLevelItem(i).insertChild(bestj + 1, chumLabel)
else:
self.topLevelItem(i).insertChild(bestj, chumLabel)
- #sys.exit(0)
+ # sys.exit(0)
self.topLevelItem(i).addChild(chumLabel)
- else: # All other sorting
+ else: # All other sorting
self.topLevelItem(i).addChild(chumLabel)
self.sort()
if self.mainwindow.config.showOnlineNumbers():
self.showOnlineNumbers()
- else: # usually means this is now the trollslum
- if not self.findItems(chumLabel.handle,
- QtCore.Qt.MatchFlag.MatchExactly
- | QtCore.Qt.MatchFlag.MatchRecursive):
- #if True:# For if it doesn't work at all :/
+ else: # usually means this is now the trollslum
+ if not self.findItems(
+ chumLabel.handle,
+ QtCore.Qt.MatchFlag.MatchExactly | QtCore.Qt.MatchFlag.MatchRecursive,
+ ):
+ # if True:# For if it doesn't work at all :/
self.topLevelItem(0).addChild(chumLabel)
self.topLevelItem(0).sortChildren(0, QtCore.Qt.SortOrder.AscendingOrder)
+
def takeItem(self, chumLabel):
r = None
- if not hasattr(chumLabel, 'chum'):
+ if not hasattr(chumLabel, "chum"):
return r
for i in range(self.topLevelItemCount()):
for j in range(self.topLevelItem(i).childCount()):
@@ -729,27 +868,31 @@ class chumArea(RightClickTree):
if self.mainwindow.config.showOnlineNumbers():
self.showOnlineNumbers()
return r
+
def updateMood(self, handle, mood):
hideoff = self.mainwindow.config.hideOfflineChums()
chums = self.getChums(handle)
oldmood = None
if hideoff:
- if mood.name() != "offline" and \
- len(chums) == 0 and \
- handle in [p.handle for p in self.chums]:
- newLabel = chumListing([p for p in self.chums if p.handle == handle][0], self.mainwindow)
+ if (
+ mood.name() != "offline"
+ and len(chums) == 0
+ and handle in [p.handle for p in self.chums]
+ ):
+ newLabel = chumListing(
+ [p for p in self.chums if p.handle == handle][0], self.mainwindow
+ )
self.addItem(newLabel)
- #self.sortItems()
+ # self.sortItems()
chums = [newLabel]
- elif mood.name() == "offline" and \
- len(chums) > 0:
+ elif mood.name() == "offline" and len(chums) > 0:
for c in chums:
- if (hasattr(c, 'mood')):
+ if hasattr(c, "mood"):
c.setMood(mood)
- #self.takeItem(c)
+ # self.takeItem(c)
chums = []
for c in chums:
- if (hasattr(c, 'mood')):
+ if hasattr(c, "mood"):
oldmood = c.mood
c.setMood(mood)
if self.mainwindow.config.sortMethod() == 1:
@@ -760,28 +903,34 @@ class chumArea(RightClickTree):
if self.mainwindow.config.showOnlineNumbers():
self.showOnlineNumbers()
return oldmood
+
def updateColor(self, handle, color):
chums = self.findItems(handle, QtCore.Qt.MatchFlag.MatchExactly)
for c in chums:
c.setColor(color)
+
def initTheme(self, theme):
self.resize(*theme["main/chums/size"])
self.move(*theme["main/chums/loc"])
if "main/chums/scrollbar" in theme:
- self.setStyleSheet("QListWidget { %s } \
+ self.setStyleSheet(
+ "QListWidget { %s } \
QScrollBar { %s } \
QScrollBar::handle { %s } \
QScrollBar::add-line { %s } \
QScrollBar::sub-line { %s } \
QScrollBar:up-arrow { %s } \
- QScrollBar:down-arrow { %s }" % \
- (theme["main/chums/style"], \
- theme["main/chums/scrollbar/style"], \
- theme["main/chums/scrollbar/handle"], \
- theme["main/chums/scrollbar/downarrow"], \
- theme["main/chums/scrollbar/uparrow"], \
- theme["main/chums/scrollbar/uarrowstyle"], \
- theme["main/chums/scrollbar/darrowstyle"] ))
+ QScrollBar:down-arrow { %s }"
+ % (
+ theme["main/chums/style"],
+ theme["main/chums/scrollbar/style"],
+ theme["main/chums/scrollbar/handle"],
+ theme["main/chums/scrollbar/downarrow"],
+ theme["main/chums/scrollbar/uparrow"],
+ theme["main/chums/scrollbar/uarrowstyle"],
+ theme["main/chums/scrollbar/darrowstyle"],
+ )
+ )
else:
self.setStyleSheet(theme["main/chums/style"])
self.pester.setText(theme["main/menus/rclickchumlist/pester"])
@@ -793,13 +942,14 @@ class chumArea(RightClickTree):
self.removegroup.setText(theme["main/menus/rclickchumlist/removegroup"])
self.renamegroup.setText(theme["main/menus/rclickchumlist/renamegroup"])
self.moveMenu.setTitle(theme["main/menus/rclickchumlist/movechum"])
+
def changeTheme(self, theme):
self.initTheme(theme)
chumlistings = []
for i in range(self.topLevelItemCount()):
for j in range(self.topLevelItem(i).childCount()):
chumlistings.append(self.topLevelItem(i).child(j))
- #chumlistings = [self.item(i) for i in range(0, self.count())]
+ # chumlistings = [self.item(i) for i in range(0, self.count())]
for c in chumlistings:
c.changeTheme(theme)
@@ -811,13 +961,14 @@ class chumArea(RightClickTree):
def sort(self):
if self.mainwindow.config.sortMethod() == 2:
- pass # Do nothing!!!!! :OOOOOOO It's manual, bitches
+ pass # Do nothing!!!!! :OOOOOOO It's manual, bitches
elif self.mainwindow.config.sortMethod() == 1:
for i in range(self.topLevelItemCount()):
self.moodSort(i)
else:
for i in range(self.topLevelItemCount()):
self.topLevelItem(i).sortChildren(0, QtCore.Qt.SortOrder.AscendingOrder)
+
def moodSort(self, group):
scrollPos = self.verticalScrollBar().sliderPosition()
chums = []
@@ -825,7 +976,13 @@ class chumArea(RightClickTree):
while listing is not None:
chums.append(self.topLevelItem(group).takeChild(0))
listing = self.topLevelItem(group).child(0)
- chums.sort(key=lambda x: ((999 if x.chum.mood.value() == 2 else x.chum.mood.value()), x.chum.handle), reverse=False)
+ chums.sort(
+ key=lambda x: (
+ (999 if x.chum.mood.value() == 2 else x.chum.mood.value()),
+ x.chum.handle,
+ ),
+ reverse=False,
+ )
for c in chums:
self.topLevelItem(group).addChild(c)
self.verticalScrollBar().setSliderPosition(scrollPos)
@@ -833,11 +990,13 @@ class chumArea(RightClickTree):
@QtCore.pyqtSlot()
def activateChum(self):
self.itemActivated.emit(self.currentItem(), 0)
+
@QtCore.pyqtSlot()
- def removeChum(self, handle = None):
+ def removeChum(self, handle=None):
if handle:
clistings = self.getChums(handle)
- if len(clistings) <= 0: return
+ if len(clistings) <= 0:
+ return
for c in clistings:
self.setCurrentItem(c)
if not self.currentItem():
@@ -847,68 +1006,78 @@ class chumArea(RightClickTree):
self.removeChumSignal.emit(self.currentItem().chum.handle)
oldlist = self.takeItem(self.currentItem())
del oldlist
+
@QtCore.pyqtSlot()
def blockChum(self):
currentChum = self.currentItem()
if not currentChum:
return
self.blockChumSignal.emit(self.currentItem().chum.handle)
+
@QtCore.pyqtSlot()
def reportChum(self):
currentChum = self.currentItem()
if not currentChum:
return
self.mainwindow.reportChum(self.currentItem().chum.handle)
+
@QtCore.pyqtSlot()
def findAlts(self):
currentChum = self.currentItem()
if not currentChum:
return
- self.mainwindow.sendMessage.emit("ALT %s" % (currentChum.chum.handle) , "calSprite")
+ self.mainwindow.sendMessage.emit(
+ "ALT %s" % (currentChum.chum.handle), "calSprite"
+ )
+
@QtCore.pyqtSlot()
def openChumLogs(self):
currentChum = self.currentItem()
if not currentChum:
return
currentChum = currentChum.text(0)
- self.pesterlogviewer = PesterLogViewer(currentChum,
- self.mainwindow.config,
- self.mainwindow.theme,
- self.mainwindow)
+ self.pesterlogviewer = PesterLogViewer(
+ currentChum, self.mainwindow.config, self.mainwindow.theme, self.mainwindow
+ )
self.pesterlogviewer.rejected.connect(self.closeActiveLog)
self.pesterlogviewer.show()
self.pesterlogviewer.raise_()
self.pesterlogviewer.activateWindow()
+
@QtCore.pyqtSlot()
def closeActiveLog(self):
self.pesterlogviewer.close()
self.pesterlogviewer = None
+
@QtCore.pyqtSlot()
def editNotes(self):
currentChum = self.currentItem()
if not currentChum:
return
- (notes, ok) = QtWidgets.QInputDialog.getText(self,
- "Notes",
- "Enter your notes...")
+ (notes, ok) = QtWidgets.QInputDialog.getText(
+ self, "Notes", "Enter your notes..."
+ )
if ok:
notes = str(notes)
self.mainwindow.chumdb.setNotes(currentChum.handle, notes)
currentChum.setToolTip(0, "%s: %s" % (currentChum.handle, notes))
+
@QtCore.pyqtSlot()
def renameGroup(self):
- if not hasattr(self, 'renamegroupdialog'):
+ if not hasattr(self, "renamegroupdialog"):
self.renamegroupdialog = None
if not self.renamegroupdialog:
- (gname, ok) = QtWidgets.QInputDialog.getText(self,
- "Rename Group",
- "Enter a new name for the group:")
+ (gname, ok) = QtWidgets.QInputDialog.getText(
+ self, "Rename Group", "Enter a new name for the group:"
+ )
if ok:
gname = str(gname)
if re.search("[^A-Za-z0-9_\s]", gname) is not None:
msgbox = QtWidgets.QMessageBox()
- msgbox.setStyleSheet("QMessageBox{ %s }"
- % self.mainwindow.theme["main/defaultwindow/style"])
+ msgbox.setStyleSheet(
+ "QMessageBox{ %s }"
+ % self.mainwindow.theme["main/defaultwindow/style"]
+ )
msgbox.setInformativeText("THIS IS NOT A VALID GROUP NAME")
msgbox.setStandardButtons(QtWidgets.QMessageBox.StandardButton.Ok)
msgbox.exec()
@@ -922,7 +1091,7 @@ class chumArea(RightClickTree):
expanded = currentGroup.isExpanded()
text = str(currentGroup.text(0))
if text.rfind(" (") != -1:
- text = text[0:text.rfind(" (")]
+ text = text[0 : text.rfind(" (")]
self.mainwindow.config.delGroup(text)
self.mainwindow.config.addGroup(gname, expanded)
gTemp = self.mainwindow.config.getGroups()
@@ -930,11 +1099,14 @@ class chumArea(RightClickTree):
self.openGroups = [g[1] for g in gTemp]
for i in range(currentGroup.childCount()):
currentGroup.child(i).chum.group = gname
- self.mainwindow.chumdb.setGroup(currentGroup.child(i).chum.handle, gname)
+ self.mainwindow.chumdb.setGroup(
+ currentGroup.child(i).chum.handle, gname
+ )
currentGroup.setText(0, gname)
if self.mainwindow.config.showOnlineNumbers():
self.showOnlineNumbers()
self.renamegroupdialog = None
+
@QtCore.pyqtSlot()
def removeGroup(self):
currentGroup = self.currentItem()
@@ -942,7 +1114,7 @@ class chumArea(RightClickTree):
return
text = str(currentGroup.text(0))
if text.rfind(" (") != -1:
- text = text[0:text.rfind(" (")]
+ text = text[0 : text.rfind(" (")]
self.mainwindow.config.delGroup(text)
gTemp = self.mainwindow.config.getGroups()
self.groups = [g[0] for g in gTemp]
@@ -959,6 +1131,7 @@ class chumArea(RightClickTree):
self.takeItem(chumLabel)
self.addItem(chumLabel)
self.takeTopLevelItem(i)
+
@QtCore.pyqtSlot(QAction)
def moveToGroup(self, item):
if not item:
@@ -972,14 +1145,15 @@ class chumArea(RightClickTree):
self.takeItem(chumLabel)
self.addItem(chumLabel)
- removeChumSignal = QtCore.pyqtSignal('QString')
- blockChumSignal = QtCore.pyqtSignal('QString')
+ removeChumSignal = QtCore.pyqtSignal("QString")
+ blockChumSignal = QtCore.pyqtSignal("QString")
+
class trollSlum(chumArea):
unblockChumSignal = QtCore.pyqtSignal()
def __init__(self, trolls, mainwindow, parent=None):
- #~super(trollSlum, self).__init__(parent)
+ # ~super(trollSlum, self).__init__(parent)
# TODO: Rework inheritance here.
QtWidgets.QTreeWidgetItem.__init__(self, parent)
self.mainwindow = mainwindow
@@ -1001,18 +1175,22 @@ class trollSlum(chumArea):
self.setIndentation(0)
self.optionsMenu = QtWidgets.QMenu(self)
- self.unblockchum = QAction(self.mainwindow.theme["main/menus/rclickchumlist/unblockchum"], self)
+ self.unblockchum = QAction(
+ self.mainwindow.theme["main/menus/rclickchumlist/unblockchum"], self
+ )
self.unblockchum.triggered.connect(self.unblockChumSignal)
self.optionsMenu.addAction(self.unblockchum)
- #self.sortItems()
+ # self.sortItems()
+
def contextMenuEvent(self, event):
- #fuckin Qt
+ # fuckin Qt
if event.reason() == QtGui.QContextMenuEvent.Reason.Mouse:
listing = self.itemAt(event.pos())
self.setCurrentItem(listing)
if self.currentItem().text(0) != "":
self.optionsMenu.popup(event.globalPos())
+
def changeTheme(self, theme):
self.setStyleSheet(theme["main/trollslum/chumroll/style"])
self.removechum.setText(theme["main/menus/rclickchumlist/removechum"])
@@ -1026,7 +1204,8 @@ class trollSlum(chumArea):
# TypeError: connect() failed between triggered(bool) and unblockChumSignal()
# I'm not sure why this was here in the first place-
# Does removing it break anything else...?
- #unblockChumSignal = QtCore.pyqtSignal('QString')
+ # unblockChumSignal = QtCore.pyqtSignal('QString')
+
class TrollSlumWindow(QtWidgets.QFrame):
def __init__(self, trolls, mainwindow, parent=None):
@@ -1060,39 +1239,47 @@ class TrollSlumWindow(QtWidgets.QFrame):
if not self.parent():
self.setWindowTitle(theme["main/menus/profile/block"])
self.setWindowIcon(self.mainwindow.windowIcon())
+
def changeTheme(self, theme):
self.initTheme(theme)
self.trollslum.changeTheme(theme)
# move unblocked trolls from slum to chumarea
+
def closeEvent(self, event):
self.mainwindow.closeTrollSlum()
def updateMood(self, handle, mood):
self.trollslum.updateMood(handle, mood)
+
def addTroll(self, chum):
self.trollslum.addChum(chum)
+
def removeTroll(self, handle):
self.trollslum.removeChum(handle)
+
@QtCore.pyqtSlot()
def removeCurrentTroll(self):
currentListing = self.trollslum.currentItem()
- if not currentListing or not hasattr(currentListing, 'chum'):
+ if not currentListing or not hasattr(currentListing, "chum"):
return
self.unblockChumSignal.emit(currentListing.chum.handle)
+
@QtCore.pyqtSlot()
def addTrollWindow(self):
- if not hasattr(self, 'addtrolldialog'):
+ if not hasattr(self, "addtrolldialog"):
self.addtrolldialog = None
if self.addtrolldialog:
return
self.addtrolldialog = QtWidgets.QInputDialog(self)
- (handle, ok) = self.addtrolldialog.getText(self,
- "Add Troll",
- "Enter Troll Handle:")
+ (handle, ok) = self.addtrolldialog.getText(
+ self, "Add Troll", "Enter Troll Handle:"
+ )
if ok:
handle = str(handle)
- if not (PesterProfile.checkLength(handle) and
- PesterProfile.checkValid(handle)[0]):
+ if not (
+ PesterProfile.checkLength(handle)
+ and PesterProfile.checkValid(handle)[0]
+ ):
errormsg = QtWidgets.QErrorMessage(self)
errormsg.showMessage("THIS IS NOT A VALID CHUMTAG!")
self.addchumdialog = None
@@ -1101,17 +1288,22 @@ class TrollSlumWindow(QtWidgets.QFrame):
self.blockChumSignal.emit(handle)
self.addtrolldialog = None
- blockChumSignal = QtCore.pyqtSignal('QString')
- unblockChumSignal = QtCore.pyqtSignal('QString')
+ blockChumSignal = QtCore.pyqtSignal("QString")
+ unblockChumSignal = QtCore.pyqtSignal("QString")
+
class PesterWindow(MovingWindow):
disconnectIRC = QtCore.pyqtSignal()
- sendMessage = QtCore.pyqtSignal('QString', 'QString')
+ sendMessage = QtCore.pyqtSignal("QString", "QString")
def __init__(self, options, parent=None, app=None):
- super(PesterWindow, self).__init__(None,
- (QtCore.Qt.WindowType.CustomizeWindowHint
- | QtCore.Qt.WindowType.FramelessWindowHint))
+ super(PesterWindow, self).__init__(
+ None,
+ (
+ QtCore.Qt.WindowType.CustomizeWindowHint
+ | QtCore.Qt.WindowType.FramelessWindowHint
+ ),
+ )
# For debugging
_CONSOLE_ENV.PAPP = self
@@ -1148,28 +1340,36 @@ class PesterWindow(MovingWindow):
self.userprofile = userProfile(self.config.defaultprofile())
self.theme = self.userprofile.getTheme()
else:
- self.userprofile = userProfile(PesterProfile("pesterClient%d"
- % (random.randint(100,999)),
- QtGui.QColor("black"),
- Mood(0)))
+ self.userprofile = userProfile(
+ PesterProfile(
+ "pesterClient%d" % (random.randint(100, 999)),
+ QtGui.QColor("black"),
+ Mood(0),
+ )
+ )
self.theme = self.userprofile.getTheme()
except Exception as e:
msgBox = QtWidgets.QMessageBox()
msgBox.setIcon(QtWidgets.QMessageBox.Icon.Information)
msgBox.setWindowTitle(":(")
- msgBox.setTextFormat(QtCore.Qt.TextFormat.RichText) # Clickable html links
- self.filename = _datadir+"pesterchum.js"
- msgBox.setText("A profile error occured, "
- "trying to switch to default pesterClient profile."
- "
%s<\h3><\html>" % e)
+ msgBox.setTextFormat(QtCore.Qt.TextFormat.RichText) # Clickable html links
+ self.filename = _datadir + "pesterchum.js"
+ msgBox.setText(
+ "A profile error occured, "
+ "trying to switch to default pesterClient profile."
+ "
%s<\h3><\html>" % e
+ )
PchumLog.critical(e)
msgBox.exec()
- self.userprofile = userProfile(PesterProfile("pesterClient%d"
- % (random.randint(100,999)),
- QtGui.QColor("black"),
- Mood(0)))
+ self.userprofile = userProfile(
+ PesterProfile(
+ "pesterClient%d" % (random.randint(100, 999)),
+ QtGui.QColor("black"),
+ Mood(0),
+ )
+ )
self.theme = self.userprofile.getTheme()
-
+
# karxi: For the record, these are set via commandline arguments. By
# default, they aren't usable any other way - you can't set them via
# the config files.
@@ -1178,7 +1378,7 @@ class PesterWindow(MovingWindow):
#
# This was almost certainly intentional.
if "advanced" in options:
- self.advanced = options["advanced"]
+ self.advanced = options["advanced"]
else:
self.advanced = False
if "server" in options:
@@ -1186,7 +1386,7 @@ class PesterWindow(MovingWindow):
if "port" in options:
self.portOverride = options["port"]
if "honk" in options:
- self.honk = options["honk"]
+ self.honk = options["honk"]
else:
self.honk = True
self.modes = ""
@@ -1204,11 +1404,16 @@ class PesterWindow(MovingWindow):
themeWarning.exec()
self.theme = pesterTheme("pesterchum")
- extraToasts = {'default': PesterToast}
+ extraToasts = {"default": PesterToast}
if pytwmn.confExists():
- extraToasts['twmn'] = pytwmn.Notification
- self.tm = PesterToastMachine(self, lambda: self.theme["main/windowtitle"], on=self.config.notify(),
- type=self.config.notifyType(), extras=extraToasts)
+ extraToasts["twmn"] = pytwmn.Notification
+ self.tm = PesterToastMachine(
+ self,
+ lambda: self.theme["main/windowtitle"],
+ on=self.config.notify(),
+ type=self.config.notifyType(),
+ extras=extraToasts,
+ )
self.tm.run()
self.chatlog = PesterLog(self.profile().handle, self)
@@ -1231,7 +1436,9 @@ class PesterWindow(MovingWindow):
opts.triggered.connect(self.openOpts)
exitaction = QAction(self.theme["main/menus/client/exit"], self)
self.exitaction = exitaction
- exitaction.triggered.connect(self.killApp, QtCore.Qt.ConnectionType.QueuedConnection)
+ exitaction.triggered.connect(
+ self.killApp, QtCore.Qt.ConnectionType.QueuedConnection
+ )
userlistaction = QAction(self.theme["main/menus/client/userlist"], self)
self.userlistaction = userlistaction
userlistaction.triggered.connect(self.showAllUsers)
@@ -1251,33 +1458,41 @@ class PesterWindow(MovingWindow):
self.menu.setObjectName("mainmenu")
if self.theme.has_key("main/menus/client/console"):
- self.console = AttrDict(dict(
- window = None,
- action = QAction(self.theme["main/menus/client/console"], self),
- is_open = False
- ))
+ self.console = AttrDict(
+ dict(
+ window=None,
+ action=QAction(self.theme["main/menus/client/console"], self),
+ is_open=False,
+ )
+ )
else:
- self.console = AttrDict(dict(
- window = None,
- action = QAction("Console", self),
- is_open = False
- ))
- self.console.shortcuts = AttrDict(dict(
- conkey = QShortcut(QtGui.QKeySequence("Ctrl+`"), self,
- context=QtCore.Qt.ShortcutContext.ApplicationShortcut),
- curwgt = QShortcut(QtGui.QKeySequence("Ctrl+Alt+w"), self,
- context=QtCore.Qt.ShortcutContext.ApplicationShortcut)
- ))
+ self.console = AttrDict(
+ dict(window=None, action=QAction("Console", self), is_open=False)
+ )
+ self.console.shortcuts = AttrDict(
+ dict(
+ conkey=QShortcut(
+ QtGui.QKeySequence("Ctrl+`"),
+ self,
+ context=QtCore.Qt.ShortcutContext.ApplicationShortcut,
+ ),
+ curwgt=QShortcut(
+ QtGui.QKeySequence("Ctrl+Alt+w"),
+ self,
+ context=QtCore.Qt.ShortcutContext.ApplicationShortcut,
+ ),
+ )
+ )
self.console.action.triggered.connect(self.toggleConsole)
# Make sure the shortcut works anywhere.
# karxi: There's something wrong with the inheritance scheme here.
- #~self.console.shortcuts.conkey.setContext(QtCore.Qt.ShortcutContext.ApplicationShortcut)
+ # ~self.console.shortcuts.conkey.setContext(QtCore.Qt.ShortcutContext.ApplicationShortcut)
self.console.shortcuts.conkey.activated.connect(self.toggleConsole)
- #~# Use new-style connections
- #~self.console.shortcut.activated.connect(self.toggleConsole)
+ # ~# Use new-style connections
+ # ~self.console.shortcut.activated.connect(self.toggleConsole)
# Apparently those can crash sometimes...c'est la vie. Can't use 'em.
- #~self.connect(self.console.shortcuts.curwgt,
- #~ QtCore.SIGNAL('activate()'), self.console.
+ # ~self.connect(self.console.shortcuts.curwgt,
+ # ~ QtCore.SIGNAL('activate()'), self.console.
self.console.is_open = False
filemenu = self.menu.addMenu(self.theme["main/menus/client/_name"])
@@ -1332,16 +1547,18 @@ class PesterWindow(MovingWindow):
self.aboutAction.triggered.connect(self.aboutPesterchum)
# Because I can't expect all themes to have this included.
- #if self.theme.has_key("main/menus/help/reportbug"):
+ # if self.theme.has_key("main/menus/help/reportbug"):
try:
- self.reportBugAction = QAction(self.theme["main/menus/help/reportbug"], self)
+ self.reportBugAction = QAction(
+ self.theme["main/menus/help/reportbug"], self
+ )
except:
self.reportBugAction = QAction("REPORT BUG", self)
try:
self.xyzRulesAction = QAction(self.theme["main/menus/help/rules"], self)
except:
self.xyzRulesAction = QAction("RULES", self)
-
+
self.reportBugAction.triggered.connect(self.reportBug)
self.xyzRulesAction.triggered.connect(self.xyzRules)
helpmenu = self.menu.addMenu(self.theme["main/menus/help/_name"])
@@ -1364,11 +1581,15 @@ class PesterWindow(MovingWindow):
chums = [PesterProfile(c, chumdb=self.chumdb) for c in set(self.config.chums())]
self.chumList = chumArea(chums, self)
- self.chumList.itemActivated[QtWidgets.QTreeWidgetItem, int].connect(self.pesterSelectedChum)
- self.chumList.removeChumSignal['QString'].connect(self.removeChum)
- self.chumList.blockChumSignal['QString'].connect(self.blockChum)
+ self.chumList.itemActivated[QtWidgets.QTreeWidgetItem, int].connect(
+ self.pesterSelectedChum
+ )
+ self.chumList.removeChumSignal["QString"].connect(self.removeChum)
+ self.chumList.blockChumSignal["QString"].connect(self.blockChum)
- self.addChumButton = QtWidgets.QPushButton(self.theme["main/addchum/text"], self)
+ self.addChumButton = QtWidgets.QPushButton(
+ self.theme["main/addchum/text"], self
+ )
self.addChumButton.setObjectName("addchumbtn")
self.addChumButton.clicked.connect(self.addChumWindow)
self.pesterButton = QtWidgets.QPushButton(self.theme["main/pester/text"], self)
@@ -1380,7 +1601,9 @@ class PesterWindow(MovingWindow):
self.moodsLabel = QtWidgets.QLabel(self.theme["main/moodlabel/text"], self)
self.moodsLabel.setObjectName("moodlabel")
- self.mychumhandleLabel = QtWidgets.QLabel(self.theme["main/mychumhandle/label/text"], self)
+ self.mychumhandleLabel = QtWidgets.QLabel(
+ self.theme["main/mychumhandle/label/text"], self
+ )
self.mychumhandleLabel.setObjectName("myhandlelabel")
self.mychumhandle = QtWidgets.QPushButton(self.profile().handle, self)
self.mychumhandle.setFlat(True)
@@ -1395,28 +1618,30 @@ class PesterWindow(MovingWindow):
self.initTheme(self.theme)
- #self.mychumhandleLabel.setStyleSheet("QLabel {);};")
+ # self.mychumhandleLabel.setStyleSheet("QLabel {);};")
self.hide()
-
+
self.waitingMessages = waitingMessageHolder(self)
- self.idler = AttrDict(dict(
+ self.idler = AttrDict(
+ dict(
# autoidle
- auto = False,
+ auto=False,
# setidle
- manual = False,
+ manual=False,
# idlethreshold
- threshold = 60*self.config.idleTime(),
+ threshold=60 * self.config.idleTime(),
# idleaction
- action = self.idleaction,
+ action=self.idleaction,
# idletimer
- timer = QtCore.QTimer(self),
+ timer=QtCore.QTimer(self),
# idleposition
- pos = QtGui.QCursor.pos(),
+ pos=QtGui.QCursor.pos(),
# idletime
- time = 0
- ))
+ time=0,
+ )
+ )
self.idler.timer.timeout.connect(self.checkIdle)
self.idler.timer.start(1000)
@@ -1424,13 +1649,13 @@ class PesterWindow(MovingWindow):
self.changeProfile()
# Fuck you some more OSX leopard! >:(
- #if not ostools.isOSXLeopard():
+ # if not ostools.isOSXLeopard():
# QtCore.QTimer.singleShot(1000, self.mspacheck)
- self.pcUpdate['QString', 'QString'].connect(self.updateMsg)
+ self.pcUpdate["QString", "QString"].connect(self.updateMsg)
- self.mychumhandleLabel.adjustSize() # Required so "CHUMHANDLE:" regardless of style-sheet.
- self.moodsLabel.adjustSize() # Required so "MOOD:" regardless of style-sheet.
+ self.mychumhandleLabel.adjustSize() # Required so "CHUMHANDLE:" regardless of style-sheet.
+ self.moodsLabel.adjustSize() # Required so "MOOD:" regardless of style-sheet.
self.chooseServerAskedToReset = False
self.chooseServer()
@@ -1448,12 +1673,12 @@ class PesterWindow(MovingWindow):
# Client --> Server pings
self.pingtimer = QtCore.QTimer()
self.pingtimer.timeout.connect(self.checkPing)
- self.sincerecv = 0 # Time since last recv
+ self.sincerecv = 0 # Time since last recv
self.lastCheckPing = None
-
+
@QtCore.pyqtSlot(QString, QString)
def updateMsg(self, ver, url):
- if not hasattr(self, 'updatemenu'):
+ if not hasattr(self, "updatemenu"):
self.updatemenu = None
if not self.updatemenu:
self.updatemenu = UpdatePesterchum(ver, url, self)
@@ -1477,10 +1702,10 @@ class PesterWindow(MovingWindow):
@QtCore.pyqtSlot()
def checkPing(self):
- '''Check if server is alive on app level,
- this function is called every 15sec'''
+ """Check if server is alive on app level,
+ this function is called every 15sec"""
# Return without irc
- if hasattr(self.parent, 'irc') == False:
+ if hasattr(self.parent, "irc") == False:
self.lastCheckPing = None
self.sincerecv = 0
return
@@ -1490,12 +1715,16 @@ class PesterWindow(MovingWindow):
timeDif = abs(currentTime - self.lastCheckPing)
if timeDif > 180: # default UnrealIRCd ping timeout time.
# 180 is the default UnrealIRCd ping timeout time.
- PchumLog.warning(("Possible desync, system time changed by %s "
- "seconds since last check. abs(%s - %s)")
- % (timeDif, currentTime, self.lastCheckPing))
+ PchumLog.warning(
+ (
+ "Possible desync, system time changed by %s "
+ "seconds since last check. abs(%s - %s)"
+ )
+ % (timeDif, currentTime, self.lastCheckPing)
+ )
self.sincerecv = 85 # Allows one more ping attempt before disconnect.
self.lastCheckPing = time.time()
-
+
# Presume connection is dead after 90 seconds of silence.
if self.sincerecv >= 90:
self.disconnectIRC.emit()
@@ -1504,28 +1733,28 @@ class PesterWindow(MovingWindow):
if self.sincerecv >= 45:
if self.parent.irc.unresponsive == False:
self.parent.irc.unresponsive = True
- self.parent.showLoading(self.parent.widget,
- "S3RV3R NOT R3SPOND1NG >:?")
+ self.parent.showLoading(self.parent.widget, "S3RV3R NOT R3SPOND1NG >:?")
self.show()
self.setFocus()
else:
self.parent.irc.unresponsive = False
- if hasattr(self, 'loadingscreen'):
+ if hasattr(self, "loadingscreen"):
if self.loadingscreen != None:
PchumLog.info("Server alive !! :O")
self.loadingscreen.done(QtWidgets.QDialog.DialogCode.Accepted)
self.loadingscreen = None
-
+
# Send a ping if it's been 30 seconds since we've heard from the server.
if self.sincerecv >= 30:
self.pingServer.emit()
- self.sincerecv += 5 # Not updating too frequently is better for performance.
+ self.sincerecv += 5 # Not updating too frequently is better for performance.
def profile(self):
return self.userprofile.chat
+
def closeConversations(self, switch=False):
- if not hasattr(self, 'tabconvo'):
+ if not hasattr(self, "tabconvo"):
self.tabconvo = None
if self.tabconvo:
self.tabconvo.close()
@@ -1544,6 +1773,7 @@ class PesterWindow(MovingWindow):
m.close()
else:
m.sendtime()
+
def paintEvent(self, event):
try:
self.backgroundImage
@@ -1558,30 +1788,31 @@ class PesterWindow(MovingWindow):
@QtCore.pyqtSlot()
def closeToTray(self):
# I'm just gonna include a toast here to make sure people don't get confused. :'3
- t = self.tm.Toast("Notice:",
- "Pesterchum has been minimized to your tray.")
+ t = self.tm.Toast("Notice:", "Pesterchum has been minimized to your tray.")
t.show()
self.hide()
self.closeToTraySignal.emit()
+
def closeEvent(self, event):
- if hasattr(self, 'trollslum') and self.trollslum:
+ if hasattr(self, "trollslum") and self.trollslum:
self.trollslum.close()
try:
setting = self.config.closeAction()
except:
- logging.exception('')
+ logging.exception("")
setting = 0
- if setting == 0: # minimize to taskbar
+ if setting == 0: # minimize to taskbar
self.showMinimized()
- elif setting == 1: # minimize to tray
+ elif setting == 1: # minimize to tray
self.closeToTray()
- elif setting == 2: # quit
+ elif setting == 2: # quit
self.closeConversations()
self.closeSignal.emit()
event.accept()
+
def newMessage(self, handle, msg):
if handle in self.config.getBlocklist():
- #yeah suck on this
+ # yeah suck on this
self.sendMessage.emit("PESTERCHUM:BLOCKED", handle)
return
# notify
@@ -1592,10 +1823,9 @@ class PesterWindow(MovingWindow):
elif not self.config.notifyOptions() & self.config.NEWCONVO:
if msg[:11] != "PESTERCHUM:":
if handle.upper() not in BOTNAMES:
- t = self.tm.Toast("From: %s" % handle,
- re.sub("?c(=.*?)?>",
- "",
- msg))
+ t = self.tm.Toast(
+ "From: %s" % handle, re.sub("?c(=.*?)?>", "", msg)
+ )
t.show()
else:
if msg == "PESTERCHUM:CEASE":
@@ -1608,7 +1838,7 @@ class PesterWindow(MovingWindow):
t = self.tm.Toast("Unblocked", handle)
t.show()
if handle not in self.convos:
- if msg == "PESTERCHUM:CEASE": # ignore cease after we hang up
+ if msg == "PESTERCHUM:CEASE": # ignore cease after we hang up
return
matchingChums = [c for c in self.chumList.chums if c.handle == handle]
if len(matchingChums) > 0:
@@ -1628,6 +1858,7 @@ class PesterWindow(MovingWindow):
self.ceasesound.play()
else:
self.alarm.play()
+
def newMemoMsg(self, chan, handle, msg):
if chan not in self.memos:
# silently ignore in case we forgot to /part
@@ -1649,7 +1880,7 @@ class PesterWindow(MovingWindow):
mentioned = False
m = convertTags(msg, "text")
if m.find(":") <= 3:
- m = m[m.find(":"):]
+ m = m[m.find(":") :]
for search in self.userprofile.getMentions():
if re.search(search, m):
mentioned = True
@@ -1666,9 +1897,9 @@ class PesterWindow(MovingWindow):
self.namesound.play()
return
if not memo.notifications_muted:
- if self.honk and re.search(r"\bhonk\b",
- convertTags(msg, "text"),
- re.I):
+ if self.honk and re.search(
+ r"\bhonk\b", convertTags(msg, "text"), re.I
+ ):
# TODO: I've got my eye on you, Gamzee.
self.honksound.play()
elif self.config.memoPing() or memo.always_beep:
@@ -1686,8 +1917,9 @@ class PesterWindow(MovingWindow):
oldmood = self.chumList.updateMood(handle, mood)
if handle in self.convos:
self.convos[handle].updateMood(mood, old=oldmood)
- if hasattr(self, 'trollslum') and self.trollslum:
+ if hasattr(self, "trollslum") and self.trollslum:
self.trollslum.updateMood(handle, mood)
+
def newConversation(self, chum, initiated=True):
if type(chum) in [str, str]:
matchingChums = [c for c in self.chumList.chums if c.handle == chum]
@@ -1709,8 +1941,10 @@ class PesterWindow(MovingWindow):
self.tabconvo.show()
else:
convoWindow = PesterConvo(chum, initiated, self)
- convoWindow.messageSent['QString', 'QString'].connect(self.sendMessage['QString', 'QString'])
- convoWindow.windowClosed['QString'].connect(self.closeConvo)
+ convoWindow.messageSent["QString", "QString"].connect(
+ self.sendMessage["QString", "QString"]
+ )
+ convoWindow.windowClosed["QString"].connect(self.closeConvo)
self.convos[chum.handle] = convoWindow
if str(chum.handle).upper() in BOTNAMES:
convoWindow.toggleQuirks(True)
@@ -1724,6 +1958,7 @@ class PesterWindow(MovingWindow):
def createTabWindow(self):
self.tabconvo = PesterTabWindow(self)
self.tabconvo.windowClosed.connect(self.tabsClosed)
+
def createMemoTabWindow(self):
self.tabmemo = MemoTabWindow(self)
self.tabmemo.windowClosed.connect(self.memoTabsClosed)
@@ -1756,9 +1991,10 @@ class PesterWindow(MovingWindow):
# No error, let's see if we're actually focused.
if focused:
PchumLog.debug(
- "{0!r} is in focus (parent: {1!r}); hiding".format(
- wgt, wgt.parent())
- )
+ "{0!r} is in focus (parent: {1!r}); hiding".format(
+ wgt, wgt.parent()
+ )
+ )
# This widget, a child of our console, has focus.
# So...the console has focus.
# Set focus to the text input just for good measure.
@@ -1810,16 +2046,20 @@ class PesterWindow(MovingWindow):
else:
memoWindow = PesterMemo(channel, timestr, self, None)
# connect signals
- self.inviteOnlyChan['QString'].connect(memoWindow.closeInviteOnly)
- self.forbiddenChan['QString', 'QString'].connect(memoWindow.closeForbidden)
- memoWindow.messageSent['QString', 'QString'].connect(self.sendMessage['QString', 'QString'])
- memoWindow.windowClosed['QString'].connect(self.closeMemo)
- self.namesUpdated['QString'].connect(memoWindow.namesUpdated)
- self.modesUpdated['QString', 'QString'].connect(memoWindow.modesUpdated)
- self.userPresentSignal['QString', 'QString', 'QString'].connect(memoWindow.userPresentChange)
+ self.inviteOnlyChan["QString"].connect(memoWindow.closeInviteOnly)
+ self.forbiddenChan["QString", "QString"].connect(memoWindow.closeForbidden)
+ memoWindow.messageSent["QString", "QString"].connect(
+ self.sendMessage["QString", "QString"]
+ )
+ memoWindow.windowClosed["QString"].connect(self.closeMemo)
+ self.namesUpdated["QString"].connect(memoWindow.namesUpdated)
+ self.modesUpdated["QString", "QString"].connect(memoWindow.modesUpdated)
+ self.userPresentSignal["QString", "QString", "QString"].connect(
+ memoWindow.userPresentChange
+ )
# chat client send memo open
self.memos[channel] = memoWindow
- self.joinChannel.emit(channel) # race condition?
+ self.joinChannel.emit(channel) # race condition?
self.secret = secret
if self.secret:
self.secret = True
@@ -1846,44 +2086,53 @@ class PesterWindow(MovingWindow):
if self.config.showOnlineNumbers():
self.chumList.showOnlineNumbers()
-
def changeProfile(self, collision=None, svsnick=None):
- if not hasattr(self, 'chooseprofile'):
+ if not hasattr(self, "chooseprofile"):
self.chooseprofile = None
if not self.chooseprofile:
- self.chooseprofile = PesterChooseProfile(self.userprofile,
- self.config,
- self.theme,
- self,
- collision=collision,
- svsnick=svsnick)
+ self.chooseprofile = PesterChooseProfile(
+ self.userprofile,
+ self.config,
+ self.theme,
+ self,
+ collision=collision,
+ svsnick=svsnick,
+ )
self.chooseprofile.exec()
def themePicker(self):
- if not hasattr(self, 'choosetheme'):
+ if not hasattr(self, "choosetheme"):
self.choosetheme = None
if not self.choosetheme:
self.choosetheme = PesterChooseTheme(self.config, self.theme, self)
self.choosetheme.exec()
+
def initTheme(self, theme):
self.resize(*theme["main/size"])
self.setWindowIcon(PesterIcon(theme["main/icon"]))
self.setWindowTitle(theme["main/windowtitle"])
self.setStyleSheet("QtWidgets.QFrame#main { %s }" % (theme["main/style"]))
-
+
self.backgroundImage = QtGui.QPixmap(theme["main/background-image"])
self.setMask(self.backgroundImage.mask())
-
- self.menu.setStyleSheet(("QMenuBar { background: transparent; %s }"
- "QMenuBar::item { background: transparent; %s }")
- % (theme["main/menubar/style"],
- theme["main/menu/menuitem"])
- + ("QMenu { background: transparent; %s }"
- "QMenu::item::selected { %s }"
- "QMenu::item::disabled { %s }")
- % (theme["main/menu/style"],
- theme["main/menu/selected"],
- theme["main/menu/disabled"]))
+
+ self.menu.setStyleSheet(
+ (
+ "QMenuBar { background: transparent; %s }"
+ "QMenuBar::item { background: transparent; %s }"
+ )
+ % (theme["main/menubar/style"], theme["main/menu/menuitem"])
+ + (
+ "QMenu { background: transparent; %s }"
+ "QMenu::item::selected { %s }"
+ "QMenu::item::disabled { %s }"
+ )
+ % (
+ theme["main/menu/style"],
+ theme["main/menu/selected"],
+ theme["main/menu/disabled"],
+ )
+ )
newcloseicon = PesterIcon(theme["main/close/image"])
self.closeButton.setIcon(newcloseicon)
self.closeButton.setIconSize(newcloseicon.realsize())
@@ -1921,10 +2170,10 @@ class PesterWindow(MovingWindow):
self.helpmenu.setTitle(self.theme["main/menus/help/_name"])
# Console
-## if self.theme.has_key("main/menus/client/console"):
-## self.console.action.setText(self.theme["main/menus/client/console"])
-## else:
-## self.console.action.setText("Console")
+ ## if self.theme.has_key("main/menus/client/console"):
+ ## self.console.action.setText(self.theme["main/menus/client/console"])
+ ## else:
+ ## self.console.action.setText("Console")
# has_key doesn't work out here for some reason, possibly because of inherits?
try:
self.console.action.setText(self.theme["main/menus/client/console"])
@@ -1940,29 +2189,36 @@ class PesterWindow(MovingWindow):
self.xyzRulesAction.setText(self.theme["main/menus/help/rules"])
except:
self.xyzRulesAction.setText("RULES")
-
+
# moods
self.moodsLabel.setText(theme["main/moodlabel/text"])
self.moodsLabel.move(*theme["main/moodlabel/loc"])
self.moodsLabel.setStyleSheet(theme["main/moodlabel/style"])
- if hasattr(self, 'moods'):
+ if hasattr(self, "moods"):
self.moods.removeButtons()
mood_list = theme["main/moods"]
- mood_list = [dict([(str(k),v) for (k,v) in d.items()])
- for d in mood_list]
- self.moods = PesterMoodHandler(self, *[PesterMoodButton(self, **d) for d in mood_list])
+ mood_list = [dict([(str(k), v) for (k, v) in d.items()]) for d in mood_list]
+ self.moods = PesterMoodHandler(
+ self, *[PesterMoodButton(self, **d) for d in mood_list]
+ )
self.moods.showButtons()
# chum
addChumStyle = "QPushButton { %s }" % (theme["main/addchum/style"])
if "main/addchum/pressed" in theme:
- addChumStyle += "QPushButton:pressed { %s }" % (theme["main/addchum/pressed"])
+ addChumStyle += "QPushButton:pressed { %s }" % (
+ theme["main/addchum/pressed"]
+ )
pesterButtonStyle = "QPushButton { %s }" % (theme["main/pester/style"])
if "main/pester/pressed" in theme:
- pesterButtonStyle += "QPushButton:pressed { %s }" % (theme["main/pester/pressed"])
+ pesterButtonStyle += "QPushButton:pressed { %s }" % (
+ theme["main/pester/pressed"]
+ )
blockButtonStyle = "QPushButton { %s }" % (theme["main/block/style"])
if "main/block/pressed" in theme:
- pesterButtonStyle += "QPushButton:pressed { %s }" % (theme["main/block/pressed"])
+ pesterButtonStyle += "QPushButton:pressed { %s }" % (
+ theme["main/block/pressed"]
+ )
self.addChumButton.setText(theme["main/addchum/text"])
self.addChumButton.resize(*theme["main/addchum/size"])
self.addChumButton.move(*theme["main/addchum/loc"])
@@ -1990,10 +2246,10 @@ class PesterWindow(MovingWindow):
# But this seems to work just as well :3c
# GWAHH why does inheriting not work with this 3
# For some reason, this only works on trollian with 'try' :/
- #if self.theme.has_key("main/mychumhandle/currentMood"):
+ # if self.theme.has_key("main/mychumhandle/currentMood"):
try:
moodicon = self.profile().mood.icon(theme)
- if hasattr(self, 'currentMoodIcon') and self.currentMoodIcon:
+ if hasattr(self, "currentMoodIcon") and self.currentMoodIcon:
self.currentMoodIcon.hide()
self.currentMoodIcon = None
self.currentMoodIcon = QtWidgets.QLabel(self)
@@ -2001,23 +2257,27 @@ class PesterWindow(MovingWindow):
self.currentMoodIcon.move(*theme["main/mychumhandle/currentMood"])
self.currentMoodIcon.show()
except:
- if hasattr(self, 'currentMoodIcon') and self.currentMoodIcon:
+ if hasattr(self, "currentMoodIcon") and self.currentMoodIcon:
self.currentMoodIcon.hide()
self.currentMoodIcon = None
# This is a better spot to put this :)
# Setting QMessageBox's style usually doesn't do anything.
- self.setStyleSheet("QInputDialog { %s } QMessageBox { %s }"
- % (self.theme["main/defaultwindow/style"],
- self.theme["main/defaultwindow/style"]))
+ self.setStyleSheet(
+ "QInputDialog { %s } QMessageBox { %s }"
+ % (
+ self.theme["main/defaultwindow/style"],
+ self.theme["main/defaultwindow/style"],
+ )
+ )
if theme["main/mychumhandle/colorswatch/text"]:
self.mychumcolor.setText(theme["main/mychumhandle/colorswatch/text"])
else:
self.mychumcolor.setText("")
- self.mychumhandleLabel.adjustSize() # Required so "CHUMHANDLE:" regardless of style-sheet.
- self.moodsLabel.adjustSize() # Required so "MOOD:" regardless of style-sheet.
+ self.mychumhandleLabel.adjustSize() # Required so "CHUMHANDLE:" regardless of style-sheet.
+ self.moodsLabel.adjustSize() # Required so "MOOD:" regardless of style-sheet.
if _CONSOLE:
if self.console.window:
@@ -2054,26 +2314,36 @@ class PesterWindow(MovingWindow):
# Use the class we chose to build the sound set.
try:
- if 'pygame' in sys.modules:
+ if "pygame" in sys.modules:
if soundclass == pygame.mixer.Sound:
self.alarm = soundclass(self.theme["main/sounds/alertsound"])
self.memosound = soundclass(self.theme["main/sounds/memosound"])
self.namesound = soundclass("themes/namealarm.wav")
self.ceasesound = soundclass(self.theme["main/sounds/ceasesound"])
self.honksound = soundclass("themes/honk.wav")
- elif 'PyQt6.QtMultimedia' in sys.modules:
+ elif "PyQt6.QtMultimedia" in sys.modules:
if soundclass == QtMultimedia.QSoundEffect:
self.alarm = soundclass()
self.memosound = soundclass()
self.namesound = soundclass()
self.ceasesound = soundclass()
self.honksound = soundclass()
-
- self.alarm.setSource(QtCore.QUrl.fromLocalFile(self.theme["main/sounds/alertsound"]))
- self.memosound.setSource(QtCore.QUrl.fromLocalFile(self.theme["main/sounds/memosound"]))
- self.namesound.setSource(QtCore.QUrl.fromLocalFile("themes/namealarm.wav"))
- self.ceasesound.setSource(QtCore.QUrl.fromLocalFile(self.theme["main/sounds/ceasesound"]))
- self.honksound.setSource(QtCore.QUrl.fromLocalFile("themes/honk.wav"))
+
+ self.alarm.setSource(
+ QtCore.QUrl.fromLocalFile(self.theme["main/sounds/alertsound"])
+ )
+ self.memosound.setSource(
+ QtCore.QUrl.fromLocalFile(self.theme["main/sounds/memosound"])
+ )
+ self.namesound.setSource(
+ QtCore.QUrl.fromLocalFile("themes/namealarm.wav")
+ )
+ self.ceasesound.setSource(
+ QtCore.QUrl.fromLocalFile(self.theme["main/sounds/ceasesound"])
+ )
+ self.honksound.setSource(
+ QtCore.QUrl.fromLocalFile("themes/honk.wav")
+ )
except Exception as err:
PchumLog.error("Warning: Error loading sounds! ({0!r})".format(err))
self.alarm = NoneSound()
@@ -2082,20 +2352,22 @@ class PesterWindow(MovingWindow):
self.ceasesound = NoneSound()
self.honksound = NoneSound()
- self.sounds = [self.alarm,
- self.memosound,
- self.namesound,
- self.ceasesound,
- self.honksound]
-
+ self.sounds = [
+ self.alarm,
+ self.memosound,
+ self.namesound,
+ self.ceasesound,
+ self.honksound,
+ ]
+
def setVolume(self, vol_percent):
- vol = vol_percent/100.0
+ vol = vol_percent / 100.0
for sound in self.sounds:
try:
- if 'pygame' in sys.modules:
+ if "pygame" in sys.modules:
if self.sound_type == pygame.mixer.Sound:
sound.set_volume(vol)
- if 'PyQt6.QtMultimedia' in sys.modules:
+ if "PyQt6.QtMultimedia" in sys.modules:
if self.sound_type == QtMultimedia.QSoundEffect:
sound.setVolume(vol)
except Exception as err:
@@ -2128,7 +2400,7 @@ class PesterWindow(MovingWindow):
# do self
self.initTheme(theme)
# set mood
- self.moods.updateMood(theme['main/defaultmood'])
+ self.moods.updateMood(theme["main/defaultmood"])
# chum area
self.chumList.changeTheme(theme)
# do open windows
@@ -2140,9 +2412,9 @@ class PesterWindow(MovingWindow):
c.changeTheme(theme)
for m in list(self.memos.values()):
m.changeTheme(theme)
- if hasattr(self, 'trollslum') and self.trollslum:
+ if hasattr(self, "trollslum") and self.trollslum:
self.trollslum.changeTheme(theme)
- if hasattr(self, 'allusers') and self.allusers:
+ if hasattr(self, "allusers") and self.allusers:
self.allusers.changeTheme(theme)
if self.config.ghostchum():
self.theme["main"]["icon"] = "themes/pesterchum/pesterdunk.png"
@@ -2174,9 +2446,9 @@ class PesterWindow(MovingWindow):
def doAutoIdentify(self):
if self.userprofile.getAutoIdentify():
- self.sendMessage.emit("identify "
- + self.userprofile.getNickServPass(),
- "NickServ")
+ self.sendMessage.emit(
+ "identify " + self.userprofile.getNickServPass(), "NickServ"
+ )
def doAutoJoins(self):
if not self.autoJoinDone:
@@ -2194,33 +2466,34 @@ class PesterWindow(MovingWindow):
self.doAutoJoins()
# Start client --> server pings
- if hasattr(self, 'pingtimer'):
- self.pingtimer.start(1000*5) # time in ms
+ if hasattr(self, "pingtimer"):
+ self.pingtimer.start(1000 * 5) # time in ms
else:
PchumLog.warning("No ping timer.")
# Desync check
- if hasattr(self, 'lastCheckPing'):
+ if hasattr(self, "lastCheckPing"):
self.lastCheckPing = time.time()
else:
PchumLog.warning("No ping timer.")
-
+
@QtCore.pyqtSlot()
def blockSelectedChum(self):
curChumListing = self.chumList.currentItem()
if curChumListing:
curChum = curChumListing.chum
self.blockChum(curChum.handle)
+
@QtCore.pyqtSlot()
def pesterSelectedChum(self):
curChum = self.chumList.currentItem()
if curChum:
text = str(curChum.text(0))
if text.rfind(" (") != -1:
- text = text[0:text.rfind(" (")]
- if text not in self.chumList.groups and \
- text != "Chums":
+ text = text[0 : text.rfind(" (")]
+ if text not in self.chumList.groups and text != "Chums":
self.newConversationWindow(curChum)
+
@QtCore.pyqtSlot(QtWidgets.QListWidgetItem)
def newConversationWindow(self, chumlisting):
# check chumdb
@@ -2229,6 +2502,7 @@ class PesterWindow(MovingWindow):
if color:
chum.color = color
self.newConversation(chum)
+
@QtCore.pyqtSlot(QString)
def closeConvo(self, handle):
h = str(handle)
@@ -2241,13 +2515,18 @@ class PesterWindow(MovingWindow):
except KeyError:
chumopen = self.convos[h.lower()].chumopen
if chumopen:
- self.chatlog.log(chum.handle,
- self.profile().pestermsg(chum,
- QtGui.QColor(self.theme["convo/systemMsgColor"]),
- self.theme["convo/text/ceasepester"]))
+ self.chatlog.log(
+ chum.handle,
+ self.profile().pestermsg(
+ chum,
+ QtGui.QColor(self.theme["convo/systemMsgColor"]),
+ self.theme["convo/text/ceasepester"],
+ ),
+ )
self.convoClosed.emit(handle)
self.chatlog.finish(h)
del self.convos[h]
+
@QtCore.pyqtSlot(QString)
def closeMemo(self, channel):
c = str(channel)
@@ -2260,10 +2539,12 @@ class PesterWindow(MovingWindow):
del self.memos[c.lower()]
except KeyError:
pass
+
@QtCore.pyqtSlot()
def tabsClosed(self):
del self.tabconvo
self.tabconvo = None
+
@QtCore.pyqtSlot()
def memoTabsClosed(self):
del self.tabmemo
@@ -2276,7 +2557,7 @@ class PesterWindow(MovingWindow):
@QtCore.pyqtSlot(QString, QtGui.QColor)
def updateColorSlot(self, handle, color):
- PchumLog.debug("updateColorSlot, "+ str(handle) +", " + str(color))
+ PchumLog.debug("updateColorSlot, " + str(handle) + ", " + str(color))
h = str(handle)
self.changeColor(h, color)
@@ -2285,23 +2566,30 @@ class PesterWindow(MovingWindow):
h = str(handle)
m = str(msg)
self.newMessage(h, m)
+
@QtCore.pyqtSlot(QString, QString, QString)
def deliverMemo(self, chan, handle, msg):
(c, h, m) = (str(chan), str(handle), str(msg))
- self.newMemoMsg(c,h,m)
+ self.newMemoMsg(c, h, m)
+
@QtCore.pyqtSlot(QString, QString)
def deliverNotice(self, handle, msg):
h = str(handle)
m = str(msg)
- if h.upper() == "NICKSERV" and m.startswith("Your nickname is now being changed to"):
+ if h.upper() == "NICKSERV" and m.startswith(
+ "Your nickname is now being changed to"
+ ):
changedto = m[39:-1]
msgbox = QtWidgets.QMessageBox()
- msgbox.setStyleSheet("QMessageBox{ %s }"
- % self.theme["main/defaultwindow/style"])
- msgbox.setText("This chumhandle has been registered; "
- "you may not use it.")
- msgbox.setInformativeText("Your handle is now being changed to %s."
- % (changedto))
+ msgbox.setStyleSheet(
+ "QMessageBox{ %s }" % self.theme["main/defaultwindow/style"]
+ )
+ msgbox.setText(
+ "This chumhandle has been registered; " "you may not use it."
+ )
+ msgbox.setInformativeText(
+ "Your handle is now being changed to %s." % (changedto)
+ )
msgbox.setStandardButtons(QtWidgets.QMessageBox.StandardButton.Ok)
msgbox.exec()
elif h == self.randhandler.randNick:
@@ -2318,17 +2606,22 @@ class PesterWindow(MovingWindow):
# "Your VHOST is actived", "You have one new memo", etc.
t = self.tm.Toast("%s:" % h, m)
t.show()
-
+
@QtCore.pyqtSlot(QString, QString)
def deliverInvite(self, handle, channel):
msgbox = QtWidgets.QMessageBox()
msgbox.setText("You're invited!")
- msgbox.setStyleSheet("QMessageBox{" + self.theme["main/defaultwindow/style"] + "}")
- msgbox.setInformativeText(("%s has invited you to the memo: %s"
- "\nWould you like to join them?")
- % (handle, channel))
- msgbox.setStandardButtons(QtWidgets.QMessageBox.StandardButton.Ok
- | QtWidgets.QMessageBox.StandardButton.Cancel)
+ msgbox.setStyleSheet(
+ "QMessageBox{" + self.theme["main/defaultwindow/style"] + "}"
+ )
+ msgbox.setInformativeText(
+ ("%s has invited you to the memo: %s" "\nWould you like to join them?")
+ % (handle, channel)
+ )
+ msgbox.setStandardButtons(
+ QtWidgets.QMessageBox.StandardButton.Ok
+ | QtWidgets.QMessageBox.StandardButton.Cancel
+ )
# Find the Cancel button and make it default
for b in msgbox.buttons():
if msgbox.buttonRole(b) == QtWidgets.QMessageBox.ButtonRole.RejectRole:
@@ -2342,15 +2635,18 @@ class PesterWindow(MovingWindow):
ret = msgbox.exec()
if ret == QtWidgets.QMessageBox.StandardButton.Ok:
self.newMemo(str(channel), "+0:00")
+
@QtCore.pyqtSlot(QString)
def chanInviteOnly(self, channel):
self.inviteOnlyChan.emit(channel)
+
@QtCore.pyqtSlot(QString, QString)
def cannotSendToChan(self, channel, msg):
self.deliverMemo(channel, "ChanServ", msg)
+
# Unused and redefined.
- #@QtCore.pyqtSlot(QString, QString)
- #def modesUpdated(self, channel, modes):
+ # @QtCore.pyqtSlot(QString, QString)
+ # def modesUpdated(self, channel, modes):
# self.modesUpdated.emit(channel, modes)
@QtCore.pyqtSlot(QString, QString, QString)
def timeCommand(self, chan, handle, command):
@@ -2373,11 +2669,12 @@ class PesterWindow(MovingWindow):
self.namesdb[c] = names
# warn interested party of names
self.namesUpdated.emit(c)
+
@QtCore.pyqtSlot(QString, QString, QString)
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]
@@ -2420,12 +2717,12 @@ class PesterWindow(MovingWindow):
except KeyError:
self.namesdb[c] = [n]
- #PchumLog.debug("handle=%s\nchannel=%s\nupdate=%s\n" % (handle, channel, update))
+ # PchumLog.debug("handle=%s\nchannel=%s\nupdate=%s\n" % (handle, channel, update))
self.userPresentSignal.emit(handle, channel, update)
@QtCore.pyqtSlot()
def addChumWindow(self):
- if not hasattr(self, 'addchumdialog'):
+ if not hasattr(self, "addchumdialog"):
self.addchumdialog = None
if not self.addchumdialog:
available_groups = [g[0] for g in self.config.getGroups()]
@@ -2440,8 +2737,10 @@ class PesterWindow(MovingWindow):
if handle in [h.handle for h in self.chumList.chums]:
self.addchumdialog = None
return
- if not (PesterProfile.checkLength(handle) and
- PesterProfile.checkValid(handle)[0]):
+ if not (
+ PesterProfile.checkLength(handle)
+ and PesterProfile.checkValid(handle)[0]
+ ):
errormsg = QtWidgets.QErrorMessage(self)
errormsg.showMessage("THIS IS NOT A VALID CHUMTAG!")
self.addchumdialog = None
@@ -2458,17 +2757,19 @@ class PesterWindow(MovingWindow):
self.chumdb.setGroup(handle, group)
self.addChum(chum)
self.addchumdialog = None
+
@QtCore.pyqtSlot(QString)
def removeChum(self, chumlisting):
self.config.removeChum(chumlisting)
+
def reportChum(self, handle):
- (reason, ok) = QtWidgets.QInputDialog.getText(self,
- "Report User",
- "Enter the reason you are reporting this user (optional):")
+ (reason, ok) = QtWidgets.QInputDialog.getText(
+ self,
+ "Report User",
+ "Enter the reason you are reporting this user (optional):",
+ )
if ok:
- self.sendMessage.emit("REPORT %s %s"
- % (handle, reason),
- "calSprite")
+ self.sendMessage.emit("REPORT %s %s" % (handle, reason), "calSprite")
@QtCore.pyqtSlot(QString)
def blockChum(self, handle):
@@ -2477,14 +2778,16 @@ class PesterWindow(MovingWindow):
self.config.removeChum(h)
if h in self.convos:
convo = self.convos[h]
- msg = self.profile().pestermsg(convo.chum,
- QtGui.QColor(self.theme["convo/systemMsgColor"]),
- self.theme["convo/text/blocked"])
+ msg = self.profile().pestermsg(
+ convo.chum,
+ QtGui.QColor(self.theme["convo/systemMsgColor"]),
+ self.theme["convo/text/blocked"],
+ )
convo.textArea.append(convertTags(msg))
self.chatlog.log(convo.chum.handle, msg)
convo.updateBlocked()
self.chumList.removeChum(h)
- if hasattr(self, 'trollslum') and self.trollslum:
+ if hasattr(self, "trollslum") and self.trollslum:
newtroll = PesterProfile(h)
self.trollslum.addTroll(newtroll)
self.moodRequest.emit(newtroll)
@@ -2496,14 +2799,16 @@ class PesterWindow(MovingWindow):
self.config.delBlocklist(h)
if h in self.convos:
convo = self.convos[h]
- msg = self.profile().pestermsg(convo.chum,
- QtGui.QColor(self.theme["convo/systemMsgColor"]),
- self.theme["convo/text/unblocked"])
+ msg = self.profile().pestermsg(
+ convo.chum,
+ QtGui.QColor(self.theme["convo/systemMsgColor"]),
+ self.theme["convo/text/unblocked"],
+ )
convo.textArea.append(convertTags(msg))
self.chatlog.log(convo.chum.handle, msg)
convo.updateMood(convo.chum.mood, unblocked=True)
chum = PesterProfile(h, chumdb=self.chumdb)
- if hasattr(self, 'trollslum') and self.trollslum:
+ if hasattr(self, "trollslum") and self.trollslum:
self.trollslum.removeTroll(handle)
self.config.addChum(chum)
self.chumList.addChum(chum)
@@ -2523,6 +2828,7 @@ class PesterWindow(MovingWindow):
self.setAway.emit(False)
self.randhandler.setIdle(False)
self.idler.time = 0
+
# karxi: TODO: Need to consider sticking an idle-setter here.
@QtCore.pyqtSlot()
def checkIdle(self):
@@ -2592,7 +2898,7 @@ class PesterWindow(MovingWindow):
f = QtWidgets.QFileDialog.getOpenFileName(self)[0]
if f == "":
return
- fp = open(f, 'r')
+ fp = open(f, "r")
regexp_state = None
for l in fp:
# import chumlist
@@ -2610,9 +2916,9 @@ class PesterWindow(MovingWindow):
re.compile(regexp_state)
except re.error:
continue
- newquirk = pesterQuirk({"type": "regexp",
- "from": regexp_state,
- "to": replace})
+ newquirk = pesterQuirk(
+ {"type": "regexp", "from": regexp_state, "to": replace}
+ )
qs = self.userprofile.quirks
qs.addQuirk(newquirk)
self.userprofile.setQuirks(qs)
@@ -2624,15 +2930,16 @@ class PesterWindow(MovingWindow):
continue
other_mo = re.match("(prefix|suffix): (.+)", l)
if other_mo is not None:
- newquirk = pesterQuirk({"type": other_mo.group(1),
- "value": other_mo.group(2)})
+ newquirk = pesterQuirk(
+ {"type": other_mo.group(1), "value": other_mo.group(2)}
+ )
qs = self.userprofile.quirks
qs.addQuirk(newquirk)
self.userprofile.setQuirks(qs)
@QtCore.pyqtSlot()
def showMemos(self, channel=""):
- if not hasattr(self, 'memochooser'):
+ if not hasattr(self, "memochooser"):
self.memochooser = None
if self.memochooser:
return
@@ -2641,6 +2948,7 @@ class PesterWindow(MovingWindow):
self.memochooser.rejected.connect(self.memoChooserClose)
self.requestChannelList.emit()
self.memochooser.show()
+
@QtCore.pyqtSlot()
def joinSelectedMemo(self):
@@ -2650,7 +2958,7 @@ class PesterWindow(MovingWindow):
# Join the ones on the list first
for SelectedMemo in self.memochooser.SelectedMemos():
- channel = "#"+str(SelectedMemo.target)
+ channel = "#" + str(SelectedMemo.target)
self.newMemo(channel, time)
if self.memochooser.newmemoname():
@@ -2658,34 +2966,36 @@ class PesterWindow(MovingWindow):
channel = str(newmemo).replace(" ", "_")
channel = re.sub(r"[^A-Za-z0-9#_\,]", "", channel)
# Allow us to join more than one with this.
- chans = channel.split(',')
+ chans = channel.split(",")
# Filter out empty entries.
chans = [_f for _f in chans if _f]
for c in chans:
- c = '#' + c
+ c = "#" + c
# We should really change this code to only make the memo once
# the server has confirmed that we've joined....
self.newMemo(c, time, secret=secret, invite=invite)
self.memochooser = None
+
@QtCore.pyqtSlot()
def memoChooserClose(self):
self.memochooser = None
@QtCore.pyqtSlot(PesterList)
def updateChannelList(self, channels):
- if hasattr(self, 'memochooser') and self.memochooser:
+ if hasattr(self, "memochooser") and self.memochooser:
self.memochooser.updateChannels(channels)
+
@QtCore.pyqtSlot()
def showAllUsers(self):
- if not hasattr(self, 'allusers'):
+ if not hasattr(self, "allusers"):
self.allusers = None
if not self.allusers:
self.allusers = PesterUserlist(self.config, self.theme, self)
self.allusers.accepted.connect(self.userListClose)
self.allusers.rejected.connect(self.userListClose)
- self.allusers.addChum['QString'].connect(self.userListAdd)
- self.allusers.pesterChum['QString'].connect(self.userListPester)
+ self.allusers.addChum["QString"].connect(self.userListAdd)
+ self.allusers.pesterChum["QString"].connect(self.userListPester)
self.requestNames.emit("#pesterchum")
self.allusers.show()
@@ -2694,17 +3004,19 @@ class PesterWindow(MovingWindow):
h = str(handle)
chum = PesterProfile(h, chumdb=self.chumdb)
self.addChum(chum)
+
@QtCore.pyqtSlot(QString)
def userListPester(self, handle):
h = str(handle)
self.newConversation(h)
+
@QtCore.pyqtSlot()
def userListClose(self):
self.allusers = None
@QtCore.pyqtSlot()
def openQuirks(self):
- if not hasattr(self, 'quirkmenu'):
+ if not hasattr(self, "quirkmenu"):
self.quirkmenu = None
if not self.quirkmenu:
self.quirkmenu = PesterChooseQuirks(self.config, self.theme, self)
@@ -2713,30 +3025,37 @@ class PesterWindow(MovingWindow):
self.quirkmenu.show()
self.quirkmenu.raise_()
self.quirkmenu.activateWindow()
+
@QtCore.pyqtSlot()
def updateQuirks(self):
for i in range(self.quirkmenu.quirkList.topLevelItemCount()):
curgroup = str(self.quirkmenu.quirkList.topLevelItem(i).text(0))
for j in range(self.quirkmenu.quirkList.topLevelItem(i).childCount()):
item = self.quirkmenu.quirkList.topLevelItem(i).child(j)
- item.quirk.quirk["on"] = item.quirk.on = (item.checkState(0) == QtCore.Qt.CheckState.Checked)
+ item.quirk.quirk["on"] = item.quirk.on = (
+ item.checkState(0) == QtCore.Qt.CheckState.Checked
+ )
item.quirk.quirk["group"] = item.quirk.group = curgroup
quirks = pesterQuirks(self.quirkmenu.quirks())
self.userprofile.setQuirks(quirks)
- if hasattr(self.quirkmenu, 'quirktester') and self.quirkmenu.quirktester:
+ if hasattr(self.quirkmenu, "quirktester") and self.quirkmenu.quirktester:
self.quirkmenu.quirktester.close()
self.quirkmenu = None
+
@QtCore.pyqtSlot()
def closeQuirks(self):
- if hasattr(self.quirkmenu, 'quirktester') and self.quirkmenu.quirktester:
+ if hasattr(self.quirkmenu, "quirktester") and self.quirkmenu.quirktester:
self.quirkmenu.quirktester.close()
self.quirkmenu = None
+
@QtCore.pyqtSlot()
def openChat(self):
if not hasattr(self, "openchatdialog"):
self.openchatdialog = None
if not self.openchatdialog:
- (chum, ok) = QtWidgets.QInputDialog.getText(self, "Pester Chum", "Enter a handle to pester:")
+ (chum, ok) = QtWidgets.QInputDialog.getText(
+ self, "Pester Chum", "Enter a handle to pester:"
+ )
try:
if ok:
self.newConversation(str(chum))
@@ -2744,9 +3063,10 @@ class PesterWindow(MovingWindow):
pass
finally:
self.openchatdialog = None
+
@QtCore.pyqtSlot()
def openLogv(self):
- if not hasattr(self, 'logusermenu'):
+ if not hasattr(self, "logusermenu"):
self.logusermenu = None
if not self.logusermenu:
self.logusermenu = PesterLogUserSelect(self.config, self.theme, self)
@@ -2755,6 +3075,7 @@ class PesterWindow(MovingWindow):
self.logusermenu.show()
self.logusermenu.raise_()
self.logusermenu.activateWindow()
+
@QtCore.pyqtSlot()
def closeLogUsers(self):
self.logusermenu.close()
@@ -2762,19 +3083,22 @@ class PesterWindow(MovingWindow):
@QtCore.pyqtSlot()
def addGroupWindow(self):
- if not hasattr(self, 'addgroupdialog'):
+ if not hasattr(self, "addgroupdialog"):
self.addgroupdialog = None
if not self.addgroupdialog:
- (gname, ok) = QtWidgets.QInputDialog.getText(self, "Add Group", "Enter a name for the new group:")
+ (gname, ok) = QtWidgets.QInputDialog.getText(
+ self, "Add Group", "Enter a name for the new group:"
+ )
if ok:
gname = str(gname)
if re.search("[^A-Za-z0-9_\s]", gname) is not None:
msgbox = QtWidgets.QMessageBox()
msgbox.setInformativeText("THIS IS NOT A VALID GROUP NAME")
msgbox.setStandardButtons(QtWidgets.QMessageBox.StandardButton.Ok)
- #Style :) (memos/style or convo/style works :3 )
- msgbox.setStyleSheet("QMessageBox{ %s }"
- % self.theme["main/defaultwindow/style"])
+ # Style :) (memos/style or convo/style works :3 )
+ msgbox.setStyleSheet(
+ "QMessageBox{ %s }" % self.theme["main/defaultwindow/style"]
+ )
msgbox.exec()
self.addgroupdialog = None
return
@@ -2783,7 +3107,7 @@ class PesterWindow(MovingWindow):
@QtCore.pyqtSlot()
def openOpts(self):
- if not hasattr(self, 'optionmenu'):
+ if not hasattr(self, "optionmenu"):
self.optionmenu = None
if not self.optionmenu:
self.optionmenu = PesterOptions(self.config, self.theme, self)
@@ -2792,10 +3116,12 @@ class PesterWindow(MovingWindow):
self.optionmenu.show()
self.optionmenu.raise_()
self.optionmenu.activateWindow()
+
@QtCore.pyqtSlot()
def closeOptions(self):
self.optionmenu.close()
self.optionmenu = None
+
@QtCore.pyqtSlot()
def updateOptions(self):
try:
@@ -2820,7 +3146,7 @@ class PesterWindow(MovingWindow):
# combine
self.createTabWindow()
newconvos = {}
- for (h,c) in self.convos.items():
+ for (h, c) in self.convos.items():
c.setParent(self.tabconvo)
self.tabconvo.addChat(c)
self.tabconvo.show()
@@ -2850,7 +3176,7 @@ class PesterWindow(MovingWindow):
# combine
newmemos = {}
self.createMemoTabWindow()
- for (h,m) in self.memos.items():
+ for (h, m) in self.memos.items():
m.setParent(self.tabmemo)
self.tabmemo.addChat(m)
self.tabmemo.show()
@@ -2878,23 +3204,23 @@ class PesterWindow(MovingWindow):
chatsoundsetting = self.optionmenu.chatsoundcheck.isChecked()
curchatsound = self.config.chatSound()
if chatsoundsetting != curchatsound:
- self.config.set('chatSound', chatsoundsetting)
+ self.config.set("chatSound", chatsoundsetting)
memosoundsetting = self.optionmenu.memosoundcheck.isChecked()
curmemosound = self.config.memoSound()
if memosoundsetting != curmemosound:
- self.config.set('memoSound', memosoundsetting)
+ self.config.set("memoSound", memosoundsetting)
memopingsetting = self.optionmenu.memopingcheck.isChecked()
curmemoping = self.config.memoPing()
if memopingsetting != curmemoping:
- self.config.set('pingSound', memopingsetting)
+ self.config.set("pingSound", memopingsetting)
namesoundsetting = self.optionmenu.namesoundcheck.isChecked()
curnamesound = self.config.nameSound()
if namesoundsetting != curnamesound:
- self.config.set('nameSound', namesoundsetting)
+ self.config.set("nameSound", namesoundsetting)
volumesetting = self.optionmenu.volume.value()
curvolume = self.config.volume()
if volumesetting != curvolume:
- self.config.set('volume', volumesetting)
+ self.config.set("volume", volumesetting)
self.setVolume(volumesetting)
# timestamps
timestampsetting = self.optionmenu.timestampcheck.isChecked()
@@ -2907,8 +3233,8 @@ class PesterWindow(MovingWindow):
secondssetting = self.optionmenu.secondscheck.isChecked()
self.config.set("showSeconds", secondssetting)
# groups
- #groupssetting = self.optionmenu.groupscheck.isChecked()
- #self.config.set("useGroups", groupssetting)
+ # groupssetting = self.optionmenu.groupscheck.isChecked()
+ # self.config.set("useGroups", groupssetting)
emptygroupssetting = self.optionmenu.showemptycheck.isChecked()
curemptygroup = self.config.showEmptyGroups()
if curemptygroup and not emptygroupssetting:
@@ -2932,7 +3258,7 @@ class PesterWindow(MovingWindow):
logpesterssetting = logpesterssetting | self.config.STAMP
curlogpesters = self.config.logPesters()
if logpesterssetting != curlogpesters:
- self.config.set('logPesters', logpesterssetting)
+ self.config.set("logPesters", logpesterssetting)
logmemossetting = 0
if self.optionmenu.logmemoscheck.isChecked():
logmemossetting = logmemossetting | self.config.LOG
@@ -2940,22 +3266,22 @@ class PesterWindow(MovingWindow):
logmemossetting = logmemossetting | self.config.STAMP
curlogmemos = self.config.logMemos()
if logmemossetting != curlogmemos:
- self.config.set('logMemos', logmemossetting)
+ self.config.set("logMemos", logmemossetting)
# memo and user links
linkssetting = self.optionmenu.userlinkscheck.isChecked()
curlinks = self.config.disableUserLinks()
if linkssetting != curlinks:
- self.config.set('userLinks', not linkssetting)
+ self.config.set("userLinks", not linkssetting)
# idle time
idlesetting = self.optionmenu.idleBox.value()
curidle = self.config.idleTime()
if idlesetting != curidle:
- self.config.set('idleTime', idlesetting)
- self.idler.threshold = 60*idlesetting
+ self.config.set("idleTime", idlesetting)
+ self.idler.threshold = 60 * idlesetting
# theme
ghostchumsetting = self.optionmenu.ghostchum.isChecked()
curghostchum = self.config.ghostchum()
- self.config.set('ghostchum', ghostchumsetting)
+ self.config.set("ghostchum", ghostchumsetting)
self.themeSelected(ghostchumsetting != curghostchum)
# randoms
if self.randhandler.running:
@@ -2964,36 +3290,36 @@ class PesterWindow(MovingWindow):
minisetting = self.optionmenu.miniBox.currentIndex()
curmini = self.config.minimizeAction()
if minisetting != curmini:
- self.config.set('miniAction', minisetting)
+ self.config.set("miniAction", minisetting)
self.setButtonAction(self.miniButton, minisetting, curmini)
closesetting = self.optionmenu.closeBox.currentIndex()
curclose = self.config.closeAction()
if closesetting != curclose:
- self.config.set('closeAction', closesetting)
+ self.config.set("closeAction", closesetting)
self.setButtonAction(self.closeButton, closesetting, curclose)
# op and voice messages
opvmesssetting = self.optionmenu.memomessagecheck.isChecked()
curopvmess = self.config.opvoiceMessages()
if opvmesssetting != curopvmess:
- self.config.set('opvMessages', opvmesssetting)
+ self.config.set("opvMessages", opvmesssetting)
# animated smiles
animatesetting = self.optionmenu.animationscheck.isChecked()
curanimate = self.config.animations()
if animatesetting != curanimate:
- self.config.set('animations', animatesetting)
+ self.config.set("animations", animatesetting)
self.animationSetting.emit(animatesetting)
# update checked
- #updatechecksetting = self.optionmenu.updateBox.currentIndex()
- #curupdatecheck = self.config.checkForUpdates()
- #if updatechecksetting != curupdatecheck:
+ # updatechecksetting = self.optionmenu.updateBox.currentIndex()
+ # curupdatecheck = self.config.checkForUpdates()
+ # if updatechecksetting != curupdatecheck:
# self.config.set('checkUpdates', updatechecksetting)
# mspa update check
- #if ostools.isOSXLeopard():
+ # if ostools.isOSXLeopard():
# mspachecksetting = false
- #else:
+ # else:
# mspachecksetting = self.optionmenu.mspaCheck.isChecked()
- #curmspacheck = self.config.checkMSPA()
- #if mspachecksetting != curmspacheck:
+ # curmspacheck = self.config.checkMSPA()
+ # if mspachecksetting != curmspacheck:
# self.config.set('mspa', mspachecksetting)
# Taskbar blink
blinksetting = 0
@@ -3003,7 +3329,7 @@ class PesterWindow(MovingWindow):
blinksetting |= self.config.MBLINK
curblink = self.config.blink()
if blinksetting != curblink:
- self.config.set('blink', blinksetting)
+ self.config.set("blink", blinksetting)
# toast notifications
self.tm.setEnabled(self.optionmenu.notifycheck.isChecked())
self.tm.setCurrentType(str(self.optionmenu.notifyOptions.currentText()))
@@ -3020,12 +3346,12 @@ class PesterWindow(MovingWindow):
notifysetting |= self.config.INITIALS
curnotify = self.config.notifyOptions()
if notifysetting != curnotify:
- self.config.set('notifyOptions', notifysetting)
+ self.config.set("notifyOptions", notifysetting)
# low bandwidth
bandwidthsetting = self.optionmenu.bandwidthcheck.isChecked()
curbandwidth = self.config.lowBandwidth()
if bandwidthsetting != curbandwidth:
- self.config.set('lowBandwidth', bandwidthsetting)
+ self.config.set("lowBandwidth", bandwidthsetting)
if bandwidthsetting:
self.leftChannel.emit("#pesterchum")
else:
@@ -3052,18 +3378,18 @@ class PesterWindow(MovingWindow):
self.optionmenu = None
def setButtonAction(self, button, setting, old):
- if old == 0: # minimize to taskbar
+ if old == 0: # minimize to taskbar
button.clicked.disconnect(self.showMinimized)
- elif old == 1: # minimize to tray
+ elif old == 1: # minimize to tray
button.clicked.disconnect(self.closeToTray)
- elif old == 2: # quit
+ elif old == 2: # quit
button.clicked.disconnect(self.app.quit)
- if setting == 0: # minimize to taskbar
+ if setting == 0: # minimize to taskbar
button.clicked.connect(self.showMinimized)
- elif setting == 1: # minimize to tray
+ elif setting == 1: # minimize to tray
button.clicked.connect(self.closeToTray)
- elif setting == 2: # quit
+ elif setting == 2: # quit
button.clicked.connect(self.app.quit)
@QtCore.pyqtSlot()
@@ -3088,13 +3414,17 @@ class PesterWindow(MovingWindow):
# update profile
self.userprofile.setTheme(self.theme)
self.choosetheme = None
+
@QtCore.pyqtSlot()
def closeTheme(self):
self.choosetheme = None
+
@QtCore.pyqtSlot()
def profileSelected(self):
- if self.chooseprofile.profileBox and \
- self.chooseprofile.profileBox.currentIndex() > 0:
+ if (
+ self.chooseprofile.profileBox
+ and self.chooseprofile.profileBox.currentIndex() > 0
+ ):
handle = str(self.chooseprofile.profileBox.currentText())
if handle == self.profile().handle:
self.chooseprofile = None
@@ -3106,27 +3436,33 @@ class PesterWindow(MovingWindow):
msgBox = QtWidgets.QMessageBox()
msgBox.setIcon(QtWidgets.QMessageBox.Icon.Warning)
msgBox.setWindowTitle(":(")
- msgBox.setTextFormat(QtCore.Qt.TextFormat.RichText) # Clickable html links
- self.filename = _datadir+"pesterchum.js"
+ msgBox.setTextFormat(
+ QtCore.Qt.TextFormat.RichText
+ ) # Clickable html links
+ self.filename = _datadir + "pesterchum.js"
try:
- msg = ("Failed to load: "
- "%s/%s.js"
- "
"
- "Try to check for syntax errors if the file exists."
- "
"
- "If you got this message at launch you may want to "
- "change your default profile."
- "
%s<\h3><\html>"
- % (self.profiledir, self.profiledir, user, e))
-
+ msg = (
+ "Failed to load: "
+ "%s/%s.js"
+ "
"
+ "Try to check for syntax errors if the file exists."
+ "
"
+ "If you got this message at launch you may want to "
+ "change your default profile."
+ "
%s<\h3><\html>"
+ % (self.profiledir, self.profiledir, user, e)
+ )
+
except:
# More generic error for if not all variables are available.
- msg = ("Unspecified profile error."
- "
Try to check for syntax errors if the "
- "file exists."
- "
If you got this message at launch you may "
- "want to change your default profile."
- "
%s<\h3><\html>" % e)
+ msg = (
+ "Unspecified profile error."
+ "
Try to check for syntax errors if the "
+ "file exists."
+ "
If you got this message at launch you may "
+ "want to change your default profile."
+ "
%s<\h3><\html>" % e
+ )
PchumLog.critical(e)
msgBox.setText(msg)
msgBox.exec()
@@ -3136,8 +3472,7 @@ class PesterWindow(MovingWindow):
if handle == self.profile().handle:
self.chooseprofile = None
return
- profile = PesterProfile(handle,
- self.chooseprofile.chumcolor)
+ profile = PesterProfile(handle, self.chooseprofile.chumcolor)
self.userprofile = userProfile.newUserProfile(profile)
self.changeTheme(self.userprofile.getTheme())
@@ -3147,28 +3482,31 @@ class PesterWindow(MovingWindow):
# is default?
if self.chooseprofile.defaultcheck.isChecked():
self.config.set("defaultprofile", self.userprofile.chat.handle)
- if hasattr(self, 'trollslum') and self.trollslum:
+ if hasattr(self, "trollslum") and self.trollslum:
self.trollslum.close()
self.chooseprofile = None
self.profileChanged.emit()
+
@QtCore.pyqtSlot()
def showTrollSlum(self):
- if not hasattr(self, 'trollslum'):
+ if not hasattr(self, "trollslum"):
self.trollslum = None
if self.trollslum:
return
trolls = [PesterProfile(h) for h in self.config.getBlocklist()]
self.trollslum = TrollSlumWindow(trolls, self)
- self.trollslum.blockChumSignal['QString'].connect(self.blockChum)
- self.trollslum.unblockChumSignal['QString'].connect(self.unblockChum)
+ self.trollslum.blockChumSignal["QString"].connect(self.blockChum)
+ self.trollslum.unblockChumSignal["QString"].connect(self.unblockChum)
self.moodsRequest.emit(PesterList(trolls))
self.trollslum.show()
+
@QtCore.pyqtSlot()
def closeTrollSlum(self):
self.trollslum = None
+
@QtCore.pyqtSlot()
def changeMyColor(self):
- if not hasattr(self, 'colorDialog'):
+ if not hasattr(self, "colorDialog"):
self.colorDialog = None
if self.colorDialog:
return
@@ -3180,17 +3518,25 @@ class PesterWindow(MovingWindow):
self.userprofile.setColor(color)
self.mycolorUpdated.emit()
self.colorDialog = None
+
@QtCore.pyqtSlot()
def closeProfile(self):
self.chooseprofile = None
+
@QtCore.pyqtSlot()
def switchProfile(self):
if self.convos:
closeWarning = QtWidgets.QMessageBox()
- closeWarning.setText("WARNING: CHANGING PROFILES WILL CLOSE ALL CONVERSATION WINDOWS!")
- closeWarning.setInformativeText("i warned you about windows bro!!!! i told you dog!")
- closeWarning.setStandardButtons(QtWidgets.QMessageBox.StandardButton.Cancel
- | QtWidgets.QMessageBox.StandardButton.Ok)
+ closeWarning.setText(
+ "WARNING: CHANGING PROFILES WILL CLOSE ALL CONVERSATION WINDOWS!"
+ )
+ closeWarning.setInformativeText(
+ "i warned you about windows bro!!!! i told you dog!"
+ )
+ closeWarning.setStandardButtons(
+ QtWidgets.QMessageBox.StandardButton.Cancel
+ | QtWidgets.QMessageBox.StandardButton.Ok
+ )
closeWarning.setDefaultButton(QtWidgets.QMessageBox.StandardButton.Ok)
ret = closeWarning.exec()
if ret == QtWidgets.QMessageBox.StandardButton.Cancel:
@@ -3206,53 +3552,77 @@ class PesterWindow(MovingWindow):
except:
PchumLog.warning("No randomEncounter set in userconfig?")
self.mycolorUpdated.emit()
-
+
def aboutPesterchum(self):
- if hasattr(self, 'aboutwindow') and self.aboutwindow:
+ if hasattr(self, "aboutwindow") and self.aboutwindow:
return
self.aboutwindow = AboutPesterchum(self)
self.aboutwindow.exec()
self.aboutwindow = None
+
@QtCore.pyqtSlot()
def loadCalsprite(self):
self.newConversation("calSprite")
+
@QtCore.pyqtSlot()
def loadChanServ(self):
self.newConversation("chanServ")
+
@QtCore.pyqtSlot()
def loadNickServ(self):
self.newConversation("nickServ")
+
@QtCore.pyqtSlot()
def launchHelp(self):
- QtGui.QDesktopServices.openUrl(QtCore.QUrl("https://github.com/Dpeta/pesterchum-alt-servers/issues",
- QtCore.QUrl.ParsingMode.TolerantMode))
- QtGui.QDesktopServices.openUrl(QtCore.QUrl("https://forum.homestuck.xyz/viewtopic.php?f=7&t=467",
- QtCore.QUrl.ParsingMode.TolerantMode))
+ QtGui.QDesktopServices.openUrl(
+ QtCore.QUrl(
+ "https://github.com/Dpeta/pesterchum-alt-servers/issues",
+ QtCore.QUrl.ParsingMode.TolerantMode,
+ )
+ )
+ QtGui.QDesktopServices.openUrl(
+ QtCore.QUrl(
+ "https://forum.homestuck.xyz/viewtopic.php?f=7&t=467",
+ QtCore.QUrl.ParsingMode.TolerantMode,
+ )
+ )
+
@QtCore.pyqtSlot()
def reportBug(self):
- QtGui.QDesktopServices.openUrl(QtCore.QUrl("https://github.com/Dpeta/pesterchum-alt-servers/issues",
- QtCore.QUrl.ParsingMode.TolerantMode))
+ QtGui.QDesktopServices.openUrl(
+ QtCore.QUrl(
+ "https://github.com/Dpeta/pesterchum-alt-servers/issues",
+ QtCore.QUrl.ParsingMode.TolerantMode,
+ )
+ )
@QtCore.pyqtSlot()
def xyzRules(self):
- QtGui.QDesktopServices.openUrl(QtCore.QUrl("https://www.pesterchum.xyz/pesterchum-rules",
- QtCore.QUrl.ParsingMode.TolerantMode))
+ QtGui.QDesktopServices.openUrl(
+ QtCore.QUrl(
+ "https://www.pesterchum.xyz/pesterchum-rules",
+ QtCore.QUrl.ParsingMode.TolerantMode,
+ )
+ )
@QtCore.pyqtSlot(QString, QString)
def nickCollision(self, handle, tmphandle):
- if hasattr(self, 'loadingscreen'):
+ 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.userprofile = userProfile(
+ PesterProfile(
+ "pesterClient%d" % (random.randint(100, 999)),
+ QtGui.QColor("black"),
+ Mood(0),
+ )
+ )
self.changeTheme(self.userprofile.getTheme())
- if not hasattr(self, 'chooseprofile'):
+ if not hasattr(self, "chooseprofile"):
self.chooseprofile = None
if not self.chooseprofile:
h = str(handle)
@@ -3260,21 +3630,22 @@ class PesterWindow(MovingWindow):
@QtCore.pyqtSlot(QString, QString)
def getSvsnickedOn(self, oldhandle, newhandle):
- if hasattr(self, 'loadingscreen'):
+ 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.userprofile = userProfile(
+ PesterProfile(newhandle, QtGui.QColor("black"), Mood(0))
+ )
self.changeTheme(self.userprofile.getTheme())
- if not hasattr(self, 'chooseprofile'):
+ if not hasattr(self, "chooseprofile"):
self.chooseprofile = None
if not self.chooseprofile:
self.changeProfile(svsnick=(oldhandle, newhandle))
+
@QtCore.pyqtSlot(QString)
def myHandleChanged(self, handle):
# Update nick in channels
@@ -3286,6 +3657,7 @@ class PesterWindow(MovingWindow):
return
else:
self.nickCollision(self.profile().handle, handle)
+
@QtCore.pyqtSlot()
def pickTheme(self):
self.themePicker()
@@ -3294,18 +3666,19 @@ class PesterWindow(MovingWindow):
def systemTrayActivated(self, reason):
if reason == QtWidgets.QSystemTrayIcon.ActivationReason.Trigger:
self.systemTrayFunction()
- #elif reason == QtWidgets.QSystemTrayIcon.Context:
+ # elif reason == QtWidgets.QSystemTrayIcon.Context:
# pass
- # show context menu i guess
- #self.showTrayContext.emit()
+ # show context menu i guess
+ # self.showTrayContext.emit()
@QtCore.pyqtSlot()
def tooManyPeeps(self):
msg = QtWidgets.QMessageBox(self)
msg.setText("D: TOO MANY PEOPLE!!!")
- msg.setInformativeText("The server has hit max capacity."
- "Please try again later.")
- #msg.setStyleSheet("QMessageBox{" + self.theme["main/defaultwindow/style"] + "}")
+ msg.setInformativeText(
+ "The server has hit max capacity." "Please try again later."
+ )
+ # msg.setStyleSheet("QMessageBox{" + self.theme["main/defaultwindow/style"] + "}")
msg.exec()
@QtCore.pyqtSlot(QString, QString)
@@ -3323,18 +3696,21 @@ class PesterWindow(MovingWindow):
def updateServerJson(self):
PchumLog.info(self.customServerPrompt_qline.text() + " chosen")
- server_and_port = self.customServerPrompt_qline.text().split(':')
+ server_and_port = self.customServerPrompt_qline.text().split(":")
try:
server = {
"server": server_and_port[0],
- "port": int(server_and_port[1]),# to make sure port is a valid integer, and raise an exception if it cannot be converted.
- "TLS": self.TLS_checkbox.isChecked()
- }
- PchumLog.info("server: "+str(server))
+ "port": int(
+ server_and_port[1]
+ ), # to make sure port is a valid integer, and raise an exception if it cannot be converted.
+ "TLS": self.TLS_checkbox.isChecked(),
+ }
+ PchumLog.info("server: " + str(server))
except:
msgbox = QtWidgets.QMessageBox()
- msgbox.setStyleSheet("QMessageBox{ %s }"
- % self.theme["main/defaultwindow/style"])
+ msgbox.setStyleSheet(
+ "QMessageBox{ %s }" % self.theme["main/defaultwindow/style"]
+ )
msgbox.setWindowIcon(PesterIcon(self.theme["main/icon"]))
msgbox.setInformativeText("Incorrect format :(")
msgbox.setStandardButtons(QtWidgets.QMessageBox.StandardButton.Ok)
@@ -3349,44 +3725,51 @@ class PesterWindow(MovingWindow):
server_list_obj.append(server)
try:
with open(_datadir + "serverlist.json", "w") as server_file:
- server_file.write(json.dumps(server_list_obj, indent = 4))
+ server_file.write(json.dumps(server_list_obj, indent=4))
server_file.close()
except:
- PchumLog.error("failed")
+ PchumLog.error("failed")
# Go back to original screen
self.chooseServer()
-
+
def resetServerlist(self):
- default_server_list = [{
- "server": "irc.pesterchum.xyz",
- "port": "6697",
- "TLS": True
- }]
+ default_server_list = [
+ {"server": "irc.pesterchum.xyz", "port": "6697", "TLS": True}
+ ]
if os.path.isfile(_datadir + "serverlist.json"):
PchumLog.error("Failed to load server list from serverlist.json.")
msgbox = QtWidgets.QMessageBox()
- msgbox.setStyleSheet("QMessageBox{ %s }"
- % self.theme["main/defaultwindow/style"])
+ msgbox.setStyleSheet(
+ "QMessageBox{ %s }" % self.theme["main/defaultwindow/style"]
+ )
msgbox.setWindowIcon(PesterIcon(self.theme["main/icon"]))
- msgbox.setInformativeText("Failed to load server list, do you want to revert to defaults?\n"
- "If you choose no, Pesterchum will most likely crash unless you manually fix serverlist.json\n"
- "Please tell me if this error occurs :'3")
- msgbox.addButton(QtWidgets.QPushButton("Yes"), QtWidgets.QMessageBox.ButtonRole.YesRole)
- msgbox.addButton(QtWidgets.QPushButton("No"), QtWidgets.QMessageBox.ButtonRole.NoRole)
+ msgbox.setInformativeText(
+ "Failed to load server list, do you want to revert to defaults?\n"
+ "If you choose no, Pesterchum will most likely crash unless you manually fix serverlist.json\n"
+ "Please tell me if this error occurs :'3"
+ )
+ msgbox.addButton(
+ QtWidgets.QPushButton("Yes"), QtWidgets.QMessageBox.ButtonRole.YesRole
+ )
+ msgbox.addButton(
+ QtWidgets.QPushButton("No"), QtWidgets.QMessageBox.ButtonRole.NoRole
+ )
msgbox.exec()
- if (reply==QtWidgets.QMessageBox.ButtonRole.YesRole):
+ if reply == QtWidgets.QMessageBox.ButtonRole.YesRole:
with open(_datadir + "serverlist.json", "w") as server_file:
- server_file.write(json.dumps(default_server_list, indent = 4) )
+ server_file.write(json.dumps(default_server_list, indent=4))
server_file.close()
else:
- PchumLog.warning("Failed to load server list because serverlist.json doesn't exist, "
- "this isn't an issue if this is the first time Pesterchum has been started.")
+ PchumLog.warning(
+ "Failed to load server list because serverlist.json doesn't exist, "
+ "this isn't an issue if this is the first time Pesterchum has been started."
+ )
with open(_datadir + "serverlist.json", "w") as server_file:
- server_file.write(json.dumps(default_server_list, indent = 4) )
- server_file.close()
+ server_file.write(json.dumps(default_server_list, indent=4))
+ server_file.close()
self.chooseServer()
def removeServer(self):
@@ -3405,20 +3788,19 @@ class PesterWindow(MovingWindow):
return 1
selected_entry = None
-
+
for i in range(len(server_list_obj)):
if server_list_obj[i]["server"] == self.removeServerBox.currentText():
selected_entry = i
if selected_entry != None:
server_list_obj.pop(selected_entry)
-
+
try:
with open(_datadir + "serverlist.json", "w") as server_file:
- server_file.write(json.dumps(server_list_obj, indent = 4))
+ server_file.write(json.dumps(server_list_obj, indent=4))
server_file.close()
except:
- PchumLog.error("failed")
-
+ PchumLog.error("failed")
self.chooseServer()
@@ -3427,45 +3809,53 @@ class PesterWindow(MovingWindow):
# Text input
self.customServerPrompt_qline = QtWidgets.QLineEdit(self)
self.customServerPrompt_qline.setMinimumWidth(200)
-
+
# Widget 1
self.customServerDialog = QtWidgets.QDialog()
-
+
# Buttons
cancel = QtWidgets.QPushButton("CANCEL")
ok = QtWidgets.QPushButton("OK")
-
+
ok.setDefault(True)
ok.clicked.connect(self.customServerDialog.accept)
cancel.clicked.connect(self.customServerDialog.reject)
-
- #Layout
+
+ # Layout
layout = QtWidgets.QHBoxLayout()
-
+
self.TLS_checkbox = QtWidgets.QCheckBox(self)
self.TLS_checkbox.setChecked(True)
- TLS_checkbox_label = QtWidgets.QLabel(":33 < Check if you want to connect over TLS!!")
- TLS_checkbox_label.setStyleSheet("QLabel { color: #416600; font-weight: bold;}")
+ TLS_checkbox_label = QtWidgets.QLabel(
+ ":33 < Check if you want to connect over TLS!!"
+ )
+ TLS_checkbox_label.setStyleSheet(
+ "QLabel { color: #416600; font-weight: bold;}"
+ )
TLS_layout = QtWidgets.QHBoxLayout()
TLS_layout.addWidget(TLS_checkbox_label)
TLS_layout.addWidget(self.TLS_checkbox)
-
+
layout.addWidget(cancel)
layout.addWidget(ok)
main_layout = QtWidgets.QVBoxLayout()
- nep_prompt = QtWidgets.QLabel(":33 < Please put in the server's address in the format HOSTNAME:PORT\n:33 < Fur example, irc.pesterchum.xyz:6697")
+ nep_prompt = QtWidgets.QLabel(
+ ":33 < Please put in the server's address in the format HOSTNAME:PORT\n:33 < Fur example, irc.pesterchum.xyz:6697"
+ )
nep_prompt.setStyleSheet("QLabel { color: #416600; font-weight: bold;}")
main_layout.addWidget(nep_prompt)
main_layout.addWidget(self.customServerPrompt_qline)
main_layout.addLayout(TLS_layout)
main_layout.addLayout(layout)
-
+
self.customServerDialog.setLayout(main_layout)
-
+
# Theme
- self.customServerDialog.setStyleSheet(self.theme["main/defaultwindow/style"])
+ self.customServerDialog.setStyleSheet(
+ self.theme["main/defaultwindow/style"]
+ )
self.customServerDialog.setWindowIcon(PesterIcon(self.theme["main/icon"]))
-
+
# Connect
self.customServerDialog.accepted.connect(self.updateServerJson)
self.customServerDialog.rejected.connect(self.chooseServer)
@@ -3473,7 +3863,7 @@ class PesterWindow(MovingWindow):
# Show
self.customServerDialog.show()
self.customServerDialog.setFocus()
-
+
elif self.serverBox.currentText() == "Remove a server [Prompt]":
# Read servers.
server_list_items = []
@@ -3489,27 +3879,27 @@ class PesterWindow(MovingWindow):
self.chooseServerAskedToReset = True
self.resetServerlist()
return 1
-
+
PchumLog.info("server_list_items: " + str(server_list_items))
-
+
# Widget 1
self.chooseRemoveServerWidged = QtWidgets.QDialog()
-
+
# removeServerBox
self.removeServerBox = QtWidgets.QComboBox()
for i in range(len(server_list_items)):
self.removeServerBox.addItem(server_list_items[i])
-
+
# Buttons
cancel = QtWidgets.QPushButton("CANCEL")
ok = QtWidgets.QPushButton("OK")
-
+
ok.setDefault(True)
ok.clicked.connect(self.chooseRemoveServerWidged.accept)
cancel.clicked.connect(self.chooseRemoveServerWidged.reject)
-
- #Layout
+
+ # Layout
layout = QtWidgets.QHBoxLayout()
layout.addWidget(cancel)
layout.addWidget(ok)
@@ -3517,13 +3907,17 @@ class PesterWindow(MovingWindow):
main_layout.addWidget(QtWidgets.QLabel("Please choose a server to remove."))
main_layout.addWidget(self.removeServerBox)
main_layout.addLayout(layout)
-
+
self.chooseRemoveServerWidged.setLayout(main_layout)
-
+
# Theme
- self.chooseRemoveServerWidged.setStyleSheet(self.theme["main/defaultwindow/style"])
- self.chooseRemoveServerWidged.setWindowIcon(PesterIcon(self.theme["main/icon"]))
-
+ self.chooseRemoveServerWidged.setStyleSheet(
+ self.theme["main/defaultwindow/style"]
+ )
+ self.chooseRemoveServerWidged.setWindowIcon(
+ PesterIcon(self.theme["main/icon"])
+ )
+
# Connect
self.chooseRemoveServerWidged.accepted.connect(self.removeServer)
self.chooseRemoveServerWidged.rejected.connect(self.chooseServer)
@@ -3540,19 +3934,19 @@ class PesterWindow(MovingWindow):
server_obj = json.loads(read_file)
selected_entry = None
-
+
for i in range(len(server_obj)):
if server_obj[i]["server"] == self.serverBox.currentText():
selected_entry = i
-
+
try:
with open(_datadir + "server.json", "w") as server_file:
json_server_file = {
- "server": server_obj[selected_entry]["server"],
- "port": server_obj[selected_entry]["port"],
- "TLS": server_obj[selected_entry]["TLS"]
- }
- server_file.write(json.dumps(json_server_file, indent = 4) )
+ "server": server_obj[selected_entry]["server"],
+ "port": server_obj[selected_entry]["port"],
+ "TLS": server_obj[selected_entry]["TLS"],
+ }
+ server_file.write(json.dumps(json_server_file, indent=4))
server_file.close()
except:
PchumLog.error("Failed to set server :(")
@@ -3562,7 +3956,7 @@ class PesterWindow(MovingWindow):
self.irc.start()
self.parent.reconnectok = False
self.parent.showLoading(self.parent.widget)
- self.show() # Not required?
+ self.show() # Not required?
self.setFocus()
def chooseServer(self):
@@ -3580,30 +3974,30 @@ class PesterWindow(MovingWindow):
self.chooseServerAskedToReset = True
self.resetServerlist()
return 1
-
+
PchumLog.info("server_list_items: " + str(server_list_items))
-
+
# Widget 1
self.chooseServerWidged = QtWidgets.QDialog()
-
+
# Serverbox
self.serverBox = QtWidgets.QComboBox()
for i in range(len(server_list_items)):
self.serverBox.addItem(server_list_items[i])
-
+
self.serverBox.addItem("Add a server [Prompt]")
self.serverBox.addItem("Remove a server [Prompt]")
-
+
# Buttons
cancel = QtWidgets.QPushButton("CANCEL")
ok = QtWidgets.QPushButton("OK")
-
+
ok.setDefault(True)
ok.clicked.connect(self.chooseServerWidged.accept)
cancel.clicked.connect(self.chooseServerWidged.reject)
-
- #Layout
+
+ # Layout
layout = QtWidgets.QHBoxLayout()
layout.addWidget(cancel)
layout.addWidget(ok)
@@ -3611,17 +4005,18 @@ class PesterWindow(MovingWindow):
main_layout.addWidget(QtWidgets.QLabel("Please choose a server."))
main_layout.addWidget(self.serverBox)
main_layout.addLayout(layout)
-
+
self.chooseServerWidged.setLayout(main_layout)
-
+
# Theme
self.chooseServerWidged.setStyleSheet(self.theme["main/defaultwindow/style"])
self.chooseServerWidged.setWindowIcon(PesterIcon(self.theme["main/icon"]))
-
+
# Connect
self.chooseServerWidged.accepted.connect(self.setServer)
- self.chooseServerWidged.rejected.connect(self.killApp,
- QtCore.Qt.ConnectionType.QueuedConnection)
+ self.chooseServerWidged.rejected.connect(
+ self.killApp, QtCore.Qt.ConnectionType.QueuedConnection
+ )
# Show
self.chooseServerWidged.show()
@@ -3632,56 +4027,62 @@ class PesterWindow(MovingWindow):
# Prompt user to connect anyway
msgbox = QtWidgets.QMessageBox()
try:
- msgbox.setStyleSheet("QMessageBox{ %s }"
- % self.theme["main/defaultwindow/style"])
+ msgbox.setStyleSheet(
+ "QMessageBox{ %s }" % self.theme["main/defaultwindow/style"]
+ )
except:
pass
msgbox.setIcon(QtWidgets.QMessageBox.Icon.Warning)
msgbox.setText("Server certificate validation failed")
- msgbox.setInformativeText("Reason: \"%s (%s)\"" % (e.verify_message, e.verify_code)
- + "\n\nConnect anyway?")
- msgbox.setStandardButtons(QtWidgets.QMessageBox.StandardButton.Yes
- | QtWidgets.QMessageBox.StandardButton.No)
+ msgbox.setInformativeText(
+ 'Reason: "%s (%s)"' % (e.verify_message, e.verify_code)
+ + "\n\nConnect anyway?"
+ )
+ msgbox.setStandardButtons(
+ QtWidgets.QMessageBox.StandardButton.Yes
+ | QtWidgets.QMessageBox.StandardButton.No
+ )
msgbox.setDefaultButton(QtWidgets.QMessageBox.StandardButton.No)
ret = msgbox.exec()
if ret == QtWidgets.QMessageBox.StandardButton.Yes:
- self.parent.restartIRC(verify_hostname=False)
+ self.parent.restartIRC(verify_hostname=False)
- pcUpdate = QtCore.pyqtSignal('QString', 'QString')
+ pcUpdate = QtCore.pyqtSignal("QString", "QString")
closeToTraySignal = QtCore.pyqtSignal()
- newConvoStarted = QtCore.pyqtSignal('QString', bool, name="newConvoStarted")
- sendMessage = QtCore.pyqtSignal('QString', 'QString')
- sendNotice = QtCore.pyqtSignal('QString', 'QString')
- sendCTCP = QtCore.pyqtSignal('QString', 'QString')
- convoClosed = QtCore.pyqtSignal('QString')
+ newConvoStarted = QtCore.pyqtSignal("QString", bool, name="newConvoStarted")
+ sendMessage = QtCore.pyqtSignal("QString", "QString")
+ sendNotice = QtCore.pyqtSignal("QString", "QString")
+ sendCTCP = QtCore.pyqtSignal("QString", "QString")
+ convoClosed = QtCore.pyqtSignal("QString")
profileChanged = QtCore.pyqtSignal()
animationSetting = QtCore.pyqtSignal(bool)
moodRequest = QtCore.pyqtSignal(PesterProfile)
moodsRequest = QtCore.pyqtSignal(PesterList)
moodUpdated = QtCore.pyqtSignal()
requestChannelList = QtCore.pyqtSignal()
- requestNames = QtCore.pyqtSignal('QString')
- namesUpdated = QtCore.pyqtSignal('QString')
- modesUpdated = QtCore.pyqtSignal('QString', 'QString')
- userPresentSignal = QtCore.pyqtSignal('QString','QString','QString')
+ requestNames = QtCore.pyqtSignal("QString")
+ namesUpdated = QtCore.pyqtSignal("QString")
+ modesUpdated = QtCore.pyqtSignal("QString", "QString")
+ userPresentSignal = QtCore.pyqtSignal("QString", "QString", "QString")
mycolorUpdated = QtCore.pyqtSignal()
trayIconSignal = QtCore.pyqtSignal(int)
- blockedChum = QtCore.pyqtSignal('QString')
- unblockedChum = QtCore.pyqtSignal('QString')
- kickUser = QtCore.pyqtSignal('QString', 'QString')
- joinChannel = QtCore.pyqtSignal('QString')
- leftChannel = QtCore.pyqtSignal('QString')
- setChannelMode = QtCore.pyqtSignal('QString', 'QString', 'QString')
- channelNames = QtCore.pyqtSignal('QString')
- inviteChum = QtCore.pyqtSignal('QString', 'QString')
- inviteOnlyChan = QtCore.pyqtSignal('QString')
- forbiddenChan = QtCore.pyqtSignal('QString', 'QString')
+ blockedChum = QtCore.pyqtSignal("QString")
+ unblockedChum = QtCore.pyqtSignal("QString")
+ kickUser = QtCore.pyqtSignal("QString", "QString")
+ joinChannel = QtCore.pyqtSignal("QString")
+ leftChannel = QtCore.pyqtSignal("QString")
+ setChannelMode = QtCore.pyqtSignal("QString", "QString", "QString")
+ channelNames = QtCore.pyqtSignal("QString")
+ inviteChum = QtCore.pyqtSignal("QString", "QString")
+ inviteOnlyChan = QtCore.pyqtSignal("QString")
+ forbiddenChan = QtCore.pyqtSignal("QString", "QString")
closeSignal = QtCore.pyqtSignal()
disconnectIRC = QtCore.pyqtSignal()
gainAttention = QtCore.pyqtSignal(QtWidgets.QWidget)
pingServer = QtCore.pyqtSignal()
setAway = QtCore.pyqtSignal(bool)
- killSomeQuirks = QtCore.pyqtSignal('QString', 'QString')
+ killSomeQuirks = QtCore.pyqtSignal("QString", "QString")
+
class PesterTray(QtWidgets.QSystemTrayIcon):
def __init__(self, icon, mainwindow, parent):
@@ -3694,10 +4095,12 @@ class PesterTray(QtWidgets.QSystemTrayIcon):
self.setIcon(PesterIcon(self.mainwindow.theme["main/icon"]))
else:
self.setIcon(PesterIcon(self.mainwindow.theme["main/newmsgicon"]))
+
@QtCore.pyqtSlot()
def mainWindowClosed(self):
self.hide()
+
class MainProgram(QtCore.QObject):
def __init__(self):
super(MainProgram, self).__init__()
@@ -3712,6 +4115,7 @@ class MainProgram(QtCore.QObject):
# Windows computer at the moment. Hopefully it'll work.
# See https://stackoverflow.com/a/1552105 for more details.
from ctypes import windll
+
# Note that this has to be unicode.
wid = "mspa.homestuck.pesterchum.314"
# Designate this as a separate process - i.e., tell Windows that
@@ -3729,46 +4133,47 @@ 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:])
-
+
# Check if the user is a silly little guy
- for folder in ['smilies', 'themes']:
+ for folder in ["smilies", "themes"]:
if not os.path.isdir(folder):
msgbox = QtWidgets.QMessageBox()
- msg = ("'%s' folder not found, Pesterchum will "
- "probably not function correctly."
- "\nIf this is an excecutable build, "
- "verify you extracted the zipfile." % folder)
+ msg = (
+ "'%s' folder not found, Pesterchum will "
+ "probably not function correctly."
+ "\nIf this is an excecutable build, "
+ "verify you extracted the zipfile." % folder
+ )
msgbox.setWindowTitle("SK1LL 1SSU3 >:[")
msgbox.setInformativeText(msg)
msgbox.setIcon(QtWidgets.QMessageBox.Icon.Critical)
msgbox.exec()
-
-
+
# If we're using pygame for sound we need to init
- if 'pygame' in sys.modules:
+ if "pygame" in sys.modules:
# we could set the frequency higher but i love how cheesy it sounds
try:
pygame.mixer.init()
except (pygame.error, Exception) as err:
print("Warning: No sound! (pygame error: %s)" % err)
-
- self.widget = PesterWindow(options, parent=self, app=self.app)
- #self.widget.show() <== Already called in showLoading()
- self.trayicon = PesterTray(PesterIcon(self.widget.theme["main/icon"]),
- self.widget,
- self.app)
+ self.widget = PesterWindow(options, parent=self, app=self.app)
+ # self.widget.show() <== Already called in showLoading()
+
+ self.trayicon = PesterTray(
+ PesterIcon(self.widget.theme["main/icon"]), self.widget, self.app
+ )
self.traymenu = QtWidgets.QMenu()
-
+
moodMenu = self.traymenu.addMenu("SET MOOD")
moodCategories = {}
for k in Mood.moodcats:
moodCategories[k] = moodMenu.addMenu(k.upper())
self.moodactions = {}
- for (i,m) in enumerate(Mood.moods):
+ for (i, m) in enumerate(Mood.moods):
maction = QAction(m.upper(), self)
mobj = PesterMoodAction(i, self.widget.moods.updateMood)
maction.triggered.connect(mobj.updateMood)
@@ -3777,41 +4182,47 @@ class MainProgram(QtCore.QObject):
miniAction = QAction("MINIMIZE", self)
miniAction.triggered.connect(self.widget.showMinimized)
exitAction = QAction("EXIT", self)
- exitAction.triggered.connect(self.widget.killApp, QtCore.Qt.ConnectionType.QueuedConnection)
+ exitAction.triggered.connect(
+ self.widget.killApp, QtCore.Qt.ConnectionType.QueuedConnection
+ )
self.traymenu.addAction(miniAction)
self.traymenu.addAction(exitAction)
self.trayicon.setContextMenu(self.traymenu)
self.trayicon.show()
- self.trayicon.activated[QtWidgets.QSystemTrayIcon.ActivationReason].connect(self.widget.systemTrayActivated)
+ self.trayicon.activated[QtWidgets.QSystemTrayIcon.ActivationReason].connect(
+ self.widget.systemTrayActivated
+ )
self.widget.trayIconSignal[int].connect(self.trayicon.changeTrayIcon)
self.widget.closeToTraySignal.connect(self.trayiconShow)
self.widget.closeSignal.connect(self.trayicon.mainWindowClosed)
self.trayicon.messageClicked.connect(self.trayMessageClick)
self.attempts = 0
-
+
# but it's at least better than the way it was before.
self.irc = PesterIRC(self.widget.config, self.widget)
self.connectWidgets(self.irc, self.widget)
- self.widget.passIRC(self.irc) # Maybe this is absolutely terrible in practice, but screw it.
+ 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.lastWindowClosed.connect(self.lastWindow)
self.app.aboutToQuit.connect(self.death)
def death(self):
# app murder in progress
- #print("death inbound")
- if hasattr(self, 'widget'):
+ # print("death inbound")
+ if hasattr(self, "widget"):
self.widget.killApp()
- #def lastWindow(self):
+ # def lastWindow(self):
# print("all windows closed")
# if hasattr(self, 'widget'):
# self.widget.killApp()
-
+
@QtCore.pyqtSlot(QtWidgets.QWidget)
def alertWindow(self, widget):
self.app.alert(widget)
@@ -3820,141 +4231,144 @@ 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."))
+ self.trayicon.showMessage(
+ "Pesterchum",
+ (
+ "Pesterchum is still running in the system tray."
+ "\n"
+ "Right click to close it."
+ ),
+ )
@QtCore.pyqtSlot()
def trayMessageClick(self):
- self.widget.config.set('traymsg', False)
+ self.widget.config.set("traymsg", False)
+
+ widget2irc = [
+ ("sendMessage(QString, QString)", "sendMessage(QString, QString)"),
+ ("sendNotice(QString, QString)", "sendNotice(QString, QString)"),
+ ("sendCTCP(QString, QString)", "sendCTCP(QString, QString)"),
+ ("newConvoStarted(QString, bool)", "startConvo(QString, bool)"),
+ ("convoClosed(QString)", "endConvo(QString)"),
+ ("profileChanged()", "updateProfile()"),
+ ("moodRequest(PyQt_PyObject)", "getMood(PyQt_PyObject)"),
+ ("moodsRequest(PyQt_PyObject)", "getMoods(PyQt_PyObject)"),
+ ("moodUpdated()", "updateMood()"),
+ ("mycolorUpdated()", "updateColor()"),
+ ("blockedChum(QString)", "blockedChum(QString)"),
+ ("unblockedChum(QString)", "unblockedChum(QString)"),
+ ("requestNames(QString)", "requestNames(QString)"),
+ ("requestChannelList()", "requestChannelList()"),
+ ("joinChannel(QString)", "joinChannel(QString)"),
+ ("leftChannel(QString)", "leftChannel(QString)"),
+ ("kickUser(QString, QString)", "kickUser(QString, QString)"),
+ (
+ "setChannelMode(QString, QString, QString)",
+ "setChannelMode(QString, QString, QString)",
+ ),
+ ("channelNames(QString)", "channelNames(QString)"),
+ ("inviteChum(QString, QString)", "inviteChum(QString, QString)"),
+ ("pingServer()", "pingServer()"),
+ ("setAway(bool)", "setAway(bool)"),
+ ("killSomeQuirks(QString, QString)", "killSomeQuirks(QString, QString)"),
+ ("disconnectIRC()", "disconnectIRC()"),
+ ]
+ # IRC --> Main window
+ irc2widget = [
+ ("connected()", "connected()"),
+ (
+ "moodUpdated(QString, PyQt_PyObject)",
+ "updateMoodSlot(QString, PyQt_PyObject)",
+ ),
+ (
+ "colorUpdated(QString, QtGui.QColor)",
+ "updateColorSlot(QString, QtGui.QColor)",
+ ),
+ ("messageReceived(QString, QString)", "deliverMessage(QString, QString)"),
+ (
+ "memoReceived(QString, QString, QString)",
+ "deliverMemo(QString, QString, QString)",
+ ),
+ ("noticeReceived(QString, QString)", "deliverNotice(QString, QString)"),
+ ("inviteReceived(QString, QString)", "deliverInvite(QString, QString)"),
+ ("nickCollision(QString, QString)", "nickCollision(QString, QString)"),
+ ("getSvsnickedOn(QString, QString)", "getSvsnickedOn(QString, QString)"),
+ ("myHandleChanged(QString)", "myHandleChanged(QString)"),
+ (
+ "namesReceived(QString, PyQt_PyObject)",
+ "updateNames(QString, PyQt_PyObject)",
+ ),
+ (
+ "userPresentUpdate(QString, QString, QString)",
+ "userPresentUpdate(QString, QString, QString)",
+ ),
+ ("channelListReceived(PyQt_PyObject)", "updateChannelList(PyQt_PyObject)"),
+ (
+ "timeCommand(QString, QString, QString)",
+ "timeCommand(QString, QString, QString)",
+ ),
+ ("chanInviteOnly(QString)", "chanInviteOnly(QString)"),
+ ("modesUpdated(QString, QString)", "modesUpdated(QString, QString)"),
+ ("cannotSendToChan(QString, QString)", "cannotSendToChan(QString, QString)"),
+ ("tooManyPeeps()", "tooManyPeeps()"),
+ (
+ "quirkDisable(QString, QString, QString)",
+ "quirkDisable(QString, QString, QString)",
+ ),
+ ("forbiddenchannel(QString)", "forbiddenchannel(QString)"),
+ ]
- widget2irc = [('sendMessage(QString, QString)',
- 'sendMessage(QString, QString)'),
- ('sendNotice(QString, QString)',
- 'sendNotice(QString, QString)'),
- ('sendCTCP(QString, QString)',
- 'sendCTCP(QString, QString)'),
- ('newConvoStarted(QString, bool)',
- 'startConvo(QString, bool)'),
- ('convoClosed(QString)',
- 'endConvo(QString)'),
- ('profileChanged()',
- 'updateProfile()'),
- ('moodRequest(PyQt_PyObject)',
- 'getMood(PyQt_PyObject)'),
- ('moodsRequest(PyQt_PyObject)',
- 'getMoods(PyQt_PyObject)'),
- ('moodUpdated()', 'updateMood()'),
- ('mycolorUpdated()','updateColor()'),
- ('blockedChum(QString)', 'blockedChum(QString)'),
- ('unblockedChum(QString)', 'unblockedChum(QString)'),
- ('requestNames(QString)','requestNames(QString)'),
- ('requestChannelList()', 'requestChannelList()'),
- ('joinChannel(QString)', 'joinChannel(QString)'),
- ('leftChannel(QString)', 'leftChannel(QString)'),
- ('kickUser(QString, QString)',
- 'kickUser(QString, QString)'),
- ('setChannelMode(QString, QString, QString)',
- 'setChannelMode(QString, QString, QString)'),
- ('channelNames(QString)',
- 'channelNames(QString)'),
- ('inviteChum(QString, QString)',
- 'inviteChum(QString, QString)'),
- ('pingServer()', 'pingServer()'),
- ('setAway(bool)', 'setAway(bool)'),
- ('killSomeQuirks(QString, QString)',
- 'killSomeQuirks(QString, QString)'),
- ('disconnectIRC()', 'disconnectIRC()')
- ]
-# IRC --> Main window
- irc2widget = [('connected()', 'connected()'),
- ('moodUpdated(QString, PyQt_PyObject)',
- 'updateMoodSlot(QString, PyQt_PyObject)'),
- ('colorUpdated(QString, QtGui.QColor)',
- 'updateColorSlot(QString, QtGui.QColor)'),
- ('messageReceived(QString, QString)',
- 'deliverMessage(QString, QString)'),
- ('memoReceived(QString, QString, QString)',
- 'deliverMemo(QString, QString, QString)'),
- ('noticeReceived(QString, QString)',
- 'deliverNotice(QString, QString)'),
- ('inviteReceived(QString, QString)',
- 'deliverInvite(QString, QString)'),
- ('nickCollision(QString, QString)',
- 'nickCollision(QString, QString)'),
- ('getSvsnickedOn(QString, QString)',
- 'getSvsnickedOn(QString, QString)'),
- ('myHandleChanged(QString)',
- 'myHandleChanged(QString)'),
- ('namesReceived(QString, PyQt_PyObject)',
- 'updateNames(QString, PyQt_PyObject)'),
- ('userPresentUpdate(QString, QString, QString)',
- 'userPresentUpdate(QString, QString, QString)'),
- ('channelListReceived(PyQt_PyObject)',
- 'updateChannelList(PyQt_PyObject)'),
- ('timeCommand(QString, QString, QString)',
- 'timeCommand(QString, QString, QString)'),
- ('chanInviteOnly(QString)',
- 'chanInviteOnly(QString)'),
- ('modesUpdated(QString, QString)',
- 'modesUpdated(QString, QString)'),
- ('cannotSendToChan(QString, QString)',
- 'cannotSendToChan(QString, QString)'),
- ('tooManyPeeps()',
- 'tooManyPeeps()'),
- ('quirkDisable(QString, QString, QString)',
- 'quirkDisable(QString, QString, QString)'),
- ('forbiddenchannel(QString)',
- 'forbiddenchannel(QString)')
- ]
def ircQtConnections(self, irc, widget):
# IRC --> Main window
- return ((widget.sendMessage, irc.sendMessage),
- (widget.sendNotice, irc.sendNotice),
- (widget.sendCTCP, irc.sendCTCP),
- (widget.newConvoStarted, irc.startConvo),
- (widget.convoClosed, irc.endConvo),
- (widget.profileChanged, irc.updateProfile),
- (widget.moodRequest, irc.getMood),
- (widget.moodsRequest, irc.getMoods),
- (widget.moodUpdated, irc.updateMood),
- (widget.mycolorUpdated, irc.updateColor),
- (widget.blockedChum, irc.blockedChum),
- (widget.unblockedChum, irc.unblockedChum),
- (widget.requestNames, irc.requestNames),
- (widget.requestChannelList, irc.requestChannelList),
- (widget.joinChannel, irc.joinChannel),
- (widget.leftChannel, irc.leftChannel),
- (widget.kickUser, irc.kickUser),
- (widget.setChannelMode, irc.setChannelMode),
- (widget.channelNames, irc.channelNames),
- (widget.inviteChum, irc.inviteChum),
- (widget.pingServer, irc.pingServer),
- (widget.setAway, irc.setAway),
- (widget.killSomeQuirks, irc.killSomeQuirks),
- (widget.disconnectIRC, irc.disconnectIRC),
- # Main window --> IRC
- (irc.connected, widget.connected),
- (irc.askToConnect, widget.connectAnyway),
- (irc.moodUpdated, widget.updateMoodSlot),
- (irc.colorUpdated, widget.updateColorSlot),
- (irc.messageReceived, widget.deliverMessage),
- (irc.memoReceived, widget.deliverMemo),
- (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),
- (irc.channelListReceived, widget.updateChannelList),
- (irc.timeCommand, widget.timeCommand),
- (irc.chanInviteOnly, widget.chanInviteOnly),
- (irc.modesUpdated, widget.modesUpdated),
- (irc.cannotSendToChan, widget.cannotSendToChan),
- (irc.forbiddenchannel, widget.forbiddenchannel),
- (irc.tooManyPeeps, widget.tooManyPeeps),
- (irc.quirkDisable, widget.quirkDisable))
+ return (
+ (widget.sendMessage, irc.sendMessage),
+ (widget.sendNotice, irc.sendNotice),
+ (widget.sendCTCP, irc.sendCTCP),
+ (widget.newConvoStarted, irc.startConvo),
+ (widget.convoClosed, irc.endConvo),
+ (widget.profileChanged, irc.updateProfile),
+ (widget.moodRequest, irc.getMood),
+ (widget.moodsRequest, irc.getMoods),
+ (widget.moodUpdated, irc.updateMood),
+ (widget.mycolorUpdated, irc.updateColor),
+ (widget.blockedChum, irc.blockedChum),
+ (widget.unblockedChum, irc.unblockedChum),
+ (widget.requestNames, irc.requestNames),
+ (widget.requestChannelList, irc.requestChannelList),
+ (widget.joinChannel, irc.joinChannel),
+ (widget.leftChannel, irc.leftChannel),
+ (widget.kickUser, irc.kickUser),
+ (widget.setChannelMode, irc.setChannelMode),
+ (widget.channelNames, irc.channelNames),
+ (widget.inviteChum, irc.inviteChum),
+ (widget.pingServer, irc.pingServer),
+ (widget.setAway, irc.setAway),
+ (widget.killSomeQuirks, irc.killSomeQuirks),
+ (widget.disconnectIRC, irc.disconnectIRC),
+ # Main window --> IRC
+ (irc.connected, widget.connected),
+ (irc.askToConnect, widget.connectAnyway),
+ (irc.moodUpdated, widget.updateMoodSlot),
+ (irc.colorUpdated, widget.updateColorSlot),
+ (irc.messageReceived, widget.deliverMessage),
+ (irc.memoReceived, widget.deliverMemo),
+ (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),
+ (irc.channelListReceived, widget.updateChannelList),
+ (irc.timeCommand, widget.timeCommand),
+ (irc.chanInviteOnly, widget.chanInviteOnly),
+ (irc.modesUpdated, widget.modesUpdated),
+ (irc.cannotSendToChan, widget.cannotSendToChan),
+ (irc.forbiddenchannel, widget.forbiddenchannel),
+ (irc.tooManyPeeps, widget.tooManyPeeps),
+ (irc.quirkDisable, widget.quirkDisable),
+ )
+
def connectWidgets(self, irc, widget):
irc.finished.connect(self.restartIRC)
irc.connected.connect(self.connected)
@@ -3983,10 +4397,10 @@ class MainProgram(QtCore.QObject):
break
newmsg.append(msg[:s])
newmsg.append("\n")
- msg = msg[s+1:]
+ msg = msg[s + 1 :]
newmsg.append(msg)
msg = "".join(newmsg)
- if hasattr(self.widget, 'loadingscreen') and widget.loadingscreen:
+ if hasattr(self.widget, "loadingscreen") and widget.loadingscreen:
widget.loadingscreen.loadinglabel.setText(msg)
if self.reconnectok:
widget.loadingscreen.showReconnect()
@@ -3997,9 +4411,11 @@ class MainProgram(QtCore.QObject):
widget.loadingscreen.loadinglabel.setText(msg)
widget.loadingscreen.rejected.connect(widget.app.quit)
self.widget.loadingscreen.tryAgain.connect(self.tryAgain)
- if (hasattr(self, 'irc')
+ if (
+ hasattr(self, "irc")
and self.irc.registeredIRC
- and self.irc.unresponsive == False):
+ and self.irc.unresponsive == False
+ ):
return
if self.reconnectok:
widget.loadingscreen.showReconnect()
@@ -4010,6 +4426,7 @@ class MainProgram(QtCore.QObject):
@QtCore.pyqtSlot()
def connected(self):
self.attempts = 0
+
@QtCore.pyqtSlot()
def tryAgain(self):
if not self.reconnectok:
@@ -4018,20 +4435,23 @@ class MainProgram(QtCore.QObject):
self.widget.loadingscreen.done(QtWidgets.QDialog.DialogCode.Accepted)
self.widget.loadingscreen = None
self.attempts += 1
- if hasattr(self, 'irc') and self.irc:
+ if hasattr(self, "irc") and self.irc:
self.irc.disconnectIRC()
else:
self.restartIRC()
+
@QtCore.pyqtSlot()
def restartIRC(self, verify_hostname=True):
- if hasattr(self, 'irc') and self.irc:
+ if hasattr(self, "irc") and self.irc:
self.disconnectWidgets(self.irc, self.widget)
stop = self.irc.stopIRC
del self.irc
else:
stop = None
if stop is None:
- self.irc = PesterIRC(self.widget.config, self.widget, verify_hostname=verify_hostname)
+ self.irc = PesterIRC(
+ self.widget.config, self.widget, verify_hostname=verify_hostname
+ )
self.connectWidgets(self.irc, self.widget)
self.irc.start()
if self.attempts == 1:
@@ -4068,7 +4488,7 @@ class MainProgram(QtCore.QObject):
except Exception as e:
print(e)
return options
-
+
return options
def uncaughtException(self, exc, value, tb):
@@ -4081,24 +4501,33 @@ class MainProgram(QtCore.QObject):
try:
lt = time.localtime()
lt_str = time.strftime("%Y-%m-%d %H-%M", lt)
- f = open(os.path.join(_datadir, 'errorlogs', ('pestererror %s.log' % lt_str)), 'a')
+ f = open(
+ os.path.join(
+ _datadir, "errorlogs", ("pestererror %s.log" % lt_str)
+ ),
+ "a",
+ )
traceback.print_tb(tb, file=f)
f.close()
except Exception as e:
print(str(e))
-
+
# Show msgbox
msgbox = QtWidgets.QMessageBox()
msgbox.setIcon(QtWidgets.QMessageBox.Icon.Critical)
try:
- msgbox.setStyleSheet("QMessageBox{" + self.widget.theme["main/defaultwindow/style"] + "}")
+ msgbox.setStyleSheet(
+ "QMessageBox{" + self.widget.theme["main/defaultwindow/style"] + "}"
+ )
except Exception as e:
print(str(e))
- msgbox.setStyleSheet("background-color: red; color: black; font-size: x-large;")
- msgbox.setText("An uncaught exception occurred: %s \n%s \n%s "
- % (exc,
- value,
- ''.join(traceback.format_tb(tb))))
+ msgbox.setStyleSheet(
+ "background-color: red; color: black; font-size: x-large;"
+ )
+ msgbox.setText(
+ "An uncaught exception occurred: %s \n%s \n%s "
+ % (exc, value, "".join(traceback.format_tb(tb)))
+ )
msgbox.exec()
except Exception as e:
print("failed to process uncaught except: " + str(e))
@@ -4107,12 +4536,14 @@ class MainProgram(QtCore.QObject):
def run(self):
sys.exit(self.app.exec())
+
def _retrieveGlobals():
# NOTE: Yes, this is a terrible kludge so that the console can work
# properly. I'm open to alternatives.
return globals()
-#def main():
+
+# def main():
# pesterchum = MainProgram()
# pesterchum.run()
diff --git a/pnc/__init__.py b/pnc/__init__.py
index 0085223..9e4eee4 100644
--- a/pnc/__init__.py
+++ b/pnc/__init__.py
@@ -5,4 +5,4 @@
##from __future__ import division
##from __future__ import absolute_import # JUST in case.
-# No __all__ or similar, for now.
\ No newline at end of file
+# No __all__ or similar, for now.
diff --git a/pnc/dep/attrdict.py b/pnc/dep/attrdict.py
index c8a1bb4..6b29762 100644
--- a/pnc/dep/attrdict.py
+++ b/pnc/dep/attrdict.py
@@ -4,29 +4,31 @@
class AttrDict(dict):
"""A dictionary with attribute-style access. It maps attribute access to
the real dictionary.
-
+
Note that accesses to preexisting (e.g. class inherited) or reserved
attributes are handled as they would be normally, and will not be
overwritten.
Overload _is_reserved if you want to change this."""
+
def __init__(self, init={}):
super(AttrDict, self).__init__(init)
def __getstate__(self):
return list(self.__dict__.items())
+
def __setstate__(self, items):
- for key, val in items: self.__dict__[key] = val
+ for key, val in items:
+ self.__dict__[key] = val
def __repr__(self):
- return "{0}({1})".format(
- type(self).__name__,
- super(AttrDict, self).__repr__()
- )
+ return "{0}({1})".format(type(self).__name__, super(AttrDict, self).__repr__())
def __setitem__(self, name, value):
return super(AttrDict, self).__setitem__(name, value)
+
def __getitem__(self, name):
return super(AttrDict, self).__getitem__(name)
+
def __delitem__(self, name):
return super(AttrDict, self).__delitem__(name)
@@ -78,7 +80,8 @@ class AttrDict(dict):
# See __setattr__.
return object.__delattr__(self, name)
else:
- try: del self[name]
+ try:
+ del self[name]
except KeyError as err:
raise AttributeError(str(err))
@@ -86,13 +89,18 @@ class AttrDict(dict):
def _is_reserved(name):
"""Check if an attribute name is reserved for system use."""
# A very simple method.
- result = name[:2] == name[-2:] == '__'
+ result = name[:2] == name[-2:] == "__"
return result
- def copy(self): return type(self)(self)
+ def copy(self):
+ return type(self)(self)
+
__copy__ = copy
+
+
## end of http://code.activestate.com/recipes/473786/ }}}
+
class DefAttrDict(AttrDict):
default_factory = None
@@ -106,8 +114,8 @@ class DefAttrDict(AttrDict):
self.default_factory,
# We skip normal processing here, since AttrDict provides basic
# repr for classes in general, which we don't want.
- dict.__repr__(self)
- )
+ dict.__repr__(self),
+ )
def __getitem__(self, name):
try:
@@ -130,7 +138,10 @@ class DefAttrDict(AttrDict):
raise
return result
- def copy(self): return type(self)(self.default_factory, self)
+ def copy(self):
+ return type(self)(self.default_factory, self)
+
__copy__ = copy
+
# vim: set autoindent ts=4 sts=4 sw=4 textwidth=79 expandtab:
diff --git a/pnc/lexercon.py b/pnc/lexercon.py
index d6ab20a..8337404 100644
--- a/pnc/lexercon.py
+++ b/pnc/lexercon.py
@@ -20,7 +20,6 @@ except NameError:
# function appropriate to the given format - e.g. CTag.convert_pchum.
-
class Lexeme(object):
def __init__(self, string, origin):
# The 'string' property is just what it came from; the original
@@ -28,21 +27,26 @@ class Lexeme(object):
# shouldn't be.
self.string = string
self.origin = origin
+
def __str__(self):
##return self.string
return self.convert(self.origin)
+
def __len__(self):
##return len(self.string)
return len(str(self))
+
def convert(self, format):
# This is supposed to be overwritten by subclasses
raise NotImplementedError
+
def rebuild(self, format):
"""Builds a copy of the owning Lexeme as if it had 'come from' a
different original format, and returns the result."""
# TODO: This. Need to decide whether overloading will be required for
# nearly every single subclass....
raise NotImplementedError
+
@classmethod
def from_mo(cls, mo, origin):
raise NotImplementedError
@@ -52,6 +56,7 @@ class Message(Lexeme):
"""An object designed to represent a message, possibly containing Lexeme
objects in their native form as well. Intended to be a combination of a
list and a string, combining the former with the latter's methods."""
+
def __init__(self, contents, origin):
lexer = Lexer.lexer_for(origin)()
working = lexer.lex(contents)
@@ -69,7 +74,8 @@ class Message(Lexeme):
working[i] = elt
self.origin = origin
self.contents = working
- self.string = ''.join(lexer.list_convert(working))
+ self.string = "".join(lexer.list_convert(working))
+
# TODO: Finish all the rest of this.
@@ -81,40 +87,51 @@ class Specifier(Lexeme):
# If this form has a more compact form, use it
compact = False
+
# Made so that certain odd message-ish things have a place to go. May have its
# class changed later.
class Chunk(Specifier):
pass
+
class FTag(Specifier):
pass
+
+
class CTag(Specifier):
"""Denotes the beginning or end of a color change."""
+
sets_color = True
+
def __init__(self, string, origin, color):
super(CTag, self).__init__(string, origin)
# So we can also have None
if isinstance(color, tuple):
- if len(color) < 2: raise ValueError
+ if len(color) < 2:
+ raise ValueError
self.color, self.bg_color = color[:2]
else:
self.color = color
self.bg_color = None
+
def has_color(self):
if self.color is not None or self.bg_color is not None:
return True
return False
+
def convert(self, format):
- text = ''
+ text = ""
color = self.color
bg = self.bg_color
if format == "irc":
# Put in the control character for a color code.
- text = '\x03'
+ text = "\x03"
if color:
text += color.ccode
- if bg: text += ',' + bg.ccode
- elif bg: text += "99," + bg.ccode
+ if bg:
+ text += "," + bg.ccode
+ elif bg:
+ text += "99," + bg.ccode
elif format == "pchum":
if not color:
text = "
"
@@ -138,7 +155,7 @@ class CTag(Specifier):
# far; use it.
text = hxs
elif format == "plaintext":
- text = ''
+ text = ""
return text
@classmethod
@@ -147,10 +164,14 @@ class CTag(Specifier):
if origin == "irc":
text = mo.group()
fg, bg = mo.groups()
- try: fg = Color('\x03' + fg)
- except: fg = None
- try: bg = Color('\x03' + bg)
- except: bg = None
+ try:
+ fg = Color("\x03" + fg)
+ except:
+ fg = None
+ try:
+ bg = Color("\x03" + bg)
+ except:
+ bg = None
inst = cls(text, origin, color=(fg, bg))
elif origin == "pchum":
text = mo.group()
@@ -168,32 +189,49 @@ class CTag(Specifier):
except:
pass
return inst
+
+
class CTagEnd(CTag):
# TODO: Make this a separate class - NOT a subclass of CTag like it is at
# present
resets_color = True
+
def convert(self, format):
- text = ''
- if format == "irc": return '\x03'
- elif format == "pchum": return ""
- elif format == "plaintext": return ''
+ text = ""
+ if format == "irc":
+ return "\x03"
+ elif format == "pchum":
+ return ""
+ elif format == "plaintext":
+ return ""
return text
- def has_color(self): return False
+
+ def has_color(self):
+ return False
@classmethod
def from_mo(cls, mo, origin):
# Turns the whole match into it (for now)
return cls(mo.group(), origin, color=None)
+
+
class LineColor(CTag):
pass
+
+
class LineColorEnd(CTagEnd):
pass
+
+
class FTagEnd(Specifier):
resets_formatting = True
+
+
class ResetTag(CTagEnd, FTagEnd):
def convert(self, format):
- text = ''
- if format == "irc": return '\x0F'
+ text = ""
+ if format == "irc":
+ return "\x0F"
elif format == "pchum":
# Later on, this one is going to be infuriatingly tricky.
# Supporting things like bold and so on doesn't really allow for an
@@ -201,14 +239,18 @@ class ResetTag(CTagEnd, FTagEnd):
# I *could* implement it, and it wouldn't be too hard, but it would
# probably confuse more people than it helped.
return ""
- elif format == "plaintext": return ''
+ elif format == "plaintext":
+ return ""
return text
+
+
class SpecifierEnd(CTagEnd, FTagEnd):
# This might not ever even be used, but you never know....
# If it does, we may need properties such as .resets_color, .resets_bold,
# and so on and so forth
pass
+
# TODO: Consider using a metaclass to check those properties - e.g. if
# a class .sets_color and a subclass .resets_color, set the subclass's
# .sets_color to False
@@ -218,9 +260,12 @@ class Lexer(object):
# Subclasses need to supply a ref themselves
ref = None
compress_tags = False
+
def breakdown(self, string, objlist):
- if not isinstance(string, basestr): msglist = string
- else: msglist = [string]
+ if not isinstance(string, basestr):
+ msglist = string
+ else:
+ msglist = [string]
for obj, rxp in objlist:
working = []
for i, msg in enumerate(msglist):
@@ -248,12 +293,14 @@ class Lexer(object):
# Exchange the old list with the processed one, and continue
msglist = working
return msglist
+
def lex(self, string):
# Needs to be implemented by subclasses
return self.breakdown(string, [])
def list_convert(self, target, format=None):
- if format is None: format = self.ref
+ if format is None:
+ format = self.ref
converted = []
for elt in target:
@@ -266,6 +313,7 @@ class Lexer(object):
converted.append(elt)
return converted
+
class Pesterchum(Lexer):
ref = "pchum"
_ctag_begin = re.compile(r"", flags=re.I)
@@ -281,11 +329,11 @@ class Pesterchum(Lexer):
def lex(self, string):
lexlist = [
- ##(mecmd, self._mecmdre),
- (CTag, self._ctag_begin),
- ##(CTag, self._ctag_end)
- (CTagEnd, self._ctag_end)
- ]
+ ##(mecmd, self._mecmdre),
+ (CTag, self._ctag_begin),
+ ##(CTag, self._ctag_end)
+ (CTagEnd, self._ctag_end),
+ ]
lexed = self.breakdown(string, lexlist)
@@ -324,7 +372,7 @@ class Pesterchum(Lexer):
## balanced.append(o)
# This will need to be re-evaluated to support the line end lexeme/etc.
if beginc > endc:
- for i in range(0, beginc-endc):
+ for i in range(0, beginc - endc):
##balanced.append(colorEnd(""))
balanced.append(CTagEnd("", self.ref, None))
return balanced
@@ -332,12 +380,15 @@ class Pesterchum(Lexer):
# TODO: Let us contextually set compression here or something, ugh. If
# 'None' assume the self-set one.
def list_convert(self, target, format=None):
- if format is None: format = self.ref
+ if format is None:
+ format = self.ref
converted = []
cstack = []
##closecolor = lambda: converted.append(CTagEnd("", self.ref, None))
- closecolor = lambda: converted.append(CTagEnd("", self.ref, None).convert(format))
+ closecolor = lambda: converted.append(
+ CTagEnd("", self.ref, None).convert(format)
+ )
for elt in target:
if isinstance(elt, LineColorEnd):
@@ -422,6 +473,7 @@ class Pesterchum(Lexer):
converted.append(elt)
return converted
+
class RelayChat(Lexer):
ref = "irc"
# This could use some cleaning up later, but it'll work for now, hopefully
@@ -435,8 +487,8 @@ class RelayChat(Lexer):
lexlist = [
(CTag, self._ccode_rxp),
(CTagEnd, self._ccode_end_rxp),
- (ResetTag, self._reset_rxp)
- ]
+ (ResetTag, self._reset_rxp),
+ ]
lexed = self.breakdown(string, lexlist)
@@ -444,7 +496,8 @@ class RelayChat(Lexer):
return lexed
def list_convert(self, target, format=None):
- if format is None: format = self.ref
+ if format is None:
+ format = self.ref
converted = []
cstack = []
@@ -525,98 +578,99 @@ class RelayChat(Lexer):
return converted
def _list_convert_new(self, target, format=None):
- if format is None: format = self.ref
- converted = []
- cstack = []
+ if format is None:
+ format = self.ref
+ converted = []
+ cstack = []
- for elt in target:
- if isinstance(elt, LineColorEnd):
- # Go down the stack until we have a line color TO end
- while cstack:
- # Add a since we'll need one anyway
+ for elt in target:
+ if isinstance(elt, LineColorEnd):
+ # Go down the stack until we have a line color TO end
+ while cstack:
+ # Add a since we'll need one anyway
+ # Is closecolor accessible here?
+ try:
+ closecolor()
+ except Exception as e:
+ print(e)
+
+ ##if isinstance(color, LineColor):
+ if isinstance(cstack.pop(), LineColor):
+ # We found what we wanted, and the color
+ # was already popped from the stack, so
+ # we're good
+ # Breaking here allows it to be appended
+ break
+ continue
+ elif isinstance(elt, ResetTag):
+ # If it says reset, reset - which means go down the
+ # stack to the most recent line color.
+ while cstack:
+ color = cstack[-1]
+ if not isinstance(color, LineColor):
+ # It's not a line color, so remove it
+ del cstack[-1]
+ # Add a
# Is closecolor accessible here?
try:
closecolor()
except Exception as e:
print(e)
-
- ##if isinstance(color, LineColor):
- if isinstance(cstack.pop(), LineColor):
- # We found what we wanted, and the color
- # was already popped from the stack, so
- # we're good
- # Breaking here allows it to be appended
- break
- continue
- elif isinstance(elt, ResetTag):
- # If it says reset, reset - which means go down the
- # stack to the most recent line color.
- while cstack:
- color = cstack[-1]
- if not isinstance(color, LineColor):
- # It's not a line color, so remove it
- del cstack[-1]
- # Add a
- # Is closecolor accessible here?
- try:
- closecolor()
- except Exception as e:
- print(e)
- else:
- # It's a line color, so stop searching.
- # Using break here prevents the 'else'
- # clause of this while statement from
- # executing.
- break
else:
- # We don't have any more entries in the stack;
- # just continue.
- continue
- ## We found the line color, so add it and continue
- ##converted.append(color.convert(format))
+ # It's a line color, so stop searching.
+ # Using break here prevents the 'else'
+ # clause of this while statement from
+ # executing.
+ break
+ else:
+ # We don't have any more entries in the stack;
+ # just continue.
continue
- ## TODO: Make this actually add the reset char
- # The above shouldn't be necessary because this is Pesterchum's
- # format, not IRC's
- elif isinstance(elt, CTagEnd):
- try:
+ ## We found the line color, so add it and continue
+ ##converted.append(color.convert(format))
+ continue
+ ## TODO: Make this actually add the reset char
+ # The above shouldn't be necessary because this is Pesterchum's
+ # format, not IRC's
+ elif isinstance(elt, CTagEnd):
+ try:
+ color = cstack[-1]
+ # Remove the oldest color, the one we're exiting
+ if not isinstance(color, LineColor):
+ # If we got here, we don't have a line color,
+ # so we're free to act as usual
+ cstack.pop()
+ # Fetch the current nested color
color = cstack[-1]
- # Remove the oldest color, the one we're exiting
- if not isinstance(color, LineColor):
- # If we got here, we don't have a line color,
- # so we're free to act as usual
- cstack.pop()
- # Fetch the current nested color
- color = cstack[-1]
- else:
- # We have a line color and the current lexeme
- # is NOT a line color end; don't even bother
- # adding it to the processed result
- continue
- except LookupError:
- # We aren't nested in a color anymore
- # Passing here causes us to fall through to normal
- # handling
- pass
- # Not necessary due to Pesterchum's format
- ##else:
- ## # We're still nested....
- ## ##converted.append(elt.convert(format))
- ## converted.append(color.convert(format))
- ## # We already added to the working list, so just
- ## # skip the rest
- ## continue
- elif isinstance(elt, CTag):
- # Push the color onto the stack - we're nested in it now
- cstack.append(elt)
- # Falling through adds it to the converted result
+ else:
+ # We have a line color and the current lexeme
+ # is NOT a line color end; don't even bother
+ # adding it to the processed result
+ continue
+ except LookupError:
+ # We aren't nested in a color anymore
+ # Passing here causes us to fall through to normal
+ # handling
+ pass
+ # Not necessary due to Pesterchum's format
+ ##else:
+ ## # We're still nested....
+ ## ##converted.append(elt.convert(format))
+ ## converted.append(color.convert(format))
+ ## # We already added to the working list, so just
+ ## # skip the rest
+ ## continue
+ elif isinstance(elt, CTag):
+ # Push the color onto the stack - we're nested in it now
+ cstack.append(elt)
+ # Falling through adds it to the converted result
- if isinstance(elt, Lexeme):
- elt = elt.convert(format)
- elif not isinstance(elt, basestr):
- # Tempted to make this toss an error, but for now, we'll be
- # safe and make it convert to str
- elt = str(elt)
- converted.append(elt)
- return converted
+ if isinstance(elt, Lexeme):
+ elt = elt.convert(format)
+ elif not isinstance(elt, basestr):
+ # Tempted to make this toss an error, but for now, we'll be
+ # safe and make it convert to str
+ elt = str(elt)
+ converted.append(elt)
+ return converted
diff --git a/pnc/unicolor.py b/pnc/unicolor.py
index e7ee0e7..7a8208b 100644
--- a/pnc/unicolor.py
+++ b/pnc/unicolor.py
@@ -7,7 +7,6 @@ __all__ = ["Color"]
# in mind that this may be phased out in the future.
-
from .dep.attrdict import AttrDict
import collections
@@ -21,11 +20,12 @@ else:
basestr = str
-
# A named tuple for containing CIE L*a*b* (CIELAB) information.
# NOTE TO THOSE MAINTAINING: If you don't know what that means, you're going to
# hate yourself *and* me if you try to edit this. I know I did when I wrote it.
-LabTuple = collections.namedtuple("LabTuple", ['L', 'a', 'b'])
+LabTuple = collections.namedtuple("LabTuple", ["L", "a", "b"])
+
+
class Color(object):
# The threshold at which to consider two colors noticeably different, even
# if only barely
@@ -38,7 +38,7 @@ class Color(object):
# TODO: Split __init__, partly using __new__, so the former just has to do
# conversions
def __init__(self, *args, **kwargs):
- self.ccode = ''
+ self.ccode = ""
self.closest_name = self.name = None
nargs = len(args)
if nargs == 1:
@@ -54,20 +54,25 @@ class Color(object):
if isinstance(arg, basestr):
# If it's a string, we've probably got a hex code, but check
# anyway just in case
- if arg.startswith('#'):
+ if arg.startswith("#"):
self.hexstr = self.sanitize_hex(arg)
rgb = self.hexstr_to_rgb(self.hexstr)
self.red, self.green, self.blue = rgb
##return
# TODO: This.
- elif (arg.startswith('\003') and len(arg) > 1
- or len(arg) < 3 and arg.isdigit()):
+ elif (
+ arg.startswith("\003")
+ and len(arg) > 1
+ or len(arg) < 3
+ and arg.isdigit()
+ ):
# We have an IRC-style color code
- arg = arg.lstrip('\003')
+ arg = arg.lstrip("\003")
# Just in case
- arg = arg.split(',')[0]
+ arg = arg.split(",")[0]
cnum = int(arg)
- try: color = _irc_colors[cnum]
+ try:
+ color = _irc_colors[cnum]
except LookupError:
raise ValueError("No color for ccode %r found" % cnum)
# We found a color; fall through and so on
@@ -75,7 +80,8 @@ class Color(object):
else:
# Presumably we have a color name
name = arg.lower()
- try: color = _svg_colors[name]
+ try:
+ color = _svg_colors[name]
except LookupError:
raise ValueError("No color with name %r found" % name)
# We found a color; fall through so we make this one a copy
@@ -103,14 +109,20 @@ class Color(object):
self.x, self.y, self.z = self.rgb_to_xyz(*self.to_rgb_tuple())
# Calculate the LAB color
self.cielab = LabTuple(*self.xyz_to_cielab(*self.to_xyz_tuple()))
- if not self.closest_name: self.closest_name = self.get_svg_name()
- if not self.ccode: self.ccode = self.get_ccode()
+ if not self.closest_name:
+ self.closest_name = self.get_svg_name()
+ if not self.ccode:
+ self.ccode = self.get_ccode()
def __eq__(self, other):
return hash(self) == hash(other)
- def __ne__(self, other): return not self.__eq__(other)
+
+ def __ne__(self, other):
+ return not self.__eq__(other)
+
def __sub__(self, other):
- if not isinstance(other, Color): raise TypeError
+ if not isinstance(other, Color):
+ raise TypeError
return self.distance(other)
def __hash__(self):
@@ -130,23 +142,27 @@ class Color(object):
##result ^= self.green
##result ^= self.blue
##return result
+
def __repr__(self):
##return "%s(%r)" % (type(self).__name__, str(self))
- return "%s(%r)" % (type(self).__name__,
- self.reduce_hexstr(self.hexstr))
+ return "%s(%r)" % (type(self).__name__, self.reduce_hexstr(self.hexstr))
+
def __str__(self):
##return self.reduce_hexstr(self.hexstr)
return self.name()
# Builtins
# These were yanked from Hostmask and changed around a bit
- def __getitem__(self, ind): return (self.red, self.green, self.blue)[ind]
+ def __getitem__(self, ind):
+ return (self.red, self.green, self.blue)[ind]
+
def __iter__(self):
targs = (self.red, self.green, self.blue)
for t in targs:
yield t
# If we got here, we're out of attributes to provide
raise StopIteration
+
##def __len__(self):
## # Acceptable so long as we're returning RGB like we currently (at TOW)
## # are
@@ -156,8 +172,8 @@ class Color(object):
def from_ccode(cls, ccode):
if isinstance(ccode, basestr):
# We were passed a string
- ccode = ccode.lstrip('\003')
- ccode = ccode.split(',')
+ ccode = ccode.lstrip("\003")
+ ccode = ccode.split(",")
if len(ccode) < 2:
fg = ccode[0]
bg = None
@@ -236,9 +252,9 @@ class Color(object):
# http://en.wikipedia.org/wiki/Color_difference
slab, olab = self.to_cielab_tuple(), other.to_cielab_tuple()
# Calculate the distance between the points for each
- dist = list(map(lambda p1, p2: (p2 - p1)**2, slab, olab))
+ dist = list(map(lambda p1, p2: (p2 - p1) ** 2, slab, olab))
# Add the results up, and sqrt to compensate for earlier squaring
- dist = sum(dist) ** .5
+ dist = sum(dist) ** 0.5
return dist
def rgb_distance(self, other):
@@ -252,17 +268,17 @@ class Color(object):
### Square the results from the above
##dist = [x**2 for x in dist]
# Do what we WOULD have done in those two lines with a single one
- dist = list(map(lambda x1, x2: (x1 - x2)**2, srgb, orgb))
+ dist = list(map(lambda x1, x2: (x1 - x2) ** 2, srgb, orgb))
# Add the results up
dist = sum(dist)
# Fetch the square root to compensate for the earlier squaring
- dist **= .5
+ dist **= 0.5
return dist
@classmethod
def hexstr_to_rgb(cls, hexstr):
hexstr = cls.sanitize_hex(hexstr)
- hexstr = hexstr.lstrip('#')
+ hexstr = hexstr.lstrip("#")
if len(hexstr) == 3:
# NOTE: This will presently never happen, due to the way
# sanitize_hex works.
@@ -270,17 +286,14 @@ class Color(object):
# first.
# Multiplying each element by 17 expands it. Dividing it does the
# opposite.
- result = tuple( (int(h, 16) * 17) for h in hexstr )
+ result = tuple((int(h, 16) * 17) for h in hexstr)
else:
# This is ugly, but the purpose is simple and it's accomplished in
# a single line...it just runs through the string, picking two
# characters at a time and converting them from hex values to ints.
- result = tuple(
- int(hexstr[i:i+2], 16) for i in range(0, len(hexstr), 2)
- )
+ result = tuple(int(hexstr[i : i + 2], 16) for i in range(0, len(hexstr), 2))
return result
-
@staticmethod
def rgb_to_hexstr(red, green, blue, compress=False):
rgb = [red, green, blue]
@@ -303,7 +316,7 @@ class Color(object):
# All of our codes were doubles; compress them all down.
result = [h[0] for h in result]
# Join and return the result
- return '#' + ''.join(result)
+ return "#" + "".join(result)
# These next two are from http://www.easyrgb.com/index.php?X=MATH
@staticmethod
@@ -311,8 +324,10 @@ class Color(object):
rgb = [red, green, blue]
for i, n in enumerate(rgb):
n /= 255
- if n > 0.04045: n = ( ( n + 0.055 ) / 1.055 ) ** 2.4
- else: n /= 12.92
+ if n > 0.04045:
+ n = ((n + 0.055) / 1.055) ** 2.4
+ else:
+ n /= 12.92
rgb[i] = n * 100
r, g, b = rgb
x = r * 0.4124 + g * 0.3576 + b * 0.1805
@@ -322,6 +337,7 @@ class Color(object):
##y = 0.222491598 * r + 0.71688606 * g + 0.060621486 * b
##z = 0.013929122 * r + 0.097097002 * g + 0.71418547 * b
return x, y, z
+
@staticmethod
def xyz_to_cielab(x, y, z):
# Reference X, Y, and Z
@@ -331,13 +347,14 @@ class Color(object):
xyz = [x, y, z]
for i, n in enumerate(xyz):
n /= refs[i]
- if n > 0.008856: n **= 1/3
+ if n > 0.008856:
+ n **= 1 / 3
else:
n *= 7.787
- n += 16/116
+ n += 16 / 116
xyz[i] = n
x, y, z = xyz
- l = (y*116) - 16
+ l = (y * 116) - 16
a = (x - y) * 500
b = (y - z) * 200
return l, a, b
@@ -347,24 +364,23 @@ class Color(object):
"""Attempt to reduce a six-character hexadecimal color code down to a
four-character one."""
orig = hexstr
- hexstr = hexstr.lstrip('#')
+ hexstr = hexstr.lstrip("#")
strlen = len(hexstr)
h = hexstr.upper()
for i in range(0, strlen, 2):
- if h[i] != h[i+1]:
+ if h[i] != h[i + 1]:
# We found a match that wouldn't work; give back the old value.
return orig
else:
# All of these can be reduced; do so and return.
- return '#' + hexstr[::2]
-
+ return "#" + hexstr[::2]
@staticmethod
def sanitize_hex(hexstr):
orig = hexstr
hexstr = hexstr.upper()
# We don't need the leading hash mark for now
- hexstr = hexstr.lstrip('#')
+ hexstr = hexstr.lstrip("#")
strlen = len(hexstr)
if strlen == 6:
# We just need to test this for validity. Fall through to the end.
@@ -372,228 +388,232 @@ class Color(object):
elif strlen == 3:
# We have a short (CSS style) code; duplicate all of the characters
hexstr = [c + c for c in hexstr]
- hexstr = ''.join(hexstr)
+ hexstr = "".join(hexstr)
else:
- raise ValueError(
- "Invalid hexadecimal value provided: %s" % orig
- )
+ raise ValueError("Invalid hexadecimal value provided: %s" % orig)
try:
# Make sure it works/is readable (no invalid characters).
int(hexstr, 16)
except ValueError:
- raise ValueError(
- "Invalid hexadecimal value provided: %s" % orig
- )
- return '#' + hexstr
+ raise ValueError("Invalid hexadecimal value provided: %s" % orig)
+ return "#" + hexstr
def to_cielab_tuple(self):
# For now, just return the stored CIELAB tuple
return self.cielab
- def to_rgb_tuple(self): return (self.red, self.green, self.blue)
+
+ def to_rgb_tuple(self):
+ return (self.red, self.green, self.blue)
+
# 2012-12-05T17:40:39-07:00: Changed 'self.blue' to 'self.z' like it SHOULD
# have been in the FIRST place. Ugh. How did I fuck THAT one up?
- def to_xyz_tuple(self): return (self.x, self.y, self.z)
+ def to_xyz_tuple(self):
+ return (self.x, self.y, self.z)
+
# All of these are effectively equivalent to the Qt-provided colors, so they
# could be phased out - but there's no need to, yet.
_svg_colors = AttrDict()
_irc_colors = {}
-_svg_colors.update({
- "aliceblue": Color(240, 248, 255),
- "antiquewhite": Color(250, 235, 215),
- "aqua": Color( 0, 255, 255),
- "aquamarine": Color(127, 255, 212),
- "azure": Color(240, 255, 255),
- "beige": Color(245, 245, 220),
- "bisque": Color(255, 228, 196),
- "black": Color( 0, 0, 0),
- "blanchedalmond": Color(255, 235, 205),
- "blue": Color( 0, 0, 255),
- "blueviolet": Color(138, 43, 226),
- "brown": Color(165, 42, 42),
- "burlywood": Color(222, 184, 135),
- "cadetblue": Color( 95, 158, 160),
- "chartreuse": Color(127, 255, 0),
- "chocolate": Color(210, 105, 30),
- "coral": Color(255, 127, 80),
- "cornflowerblue": Color(100, 149, 237),
- "cornsilk": Color(255, 248, 220),
- "crimson": Color(220, 20, 60),
- "cyan": Color( 0, 255, 255),
- "darkblue": Color( 0, 0, 139),
- "darkcyan": Color( 0, 139, 139),
- "darkgoldenrod": Color(184, 134, 11),
- "darkgray": Color(169, 169, 169),
- "darkgreen": Color( 0, 100, 0),
- "darkgrey": Color(169, 169, 169),
- "darkkhaki": Color(189, 183, 107),
- "darkmagenta": Color(139, 0, 139),
- "darkolivegreen": Color( 85, 107, 47),
- "darkorange": Color(255, 140, 0),
- "darkorchid": Color(153, 50, 204),
- "darkred": Color(139, 0, 0),
- "darksalmon": Color(233, 150, 122),
- "darkseagreen": Color(143, 188, 143),
- "darkslateblue": Color( 72, 61, 139),
- "darkslategray": Color( 47, 79, 79),
- "darkslategrey": Color( 47, 79, 79),
- "darkturquoise": Color( 0, 206, 209),
- "darkviolet": Color(148, 0, 211),
- "deeppink": Color(255, 20, 147),
- "deepskyblue": Color( 0, 191, 255),
- "dimgray": Color(105, 105, 105),
- "dimgrey": Color(105, 105, 105),
- "dodgerblue": Color( 30, 144, 255),
- "firebrick": Color(178, 34, 34),
- "floralwhite": Color(255, 250, 240),
- "forestgreen": Color( 34, 139, 34),
- "fuchsia": Color(255, 0, 255),
- "gainsboro": Color(220, 220, 220),
- "ghostwhite": Color(248, 248, 255),
- "gold": Color(255, 215, 0),
- "goldenrod": Color(218, 165, 32),
- "gray": Color(128, 128, 128),
- "grey": Color(128, 128, 128),
- "green": Color( 0, 128, 0),
- "greenyellow": Color(173, 255, 47),
- "honeydew": Color(240, 255, 240),
- "hotpink": Color(255, 105, 180),
- "indianred": Color(205, 92, 92),
- "indigo": Color( 75, 0, 130),
- "ivory": Color(255, 255, 240),
- "khaki": Color(240, 230, 140),
- "lavender": Color(230, 230, 250),
- "lavenderblush": Color(255, 240, 245),
- "lawngreen": Color(124, 252, 0),
- "lemonchiffon": Color(255, 250, 205),
- "lightblue": Color(173, 216, 230),
- "lightcoral": Color(240, 128, 128),
- "lightcyan": Color(224, 255, 255),
- "lightgoldenrodyellow": Color(250, 250, 210),
- "lightgray": Color(211, 211, 211),
- "lightgreen": Color(144, 238, 144),
- "lightgrey": Color(211, 211, 211),
- "lightpink": Color(255, 182, 193),
- "lightsalmon": Color(255, 160, 122),
- "lightseagreen": Color( 32, 178, 170),
- "lightskyblue": Color(135, 206, 250),
- "lightslategray": Color(119, 136, 153),
- "lightslategrey": Color(119, 136, 153),
- "lightsteelblue": Color(176, 196, 222),
- "lightyellow": Color(255, 255, 224),
- "lime": Color( 0, 255, 0),
- "limegreen": Color( 50, 205, 50),
- "linen": Color(250, 240, 230),
- "magenta": Color(255, 0, 255),
- "maroon": Color(128, 0, 0),
- "mediumaquamarine": Color(102, 205, 170),
- "mediumblue": Color( 0, 0, 205),
- "mediumorchid": Color(186, 85, 211),
- "mediumpurple": Color(147, 112, 219),
- "mediumseagreen": Color( 60, 179, 113),
- "mediumslateblue": Color(123, 104, 238),
- "mediumspringgreen": Color( 0, 250, 154),
- "mediumturquoise": Color( 72, 209, 204),
- "mediumvioletred": Color(199, 21, 133),
- "midnightblue": Color( 25, 25, 112),
- "mintcream": Color(245, 255, 250),
- "mistyrose": Color(255, 228, 225),
- "moccasin": Color(255, 228, 181),
- "navajowhite": Color(255, 222, 173),
- "navy": Color( 0, 0, 128),
- "oldlace": Color(253, 245, 230),
- "olive": Color(128, 128, 0),
- "olivedrab": Color(107, 142, 35),
- "orange": Color(255, 165, 0),
- "orangered": Color(255, 69, 0),
- "orchid": Color(218, 112, 214),
- "palegoldenrod": Color(238, 232, 170),
- "palegreen": Color(152, 251, 152),
- "paleturquoise": Color(175, 238, 238),
- "palevioletred": Color(219, 112, 147),
- "papayawhip": Color(255, 239, 213),
- "peachpuff": Color(255, 218, 185),
- "peru": Color(205, 133, 63),
- "pink": Color(255, 192, 203),
- "plum": Color(221, 160, 221),
- "powderblue": Color(176, 224, 230),
- "purple": Color(128, 0, 128),
- "red": Color(255, 0, 0),
- "rosybrown": Color(188, 143, 143),
- "royalblue": Color( 65, 105, 225),
- "saddlebrown": Color(139, 69, 19),
- "salmon": Color(250, 128, 114),
- "sandybrown": Color(244, 164, 96),
- "seagreen": Color( 46, 139, 87),
- "seashell": Color(255, 245, 238),
- "sienna": Color(160, 82, 45),
- "silver": Color(192, 192, 192),
- "skyblue": Color(135, 206, 235),
- "slateblue": Color(106, 90, 205),
- "slategray": Color(112, 128, 144),
- "slategrey": Color(112, 128, 144),
- "snow": Color(255, 250, 250),
- "springgreen": Color( 0, 255, 127),
- "steelblue": Color( 70, 130, 180),
- "tan": Color(210, 180, 140),
- "teal": Color( 0, 128, 128),
- "thistle": Color(216, 191, 216),
- "tomato": Color(255, 99, 71),
- "turquoise": Color( 64, 224, 208),
- "violet": Color(238, 130, 238),
- "wheat": Color(245, 222, 179),
- "white": Color(255, 255, 255),
- "whitesmoke": Color(245, 245, 245),
- "yellow": Color(255, 255, 0),
- "yellowgreen": Color(154, 205, 50)
- })
+_svg_colors.update(
+ {
+ "aliceblue": Color(240, 248, 255),
+ "antiquewhite": Color(250, 235, 215),
+ "aqua": Color(0, 255, 255),
+ "aquamarine": Color(127, 255, 212),
+ "azure": Color(240, 255, 255),
+ "beige": Color(245, 245, 220),
+ "bisque": Color(255, 228, 196),
+ "black": Color(0, 0, 0),
+ "blanchedalmond": Color(255, 235, 205),
+ "blue": Color(0, 0, 255),
+ "blueviolet": Color(138, 43, 226),
+ "brown": Color(165, 42, 42),
+ "burlywood": Color(222, 184, 135),
+ "cadetblue": Color(95, 158, 160),
+ "chartreuse": Color(127, 255, 0),
+ "chocolate": Color(210, 105, 30),
+ "coral": Color(255, 127, 80),
+ "cornflowerblue": Color(100, 149, 237),
+ "cornsilk": Color(255, 248, 220),
+ "crimson": Color(220, 20, 60),
+ "cyan": Color(0, 255, 255),
+ "darkblue": Color(0, 0, 139),
+ "darkcyan": Color(0, 139, 139),
+ "darkgoldenrod": Color(184, 134, 11),
+ "darkgray": Color(169, 169, 169),
+ "darkgreen": Color(0, 100, 0),
+ "darkgrey": Color(169, 169, 169),
+ "darkkhaki": Color(189, 183, 107),
+ "darkmagenta": Color(139, 0, 139),
+ "darkolivegreen": Color(85, 107, 47),
+ "darkorange": Color(255, 140, 0),
+ "darkorchid": Color(153, 50, 204),
+ "darkred": Color(139, 0, 0),
+ "darksalmon": Color(233, 150, 122),
+ "darkseagreen": Color(143, 188, 143),
+ "darkslateblue": Color(72, 61, 139),
+ "darkslategray": Color(47, 79, 79),
+ "darkslategrey": Color(47, 79, 79),
+ "darkturquoise": Color(0, 206, 209),
+ "darkviolet": Color(148, 0, 211),
+ "deeppink": Color(255, 20, 147),
+ "deepskyblue": Color(0, 191, 255),
+ "dimgray": Color(105, 105, 105),
+ "dimgrey": Color(105, 105, 105),
+ "dodgerblue": Color(30, 144, 255),
+ "firebrick": Color(178, 34, 34),
+ "floralwhite": Color(255, 250, 240),
+ "forestgreen": Color(34, 139, 34),
+ "fuchsia": Color(255, 0, 255),
+ "gainsboro": Color(220, 220, 220),
+ "ghostwhite": Color(248, 248, 255),
+ "gold": Color(255, 215, 0),
+ "goldenrod": Color(218, 165, 32),
+ "gray": Color(128, 128, 128),
+ "grey": Color(128, 128, 128),
+ "green": Color(0, 128, 0),
+ "greenyellow": Color(173, 255, 47),
+ "honeydew": Color(240, 255, 240),
+ "hotpink": Color(255, 105, 180),
+ "indianred": Color(205, 92, 92),
+ "indigo": Color(75, 0, 130),
+ "ivory": Color(255, 255, 240),
+ "khaki": Color(240, 230, 140),
+ "lavender": Color(230, 230, 250),
+ "lavenderblush": Color(255, 240, 245),
+ "lawngreen": Color(124, 252, 0),
+ "lemonchiffon": Color(255, 250, 205),
+ "lightblue": Color(173, 216, 230),
+ "lightcoral": Color(240, 128, 128),
+ "lightcyan": Color(224, 255, 255),
+ "lightgoldenrodyellow": Color(250, 250, 210),
+ "lightgray": Color(211, 211, 211),
+ "lightgreen": Color(144, 238, 144),
+ "lightgrey": Color(211, 211, 211),
+ "lightpink": Color(255, 182, 193),
+ "lightsalmon": Color(255, 160, 122),
+ "lightseagreen": Color(32, 178, 170),
+ "lightskyblue": Color(135, 206, 250),
+ "lightslategray": Color(119, 136, 153),
+ "lightslategrey": Color(119, 136, 153),
+ "lightsteelblue": Color(176, 196, 222),
+ "lightyellow": Color(255, 255, 224),
+ "lime": Color(0, 255, 0),
+ "limegreen": Color(50, 205, 50),
+ "linen": Color(250, 240, 230),
+ "magenta": Color(255, 0, 255),
+ "maroon": Color(128, 0, 0),
+ "mediumaquamarine": Color(102, 205, 170),
+ "mediumblue": Color(0, 0, 205),
+ "mediumorchid": Color(186, 85, 211),
+ "mediumpurple": Color(147, 112, 219),
+ "mediumseagreen": Color(60, 179, 113),
+ "mediumslateblue": Color(123, 104, 238),
+ "mediumspringgreen": Color(0, 250, 154),
+ "mediumturquoise": Color(72, 209, 204),
+ "mediumvioletred": Color(199, 21, 133),
+ "midnightblue": Color(25, 25, 112),
+ "mintcream": Color(245, 255, 250),
+ "mistyrose": Color(255, 228, 225),
+ "moccasin": Color(255, 228, 181),
+ "navajowhite": Color(255, 222, 173),
+ "navy": Color(0, 0, 128),
+ "oldlace": Color(253, 245, 230),
+ "olive": Color(128, 128, 0),
+ "olivedrab": Color(107, 142, 35),
+ "orange": Color(255, 165, 0),
+ "orangered": Color(255, 69, 0),
+ "orchid": Color(218, 112, 214),
+ "palegoldenrod": Color(238, 232, 170),
+ "palegreen": Color(152, 251, 152),
+ "paleturquoise": Color(175, 238, 238),
+ "palevioletred": Color(219, 112, 147),
+ "papayawhip": Color(255, 239, 213),
+ "peachpuff": Color(255, 218, 185),
+ "peru": Color(205, 133, 63),
+ "pink": Color(255, 192, 203),
+ "plum": Color(221, 160, 221),
+ "powderblue": Color(176, 224, 230),
+ "purple": Color(128, 0, 128),
+ "red": Color(255, 0, 0),
+ "rosybrown": Color(188, 143, 143),
+ "royalblue": Color(65, 105, 225),
+ "saddlebrown": Color(139, 69, 19),
+ "salmon": Color(250, 128, 114),
+ "sandybrown": Color(244, 164, 96),
+ "seagreen": Color(46, 139, 87),
+ "seashell": Color(255, 245, 238),
+ "sienna": Color(160, 82, 45),
+ "silver": Color(192, 192, 192),
+ "skyblue": Color(135, 206, 235),
+ "slateblue": Color(106, 90, 205),
+ "slategray": Color(112, 128, 144),
+ "slategrey": Color(112, 128, 144),
+ "snow": Color(255, 250, 250),
+ "springgreen": Color(0, 255, 127),
+ "steelblue": Color(70, 130, 180),
+ "tan": Color(210, 180, 140),
+ "teal": Color(0, 128, 128),
+ "thistle": Color(216, 191, 216),
+ "tomato": Color(255, 99, 71),
+ "turquoise": Color(64, 224, 208),
+ "violet": Color(238, 130, 238),
+ "wheat": Color(245, 222, 179),
+ "white": Color(255, 255, 255),
+ "whitesmoke": Color(245, 245, 245),
+ "yellow": Color(255, 255, 0),
+ "yellowgreen": Color(154, 205, 50),
+ }
+)
for k, v in list(_svg_colors.items()):
v.closest_name = v.name = k
# 2012-12-08T14:29-07:00: Copied over from Colors.hexstr_for_ccodes in the main
# textsub file, and subsequently modified.
-_irc_colors.update({
- # These are all taken from *MY* XChat settings - they aren't guaranteed to
- # please everyone!
- 0: Color(0xFFFFFF),
- 1: Color(0x1F1F1F),
- 2: Color(0x00007F),
- 3: Color(0x007F00),
- 4: Color(0xFF0000),
- 5: Color(0x7F0000),
- 6: Color(0x9C009C),
- 7: Color(0xFC7F00),
- 8: Color(0xFFFF00),
- 9: Color(0x00FC00),
- ##10: Color(0x009393),
- 10: Color(0x008282),
- 11: Color(0x00FFFF),
- 12: Color(0x0000FC),
- 13: Color(0xFF00FF),
- 14: Color(0x7F7F7F),
- 15: Color(0xD2D2D2),
- # My local colors
- 16: Color(0xCCCCCC),
- ##17: Color(0x000000), # Commented out 'til readability checks are in
- 17: Color(0x1F1F1F),
- 18: Color(0x000056),
- 19: Color(0x008141),
- 20: Color(0xE00707),
- 21: Color(0xA10000),
- 22: Color(0x6A006A),
- 23: Color(0xA15000),
- 24: Color(0xA1A100),
- 25: Color(0x416600),
- ##26: Color(0x008282),
- 26: Color(0x005682),
- 27: Color(0x00D5F2),
- 28: Color(0x0715CD),
- 29: Color(0x99004D),
- 30: Color(0x323232),
- 31: Color(0x929292),
-
- 99: Color(0x999999) # Until I think of a better solution to this
- })
+_irc_colors.update(
+ {
+ # These are all taken from *MY* XChat settings - they aren't guaranteed to
+ # please everyone!
+ 0: Color(0xFFFFFF),
+ 1: Color(0x1F1F1F),
+ 2: Color(0x00007F),
+ 3: Color(0x007F00),
+ 4: Color(0xFF0000),
+ 5: Color(0x7F0000),
+ 6: Color(0x9C009C),
+ 7: Color(0xFC7F00),
+ 8: Color(0xFFFF00),
+ 9: Color(0x00FC00),
+ ##10: Color(0x009393),
+ 10: Color(0x008282),
+ 11: Color(0x00FFFF),
+ 12: Color(0x0000FC),
+ 13: Color(0xFF00FF),
+ 14: Color(0x7F7F7F),
+ 15: Color(0xD2D2D2),
+ # My local colors
+ 16: Color(0xCCCCCC),
+ ##17: Color(0x000000), # Commented out 'til readability checks are in
+ 17: Color(0x1F1F1F),
+ 18: Color(0x000056),
+ 19: Color(0x008141),
+ 20: Color(0xE00707),
+ 21: Color(0xA10000),
+ 22: Color(0x6A006A),
+ 23: Color(0xA15000),
+ 24: Color(0xA1A100),
+ 25: Color(0x416600),
+ ##26: Color(0x008282),
+ 26: Color(0x005682),
+ 27: Color(0x00D5F2),
+ 28: Color(0x0715CD),
+ 29: Color(0x99004D),
+ 30: Color(0x323232),
+ 31: Color(0x929292),
+ 99: Color(0x999999), # Until I think of a better solution to this
+ }
+)
for k, v in list(_irc_colors.items()):
v.ccode = "%02d" % k
del k, v
diff --git a/profile.py b/profile.py
index a2bee51..90678f9 100644
--- a/profile.py
+++ b/profile.py
@@ -22,7 +22,7 @@ from dataobjs import PesterProfile, pesterQuirks
from parsetools import convertTags
_datadir = ostools.getDataDir()
-PchumLog = logging.getLogger('pchumLogger')
+PchumLog = logging.getLogger("pchumLogger")
class PesterLog(object):
@@ -31,7 +31,7 @@ class PesterLog(object):
self.parent = parent
self.handle = handle
self.convos = {}
- self.logpath = _datadir+"logs"
+ self.logpath = _datadir + "logs"
def log(self, handle, msg):
if self.parent.config.time12Format():
@@ -42,34 +42,46 @@ class PesterLog(object):
log_time += strftime(":%S] ")
else:
log_time += "] "
- if handle[0] == '#':
- if not self.parent.config.logMemos() & self.parent.config.LOG: return
+ if handle[0] == "#":
+ if not self.parent.config.logMemos() & self.parent.config.LOG:
+ return
if not self.parent.config.logMemos() & self.parent.config.STAMP:
log_time = ""
else:
- if not self.parent.config.logPesters() & self.parent.config.LOG: return
+ if not self.parent.config.logPesters() & self.parent.config.LOG:
+ return
if not self.parent.config.logPesters() & self.parent.config.STAMP:
log_time = ""
- if self.parent.isBot(handle): return
- #watch out for illegal characters
+ if self.parent.isBot(handle):
+ return
+ # watch out for illegal characters
handle = re.sub(r'[<>:"/\\|?*]', "_", handle)
bbcodemsg = log_time + convertTags(msg, "bbcode")
- html = log_time + convertTags(msg, "html")+"
"
- msg = log_time +convertTags(msg, "text")
+ html = log_time + convertTags(msg, "html") + "
"
+ msg = log_time + convertTags(msg, "text")
modes = {"bbcode": bbcodemsg, "html": html, "text": msg}
try:
if handle not in self.convos:
log_time = datetime.now().strftime("%Y-%m-%d.%H.%M")
self.convos[handle] = {}
for (format, t) in modes.items():
- if not os.path.exists("%s/%s/%s/%s" % (self.logpath, self.handle, handle, format)):
- os.makedirs("%s/%s/%s/%s" % (self.logpath, self.handle, handle, format))
- fp = codecs.open("%s/%s/%s/%s/%s.%s.txt" % (self.logpath, self.handle, handle, format, handle, log_time), encoding='utf-8', mode='a')
+ if not os.path.exists(
+ "%s/%s/%s/%s" % (self.logpath, self.handle, handle, format)
+ ):
+ os.makedirs(
+ "%s/%s/%s/%s" % (self.logpath, self.handle, handle, format)
+ )
+ fp = codecs.open(
+ "%s/%s/%s/%s/%s.%s.txt"
+ % (self.logpath, self.handle, handle, format, handle, log_time),
+ encoding="utf-8",
+ mode="a",
+ )
self.convos[handle][format] = fp
-
+
for (format, t) in modes.items():
f = self.convos[handle][format]
- f.write(t+"\r\n")
+ f.write(t + "\r\n")
# flush + fsync force a write,
# makes sure logs are saved in the case of a crash.
f.flush()
@@ -78,34 +90,41 @@ class PesterLog(object):
# This way the file descriptors are closed and reopened for every message,
# which is sub-optimal and definitely a performance drain but,
# otherwise we still run into the ulimit on platforms like MacOS fairly easily.
- #if ostools.isOSX() == True:
+ # if ostools.isOSX() == True:
# for (format, t) in modes.items():
# self.finish(handle)
-
+
except (IOError, OSError, KeyError, IndexError, ValueError) as e:
# Catching this exception does not stop pchum from dying if we run out of file handles 3
PchumLog.critical(e)
errmsg = QtWidgets.QMessageBox()
errmsg.setIcon(QtWidgets.QMessageBox.Icon.Warning)
- errmsg.setText("Warning: Pesterchum could not open the log file for %s!" % (handle))
- errmsg.setInformativeText("Your log for %s will not be saved because something went wrong. We suggest restarting Pesterchum. Sorry :(" % (handle)
- + '\n'
- + str(e))
+ errmsg.setText(
+ "Warning: Pesterchum could not open the log file for %s!" % (handle)
+ )
+ errmsg.setInformativeText(
+ "Your log for %s will not be saved because something went wrong. We suggest restarting Pesterchum. Sorry :("
+ % (handle)
+ + "\n"
+ + str(e)
+ )
errmsg.setWindowTitle(":(")
errmsg.exec()
PchumLog.debug("post-error msg")
-
+
def finish(self, handle):
if handle not in self.convos:
return
for f in list(self.convos[handle].values()):
f.close()
del self.convos[handle]
+
def close(self):
for h in list(self.convos.keys()):
for f in list(self.convos[h].values()):
f.close()
+
class userConfig(object):
def __init__(self, parent):
self.parent = parent
@@ -116,12 +135,12 @@ class userConfig(object):
self.PBLINK = 1
self.MBLINK = 2
# Use for bit flag notfications
- self.SIGNIN = 1
- self.SIGNOUT = 2
- self.NEWMSG = 4
+ self.SIGNIN = 1
+ self.SIGNOUT = 2
+ self.NEWMSG = 4
self.NEWCONVO = 8
- self.INITIALS = 16
- self.filename = _datadir+"pesterchum.js"
+ self.INITIALS = 16
+ self.filename = _datadir + "pesterchum.js"
try:
with open(self.filename) as fp:
self.config = json.load(fp)
@@ -132,10 +151,18 @@ class userConfig(object):
msgbox = QtWidgets.QMessageBox()
msgbox.setIcon(QtWidgets.QMessageBox.Icon.Warning)
msgbox.setWindowTitle(":(")
- msgbox.setTextFormat(QtCore.Qt.TextFormat.RichText) # Clickable html links
- msgbox.setInformativeText("Failed to load pesterchum.js, this might require manual intervention.
\
+ msgbox.setTextFormat(QtCore.Qt.TextFormat.RichText) # Clickable html links
+ msgbox.setInformativeText(
+ "Failed to load pesterchum.js, this might require manual intervention.
\
Consider overriding: %s
\
-with a backup from: %s
" % (_datadir, self.filename, os.path.join(_datadir, "backup"), os.path.join(_datadir, "backup")))
+with a backup from: %s
"
+ % (
+ _datadir,
+ self.filename,
+ os.path.join(_datadir, "backup"),
+ os.path.join(_datadir, "backup"),
+ )
+ )
msgbox.exec()
sys.exit()
@@ -152,23 +179,23 @@ with a backup from: %s" % (_datadir, self.filename,
else:
self.userprofile = None
- self.logpath = _datadir+"logs"
+ self.logpath = _datadir + "logs"
if not os.path.exists(self.logpath):
os.makedirs(self.logpath)
try:
- with open("%s/groups.js" % (self.logpath), 'r') as fp:
+ with open("%s/groups.js" % (self.logpath), "r") as fp:
self.groups = json.load(fp)
except (IOError, ValueError):
self.groups = {}
- with open("%s/groups.js" % (self.logpath), 'w') as fp:
+ with open("%s/groups.js" % (self.logpath), "w") as fp:
json.dump(self.groups, fp)
self.backup()
def backup(self):
# Backups
-
+
try:
# Backup pesterchum.js file.
# Useful because it seems to randomly get blanked for people.
@@ -176,17 +203,26 @@ with a backup from: %s" % (_datadir, self.filename,
if os.path.exists(backup_path) == False:
os.makedirs(backup_path)
current_backup = datetime.now().day % 5
- shutil.copyfile(self.filename, os.path.join(backup_path, "pesterchum.backup-" + str(current_backup) + ".js"))
+ shutil.copyfile(
+ self.filename,
+ os.path.join(
+ backup_path, "pesterchum.backup-" + str(current_backup) + ".js"
+ ),
+ )
# Backup profiles.
# Useful because people don't know how to add underscores to handles.
profile_path = os.path.join(_datadir, "profiles")
profile_list = os.listdir(profile_path)
- with zipfile.ZipFile(os.path.join(backup_path, "profiles.backup-" + str(current_backup)) + ".zip", 'w') as pzip:
+ with zipfile.ZipFile(
+ os.path.join(backup_path, "profiles.backup-" + str(current_backup))
+ + ".zip",
+ "w",
+ ) as pzip:
for x in profile_list:
if x.endswith(".js") == True:
with open(self.filename) as f:
- pzip.writestr(x, f.read())
+ pzip.writestr(x, f.read())
PchumLog.info("Updated backups-%s." % current_backup)
except OSError as e:
@@ -198,81 +234,103 @@ with a backup from: %s" % (_datadir, self.filename,
except zipfile.BadZipFile as e:
PchumLog.warning("Failed to make backup, BadZipFile?")
PchumLog.warning(e)
-
+
def chums(self):
- if 'chums' not in self.config:
+ if "chums" not in self.config:
self.set("chums", [])
- return self.config.get('chums', [])
+ return self.config.get("chums", [])
+
def setChums(self, newchums):
with open(self.filename) as fp:
# what if we have two clients open??
newconfig = json.load(fp)
- oldchums = newconfig['chums']
+ oldchums = newconfig["chums"]
# Time to merge these two! :OOO
for c in list(set(oldchums) - set(newchums)):
newchums.append(c)
self.set("chums", newchums)
+
def hideOfflineChums(self):
- return self.config.get('hideOfflineChums', False)
+ return self.config.get("hideOfflineChums", False)
+
def defaultprofile(self):
try:
- return self.config['defaultprofile']
+ return self.config["defaultprofile"]
except KeyError:
return None
+
def tabs(self):
return self.config.get("tabs", True)
+
def tabMemos(self):
- if 'tabmemos' not in self.config:
+ if "tabmemos" not in self.config:
self.set("tabmemos", self.tabs())
return self.config.get("tabmemos", True)
+
def showTimeStamps(self):
- if 'showTimeStamps' not in self.config:
+ if "showTimeStamps" not in self.config:
self.set("showTimeStamps", True)
- return self.config.get('showTimeStamps', True)
+ return self.config.get("showTimeStamps", True)
+
def time12Format(self):
- if 'time12Format' not in self.config:
+ if "time12Format" not in self.config:
self.set("time12Format", True)
- return self.config.get('time12Format', True)
+ return self.config.get("time12Format", True)
+
def showSeconds(self):
- if 'showSeconds' not in self.config:
+ if "showSeconds" not in self.config:
self.set("showSeconds", False)
- return self.config.get('showSeconds', False)
+ return self.config.get("showSeconds", False)
+
def sortMethod(self):
- return self.config.get('sortMethod', 0)
+ return self.config.get("sortMethod", 0)
+
def useGroups(self):
- return self.config.get('useGroups', False)
+ return self.config.get("useGroups", False)
+
def openDefaultGroup(self):
groups = self.getGroups()
for g in groups:
if g[0] == "Chums":
return g[1]
return True
+
def showEmptyGroups(self):
- if 'emptyGroups' not in self.config:
+ if "emptyGroups" not in self.config:
self.set("emptyGroups", False)
- return self.config.get('emptyGroups', False)
+ return self.config.get("emptyGroups", False)
+
def showOnlineNumbers(self):
- if 'onlineNumbers' not in self.config:
+ if "onlineNumbers" not in self.config:
self.set("onlineNumbers", False)
- return self.config.get('onlineNumbers', False)
+ return self.config.get("onlineNumbers", False)
+
def logPesters(self):
- return self.config.get('logPesters', self.LOG | self.STAMP)
+ return self.config.get("logPesters", self.LOG | self.STAMP)
+
def logMemos(self):
- return self.config.get('logMemos', self.LOG)
+ return self.config.get("logMemos", self.LOG)
+
def disableUserLinks(self):
- return not self.config.get('userLinks', True)
+ return not self.config.get("userLinks", True)
+
def idleTime(self):
- return self.config.get('idleTime', 10)
+ return self.config.get("idleTime", 10)
+
def minimizeAction(self):
- return self.config.get('miniAction', 0)
+ return self.config.get("miniAction", 0)
+
def closeAction(self):
- return self.config.get('closeAction', 1)
+ return self.config.get("closeAction", 1)
+
def opvoiceMessages(self):
- return self.config.get('opvMessages', True)
+ return self.config.get("opvMessages", True)
+
def animations(self):
- return self.config.get('animations', True)
- #def checkForUpdates(self):
+ return self.config.get("animations", True)
+
+ # def checkForUpdates(self):
# u = self.config.get('checkUpdates', 0)
# if type(u) == type(bool()):
# if u: u = 2
@@ -282,53 +340,67 @@ with a backup from: %s" % (_datadir, self.filename,
# # Once a week
# # Only on start
# # Never
- #def lastUCheck(self):
+ # def lastUCheck(self):
# return self.config.get('lastUCheck', 0)
- #def checkMSPA(self):
+ # def checkMSPA(self):
# return self.config.get('mspa', False)
def blink(self):
- return self.config.get('blink', self.PBLINK | self.MBLINK)
+ return self.config.get("blink", self.PBLINK | self.MBLINK)
+
def notify(self):
- return self.config.get('notify', True)
+ return self.config.get("notify", True)
+
def notifyType(self):
- return self.config.get('notifyType', "default")
+ return self.config.get("notifyType", "default")
+
def notifyOptions(self):
- return self.config.get('notifyOptions', self.SIGNIN | self.NEWMSG | self.NEWCONVO | self.INITIALS)
+ return self.config.get(
+ "notifyOptions", self.SIGNIN | self.NEWMSG | self.NEWCONVO | self.INITIALS
+ )
+
def lowBandwidth(self):
- return self.config.get('lowBandwidth', False)
+ return self.config.get("lowBandwidth", False)
+
def ghostchum(self):
- return self.config.get('ghostchum', False)
+ return self.config.get("ghostchum", False)
+
def addChum(self, chum):
if chum.handle not in self.chums():
with open(self.filename) as fp:
# what if we have two clients open??
newconfig = json.load(fp)
- newchums = newconfig['chums'] + [chum.handle]
+ newchums = newconfig["chums"] + [chum.handle]
self.set("chums", newchums)
+
def removeChum(self, chum):
if type(chum) is PesterProfile:
handle = chum.handle
else:
handle = chum
- newchums = [c for c in self.config['chums'] if c != handle]
+ newchums = [c for c in self.config["chums"] if c != handle]
self.set("chums", newchums)
+
def getBlocklist(self):
- if 'block' not in self.config:
- self.set('block', [])
- return self.config['block']
+ if "block" not in self.config:
+ self.set("block", [])
+ return self.config["block"]
+
def addBlocklist(self, handle):
l = self.getBlocklist()
if handle not in l:
l.append(handle)
- self.set('block', l)
+ self.set("block", l)
+
def delBlocklist(self, handle):
l = self.getBlocklist()
l.pop(l.index(handle))
- self.set('block', l)
+ self.set("block", l)
+
def getGroups(self):
- if 'groups' not in self.groups:
+ if "groups" not in self.groups:
self.saveGroups([["Chums", True]])
- return self.groups.get('groups', [["Chums", True]])
+ return self.groups.get("groups", [["Chums", True]])
+
def addGroup(self, group, open=True):
l = self.getGroups()
exists = False
@@ -337,18 +409,21 @@ with a backup from: %s