Ejemplo n.º 1
0
def handleProfileImportedEvent(event):
    if event.profile_id is None or not event.full_import:
        return

    context = event.tool

    # We need a request to scribble some data in
    request = getattr(context, "REQUEST", None)
    if request is None:
        return

    storage = IAnnotatable(request, None)
    if storage is None:
        return

    data = storage.get("Products.CMFQuickInstallerTool.Events", [])
    if event.profile_id not in data:
        return
    info = data[event.profile_id]

    qi = getToolByName(context, "portal_quickinstaller", None)
    if qi is None:
        return

    after = qi.snapshotPortal(aq_parent(context))

    settings = qi.deriveSettingsFromSnapshots(info["snapshot"], after)
    version = qi.getProductVersion(info["product"])
    qi.notifyInstalled(
        info["product"],
        locked=False,
        logmsg="Installed via setup tool",
        settings=settings,
        installedversion=version,
        status='installed',
        error=False,
    )
Ejemplo n.º 2
0
def handleBeforeProfileImportEvent(event):
    profile_id = event.profile_id
    if profile_id is None or not event.full_import:
        return

    if profile_id.startswith("profile-"):
        profile_id = profile_id[8:]
    context = event.tool

    # We need a request to scribble some data in
    request = getattr(context, "REQUEST", None)
    if request is None:
        return

    qi = getToolByName(context, "portal_quickinstaller", None)
    if qi is None:
        return

    product = findProductForProfile(context, profile_id, qi)
    if product is None:
        return

    snapshot = qi.snapshotPortal(aq_parent(context))

    storage = IAnnotatable(request, None)
    if storage is None:
        return

    installing = storage.get("Products.CMFQuickInstaller.Installing", [])
    if product in installing:
        return

    if "Products.CMFQuickInstallerTool.Events" in storage:
        data = storage["Products.CMFQuickInstallerTool.Events"]
    else:
        data = storage["Products.CMFQuickInstallerTool.Events"] = {}
    data[event.profile_id] = dict(product=product, snapshot=snapshot)
Ejemplo n.º 3
0
    def installProduct(self,
                       product_name,
                       locked=False,
                       hidden=False,
                       swallowExceptions=None,
                       reinstall=False,
                       forceProfile=False,
                       omitSnapshots=True,
                       profile=None,
                       blacklistedSteps=None):
        """Install a product by name
        """
        __traceback_info__ = (product_name, )

        if profile is not None:
            forceProfile = True

        if self.isProductInstalled(product_name):
            prod = self._getOb(product_name)
            msg = ('This product is already installed, '
                   'please uninstall before reinstalling it.')
            prod.log(msg)
            return msg

        portal = aq_parent(aq_inner(self))

        before = self.snapshotPortal(portal)

        if hasattr(self, "REQUEST"):
            reqstorage = IAnnotatable(self.REQUEST, None)
            if reqstorage is not None:
                installing = reqstorage.get(
                    "Products.CMFQUickInstaller.Installing", set())
                installing.add(product_name)
        else:
            reqstorage = None

        # XXX We can not use getToolByName since that returns a utility
        # without a RequestContainer. This breaks import steps that need
        # to run tools which request self.REQUEST.
        portal_setup = aq_get(portal, 'portal_setup', None, 1)
        status = None
        res = ''

        # Create a snapshot before installation
        before_id = portal_setup._mangleTimestampName('qi-before-%s' %
                                                      product_name)
        if not omitSnapshots:
            portal_setup.createSnapshot(before_id)

        install = False
        if not forceProfile:
            try:
                # Install via external method
                install = self.getInstallMethod(product_name).__of__(portal)
            except AttributeError:
                # No classic install method found
                pass

        if install and not forceProfile:
            try:
                res = install(portal, reinstall=reinstall)
            except TypeError:
                res = install(portal)
            status = 'installed'
        else:
            profiles = self.getInstallProfiles(product_name)
            if profiles:
                if profile is None:
                    profile = profiles[0]
                    if len(profiles) > 1:
                        logger.info(
                            'Multiple extension profiles found for product '
                            '%s. Used profile: %s' % (product_name, profile))

                portal_setup.runAllImportStepsFromProfile(
                    'profile-%s' % profile,
                    blacklisted_steps=blacklistedSteps,
                )
                status = 'installed'
            else:
                # No install method and no profile, log / abort?
                pass

        if reqstorage is not None:
            installing.remove(product_name)

        # Create a snapshot after installation
        after_id = portal_setup._mangleTimestampName('qi-after-%s' %
                                                     product_name)
        if not omitSnapshots:
            portal_setup.createSnapshot(after_id)

        if profile:
            # If installation was done via a profile, the settings were already
            # snapshotted in the IProfileImportedEvent handler, and we should
            # use those because the ones derived here include settings from
            # dependency profiles.
            settings = {}
        else:
            after = self.snapshotPortal(portal)
            settings = self.deriveSettingsFromSnapshots(before, after)

        rr_css = getToolByName(self, 'portal_css', None)
        if rr_css is not None:
            if ('resources_css' in settings
                    and len(settings['resources_css']) > 0):
                rr_css.cookResources()

        msg = str(res)
        version = self.getProductVersion(product_name)

        # add the product
        self.notifyInstalled(product_name,
                             settings=settings,
                             installedversion=version,
                             logmsg=res,
                             status=status,
                             error=False,
                             locked=locked,
                             hidden=hidden,
                             afterid=after_id,
                             beforeid=before_id)

        prod = getattr(self, product_name)
        afterInstall = prod.getAfterInstallMethod()
        if afterInstall is not None:
            afterInstall = afterInstall.__of__(portal)
            afterRes = afterInstall(portal, reinstall=reinstall, product=prod)
            if afterRes:
                res = res + '\n' + str(afterRes)
        return res