fds
This commit is contained in:
parent
0337a77bb5
commit
7cc312a4bd
13 changed files with 133 additions and 44 deletions
17
TODO
17
TODO
|
@ -1,11 +1,15 @@
|
|||
Features:
|
||||
-- package
|
||||
* CEASE shouldn't be sent if chum window is closed
|
||||
* icon not restored after client logs back on -- User signon
|
||||
* color is lost if you close window!
|
||||
* chumdb still trying to serialize QString?
|
||||
* Windows: courier doesn't bold??
|
||||
* Transparent background
|
||||
* switch focus to lineedit
|
||||
* colors from ppl msging you not on your buddy list dont work
|
||||
* colors from ppl msging you not on your buddy list dont work - check chumdb
|
||||
* scaling icons
|
||||
* menubar should pass on mouse move
|
||||
* chat scrolls when switch theme
|
||||
* softcode menu names and protocol messages, menu location
|
||||
* eliminate "SWITCH" in profile menu
|
||||
* windows text goes gray when out of focus
|
||||
* Logging
|
||||
* Block list
|
||||
* User list/add from list
|
||||
|
@ -13,10 +17,9 @@ Features:
|
|||
* User commands/stop user from sending commands accidentally
|
||||
* Hyperlinks
|
||||
* color tags
|
||||
* Transparent background
|
||||
* /me
|
||||
-- release alpha
|
||||
* shared buddy lists - changes to the buddy list should refresh it?
|
||||
* shared buddy lists - changes to the buddy list should refresh it?
|
||||
multiple clients share buddy list???
|
||||
* User profile menu options (color...?)
|
||||
* System tray menu
|
||||
|
|
Binary file not shown.
BIN
oyoyo/client.pyc
BIN
oyoyo/client.pyc
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
oyoyo/parse.pyc
BIN
oyoyo/parse.pyc
Binary file not shown.
|
@ -1 +1 @@
|
|||
{"tabs": true, "chums": ["aquaMarinist", "gardenGnostic", "gamblingGenocider", "schlagzeugGator", "mechanicalSpectacle"]}
|
||||
{"tabs": true, "chums": ["aquaMarinist", "gardenGnostic", "gamblingGenocider", "schlagzeugGator", "mechanicalSpectacle", "marineAquist"], "defaultprofile": "testProfile"}
|
109
pesterchum.py
109
pesterchum.py
|
@ -64,10 +64,47 @@ class waitingMessageHolder(object):
|
|||
class NoneSound(object):
|
||||
def play(self): pass
|
||||
|
||||
class PesterProfileDB(dict):
|
||||
def __init__(self):
|
||||
try:
|
||||
fp = open("logs/chums.js", 'r')
|
||||
chumdict = json.load(fp)
|
||||
fp.close()
|
||||
except IOError:
|
||||
chumdict = {}
|
||||
fp = open("logs/chums.js", 'w')
|
||||
json.dump(chumdict, fp)
|
||||
fp.close()
|
||||
converted = dict([(handle, PesterProfile(handle, color=QtGui.Color(c['color']), mood=Mood(c['mood']))) for (handle, c) in chumdict.iteritems()])
|
||||
self.update(converted)
|
||||
|
||||
def save(self):
|
||||
fp = open("logs/chums.js", 'w')
|
||||
chumdict = dict([p.plaindict() for p in self.itervalues()])
|
||||
json.dump(chumdict, fp)
|
||||
fp.close()
|
||||
def getColor(self, handle, default=None):
|
||||
if not self.has_key(handle):
|
||||
return default
|
||||
else:
|
||||
return self[handle]["color"]
|
||||
def setColor(self, handle, color):
|
||||
if self.has_key(handle):
|
||||
self[handle].color = color
|
||||
else:
|
||||
self[handle] = PesterProfile(handle, color)
|
||||
def __setitem__(self, key, val):
|
||||
dict.__setitem__(self, key, val)
|
||||
self.save()
|
||||
|
||||
class PesterProfile(object):
|
||||
def __init__(self, handle, color=QtGui.QColor("black"),
|
||||
mood=Mood("offline")):
|
||||
def __init__(self, handle, color=None, mood=Mood("offline"), chumdb=None):
|
||||
self.handle = handle
|
||||
if color is None:
|
||||
if chumdb:
|
||||
color = chumdb.getColor(handle, QtGui.QColor("black"))
|
||||
else:
|
||||
color = QtGui.QColor("black")
|
||||
self.color = color
|
||||
self.mood = mood
|
||||
def initials(self):
|
||||
|
@ -81,6 +118,11 @@ class PesterProfile(object):
|
|||
def colorcmd(self):
|
||||
(r, g, b, a) = self.color.getRgb()
|
||||
return "%d,%d,%d" % (r,g,b)
|
||||
def plaindict(self):
|
||||
return (self.handle, {"handle": self.handle,
|
||||
"mood": self.mood.name(),
|
||||
"color": unicode(self.color.name())})
|
||||
|
||||
def beganpestermsg(self, otherchum):
|
||||
return "<span style='color:black;'>-- %s <span style='color:%s'>[%s]</span> began pestering %s <span style='color:%s'>[%s]</span> at %s --</span>" % (self.handle, self.colorhtml(), self.initials(), otherchum.handle, otherchum.colorhtml(), otherchum.initials(), datetime.now().strftime("%H:%M"))
|
||||
def ceasedpestermsg(self, otherchum):
|
||||
|
@ -230,7 +272,11 @@ class userProfile(object):
|
|||
fp = open("profiles/%s.js" % (user))
|
||||
self.userprofile = json.load(fp)
|
||||
fp.close()
|
||||
self.theme = pesterTheme(self.userprofile["theme"])
|
||||
try:
|
||||
self.theme = pesterTheme(self.userprofile["theme"])
|
||||
except ValueError, e:
|
||||
self.theme = pesterTheme("pesterchum")
|
||||
|
||||
self.chat = PesterProfile(self.userprofile["handle"],
|
||||
QtGui.QColor(self.userprofile["color"]),
|
||||
Mood(self.theme["main/defaultmood"]))
|
||||
|
@ -310,7 +356,7 @@ class PesterQuirkItem(QtGui.QListWidgetItem):
|
|||
def __init__(self, quirk, parent):
|
||||
QtGui.QListWidgetItem.__init__(self, parent)
|
||||
self.quirk = quirk
|
||||
self.setText(str(quirk))
|
||||
self.setText(unicode(quirk))
|
||||
|
||||
def __lt__(self, quirkitem):
|
||||
if self.quirk.type == "prefix":
|
||||
|
@ -1018,7 +1064,7 @@ class PesterConvo(QtGui.QFrame):
|
|||
|
||||
def updateMood(self, mood):
|
||||
if mood.name() == "offline":
|
||||
msg = self.mainwindow.profile().ceasepestermsg(self.chum)
|
||||
msg = self.mainwindow.profile().ceasedpestermsg(self.chum)
|
||||
self.textArea.append(msg)
|
||||
self.chumopen = False
|
||||
if self.parent():
|
||||
|
@ -1156,6 +1202,8 @@ class PesterWindow(MovingWindow):
|
|||
self.connect(self.miniButton, QtCore.SIGNAL('clicked()'),
|
||||
self, QtCore.SLOT('showMinimized()'))
|
||||
|
||||
self.chumdb = PesterProfileDB()
|
||||
|
||||
chums = [PesterProfile(c) for c in set(self.config.chums())]
|
||||
self.chumList = chumArea(chums, self)
|
||||
self.connect(self.chumList,
|
||||
|
@ -1174,6 +1222,8 @@ class PesterWindow(MovingWindow):
|
|||
self.connect(self.pesterButton, QtCore.SIGNAL('clicked()'),
|
||||
self, QtCore.SLOT('pesterSelectedChum()'))
|
||||
|
||||
self.moodsLabel = QtGui.QLabel(self.theme["main/moodlabel/text"], self)
|
||||
|
||||
self.mychumhandleLabel = QtGui.QLabel(self.theme["main/mychumhandle/label/text"], self)
|
||||
self.mychumhandle = QtGui.QPushButton(self.profile().handle, self)
|
||||
self.mychumhandle.setFlat(True)
|
||||
|
@ -1227,6 +1277,7 @@ class PesterWindow(MovingWindow):
|
|||
self.chumList.updateColor(handle, color)
|
||||
if self.convos.has_key(handle):
|
||||
self.convos[handle].updateColor(color)
|
||||
self.chumdb.setColor(handle, color)
|
||||
|
||||
def updateMood(self, handle, mood):
|
||||
self.chumList.updateMood(handle, mood)
|
||||
|
@ -1280,6 +1331,10 @@ class PesterWindow(MovingWindow):
|
|||
self.miniButton.setIcon(QtGui.QIcon(theme["main/minimize/image"]))
|
||||
self.miniButton.move(*theme["main/minimize/loc"])
|
||||
# moods
|
||||
self.moodsLabel.setText(theme["main/moodlabel/text"])
|
||||
self.moodsLabel.move(*theme["main/moodlabel/loc"])
|
||||
self.moodsLabel.setStyleSheet(theme["main/moodlabel/style"])
|
||||
|
||||
if hasattr(self, 'moods'):
|
||||
self.moods.removeButtons()
|
||||
self.moods = PesterMoodHandler(self, *[PesterMoodButton(self, **d) for d in theme["main/moods"]])
|
||||
|
@ -1358,9 +1413,11 @@ class PesterWindow(MovingWindow):
|
|||
self.newConversation(chum)
|
||||
@QtCore.pyqtSlot(QtCore.QString)
|
||||
def closeConvo(self, handle):
|
||||
h = str(handle)
|
||||
h = unicode(handle)
|
||||
chumopen = self.convos[h].chumopen
|
||||
del self.convos[h]
|
||||
self.convoClosed.emit(handle)
|
||||
if chumopen:
|
||||
self.convoClosed.emit(handle)
|
||||
@QtCore.pyqtSlot()
|
||||
def tabsClosed(self):
|
||||
del self.tabconvo
|
||||
|
@ -1368,18 +1425,18 @@ class PesterWindow(MovingWindow):
|
|||
|
||||
@QtCore.pyqtSlot(QtCore.QString, Mood)
|
||||
def updateMoodSlot(self, handle, mood):
|
||||
h = str(handle)
|
||||
h = unicode(handle)
|
||||
self.updateMood(h, mood)
|
||||
|
||||
@QtCore.pyqtSlot(QtCore.QString, QtGui.QColor)
|
||||
def updateColorSlot(self, handle, color):
|
||||
h = str(handle)
|
||||
h = unicode(handle)
|
||||
self.changeColor(h, color)
|
||||
|
||||
@QtCore.pyqtSlot(QtCore.QString, QtCore.QString)
|
||||
def deliverMessage(self, handle, msg):
|
||||
h = str(handle)
|
||||
m = str(msg)
|
||||
h = unicode(handle)
|
||||
m = unicode(msg)
|
||||
self.newMessage(h, m)
|
||||
|
||||
@QtCore.pyqtSlot()
|
||||
|
@ -1477,7 +1534,12 @@ class PesterWindow(MovingWindow):
|
|||
def themeSelected(self):
|
||||
themename = unicode(self.choosetheme.themeBox.currentText())
|
||||
if themename != self.theme.name:
|
||||
self.changeTheme(pesterTheme(themename))
|
||||
try:
|
||||
self.changeTheme(pesterTheme(themename))
|
||||
except ValueError, e:
|
||||
themeWarning = QtGui.QMessageBox()
|
||||
closeWarning.setText("Theme Error: %s", e)
|
||||
return
|
||||
# update profile
|
||||
self.userprofile.setTheme(self.theme)
|
||||
self.choosetheme = None
|
||||
|
@ -1520,6 +1582,7 @@ class PesterWindow(MovingWindow):
|
|||
color = self.colorDialog.getColor(initial=self.profile().color)
|
||||
self.mychumcolor.setStyleSheet("background: %s" % color.name())
|
||||
self.userprofile.setColor(color)
|
||||
self.mycolorUpdated.emit()
|
||||
self.colorDialog = None
|
||||
@QtCore.pyqtSlot()
|
||||
def closeProfile(self):
|
||||
|
@ -1561,6 +1624,7 @@ class PesterWindow(MovingWindow):
|
|||
profileChanged = QtCore.pyqtSignal()
|
||||
moodRequest = QtCore.pyqtSignal(PesterProfile)
|
||||
moodUpdated = QtCore.pyqtSignal()
|
||||
mycolorUpdated = QtCore.pyqtSignal()
|
||||
trayIconSignal = QtCore.pyqtSignal(int)
|
||||
|
||||
class PesterIRC(QtCore.QObject):
|
||||
|
@ -1584,13 +1648,13 @@ class PesterIRC(QtCore.QObject):
|
|||
|
||||
@QtCore.pyqtSlot(QtCore.QString, bool)
|
||||
def startConvo(self, handle, initiated):
|
||||
h = str(handle)
|
||||
h = unicode(handle)
|
||||
if initiated:
|
||||
helpers.msg(self.cli, h, "PESTERCHUM:BEGIN")
|
||||
helpers.msg(self.cli, h, "COLOR >%s" % (self.mainwindow.profile().colorcmd()))
|
||||
@QtCore.pyqtSlot(QtCore.QString)
|
||||
def endConvo(self, handle):
|
||||
h = str(handle)
|
||||
h = unicode(handle)
|
||||
helpers.msg(self.cli, h, "PESTERCHUM:CEASE")
|
||||
@QtCore.pyqtSlot()
|
||||
def updateProfile(self):
|
||||
|
@ -1602,6 +1666,11 @@ class PesterIRC(QtCore.QObject):
|
|||
def updateMood(self):
|
||||
me = self.mainwindow.profile()
|
||||
helpers.msg(self.cli, "#pesterchum", "MOOD >%d" % (me.mood.value()))
|
||||
@QtCore.pyqtSlot()
|
||||
def updateColor(self):
|
||||
me = self.mainwindow.profile()
|
||||
for h in self.mainwindow.convos.keys():
|
||||
helpers.msg(self.cli, h, "COLOR >%s" % (self.mainwindow.profile().colorcmd()))
|
||||
def updateIRC(self):
|
||||
self.conn.next()
|
||||
|
||||
|
@ -1664,10 +1733,14 @@ class PesterHandler(DefaultCommandHandler):
|
|||
def quit(self, nick, reason):
|
||||
handle = nick[0:nick.find("!")]
|
||||
self.parent.moodUpdated.emit(handle, Mood("offline"))
|
||||
def part(self, nick, channel):
|
||||
def part(self, nick, channel, reason="nanchos"):
|
||||
handle = nick[0:nick.find("!")]
|
||||
if channel == "#pesterchum":
|
||||
self.parent.moodUpdated.emit(handle, Mood("offline"))
|
||||
self.parent.moodUpdated.emit(handle, Mood("offline"))
|
||||
def join(self, nick, channel):
|
||||
handle = nick[0:nick.find("!")]
|
||||
if channel == "#pesterchum":
|
||||
self.parent.moodUpdated.emit(handle, Mood("chummy"))
|
||||
def nick(self, oldnick, newnick):
|
||||
oldhandle = oldnick[0:oldnick.find("!")]
|
||||
newchum = PesterProfile(newnick)
|
||||
|
@ -1756,6 +1829,10 @@ def main():
|
|||
QtCore.SIGNAL('moodUpdated()'),
|
||||
irc,
|
||||
QtCore.SLOT('updateMood()'))
|
||||
irc.connect(widget,
|
||||
QtCore.SIGNAL('mycolorUpdated()'),
|
||||
irc,
|
||||
QtCore.SLOT('updateColor()'))
|
||||
irc.connect(irc,
|
||||
QtCore.SIGNAL('moodUpdated(QString, PyQt_PyObject)'),
|
||||
widget,
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"color": "#ff00ff", "theme": "pesterchum", "quirks": [], "handle": "ghostDunk"}
|
||||
{"color": "#ff00ff", "theme": "trollian", "quirks": [], "handle": "ghostDunk"}
|
1
profiles/testProfile.js
Normal file
1
profiles/testProfile.js
Normal file
|
@ -0,0 +1 @@
|
|||
{"color": "#aa00ff", "theme": "pesterchum", "quirks": [], "handle": "testProfile"}
|
|
@ -45,12 +45,12 @@
|
|||
}
|
||||
},
|
||||
"mychumhandle": { "label": { "text": "MYCHUMHANDLE",
|
||||
"loc": [70,410],
|
||||
"loc": [70,380],
|
||||
"style": "color:black;font:bold;" },
|
||||
"handle": { "style": "border:3px solid yellow; background: black; color:white;",
|
||||
"loc": [20,430],
|
||||
"loc": [20,400],
|
||||
"size": [220,30] },
|
||||
"colorswatch": { "loc": [243,430],
|
||||
"colorswatch": { "loc": [243,400],
|
||||
"size": [40,30],
|
||||
"text": "" }
|
||||
},
|
||||
|
@ -66,7 +66,11 @@
|
|||
"size": [100, 40],
|
||||
"text": "PESTER!"
|
||||
},
|
||||
"defaultmood": 0,
|
||||
"defaultmood": "chummy",
|
||||
"moodlabel": { "style": "",
|
||||
"loc": [20, 430],
|
||||
"text": "MOODS"
|
||||
},
|
||||
"moods": [
|
||||
{ "style": "text-align:left; background: white; border:3px solid black; padding: 5px;color:#919191;",
|
||||
"selected": "text-align:left; background: white; border:3px solid black; padding: 5px;font: bold;",
|
||||
|
@ -74,7 +78,7 @@
|
|||
"size": [133, 30],
|
||||
"text": "CHUMMY",
|
||||
"icon": "$path/chummy.gif",
|
||||
"mood": 0
|
||||
"mood": "chummy"
|
||||
},
|
||||
{ "style": "text-align:left; background: white; border:3px solid black; padding: 5px;color: #919191",
|
||||
"selected": "text-align:left; background: white; border:3px solid black; padding: 5px;font: bold;",
|
||||
|
@ -82,7 +86,7 @@
|
|||
"size": [133, 30],
|
||||
"text": "PLEASANT",
|
||||
"icon": "$path/pleasant.gif",
|
||||
"mood": 3
|
||||
"mood": "pleasant"
|
||||
},
|
||||
{ "style": "text-align:left; background: white; border:3px solid black; padding: 5px;color:#919191;",
|
||||
"selected": "text-align:left; background: white; border:3px solid black; padding: 5px;font: bold;",
|
||||
|
@ -90,7 +94,7 @@
|
|||
"size": [133, 30],
|
||||
"text": "DISTRAUGHT",
|
||||
"icon": "$path/distraught.gif",
|
||||
"mood": 4
|
||||
"mood": "distraught"
|
||||
},
|
||||
{ "style": "text-align:left; background: white; border:3px solid black; padding: 5px;color:#919191;",
|
||||
"selected": "text-align:left; background: white; border:3px solid black; padding: 5px;font: bold;",
|
||||
|
@ -98,7 +102,7 @@
|
|||
"size": [133, 30],
|
||||
"text": "UNRULY",
|
||||
"icon": "$path/unruly.gif",
|
||||
"mood": 5
|
||||
"mood": "unruly"
|
||||
},
|
||||
{ "style": "text-align:left; background: white; border:3px solid black; padding: 5px;color:#919191;",
|
||||
"selected": "text-align:left; background: white; border:3px solid black; padding: 5px;font: bold;",
|
||||
|
@ -106,7 +110,7 @@
|
|||
"size": [133, 30],
|
||||
"text": "SMOOTH",
|
||||
"icon": "$path/smooth.gif",
|
||||
"mood": 6
|
||||
"mood": "smooth"
|
||||
},
|
||||
{ "style": "text-align:left; background: red; border:3px solid black; padding: 5px;",
|
||||
"selected": "text-align:left; background: red; border:3px solid black; padding: 5px;font: bold;",
|
||||
|
@ -114,7 +118,7 @@
|
|||
"size": [133, 30],
|
||||
"text": "RANCOROUS",
|
||||
"icon": "$path/rancorous.gif",
|
||||
"mood": 1
|
||||
"mood": "rancorous"
|
||||
},
|
||||
{ "style": "text-align:center; background: #919191; border:3px solid black; padding: 5px;",
|
||||
"selected": "text-align:center; background: #919191; border:3px solid black; padding: 5px;font: bold;",
|
||||
|
@ -122,7 +126,7 @@
|
|||
"size": [263, 30],
|
||||
"text": "ABSCOND",
|
||||
"icon": "$path/offline.gif",
|
||||
"mood": 2
|
||||
"mood": "offline"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
@ -66,7 +66,11 @@
|
|||
"size": [100, 40],
|
||||
"text": "TROLL"
|
||||
},
|
||||
"defaultmood": 7,
|
||||
"defaultmood": "ecstatic",
|
||||
"moodlabel": { "style": "",
|
||||
"loc": [20, 430],
|
||||
"text": "MOODS"
|
||||
},
|
||||
"moods": [
|
||||
{ "style": "text-align:left; background: black; border:3px solid black; padding: 5px;color:#dbdbdb;",
|
||||
"selected": "text-align:left; background: white; border:3px solid black; padding: 5px;font: bold;",
|
||||
|
@ -74,7 +78,7 @@
|
|||
"size": [133, 30],
|
||||
"text": "ECSTATIC",
|
||||
"icon": "$path/estatic.gif",
|
||||
"mood": 7
|
||||
"mood": "ecstatic"
|
||||
},
|
||||
{ "style": "text-align:left; background: black; border:3px solid black; padding: 5px;color: #dbdbdb",
|
||||
"selected": "text-align:left; background: white; border:3px solid black; padding: 5px;font: bold;",
|
||||
|
@ -82,7 +86,7 @@
|
|||
"size": [133, 30],
|
||||
"text": "RELAXED",
|
||||
"icon": "$path/relaxed.gif",
|
||||
"mood": 8
|
||||
"mood": "relaxed"
|
||||
},
|
||||
{ "style": "text-align:left; background: black; border:3px solid black; padding: 5px;color:#dbdbdb;",
|
||||
"selected": "text-align:left; background: white; border:3px solid black; padding: 5px;font: bold;",
|
||||
|
@ -90,7 +94,7 @@
|
|||
"size": [133, 30],
|
||||
"text": "DISCONTENT",
|
||||
"icon": "$path/discontent.gif",
|
||||
"mood": 9
|
||||
"mood": "discontent"
|
||||
},
|
||||
{ "style": "text-align:left; background: black; border:3px solid black; padding: 5px;color:#dbdbdb;",
|
||||
"selected": "text-align:left; background: white; border:3px solid black; padding: 5px;font: bold;",
|
||||
|
@ -98,7 +102,7 @@
|
|||
"size": [133, 30],
|
||||
"text": "DEVIOUS",
|
||||
"icon": "$path/devious.gif",
|
||||
"mood": 10
|
||||
"mood": "devious"
|
||||
},
|
||||
{ "style": "text-align:left; background: black; border:3px solid black; padding: 5px;color:#dbdbdb;",
|
||||
"selected": "text-align:left; background: white; border:3px solid black; padding: 5px;font: bold;",
|
||||
|
@ -106,7 +110,7 @@
|
|||
"size": [133, 30],
|
||||
"text": "SLEEK",
|
||||
"icon": "$path/sleek.gif",
|
||||
"mood": 11
|
||||
"mood": "sleek"
|
||||
},
|
||||
{ "style": "text-align:left; background: red; border:3px solid black; padding: 5px;",
|
||||
"selected": "text-align:left; background: red; border:3px solid black; padding: 5px;font: bold;",
|
||||
|
@ -114,7 +118,7 @@
|
|||
"size": [133, 30],
|
||||
"text": "DETESTFUL",
|
||||
"icon": "$path/detestful.gif",
|
||||
"mood": 12
|
||||
"mood": "detestful"
|
||||
},
|
||||
{ "style": "text-align:center; background: #919191; border:3px solid black; padding: 5px;",
|
||||
"selected": "text-align:center; background: #919191; border:3px solid black; padding: 5px;font: bold;",
|
||||
|
@ -122,7 +126,7 @@
|
|||
"size": [263, 30],
|
||||
"text": "ABSCOND",
|
||||
"icon": "$path/offline.gif",
|
||||
"mood": 2
|
||||
"mood": "offline"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue