diff --git a/pyscript/plot.py b/pyscript/plot.py new file mode 100644 index 0000000..7baf628 --- /dev/null +++ b/pyscript/plot.py @@ -0,0 +1,60 @@ +# +# Copyright (c) 2005 Helmut Merz helmutm@cy55.de +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +""" +View class(es) for images (plots). + +$Id$ +""" + +import os +from zope.interface import Interface, implements +from zope.cachedescriptors.property import Lazy + + +class PlotView(object): + """ Abstract basic view class for Flash movies . + + The assessment attribute has to be set by the subclass. + """ + + def __init__(self, context, request): + self.context = context + self.request = request + self.traverse_subpath = [] + + def publishTraverse(self, request, name): + self.traverse_subpath.append(name) + return self + + def __call__(self): + path = str('/' + os.path.join(*self.traverse_subpath)) + # TODO: keep path in temporary dictionary with hashed keys. + self.setHeaders(path) + f = open(path, 'rb') + data = f.read() + f.close() + return data + + def setHeaders(self, name=None): + response = self.request.response + # TODO: get content type from name (extension) + response.setHeader('Content-Type', 'image/jpeg') + response.setHeader('Expires', 'Sat, 1 Jan 2000 00:00:00 GMT'); + response.setHeader('Pragma', 'no-cache'); + diff --git a/pyscript/rstat.py b/pyscript/rstat.py index 5e19cd2..134ab08 100644 --- a/pyscript/rstat.py +++ b/pyscript/rstat.py @@ -22,6 +22,7 @@ Working transparently with the R statistics package. $Id$ """ +import os import rpy from rpy import r from zope.proxy import removeAllProxies @@ -34,18 +35,22 @@ class RWrapper(object): def __getattr__(self, attr): value = getattr(self.context, attr) - # TODO (Zope 2): return aq_base(value) return removeAllProxies(value) def __call__(self, *args, **kw): value = self.context.__call__(*args, **kw) value = removeAllProxies(value) return RWrapper(value) - # TODO (subclass for Zope 2): return aq_base(value) r = RWrapper(r) with_mode = RWrapper(rpy.with_mode) -as_py = RWrapper(rpy.as_py) +#as_py = RWrapper(rpy.as_py) + + +def graphics(*args, **kw): + filename = os.tempnam() + rc = r.GDD(filename, *args, **kw) + return filename + '.jpg', rc diff --git a/pyscript/script.py b/pyscript/script.py index 57125d7..387727b 100644 --- a/pyscript/script.py +++ b/pyscript/script.py @@ -1,45 +1,50 @@ -############################################################################## # -# Copyright (c) 2004 Zope Corporation and Contributors. -# All Rights Reserved. +# Copyright (c) 2007 Helmut Merz helmutm@cy55.de # -# This software is subject to the provisions of the Zope Public License, -# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. -# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -# FOR A PARTICULAR PURPOSE. +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. # -############################################################################## -"""Python Page +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +""" Simple implementation of Python scripts. $Id$ """ -__docformat__ = 'restructuredtext' - import new import re +import compiler.pycodegen from cStringIO import StringIO from persistent import Persistent -from zope.proxy import removeAllProxies -from zope.security.untrustedpython.builtins import SafeBuiltins -#from zope.security.untrustedpython.rcompile import compile -from zope.traversing.api import getParent, getPath -from zope.app.container.contained import Contained -from zope.interface import implements -from zope.app.i18n import ZopeMessageFactory as _ - -from cybertools.pyscript.interfaces import IPythonScript, IScriptContainer - - -import compiler.pycodegen import RestrictedPython.RCompile from RestrictedPython.SelectCompiler import ast +from zope.app.container.btree import BTreeContainer +from zope.app.container.contained import Contained +from zope.interface import implements +from zope.proxy import removeAllProxies +from zope.security.untrustedpython.builtins import SafeBuiltins from zope.security.untrustedpython.rcompile import RestrictionMutator as BaseRM +from zope.traversing.api import getParent, getPath + +from cybertools.pyscript.interfaces import IPythonScript, IScriptContainer +try: + from cybertools.pyscript.rstat import r, rpy + HAS_R = True +except ImportError: + HAS_R = False -unrestricted_objects = ('rpy', 'r', 'as_py') +unrestricted_objects = ('rpy', 'r', 'as_py', 'rstat') def compile(text, filename, mode): @@ -60,6 +65,7 @@ class RExpression(RestrictedPython.RCompile.RestrictedCompileMode): self, source, filename) self.rm = RestrictionMutator() + class RestrictionMutator(BaseRM): unrestricted_objects = unrestricted_objects @@ -173,3 +179,16 @@ def _print_usrc(match): if raw: return match.group(1)+'print '+`string` return match.group(1)+'print '+match.group(3).encode('unicode-escape') + + +class ScriptContainer(BTreeContainer): + + implements(IScriptContainer) + + unrestricted_objects = ('rstat') # not used (yet) + + def updateGlobals(self, globs): + if HAS_R: + from cybertools.pyscript import rstat + globs['rstat'] = rstat + diff --git a/pyscript/tests.py b/pyscript/tests.py index deda160..8eb6798 100644 --- a/pyscript/tests.py +++ b/pyscript/tests.py @@ -17,7 +17,7 @@ $Id$ """ import unittest, doctest -import zope.component +from zope import component from zope.interface import implements from zope.location.traversing import LocationPhysicallyLocatable from zope.testing.doctestunit import DocFileSuite @@ -25,10 +25,11 @@ from zope.traversing.interfaces import IContainmentRoot from zope.traversing.interfaces import IPhysicallyLocatable from zope.traversing.adapters import RootPhysicallyLocatable from zope.app.container.contained import Contained -from zope.app.testing import placelesssetup, ztapi +from zope.app.testing import placelesssetup +from cybertools.pyscript.script import ScriptContainer -class Root(Contained): +class Root(ScriptContainer, Contained): implements(IContainmentRoot) __parent__ = None @@ -37,11 +38,8 @@ class Root(Contained): def setUp(test): placelesssetup.setUp() - - ztapi.provideAdapter(None, IPhysicallyLocatable, - LocationPhysicallyLocatable) - ztapi.provideAdapter(IContainmentRoot, IPhysicallyLocatable, - RootPhysicallyLocatable) + component.provideAdapter(LocationPhysicallyLocatable) + component.provideAdapter(RootPhysicallyLocatable) def test_suite():