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: 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) 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 registerHelp(self, directory='help', clear=1, title_re=re.compile(r'<title>(.+?)</title>', re.I)): """ Registers Help Topics for all objects in a directory. Nothing will be done if the files in the directory haven't changed since the last registerHelp call. 'clear' indicates whether or not to delete all existing Topics from the Product. HelpTopics are created for these kind of files .dtml -- DTMLHelpTopic .html .htm -- TextHelpTopic .stx .txt -- STXHelpTopic .jpg .png .gif -- ImageHelpTopic .py -- APIHelpTopic """ if not doInstall(): return help = self.getProductHelp() path = os.path.join(Globals.package_home(self.__pack.__dict__), directory) # If help directory does not exist, log a warning and return. try: dir_mod_time = DateTime(os.stat(path)[stat.ST_MTIME]) except OSError, (errno, text): LOG.warn('%s: %s' % (text, path)) return
def registerHelp(self, directory='help', clear=1, title_re=re.compile(r'<title>(.+?)</title>', re.I)): """ Registers Help Topics for all objects in a directory. Nothing will be done if the files in the directory haven't changed since the last registerHelp call. 'clear' indicates whether or not to delete all existing Topics from the Product. HelpTopics are created for these kind of files .dtml -- DTMLHelpTopic .html .htm -- TextHelpTopic .stx .txt -- STXHelpTopic .jpg .png .gif -- ImageHelpTopic .py -- APIHelpTopic """ if not doInstall(): return help=self.getProductHelp() path=os.path.join(Globals.package_home(self.__pack.__dict__), directory) # If help directory does not exist, log a warning and return. try: dir_mod_time=DateTime(os.stat(path)[stat.ST_MTIME]) except OSError, (errno, text): LOG("Zope", WARNING, '%s: %s' % (text, path)) return
def initialize(context): # abuse registerClass to get a tutorial constructor # in the product add list context.registerClass( None, meta_type='Zope Tutorial', constructors=(TutorialTopic.addTutorialForm, TutorialTopic.addTutorial), ) from App.Product import doInstall if not doInstall(): return # create tutorial help topics lesson_path=os.path.join(App.Common.package_home(globals()), 'tutorial.stx') glossary_path=os.path.join(App.Common.package_home(globals()), 'glossary.stx') help=context.getProductHelp() # test to see if nothing has changed since last registration if help.lastRegistered is not None and \ help.lastRegistered >= DateTime(os.stat(lesson_path)[stat.ST_MTIME]): return help.lastRegistered=DateTime() # delete old help topics for id in help.objectIds('Help Topic'): help._delObject(id) # create glossary text=open(glossary_path).read() text=term_pat.sub(defineTerm, text) glossary=TutorialTopic.GlossaryTopic('tutorialGlossary', 'Zope Tutorial Glossary', text) context.registerHelpTopic('tutorialGlossary', glossary) # create lessons f=open(lesson_path) lines=[] id=0 while 1: line = f.readline() if (line.strip() and line.find(' ') != 0) or line=='': # new topic if lines: id = id + 1 topic_id = 'topic_%02d' % id text=''.join(lines[1:]) text=term_pat.sub(glossaryTerm, text) topic=TutorialTopic.TutorialTopic(topic_id, lines[0].strip(), spacestrip(text)) context.registerHelpTopic(topic_id, topic) lines=[line] else: lines.append(line) if line == '': break f.close()
def check_zglobals(self): if not doInstall(): return app = self.getApp() # Check for dangling pointers (broken zclass dependencies) in the # global class registry. If found, rebuild the registry. Note that # if the check finds problems but fails to successfully rebuild the # registry we abort the transaction so that we don't leave it in an # indeterminate state. did_fixups = 0 bad_things = 0 try: if app.checkGlobalRegistry(): LOG.info( 'Beginning attempt to rebuild the global ZClass registry.') app.fixupZClassDependencies(rebuild=1) did_fixups = 1 LOG.info( 'The global ZClass registry has successfully been rebuilt.' ) transaction.get().note('Rebuilt global product registry') transaction.commit() except: bad_things = 1 LOG.error('The attempt to rebuild the registry failed.', exc_info=True) transaction.abort() # Now we need to see if any (disk-based) products were installed # during intialization. If so (and the registry has no errors), # there may still be zclasses dependent on a base class in the # newly installed product that were previously broken and need to # be fixed up. If any really Bad Things happened (dangling pointers # were found in the registry but it couldn't be rebuilt), we don't # try to do anything to avoid making the problem worse. if (not did_fixups) and (not bad_things): # App.Product.initializeProduct will set this if a disk-based # product was added or updated and we are not a ZEO client. if getattr(Globals, '__disk_product_installed__', None): try: LOG.info( 'New disk product detected, determining if we need ' 'to fix up any ZClasses.') if app.fixupZClassDependencies(): LOG.info('Repaired broken ZClass dependencies.') self.commit('Repaired broked ZClass dependencies') except: LOG.error( 'Attempt to fixup ZClass dependencies after ' 'detecting an updated disk-based product failed.', exc_info=sys.exc_info()) transaction.abort()
def check_zglobals(self): if not doInstall(): return app = self.getApp() # Check for dangling pointers (broken zclass dependencies) in the # global class registry. If found, rebuild the registry. Note that # if the check finds problems but fails to successfully rebuild the # registry we abort the transaction so that we don't leave it in an # indeterminate state. did_fixups=0 bad_things=0 try: if app.checkGlobalRegistry(): logger.info('Beginning attempt to rebuild the global ZClass registry.') app.fixupZClassDependencies(rebuild=1) did_fixups=1 logger.info('The global ZClass registry has successfully been rebuilt.') transaction.get().note('Rebuilt global product registry') transaction.commit() except: bad_things=1 logger.info('The attempt to rebuild the registry failed.', exc_info=True) transaction.abort() # Now we need to see if any (disk-based) products were installed # during intialization. If so (and the registry has no errors), # there may still be zclasses dependent on a base class in the # newly installed product that were previously broken and need to # be fixed up. If any really Bad Things happened (dangling pointers # were found in the registry but it couldn't be rebuilt), we don't # try to do anything to avoid making the problem worse. if (not did_fixups) and (not bad_things): # App.Product.initializeProduct will set this if a disk-based # product was added or updated and we are not a ZEO client. if getattr(Globals, '__disk_product_installed__', None): try: logger.info( ('New disk product detected, determining if we need ' 'to fix up any ZClasses.')) if app.fixupZClassDependencies(): logger.info('Repaired broken ZClass dependencies.') self.commit('Repaired broked ZClass dependencies') except: logger.error( ('Attempt to fixup ZClass dependencies after ' 'detecting an updated disk-based product failed.'), exc_info=True) transaction.abort()
def install(self, raise_exc=True, log_exc=True): __traceback_info__ = self.productname package = self.package product = self.product productname = self.productname initializer = self.initializer permissions = self.permissions folder_permissions = get_folder_permissions() init_data = None try: self.set_package_module_aliases() self.set_package_misc_attrs() # allow entry points that are "dummies" (e.g. just the module) # in case the product doesn't have an initialize function that # needs to be called if callable(initializer): init_data = initializer(self) self.set_package_ac_permissions() self.munge_package_meta_types() self.set_package_methods() if self.new_permissions: new_permissions = self.new_permissions.items() for permission, names in new_permissions: folder_permissions[permission] = names new_permissions.sort() Folder.__ac_permissions__ = tuple( list(Folder.__ac_permissions__) + new_permissions) if not doInstall(): transaction().abort() else: transaction.get().note('Installed product ' + productname) transaction.commit() except: if log_exc: zLOG.LOG('Zope', zLOG.ERROR, 'Couldn\'t install %s' % productname, error=sys.exc_info()) transaction.abort() if raise_exc: raise return init_data
def install(self, raise_exc=True, log_exc=True): __traceback_info__ = self.productname package = self.package product = self.product productname = self.productname initializer = self.initializer permissions = self.permissions folder_permissions = get_folder_permissions() init_data = None try: self.set_package_module_aliases() self.set_package_misc_attrs() # allow entry points that are "dummies" (e.g. just the module) # in case the product doesn't have an initialize function that # needs to be called if callable(initializer): init_data = initializer(self) self.set_package_ac_permissions() self.munge_package_meta_types() self.set_package_methods() if self.new_permissions: new_permissions = self.new_permissions.items() for permission, names in new_permissions: folder_permissions[permission]=names new_permissions.sort() Folder.__ac_permissions__=tuple( list(Folder.__ac_permissions__)+new_permissions) if not doInstall(): transaction().abort() else: transaction.get().note('Installed product '+productname) transaction.commit() except: if log_exc: zLOG.LOG('Zope',zLOG.ERROR,'Couldn\'t install %s' % productname, error=sys.exc_info()) transaction.abort() if raise_exc: raise return init_data
def install_package(app, module, init_func, raise_exc=False, log_exc=True): """Installs a Python package like a product.""" try: product = App.Product.initializeProduct(module, module.__name__, module.__path__[0], app) product.package_name = module.__name__ if init_func is not None: newContext = ProductContext(product, app, module) init_func(newContext) if not doInstall(): transaction.abort() else: transaction.get().note('Installed package %s' % module.__name__) transaction.commit() except: if log_exc: LOG.error("Couldn't install %s" % module.__name__, exc_info=True) transaction.abort() if raise_exc: raise
def create_product_object(self): """ Create a persistent object in the ControlPanel.Products area representing a product packaged as an egg and return it """ products = self.app.Control_Panel.Products fver = '' packagename = self.package.__name__ productname = self.productname ie = getattr(self.package, '__import_error__', None) # Retrieve version number from any suitable version.txt for fname in ('version.txt', 'VERSION.txt', 'VERSION.TXT'): if pkg_resources.resource_exists(packagename, fname): fver = pkg_resources.resource_string(packagename, fname).strip() break old = None if ihasattr(products, productname): old = getattr(products, productname) if ihasattr(old, 'version') and old.version == fver: old_ie = getattr(old, 'import_error_', None) if old_ie == ie: # Version hasn't changed. Don't reinitialize. return old f = fver and ("(%s)" % fver) product = EggProduct( productname, 'Installed egg product %s %s from %s' % (productname, f, self.eggname), packagename) if old is not None: self.app._manage_remove_product_meta_type(product) products._delObject(productname) for id, v in old.objectItems(): try: product._setObject(id, v) except: zLOG.LOG('EggProductContext Initialization', zLOG.INFO, ('Error when cleaning old persistent data from ' 'Control Panel for %s.%s' % (productname, id)), error=sys.exc_info()) products._setObject(productname, product) product.icon = 'misc_/Basket/icon_egg.gif' product.version = fver product.home = str(self.package.__path__) product.manage_options = (Folder.manage_options[0],) + \ tuple(Folder.manage_options[2:]) product._distribution = None product.manage_distribution = None product.thisIsAnInstalledProduct = 1 if ie: product.import_error_ = ie product.title = 'Broken product %s' % productname product.icon = 'p_/BrokenProduct_icon' product.manage_options = ({ 'label': 'Traceback', 'action': 'manage_traceback' }, ) for fname in ('README.txt', 'README.TXT', 'readme.txt'): if pkg_resources.resource_exists(packagename, fname): product.manage_options = product.manage_options + ( { 'label': 'README', 'action': 'manage_readme' }, ) break if not doInstall(): transaction.abort() return product # Give the ZClass fixup code in Application Globals.__disk_product_installed__ = 1 product.name = productname return product
def install_product(app, product_dir, product_name, meta_types, folder_permissions, raise_exc=0, log_exc=1): path_join=os.path.join isdir=os.path.isdir exists=os.path.exists DictType=type({}) 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) # 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 type(misc_) is DictType: misc_=Misc_(product_name, misc_) Application.misc_.__dict__[product_name]=misc_ # 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. productObject=App.Product.initializeProduct( product, product_name, package_dir, app) context=ProductContext(productObject, app, product) # Look for an 'initialize' method in the product. If it does # not exist, then this is an old product that has never been # updated. In that case, we will analyze the product and # build up enough information to do initialization manually. initmethod=pgetattr(product, 'initialize', None) if initmethod is not None: initmethod(context) # Support old-style product metadata. Older products may # define attributes to name their permissions, meta_types, # constructors, etc. permissions={} new_permissions={} for p in pgetattr(product, '__ac_permissions__', ()): permission, names, default = ( tuple(p)+('Manager',))[:3] if names: for name in names: permissions[name]=permission elif not folder_permissions.has_key(permission): new_permissions[permission]=() for meta_type in pgetattr(product, 'meta_types', ()): # Modern product initialization via a ProductContext # adds 'product' and 'permission' keys to the meta_type # mapping. We have to add these here for old products. pname=permissions.get(meta_type['action'], None) if pname is not None: meta_type['permission']=pname meta_type['product']=productObject.id meta_type['visibility'] = 'Global' meta_types.append(meta_type) for name,method in pgetattr( product, 'methods', {}).items(): if not hasattr(Folder.Folder, name): setattr(Folder.Folder, name, method) if name[-9:]!='__roles__': # not Just setting roles if (permissions.has_key(name) and not folder_permissions.has_key( permissions[name])): permission=permissions[name] if new_permissions.has_key(permission): new_permissions[permission].append(name) else: new_permissions[permission]=[name] if new_permissions: new_permissions=new_permissions.items() for permission, names in new_permissions: folder_permissions[permission]=names new_permissions.sort() Folder.Folder.__dict__['__ac_permissions__']=tuple( list(Folder.Folder.__ac_permissions__)+new_permissions) if not doInstall(): get_transaction().abort() else: get_transaction().note('Installed product '+product_name) get_transaction().commit() except: if log_exc: LOG('Zope',ERROR,'Couldn\'t install %s' % product_name, error=sys.exc_info()) get_transaction().abort() if raise_exc: raise
def initialize(app): # Initialize the application # The following items marked b/c are backward compatibility hacks # which make sure that expected system objects are added to the # bobobase. This is required because the bobobase in use may pre- # date the introduction of certain system objects such as those # which provide Lever support. # b/c: Ensure that Control Panel exists. if not hasattr(app, 'Control_Panel'): cpl=ApplicationManager() cpl._init() app._setObject('Control_Panel', cpl) get_transaction().note('Added Control_Panel') get_transaction().commit() # Initialize the cache: app.Control_Panel.initialize_cache() # b/c: Ensure that a ProductFolder exists. if not hasattr(aq_base(app.Control_Panel), 'Products'): app.Control_Panel.Products=App.Product.ProductFolder() get_transaction().note('Added Control_Panel.Products') get_transaction().commit() # Ensure that a temp folder exists if not hasattr(app, 'temp_folder'): from Products.TemporaryFolder.TemporaryFolder import \ MountedTemporaryFolder tf = MountedTemporaryFolder('temp_folder','Temporary Folder') app._setObject('temp_folder', tf) get_transaction().note('Added temp_folder') get_transaction().commit() del tf # Ensure that there is a transient container in the temp folder tf = app.temp_folder if not hasattr(aq_base(tf), 'session_data'): env_has = os.environ.get from Products.Transience.Transience import TransientObjectContainer addnotify = env_has('ZSESSION_ADD_NOTIFY', None) delnotify = env_has('ZSESSION_DEL_NOTIFY', None) default_limit = 1000 limit = env_has('ZSESSION_OBJECT_LIMIT', default_limit) try: limit=int(limit) if limit != default_limit: LOG('Zope Default Object Creation', INFO, ('using ZSESSION_OBJECT_LIMIT-specified max objects ' 'value of %s' % limit)) except ValueError: LOG('Zope Default Object Creation', WARNING, ('Noninteger value %s specified for ZSESSION_OBJECT_LIMIT, ' 'defaulting to %s' % (limit, default_limit))) limit = default_limit if addnotify and app.unrestrictedTraverse(addnotify, None) is None: LOG('Zope Default Object Creation', WARNING, ('failed to use nonexistent "%s" script as ' 'ZSESSION_ADD_NOTIFY' % addnotify)) addnotify=None elif addnotify: LOG('Zope Default Object Creation', INFO, 'using %s as add notification script' % addnotify) if delnotify and app.unrestrictedTraverse(delnotify, None) is None: LOG('Zope Default Object Creation', WARNING, ('failed to use nonexistent "%s" script as ' 'ZSESSION_DEL_NOTIFY' % delnotify)) delnotify=None elif delnotify: LOG('Zope Default Object Creation', INFO, 'using %s as delete notification script' % delnotify) toc = TransientObjectContainer('session_data', 'Session Data Container', addNotification = addnotify, delNotification = delnotify, limit=limit) timeout_spec = env_has('ZSESSION_TIMEOUT_MINS', '') if timeout_spec: try: timeout_spec = int(timeout_spec) except ValueError: LOG('Zope Default Object Creation', WARNING, ('"%s" is an illegal value for ZSESSION_TIMEOUT_MINS, ' 'using default timeout instead.' % timeout_spec)) else: LOG('Zope Default Object Creation', INFO, ('using ZSESSION_TIMEOUT_MINS-specified session timeout ' 'value of %s' % timeout_spec)) toc = TransientObjectContainer('session_data', 'Session Data Container', timeout_mins = timeout_spec, addNotification=addnotify, delNotification = delnotify, limit=limit) tf._setObject('session_data', toc) tf_reserved = getattr(tf, '_reserved_names', ()) if 'session_data' not in tf_reserved: tf._reserved_names = tf_reserved + ('session_data',) get_transaction().note('Added session_data to temp_folder') get_transaction().commit() del toc del addnotify del delnotify del timeout_spec del env_has del tf # Ensure that a browser ID manager exists if not hasattr(app, 'browser_id_manager'): from Products.Sessions.BrowserIdManager import BrowserIdManager bid = BrowserIdManager('browser_id_manager', 'Browser Id Manager') app._setObject('browser_id_manager', bid) get_transaction().note('Added browser_id_manager') get_transaction().commit() del bid # Ensure that a session data manager exists if not hasattr(app, 'session_data_manager'): from Products.Sessions.SessionDataManager import SessionDataManager sdm = SessionDataManager('session_data_manager', title='Session Data Manager', path='/temp_folder/session_data', requestName='SESSION') app._setObject('session_data_manager', sdm) get_transaction().note('Added session_data_manager') get_transaction().commit() del sdm # Ensure that there's an Examples folder with examples. # However, make sure that if the examples have been added already # and then deleted that we don't add them again. if not hasattr(app, 'Examples') and not \ hasattr(app, '_Zope25_examples_have_been_added'): examples_path = os.path.join(Globals.ZOPE_HOME, \ 'import', 'Examples.zexp') if os.path.isfile(examples_path): app._importObjectFromFile(examples_path, verify=0) app._Zope25_examples_have_been_added=1 get_transaction().note('Added Examples folder') get_transaction().commit() else: LOG('Zope Default Object Creation', INFO, '%s examples import file could not be found.' % examples_path) # b/c: Ensure that Owner role exists. if hasattr(app, '__ac_roles__') and not ('Owner' in app.__ac_roles__): app.__ac_roles__=app.__ac_roles__ + ('Owner',) get_transaction().note('Added Owner role') get_transaction().commit() # ensure the Authenticated role exists. if hasattr(app, '__ac_roles__'): if not 'Authenticated' in app.__ac_roles__: app.__ac_roles__=app.__ac_roles__ + ('Authenticated',) get_transaction().note('Added Authenticated role') get_transaction().commit() # Make sure we have Globals root=app._p_jar.root() if not root.has_key('ZGlobals'): import BTree app._p_jar.root()['ZGlobals']=BTree.BTree() get_transaction().note('Added Globals') get_transaction().commit() # Install the initial user. if hasattr(app, 'acl_users'): users = app.acl_users if hasattr(users, '_createInitialUser'): app.acl_users._createInitialUser() get_transaction().note('Created initial user') get_transaction().commit() # Install an error_log if not hasattr(app, 'error_log'): from Products.SiteErrorLog.SiteErrorLog import SiteErrorLog error_log = SiteErrorLog() app._setObject('error_log', error_log) get_transaction().note('Added site error_log at /error_log') get_transaction().commit() install_products(app) install_standards(app) # Note that the code from here on only runs if we are not a ZEO # client, or if we are a ZEO client and we've specified by way # of env variable that we want to force products to load. if not doInstall(): return # Check for dangling pointers (broken zclass dependencies) in the # global class registry. If found, rebuild the registry. Note that # if the check finds problems but fails to successfully rebuild the # registry we abort the transaction so that we don't leave it in an # indeterminate state. did_fixups=0 bad_things=0 try: if app.checkGlobalRegistry(): LOG('Zope', INFO, 'Beginning attempt to rebuild the global ZClass registry.') app.fixupZClassDependencies(rebuild=1) did_fixups=1 LOG('Zope', INFO, 'The global ZClass registry has successfully been rebuilt.') get_transaction().note('Rebuilt global product registry') get_transaction().commit() except: bad_things=1 LOG('Zope', ERROR, 'The attempt to rebuild the registry failed.', error=sys.exc_info()) get_transaction().abort() # Now we need to see if any (disk-based) products were installed # during intialization. If so (and the registry has no errors), # there may still be zclasses dependent on a base class in the # newly installed product that were previously broken and need to # be fixed up. If any really Bad Things happened (dangling pointers # were found in the registry but it couldn't be rebuilt), we don't # try to do anything to avoid making the problem worse. if (not did_fixups) and (not bad_things): # App.Product.initializeProduct will set this if a disk-based # product was added or updated and we are not a ZEO client. if getattr(Globals, '__disk_product_installed__', 0): try: LOG('Zope', INFO, 'New disk product detected, determining '\ 'if we need to fix up any ZClasses.') if app.fixupZClassDependencies(): LOG('Zope', INFO, 'Repaired broken ZClass dependencies.') get_transaction().commit() except: LOG('Zope', ERROR, 'Attempt to fixup ZClass dependencies after detecting ' \ 'an updated disk-based product failed.', error=sys.exc_info()) get_transaction().abort()
def install_product(app, product_dir, product_name, meta_types, folder_permissions, raise_exc=0, log_exc=1): 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) # 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_ # 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) # Look for an 'initialize' method in the product. initmethod = pgetattr(product, 'initialize', None) if initmethod is not None: initmethod(context) if do_install: transaction.get().note('Installed product ' + product_name) transaction.commit() 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_product(app, product_dir, product_name, meta_types, folder_permissions, raise_exc=0, log_exc=1): 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) # 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_ # 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. productObject = App.Product.initializeProduct( product, product_name, package_dir, app) context = ProductContext(productObject, app, product) # Look for an 'initialize' method in the product. If it does # not exist, then this is an old product that has never been # updated. In that case, we will analyze the product and # build up enough information to do initialization manually. initmethod = pgetattr(product, 'initialize', None) if initmethod is not None: initmethod(context) # Support old-style product metadata. Older products may # define attributes to name their permissions, meta_types, # constructors, etc. permissions = {} new_permissions = {} if pgetattr(product, '__ac_permissions__', None) is not None: warn( '__init__.py of %s has a long deprecated ' '\'__ac_permissions__\' attribute. ' '\'__ac_permissions__\' will be ignored by ' 'install_product in Zope 2.11. Please use registerClass ' 'instead.' % product.__name__, DeprecationWarning) for p in pgetattr(product, '__ac_permissions__', ()): permission, names, default = (tuple(p) + ('Manager', ))[:3] if names: for name in names: permissions[name] = permission elif not folder_permissions.has_key(permission): new_permissions[permission] = () if pgetattr(product, 'meta_types', None) is not None: warn( '__init__.py of %s has a long deprecated \'meta_types\' ' 'attribute. \'meta_types\' will be ignored by ' 'install_product in Zope 2.11. Please use registerClass ' 'instead.' % product.__name__, DeprecationWarning) for meta_type in pgetattr(product, 'meta_types', ()): # Modern product initialization via a ProductContext # adds 'product' and 'permission' keys to the meta_type # mapping. We have to add these here for old products. pname = permissions.get(meta_type['action'], None) if pname is not None: meta_type['permission'] = pname meta_type['product'] = productObject.id meta_type['visibility'] = 'Global' meta_types.append(meta_type) if pgetattr(product, 'methods', None) is not None: warn( "__init__.py of %s has a long deprecated 'methods' " "attribute. 'methods' support might be removed in Zope " "2.11 or a later feature release. Please use the " "'legacy' argument of registerClass instead if the " "methods are constructors. Or refactor the product " "using adapters." % product.__name__, DeprecationWarning) for name, method in pgetattr(product, 'methods', {}).items(): if not hasattr(Folder.Folder, name): setattr(Folder.Folder, name, method) if name[-9:] != '__roles__': # not Just setting roles if (permissions.has_key(name) and not folder_permissions.has_key( permissions[name])): permission = permissions[name] if new_permissions.has_key(permission): new_permissions[permission].append(name) else: new_permissions[permission] = [name] if new_permissions: new_permissions = new_permissions.items() for permission, names in new_permissions: folder_permissions[permission] = names new_permissions.sort() Folder.Folder.__ac_permissions__ = tuple( list(Folder.Folder.__ac_permissions__) + new_permissions) if not doInstall(): transaction.abort() else: transaction.get().note('Installed product ' + product_name) transaction.commit() except: if log_exc: LOG.error('Couldn\'t install %s' % product_name, exc_info=sys.exc_info()) transaction.abort() if raise_exc: raise
def install_product(app, product_dir, product_name, meta_types, folder_permissions, raise_exc=0, log_exc=1): 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) # 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_ # 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) # Look for an 'initialize' method in the product. initmethod = pgetattr(product, 'initialize', None) if initmethod is not None: initmethod(context) if do_install: transaction.get().note('Installed product ' + product_name) transaction.commit() 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 create_product_object(self): """ Create a persistent object in the ControlPanel.Products area representing a product packaged as an egg and return it """ products = self.app.Control_Panel.Products fver = '' packagename = self.package.__name__ productname = self.productname ie = getattr(self.package, '__import_error__', None) # Retrieve version number from any suitable version.txt for fname in ('version.txt', 'VERSION.txt', 'VERSION.TXT'): if pkg_resources.resource_exists(packagename, fname): fver = pkg_resources.resource_string(packagename, fname).strip() break old = None if ihasattr(products, productname): old = getattr(products, productname) if ihasattr(old, 'version') and old.version == fver: old_ie = getattr(old, 'import_error_', None) if old_ie == ie: # Version hasn't changed. Don't reinitialize. return old f = fver and ("(%s)" % fver) product = EggProduct( productname, 'Installed egg product %s %s from %s' % (productname, f, self.eggname), packagename) if old is not None: self.app._manage_remove_product_meta_type(product) products._delObject(productname) for id, v in old.objectItems(): try: product._setObject(id, v) except: zLOG.LOG('EggProductContext Initialization', zLOG.INFO, ('Error when cleaning old persistent data from ' 'Control Panel for %s.%s' % (productname, id)), error=sys.exc_info()) products._setObject(productname, product) product.icon = 'misc_/Basket/icon_egg.gif' product.version = fver product.home = str(self.package.__path__) product.manage_options = (Folder.manage_options[0],) + \ tuple(Folder.manage_options[2:]) product._distribution = None product.manage_distribution = None product.thisIsAnInstalledProduct = 1 if ie: product.import_error_ = ie product.title = 'Broken product %s' % productname product.icon = 'p_/BrokenProduct_icon' product.manage_options = ( {'label':'Traceback', 'action':'manage_traceback'}, ) for fname in ('README.txt', 'README.TXT', 'readme.txt'): if pkg_resources.resource_exists(packagename, fname): product.manage_options = product.manage_options+( {'label':'README', 'action':'manage_readme'}, ) break if not doInstall(): transaction.abort() return product # Give the ZClass fixup code in Application Globals.__disk_product_installed__ = 1 product.name = productname return product