diff --git a/pyscript/configure.zcml b/pyscript/configure.zcml index 97bebf0..1805f42 100644 --- a/pyscript/configure.zcml +++ b/pyscript/configure.zcml @@ -20,7 +20,7 @@ /> 10: # clean up old cache entries + old = cachedImages.pop(0).path + if os.path.exists(old): + os.unlink(old) + return image.name + class PlotView(object): - """ Abstract basic view class for Flash movies . - - The assessment attribute has to be set by the subclass. + """ Access to temporary filesystem images. """ def __init__(self, context, request): @@ -44,10 +70,10 @@ class PlotView(object): def __call__(self): if self.traverse_subpath: - path = str('/' + os.path.join(*self.traverse_subpath)) + key = self.traverse_subpath[0] else: - path = self.request.form.get('image') - # TODO: keep path in temporary dictionary with hashed keys. + key = self.request.form.get('image', 'not_found') + path = cachedImages[key].path self.setHeaders(path) f = open(path, 'rb') data = f.read() diff --git a/pyscript/rstat.py b/pyscript/rstat.py index 126b3c2..a5a2e42 100644 --- a/pyscript/rstat.py +++ b/pyscript/rstat.py @@ -26,6 +26,9 @@ import os import rpy from rpy import r from zope.proxy import removeAllProxies +from zope.traversing.browser import absoluteURL + +from cybertools.pyscript.plot import registerImage class RWrapper(object): @@ -49,8 +52,36 @@ with_mode = RWrapper(rpy.with_mode) #as_py = RWrapper(rpy.as_py) -def graphics(*args, **kw): - filename = os.tempnam() - rc = r.GDD(filename, *args, **kw) - return filename + '.jpg', rc +def gdd(**kw): + r.library('GDD') + filename = os.tempnam(None, 'rplot') + robj = r.GDD(filename, type='jpg', **kw) + return filename + '.jpg', robj + +def graphics(**kw): + context = kw.pop('context', None) + request = kw.pop('request', None) + fn, robj = gdd(**kw) + key = registerImage(fn) + return '%s/@@plot?image=%s' % (absoluteURL(context, request), key) + + +class RStat(object): + + def __init__(self, context, request): + self.context = context + self.request = request + + def gdd(self, **kw): + r.library('GDD') + filename = os.tempnam(None, 'rplot') + robj = r.GDD(filename, type='jpg', **kw) + return filename + '.jpg', robj + + def graphics(self, **kw): + request = self.request + context = self.context + fn, robj = gdd(**kw) + key = registerImage(fn) + return '%s/@@plot?image=%s' % (absoluteURL(context, request), key) diff --git a/pyscript/script.py b/pyscript/script.py index 83a4bba..1ff5188 100644 --- a/pyscript/script.py +++ b/pyscript/script.py @@ -89,11 +89,14 @@ class PythonScript(Contained, Persistent): _v_compiled = None - def __init__(self, source=u'', contentType=u'text/plain'): + parameters = u'' + + def __init__(self, source=u'', parameters=u'', contentType=u'text/plain'): """Initialize the object.""" super(PythonScript, self).__init__() self.source = source self.contentType = contentType + self.parameters = parameters or u'' def __filename(self): if self.__parent__ is None: @@ -110,7 +113,8 @@ class PythonScript(Contained, Persistent): self.__source = source self.__prepared_source = self.prepareSource(source) # Compile objects cannot be pickled - self._v_compiled = Function(self.__prepared_source, self.__filename()) + self._v_compiled = Function(self.__prepared_source, self.parameters, + self.__filename()) _tripleQuotedString = re.compile( r"^([ \t]*)[uU]?([rR]?)(('''|\"\"\")(.*)\4)", re.MULTILINE | re.DOTALL) @@ -136,11 +140,11 @@ class PythonScript(Contained, Persistent): source = property(getSource, setSource) - def __call__(self, request, **kw): + def __call__(self, request, *args, **kw): output = StringIO() if self._v_compiled is None: - self._v_compiled = Function(self.__prepared_source, - self.__filename()) + self._v_compiled = Function(self.__prepared_source, self.parameters, + self.__filename(),) parent = getParent(self) kw['request'] = request kw['script'] = self @@ -149,7 +153,7 @@ class PythonScript(Contained, Persistent): kw['script_result'] = None if IScriptContainer.providedBy(parent): parent.updateGlobals(kw) - self._v_compiled(kw) + self._v_compiled(args, kw) result = kw['script_result'] if result == output: result = result.getvalue().decode('unicode-escape') @@ -160,8 +164,13 @@ class Function(object): """A compiled function. """ - def __init__(self, source, filename=''): + parameters = '' + + def __init__(self, source, parameters='', filename=''): lines = [] + if parameters: + self.parameters = str(parameters).split() + #print '*** Function.parameters:', repr(self.parameters) lines.insert(0, 'def dummy(): \n pass') for line in source.splitlines(): lines.append(' ' + line) @@ -170,8 +179,10 @@ class Function(object): #print '*** source:', source self.code = compile(source, filename, 'exec') - def __call__(self, globals): + def __call__(self, args, globals): globals['__builtins__'] = SafeBuiltins + for idx, p in enumerate(self.parameters): + globals[p] = args[idx] exec self.code in globals, None @@ -192,7 +203,10 @@ class ScriptContainer(BTreeContainer): def updateGlobals(self, globs): if HAS_R: from cybertools.pyscript import rstat - globs['rstat'] = rstat + #globs['rstat'] = rstat + context = globs['context'] + request = globs['request'] + globs['rstat'] = rstat.RStat(context, request) globs['r'] = r globs['rpy'] = rpy