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
    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
Exemple #3
0
class ThemingControlpanel(BrowserView):

    def __call__(self):
        ptool = getToolByName(self.context, 'portal_properties')
        self.props = ptool.site_properties
        self.pskin = getToolByName(self.context, 'portal_skins')

        if self.update():
            return self.index()
        return ''

    def _setup(self):
        self.settings = getUtility(IRegistry).forInterface(
            IThemeSettings,
            False
        )
        self.zodbThemes = getZODBThemes()
        self.availableThemes = getAvailableThemes()
        self.selectedTheme = self.getSelectedTheme(
            self.availableThemes,
            self.settings.rules
        )
        self.overlay = ''

        self.skinsVocabulary = getUtility(
            IVocabularyFactory,
            name='plone.app.vocabularies.Skins'
        )(
            self.context
        )

        # Set response header to make sure control panel is never themed
        self.request.response.setHeader('X-Theme-Disabled', '1')

    def redirect(self, url):
        self.request.response.redirect(url)

    def get_mark_special_links(self):
        msl = getattr(self.props, 'mark_special_links', False)
        if msl == 'true':
            return True
        return False

    def set_mark_special_links(self, value):
        if value:
            mark_special_links = 'true'
        else:
            mark_special_links = 'false'
        if self.props.hasProperty('mark_special_links'):
            self.props.manage_changeProperties(mark_special_links=mark_special_links)
        else:
            self.props.manage_addProperty(
                'mark_special_links', mark_special_links, 'string')

    mark_special_links = property(get_mark_special_links,
                                  set_mark_special_links)

    def get_ext_links_open_new_window(self):
        elonw = self.props.external_links_open_new_window
        if elonw == 'true':
            return True
        return False

    def set_ext_links_open_new_window(self, value):
        if value:
            self.props.manage_changeProperties(external_links_open_new_window='true')
        else:
            self.props.manage_changeProperties(external_links_open_new_window='false')

    ext_links_open_new_window = property(get_ext_links_open_new_window,
                                         set_ext_links_open_new_window)

    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}/plone_control_panel".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.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.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)
                    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.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.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.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

        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.settings.enabled = True

                portalUrl = getToolByName(self.context, 'portal_url')()
                self.redirect(
                    "{0}/++theme++{1}/@@theming-controlpanel-mapper".format(
                        portalUrl,
                        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
    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
Exemple #5
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