Minor source cleanup, pending rewrites

This commit is contained in:
karxi 2017-01-02 13:49:54 -05:00
parent 9f6ee05d43
commit 1cf0926e9f
5 changed files with 93 additions and 63 deletions

View file

@ -78,14 +78,43 @@
### GUI ### GUI
* Refactor code to make way for QShortcut usage. (Unify shortcut processing?) * 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+W closes tab
* Ctrl+Shift+PGUP/PGDN shifts tab * Ctrl+Shift+PGUP/PGDN moves tab
* Make Ctrl+J/K usable for tab shifting * Make Ctrl+J/K usable for tab changing
* Option to disable Ctrl+Tab's jump to newest * Option to disable Ctrl+Tab's jump to newest
* Ctrl+Shift+V "Mass Paste" option (parse lines in sequence)? * Ctrl+Shift+V "Mass Paste" option (parse lines in sequence)?
* Make system messages use timestamps like everything else * Make system messages use timestamps like everything else
* Offer option for timestamps in memos * 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 ### Advanced
* Offer option for 'new' syntax adjustments * Offer option for 'new' syntax adjustments
@ -141,6 +170,7 @@
### General ### General
* Implement new Lexer for the sake of everyone's sanity * 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 `PESTERCHUM:` processing/redo whole msg received processing chain
* Redo text processing in general * Redo text processing in general
* Redo quirk processing (use pieces from Textsub if needed) * Redo quirk processing (use pieces from Textsub if needed)

View file

@ -1,4 +1,3 @@
# vim: set autoindent ts=4 softtabstop=4 shiftwidth=4 textwidth=79 expandtab:
# -*- coding=UTF-8; tab-width: 4 -*- # -*- coding=UTF-8; tab-width: 4 -*-
from PyQt4 import QtGui, QtCore from PyQt4 import QtGui, QtCore
@ -9,6 +8,8 @@ from os import remove
import dataobjs, generic, memos, parsetools, ostools import dataobjs, generic, memos, parsetools, ostools
from version import _pcVersion from version import _pcVersion
from pnc.dep.attrdict import AttrDict
_datadir = ostools.getDataDir() _datadir = ostools.getDataDir()
import logging import logging
@ -20,9 +21,8 @@ logging.basicConfig(level=logging.WARNING)
class ConsoleWindow(QtGui.QDialog): class ConsoleWindow(QtGui.QDialog):
# A simple console class, cobbled together from the corpse of another. # A simple console class, cobbled together from the corpse of another.
textArea = None # This is a holder for our text inputs.
textInput = None text = AttrDict()
history = None
# I should probably put up constants for 'direction' if this is going to # I should probably put up constants for 'direction' if this is going to
# get this complicated. TODO! # get this complicated. TODO!
incoming_prefix = "<<<" incoming_prefix = "<<<"
@ -39,28 +39,30 @@ class ConsoleWindow(QtGui.QDialog):
self.mainwindow = parent self.mainwindow = parent
theme = self.mainwindow.theme theme = self.mainwindow.theme
self.text = AttrDict()
# Set up our style/window specifics # Set up our style/window specifics
self.setStyleSheet(theme["main/defaultwindow/style"]) self.setStyleSheet(theme["main/defaultwindow/style"])
self.setWindowTitle("==> Console") self.setWindowTitle("==> Console")
self.resize(350,300) self.resize(350,300)
self.textArea = ConsoleText(theme, self) self.text.area = ConsoleText(theme, self)
self.textInput = ConsoleInput(theme, self) self.text.input = ConsoleInput(theme, self)
self.textInput.setFocus() self.text.input.setFocus()
self.connect(self.textInput, QtCore.SIGNAL('returnPressed()'), self.connect(self.text.input, QtCore.SIGNAL('returnPressed()'),
self, QtCore.SLOT('sentMessage()')) self, QtCore.SLOT('sentMessage()'))
self.chumopen = True self.chumopen = True
self.chum = self.mainwindow.profile() self.chum = self.mainwindow.profile()
self.history = dataobjs.PesterHistory() self.text.history = dataobjs.PesterHistory()
# For backing these up # For backing these up
self.stdout = self.stderr = None self.stdout = self.stderr = None
layout_0 = QtGui.QVBoxLayout() layout_0 = QtGui.QVBoxLayout()
layout_0.addWidget(self.textArea) layout_0.addWidget(self.text.area)
layout_0.addWidget(self.textInput) layout_0.addWidget(self.text.input)
self.setLayout(layout_0) self.setLayout(layout_0)
def parent(self): def parent(self):
@ -71,21 +73,21 @@ class ConsoleWindow(QtGui.QDialog):
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
def sentMessage(self): 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. # TODO: Make this deal with unicode text, it'll crash and burn as-is.
text = str(text) text = str(text)
text = text.rstrip() text = text.rstrip()
self.history.add(text) self.text.history.add(text)
self.textInput.setText("") self.text.input.setText("")
self.execInConsole(text) self.execInConsole(text)
# Scroll down to the bottom so we can see the results. # Scroll down to the bottom so we can see the results.
sb = self.textArea.verticalScrollBar() sb = self.text.area.verticalScrollBar()
sb.setValue(sb.maximum()) sb.setValue(sb.maximum())
def addTraceback(self, tb=None): 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. # to addMessage whatever output we produced.
# If we're called by addMessage - and we should be - then sys.stdout is # If we're called by addMessage - and we should be - then sys.stdout is
# still being redirected into the console. # still being redirected into the console.
@ -99,7 +101,7 @@ class ConsoleWindow(QtGui.QDialog):
def addMessage(self, msg, direction): def addMessage(self, msg, direction):
# Redirect to where these things belong. # Redirect to where these things belong.
self.textArea.addMessage(msg, direction=direction) self.text.area.addMessage(msg, direction=direction)
def closeEvent(self, event): def closeEvent(self, event):
# TODO: Set up ESC to close the console...or refer to hiding it as # 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): class ConsoleText(QtGui.QTextEdit):
scrollbar_qtss = """ stylesheet_template = """
QTextEdit {{ {style[convo/textarea/style]} }}
QScrollBar:vertical {{ {style[convo/scrollbar/style]} }} QScrollBar:vertical {{ {style[convo/scrollbar/style]} }}
QScrollBar::handle:vertical {{ {style[convo/scrollbar/handle]} }} QScrollBar::handle:vertical {{ {style[convo/scrollbar/handle]} }}
QScrollBar::add-line:vertical {{ {style[convo/scrollbar/downarrow]} }} 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:up-arrow:vertical {{ {style[convo/scrollbar/uarrowstyle]} }}
QScrollBar:down-arrow:vertical {{ {style[convo/scrollbar/darrowstyle]} }} 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): def __init__(self, theme, parent=None):
super(ConsoleText, self).__init__(parent) super(ConsoleText, self).__init__(parent)
if hasattr(self.parent(), 'mainwindow'): if hasattr(self.window(), 'mainwindow'):
self.mainwindow = self.parent().mainwindow self.mainwindow = self.window().mainwindow
else: else:
self.mainwindow = self.parent() self.mainwindow = self.window()
self.hasTabs = False self.hasTabs = False
self.initTheme(theme) self.initTheme(theme)
@ -212,27 +219,16 @@ class ConsoleText(QtGui.QTextEdit):
self.textSelected = ready self.textSelected = ready
def initTheme(self, theme): 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 # TODO: Make all of this into a Styler mixin, so we can just feed
# it a theme whenever we want to change. # it a theme whenever we want to change.
# We'd have to define the keys we're affecting, but that shouldn't # We'd have to define the keys we're affecting, but that shouldn't
# be too hard - it's what dicts are for. # be too hard - it's what dicts are for.
# These will be passed to format(), so we need to escape the # Add the rest.
# containing braces. stylesheet += '\n' + self.stylesheet_template
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]} }}"
stylesheet = stylesheet.format(style=theme) stylesheet = stylesheet.format(style=theme)
self.setStyleSheet(stylesheet) self.setStyleSheet(stylesheet)
@ -243,7 +239,7 @@ class ConsoleText(QtGui.QTextEdit):
return return
#~color = chum.colorcmd() #~color = chum.colorcmd()
#~initials = chum.initials() #~initials = chum.initials()
parent = self.parent() parent = self.window()
mwindow = parent.mainwindow mwindow = parent.mainwindow
systemColor = QtGui.QColor(mwindow.theme["convo/systemMsgColor"]) systemColor = QtGui.QColor(mwindow.theme["convo/systemMsgColor"])
@ -278,7 +274,6 @@ class ConsoleText(QtGui.QTextEdit):
# do that there. # do that there.
result = "{}{} {}\n" result = "{}{} {}\n"
result = result.format(timestamp, prefix, msg) result = result.format(timestamp, prefix, msg)
#~self.append(result)
self.appendPlainText(result) self.appendPlainText(result)
# Direction doesn't matter here - it's the console. # Direction doesn't matter here - it's the console.
@ -302,17 +297,17 @@ class ConsoleText(QtGui.QTextEdit):
sb.setValue(sb.maximum()) sb.setValue(sb.maximum())
def focusInEvent(self, event): def focusInEvent(self, event):
self.parent().clearNewMessage() self.window().clearNewMessage()
super(ConsoleText, self).focusInEvent(event) super(ConsoleText, self).focusInEvent(event)
def keyPressEvent(self, event): def keyPressEvent(self, event):
# NOTE: This doesn't give focus to the input bar, which it probably # NOTE: This doesn't give focus to the input bar, which it probably
# should. # should.
# karxi: Test for tab changing? # 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, if event.key() not in (QtCore.Qt.Key_PageUp, QtCore.Qt.Key_PageDown,
QtCore.Qt.Key_Up, QtCore.Qt.Key_Down): QtCore.Qt.Key_Up, QtCore.Qt.Key_Down):
self.parent().textInput.keyPressEvent(event) self.window().text.input.keyPressEvent(event)
super(ConsoleText, self).keyPressEvent(event) super(ConsoleText, self).keyPressEvent(event)
@ -366,14 +361,14 @@ class ConsoleInput(QtGui.QLineEdit):
def focusInEvent(self, event): def focusInEvent(self, event):
# We gained focus. Notify the parent window that this happened. # We gained focus. Notify the parent window that this happened.
self.parent().clearNewMessage() self.window().clearNewMessage()
self.parent().textArea.textCursor().clearSelection() self.window().text.area.textCursor().clearSelection()
super(ConsoleInput, self).focusInEvent(event) super(ConsoleInput, self).focusInEvent(event)
def keyPressEvent(self, event): def keyPressEvent(self, event):
evtkey = event.key() evtkey = event.key()
parent = self.parent() parent = self.window()
# If a key is pressed here, we're not idle.... # If a key is pressed here, we're not idle....
# NOTE: Do we really want everyone knowing we're around if we're # 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: if evtkey == QtCore.Qt.Key_Up:
text = unicode(self.text()) text = unicode(self.text())
next = parent.history.next(text) next = parent.text.history.next(text)
if next is not None: if next is not None:
self.setText(next) self.setText(next)
elif evtkey == QtCore.Qt.Key_Down: elif evtkey == QtCore.Qt.Key_Down:
prev = parent.history.prev() prev = parent.text.history.prev()
if prev is not None: if prev is not None:
self.setText(prev) self.setText(prev)
elif evtkey in (QtCore.Qt.Key_PageUp, QtCore.Qt.Key_PageDown): elif evtkey in (QtCore.Qt.Key_PageUp, QtCore.Qt.Key_PageDown):
parent.textArea.keyPressEvent(event) parent.text.area.keyPressEvent(event)
else: else:
super(ConsoleInput, self).keyPressEvent(event) 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:

View file

@ -1,3 +1,4 @@
# -*- coding=UTF-8; tab-width: 4 -*-
# Heavily modified version of the code featured at the given link # Heavily modified version of the code featured at the given link
## {{{ http://code.activestate.com/recipes/473786/ (r1) ## {{{ http://code.activestate.com/recipes/473786/ (r1)
class AttrDict(dict): class AttrDict(dict):
@ -131,3 +132,5 @@ class DefAttrDict(AttrDict):
def copy(self): return type(self)(self.default_factory, self) def copy(self): return type(self)(self.default_factory, self)
__copy__ = copy __copy__ = copy
# vim: set autoindent ts=4 sts=4 sw=4 textwidth=79 expandtab:

View file

@ -3,8 +3,8 @@ from __future__ import division
__all__ = ["Color"] __all__ = ["Color"]
# Copied from my old Textsub script. Please forgive the mess, and keep in mind # karxi: Copied from my old Textsub script. Please forgive the mess, and keep
# that this may be phased out in the future. # 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(): for k, v in _irc_colors.items():
v.ccode = "%02d" % k v.ccode = "%02d" % k
del k, v del k, v
# vim: set autoindent ts=4 sts=4 sw=4 textwidth=79 expandtab:

View file

@ -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.LOG: return
if not self.parent.config.logPesters() & self.parent.config.STAMP: if not self.parent.config.logPesters() & self.parent.config.STAMP:
time = "" time = ""
if unicode(handle).upper() == "NICKSERV": return if self.parent.isBot(handle): return
#watch out for illegal characters #watch out for illegal characters
handle = re.sub(r'[<>:"/\\|?*]', "_", handle) handle = re.sub(r'[<>:"/\\|?*]', "_", handle)
bbcodemsg = time + convertTags(msg, "bbcode") bbcodemsg = time + convertTags(msg, "bbcode")
@ -591,11 +591,11 @@ class pesterTheme(dict):
def __getitem__(self, key): def __getitem__(self, key):
keys = key.split("/") keys = key.split("/")
try: try:
v = dict.__getitem__(self, keys.pop(0)) v = super(pesterTheme, self).__getitem__(keys.pop(0))
except KeyError as e: except KeyError as e:
if hasattr(self, 'inheritedTheme'): if hasattr(self, 'inheritedTheme'):
return self.inheritedTheme[key] return self.inheritedTheme[key]
if hasattr(self, 'defaultTheme'): elif hasattr(self, 'defaultTheme'):
return self.defaultTheme[key] return self.defaultTheme[key]
else: else:
raise e raise e
@ -605,21 +605,21 @@ class pesterTheme(dict):
except KeyError as e: except KeyError as e:
if hasattr(self, 'inheritedTheme'): if hasattr(self, 'inheritedTheme'):
return self.inheritedTheme[key] return self.inheritedTheme[key]
if hasattr(self, 'defaultTheme'): elif hasattr(self, 'defaultTheme'):
return self.defaultTheme[key] return self.defaultTheme[key]
else: else:
raise e raise e
return v return v
def pathHook(self, d): def pathHook(self, d):
for (k, v) in d.iteritems(): for (k, v) in d.iteritems():
if type(v) is unicode: if isinstance(v, unicode):
s = Template(v) s = Template(v)
d[k] = s.safe_substitute(path=self.path) d[k] = s.safe_substitute(path=self.path)
return d return d
def get(self, key, default): def get(self, key, default):
keys = key.split("/") keys = key.split("/")
try: try:
v = dict.__getitem__(self, keys.pop(0)) v = super(pesterTheme, self).__getitem__(keys.pop(0))
for k in keys: for k in keys:
v = v[k] v = v[k]
return default if v is None else v return default if v is None else v
@ -632,10 +632,10 @@ class pesterTheme(dict):
def has_key(self, key): def has_key(self, key):
keys = key.split("/") keys = key.split("/")
try: try:
v = dict.__getitem__(self, keys.pop(0)) v = super(pesterTheme, self).__getitem__(keys.pop(0))
for k in keys: for k in keys:
v = v[k] v = v[k]
return False if v is None else True return (v is not None)
except KeyError: except KeyError:
if hasattr(self, 'inheritedTheme'): if hasattr(self, 'inheritedTheme'):
return self.inheritedTheme.has_key(key) return self.inheritedTheme.has_key(key)