Minor source cleanup, pending rewrites
This commit is contained in:
parent
9f6ee05d43
commit
1cf0926e9f
5 changed files with 93 additions and 63 deletions
36
TODO.mkdn
36
TODO.mkdn
|
@ -78,14 +78,43 @@
|
|||
|
||||
### GUI
|
||||
* Refactor code to make way for QShortcut usage. (Unify shortcut processing?)
|
||||
* Enable/Disable toggle (Firefox style option sheet? Seems okay.)
|
||||
* Enable/Disable toggle (Firefox style option sheet-esque? Seems okay.)
|
||||
* Ctrl+W closes tab
|
||||
* Ctrl+Shift+PGUP/PGDN shifts tab
|
||||
* Make Ctrl+J/K usable for tab shifting
|
||||
* Ctrl+Shift+PGUP/PGDN moves tab
|
||||
* Make Ctrl+J/K usable for tab changing
|
||||
* Option to disable Ctrl+Tab's jump to newest
|
||||
* Ctrl+Shift+V "Mass Paste" option (parse lines in sequence)?
|
||||
* Make system messages use timestamps like everything else
|
||||
* Offer option for timestamps in memos
|
||||
* Make certain dialogues start on the safer of the two options
|
||||
* Make the Reconnect dialog start on reconnect
|
||||
* Make the Rejoin dialog start on rejoin
|
||||
* Make the Invite dialog start on decline
|
||||
* Make a status window/popup to contain logs of information like invites
|
||||
|
||||
### "Security"
|
||||
**Note: The idea of security on this platform is pretty much laughable. Most of
|
||||
these changes are simply bandages being placed over fundamentally flawed
|
||||
design.**
|
||||
|
||||
If you want Pesterchum to be more secure, either get ghostDunk to make changes
|
||||
to the server and its administration policies, or get everyone to switch to this
|
||||
version of the client. There aren't really any other choices.
|
||||
|
||||
* Flood protection (don't send because of the same target too many times in a
|
||||
row)
|
||||
* Just requires a timer + lastmessage date check.
|
||||
* Lock exploitable functionality to those on your friends list (optional)
|
||||
* Canon handles are excluded from this concern, but subject to flood
|
||||
controls regardless.
|
||||
* A measure of politeness is reasonable here - checking if a friend is on
|
||||
as a different handle should be okay, once IRC access is revamped.
|
||||
* Don't send MOOD answers to those not friended
|
||||
* Ignore pesters from those not on your friends list (optional)
|
||||
* Ignore pesters from those not sharing a memo? (optional)
|
||||
* Make BLOCKED list persistent, if it isn't already
|
||||
* Offer option to block hosts, not just handles...
|
||||
* Explain to the user that this option is very dangerous.
|
||||
|
||||
### Advanced
|
||||
* Offer option for 'new' syntax adjustments
|
||||
|
@ -141,6 +170,7 @@
|
|||
|
||||
### General
|
||||
* Implement new Lexer for the sake of everyone's sanity
|
||||
* This is half-done - rendering still uses the old lexer
|
||||
* Redo `PESTERCHUM:` processing/redo whole msg received processing chain
|
||||
* Redo text processing in general
|
||||
* Redo quirk processing (use pieces from Textsub if needed)
|
||||
|
|
95
console.py
95
console.py
|
@ -1,4 +1,3 @@
|
|||
# vim: set autoindent ts=4 softtabstop=4 shiftwidth=4 textwidth=79 expandtab:
|
||||
# -*- coding=UTF-8; tab-width: 4 -*-
|
||||
|
||||
from PyQt4 import QtGui, QtCore
|
||||
|
@ -9,6 +8,8 @@ from os import remove
|
|||
import dataobjs, generic, memos, parsetools, ostools
|
||||
from version import _pcVersion
|
||||
|
||||
from pnc.dep.attrdict import AttrDict
|
||||
|
||||
_datadir = ostools.getDataDir()
|
||||
|
||||
import logging
|
||||
|
@ -20,9 +21,8 @@ logging.basicConfig(level=logging.WARNING)
|
|||
class ConsoleWindow(QtGui.QDialog):
|
||||
# A simple console class, cobbled together from the corpse of another.
|
||||
|
||||
textArea = None
|
||||
textInput = None
|
||||
history = None
|
||||
# This is a holder for our text inputs.
|
||||
text = AttrDict()
|
||||
# I should probably put up constants for 'direction' if this is going to
|
||||
# get this complicated. TODO!
|
||||
incoming_prefix = "<<<"
|
||||
|
@ -39,28 +39,30 @@ class ConsoleWindow(QtGui.QDialog):
|
|||
self.mainwindow = parent
|
||||
theme = self.mainwindow.theme
|
||||
|
||||
self.text = AttrDict()
|
||||
|
||||
# Set up our style/window specifics
|
||||
self.setStyleSheet(theme["main/defaultwindow/style"])
|
||||
self.setWindowTitle("==> Console")
|
||||
self.resize(350,300)
|
||||
|
||||
self.textArea = ConsoleText(theme, self)
|
||||
self.textInput = ConsoleInput(theme, self)
|
||||
self.textInput.setFocus()
|
||||
self.text.area = ConsoleText(theme, self)
|
||||
self.text.input = ConsoleInput(theme, self)
|
||||
self.text.input.setFocus()
|
||||
|
||||
self.connect(self.textInput, QtCore.SIGNAL('returnPressed()'),
|
||||
self.connect(self.text.input, QtCore.SIGNAL('returnPressed()'),
|
||||
self, QtCore.SLOT('sentMessage()'))
|
||||
|
||||
self.chumopen = True
|
||||
self.chum = self.mainwindow.profile()
|
||||
self.history = dataobjs.PesterHistory()
|
||||
self.text.history = dataobjs.PesterHistory()
|
||||
|
||||
# For backing these up
|
||||
self.stdout = self.stderr = None
|
||||
|
||||
layout_0 = QtGui.QVBoxLayout()
|
||||
layout_0.addWidget(self.textArea)
|
||||
layout_0.addWidget(self.textInput)
|
||||
layout_0.addWidget(self.text.area)
|
||||
layout_0.addWidget(self.text.input)
|
||||
self.setLayout(layout_0)
|
||||
|
||||
def parent(self):
|
||||
|
@ -71,21 +73,21 @@ class ConsoleWindow(QtGui.QDialog):
|
|||
|
||||
@QtCore.pyqtSlot()
|
||||
def sentMessage(self):
|
||||
text = self.textInput.text()
|
||||
text = self.text.input.text()
|
||||
# TODO: Make this deal with unicode text, it'll crash and burn as-is.
|
||||
text = str(text)
|
||||
text = text.rstrip()
|
||||
|
||||
self.history.add(text)
|
||||
self.textInput.setText("")
|
||||
self.text.history.add(text)
|
||||
self.text.input.setText("")
|
||||
|
||||
self.execInConsole(text)
|
||||
# Scroll down to the bottom so we can see the results.
|
||||
sb = self.textArea.verticalScrollBar()
|
||||
sb = self.text.area.verticalScrollBar()
|
||||
sb.setValue(sb.maximum())
|
||||
|
||||
def addTraceback(self, tb=None):
|
||||
# We should do the formatting here, but eventually pass it to textArea
|
||||
# We should do the formatting here, but eventually pass it to text.area
|
||||
# to addMessage whatever output we produced.
|
||||
# If we're called by addMessage - and we should be - then sys.stdout is
|
||||
# still being redirected into the console.
|
||||
|
@ -99,7 +101,7 @@ class ConsoleWindow(QtGui.QDialog):
|
|||
|
||||
def addMessage(self, msg, direction):
|
||||
# Redirect to where these things belong.
|
||||
self.textArea.addMessage(msg, direction=direction)
|
||||
self.text.area.addMessage(msg, direction=direction)
|
||||
|
||||
def closeEvent(self, event):
|
||||
# TODO: Set up ESC to close the console...or refer to hiding it as
|
||||
|
@ -179,8 +181,7 @@ class ConsoleWindow(QtGui.QDialog):
|
|||
|
||||
|
||||
class ConsoleText(QtGui.QTextEdit):
|
||||
scrollbar_qtss = """
|
||||
QTextEdit {{ {style[convo/textarea/style]} }}
|
||||
stylesheet_template = """
|
||||
QScrollBar:vertical {{ {style[convo/scrollbar/style]} }}
|
||||
QScrollBar::handle:vertical {{ {style[convo/scrollbar/handle]} }}
|
||||
QScrollBar::add-line:vertical {{ {style[convo/scrollbar/downarrow]} }}
|
||||
|
@ -188,12 +189,18 @@ class ConsoleText(QtGui.QTextEdit):
|
|||
QScrollBar:up-arrow:vertical {{ {style[convo/scrollbar/uarrowstyle]} }}
|
||||
QScrollBar:down-arrow:vertical {{ {style[convo/scrollbar/darrowstyle]} }}
|
||||
"""
|
||||
stylesheet_path = "convo/textarea/style"
|
||||
# NOTE: Qt applies stylesheets like switching CSS files. They are NOT
|
||||
# applied piecemeal.
|
||||
# TODO: Consider parsing the themes out into stylesheets with pieces that
|
||||
# we can hand to each widget.
|
||||
|
||||
def __init__(self, theme, parent=None):
|
||||
super(ConsoleText, self).__init__(parent)
|
||||
if hasattr(self.parent(), 'mainwindow'):
|
||||
self.mainwindow = self.parent().mainwindow
|
||||
if hasattr(self.window(), 'mainwindow'):
|
||||
self.mainwindow = self.window().mainwindow
|
||||
else:
|
||||
self.mainwindow = self.parent()
|
||||
self.mainwindow = self.window()
|
||||
|
||||
self.hasTabs = False
|
||||
self.initTheme(theme)
|
||||
|
@ -212,27 +219,16 @@ class ConsoleText(QtGui.QTextEdit):
|
|||
self.textSelected = ready
|
||||
|
||||
def initTheme(self, theme):
|
||||
if theme.has_key("convo/scrollbar"):
|
||||
# The basic style...
|
||||
stylesheet = "QTextEdit {{ {style[convo/textarea/style]} }}"
|
||||
if "convo/scrollbar" in theme:
|
||||
# TODO: Make all of this into a Styler mixin, so we can just feed
|
||||
# it a theme whenever we want to change.
|
||||
# We'd have to define the keys we're affecting, but that shouldn't
|
||||
# be too hard - it's what dicts are for.
|
||||
|
||||
# These will be passed to format(), so we need to escape the
|
||||
# containing braces.
|
||||
stylesheet = self.scrollbar_qtss
|
||||
#~themekeys = (
|
||||
#~ "convo/textarea/style",
|
||||
#~ "convo/scrollbar/style",
|
||||
#~ "convo/scrollbar/handle",
|
||||
#~ "convo/scrollbar/downarrow",
|
||||
#~ "convo/scrollbar/uparrow",
|
||||
#~ "convo/scrollbar/uarrowstyle",
|
||||
#~ "convo/scrollbar/darrowstyle"
|
||||
#~ )
|
||||
#~style = (k: theme[k] for k in themekeys)
|
||||
else:
|
||||
stylesheet = "QTextEdit {{ {style[convo/textarea/style]} }}"
|
||||
# Add the rest.
|
||||
stylesheet += '\n' + self.stylesheet_template
|
||||
stylesheet = stylesheet.format(style=theme)
|
||||
self.setStyleSheet(stylesheet)
|
||||
|
||||
|
@ -243,7 +239,7 @@ class ConsoleText(QtGui.QTextEdit):
|
|||
return
|
||||
#~color = chum.colorcmd()
|
||||
#~initials = chum.initials()
|
||||
parent = self.parent()
|
||||
parent = self.window()
|
||||
mwindow = parent.mainwindow
|
||||
|
||||
systemColor = QtGui.QColor(mwindow.theme["convo/systemMsgColor"])
|
||||
|
@ -278,7 +274,6 @@ class ConsoleText(QtGui.QTextEdit):
|
|||
# do that there.
|
||||
result = "{}{} {}\n"
|
||||
result = result.format(timestamp, prefix, msg)
|
||||
#~self.append(result)
|
||||
self.appendPlainText(result)
|
||||
|
||||
# Direction doesn't matter here - it's the console.
|
||||
|
@ -302,17 +297,17 @@ class ConsoleText(QtGui.QTextEdit):
|
|||
sb.setValue(sb.maximum())
|
||||
|
||||
def focusInEvent(self, event):
|
||||
self.parent().clearNewMessage()
|
||||
self.window().clearNewMessage()
|
||||
super(ConsoleText, self).focusInEvent(event)
|
||||
|
||||
def keyPressEvent(self, event):
|
||||
# NOTE: This doesn't give focus to the input bar, which it probably
|
||||
# should.
|
||||
# karxi: Test for tab changing?
|
||||
if hasattr(self.parent(), 'textInput'):
|
||||
if self.window().text.input:
|
||||
if event.key() not in (QtCore.Qt.Key_PageUp, QtCore.Qt.Key_PageDown,
|
||||
QtCore.Qt.Key_Up, QtCore.Qt.Key_Down):
|
||||
self.parent().textInput.keyPressEvent(event)
|
||||
self.window().text.input.keyPressEvent(event)
|
||||
|
||||
super(ConsoleText, self).keyPressEvent(event)
|
||||
|
||||
|
@ -366,14 +361,14 @@ class ConsoleInput(QtGui.QLineEdit):
|
|||
|
||||
def focusInEvent(self, event):
|
||||
# We gained focus. Notify the parent window that this happened.
|
||||
self.parent().clearNewMessage()
|
||||
self.parent().textArea.textCursor().clearSelection()
|
||||
self.window().clearNewMessage()
|
||||
self.window().text.area.textCursor().clearSelection()
|
||||
|
||||
super(ConsoleInput, self).focusInEvent(event)
|
||||
|
||||
def keyPressEvent(self, event):
|
||||
evtkey = event.key()
|
||||
parent = self.parent()
|
||||
parent = self.window()
|
||||
|
||||
# If a key is pressed here, we're not idle....
|
||||
# NOTE: Do we really want everyone knowing we're around if we're
|
||||
|
@ -382,18 +377,18 @@ class ConsoleInput(QtGui.QLineEdit):
|
|||
|
||||
if evtkey == QtCore.Qt.Key_Up:
|
||||
text = unicode(self.text())
|
||||
next = parent.history.next(text)
|
||||
next = parent.text.history.next(text)
|
||||
if next is not None:
|
||||
self.setText(next)
|
||||
elif evtkey == QtCore.Qt.Key_Down:
|
||||
prev = parent.history.prev()
|
||||
prev = parent.text.history.prev()
|
||||
if prev is not None:
|
||||
self.setText(prev)
|
||||
elif evtkey in (QtCore.Qt.Key_PageUp, QtCore.Qt.Key_PageDown):
|
||||
parent.textArea.keyPressEvent(event)
|
||||
parent.text.area.keyPressEvent(event)
|
||||
else:
|
||||
super(ConsoleInput, self).keyPressEvent(event)
|
||||
|
||||
|
||||
|
||||
# vim: set autoindent ts=4 softtabstop=4 shiftwidth=4 textwidth=79 expandtab:
|
||||
# vim: set autoindent ts=4 sts=4 sw=4 textwidth=79 expandtab:
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
# -*- coding=UTF-8; tab-width: 4 -*-
|
||||
# Heavily modified version of the code featured at the given link
|
||||
## {{{ http://code.activestate.com/recipes/473786/ (r1)
|
||||
class AttrDict(dict):
|
||||
|
@ -131,3 +132,5 @@ class DefAttrDict(AttrDict):
|
|||
|
||||
def copy(self): return type(self)(self.default_factory, self)
|
||||
__copy__ = copy
|
||||
|
||||
# vim: set autoindent ts=4 sts=4 sw=4 textwidth=79 expandtab:
|
||||
|
|
|
@ -3,8 +3,8 @@ from __future__ import division
|
|||
|
||||
__all__ = ["Color"]
|
||||
|
||||
# Copied from my old Textsub script. Please forgive the mess, and keep in mind
|
||||
# that this may be phased out in the future.
|
||||
# karxi: Copied from my old Textsub script. Please forgive the mess, and keep
|
||||
# in mind that this may be phased out in the future.
|
||||
|
||||
|
||||
|
||||
|
@ -597,3 +597,5 @@ _irc_colors.update({
|
|||
for k, v in _irc_colors.items():
|
||||
v.ccode = "%02d" % k
|
||||
del k, v
|
||||
|
||||
# vim: set autoindent ts=4 sts=4 sw=4 textwidth=79 expandtab:
|
||||
|
|
16
profile.py
16
profile.py
|
@ -41,7 +41,7 @@ class PesterLog(object):
|
|||
if not self.parent.config.logPesters() & self.parent.config.LOG: return
|
||||
if not self.parent.config.logPesters() & self.parent.config.STAMP:
|
||||
time = ""
|
||||
if unicode(handle).upper() == "NICKSERV": return
|
||||
if self.parent.isBot(handle): return
|
||||
#watch out for illegal characters
|
||||
handle = re.sub(r'[<>:"/\\|?*]', "_", handle)
|
||||
bbcodemsg = time + convertTags(msg, "bbcode")
|
||||
|
@ -591,11 +591,11 @@ class pesterTheme(dict):
|
|||
def __getitem__(self, key):
|
||||
keys = key.split("/")
|
||||
try:
|
||||
v = dict.__getitem__(self, keys.pop(0))
|
||||
v = super(pesterTheme, self).__getitem__(keys.pop(0))
|
||||
except KeyError as e:
|
||||
if hasattr(self, 'inheritedTheme'):
|
||||
return self.inheritedTheme[key]
|
||||
if hasattr(self, 'defaultTheme'):
|
||||
elif hasattr(self, 'defaultTheme'):
|
||||
return self.defaultTheme[key]
|
||||
else:
|
||||
raise e
|
||||
|
@ -605,21 +605,21 @@ class pesterTheme(dict):
|
|||
except KeyError as e:
|
||||
if hasattr(self, 'inheritedTheme'):
|
||||
return self.inheritedTheme[key]
|
||||
if hasattr(self, 'defaultTheme'):
|
||||
elif hasattr(self, 'defaultTheme'):
|
||||
return self.defaultTheme[key]
|
||||
else:
|
||||
raise e
|
||||
return v
|
||||
def pathHook(self, d):
|
||||
for (k, v) in d.iteritems():
|
||||
if type(v) is unicode:
|
||||
if isinstance(v, unicode):
|
||||
s = Template(v)
|
||||
d[k] = s.safe_substitute(path=self.path)
|
||||
return d
|
||||
def get(self, key, default):
|
||||
keys = key.split("/")
|
||||
try:
|
||||
v = dict.__getitem__(self, keys.pop(0))
|
||||
v = super(pesterTheme, self).__getitem__(keys.pop(0))
|
||||
for k in keys:
|
||||
v = v[k]
|
||||
return default if v is None else v
|
||||
|
@ -632,10 +632,10 @@ class pesterTheme(dict):
|
|||
def has_key(self, key):
|
||||
keys = key.split("/")
|
||||
try:
|
||||
v = dict.__getitem__(self, keys.pop(0))
|
||||
v = super(pesterTheme, self).__getitem__(keys.pop(0))
|
||||
for k in keys:
|
||||
v = v[k]
|
||||
return False if v is None else True
|
||||
return (v is not None)
|
||||
except KeyError:
|
||||
if hasattr(self, 'inheritedTheme'):
|
||||
return self.inheritedTheme.has_key(key)
|
||||
|
|
Loading…
Reference in a new issue