def update(self):
        form = self.request.form
        self.settings = getUtility(IRegistry).forInterface(
            IThemeSettings, False)
        gallerysettings = getUtility(IRegistry).forInterface(
            IThemeGallerySettingsSchema, False)

        url = gallerysettings.tgserver_url
        if not url.endswith('/'):
            url +='/'
        self.base_url = '%s__rest__/cms/content:themes' % url
        self.api = '%s__rest__/cms/applications' % url
        if 'form.button.install' in form:
            theme = form.get('theme_uuid', None)

            if theme is not None:
                tfile = self.loadTheme(theme)
                try:
                    themeZip = zipfile.ZipFile(tfile)
                except (zipfile.BadZipfile, zipfile.LargeZipFile,):
                    logger.exception("Could not read zip file")
                    self.error = u"The uploaded file is not a valid Zip archive"
                    return

                if themeZip:
                    try:
                        themeData = extractThemeInfo(themeZip)
                    except (ValueError, KeyError,), e:
                        logger.warn(str(e))
                        self.error = u"The uploaded file does not contain a valid theme archive."

                    else:
                        themeContainer=getOrCreatePersistentResourceDirectory()
                        themeExists = themeData.__name__ in themeContainer

                        if themeExists:
                            del themeContainer[themeData.__name__]

                        themeContainer.importZip(themeZip)
                        themeDirectory = queryResourceDirectory(
                            THEME_RESOURCE_NAME, themeData.__name__)
                        if themeDirectory is not None:
                            plugins = getPlugins()
                            pluginSettings = getPluginSettings(
                                themeDirectory, plugins)
                            if pluginSettings is not None:
                                for name, plugin in plugins:
                                    plugin.onCreated(
                                        themeData.__name__,
                                        pluginSettings[name],
                                        pluginSettings)

                        applyTheme(themeData)
                        self.settings.enabled = True

                        IStatusMessage(self.request).add(
                            "Theme has been installed.")
Example #2
0
def onStartup(event):
    """Call onDiscovery() on each plugin for each theme on startup
    """
    plugins = getPlugins()

    for themeDirectory in iterDirectoriesOfType(THEME_RESOURCE_NAME):
        pluginSettings = getPluginSettings(themeDirectory, plugins)

        for name, plugin in plugins:
            plugin.onDiscovery(themeDirectory.__name__, pluginSettings[name], pluginSettings)
Example #3
0
def onStartup(event):
    """Call onDiscovery() on each plugin for each theme on startup
    """
    plugins = getPlugins()

    for themeDirectory in iterDirectoriesOfType(THEME_RESOURCE_NAME):
        pluginSettings = getPluginSettings(themeDirectory, plugins)

        for name, plugin in plugins:
            plugin.onDiscovery(themeDirectory.__name__, pluginSettings[name],
                               pluginSettings)
Example #4
0
def applyTheme(theme):
    """Apply an ITheme
    """

    settings = getUtility(IRegistry).forInterface(IThemeSettings, False)

    plugins = None
    themeDirectory = None
    pluginSettings = None
    currentTheme = getCurrentTheme()

    if currentTheme is not None:
        themeDirectory = queryResourceDirectory(
            THEME_RESOURCE_NAME, currentTheme)
        if themeDirectory is not None:
            plugins = getPlugins()
            pluginSettings = getPluginSettings(themeDirectory, plugins)

    if theme is None:

        settings.currentTheme = None
        settings.rules = None
        settings.absolutePrefix = None
        settings.parameterExpressions = {}
        settings.doctype = ""

        if pluginSettings is not None:
            for name, plugin in plugins:
                plugin.onDisabled(currentTheme, pluginSettings[name],
                                  pluginSettings)

    else:

        if isinstance(theme.rules, str):
            theme.rules = theme.rules.decode('utf-8')

        if isinstance(theme.absolutePrefix, str):
            theme.absolutePrefix = theme.absolutePrefix.decode('utf-8')

        if isinstance(theme.__name__, str):
            theme.__name__ = theme.__name__.decode('utf-8')

        settings.currentTheme = theme.__name__
        settings.rules = theme.rules
        settings.absolutePrefix = theme.absolutePrefix
        settings.parameterExpressions = theme.parameterExpressions
        settings.doctype = theme.doctype

        if pluginSettings is not None:
            for name, plugin in plugins:
                plugin.onDisabled(currentTheme, pluginSettings[name],
                                  pluginSettings)
                plugin.onEnabled(theme, pluginSettings[name], pluginSettings)
        notify(ThemeAppliedEvent(theme))
Example #5
0
def applyTheme(theme):
    """Apply an ITheme
    """

    settings = getUtility(IRegistry).forInterface(IThemeSettings, False)

    plugins = None
    themeDirectory = None
    pluginSettings = None
    currentTheme = getCurrentTheme()

    if currentTheme is not None:
        themeDirectory = queryResourceDirectory(
            THEME_RESOURCE_NAME, currentTheme)
        if themeDirectory is not None:
            plugins = getPlugins()
            pluginSettings = getPluginSettings(themeDirectory, plugins)

    if theme is None:

        settings.currentTheme = None
        settings.rules = None
        settings.absolutePrefix = None
        settings.parameterExpressions = {}
        settings.doctype = ""

        if pluginSettings is not None:
            for name, plugin in plugins:
                plugin.onDisabled(currentTheme, pluginSettings[name],
                                  pluginSettings)

    else:

        if isinstance(theme.rules, str):
            theme.rules = theme.rules.decode('utf-8')

        if isinstance(theme.absolutePrefix, str):
            theme.absolutePrefix = theme.absolutePrefix.decode('utf-8')

        if isinstance(theme.__name__, str):
            theme.__name__ = theme.__name__.decode('utf-8')

        settings.currentTheme = theme.__name__
        settings.rules = theme.rules
        settings.absolutePrefix = theme.absolutePrefix
        settings.parameterExpressions = theme.parameterExpressions
        settings.doctype = theme.doctype

        if pluginSettings is not None:
            for name, plugin in plugins:
                plugin.onDisabled(currentTheme, pluginSettings[name],
                                  pluginSettings)
                plugin.onEnabled(theme, pluginSettings[name], pluginSettings)
Example #6
0
def applyTheme(theme):
    """Apply an ITheme
    """

    toadapt = (getSite(), getRequest())
    settings = getMultiAdapter(toadapt, IThemeSettings)

    plugins = None
    themeDirectory = None
    pluginSettings = None
    currentTheme = getCurrentTheme()

    if currentTheme is not None:
        themeDirectory = queryResourceDirectory(THEME_RESOURCE_NAME, currentTheme)
        if themeDirectory is not None:
            plugins = getPlugins()
            pluginSettings = getPluginSettings(themeDirectory, plugins)

    if theme is None:

        settings.currentTheme = None
        settings.rules = None
        settings.absolutePrefix = None
        settings.parameterExpressions = {}
        settings.doctype = ""

        if pluginSettings is not None:
            for name, plugin in plugins:
                plugin.onDisabled(currentTheme, pluginSettings[name], pluginSettings)

    else:

        if isinstance(theme.rules, str):
            theme.rules = theme.rules.decode("utf-8")

        if isinstance(theme.absolutePrefix, str):
            theme.absolutePrefix = theme.absolutePrefix.decode("utf-8")

        if isinstance(theme.__name__, str):
            theme.__name__ = theme.__name__.decode("utf-8")

        settings.currentTheme = theme.__name__
        settings.rules = theme.rules
        settings.absolutePrefix = theme.absolutePrefix
        settings.parameterExpressions = theme.parameterExpressions
        settings.doctype = theme.doctype

        if pluginSettings is not None:
            for name, plugin in plugins:
                plugin.onDisabled(currentTheme, pluginSettings[name], pluginSettings)
                plugin.onEnabled(theme, pluginSettings[name], pluginSettings)
def getPluginSettings(themeDirectory, plugins=None):
    """Given an IResourceDirectory for a theme, return the settings for the
    given list of plugins (or all plugins, if not given) provided as a list
    of (name, plugin) pairs.

    Returns a dict of dicts, with the outer dict having plugin names as keys
    and containing plugins settings (key/value pairs) as values.
    """

    if plugins is None:
        plugins = getPlugins()

    # noinspection PyPep8Naming
    manifestContents = {}

    if themeDirectory.isFile(MANIFEST_FILENAME):
        parser = ConfigParser()
        fp = themeDirectory.openFile(MANIFEST_FILENAME)

        try:
            if six.PY2:
                parser.readfp(fp)
            else:
                parser.read_string(fp.read().decode())
            for section in parser.sections():
                manifestContents[section] = {}

                for name, value in parser.items(section):
                    manifestContents[section][name] = value

        finally:
            try:
                fp.close()
            except AttributeError:
                pass

    pluginSettings = {}
    for name, plugin in plugins:
        pluginSettings[name] = manifestContents.get(
            "%s:%s" % (THEME_RESOURCE_NAME, name), {})  # noqa

    return pluginSettings
Example #8
0
def onRequest(object, event):
    """Call onRequest() on each plugin for the eanbled theme on each request
    """

    request = event.request

    if not isThemeEnabled(request):
        return

    theme = getCurrentTheme()
    if theme is None:
        return

    themeDirectory = queryResourceDirectory(THEME_RESOURCE_NAME, theme)
    if themeDirectory is None:
        return

    plugins = getPlugins()
    pluginSettings = getPluginSettings(themeDirectory, plugins)

    for name, plugin in plugins:
        plugin.onRequest(request, theme, pluginSettings[name], pluginSettings)
Example #9
0
def onRequest(object, event):
    """Call onRequest() on each plugin for the eanbled theme on each request
    """

    request = event.request

    if not isThemeEnabled(request):
        return

    theme = getCurrentTheme()
    if theme is None:
        return

    themeDirectory = queryResourceDirectory(THEME_RESOURCE_NAME, theme)
    if themeDirectory is None:
        return

    plugins = getPlugins()
    pluginSettings = getPluginSettings(themeDirectory, plugins)

    for name, plugin in plugins:
        plugin.onRequest(request, theme, pluginSettings[name], pluginSettings)
def getPluginSettings(themeDirectory, plugins=None):
    """Given an IResourceDirectory for a theme, return the settings for the
    given list of plugins (or all plugins, if not given) provided as a list
    of (name, plugin) pairs.

    Returns a dict of dicts, with the outer dict having plugin names as keys
    and containing plugins settings (key/value pairs) as values.
    """

    if plugins is None:
        plugins = getPlugins()

    # noinspection PyPep8Naming
    manifestContents = {}

    if themeDirectory.isFile(MANIFEST_FILENAME):
        parser = SafeConfigParser()
        fp = themeDirectory.openFile(MANIFEST_FILENAME)

        try:
            parser.readfp(fp)
            for section in parser.sections():
                manifestContents[section] = {}

                for name, value in parser.items(section):
                    manifestContents[section][name] = value

        finally:
            try:
                fp.close()
            except AttributeError:
                pass

    pluginSettings = {}
    for name, plugin in plugins:
        pluginSettings[name] = manifestContents.get("%s:%s" % (THEME_RESOURCE_NAME, name), {})  # noqa

    return pluginSettings
    def update(self):
        form = self.request.form
        self.settings = getUtility(IRegistry).forInterface(
            IThemeSettings, False)
        gallerysettings = getUtility(IRegistry).forInterface(
            IThemeGallerySettingsSchema, False)

        url = gallerysettings.tgserver_url
        if not url.endswith('/'):
            url += '/'
        self.base_url = '%s__rest__/cms/content:themes' % url
        self.api = '%s__rest__/cms/applications' % url
        if 'form.button.install' in form:
            theme = form.get('theme_uuid', None)

            if theme is not None:
                tfile = self.loadTheme(theme)
                try:
                    themeZip = zipfile.ZipFile(tfile)
                except (
                        zipfile.BadZipfile,
                        zipfile.LargeZipFile,
                ):
                    logger.exception("Could not read zip file")
                    self.error = u"The uploaded file is not a valid Zip archive"
                    return

                if themeZip:
                    try:
                        themeData = extractThemeInfo(themeZip)
                    except (
                            ValueError,
                            KeyError,
                    ), e:
                        logger.warn(str(e))
                        self.error = u"The uploaded file does not contain a valid theme archive."

                    else:
                        themeContainer = getOrCreatePersistentResourceDirectory(
                        )
                        themeExists = themeData.__name__ in themeContainer

                        if themeExists:
                            del themeContainer[themeData.__name__]

                        themeContainer.importZip(themeZip)
                        themeDirectory = queryResourceDirectory(
                            THEME_RESOURCE_NAME, themeData.__name__)
                        if themeDirectory is not None:
                            plugins = getPlugins()
                            pluginSettings = getPluginSettings(
                                themeDirectory, plugins)
                            if pluginSettings is not None:
                                for name, plugin in plugins:
                                    plugin.onCreated(themeData.__name__,
                                                     pluginSettings[name],
                                                     pluginSettings)

                        applyTheme(themeData)
                        self.settings.enabled = True

                        IStatusMessage(
                            self.request).add("Theme has been installed.")
Example #12
0
    def update(self):
        # XXX: complexity too high: refactoring needed
        processInputs(self.request)
        self._setup()
        self.errors = {}
        form = self.request.form

        if 'form.button.Cancel' in form:
            IStatusMessage(self.request).add(_(u"Changes cancelled"))
            self.redirect("{0}/@@overview-controlpanel".format(self.site_url))
            return False

        if 'form.button.Enable' in form:
            self.authorize()

            themeSelection = form.get('themeName', None)

            if themeSelection:
                themeData = self.getThemeData(
                    self.availableThemes,
                    themeSelection
                )
                applyTheme(themeData)
                self.theme_settings.enabled = True

            IStatusMessage(
                self.request
            ).add(
                _(
                    u"Theme enabled. Note that this control panel page is "
                    u"never themed."
                )
            )
            self._setup()
            return True

        if 'form.button.InvalidateCache' in form:
            self.authorize()
            policy = theming_policy()
            policy.invalidateCache()
            return True

        if 'form.button.Disable' in form:
            self.authorize()

            applyTheme(None)
            self.theme_settings.enabled = False

            IStatusMessage(self.request).add(_(u"Theme disabled."))
            self._setup()
            return True

        if 'form.button.AdvancedSave' in form:
            self.authorize()

            self.theme_settings.readNetwork = form.get('readNetwork', False)

            themeEnabled = form.get('themeEnabled', False)
            rules = form.get('rules', None)
            prefix = form.get('absolutePrefix', None)
            doctype = str(form.get('doctype', ""))

            hostnameBlacklist = form.get('hostnameBlacklist', [])

            parameterExpressions = {}
            parameterExpressionsList = form.get('parameterExpressions', [])

            for line in parameterExpressionsList:
                try:
                    name, expression = line.split('=', 1)
                    name = str(name.strip())
                    expression = str(expression.strip())
                    parameterExpressions[name] = expression
                except ValueError:
                    message = _(
                        'error_invalid_parameter_expressions',
                        default=u"Please ensure you enter one expression per "
                                u"line, in the format <name> = <expression>."
                    )
                    self.errors['parameterExpressions'] = message

            themeBase = form.get('themeBase', None)
            markSpecialLinks = form.get('markSpecialLinks', None)
            extLinksOpenInNewWindow = form.get('extLinksOpenInNewWindow', None)

            if not self.errors:
                # Trigger onDisabled() on plugins if theme was active
                # previously and rules were changed
                if self.theme_settings.rules != rules:
                    applyTheme(None)

                self.theme_settings.enabled = themeEnabled
                self.theme_settings.rules = rules
                self.theme_settings.absolutePrefix = prefix
                self.theme_settings.parameterExpressions = parameterExpressions
                self.theme_settings.hostnameBlacklist = hostnameBlacklist
                self.theme_settings.doctype = doctype

                # Theme base settings
                if themeBase is not None:
                    if six.PY2:
                        themeBase = themeBase.encode('utf-8')
                    self.pskin.default_skin = themeBase
                if markSpecialLinks is not None:
                    self.mark_special_links = markSpecialLinks
                if extLinksOpenInNewWindow is not None:
                    self.ext_links_open_new_window = extLinksOpenInNewWindow

                IStatusMessage(self.request).add(_(u"Changes saved"))
                self._setup()
                return True
            else:
                IStatusMessage(self.request).add(
                    _(u"There were errors"), 'error'
                )
                self.redirectToFieldset('advanced')
                return False

        if 'form.button.Import' in form:
            self.authorize()

            enableNewTheme = form.get('enableNewTheme', False)
            replaceExisting = form.get('replaceExisting', False)
            themeArchive = form.get('themeArchive', None)

            themeZip = None
            performImport = False

            try:
                themeZip = zipfile.ZipFile(themeArchive)
            except (zipfile.BadZipfile, zipfile.LargeZipFile):
                logger.exception("Could not read zip file")
                self.errors['themeArchive'] = _(
                    'error_invalid_zip',
                    default=u"The uploaded file is not a valid Zip archive"
                )

            if themeZip:

                try:
                    themeData = extractThemeInfo(themeZip, checkRules=False)
                except (ValueError, KeyError) as e:
                    logger.warn(str(e))
                    self.errors['themeArchive'] = _(
                        'error_no_rules_file',
                        u"The uploaded file does not contain a valid theme "
                        u"archive."
                    )
                else:

                    themeContainer = getOrCreatePersistentResourceDirectory()
                    themeExists = themeData.__name__ in themeContainer

                    if themeExists:
                        if not replaceExisting:
                            self.errors['themeArchive'] = _(
                                'error_already_installed',
                                u"This theme is already installed. Select "
                                u"'Replace existing theme' and re-upload to "
                                u"replace it."
                            )
                        else:
                            del themeContainer[themeData.__name__]
                            performImport = True
                    else:
                        performImport = True

            if performImport:
                themeContainer.importZip(themeZip)

                themeDirectory = queryResourceDirectory(
                    THEME_RESOURCE_NAME,
                    themeData.__name__
                )
                if themeDirectory is not None:
                    # If we don't have a rules file, use the template
                    if themeData.rules == u"/++{0:s}++{1:s}/{2:s}".format(
                        THEME_RESOURCE_NAME,
                        themeData.__name__,
                        RULE_FILENAME,
                    ) and not themeDirectory.isFile(RULE_FILENAME):
                        templateThemeDirectory = queryResourceDirectory(
                            THEME_RESOURCE_NAME,
                            TEMPLATE_THEME
                        )
                        themeDirectory.writeFile(
                            RULE_FILENAME,
                            templateThemeDirectory.readFile(RULE_FILENAME)
                        )

                        if not themeDirectory.isFile(DEFAULT_THEME_FILENAME):
                            IStatusMessage(self.request).add(
                                _(
                                    u"A boilerplate rules.xml was added to "
                                    u"your theme, but no index.html file "
                                    u"found. Update rules.xml to reference "
                                    u"the current theme file."
                                ),
                                'warning',
                            )

                    plugins = getPlugins()
                    pluginSettings = getPluginSettings(themeDirectory, plugins)
                    if pluginSettings is not None:
                        for name, plugin in plugins:
                            plugin.onCreated(
                                themeData.__name__,
                                pluginSettings[name],
                                pluginSettings
                            )

                if enableNewTheme:
                    applyTheme(themeData)
                    self.theme_settings.enabled = True

            if not self.errors:
                self.redirect(
                    "{0}/++theme++{1}/@@theming-controlpanel-mapper".format(
                        self.site_url,
                        themeData.__name__
                    )
                )
                return False
            else:
                IStatusMessage(self.request).add(
                    _(u"There were errors"),
                    "error"
                )

                self.renderOverlay('upload')
                return True

        if 'form.button.CreateTheme' in form:
            self.authorize()

            title = form.get('title')
            description = form.get('description') or ''
            baseOn = form.get('baseOn', TEMPLATE_THEME)
            enableImmediately = form.get('enableImmediately', True)

            if not title:
                self.errors['title'] = _(u"Title is required")

                IStatusMessage(self.request).add(
                    _(u"There were errors"),
                    'error'
                )

                self.renderOverlay('new-theme')
                return True

            else:

                if any(x.__name__ == title for x in getZODBThemes()):
                    self.errors['title'] = _(u"Duplicate title")

                    IStatusMessage(self.request).add(
                        _(u"This title is already in use"),
                        'error'
                    )

                    return True

                name = createThemeFromTemplate(title, description, baseOn)
                self._setup()

                if enableImmediately:
                    themeData = self.getThemeData(self.availableThemes, name)
                    applyTheme(themeData)
                    self.theme_settings.enabled = True

                self.redirect(
                    "{0}/++theme++{1}/@@theming-controlpanel-mapper".format(
                        self.site_url,
                        name
                    )
                )
                return False

        if 'form.button.DeleteSelected' in form:
            self.authorize()

            toDelete = form.get('themes', [])
            themeDirectory = getOrCreatePersistentResourceDirectory()

            for theme in toDelete:
                del themeDirectory[theme]

            IStatusMessage(self.request).add(_(u"Theme deleted"), 'info')

            self._setup()
            return True

        return True
Example #13
0
    def update(self):
        processInputs(self.request)
        self._setup()
        self.errors = {}
        submitted = False
        form = self.request.form

        if 'form.button.Cancel' in form:
            self.redirect(_(u"Changes canceled."))
            return False

        if 'form.button.BasicSave' in form:
            self.authorize()
            submitted = True

            self.settings.enabled = form.get('enabled', False)
            themeSelection = form.get('selectedTheme', None)

            if themeSelection != "_other_":
                themeData = self.getThemeData(self.availableThemes, themeSelection)
                applyTheme(themeData)

        if 'form.button.AdvancedSave' in form:
            self.authorize()
            submitted = True

            self.settings.readNetwork = form.get('readNetwork', False)

            rules = form.get('rules', None)
            prefix = form.get('absolutePrefix', None)
            doctype = str(form.get('doctype', ""))

            hostnameBlacklist = form.get('hostnameBlacklist', [])

            parameterExpressions = {}
            parameterExpressionsList = form.get('parameterExpressions', [])

            for line in parameterExpressionsList:
                try:
                    name, expression = line.split('=', 1)
                    parameterExpressions[str(name.strip())] = str(expression.strip())
                except ValueError:
                    self.errors['parameterExpressions'] = _('error_invalid_parameter_expressions',
                        default=u"Please ensure you enter one expression per line, in the format <name> = <expression>."
                    )

            if not self.errors:

                # Trigger onDisabled() on plugins if theme was active
                # previously and rules were changed

                if self.settings.rules != rules:
                    applyTheme(None)

                self.settings.rules = rules
                self.settings.absolutePrefix = prefix
                self.settings.parameterExpressions = parameterExpressions
                self.settings.hostnameBlacklist = hostnameBlacklist
                self.settings.doctype = doctype

        if 'form.button.Import' in form:
            self.authorize()
            submitted = True

            enableNewTheme = form.get('enableNewTheme', False)
            replaceExisting = form.get('replaceExisting', False)
            themeArchive = form.get('themeArchive', None)

            themeZip = None
            performImport = False

            try:
                themeZip = zipfile.ZipFile(themeArchive)
            except (zipfile.BadZipfile, zipfile.LargeZipFile,):
                logger.exception("Could not read zip file")
                self.errors['themeArchive'] = _('error_invalid_zip',
                        default=u"The uploaded file is not a valid Zip archive"
                    )

            if themeZip:

                try:
                    themeData = extractThemeInfo(themeZip)
                except (ValueError, KeyError,), e:
                    logger.warn(str(e))
                    self.errors['themeArchive'] = _('error_no_rules_file',
                            u"The uploaded file does not contain a valid theme archive."
                        )
                else:

                    themeContainer = getOrCreatePersistentResourceDirectory()
                    themeExists = themeData.__name__ in themeContainer

                    if themeExists:
                        if not replaceExisting:
                            self.errors['themeArchive'] = _('error_already_installed',
                                    u"This theme is already installed. Select 'Replace existing theme' and re-upload to replace it."
                                )
                        else:
                            del themeContainer[themeData.__name__]
                            performImport = True
                    else:
                        performImport = True

            if performImport:
                themeContainer.importZip(themeZip)

                themeDirectory = queryResourceDirectory(THEME_RESOURCE_NAME, themeData.__name__)
                if themeDirectory is not None:
                    plugins = getPlugins()
                    pluginSettings = getPluginSettings(themeDirectory, plugins)
                    if pluginSettings is not None:
                        for name, plugin in plugins:
                            plugin.onCreated(themeData.__name__, pluginSettings[name], pluginSettings)

                if enableNewTheme:
                    applyTheme(themeData)
                    self.settings.enabled = True
    def update(self):
        # XXX: complexity too high: refactoring needed
        processInputs(self.request)
        self._setup()
        self.errors = {}
        form = self.request.form

        if 'form.button.Cancel' in form:
            IStatusMessage(self.request).add(_(u"Changes cancelled"))

            portalUrl = getToolByName(self.context, 'portal_url')()
            self.redirect("{0:s}/@@overview-controlpanel".format(portalUrl))

            return False

        if 'form.button.Enable' in form:
            self.authorize()

            themeSelection = form.get('themeName', None)

            if themeSelection:
                themeData = self.getThemeData(self.availableThemes,
                                              themeSelection)
                applyTheme(themeData)
                self.theme_settings.enabled = True

            IStatusMessage(self.request).add(
                _(u"Theme enabled. Note that this control panel page is "
                  u"never themed."))
            self._setup()
            return True

        if 'form.button.InvalidateCache' in form:
            self.authorize()
            policy = theming_policy()
            policy.invalidateCache()
            return True

        if 'form.button.Disable' in form:
            self.authorize()

            applyTheme(None)
            self.theme_settings.enabled = False

            IStatusMessage(self.request).add(_(u"Theme disabled."))
            self._setup()
            return True

        if 'form.button.AdvancedSave' in form:
            self.authorize()

            self.theme_settings.readNetwork = form.get('readNetwork', False)

            themeEnabled = form.get('themeEnabled', False)
            rules = form.get('rules', None)
            prefix = form.get('absolutePrefix', None)
            doctype = str(form.get('doctype', ""))

            hostnameBlacklist = form.get('hostnameBlacklist', [])

            parameterExpressions = {}
            parameterExpressionsList = form.get('parameterExpressions', [])

            for line in parameterExpressionsList:
                try:
                    name, expression = line.split('=', 1)
                    name = str(name.strip())
                    expression = str(expression.strip())
                    parameterExpressions[name] = expression
                except ValueError:
                    message = _(
                        'error_invalid_parameter_expressions',
                        default=u"Please ensure you enter one expression per "
                        u"line, in the format <name> = <expression>.")
                    self.errors['parameterExpressions'] = message

            themeBase = form.get('themeBase', None)
            markSpecialLinks = form.get('markSpecialLinks', None)
            extLinksOpenInNewWindow = form.get('extLinksOpenInNewWindow', None)

            if not self.errors:
                # Trigger onDisabled() on plugins if theme was active
                # previously and rules were changed
                if self.theme_settings.rules != rules:
                    applyTheme(None)

                self.theme_settings.enabled = themeEnabled
                self.theme_settings.rules = rules
                self.theme_settings.absolutePrefix = prefix
                self.theme_settings.parameterExpressions = parameterExpressions
                self.theme_settings.hostnameBlacklist = hostnameBlacklist
                self.theme_settings.doctype = doctype

                # Theme base settings
                if themeBase is not None:
                    self.pskin.default_skin = themeBase.encode('utf-8')
                if markSpecialLinks is not None:
                    self.mark_special_links = markSpecialLinks
                if extLinksOpenInNewWindow is not None:
                    self.ext_links_open_new_window = extLinksOpenInNewWindow

                IStatusMessage(self.request).add(_(u"Changes saved"))
                self._setup()
                return True
            else:
                IStatusMessage(self.request).add(_(u"There were errors"),
                                                 'error')
                self.redirectToFieldset('advanced')
                return False

        if 'form.button.Import' in form:
            self.authorize()

            enableNewTheme = form.get('enableNewTheme', False)
            replaceExisting = form.get('replaceExisting', False)
            themeArchive = form.get('themeArchive', None)

            themeZip = None
            performImport = False

            try:
                themeZip = zipfile.ZipFile(themeArchive)
            except (
                    zipfile.BadZipfile,
                    zipfile.LargeZipFile,
            ):
                logger.exception("Could not read zip file")
                self.errors['themeArchive'] = _(
                    'error_invalid_zip',
                    default=u"The uploaded file is not a valid Zip archive")

            if themeZip:

                try:
                    themeData = extractThemeInfo(themeZip, checkRules=False)
                except (
                        ValueError,
                        KeyError,
                ), e:
                    logger.warn(str(e))
                    self.errors['themeArchive'] = _(
                        'error_no_rules_file',
                        u"The uploaded file does not contain a valid theme "
                        u"archive.")
                else:

                    themeContainer = getOrCreatePersistentResourceDirectory()
                    themeExists = themeData.__name__ in themeContainer

                    if themeExists:
                        if not replaceExisting:
                            self.errors['themeArchive'] = _(
                                'error_already_installed',
                                u"This theme is already installed. Select "
                                u"'Replace existing theme' and re-upload to "
                                u"replace it.")
                        else:
                            del themeContainer[themeData.__name__]
                            performImport = True
                    else:
                        performImport = True

            if performImport:
                themeContainer.importZip(themeZip)

                themeDirectory = queryResourceDirectory(
                    THEME_RESOURCE_NAME, themeData.__name__)
                if themeDirectory is not None:
                    # If we don't have a rules file, use the template
                    if themeData.rules == u"/++{0:s}++{1:s}/{2:s}".format(
                            THEME_RESOURCE_NAME,
                            themeData.__name__,
                            RULE_FILENAME,
                    ) and not themeDirectory.isFile(RULE_FILENAME):
                        templateThemeDirectory = queryResourceDirectory(
                            THEME_RESOURCE_NAME, TEMPLATE_THEME)
                        themeDirectory.writeFile(
                            RULE_FILENAME,
                            templateThemeDirectory.readFile(RULE_FILENAME))

                        if not themeDirectory.isFile(DEFAULT_THEME_FILENAME):
                            IStatusMessage(self.request).add(
                                _(u"A boilerplate rules.xml was added to "
                                  u"your theme, but no index.html file "
                                  u"found. Update rules.xml to reference "
                                  u"the current theme file."),
                                'warning',
                            )

                    plugins = getPlugins()
                    pluginSettings = getPluginSettings(themeDirectory, plugins)
                    if pluginSettings is not None:
                        for name, plugin in plugins:
                            plugin.onCreated(themeData.__name__,
                                             pluginSettings[name],
                                             pluginSettings)

                if enableNewTheme:
                    applyTheme(themeData)
                    self.theme_settings.enabled = True

            if not self.errors:
                portalUrl = getToolByName(self.context, 'portal_url')()
                self.redirect(
                    "{0}/++theme++{1}/@@theming-controlpanel-mapper".format(
                        portalUrl, themeData.__name__))
                return False
            else:
                IStatusMessage(self.request).add(_(u"There were errors"),
                                                 "error")

                self.renderOverlay('upload')
                return True
Example #15
0
def applyTheme(theme):
    """Apply an ITheme
    """
    # on write, force using default policy
    policy = IThemingPolicy(NoRequest())
    settings = policy.getSettings()

    plugins = None
    themeDirectory = None
    pluginSettings = None
    currentTheme = policy.getCurrentTheme()

    if currentTheme is not None:
        themeDirectory = queryResourceDirectory(THEME_RESOURCE_NAME,
                                                currentTheme)
        if themeDirectory is not None:
            plugins = getPlugins()
            pluginSettings = getPluginSettings(themeDirectory, plugins)

    if theme is None:

        settings.currentTheme = None
        settings.rules = None
        settings.absolutePrefix = None
        settings.parameterExpressions = {}
        settings.doctype = ""

        if pluginSettings is not None:
            for name, plugin in plugins:
                plugin.onDisabled(currentTheme, pluginSettings[name],
                                  pluginSettings)

    else:

        if isinstance(theme.rules, str):
            theme.rules = theme.rules.decode('utf-8')

        if isinstance(theme.absolutePrefix, str):
            theme.absolutePrefix = theme.absolutePrefix.decode('utf-8')

        if isinstance(theme.__name__, str):
            theme.__name__ = theme.__name__.decode('utf-8')

        settings.currentTheme = theme.__name__
        settings.rules = theme.rules
        settings.absolutePrefix = theme.absolutePrefix
        settings.parameterExpressions = theme.parameterExpressions
        settings.doctype = theme.doctype

        if pluginSettings is not None:
            for name, plugin in plugins:
                plugin.onDisabled(currentTheme, pluginSettings[name],
                                  pluginSettings)

        currentTheme = settings.currentTheme
        themeDirectory = queryResourceDirectory(THEME_RESOURCE_NAME,
                                                currentTheme)
        if themeDirectory is not None:
            plugins = getPlugins()
            pluginSettings = getPluginSettings(themeDirectory, plugins)

        if pluginSettings is not None:
            for name, plugin in plugins:
                plugin.onEnabled(currentTheme, pluginSettings[name],
                                 pluginSettings)
        policy.set_theme(currentTheme, theme)
Example #16
0
def applyTheme(theme):
    """Apply an ITheme
    """
    # on write, force using default policy
    policy = IThemingPolicy(NoRequest())
    settings = policy.getSettings()

    plugins = None
    themeDirectory = None
    pluginSettings = None
    currentTheme = policy.getCurrentTheme()

    if currentTheme is not None:
        themeDirectory = queryResourceDirectory(
            THEME_RESOURCE_NAME, currentTheme)
        if themeDirectory is not None:
            plugins = getPlugins()
            pluginSettings = getPluginSettings(themeDirectory, plugins)

    if theme is None:

        settings.currentTheme = None
        settings.rules = None
        settings.absolutePrefix = None
        settings.parameterExpressions = {}
        settings.doctype = ""

        if pluginSettings is not None:
            for name, plugin in plugins:
                plugin.onDisabled(currentTheme, pluginSettings[name],
                                  pluginSettings)

    else:

        if not isinstance(theme.rules, six.text_type):
            theme.rules = theme.rules.decode('utf-8')

        if not isinstance(theme.absolutePrefix, six.text_type):
            theme.absolutePrefix = theme.absolutePrefix.decode('utf-8')

        if not isinstance(theme.__name__, six.text_type):
            theme.__name__ = theme.__name__.decode('utf-8')

        settings.currentTheme = theme.__name__
        settings.rules = theme.rules
        settings.absolutePrefix = theme.absolutePrefix
        settings.parameterExpressions = theme.parameterExpressions
        settings.doctype = theme.doctype

        if pluginSettings is not None:
            for name, plugin in plugins:
                plugin.onDisabled(currentTheme, pluginSettings[name],
                                  pluginSettings)

        currentTheme = settings.currentTheme
        themeDirectory = queryResourceDirectory(
            THEME_RESOURCE_NAME, currentTheme)
        if themeDirectory is not None:
            plugins = getPlugins()
            pluginSettings = getPluginSettings(themeDirectory, plugins)

        if pluginSettings is not None:
            for name, plugin in plugins:
                plugin.onEnabled(currentTheme, pluginSettings[name],
                                 pluginSettings)
        policy.set_theme(currentTheme, theme)
Example #17
0
    def update(self):
        processInputs(self.request)
        self._setup()
        self.errors = {}
        form = self.request.form

        if 'form.button.Cancel' in form:
            IStatusMessage(self.request).add(_(u"Changes cancelled"))

            portalUrl = getToolByName(self.context, 'portal_url')()
            self.redirect("%s/plone_control_panel" % portalUrl)

            return False

        if 'form.button.Enable' in form:
            self.authorize()

            themeSelection = form.get('themeName', None)

            if themeSelection:
                themeData = self.getThemeData(self.availableThemes, themeSelection)
                applyTheme(themeData)
                self.settings.enabled = True

            IStatusMessage(self.request).add(_(u"Theme enabled. Note that this control panel page is never themed."))
            self._setup()
            return True

        if 'form.button.Disable' in form:
            self.authorize()

            applyTheme(None)
            self.settings.enabled = False

            IStatusMessage(self.request).add(_(u"Theme disabled."))
            self._setup()
            return True

        if 'form.button.AdvancedSave' in form:
            self.authorize()

            self.settings.readNetwork = form.get('readNetwork', False)

            themeEnabled = form.get('themeEnabled', False)
            rules = form.get('rules', None)
            prefix = form.get('absolutePrefix', None)
            doctype = str(form.get('doctype', ""))

            hostnameBlacklist = form.get('hostnameBlacklist', [])

            parameterExpressions = {}
            parameterExpressionsList = form.get('parameterExpressions', [])

            for line in parameterExpressionsList:
                try:
                    name, expression = line.split('=', 1)
                    parameterExpressions[str(name.strip())] = \
                                                    str(expression.strip())
                except ValueError:
                    self.errors['parameterExpressions'] = \
                                    _('error_invalid_parameter_expressions',
                        default=u"Please ensure you enter one "
                                u"expression per line, in the "
                                u"format <name> = <expression>."
                    )

            themeBase = form.get('themeBase', None)
            markSpecialLinks = form.get('markSpecialLinks', None)
            extLinksOpenInNewWindow = form.get('extLinksOpenInNewWindow', None)
            usePopups = form.get('usePopups', None)
            iconVisibility = form.get('iconVisibility', None)

            if not self.errors:

                # Trigger onDisabled() on plugins if theme was active
                # previously and rules were changed

                if self.settings.rules != rules:
                    applyTheme(None)

                self.settings.enabled = themeEnabled
                self.settings.rules = rules
                self.settings.absolutePrefix = prefix
                self.settings.parameterExpressions = parameterExpressions
                self.settings.hostnameBlacklist = hostnameBlacklist
                self.settings.doctype = doctype

                # Theme base settings

                if themeBase is not None:
                    self.skinsSettings.theme = themeBase.encode('utf-8')
                if markSpecialLinks is not None:
                    self.skinsSettings.mark_special_links = markSpecialLinks
                if extLinksOpenInNewWindow is not None:
                    self.skinsSettings.ext_links_open_new_window = extLinksOpenInNewWindow
                if usePopups is not None:
                    self.skinsSettings.use_popups = usePopups
                if iconVisibility is not None:
                    self.skinsSettings.icon_visibility = iconVisibility.encode('utf-8')

                IStatusMessage(self.request).add(_(u"Changes saved"))
                self._setup()
                return True
            else:
                IStatusMessage(self.request).add(_(u"There were errors"), 'error')
                self.redirectToFieldset('advanced')
                return False

        if 'form.button.Import' in form:
            self.authorize()

            enableNewTheme = form.get('enableNewTheme', False)
            replaceExisting = form.get('replaceExisting', False)
            themeArchive = form.get('themeArchive', None)

            themeZip = None
            performImport = False

            try:
                themeZip = zipfile.ZipFile(themeArchive)
            except (zipfile.BadZipfile, zipfile.LargeZipFile,):
                logger.exception("Could not read zip file")
                self.errors['themeArchive'] = _('error_invalid_zip',
                        default=u"The uploaded file is not a valid Zip archive"
                    )

            if themeZip:

                try:
                    themeData = extractThemeInfo(themeZip, checkRules=False)
                except (ValueError, KeyError,), e:
                    logger.warn(str(e))
                    self.errors['themeArchive'] = _('error_no_rules_file',
                            u"The uploaded file does not contain "
                            u"a valid theme archive."
                        )
                else:

                    themeContainer = getOrCreatePersistentResourceDirectory()
                    themeExists = themeData.__name__ in themeContainer

                    if themeExists:
                        if not replaceExisting:
                            self.errors['themeArchive'] = \
                                _('error_already_installed',
                                    u"This theme is already installed. "
                                    u"Select 'Replace existing theme' "
                                    u"and re-upload to replace it."
                                )
                        else:
                            del themeContainer[themeData.__name__]
                            performImport = True
                    else:
                        performImport = True

            if performImport:
                themeContainer.importZip(themeZip)

                themeDirectory = queryResourceDirectory(THEME_RESOURCE_NAME, themeData.__name__)
                if themeDirectory is not None:

                    # If we don't have a rules file, use the template
                    if themeData.rules == u"/++%s++%s/%s" % (THEME_RESOURCE_NAME, themeData.__name__, RULE_FILENAME,):
                        if not themeDirectory.isFile(RULE_FILENAME):
                            templateThemeDirectory = queryResourceDirectory(THEME_RESOURCE_NAME, TEMPLATE_THEME)
                            themeDirectory.writeFile(RULE_FILENAME, templateThemeDirectory.readFile(RULE_FILENAME))

                            if not themeDirectory.isFile(DEFAULT_THEME_FILENAME):
                                IStatusMessage(self.request).add(
                                        _(u"A boilerplate rules.xml was added to your theme, but no index.html file found. Update rules.xml to reference the current theme file."),
                                        'warning',
                                    )

                    plugins = getPlugins()
                    pluginSettings = getPluginSettings(themeDirectory, plugins)
                    if pluginSettings is not None:
                        for name, plugin in plugins:
                            plugin.onCreated(themeData.__name__,
                                             pluginSettings[name],
                                             pluginSettings)

                if enableNewTheme:
                    applyTheme(themeData)
                    self.settings.enabled = True

            if not self.errors:
                portalUrl = getToolByName(self.context, 'portal_url')()
                self.redirect(
                    "%s/++theme++%s/@@theming-controlpanel-mapper" % (
                        portalUrl, themeData.__name__,)
                    )
                return False
            else:
                IStatusMessage(self.request).add(
                        _(u"There were errors"), "error"
                    )

                self.renderOverlay('upload')
                return True