Skip to content

Instantly share code, notes, and snippets.

@jensens
Created June 19, 2018 06:24
Show Gist options
  • Save jensens/f000483da7413a0af51e67dafd996fd3 to your computer and use it in GitHub Desktop.
Save jensens/f000483da7413a0af51e67dafd996fd3 to your computer and use it in GitHub Desktop.
Plone Registry Exporter (parts only)
<configure
i18n_domain="kup.akivdb"
xmlns="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser"
xmlns:plone="http://namespaces.plone.org/plone">
<!-- ADMIN -->
<browser:page
class=".registryexporter.RegistryExporterView"
for="plone.app.layout.navigation.interfaces.INavigationRoot"
name="plone-export-registry"
permission="cmf.ManagePortal"
/>
</configure>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:metal="http://xml.zope.org/namespaces/metal"
xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:i18n="http://xml.zope.org/namespaces/i18n"
xml:lang="en" lang="en"
metal:use-macro="context/prefs_main_template/macros/master"
i18n:domain="plone">
<body>
<metal:main fill-slot="prefs_configlet_main">
<a href="${string:$portal_url/@@overview-controlpanel}"
id="setup-link"
i18n:translate="">
Site Setup
</a>
<h1 class="documentFirstHeading"
i18n:translate=""
metal:define-slot="heading">
Registry Exporter
</h1>
<div class="documentDescription" i18n:translate="">
Export parts of the registry based on the Interface/Prefix
</div>
<div id="content-core">
<h2>Interfaces</h2>
<ul>
<li tal:repeat="prefix python:view.interfaces()"><a href="${python:prefix[1]}">${python:prefix[0]}</a></li>
</ul>
<h2>Prefixes</h2>
<ul>
<li tal:repeat="prefix python:view.prefixes()"><a href="${python:prefix[1]}">${python:prefix[0]}</a></li>
</ul>
</div>
</metal:main>
</body>
</html>
# -*- coding: utf-8 -*-
from lxml import etree
from plone.registry.interfaces import IRegistry
from Products.Five import BrowserView
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
from zope.component import getUtility
def _sort_first_lower(key):
return key[0].lower()
class RegistryExporterView(BrowserView):
"""this view make sane exports of the registry.
Main goal is to export in a way, that the output can be reused as
best practive settings
"""
template = ViewPageTemplateFile("registryexporter.pt")
def __call__(self):
interface = self.request.form.get("interface", None)
name = self.request.form.get("name", None)
if not interface and not name:
return self.template()
return self.export(sinterface=interface, sname=name)
def interfaces(self):
prefixes = []
registry = getUtility(IRegistry)
baseurl = "{0}/@@plone-export-registry?interface=".format(
self.context.absolute_url()
)
for record in registry.records.values():
if record.interfaceName is None:
continue
name = record.interfaceName
url = "{0}{1}".format(baseurl, record.interfaceName)
pair = (name, url)
if pair not in prefixes:
prefixes.append(pair)
return sorted(prefixes, key=_sort_first_lower)
def prefixes(self):
prefixes = []
registry = getUtility(IRegistry)
baseurl = "{0}/@@plone-export-registry?".format(self.context.absolute_url())
for record in registry.records.values():
if record.interfaceName == record.__name__:
continue
def add_split(part):
url = "{0}name={1}".format(baseurl, part)
pair = (part, url)
if pair not in prefixes:
prefixes.append(pair)
if part.rfind("/") > part.rfind("."):
new_parts = part.rsplit("/", 1)
else:
new_parts = part.rsplit(".", 1)
if len(new_parts) > 1:
add_split(new_parts[0])
add_split(record.__name__)
return sorted(prefixes, key=_sort_first_lower)
def export(self, sinterface=None, sname=None):
registry = getUtility(IRegistry)
root = etree.Element("registry")
values = {} # full prefix to valuerecord
interface2values = {}
interface2prefix = {}
for record in registry.records.values():
if sinterface and sinterface != record.interfaceName:
continue
if sname and not record.__name__.startswith(sname):
continue
prefix, value_key = record.__name__.rsplit(".", 1)
xmlvalue = etree.Element("value")
if isinstance(record.value, basestring):
xmlvalue.text = record.value
elif isinstance(record.value, (list, tuple)):
for element in record.value:
xmlel = etree.SubElement(xmlvalue, "element")
xmlel.text = element
elif isinstance(record.value, bool):
xmlvalue.text = "True" if record.value else "False"
else:
continue
if record.interfaceName:
xmlvalue.attrib["key"] = value_key
if record.interfaceName not in interface2values:
interface2values[record.interfaceName] = []
interface2values[record.interfaceName].append(record.__name__)
interface2prefix[record.interfaceName] = prefix
values[record.__name__] = xmlvalue
for ifname in sorted(interface2values):
xmlrecord = etree.SubElement(root, "records")
xmlrecord.attrib["interface"] = ifname
xmlrecord.attrib["prefix"] = interface2prefix[ifname]
for value in sorted(interface2values[ifname]):
xmlrecord.append(values.pop(value))
for name, xmlvalue in values.items():
xmlrecord = etree.SubElement(root, "records")
xmlrecord.attrib["prefix"] = name
xmlrecord.append(xmlvalue)
self.request.response.setHeader("Content-Type", "text/xml")
filename = ""
if sinterface:
filename += sinterface
if sinterface and sname:
filename += "_-_"
if sname:
filename += sname
self.request.response.setHeader(
"Content-Disposition", "attachment; filename={0}.xml".format(filename)
)
return etree.tostring(
root, pretty_print=True, xml_declaration=True, encoding="UTF-8"
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment