pesterchum/pesterchum.py

677 lines
24 KiB
Python
Raw Normal View History

2011-01-21 05:18:22 -05:00
# pesterchum
from oyoyo.client import IRCClient
from oyoyo.cmdhandler import DefaultCommandHandler
from oyoyo import helpers
import logging
import sys
import json
from PyQt4 import QtGui, QtCore
logging.basicConfig(level=logging.INFO)
2011-01-22 04:36:24 -05:00
class Mood(object):
moods = ["chummy", "rancorous", "offline"]
def __init__(self, mood):
if type(mood) is int:
self.mood = mood
else:
self.mood = self.moods.index(mood)
def value(self):
return self.mood
def name(self):
2011-01-24 13:02:00 -05:00
try:
name = self.moods[self.mood]
except IndexError:
name = "chummy"
return name
2011-01-24 04:10:44 -05:00
def icon(self, theme):
f = theme["main/chums/moods"][self.name()]["icon"]
return QtGui.QIcon(f)
2011-01-22 04:36:24 -05:00
2011-01-24 02:34:07 -05:00
class PesterProfile(object):
2011-01-24 04:10:44 -05:00
def __init__(self, handle, color=QtGui.QColor("black"),
mood=Mood("offline")):
2011-01-24 02:34:07 -05:00
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 = [""]
2011-01-24 04:10:44 -05:00
return (handle[0]+caps[0]).upper()
def colorhtml(self):
return self.color.name()
def colorcmd(self):
(r, g, b, a) = self.color.getRgb()
return "%d,%d,%d" % (r,g,b)
2011-01-22 04:36:24 -05:00
2011-01-24 02:34:07 -05:00
class pesterTheme(dict):
2011-01-22 04:36:24 -05:00
def __init__(self, name):
self.path = "themes/%s" % (name)
fp = open(self.path+"/style.js")
2011-01-24 02:34:07 -05:00
theme = json.load(fp, object_hook=self.pathHook)
self.update(theme)
2011-01-22 04:36:24 -05:00
fp.close()
2011-01-24 02:34:07 -05:00
def __getitem__(self, key):
keys = key.split("/")
v = dict.__getitem__(self, keys.pop(0))
for k in keys:
v = v[k]
return v
2011-01-22 04:36:24 -05:00
def pathHook(self, d):
from string import Template
for (k, v) in d.iteritems():
if type(v) is unicode:
s = Template(v)
d[k] = s.substitute(path=self.path)
return d
2011-01-21 05:18:22 -05:00
class userConfig(object):
2011-01-27 04:46:47 -05:00
def __init__(self):
fp = open("pesterchum.js")
2011-01-21 05:18:22 -05:00
self.config = json.load(fp)
fp.close()
2011-01-22 04:36:24 -05:00
self.theme = pesterTheme(self.config["theme"])
2011-01-21 05:18:22 -05:00
def chums(self):
return self.config['chums']
2011-01-22 04:36:24 -05:00
def getTheme(self):
return self.theme
2011-01-26 05:32:35 -05:00
def tabs(self):
return self.config["tabs"]
2011-01-27 04:46:47 -05:00
def set(self, item, setting):
self.config[item] = setting
fp = open("pesterchum.js", 'w')
json.dump(self.config, fp)
fp.close()
class PesterOptions(QtGui.QDialog):
def __init__(self, config, theme, parent):
QtGui.QDialog.__init__(self, parent)
self.setModal(False)
self.config = config
self.theme = theme
self.setStyleSheet(self.theme["main/defaultwindow/style"])
self.tabcheck = QtGui.QCheckBox(self)
if self.config.tabs():
self.tabcheck.setChecked(True)
self.tablabel = QtGui.QLabel("Tabbed Conversations", self)
layout_1 = QtGui.QHBoxLayout()
layout_1.addWidget(self.tablabel)
layout_1.addWidget(self.tabcheck)
self.ok = QtGui.QPushButton("OK", self)
self.ok.setDefault(True)
self.connect(self.ok, QtCore.SIGNAL('clicked()'),
self, QtCore.SLOT('accept()'))
layout_0 = QtGui.QVBoxLayout()
layout_0.addLayout(layout_1)
layout_0.addWidget(self.ok)
self.setLayout(layout_0)
2011-01-21 05:18:22 -05:00
2011-01-27 04:46:47 -05:00
class WMButton(QtGui.QPushButton):
2011-01-21 05:18:22 -05:00
def __init__(self, icon, parent=None):
QtGui.QPushButton.__init__(self, icon, "", parent)
self.setFlat(True)
2011-01-22 04:36:24 -05:00
self.setStyleSheet("QPushButton { padding: 0px; }")
self.setAutoDefault(False)
class chumListing(QtGui.QListWidgetItem):
2011-01-24 02:34:07 -05:00
def __init__(self, chum, theme):
QtGui.QListWidgetItem.__init__(self, chum.handle)
2011-01-24 04:10:44 -05:00
self.theme = theme
2011-01-24 02:34:07 -05:00
self.chum = chum
self.handle = chum.handle
2011-01-22 04:36:24 -05:00
self.setMood(Mood("offline"))
def setMood(self, mood):
2011-01-24 04:10:44 -05:00
self.chum.mood = mood
self.updateMood()
def updateMood(self):
mood = self.chum.mood
2011-01-22 04:36:24 -05:00
self.mood = mood
2011-01-24 04:10:44 -05:00
self.setIcon(self.mood.icon(self.theme))
self.setTextColor(QtGui.QColor(self.theme["main/chums/moods"][self.mood.name()]["color"]))
2011-01-22 04:36:24 -05:00
def __lt__(self, cl):
h1 = self.handle.lower()
h2 = cl.handle.lower()
return (h1 < h2)
2011-01-21 05:18:22 -05:00
class chumArea(QtGui.QListWidget):
2011-01-22 04:36:24 -05:00
def __init__(self, chums, theme, parent=None):
2011-01-21 05:18:22 -05:00
QtGui.QListWidget.__init__(self, parent)
2011-01-24 02:34:07 -05:00
geometry = theme["main/chums/loc"] + theme["main/chums/size"]
2011-01-22 04:36:24 -05:00
self.setGeometry(*geometry)
2011-01-24 02:34:07 -05:00
self.setStyleSheet(theme["main/chums/style"])
2011-01-21 05:18:22 -05:00
self.chums = chums
for c in self.chums:
2011-01-24 02:34:07 -05:00
chandle = c.handle
if not self.findItems(chandle, QtCore.Qt.MatchFlags(0)):
chumLabel = chumListing(c, theme)
2011-01-22 04:36:24 -05:00
self.addItem(chumLabel)
self.sortItems()
2011-01-24 02:34:07 -05:00
def updateMood(self, handle, mood):
chums = self.findItems(handle, QtCore.Qt.MatchFlags(0))
2011-01-22 04:36:24 -05:00
for c in chums:
c.setMood(mood)
2011-01-21 05:18:22 -05:00
2011-01-22 04:36:24 -05:00
class MovingWindow(QtGui.QFrame):
def __init__(self, *x, **y):
QtGui.QFrame.__init__(self, *x, **y)
2011-01-21 05:18:22 -05:00
self.moving = None
2011-01-21 19:37:02 -05:00
self.moveupdate = 0
2011-01-21 05:18:22 -05:00
def mouseMoveEvent(self, event):
if self.moving:
move = event.globalPos() - self.moving
2011-01-21 19:37:02 -05:00
self.move(move)
self.moveupdate += 1
if self.moveupdate > 5:
self.moveupdate = 0
self.update()
2011-01-21 05:18:22 -05:00
def mousePressEvent(self, event):
if event.button() == 1:
2011-01-21 19:37:02 -05:00
self.moving = event.globalPos() - self.pos()
2011-01-21 05:18:22 -05:00
def mouseReleaseEvent(self, event):
if event.button() == 1:
2011-01-21 19:37:02 -05:00
self.update()
2011-01-21 05:18:22 -05:00
self.moving = None
2011-01-22 04:36:24 -05:00
2011-01-26 05:32:35 -05:00
class PesterTabWindow(QtGui.QFrame):
def __init__(self, mainwindow, parent=None):
QtGui.QFrame.__init__(self, parent)
self.mainwindow = mainwindow
self.theme = mainwindow.theme
self.resize(*self.theme["convo/size"])
self.setStyleSheet(self.theme["convo/style"])
self.tabs = QtGui.QTabBar(self)
2011-01-27 05:41:53 -05:00
self.tabs.setTabsClosable(True)
2011-01-26 05:32:35 -05:00
self.connect(self.tabs, QtCore.SIGNAL('currentChanged(int)'),
self, QtCore.SLOT('changeTab(int)'))
2011-01-27 05:41:53 -05:00
self.connect(self.tabs, QtCore.SIGNAL('tabCloseRequested(int)'),
self, QtCore.SLOT('tabClose(int)'))
2011-01-26 05:32:35 -05:00
self.tabs.setShape(self.theme["convo/tabstyle"])
self.layout = QtGui.QVBoxLayout()
self.layout.setContentsMargins(0,0,0,0)
self.layout.addWidget(self.tabs)
self.setLayout(self.layout)
self.convos = {}
self.tabIndices = {}
self.currentConvo = None
self.changedTab = False
2011-01-27 06:05:36 -05:00
self.softclose = False
2011-01-26 05:32:35 -05:00
def addChat(self, convo):
self.convos[convo.chum.handle] = convo
# either addTab or setCurrentIndex will trigger changed()
newindex = self.tabs.addTab(convo.chum.handle)
self.tabIndices[convo.chum.handle] = newindex
self.tabs.setCurrentIndex(newindex)
self.tabs.setTabIcon(newindex, convo.chum.mood.icon(self.theme))
def showChat(self, handle):
self.tabs.setCurrentIndex(self.tabIndices[handle])
def keyPressEvent(self, event):
keypress = event.key()
mods = event.modifiers()
if ((mods & QtCore.Qt.ControlModifier) and
keypress == QtCore.Qt.Key_Tab):
nexti = (self.tabIndices[self.currentConvo.chum.handle] + 1) % self.tabs.count()
self.tabs.setCurrentIndex(nexti)
2011-01-27 06:05:36 -05:00
def closeSoft(self):
self.softclose = True
self.close()
2011-01-26 05:50:00 -05:00
def updateMood(self, handle, mood):
i = self.tabIndices[handle]
self.tabs.setTabIcon(i, mood.icon(self.theme))
2011-01-27 05:41:53 -05:00
def closeEvent(self, event):
2011-01-27 06:05:36 -05:00
if not self.softclose:
while self.tabs.count() > 0:
self.tabClose(0)
2011-01-27 05:41:53 -05:00
self.windowClosed.emit()
@QtCore.pyqtSlot(int)
def tabClose(self, i):
handle = unicode(self.tabs.tabText(i))
convo = self.convos[handle]
del self.convos[handle]
del self.tabIndices[handle]
self.tabs.removeTab(i)
for (h, j) in self.tabIndices.iteritems():
if j > i:
self.tabIndices[h] = j-1
self.layout.removeWidget(convo)
convo.close()
if self.tabs.count() == 0:
self.close()
return
if self.currentConvo == convo:
currenti = self.tabs.currentIndex()
currenth = unicode(self.tabs.tabText(currenti))
self.currentConvo = self.convos[currenth]
self.currentConvo.raiseChat()
2011-01-26 05:32:35 -05:00
@QtCore.pyqtSlot(int)
def changeTab(self, i):
2011-01-27 05:41:53 -05:00
if i < 0:
return
2011-01-26 05:32:35 -05:00
if self.changedTab:
self.changedTab = False
return
handle = unicode(self.tabs.tabText(i))
convo = self.convos[handle]
if self.currentConvo:
self.layout.removeWidget(self.currentConvo)
self.currentConvo = convo
self.layout.addWidget(convo)
2011-01-26 05:50:00 -05:00
self.setWindowIcon(convo.chum.mood.icon(self.theme))
self.activateWindow()
self.raise_()
2011-01-26 05:32:35 -05:00
convo.raiseChat()
2011-01-27 05:41:53 -05:00
windowClosed = QtCore.pyqtSignal()
2011-01-24 02:34:07 -05:00
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):
2011-01-24 04:10:44 -05:00
color = chum.colorhtml()
2011-01-24 02:34:07 -05:00
initials = chum.initials()
msg = str(text)
msg = msg.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")
2011-01-24 04:10:44 -05:00
self.append("<span style='color:%s'>%s: %s</span>" % \
(color, initials, msg))
2011-01-24 02:34:07 -05:00
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):
2011-01-24 04:10:44 -05:00
def __init__(self, chum, initiated, mainwindow, parent=None):
2011-01-24 02:34:07 -05:00
QtGui.QFrame.__init__(self, parent)
2011-01-24 04:10:44 -05:00
self.chum = chum
2011-01-24 02:34:07 -05:00
self.theme = mainwindow.theme
self.mainwindow = mainwindow
convo = self.theme["convo"]
self.resize(*convo["size"])
self.setStyleSheet(convo["style"])
2011-01-24 04:10:44 -05:00
self.setWindowIcon(chum.mood.icon(self.theme))
self.setWindowTitle(chum.handle)
2011-01-24 02:34:07 -05:00
2011-01-24 04:10:44 -05:00
self.chumLabel = QtGui.QLabel(chum.handle, self)
2011-01-24 02:34:07 -05:00
self.chumLabel.setStyleSheet(self.theme["convo/chumlabel/style"])
self.textArea = PesterText(self.theme, self)
self.textInput = PesterInput(self.theme, self)
2011-01-24 04:10:44 -05:00
self.textInput.setFocus()
2011-01-24 02:34:07 -05:00
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)
2011-01-26 05:32:35 -05:00
if parent:
parent.addChat(self)
2011-01-24 02:34:07 -05:00
def updateMood(self, mood):
2011-01-26 05:50:00 -05:00
if self.parent():
self.parent().updateMood(self.chum.handle, mood)
else:
self.setWindowIcon(mood.icon(self.theme))
2011-01-24 02:34:07 -05:00
# print mood update?
2011-01-24 04:10:44 -05:00
def addMessage(self, text, me=True):
if me:
chum = self.mainwindow.profile
else:
chum = self.chum
2011-01-24 02:34:07 -05:00
self.textArea.addMessage(text, chum)
2011-01-26 05:32:35 -05:00
def raiseChat(self):
2011-01-24 13:02:00 -05:00
self.activateWindow()
self.raise_()
self.textInput.setFocus()
2011-01-24 02:34:07 -05:00
2011-01-26 05:32:35 -05:00
def showChat(self):
if self.parent():
self.parent().showChat(self.chum.handle)
self.raiseChat()
def closeEvent(self, event):
self.windowClosed.emit(self.chum.handle)
2011-01-24 02:34:07 -05:00
@QtCore.pyqtSlot()
def sentMessage(self):
text = self.textInput.text()
# deal with quirks here
self.textInput.setText("")
2011-01-24 04:10:44 -05:00
self.addMessage(text, True)
self.messageSent.emit(text, self.chum)
2011-01-24 02:34:07 -05:00
2011-01-24 04:10:44 -05:00
messageSent = QtCore.pyqtSignal(QtCore.QString, PesterProfile)
2011-01-26 05:32:35 -05:00
windowClosed = QtCore.pyqtSignal(QtCore.QString)
2011-01-24 02:34:07 -05:00
2011-01-22 04:36:24 -05:00
class PesterWindow(MovingWindow):
def __init__(self, parent=None):
MovingWindow.__init__(self, parent,
flags=QtCore.Qt.CustomizeWindowHint)
self.setObjectName("main")
self.config = userConfig()
2011-01-24 02:34:07 -05:00
self.theme = self.config.getTheme()
main = self.theme["main"]
2011-01-24 13:02:00 -05:00
size = main['size']
self.setGeometry(100, 100, size[0], size[1])
2011-01-22 04:36:24 -05:00
self.setWindowIcon(QtGui.QIcon(main["icon"]))
self.setStyleSheet("QFrame#main { "+main["style"]+" }")
2011-01-27 04:46:47 -05:00
opts = QtGui.QAction("OPTIONS", self)
self.connect(opts, QtCore.SIGNAL('triggered()'),
self, QtCore.SLOT('openOpts()'))
exitaction = QtGui.QAction("EXIT", self)
self.connect(exitaction, QtCore.SIGNAL('triggered()'),
self, QtCore.SLOT('close()'))
self.menu = QtGui.QMenuBar(self)
qmenustyle = "QMenu { background: transparent; %s } QMenu::item::selected { %s }" % (self.theme["main/menu/style"], self.theme["main/menu/selected"])
filemenu = self.menu.addMenu("FILE")
filemenu.addAction(opts)
filemenu.addAction(exitaction)
filemenu.setStyleSheet(qmenustyle)
self.menu.setStyleSheet("QMenuBar { background: transparent; %s } QMenuBar::item { background: transparent; } " % (self.theme["main/menubar/style"]))
2011-01-22 04:36:24 -05:00
closestyle = main["close"]
2011-01-27 04:46:47 -05:00
self.closeButton = WMButton(QtGui.QIcon(closestyle["image"]), self)
2011-01-22 04:36:24 -05:00
self.closeButton.move(*closestyle["loc"])
self.connect(self.closeButton, QtCore.SIGNAL('clicked()'),
self, QtCore.SLOT('close()'))
2011-01-27 04:46:47 -05:00
self.miniButton = WMButton(QtGui.QIcon(self.theme["main/minimize/image"]), self)
self.miniButton.move(*(self.theme["main/minimize/loc"]))
self.connect(self.miniButton, QtCore.SIGNAL('clicked()'),
self, QtCore.SLOT('showMinimized()'))
2011-01-24 02:34:07 -05:00
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 *)'),
2011-01-24 04:10:44 -05:00
self, QtCore.SLOT('newConversationWindow(QListWidgetItem *)'))
2011-01-22 04:36:24 -05:00
2011-01-24 02:34:07 -05:00
self.profile = PesterProfile("superGhost", QtGui.QColor("red"), Mood(0))
2011-01-22 04:36:24 -05:00
self.convos = {}
2011-01-26 05:32:35 -05:00
self.tabconvo = None
2011-01-27 04:46:47 -05:00
self.optionmenu = None
2011-01-24 02:34:07 -05:00
def closeEvent(self, event):
2011-01-27 05:41:53 -05:00
for c in self.convos.values():
2011-01-24 02:34:07 -05:00
c.close()
2011-01-26 05:32:35 -05:00
if self.tabconvo:
self.tabconvo.close()
2011-01-24 02:34:07 -05:00
event.accept()
def newMessage(self, handle, msg):
2011-01-24 04:10:44 -05:00
if not self.convos.has_key(handle):
chum = PesterProfile(handle)
self.newConversation(chum, False)
convo = self.convos[handle]
convo.addMessage(msg, False)
# play sound here
def changeColor(self, handle, color):
2011-01-24 02:34:07 -05:00
pass
def updateMood(self, handle, mood):
self.chumList.updateMood(handle, mood)
if self.convos.has_key(handle):
self.convos[handle].updateMood(mood)
def newConversation(self, chum, initiated=True):
2011-01-24 13:02:00 -05:00
if self.convos.has_key(chum.handle):
self.convos[chum.handle].showChat()
if not initiated:
# self.convos[chum.handle]
# add pesterchum:begin
pass
return
2011-01-26 05:50:00 -05:00
if self.config.tabs():
2011-01-26 05:32:35 -05:00
if not self.tabconvo:
self.tabconvo = PesterTabWindow(self)
2011-01-27 05:41:53 -05:00
self.connect(self.tabconvo, QtCore.SIGNAL('windowClosed()'),
self, QtCore.SLOT('tabsClosed()'))
2011-01-26 05:32:35 -05:00
convoWindow = PesterConvo(chum, initiated, self, self.tabconvo)
self.tabconvo.show()
else:
convoWindow = PesterConvo(chum, initiated, self)
2011-01-24 02:34:07 -05:00
self.connect(convoWindow, QtCore.SIGNAL('messageSent(QString, PyQt_PyObject)'),
self, QtCore.SIGNAL('sendMessage(QString, PyQt_PyObject)'))
2011-01-27 04:46:47 -05:00
self.connect(convoWindow, QtCore.SIGNAL('windowClosed(QString)'),
self, QtCore.SLOT('closeConvo(QString)'))
2011-01-24 02:34:07 -05:00
self.convos[chum.handle] = convoWindow
2011-01-24 04:10:44 -05:00
self.newConvoStarted.emit(QtCore.QString(chum.handle), initiated)
2011-01-24 02:34:07 -05:00
convoWindow.show()
2011-01-22 04:36:24 -05:00
2011-01-24 04:10:44 -05:00
@QtCore.pyqtSlot(QtGui.QListWidgetItem)
def newConversationWindow(self, chumlisting):
chum = chumlisting.chum
self.newConversation(chum)
2011-01-26 05:32:35 -05:00
@QtCore.pyqtSlot(QtCore.QString)
def closeConvo(self, handle):
h = str(handle)
2011-01-27 04:46:47 -05:00
del self.convos[h]
self.convoClosed.emit(handle)
2011-01-27 06:05:36 -05:00
@QtCore.pyqtSlot()
2011-01-27 05:41:53 -05:00
def tabsClosed(self):
del self.tabconvo
self.tabconvo = None
2011-01-24 04:10:44 -05:00
2011-01-24 07:17:12 -05:00
@QtCore.pyqtSlot(QtCore.QString, Mood)
def updateMoodSlot(self, handle, mood):
h = str(handle)
self.updateMood(h, mood)
@QtCore.pyqtSlot(QtCore.QString, QtGui.QColor)
def updateColorSlot(self, handle, color):
h = str(handle)
self.changeColor(h, color)
@QtCore.pyqtSlot(PesterProfile)
def pesterchumBeginSlot(self, chum):
self.newConversation(chum, False)
@QtCore.pyqtSlot(QtCore.QString, QtCore.QString)
def deliverMessage(self, handle, msg):
h = str(handle)
m = str(msg)
self.newMessage(h, m)
2011-01-27 04:46:47 -05:00
@QtCore.pyqtSlot()
def openOpts(self):
if not self.optionmenu:
self.optionmenu = PesterOptions(self.config, self.theme, self)
self.connect(self.optionmenu, QtCore.SIGNAL('accepted()'),
self, QtCore.SLOT('updateOptions()'))
self.optionmenu.show()
self.optionmenu.raise_()
self.optionmenu.activateWindow()
@QtCore.pyqtSlot()
def updateOptions(self):
# tabs
curtab = self.config.tabs()
tabsetting = self.optionmenu.tabcheck.isChecked()
if curtab and not tabsetting:
# split tabs into windows
2011-01-27 06:05:36 -05:00
if self.tabconvo:
windows = list(self.tabconvo.convos.values())
for w in windows:
w.setParent(None)
w.show()
w.raiseChat()
self.tabconvo.closeSoft()
2011-01-27 04:46:47 -05:00
# save options
self.config.set("tabs", tabsetting)
pass
elif tabsetting and not curtab:
# combine
# save options
self.config.set("tabs", tabsetting)
pass
self.optionmenu = None
2011-01-24 04:10:44 -05:00
newConvoStarted = QtCore.pyqtSignal(QtCore.QString, bool, name="newConvoStarted")
sendMessage = QtCore.pyqtSignal(QtCore.QString, PesterProfile)
2011-01-27 04:46:47 -05:00
convoClosed = QtCore.pyqtSignal(QtCore.QString)
2011-01-24 02:34:07 -05:00
class PesterIRC(QtCore.QObject):
2011-01-24 07:17:12 -05:00
def __init__(self, profile, chums):
2011-01-24 02:34:07 -05:00
QtCore.QObject.__init__(self)
2011-01-24 07:17:12 -05:00
self.profile = profile
self.chums = chums
2011-01-24 02:34:07 -05:00
def IRCConnect(self):
2011-01-24 07:17:12 -05:00
self.cli = IRCClient(PesterHandler, host="irc.tymoon.eu", port=6667, nick=self.profile.handle, blocking=True)
self.cli.command_handler.parent = self
self.cli.command_handler.profile = self.profile
self.cli.command_handler.chums = self.chums
2011-01-24 02:34:07 -05:00
self.conn = self.cli.connect()
2011-01-24 04:10:44 -05:00
def getMood(self, *chums):
self.cli.command_handler.getMood(*chums)
2011-01-24 02:34:07 -05:00
2011-01-24 04:10:44 -05:00
@QtCore.pyqtSlot(QtCore.QString, PesterProfile)
def sendMessage(self, text, chum):
handle = chum.handle
2011-01-24 02:34:07 -05:00
helpers.msg(self.cli, handle, text)
2011-01-24 04:10:44 -05:00
@QtCore.pyqtSlot(QtCore.QString, bool)
def startConvo(self, handle, initiated):
h = str(handle)
if initiated:
helpers.msg(self.cli, h, "PESTERCHUM:BEGIN")
2011-01-27 05:41:53 -05:00
helpers.msg(self.cli, h, "COLOR >%s" % (self.profile.colorcmd()))
2011-01-27 04:46:47 -05:00
@QtCore.pyqtSlot(QtCore.QString)
def endConvo(self, handle):
h = str(handle)
helpers.msg(self.cli, h, "PESTERCHUM:CEASE")
2011-01-24 04:10:44 -05:00
2011-01-24 02:34:07 -05:00
def updateIRC(self):
self.conn.next()
2011-01-24 07:17:12 -05:00
moodUpdated = QtCore.pyqtSignal(QtCore.QString, Mood)
colorUpdated = QtCore.pyqtSignal(QtCore.QString, QtGui.QColor)
pesterchumBegin = QtCore.pyqtSignal(PesterProfile)
messageReceived = QtCore.pyqtSignal(QtCore.QString, QtCore.QString)
2011-01-24 02:34:07 -05:00
class PesterHandler(DefaultCommandHandler):
def privmsg(self, nick, chan, msg):
# display msg, do other stuff
2011-01-24 04:10:44 -05:00
# silently ignore CTCP
if msg[0] == '\x01':
return
2011-01-24 02:34:07 -05:00
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)
2011-01-24 07:17:12 -05:00
self.parent.moodUpdated.emit(handle, mood)
2011-01-24 02:34:07 -05:00
elif msg[0:7] == "GETMOOD":
2011-01-24 07:17:12 -05:00
mychumhandle = self.profile.handle
mymood = self.profile.mood.value()
2011-01-24 02:34:07 -05:00
if msg.find(mychumhandle, 8) != -1:
helpers.msg(self.client, "#pesterchum",
"MOOD >%d" % (mymood))
else:
# private message
2011-01-24 04:10:44 -05:00
if msg[0:7] == "COLOR >":
colors = msg[7:].split(",")
try:
colors = [int(d) for d in colors]
except ValueError:
colors = [0,0,0]
color = QtGui.QColor(*colors)
2011-01-24 07:17:12 -05:00
self.parent.colorUpdated.emit(handle, color)
2011-01-24 04:10:44 -05:00
elif msg == "PESTERCHUM:BEGIN":
chum = PesterProfile(handle)
2011-01-24 07:17:12 -05:00
self.parent.pesterchumBegin.emit(chum)
2011-01-24 04:10:44 -05:00
else:
2011-01-24 07:17:12 -05:00
self.parent.messageReceived.emit(handle, msg)
2011-01-24 04:10:44 -05:00
2011-01-24 02:34:07 -05:00
def welcome(self, server, nick, msg):
helpers.join(self.client, "#pesterchum")
2011-01-24 07:17:12 -05:00
mychumhandle = self.profile.handle
mymood = self.profile.mood.value()
2011-01-24 02:34:07 -05:00
helpers.msg(self.client, "#pesterchum", "MOOD >%d" % (mymood))
2011-01-24 07:17:12 -05:00
chums = self.chums
2011-01-24 04:10:44 -05:00
self.getMood(*chums)
def getMood(self, *chums):
2011-01-24 02:34:07 -05:00
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)
2011-01-21 05:18:22 -05:00
2011-01-24 07:17:12 -05:00
class IRCThread(QtCore.QThread):
def __init__(self, ircobj):
QtCore.QThread.__init__(self)
self.irc = ircobj
def run(self):
irc = self.irc
while 1:
irc.updateIRC()
2011-01-21 05:18:22 -05:00
def main():
app = QtGui.QApplication(sys.argv)
widget = PesterWindow()
widget.show()
trayicon = QtGui.QSystemTrayIcon(QtGui.QIcon("themes/pesterchum/trayicon.gif"), app)
traymenu = QtGui.QMenu()
traymenu.addAction("Hi!! HI!!")
trayicon.setContextMenu(traymenu)
trayicon.show()
2011-01-24 07:17:12 -05:00
irc = PesterIRC(widget.profile, widget.chumList.chums)
2011-01-22 04:36:24 -05:00
irc.IRCConnect()
2011-01-24 02:34:07 -05:00
irc.connect(widget, QtCore.SIGNAL('sendMessage(QString, PyQt_PyObject)'),
irc, QtCore.SLOT('sendMessage(QString, PyQt_PyObject)'))
2011-01-24 04:10:44 -05:00
irc.connect(widget,
QtCore.SIGNAL('newConvoStarted(QString, bool)'),
irc, QtCore.SLOT('startConvo(QString, bool)'))
2011-01-27 04:46:47 -05:00
irc.connect(widget,
QtCore.SIGNAL('convoClosed(QString)'),
irc, QtCore.SLOT('endConvo(QString)'))
2011-01-24 07:17:12 -05:00
irc.connect(irc,
QtCore.SIGNAL('moodUpdated(QString, PyQt_PyObject)'),
widget,
QtCore.SLOT('updateMoodSlot(QString, PyQt_PyObject)'))
irc.connect(irc,
QtCore.SIGNAL('colorUpdated(QString, QColor)'),
widget,
QtCore.SLOT('updateColorSlot(QString, QColor)'))
irc.connect(irc,
QtCore.SIGNAL('pesterchumBegin(PyQt_PyObject)'),
widget,
QtCore.SLOT('pesterchumBeginSlot(PyQt_PyObject)'))
irc.connect(irc,
QtCore.SIGNAL('messageReceived(QString, QString)'),
widget,
QtCore.SLOT('deliverMessage(QString, QString)'))
ircapp = IRCThread(irc)
ircapp.start()
2011-01-21 05:18:22 -05:00
sys.exit(app.exec_())
main()