[Zope-Checkins] SVN: Zope/trunk/ Removed various persistent product related code and options. The `enable-product-installation` `zope.conf` setting is now a no-op.
Hanno Schlichting
hannosch at hannosch.eu
Sat Jul 2 14:08:33 EDT 2011
Log message for revision 122065:
Removed various persistent product related code and options. The `enable-product-installation` `zope.conf` setting is now a no-op.
Changed:
U Zope/trunk/doc/CHANGES.rst
U Zope/trunk/src/App/ApplicationManager.py
U Zope/trunk/src/App/FactoryDispatcher.py
U Zope/trunk/src/App/Product.py
U Zope/trunk/src/App/ProductContext.py
D Zope/trunk/src/App/ProductRegistry.py
D Zope/trunk/src/App/RefreshFuncs.py
D Zope/trunk/src/App/dtml/readme.dtml
D Zope/trunk/src/App/dtml/refresh.dtml
D Zope/trunk/src/App/dtml/traceback.dtml
U Zope/trunk/src/App/tests/test_ApplicationManager.py
U Zope/trunk/src/OFS/Application.py
U Zope/trunk/src/OFS/ObjectManager.py
U Zope/trunk/src/OFS/tests/testProductInit.py
U Zope/trunk/src/OFS/tests/test_registerpackage.py
U Zope/trunk/src/Testing/ZopeTestCase/ZopeLite.py
U Zope/trunk/src/Zope2/App/startup.py
U Zope/trunk/src/Zope2/Startup/zopeschema.xml
-=-
Modified: Zope/trunk/doc/CHANGES.rst
===================================================================
--- Zope/trunk/doc/CHANGES.rst 2011-07-02 17:12:27 UTC (rev 122064)
+++ Zope/trunk/doc/CHANGES.rst 2011-07-02 18:08:30 UTC (rev 122065)
@@ -33,6 +33,9 @@
Restructuring
+++++++++++++
+- Removed various persistent product related code and options. The
+ `enable-product-installation` `zope.conf` setting is now a no-op.
+
- Changed the value for `default-zpublisher-encoding` and
`management_page_charset` to `utf-8`.
Modified: Zope/trunk/src/App/ApplicationManager.py
===================================================================
--- Zope/trunk/src/App/ApplicationManager.py 2011-07-02 17:12:27 UTC (rev 122064)
+++ Zope/trunk/src/App/ApplicationManager.py 2011-07-02 18:08:30 UTC (rev 122065)
@@ -254,7 +254,7 @@
-class ApplicationManager(Folder,CacheManager):
+class ApplicationManager(Folder, CacheManager):
"""System management
"""
__roles__ = ('Manager',)
Modified: Zope/trunk/src/App/FactoryDispatcher.py
===================================================================
--- Zope/trunk/src/App/FactoryDispatcher.py 2011-07-02 17:12:27 UTC (rev 122064)
+++ Zope/trunk/src/App/FactoryDispatcher.py 2011-07-02 18:08:30 UTC (rev 122065)
@@ -98,13 +98,7 @@
'__FactoryDispatcher__',
FactoryDispatcher)
- productfolder = self.aq_acquire('_getProducts')()
- try:
- product = productfolder._product(name)
- except AttributeError:
- # If we do not have a persistent product entry, return
- product = Product(name)
-
+ product = Product(name)
dispatcher=dispatcher_class(product, self.aq_parent, REQUEST)
return dispatcher.__of__(self)
Modified: Zope/trunk/src/App/Product.py
===================================================================
--- Zope/trunk/src/App/Product.py 2011-07-02 17:12:27 UTC (rev 122064)
+++ Zope/trunk/src/App/Product.py 2011-07-02 18:08:30 UTC (rev 122065)
@@ -10,37 +10,9 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""Product objects
-"""
-# The new Product model:
-#
-# Products may be defined in the Products folder or by placing directories
-# in lib/python/Products.
-#
-# Products in lib/python/Products may have up to three sources of information:
-#
-# - Static information defined via Python. This information is
-# described and made available via __init__.py.
-#
-# - Dynamic object data that gets copied into the Bobobase.
-# This is contained in product.dat (which is obfuscated).
-#
-# - Static extensions supporting the dynamic data. These too
-# are obfuscated.
-#
-# Products may be copied and pasted only within the products folder.
-#
-# If a product is deleted (or cut), it is automatically recreated
-# on restart if there is still a product directory.
-
-import os
-
from AccessControl.class_init import InitializeClass
from AccessControl.owner import UnownableOwner
-from AccessControl.SecurityInfo import ClassSecurityInfo
-from AccessControl.unauthorized import Unauthorized
-from App.special_dtml import DTMLFile
from OFS.Folder import Folder
@@ -65,225 +37,3 @@
return 0
InitializeClass(ProductFolder)
-
-
-class Product(Folder):
- """Model a product that can be created through the web.
- """
-
- security = ClassSecurityInfo()
-
- meta_type='Product'
- icon='p_/Product_icon'
- version=''
- configurable_objects_=()
- import_error_=None
-
- manage_options = (
- (Folder.manage_options[0],) +
- tuple(Folder.manage_options[2:])
- )
-
- _properties = Folder._properties+(
- {'id':'version', 'type': 'string'},
- )
-
- _reserved_names=('Help',)
-
- def __init__(self, id, title):
- from HelpSys.HelpSys import ProductHelp
-
- self.id = id
- self.title = title
- self._setObject('Help', ProductHelp('Help', id))
-
- security.declarePublic('Destination')
- def Destination(self):
- "Return the destination for factory output"
- return self
-
- security.declarePublic('DestinationURL')
- def DestinationURL(self):
- "Return the URL for the destination for factory output"
- return self.REQUEST['BASE4']
-
-
- manage_traceback = DTMLFile('dtml/traceback', globals())
- manage_readme = DTMLFile('dtml/readme', globals())
- def manage_get_product_readme__(self):
- for name in ('README.txt', 'README.TXT', 'readme.txt'):
- path = os.path.join(self.home, name)
- if os.path.isfile(path):
- return open(path).read()
- return ''
-
- def permissionMappingPossibleValues(self):
- return self.possible_permissions()
-
- def getProductHelp(self):
- """Returns the ProductHelp object associated with the Product.
- """
- from HelpSys.HelpSys import ProductHelp
- if not hasattr(self, 'Help'):
- self._setObject('Help', ProductHelp('Help', self.id))
- return self.Help
-
- #
- # Product refresh
- #
-
- _refresh_dtml = DTMLFile('dtml/refresh', globals())
-
- def _readRefreshTxt(self, pid=None):
- import Products
- refresh_txt = None
- if pid is None:
- pid = self.id
- for productDir in Products.__path__:
- found = 0
- for name in ('refresh.txt', 'REFRESH.txt', 'REFRESH.TXT'):
- p = os.path.join(productDir, pid, name)
- if os.path.exists(p):
- found = 1
- break
- if found:
- try:
- file = open(p)
- text = file.read()
- file.close()
- refresh_txt = text
- break
- except:
- # Not found here.
- pass
- return refresh_txt
-
- def manage_performRefresh(self, REQUEST=None):
- """ Attempts to perform a refresh operation.
- """
- from App.RefreshFuncs import performFullRefresh
- if self._readRefreshTxt() is None:
- raise Unauthorized, 'refresh.txt not found'
- message = None
- if performFullRefresh(self._p_jar, self.id):
- from ZODB import Connection
- Connection.resetCaches() # Clears cache in future connections.
- message = 'Product refreshed.'
- else:
- message = 'An exception occurred.'
- if REQUEST is not None:
- return self.manage_refresh(REQUEST, manage_tabs_message=message)
-
- def manage_enableAutoRefresh(self, enable=0, REQUEST=None):
- """ Changes the auto refresh flag for this product.
- """
- from App.RefreshFuncs import enableAutoRefresh
- if self._readRefreshTxt() is None:
- raise Unauthorized, 'refresh.txt not created'
- enableAutoRefresh(self._p_jar, self.id, enable)
- if enable:
- message = 'Enabled auto refresh.'
- else:
- message = 'Disabled auto refresh.'
- if REQUEST is not None:
- return self.manage_refresh(REQUEST, manage_tabs_message=message)
-
- def manage_selectDependentProducts(self, selections=(), REQUEST=None):
- """ Selects which products to refresh simultaneously.
- """
- from App.RefreshFuncs import setDependentProducts
- if self._readRefreshTxt() is None:
- raise Unauthorized, 'refresh.txt not created'
- setDependentProducts(self._p_jar, self.id, selections)
- if REQUEST is not None:
- return self.manage_refresh(REQUEST)
-
-InitializeClass(Product)
-
-
-def initializeProduct(productp, name, home, app):
- # Initialize a persistent product
- assert doInstall()
- fver = ''
-
- if hasattr(productp, '__import_error__'):
- ie = productp.__import_error__
- else:
- ie = None
-
- # Retrieve version number from any suitable version.txt
- for fname in ('version.txt', 'VERSION.txt', 'VERSION.TXT'):
- try:
- fpath = os.path.join(home, fname)
- fhandle = open(fpath, 'r')
- fver = fhandle.read().strip()
- fhandle.close()
- break
- except IOError:
- continue
-
- old = None
- products = app.Control_Panel.Products
- try:
- if ihasattr(products, name):
- old=getattr(products, name)
- if ihasattr(old,'version') and old.version==fver:
- if hasattr(old, 'import_error_') and \
- old.import_error_==ie:
- # Version hasn't changed. Don't reinitialize.
- return old
- except:
- pass
-
- f = fver and (" (%s)" % fver)
- product=Product(name, 'Installed product %s%s' % (name, f))
-
- if old is not None:
- app._manage_remove_product_meta_type(product)
- products._delObject(name)
- for id, v in old.objectItems():
- try:
- product._setObject(id, v)
- except:
- pass
-
- products._setObject(name, product)
- product.home = home
-
- if ie:
- product.import_error_=ie
- product.title='Broken product %s' % name
- product.icon='p_/BrokenProduct_icon'
- product.manage_options=(
- {'label':'Traceback', 'action':'manage_traceback'},
- )
-
- for name in ('README.txt', 'README.TXT', 'readme.txt'):
- path = os.path.join(home, name)
- if os.path.isfile(path):
- product.manage_options=product.manage_options+(
- {'label':'README', 'action':'manage_readme'},
- )
- break
-
- # Ensure this product has a refresh tab.
- found = 0
- for option in product.manage_options:
- if option.get('label') == 'Refresh':
- found = 1
- break
- if not found:
- product.manage_options = product.manage_options + (
- {'label':'Refresh', 'action':'manage_refresh'},
- )
-
- return product
-
-
-def ihasattr(o, name):
- return hasattr(o, name) and o.__dict__.has_key(name)
-
-
-def doInstall():
- from App.config import getConfiguration
- return getConfiguration().enable_product_installation
Modified: Zope/trunk/src/App/ProductContext.py
===================================================================
--- Zope/trunk/src/App/ProductContext.py 2011-07-02 17:12:27 UTC (rev 122064)
+++ Zope/trunk/src/App/ProductContext.py 2011-07-02 18:08:30 UTC (rev 122065)
@@ -190,9 +190,7 @@
# currently also required by the _verifyObjectPaste
# method of CopyContainers like Folders.
'action': ('manage_addProduct/%s/%s' % (pid, name)),
- # 'product': Used by ProductRegistry for TTW products and by
- # OFS.Application for refreshing products.
- # This key might not be available.
+ # 'product': No longer used
'product': pid,
# 'permission': Guards the add action.
'permission': permission,
Deleted: Zope/trunk/src/App/ProductRegistry.py
===================================================================
--- Zope/trunk/src/App/ProductRegistry.py 2011-07-02 17:12:27 UTC (rev 122064)
+++ Zope/trunk/src/App/ProductRegistry.py 2011-07-02 18:08:30 UTC (rev 122065)
@@ -1,131 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2002 Zope Foundation and Contributors.
-#
-# 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
-#
-##############################################################################
-
-# Product registry and new product factory model. There will be a new
-# mechanism for defining actions for meta types. If an action is of
-# the form:
-#
-# manage_addProduct-name-factoryid
-#
-# Then the machinery that invokes an add-product form
-# will return:
-# ....what?
-
-class ProductRegistryMixin:
- # This class implements a protocol for registering products that
- # are defined through the web.
-
- # This class is a mix-in class for the top-level application object.
-
- def _manage_remove_product_meta_type(self, product,
- id=None, meta_type=None):
- r=[]
- pid=product.id
- for mt in self._getProductRegistryMetaTypes():
- if 'product' in mt:
- if mt['product']==pid and (
- meta_type is None or meta_type==mt['name']):
- continue
- elif meta_type==mt['name']: continue
- r.append(mt)
-
- self._setProductRegistryMetaTypes(tuple(r))
-
- def _constructor_prefix_string(self, pid):
- return 'manage_addProduct/%s/' % pid
-
- def _manage_add_product_meta_type(self, product, id, meta_type,
- permission=''):
- pid=product.id
-
- meta_types=self._getProductRegistryMetaTypes()
-
- for mt in meta_types:
- if mt['name']==meta_type:
- if 'product' not in mt: mt['product']=pid
- if mt['product'] != pid:
- raise ValueError, (
- 'The type <em>%s</em> is already defined.' % meta_type)
- mt['action']='%s%s' % (
- self._constructor_prefix_string(pid), id)
- if permission: mt['permission']=permission
- return
-
- mt={
- 'name': meta_type,
- 'action': ('%s%s' % (
- self._constructor_prefix_string(pid), id)),
- 'product': pid
- }
- if permission: mt['permission']=permission
-
- self._setProductRegistryMetaTypes(meta_types+(mt,))
-
- # HACK - sometimes an unwrapped App object seems to be passed as
- # self to these methods, which means that they dont have an aq_aquire
- # method. Until Jim has time to look into this, this aq_maybe method
- # appears to be an effective work-around...
- def aq_maybe(self, name):
- if hasattr(self, name):
- return getattr(self, name)
- return self.aq_acquire(name)
-
- def _manage_add_product_data(self, type, product, id, **data):
- values=filter(
- lambda d, product=product, id=id:
- not (d['product']==product and d['id']==id),
- list(self.aq_maybe('_getProductRegistryData')(type))
- )
-
- data['product']=product
- data['id']=id
- values.append(data)
-
- self.aq_maybe('_setProductRegistryData')(type, tuple(values))
-
- def _manage_remove_product_data(self, type, product, id):
- values=filter(
- lambda d, product=product, id=id:
- not (d['product']==product and d['id']==id),
- self.aq_maybe('_getProductRegistryData')(type)
- )
-
- self.aq_maybe('_setProductRegistryData')(type, tuple(values))
-
-
-class ProductRegistry(ProductRegistryMixin):
- # This class implements a protocol for registering products that
- # are defined through the web. It also provides methods for
- # getting hold of the Product Registry, Control_Panel.Products.
-
- # This class is a mix-in class for the top-level application object.
-
- def _getProducts(self): return self.Control_Panel.Products
-
- _product_meta_types=()
-
- def _getProductRegistryMetaTypes(self):
- return self._product_meta_types
-
- def _setProductRegistryMetaTypes(self, v):
- self._product_meta_types=v
-
- def _getProductRegistryData(self, name):
- return getattr(self, '_product_%s' % name)
-
- def _setProductRegistryData(self, name, v):
- name='_product_%s' % name
- if hasattr(self, name):
- return setattr(self, name, v)
- else:
- raise AttributeError, name
Deleted: Zope/trunk/src/App/RefreshFuncs.py
===================================================================
--- Zope/trunk/src/App/RefreshFuncs.py 2011-07-02 17:12:27 UTC (rev 122064)
+++ Zope/trunk/src/App/RefreshFuncs.py 2011-07-02 18:08:30 UTC (rev 122065)
@@ -1,339 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2002 Zope Foundation and Contributors.
-#
-# 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
-#
-##############################################################################
-'''
-Functions for refreshing products.
-'''
-
-from logging import getLogger
-import os
-import sys
-from time import time
-from traceback import format_exception
-
-from ExtensionClass import Base
-from Persistence import PersistentMapping
-
-LOG = getLogger('RefreshFuncs')
-global_classes_timestamp = 0
-products_mod_times = {}
-
-_marker = [] # create a new marker object.
-
-refresh_exc_info = {}
-
-class dummyClass:
- pass
-
-class dummyClass2(Base):
- pass
-
-def dummyFunc():
- pass
-
-ClassTypes = (type(dummyClass), type(dummyClass2))
-ModuleType = type(sys)
-FuncType = type(dummyFunc)
-
-next_auto_refresh_check = 0
-AUTO_REFRESH_INTERVAL = 2 # 2 seconds.
-
-# Functions for storing and retrieving the auto-refresh state for
-# each product.
-
-def _getCentralRefreshData(jar, create=0):
- root = jar.root()
- if root.has_key('RefreshData'):
- rd = root['RefreshData']
- else:
- rd = PersistentMapping()
- if create:
- root['RefreshData'] = rd
- return rd
-
-def isAutoRefreshEnabled(jar, productid):
- rd = _getCentralRefreshData(jar)
- ids = rd.get('auto', None)
- if ids:
- return ids.get(productid, 0)
- else:
- return 0
-
-def enableAutoRefresh(jar, productid, enable):
- productid = str(productid)
- rd = _getCentralRefreshData(jar, 1)
- ids = rd.get('auto', None)
- if ids is None:
- if enable:
- rd['auto'] = ids = PersistentMapping()
- else:
- return
- if enable:
- ids[productid] = 1
- else:
- if ids.has_key(productid):
- del ids[productid]
-
-def listAutoRefreshableProducts(jar):
- rd = _getCentralRefreshData(jar)
- auto = rd.get('auto', None)
- if auto:
- ids = []
- for k, v in auto.items():
- if v:
- ids.append(k)
- return ids
- else:
- return ()
-
-def getDependentProducts(jar, productid):
- rd = _getCentralRefreshData(jar)
- products = rd.get('products', None)
- if products is None:
- return ()
- product = products.get(productid, None)
- if product is None:
- return ()
- return product.get('dependent_products', ())
-
-def setDependentProducts(jar, productid, dep_ids):
- productid = str(productid)
- rd = _getCentralRefreshData(jar, 1)
- products = rd.get('products', None)
- if products is None:
- rd['products'] = products = PersistentMapping()
- product = products.get(productid, None)
- if product is None:
- products[productid] = product = PersistentMapping()
- product['dependent_products'] = tuple(map(str, dep_ids))
-
-
-# Functions for performing refresh.
-
-def getReloadVar(module):
- reload_var = getattr(module, '__refresh_module__', _marker)
- if reload_var is _marker:
- reload_var = getattr(module, '__reload_module__', _marker)
- if reload_var is _marker:
- reload_var = 1
- return reload_var
-
-def listRefreshableModules(productid):
- prefix = "Products.%s" % productid
- prefixdot = prefix + '.'
- lpdot = len(prefixdot)
- rval = []
- for name, module in sys.modules.items():
- if module and (name == prefix or name[:lpdot] == prefixdot):
- reload_var = getReloadVar(module)
- if reload_var:
- rval.append((name, module))
- return rval
-
-def logBadRefresh(productid):
- exc = sys.exc_info()
- try:
- LOG.error('Exception while refreshing %s' % productid, exc_info=exc)
- if hasattr(exc[0], '__name__'):
- error_type = exc[0].__name__
- else:
- error_type = str(exc[0])
- error_value = str(exc[1])
- info = ''.join(format_exception(exc[0], exc[1], exc[2], limit=200))
- refresh_exc_info[productid] = (error_type, error_value, info)
- finally:
- exc = None
-
-def performRefresh(jar, productid):
- '''Attempts to perform a refresh operation.
- '''
- refresh_exc_info[productid] = None
- setupModTimes(productid) # Refresh again only if changed again.
-
- modlist = listRefreshableModules(productid)
- former_modules = {}
- try:
- # Remove modules from sys.modules but keep a handle
- # on the old modules in case there's a problem.
- for name, module in modlist:
- m = sys.modules.get(name, None)
- if m is not None:
- former_modules[name] = m
- del sys.modules[name]
-
- # Reimport and reinstall the product.
- from OFS import Application
- Application.reimport_product(productid)
- app = jar.root()['Application']
- Application.reinstall_product(app, productid)
- return 1
- except:
- # Couldn't refresh. Reinstate removed modules.
- for name, module in former_modules.items():
- sys.modules[name] = module
- raise
-
-def performSafeRefresh(jar, productid):
- try:
- LOG.info('Refreshing product %s' % productid)
- if not performRefresh(jar, productid):
- return 0
- except:
- logBadRefresh(productid)
- return 0
- else:
- return 1
-
-def performFullRefresh(jar, productid):
- # Refresh dependent products also.
- if performSafeRefresh(jar, productid):
- dep_ids = getDependentProducts(jar, productid)
- for dep_id in dep_ids:
- if isAutoRefreshEnabled(jar, dep_id):
- if not performSafeRefresh(jar, dep_id):
- return 0
- else:
- return 0
- return 1
-
-def getLastRefreshException(productid):
- return refresh_exc_info.get(productid, None)
-
-# Functions for quickly scanning the dates of product modules.
-
-def tryFindProductDirectory(productid):
- import Products
- path_join = os.path.join
- isdir = os.path.isdir
- exists = os.path.exists
-
- for products_dir in Products.__path__:
- product_dir = path_join(products_dir, productid)
- if not isdir(product_dir): continue
- if not exists(path_join(product_dir, '__init__.py')):
- if not exists(path_join(product_dir, '__init__.pyc')):
- continue
- return product_dir
- return None
-
-def tryFindModuleFilename(product_dir, filename):
- # Try different variations of the filename of a module.
- path_join = os.path.join
- isdir = os.path.isdir
- exists = os.path.exists
-
- found = None
- fn = path_join(product_dir, filename + '.py')
- if exists(fn):
- found = fn
- if not found:
- fn = fn + 'c'
- if exists(fn):
- found = fn
- if not found:
- fn = path_join(product_dir, filename)
- if isdir(fn):
- fn = path_join(fn, '__init__.py')
- if exists(fn):
- found = fn
- else:
- fn = fn + 'c'
- if exists(fn):
- found = fn
- return found
-
-def setupModTimes(productid):
- mod_times = []
- product_dir = tryFindProductDirectory(productid)
- if product_dir is not None:
- modlist = listRefreshableModules(productid)
-
- path_join = os.path.join
- exists = os.path.exists
-
- for name, module in modlist:
- splitname = name.split( '.')[2:]
- if not splitname:
- filename = '__init__'
- else:
- filename = apply(path_join, splitname)
- found = tryFindModuleFilename(product_dir, filename)
-
- if found:
- try: mtime = os.stat(found)[8]
- except: mtime = 0
- mod_times.append((found, mtime))
- products_mod_times[productid] = mod_times
-
-def checkModTimes(productid):
- # Returns 1 if there were changes.
- mod_times = products_mod_times.get(productid, None)
- if mod_times is None:
- # Initialize the mod times.
- setupModTimes(productid)
- return 0
- for filename, mod_time in mod_times:
- try: mtime = os.stat(filename)[8]
- except: mtime = 0
- if mtime != mod_time:
- # Something changed!
- return 1
- return 0
-
-# Functions for performing auto-refresh.
-
-def checkAutoRefresh(jar):
- '''
- Returns the IDs of products that need to be auto-refreshed.
- '''
- # Note: this function is NOT allowed to change the database!
- global next_auto_refresh_check
- now = time()
- if next_auto_refresh_check and next_auto_refresh_check > now:
- # Not enough time has passed.
- return ()
- next_auto_refresh_check = now + AUTO_REFRESH_INTERVAL
-
- rd = _getCentralRefreshData(jar)
- ids = rd.get('auto', None)
- if not ids:
- return ()
- auto_refresh_ids = []
- for productid in ids.keys():
- if checkModTimes(productid):
- auto_refresh_ids.append(productid)
- return auto_refresh_ids
-
-def finishAutoRefresh(jar, productids):
- # This function is allowed to change the database.
- for productid in productids:
- performFullRefresh(jar, productid)
-
-def autoRefresh(jar):
- # Must be called before there are any changes made
- # by the connection to the database!
- import transaction
- auto_refresh_ids = checkAutoRefresh(jar)
- if auto_refresh_ids:
- finishAutoRefresh(jar, auto_refresh_ids)
- from ZODB import Connection
- Connection.resetCaches()
- transaction.commit()
- jar._resetCache()
- transaction.begin()
-
-def setupAutoRefresh(jar):
- # Install hook.
- from App.ZApplication import connection_open_hooks
- connection_open_hooks.append(autoRefresh)
- # Init mod times.
- checkAutoRefresh(jar)
Deleted: Zope/trunk/src/App/dtml/readme.dtml
===================================================================
--- Zope/trunk/src/App/dtml/readme.dtml 2011-07-02 17:12:27 UTC (rev 122064)
+++ Zope/trunk/src/App/dtml/readme.dtml 2011-07-02 18:08:30 UTC (rev 122065)
@@ -1,6 +0,0 @@
-<dtml-var manage_page_header>
-<dtml-var manage_tabs>
-
-<dtml-var manage_get_product_readme__ fmt=structured-text>
-
-<dtml-var manage_page_footer>
Deleted: Zope/trunk/src/App/dtml/refresh.dtml
===================================================================
--- Zope/trunk/src/App/dtml/refresh.dtml 2011-07-02 17:12:27 UTC (rev 122064)
+++ Zope/trunk/src/App/dtml/refresh.dtml 2011-07-02 18:08:30 UTC (rev 122065)
@@ -1,116 +0,0 @@
-<dtml-comment>
- Arguments for this method:
- id, refresh_txt, error_type, error_value, error_tb, devel_mode,
- auto_refresh_enabled, auto_refresh_other, dependent_products,
- loaded_modules
-</dtml-comment>
-<dtml-let form_title="'Refresh product: ' + id">
-<dtml-if manage_page_header>
- <dtml-var manage_page_header>
-<dtml-else>
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
- <html lang="en">
- <head>
- <title>&dtml-form_title;</title>
- </head>
- <body bgcolor="#FFFFFF" link="#000099" vlink="#555555">
- <h3>&dtml-form_title;</h3>
-</dtml-if>
-</dtml-let>
-<dtml-var manage_tabs>
-
-<dtml-if expr="refresh_txt == _.None">
- <p>The refresh function, designed to ease the development of Zope
- products, is not currently enabled for this product.
- To make it available, put a file named "refresh.txt" in the &dtml-id;
- product directory. Please note that not all products are
- compatible with the refresh function.</p>
-<dtml-else>
-
- <dtml-if error_type>
- <p><b>An exception occurred during the last refresh.</b><br />
- Exception type: <b>&dtml-error_type;</b> <br />
- Exception value: <b>&dtml-error_value;</b>
- </p>
- <pre>&dtml-error_tb;</pre>
- <hr />
- </dtml-if>
-
- <form action="&dtml-absolute_url;" method="POST">
- <table border="0">
- <tr>
- <td valign="top">
-
- <dtml-if expr="_.string.strip(refresh_txt)">
- <p>
- <b>Important information about refreshing this product:</b><br />
- <dtml-var refresh_txt fmt="structured-text">
- </p>
- </dtml-if>
-
- <div align="center"><input type="submit"
- name="manage_performRefresh:method" value="Refresh this product" />
- </div>
-
- <p>
- <dtml-if auto_refresh_enabled>
- <dtml-if devel_mode>
- Auto refresh is enabled. Zope will repeatedly scan for
- changes to the Python modules that make up this product and
- execute a refresh when needed.
- <dtml-else>
- Although auto refresh is enabled, Zope is not in development
- mode so auto refresh is not available. Use the "-D" argument
- when starting Zope to enable development mode.
- </dtml-if>
- <dtml-else>
- Auto refresh is disabled. Enable auto refresh
- to cause Zope to frequently scan this product for changes.
- Note that auto refresh can slow down Zope considerably
- if enabled for more than a few products.
- </dtml-if>
- <br />
- <dtml-let checked="auto_refresh_enabled and 'checked' or ' '">
- <input type="checkbox" name="enable" value="1" &dtml-checked; />
- Auto refresh mode
- <input type="submit" name="manage_enableAutoRefresh:method"
- value="Change" />
- </dtml-let>
- </p>
-
- <dtml-if auto_refresh_other>
- <p>Select dependent auto-refreshable products to be refreshed
- simultaneously.<br />
- <dtml-in auto_refresh_other sort>
- <dtml-let checked="(_['sequence-item'] in dependent_products) and
- 'checked' or ' '">
- <input type="checkbox" name="selections:list"
- value="&dtml-sequence-item;" &dtml-checked; />
- </dtml-let>
- </dtml-in>
- <input type="submit" name="manage_selectDependentProducts:method"
- value="Change" />
- </p>
- </dtml-if>
-
- </td>
- <td valign="top" class="row-hilite">
-
- <p><b>Refreshable product modules:</b></p>
- <ul>
- <dtml-in loaded_modules sort>
- <li>&dtml-sequence-item;</li>
- </dtml-in>
- </ul>
-
- </td>
- </tr>
- </table>
- </form>
-</dtml-if>
-
-<dtml-if manage_page_footer>
- <dtml-var manage_page_footer>
-<dtml-else>
- </body></html>
-</dtml-if>
Deleted: Zope/trunk/src/App/dtml/traceback.dtml
===================================================================
--- Zope/trunk/src/App/dtml/traceback.dtml 2011-07-02 17:12:27 UTC (rev 122064)
+++ Zope/trunk/src/App/dtml/traceback.dtml 2011-07-02 18:08:30 UTC (rev 122065)
@@ -1,8 +0,0 @@
-<dtml-var manage_page_header>
-<dtml-var manage_tabs>
-
-<h3>Import Traceback</h3>
-
-<pre>&dtml-import_error_;</pre>
-
-<dtml-var manage_page_footer>
Modified: Zope/trunk/src/App/tests/test_ApplicationManager.py
===================================================================
--- Zope/trunk/src/App/tests/test_ApplicationManager.py 2011-07-02 17:12:27 UTC (rev 122064)
+++ Zope/trunk/src/App/tests/test_ApplicationManager.py 2011-07-02 18:08:30 UTC (rev 122065)
@@ -350,11 +350,6 @@
am = self._makeOne()
self.assertEqual(am.sys_platform(), sys.platform)
- def test_ctor_initializes_Products(self):
- from App.Product import ProductFolder
- am = self._makeOne()
- self.assertTrue(isinstance(am.Products, ProductFolder))
-
def test__canCopy(self):
am = self._makeOne()
self.assertFalse(am._canCopy())
Modified: Zope/trunk/src/OFS/Application.py
===================================================================
--- Zope/trunk/src/OFS/Application.py 2011-07-02 17:12:27 UTC (rev 122064)
+++ Zope/trunk/src/OFS/Application.py 2011-07-02 18:08:30 UTC (rev 122065)
@@ -13,14 +13,11 @@
"""Application support
"""
-import os, sys, traceback
+import os, sys
from logging import getLogger
from cgi import escape
-from StringIO import StringIO
import Products
-import App.Product
-import App.ProductRegistry
import transaction
from AccessControl import ClassSecurityInfo
from AccessControl.class_init import InitializeClass
@@ -29,7 +26,6 @@
from App.ApplicationManager import ApplicationManager
from App.config import getConfiguration
from App import FactoryDispatcher
-from App.Product import doInstall
from DateTime import DateTime
from HelpSys.HelpSys import HelpSys
from OFS.metaconfigure import get_packages_to_initialize
@@ -56,7 +52,6 @@
class Application(ApplicationDefaultPermissions,
ZDOM.Root,
Folder.Folder,
- App.ProductRegistry.ProductRegistry,
FindSupport,
):
"""Top-level system object"""
@@ -292,7 +287,6 @@
global APP_MANAGER
APP_MANAGER = ApplicationManager()
APP_MANAGER._init()
- APP_MANAGER.Products=App.Product.ProductFolder()
app = self.getApp()
app._p_activate()
@@ -498,46 +492,33 @@
self.commit('Added virtual_hosting')
def install_products(self):
- app = self.getApp()
- # this defers to a function for b/c reasons
- return install_products(app)
+ return install_products()
def install_standards(self):
app = self.getApp()
# this defers to a function for b/c reasons
return install_standards(app)
-def install_products(app):
- # Install a list of products into the basic folder class, so
- # that all folders know about top-level objects, aka products
-
+def install_products(app=None):
folder_permissions = get_folder_permissions()
- meta_types=[]
- done={}
-
- debug_mode = getConfiguration().debug_mode
-
- transaction.get().note('Prior to product installs')
- transaction.commit()
-
- products = get_products()
-
- for priority, product_name, index, product_dir in products:
+ meta_types = []
+ done = {}
+ for priority, product_name, index, product_dir in get_products():
# For each product, we will import it and try to call the
# intialize() method in the product __init__ module. If
# the method doesnt exist, we put the old-style information
# together and do a default initialization.
- if done.has_key(product_name):
+ if product_name in done:
continue
- done[product_name]=1
+ done[product_name] = 1
install_product(app, product_dir, product_name, meta_types,
- folder_permissions, raise_exc=debug_mode)
+ folder_permissions)
# Delayed install of packages-as-products
for module, init_func in tuple(get_packages_to_initialize()):
- install_package(app, module, init_func, raise_exc=debug_mode)
+ install_package(app, module, init_func)
- Products.meta_types=Products.meta_types+tuple(meta_types)
+ Products.meta_types = Products.meta_types + tuple(meta_types)
InitializeClass(Folder.Folder)
def get_products():
@@ -564,68 +545,47 @@
products.sort()
return products
-def import_products():
- # Try to import each product, checking for and catching errors.
- done={}
- products = get_products()
- debug_mode = getConfiguration().debug_mode
-
- for priority, product_name, index, product_dir in products:
- if done.has_key(product_name):
+def import_products():
+ done = {}
+ for priority, product_name, index, product_dir in get_products():
+ if product_name in done:
LOG.warn('Duplicate Product name: '
'After loading Product %s from %s, '
'I skipped the one in %s.' % (
`product_name`, `done[product_name]`, `product_dir`) )
continue
- done[product_name]=product_dir
- import_product(product_dir, product_name, raise_exc=debug_mode)
+ done[product_name] = product_dir
+ import_product(product_dir, product_name)
return done.keys()
-def import_product(product_dir, product_name, raise_exc=0, log_exc=1):
+
+def import_product(product_dir, product_name, raise_exc=None):
path_join=os.path.join
isdir=os.path.isdir
exists=os.path.exists
- _st=type('')
global_dict=globals()
- silly=('__doc__',)
modules=sys.modules
- have_module=modules.has_key
- try:
- package_dir=path_join(product_dir, product_name)
- if not isdir(package_dir): return
- if not exists(path_join(package_dir, '__init__.py')):
- if not exists(path_join(package_dir, '__init__.pyc')):
- if not exists(path_join(package_dir, '__init__.pyo')):
- return
+ package_dir = path_join(product_dir, product_name)
+ if not isdir(package_dir):
+ return
- pname="Products.%s" % product_name
- try:
- product=__import__(pname, global_dict, global_dict, silly)
- if hasattr(product, '__module_aliases__'):
- for k, v in product.__module_aliases__:
- if not have_module(k):
- if type(v) is _st and have_module(v): v=modules[v]
- modules[k]=v
- except KeyboardInterrupt:
- raise
- except:
- exc = sys.exc_info()
- if log_exc:
- LOG.error('Could not import %s' % pname,
- exc_info=exc)
- f=StringIO()
- traceback.print_exc(100,f)
- f=f.getvalue()
- try: modules[pname].__import_error__=f
- except: pass
- if raise_exc:
- raise exc[0], exc[1], exc[2]
- finally:
- exc = None
+ if not exists(path_join(package_dir, '__init__.py')):
+ if not exists(path_join(package_dir, '__init__.pyc')):
+ if not exists(path_join(package_dir, '__init__.pyo')):
+ return
+ pname = "Products.%s" % product_name
+ product = __import__(pname, global_dict, global_dict, ('__doc__', ))
+ if hasattr(product, '__module_aliases__'):
+ for k, v in product.__module_aliases__:
+ if k not in modules:
+ if isinstance(v, str) and v in modules:
+ v = modules[v]
+ modules[k] = v
+
def get_folder_permissions():
folder_permissions={}
for p in Folder.Folder.__ac_permissions__:
@@ -635,106 +595,57 @@
def install_product(app, product_dir, product_name, meta_types,
- folder_permissions, raise_exc=0, log_exc=1):
+ folder_permissions, raise_exc=None):
from App.ProductContext import ProductContext
path_join=os.path.join
isdir=os.path.isdir
exists=os.path.exists
global_dict=globals()
- silly=('__doc__',)
- if 1: # Preserve indentation for diff :-)
- package_dir=path_join(product_dir, product_name)
- __traceback_info__=product_name
- if not isdir(package_dir): return
- if not exists(path_join(package_dir, '__init__.py')):
- if not exists(path_join(package_dir, '__init__.pyc')):
- if not exists(path_join(package_dir, '__init__.pyo')):
- return
- try:
- product=__import__("Products.%s" % product_name,
- global_dict, global_dict, silly)
+ package_dir=path_join(product_dir, product_name)
+ __traceback_info__=product_name
+ if not isdir(package_dir): return
+ if not exists(path_join(package_dir, '__init__.py')):
+ if not exists(path_join(package_dir, '__init__.pyc')):
+ if not exists(path_join(package_dir, '__init__.pyo')):
+ return
- # Install items into the misc_ namespace, used by products
- # and the framework itself to store common static resources
- # like icon images.
- misc_=pgetattr(product, 'misc_', {})
- if misc_:
- if isinstance(misc_, dict):
- misc_=Misc_(product_name, misc_)
- Application.misc_.__dict__[product_name]=misc_
+ product=__import__("Products.%s" % product_name,
+ global_dict, global_dict, ('__doc__', ))
- # Here we create a ProductContext object which contains
- # information about the product and provides an interface
- # for registering things like classes and help topics that
- # should be associated with that product. Products are
- # expected to implement a method named 'initialize' in
- # their __init__.py that takes the ProductContext as an
- # argument.
- do_install = doInstall()
- if do_install:
- productObject = App.Product.initializeProduct(
- product, product_name, package_dir, app)
- context = ProductContext(productObject, app, product)
- else:
- # avoid any persistent connection
- productObject = FactoryDispatcher.Product(product_name)
- context = ProductContext(productObject, None, product)
+ # Install items into the misc_ namespace, used by products
+ # and the framework itself to store common static resources
+ # like icon images.
+ misc_ = pgetattr(product, 'misc_', {})
+ if misc_:
+ if isinstance(misc_, dict):
+ misc_=Misc_(product_name, misc_)
+ Application.misc_.__dict__[product_name]=misc_
- # Look for an 'initialize' method in the product.
- initmethod = pgetattr(product, 'initialize', None)
- if initmethod is not None:
- initmethod(context)
+ productObject = FactoryDispatcher.Product(product_name)
+ context = ProductContext(productObject, None, product)
- if do_install:
- transaction.get().note('Installed product ' + product_name)
- transaction.commit()
+ # Look for an 'initialize' method in the product.
+ initmethod = pgetattr(product, 'initialize', None)
+ if initmethod is not None:
+ initmethod(context)
- except Exception:
- if log_exc:
- LOG.error('Couldn\'t install %s' % product_name,
- exc_info=sys.exc_info())
- transaction.abort()
- if raise_exc:
- raise
-
-def install_package(app, module, init_func, raise_exc=False, log_exc=True):
+def install_package(app, module, init_func, raise_exc=None):
"""Installs a Python package like a product."""
from App.ProductContext import ProductContext
- try:
- do_install = doInstall()
- name = module.__name__
- if do_install:
- product = App.Product.initializeProduct(module,
- name,
- module.__path__[0],
- app)
- else:
- product = FactoryDispatcher.Product(name)
- app = None
+ name = module.__name__
+ product = FactoryDispatcher.Product(name)
+ product.package_name = name
- product.package_name = name
+ if init_func is not None:
+ newContext = ProductContext(product, None, module)
+ init_func(newContext)
- if init_func is not None:
- newContext = ProductContext(product, app, module)
- init_func(newContext)
+ package_initialized(module, init_func)
- package_initialized(module, init_func)
- if do_install:
- transaction.get().note('Installed package %s' % module.__name__)
- transaction.commit()
- except Exception:
- if log_exc:
- LOG.error("Couldn't install %s" % module.__name__,
- exc_info=True)
- transaction.abort()
- if raise_exc:
- raise
-
-
def install_standards(app):
# Check to see if we've already done this before
if getattr(app, '_standard_objects_have_been_added', 0):
@@ -774,58 +685,16 @@
transaction.get().note('Installed standard objects')
transaction.commit()
-def reinstall_product(app, product_name):
- folder_permissions = get_folder_permissions()
- meta_types=[]
- transaction.get().note('Prior to product reinstall')
- transaction.commit()
-
- for product_dir in Products.__path__:
- product_names=os.listdir(product_dir)
- product_names.sort()
- if product_name in product_names:
- removeProductMetaTypes(product_name)
- install_product(app, product_dir, product_name, meta_types,
- folder_permissions, raise_exc=1, log_exc=0)
- break
-
- Products.meta_types=Products.meta_types+tuple(meta_types)
- InitializeClass(Folder.Folder)
-
-
-def reimport_product(product_name):
- for product_dir in Products.__path__:
- product_names=os.listdir(product_dir)
- product_names.sort()
- if product_name in product_names:
- import_product(product_dir, product_name,
- raise_exc=1, log_exc=0)
- break
-
-
-def removeProductMetaTypes(pid):
- """Unregisters the meta types registered by a product.
- """
- meta_types = Products.meta_types
- new_mts = []
- changed = 0
- for meta_type in meta_types:
- if meta_type.get('product', None) == pid:
- # Remove this meta type.
- changed = 1
- else:
- new_mts.append(meta_type)
- if changed:
- Products.meta_types = tuple(new_mts)
-
-
def pgetattr(product, name, default=install_products, __init__=0):
- if not __init__ and hasattr(product, name): return getattr(product, name)
+ if not __init__ and hasattr(product, name):
+ return getattr(product, name)
if hasattr(product, '__init__'):
product=product.__init__
- if hasattr(product, name): return getattr(product, name)
+ if hasattr(product, name):
+ return getattr(product, name)
- if default is not install_products: return default
+ if default is not install_products:
+ return default
- raise AttributeError, name
+ raise AttributeError(name)
Modified: Zope/trunk/src/OFS/ObjectManager.py
===================================================================
--- Zope/trunk/src/OFS/ObjectManager.py 2011-07-02 17:12:27 UTC (rev 122064)
+++ Zope/trunk/src/OFS/ObjectManager.py 2011-07-02 18:08:30 UTC (rev 122065)
@@ -210,14 +210,6 @@
import Products
external_candidates = []
- # Look at _product_meta_types, if there is one
- _pmt=()
- if hasattr(self, '_product_meta_types'): _pmt=self._product_meta_types
- elif hasattr(self, 'aq_acquire'):
- try: _pmt=self.aq_acquire('_product_meta_types')
- except: pass
- external_candidates.extend(list(_pmt))
-
# Look at all globally visible meta types.
for entry in getattr(Products, 'meta_types', ()):
if ( (interfaces is not None) or (entry.get("visibility", None)=="Global") ):
Modified: Zope/trunk/src/OFS/tests/testProductInit.py
===================================================================
--- Zope/trunk/src/OFS/tests/testProductInit.py 2011-07-02 17:12:27 UTC (rev 122064)
+++ Zope/trunk/src/OFS/tests/testProductInit.py 2011-07-02 18:08:30 UTC (rev 122065)
@@ -221,23 +221,11 @@
self.configure(cfg)
app = getApp()
from OFS.Application import install_products
- install_products(app)
+ install_products()
obids = app.Control_Panel.Products.keys()
self.assertEquals(obids, [])
- def test_install_products_enabled(self):
- self.makeFakeProducts()
- cfg2 = cfg + '\nenable-product-installation on'
- self.configure(cfg2)
- app = getApp()
- from OFS.Application import install_products
- install_products(app)
- obids = app.Control_Panel.Products.keys()
- for name in FAKEPRODUCTS:
- self.assert_(name in obids)
-
-
def test_suite():
suite = unittest.TestSuite()
suite.addTest( unittest.makeSuite( TestProductInit ) )
Modified: Zope/trunk/src/OFS/tests/test_registerpackage.py
===================================================================
--- Zope/trunk/src/OFS/tests/test_registerpackage.py 2011-07-02 17:12:27 UTC (rev 122064)
+++ Zope/trunk/src/OFS/tests/test_registerpackage.py 2011-07-02 18:08:30 UTC (rev 122065)
@@ -51,9 +51,7 @@
>>> import Zope2
>>> from OFS.Application import install_products
-
- >>> app = Zope2.app()
- >>> install_products(app)
+ >>> install_products()
pythonproduct2 initialized
Make sure it is registered:
Modified: Zope/trunk/src/Testing/ZopeTestCase/ZopeLite.py
===================================================================
--- Zope/trunk/src/Testing/ZopeTestCase/ZopeLite.py 2011-07-02 17:12:27 UTC (rev 122064)
+++ Zope/trunk/src/Testing/ZopeTestCase/ZopeLite.py 2011-07-02 18:08:30 UTC (rev 122065)
@@ -176,11 +176,10 @@
if _patched and not _installedProducts.has_key(name):
for priority, product_name, index, product_dir in get_products():
if product_name == name:
- if not quiet: _print('Installing %s ... ' % product_name)
- # We want to fail immediately if a product throws an exception
- # during install, so we set the raise_exc flag.
+ if not quiet:
+ _print('Installing %s ... ' % product_name)
install_product(_theApp, product_dir, product_name, meta_types,
- get_folder_permissions(), raise_exc=1)
+ get_folder_permissions())
_installedProducts[product_name] = 1
Products.meta_types = Products.meta_types + tuple(meta_types)
InitializeClass(Folder)
@@ -207,10 +206,9 @@
if _patched and not _installedPackages.has_key(name):
for module, init_func in get_packages_to_initialize():
if module.__name__ == name:
- if not quiet: _print('Installing %s ... ' % module.__name__)
- # We want to fail immediately if a package throws an exception
- # during install, so we set the raise_exc flag.
- install_package(_theApp, module, init_func, raise_exc=1)
+ if not quiet:
+ _print('Installing %s ... ' % module.__name__)
+ install_package(_theApp, module, init_func)
_installedPackages[module.__name__] = 1
if not quiet:
_print('done (%.3fs)\n' % (time.time() - start))
Modified: Zope/trunk/src/Zope2/App/startup.py
===================================================================
--- Zope/trunk/src/Zope2/App/startup.py 2011-07-02 17:12:27 UTC (rev 122064)
+++ Zope/trunk/src/Zope2/App/startup.py 2011-07-02 18:08:30 UTC (rev 122065)
@@ -127,10 +127,6 @@
# Initialize the app object
application = app()
OFS.Application.initialize(application)
- if getConfiguration().debug_mode:
- # Set up auto-refresh.
- from App.RefreshFuncs import setupAutoRefresh
- setupAutoRefresh(application._p_jar)
application._p_jar.close()
# "Log off" as system user
Modified: Zope/trunk/src/Zope2/Startup/zopeschema.xml
===================================================================
--- Zope/trunk/src/Zope2/Startup/zopeschema.xml 2011-07-02 17:12:27 UTC (rev 122064)
+++ Zope/trunk/src/Zope2/Startup/zopeschema.xml 2011-07-02 18:08:30 UTC (rev 122065)
@@ -414,10 +414,7 @@
<key name="enable-product-installation" datatype="boolean" default="off">
<description>
- If this directive is turned on, Zope performs 'product installation'
- (the registration of Python modules in various Products directories)
- at startup. Only turn this on if your code relies on the Products section
- in the Control_Panel to be populated.
+ BBB: This directive has no effect anymore.
</description>
<metadefault>off</metadefault>
</key>
More information about the Zope-Checkins
mailing list