step 1 of profiles

This commit is contained in:
Stephen Dranger 2011-01-27 20:21:02 -06:00
parent 1d93008e2a
commit e3ae0bee89
7 changed files with 219 additions and 9 deletions

16
TODO Normal file
View file

@ -0,0 +1,16 @@
Features:
* Profile management
* Theme Changing
* Handle user signoffs
* Logging
* Moods
* Add chum
* REMOVE chum
* New message reminder
* User profile options
* Quirks
* Block list
* User list/add from list
* Chat rooms
* Spy mode

View file

@ -23,6 +23,9 @@ def msg(cli, user, msg):
for line in msg.split('\n'): for line in msg.split('\n'):
cli.send("PRIVMSG", user, ":%s" % line) cli.send("PRIVMSG", user, ":%s" % line)
def nick(cli, nick):
cli.send("NICK", nick)
def msgrandom(cli, choices, dest, user=None): def msgrandom(cli, choices, dest, user=None):
o = "%s: " % user if user else "" o = "%s: " % user if user else ""
o += random.choice(choices) o += random.choice(choices)

Binary file not shown.

View file

@ -3,7 +3,9 @@ from oyoyo.client import IRCClient
from oyoyo.cmdhandler import DefaultCommandHandler from oyoyo.cmdhandler import DefaultCommandHandler
from oyoyo import helpers from oyoyo import helpers
import logging import logging
import sys import os, sys
import os.path
import random
import json import json
from PyQt4 import QtGui, QtCore from PyQt4 import QtGui, QtCore
@ -72,11 +74,18 @@ class userConfig(object):
fp = open("pesterchum.js") fp = open("pesterchum.js")
self.config = json.load(fp) self.config = json.load(fp)
fp.close() fp.close()
self.theme = pesterTheme(self.config["theme"]) self.defaulttheme = pesterTheme("pesterchum")
if self.config.has_key("defaultprofile"):
self.profile = userProfile(self.config["defaultprofile"])
else:
self.profile = None
def chums(self): def chums(self):
return self.config['chums'] return self.config['chums']
def getTheme(self): def getTheme(self):
return self.theme if self.profile:
return self.profile.getTheme()
else:
return self.defaulttheme
def tabs(self): def tabs(self):
return self.config["tabs"] return self.config["tabs"]
def set(self, item, setting): def set(self, item, setting):
@ -84,6 +93,135 @@ class userConfig(object):
fp = open("pesterchum.js", 'w') fp = open("pesterchum.js", 'w')
json.dump(self.config, fp) json.dump(self.config, fp)
fp.close() fp.close()
def availableProfiles(self):
profs = []
for dirname, dirnames, filenames in os.walk('profiles'):
for filename in filenames:
l = len(filename)
if filename[l-3:l] == ".js":
profs.append(filename[0:l-3])
profs.sort()
return [userProfile(p) for p in profs]
class userProfile(object):
def __init__(self, user):
if type(user) is PesterProfile:
self.chat = user
self.userprofile = {"handle":user.handle,
"color": unicode(user.color.name()),
"quirks": [],
"theme": "pesterchum"}
self.theme = pesterTheme("pesterchum")
self.quirks = pesterQuirks([])
else:
fp = open("profiles/%s.js" % (user))
self.userprofile = json.load(fp)
fp.close()
self.chat = PesterProfile(self.userprofile["handle"],
QtGui.QColor(self.userprofile["color"]),
Mood(0))
self.theme = pesterTheme(self.userprofile["theme"])
self.quirks = pesterQuirks(self.userprofile["quirks"])
def getTheme(self):
return self.theme
def save(self):
handle = self.chat.handle
fp = open("profiles/%s.js" % (handle), 'w')
json.dump(self.userprofile, fp)
fp.close()
@staticmethod
def newUserProfile(chatprofile):
if os.path.exists("profiles/%s.js" % (chatprofile.handle)):
newprofile = userProfile(chatprofile.handle)
else:
newprofile = userProfile(chatprofile)
newprofile.save()
return newprofile
class pesterQuirks(object):
def __init__(self, quirklist):
self.quirklist = quirklist
class PesterChooseProfile(QtGui.QDialog):
def __init__(self, userprofile, config, theme, parent):
QtGui.QDialog.__init__(self, parent)
self.userprofile = userprofile
self.theme = theme
self.config = config
self.parent = parent
self.setStyleSheet(self.theme["main/defaultwindow/style"])
self.chumHandle = QtGui.QLineEdit(self)
self.chumHandle.setMinimumWidth(200)
self.chumHandleLabel = QtGui.QLabel(self.theme["main/labels/mychumhandle"], self)
self.chumColorButton = QtGui.QPushButton(self)
self.chumColorButton.resize(50, 20)
self.chumColorButton.setStyleSheet("background: %s" % (userprofile.chat.colorhtml()))
self.chumcolor = userprofile.chat.color
self.connect(self.chumColorButton, QtCore.SIGNAL('clicked()'),
self, QtCore.SLOT('openColorDialog()'))
layout_1 = QtGui.QHBoxLayout()
layout_1.addWidget(self.chumHandleLabel)
layout_1.addWidget(self.chumHandle)
layout_1.addWidget(self.chumColorButton)
# available profiles?
avail_profiles = self.config.availableProfiles()
if avail_profiles:
self.profileBox = QtGui.QComboBox(self)
self.profileBox.addItem("Choose a profile...")
for p in avail_profiles:
self.profileBox.addItem(p.chat.handle)
else:
self.profileBox = None
self.ok = QtGui.QPushButton("OK", self)
self.ok.setDefault(True)
self.connect(self.ok, QtCore.SIGNAL('clicked()'),
self, QtCore.SLOT('validateProfile()'))
self.cancel = QtGui.QPushButton("CANCEL", self)
self.connect(self.cancel, QtCore.SIGNAL('clicked()'),
self, QtCore.SLOT('reject()'))
layout_ok = QtGui.QHBoxLayout()
layout_ok.addWidget(self.cancel)
layout_ok.addWidget(self.ok)
layout_0 = QtGui.QVBoxLayout()
layout_0.addLayout(layout_1)
if avail_profiles:
profileLabel = QtGui.QLabel("Or choose an existing profile:", self)
layout_0.addWidget(profileLabel)
layout_0.addWidget(self.profileBox)
layout_0.addLayout(layout_ok)
self.errorMsg = QtGui.QLabel(self)
self.errorMsg.setStyleSheet("color:red;")
layout_0.addWidget(self.errorMsg)
self.setLayout(layout_0)
self.connect(self, QtCore.SIGNAL('accepted()'),
parent, QtCore.SLOT('profileSelected()'))
self.connect(self, QtCore.SIGNAL('rejected()'),
parent, QtCore.SLOT('closeProfile()'))
@QtCore.pyqtSlot()
def openColorDialog(self):
self.colorDialog = QtGui.QColorDialog(self)
color = self.colorDialog.getColor(initial=self.userprofile.chat.color)
self.chumColorButton.setStyleSheet("background: %s" % color.name())
self.chumcolor = color
self.colorDialog = None
@QtCore.pyqtSlot()
def validateProfile(self):
if not self.profileBox or self.profileBox.currentIndex() == 0:
handle = unicode(self.chumHandle.text())
if len(handle) > 256:
self.errorMsg.setText("PROFILE HANDLE IS TOO LONG")
return
caps = [l for l in handle if l.isupper()]
if len(caps) != 1 or handle[0].isupper():
self.errorMsg.setText("NOT A VALID CHUMTAG")
return
self.accept()
class PesterOptions(QtGui.QDialog): class PesterOptions(QtGui.QDialog):
def __init__(self, config, theme, parent): def __init__(self, config, theme, parent):
@ -105,10 +243,16 @@ class PesterOptions(QtGui.QDialog):
self.ok.setDefault(True) self.ok.setDefault(True)
self.connect(self.ok, QtCore.SIGNAL('clicked()'), self.connect(self.ok, QtCore.SIGNAL('clicked()'),
self, QtCore.SLOT('accept()')) self, QtCore.SLOT('accept()'))
self.cancel = QtGui.QPushButton("CANCEL", self)
self.connect(self.cancel, QtCore.SIGNAL('clicked()'),
self, QtCore.SLOT('reject()'))
layout_2 = QtGui.QHBoxLayout()
layout_2.addWidget(self.cancel)
layout_2.addWidget(self.ok)
layout_0 = QtGui.QVBoxLayout() layout_0 = QtGui.QVBoxLayout()
layout_0.addLayout(layout_1) layout_0.addLayout(layout_1)
layout_0.addWidget(self.ok) layout_0.addLayout(layout_2)
self.setLayout(layout_0) self.setLayout(layout_0)
@ -403,8 +547,16 @@ class PesterWindow(MovingWindow):
self.chumList = chumArea(chums, self.theme, self) self.chumList = chumArea(chums, self.theme, self)
self.connect(self.chumList, QtCore.SIGNAL('itemDoubleClicked(QListWidgetItem *)'), self.connect(self.chumList, QtCore.SIGNAL('itemDoubleClicked(QListWidgetItem *)'),
self, QtCore.SLOT('newConversationWindow(QListWidgetItem *)')) self, QtCore.SLOT('newConversationWindow(QListWidgetItem *)'))
if self.config.profile:
pass
#self.userprofile = self.config.profile
#self.profile = self.userprofile.chat
else:
self.userprofile = userProfile(PesterProfile("pesterClient%d" % (random.randint(100,999)), QtGui.QColor("black"), Mood(0)))
self.profile = self.userprofile.chat
self.chooseprofile = PesterChooseProfile(self.userprofile, self.config, self.theme, self)
self.chooseprofile.exec_()
self.profile = PesterProfile("superGhost", QtGui.QColor("red"), Mood(0))
self.convos = {} self.convos = {}
self.tabconvo = None self.tabconvo = None
self.optionmenu = None self.optionmenu = None
@ -497,10 +649,16 @@ class PesterWindow(MovingWindow):
self.optionmenu = PesterOptions(self.config, self.theme, self) self.optionmenu = PesterOptions(self.config, self.theme, self)
self.connect(self.optionmenu, QtCore.SIGNAL('accepted()'), self.connect(self.optionmenu, QtCore.SIGNAL('accepted()'),
self, QtCore.SLOT('updateOptions()')) self, QtCore.SLOT('updateOptions()'))
self.connect(self.optionmenu, QtCore.SIGNAL('rejected()'),
self, QtCore.SLOT('closeOptions()'))
self.optionmenu.show() self.optionmenu.show()
self.optionmenu.raise_() self.optionmenu.raise_()
self.optionmenu.activateWindow() self.optionmenu.activateWindow()
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
def closeOptions(self):
self.optionmenu.close()
self.optionmenu = None
@QtCore.pyqtSlot()
def updateOptions(self): def updateOptions(self):
# tabs # tabs
curtab = self.config.tabs() curtab = self.config.tabs()
@ -528,9 +686,31 @@ class PesterWindow(MovingWindow):
self.convos = newconvos self.convos = newconvos
# save options # save options
self.config.set("tabs", tabsetting) self.config.set("tabs", tabsetting)
pass
self.optionmenu = None self.optionmenu = None
@QtCore.pyqtSlot()
def profileSelected(self):
if self.chooseprofile.profileBox and \
self.chooseprofile.profileBox.currentIndex > 0:
handle = unicode(self.chooseprofile.profileBox.currentText())
self.userprofile = userProfile(handle)
self.profile = self.userprofile.chat
# update themes here
else:
profile = PesterProfile(unicode(self.chooseprofile.chumHandle.text()),
self.chooseprofile.chumcolor,
Mood(0))
self.userprofile = userProfile.newUserProfile(profile)
self.profile = self.userprofile.chat
self.chooseprofile = None
@QtCore.pyqtSlot()
def closeProfile(self):
self.chooseprofile = None
@QtCore.pyqtSlot()
def nickCollision(self):
pass
newConvoStarted = QtCore.pyqtSignal(QtCore.QString, bool, name="newConvoStarted") newConvoStarted = QtCore.pyqtSignal(QtCore.QString, bool, name="newConvoStarted")
sendMessage = QtCore.pyqtSignal(QtCore.QString, PesterProfile) sendMessage = QtCore.pyqtSignal(QtCore.QString, PesterProfile)
@ -574,7 +754,7 @@ class PesterIRC(QtCore.QObject):
colorUpdated = QtCore.pyqtSignal(QtCore.QString, QtGui.QColor) colorUpdated = QtCore.pyqtSignal(QtCore.QString, QtGui.QColor)
pesterchumBegin = QtCore.pyqtSignal(PesterProfile) pesterchumBegin = QtCore.pyqtSignal(PesterProfile)
messageReceived = QtCore.pyqtSignal(QtCore.QString, QtCore.QString) messageReceived = QtCore.pyqtSignal(QtCore.QString, QtCore.QString)
nickCollision = QtCore.pyqtSignal()
class PesterHandler(DefaultCommandHandler): class PesterHandler(DefaultCommandHandler):
def privmsg(self, nick, chan, msg): def privmsg(self, nick, chan, msg):
@ -623,6 +803,10 @@ class PesterHandler(DefaultCommandHandler):
chums = self.chums chums = self.chums
self.getMood(*chums) self.getMood(*chums)
def nicknameinuse(self, server, cmd, nick, msg):
helpers.nick(self.client, "pesterClient%d" % (random.randint(100,999)))
self.parent().emit.nickCollision.emit()
def getMood(self, *chums): def getMood(self, *chums):
chumglub = "GETMOOD " chumglub = "GETMOOD "
for c in chums: for c in chums:
@ -680,6 +864,10 @@ def main():
QtCore.SIGNAL('messageReceived(QString, QString)'), QtCore.SIGNAL('messageReceived(QString, QString)'),
widget, widget,
QtCore.SLOT('deliverMessage(QString, QString)')) QtCore.SLOT('deliverMessage(QString, QString)'))
irc.connect(irc,
QtCore.SIGNAL('nickCollision()'),
widget,
QtCore.SLOT('nickCollision()'))
ircapp = IRCThread(irc) ircapp = IRCThread(irc)
ircapp.start() ircapp.start()

1
profiles/geniusBar.js Normal file
View file

@ -0,0 +1 @@
{"color": "#ff007f", "theme": "pesterchum", "quirks": [], "handle": "geniusBar"}

1
profiles/ghostDunk.js Normal file
View file

@ -0,0 +1 @@
{"color": "#ff00ff", "theme": "pesterchum", "quirks": [], "handle": "ghostDunk"}

View file

@ -21,8 +21,9 @@
"color": "red" } "color": "red" }
} }
}, },
"defaultwindow": { "style": "background: #fdb302;" "defaultwindow": { "style": "background: #fdb302; font-family:'Courier New';font:bold;"
}, },
"labels": { "mychumhandle": "MYCHUMHANDLE" },
"elements": [ "elements": [
{ "style": "" } { "style": "" }
] ]