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, )
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)
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