This commit is contained in:
Stephen Dranger 2011-02-23 05:06:00 -06:00
parent c389f71681
commit 4795608dca
23 changed files with 168 additions and 44 deletions

3
.gitignore vendored
View file

@ -1,4 +1,5 @@
logs/*
build/*
profiles/*
irctest.log
irctest.log
*.pyc

3
TODO
View file

@ -1,9 +1,6 @@
Bugs:
* finish QDB submission
* import quirks from 2.5!
* edit quirks?
* mood trees - chums, trolls, other
* begin and end regexps should only be applied once!
* X and _ buttons move around all crazy like
Features:

View file

@ -1,13 +1,14 @@
from string import Template
import re
import platform
import httplib, urllib
from copy import copy
from datetime import datetime, timedelta
from PyQt4 import QtGui, QtCore
from dataobjs import PesterProfile, Mood, PesterHistory
from generic import PesterIcon, RightClickList
from parsetools import convertTags, lexMessage, mecmd, colorBegin, colorEnd
from parsetools import convertTags, lexMessage, mecmd, colorBegin, colorEnd, img2smiley
class PesterTabWindow(QtGui.QFrame):
def __init__(self, mainwindow, parent=None, convo="convo"):
@ -204,7 +205,6 @@ class PesterText(QtGui.QTextEdit):
self, QtCore.SLOT('textReady(bool)'))
@QtCore.pyqtSlot(bool)
def textReady(self, ready):
print "setting textselected to %s" % (ready)
self.textSelected = ready
def initTheme(self, theme):
if theme.has_key("convo/scrollbar"):
@ -312,10 +312,44 @@ class PesterText(QtGui.QTextEdit):
textMenu.addAction(self.submitLogAction)
textMenu.exec_(event.globalPos())
def submitLogTitle(self):
return "[%s -> %s]" % (self.parent().mainwindow.profile().handle,
self.parent().chum.handle)
@QtCore.pyqtSlot()
def submitLog(self):
mimedata = self.createMimeDataFromSelection()
print mimedata.data("text/unicode")
htmldata = img2smiley(mimedata.data("text/html"))
textdoc = QtGui.QTextDocument()
textdoc.setHtml(htmldata)
logdata = textdoc.toPlainText()
self.sending = QtGui.QDialog(self)
layout = QtGui.QVBoxLayout()
self.sending.sendinglabel = QtGui.QLabel("S3ND1NG...", self.sending)
cancelbutton = QtGui.QPushButton("OK", self.sending)
self.sending.connect(cancelbutton, QtCore.SIGNAL('clicked()'),
self.sending, QtCore.SLOT('close()'))
layout.addWidget(self.sending.sendinglabel)
layout.addWidget(cancelbutton)
self.sending.setLayout(layout)
self.sending.show()
params = urllib.urlencode({'quote': logdata, 'do': "add"})
headers = {"Content-type": "application/x-www-form-urlencoded",
"Accept": "text/plain"}
try:
pass
hconn = httplib.HTTPConnection('luke.violentlemon.com', 80,
timeout=15)
hconn.request("POST", "/index.php", params, headers)
response = hconn.getresponse()
if response.status == "200":
self.sending.sendinglabel.setText("SUCC3SS!")
else:
self.sending.sendinglabel.setText("F41L3D")
hconn.close()
except Exception, e:
self.sending.sendinglabel.setText("F41L3D: %s" % (e))
del self.sending
class PesterInput(QtGui.QLineEdit):
def __init__(self, theme, parent=None):
@ -418,6 +452,12 @@ class PesterConvo(QtGui.QFrame):
return self.chum.handle
def icon(self):
return self.chum.mood.icon(self.mainwindow.theme)
def myUpdateMood(self, mood):
chum = self.mainwindow.profile()
syscolor = QtGui.QColor(self.mainwindow.theme["convo/systemMsgColor"])
msg = chum.moodmsg(mood, syscolor, self.mainwindow.theme)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.title(), msg)
def updateMood(self, mood, unblocked=False, old=None):
syscolor = QtGui.QColor(self.mainwindow.theme["convo/systemMsgColor"])

BIN
convo.pyc

Binary file not shown.

View file

@ -15,6 +15,9 @@ class Mood(object):
"devious", "sleek", "detestful", "mirthful", "manipulative",
"vigorous", "perky", "acceptant", "protective", "mystified",
"amazed", "insolent", "bemused" ]
moodcats = ["chums", "trolls", "other"]
revmoodcats = {'discontent': 'trolls', 'insolent': 'other', 'rancorous': 'chums', 'sleek': 'trolls', 'bemused': 'other', 'mystified': 'other', 'pranky': 'chums', 'distraught': 'chums', 'offline': 'chums', 'chummy': 'chums', 'protective': 'other', 'vigorous': 'trolls', 'ecstatic': 'trolls', 'relaxed': 'trolls', 'pleasant': 'chums', 'manipulative': 'trolls', 'detestful': 'trolls', 'smooth': 'chums', 'mirthful': 'trolls', 'acceptant': 'trolls', 'perky': 'trolls', 'devious': 'trolls', 'amazed': 'other'}
def __init__(self, mood):
if type(mood) is int:
self.mood = mood

Binary file not shown.

Binary file not shown.

BIN
irc.pyc

Binary file not shown.

View file

@ -300,7 +300,8 @@ class MemoText(PesterText):
def changeTheme(self, theme):
self.initTheme(theme)
def submitLogTitle(self):
return "[%s]" % (self.parent().title())
class MemoInput(PesterInput):
def __init__(self, theme, parent=None):

BIN
memos.pyc

Binary file not shown.

135
menus.py
View file

@ -10,7 +10,9 @@ class PesterQuirkItem(QtGui.QListWidgetItem):
QtGui.QListWidgetItem.__init__(self, parent)
self.quirk = quirk
self.setText(unicode(quirk))
def update(self, quirk):
self.quirk = quirk
self.setText(unicode(quirk))
def __lt__(self, quirkitem):
if self.quirk.type == "prefix":
return True
@ -32,6 +34,9 @@ class PesterQuirkList(QtGui.QListWidget):
self.addItem(item)
#self.sortItems()
def currentQuirk(self):
return self.item(self.currentRow())
@QtCore.pyqtSlot()
def removeCurrent(self):
i = self.currentRow()
@ -78,13 +83,13 @@ class MispellQuirkDialog(QtGui.QDialog):
return None
class RandomQuirkDialog(MultiTextDialog):
def __init__(self, parent):
def __init__(self, parent, values={}):
QtGui.QDialog.__init__(self, parent)
self.setWindowTitle("RANDOM QUIRK")
self.inputs = {}
layout_1 = QtGui.QHBoxLayout()
regexpl = QtGui.QLabel("REGEXP:", self)
self.regexp = QtGui.QLineEdit(self)
self.regexp = QtGui.QLineEdit(values.get("regexp",""), self)
layout_1.addWidget(regexpl)
layout_1.addWidget(self.regexp)
replacewithl = QtGui.QLabel("REPLACE WITH:", self)
@ -92,6 +97,8 @@ class RandomQuirkDialog(MultiTextDialog):
layout_2 = QtGui.QVBoxLayout()
layout_3 = QtGui.QHBoxLayout()
self.replacelist = QtGui.QListWidget(self)
for v in values.get("list", []):
item = QtGui.QListWidgetItem(v, self.replacelist)
self.replaceinput = QtGui.QLineEdit(self)
addbutton = QtGui.QPushButton("ADD", self)
self.connect(addbutton, QtCore.SIGNAL('clicked()'),
@ -190,9 +197,15 @@ class PesterChooseQuirks(QtGui.QDialog):
layout_2.addWidget(self.addRandomReplaceButton)
layout_2.addWidget(self.addMispellingButton)
self.editSelectedButton = QtGui.QPushButton("EDIT", self)
self.connect(self.editSelectedButton, QtCore.SIGNAL('clicked()'),
self, QtCore.SLOT('editSelected()'))
self.removeSelectedButton = QtGui.QPushButton("REMOVE", self)
self.connect(self.removeSelectedButton, QtCore.SIGNAL('clicked()'),
self.quirkList, QtCore.SLOT('removeCurrent()'))
layout_3 = QtGui.QHBoxLayout()
layout_3.addWidget(self.editSelectedButton)
layout_3.addWidget(self.removeSelectedButton)
self.ok = QtGui.QPushButton("OK", self)
self.ok.setDefault(True)
@ -209,47 +222,90 @@ class PesterChooseQuirks(QtGui.QDialog):
layout_0.addWidget(self.quirkList)
layout_0.addLayout(layout_1)
layout_0.addLayout(layout_2)
layout_0.addWidget(self.removeSelectedButton)
layout_0.addLayout(layout_3)
layout_0.addLayout(layout_ok)
self.setLayout(layout_0)
def quirks(self):
return [self.quirkList.item(i).quirk for i in
range(0,self.quirkList.count())]
@QtCore.pyqtSlot()
def addPrefixDialog(self):
pdict = MultiTextDialog("ENTER PREFIX", self, {"label": "Value:", "inputname": "value"}).getText()
def editSelected(self):
q = self.quirkList.currentQuirk()
quirk = q.quirk
if quirk.type == "prefix":
self.addPrefixDialog(q)
elif quirk.type == "suffix":
self.addSuffixDialog(q)
elif quirk.type == "replace":
self.addSimpleReplaceDialog(q)
elif quirk.type == "regexp":
self.addRegexpDialog(q)
elif quirk.type == "random":
self.addRandomDialog(q)
elif quirk.type == "spelling":
self.addSpellDialog(q)
@QtCore.pyqtSlot()
def addPrefixDialog(self, qitem=None):
d = {"label": "Value:", "inputname": "value" }
if qitem is not None:
d["value"] = qitem.quirk.quirk["value"]
pdict = MultiTextDialog("ENTER PREFIX", self, d).getText()
if pdict is None:
return
pdict["type"] = "prefix"
prefix = pesterQuirk(pdict)
pitem = PesterQuirkItem(prefix, self.quirkList)
self.quirkList.addItem(pitem)
if qitem is None:
pitem = PesterQuirkItem(prefix, self.quirkList)
self.quirkList.addItem(pitem)
else:
qitem.update(prefix)
#self.quirkList.sortItems()
@QtCore.pyqtSlot()
def addSuffixDialog(self):
vdict = MultiTextDialog("ENTER SUFFIX", self, {"label": "Value:", "inputname": "value"}).getText()
def addSuffixDialog(self, qitem=None):
d = {"label": "Value:", "inputname": "value" }
if qitem is not None:
d["value"] = qitem.quirk.quirk["value"]
vdict = MultiTextDialog("ENTER SUFFIX", self, d).getText()
if vdict is None:
return
vdict["type"] = "suffix"
quirk = pesterQuirk(vdict)
item = PesterQuirkItem(quirk, self.quirkList)
self.quirkList.addItem(item)
newquirk = pesterQuirk(vdict)
if qitem is None:
item = PesterQuirkItem(newquirk, self.quirkList)
self.quirkList.addItem(item)
else:
qitem.update(newquirk)
#self.quirkList.sortItems()
@QtCore.pyqtSlot()
def addSimpleReplaceDialog(self):
vdict = MultiTextDialog("REPLACE", self, {"label": "Replace:", "inputname": "from"}, {"label": "With:", "inputname": "to"}).getText()
def addSimpleReplaceDialog(self, qitem=None):
d = [{"label": "Replace:", "inputname": "from"}, {"label": "With:", "inputname": "to"}]
if qitem is not None:
d[0]["value"] = qitem.quirk.quirk["from"]
d[1]["value"] = qitem.quirk.quirk["to"]
vdict = MultiTextDialog("REPLACE", self, *d).getText()
if vdict is None:
return
vdict["type"] = "replace"
quirk = pesterQuirk(vdict)
item = PesterQuirkItem(quirk, self.quirkList)
self.quirkList.addItem(item)
newquirk = pesterQuirk(vdict)
if qitem is None:
item = PesterQuirkItem(newquirk, self.quirkList)
self.quirkList.addItem(item)
else:
qitem.update(newquirk)
#self.quirkList.sortItems()
@QtCore.pyqtSlot()
def addRegexpDialog(self):
vdict = MultiTextDialog("REGEXP REPLACE", self, {"label": "Regexp:", "inputname": "from"}, {"label": "Replace With:", "inputname": "to"}).getText()
def addRegexpDialog(self, qitem=None):
d = [{"label": "Regexp:", "inputname": "from"}, {"label": "Replace With:", "inputname": "to"}]
if qitem is not None:
d[0]["value"] = qitem.quirk.quirk["from"]
d[1]["value"] = qitem.quirk.quirk["to"]
vdict = MultiTextDialog("REGEXP REPLACE", self, *d).getText()
if vdict is None:
return
vdict["type"] = "regexp"
@ -262,13 +318,20 @@ class PesterChooseQuirks(QtGui.QDialog):
quirkWarning.exec_()
return
quirk = pesterQuirk(vdict)
item = PesterQuirkItem(quirk, self.quirkList)
self.quirkList.addItem(item)
newquirk = pesterQuirk(vdict)
if qitem is None:
item = PesterQuirkItem(newquirk, self.quirkList)
self.quirkList.addItem(item)
else:
qitem.update(newquirk)
#self.quirkList.sortItems()
@QtCore.pyqtSlot()
def addRandomDialog(self):
vdict = RandomQuirkDialog(self).getText()
def addRandomDialog(self, qitem=None):
values = {}
if qitem is not None:
values["list"] = qitem.quirk.quirk["randomlist"]
values["regexp"] = qitem.quirk.quirk["from"]
vdict = RandomQuirkDialog(self, values).getText()
if vdict is None:
return
vdict["type"] = "random"
@ -280,19 +343,25 @@ class PesterChooseQuirks(QtGui.QDialog):
quirkWarning.setInformativeText("H3R3S WHY DUMP4SS: %s" % (e))
quirkWarning.exec_()
return
quirk = pesterQuirk(vdict)
item = PesterQuirkItem(quirk, self.quirkList)
self.quirkList.addItem(item)
newquirk = pesterQuirk(vdict)
if qitem is None:
item = PesterQuirkItem(newquirk, self.quirkList)
self.quirkList.addItem(item)
else:
qitem.update(newquirk)
#self.quirkList.sortItems()
@QtCore.pyqtSlot()
def addSpellDialog(self):
def addSpellDialog(self, qitem=None):
vdict = MispellQuirkDialog(self).getPercentage()
if vdict is None:
return
vdict["type"] = "spelling"
quirk = pesterQuirk(vdict)
item = PesterQuirkItem(quirk, self.quirkList)
self.quirkList.addItem(item)
newquirk = pesterQuirk(vdict)
if qitem is None:
item = PesterQuirkItem(newquirk, self.quirkList)
self.quirkList.addItem(item)
else:
qitem.update(newquirk)
#self.quirkList.sortItems()
class PesterChooseTheme(QtGui.QDialog):

BIN
menus.pyc

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -114,7 +114,7 @@ class smiley(object):
self.string = string
def convert(self, format):
if format == "html":
return "<img src='smilies/%s' />" % (smiledict[self.string])
return "<img src='smilies/%s' alt='%s' title='%s' />" % (smiledict[self.string], self.string, self.string)
else:
return self.string
class mecmd(object):
@ -227,6 +227,12 @@ def timeDifference(td):
timetext = "%d HOURS %s" % (hours, when)
return timetext
def img2smiley(string):
string = unicode(string)
def imagerep(mo):
return reverse_smiley[mo.group(1)]
string = re.sub(r'<img src="smilies/(\S+)" />', imagerep, string)
return string
smiledict = {
":rancorous:": "pc_rancorous.gif",
@ -269,4 +275,5 @@ smiledict = {
":pumpkin:": "whatpumpkin.gif",
":trollcool:": "trollcool.gif"}
reverse_smiley = dict((v,k) for k, v in smiledict.iteritems())
_smilere = re.compile("|".join(smiledict.keys()))

Binary file not shown.

View file

@ -1 +1 @@
{"tabs": false, "soundon": true, "server": "irc.tymoon.eu", "chums": ["unknownTraveler", "tentacleTherapist", "vaginalEngineer", "mechanicalSpectacle", "carcinoGeneticist", "schlagzeugGator", "gamblingGenocider", "gardenGnostic", "superGhost", "centaursTesticle", "arachnidsGrip", "grimAuxiliatrix", "remoteBloodbath", "nitroZealist", "greenZephyr", "arsenicCatnip", "cuttlefishCuller", "rageInducer", "gallowsCalibrator", "caligulasAquarium", "terminallyCapricious", "illuminatedWax", "aquaMarinist", "elegantDiversion", "moirailBunp", "uroborosUnbound", "androidTechnician", "midnightSparrow", "apocalypseArisen", "anguillaNuntia", "oilslickOrchid", "confusedTransient", "pretentiousFantasia", "aquaticMarinist", "lyricalKeraunoscopic", "counterRealist", "ectoBiologist", "percipientPedestrian", "asceticClinician", "doctectiveMiracles", "noSense", "obliviousCrafter", "ircMonster", "twinArmageddons", "cannabisHero", "jetRocket", "dFd"], "defaultprofile": "ghostDunk", "block": []}
{"tabs": true, "soundon": true, "server": "irc.tymoon.eu", "chums": ["unknownTraveler", "tentacleTherapist", "vaginalEngineer", "mechanicalSpectacle", "carcinoGeneticist", "schlagzeugGator", "gamblingGenocider", "gardenGnostic", "superGhost", "centaursTesticle", "arachnidsGrip", "grimAuxiliatrix", "remoteBloodbath", "nitroZealist", "greenZephyr", "arsenicCatnip", "cuttlefishCuller", "rageInducer", "gallowsCalibrator", "caligulasAquarium", "terminallyCapricious", "illuminatedWax", "aquaMarinist", "elegantDiversion", "moirailBunp", "uroborosUnbound", "androidTechnician", "midnightSparrow", "apocalypseArisen", "anguillaNuntia", "oilslickOrchid", "confusedTransient", "pretentiousFantasia", "aquaticMarinist", "lyricalKeraunoscopic", "counterRealist", "ectoBiologist", "percipientPedestrian", "asceticClinician", "doctectiveMiracles", "noSense", "obliviousCrafter", "ircMonster", "twinArmageddons", "cannabisHero", "jetRocket"], "defaultprofile": "ghostDunk", "block": []}

View file

@ -607,6 +607,8 @@ class PesterMoodHandler(QtCore.QObject):
if self.mainwindow.currentMoodIcon:
moodicon = newmood.icon(self.mainwindow.theme)
self.mainwindow.currentMoodIcon.setPixmap(moodicon.pixmap(moodicon.realsize()))
for c in self.mainwindow.convos.values():
c.myUpdateMood(newmood)
self.mainwindow.moodUpdated.emit()
class PesterMoodButton(QtGui.QPushButton):
@ -1683,6 +1685,7 @@ class MainProgram(QtCore.QObject):
def __init__(self):
QtCore.QObject.__init__(self)
self.app = QtGui.QApplication(sys.argv)
self.app.setApplicationName("Pesterchum 3.14");
if pygame.mixer:
# we could set the frequency higher but i love how cheesy it sounds
try:
@ -1697,6 +1700,9 @@ class MainProgram(QtCore.QObject):
self.trayicon = PesterTray(PesterIcon(self.widget.theme["main/icon"]), self.widget, self.app)
self.traymenu = QtGui.QMenu()
moodMenu = self.traymenu.addMenu("SET MOOD")
moodCategories = {}
for k in Mood.moodcats:
moodCategories[k] = moodMenu.addMenu(k.upper())
self.moodactions = {}
for (i,m) in enumerate(Mood.moods):
maction = QtGui.QAction(m.upper(), self)
@ -1704,7 +1710,7 @@ class MainProgram(QtCore.QObject):
self.trayicon.connect(maction, QtCore.SIGNAL('triggered()'),
mobj, QtCore.SLOT('updateMood()'))
self.moodactions[i] = mobj
moodMenu.addAction(maction)
moodCategories[Mood.revmoodcats[m]].addAction(maction)
exitAction = QtGui.QAction("EXIT", self)
self.trayicon.connect(exitAction, QtCore.SIGNAL('triggered()'),
self.widget, QtCore.SLOT('close()'))