Revert "python 2 to 3 first shot"

This reverts commit 7bc57b8b7d.

Practically speaking, this reverts the Python 3 changes, since they're
broken.
This commit is contained in:
karxi 2016-11-13 01:12:58 -05:00
parent b78e14dc7e
commit 5d839aae47
30 changed files with 1737 additions and 3532 deletions

View file

@ -1,5 +1,5 @@
from PyQt5 import QtGui, QtCore, QtWidgets from PyQt5 import QtGui, QtCore, QtWidgets
import urllib.request, urllib.parse, urllib.error import urllib
import ostools import ostools
import version import version
@ -51,13 +51,13 @@ class BugReporter(QtWidgets.QDialog):
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
def sendReport(self): def sendReport(self):
name = str(self.mainwindow.profile().handle) name = unicode(self.mainwindow.profile().handle)
bestname = str(self.name.text()) bestname = unicode(self.name.text())
os = ostools.osVer() os = ostools.osVer()
full = ostools.platform.platform() full = ostools.platform.platform()
python = ostools.platform.python_version() python = ostools.platform.python_version()
qt = QtCore.qVersion() qt = QtCore.qVersion()
msg = str(self.textarea.toPlainText()) msg = unicode(self.textarea.toPlainText())
if len(bestname) <= 0 or len(msg) <= 0: if len(bestname) <= 0 or len(msg) <= 0:
msgbox = QtWidgets.QMessageBox() msgbox = QtWidgets.QMessageBox()
@ -68,13 +68,13 @@ class BugReporter(QtWidgets.QDialog):
return return
QtWidgets.QDialog.accept(self) QtWidgets.QDialog.accept(self)
data = urllib.parse.urlencode({"name":name, "version": version._pcVersion, "bestname":bestname, "os":os, "platform":full, "python":python, "qt":qt, "msg":msg}) data = urllib.urlencode({"name":name, "version": version._pcVersion, "bestname":bestname, "os":os, "platform":full, "python":python, "qt":qt, "msg":msg})
print("Sending...") print "Sending..."
f = urllib.request.urlopen("http://distantsphere.com/pc/reporter.php", data) f = urllib.urlopen("http://distantsphere.com/pc/reporter.php", data)
text = f.read() text = f.read()
print(text) print text
if text == "success!": if text == "success!":
print("Sent!") print "Sent!"
else: else:
print("Problems ):") print "Problems ):"

View file

@ -1,7 +1,7 @@
from string import Template from string import Template
import re import re
import platform import platform
import http.client, urllib.request, urllib.parse, urllib.error import httplib, urllib
from time import strftime from time import strftime
from copy import copy from copy import copy
from datetime import datetime, timedelta from datetime import datetime, timedelta
@ -77,7 +77,7 @@ class PesterTabWindow(QtWidgets.QFrame):
mods = event.modifiers() mods = event.modifiers()
if ((mods & QtCore.Qt.ControlModifier) and if ((mods & QtCore.Qt.ControlModifier) and
keypress == QtCore.Qt.Key_Tab): keypress == QtCore.Qt.Key_Tab):
handles = list(self.convos.keys()) handles = self.convos.keys()
waiting = self.mainwindow.waitingMessages.waitingHandles() waiting = self.mainwindow.waitingMessages.waitingHandles()
waitinghandles = list(set(handles) & set(waiting)) waitinghandles = list(set(handles) & set(waiting))
if len(waitinghandles) > 0: if len(waitinghandles) > 0:
@ -114,7 +114,7 @@ class PesterTabWindow(QtWidgets.QFrame):
i = self.tabs.tabAt(self.mapFromGlobal(QtGui.QCursor.pos())) i = self.tabs.tabAt(self.mapFromGlobal(QtGui.QCursor.pos()))
if i == -1: if i == -1:
i = self.tabs.currentIndex() i = self.tabs.currentIndex()
handle = str(self.tabs.tabText(i)) handle = unicode(self.tabs.tabText(i))
self.clearNewMessage(handle) self.clearNewMessage(handle)
def convoHasFocus(self, handle): def convoHasFocus(self, handle):
i = self.tabIndices[handle] i = self.tabIndices[handle]
@ -151,19 +151,19 @@ class PesterTabWindow(QtWidgets.QFrame):
self.tabs.setTabIcon(tabi, c.icon()) self.tabs.setTabIcon(tabi, c.icon())
currenttabi = self.tabs.currentIndex() currenttabi = self.tabs.currentIndex()
if currenttabi >= 0: if currenttabi >= 0:
currentHandle = str(self.tabs.tabText(self.tabs.currentIndex())) currentHandle = unicode(self.tabs.tabText(self.tabs.currentIndex()))
self.setWindowIcon(self.convos[currentHandle].icon()) self.setWindowIcon(self.convos[currentHandle].icon())
self.defaultTabTextColor = self.getTabTextColor() self.defaultTabTextColor = self.getTabTextColor()
@QtCore.pyqtSlot(int) @QtCore.pyqtSlot(int)
def tabClose(self, i): def tabClose(self, i):
handle = str(self.tabs.tabText(i)) handle = unicode(self.tabs.tabText(i))
self.mainwindow.waitingMessages.messageAnswered(handle) self.mainwindow.waitingMessages.messageAnswered(handle)
convo = self.convos[handle] convo = self.convos[handle]
del self.convos[handle] del self.convos[handle]
del self.tabIndices[handle] del self.tabIndices[handle]
self.tabs.removeTab(i) self.tabs.removeTab(i)
for (h, j) in self.tabIndices.items(): for (h, j) in self.tabIndices.iteritems():
if j > i: if j > i:
self.tabIndices[h] = j-1 self.tabIndices[h] = j-1
self.layout.removeWidget(convo) self.layout.removeWidget(convo)
@ -173,7 +173,7 @@ class PesterTabWindow(QtWidgets.QFrame):
return return
if self.currentConvo == convo: if self.currentConvo == convo:
currenti = self.tabs.currentIndex() currenti = self.tabs.currentIndex()
currenth = str(self.tabs.tabText(currenti)) currenth = unicode(self.tabs.tabText(currenti))
self.currentConvo = self.convos[currenth] self.currentConvo = self.convos[currenth]
self.currentConvo.raiseChat() self.currentConvo.raiseChat()
@ -184,7 +184,7 @@ class PesterTabWindow(QtWidgets.QFrame):
if self.changedTab: if self.changedTab:
self.changedTab = False self.changedTab = False
return return
handle = str(self.tabs.tabText(i)) handle = unicode(self.tabs.tabText(i))
convo = self.convos[handle] convo = self.convos[handle]
if self.currentConvo: if self.currentConvo:
self.layout.removeWidget(self.currentConvo) self.layout.removeWidget(self.currentConvo)
@ -219,7 +219,7 @@ class PesterMovie(QtGui.QMovie):
if text.mainwindow.config.animations(): if text.mainwindow.config.animations():
movie = self movie = self
url = text.urls[movie].toString() url = text.urls[movie].toString()
html = str(text.toHtml()) html = unicode(text.toHtml())
if html.find(url) != -1: if html.find(url) != -1:
if text.hasTabs: if text.hasTabs:
i = text.tabobject.tabIndices[text.parent().title()] i = text.tabobject.tabIndices[text.parent().title()]
@ -265,13 +265,13 @@ class PesterText(QtWidgets.QTextEdit):
def animateChanged(self, animate): def animateChanged(self, animate):
if animate: if animate:
for m in self.urls: for m in self.urls:
html = str(self.toHtml()) html = unicode(self.toHtml())
if html.find(self.urls[m].toString()) != -1: if html.find(self.urls[m].toString()) != -1:
if m.frameCount() > 1: if m.frameCount() > 1:
m.start() m.start()
else: else:
for m in self.urls: for m in self.urls:
html = str(self.toHtml()) html = unicode(self.toHtml())
if html.find(self.urls[m].toString()) != -1: if html.find(self.urls[m].toString()) != -1:
if m.frameCount() > 1: if m.frameCount() > 1:
m.stop() m.stop()
@ -280,7 +280,7 @@ class PesterText(QtWidgets.QTextEdit):
def textReady(self, ready): def textReady(self, ready):
self.textSelected = ready self.textSelected = ready
def initTheme(self, theme): def initTheme(self, theme):
if "convo/scrollbar" in theme: if theme.has_key("convo/scrollbar"):
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: else:
self.setStyleSheet("QTextEdit { %s }" % (theme["convo/textarea/style"])) self.setStyleSheet("QTextEdit { %s }" % (theme["convo/textarea/style"]))
@ -393,7 +393,7 @@ class PesterText(QtWidgets.QTextEdit):
if url[0] == "#" and url != "#pesterchum": if url[0] == "#" and url != "#pesterchum":
self.parent().mainwindow.showMemos(url[1:]) self.parent().mainwindow.showMemos(url[1:])
elif url[0] == "@": elif url[0] == "@":
handle = str(url[1:]) handle = unicode(url[1:])
self.parent().mainwindow.newConversation(handle) self.parent().mainwindow.newConversation(handle)
else: else:
if event.modifiers() == QtCore.Qt.ControlModifier: if event.modifiers() == QtCore.Qt.ControlModifier:
@ -435,12 +435,12 @@ class PesterText(QtWidgets.QTextEdit):
layout.addWidget(cancelbutton) layout.addWidget(cancelbutton)
self.sending.setLayout(layout) self.sending.setLayout(layout)
self.sending.show() self.sending.show()
params = urllib.parse.urlencode({'quote': logdata, 'do': "add"}) params = urllib.urlencode({'quote': logdata, 'do': "add"})
headers = {"Content-type": "application/x-www-form-urlencoded", headers = {"Content-type": "application/x-www-form-urlencoded",
"Accept": "text/plain"} "Accept": "text/plain"}
try: try:
pass pass
hconn = http.client.HTTPConnection('qdb.pesterchum.net', 80, hconn = httplib.HTTPConnection('qdb.pesterchum.net', 80,
timeout=15) timeout=15)
hconn.request("POST", "/index.php", params, headers) hconn.request("POST", "/index.php", params, headers)
response = hconn.getresponse() response = hconn.getresponse()
@ -449,7 +449,7 @@ class PesterText(QtWidgets.QTextEdit):
else: else:
self.sending.sendinglabel.setText("F41L3D: %s %s" % (response.status, response.reason)) self.sending.sendinglabel.setText("F41L3D: %s %s" % (response.status, response.reason))
hconn.close() hconn.close()
except Exception as e: except Exception, e:
self.sending.sendinglabel.setText("F41L3D: %s" % (e)) self.sending.sendinglabel.setText("F41L3D: %s" % (e))
del self.sending del self.sending
@ -465,7 +465,7 @@ class PesterInput(QtWidgets.QLineEdit):
QtWidgets.QLineEdit.focusInEvent(self, event) QtWidgets.QLineEdit.focusInEvent(self, event)
def keyPressEvent(self, event): def keyPressEvent(self, event):
if event.key() == QtCore.Qt.Key_Up: if event.key() == QtCore.Qt.Key_Up:
text = str(self.text()) text = unicode(self.text())
next = self.parent().history.next(text) next = self.parent().history.next(text)
if next is not None: if next is not None:
self.setText(next) self.setText(next)
@ -596,7 +596,7 @@ class PesterConvo(QtWidgets.QFrame):
def updateColor(self, color): def updateColor(self, color):
self.chum.color = color self.chum.color = color
def addMessage(self, msg, me=True): def addMessage(self, msg, me=True):
if type(msg) is str: if type(msg) in [str, unicode]:
lexmsg = lexMessage(msg) lexmsg = lexMessage(msg)
else: else:
lexmsg = msg lexmsg = msg
@ -696,7 +696,7 @@ class PesterConvo(QtWidgets.QFrame):
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
def sentMessage(self): def sentMessage(self):
text = str(self.textInput.text()) text = unicode(self.textInput.text())
if text == "" or text[0:11] == "PESTERCHUM:": if text == "" or text[0:11] == "PESTERCHUM:":
return return
oocDetected = oocre.match(text.strip()) oocDetected = oocre.match(text.strip())

View file

@ -111,7 +111,7 @@ class pesterQuirks(object):
newlist = [] newlist = []
for (i, o) in enumerate(lexed): for (i, o) in enumerate(lexed):
if type(o) not in [str]: if type(o) not in [str, unicode]:
if i == 0: if i == 0:
string = " " string = " "
for p in prefix: for p in prefix:
@ -135,7 +135,7 @@ class pesterQuirks(object):
final = [] final = []
for n in newlist: for n in newlist:
if type(n) in [str]: if type(n) in [str, unicode]:
final.extend(lexMessage(n)) final.extend(lexMessage(n))
else: else:
final.append(n) final.append(n)
@ -191,9 +191,9 @@ class PesterProfile(object):
def plaindict(self): def plaindict(self):
return (self.handle, {"handle": self.handle, return (self.handle, {"handle": self.handle,
"mood": self.mood.name(), "mood": self.mood.name(),
"color": str(self.color.name()), "color": unicode(self.color.name()),
"group": str(self.group), "group": unicode(self.group),
"notes": str(self.notes)}) "notes": unicode(self.notes)})
def blocked(self, config): def blocked(self, config):
return self.handle in config.getBlocklist() return self.handle in config.getBlocklist()
@ -238,7 +238,7 @@ class PesterProfile(object):
(opchum.colorhtml(), opinit, self.colorhtml(), ", ".join(initials)) (opchum.colorhtml(), opinit, self.colorhtml(), ", ".join(initials))
else: else:
return "<c=%s>%s</c> banned <c=%s>%s</c> from responding to memo: <c=black>[%s]</c>." % \ return "<c=%s>%s</c> banned <c=%s>%s</c> from responding to memo: <c=black>[%s]</c>." % \
(opchum.colorhtml(), opinit, self.colorhtml(), ", ".join(initials), str(reason)) (opchum.colorhtml(), opinit, self.colorhtml(), ", ".join(initials), unicode(reason))
else: else:
initials = timeGrammar.pcf+self.initials()+timeGrammar.number initials = timeGrammar.pcf+self.initials()+timeGrammar.number
if opchum.handle == reason: if opchum.handle == reason:
@ -246,7 +246,7 @@ class PesterProfile(object):
(opchum.colorhtml(), opinit, self.colorhtml(), initials) (opchum.colorhtml(), opinit, self.colorhtml(), initials)
else: else:
return "<c=%s>%s</c> banned <c=%s>%s</c> from responding to memo: <c=black>[%s]</c>." % \ return "<c=%s>%s</c> banned <c=%s>%s</c> from responding to memo: <c=black>[%s]</c>." % \
(opchum.colorhtml(), opinit, self.colorhtml(), initials, str(reason)) (opchum.colorhtml(), opinit, self.colorhtml(), initials, unicode(reason))
def memopermabanmsg(self, opchum, opgrammar, syscolor, timeGrammar): def memopermabanmsg(self, opchum, opgrammar, syscolor, timeGrammar):
initials = timeGrammar.pcf+self.initials()+timeGrammar.number initials = timeGrammar.pcf+self.initials()+timeGrammar.number
opinit = opgrammar.pcf+opchum.initials()+opgrammar.number opinit = opgrammar.pcf+opchum.initials()+opgrammar.number

View file

@ -8,8 +8,6 @@ class mysteryTime(timedelta):
return (type(other) is mysteryTime) return (type(other) is mysteryTime)
def __neq__(self, other): def __neq__(self, other):
return (type(other) is not mysteryTime) return (type(other) is not mysteryTime)
def __hash__(self):
return 0
class CaseInsensitiveDict(dict): class CaseInsensitiveDict(dict):
def __setitem__(self, key, value): def __setitem__(self, key, value):
@ -19,7 +17,7 @@ class CaseInsensitiveDict(dict):
def __contains__(self, key): def __contains__(self, key):
return super(CaseInsensitiveDict, self).__contains__(key.lower()) return super(CaseInsensitiveDict, self).__contains__(key.lower())
def has_key(self, key): def has_key(self, key):
return key.lower() in super(CaseInsensitiveDict, self) return super(CaseInsensitiveDict, self).has_key(key.lower())
def __delitem__(self, key): def __delitem__(self, key):
super(CaseInsensitiveDict, self).__delitem__(key.lower()) super(CaseInsensitiveDict, self).__delitem__(key.lower())
@ -30,7 +28,7 @@ class PesterList(list):
class PesterIcon(QtGui.QIcon): class PesterIcon(QtGui.QIcon):
def __init__(self, *x): def __init__(self, *x):
QtGui.QIcon.__init__(self, x[0]) QtGui.QIcon.__init__(self, x[0])
if type(x[0]) in [str]: if type(x[0]) in [str, unicode]:
self.icon_pixmap = QtGui.QPixmap(x[0]) self.icon_pixmap = QtGui.QPixmap(x[0])
else: else:
self.icon_pixmap = None self.icon_pixmap = None
@ -98,8 +96,8 @@ class MultiTextDialog(QtWidgets.QDialog):
r = self.exec_() r = self.exec_()
if r == QtWidgets.QDialog.Accepted: if r == QtWidgets.QDialog.Accepted:
retval = {} retval = {}
for (name, widget) in self.inputs.items(): for (name, widget) in self.inputs.iteritems():
retval[name] = str(widget.text()) retval[name] = unicode(widget.text())
return retval return retval
else: else:
return None return None
@ -127,7 +125,7 @@ class MovingWindow(QtWidgets.QFrame):
class NoneSound(object): class NoneSound(object):
def play(self): pass def play(self): pass
def setVolume(self, v): pass def set_volume(self, v): pass
class WMButton(QtWidgets.QPushButton): class WMButton(QtWidgets.QPushButton):
def __init__(self, icon, parent=None): def __init__(self, icon, parent=None):

89
irc.py
View file

@ -38,7 +38,7 @@ class PesterIRC(QtCore.QThread):
def run(self): def run(self):
try: try:
self.IRCConnect() self.IRCConnect()
except socket.error as se: except socket.error, se:
self.stopIRC = se self.stopIRC = se
return return
while 1: while 1:
@ -46,12 +46,12 @@ class PesterIRC(QtCore.QThread):
try: try:
logging.debug("updateIRC()") logging.debug("updateIRC()")
res = self.updateIRC() res = self.updateIRC()
except socket.timeout as se: except socket.timeout, se:
logging.debug("timeout in thread %s" % (self)) logging.debug("timeout in thread %s" % (self))
self.cli.close() self.cli.close()
self.stopIRC = se self.stopIRC = se
return return
except socket.error as se: except socket.error, se:
if self.registeredIRC: if self.registeredIRC:
self.stopIRC = None self.stopIRC = None
else: else:
@ -73,13 +73,13 @@ class PesterIRC(QtCore.QThread):
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
def updateIRC(self): def updateIRC(self):
try: try:
res = next(self.conn) res = self.conn.next()
except socket.timeout as se: except socket.timeout, se:
if self.registeredIRC: if self.registeredIRC:
return True return True
else: else:
raise se raise se
except socket.error as se: except socket.error, se:
raise se raise se
except StopIteration: except StopIteration:
self.conn = self.cli.conn() self.conn = self.cli.conn()
@ -99,16 +99,16 @@ class PesterIRC(QtCore.QThread):
self.cli.command_handler.getMood(*chums) self.cli.command_handler.getMood(*chums)
@QtCore.pyqtSlot('QString', 'QString') @QtCore.pyqtSlot('QString', 'QString')
def sendNotice(self, text, handle): def sendNotice(self, text, handle):
h = str(handle) h = unicode(handle)
t = str(text) t = unicode(text)
try: try:
helpers.notice(self.cli, h, t) helpers.notice(self.cli, h, t)
except socket.error: except socket.error:
self.setConnectionBroken() self.setConnectionBroken()
@QtCore.pyqtSlot('QString', 'QString') @QtCore.pyqtSlot('QString', 'QString')
def sendMessage(self, text, handle): def sendMessage(self, text, handle):
h = str(handle) h = unicode(handle)
textl = [str(text)] textl = [unicode(text)]
def splittext(l): def splittext(l):
if len(l[0]) > 450: if len(l[0]) > 450:
space = l[0].rfind(" ", 0,430) space = l[0].rfind(" ", 0,430)
@ -153,7 +153,7 @@ class PesterIRC(QtCore.QThread):
self.setConnectionBroken() self.setConnectionBroken()
@QtCore.pyqtSlot('QString', bool) @QtCore.pyqtSlot('QString', bool)
def startConvo(self, handle, initiated): def startConvo(self, handle, initiated):
h = str(handle) h = unicode(handle)
try: try:
if initiated: if initiated:
helpers.msg(self.cli, h, "PESTERCHUM:BEGIN") helpers.msg(self.cli, h, "PESTERCHUM:BEGIN")
@ -162,7 +162,7 @@ class PesterIRC(QtCore.QThread):
self.setConnectionBroken() self.setConnectionBroken()
@QtCore.pyqtSlot('QString') @QtCore.pyqtSlot('QString')
def endConvo(self, handle): def endConvo(self, handle):
h = str(handle) h = unicode(handle)
try: try:
helpers.msg(self.cli, h, "PESTERCHUM:CEASE") helpers.msg(self.cli, h, "PESTERCHUM:CEASE")
except socket.error: except socket.error:
@ -197,21 +197,21 @@ class PesterIRC(QtCore.QThread):
self.setConnectionBroken() self.setConnectionBroken()
@QtCore.pyqtSlot('QString') @QtCore.pyqtSlot('QString')
def blockedChum(self, handle): def blockedChum(self, handle):
h = str(handle) h = unicode(handle)
try: try:
helpers.msg(self.cli, h, "PESTERCHUM:BLOCK") helpers.msg(self.cli, h, "PESTERCHUM:BLOCK")
except socket.error: except socket.error:
self.setConnectionBroken() self.setConnectionBroken()
@QtCore.pyqtSlot('QString') @QtCore.pyqtSlot('QString')
def unblockedChum(self, handle): def unblockedChum(self, handle):
h = str(handle) h = unicode(handle)
try: try:
helpers.msg(self.cli, h, "PESTERCHUM:UNBLOCK") helpers.msg(self.cli, h, "PESTERCHUM:UNBLOCK")
except socket.error: except socket.error:
self.setConnectionBroken() self.setConnectionBroken()
@QtCore.pyqtSlot('QString') @QtCore.pyqtSlot('QString')
def requestNames(self, channel): def requestNames(self, channel):
c = str(channel) c = unicode(channel)
try: try:
helpers.names(self.cli, c) helpers.names(self.cli, c)
except socket.error: except socket.error:
@ -224,7 +224,7 @@ class PesterIRC(QtCore.QThread):
self.setConnectionBroken() self.setConnectionBroken()
@QtCore.pyqtSlot('QString') @QtCore.pyqtSlot('QString')
def joinChannel(self, channel): def joinChannel(self, channel):
c = str(channel) c = unicode(channel)
try: try:
helpers.join(self.cli, c) helpers.join(self.cli, c)
helpers.mode(self.cli, c, "", None) helpers.mode(self.cli, c, "", None)
@ -232,7 +232,7 @@ class PesterIRC(QtCore.QThread):
self.setConnectionBroken() self.setConnectionBroken()
@QtCore.pyqtSlot('QString') @QtCore.pyqtSlot('QString')
def leftChannel(self, channel): def leftChannel(self, channel):
c = str(channel) c = unicode(channel)
try: try:
helpers.part(self.cli, c) helpers.part(self.cli, c)
self.cli.command_handler.joined = False self.cli.command_handler.joined = False
@ -241,13 +241,13 @@ class PesterIRC(QtCore.QThread):
@QtCore.pyqtSlot('QString', 'QString') @QtCore.pyqtSlot('QString', 'QString')
def kickUser(self, handle, channel): def kickUser(self, handle, channel):
l = handle.split(":") l = handle.split(":")
c = str(channel) c = unicode(channel)
h = str(l[0]) h = unicode(l[0])
if len(l) > 1: if len(l) > 1:
reason = str(l[1]) reason = unicode(l[1])
if len(l) > 2: if len(l) > 2:
for x in l[2:]: for x in l[2:]:
reason += str(":") + str(x) reason += unicode(":") + unicode(x)
else: else:
reason = "" reason = ""
try: try:
@ -256,9 +256,9 @@ class PesterIRC(QtCore.QThread):
self.setConnectionBroken() self.setConnectionBroken()
@QtCore.pyqtSlot('QString', 'QString', 'QString') @QtCore.pyqtSlot('QString', 'QString', 'QString')
def setChannelMode(self, channel, mode, command): def setChannelMode(self, channel, mode, command):
c = str(channel) c = unicode(channel)
m = str(mode) m = unicode(mode)
cmd = str(command) cmd = unicode(command)
if cmd == "": if cmd == "":
cmd = None cmd = None
try: try:
@ -267,15 +267,15 @@ class PesterIRC(QtCore.QThread):
self.setConnectionBroken() self.setConnectionBroken()
@QtCore.pyqtSlot('QString') @QtCore.pyqtSlot('QString')
def channelNames(self, channel): def channelNames(self, channel):
c = str(channel) c = unicode(channel)
try: try:
helpers.names(self.cli, c) helpers.names(self.cli, c)
except socket.error: except socket.error:
self.setConnectionBroken() self.setConnectionBroken()
@QtCore.pyqtSlot('QString', 'QString') @QtCore.pyqtSlot('QString', 'QString')
def inviteChum(self, handle, channel): def inviteChum(self, handle, channel):
h = str(handle) h = unicode(handle)
c = str(channel) c = unicode(channel)
try: try:
helpers.invite(self.cli, h, c) helpers.invite(self.cli, h, c)
except socket.error: except socket.error:
@ -300,8 +300,8 @@ class PesterIRC(QtCore.QThread):
@QtCore.pyqtSlot('QString', 'QString') @QtCore.pyqtSlot('QString', 'QString')
def killSomeQuirks(self, channel, handle): def killSomeQuirks(self, channel, handle):
c = str(channel) c = unicode(channel)
h = str(handle) h = unicode(handle)
try: try:
helpers.ctcp(self.cli, c, "NOQUIRKS", h) helpers.ctcp(self.cli, c, "NOQUIRKS", h)
except socket.error: except socket.error:
@ -333,8 +333,6 @@ class PesterHandler(DefaultCommandHandler):
msg = msg.decode('utf-8') msg = msg.decode('utf-8')
except UnicodeDecodeError: except UnicodeDecodeError:
msg = msg.decode('iso-8859-1', 'ignore') msg = msg.decode('iso-8859-1', 'ignore')
nick = nick.decode('utf-8')
chan = chan.decode('utf-8')
handle = nick[0:nick.find("!")] handle = nick[0:nick.find("!")]
logging.info("---> recv \"NOTICE %s :%s\"" % (handle, msg)) logging.info("---> recv \"NOTICE %s :%s\"" % (handle, msg))
if handle == "ChanServ" and chan == self.parent.mainwindow.profile().handle and msg[0:2] == "[#": if handle == "ChanServ" and chan == self.parent.mainwindow.profile().handle and msg[0:2] == "[#":
@ -346,8 +344,6 @@ class PesterHandler(DefaultCommandHandler):
msg = msg.decode('utf-8') msg = msg.decode('utf-8')
except UnicodeDecodeError: except UnicodeDecodeError:
msg = msg.decode('iso-8859-1', 'ignore') msg = msg.decode('iso-8859-1', 'ignore')
nick = nick.decode('utf-8')
chan = chan.decode('utf-8')
# display msg, do other stuff # display msg, do other stuff
if len(msg) == 0: if len(msg) == 0:
return return
@ -410,11 +406,8 @@ class PesterHandler(DefaultCommandHandler):
def nicknameinuse(self, server, cmd, nick, msg): 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) helpers.nick(self.client, newnick)
nick = nick.decode('utf-8')
self.parent.nickCollision.emit(nick, newnick) self.parent.nickCollision.emit(nick, newnick)
def quit(self, nick, reason): def quit(self, nick, reason):
nick = nick.decode('utf-8')
reason = reason.decode('utf-8')
handle = nick[0:nick.find("!")] handle = nick[0:nick.find("!")]
logging.info("---> recv \"QUIT %s: %s\"" % (handle, reason)) logging.info("---> recv \"QUIT %s: %s\"" % (handle, reason))
if handle == self.parent.mainwindow.randhandler.randNick: if handle == self.parent.mainwindow.randhandler.randNick:
@ -427,22 +420,17 @@ class PesterHandler(DefaultCommandHandler):
self.parent.userPresentUpdate.emit(handle, "", "quit") self.parent.userPresentUpdate.emit(handle, "", "quit")
self.parent.moodUpdated.emit(handle, Mood("offline")) self.parent.moodUpdated.emit(handle, Mood("offline"))
def kick(self, opnick, channel, handle, reason): def kick(self, opnick, channel, handle, reason):
opnick = opnick.decode('utf-8')
op = opnick[0:opnick.find("!")] op = opnick[0:opnick.find("!")]
self.parent.userPresentUpdate.emit(handle, channel, "kick:%s:%s" % (op, reason)) self.parent.userPresentUpdate.emit(handle, channel, "kick:%s:%s" % (op, reason))
# ok i shouldnt be overloading that but am lazy # ok i shouldnt be overloading that but am lazy
def part(self, nick, channel, reason="nanchos"): def part(self, nick, channel, reason="nanchos"):
nick = nick.decode('utf-8')
channel = channel.decode('utf-8')
handle = nick[0:nick.find("!")] handle = nick[0:nick.find("!")]
logging.info("---> recv \"PART %s: %s\"" % (handle, channel)) logging.info("---> recv \"PART %s: %s\"" % (handle, channel))
self.parent.userPresentUpdate.emit(handle, channel, "left") self.parent.userPresentUpdate.emit(handle, channel, "left")
if channel == "#pesterchum": if channel == "#pesterchum":
self.parent.moodUpdated.emit(handle, Mood("offline")) self.parent.moodUpdated.emit(handle, Mood("offline"))
def join(self, nick, channel): def join(self, nick, channel):
nick = nick.decode('utf-8')
handle = nick[0:nick.find("!")] handle = nick[0:nick.find("!")]
channel = channel.decode('utf-8')
logging.info("---> recv \"JOIN %s: %s\"" % (handle, channel)) logging.info("---> recv \"JOIN %s: %s\"" % (handle, channel))
self.parent.userPresentUpdate.emit(handle, channel, "join") self.parent.userPresentUpdate.emit(handle, channel, "join")
if channel == "#pesterchum": if channel == "#pesterchum":
@ -450,9 +438,6 @@ class PesterHandler(DefaultCommandHandler):
self.parent.mainwindow.randhandler.setRunning(True) self.parent.mainwindow.randhandler.setRunning(True)
self.parent.moodUpdated.emit(handle, Mood("chummy")) self.parent.moodUpdated.emit(handle, Mood("chummy"))
def mode(self, op, channel, mode, *handles): def mode(self, op, channel, mode, *handles):
op = op.decode('utf-8')
channel = channel.decode('utf-8')
mode = mode.decode('utf-8')
if len(handles) <= 0: handles = [""] if len(handles) <= 0: handles = [""]
opnick = op[0:op.find("!")] opnick = op[0:op.find("!")]
if op == channel or channel == self.parent.mainwindow.profile().handle: if op == channel or channel == self.parent.mainwindow.profile().handle:
@ -482,8 +467,6 @@ class PesterHandler(DefaultCommandHandler):
except IndexError: except IndexError:
self.parent.userPresentUpdate.emit("", channel, m+":%s" % (op)) self.parent.userPresentUpdate.emit("", channel, m+":%s" % (op))
def nick(self, oldnick, newnick): def nick(self, oldnick, newnick):
oldnick = oldnick.decode('utf-8')
newnick = newnick.decode('utf-8')
oldhandle = oldnick[0:oldnick.find("!")] oldhandle = oldnick[0:oldnick.find("!")]
if oldhandle == self.mainwindow.profile().handle: if oldhandle == self.mainwindow.profile().handle:
self.parent.myHandleChanged.emit(newnick) self.parent.myHandleChanged.emit(newnick)
@ -497,8 +480,6 @@ class PesterHandler(DefaultCommandHandler):
elif newnick == self.parent.mainwindow.randhandler.randNick: 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): def namreply(self, server, nick, op, channel, names):
channel = channel.decode('utf-8')
names = names.decode('utf-8')
namelist = names.split(" ") namelist = names.split(" ")
logging.info("---> recv \"NAMES %s: %d names\"" % (channel, len(namelist))) logging.info("---> recv \"NAMES %s: %d names\"" % (channel, len(namelist)))
if not hasattr(self, 'channelnames'): if not hasattr(self, 'channelnames'):
@ -507,7 +488,6 @@ class PesterHandler(DefaultCommandHandler):
self.channelnames[channel] = [] self.channelnames[channel] = []
self.channelnames[channel].extend(namelist) self.channelnames[channel].extend(namelist)
def endofnames(self, server, nick, channel, msg): def endofnames(self, server, nick, channel, msg):
channel = channel.decode('utf-8')
namelist = self.channelnames[channel] namelist = self.channelnames[channel]
pl = PesterList(namelist) pl = PesterList(namelist)
del self.channelnames[channel] del self.channelnames[channel]
@ -525,11 +505,10 @@ class PesterHandler(DefaultCommandHandler):
def liststart(self, server, handle, *info): def liststart(self, server, handle, *info):
self.channel_list = [] self.channel_list = []
info = [i.decode('utf-8') for i in info] info = list(info)
self.channel_field = info.index("Channel") # dunno if this is protocol self.channel_field = info.index("Channel") # dunno if this is protocol
logging.info("---> recv \"CHANNELS: %s " % (self.channel_field)) logging.info("---> recv \"CHANNELS: %s " % (self.channel_field))
def list(self, server, handle, *info): def list(self, server, handle, *info):
info = [i.decode('utf-8') for i in info]
channel = info[self.channel_field] channel = info[self.channel_field]
usercount = info[1] usercount = info[1]
if channel not in self.channel_list and channel != "#pesterchum": if channel not in self.channel_list and channel != "#pesterchum":
@ -542,29 +521,21 @@ class PesterHandler(DefaultCommandHandler):
self.channel_list = [] self.channel_list = []
def umodeis(self, server, handle, modes): def umodeis(self, server, handle, modes):
modes = modes.decode('utf-8')
self.parent.mainwindow.modes = modes self.parent.mainwindow.modes = modes
def invite(self, sender, you, channel): def invite(self, sender, you, channel):
sender = sender.decode('utf-8')
handle = sender.split('!')[0] handle = sender.split('!')[0]
self.parent.inviteReceived.emit(handle, channel) self.parent.inviteReceived.emit(handle, channel)
def inviteonlychan(self, server, handle, channel, msg): def inviteonlychan(self, server, handle, channel, msg):
channel = channel.decode('utf-8')
self.parent.chanInviteOnly.emit(channel) self.parent.chanInviteOnly.emit(channel)
def channelmodeis(self, server, handle, channel, modes): def channelmodeis(self, server, handle, channel, modes):
modes = modes.decode('utf-8')
channel = channel.decode('utf-8')
self.parent.modesUpdated.emit(channel, modes) self.parent.modesUpdated.emit(channel, modes)
def cannotsendtochan(self, server, handle, channel, msg): def cannotsendtochan(self, server, handle, channel, msg):
msg = msg.decode('utf-8')
channel = channel.decode('utf-8')
self.parent.cannotSendToChan.emit(channel, msg) self.parent.cannotSendToChan.emit(channel, msg)
def toomanypeeps(self, *stuff): def toomanypeeps(self, *stuff):
self.parent.tooManyPeeps.emit() self.parent.tooManyPeeps.emit()
def ping(self, prefix, server): def ping(self, prefix, server):
self.parent.mainwindow.lastping = int(time()) self.parent.mainwindow.lastping = int(time())
server = server.decode('utf-8')
self.client.send('PONG', server) self.client.send('PONG', server)
def getMood(self, *chums): def getMood(self, *chums):

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,7 @@
""" """
Adam Hupp (adam@hupp.org)
http://github.com/ahupp/python-magic
magic is a wrapper around the libmagic file identification library. magic is a wrapper around the libmagic file identification library.
See README for more information. See README for more information.
@ -17,12 +20,9 @@ Usage:
""" """
import sys
import glob
import os.path import os.path
import ctypes import ctypes
import ctypes.util import ctypes.util
import threading
from ctypes import c_char_p, c_int, c_size_t, c_void_p from ctypes import c_char_p, c_int, c_size_t, c_void_p
@ -34,112 +34,74 @@ class Magic:
""" """
def __init__(self, mime=False, magic_file=None, mime_encoding=False, def __init__(self, mime=False, magic_file=None, mime_encoding=False):
keep_going=False):
""" """
Create a new libmagic wrapper. Create a new libmagic wrapper.
mime - if True, mimetypes are returned instead of textual descriptions mime - if True, mimetypes are returned instead of textual descriptions
mime_encoding - if True, codec is returned mime_encoding - if True, codec is returned
magic_file - use a mime database other than the system default magic_file - use a mime database other than the system default
keep_going - don't stop at the first match, keep going
"""
self.flags = MAGIC_NONE
if mime:
self.flags |= MAGIC_MIME
elif mime_encoding:
self.flags |= MAGIC_MIME_ENCODING
if keep_going:
self.flags |= MAGIC_CONTINUE
self.cookie = magic_open(self.flags) """
flags = MAGIC_NONE
if mime:
flags |= MAGIC_MIME
elif mime_encoding:
flags |= MAGIC_MIME_ENCODING
self.cookie = magic_open(flags)
magic_load(self.cookie, magic_file) magic_load(self.cookie, magic_file)
self.thread = threading.currentThread()
def from_buffer(self, buf): def from_buffer(self, buf):
""" """
Identify the contents of `buf` Identify the contents of `buf`
""" """
self._thread_check() return magic_buffer(self.cookie, buf)
try:
return magic_buffer(self.cookie, buf)
except MagicException as e:
return self._handle509Bug(e)
def from_file(self, filename): def from_file(self, filename):
""" """
Identify the contents of file `filename` Identify the contents of file `filename`
raises IOError if the file does not exist raises IOError if the file does not exist
""" """
self._thread_check()
if not os.path.exists(filename): if not os.path.exists(filename):
raise IOError("File does not exist: " + filename) raise IOError("File does not exist: " + filename)
try:
return magic_file(self.cookie, filename)
except MagicException as e:
return self._handle509Bug(e)
def _handle509Bug(self, e): return magic_file(self.cookie, filename)
# libmagic 5.09 has a bug where it might mail to identify the
# mimetype of a file and returns null from magic_file (and
# likely _buffer), but also does not return an error message.
if e.message is None and (self.flags & MAGIC_MIME):
return "application/octet-stream"
def _thread_check(self):
if self.thread != threading.currentThread():
raise Exception('attempting to use libmagic on multiple threads will '
'end in SEGV. Prefer to use the module functions '
'from_file or from_buffer, or carefully manage direct '
'use of the Magic class')
def __del__(self): def __del__(self):
# no _thread_check here because there can be no other if self.cookie:
# references to this object at this point.
# during shutdown magic_close may have been cleared already so
# make sure it exists before using it.
# the self.cookie check should be unnessary and was an
# incorrect fix for a threading problem, however I'm leaving
# it in because it's harmless and I'm slightly afraid to
# remove it.
if self.cookie and magic_close:
magic_close(self.cookie) magic_close(self.cookie)
self.cookie = None self.cookie = None
_magic_mime = None
_magic = None
instances = threading.local() def _get_magic_mime():
global _magic_mime
if not _magic_mime:
_magic_mime = Magic(mime=True)
return _magic_mime
def _get_magic():
global _magic
if not _magic:
_magic = Magic()
return _magic
def _get_magic_type(mime): def _get_magic_type(mime):
i = instances.__dict__.get(mime) if mime:
if i is None: return _get_magic_mime()
i = instances.__dict__[mime] = Magic(mime=mime) else:
return i return _get_magic()
def from_file(filename, mime=False): def from_file(filename, mime=False):
""""
Accepts a filename and returns the detected filetype. Return
value is the mimetype if mime=True, otherwise a human readable
name.
>>> magic.from_file("testdata/test.pdf", mime=True)
'application/pdf'
"""
m = _get_magic_type(mime) m = _get_magic_type(mime)
return m.from_file(filename) return m.from_file(filename)
def from_buffer(buffer, mime=False): def from_buffer(buffer, mime=False):
"""
Accepts a binary string and returns the detected filetype. Return
value is the mimetype if mime=True, otherwise a human readable
name.
>>> magic.from_buffer(open("testdata/test.pdf").read(1024))
'PDF document, version 1.2'
"""
m = _get_magic_type(mime) m = _get_magic_type(mime)
return m.from_buffer(buffer) return m.from_buffer(buffer)
@ -148,22 +110,19 @@ def from_buffer(buffer, mime=False):
libmagic = None libmagic = None
# Let's try to find magic or magic1 # Let's try to find magic or magic1
dll = ctypes.util.find_library('magic') or ctypes.util.find_library('magic1') or ctypes.util.find_library('cygmagic-1') dll = ctypes.util.find_library('magic') or ctypes.util.find_library('magic1')
# This is necessary because find_library returns None if it doesn't find the library # This is necessary because find_library returns None if it doesn't find the library
if dll: if dll:
libmagic = ctypes.CDLL(dll) libmagic = ctypes.CDLL(dll)
if not libmagic or not libmagic._name: if not libmagic or not libmagic._name:
platform_to_lib = {'darwin': ['/opt/local/lib/libmagic.dylib', import sys
'/usr/local/lib/libmagic.dylib'] + platform_to_lib = {'darwin': '/opt/local/lib/libmagic.dylib',
# Assumes there will only be one version installed 'win32': 'magic1.dll'}
glob.glob('/usr/local/Cellar/libmagic/*/lib/libmagic.dylib'), if sys.platform in platform_to_lib:
'win32': ['magic1.dll','cygmagic-1.dll']}
for dll in platform_to_lib.get(sys.platform, []):
try: try:
libmagic = ctypes.CDLL(dll) libmagic = ctypes.CDLL(platform_to_lib[sys.platform])
break
except OSError: except OSError:
pass pass
@ -173,38 +132,13 @@ if not libmagic or not libmagic._name:
magic_t = ctypes.c_void_p magic_t = ctypes.c_void_p
def errorcheck_null(result, func, args): def errorcheck(result, func, args):
if result is None: err = magic_error(args[0])
err = magic_error(args[0]) if err is not None:
raise MagicException(err) raise MagicException(err)
else: else:
return result return result
def errorcheck_negative_one(result, func, args):
if result is -1:
err = magic_error(args[0])
raise MagicException(err)
else:
return result
def coerce_filename(filename):
if filename is None:
return None
# ctypes will implicitly convert unicode strings to bytes with
# .encode('ascii'). If you use the filesystem encoding
# then you'll get inconsistent behavior (crashes) depending on the user's
# LANG environment variable
is_unicode = (sys.version_info[0] <= 2 and
isinstance(filename, unicode)) or \
(sys.version_info[0] >= 3 and
isinstance(filename, str))
if is_unicode:
return filename.encode('utf-8')
else:
return filename
magic_open = libmagic.magic_open magic_open = libmagic.magic_open
magic_open.restype = magic_t magic_open.restype = magic_t
magic_open.argtypes = [c_int] magic_open.argtypes = [c_int]
@ -221,30 +155,26 @@ magic_errno = libmagic.magic_errno
magic_errno.restype = c_int magic_errno.restype = c_int
magic_errno.argtypes = [magic_t] magic_errno.argtypes = [magic_t]
_magic_file = libmagic.magic_file magic_file = libmagic.magic_file
_magic_file.restype = c_char_p magic_file.restype = c_char_p
_magic_file.argtypes = [magic_t, c_char_p] magic_file.argtypes = [magic_t, c_char_p]
_magic_file.errcheck = errorcheck_null magic_file.errcheck = errorcheck
def magic_file(cookie, filename):
return _magic_file(cookie, coerce_filename(filename))
_magic_buffer = libmagic.magic_buffer _magic_buffer = libmagic.magic_buffer
_magic_buffer.restype = c_char_p _magic_buffer.restype = c_char_p
_magic_buffer.argtypes = [magic_t, c_void_p, c_size_t] _magic_buffer.argtypes = [magic_t, c_void_p, c_size_t]
_magic_buffer.errcheck = errorcheck_null _magic_buffer.errcheck = errorcheck
def magic_buffer(cookie, buf): def magic_buffer(cookie, buf):
return _magic_buffer(cookie, buf, len(buf)) return _magic_buffer(cookie, buf, len(buf))
_magic_load = libmagic.magic_load magic_load = libmagic.magic_load
_magic_load.restype = c_int magic_load.restype = c_int
_magic_load.argtypes = [magic_t, c_char_p] magic_load.argtypes = [magic_t, c_char_p]
_magic_load.errcheck = errorcheck_negative_one magic_load.errcheck = errorcheck
def magic_load(cookie, filename):
return _magic_load(cookie, coerce_filename(filename))
magic_setflags = libmagic.magic_setflags magic_setflags = libmagic.magic_setflags
magic_setflags.restype = c_int magic_setflags.restype = c_int

View file

@ -45,8 +45,8 @@ def init(host="127.0.0.1", port=None):
class Notification(object): class Notification(object):
def __init__(self, title="", msg="", icon=""): def __init__(self, title="", msg="", icon=""):
self.title = str(title) self.title = unicode(title)
self.msg = str(msg) self.msg = unicode(msg)
if icon.startswith("file://"): if icon.startswith("file://"):
icon = icon[7:] icon = icon[7:]
self.icon = icon self.icon = icon

View file

@ -1,547 +0,0 @@
"""A parser for SGML, using the derived class as a static DTD."""
# XXX This only supports those SGML features used by HTML.
# XXX There should be a way to distinguish between PCDATA (parsed
# character data -- the normal case), RCDATA (replaceable character
# data -- only char and entity references and end tags are special)
# and CDATA (character data -- only end tags are special). RCDATA is
# not supported at all.
import _markupbase
import re
__all__ = ["SGMLParser", "SGMLParseError"]
# Regular expressions used for parsing
interesting = re.compile('[&<]')
incomplete = re.compile('&([a-zA-Z][a-zA-Z0-9]*|#[0-9]*)?|'
'<([a-zA-Z][^<>]*|'
'/([a-zA-Z][^<>]*)?|'
'![^<>]*)?')
entityref = re.compile('&([a-zA-Z][-.a-zA-Z0-9]*)[^a-zA-Z0-9]')
charref = re.compile('&#([0-9]+)[^0-9]')
starttagopen = re.compile('<[>a-zA-Z]')
shorttagopen = re.compile('<[a-zA-Z][-.a-zA-Z0-9]*/')
shorttag = re.compile('<([a-zA-Z][-.a-zA-Z0-9]*)/([^/]*)/')
piclose = re.compile('>')
endbracket = re.compile('[<>]')
tagfind = re.compile('[a-zA-Z][-_.a-zA-Z0-9]*')
attrfind = re.compile(
r'\s*([a-zA-Z_][-:.a-zA-Z_0-9]*)(\s*=\s*'
r'(\'[^\']*\'|"[^"]*"|[][\-a-zA-Z0-9./,:;+*%?!&$\(\)_#=~\'"@]*))?')
class SGMLParseError(RuntimeError):
"""Exception raised for all parse errors."""
pass
# SGML parser base class -- find tags and call handler functions.
# Usage: p = SGMLParser(); p.feed(data); ...; p.close().
# The dtd is defined by deriving a class which defines methods
# with special names to handle tags: start_foo and end_foo to handle
# <foo> and </foo>, respectively, or do_foo to handle <foo> by itself.
# (Tags are converted to lower case for this purpose.) The data
# between tags is passed to the parser by calling self.handle_data()
# with some data as argument (the data may be split up in arbitrary
# chunks). Entity references are passed by calling
# self.handle_entityref() with the entity reference as argument.
class SGMLParser(_markupbase.ParserBase):
# Definition of entities -- derived classes may override
entity_or_charref = re.compile('&(?:'
'([a-zA-Z][-.a-zA-Z0-9]*)|#([0-9]+)'
')(;?)')
def __init__(self, verbose=0):
"""Initialize and reset this instance."""
self.verbose = verbose
self.reset()
def reset(self):
"""Reset this instance. Loses all unprocessed data."""
self.__starttag_text = None
self.rawdata = ''
self.stack = []
self.lasttag = '???'
self.nomoretags = 0
self.literal = 0
_markupbase.ParserBase.reset(self)
def setnomoretags(self):
"""Enter literal mode (CDATA) till EOF.
Intended for derived classes only.
"""
self.nomoretags = self.literal = 1
def setliteral(self, *args):
"""Enter literal mode (CDATA).
Intended for derived classes only.
"""
self.literal = 1
def feed(self, data):
"""Feed some data to the parser.
Call this as often as you want, with as little or as much text
as you want (may include '\n'). (This just saves the text,
all the processing is done by goahead().)
"""
self.rawdata = self.rawdata + data
self.goahead(0)
def close(self):
"""Handle the remaining data."""
self.goahead(1)
def error(self, message):
raise SGMLParseError(message)
# Internal -- handle data as far as reasonable. May leave state
# and data to be processed by a subsequent call. If 'end' is
# true, force handling all data as if followed by EOF marker.
def goahead(self, end):
rawdata = self.rawdata
i = 0
n = len(rawdata)
while i < n:
if self.nomoretags:
self.handle_data(rawdata[i:n])
i = n
break
match = interesting.search(rawdata, i)
if match: j = match.start()
else: j = n
if i < j:
self.handle_data(rawdata[i:j])
i = j
if i == n: break
if rawdata[i] == '<':
if starttagopen.match(rawdata, i):
if self.literal:
self.handle_data(rawdata[i])
i = i+1
continue
k = self.parse_starttag(i)
if k < 0: break
i = k
continue
if rawdata.startswith("</", i):
k = self.parse_endtag(i)
if k < 0: break
i = k
self.literal = 0
continue
if self.literal:
if n > (i + 1):
self.handle_data("<")
i = i+1
else:
# incomplete
break
continue
if rawdata.startswith("<!--", i):
# Strictly speaking, a comment is --.*--
# within a declaration tag <!...>.
# This should be removed,
# and comments handled only in parse_declaration.
k = self.parse_comment(i)
if k < 0: break
i = k
continue
if rawdata.startswith("<?", i):
k = self.parse_pi(i)
if k < 0: break
i = i+k
continue
if rawdata.startswith("<!", i):
# This is some sort of declaration; in "HTML as
# deployed," this should only be the document type
# declaration ("<!DOCTYPE html...>").
k = self.parse_declaration(i)
if k < 0: break
i = k
continue
elif rawdata[i] == '&':
if self.literal:
self.handle_data(rawdata[i])
i = i+1
continue
match = charref.match(rawdata, i)
if match:
name = match.group(1)
self.handle_charref(name)
i = match.end(0)
if rawdata[i-1] != ';': i = i-1
continue
match = entityref.match(rawdata, i)
if match:
name = match.group(1)
self.handle_entityref(name)
i = match.end(0)
if rawdata[i-1] != ';': i = i-1
continue
else:
self.error('neither < nor & ??')
# We get here only if incomplete matches but
# nothing else
match = incomplete.match(rawdata, i)
if not match:
self.handle_data(rawdata[i])
i = i+1
continue
j = match.end(0)
if j == n:
break # Really incomplete
self.handle_data(rawdata[i:j])
i = j
# end while
if end and i < n:
self.handle_data(rawdata[i:n])
i = n
self.rawdata = rawdata[i:]
# XXX if end: check for empty stack
# Extensions for the DOCTYPE scanner:
_decl_otherchars = '='
# Internal -- parse processing instr, return length or -1 if not terminated
def parse_pi(self, i):
rawdata = self.rawdata
if rawdata[i:i+2] != '<?':
self.error('unexpected call to parse_pi()')
match = piclose.search(rawdata, i+2)
if not match:
return -1
j = match.start(0)
self.handle_pi(rawdata[i+2: j])
j = match.end(0)
return j-i
def get_starttag_text(self):
return self.__starttag_text
# Internal -- handle starttag, return length or -1 if not terminated
def parse_starttag(self, i):
self.__starttag_text = None
start_pos = i
rawdata = self.rawdata
if shorttagopen.match(rawdata, i):
# SGML shorthand: <tag/data/ == <tag>data</tag>
# XXX Can data contain &... (entity or char refs)?
# XXX Can data contain < or > (tag characters)?
# XXX Can there be whitespace before the first /?
match = shorttag.match(rawdata, i)
if not match:
return -1
tag, data = match.group(1, 2)
self.__starttag_text = '<%s/' % tag
tag = tag.lower()
k = match.end(0)
self.finish_shorttag(tag, data)
self.__starttag_text = rawdata[start_pos:match.end(1) + 1]
return k
# XXX The following should skip matching quotes (' or ")
# As a shortcut way to exit, this isn't so bad, but shouldn't
# be used to locate the actual end of the start tag since the
# < or > characters may be embedded in an attribute value.
match = endbracket.search(rawdata, i+1)
if not match:
return -1
j = match.start(0)
# Now parse the data between i+1 and j into a tag and attrs
attrs = []
if rawdata[i:i+2] == '<>':
# SGML shorthand: <> == <last open tag seen>
k = j
tag = self.lasttag
else:
match = tagfind.match(rawdata, i+1)
if not match:
self.error('unexpected call to parse_starttag')
k = match.end(0)
tag = rawdata[i+1:k].lower()
self.lasttag = tag
while k < j:
match = attrfind.match(rawdata, k)
if not match: break
attrname, rest, attrvalue = match.group(1, 2, 3)
if not rest:
attrvalue = attrname
else:
if (attrvalue[:1] == "'" == attrvalue[-1:] or
attrvalue[:1] == '"' == attrvalue[-1:]):
# strip quotes
attrvalue = attrvalue[1:-1]
attrvalue = self.entity_or_charref.sub(
self._convert_ref, attrvalue)
attrs.append((attrname.lower(), attrvalue))
k = match.end(0)
if rawdata[j] == '>':
j = j+1
self.__starttag_text = rawdata[start_pos:j]
self.finish_starttag(tag, attrs)
return j
# Internal -- convert entity or character reference
def _convert_ref(self, match):
if match.group(2):
return self.convert_charref(match.group(2)) or \
'&#%s%s' % match.groups()[1:]
elif match.group(3):
return self.convert_entityref(match.group(1)) or \
'&%s;' % match.group(1)
else:
return '&%s' % match.group(1)
# Internal -- parse endtag
def parse_endtag(self, i):
rawdata = self.rawdata
match = endbracket.search(rawdata, i+1)
if not match:
return -1
j = match.start(0)
tag = rawdata[i+2:j].strip().lower()
if rawdata[j] == '>':
j = j+1
self.finish_endtag(tag)
return j
# Internal -- finish parsing of <tag/data/ (same as <tag>data</tag>)
def finish_shorttag(self, tag, data):
self.finish_starttag(tag, [])
self.handle_data(data)
self.finish_endtag(tag)
# Internal -- finish processing of start tag
# Return -1 for unknown tag, 0 for open-only tag, 1 for balanced tag
def finish_starttag(self, tag, attrs):
try:
method = getattr(self, 'start_' + tag)
except AttributeError:
try:
method = getattr(self, 'do_' + tag)
except AttributeError:
self.unknown_starttag(tag, attrs)
return -1
else:
self.handle_starttag(tag, method, attrs)
return 0
else:
self.stack.append(tag)
self.handle_starttag(tag, method, attrs)
return 1
# Internal -- finish processing of end tag
def finish_endtag(self, tag):
if not tag:
found = len(self.stack) - 1
if found < 0:
self.unknown_endtag(tag)
return
else:
if tag not in self.stack:
try:
method = getattr(self, 'end_' + tag)
except AttributeError:
self.unknown_endtag(tag)
else:
self.report_unbalanced(tag)
return
found = len(self.stack)
for i in range(found):
if self.stack[i] == tag: found = i
while len(self.stack) > found:
tag = self.stack[-1]
try:
method = getattr(self, 'end_' + tag)
except AttributeError:
method = None
if method:
self.handle_endtag(tag, method)
else:
self.unknown_endtag(tag)
del self.stack[-1]
# Overridable -- handle start tag
def handle_starttag(self, tag, method, attrs):
method(attrs)
# Overridable -- handle end tag
def handle_endtag(self, tag, method):
method()
# Example -- report an unbalanced </...> tag.
def report_unbalanced(self, tag):
if self.verbose:
print('*** Unbalanced </' + tag + '>')
print('*** Stack:', self.stack)
def convert_charref(self, name):
"""Convert character reference, may be overridden."""
try:
n = int(name)
except ValueError:
return
if not 0 <= n <= 127:
return
return self.convert_codepoint(n)
def convert_codepoint(self, codepoint):
return chr(codepoint)
def handle_charref(self, name):
"""Handle character reference, no need to override."""
replacement = self.convert_charref(name)
if replacement is None:
self.unknown_charref(name)
else:
self.handle_data(replacement)
# Definition of entities -- derived classes may override
entitydefs = \
{'lt': '<', 'gt': '>', 'amp': '&', 'quot': '"', 'apos': '\''}
def convert_entityref(self, name):
"""Convert entity references.
As an alternative to overriding this method; one can tailor the
results by setting up the self.entitydefs mapping appropriately.
"""
table = self.entitydefs
if name in table:
return table[name]
else:
return
def handle_entityref(self, name):
"""Handle entity references, no need to override."""
replacement = self.convert_entityref(name)
if replacement is None:
self.unknown_entityref(name)
else:
self.handle_data(replacement)
# Example -- handle data, should be overridden
def handle_data(self, data):
pass
# Example -- handle comment, could be overridden
def handle_comment(self, data):
pass
# Example -- handle declaration, could be overridden
def handle_decl(self, decl):
pass
# Example -- handle processing instruction, could be overridden
def handle_pi(self, data):
pass
# To be overridden -- handlers for unknown objects
def unknown_starttag(self, tag, attrs): pass
def unknown_endtag(self, tag): pass
def unknown_charref(self, ref): pass
def unknown_entityref(self, ref): pass
class TestSGMLParser(SGMLParser):
def __init__(self, verbose=0):
self.testdata = ""
SGMLParser.__init__(self, verbose)
def handle_data(self, data):
self.testdata = self.testdata + data
if len(repr(self.testdata)) >= 70:
self.flush()
def flush(self):
data = self.testdata
if data:
self.testdata = ""
print('data:', repr(data))
def handle_comment(self, data):
self.flush()
r = repr(data)
if len(r) > 68:
r = r[:32] + '...' + r[-32:]
print('comment:', r)
def unknown_starttag(self, tag, attrs):
self.flush()
if not attrs:
print('start tag: <' + tag + '>')
else:
print('start tag: <' + tag, end=' ')
for name, value in attrs:
print(name + '=' + '"' + value + '"', end=' ')
print('>')
def unknown_endtag(self, tag):
self.flush()
print('end tag: </' + tag + '>')
def unknown_entityref(self, ref):
self.flush()
print('*** unknown entity ref: &' + ref + ';')
def unknown_charref(self, ref):
self.flush()
print('*** unknown char ref: &#' + ref + ';')
def unknown_decl(self, data):
self.flush()
print('*** unknown decl: [' + data + ']')
def close(self):
SGMLParser.close(self)
self.flush()
def test(args = None):
import sys
if args is None:
args = sys.argv[1:]
if args and args[0] == '-s':
args = args[1:]
klass = SGMLParser
else:
klass = TestSGMLParser
if args:
file = args[0]
else:
file = 'test.html'
if file == '-':
f = sys.stdin
else:
try:
f = open(file, 'r')
except IOError as msg:
print(file, ":", msg)
sys.exit(1)
data = f.read()
if f is not sys.stdin:
f.close()
x = klass()
for c in data:
x.feed(c)
x.close()
if __name__ == '__main__':
test()

View file

@ -33,7 +33,7 @@ class PesterLogHighlighter(QtGui.QSyntaxHighlighter):
self.hilightstyle.setForeground(QtGui.QBrush(QtCore.Qt.black)) self.hilightstyle.setForeground(QtGui.QBrush(QtCore.Qt.black))
def highlightBlock(self, text): def highlightBlock(self, text):
for i in range(0, len(text)-(len(self.searchTerm)-1)): for i in range(0, len(text)-(len(self.searchTerm)-1)):
if str(text[i:i+len(self.searchTerm)]).lower() == str(self.searchTerm).lower(): if unicode(text[i:i+len(self.searchTerm)]).lower() == unicode(self.searchTerm).lower():
self.setFormat(i, len(self.searchTerm), self.hilightstyle) self.setFormat(i, len(self.searchTerm), self.hilightstyle)
class PesterLogUserSelect(QtWidgets.QDialog): class PesterLogUserSelect(QtWidgets.QDialog):
@ -162,7 +162,7 @@ class PesterLogViewer(QtWidgets.QDialog):
self.textArea = PesterLogText(theme, self.parent) self.textArea = PesterLogText(theme, self.parent)
self.textArea.setReadOnly(True) self.textArea.setReadOnly(True)
self.textArea.setFixedWidth(600) self.textArea.setFixedWidth(600)
if "convo/scrollbar" in theme: if theme.has_key("convo/scrollbar"):
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: else:
self.textArea.setStyleSheet("QTextEdit { width:500px; %s }" % (theme["convo/textarea/style"])) self.textArea.setStyleSheet("QTextEdit { width:500px; %s }" % (theme["convo/textarea/style"]))
@ -174,7 +174,7 @@ class PesterLogViewer(QtWidgets.QDialog):
self.tree.optionsMenu = QtWidgets.QMenu(self) self.tree.optionsMenu = QtWidgets.QMenu(self)
self.tree.setFixedSize(260, 300) self.tree.setFixedSize(260, 300)
self.tree.header().hide() self.tree.header().hide()
if "convo/scrollbar" in theme: if theme.has_key("convo/scrollbar"):
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: else:
self.tree.setStyleSheet("%s" % (theme["convo/textarea/style"])) self.tree.setStyleSheet("%s" % (theme["convo/textarea/style"]))
@ -250,7 +250,7 @@ class PesterLogViewer(QtWidgets.QDialog):
textCur = self.textArea.textCursor() textCur = self.textArea.textCursor()
textCur.movePosition(1) textCur.movePosition(1)
self.textArea.setTextCursor(textCur) 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(unicode(fname)))
def logSearch(self, search): def logSearch(self, search):
self.hilight.searchTerm = search self.hilight.searchTerm = search
@ -277,7 +277,7 @@ class PesterLogText(PesterText):
if url[0] == "#" and url != "#pesterchum": if url[0] == "#" and url != "#pesterchum":
self.parent().parent.showMemos(url[1:]) self.parent().parent.showMemos(url[1:])
elif url[0] == "@": elif url[0] == "@":
handle = str(url[1:]) handle = unicode(url[1:])
self.parent().parent.newConversation(handle) self.parent().parent.newConversation(handle)
else: else:
QtGui.QDesktopServices.openUrl(QtCore.QUrl(url, QtCore.QUrl.TolerantMode)) QtGui.QDesktopServices.openUrl(QtCore.QUrl(url, QtCore.QUrl.TolerantMode))

View file

@ -18,7 +18,7 @@ class LuaQuirks(ScriptQuirks):
try: try:
return lua.require(name) return lua.require(name)
except Error as e: except Error as e:
print(e) print e
return None return None
finally: finally:
os.chdir(CurrentDir) os.chdir(CurrentDir)
@ -48,10 +48,10 @@ class LuaQuirks(ScriptQuirks):
for name in module.commands: for name in module.commands:
CommandWrapper = Wrapper(module,name) CommandWrapper = Wrapper(module,name)
try: try:
if not isinstance(CommandWrapper("test"), str): if not isinstance(CommandWrapper("test"), basestring):
raise Exception raise Exception
except: except:
print("Quirk malformed: %s" % (name)) print "Quirk malformed: %s" % (name)
msgbox = QtWidgets.QMessageBox() msgbox = QtWidgets.QMessageBox()
msgbox.setWindowTitle("Error!") msgbox.setWindowTitle("Error!")
msgbox.setText("Quirk malformed: %s" % (name)) msgbox.setText("Quirk malformed: %s" % (name))

View file

@ -152,7 +152,7 @@ class TimeTracker(list):
except ValueError: except ValueError:
return None return None
def openTime(self, time): def openTime(self, time):
if time in self.open: if self.open.has_key(time):
self.open[time] = True self.open[time] = True
def openCurrentTime(self): def openCurrentTime(self):
timed = self.getTime() timed = self.getTime()
@ -190,7 +190,7 @@ class TimeInput(QtWidgets.QLineEdit):
self.setText(self.timeslider.getTime()) self.setText(self.timeslider.getTime())
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
def setSlider(self): def setSlider(self):
value = str(self.text()) value = unicode(self.text())
timed = txt2delta(value) timed = txt2delta(value)
if type(timed) is mysteryTime: if type(timed) is mysteryTime:
self.timeslider.setValue(0) self.timeslider.setValue(0)
@ -262,13 +262,13 @@ class MemoText(PesterText):
self.mainwindow.animationSetting.connect(self.animateChanged) self.mainwindow.animationSetting.connect(self.animateChanged)
def initTheme(self, theme): def initTheme(self, theme):
if "memos/scrollbar" in theme: if theme.has_key("memos/scrollbar"):
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: else:
self.setStyleSheet("QTextEdit { %s }" % theme["memos/textarea/style"]) self.setStyleSheet("QTextEdit { %s }" % theme["memos/textarea/style"])
def addMessage(self, msg, chum): def addMessage(self, msg, chum):
if type(msg) in [str]: if type(msg) in [str, unicode]:
lexmsg = lexMessage(msg) lexmsg = lexMessage(msg)
else: else:
lexmsg = msg lexmsg = msg
@ -299,7 +299,7 @@ class MemoText(PesterText):
chum.color = color chum.color = color
systemColor = QtGui.QColor(window.theme["memos/systemMsgColor"]) systemColor = QtGui.QColor(window.theme["memos/systemMsgColor"])
if chum is not me: if chum is not me:
if chum.handle in parent.times: if parent.times.has_key(chum.handle):
time = parent.times[chum.handle] time = parent.times[chum.handle]
if time.getTime() is None: if time.getTime() is None:
# MY WAY OR THE HIGHWAY # MY WAY OR THE HIGHWAY
@ -521,9 +521,9 @@ class PesterMemo(PesterConvo):
self.userlist.optionsMenu.setStyleSheet(theme["main/defaultwindow/style"]) self.userlist.optionsMenu.setStyleSheet(theme["main/defaultwindow/style"])
scrolls = "width: 12px; height: 12px; border: 0; padding: 0;" scrolls = "width: 12px; height: 12px; border: 0; padding: 0;"
if "main/chums/scrollbar" in theme: if theme.has_key("main/chums/scrollbar"):
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: elif theme.has_key("convo/scrollbar"):
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: 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;"))
@ -646,7 +646,7 @@ class PesterMemo(PesterConvo):
systemColor = QtGui.QColor(self.mainwindow.theme["memos/systemMsgColor"]) systemColor = QtGui.QColor(self.mainwindow.theme["memos/systemMsgColor"])
chum = self.mainwindow.profile() chum = self.mainwindow.profile()
opchum = PesterProfile(op) opchum = PesterProfile(op)
if op in self.times: if self.times.has_key(op):
opgrammar = self.times[op].getGrammar() opgrammar = self.times[op].getGrammar()
elif op == self.mainwindow.profile().handle: elif op == self.mainwindow.profile().handle:
opgrammar = self.time.getGrammar() opgrammar = self.time.getGrammar()
@ -741,7 +741,7 @@ class PesterMemo(PesterConvo):
else: else:
timed = timeProtocol(cmd) timed = timeProtocol(cmd)
if handle in self.times: if self.times.has_key(handle):
if close is not None: if close is not None:
if close in self.times[handle]: if close in self.times[handle]:
self.times[handle].setCurrent(close) self.times[handle].setCurrent(close)
@ -761,7 +761,7 @@ class PesterMemo(PesterConvo):
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
def sentMessage(self): def sentMessage(self):
text = str(self.textInput.text()) text = unicode(self.textInput.text())
if text == "" or text[0:11] == "PESTERCHUM:": if text == "" or text[0:11] == "PESTERCHUM:":
return return
oocDetected = oocre.match(text.strip()) oocDetected = oocre.match(text.strip())
@ -794,7 +794,7 @@ class PesterMemo(PesterConvo):
self.textInput.setText("") self.textInput.setText("")
@QtCore.pyqtSlot('QString') @QtCore.pyqtSlot('QString')
def namesUpdated(self, channel): def namesUpdated(self, channel):
c = str(channel) c = unicode(channel)
if c.lower() != self.channel.lower(): return if c.lower() != self.channel.lower(): return
# get namesdb # get namesdb
namesdb = self.mainwindow.namesdb namesdb = self.mainwindow.namesdb
@ -804,17 +804,17 @@ class PesterMemo(PesterConvo):
self.addUser(n) self.addUser(n)
@QtCore.pyqtSlot('QString', 'QString') @QtCore.pyqtSlot('QString', 'QString')
def modesUpdated(self, channel, modes): def modesUpdated(self, channel, modes):
c = str(channel) c = unicode(channel)
if c.lower() == self.channel.lower(): if c.lower() == self.channel.lower():
self.updateChanModes(modes, None) self.updateChanModes(modes, None)
@QtCore.pyqtSlot('QString') @QtCore.pyqtSlot('QString')
def closeInviteOnly(self, channel): def closeInviteOnly(self, channel):
c = str(channel) c = unicode(channel)
if c.lower() == self.channel.lower(): if c.lower() == self.channel.lower():
self.mainwindow.inviteOnlyChan.disconnect(self.closeInviteOnly) self.mainwindow.inviteOnlyChan.disconnect(self.closeInviteOnly)
if self.parent(): if self.parent():
print(self.channel) print self.channel
i = self.parent().tabIndices[self.channel] i = self.parent().tabIndices[self.channel]
self.parent().tabClose(i) self.parent().tabClose(i)
else: else:
@ -835,7 +835,7 @@ class PesterMemo(PesterConvo):
systemColor = QtGui.QColor(self.mainwindow.theme["memos/systemMsgColor"]) systemColor = QtGui.QColor(self.mainwindow.theme["memos/systemMsgColor"])
chum = self.mainwindow.profile() chum = self.mainwindow.profile()
opchum = PesterProfile(op) opchum = PesterProfile(op)
if op in self.times: if self.times.has_key(op):
opgrammar = self.times[op].getGrammar() opgrammar = self.times[op].getGrammar()
elif op == self.mainwindow.profile().handle: elif op == self.mainwindow.profile().handle:
opgrammar = self.time.getGrammar() opgrammar = self.time.getGrammar()
@ -851,12 +851,12 @@ class PesterMemo(PesterConvo):
chum = self.mainwindow.profile() chum = self.mainwindow.profile()
ttracker = self.time ttracker = self.time
curtime = self.time.getTime() curtime = self.time.getTime()
elif h in self.times: elif self.times.has_key(h):
ttracker = self.times[h] ttracker = self.times[h]
else: else:
ttracker = TimeTracker(timedelta(0)) ttracker = TimeTracker(timedelta(0))
opchum = PesterProfile(op) opchum = PesterProfile(op)
if op in self.times: if self.times.has_key(op):
opgrammar = self.times[op].getGrammar() opgrammar = self.times[op].getGrammar()
elif op == self.mainwindow.profile().handle: elif op == self.mainwindow.profile().handle:
opgrammar = self.time.getGrammar() opgrammar = self.time.getGrammar()
@ -887,9 +887,9 @@ class PesterMemo(PesterConvo):
@QtCore.pyqtSlot('QString', 'QString', 'QString') @QtCore.pyqtSlot('QString', 'QString', 'QString')
def userPresentChange(self, handle, channel, update): def userPresentChange(self, handle, channel, update):
h = str(handle) h = unicode(handle)
c = str(channel) c = unicode(channel)
update = str(update) update = unicode(update)
if update[0:4] == "kick": # yeah, i'm lazy. if update[0:4] == "kick": # yeah, i'm lazy.
l = update.split(":") l = update.split(":")
update = l[0] update = l[0]
@ -920,7 +920,7 @@ class PesterMemo(PesterConvo):
for c in chums: for c in chums:
chum = PesterProfile(h) chum = PesterProfile(h)
self.userlist.takeItem(self.userlist.row(c)) self.userlist.takeItem(self.userlist.row(c))
if h not in self.times: if not self.times.has_key(h):
self.times[h] = TimeTracker(timedelta(0)) self.times[h] = TimeTracker(timedelta(0))
allinitials = [] allinitials = []
while self.times[h].getTime() is not None: while self.times[h].getTime() is not None:
@ -954,13 +954,13 @@ class PesterMemo(PesterConvo):
chum = self.mainwindow.profile() chum = self.mainwindow.profile()
ttracker = self.time ttracker = self.time
curtime = self.time.getTime() curtime = self.time.getTime()
elif h in self.times: elif self.times.has_key(h):
ttracker = self.times[h] ttracker = self.times[h]
else: else:
ttracker = TimeTracker(timedelta(0)) ttracker = TimeTracker(timedelta(0))
allinitials = [] allinitials = []
opchum = PesterProfile(op) opchum = PesterProfile(op)
if op in self.times: if self.times.has_key(op):
opgrammar = self.times[op].getGrammar() opgrammar = self.times[op].getGrammar()
elif op == self.mainwindow.profile().handle: elif op == self.mainwindow.profile().handle:
opgrammar = self.time.getGrammar() opgrammar = self.time.getGrammar()
@ -1024,7 +1024,7 @@ class PesterMemo(PesterConvo):
for c in chums: for c in chums:
c.op = True c.op = True
self.iconCrap(c) self.iconCrap(c)
if str(c.text()) == self.mainwindow.profile().handle: if unicode(c.text()) == self.mainwindow.profile().handle:
self.userlist.optionsMenu.addAction(self.opAction) self.userlist.optionsMenu.addAction(self.opAction)
self.userlist.optionsMenu.addAction(self.voiceAction) self.userlist.optionsMenu.addAction(self.voiceAction)
self.userlist.optionsMenu.addAction(self.banuserAction) self.userlist.optionsMenu.addAction(self.banuserAction)
@ -1041,7 +1041,7 @@ class PesterMemo(PesterConvo):
for c in chums: for c in chums:
c.op = False c.op = False
self.iconCrap(c) self.iconCrap(c)
if str(c.text()) == self.mainwindow.profile().handle: if unicode(c.text()) == self.mainwindow.profile().handle:
self.userlist.optionsMenu.removeAction(self.opAction) self.userlist.optionsMenu.removeAction(self.opAction)
self.userlist.optionsMenu.removeAction(self.voiceAction) self.userlist.optionsMenu.removeAction(self.voiceAction)
self.userlist.optionsMenu.removeAction(self.banuserAction) self.userlist.optionsMenu.removeAction(self.banuserAction)
@ -1057,7 +1057,7 @@ class PesterMemo(PesterConvo):
for c in chums: for c in chums:
c.halfop = True c.halfop = True
self.iconCrap(c) self.iconCrap(c)
if str(c.text()) == self.mainwindow.profile().handle: if unicode(c.text()) == self.mainwindow.profile().handle:
self.userlist.optionsMenu.addAction(self.opAction) self.userlist.optionsMenu.addAction(self.opAction)
self.userlist.optionsMenu.addAction(self.voiceAction) self.userlist.optionsMenu.addAction(self.voiceAction)
self.userlist.optionsMenu.addAction(self.banuserAction) self.userlist.optionsMenu.addAction(self.banuserAction)
@ -1074,7 +1074,7 @@ class PesterMemo(PesterConvo):
for c in chums: for c in chums:
c.halfop = False c.halfop = False
self.iconCrap(c) self.iconCrap(c)
if str(c.text()) == self.mainwindow.profile().handle: if unicode(c.text()) == self.mainwindow.profile().handle:
self.userlist.optionsMenu.removeAction(self.opAction) self.userlist.optionsMenu.removeAction(self.opAction)
self.userlist.optionsMenu.removeAction(self.voiceAction) self.userlist.optionsMenu.removeAction(self.voiceAction)
self.userlist.optionsMenu.removeAction(self.banuserAction) self.userlist.optionsMenu.removeAction(self.banuserAction)
@ -1120,13 +1120,13 @@ class PesterMemo(PesterConvo):
def addChumSlot(self): def addChumSlot(self):
if not self.userlist.currentItem(): if not self.userlist.currentItem():
return return
currentChum = PesterProfile(str(self.userlist.currentItem().text())) currentChum = PesterProfile(unicode(self.userlist.currentItem().text()))
self.mainwindow.addChum(currentChum) self.mainwindow.addChum(currentChum)
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
def banSelectedUser(self): def banSelectedUser(self):
if not self.userlist.currentItem(): if not self.userlist.currentItem():
return return
currentHandle = str(self.userlist.currentItem().text()) currentHandle = unicode(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: if ok:
self.mainwindow.kickUser.emit("%s:%s" % (currentHandle, reason), self.channel) self.mainwindow.kickUser.emit("%s:%s" % (currentHandle, reason), self.channel)
@ -1134,19 +1134,19 @@ class PesterMemo(PesterConvo):
def opSelectedUser(self): def opSelectedUser(self):
if not self.userlist.currentItem(): if not self.userlist.currentItem():
return return
currentHandle = str(self.userlist.currentItem().text()) currentHandle = unicode(self.userlist.currentItem().text())
self.mainwindow.setChannelMode.emit(self.channel, "+o", currentHandle) self.mainwindow.setChannelMode.emit(self.channel, "+o", currentHandle)
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
def voiceSelectedUser(self): def voiceSelectedUser(self):
if not self.userlist.currentItem(): if not self.userlist.currentItem():
return return
currentHandle = str(self.userlist.currentItem().text()) currentHandle = unicode(self.userlist.currentItem().text())
self.mainwindow.setChannelMode.emit(self.channel, "+v", currentHandle) self.mainwindow.setChannelMode.emit(self.channel, "+v", currentHandle)
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
def killQuirkUser(self): def killQuirkUser(self):
if not self.userlist.currentItem(): if not self.userlist.currentItem():
return return
currentHandle = str(self.userlist.currentItem().text()) currentHandle = unicode(self.userlist.currentItem().text())
self.mainwindow.killSomeQuirks.emit(self.channel, currentHandle) self.mainwindow.killSomeQuirks.emit(self.channel, currentHandle)
def resetSlider(self, time, send=True): def resetSlider(self, time, send=True):
@ -1171,7 +1171,7 @@ class PesterMemo(PesterConvo):
if not self.invitechums: 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: if ok:
chum = str(chum) chum = unicode(chum)
self.mainwindow.inviteChum.emit(chum, self.channel) self.mainwindow.inviteChum.emit(chum, self.channel)
self.invitechums = None self.invitechums = None

View file

@ -14,10 +14,10 @@ class PesterQuirkItem(QtWidgets.QTreeWidgetItem):
parent = None parent = None
QtWidgets.QTreeWidgetItem.__init__(self, parent) QtWidgets.QTreeWidgetItem.__init__(self, parent)
self.quirk = quirk self.quirk = quirk
self.setText(0, str(quirk)) self.setText(0, unicode(quirk))
def update(self, quirk): def update(self, quirk):
self.quirk = quirk self.quirk = quirk
self.setText(0, str(quirk)) self.setText(0, unicode(quirk))
def __lt__(self, quirkitem): def __lt__(self, quirkitem):
"""Sets the order of quirks if auto-sorted by Qt. Obsolete now.""" """Sets the order of quirks if auto-sorted by Qt. Obsolete now."""
if self.quirk.type == "prefix": if self.quirk.type == "prefix":
@ -163,7 +163,7 @@ class PesterQuirkList(QtWidgets.QTreeWidget):
if not self.addgroupdialog: 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: if ok:
gname = str(gname) gname = unicode(gname)
if re.search("[^A-Za-z0-9_\s]", gname) is not None: if re.search("[^A-Za-z0-9_\s]", gname) is not None:
msgbox = QtWidgets.QMessageBox() msgbox = QtWidgets.QMessageBox()
msgbox.setInformativeText("THIS IS NOT A VALID GROUP NAME") msgbox.setInformativeText("THIS IS NOT A VALID GROUP NAME")
@ -242,7 +242,7 @@ class QuirkTesterWindow(QtWidgets.QDialog):
pass pass
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
def sentMessage(self): def sentMessage(self):
text = str(self.textInput.text()) text = unicode(self.textInput.text())
if text == "" or text[0:11] == "PESTERCHUM:": if text == "" or text[0:11] == "PESTERCHUM:":
return return
self.history.add(text) self.history.add(text)
@ -251,7 +251,7 @@ class QuirkTesterWindow(QtWidgets.QDialog):
if type(lexmsg[0]) is not mecmd: if type(lexmsg[0]) is not mecmd:
try: try:
lexmsg = quirks.apply(lexmsg) lexmsg = quirks.apply(lexmsg)
except Exception as e: except Exception, e:
msgbox = QtWidgets.QMessageBox() msgbox = QtWidgets.QMessageBox()
msgbox.setText("Whoa there! There seems to be a problem.") msgbox.setText("Whoa there! There seems to be a problem.")
msgbox.setInformativeText("A quirk seems to be having a problem. (Possibly you're trying to capture a non-existant group?)\n\ msgbox.setInformativeText("A quirk seems to be having a problem. (Possibly you're trying to capture a non-existant group?)\n\
@ -266,7 +266,7 @@ class QuirkTesterWindow(QtWidgets.QDialog):
text = convertTags(serverMsg, "ctag") text = convertTags(serverMsg, "ctag")
self.textInput.setText("") self.textInput.setText("")
def addMessage(self, msg, me=True): def addMessage(self, msg, me=True):
if type(msg) in [str]: if type(msg) in [str, unicode]:
lexmsg = lexMessage(msg) lexmsg = lexMessage(msg)
else: else:
lexmsg = msg lexmsg = msg
@ -527,7 +527,7 @@ class PesterQuirkTypes(QtWidgets.QDialog):
self.current.setText(str(value)+"%") self.current.setText(str(value)+"%")
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
def addRandomString(self): def addRandomString(self):
text = str(self.replaceinput.text()) text = unicode(self.replaceinput.text())
item = QtWidgets.QListWidgetItem(text, self.replacelist) item = QtWidgets.QListWidgetItem(text, self.replacelist)
self.replaceinput.setText("") self.replaceinput.setText("")
self.replaceinput.setFocus() self.replaceinput.setFocus()
@ -543,7 +543,7 @@ class PesterQuirkTypes(QtWidgets.QDialog):
def reloadQuirkFuncSlot(self): def reloadQuirkFuncSlot(self):
from parsetools import reloadQuirkFunctions, quirkloader from parsetools import reloadQuirkFunctions, quirkloader
reloadQuirkFunctions() reloadQuirkFunctions()
funcs = [q+"()" for q in list(quirkloader.quirks.keys())] funcs = [q+"()" for q in quirkloader.quirks.keys()]
funcs.sort() funcs.sort()
self.funclist.clear() self.funclist.clear()
self.funclist.addItems(funcs) self.funclist.addItems(funcs)
@ -656,16 +656,16 @@ class PesterChooseQuirks(QtWidgets.QDialog):
vdict["type"] = types[self.quirkadd.pages.currentIndex()-1] vdict["type"] = types[self.quirkadd.pages.currentIndex()-1]
page = self.quirkadd.pages.currentWidget().layout() 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()) vdict["value"] = unicode(page.itemAt(1).layout().itemAt(1).widget().text())
elif vdict["type"] == "replace": elif vdict["type"] == "replace":
vdict["from"] = str(page.itemAt(1).layout().itemAt(1).widget().text()) vdict["from"] = unicode(page.itemAt(1).layout().itemAt(1).widget().text())
vdict["to"] = str(page.itemAt(2).layout().itemAt(1).widget().text()) vdict["to"] = unicode(page.itemAt(2).layout().itemAt(1).widget().text())
elif vdict["type"] == "regexp": elif vdict["type"] == "regexp":
vdict["from"] = str(page.itemAt(2).layout().itemAt(1).layout().itemAt(1).widget().text()) vdict["from"] = unicode(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["to"] = unicode(page.itemAt(2).layout().itemAt(2).layout().itemAt(1).widget().text())
elif vdict["type"] == "random": elif vdict["type"] == "random":
vdict["from"] = str(self.quirkadd.regexp.text()) vdict["from"] = unicode(self.quirkadd.regexp.text())
randomlist = [str(self.quirkadd.replacelist.item(i).text()) randomlist = [unicode(self.quirkadd.replacelist.item(i).text())
for i in range(0,self.quirkadd.replacelist.count())] for i in range(0,self.quirkadd.replacelist.count())]
vdict["randomlist"] = randomlist vdict["randomlist"] = randomlist
elif vdict["type"] == "spelling": elif vdict["type"] == "spelling":
@ -674,7 +674,7 @@ class PesterChooseQuirks(QtWidgets.QDialog):
if vdict["type"] in ("regexp", "random"): if vdict["type"] in ("regexp", "random"):
try: try:
re.compile(vdict["from"]) re.compile(vdict["from"])
except re.error as e: except re.error, e:
quirkWarning = QtWidgets.QMessageBox(self) quirkWarning = QtWidgets.QMessageBox(self)
quirkWarning.setText("Not a valid regular expression!") quirkWarning.setText("Not a valid regular expression!")
quirkWarning.setInformativeText("H3R3S WHY DUMP4SS: %s" % (e)) quirkWarning.setInformativeText("H3R3S WHY DUMP4SS: %s" % (e))
@ -809,7 +809,7 @@ class PesterChooseProfile(QtWidgets.QDialog):
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
def validateProfile(self): def validateProfile(self):
if not self.profileBox or self.profileBox.currentIndex() == 0: if not self.profileBox or self.profileBox.currentIndex() == 0:
handle = str(self.chumHandle.text()) handle = unicode(self.chumHandle.text())
if not PesterProfile.checkLength(handle): if not PesterProfile.checkLength(handle):
self.errorMsg.setText("PROFILE HANDLE IS TOO LONG") self.errorMsg.setText("PROFILE HANDLE IS TOO LONG")
return return
@ -821,7 +821,7 @@ class PesterChooseProfile(QtWidgets.QDialog):
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
def deleteProfile(self): def deleteProfile(self):
if self.profileBox and self.profileBox.currentIndex() > 0: if self.profileBox and self.profileBox.currentIndex() > 0:
handle = str(self.profileBox.currentText()) handle = unicode(self.profileBox.currentText())
if handle == self.parent.profile().handle: if handle == self.parent.profile().handle:
problem = QtWidgets.QMessageBox() problem = QtWidgets.QMessageBox()
problem.setStyleSheet(self.theme["main/defaultwindow/style"]) problem.setStyleSheet(self.theme["main/defaultwindow/style"])
@ -898,7 +898,7 @@ class PesterMentions(QtWidgets.QDialog):
return return
try: try:
re.compile(pdict["value"]) re.compile(pdict["value"])
except re.error as e: except re.error, e:
quirkWarning = QtWidgets.QMessageBox(self) quirkWarning = QtWidgets.QMessageBox(self)
quirkWarning.setText("Not a valid regular expression!") quirkWarning.setText("Not a valid regular expression!")
quirkWarning.setInformativeText("H3R3S WHY DUMP4SS: %s" % (e)) quirkWarning.setInformativeText("H3R3S WHY DUMP4SS: %s" % (e))
@ -1482,8 +1482,8 @@ class PesterUserlist(QtWidgets.QDialog):
self.userarea.sortItems() self.userarea.sortItems()
@QtCore.pyqtSlot('QString', 'QString', 'QString') @QtCore.pyqtSlot('QString', 'QString', 'QString')
def updateUserPresent(self, handle, channel, update): def updateUserPresent(self, handle, channel, update):
h = str(handle) h = unicode(handle)
c = str(channel) c = unicode(channel)
if update == "quit": if update == "quit":
self.delUser(h) self.delUser(h)
elif update == "left" and c == "#pesterchum": elif update == "left" and c == "#pesterchum":

View file

@ -21,12 +21,12 @@ def mispeller(word):
num = 1 num = 1
else: else:
num = random.choice([1,2]) num = random.choice([1,2])
wordseq = list(range(0, len(word))) wordseq = range(0, len(word))
random.shuffle(wordseq) random.shuffle(wordseq)
letters = wordseq[0:num] letters = wordseq[0:num]
def mistype(string, i): def mistype(string, i):
l = string[i] l = string[i]
if l not in kbdict: if not kbdict.has_key(l):
return string return string
lpos = kbdict[l] lpos = kbdict[l]
newpos = lpos newpos = lpos

View file

@ -33,10 +33,10 @@ def getDataDir():
# TODO: fix error if standardLocations is not what we expect # TODO: fix error if standardLocations is not what we expect
try: try:
if isOSX(): if isOSX():
return os.path.join(str(QStandardPaths.standardLocations(QStandardPaths.DataLocation)[0]), "Pesterchum/") return os.path.join(unicode(QStandardPaths.standardLocations(QStandardPaths.DataLocation)[0]), "Pesterchum/")
elif isLinux(): elif isLinux():
return os.path.join(str(QStandardPaths.standardLocations(QStandardPaths.HomeLocation)[0]), ".pesterchum/") return os.path.join(unicode(QStandardPaths.standardLocations(QStandardPaths.HomeLocation)[0]), ".pesterchum/")
else: else:
return os.path.join(str(QStandardPaths.standardLocations(QStandardPaths.DataLocation)[0]), "pesterchum/") return os.path.join(unicode(QStandardPaths.standardLocations(QStandardPaths.DataLocation)[0]), "pesterchum/")
except UnicodeDecodeError: except UnicodeDecodeError:
return '' return ''

View file

@ -28,7 +28,6 @@ import traceback
from oyoyo.parse import * from oyoyo.parse import *
from oyoyo import helpers from oyoyo import helpers
from oyoyo.cmdhandler import CommandError from oyoyo.cmdhandler import CommandError
import collections
# Python < 3 compatibility # Python < 3 compatibility
if sys.version_info < (3,): if sys.version_info < (3,):
@ -128,7 +127,7 @@ class IRCClient:
logging.info('---> send "%s"' % msg) logging.info('---> send "%s"' % msg)
try: try:
self.socket.send(msg + bytes("\r\n", "ascii")) self.socket.send(msg + bytes("\r\n", "ascii"))
except socket.error as se: except socket.error, se:
try: # a little dance of compatibility to get the errno try: # a little dance of compatibility to get the errno
errno = se.errno errno = se.errno
except AttributeError: except AttributeError:
@ -161,12 +160,12 @@ class IRCClient:
while not self._end: while not self._end:
try: try:
buffer += self.socket.recv(1024) buffer += self.socket.recv(1024)
except socket.timeout as e: except socket.timeout, e:
if self._end: if self._end:
break break
logging.debug("timeout in client.py") logging.debug("timeout in client.py")
raise e raise e
except socket.error as e: except socket.error, e:
if self._end: if self._end:
break break
logging.debug("error %s" % e) logging.debug("error %s" % e)
@ -196,16 +195,16 @@ class IRCClient:
pass pass
yield True yield True
except socket.timeout as se: except socket.timeout, se:
logging.debug("passing timeout") logging.debug("passing timeout")
raise se raise se
except socket.error as se: except socket.error, se:
logging.debug("problem: %s" % (se)) logging.debug("problem: %s" % (se))
if self.socket: if self.socket:
logging.info('error: closing socket') logging.info('error: closing socket')
self.socket.close() self.socket.close()
raise se raise se
except Exception as e: except Exception, e:
logging.debug("other exception: %s" % e) logging.debug("other exception: %s" % e)
raise e raise e
else: else:
@ -254,7 +253,7 @@ class IRCApp:
garuntee the callback will be called after seconds has passed. garuntee the callback will be called after seconds has passed.
( the only advantage to these timers is they dont use threads ) ( the only advantage to these timers is they dont use threads )
""" """
assert isinstance(cb, collections.Callable) assert callable(cb)
logging.info('added timer to call %s in %ss' % (cb, seconds)) logging.info('added timer to call %s in %ss' % (cb, seconds))
self._timers.append((time.time() + seconds, cb)) self._timers.append((time.time() + seconds, cb))
@ -265,13 +264,13 @@ class IRCApp:
while self.running: while self.running:
found_one_alive = False found_one_alive = False
for client, clientdesc in self._clients.items(): for client, clientdesc in self._clients.iteritems():
if clientdesc.con is None: if clientdesc.con is None:
clientdesc.con = client.connect() clientdesc.con = client.connect()
try: try:
next(clientdesc.con) clientdesc.con.next()
except Exception as e: except Exception, e:
logging.error('client error %s' % e) logging.error('client error %s' % e)
logging.error(traceback.format_exc()) logging.error(traceback.format_exc())
if clientdesc.autoreconnect: if clientdesc.autoreconnect:

View file

@ -65,17 +65,13 @@ class CommandHandler(object):
its possible to pass both "command.sub.func" and its possible to pass both "command.sub.func" and
["command", "sub", "func"]. ["command", "sub", "func"].
""" """
if isinstance(in_command_parts, (bytes)): if isinstance(in_command_parts, (str, bytes)):
in_command_parts = in_command_parts.split(bytes('.', 'ascii')) in_command_parts = in_command_parts.split(bytes('.', 'ascii'))
elif isinstance(in_command_parts, (str)):
in_command_parts = in_command_parts.split('.')
command_parts = in_command_parts[:] command_parts = in_command_parts[:]
p = self p = self
while command_parts: while command_parts:
cmd = command_parts.pop(0) cmd = command_parts.pop(0).decode('ascii')
if type(cmd) is bytes:
cmd = cmd.decode('utf-8')
if cmd.startswith('_'): if cmd.startswith('_'):
raise ProtectedCommandError(in_command_parts) raise ProtectedCommandError(in_command_parts)
@ -109,7 +105,7 @@ class CommandHandler(object):
try: try:
f(*args) f(*args)
except Exception as e: except Exception, e:
logging.error('command raised %s' % e) logging.error('command raised %s' % e)
logging.error(traceback.format_exc()) logging.error(traceback.format_exc())
raise CommandError(command) raise CommandError(command)
@ -155,7 +151,7 @@ class DefaultBotCommandHandler(CommandHandler):
else: else:
try: try:
f = self.get(arg) f = self.get(arg)
except CommandError as e: except CommandError, e:
helpers.msg(self.client, dest, str(e)) helpers.msg(self.client, dest, str(e))
return return
@ -202,7 +198,7 @@ class BotCommandHandler(DefaultCommandHandler):
try: try:
self.command_handler.run(command, prefix, dest, *arg) self.command_handler.run(command, prefix, dest, *arg)
except CommandError as e: except CommandError, e:
helpers.msg(self.client, dest, str(e)) helpers.msg(self.client, dest, str(e))
return True return True

View file

@ -21,7 +21,7 @@ class MyHandler(DefaultCommandHandler):
match = re.match('\!say (.*)', msg) match = re.match('\!say (.*)', msg)
if match: if match:
to_say = match.group(1).strip() to_say = match.group(1).strip()
print(('Saying, "%s"' % to_say)) print('Saying, "%s"' % to_say)
helpers.msg(self.client, chan, to_say) helpers.msg(self.client, chan, to_say)
@ -37,7 +37,7 @@ def main():
conn = cli.connect() conn = cli.connect()
while True: while True:
next(conn) ## python 2 conn.next() ## python 2
# next(conn) ## python 3 # next(conn) ## python 3

View file

@ -111,7 +111,7 @@ def _addNumerics():
cli.send(cmd_num, *args) cli.send(cmd_num, *args)
return f return f
m = sys.modules[__name__] m = sys.modules[__name__]
for num, name in ircevents.numeric_events.items(): for num, name in ircevents.numeric_events.iteritems():
setattr(m, name, numericcmd(num, name)) setattr(m, name, numericcmd(num, name))
_addNumerics() _addNumerics()

View file

@ -179,8 +179,6 @@ numeric_events = {
"502": "usersdontmatch", "502": "usersdontmatch",
} }
numeric_events = {bytes(k, 'ascii'):v for k, v in numeric_events.items()}
generated_events = [ generated_events = [
# Generated events # Generated events
"dcc_connect", "dcc_connect",
@ -208,5 +206,5 @@ protocol_events = [
"pong", "pong",
] ]
all_events = generated_events + protocol_events + list(numeric_events.values()) all_events = generated_events + protocol_events + numeric_events.values()

View file

@ -1,5 +1,5 @@
import sys import sys
from .helpers import msg from helpers import msg
# NickServ basic functions # NickServ basic functions
_nickservfuncs = ( _nickservfuncs = (
@ -103,7 +103,7 @@ def _addServ(serv, funcs, prefix=""):
if prefix: if prefix:
cmd_name = prefix.upper() + " " + cmd_name cmd_name = prefix.upper() + " " + cmd_name
def f(cli, *args): def f(cli, *args):
print(cmd_name, " ".join(args)) print cmd_name, " ".join(args)
#cli.send(cmd_name, serv.name, *args) #cli.send(cmd_name, serv.name, *args)
return f return f
for t in funcs: for t in funcs:

View file

@ -29,7 +29,7 @@ quirkloader = ScriptQuirks()
quirkloader.add(PythonQuirks()) quirkloader.add(PythonQuirks())
quirkloader.add(LuaQuirks()) quirkloader.add(LuaQuirks())
quirkloader.loadAll() quirkloader.loadAll()
print(quirkloader.funcre()) print quirkloader.funcre()
_functionre = re.compile(r"%s" % quirkloader.funcre()) _functionre = re.compile(r"%s" % quirkloader.funcre())
_groupre = re.compile(r"\\([0-9]+)") _groupre = re.compile(r"\\([0-9]+)")
@ -44,7 +44,7 @@ def lexer(string, objlist):
for (oType, regexp) in objlist: for (oType, regexp) in objlist:
newstringlist = [] newstringlist = []
for (stri, s) in enumerate(stringlist): for (stri, s) in enumerate(stringlist):
if type(s) not in [str]: if type(s) not in [str, unicode]:
newstringlist.append(s) newstringlist.append(s)
continue continue
lasti = 0 lasti = 0
@ -207,9 +207,9 @@ def lexMessage(string):
(smiley, _smilere), (smiley, _smilere),
(honker, _honk)] (honker, _honk)]
string = str(string) string = unicode(string)
string = string.replace("\n", " ").replace("\r", " ") string = string.replace("\n", " ").replace("\r", " ")
lexed = lexer(str(string), lexlist) lexed = lexer(unicode(string), lexlist)
balanced = [] balanced = []
beginc = 0 beginc = 0
@ -231,7 +231,7 @@ def lexMessage(string):
balanced.append(colorEnd("</c>")) balanced.append(colorEnd("</c>"))
if len(balanced) == 0: if len(balanced) == 0:
balanced.append("") balanced.append("")
if type(balanced[len(balanced)-1]) not in [str]: if type(balanced[len(balanced)-1]) not in [str, unicode]:
balanced.append("") balanced.append("")
return balanced return balanced
@ -239,12 +239,12 @@ def convertTags(lexed, format="html"):
if format not in ["html", "bbcode", "ctag", "text"]: if format not in ["html", "bbcode", "ctag", "text"]:
raise ValueError("Color format not recognized") raise ValueError("Color format not recognized")
if type(lexed) in [str]: if type(lexed) in [str, unicode]:
lexed = lexMessage(lexed) lexed = lexMessage(lexed)
escaped = "" escaped = ""
firststr = True firststr = True
for (i, o) in enumerate(lexed): for (i, o) in enumerate(lexed):
if type(o) in [str]: if type(o) in [str, unicode]:
if format == "html": if format == "html":
escaped += o.replace("&", "&amp;").replace(">", "&gt;").replace("<","&lt;") escaped += o.replace("&", "&amp;").replace(">", "&gt;").replace("<","&lt;")
else: else:
@ -259,7 +259,7 @@ def splitMessage(msg, format="ctag"):
# split long text lines # split long text lines
buf = [] buf = []
for o in msg: for o in msg:
if type(o) in [str] and len(o) > 200: if type(o) in [str, unicode] and len(o) > 200:
for i in range(0, len(o), 200): for i in range(0, len(o), 200):
buf.append(o[i:i+200]) buf.append(o[i:i+200])
else: else:
@ -401,7 +401,7 @@ def parseRegexpFunctions(to):
backr = _groupre.search(mo.group()) backr = _groupre.search(mo.group())
if backr is not None: if backr is not None:
current.append(backreference(backr.group(1))) current.append(backreference(backr.group(1)))
elif mo.group()[:-1] in list(functiondict.keys()): elif mo.group()[:-1] in functiondict.keys():
p = parseLeaf(functiondict[mo.group()[:-1]], current) p = parseLeaf(functiondict[mo.group()[:-1]], current)
current.append(p) current.append(p)
current = p current = p
@ -418,7 +418,7 @@ def parseRegexpFunctions(to):
def img2smiley(string): def img2smiley(string):
string = str(string) string = unicode(string)
def imagerep(mo): def imagerep(mo):
return reverse_smiley[mo.group(1)] return reverse_smiley[mo.group(1)]
string = re.sub(r'<img src="smilies/(\S+)" />', imagerep, string) string = re.sub(r'<img src="smilies/(\S+)" />', imagerep, string)
@ -499,8 +499,8 @@ if ostools.isOSXBundle():
reverse_smiley = dict((v,k) for k, v in smiledict.items()) reverse_smiley = dict((v,k) for k, v in smiledict.iteritems())
_smilere = re.compile("|".join(list(smiledict.keys()))) _smilere = re.compile("|".join(smiledict.keys()))
class ThemeException(Exception): class ThemeException(Exception):
def __init__(self, value): def __init__(self, value):

View file

@ -9,22 +9,28 @@ from datetime import *
import random import random
import re import re
from time import time from time import time
import threading, queue import threading, Queue
reqmissing = [] reqmissing = []
optmissing = [] optmissing = []
try: try:
from PyQt5 import QtGui, QtCore, QtWidgets, QtMultimedia from PyQt5 import QtGui, QtCore, QtWidgets
except ImportError as e: except ImportError, e:
module = str(e) module = str(e)
if module.startswith("No module named ") or \ if module.startswith("No module named ") or \
module.startswith("cannot import name "): module.startswith("cannot import name "):
reqmissing.append(module[module.rfind(" ")+1:]) reqmissing.append(module[module.rfind(" ")+1:])
else: print(e) else: print e
try:
import pygame
except ImportError, e:
pygame = None
module = str(e)
if module[:16] == "No module named ": optmissing.append(module[16:])
else: print e
if reqmissing: if reqmissing:
print("ERROR: The following modules are required for Pesterchum to run and are missing on your system:") print "ERROR: The following modules are required for Pesterchum to run and are missing on your system:"
for m in reqmissing: print("* "+m) for m in reqmissing: print "* "+m
exit() exit()
vnum = QtCore.qVersion() vnum = QtCore.qVersion()
major = int(vnum[:vnum.find(".")]) major = int(vnum[:vnum.find(".")])
@ -33,8 +39,8 @@ if vnum.find(".", vnum.find(".")+1) != -1:
else: else:
minor = int(vnum[vnum.find(".")+1:]) minor = int(vnum[vnum.find(".")+1:])
if not ((major > 4) or (major == 4 and minor >= 6)): if not ((major > 4) or (major == 4 and minor >= 6)):
print("ERROR: Pesterchum requires Qt version >= 4.6") print "ERROR: Pesterchum requires Qt version >= 4.6"
print("You currently have version " + vnum + ". Please upgrade Qt") print "You currently have version " + vnum + ". Please upgrade Qt"
exit() exit()
import ostools import ostools
@ -107,7 +113,7 @@ class waitingMessageHolder(object):
def __init__(self, mainwindow, **msgfuncs): def __init__(self, mainwindow, **msgfuncs):
self.mainwindow = mainwindow self.mainwindow = mainwindow
self.funcs = msgfuncs self.funcs = msgfuncs
self.queue = list(msgfuncs.keys()) self.queue = msgfuncs.keys()
if len(self.queue) > 0: if len(self.queue) > 0:
self.mainwindow.updateSystemTray() self.mainwindow.updateSystemTray()
def waitingHandles(self): def waitingHandles(self):
@ -123,7 +129,7 @@ class waitingMessageHolder(object):
if len(self.queue) == 0: if len(self.queue) == 0:
self.mainwindow.updateSystemTray() self.mainwindow.updateSystemTray()
def addMessage(self, handle, func): def addMessage(self, handle, func):
if handle not in self.funcs: if not self.funcs.has_key(handle):
self.queue.append(handle) self.queue.append(handle)
self.funcs[handle] = func self.funcs[handle] = func
if len(self.queue) > 0: if len(self.queue) > 0:
@ -276,13 +282,13 @@ class chumArea(RightClickTree):
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
def beginNotify(self): def beginNotify(self):
print("BEGIN NOTIFY") print "BEGIN NOTIFY"
self.notify = True self.notify = True
def getOptionsMenu(self): def getOptionsMenu(self):
if not self.currentItem(): if not self.currentItem():
return None return None
text = str(self.currentItem().text(0)) text = unicode(self.currentItem().text(0))
if text.rfind(" (") != -1: if text.rfind(" (") != -1:
text = text[0:text.rfind(" (")] text = text[0:text.rfind(" (")]
if text == "Chums": if text == "Chums":
@ -328,13 +334,13 @@ class chumArea(RightClickTree):
if thisitem.rfind(" (") != -1: if thisitem.rfind(" (") != -1:
thisitem = thisitem[0:thisitem.rfind(" (")] thisitem = thisitem[0:thisitem.rfind(" (")]
# Drop item is a group # Drop item is a group
thisitem = str(event.source().currentItem().text(0)) thisitem = unicode(event.source().currentItem().text(0))
if thisitem.rfind(" (") != -1: if thisitem.rfind(" (") != -1:
thisitem = thisitem[0:thisitem.rfind(" (")] thisitem = thisitem[0:thisitem.rfind(" (")]
if thisitem == "Chums" or thisitem in self.groups: if thisitem == "Chums" or thisitem in self.groups:
droppos = self.itemAt(event.pos()) droppos = self.itemAt(event.pos())
if not droppos: return if not droppos: return
droppos = str(droppos.text(0)) droppos = unicode(droppos.text(0))
if droppos.rfind(" ") != -1: if droppos.rfind(" ") != -1:
droppos = droppos[0:droppos.rfind(" ")] droppos = droppos[0:droppos.rfind(" ")]
if droppos == "Chums" or droppos in self.groups: if droppos == "Chums" or droppos in self.groups:
@ -347,16 +353,16 @@ class chumArea(RightClickTree):
gTemp = [] gTemp = []
for i in range(self.topLevelItemCount()): for i in range(self.topLevelItemCount()):
text = str(self.topLevelItem(i).text(0)) text = unicode(self.topLevelItem(i).text(0))
if text.rfind(" (") != -1: if text.rfind(" (") != -1:
text = text[0:text.rfind(" (")] text = text[0:text.rfind(" (")]
gTemp.append([str(text), self.topLevelItem(i).isExpanded()]) gTemp.append([unicode(text), self.topLevelItem(i).isExpanded()])
self.mainwindow.config.saveGroups(gTemp) self.mainwindow.config.saveGroups(gTemp)
# Drop item is a chum # Drop item is a chum
else: else:
item = self.itemAt(event.pos()) item = self.itemAt(event.pos())
if item: if item:
text = str(item.text(0)) text = unicode(item.text(0))
# Figure out which group to drop into # Figure out which group to drop into
if text.rfind(" (") != -1: if text.rfind(" (") != -1:
text = text[0:text.rfind(" (")] text = text[0:text.rfind(" (")]
@ -364,7 +370,7 @@ class chumArea(RightClickTree):
group = text group = text
gitem = item gitem = item
else: else:
ptext = str(item.parent().text(0)) ptext = unicode(item.parent().text(0))
if ptext.rfind(" ") != -1: if ptext.rfind(" ") != -1:
ptext = ptext[0:ptext.rfind(" ")] ptext = ptext[0:ptext.rfind(" ")]
group = ptext group = ptext
@ -387,7 +393,7 @@ class chumArea(RightClickTree):
if chums.index(thisitem) < inPos: if chums.index(thisitem) < inPos:
inPos -= 1 inPos -= 1
chums.remove(thisitem) chums.remove(thisitem)
chums.insert(inPos, str(thisitem)) chums.insert(inPos, unicode(thisitem))
self.mainwindow.config.setChums(chums) self.mainwindow.config.setChums(chums)
else: else:
@ -399,9 +405,9 @@ class chumArea(RightClickTree):
currentGroup = self.currentItem() currentGroup = self.currentItem()
if currentGroup: if currentGroup:
if currentGroup.parent(): if currentGroup.parent():
text = str(currentGroup.parent().text(0)) text = unicode(currentGroup.parent().text(0))
else: else:
text = str(currentGroup.text(0)) text = unicode(currentGroup.text(0))
if text.rfind(" (") != -1: if text.rfind(" (") != -1:
text = text[0:text.rfind(" (")] text = text[0:text.rfind(" (")]
currentGroup = text currentGroup = text
@ -459,7 +465,7 @@ class chumArea(RightClickTree):
return return
curgroups = [] curgroups = []
for i in range(self.topLevelItemCount()): for i in range(self.topLevelItemCount()):
text = str(self.topLevelItem(i).text(0)) text = unicode(self.topLevelItem(i).text(0))
if text.rfind(" (") != -1: if text.rfind(" (") != -1:
text = text[0:text.rfind(" (")] text = text[0:text.rfind(" (")]
curgroups.append(text) curgroups.append(text)
@ -483,31 +489,31 @@ class chumArea(RightClickTree):
totals = {'Chums': 0} totals = {'Chums': 0}
online = {'Chums': 0} online = {'Chums': 0}
for g in self.groups: for g in self.groups:
totals[str(g)] = 0 totals[unicode(g)] = 0
online[str(g)] = 0 online[unicode(g)] = 0
for c in self.chums: for c in self.chums:
yes = c.mood.name() != "offline" yes = c.mood.name() != "offline"
if c.group == "Chums": if c.group == "Chums":
totals[str(c.group)] = totals[str(c.group)]+1 totals[unicode(c.group)] = totals[unicode(c.group)]+1
if yes: if yes:
online[str(c.group)] = online[str(c.group)]+1 online[unicode(c.group)] = online[unicode(c.group)]+1
elif c.group in totals: elif c.group in totals:
totals[str(c.group)] = totals[str(c.group)]+1 totals[unicode(c.group)] = totals[unicode(c.group)]+1
if yes: if yes:
online[str(c.group)] = online[str(c.group)]+1 online[unicode(c.group)] = online[unicode(c.group)]+1
else: else:
totals["Chums"] = totals["Chums"]+1 totals["Chums"] = totals["Chums"]+1
if yes: if yes:
online["Chums"] = online["Chums"]+1 online["Chums"] = online["Chums"]+1
for i in range(self.topLevelItemCount()): for i in range(self.topLevelItemCount()):
text = str(self.topLevelItem(i).text(0)) text = unicode(self.topLevelItem(i).text(0))
if text.rfind(" (") != -1: if text.rfind(" (") != -1:
text = text[0:text.rfind(" (")] text = text[0:text.rfind(" (")]
if text in online: 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): def hideOnlineNumbers(self):
for i in range(self.topLevelItemCount()): for i in range(self.topLevelItemCount()):
text = str(self.topLevelItem(i).text(0)) text = unicode(self.topLevelItem(i).text(0))
if text.rfind(" (") != -1: if text.rfind(" (") != -1:
text = text[0:text.rfind(" (")] text = text[0:text.rfind(" (")]
self.topLevelItem(i).setText(0, "%s" % (text)) self.topLevelItem(i).setText(0, "%s" % (text))
@ -523,7 +529,7 @@ class chumArea(RightClickTree):
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
def expandGroup(self): def expandGroup(self):
item = self.currentItem() item = self.currentItem()
text = str(item.text(0)) text = unicode(item.text(0))
if text.rfind(" (") != -1: if text.rfind(" (") != -1:
text = text[0:text.rfind(" (")] text = text[0:text.rfind(" (")]
@ -538,7 +544,7 @@ class chumArea(RightClickTree):
self.mainwindow.config.addGroup("Chums") self.mainwindow.config.addGroup("Chums")
curgroups = [] curgroups = []
for i in range(self.topLevelItemCount()): for i in range(self.topLevelItemCount()):
text = str(self.topLevelItem(i).text(0)) text = unicode(self.topLevelItem(i).text(0))
if text.rfind(" (") != -1: if text.rfind(" (") != -1:
text = text[0:text.rfind(" (")] text = text[0:text.rfind(" (")]
curgroups.append(text) curgroups.append(text)
@ -555,7 +561,7 @@ class chumArea(RightClickTree):
if self.openGroups[self.groups.index("%s" % (chumLabel.chum.group))]: if self.openGroups[self.groups.index("%s" % (chumLabel.chum.group))]:
child_1.setExpanded(True) child_1.setExpanded(True)
for i in range(self.topLevelItemCount()): for i in range(self.topLevelItemCount()):
text = str(self.topLevelItem(i).text(0)) text = unicode(self.topLevelItem(i).text(0))
if text.rfind(" (") != -1: if text.rfind(" (") != -1:
text = text[0:text.rfind(" (")] text = text[0:text.rfind(" (")]
if text == chumLabel.chum.group: if text == chumLabel.chum.group:
@ -574,7 +580,7 @@ class chumArea(RightClickTree):
bestname = "" bestname = ""
if fi > 0: if fi > 0:
while not bestj: while not bestj:
for j in range(self.topLevelItem(i).childCount()): for j in xrange(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 bestj = j
bestname = chums[fi-c] bestname = chums[fi-c]
@ -649,7 +655,7 @@ class chumArea(RightClickTree):
def initTheme(self, theme): def initTheme(self, theme):
self.resize(*theme["main/chums/size"]) self.resize(*theme["main/chums/size"])
self.move(*theme["main/chums/loc"]) self.move(*theme["main/chums/loc"])
if "main/chums/scrollbar" in theme: if theme.has_key("main/chums/scrollbar"):
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"] )) 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"] ))
else: else:
self.setStyleSheet(theme["main/chums/style"]) self.setStyleSheet(theme["main/chums/style"])
@ -757,7 +763,7 @@ class chumArea(RightClickTree):
return return
(notes, ok) = QtWidgets.QInputDialog.getText(self, "Notes", "Enter your notes...") (notes, ok) = QtWidgets.QInputDialog.getText(self, "Notes", "Enter your notes...")
if ok: if ok:
notes = str(notes) notes = unicode(notes)
self.mainwindow.chumdb.setNotes(currentChum.handle, notes) self.mainwindow.chumdb.setNotes(currentChum.handle, notes)
currentChum.setToolTip(0, "%s: %s" % (currentChum.handle, notes)) currentChum.setToolTip(0, "%s: %s" % (currentChum.handle, notes))
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
@ -767,7 +773,7 @@ class chumArea(RightClickTree):
if not self.renamegroupdialog: 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: if ok:
gname = str(gname) gname = unicode(gname)
if re.search("[^A-Za-z0-9_\s]", gname) is not None: if re.search("[^A-Za-z0-9_\s]", gname) is not None:
msgbox = QtWidgets.QMessageBox() msgbox = QtWidgets.QMessageBox()
msgbox.setInformativeText("THIS IS NOT A VALID GROUP NAME") msgbox.setInformativeText("THIS IS NOT A VALID GROUP NAME")
@ -781,7 +787,7 @@ class chumArea(RightClickTree):
index = self.indexOfTopLevelItem(currentGroup) index = self.indexOfTopLevelItem(currentGroup)
if index != -1: if index != -1:
expanded = currentGroup.isExpanded() expanded = currentGroup.isExpanded()
text = str(currentGroup.text(0)) text = unicode(currentGroup.text(0))
if text.rfind(" (") != -1: if text.rfind(" (") != -1:
text = text[0:text.rfind(" (")] text = text[0:text.rfind(" (")]
self.mainwindow.config.delGroup(text) self.mainwindow.config.delGroup(text)
@ -801,7 +807,7 @@ class chumArea(RightClickTree):
currentGroup = self.currentItem() currentGroup = self.currentItem()
if not currentGroup: if not currentGroup:
return return
text = str(currentGroup.text(0)) text = unicode(currentGroup.text(0))
if text.rfind(" (") != -1: if text.rfind(" (") != -1:
text = text[0:text.rfind(" (")] text = text[0:text.rfind(" (")]
self.mainwindow.config.delGroup(text) self.mainwindow.config.delGroup(text)
@ -824,7 +830,7 @@ class chumArea(RightClickTree):
def moveToGroup(self, item): def moveToGroup(self, item):
if not item: if not item:
return return
group = str(item.text()) group = unicode(item.text())
chumLabel = self.currentItem() chumLabel = self.currentItem()
if not chumLabel: if not chumLabel:
return return
@ -939,7 +945,7 @@ class TrollSlumWindow(QtWidgets.QFrame):
self.addtrolldialog = QtWidgets.QInputDialog(self) 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: if ok:
handle = str(handle) handle = unicode(handle)
if not (PesterProfile.checkLength(handle) and if not (PesterProfile.checkLength(handle) and
PesterProfile.checkValid(handle)[0]): PesterProfile.checkValid(handle)[0]):
errormsg = QtWidgets.QErrorMessage(self) errormsg = QtWidgets.QErrorMessage(self)
@ -990,9 +996,8 @@ class PesterWindow(MovingWindow):
try: try:
themeChecker(self.theme) themeChecker(self.theme)
except ThemeException as xxx_todo_changeme: except ThemeException, (inst):
(inst) = xxx_todo_changeme print "Caught: "+inst.parameter
print("Caught: "+inst.parameter)
themeWarning = QtWidgets.QMessageBox(self) themeWarning = QtWidgets.QMessageBox(self)
themeWarning.setText("Theme Error: %s" % (inst)) themeWarning.setText("Theme Error: %s" % (inst))
themeWarning.exec_() themeWarning.exec_()
@ -1152,7 +1157,7 @@ class PesterWindow(MovingWindow):
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
def updatePC(self): def updatePC(self):
version.updateDownload(str(self.updatemenu.url)) version.updateDownload(unicode(self.updatemenu.url))
self.updatemenu = None self.updatemenu = None
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
def noUpdatePC(self): def noUpdatePC(self):
@ -1208,7 +1213,7 @@ class PesterWindow(MovingWindow):
return return
# notify # notify
if self.config.notifyOptions() & self.config.NEWMSG: if self.config.notifyOptions() & self.config.NEWMSG:
if handle not in self.convos: if not self.convos.has_key(handle):
t = self.tm.Toast("New Conversation", "From: %s" % handle) t = self.tm.Toast("New Conversation", "From: %s" % handle)
t.show() t.show()
elif not self.config.notifyOptions() & self.config.NEWCONVO: elif not self.config.notifyOptions() & self.config.NEWCONVO:
@ -1226,7 +1231,7 @@ class PesterWindow(MovingWindow):
elif msg == "PESTERCHUM:UNBLOCK": elif msg == "PESTERCHUM:UNBLOCK":
t = self.tm.Toast("Unblocked", handle) t = self.tm.Toast("Unblocked", handle)
t.show() t.show()
if handle not in self.convos: if not self.convos.has_key(handle):
if msg == "PESTERCHUM:CEASE": # ignore cease after we hang up if msg == "PESTERCHUM:CEASE": # ignore cease after we hang up
return return
matchingChums = [c for c in self.chumList.chums if c.handle == handle] matchingChums = [c for c in self.chumList.chums if c.handle == handle]
@ -1248,12 +1253,12 @@ class PesterWindow(MovingWindow):
else: else:
self.alarm.play() self.alarm.play()
def newMemoMsg(self, chan, handle, msg): def newMemoMsg(self, chan, handle, msg):
if chan not in self.memos: if not self.memos.has_key(chan):
# silently ignore in case we forgot to /part # silently ignore in case we forgot to /part
return return
memo = self.memos[chan] memo = self.memos[chan]
msg = str(msg) msg = unicode(msg)
if handle not in memo.times: if not memo.times.has_key(handle):
# new chum! time current # new chum! time current
newtime = timedelta(0) newtime = timedelta(0)
time = TimeTracker(newtime) time = TimeTracker(newtime)
@ -1291,19 +1296,19 @@ class PesterWindow(MovingWindow):
def changeColor(self, handle, color): def changeColor(self, handle, color):
# pesterconvo and chumlist # pesterconvo and chumlist
self.chumList.updateColor(handle, color) self.chumList.updateColor(handle, color)
if handle in self.convos: if self.convos.has_key(handle):
self.convos[handle].updateColor(color) self.convos[handle].updateColor(color)
self.chumdb.setColor(handle, color) self.chumdb.setColor(handle, color)
def updateMood(self, handle, mood): def updateMood(self, handle, mood):
# updates OTHER chums' moods # updates OTHER chums' moods
oldmood = self.chumList.updateMood(handle, mood) oldmood = self.chumList.updateMood(handle, mood)
if handle in self.convos: if self.convos.has_key(handle):
self.convos[handle].updateMood(mood, old=oldmood) 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) self.trollslum.updateMood(handle, mood)
def newConversation(self, chum, initiated=True): def newConversation(self, chum, initiated=True):
if type(chum) in [str, str]: if type(chum) in [str, unicode]:
matchingChums = [c for c in self.chumList.chums if c.handle == chum] matchingChums = [c for c in self.chumList.chums if c.handle == chum]
if len(matchingChums) > 0: if len(matchingChums) > 0:
mood = matchingChums[0].mood mood = matchingChums[0].mood
@ -1313,7 +1318,7 @@ class PesterWindow(MovingWindow):
if len(matchingChums) == 0: if len(matchingChums) == 0:
self.moodRequest.emit(chum) self.moodRequest.emit(chum)
if chum.handle in self.convos: if self.convos.has_key(chum.handle):
self.convos[chum.handle].showChat() self.convos[chum.handle].showChat()
return return
if self.config.tabs(): if self.config.tabs():
@ -1326,10 +1331,10 @@ class PesterWindow(MovingWindow):
convoWindow.messageSent.connect(self.sendMessage) convoWindow.messageSent.connect(self.sendMessage)
convoWindow.windowClosed.connect(self.closeConvo) convoWindow.windowClosed.connect(self.closeConvo)
self.convos[chum.handle] = convoWindow self.convos[chum.handle] = convoWindow
if str(chum.handle).upper() in BOTNAMES: if unicode(chum.handle).upper() in BOTNAMES:
convoWindow.toggleQuirks(True) convoWindow.toggleQuirks(True)
convoWindow.quirksOff.setChecked(True) convoWindow.quirksOff.setChecked(True)
if str(chum.handle).upper() in CUSTOMBOTS: if unicode(chum.handle).upper() in CUSTOMBOTS:
self.newConvoStarted.emit(chum.handle, initiated) self.newConvoStarted.emit(chum.handle, initiated)
else: else:
self.newConvoStarted.emit(chum.handle, initiated) self.newConvoStarted.emit(chum.handle, initiated)
@ -1345,7 +1350,7 @@ class PesterWindow(MovingWindow):
def newMemo(self, channel, timestr, secret=False, invite=False): def newMemo(self, channel, timestr, secret=False, invite=False):
if channel == "#pesterchum": if channel == "#pesterchum":
return return
if channel in self.memos: if self.memos.has_key(channel):
self.memos[channel].showChat() self.memos[channel].showChat()
return return
# do slider dialog then set # do slider dialog then set
@ -1460,19 +1465,19 @@ class PesterWindow(MovingWindow):
if hasattr(self, 'moods'): if hasattr(self, 'moods'):
self.moods.removeButtons() self.moods.removeButtons()
mood_list = theme["main/moods"] mood_list = theme["main/moods"]
mood_list = [dict([(str(k),v) for (k,v) in d.items()]) mood_list = [dict([(str(k),v) for (k,v) in d.iteritems()])
for d in mood_list] for d in mood_list]
self.moods = PesterMoodHandler(self, *[PesterMoodButton(self, **d) for d in mood_list]) self.moods = PesterMoodHandler(self, *[PesterMoodButton(self, **d) for d in mood_list])
self.moods.showButtons() self.moods.showButtons()
# chum # chum
addChumStyle = "QPushButton { %s }" % (theme["main/addchum/style"]) addChumStyle = "QPushButton { %s }" % (theme["main/addchum/style"])
if "main/addchum/pressed" in theme: if theme.has_key("main/addchum/pressed"):
addChumStyle += "QPushButton:pressed { %s }" % (theme["main/addchum/pressed"]) addChumStyle += "QPushButton:pressed { %s }" % (theme["main/addchum/pressed"])
pesterButtonStyle = "QPushButton { %s }" % (theme["main/pester/style"]) pesterButtonStyle = "QPushButton { %s }" % (theme["main/pester/style"])
if "main/pester/pressed" in theme: if theme.has_key("main/pester/pressed"):
pesterButtonStyle += "QPushButton:pressed { %s }" % (theme["main/pester/pressed"]) pesterButtonStyle += "QPushButton:pressed { %s }" % (theme["main/pester/pressed"])
blockButtonStyle = "QPushButton { %s }" % (theme["main/block/style"]) blockButtonStyle = "QPushButton { %s }" % (theme["main/block/style"])
if "main/block/pressed" in theme: if theme.has_key("main/block/pressed"):
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.setText(theme["main/addchum/text"])
self.addChumButton.resize(*theme["main/addchum/size"]) self.addChumButton.resize(*theme["main/addchum/size"])
@ -1497,7 +1502,7 @@ class PesterWindow(MovingWindow):
self.mychumcolor.resize(*theme["main/mychumhandle/colorswatch/size"]) self.mychumcolor.resize(*theme["main/mychumhandle/colorswatch/size"])
self.mychumcolor.move(*theme["main/mychumhandle/colorswatch/loc"]) self.mychumcolor.move(*theme["main/mychumhandle/colorswatch/loc"])
self.mychumcolor.setStyleSheet("background: %s" % (self.profile().colorhtml())) self.mychumcolor.setStyleSheet("background: %s" % (self.profile().colorhtml()))
if "main/mychumhandle/currentMood" in self.theme: if self.theme.has_key("main/mychumhandle/currentMood"):
moodicon = self.profile().mood.icon(theme) 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.hide()
@ -1518,36 +1523,40 @@ class PesterWindow(MovingWindow):
self.mychumcolor.setText("") self.mychumcolor.setText("")
# sounds # sounds
try: if not pygame or not pygame.mixer:
self.alarm, self.memosound, self.namesound, self.ceasesound, self.honksound = \
[QtMultimedia.QSoundEffect() for i in range(5)]
self.alarm.setSource(QtCore.QUrl.fromLocalFile(theme["main/sounds/alertsound"]))
self.memosound.setSource(QtCore.QUrl.fromLocalFile(theme["main/sounds/memosound"]))
self.namesound.setSource(QtCore.QUrl.fromLocalFile("themes/namealarm.wav"))
self.ceasesound.setSource(QtCore.QUrl.fromLocalFile(theme["main/sounds/ceasesound"]))
self.honksound.setSource(QtCore.QUrl.fromLocalFile("themes/honk.wav"))
except Exception as e:
self.alarm = NoneSound() self.alarm = NoneSound()
self.memosound = NoneSound() self.memosound = NoneSound()
self.namesound = NoneSound() self.namesound = NoneSound()
self.ceasesound = NoneSound() self.ceasesound = NoneSound()
self.honksound = NoneSound() self.honksound = NoneSound()
else:
try:
self.alarm = pygame.mixer.Sound(theme["main/sounds/alertsound"])
self.memosound = pygame.mixer.Sound(theme["main/sounds/memosound"])
self.namesound = pygame.mixer.Sound("themes/namealarm.wav")
self.ceasesound = pygame.mixer.Sound(theme["main/sounds/ceasesound"])
self.honksound = pygame.mixer.Sound("themes/honk.wav")
except Exception, e:
self.alarm = NoneSound()
self.memosound = NoneSound()
self.namesound = NoneSound()
self.ceasesound = NoneSound()
self.honksound = NoneSound()
self.setVolume(self.config.volume()) self.setVolume(self.config.volume())
def setVolume(self, vol): def setVolume(self, vol):
vol = vol/100.0 vol = vol/100.0
self.alarm.setVolume(vol) self.alarm.set_volume(vol)
self.memosound.setVolume(vol) self.memosound.set_volume(vol)
self.namesound.setVolume(vol) self.namesound.set_volume(vol)
self.ceasesound.setVolume(vol) self.ceasesound.set_volume(vol)
self.honksound.setVolume(vol) self.honksound.set_volume(vol)
def changeTheme(self, theme): def changeTheme(self, theme):
# check theme # check theme
try: try:
themeChecker(theme) themeChecker(theme)
except ThemeException as xxx_todo_changeme1: except ThemeException, (inst):
(inst) = xxx_todo_changeme1
themeWarning = QtWidgets.QMessageBox(self) themeWarning = QtWidgets.QMessageBox(self)
themeWarning.setText("Theme Error: %s" % (inst)) themeWarning.setText("Theme Error: %s" % (inst))
themeWarning.exec_() themeWarning.exec_()
@ -1630,7 +1639,7 @@ class PesterWindow(MovingWindow):
def pesterSelectedChum(self): def pesterSelectedChum(self):
curChum = self.chumList.currentItem() curChum = self.chumList.currentItem()
if curChum: if curChum:
text = str(curChum.text(0)) text = unicode(curChum.text(0))
if text.rfind(" (") != -1: if text.rfind(" (") != -1:
text = text[0:text.rfind(" (")] text = text[0:text.rfind(" (")]
if text not in self.chumList.groups and \ if text not in self.chumList.groups and \
@ -1646,7 +1655,7 @@ class PesterWindow(MovingWindow):
self.newConversation(chum) self.newConversation(chum)
@QtCore.pyqtSlot('QString') @QtCore.pyqtSlot('QString')
def closeConvo(self, handle): def closeConvo(self, handle):
h = str(handle) h = unicode(handle)
try: try:
chum = self.convos[h].chum chum = self.convos[h].chum
except KeyError: except KeyError:
@ -1662,7 +1671,7 @@ class PesterWindow(MovingWindow):
del self.convos[h] del self.convos[h]
@QtCore.pyqtSlot('QString') @QtCore.pyqtSlot('QString')
def closeMemo(self, channel): def closeMemo(self, channel):
c = str(channel) c = unicode(channel)
self.chatlog.finish(c) self.chatlog.finish(c)
self.leftChannel.emit(channel) self.leftChannel.emit(channel)
try: try:
@ -1680,27 +1689,27 @@ class PesterWindow(MovingWindow):
@QtCore.pyqtSlot('QString', Mood) @QtCore.pyqtSlot('QString', Mood)
def updateMoodSlot(self, handle, mood): def updateMoodSlot(self, handle, mood):
h = str(handle) h = unicode(handle)
self.updateMood(h, mood) self.updateMood(h, mood)
@QtCore.pyqtSlot('QString', QtGui.QColor) @QtCore.pyqtSlot('QString', QtGui.QColor)
def updateColorSlot(self, handle, color): def updateColorSlot(self, handle, color):
h = str(handle) h = unicode(handle)
self.changeColor(h, color) self.changeColor(h, color)
@QtCore.pyqtSlot('QString', 'QString') @QtCore.pyqtSlot('QString', 'QString')
def deliverMessage(self, handle, msg): def deliverMessage(self, handle, msg):
h = str(handle) h = unicode(handle)
m = str(msg) m = unicode(msg)
self.newMessage(h, m) self.newMessage(h, m)
@QtCore.pyqtSlot('QString', 'QString', 'QString') @QtCore.pyqtSlot('QString', 'QString', 'QString')
def deliverMemo(self, chan, handle, msg): def deliverMemo(self, chan, handle, msg):
(c, h, m) = (str(chan), str(handle), str(msg)) (c, h, m) = (unicode(chan), unicode(handle), unicode(msg))
self.newMemoMsg(c,h,m) self.newMemoMsg(c,h,m)
@QtCore.pyqtSlot('QString', 'QString') @QtCore.pyqtSlot('QString', 'QString')
def deliverNotice(self, handle, msg): def deliverNotice(self, handle, msg):
h = str(handle) h = unicode(handle)
m = str(msg) m = unicode(msg)
if m.startswith("Your nickname is now being changed to"): if m.startswith("Your nickname is now being changed to"):
changedto = m[39:-1] changedto = m[39:-1]
msgbox = QtWidgets.QMessageBox() msgbox = QtWidgets.QMessageBox()
@ -1710,7 +1719,7 @@ class PesterWindow(MovingWindow):
ret = msgbox.exec_() ret = msgbox.exec_()
elif h == self.randhandler.randNick: elif h == self.randhandler.randNick:
self.randhandler.incoming(msg) self.randhandler.incoming(msg)
elif h in self.convos: elif self.convos.has_key(h):
self.newMessage(h, m) self.newMessage(h, m)
elif h.upper() == "NICKSERV" and "PESTERCHUM:" not in m: elif h.upper() == "NICKSERV" and "PESTERCHUM:" not in m:
m = nickservmsgs.translate(m) m = nickservmsgs.translate(m)
@ -1725,7 +1734,7 @@ class PesterWindow(MovingWindow):
msgbox.setStandardButtons(QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel) msgbox.setStandardButtons(QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel)
ret = msgbox.exec_() ret = msgbox.exec_()
if ret == QtWidgets.QMessageBox.Ok: if ret == QtWidgets.QMessageBox.Ok:
self.newMemo(str(channel), "+0:00") self.newMemo(unicode(channel), "+0:00")
@QtCore.pyqtSlot('QString') @QtCore.pyqtSlot('QString')
def chanInviteOnly(self, channel): def chanInviteOnly(self, channel):
self.inviteOnlyChan.emit(channel) self.inviteOnlyChan.emit(channel)
@ -1737,35 +1746,35 @@ class PesterWindow(MovingWindow):
self.modesUpdated.emit(channel, modes) self.modesUpdated.emit(channel, modes)
@QtCore.pyqtSlot('QString', 'QString', 'QString') @QtCore.pyqtSlot('QString', 'QString', 'QString')
def timeCommand(self, chan, handle, command): def timeCommand(self, chan, handle, command):
(c, h, cmd) = (str(chan), str(handle), str(command)) (c, h, cmd) = (unicode(chan), unicode(handle), unicode(command))
if self.memos[c]: if self.memos[c]:
self.memos[c].timeUpdate(h, cmd) self.memos[c].timeUpdate(h, cmd)
@QtCore.pyqtSlot('QString', 'QString', 'QString') @QtCore.pyqtSlot('QString', 'QString', 'QString')
def quirkDisable(self, channel, msg, op): def quirkDisable(self, channel, msg, op):
(c, msg, op) = (str(channel), str(msg), str(op)) (c, msg, op) = (unicode(channel), unicode(msg), unicode(op))
if c not in self.memos: if not self.memos.has_key(c):
return return
memo = self.memos[c] memo = self.memos[c]
memo.quirkDisable(op, msg) memo.quirkDisable(op, msg)
@QtCore.pyqtSlot('QString', PesterList) @QtCore.pyqtSlot('QString', PesterList)
def updateNames(self, channel, names): def updateNames(self, channel, names):
c = str(channel) c = unicode(channel)
# update name DB # update name DB
self.namesdb[c] = names self.namesdb[c] = names
# warn interested party of names # warn interested party of names
self.namesUpdated.emit(c) self.namesUpdated.emit(c)
@QtCore.pyqtSlot('QString', 'QString', 'QString') @QtCore.pyqtSlot('QString', 'QString', 'QString')
def userPresentUpdate(self, handle, channel, update): def userPresentUpdate(self, handle, channel, update):
c = str(channel) c = unicode(channel)
n = str(handle) n = unicode(handle)
if update == "nick": if update == "nick":
l = n.split(":") l = n.split(":")
oldnick = l[0] oldnick = l[0]
newnick = l[1] newnick = l[1]
if update in ("quit", "netsplit"): if update in ("quit", "netsplit"):
for c in list(self.namesdb.keys()): for c in self.namesdb.keys():
try: try:
i = self.namesdb[c].index(n) i = self.namesdb[c].index(n)
self.namesdb[c].pop(i) self.namesdb[c].pop(i)
@ -1782,7 +1791,7 @@ class PesterWindow(MovingWindow):
except KeyError: except KeyError:
self.namesdb[c] = [] self.namesdb[c] = []
elif update == "nick": elif update == "nick":
for c in list(self.namesdb.keys()): for c in self.namesdb.keys():
try: try:
i = self.namesdb[c].index(oldnick) i = self.namesdb[c].index(oldnick)
self.namesdb[c].pop(i) self.namesdb[c].pop(i)
@ -1809,12 +1818,12 @@ class PesterWindow(MovingWindow):
available_groups = [g[0] for g in self.config.getGroups()] available_groups = [g[0] for g in self.config.getGroups()]
self.addchumdialog = AddChumDialog(available_groups, self) self.addchumdialog = AddChumDialog(available_groups, self)
ok = self.addchumdialog.exec_() ok = self.addchumdialog.exec_()
handle = str(self.addchumdialog.chumBox.text()).strip() handle = unicode(self.addchumdialog.chumBox.text()).strip()
newgroup = str(self.addchumdialog.newgroup.text()).strip() newgroup = unicode(self.addchumdialog.newgroup.text()).strip()
selectedGroup = self.addchumdialog.groupBox.currentText() selectedGroup = self.addchumdialog.groupBox.currentText()
group = newgroup if newgroup else selectedGroup group = newgroup if newgroup else selectedGroup
if ok: if ok:
handle = str(handle) handle = unicode(handle)
if handle in [h.handle for h in self.chumList.chums]: if handle in [h.handle for h in self.chumList.chums]:
self.addchumdialog = None self.addchumdialog = None
return return
@ -1846,10 +1855,10 @@ class PesterWindow(MovingWindow):
@QtCore.pyqtSlot('QString') @QtCore.pyqtSlot('QString')
def blockChum(self, handle): def blockChum(self, handle):
h = str(handle) h = unicode(handle)
self.config.addBlocklist(h) self.config.addBlocklist(h)
self.config.removeChum(h) self.config.removeChum(h)
if h in self.convos: if self.convos.has_key(h):
convo = self.convos[h] 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)) convo.textArea.append(convertTags(msg))
@ -1864,9 +1873,9 @@ class PesterWindow(MovingWindow):
@QtCore.pyqtSlot('QString') @QtCore.pyqtSlot('QString')
def unblockChum(self, handle): def unblockChum(self, handle):
h = str(handle) h = unicode(handle)
self.config.delBlocklist(h) self.config.delBlocklist(h)
if h in self.convos: if self.convos.has_key(h):
convo = self.convos[h] 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)) convo.textArea.append(convertTags(msg))
@ -1887,7 +1896,7 @@ class PesterWindow(MovingWindow):
self.randhandler.setIdle(True) self.randhandler.setIdle(True)
sysColor = QtGui.QColor(self.theme["convo/systemMsgColor"]) sysColor = QtGui.QColor(self.theme["convo/systemMsgColor"])
verb = self.theme["convo/text/idle"] verb = self.theme["convo/text/idle"]
for (h, convo) in self.convos.items(): for (h, convo) in self.convos.iteritems():
if convo.chumopen: if convo.chumopen:
msg = self.profile().idlemsg(sysColor, verb) msg = self.profile().idlemsg(sysColor, verb)
convo.textArea.append(convertTags(msg)) convo.textArea.append(convertTags(msg))
@ -1921,7 +1930,7 @@ class PesterWindow(MovingWindow):
return return
fp = open(f, 'r') fp = open(f, 'r')
regexp_state = None regexp_state = None
for l in fp: for l in fp.xreadlines():
# import chumlist # import chumlist
l = l.rstrip() l = l.rstrip()
chum_mo = re.match("handle: ([A-Za-z0-9]+)", l) chum_mo = re.match("handle: ([A-Za-z0-9]+)", l)
@ -1935,7 +1944,7 @@ class PesterWindow(MovingWindow):
replace = replace_mo.group(1) replace = replace_mo.group(1)
try: try:
re.compile(regexp_state) re.compile(regexp_state)
except re.error as e: except re.error, e:
continue continue
newquirk = pesterQuirk({"type": "regexp", newquirk = pesterQuirk({"type": "regexp",
"from": regexp_state, "from": regexp_state,
@ -1971,18 +1980,18 @@ class PesterWindow(MovingWindow):
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
def joinSelectedMemo(self): def joinSelectedMemo(self):
time = str(self.memochooser.timeinput.text()) time = unicode(self.memochooser.timeinput.text())
secret = self.memochooser.secretChannel.isChecked() secret = self.memochooser.secretChannel.isChecked()
invite = self.memochooser.inviteChannel.isChecked() invite = self.memochooser.inviteChannel.isChecked()
if self.memochooser.newmemoname(): if self.memochooser.newmemoname():
newmemo = self.memochooser.newmemoname() newmemo = self.memochooser.newmemoname()
channel = "#"+str(newmemo).replace(" ", "_") channel = "#"+unicode(newmemo).replace(" ", "_")
channel = re.sub(r"[^A-Za-z0-9#_]", "", channel) channel = re.sub(r"[^A-Za-z0-9#_]", "", channel)
self.newMemo(channel, time, secret=secret, invite=invite) self.newMemo(channel, time, secret=secret, invite=invite)
for SelectedMemo in self.memochooser.SelectedMemos(): for SelectedMemo in self.memochooser.SelectedMemos():
channel = "#"+str(SelectedMemo.target) channel = "#"+unicode(SelectedMemo.target)
self.newMemo(channel, time) self.newMemo(channel, time)
self.memochooser = None self.memochooser = None
@ -2009,12 +2018,12 @@ class PesterWindow(MovingWindow):
@QtCore.pyqtSlot('QString') @QtCore.pyqtSlot('QString')
def userListAdd(self, handle): def userListAdd(self, handle):
h = str(handle) h = unicode(handle)
chum = PesterProfile(h, chumdb=self.chumdb) chum = PesterProfile(h, chumdb=self.chumdb)
self.addChum(chum) self.addChum(chum)
@QtCore.pyqtSlot('QString') @QtCore.pyqtSlot('QString')
def userListPester(self, handle): def userListPester(self, handle):
h = str(handle) h = unicode(handle)
self.newConversation(h) self.newConversation(h)
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
def userListClose(self): def userListClose(self):
@ -2034,7 +2043,7 @@ class PesterWindow(MovingWindow):
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
def updateQuirks(self): def updateQuirks(self):
for i in range(self.quirkmenu.quirkList.topLevelItemCount()): for i in range(self.quirkmenu.quirkList.topLevelItemCount()):
curgroup = str(self.quirkmenu.quirkList.topLevelItem(i).text(0)) curgroup = unicode(self.quirkmenu.quirkList.topLevelItem(i).text(0))
for j in range(self.quirkmenu.quirkList.topLevelItem(i).childCount()): for j in range(self.quirkmenu.quirkList.topLevelItem(i).childCount()):
item = self.quirkmenu.quirkList.topLevelItem(i).child(j) item = self.quirkmenu.quirkList.topLevelItem(i).child(j)
item.quirk.quirk["on"] = item.quirk.on = (item.checkState(0) == QtCore.Qt.Checked) item.quirk.quirk["on"] = item.quirk.on = (item.checkState(0) == QtCore.Qt.Checked)
@ -2057,7 +2066,7 @@ class PesterWindow(MovingWindow):
(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: try:
if ok: if ok:
self.newConversation(str(chum)) self.newConversation(unicode(chum))
except: except:
pass pass
finally: finally:
@ -2085,7 +2094,7 @@ class PesterWindow(MovingWindow):
if not self.addgroupdialog: 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: if ok:
gname = str(gname) gname = unicode(gname)
if re.search("[^A-Za-z0-9_\s]", gname) is not None: if re.search("[^A-Za-z0-9_\s]", gname) is not None:
msgbox = QtWidgets.QMessageBox() msgbox = QtWidgets.QMessageBox()
msgbox.setInformativeText("THIS IS NOT A VALID GROUP NAME") msgbox.setInformativeText("THIS IS NOT A VALID GROUP NAME")
@ -2135,7 +2144,7 @@ class PesterWindow(MovingWindow):
# combine # combine
self.createTabWindow() self.createTabWindow()
newconvos = {} newconvos = {}
for (h,c) in self.convos.items(): for (h,c) in self.convos.iteritems():
c.setParent(self.tabconvo) c.setParent(self.tabconvo)
self.tabconvo.addChat(c) self.tabconvo.addChat(c)
self.tabconvo.show() self.tabconvo.show()
@ -2165,7 +2174,7 @@ class PesterWindow(MovingWindow):
# combine # combine
newmemos = {} newmemos = {}
self.createMemoTabWindow() self.createMemoTabWindow()
for (h,m) in self.memos.items(): for (h,m) in self.memos.iteritems():
m.setParent(self.tabmemo) m.setParent(self.tabmemo)
self.tabmemo.addChat(m) self.tabmemo.addChat(m)
self.tabmemo.show() self.tabmemo.show()
@ -2214,7 +2223,7 @@ class PesterWindow(MovingWindow):
# timestamps # timestamps
timestampsetting = self.optionmenu.timestampcheck.isChecked() timestampsetting = self.optionmenu.timestampcheck.isChecked()
self.config.set("showTimeStamps", timestampsetting) self.config.set("showTimeStamps", timestampsetting)
timeformatsetting = str(self.optionmenu.timestampBox.currentText()) timeformatsetting = unicode(self.optionmenu.timestampBox.currentText())
if timeformatsetting == "12 hour": if timeformatsetting == "12 hour":
self.config.set("time12Format", True) self.config.set("time12Format", True)
else: else:
@ -2324,7 +2333,7 @@ class PesterWindow(MovingWindow):
self.config.set('blink', blinksetting) self.config.set('blink', blinksetting)
# toast notifications # toast notifications
self.tm.setEnabled(self.optionmenu.notifycheck.isChecked()) self.tm.setEnabled(self.optionmenu.notifycheck.isChecked())
self.tm.setCurrentType(str(self.optionmenu.notifyOptions.currentText())) self.tm.setCurrentType(unicode(self.optionmenu.notifyOptions.currentText()))
notifysetting = 0 notifysetting = 0
if self.optionmenu.notifySigninCheck.isChecked(): if self.optionmenu.notifySigninCheck.isChecked():
notifysetting |= self.config.SIGNIN notifysetting |= self.config.SIGNIN
@ -2364,7 +2373,7 @@ class PesterWindow(MovingWindow):
newmodes = self.optionmenu.modechange.text() newmodes = self.optionmenu.modechange.text()
if newmodes: if newmodes:
self.setChannelMode.emit(self.profile().handle, newmodes, "") self.setChannelMode.emit(self.profile().handle, newmodes, "")
except Exception as e: except Exception, e:
logging.error(e) logging.error(e)
finally: finally:
self.optionmenu = None self.optionmenu = None
@ -2391,13 +2400,13 @@ class PesterWindow(MovingWindow):
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
def themeSelected(self, override=False): def themeSelected(self, override=False):
if not override: if not override:
themename = str(self.optionmenu.themeBox.currentText()) themename = unicode(self.optionmenu.themeBox.currentText())
else: else:
themename = override themename = override
if override or themename != self.theme.name: if override or themename != self.theme.name:
try: try:
self.changeTheme(pesterTheme(themename)) self.changeTheme(pesterTheme(themename))
except ValueError as e: except ValueError, e:
themeWarning = QtWidgets.QMessageBox(self) themeWarning = QtWidgets.QMessageBox(self)
themeWarning.setText("Theme Error: %s" % (e)) themeWarning.setText("Theme Error: %s" % (e))
themeWarning.exec_() themeWarning.exec_()
@ -2413,14 +2422,14 @@ class PesterWindow(MovingWindow):
def profileSelected(self): def profileSelected(self):
if self.chooseprofile.profileBox and \ if self.chooseprofile.profileBox and \
self.chooseprofile.profileBox.currentIndex() > 0: self.chooseprofile.profileBox.currentIndex() > 0:
handle = str(self.chooseprofile.profileBox.currentText()) handle = unicode(self.chooseprofile.profileBox.currentText())
if handle == self.profile().handle: if handle == self.profile().handle:
self.chooseprofile = None self.chooseprofile = None
return return
self.userprofile = userProfile(handle) self.userprofile = userProfile(handle)
self.changeTheme(self.userprofile.getTheme()) self.changeTheme(self.userprofile.getTheme())
else: else:
handle = str(self.chooseprofile.chumHandle.text()) handle = unicode(self.chooseprofile.chumHandle.text())
if handle == self.profile().handle: if handle == self.profile().handle:
self.chooseprofile = None self.chooseprofile = None
return return
@ -2519,7 +2528,7 @@ class PesterWindow(MovingWindow):
if not hasattr(self, 'chooseprofile'): if not hasattr(self, 'chooseprofile'):
self.chooseprofile = None self.chooseprofile = None
if not self.chooseprofile: if not self.chooseprofile:
h = str(handle) h = unicode(handle)
self.changeProfile(collision=h) self.changeProfile(collision=h)
@QtCore.pyqtSlot('QString') @QtCore.pyqtSlot('QString')
def myHandleChanged(self, handle): def myHandleChanged(self, handle):
@ -2607,6 +2616,15 @@ class MainProgram(QtCore.QObject):
options = self.oppts(sys.argv[1:]) options = self.oppts(sys.argv[1:])
if pygame and pygame.mixer:
# we could set the frequency higher but i love how cheesy it sounds
try:
pygame.mixer.init()
pygame.mixer.init()
except pygame.error, e:
print "Warning: No sound! %s" % (e)
else:
print "Warning: No sound!"
self.widget = PesterWindow(options, app=self.app) self.widget = PesterWindow(options, app=self.app)
self.widget.show() self.widget.show()
@ -2664,7 +2682,7 @@ class MainProgram(QtCore.QObject):
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
def runUpdateSlot(self): def runUpdateSlot(self):
q = queue.Queue(1) q = Queue.Queue(1)
s = threading.Thread(target=version.updateCheck, args=(q,)) s = threading.Thread(target=version.updateCheck, args=(q,))
w = threading.Thread(target=self.showUpdate, args=(q,)) w = threading.Thread(target=self.showUpdate, args=(q,))
w.start() w.start()
@ -2795,7 +2813,7 @@ Click this message to never see this again.")
for c in self.widget.tabmemo.convos: for c in self.widget.tabmemo.convos:
self.irc.joinChannel(c) self.irc.joinChannel(c)
else: else:
for c in list(self.widget.memos.values()): for c in self.widget.memos.values():
self.irc.joinChannel(c.channel) self.irc.joinChannel(c.channel)
return True return True

View file

@ -41,17 +41,17 @@ class PesterLog(object):
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: if not self.parent.config.logPesters() & self.parent.config.STAMP:
time = "" time = ""
if str(handle).upper() == "NICKSERV": return if unicode(handle).upper() == "NICKSERV": return
#watch out for illegal characters #watch out for illegal characters
handle = re.sub(r'[<>:"/\\|?*]', "_", handle) handle = re.sub(r'[<>:"/\\|?*]', "_", handle)
bbcodemsg = time + convertTags(msg, "bbcode") bbcodemsg = time + convertTags(msg, "bbcode")
html = time + convertTags(msg, "html")+"<br />" html = time + convertTags(msg, "html")+"<br />"
msg = time +convertTags(msg, "text") msg = time +convertTags(msg, "text")
modes = {"bbcode": bbcodemsg, "html": html, "text": msg} modes = {"bbcode": bbcodemsg, "html": html, "text": msg}
if handle not in self.convos: if not self.convos.has_key(handle):
time = datetime.now().strftime("%Y-%m-%d.%H.%M") time = datetime.now().strftime("%Y-%m-%d.%H.%M")
self.convos[handle] = {} self.convos[handle] = {}
for (format, t) in modes.items(): for (format, t) in modes.iteritems():
if not os.path.exists("%s/%s/%s/%s" % (self.logpath, self.handle, handle, format)): 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)) os.makedirs("%s/%s/%s/%s" % (self.logpath, self.handle, handle, format))
try: try:
@ -63,7 +63,7 @@ class PesterLog(object):
errmsg.show() errmsg.show()
continue continue
self.convos[handle][format] = fp self.convos[handle][format] = fp
for (format, t) in modes.items(): for (format, t) in modes.iteritems():
f = self.convos[handle][format] f = self.convos[handle][format]
if platform.system() == "Windows": if platform.system() == "Windows":
f.write(t+"\r\n") f.write(t+"\r\n")
@ -71,14 +71,14 @@ class PesterLog(object):
f.write(t+"\r\n") f.write(t+"\r\n")
f.flush() f.flush()
def finish(self, handle): def finish(self, handle):
if handle not in self.convos: if not self.convos.has_key(handle):
return return
for f in list(self.convos[handle].values()): for f in self.convos[handle].values():
f.close() f.close()
del self.convos[handle] del self.convos[handle]
def close(self): def close(self):
for h in list(self.convos.keys()): for h in self.convos.keys():
for f in list(self.convos[h].values()): for f in self.convos[h].values():
f.close() f.close()
class userConfig(object): class userConfig(object):
@ -100,7 +100,7 @@ class userConfig(object):
fp = open(self.filename) fp = open(self.filename)
self.config = json.load(fp) self.config = json.load(fp)
fp.close() fp.close()
if "defaultprofile" in self.config: if self.config.has_key("defaultprofile"):
self.userprofile = userProfile(self.config["defaultprofile"]) self.userprofile = userProfile(self.config["defaultprofile"])
else: else:
self.userprofile = None self.userprofile = None
@ -125,7 +125,7 @@ class userConfig(object):
fp.close() fp.close()
def chums(self): def chums(self):
if 'chums' not in self.config: if not self.config.has_key('chums'):
self.set("chums", []) self.set("chums", [])
return self.config.get('chums', []) return self.config.get('chums', [])
def setChums(self, newchums): def setChums(self, newchums):
@ -148,19 +148,19 @@ class userConfig(object):
def tabs(self): def tabs(self):
return self.config.get("tabs", True) return self.config.get("tabs", True)
def tabMemos(self): def tabMemos(self):
if 'tabmemos' not in self.config: if not self.config.has_key('tabmemos'):
self.set("tabmemos", self.tabs()) self.set("tabmemos", self.tabs())
return self.config.get("tabmemos", True) return self.config.get("tabmemos", True)
def showTimeStamps(self): def showTimeStamps(self):
if 'showTimeStamps' not in self.config: if not self.config.has_key('showTimeStamps'):
self.set("showTimeStamps", True) self.set("showTimeStamps", True)
return self.config.get('showTimeStamps', True) return self.config.get('showTimeStamps', True)
def time12Format(self): def time12Format(self):
if 'time12Format' not in self.config: if not self.config.has_key('time12Format'):
self.set("time12Format", True) self.set("time12Format", True)
return self.config.get('time12Format', True) return self.config.get('time12Format', True)
def showSeconds(self): def showSeconds(self):
if 'showSeconds' not in self.config: if not self.config.has_key('showSeconds'):
self.set("showSeconds", False) self.set("showSeconds", False)
return self.config.get('showSeconds', False) return self.config.get('showSeconds', False)
def sortMethod(self): def sortMethod(self):
@ -174,11 +174,11 @@ class userConfig(object):
return g[1] return g[1]
return True return True
def showEmptyGroups(self): def showEmptyGroups(self):
if 'emptyGroups' not in self.config: if not self.config.has_key('emptyGroups'):
self.set("emptyGroups", False) self.set("emptyGroups", False)
return self.config.get('emptyGroups', False) return self.config.get('emptyGroups', False)
def showOnlineNumbers(self): def showOnlineNumbers(self):
if 'onlineNumbers' not in self.config: if not self.config.has_key('onlineNumbers'):
self.set("onlineNumbers", False) self.set("onlineNumbers", False)
return self.config.get('onlineNumbers', False) return self.config.get('onlineNumbers', False)
def logPesters(self): def logPesters(self):
@ -238,7 +238,7 @@ class userConfig(object):
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) self.set("chums", newchums)
def getBlocklist(self): def getBlocklist(self):
if 'block' not in self.config: if not self.config.has_key('block'):
self.set('block', []) self.set('block', [])
return self.config['block'] return self.config['block']
def addBlocklist(self, handle): def addBlocklist(self, handle):
@ -251,7 +251,7 @@ class userConfig(object):
l.pop(l.index(handle)) l.pop(l.index(handle))
self.set('block', l) self.set('block', l)
def getGroups(self): def getGroups(self):
if 'groups' not in self.groups: if not self.groups.has_key('groups'):
self.saveGroups([["Chums", True]]) self.saveGroups([["Chums", True]])
return self.groups.get('groups', [["Chums", True]]) return self.groups.get('groups', [["Chums", True]])
def addGroup(self, group, open=True): def addGroup(self, group, open=True):
@ -285,7 +285,7 @@ class userConfig(object):
self.groups['groups'] = groups self.groups['groups'] = groups
try: try:
jsonoutput = json.dumps(self.groups) jsonoutput = json.dumps(self.groups)
except ValueError as e: except ValueError, e:
raise e raise e
fp = open("%s/groups.js" % (self.logpath), 'w') fp = open("%s/groups.js" % (self.logpath), 'w')
fp.write(jsonoutput) fp.write(jsonoutput)
@ -300,7 +300,7 @@ class userConfig(object):
return self.parent.portOverride return self.parent.portOverride
return self.config.get('port', '6667') return self.config.get('port', '6667')
def soundOn(self): def soundOn(self):
if 'soundon' not in self.config: if not self.config.has_key('soundon'):
self.set('soundon', True) self.set('soundon', True)
return self.config['soundon'] return self.config['soundon']
def chatSound(self): def chatSound(self):
@ -319,7 +319,7 @@ class userConfig(object):
self.config[item] = setting self.config[item] = setting
try: try:
jsonoutput = json.dumps(self.config) jsonoutput = json.dumps(self.config)
except ValueError as e: except ValueError, e:
raise e raise e
fp = open(self.filename, 'w') fp = open(self.filename, 'w')
fp.write(jsonoutput) fp.write(jsonoutput)
@ -356,7 +356,7 @@ class userProfile(object):
if type(user) is PesterProfile: if type(user) is PesterProfile:
self.chat = user self.chat = user
self.userprofile = {"handle":user.handle, self.userprofile = {"handle":user.handle,
"color": str(user.color.name()), "color": unicode(user.color.name()),
"quirks": [], "quirks": [],
"theme": "pesterchum"} "theme": "pesterchum"}
self.theme = pesterTheme("pesterchum") self.theme = pesterTheme("pesterchum")
@ -377,7 +377,7 @@ class userProfile(object):
fp.close() fp.close()
try: try:
self.theme = pesterTheme(self.userprofile["theme"]) self.theme = pesterTheme(self.userprofile["theme"])
except ValueError as e: except ValueError, e:
self.theme = pesterTheme("pesterchum") self.theme = pesterTheme("pesterchum")
self.lastmood = self.userprofile.get('lastmood', self.theme["main/defaultmood"]) self.lastmood = self.userprofile.get('lastmood', self.theme["main/defaultmood"])
self.chat = PesterProfile(self.userprofile["handle"], self.chat = PesterProfile(self.userprofile["handle"],
@ -402,7 +402,7 @@ class userProfile(object):
try: try:
with open(_datadir+"passwd.js") as fp: with open(_datadir+"passwd.js") as fp:
self.passwd = json.load(fp) self.passwd = json.load(fp)
except Exception as e: except Exception, e:
self.passwd = {} self.passwd = {}
self.autoidentify = False self.autoidentify = False
self.nickservpass = "" self.nickservpass = ""
@ -418,7 +418,7 @@ class userProfile(object):
self.save() self.save()
def setColor(self, color): def setColor(self, color):
self.chat.color = color self.chat.color = color
self.userprofile["color"] = str(color.name()) self.userprofile["color"] = unicode(color.name())
self.save() self.save()
def setQuirks(self, quirks): def setQuirks(self, quirks):
self.quirks = quirks self.quirks = quirks
@ -436,7 +436,7 @@ class userProfile(object):
try: try:
for (i,m) in enumerate(mentions): for (i,m) in enumerate(mentions):
re.compile(m) re.compile(m)
except re.error as e: except re.error, e:
logging.error("#%s Not a valid regular expression: %s" % (i, e)) logging.error("#%s Not a valid regular expression: %s" % (i, e))
else: else:
self.mentions = mentions self.mentions = mentions
@ -479,19 +479,19 @@ class userProfile(object):
return return
try: try:
jsonoutput = json.dumps(self.userprofile) jsonoutput = json.dumps(self.userprofile)
except ValueError as e: except ValueError, e:
raise e raise e
fp = open("%s/%s.js" % (self.profiledir, handle), 'w') fp = open("%s/%s.js" % (self.profiledir, handle), 'w')
fp.write(jsonoutput) fp.write(jsonoutput)
fp.close() fp.close()
def saveNickServPass(self): def saveNickServPass(self):
# remove profiles with no passwords # remove profiles with no passwords
for h,t in list(self.passwd.items()): for h,t in self.passwd.items():
if "auto" not in t or "pw" not in t or t["pw"] == "": if "auto" not in t or "pw" not in t or t["pw"] == "":
del self.passwd[h] del self.passwd[h]
try: try:
jsonoutput = json.dumps(self.passwd, indent=4) jsonoutput = json.dumps(self.passwd, indent=4)
except ValueError as e: except ValueError, e:
raise e raise e
with open(_datadir+"passwd.js", 'w') as fp: with open(_datadir+"passwd.js", 'w') as fp:
fp.write(jsonoutput) fp.write(jsonoutput)
@ -526,7 +526,7 @@ class PesterProfileDB(dict):
fp.close() fp.close()
u = [] u = []
for (handle, c) in chumdict.items(): for (handle, c) in chumdict.iteritems():
options = dict() options = dict()
if 'group' in c: if 'group' in c:
options['group'] = c['group'] options['group'] = c['group']
@ -543,39 +543,39 @@ class PesterProfileDB(dict):
def save(self): def save(self):
try: try:
fp = open("%s/chums.js" % (self.logpath), 'w') fp = open("%s/chums.js" % (self.logpath), 'w')
chumdict = dict([p.plaindict() for p in self.values()]) chumdict = dict([p.plaindict() for p in self.itervalues()])
json.dump(chumdict, fp) json.dump(chumdict, fp)
fp.close() fp.close()
except Exception as e: except Exception, e:
raise e raise e
def getColor(self, handle, default=None): def getColor(self, handle, default=None):
if handle not in self: if not self.has_key(handle):
return default return default
else: else:
return self[handle].color return self[handle].color
def setColor(self, handle, color): def setColor(self, handle, color):
if handle in self: if self.has_key(handle):
self[handle].color = color self[handle].color = color
else: else:
self[handle] = PesterProfile(handle, color) self[handle] = PesterProfile(handle, color)
def getGroup(self, handle, default="Chums"): def getGroup(self, handle, default="Chums"):
if handle not in self: if not self.has_key(handle):
return default return default
else: else:
return self[handle].group return self[handle].group
def setGroup(self, handle, theGroup): def setGroup(self, handle, theGroup):
if handle in self: if self.has_key(handle):
self[handle].group = theGroup self[handle].group = theGroup
else: else:
self[handle] = PesterProfile(handle, group=theGroup) self[handle] = PesterProfile(handle, group=theGroup)
self.save() self.save()
def getNotes(self, handle, default=""): def getNotes(self, handle, default=""):
if handle not in self: if not self.has_key(handle):
return default return default
else: else:
return self[handle].notes return self[handle].notes
def setNotes(self, handle, notes): def setNotes(self, handle, notes):
if handle in self: if self.has_key(handle):
self[handle].notes = notes self[handle].notes = notes
else: else:
self[handle] = PesterProfile(handle, notes=notes) self[handle] = PesterProfile(handle, notes=notes)
@ -604,7 +604,7 @@ class pesterTheme(dict):
except IOError: except IOError:
theme = json.loads("{}") theme = json.loads("{}")
self.update(theme) self.update(theme)
if "inherits" in self: if self.has_key("inherits"):
self.inheritedTheme = pesterTheme(self["inherits"]) self.inheritedTheme = pesterTheme(self["inherits"])
if not default: if not default:
self.defaultTheme = pesterTheme("pesterchum", default=True) self.defaultTheme = pesterTheme("pesterchum", default=True)
@ -612,7 +612,7 @@ class pesterTheme(dict):
keys = key.split("/") keys = key.split("/")
try: try:
v = dict.__getitem__(self, keys.pop(0)) v = dict.__getitem__(self, keys.pop(0))
except KeyError as e: except KeyError, e:
if hasattr(self, 'inheritedTheme'): if hasattr(self, 'inheritedTheme'):
return self.inheritedTheme[key] return self.inheritedTheme[key]
if hasattr(self, 'defaultTheme'): if hasattr(self, 'defaultTheme'):
@ -622,7 +622,7 @@ class pesterTheme(dict):
for k in keys: for k in keys:
try: try:
v = v[k] v = v[k]
except KeyError as e: except KeyError, e:
if hasattr(self, 'inheritedTheme'): if hasattr(self, 'inheritedTheme'):
return self.inheritedTheme[key] return self.inheritedTheme[key]
if hasattr(self, 'defaultTheme'): if hasattr(self, 'defaultTheme'):
@ -631,8 +631,8 @@ class pesterTheme(dict):
raise e raise e
return v return v
def pathHook(self, d): def pathHook(self, d):
for (k, v) in d.items(): for (k, v) in d.iteritems():
if type(v) is str: if type(v) is unicode:
s = Template(v) s = Template(v)
d[k] = s.safe_substitute(path=self.path) d[k] = s.safe_substitute(path=self.path)
return d return d
@ -658,6 +658,6 @@ class pesterTheme(dict):
return False if v is None else True return False if v is None else True
except KeyError: except KeyError:
if hasattr(self, 'inheritedTheme'): if hasattr(self, 'inheritedTheme'):
return key in self.inheritedTheme return self.inheritedTheme.has_key(key)
else: else:
return False return False

View file

@ -12,20 +12,20 @@ class PythonQuirks(ScriptQuirks):
def modHas(self, module, attr): def modHas(self, module, attr):
if attr == 'commands': if attr == 'commands':
variables = vars(module) variables = vars(module)
for name, obj in variables.items(): for name, obj in variables.iteritems():
if self.modHas(obj, 'command'): if self.modHas(obj, 'command'):
return True return True
return hasattr(module, attr) return hasattr(module, attr)
def register(self, module): def register(self, module):
variables = vars(module) variables = vars(module)
for name, obj in variables.items(): for name, obj in variables.iteritems():
if self.modHas(obj, 'command'): if self.modHas(obj, 'command'):
try: try:
if not isinstance(obj("test"), str): if not isinstance(obj("test"), basestring):
raise Exception raise Exception
except: except:
print("Quirk malformed: %s" % (obj.command)) print "Quirk malformed: %s" % (obj.command)
msgbox = QtWidgets.QMessageBox() msgbox = QtWidgets.QMessageBox()
msgbox.setWindowTitle("Error!") msgbox.setWindowTitle("Error!")
msgbox.setText("Quirk malformed: %s" % (obj.command)) msgbox.setText("Quirk malformed: %s" % (obj.command))

View file

@ -20,7 +20,7 @@ class ScriptQuirks(object):
self.last = self.quirks.copy() self.last = self.quirks.copy()
self.quirks.clear() self.quirks.clear()
for script in self.scripts: for script in self.scripts:
print(script.getExtension()) print script.getExtension()
script.load() script.load()
#print script.quirks #print script.quirks
for q in script.quirks: for q in script.quirks:
@ -31,9 +31,9 @@ class ScriptQuirks(object):
del self.quirks[k] del self.quirks[k]
#print self.quirks #print self.quirks
if self.quirks: if self.quirks:
print('Registered quirks:', '(), '.join(self.quirks) + "()") print 'Registered quirks:', '(), '.join(self.quirks) + "()"
else: else:
print("Warning: Couldn't find any script quirks") print "Warning: Couldn't find any script quirks"
def add(self, script): def add(self, script):
self.scripts.append(script) self.scripts.append(script)
@ -64,8 +64,8 @@ class ScriptQuirks(object):
module = self.loadModule(name, filename) module = self.loadModule(name, filename)
if module is None: if module is None:
continue continue
except Exception as e: except Exception, e:
print("Error loading %s: %s (in quirks.py)" % (os.path.basename(name), e)) print "Error loading %s: %s (in quirks.py)" % (os.path.basename(name), e)
msgbox = QtWidgets.QMessageBox() msgbox = QtWidgets.QMessageBox()
msgbox.setWindowTitle("Error!") msgbox.setWindowTitle("Error!")
msgbox.setText("Error loading %s: %s (in quirks.py)" % (os.path.basename(filename), e)) msgbox.setText("Error loading %s: %s (in quirks.py)" % (os.path.basename(filename), e))

View file

@ -63,6 +63,6 @@ class RandomHandler(QtCore.QObject):
msgbox.setInformativeText("Try again later :(") msgbox.setInformativeText("Try again later :(")
msgbox.exec_() msgbox.exec_()
return return
name = str(l[1]) name = unicode(l[1])
print(name) print name
self.mainwindow.newConversation(name) self.mainwindow.newConversation(name)

View file

@ -4,29 +4,27 @@ import time, os
import ostools import ostools
from PyQt5 import QtGui, QtCore, QtWidgets from PyQt5 import QtGui, QtCore, QtWidgets
import logging
try: try:
import pynotify import pynotify
except: except:
pynotify = None pynotify = None
class DefaultToast(QtWidgets.QWidget): class DefaultToast(object):
def __init__(self, parent, **kwds): def __init__(self, parent, **kwds):
super().__init__(parent) super(DefaultToast, self).__init__(parent, **kwds)
self.machine = kwds.get('machine') self.machine = kwds.get('machine')
self.title = kwds.get('title') self.title = kwds.get('title')
self.msg = kwds.get('msg') self.msg = kwds.get('msg')
self.icon = kwds.get('icon') self.icon = kwds.get('icon')
def show(self): def show(self):
print(self.title, self.msg, self.icon) print self.title, self.msg, self.icon
self.done() self.done()
def done(self): def done(self):
t = self.machine.toasts[0] t = self.machine.toasts[0]
if t.title == self.title and t.msg == self.msg and t.icon == self.icon: if t.title == self.title and t.msg == self.msg and t.icon == self.icon:
self.machine.toasts.pop(0) self.machine.toasts.pop(0)
self.machine.displaying = False self.machine.displaying = False
print("Done") print "Done"
class ToastMachine(object): class ToastMachine(object):
class __Toast__(object): class __Toast__(object):
@ -75,7 +73,7 @@ class ToastMachine(object):
def realShow(self): def realShow(self):
self.machine.displaying = True self.machine.displaying = True
t = None t = None
for (k,v) in self.machine.types.items(): for (k,v) in self.machine.types.iteritems():
if self.machine.type == k: if self.machine.type == k:
try: try:
args = inspect.getargspec(v.__init__).args args = inspect.getargspec(v.__init__).args
@ -145,15 +143,15 @@ class ToastMachine(object):
if type in self.types: if type in self.types:
if type == "libnotify": if type == "libnotify":
if not pynotify or not pynotify.init("ToastMachine"): if not pynotify or not pynotify.init("ToastMachine"):
print("Problem initilizing pynotify") print "Problem initilizing pynotify"
return return
#self.type = type = "default" #self.type = type = "default"
elif type == "twmn": elif type == "twmn":
from libs import pytwmn from libs import pytwmn
try: try:
pytwmn.init() pytwmn.init()
except pytwmn.ERROR as e: except pytwmn.ERROR, e:
print("Problem initilizing pytwmn: " + str(e)) print "Problem initilizing pytwmn: " + str(e)
return return
#self.type = type = "default" #self.type = type = "default"
self.type = type self.type = type
@ -179,11 +177,9 @@ class ToastMachine(object):
self.showNext() self.showNext()
class PesterToast(DefaultToast): class PesterToast(QtWidgets.QWidget, DefaultToast):
def __init__(self, machine, title, msg, icon, time=3000, parent=None): def __init__(self, machine, title, msg, icon, time=3000, parent=None):
logging.info(isinstance(parent, QtWidgets.QWidget)) super(PesterToast, self).__init__(self, parent, machine=machine, title=title, msg=msg, icon=icon)
kwds = dict(machine=machine, title=title, msg=msg, icon=icon)
super().__init__(parent, **kwds)
self.machine = machine self.machine = machine
self.time = time self.time = time
@ -214,6 +210,7 @@ class PesterToast(DefaultToast):
self.icon.pixmap().fill(QtGui.QColor(0,0,0,0)) self.icon.pixmap().fill(QtGui.QColor(0,0,0,0))
layout_0 = QtWidgets.QVBoxLayout() layout_0 = QtWidgets.QVBoxLayout()
layout_0.setMargin(0)
layout_0.setContentsMargins(0, 0, 0, 0) layout_0.setContentsMargins(0, 0, 0, 0)
if self.icon: if self.icon:
@ -240,7 +237,7 @@ class PesterToast(DefaultToast):
self.msg.setStyleSheet(self.parent().theme["toasts/content/style"]) self.msg.setStyleSheet(self.parent().theme["toasts/content/style"])
self.layout().setSpacing(0) self.layout().setSpacing(0)
self.msg.setText(PesterToast.wrapText(self.msg.font(), str(self.msg.text()), self.parent().theme["toasts/width"], self.parent().theme["toasts/content/style"])) self.msg.setText(PesterToast.wrapText(self.msg.font(), unicode(self.msg.text()), self.parent().theme["toasts/width"], self.parent().theme["toasts/content/style"]))
p = QtWidgets.QApplication.desktop().availableGeometry(self).bottomRight() p = QtWidgets.QApplication.desktop().availableGeometry(self).bottomRight()
o = QtWidgets.QApplication.desktop().screenGeometry(self).bottomRight() o = QtWidgets.QApplication.desktop().screenGeometry(self).bottomRight()
@ -258,8 +255,8 @@ class PesterToast(DefaultToast):
def done(self): def done(self):
QtWidgets.QWidget.hide(self) QtWidgets.QWidget.hide(self)
t = self.machine.toasts[0] t = self.machine.toasts[0]
if t.title == str(self.title.text()) and \ if t.title == unicode(self.title.text()) and \
t.msg == str(self.content): t.msg == unicode(self.content):
self.machine.toasts.pop(0) self.machine.toasts.pop(0)
self.machine.displaying = False self.machine.displaying = False
if self.machine.on: if self.machine.on:
@ -269,7 +266,7 @@ class PesterToast(DefaultToast):
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
def reverseTrigger(self): def reverseTrigger(self):
if self.time >= 0: if self.time >= 0:
QtCore.QTimer.singleShot(self.time, self.reverseStart) QtCore.QTimer.singleShot(self.time, self, QtCore.SLOT('reverseStart()'))
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
def reverseStart(self): def reverseStart(self):
@ -286,7 +283,7 @@ class PesterToast(DefaultToast):
def updateBottomLeftAnimation(self, value): def updateBottomLeftAnimation(self, value):
p = QtWidgets.QApplication.desktop().availableGeometry(self).bottomRight() p = QtWidgets.QApplication.desktop().availableGeometry(self).bottomRight()
val = float(self.height())/100 val = float(self.height())/100
self.move(p.x()-self.width(), p.y() - (value * val) +1) self.move(p.x()-self.width(), p.y() - (value.toInt()[0] * val) +1)
self.layout().setSpacing(0) self.layout().setSpacing(0)
QtWidgets.QWidget.show(self) QtWidgets.QWidget.show(self)
@ -352,7 +349,7 @@ class PesterToast(DefaultToast):
break break
if (metric.width(text[:lastspace]) > maxwidth) or \ if (metric.width(text[:lastspace]) > maxwidth) or \
len(text[:lastspace]) < 1: len(text[:lastspace]) < 1:
for i in range(len(text)): for i in xrange(len(text)):
if metric.width(text[:i]) > maxwidth: if metric.width(text[:i]) > maxwidth:
lastspace = i-1 lastspace = i-1
break break

View file

@ -34,20 +34,19 @@ class MSPAChecker(QtWidgets.QWidget):
raise raise
if os.path.exists("status_old.pkl"): if os.path.exists("status_old.pkl"):
os.remove("status_old.pkl") os.remove("status_old.pkl")
except Exception as e: except Exception, e:
print(e) print e
msg = QtWidgets.QMessageBox(self) msg = QtWidgets.QMessageBox(self)
msg.setText("Problems writing save file.") msg.setText("Problems writing save file.")
msg.show() msg.show()
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
def check_site_wrapper(self): def check_site_wrapper(self):
return # turn off MSPA check; python3 doesnt like it
if not self.mainwindow.config.checkMSPA(): if not self.mainwindow.config.checkMSPA():
return return
if self.lock: if self.lock:
return return
print("Checking MSPA updates...") print "Checking MSPA updates..."
s = threading.Thread(target=self.check_site) s = threading.Thread(target=self.check_site)
s.start() s.start()
@ -89,7 +88,7 @@ class MSPAChecker(QtWidgets.QWidget):
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
def visit_site(self): def visit_site(self):
print(self.status['last_visited']['link']) print self.status['last_visited']['link']
QtGui.QDesktopServices.openUrl(QtCore.QUrl(self.status['last_visited']['link'], QtCore.QUrl.TolerantMode)) QtGui.QDesktopServices.openUrl(QtCore.QUrl(self.status['last_visited']['link'], QtCore.QUrl.TolerantMode))
if self.status['last_seen']['pubdate'] > self.status['last_visited']['pubdate']: if self.status['last_seen']['pubdate'] > self.status['last_visited']['pubdate']:
#Visited for the first time. Untrip the icon and remember that we saw it. #Visited for the first time. Untrip the icon and remember that we saw it.

View file

@ -1,4 +1,4 @@
import urllib.request, urllib.parse, urllib.error import urllib
import re import re
import time import time
try: try:
@ -67,31 +67,31 @@ def lexVersion(short=False):
# Naughty I know, but it lets me grab it from the bash script. # Naughty I know, but it lets me grab it from the bash script.
if __name__ == "__main__": if __name__ == "__main__":
print(lexVersion()) print lexVersion()
def verStrToNum(ver): def verStrToNum(ver):
w = re.match("(\d+\.?\d+)\.(\d+)-?([A-Za-z]{0,2})\.?(\d*):(\S+)", ver) w = re.match("(\d+\.?\d+)\.(\d+)-?([A-Za-z]{0,2})\.?(\d*):(\S+)", ver)
if not w: if not w:
print("Update check Failure: 3"); return print "Update check Failure: 3"; return
full = ver[:ver.find(":")] full = ver[:ver.find(":")]
return full,w.group(1),w.group(2),w.group(3),w.group(4),w.group(5) return full,w.group(1),w.group(2),w.group(3),w.group(4),w.group(5)
def updateCheck(q): def updateCheck(q):
time.sleep(3) time.sleep(3)
data = urllib.parse.urlencode({"type" : USER_TYPE, "os" : OS_TYPE, "install" : INSTALL_TYPE}) data = urllib.urlencode({"type" : USER_TYPE, "os" : OS_TYPE, "install" : INSTALL_TYPE})
try: try:
f = urllib.request.urlopen("http://distantsphere.com/pesterchum.php?" + data) f = urllib.urlopen("http://distantsphere.com/pesterchum.php?" + data)
except: except:
print("Update check Failure: 1"); return q.put((False,1)) print "Update check Failure: 1"; return q.put((False,1))
newest = f.read() newest = f.read()
f.close() f.close()
if not newest or newest[0] == "<": if not newest or newest[0] == "<":
print("Update check Failure: 2"); return q.put((False,2)) print "Update check Failure: 2"; return q.put((False,2))
try: try:
(full, major, minor, status, revision, url) = verStrToNum(newest) (full, major, minor, status, revision, url) = verStrToNum(newest)
except TypeError: except TypeError:
return q.put((False,3)) return q.put((False,3))
print(full) print full
if major <= _pcMajor: if major <= _pcMajor:
if minor <= _pcMinor: if minor <= _pcMinor:
if status: if status:
@ -102,7 +102,7 @@ def updateCheck(q):
if not _pcStatus: if not _pcStatus:
if revision <= _pcRevision: if revision <= _pcRevision:
return q.put((False,0)) return q.put((False,0))
print("A new version of Pesterchum is avaliable!") print "A new version of Pesterchum is avaliable!"
q.put((full,url)) q.put((full,url))
@ -128,9 +128,9 @@ def copyUpdate(path):
def updateExtract(url, extension): def updateExtract(url, extension):
if extension: if extension:
fn = "update" + extension fn = "update" + extension
urllib.request.urlretrieve(url, fn) urllib.urlretrieve(url, fn)
else: else:
fn = urllib.request.urlretrieve(url)[0] fn = urllib.urlretrieve(url)[0]
if tarfile and tarfile.is_tarfile(fn): if tarfile and tarfile.is_tarfile(fn):
extension = ".tar.gz" extension = ".tar.gz"
elif zipfile.is_zipfile(fn): elif zipfile.is_zipfile(fn):
@ -144,17 +144,17 @@ def updateExtract(url, extension):
except: except:
pass pass
print(url, fn, extension) print url, fn, extension
if extension == ".exe": if extension == ".exe":
pass pass
elif extension == ".zip" or extension.startswith(".tar"): elif extension == ".zip" or extension.startswith(".tar"):
if extension == ".zip": if extension == ".zip":
from zipfile import is_zipfile as is_updatefile, ZipFile as openupdate from zipfile import is_zipfile as is_updatefile, ZipFile as openupdate
print("Opening .zip") print "Opening .zip"
elif tarfile and extension.startswith(".tar"): elif tarfile and extension.startswith(".tar"):
from tarfile import is_tarfile as is_updatefile, open as openupdate from tarfile import is_tarfile as is_updatefile, open as openupdate
print("Opening .tar") print "Opening .tar"
else: else:
return return