home *** CD-ROM | disk | FTP | other *** search
- ##################################################
- # SPYCE - Python-based HTML Scripting
- # Copyright (c) 2002 Rimon Barr.
- #
- # Refer to spyce.py
- # CVS: $Id: stdout.py 20864 2009-06-02 06:16:47Z ceros7 $
- ##################################################
-
- from spyceModule import spyceModule
- from spyceUtil import NoCloseOut
- from cStringIO import StringIO
-
- __doc__ = '''Sets the thread-safe server stdout to the response object for
- convenience of using print statements, and supports output redirection.'''
-
- class stdout(spyceModule):
- def start(self):
- # thread-safe stdout swap
- self.stdout = self._api.getStdout()
- self._api.setStdout(myResponseWrapper(self))
- # output redirection stack
- self.outputStack = []
- # memoize storage
- try: self.memoizeCache = self._api.getServerObject().memoized
- except AttributeError:
- self.memoizeCache = self._api.getServerObject().memoized = {}
- def finish(self, theError=None):
- # close all redirects
- while self.outputStack:
- self.pop()
- # thread-safe stdout swap back
- self._api.setStdout(self.stdout)
- def push(self, file=None):
- 'Redirect stdout to buffer'
- old_response = self._api.getResponse()
- old_response_mod = self._api.getModule('response')
- new_response = spyceCaptureResponse(old_response)
- self._api.setResponse(new_response)
- new_response_mod = self._api.spyceModule('response', 'response.py')(self._api)
- self._api.setModule('response', new_response_mod)
- new_response_mod.start()
- self.outputStack.append( (file, old_response, old_response_mod) )
- def pop(self):
- 'Return buffer value, and possible write to file'
- self._api.getModule('response').finish()
- buffer = self._api.getResponse().getCapturedOutput()
- file, old_response, old_response_mod = self.outputStack.pop()
- self._api.setModule('response', old_response_mod)
- self._api.setResponse(old_response)
- if file:
- file = os.path.join(os.path.dirname(self._api.getFilename()), file)
- out = None
- try:
- out = open(file, 'w')
- out.write(buffer)
- finally:
- if out: out.close()
- return buffer
- def capture(self, _spyceReserved, *args, **kwargs):
- 'Capture the output side-effects of a function'
- f = _spyceReserved # placeholder not to collide with kwargs
- self.push()
- r = apply(f, args, kwargs)
- s = self.pop()
- return r, s
- def __repr__(self):
- return 'depth: %s' % len(self.outputStack)
-
- class myResponseWrapper:
- def __init__(self, mod):
- self._mod = mod
- mod._api.registerModuleCallback(self.syncResponse)
- self.syncResponse()
- def syncResponse(self):
- response = self._mod._api.getModule('response')
- # functions (for performance)
- self.write = response.write
- self.writeln = response.writeln
- self.flush = response.flush
- def close(self):
- raise 'method not allowed'
-
- class spyceCaptureResponse:
- "Capture output, and let everything else through."
- def __init__(self, old_response):
- self._old_response = old_response
- self._buf = StringIO()
- def write(self, s):
- self._buf.write(s)
- def close(self):
- raise 'cannot close output while capturing output'
- def clear(self):
- self._buf = StringIO()
- def sendHeaders(self):
- raise 'cannot sendHeaders while capturing output!'
- def flush(self, stopFlag=0):
- pass
- def unbuffer(self):
- raise 'cannot unbuffer output while capturing output!'
- def __getattr__(self, name):
- return eval('self._old_response.%s'%name)
- def getCapturedOutput(self):
- return self._buf.getvalue()
-
-