Skip to content

Commit

Permalink
feat(KREAT-39): Fix folder factory core issue
Browse files Browse the repository at this point in the history
Refactor local setup and add work around for plone core issue:
plone/plone.app.content#194
  • Loading branch information
potzenheimer committed Oct 26, 2022
1 parent 112029b commit 143f1fd
Show file tree
Hide file tree
Showing 14 changed files with 476 additions and 6 deletions.
1 change: 1 addition & 0 deletions .python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.8.13
1 change: 1 addition & 0 deletions build/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ paths:
site_theme: ../theme
gulp_location: ../build/gulp
modules:
template:
virtualenv:
python_bin: python2
docker:
Expand Down
2 changes: 1 addition & 1 deletion development.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ auto-checkout =
# ade25.fabfiles
ade25.panelpage
ade25.widgets
bobtemplates.ade25
# bobtemplates.ade25
# collective.embedly
# collective.z3cform.datagridfield
hph.bulletinboard
Expand Down
2 changes: 2 additions & 0 deletions packages.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ addon =
collective.beaker
collective.easyform
collective.js.jqueryui
collective.relationhelpers
collective.z3cform.datagridfield
jsonpickle
Pillow
Expand All @@ -61,6 +62,7 @@ test =
hph.corporatetheme [test]
devtools =
# ade25.fabfiles
experimental.gracefulblobmissing
pdbpp
plone.reload
Products.PDBDebugMode
Expand Down
4 changes: 2 additions & 2 deletions pyvenv.cfg
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
home = /usr/local/opt/python@3.10/bin
home = /Users/cbf/.pyenv/versions/3.8.13/bin
include-system-site-packages = false
version = 3.10.6
version = 3.8.13
2 changes: 1 addition & 1 deletion src/hph.membership/hph/membership/browser/usermanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def extractCriteriaFromRequest(criteria):
'form.widgets.groups-empty-marker', ]:
if key in criteria:
del criteria[key]
for (key, value) in criteria.items():
for (key, value) in criteria.copy().items():
if not value:
del criteria[key]
else:
Expand Down
3 changes: 3 additions & 0 deletions src/hph.policy/hph/policy/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,7 @@
/>
<!-- -*- extra stuff goes here -*- -->

<!-- Custom upgrade handler for package cleanups -->
<include file="upgrades.zcml" />

</configure>
2 changes: 2 additions & 0 deletions src/hph.policy/hph/policy/migration/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
"""Module providing migration helpers"""
163 changes: 163 additions & 0 deletions src/hph.policy/hph/policy/migration/post_python3_fixes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
# -*- coding: utf-8 -*-
from ComputedAttribute import ComputedAttribute
from logging import getLogger
from plone import api
from plone.portlets.interfaces import IPortletAssignmentMapping
from plone.portlets.interfaces import IPortletManager
from plone.registry.interfaces import IRegistry
from zope.annotation.interfaces import IAnnotations
from zope.component import getUtility
from zope.component import queryMultiAdapter
from zope.component import queryUtility
from zope.globalrequest import getRequest

import logging

log = logging.getLogger(__name__)


def fix_event_indexes(context=None):
# Metadata on brains is still old DateTime
for brain in api.content.find(portal_type='Event'):
obj = brain.getObject()
obj.reindexObject()


def fix_searchable_text(context=None):
# Fix bytes in opkapiindex
# See https://github.com/plone/Products.CMFPlone/issues/2905
from Products.ZCTextIndex.interfaces import IZCTextIndex
from Products.ZCTextIndex.interfaces import ILexicon
catalog = api.portal.get_tool('portal_catalog')
zctextindex = catalog._catalog.indexes['SearchableText']
opkapiindex = zctextindex.index
values = opkapiindex._docwords.values()
first_item = values[0]
if isinstance(first_item, bytes):
log.info('Rebuilding ZCTextIndexes. First item is a byte:')
log.info(first_item)
lexica = [i for i in catalog.values() if ILexicon.providedBy(i)]
for lexicon in lexica:
lexicon.clear()

indexes = [i for i in catalog.Indexes.objectValues()
if IZCTextIndex.providedBy(i)]
for index in indexes:
try:
index.clear()
except AttributeError as e:
log.info(e)
log.info('rebuilding {}'.format(index.__name__))
catalog._catalog.reindexIndex(index.__name__, getRequest())
else:
log.info('Not rebuilding ZCTextIndexes. First item is not bytes:')
log.info(first_item)


def fix_portlets(context=None):
"""Fix portlets that use ComputedValue for path-storage instead of a UUID.
"""
catalog = api.portal.get_tool('portal_catalog')
portal = api.portal.get()
fix_portlets_for(portal)
for brain in catalog.getAllBrains():
try:
obj = brain.getObject()
except KeyError:
log.info('Broken brain for {}'.format(brain.getPath()))
continue
fix_portlets_for(obj)


def fix_portlets_for(obj):
"""Fix portlets for a certain object."""
attrs_to_fix = [
'root_uid',
'search_base_uid',
'uid',
]
for manager_name in ['plone.leftcolumn', 'plone.rightcolumn', 'plone.footerportlets']:
manager = queryUtility(IPortletManager, name=manager_name, context=obj)
if not manager:
continue
mappings = queryMultiAdapter((obj, manager), IPortletAssignmentMapping)
if not mappings:
continue
for key, assignment in mappings.items():
for attr in attrs_to_fix:
if getattr(assignment, attr, None) is not None and isinstance(getattr(assignment, attr), ComputedAttribute):
setattr(assignment, attr, None)
log.info('Reset {} for portlet {} assigned at {} in {}'.format(attr, key, obj.absolute_url(), manager_name)) # noqa: E501
log.info('You may need to configure it manually at {}/@@manage-portlets'.format(obj.absolute_url())) # noqa: E501


def fix_discussions(context=None):
"""Fix conversations that still have the old AT content as __parent__"""
portal = api.portal.get()
log.info('Fixing conversations...')

def fix_at_parent_for_discussions(obj, path):
annotations = IAnnotations(obj, None)
if not annotations:
return
if 'plone.app.discussion:conversation' not in annotations.keys():
return
conversation = annotations['plone.app.discussion:conversation']
if 'broken' in str(conversation.__parent__):
conversation.__parent__ = obj
log.info(f'Fix conversation for {obj.absolute_url()}')
else:
log.info(f'Conversation parent ok: {conversation.__parent__}')

portal.ZopeFindAndApply(
portal, search_sub=True, apply_func=fix_at_parent_for_discussions
)
log.info('Fixed conversations!')


def fix_registry(context=None):
"""Remove registry-records where the interface is no longer there."""
registry = getUtility(IRegistry)
keys = [i for i in registry.records.keys()]
for key in keys:
record = registry.records[key]
if not record.field.interface:
# That's fine...
continue
try:
iface = record.field.interface()
except TypeError:
# That's also fine...
continue
if 'broken' in str(iface):
logger.info(f'Removing broken record {key}')
del registry.records[key]


def rebuild_relations(context=None):
"""Export all valid reations from the relation-catalog, purge the relation-catalog
(and cleanup the intid-catalog) and restores all valid relations."""
from collective.relationhelpers import api as relapi
relapi.rebuild_relations()


def export_relations(context=None):
"""Export all relations as a json file all_relations.json in you buildout directory."""
from collective.relationhelpers import api as relapi
relapi.export_relations()


def restore_relations(all_relations=None):
"""Recreate relations from a annotation on the portal or a list of dicts
(e.g. restored from the json-file created by export_relations).
This works fine for all kinds of relations, RelationList- or RelationChoice-fields
(including the default field "Related Items") as well as for linkintegrity-relations
and relations between working-copies."""
from collective.relationhelpers import api as relapi
relapi.restore_relations(all_relations=all_relations)


def cleanup_intids(context=None):
"""Purge all RelationValues and all references to broken objects from the IntId catalog."""
from collective.relationhelpers import api as relapi
relapi.cleanup_intids()
2 changes: 1 addition & 1 deletion src/hph.policy/hph/policy/profiles/default/metadata.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0"?>
<metadata>
<version>1000</version>
<version>1002</version>
</metadata>
Loading

0 comments on commit 143f1fd

Please sign in to comment.