From 16b55f9476373347a3c2553e070497b383288360 Mon Sep 17 00:00:00 2001 From: Henrique Date: Fri, 22 Nov 2019 10:00:17 -0500 Subject: Implemented feature to save command history to a file. This allows users to reuse their commands the next time they open mitmproxy --- mitmproxy/tools/console/commander/commander.py | 46 +++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 5 deletions(-) (limited to 'mitmproxy/tools/console/commander/commander.py') diff --git a/mitmproxy/tools/console/commander/commander.py b/mitmproxy/tools/console/commander/commander.py index d751422b..d661d530 100644 --- a/mitmproxy/tools/console/commander/commander.py +++ b/mitmproxy/tools/console/commander/commander.py @@ -2,6 +2,7 @@ import abc import collections import copy import typing +import os import urwid from urwid.text_layout import calc_coords @@ -147,29 +148,55 @@ class CommandBuffer: self.completion = None +# TODO: This class should be a Singleton class CommandHistory: - def __init__(self, master: mitmproxy.master.Master, size: int = 30) -> None: + def __init__(self, master: mitmproxy.master.Master, size: int = 300) -> None: self.saved_commands: collections.deque = collections.deque( [CommandBuffer(master, "")], maxlen=size ) self.index: int = 0 + self.size: int = size + self.master: mitmproxy.master.Master = master + + _command_history_path = os.path.join(os.path.expanduser(mitmproxy.options.CONF_DIR), 'command_history') + if os.path.exists(_command_history_path): + with open(_command_history_path, 'r') as f: + for l in f.readlines(): + cbuf = CommandBuffer(master, l.strip()) + self.add_command(cbuf) + f.close() + + self.command_history_file = open(_command_history_path, 'w') @property def last_index(self): return len(self.saved_commands) - 1 + def clear_history(self): + """ + Needed for test suite. + TODO: Maybe create a command to clear the history? + """ + self.saved_commands: collections.deque = collections.deque( + [CommandBuffer(self.master, "")], + maxlen=self.size + ) + + self.index = 0 + self.command_history_file.truncate(0) + self.command_history_file.seek(0) + self.command_history_file.flush() + def get_next(self) -> typing.Optional[CommandBuffer]: if self.index < self.last_index: self.index = self.index + 1 - return self.saved_commands[self.index] - return None + return self.saved_commands[self.index] def get_prev(self) -> typing.Optional[CommandBuffer]: if self.index > 0: self.index = self.index - 1 - return self.saved_commands[self.index] - return None + return self.saved_commands[self.index] def add_command(self, command: CommandBuffer, execution: bool = False) -> None: if self.index == self.last_index or execution: @@ -184,6 +211,15 @@ class CommandHistory: if execution: self.index = self.last_index + # This prevents the constructor from trying to overwrite the file + # that it is currently reading + if hasattr(self, 'command_history_file'): + _history_str = "\n".join([c.text for c in self.saved_commands]) + self.command_history_file.truncate(0) + self.command_history_file.seek(0) + self.command_history_file.write(_history_str) + self.command_history_file.flush() + class CommandEdit(urwid.WidgetWrap): leader = ": " -- cgit v1.2.3