2 of us spent a bunch of time on this last night and today. We came up with 2 possibilities:
Hijack stdout using something like the following:
# In recon-ng.py, have a global flag which determines whether or not you are in spool mode.__builtin__.spool=0# In framework.py, create a class like this:classwriter:def__init__(self,filename):spool=open(filename)self.writers=(sys.stdout,spool)defwrite(self,text):forwinself.writers:w.write(text)w.flush()# In framework.py, add a method to the framework to control spooling.defdo_spool(self,params):ifnot__builtin__.spool:sys.stdout=writer(self.goptions['spool_file'])self.output('Spooling ON.')else:sys.stdout=sys.__stdout__self.output('Spooling OFF.')
However, this breaks things like tab completion.
Create a custom print function and force all developers to use it by implementing from __future__ import print_function.
While this is a little unorthodox and less pythonic, it is much more flexible and makes for an easy transition to Python3.
The user see exactly the same thing as before and tab completion works. The framework print to an output file too when spooling is on. The question is : is this relevant to print to the output file the commands that the user enter ? What about completion ? Do we output it in the file too ?
I think the output should be identical so that when users or clients review the data, the fully understand the input that drove the output. Also, I would open file in append mode. That way users don't accidentally blow out old data that they forgot to rename, move, etc.