[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [arm/release] Moving content and backlog tracking to interpretor
commit 59b70998b162c461ec03780e9ca4cabdb7411af4
Author: Damian Johnson <atagar@xxxxxxxxxxxxxx>
Date: Tue Aug 30 09:41:53 2011 -0700
Moving content and backlog tracking to interpretor
The interpretor class will be tracking state so moving this information to it
from the panel. This will make a common saving function feasable.
---
src/cli/interpretorPanel.py | 49 +++++++++++-----------------------
src/util/torInterpretor.py | 60 +++++++++++++++++++++++++++++++++++--------
2 files changed, 65 insertions(+), 44 deletions(-)
diff --git a/src/cli/interpretorPanel.py b/src/cli/interpretorPanel.py
index 02868ce..cc8b496 100644
--- a/src/cli/interpretorPanel.py
+++ b/src/cli/interpretorPanel.py
@@ -10,17 +10,12 @@ from util import panel, textInput, torInterpretor, uiTools
USAGE_INFO = "to use this panel press enter"
PROMPT_LINE = [torInterpretor.PROMPT, (USAGE_INFO, torInterpretor.USAGE_FORMAT)]
-# limits used for cropping
-BACKLOG_LIMIT = 100
-LINES_LIMIT = 2000
-
-# lazy loaded curses formatting constants
+# lazy loaded mapping of interpretor attributes to curses formatting constants
FORMATS = {}
def getFormat(formatAttr):
"""
- Provides the curses drawing attributes for torInterpretor formatting
- attributes.
+ Provides the curses drawing attributes for torInterpretor formats.
Arguments:
formatAttr - list of formatting attributes
@@ -45,11 +40,10 @@ def getFormat(formatAttr):
class InterpretorPanel(panel.Panel):
def __init__(self, stdscr):
panel.Panel.__init__(self, stdscr, "interpretor", 0)
+ self.interpretor = torInterpretor.ControlInterpretor()
+ self.inputCompleter = torInterpretor.TorControlCompleter()
self.isInputMode = False
self.scroll = 0
- self.interpretor = torInterpretor.ControlInterpretor()
- self.previousCommands = [] # user input, newest to oldest
- self.contents = [PROMPT_LINE] # (msg, format enum) tuples being displayed (oldest to newest)
def prompt(self):
"""
@@ -64,17 +58,16 @@ class InterpretorPanel(panel.Panel):
self.redraw(True)
# intercepts input so user can cycle through the history
- torCommands = torInterpretor.TorControlCompleter()
-
validator = textInput.BasicValidator()
- validator = textInput.HistoryValidator(self.previousCommands, validator)
- validator = textInput.TabCompleter(torCommands.getMatches, validator)
+ validator = textInput.HistoryValidator(list(reversed(self.interpretor.getBacklog())), validator)
+ validator = textInput.TabCompleter(self.inputCompleter.getMatches, validator)
xOffset = len(torInterpretor.PROMPT[0])
- if len(self.contents) > self.maxY - 1:
+ displayLength = len(self.interpretor.getDisplayContents(PROMPT_LINE))
+ if displayLength > self.maxY - 1:
xOffset += 3 # offset for scrollbar
- inputLine = min(self.maxY - 1, len(self.contents))
+ inputLine = min(self.maxY - 1, displayLength)
inputFormat = getFormat(torInterpretor.INPUT_FORMAT)
input = self.getstr(inputLine, xOffset, "", inputFormat, validator = validator)
input, isDone = input.strip(), False
@@ -83,22 +76,10 @@ class InterpretorPanel(panel.Panel):
# terminate input when we get a blank line
isDone = True
else:
- self.previousCommands.insert(0, input)
- self.previousCommands = self.previousCommands[:BACKLOG_LIMIT]
-
try:
inputEntry, outputEntry = self.interpretor.handleQuery(input)
except torInterpretor.InterpretorClosed:
isDone = True
-
- promptEntry = self.contents.pop() # removes old prompt entry
- self.contents += inputEntry
- self.contents += outputEntry
- self.contents.append(promptEntry)
-
- # if too long then crop lines
- cropLines = len(self.contents) - LINES_LIMIT
- if cropLines > 0: self.contents = self.contents[cropLines:]
if isDone:
self.isInputMode = False
@@ -112,7 +93,8 @@ class InterpretorPanel(panel.Panel):
self.prompt()
elif uiTools.isScrollKey(key) and not self.isInputMode:
pageHeight = self.getPreferredSize()[0] - 1
- newScroll = uiTools.getScrollPosition(key, self.scroll, pageHeight, len(self.contents))
+ displayLength = len(self.interpretor.getDisplayContents(PROMPT_LINE))
+ newScroll = uiTools.getScrollPosition(key, self.scroll, pageHeight, displayLength)
if self.scroll != newScroll:
self.scroll = newScroll
@@ -127,17 +109,18 @@ class InterpretorPanel(panel.Panel):
self.addstr(0, 0, "Control Interpretor%s:" % usageMsg, curses.A_STANDOUT)
xOffset = 0
- if len(self.contents) > height - 1:
+ displayContents = self.interpretor.getDisplayContents(PROMPT_LINE)
+ if len(displayContents) > height - 1:
# if we're in input mode then make sure the last line is visible
if self.isInputMode:
- self.scroll = len(self.contents) - height + 1
+ self.scroll = len(displayContents) - height + 1
xOffset = 3
- self.addScrollBar(self.scroll, self.scroll + height - 1, len(self.contents), 1)
+ self.addScrollBar(self.scroll, self.scroll + height - 1, len(displayContents), 1)
# draws prior commands and output
drawLine = 1
- for entry in self.contents[self.scroll:]:
+ for entry in displayContents[self.scroll:]:
cursor = xOffset
for msg, formatEntry in entry:
diff --git a/src/util/torInterpretor.py b/src/util/torInterpretor.py
index c7bcebb..e062532 100644
--- a/src/util/torInterpretor.py
+++ b/src/util/torInterpretor.py
@@ -31,6 +31,10 @@ ERROR_FORMAT = (Attr.BOLD, Color.RED)
CSI = "\x1B[%sm"
RESET = CSI % "0"
+# limits used for cropping
+BACKLOG_LIMIT = 100
+CONTENT_LIMIT = 2000
+
class InterpretorClosed(Exception):
"""
Exception raised when the interpretor should be shut down.
@@ -92,11 +96,10 @@ class TorControlCompleter:
if line.startswith("config/*") or line.startswith("dir-usage"):
continue
- # strips off the ending asterisk if it accepts a value
infoOpt = line.split(" ", 1)[0]
- if infoOpt.endswith("*"):
- infoOpt = infoOpt[:-1]
+ # strips off the ending asterisk if it accepts a value
+ if infoOpt.endswith("*"): infoOpt = infoOpt[:-1]
self.commands.append("GETINFO %s" % infoOpt)
else: self.commands.append("GETINFO ")
@@ -157,7 +160,7 @@ class TorControlCompleter:
def getMatches(self, text):
"""
- Provides all options that match the given input.
+ Provides all options that match the given input. This is case insensetive.
Arguments:
text - user input text to be matched against
@@ -171,10 +174,9 @@ class TorControlCompleter:
the readlines set_completer function.
"""
- for cmd in self.commands:
- if cmd.lower().startswith(text.lower()):
- if not state: return cmd
- else: state -= 1
+ for cmd in self.getMatches(text):
+ if not state: return cmd
+ else: state -= 1
class ControlInterpretor:
"""
@@ -183,8 +185,29 @@ class ControlInterpretor:
"""
def __init__(self):
- self.queries = [] # requests made, newest to oldest
- self.contents = [] # (msg, format list) tuples of both input and output (oldest to newest)
+ self.backlog = [] # prior requests the user has made
+ self.contents = [] # (msg, format list) tuples for what's been displayed
+
+ def getBacklog(self):
+ """
+ Provides the backlog of prior user input.
+ """
+
+ return self.backlog
+
+ def getDisplayContents(self, appendPrompt = None):
+ """
+ Provides a list of lines to be displayed, each being a list of (msg,
+ format) tuples for the content to be displayed. This is ordered as the
+ oldest to newest.
+
+ Arguments:
+ appendPrompt - adds the given line to the end
+ """
+
+ if appendPrompt:
+ return self.contents + [appendPrompt]
+ else: return self.contents
def handleQuery(self, input):
"""
@@ -199,6 +222,12 @@ class ControlInterpretor:
"""
input = input.strip()
+
+ # appends new input, cropping if too long
+ self.backlog.append(input)
+ backlogCrop = len(self.backlog) - BACKLOG_LIMIT
+ if backlogCrop > 0: self.backlog = self.backlog[backlogCrop:]
+
inputEntry, outputEntry = [PROMPT], []
conn = torTools.getConn()
@@ -258,7 +287,16 @@ class ControlInterpretor:
except Exception, exc:
outputEntry.append((str(exc), ERROR_FORMAT))
- return (_splitOnNewlines(inputEntry), _splitOnNewlines(outputEntry))
+ # converts to lists split on newlines
+ inputLines = _splitOnNewlines(inputEntry)
+ outputLines = _splitOnNewlines(outputEntry)
+
+ # appends new contents, cropping if too long
+ self.contents += inputLines + outputLines
+ cropLines = len(self.contents) - CONTENT_LIMIT
+ if cropLines > 0: self.contents = self.contents[cropLines:]
+
+ return (inputLines, outputLines)
def prompt():
prompt = format(">>> ", Color.GREEN, Attr.BOLD)
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits