From 396dc8f8e460efe7c95494ccf44ac6e86c42b9fb Mon Sep 17 00:00:00 2001 From: Mike Auty Date: Fri, 23 Mar 2018 15:41:55 +0000 Subject: [PATCH] Add in the ability for plugins to report their progress if applicable. --- volatility/cli/__init__.py | 40 +++++++++++++--------- volatility/framework/interfaces/plugins.py | 4 ++- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/volatility/cli/__init__.py b/volatility/cli/__init__.py index bdede40aa..9b1e895d2 100644 --- a/volatility/cli/__init__.py +++ b/volatility/cli/__init__.py @@ -33,6 +33,24 @@ console.setFormatter(formatter) vollog.addHandler(console) +class PrintedProgress(object): + def __init__(self): + self._max_message_len = 0 + + def __call__(self, progress, description = None): + """ A sinmple function for providing text-based feedback + + .. warning:: Only for development use. + + :param progress: Percentage of progress of the current procedure + :type progress: int or float + """ + message = "\rProgress: {0: 7.2f}\t\t{1:}".format(round(progress, 2), description or '') + message_len = len(message) + self._max_message_len = max([self._max_message_len, message_len]) + print(message, end = ' ' * (self._max_message_len - message_len)) + + class CommandLine(object): """Constructs a command-line interface object for users to run plugins""" @@ -165,10 +183,11 @@ class CommandLine(object): # BACK TO THE FRAMEWORK ### # Clever magic figures out how to fulfill each requirement that might not be fulfilled - if not args.quiet: - errors = automagic.run(automagics, ctx, plugin, "plugins", progress_callback = progress_callback) - else: - errors = automagic.run(automagics, ctx, plugin, "plugins") + progress_callback = PrintedProgress() + if args.quiet: + progress_callback = None + + errors = automagic.run(automagics, ctx, plugin, "plugins", progress_callback = progress_callback) # Check all the requirements and/or go back to the automagic step unsatisfied = plugin.unsatisfied(ctx, plugin_config_path) @@ -181,7 +200,7 @@ class CommandLine(object): print("\n\n") - constructed = plugin(ctx, plugin_config_path) + constructed = plugin(ctx, plugin_config_path, progress_callback = progress_callback) if args.write_config: vollog.debug("Writing out configuration data to config.json") @@ -291,17 +310,6 @@ class HelpfulSubparserAction(argparse._SubParsersAction): getattr(namespace, argparse._UNRECOGNIZED_ARGS_ATTR).extend(arg_strings) -def progress_callback(progress, description = None): - """ A sinmple function for providing text-based feedback - - .. warning:: Only for development use. - - :param progress: Percentage of progress of the current procedure - :type progress: int or float - """ - print("\rProgress: {0: 7.2f}\t\t{1:}".format(round(progress, 2), description or ''), end = '\n') - - def main(): """A convenience function for constructing and running the :class:`CommandLine`'s run method""" CommandLine().run() diff --git a/volatility/framework/interfaces/plugins.py b/volatility/framework/interfaces/plugins.py index dc2d28c89..819fca22e 100644 --- a/volatility/framework/interfaces/plugins.py +++ b/volatility/framework/interfaces/plugins.py @@ -40,8 +40,10 @@ class PluginInterface(interfaces_configuration.ConfigurableInterface, validity.V def __init__(self, context: 'interfaces.context.ContextInterface', - config_path: str) -> None: + config_path: str, + progress_callback: validity.ProgressCallback = None) -> None: super().__init__(context, config_path) + self._progress_callback = progress_callback # Plugins self validate on construction, it makes it more difficult to work with them, but then # the validation doesn't need to be repeated over and over again by externals if self.unsatisfied(context, config_path):