From 7caefa69714022765e21bf431e7e1f8fda5d6f38 Mon Sep 17 00:00:00 2001 From: Stephen Dranger Date: Mon, 24 Jan 2011 01:34:07 -0600 Subject: [PATCH] fds --- pesterchum.js | 3 +- pesterchum.py | 260 ++++++++++++++++++++++++++----------- themes/pesterchum/style.js | 12 ++ 3 files changed, 200 insertions(+), 75 deletions(-) diff --git a/pesterchum.js b/pesterchum.js index 048679f..0256a58 100644 --- a/pesterchum.js +++ b/pesterchum.js @@ -1,7 +1,8 @@ { "chums": ["gamblingGenocider", "grimAuxiliatrix", - "gardenGnostic" + "gardenGnostic", + "ghostDunk" ], "theme": "pesterchum" } \ No newline at end of file diff --git a/pesterchum.py b/pesterchum.py index f2c4ea2..1915df1 100644 --- a/pesterchum.py +++ b/pesterchum.py @@ -9,7 +9,6 @@ from PyQt4 import QtGui, QtCore logging.basicConfig(level=logging.INFO) - class Mood(object): moods = ["chummy", "rancorous", "offline"] def __init__(self, mood): @@ -22,65 +21,32 @@ class Mood(object): def name(self): return self.moods[self.mood] -class PesterIRC(QtCore.QObject): - def __init__(self, window): - QtCore.QObject.__init__(self) - self.window = window - def IRCConnect(self): - self.cli = IRCClient(PesterHandler, host="irc.tymoon.eu", port=6667, nick=self.window.currentHandle) - self.cli.command_handler.window = self.window - self.conn = self.cli.connect() +class PesterProfile(object): + def __init__(self, handle, color=None, mood=None): + self.handle = handle + self.color = color + self.mood = mood + def initials(self): + handle = self.handle + caps = [l for l in handle if l.isupper()] + if not caps: + caps = [""] + return (handle[0]+caps[0]).upper() - @QtCore.pyqtSlot() - def updateIRC(self): - self.conn.next() -class PesterHandler(DefaultCommandHandler): - def privmsg(self, nick, chan, msg): - # display msg, do other stuff - handle = nick[0:nick.find("!")] - if chan == "#pesterchum": - # follow instructions - if msg[0:6] == "MOOD >": - try: - mood = Mood(int(msg[6:])) - except ValueError: - mood = Mood(0) - self.window.updateMood(handle, mood) - elif msg[0:7] == "GETMOOD": - mychumhandle = self.window.currentHandle - mymood = self.window.currentMood.value() - if msg.find(mychumhandle, 8) != -1: - helpers.msg(self.client, "#pesterchum", - "MOOD >%d" % (mymood)) - - else: - # private message - pass - def welcome(self, server, nick, msg): - helpers.join(self.client, "#pesterchum") - mychumhandle = self.window.currentHandle - mymood = self.window.currentMood.value() - helpers.msg(self.client, "#pesterchum", "MOOD >%d" % (mymood)) - - chums = self.window.chumList.chums - chumglob = "GETMOOD " - for c in chums: - if len(chumglob+c) >= 510: - helpers.msg(self.client, "#pesterchum", chumglob) - chumglob = "GETMOOD " - chumglob += c - if chumglob != "GETMOOD ": - helpers.msg(self.client, "#pesterchum", chumglob) - -class pesterTheme(object): +class pesterTheme(dict): def __init__(self, name): self.path = "themes/%s" % (name) fp = open(self.path+"/style.js") - self.theme = json.load(fp, object_hook=self.pathHook) + theme = json.load(fp, object_hook=self.pathHook) + self.update(theme) fp.close() - def getSection(self, section): - return self.theme[section] + def __getitem__(self, key): + keys = key.split("/") + v = dict.__getitem__(self, keys.pop(0)) + for k in keys: + v = v[k] + return v def pathHook(self, d): from string import Template for (k, v) in d.iteritems(): @@ -108,10 +74,11 @@ class exitButton(QtGui.QPushButton): self.setAutoDefault(False) class chumListing(QtGui.QListWidgetItem): - def __init__(self, chumhandle, moodtheme): - QtGui.QListWidgetItem.__init__(self, chumhandle) - self.theme = moodtheme - self.handle = chumhandle + def __init__(self, chum, theme): + QtGui.QListWidgetItem.__init__(self, chum.handle) + self.theme = theme["main/chums/moods"] + self.chum = chum + self.handle = chum.handle self.setMood(Mood("offline")) def setMood(self, mood): self.mood = mood @@ -125,17 +92,18 @@ class chumListing(QtGui.QListWidgetItem): class chumArea(QtGui.QListWidget): def __init__(self, chums, theme, parent=None): QtGui.QListWidget.__init__(self, parent) - geometry = theme["loc"] + theme["size"] + geometry = theme["main/chums/loc"] + theme["main/chums/size"] self.setGeometry(*geometry) - self.setStyleSheet(theme["style"]) + self.setStyleSheet(theme["main/chums/style"]) self.chums = chums for c in self.chums: - if not self.findItems(c, QtCore.Qt.MatchFlags(0)): - chumLabel = chumListing(c, theme["moods"]) + chandle = c.handle + if not self.findItems(chandle, QtCore.Qt.MatchFlags(0)): + chumLabel = chumListing(c, theme) self.addItem(chumLabel) self.sortItems() - def updateMood(self, nick, mood): - chums = self.findItems(nick, QtCore.Qt.MatchFlags(0)) + def updateMood(self, handle, mood): + chums = self.findItems(handle, QtCore.Qt.MatchFlags(0)) for c in chums: c.setMood(mood) @@ -160,14 +128,79 @@ class MovingWindow(QtGui.QFrame): self.update() self.moving = None +class PesterText(QtGui.QTextEdit): + def __init__(self, theme, parent=None): + QtGui.QTextEdit.__init__(self, parent) + self.setStyleSheet(theme["convo/textarea/style"]) + self.setReadOnly(True) + def addMessage(self, text, chum): + if chum is None: + chum = self.parent().mainwindow.profile + color = chum.color + initials = chum.initials() + msg = str(text) + msg = msg.replace("&", "&").replace("<", "<").replace(">", ">") + self.append("%s: %s" % (color, initials, msg)) + +class PesterInput(QtGui.QLineEdit): + def __init__(self, theme, parent=None): + QtGui.QLineEdit.__init__(self, parent) + self.setStyleSheet(theme["convo/input/style"]) + +class PesterConvo(QtGui.QFrame): + def __init__(self, chumlisting, initiated, mainwindow, parent=None): + QtGui.QFrame.__init__(self, parent) + + self.chumlisting = chumlisting + self.theme = mainwindow.theme + self.mainwindow = mainwindow + convo = self.theme["convo"] + self.resize(*convo["size"]) + self.setStyleSheet(convo["style"]) + self.setWindowIcon(chumlisting.icon()) + self.setWindowTitle(chumlisting.handle) + + self.chumLabel = QtGui.QLabel(chumlisting.handle, self) + self.chumLabel.setStyleSheet(self.theme["convo/chumlabel/style"]) + self.textArea = PesterText(self.theme, self) + self.textInput = PesterInput(self.theme, self) + + self.connect(self.textInput, QtCore.SIGNAL('returnPressed()'), + self, QtCore.SLOT('sentMessage()')) + + self.layout = QtGui.QVBoxLayout() + self.layout.addWidget(self.chumLabel) + self.layout.addWidget(self.textArea) + self.layout.addWidget(self.textInput) + + self.setLayout(self.layout) + + def updateMood(self, mood): + icon = theme["chums/moods"][mood.name()] + self.setWindowIcon(icon) + # print mood update? + def addMessage(self, text, chum=None): + self.textArea.addMessage(text, chum) + + @QtCore.pyqtSlot() + def sentMessage(self): + text = self.textInput.text() + # deal with quirks here + self.textInput.setText("") + self.addMessage(text, None) + self.messageSent.emit(text, self.chumlisting) + + messageSent = QtCore.pyqtSignal(QtCore.QString, chumListing) + + class PesterWindow(MovingWindow): def __init__(self, parent=None): MovingWindow.__init__(self, parent, flags=QtCore.Qt.CustomizeWindowHint) self.setObjectName("main") self.config = userConfig() - theme = self.config.getTheme() - main = theme.getSection("main") + self.theme = self.config.getTheme() + main = self.theme["main"] width = int(main['width']) height = int(main['height']) self.setGeometry(100, 100, width, height) @@ -179,17 +212,93 @@ class PesterWindow(MovingWindow): self.closeButton.move(*closestyle["loc"]) self.connect(self.closeButton, QtCore.SIGNAL('clicked()'), self, QtCore.SLOT('close()')) - self.chumList = chumArea(self.config.chums(), main["chums"], self) + chums = [PesterProfile(c) for c in set(self.config.chums())] + self.chumList = chumArea(chums, self.theme, self) + self.connect(self.chumList, QtCore.SIGNAL('itemDoubleClicked(QListWidgetItem *)'), + self, QtCore.SLOT('newConversation(QListWidgetItem *)')) - self.currentHandle = "superGhost" - self.currentMood = Mood(0) + self.profile = PesterProfile("superGhost", QtGui.QColor("red"), Mood(0)) self.convos = {} - def updateMood(self, nick, mood): - self.chumList.updateMood(nick, mood) - def newConversation(self, nick): - convoWindow = PesterConvo(nick, self.theme) - self.convos[nick] = convoWindow + def closeEvent(self, event): + for c in self.convos.itervalues(): + c.close() + event.accept() + def newMessage(self, handle, msg): + pass + def updateMood(self, handle, mood): + self.chumList.updateMood(handle, mood) + if self.convos.has_key(handle): + self.convos[handle].updateMood(mood) + + @QtCore.pyqtSlot(QtGui.QListWidgetItem) + def newConversation(self, chum, initiated=True): + convoWindow = PesterConvo(chum, initiated, self) + self.connect(convoWindow, QtCore.SIGNAL('messageSent(QString, PyQt_PyObject)'), + self, QtCore.SIGNAL('sendMessage(QString, PyQt_PyObject)')) + self.convos[chum.handle] = convoWindow + + convoWindow.show() + + sendMessage = QtCore.pyqtSignal(QtCore.QString, chumListing) + +class PesterIRC(QtCore.QObject): + def __init__(self, window): + QtCore.QObject.__init__(self) + self.window = window + def IRCConnect(self): + self.cli = IRCClient(PesterHandler, host="irc.tymoon.eu", port=6667, nick=self.window.profile.handle) + self.cli.command_handler.window = self.window + self.conn = self.cli.connect() + + @QtCore.pyqtSlot(QtCore.QString, chumListing) + def sendMessage(self, text, chumlisting): + handle = chumlisting.handle + helpers.msg(self.cli, handle, text) + + @QtCore.pyqtSlot() + def updateIRC(self): + self.conn.next() + +class PesterHandler(DefaultCommandHandler): + def privmsg(self, nick, chan, msg): + # display msg, do other stuff + handle = nick[0:nick.find("!")] + if chan == "#pesterchum": + # follow instructions + if msg[0:6] == "MOOD >": + try: + mood = Mood(int(msg[6:])) + except ValueError: + mood = Mood(0) + self.window.updateMood(handle, mood) + elif msg[0:7] == "GETMOOD": + mychumhandle = self.window.profile.handle + mymood = self.window.profile.mood.value() + if msg.find(mychumhandle, 8) != -1: + helpers.msg(self.client, "#pesterchum", + "MOOD >%d" % (mymood)) + + else: + # private message + self.window.newMessage(handle, msg) + pass + def welcome(self, server, nick, msg): + helpers.join(self.client, "#pesterchum") + mychumhandle = self.window.profile.handle + mymood = self.window.profile.mood.value() + helpers.msg(self.client, "#pesterchum", "MOOD >%d" % (mymood)) + + chums = self.window.chumList.chums + chumglub = "GETMOOD " + for c in chums: + chandle = c.handle + if len(chumglub+chandle) >= 510: + helpers.msg(self.client, "#pesterchum", chumglub) + chumglub = "GETMOOD " + chumglub += chandle + if chumglub != "GETMOOD ": + helpers.msg(self.client, "#pesterchum", chumglub) def main(): @@ -205,6 +314,9 @@ def main(): irc = PesterIRC(widget) irc.IRCConnect() + irc.connect(widget, QtCore.SIGNAL('sendMessage(QString, PyQt_PyObject)'), + irc, QtCore.SLOT('sendMessage(QString, PyQt_PyObject)')) + irctimer = QtCore.QTimer(widget) widget.connect(irctimer, QtCore.SIGNAL('timeout()'), irc, QtCore.SLOT('updateIRC()')) diff --git a/themes/pesterchum/style.js b/themes/pesterchum/style.js index 23ba915..d3ad024 100644 --- a/themes/pesterchum/style.js +++ b/themes/pesterchum/style.js @@ -19,5 +19,17 @@ "elements": [ { "style": "" } ] + }, + "convo": + {"style": "background: #fdb302; font-family: 'Courier New'", + "size": [500, 500], + "chumlabel": { "style": "background: rgba(255, 255, 255, 25%);" }, + "textarea": { + "style": "background: white;" + }, + "input": { + "style": "background: white;" + } } + } \ No newline at end of file