From 4b39e0f3c604ad395420bef6501c536ae30508a5 Mon Sep 17 00:00:00 2001 From: Kiooeht Date: Mon, 12 Nov 2012 20:52:26 -0800 Subject: [PATCH 01/15] Lua quirks --- luaquirks.py | 44 ++++++++++++++++++++++ menus.py | 4 +- parsetools.py | 14 +++++-- pyquirks.py | 73 +++++++++---------------------------- quirks.py | 91 ++++++++++++++++++++++++++++++++++++++++++++++ quirks/example.lua | 18 +++++++++ 6 files changed, 182 insertions(+), 62 deletions(-) create mode 100644 luaquirks.py create mode 100644 quirks.py create mode 100644 quirks/example.lua diff --git a/luaquirks.py b/luaquirks.py new file mode 100644 index 0000000..32ef26a --- /dev/null +++ b/luaquirks.py @@ -0,0 +1,44 @@ +import os, sys, re, ostools +try: + import lua +except ImportError: + lua = None +from quirks import ScriptQuirks +from PyQt4 import QtGui, QtCore + +class LuaQuirks(ScriptQuirks): + def loadModule(self, name, filename): + if lua is None: + return None + fullname = os.path.join('quirks', name) + lua.globals().package.loaded[fullname] = None + return lua.require(fullname) + + def getExtension(self): + return '.lua' + + def modHas(self, module, attr): + return module[attr] is not None + + def register(self, module): + class Wrapper(object): + def __init__(self, module, name): + self.module = module + self.name = name + + def __call__(self, text): + return self.module.commands[self.name](lua.globals().tostring(text)) + + for name in module.commands: + try: + if not isinstance(module.commands[name]("test"), basestring): + raise Exception + except: + print "Quirk malformed: %s" % (name) + msgbox = QtGui.QMessageBox() + msgbox.setWindowTitle("Error!") + msgbox.setText("Quirk malformed: %s" % (name)) + msgbox.exec_() + else: + self.quirks[name] = Wrapper(module, name) + diff --git a/menus.py b/menus.py index 98ce597..9bd1f1c 100644 --- a/menus.py +++ b/menus.py @@ -323,7 +323,7 @@ class PesterQuirkTypes(QtGui.QDialog): self.funclist2.setStyleSheet("color: #000000; background-color: #FFFFFF;") from parsetools import quirkloader - funcs = [q+")" for q in quirkloader.quirks.keys()] + funcs = [q+"()" for q in quirkloader.quirks.keys()] funcs.sort() self.funclist.addItems(funcs) self.funclist2.addItems(funcs) @@ -561,7 +561,7 @@ class PesterQuirkTypes(QtGui.QDialog): def reloadQuirkFuncSlot(self): from parsetools import reloadQuirkFunctions, quirkloader reloadQuirkFunctions() - funcs = [q+")" for q in quirkloader.quirks.keys()] + funcs = [q+"()" for q in quirkloader.quirks.keys()] funcs.sort() self.funclist.clear() self.funclist.addItems(funcs) diff --git a/parsetools.py b/parsetools.py index 4c17e18..cc0feef 100644 --- a/parsetools.py +++ b/parsetools.py @@ -6,7 +6,9 @@ from datetime import timedelta from PyQt4 import QtGui from generic import mysteryTime +from quirks import ScriptQuirks from pyquirks import PythonQuirks +from luaquirks import LuaQuirks _ctag_begin = re.compile(r'(?i)') _gtag_begin = re.compile(r'(?i)') @@ -23,12 +25,16 @@ _format_begin = re.compile(r'(?i)<([ibu])>') _format_end = re.compile(r'(?i)') _honk = re.compile(r"(?i)\bhonk\b") -quirkloader = PythonQuirks() +quirkloader = ScriptQuirks() +quirkloader.add(PythonQuirks()) +quirkloader.add(LuaQuirks()) +quirkloader.loadAll() +print quirkloader.funcre() _functionre = re.compile(r"%s" % quirkloader.funcre()) _groupre = re.compile(r"\\([0-9]+)") def reloadQuirkFunctions(): - quirkloader.load() + quirkloader.loadAll() global _functionre _functionre = re.compile(r"%s" % quirkloader.funcre()) @@ -395,8 +401,8 @@ def parseRegexpFunctions(to): backr = _groupre.search(mo.group()) if backr is not None: current.append(backreference(backr.group(1))) - elif mo.group() in functiondict.keys(): - p = parseLeaf(functiondict[mo.group()], current) + elif mo.group()[:-1] in functiondict.keys(): + p = parseLeaf(functiondict[mo.group()[:-1]], current) current.append(p) current = p elif mo.group() == ")": diff --git a/pyquirks.py b/pyquirks.py index 593be70..8ecf999 100644 --- a/pyquirks.py +++ b/pyquirks.py @@ -1,57 +1,26 @@ import os, sys, imp, re, ostools +from quirks import ScriptQuirks from PyQt4 import QtGui, QtCore -class PythonQuirks(object): - def __init__(self): - self._datadir = ostools.getDataDir() - self.home = os.getcwd() - self.quirks = {} - self.last = {} - self.load() +class PythonQuirks(ScriptQuirks): + def loadModule(self, name, filename): + return imp.load_source(name, filename) - def load(self): - self.last = self.quirks.copy() - self.quirks.clear() - filenames = [] - if not os.path.exists(os.path.join(self.home, 'quirks')): - os.mkdir(os.path.join(self.home, 'quirks')) - for fn in os.listdir(os.path.join(self.home, 'quirks')): - if fn.endswith('.py') and not fn.startswith('_'): - filenames.append(os.path.join(self.home, 'quirks', fn)) - if self._datadir: - if not os.path.exists(os.path.join(self._datadir, 'quirks')): - os.mkdir(os.path.join(self._datadir, 'quirks')) - for fn in os.listdir(os.path.join(self._datadir, 'quirks')): - if fn.endswith('.py') and not fn.startswith('_'): - filenames.append(os.path.join(self._datadir, 'quirks', fn)) + def getExtension(self): + return '.py' - modules = [] - for filename in filenames: - name = os.path.basename(filename)[:-3] - try: module = imp.load_source(name, filename) - except Exception, e: - print "Error loading %s: %s (in pyquirks.py)" % (name, e) - msgbox = QtGui.QMessageBox() - msgbox.setWindowTitle("Error!") - msgbox.setText("Error loading %s: %s (in pyquirks.py)" % (name, e)) - msgbox.exec_() - else: - if hasattr(module, 'setup'): - module.setup() - self.register(vars(module)) - modules.append(name) - for k in self.last: - if k in self.quirks: - if self.last[k] == self.quirks[k]: - del self.quirks[k] + def modHas(self, module, attr): + if attr == 'commands': + variables = vars(module) + for name, obj in variables.iteritems(): + if self.modHas(obj, 'command'): + return True + return hasattr(module, attr) - if self.quirks: - print 'Registered quirks:', '), '.join(self.quirks) + ")" - else:print "Warning: Couldn't find any python quirks" - - def register(self, variables): + def register(self, module): + variables = vars(module) for name, obj in variables.iteritems(): - if hasattr(obj, 'command'): + if self.modHas(obj, 'command'): try: if not isinstance(obj("test"), basestring): raise Exception @@ -62,13 +31,5 @@ class PythonQuirks(object): msgbox.setText("Quirk malformed: %s" % (obj.command)) msgbox.exec_() else: - self.quirks[obj.command+"("] = obj + self.quirks[obj.command] = obj - def funcre(self): - if not self.quirks: - return r"\\[0-9]+" - f = r"(" - for q in self.quirks: - f = f + q[:-1]+r"\(|" - f = f + r"\)|\\[0-9]+)" - return f diff --git a/quirks.py b/quirks.py new file mode 100644 index 0000000..e07b14b --- /dev/null +++ b/quirks.py @@ -0,0 +1,91 @@ +import os, sys, re, ostools +from PyQt4 import QtGui, QtCore + +class ScriptQuirks(object): + def __init__(self): + self._datadir = ostools.getDataDir() + self.home = os.getcwd() + self.quirks = {} + self.last = {} + self.scripts = [] + #self.load() + + def loadModule(self, name, filename): + raise Exception + + def modHas(self, module, attr): + return False + + def loadAll(self): + self.last = self.quirks.copy() + self.quirks.clear() + for script in self.scripts: + print script.getExtension() + script.load() + #print script.quirks + for q in script.quirks: + self.quirks.update(script.quirks) + for k in self.last: + if k in self.quirks: + if self.last[k] == self.quirks[k]: + del self.quirks[k] + #print self.quirks + if self.quirks: + print 'Registered quirks:', '(), '.join(self.quirks) + "()" + else: + print "Warning: Couldn't find any script quirks" + + def add(self, script): + self.scripts.append(script) + + def load(self): + self.last = self.quirks.copy() + self.quirks.clear() + extension = self.getExtension() + filenames = [] + if not os.path.exists(os.path.join(self.home, 'quirks')): + os.mkdir(os.path.join(self.home, 'quirks')) + for fn in os.listdir(os.path.join(self.home, 'quirks')): + if fn.endswith(extension) and not fn.startswith('_'): + filenames.append(os.path.join(self.home, 'quirks', fn)) + if self._datadir: + if not os.path.exists(os.path.join(self._datadir, 'quirks')): + os.mkdir(os.path.join(self._datadir, 'quirks')) + for fn in os.listdir(os.path.join(self._datadir, 'quirks')): + if fn.endswith(extension) and not fn.startswith('_'): + filenames.append(os.path.join(self._datadir, 'quirks', fn)) + + + modules = [] + for filename in filenames: + extension_length = len(self.getExtension()) + name = os.path.basename(filename)[:-extension_length] + try: + module = self.loadModule(name, filename) + if module is None: + continue + except Exception, e: + print "Error loading %s: %s (in quirks.py)" % (os.path.basename(name), e) + msgbox = QtGui.QMessageBox() + msgbox.setWindowTitle("Error!") + msgbox.setText("Error loading %s: %s (in quirks.py)" % (os.path.basename(filename), e)) + msgbox.exec_() + else: + if self.modHas(module, 'setup'): + module.setup() + if self.modHas(module, 'commands'): + self.register(module) + modules.append(name) + for k in self.last: + if k in self.quirks: + if self.last[k] == self.quirks[k]: + del self.quirks[k] + + def funcre(self): + if not self.quirks: + return r"\\[0-9]+" + f = r"(" + for q in self.quirks: + f = f + q+r"\(|" + f = f + r"\)|\\[0-9]+)" + return f diff --git a/quirks/example.lua b/quirks/example.lua new file mode 100644 index 0000000..82f8045 --- /dev/null +++ b/quirks/example.lua @@ -0,0 +1,18 @@ +module(..., package.seeall) +commands = {} + +local function upper(text) + return string.upper(text) +end +commands.luaupper = upper + +local function lower(text) + return string.lower(text) +end +commands.lualower = lower + +local function utf8reverse(text) + return text:gsub("([\194-\244][\128-\191]+)", string.reverse):reverse() +end +commands.luareverse = utf8reverse + From 42efeaa6e54f91c26483dd16c970849bf7b25e42 Mon Sep 17 00:00:00 2001 From: brachyonic Date: Wed, 6 Feb 2013 13:36:14 -0500 Subject: [PATCH 02/15] implemented multiple selection of memos in memo chooser, fixed small spelling mistake in pesterchum.py, added some vim-related ignore patterns to .gitignore --- .gitignore | 2 ++ menus.py | 24 ++++++++++++++---------- pesterchum.py | 15 +++++++++------ 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/.gitignore b/.gitignore index 755e919..771d49e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +*.swp +*~ logs/* build/* profiles/* diff --git a/menus.py b/menus.py index 9bd1f1c..f791356 100644 --- a/menus.py +++ b/menus.py @@ -1588,6 +1588,7 @@ class PesterMemoList(QtGui.QDialog): self.label = QtGui.QLabel("MEMOS") self.channelarea = RightClickTree(self) + self.channelarea.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection) self.channelarea.setStyleSheet(self.theme["main/chums/style"]) self.channelarea.optionsMenu = QtGui.QMenu(self) self.channelarea.setColumnCount(2) @@ -1599,7 +1600,7 @@ class PesterMemoList(QtGui.QDialog): self.channelarea.sortByColumn(0, QtCore.Qt.AscendingOrder) self.connect(self.channelarea, QtCore.SIGNAL('itemDoubleClicked(QTreeWidgetItem *, int)'), - self, QtCore.SLOT('joinActivatedMemo()')) + self, QtCore.SLOT('AcceptSelection()')) self.orjoinlabel = QtGui.QLabel("OR MAKE A NEW MEMO:") self.newmemo = QtGui.QLineEdit(channel, self) @@ -1616,7 +1617,7 @@ class PesterMemoList(QtGui.QDialog): self.join = QtGui.QPushButton("JOIN", self) self.join.setDefault(True) self.connect(self.join, QtCore.SIGNAL('clicked()'), - self, QtCore.SLOT('checkEmpty()')) + self, QtCore.SLOT('AcceptIfSelectionMade()')) layout_ok = QtGui.QHBoxLayout() layout_ok.addWidget(self.cancel) layout_ok.addWidget(self.join) @@ -1644,8 +1645,12 @@ class PesterMemoList(QtGui.QDialog): def newmemoname(self): return self.newmemo.text() - def selectedmemo(self): - return self.channelarea.currentItem() + + def SelectedMemos(self): + return self.channelarea.selectedItems() + + def HasSelection(self): + return len(self.SelectedMemos()) > 0 or self.newmemoname() def updateChannels(self, channels): for c in channels: @@ -1663,13 +1668,12 @@ class PesterMemoList(QtGui.QDialog): item.setIcon(QtGui.QIcon(theme["memos/memoicon"])) @QtCore.pyqtSlot() - def checkEmpty(self): - newmemo = self.newmemoname() - selectedmemo = self.selectedmemo() - if newmemo or selectedmemo: - self.accept() + def AcceptIfSelectionMade(self): + if self.HasSelection(): + self.AcceptSelection() + @QtCore.pyqtSlot() - def joinActivatedMemo(self): + def AcceptSelection(self): self.accept() diff --git a/pesterchum.py b/pesterchum.py index 34e4706..6aeaeea 100644 --- a/pesterchum.py +++ b/pesterchum.py @@ -40,7 +40,7 @@ else: minor = int(vnum[vnum.find(".")+1:]) if not ((major > 4) or (major == 4 and minor >= 6)): print "ERROR: Pesterchum requires Qt version >= 4.6" - print "You currently have version " + vnum + ". Please ungrade Qt" + print "You currently have version " + vnum + ". Please upgrade Qt" exit() import ostools @@ -2058,18 +2058,21 @@ class PesterWindow(MovingWindow): self.memochooser.show() @QtCore.pyqtSlot() def joinSelectedMemo(self): - newmemo = self.memochooser.newmemoname() - selectedmemo = self.memochooser.selectedmemo() + time = unicode(self.memochooser.timeinput.text()) secret = self.memochooser.secretChannel.isChecked() invite = self.memochooser.inviteChannel.isChecked() - if newmemo: + + if self.memochooser.newmemoname(): + newmemo = self.memochooser.newmemoname() channel = "#"+unicode(newmemo).replace(" ", "_") channel = re.sub(r"[^A-Za-z0-9#_]", "", channel) self.newMemo(channel, time, secret=secret, invite=invite) - elif selectedmemo: - channel = "#"+unicode(selectedmemo.target) + + for SelectedMemo in self.memochooser.SelectedMemos(): + channel = "#"+unicode(SelectedMemo.target) self.newMemo(channel, time) + self.memochooser = None @QtCore.pyqtSlot() def memoChooserClose(self): From 0ed9543d50f909344463fecf41eb3a84366c5e80 Mon Sep 17 00:00:00 2001 From: brachyonic Date: Sun, 10 Feb 2013 12:49:44 -0500 Subject: [PATCH 03/15] Now chdirs into the quirks folder before executing lua quirks, allowing require() to be used without having to preprend 'quirks.', just a bit cleaner --- luaquirks.py | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/luaquirks.py b/luaquirks.py index 32ef26a..8cefbfd 100644 --- a/luaquirks.py +++ b/luaquirks.py @@ -10,9 +10,20 @@ class LuaQuirks(ScriptQuirks): def loadModule(self, name, filename): if lua is None: return None - fullname = os.path.join('quirks', name) - lua.globals().package.loaded[fullname] = None - return lua.require(fullname) + + lua.globals().package.loaded[name] = None + + CurrentDir = os.getcwd() + os.chdir('quirks') + try: + print("a") + return lua.require(name) + except Error as e: + print(e) + return None + finally: + print("back") + os.chdir(CurrentDir) def getExtension(self): return '.lua' @@ -27,11 +38,19 @@ class LuaQuirks(ScriptQuirks): self.name = name def __call__(self, text): - return self.module.commands[self.name](lua.globals().tostring(text)) + CurrentDir = os.getcwd() + os.chdir('quirks') + try: + return self.module.commands[self.name](lua.globals().tostring(text)) + except: + return None + finally: + os.chdir(CurrentDir) for name in module.commands: + CommandWrapper = Wrapper(module,name) try: - if not isinstance(module.commands[name]("test"), basestring): + if not isinstance(CommandWrapper("test"), basestring): raise Exception except: print "Quirk malformed: %s" % (name) @@ -40,5 +59,5 @@ class LuaQuirks(ScriptQuirks): msgbox.setText("Quirk malformed: %s" % (name)) msgbox.exec_() else: - self.quirks[name] = Wrapper(module, name) + self.quirks[name] = CommandWrapper From e16965e77123f6f4bbccfbd5bebf9fba20e7ae5d Mon Sep 17 00:00:00 2001 From: Kiooeht Date: Mon, 25 Feb 2013 21:52:38 -0800 Subject: [PATCH 04/15] Fix thing with inspect on non-python function for libnotify --- toast.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/toast.py b/toast.py index 2bcec80..7691332 100644 --- a/toast.py +++ b/toast.py @@ -74,7 +74,11 @@ class ToastMachine(object): t = None for (k,v) in self.machine.types.iteritems(): if self.machine.type == k: - args = inspect.getargspec(v.__init__).args + try: + args = inspect.getargspec(v.__init__).args + except: + args = [] + extras = {} if 'parent' in args: extras['parent'] = self.machine.parent From bf1345046eb3b33bb97c71efa66eb65b1a3f6310 Mon Sep 17 00:00:00 2001 From: Kiooeht Date: Mon, 25 Feb 2013 22:02:30 -0800 Subject: [PATCH 05/15] Clean up unneeded prints --- luaquirks.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/luaquirks.py b/luaquirks.py index 8cefbfd..b81e386 100644 --- a/luaquirks.py +++ b/luaquirks.py @@ -12,17 +12,15 @@ class LuaQuirks(ScriptQuirks): return None lua.globals().package.loaded[name] = None - + CurrentDir = os.getcwd() os.chdir('quirks') try: - print("a") return lua.require(name) except Error as e: - print(e) + print e return None finally: - print("back") os.chdir(CurrentDir) def getExtension(self): From e29791402dc7eadfd3a78cff699da9d91cb47ee9 Mon Sep 17 00:00:00 2001 From: Kiooeht Date: Fri, 10 Jan 2014 22:59:28 -0800 Subject: [PATCH 06/15] Fix toast notifications to not require sound be on --- pesterchum.py | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/pesterchum.py b/pesterchum.py index 6aeaeea..8e789de 100644 --- a/pesterchum.py +++ b/pesterchum.py @@ -1355,19 +1355,25 @@ class PesterWindow(MovingWindow): systemColor = QtGui.QColor(self.theme["memos/systemMsgColor"]) msg = "%s" % (systemColor.name(), msg) memo.addMessage(msg, handle) + mentioned = False + m = convertTags(msg, "text") + if m.find(":") <= 3: + m = m[m.find(":"):] + for search in self.userprofile.getMentions(): + if re.search(search, m): + mentioned = True + break + if mentioned: + if self.config.notifyOptions() & self.config.INITIALS: + t = self.tm.Toast(chan, re.sub("", "", msg)) + t.show() + if self.config.soundOn(): if self.config.memoSound(): if self.config.nameSound(): - m = convertTags(msg, "text") - if m.find(":") <= 3: - m = m[m.find(":"):] - for search in self.userprofile.getMentions(): - if re.search(search, m): - if self.config.notifyOptions() & self.config.INITIALS: - t = self.tm.Toast(chan, re.sub("", "", msg)) - t.show() - self.namesound.play() - return + if mentioned: + self.namesound.play() + return if self.honk and re.search(r"\bhonk\b", convertTags(msg, "text"), re.I): self.honksound.play() elif self.config.memoPing(): @@ -2058,17 +2064,17 @@ class PesterWindow(MovingWindow): self.memochooser.show() @QtCore.pyqtSlot() def joinSelectedMemo(self): - + time = unicode(self.memochooser.timeinput.text()) secret = self.memochooser.secretChannel.isChecked() invite = self.memochooser.inviteChannel.isChecked() - + if self.memochooser.newmemoname(): newmemo = self.memochooser.newmemoname() channel = "#"+unicode(newmemo).replace(" ", "_") channel = re.sub(r"[^A-Za-z0-9#_]", "", channel) self.newMemo(channel, time, secret=secret, invite=invite) - + for SelectedMemo in self.memochooser.SelectedMemos(): channel = "#"+unicode(SelectedMemo.target) self.newMemo(channel, time) From be901f46e88546572055ae90e6c88b6b8cc6f159 Mon Sep 17 00:00:00 2001 From: Kiooeht Date: Sat, 11 Jan 2014 00:19:14 -0800 Subject: [PATCH 07/15] Bug fix: Don't close program when closing a window while main window is minimized --- TODO.mkdn | 2 -- pesterchum.py | 16 +++++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/TODO.mkdn b/TODO.mkdn index 96d3fef..3b2fb75 100644 --- a/TODO.mkdn +++ b/TODO.mkdn @@ -35,8 +35,6 @@ Bugs * Closing a timeclone doesn't actually cease for everyone else * Kill Zalgo * Random invisible, tiny links to last link at end of every message -* Clicking link to invite-only memo crashes -* Close when banned from memo when main PC window minimized * Chums not appearing on chumroll when initals are the same? (bS) * Recognize IRC 471, 473, 474 and 475 * memo links aren't case sensitive diff --git a/pesterchum.py b/pesterchum.py index 8e789de..7e7b579 100644 --- a/pesterchum.py +++ b/pesterchum.py @@ -982,10 +982,11 @@ class TrollSlumWindow(QtGui.QFrame): unblockChumSignal = QtCore.pyqtSignal(QtCore.QString) class PesterWindow(MovingWindow): - def __init__(self, options, parent=None): + def __init__(self, options, parent=None, app=None): MovingWindow.__init__(self, parent, (QtCore.Qt.CustomizeWindowHint | QtCore.Qt.FramelessWindowHint)) + self.app = app self.convos = CaseInsensitiveDict() self.memos = CaseInsensitiveDict() self.tabconvo = None @@ -1056,7 +1057,7 @@ class PesterWindow(MovingWindow): exitaction = QtGui.QAction(self.theme["main/menus/client/exit"], self) self.exitaction = exitaction self.connect(exitaction, QtCore.SIGNAL('triggered()'), - self, QtCore.SLOT('close()')) + self.app, QtCore.SLOT('quit()')) userlistaction = QtGui.QAction(self.theme["main/menus/client/userlist"], self) self.userlistaction = userlistaction self.connect(userlistaction, QtCore.SIGNAL('triggered()'), @@ -2472,7 +2473,7 @@ class PesterWindow(MovingWindow): self, QtCore.SLOT('closeToTray()')); elif old == 2: # quit self.disconnect(button, QtCore.SIGNAL('clicked()'), - self, QtCore.SLOT('close()')); + self.app, QtCore.SLOT('quit()')); if setting == 0: # minimize to taskbar self.connect(button, QtCore.SIGNAL('clicked()'), @@ -2482,7 +2483,7 @@ class PesterWindow(MovingWindow): self, QtCore.SLOT('closeToTray()')); elif setting == 2: # quit self.connect(button, QtCore.SIGNAL('clicked()'), - self, QtCore.SLOT('close()')); + self.app, QtCore.SLOT('quit()')); @QtCore.pyqtSlot() def themeSelectOverride(self): @@ -2704,6 +2705,7 @@ class MainProgram(QtCore.QObject): QtCore.QObject.__init__(self) self.app = QtGui.QApplication(sys.argv) self.app.setApplicationName("Pesterchum 3.14") + self.app.setQuitOnLastWindowClosed(False) options = self.oppts(sys.argv[1:]) @@ -2716,7 +2718,7 @@ class MainProgram(QtCore.QObject): print "Warning: No sound! %s" % (e) else: print "Warning: No sound!" - self.widget = PesterWindow(options) + self.widget = PesterWindow(options, app=self.app) self.widget.show() self.trayicon = PesterTray(PesterIcon(self.widget.theme["main/icon"]), self.widget, self.app) @@ -2738,7 +2740,7 @@ class MainProgram(QtCore.QObject): self.widget, QtCore.SLOT('showMinimized()')) exitAction = QtGui.QAction("EXIT", self) self.trayicon.connect(exitAction, QtCore.SIGNAL('triggered()'), - self.widget, QtCore.SLOT('close()')) + self.app, QtCore.SLOT('quit()')) self.traymenu.addAction(miniAction) self.traymenu.addAction(exitAction) @@ -2951,7 +2953,7 @@ Click this message to never see this again.") widget.loadingscreen = LoadingScreen(widget) widget.loadingscreen.loadinglabel.setText(msg) self.connect(widget.loadingscreen, QtCore.SIGNAL('rejected()'), - widget, QtCore.SLOT('close()')) + widget.app, QtCore.SLOT('quit()')) self.connect(self.widget.loadingscreen, QtCore.SIGNAL('tryAgain()'), self, QtCore.SLOT('tryAgain()')) if hasattr(self, 'irc') and self.irc.registeredIRC: From 7dbe1e37d26c786953f420f34fe160959c6eecb4 Mon Sep 17 00:00:00 2001 From: Kiooeht Date: Sat, 11 Jan 2014 00:20:33 -0800 Subject: [PATCH 08/15] Changelog update --- CHANGELOG.mkdn | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.mkdn b/CHANGELOG.mkdn index 4455722..4007639 100644 --- a/CHANGELOG.mkdn +++ b/CHANGELOG.mkdn @@ -22,6 +22,8 @@ CHANGELOG * FTP and Magnet links - oakwhiz * Userlist search - oakwhiz * Chanserv in menus - Cerxi [binaryCabalist] +* Lua quirks +* Multi-select memo chooser * Bug fixes * Don't require pygame (it's kind of optional, you just don't get sound) - Kiooeht [evacipatedBox] * Allow add chum dialog to open after adding an existing chum - Kiooeht [evacipatedBox] @@ -32,6 +34,9 @@ CHANGELOG * Move hidden chums when deleting group - Kiooeht [evacipatedBox] * Don't allow rename groups with parenthesis - Kiooeht [evacipatedBox] * Wrap long error messages - Kiooeht [evacipatedBox] + * chdir into quirks folder for Lua quirks - [alGore] + * Toast notifications don't require sound to be on - Kiooeht [evacipatedBox] + * Don't close Pesterchum if a window is closed while main window minimized - Kiooeht [evacipatedBox] ### 3.41.3 From 525b2b1bf84c5bf0d61d5448b0d645aad5e8aec2 Mon Sep 17 00:00:00 2001 From: Kiooeht Date: Sat, 11 Jan 2014 23:33:33 -0800 Subject: [PATCH 09/15] Dont' toast messages from base bots --- pesterchum.py | 8 +++++--- randomer.py | 4 +++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/pesterchum.py b/pesterchum.py index 7e7b579..271b71f 100644 --- a/pesterchum.py +++ b/pesterchum.py @@ -89,7 +89,7 @@ from memos import PesterMemo, MemoTabWindow, TimeTracker from irc import PesterIRC from logviewer import PesterLogUserSelect, PesterLogViewer from bugreport import BugReporter -from randomer import RandomHandler +from randomer import RandomHandler, RANDNICK # Rawr, fuck you OSX leopard if not ostools.isOSXLeopard(): @@ -103,6 +103,7 @@ canon_handles = ["apocalypseArisen", "arsenicCatnip", "arachnidsGrip", "adiosTor "caligulasAquarium", "cuttlefishCuller", "carcinoGeneticist", "centaursTesticle", \ "grimAuxiliatrix", "gallowsCalibrator", "gardenGnostic", "ectoBiologist", \ "twinArmageddons", "terminallyCapricious", "turntechGodhead", "tentacleTherapist"] +BOTNAMES = ["NICKSERV", "CHANSERV", "MEMOSERV", "OPERSERV", "HELPSERV", "CALSPRITE", RANDNICK.upper()] class waitingMessageHolder(object): @@ -1306,8 +1307,9 @@ class PesterWindow(MovingWindow): t.show() elif not self.config.notifyOptions() & self.config.NEWCONVO: if msg[:11] != "PESTERCHUM:": - t = self.tm.Toast("From: %s" % handle, re.sub("", "", msg)) - t.show() + if handle.upper() not in BOTNAMES: + t = self.tm.Toast("From: %s" % handle, re.sub("", "", msg)) + t.show() else: if msg == "PESTERCHUM:CEASE": t = self.tm.Toast("Closed Conversation", handle) diff --git a/randomer.py b/randomer.py index 6078d56..ff62399 100644 --- a/randomer.py +++ b/randomer.py @@ -1,9 +1,11 @@ from PyQt4 import QtGui, QtCore +RANDNICK = "randomEncounter" + class RandomHandler(QtCore.QObject): def __init__(self, parent): QtCore.QObject.__init__(self, parent) - self.randNick = "randomEncounter" + self.randNick = RANDNICK self.mainwindow = parent self.queue = [] self.running = False From ecade05310414569837498a56d3e989c47ba4df5 Mon Sep 17 00:00:00 2001 From: Kiooeht Date: Sat, 11 Jan 2014 23:42:39 -0800 Subject: [PATCH 10/15] Use bot name definitions instead of hardcoded names --- pesterchum.py | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/pesterchum.py b/pesterchum.py index 271b71f..b9ff0f4 100644 --- a/pesterchum.py +++ b/pesterchum.py @@ -103,7 +103,9 @@ canon_handles = ["apocalypseArisen", "arsenicCatnip", "arachnidsGrip", "adiosTor "caligulasAquarium", "cuttlefishCuller", "carcinoGeneticist", "centaursTesticle", \ "grimAuxiliatrix", "gallowsCalibrator", "gardenGnostic", "ectoBiologist", \ "twinArmageddons", "terminallyCapricious", "turntechGodhead", "tentacleTherapist"] -BOTNAMES = ["NICKSERV", "CHANSERV", "MEMOSERV", "OPERSERV", "HELPSERV", "CALSPRITE", RANDNICK.upper()] +CUSTOMBOTS = ["CALSPRITE", RANDNICK.upper()] +BOTNAMES = ["NICKSERV", "CHANSERV", "MEMOSERV", "OPERSERV", "HELPSERV"] +BOTNAMES.extend(CUSTOMBOTS) class waitingMessageHolder(object): @@ -1422,19 +1424,11 @@ class PesterWindow(MovingWindow): self.connect(convoWindow, QtCore.SIGNAL('windowClosed(QString)'), self, QtCore.SLOT('closeConvo(QString)')) self.convos[chum.handle] = convoWindow - if unicode(chum.handle).upper() == "CHANSERV" or \ - unicode(chum.handle).upper() == "NICKSERV" or \ - unicode(chum.handle).upper() == "MEMOSERV" or \ - unicode(chum.handle).upper() == "OPERSERV" or \ - unicode(chum.handle).upper() == "HELPSERV": + if unicode(chum.handle).upper() in BOTNAMES: convoWindow.toggleQuirks(True) convoWindow.quirksOff.setChecked(True) - else: - if unicode(chum.handle).upper() == "CALSPRITE" or \ - unicode(chum.handle).upper() == "RANDOMENCOUNTER": - convoWindow.toggleQuirks(True) - convoWindow.quirksOff.setChecked(True) - self.newConvoStarted.emit(QtCore.QString(chum.handle), initiated) + if unicode(chum.handle).upper() in CUSTOMBOTS: + self.newConvoStarted.emit(QtCore.QString(chum.handle), initiated) convoWindow.show() def createTabWindow(self): From db9caf210e25aad6321afe8983ac92fd8f16f547 Mon Sep 17 00:00:00 2001 From: Kiooeht Date: Sun, 12 Jan 2014 00:14:16 -0800 Subject: [PATCH 11/15] Auto-identify with NickServ --- CHANGELOG.mkdn | 3 ++- irc.py | 1 + menus.py | 32 ++++++++++++++++++++++++++++---- nickservmsgs.py | 19 +++++++++++++++++++ pesterchum.py | 19 +++++++++++++++++++ profile.py | 30 ++++++++++++++++++++++++++++++ 6 files changed, 99 insertions(+), 5 deletions(-) create mode 100644 nickservmsgs.py diff --git a/CHANGELOG.mkdn b/CHANGELOG.mkdn index 4007639..6ba8856 100644 --- a/CHANGELOG.mkdn +++ b/CHANGELOG.mkdn @@ -23,7 +23,8 @@ CHANGELOG * Userlist search - oakwhiz * Chanserv in menus - Cerxi [binaryCabalist] * Lua quirks -* Multi-select memo chooser +* Multi-select memo chooser - [alGore] +* Auto-identify with NickServ - Kiooeht [evacipatedBox] * Bug fixes * Don't require pygame (it's kind of optional, you just don't get sound) - Kiooeht [evacipatedBox] * Allow add chum dialog to open after adding an existing chum - Kiooeht [evacipatedBox] diff --git a/irc.py b/irc.py index 0fe8e26..4cec0a5 100644 --- a/irc.py +++ b/irc.py @@ -176,6 +176,7 @@ class PesterIRC(QtCore.QThread): except socket.error: self.setConnectionBroken() self.mainwindow.closeConversations(True) + self.mainwindow.doAutoIdentify() self.updateMood() @QtCore.pyqtSlot() def updateMood(self): diff --git a/menus.py b/menus.py index f791356..37d3bb7 100644 --- a/menus.py +++ b/menus.py @@ -1001,7 +1001,7 @@ class PesterOptions(QtGui.QDialog): self.tabs = QtGui.QButtonGroup(self) self.connect(self.tabs, QtCore.SIGNAL('buttonClicked(int)'), self, QtCore.SLOT('changePage(int)')) - tabNames = ["Chum List", "Conversations", "Interface", "Sound", "Notifications", "Logging", "Idle/Updates", "Theme"] + tabNames = ["Chum List", "Conversations", "Interface", "Sound", "Notifications", "Logging", "Idle/Updates", "Theme", "Connection"] if parent.advanced: tabNames.append("Advanced") for t in tabNames: button = QtGui.QPushButton(t) @@ -1020,6 +1020,15 @@ class PesterOptions(QtGui.QDialog): font.setPointSize(8) bandwidthLabel.setFont(font) + self.autonickserv = QtGui.QCheckBox("Auto-Identify with NickServ", self) + self.autonickserv.setChecked(parent.userprofile.getAutoIdentify()) + self.connect(self.autonickserv, QtCore.SIGNAL('stateChanged(int)'), + self, QtCore.SLOT('autoNickServChange(int)')) + self.nickservpass = QtGui.QLineEdit(self) + self.nickservpass.setPlaceholderText("NickServ Password") + self.nickservpass.setEchoMode(QtGui.QLineEdit.PasswordEchoOnEdit) + self.nickservpass.setText(parent.userprofile.getNickServPass()) + self.tabcheck = QtGui.QCheckBox("Tabbed Conversations", self) if self.config.tabs(): self.tabcheck.setChecked(True) @@ -1259,8 +1268,6 @@ class PesterOptions(QtGui.QDialog): layout_chumlist.addWidget(self.showemptycheck) layout_chumlist.addWidget(self.showonlinenumbers) layout_chumlist.addLayout(layout_3) - layout_chumlist.addWidget(self.bandwidthcheck) - layout_chumlist.addWidget(bandwidthLabel) self.pages.addWidget(widget) # Conversations @@ -1365,6 +1372,19 @@ class PesterOptions(QtGui.QDialog): layout_theme.addWidget(self.ghostchum) self.pages.addWidget(widget) + # Connection + widget = QtGui.QWidget() + layout_connect = QtGui.QVBoxLayout(widget) + layout_connect.setAlignment(QtCore.Qt.AlignTop) + layout_connect.addWidget(self.bandwidthcheck) + layout_connect.addWidget(bandwidthLabel) + layout_connect.addWidget(self.autonickserv) + layout_indent = QtGui.QVBoxLayout() + layout_indent.addWidget(self.nickservpass) + layout_indent.setContentsMargins(22,0,0,0) + layout_connect.addLayout(layout_indent) + self.pages.addWidget(widget) + # Advanced if parent.advanced: widget = QtGui.QWidget() @@ -1411,6 +1431,10 @@ class PesterOptions(QtGui.QDialog): self.notifyNewConvoCheck.setEnabled(True) self.notifyMentionsCheck.setEnabled(True) + @QtCore.pyqtSlot(int) + def autoNickServChange(self, state): + self.nickservpass.setEnabled(state != 0) + @QtCore.pyqtSlot(int) def soundChange(self, state): if state == 0: @@ -1648,7 +1672,7 @@ class PesterMemoList(QtGui.QDialog): def SelectedMemos(self): return self.channelarea.selectedItems() - + def HasSelection(self): return len(self.SelectedMemos()) > 0 or self.newmemoname() diff --git a/nickservmsgs.py b/nickservmsgs.py new file mode 100644 index 0000000..f03709f --- /dev/null +++ b/nickservmsgs.py @@ -0,0 +1,19 @@ +# 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." +} + +def translate(msg): + if msg in messages: + if messages[msg] == "": + return msg + return messages[msg] + return None diff --git a/pesterchum.py b/pesterchum.py index b9ff0f4..c64cefe 100644 --- a/pesterchum.py +++ b/pesterchum.py @@ -90,6 +90,7 @@ from irc import PesterIRC from logviewer import PesterLogUserSelect, PesterLogViewer from bugreport import BugReporter from randomer import RandomHandler, RANDNICK +import nickservmsgs # Rawr, fuck you OSX leopard if not ostools.isOSXLeopard(): @@ -1709,11 +1710,18 @@ class PesterWindow(MovingWindow): else: self.waitingMessages.answerMessage() + def doAutoIdentify(self): + if self.userprofile.getAutoIdentify(): + self.sendMessage.emit("identify " + self.userprofile.getNickServPass(), "NickServ") + @QtCore.pyqtSlot() def connected(self): if self.loadingscreen: self.loadingscreen.done(QtGui.QDialog.Accepted) self.loadingscreen = None + + self.doAutoIdentify() + @QtCore.pyqtSlot() def blockSelectedChum(self): curChumListing = self.chumList.currentItem() @@ -1806,6 +1814,11 @@ class PesterWindow(MovingWindow): self.randhandler.incoming(msg) elif self.convos.has_key(h): self.newMessage(h, m) + elif h.upper() == "NICKSERV" and "PESTERCHUM:" not in m: + m = nickservmsgs.translate(m) + if m: + t = self.tm.Toast("NickServ:", m) + t.show() @QtCore.pyqtSlot(QtCore.QString, QtCore.QString) def deliverInvite(self, handle, channel): msgbox = QtGui.QMessageBox() @@ -2449,6 +2462,11 @@ class PesterWindow(MovingWindow): self.leftChannel.emit("#pesterchum") else: self.joinChannel.emit("#pesterchum") + # nickserv + autoidentify = self.optionmenu.autonickserv.isChecked() + nickservpass = self.optionmenu.nickservpass.text() + self.userprofile.setAutoIdentify(autoidentify) + self.userprofile.setNickServPass(str(nickservpass)) # advanced ## user mode if self.advanced: @@ -2624,6 +2642,7 @@ class PesterWindow(MovingWindow): @QtCore.pyqtSlot(QtCore.QString) def myHandleChanged(self, handle): if self.profile().handle == handle: + self.doAutoIdentify() return else: self.nickCollision(self.profile().handle, handle) diff --git a/profile.py b/profile.py index a271aae..c266330 100644 --- a/profile.py +++ b/profile.py @@ -395,6 +395,17 @@ class userProfile(object): self.userprofile["mentions"] = [] self.mentions = self.userprofile["mentions"] + with open(_datadir+"passwd.js") as fp: + try: + self.passwd = json.load(fp) + except ValueError, e: + self.passwd = {} + self.autoidentify = False + self.nickservpass = "" + if self.chat.handle in self.passwd: + self.autoidentify = self.passwd[self.chat.handle]["auto"] + self.nickservpass = self.passwd[self.chat.handle]["pw"] + def setMood(self, mood): self.chat.mood = mood def setTheme(self, theme): @@ -435,6 +446,18 @@ class userProfile(object): self.save() def getTheme(self): return self.theme + def getAutoIdentify(self): + return self.autoidentify + def setAutoIdentify(self, b): + self.autoidentify = b + self.passwd[self.chat.handle]["auto"] = b + self.saveNickServPass() + def getNickServPass(self): + return self.nickservpass + def setNickServPass(self, pw): + self.nickservpass = pw + self.passwd[self.chat.handle]["pw"] = pw + self.saveNickServPass() def save(self): handle = self.chat.handle if handle[0:12] == "pesterClient": @@ -447,6 +470,13 @@ class userProfile(object): fp = open("%s/%s.js" % (self.profiledir, handle), 'w') fp.write(jsonoutput) fp.close() + def saveNickServPass(self): + try: + jsonoutput = json.dumps(self.passwd, indent=4) + except ValueError, e: + raise e + with open(_datadir+"passwd.js", 'w') as fp: + fp.write(jsonoutput) @staticmethod def newUserProfile(chatprofile): if os.path.exists("%s/%s.js" % (_datadir+"profiles", chatprofile.handle)): From f63d224c6675a634d3581cf431cd7b1ee897b60b Mon Sep 17 00:00:00 2001 From: Kiooeht Date: Sun, 12 Jan 2014 17:49:18 -0800 Subject: [PATCH 12/15] Don't save empty NickServ passwords --- profile.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/profile.py b/profile.py index c266330..13c48ea 100644 --- a/profile.py +++ b/profile.py @@ -450,12 +450,16 @@ class userProfile(object): return self.autoidentify def setAutoIdentify(self, b): self.autoidentify = b + if self.chat.handle not in self.passwd: + self.passwd[self.chat.handle] = {} self.passwd[self.chat.handle]["auto"] = b self.saveNickServPass() def getNickServPass(self): return self.nickservpass def setNickServPass(self, pw): self.nickservpass = pw + if self.chat.handle not in self.passwd: + self.passwd[self.chat.handle] = {} self.passwd[self.chat.handle]["pw"] = pw self.saveNickServPass() def save(self): @@ -471,6 +475,10 @@ class userProfile(object): fp.write(jsonoutput) fp.close() def saveNickServPass(self): + # remove profiles with no passwords + for h,t in self.passwd.items(): + if "auto" not in t or "pw" not in t or t["pw"] == "": + del self.passwd[h] try: jsonoutput = json.dumps(self.passwd, indent=4) except ValueError, e: From 1a2ddcf553086002ef37323130549d3e97d0838f Mon Sep 17 00:00:00 2001 From: Kiooeht Date: Sun, 12 Jan 2014 17:50:01 -0800 Subject: [PATCH 13/15] Auto-join memos --- CHANGELOG.mkdn | 1 + irc.py | 2 ++ menus.py | 37 +++++++++++++++++++++++++++++++++++++ pesterchum.py | 14 ++++++++++++++ profile.py | 10 ++++++++++ 5 files changed, 64 insertions(+) diff --git a/CHANGELOG.mkdn b/CHANGELOG.mkdn index 6ba8856..5f2dce4 100644 --- a/CHANGELOG.mkdn +++ b/CHANGELOG.mkdn @@ -25,6 +25,7 @@ CHANGELOG * Lua quirks * Multi-select memo chooser - [alGore] * Auto-identify with NickServ - Kiooeht [evacipatedBox] +* Auto-join memos - Kiooeht [evacipatedBox] * Bug fixes * Don't require pygame (it's kind of optional, you just don't get sound) - Kiooeht [evacipatedBox] * Allow add chum dialog to open after adding an existing chum - Kiooeht [evacipatedBox] diff --git a/irc.py b/irc.py index 4cec0a5..5d794c6 100644 --- a/irc.py +++ b/irc.py @@ -177,6 +177,8 @@ class PesterIRC(QtCore.QThread): self.setConnectionBroken() self.mainwindow.closeConversations(True) self.mainwindow.doAutoIdentify() + self.mainwindow.autoJoinDone = False + self.mainwindow.doAutoJoins() self.updateMood() @QtCore.pyqtSlot() def updateMood(self): diff --git a/menus.py b/menus.py index 37d3bb7..8e542e1 100644 --- a/menus.py +++ b/menus.py @@ -1029,6 +1029,15 @@ class PesterOptions(QtGui.QDialog): self.nickservpass.setEchoMode(QtGui.QLineEdit.PasswordEchoOnEdit) self.nickservpass.setText(parent.userprofile.getNickServPass()) + self.autojoinlist = QtGui.QListWidget(self) + self.autojoinlist.addItems(parent.userprofile.getAutoJoins()) + self.addAutoJoinBtn = QtGui.QPushButton("Add", self) + self.connect(self.addAutoJoinBtn, QtCore.SIGNAL('clicked()'), + self, QtCore.SLOT('addAutoJoin()')) + self.delAutoJoinBtn = QtGui.QPushButton("Remove", self) + self.connect(self.delAutoJoinBtn, QtCore.SIGNAL('clicked()'), + self, QtCore.SLOT('delAutoJoin()')) + self.tabcheck = QtGui.QCheckBox("Tabbed Conversations", self) if self.config.tabs(): self.tabcheck.setChecked(True) @@ -1383,6 +1392,12 @@ class PesterOptions(QtGui.QDialog): layout_indent.addWidget(self.nickservpass) layout_indent.setContentsMargins(22,0,0,0) layout_connect.addLayout(layout_indent) + layout_connect.addWidget(QtGui.QLabel("Auto-Join Memos:")) + layout_connect.addWidget(self.autojoinlist) + layout_8 = QtGui.QHBoxLayout() + layout_8.addWidget(self.addAutoJoinBtn) + layout_8.addWidget(self.delAutoJoinBtn) + layout_connect.addLayout(layout_8) self.pages.addWidget(widget) # Advanced @@ -1435,6 +1450,28 @@ class PesterOptions(QtGui.QDialog): def autoNickServChange(self, state): self.nickservpass.setEnabled(state != 0) + @QtCore.pyqtSlot() + def addAutoJoin(self, mitem=None): + d = {"label": "Memo:", "inputname": "value" } + if mitem is not None: + d["value"] = str(mitem.text()) + pdict = MultiTextDialog("ENTER MEMO", self, d).getText() + if pdict is None: + return + pdict["value"] = "#" + pdict["value"] + if mitem is None: + items = self.autojoinlist.findItems(pdict["value"], QtCore.Qt.MatchFixedString) + if len(items) == 0: + self.autojoinlist.addItem(pdict["value"]) + else: + mitem.setText(pdict["value"]) + + @QtCore.pyqtSlot() + def delAutoJoin(self): + i = self.autojoinlist.currentRow() + if i >= 0: + self.autojoinlist.takeItem(i) + @QtCore.pyqtSlot(int) def soundChange(self, state): if state == 0: diff --git a/pesterchum.py b/pesterchum.py index c64cefe..f5b7b41 100644 --- a/pesterchum.py +++ b/pesterchum.py @@ -990,6 +990,7 @@ class PesterWindow(MovingWindow): MovingWindow.__init__(self, parent, (QtCore.Qt.CustomizeWindowHint | QtCore.Qt.FramelessWindowHint)) + self.autoJoinDone = False self.app = app self.convos = CaseInsensitiveDict() self.memos = CaseInsensitiveDict() @@ -1714,6 +1715,12 @@ class PesterWindow(MovingWindow): if self.userprofile.getAutoIdentify(): self.sendMessage.emit("identify " + self.userprofile.getNickServPass(), "NickServ") + def doAutoJoins(self): + if not self.autoJoinDone: + self.autoJoinDone = True + for memo in self.userprofile.getAutoJoins(): + self.newMemo(memo, "i") + @QtCore.pyqtSlot() def connected(self): if self.loadingscreen: @@ -1721,6 +1728,7 @@ class PesterWindow(MovingWindow): self.loadingscreen = None self.doAutoIdentify() + self.doAutoJoins() @QtCore.pyqtSlot() def blockSelectedChum(self): @@ -2467,6 +2475,11 @@ class PesterWindow(MovingWindow): nickservpass = self.optionmenu.nickservpass.text() self.userprofile.setAutoIdentify(autoidentify) self.userprofile.setNickServPass(str(nickservpass)) + # auto join memos + autojoins = [] + for i in range(self.optionmenu.autojoinlist.count()): + autojoins.append(str(self.optionmenu.autojoinlist.item(i).text())) + self.userprofile.setAutoJoins(autojoins) # advanced ## user mode if self.advanced: @@ -2643,6 +2656,7 @@ class PesterWindow(MovingWindow): def myHandleChanged(self, handle): if self.profile().handle == handle: self.doAutoIdentify() + self.doAutoJoins() return else: self.nickCollision(self.profile().handle, handle) diff --git a/profile.py b/profile.py index 13c48ea..5e6915b 100644 --- a/profile.py +++ b/profile.py @@ -370,6 +370,7 @@ class userProfile(object): self.mentions = [r"\b(%s)\b" % ("|".join(initials))] else: self.mentions = [] + self.autojoins = [] else: fp = open("%s/%s.js" % (self.profiledir, user)) self.userprofile = json.load(fp) @@ -394,6 +395,9 @@ class userProfile(object): else: self.userprofile["mentions"] = [] self.mentions = self.userprofile["mentions"] + if "autojoins" not in self.userprofile: + self.userprofile["autojoins"] = [] + self.autojoins = self.userprofile["autojoins"] with open(_datadir+"passwd.js") as fp: try: @@ -462,6 +466,12 @@ class userProfile(object): self.passwd[self.chat.handle] = {} self.passwd[self.chat.handle]["pw"] = pw self.saveNickServPass() + def getAutoJoins(self): + return self.autojoins + def setAutoJoins(self, autojoins): + self.autojoins = autojoins + self.userprofile["autojoins"] = self.autojoins + self.save() def save(self): handle = self.chat.handle if handle[0:12] == "pesterClient": From 5310d8624819ba58f51846a93467a27d3b4765cd Mon Sep 17 00:00:00 2001 From: Kiooeht Date: Sat, 18 Jan 2014 01:25:27 -0800 Subject: [PATCH 14/15] Fix not sending PESTERCHUM:BEGIN to anyone --- pesterchum.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pesterchum.py b/pesterchum.py index f5b7b41..d9e5783 100644 --- a/pesterchum.py +++ b/pesterchum.py @@ -1431,6 +1431,8 @@ class PesterWindow(MovingWindow): convoWindow.quirksOff.setChecked(True) if unicode(chum.handle).upper() in CUSTOMBOTS: self.newConvoStarted.emit(QtCore.QString(chum.handle), initiated) + else: + self.newConvoStarted.emit(QtCore.QString(chum.handle), initiated) convoWindow.show() def createTabWindow(self): From 186aab81638202e8dab37761895adeb341a1c437 Mon Sep 17 00:00:00 2001 From: Kiooeht Date: Mon, 17 Mar 2014 23:07:26 -0700 Subject: [PATCH 15/15] Fix for passwd.js not existing --- profile.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/profile.py b/profile.py index 5e6915b..029f9f5 100644 --- a/profile.py +++ b/profile.py @@ -399,11 +399,11 @@ class userProfile(object): self.userprofile["autojoins"] = [] self.autojoins = self.userprofile["autojoins"] - with open(_datadir+"passwd.js") as fp: - try: + try: + with open(_datadir+"passwd.js") as fp: self.passwd = json.load(fp) - except ValueError, e: - self.passwd = {} + except Exception, e: + self.passwd = {} self.autoidentify = False self.nickservpass = "" if self.chat.handle in self.passwd: