Commit 01beaca6 authored by Hanno Schlichting's avatar Hanno Schlichting

Changed product install so it won't write persistent changes only to abort...

Changed product install so it won't write persistent changes only to abort them. Instead we don't make any database changes in the first place.
parent c926c4fe
......@@ -18,6 +18,11 @@ Bugs Fixed
Features Added
++++++++++++++
- Changed product install so it won't write persistent changes only to abort
them. Instead we don't make any database changes in the first place.
- Disabled persistent product installation in the default test configuration.
- Directly extend and use the Zope Toolkit KGS release 1.0dev-r113891 from
http://download.zope.org/zopetoolkit/index/.
......
......@@ -23,6 +23,8 @@ from AccessControl.PermissionMapping import aqwrap
from Acquisition import Acquired
from Acquisition import aq_base
from Acquisition import Implicit
from ExtensionClass import Base
def _product_packages():
"""Returns all product packages including the regularly defined
......@@ -41,7 +43,7 @@ def _product_packages():
return packages
class Product(object):
class Product(Base):
"""Model a non-persistent product wrapper.
"""
......
......@@ -36,8 +36,6 @@
import os
import transaction
from AccessControl.class_init import InitializeClass
from AccessControl.owner import UnownableOwner
from AccessControl.SecurityInfo import ClassSecurityInfo
......@@ -204,13 +202,16 @@ InitializeClass(Product)
def initializeProduct(productp, name, home, app):
# Initialize a levered product
# Initialize a persistent product
assert doInstall()
import Globals # to set data
products = app.Control_Panel.Products
fver = ''
if hasattr(productp, '__import_error__'): ie=productp.__import_error__
else: ie=None
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'):
......@@ -223,32 +224,33 @@ def initializeProduct(productp, name, home, app):
except IOError:
continue
old=None
old = None
products = app.Control_Panel.Products
try:
if ihasattr(products,name):
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
except:
pass
f = fver and (" (%s)" % fver)
product=Product(name, 'Installed product %s%s' % (name,f))
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
try:
product._setObject(id, v)
except:
pass
products._setObject(name, product)
product.icon='p_/InstalledProduct_icon'
product.version=fver
product.home=home
product.thisIsAnInstalledProduct=1
product.home = home
if ie:
product.import_error_=ie
......@@ -277,12 +279,9 @@ def initializeProduct(productp, name, home, app):
{'label':'Refresh', 'action':'manage_refresh',
'help': ('OFSP','Product_Refresh.stx')},)
if not doInstall():
transaction.abort()
return product
return product
def ihasattr(o, name):
return hasattr(o, name) and o.__dict__.has_key(name)
......
......@@ -24,7 +24,6 @@ from AccessControl.Permission import registerPermissions
from AccessControl.PermissionRole import PermissionRole
from App.Common import package_home
from App.ImageFile import ImageFile
from App.Product import doInstall
from DateTime.DateTime import DateTime
from HelpSys import APIHelpTopic
from HelpSys import HelpTopic
......@@ -50,14 +49,15 @@ LOG = getLogger('ProductContext')
class ProductContext:
def __init__(self, product, app, package):
self.__prod=product
self.__app=app
self.__pack=package
self.__prod = product
# app is None by default which signals disabled product installation
self.__app = app
self.__pack = package
def registerClass(self, instance_class=None, meta_type='',
permission=None, constructors=(),
icon=None, permissions=None, legacy=(),
visibility="Global",interfaces=_marker,
visibility="Global", interfaces=_marker,
container_filter=None
):
"""Register a constructor
......@@ -140,7 +140,7 @@ class ProductContext:
else:
default = ('Manager',)
pr=PermissionRole(permission,default)
pr = PermissionRole(permission,default)
registerPermissions(((permission, (), default),))
############################################################
......@@ -168,7 +168,7 @@ class ProductContext:
else:
name = initial.__name__
fd=getattr(pack, '__FactoryDispatcher__', None)
fd = getattr(pack, '__FactoryDispatcher__', None)
if fd is None:
class __FactoryDispatcher__(FactoryDispatcher):
"Factory Dispatcher for a Specific Product"
......@@ -231,6 +231,8 @@ class ProductContext:
"""
Returns the ProductHelp associated with the current Product.
"""
if self.__app is None:
return self.__prod.getProductHelp()
return self.__prod.__of__(self.__app.Control_Panel.Products).getProductHelp()
def registerHelpTopic(self, id, topic):
......@@ -267,7 +269,7 @@ class ProductContext:
.py -- APIHelpTopic
"""
if not doInstall():
if not self.__app:
return
help=self.getProductHelp()
......
......@@ -30,6 +30,7 @@ from AccessControl.Permission import ApplicationDefaultPermissions
from Acquisition import aq_base
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
......@@ -676,24 +677,26 @@ def install_product(app, product_dir, product_name, meta_types,
# expected to implement a method named 'initialize' in
# their __init__.py that takes the ProductContext as an
# argument.
productObject = App.Product.initializeProduct(
product, product_name, package_dir, app)
context = ProductContext(productObject, app, product)
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)
# Look for an 'initialize' method in the product.
initmethod = pgetattr(product, 'initialize', None)
if initmethod is not None:
initmethod(context)
if not doInstall():
transaction.abort()
else:
if do_install:
transaction.get().note('Installed product ' + product_name)
transaction.commit()
except KeyboardInterrupt:
raise
except:
except Exception:
if log_exc:
LOG.error('Couldn\'t install %s' % product_name,
exc_info=sys.exc_info())
......@@ -706,23 +709,27 @@ def install_package(app, module, init_func, raise_exc=False, log_exc=True):
"""Installs a Python package like a product."""
from App.ProductContext import ProductContext
try:
product = App.Product.initializeProduct(module,
module.__name__,
module.__path__[0],
app)
product.package_name = module.__name__
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
product.package_name = name
if init_func is not None:
newContext = ProductContext(product, app, module)
init_func(newContext)
if not doInstall():
transaction.abort()
else:
if do_install:
transaction.get().note('Installed package %s' % module.__name__)
transaction.commit()
except KeyboardInterrupt:
raise
except:
except Exception:
if log_exc:
LOG.error("Couldn't install %s" % module.__name__,
exc_info=True)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment