Back to index

plone3  3.1.7
ControllerPythonScript.py
Go to the documentation of this file.
00001 ##############################################################################
00002 #
00003 # Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
00004 #
00005 # This software is subject to the provisions of the Zope Public License,
00006 # Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
00007 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
00008 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00009 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
00010 # FOR A PARTICULAR PURPOSE
00011 #
00012 # THIS FILE CONTAINS MODIFIED CODE FROM ZOPE 2.6.2
00013 ##############################################################################
00014 
00015 """Controller Python Scripts Product
00016 
00017 This product provides support for Script objects containing restricted
00018 Python code.
00019 """
00020 
00021 import os, re
00022 from Globals import package_home
00023 import AccessControl
00024 from OFS.SimpleItem import SimpleItem
00025 from urllib import quote
00026 from Shared.DC.Scripts.Script import BindingsUI
00027 from OFS.History import Historical
00028 from OFS.Cache import Cacheable
00029 from Products.PageTemplates.PageTemplateFile import PageTemplateFile
00030 from Products.CMFCore.utils import getToolByName
00031 from Script import PythonScript as BaseClass
00032 from ControllerBase import ControllerBase
00033 from ControllerState import ControllerState
00034 from FormAction import FormActionContainer
00035 from FormValidator import FormValidatorContainer
00036 from interfaces import IControllerPythonScript
00037 
00038 from zope.interface import implements
00039 
00040 # Track the Python bytecode version
00041 import imp
00042 Python_magic = imp.get_magic()
00043 del imp
00044 
00045 # This should only be incremented to force recompilation.
00046 Script_magic = 3
00047 _log_complaint = (
00048     'Some of your Scripts have stale code cached.  Since Zope cannot'
00049     ' use this code, startup will be slightly slower until these Scripts'
00050     ' are edited. You can automatically recompile all Scripts that have'
00051     ' this problem by visiting /manage_addProduct/PythonScripts/recompile'
00052     ' of your server in a browser.')
00053 
00054 _default_file = os.path.join(package_home(globals()),
00055                              'www', 'default_cpy')
00056 
00057 _marker = []  # Create a new marker object
00058 
00059 
00060 _first_indent = re.compile('(?m)^ *(?! |$)')
00061 _nonempty_line = re.compile('(?m)^(.*\S.*)$')
00062 
00063 # ###########################################################################
00064 # Product registration and Add support
00065 manage_addControllerPythonScriptForm = PageTemplateFile('www/cpyAdd', globals())
00066 manage_addControllerPythonScriptForm.__name__='manage_addControllerPythonScriptForm'
00067 
00068 def manage_addControllerPythonScript(self, id, REQUEST=None, submit=None):
00069     """Add a Python script to a folder.
00070     """
00071     id = str(id)
00072     id = self._setObject(id, ControllerPythonScript(id))
00073     if REQUEST is not None:
00074         file = REQUEST.form.get('file', '')
00075         if not isinstance(file, str):
00076             file = file.read()
00077         if not file:
00078             file = open(_default_file).read()
00079         self._getOb(id).write(file)
00080         try: u = self.DestinationURL()
00081         except: u = REQUEST['URL1']
00082         if submit==" Add and Edit ": u="%s/%s" % (u,quote(id))
00083         REQUEST.RESPONSE.redirect(u+'/manage_main')
00084     return ''
00085 
00086 
00087 class ControllerPythonScript(BaseClass, ControllerBase):
00088     """Web-callable scripts written in a safe subset of Python.
00089 
00090     The function may include standard python code, so long as it does
00091     not attempt to use the "exec" statement or certain restricted builtins.
00092     """
00093 
00094     meta_type='Controller Python Script'
00095 
00096     implements(IControllerPythonScript)
00097 
00098     manage_options = (
00099         {'label':'Edit',
00100          'action':'ZPythonScriptHTML_editForm',
00101          'help': ('PythonScripts', 'PythonScript_edit.stx')},
00102         ) + BindingsUI.manage_options + (
00103         {'label':'Test',
00104          'action':'ZScriptHTML_tryForm',
00105          'help': ('PythonScripts', 'PythonScript_test.stx')},
00106         {'label':'Validation',
00107          'action':'manage_formValidatorsForm'},
00108         {'label':'Actions',
00109          'action':'manage_formActionsForm'},
00110         {'label':'Proxy',
00111          'action':'manage_proxyForm',
00112          'help': ('OFSP','DTML-DocumentOrMethod_Proxy.stx')},
00113         ) + Historical.manage_options + SimpleItem.manage_options + \
00114         Cacheable.manage_options
00115 
00116     is_validator = 0
00117 
00118     security = AccessControl.ClassSecurityInfo()
00119     security.declareObjectProtected('View')
00120 
00121     security.declareProtected('View', '__call__')
00122 
00123     security.declareProtected('View management screens',
00124       'ZPythonScriptHTML_editForm', 'manage_main', 'read',
00125       'ZScriptHTML_tryForm', 'PrincipiaSearchSource',
00126       'document_src', 'params', 'body')
00127 
00128     security.declareProtected('Change Python Scripts',
00129       'ZPythonScriptHTML_editAction',
00130       'ZPythonScript_setTitle', 'ZPythonScript_edit',
00131       'ZPythonScriptHTML_upload', 'ZPythonScriptHTML_changePrefs')
00132 
00133 
00134     def __init__(self, *args, **kwargs):
00135         self.validators = FormValidatorContainer()
00136         self.actions = FormActionContainer()
00137         return ControllerPythonScript.inheritedAttribute('__init__')(self, *args, **kwargs)
00138 
00139 
00140     def __call__(self, *args, **kwargs):
00141         REQUEST = self.REQUEST
00142         controller = getToolByName(self, 'portal_form_controller')
00143         controller_state = controller.getState(self, is_validator=0)
00144         controller_state = self.getButton(controller_state, REQUEST)
00145         validators = self.getValidators(controller_state, REQUEST).getValidators()
00146 
00147         # put all arguments into a dict
00148         c = self.func_code
00149         param_names = c.co_varnames[:c.co_argcount]
00150         argdict = {}
00151         index = 0
00152         # grab the names for positional arguments out of the function code
00153         for a in args:
00154             argdict[param_names[index]] = a
00155             index += 1
00156         argdict.update(kwargs)
00157 
00158         controller_state = controller.validate(controller_state, REQUEST, validators, argdict)
00159 
00160         if controller_state.getStatus() == 'success':
00161             result = ControllerPythonScript.inheritedAttribute('__call__')(self, *args, **kwargs)
00162             if getattr(result, '__class__', None) == ControllerState and not result._isValidating():
00163                 return self.getNext(result, self.REQUEST)
00164             return result
00165         else:
00166             return self.getNext(controller_state, self.REQUEST)
00167 
00168 
00169     def _getState(self):
00170         return getToolByName(self, 'portal_form_controller').getState(self, is_validator=0)
00171 
00172 
00173     def _notifyOfCopyTo(self, container, op=0):
00174         # BaseClass.inheritedAttribute('notifyOfCopyTo')(self, container, op)
00175         self._base_notifyOfCopyTo(container, op)
00176 
00177     def manage_afterAdd(self, object, container):
00178         BaseClass.inheritedAttribute('manage_afterAdd')(self, object, container)
00179         self._base_manage_afterAdd(object, container)
00180 
00181     def manage_afterClone(self, object):
00182         BaseClass.inheritedAttribute('manage_afterClone')(self, object)
00183         self._base_manage_afterClone(object)