Beispiel #1
0
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
Beispiel #2
0
    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 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("Zope", WARNING, '%s: %s' % (text, path))
            return
Beispiel #5
0
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()
Beispiel #6
0
    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()
Beispiel #7
0
    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()
Beispiel #8
0
    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
Beispiel #9
0
    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
Beispiel #10
0
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
Beispiel #11
0
    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
Beispiel #12
0
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
Beispiel #13
0
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
Beispiel #15
0
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
Beispiel #16
0
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
Beispiel #17
0
    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