Timestamps for conversations and logs.

Options for turning timestamps on/off, 12/24 hour time, seconds/no seconds.
This commit is contained in:
Kiooeht 2011-03-11 23:44:59 -08:00
parent b2e5841469
commit 06bcad0ca0
3 changed files with 114 additions and 59 deletions

View file

@ -2,6 +2,7 @@ from string import Template
import re
import platform
import httplib, urllib
from time import strftime
from copy import copy
from datetime import datetime, timedelta
from PyQt4 import QtGui, QtCore
@ -65,14 +66,14 @@ class PesterTabWindow(QtGui.QFrame):
self.tabs.setCurrentIndex(tabi)
def convoHasFocus(self, convo):
if ((self.hasFocus() or self.tabs.hasFocus()) and
if ((self.hasFocus() or self.tabs.hasFocus()) and
self.tabs.tabText(self.tabs.currentIndex()) == convo.title()):
return True
def keyPressEvent(self, event):
keypress = event.key()
mods = event.modifiers()
if ((mods & QtCore.Qt.ControlModifier) and
if ((mods & QtCore.Qt.ControlModifier) and
keypress == QtCore.Qt.Key_Tab):
handles = self.convos.keys()
waiting = self.mainwindow.waitingMessages.waitingHandles()
@ -115,7 +116,7 @@ class PesterTabWindow(QtGui.QFrame):
self.clearNewMessage(handle)
def convoHasFocus(self, handle):
i = self.tabIndices[handle]
if (self.tabs.currentIndex() == i and
if (self.tabs.currentIndex() == i and
(self.hasFocus() or self.tabs.hasFocus())):
return True
else:
@ -221,6 +222,17 @@ class PesterText(QtGui.QTextEdit):
parent = self.parent()
window = parent.mainwindow
me = window.profile()
if self.parent().mainwindow.config.showTimeStamps():
if self.parent().mainwindow.config.time12Format():
time = strftime("[%I:%M")
else:
time = strftime("[%H:%M")
if self.parent().mainwindow.config.showSeconds():
time += strftime(":%S] ")
else:
time += "] "
else:
time = ""
if lexmsg[0] == "PESTERCHUM:BEGIN":
parent.setChumOpen(True)
pmsg = chum.pestermsg(me, systemColor, window.theme["convo/text/beganpester"])
@ -253,7 +265,7 @@ class PesterText(QtGui.QTextEdit):
window.chatlog.log(parent.chum.handle, memsg)
else:
window.chatlog.log(chum.handle, memsg)
self.append(convertTags(memsg))
self.append(time + convertTags(memsg))
else:
if not parent.chumopen and chum is not me:
beginmsg = chum.pestermsg(me, systemColor, window.theme["convo/text/beganpester"])
@ -261,10 +273,10 @@ class PesterText(QtGui.QTextEdit):
window.chatlog.log(chum.handle, beginmsg)
self.append(convertTags(beginmsg))
lexmsg[0:0] = [colorBegin("<c=%s>" % (color), color),
lexmsg[0:0] = [colorBegin("<c=%s>" % (color), color),
"%s: " % (initials)]
lexmsg.append(colorEnd("</c>"))
self.append(convertTags(lexmsg))
self.append(time + convertTags(lexmsg))
if chum is me:
window.chatlog.log(parent.chum.handle, lexmsg)
else:
@ -308,7 +320,7 @@ class PesterText(QtGui.QTextEdit):
if self.textSelected:
self.submitLogAction = QtGui.QAction("Submit to Pesterchum QDB", self)
self.connect(self.submitLogAction, QtCore.SIGNAL('triggered()'),
self, QtCore.SLOT('submitLog()'))
self, QtCore.SLOT('submitLog()'))
textMenu.addAction(self.submitLogAction)
textMenu.exec_(event.globalPos())
@ -338,7 +350,7 @@ class PesterText(QtGui.QTextEdit):
"Accept": "text/plain"}
try:
pass
hconn = httplib.HTTPConnection('luke.violentlemon.com', 80,
hconn = httplib.HTTPConnection('luke.violentlemon.com', 80,
timeout=15)
hconn.request("POST", "/index.php", params, headers)
response = hconn.getresponse()
@ -391,7 +403,7 @@ class PesterConvo(QtGui.QFrame):
self.setWindowTitle(self.title())
t = Template(self.mainwindow.theme["convo/chumlabel/text"])
self.chumLabel = QtGui.QLabel(t.safe_substitute(handle=chum.handle), self)
self.chumLabel.setStyleSheet(self.mainwindow.theme["convo/chumlabel/style"])
self.chumLabel.setAlignment(self.aligndict["h"][self.mainwindow.theme["convo/chumlabel/align/h"]] | self.aligndict["v"][self.mainwindow.theme["convo/chumlabel/align/v"]])
@ -413,7 +425,7 @@ class PesterConvo(QtGui.QFrame):
margins = self.mainwindow.theme["convo/margins"]
self.layout.setContentsMargins(margins["left"], margins["top"],
margins["right"], margins["bottom"])
self.setLayout(self.layout)
self.optionsMenu = QtGui.QMenu(self)
@ -508,8 +520,8 @@ class PesterConvo(QtGui.QFrame):
def notifyNewMessage(self):
# first see if this conversation HASS the focus
if not (self.hasFocus() or self.textArea.hasFocus() or
self.textInput.hasFocus() or
if not (self.hasFocus() or self.textArea.hasFocus() or
self.textInput.hasFocus() or
(self.parent() and self.parent().convoHasFocus(self.title()))):
# ok if it has a tabconvo parent, send that the notify.
if self.parent():
@ -521,7 +533,7 @@ class PesterConvo(QtGui.QFrame):
def func():
self.showChat()
self.mainwindow.waitingMessages.addMessage(self.title(), func)
def clearNewMessage(self):
if self.parent():
self.parent().clearNewMessage(self.title())
@ -555,7 +567,7 @@ class PesterConvo(QtGui.QFrame):
def changeTheme(self, theme):
self.resize(*theme["convo/size"])
self.setStyleSheet("QFrame#%s { %s }" % (self.chum.handle, theme["convo/style"]))
margins = theme["convo/margins"]
self.layout.setContentsMargins(margins["left"], margins["top"],
margins["right"], margins["bottom"])

View file

@ -21,7 +21,7 @@ class PesterQuirkItem(QtGui.QListWidgetItem):
return True
else:
return False
class PesterQuirkList(QtGui.QListWidget):
def __init__(self, mainwindow, parent):
QtGui.QListWidget.__init__(self, parent)
@ -93,7 +93,7 @@ class RandomQuirkDialog(MultiTextDialog):
layout_1.addWidget(regexpl)
layout_1.addWidget(self.regexp)
replacewithl = QtGui.QLabel("REPLACE WITH:", self)
layout_2 = QtGui.QVBoxLayout()
layout_3 = QtGui.QHBoxLayout()
self.replacelist = QtGui.QListWidget(self)
@ -141,7 +141,7 @@ class RandomQuirkDialog(MultiTextDialog):
else:
return None
@QtCore.pyqtSlot()
def addRandomString(self):
text = unicode(self.replaceinput.text())
@ -167,7 +167,7 @@ class PesterChooseQuirks(QtGui.QDialog):
self.setWindowTitle("Set Quirks")
self.quirkList = PesterQuirkList(self.mainwindow, self)
self.addPrefixButton = QtGui.QPushButton("ADD PREFIX", self)
self.connect(self.addPrefixButton, QtCore.SIGNAL('clicked()'),
self, QtCore.SLOT('addPrefixDialog()'))
@ -206,7 +206,7 @@ class PesterChooseQuirks(QtGui.QDialog):
layout_3 = QtGui.QHBoxLayout()
layout_3.addWidget(self.editSelectedButton)
layout_3.addWidget(self.removeSelectedButton)
self.ok = QtGui.QPushButton("OK", self)
self.ok.setDefault(True)
self.connect(self.ok, QtCore.SIGNAL('clicked()'),
@ -227,7 +227,7 @@ class PesterChooseQuirks(QtGui.QDialog):
self.setLayout(layout_0)
def quirks(self):
return [self.quirkList.item(i).quirk for i in
return [self.quirkList.item(i).quirk for i in
range(0,self.quirkList.count())]
@QtCore.pyqtSlot()
@ -317,7 +317,7 @@ class PesterChooseQuirks(QtGui.QDialog):
quirkWarning.setInformativeText("H3R3S WHY DUMP4SS: %s" % (e))
quirkWarning.exec_()
return
newquirk = pesterQuirk(vdict)
if qitem is None:
item = PesterQuirkItem(newquirk, self.quirkList)
@ -444,7 +444,7 @@ class PesterChooseProfile(QtGui.QDialog):
layout_2 = QtGui.QHBoxLayout()
layout_2.addWidget(self.defaultlabel)
layout_2.addWidget(self.defaultcheck)
self.ok = QtGui.QPushButton("OK", self)
self.ok.setDefault(True)
self.connect(self.ok, QtCore.SIGNAL('clicked()'),
@ -517,6 +517,22 @@ class PesterOptions(QtGui.QDialog):
self.soundcheck = QtGui.QCheckBox("Sounds On", self)
if self.config.soundOn():
self.soundcheck.setChecked(True)
self.timestampcheck = QtGui.QCheckBox("Time Stamps", self)
if self.config.showTimeStamps():
self.timestampcheck.setChecked(True)
self.timestampBox = QtGui.QComboBox(self)
self.timestampBox.addItem("12 hour")
self.timestampBox.addItem("24 hour")
if self.config.time12Format():
self.timestampBox.setCurrentIndex(0)
else:
self.timestampBox.setCurrentIndex(1)
self.secondscheck = QtGui.QCheckBox("Show Seconds", self)
if self.config.showSeconds():
self.secondscheck.setChecked(True)
self.ok = QtGui.QPushButton("OK", self)
self.ok.setDefault(True)
self.connect(self.ok, QtCore.SIGNAL('clicked()'),
@ -532,6 +548,9 @@ class PesterOptions(QtGui.QDialog):
layout_0.addWidget(self.tabcheck)
layout_0.addWidget(self.soundcheck)
layout_0.addWidget(self.hideOffline)
layout_0.addWidget(self.timestampcheck)
layout_0.addWidget(self.timestampBox)
layout_0.addWidget(self.secondscheck)
layout_0.addLayout(layout_2)
self.setLayout(layout_0)
@ -565,15 +584,15 @@ class PesterUserlist(QtGui.QDialog):
layout_0.addWidget(self.label)
layout_0.addWidget(self.userarea)
layout_0.addWidget(self.ok)
self.setLayout(layout_0)
self.connect(self.mainwindow, QtCore.SIGNAL('namesUpdated()'),
self, QtCore.SLOT('updateUsers()'))
self.connect(self.mainwindow,
self.connect(self.mainwindow,
QtCore.SIGNAL('userPresentSignal(QString, QString, QString)'),
self,
self,
QtCore.SLOT('updateUserPresent(QString, QString, QString)'))
self.updateUsers()
@QtCore.pyqtSlot()
@ -635,7 +654,7 @@ class PesterMemoList(QtGui.QDialog):
self.channelarea = RightClickList(self)
self.channelarea.setStyleSheet(self.theme["main/chums/style"])
self.channelarea.optionsMenu = QtGui.QMenu(self)
self.connect(self.channelarea,
self.connect(self.channelarea,
QtCore.SIGNAL('itemActivated(QListWidgetItem *)'),
self, QtCore.SLOT('joinActivatedMemo(QListWidgetItem *)'))
@ -668,7 +687,7 @@ class PesterMemoList(QtGui.QDialog):
layout_0.addWidget(self.timeslider)
layout_0.addWidget(self.timeinput)
layout_0.addLayout(layout_ok)
self.setLayout(layout_0)
def newmemoname(self):
@ -689,7 +708,7 @@ class PesterMemoList(QtGui.QDialog):
for item in [self.userarea.item(i) for i in range(0, self.channelarea.count())]:
item.setTextColor(QtGui.QColor(theme["main/chums/userlistcolor"]))
item.setIcon(QtGui.QIcon(theme["memos/memoicon"]))
@QtCore.pyqtSlot()
def checkEmpty(self):
newmemo = self.newmemoname()
@ -704,7 +723,7 @@ class PesterMemoList(QtGui.QDialog):
class LoadingScreen(QtGui.QDialog):
def __init__(self, parent=None):
QtGui.QDialog.__init__(self, parent, flags=(QtCore.Qt.CustomizeWindowHint |
QtGui.QDialog.__init__(self, parent, flags=(QtCore.Qt.CustomizeWindowHint |
QtCore.Qt.FramelessWindowHint))
self.mainwindow = parent
self.setStyleSheet(self.mainwindow.theme["main/defaultwindow/style"])

View file

@ -12,6 +12,7 @@ import socket
import platform
from PyQt4 import QtGui, QtCore
import pygame
from time import strftime
from menus import PesterChooseQuirks, PesterChooseTheme, \
PesterChooseProfile, PesterOptions, PesterUserlist, PesterMemoList, \
@ -76,9 +77,10 @@ class PesterLog(object):
self.logpath = _datadir+"logs"
def log(self, handle, msg):
bbcodemsg = convertTags(msg, "bbcode")
html = convertTags(msg, "html")+"<br />"
msg = convertTags(msg, "text")
time = strftime("[%H:%M:%S] ")
bbcodemsg = time + convertTags(msg, "bbcode")
html = time + convertTags(msg, "html")+"<br />"
msg = time + convertTags(msg, "text")
modes = {"bbcode": bbcodemsg, "html": html, "text": msg}
if not self.convos.has_key(handle):
time = datetime.now().strftime("%Y-%m-%d.%H.%M")
@ -127,7 +129,7 @@ class PesterProfileDB(dict):
fp = open("%s/chums.js" % (self.logpath), 'w')
json.dump(chumdict, fp)
fp.close()
converted = dict([(handle, PesterProfile(handle, color=QtGui.QColor(c['color']), mood=Mood(c['mood']))) for (handle, c) in chumdict.iteritems()])
self.update(converted)
@ -179,7 +181,7 @@ class pesterTheme(dict):
if hasattr(self, 'defaultTheme'):
return self.defaultTheme[key]
else:
raise e
raise e
for k in keys:
try:
v = v[k]
@ -225,7 +227,7 @@ class pesterTheme(dict):
class userConfig(object):
def __init__(self):
if sys.platform != "darwin":
if sys.platform != "darwin":
self.filename = "pesterchum.js"
else:
self.filename = _datadir+"pesterchum.js"
@ -249,6 +251,18 @@ class userConfig(object):
return None
def tabs(self):
return self.config.get("tabs", True)
def showTimeStamps(self):
if not self.config.has_key('showTimeStamps'):
self.set("showTimeStamps", True)
return self.config.get('showTimeStamps', True)
def time12Format(self):
if not self.config.has_key('time12Format'):
self.set("time12Format", True)
return self.config.get('time12Format', True)
def showSeconds(self):
if not self.config.has_key('showSeconds'):
self.set("showSeconds", False)
return self.config.get('showSeconds', False)
def addChum(self, chum):
if chum.handle not in self.chums():
fp = open(self.filename) # what if we have two clients open??
@ -311,7 +325,7 @@ class userConfig(object):
return [userProfile(p) for p in profs]
class userProfile(object):
def __init__(self, user):
if sys.platform != "darwin":
if sys.platform != "darwin":
self.profiledir = "profiles"
else:
self.profiledir = _datadir+"profiles"
@ -450,7 +464,7 @@ class chumArea(RightClickList):
if len([c for c in self.chums if c.handle == chum.handle]) != 0:
return
self.chums.append(chum)
if not (self.mainwindow.config.hideOfflineChums() and
if not (self.mainwindow.config.hideOfflineChums() and
chum.mood.name() == "offline"):
chumLabel = chumListing(chum, self.mainwindow)
self.addItem(chumLabel)
@ -459,7 +473,7 @@ class chumArea(RightClickList):
def getChums(self, handle):
chums = self.findItems(handle, QtCore.Qt.MatchFlags(0))
return chums
def showAllChums(self):
for c in self.chums:
chandle = c.handle
@ -753,8 +767,8 @@ class MovingWindow(QtGui.QFrame):
class PesterWindow(MovingWindow):
def __init__(self, parent=None):
MovingWindow.__init__(self, parent,
flags=(QtCore.Qt.CustomizeWindowHint |
MovingWindow.__init__(self, parent,
flags=(QtCore.Qt.CustomizeWindowHint |
QtCore.Qt.FramelessWindowHint))
self.convos = {}
@ -804,7 +818,7 @@ class PesterWindow(MovingWindow):
self, QtCore.SIGNAL('reconnectIRC()'))
self.menu = QtGui.QMenuBar(self)
filemenu = self.menu.addMenu(self.theme["main/menus/client/_name"])
self.filemenu = filemenu
filemenu.addAction(opts)
@ -856,7 +870,7 @@ class PesterWindow(MovingWindow):
self.helpmenu = helpmenu
self.helpmenu.addAction(self.helpAction)
self.helpmenu.addAction(self.aboutAction)
self.closeButton = WMButton(PesterIcon(self.theme["main/close/image"]), self)
self.connect(self.closeButton, QtCore.SIGNAL('clicked()'),
@ -870,9 +884,9 @@ class PesterWindow(MovingWindow):
chums = [PesterProfile(c, chumdb=self.chumdb) for c in set(self.config.chums())]
self.chumList = chumArea(chums, self)
self.connect(self.chumList,
self.connect(self.chumList,
QtCore.SIGNAL('itemActivated(QListWidgetItem *)'),
self,
self,
QtCore.SLOT('newConversationWindow(QListWidgetItem *)'))
self.connect(self.chumList,
QtCore.SIGNAL('removeChumSignal(QListWidgetItem *)'),
@ -882,7 +896,7 @@ class PesterWindow(MovingWindow):
QtCore.SIGNAL('blockChumSignal(QString)'),
self,
QtCore.SLOT('blockChum(QString)'))
self.addChumButton = QtGui.QPushButton(self.theme["main/addchum/text"], self)
self.connect(self.addChumButton, QtCore.SIGNAL('clicked()'),
self, QtCore.SLOT('addChumWindow()'))
@ -1041,7 +1055,7 @@ class PesterWindow(MovingWindow):
if self.memos.has_key(channel):
self.memos[channel].showChat()
return
# do slider dialog then set
# do slider dialog then set
if self.config.tabs():
if not self.tabmemo:
self.createMemoTabWindow()
@ -1056,7 +1070,7 @@ class PesterWindow(MovingWindow):
self, QtCore.SLOT('closeMemo(QString)'))
self.connect(self, QtCore.SIGNAL('namesUpdated()'),
memoWindow, QtCore.SLOT('namesUpdated()'))
self.connect(self,
self.connect(self,
QtCore.SIGNAL('userPresentSignal(QString, QString, QString)'),
memoWindow, QtCore.SLOT('userPresentChange(QString, QString, QString)'))
# chat client send memo open
@ -1131,7 +1145,7 @@ class PesterWindow(MovingWindow):
if hasattr(self, 'moods'):
self.moods.removeButtons()
mood_list = theme["main/moods"]
mood_list = [dict([(str(k),v) for (k,v) in d.iteritems()])
mood_list = [dict([(str(k),v) for (k,v) in d.iteritems()])
for d in mood_list]
self.moods = PesterMoodHandler(self, *[PesterMoodButton(self, **d) for d in mood_list])
self.moods.showButtons()
@ -1182,7 +1196,7 @@ class PesterWindow(MovingWindow):
self.currentMoodIcon.hide()
self.currentMoodIcon = None
if theme["main/mychumhandle/colorswatch/text"]:
self.mychumcolor.setText(theme["main/mychumhandle/colorswatch/text"])
else:
@ -1199,7 +1213,7 @@ class PesterWindow(MovingWindow):
except Exception, e:
self.alarm = NoneSound()
self.ceasesound = NoneSound()
def changeTheme(self, theme):
self.theme = theme
# do self
@ -1293,7 +1307,7 @@ class PesterWindow(MovingWindow):
def memoTabsClosed(self):
del self.tabmemo
self.tabmemo = None
@QtCore.pyqtSlot(QtCore.QString, Mood)
def updateMoodSlot(self, handle, mood):
h = unicode(handle)
@ -1613,7 +1627,7 @@ class PesterWindow(MovingWindow):
windows = list(self.tabconvo.convos.values())
if self.tabmemo:
windows += list(self.tabmemo.convos.values())
for w in windows:
w.setParent(None)
w.show()
@ -1655,6 +1669,16 @@ class PesterWindow(MovingWindow):
# sound
soundsetting = self.optionmenu.soundcheck.isChecked()
self.config.set("soundon", soundsetting)
# timestamps
timestampsetting = self.optionmenu.timestampcheck.isChecked()
self.config.set("showTimeStamps", timestampsetting)
timeformatsetting = unicode(self.optionmenu.timestampBox.currentText())
if timeformatsetting == "12 hour":
self.config.set("time12Format", True)
else:
self.config.set("time12Format", False)
secondssetting = self.optionmenu.secondscheck.isChecked()
self.config.set("showSeconds", secondssetting)
self.optionmenu = None
@QtCore.pyqtSlot()
@ -1717,7 +1741,7 @@ class PesterWindow(MovingWindow):
self.trollslum = TrollSlumWindow(trolls, self)
self.connect(self.trollslum, QtCore.SIGNAL('blockChumSignal(QString)'),
self, QtCore.SLOT('blockChum(QString)'))
self.connect(self.trollslum,
self.connect(self.trollslum,
QtCore.SIGNAL('unblockChumSignal(QString)'),
self, QtCore.SLOT('unblockChum(QString)'))
self.moodsRequest.emit(PesterList(trolls))
@ -1874,7 +1898,7 @@ class MainProgram(QtCore.QObject):
self.trayicon.setContextMenu(self.traymenu)
self.trayicon.show()
self.trayicon.connect(self.trayicon,
self.trayicon.connect(self.trayicon,
QtCore.SIGNAL('activated(QSystemTrayIcon::ActivationReason)'),
self.widget,
QtCore.SLOT('systemTrayActivated(QSystemTrayIcon::ActivationReason)'))
@ -1896,7 +1920,7 @@ class MainProgram(QtCore.QObject):
self.irc = PesterIRC(self.widget.config, self.widget)
self.connectWidgets(self.irc, self.widget)
widget2irc = [('sendMessage(QString, QString)',
widget2irc = [('sendMessage(QString, QString)',
'sendMessage(QString, QString)'),
('newConvoStarted(QString, bool)',
'startConvo(QString, bool)'),
@ -1916,15 +1940,15 @@ class MainProgram(QtCore.QObject):
('requestChannelList()', 'requestChannelList()'),
('joinChannel(QString)', 'joinChannel(QString)'),
('leftChannel(QString)', 'leftChannel(QString)'),
('kickUser(QString, QString)',
('kickUser(QString, QString)',
'kickUser(QString, QString)'),
('setChannelMode(QString, QString, QString)',
'setChannelMode(QString, QString, QString)'),
('reconnectIRC()', 'reconnectIRC()')
('reconnectIRC()', 'reconnectIRC()')
]
# IRC --> Main window
irc2widget = [('connected()', 'connected()'),
('moodUpdated(QString, PyQt_PyObject)',
('moodUpdated(QString, PyQt_PyObject)',
'updateMoodSlot(QString, PyQt_PyObject)'),
('colorUpdated(QString, QColor)',
'updateColorSlot(QString, QColor)'),