Skip to content

Commit

Permalink
Merge branch 'master' into portal_checklink
Browse files Browse the repository at this point in the history
  • Loading branch information
mamico authored Mar 20, 2024
2 parents 0363bbf + 0bd25bd commit b2a865f
Show file tree
Hide file tree
Showing 17 changed files with 377 additions and 81 deletions.
44 changes: 43 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,12 +1,54 @@
Changelog
=========

5.4.4 (unreleased)
5.4.9 (unreleased)
------------------

- Nothing changed yet.


5.4.8 (2024-03-19)
------------------

- Do not try to convert strings in internal paths for *form* blocks.
- Handle None values in link integrity blocks adapter.
- Patch in @querystring-search that avoid to search through all the site if there is an absolutePath criteria with non existing UID and b_size==1.
See #99 for more details.
[cekk]


5.4.7 (2024-03-11)
------------------

- Add adapter handler for event in rss feed to export
start date instead of publication date
[lucabel]


5.4.6 (2024-03-06)
------------------

- Added check if value is a dict before using get method.
[eikichi18]


5.4.5 (2024-03-05)
------------------

- Update plone.restapi requirement to 9.6.0 version
[folix-01]
- Removed monkeypatch for plone.restartpi.serializer.utils.RESOLVEUID_RE
[folix-01]

5.4.4 (2024-02-20)
------------------

- Add adapters for link integrity for content-types with BlocksField fields.
[cekk]
- Fix: occurrences indexing
[mamico]


5.4.3 (2024-01-30)
------------------

Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

setup(
name="redturtle.volto",
version="5.4.4.dev0",
version="5.4.9.dev0",
description="Helper package to setup a RedTurtle's Plone site ready to work with Volto.",
long_description=long_description,
# Get more from https://pypi.org/classifiers/
Expand Down Expand Up @@ -59,7 +59,7 @@
"collective.purgebyid",
"kitconcept.seo>=2.0.0",
"plone.volto>=4.0.0",
"plone.restapi>=8.36.0",
"plone.restapi>=9.6.0",
"Products.PortalTransforms>=3.2.0",
],
extras_require={
Expand Down
5 changes: 0 additions & 5 deletions src/redturtle/volto/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@
"""Init and utils."""
from plone.app.content.browser.vocabulary import PERMISSIONS
from plone.folder.nogopip import GopipIndex
from plone.restapi.serializer import utils
from Products.ZCatalog.Catalog import Catalog
from redturtle.volto.catalogplan import Catalog_sorted_search_indexes
from zope.i18nmessageid import MessageFactory
from ZTUtils.Lazy import LazyCat
from ZTUtils.Lazy import LazyMap

import logging
import re


logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -77,6 +75,3 @@ def Catalog_sortResults(
logger.info("install monkey patch for Products.ZCatalog.Catalog.Catalog.sortResults")
Catalog._orig_sortResults = Catalog.sortResults
Catalog.sortResults = Catalog_sortResults

# patch plone.restapi regexp to catch also other
utils.RESOLVEUID_RE = re.compile("^(?:|.*/)resolve[Uu]id/([^/]*)/?(.*)$")
106 changes: 106 additions & 0 deletions src/redturtle/volto/adapters/blocks_linkintegrity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
from collective.volto.blocksfield.field import BlocksField
from plone.app.linkintegrity.interfaces import IRetriever
from plone.app.linkintegrity.parser import extractLinks
from plone.app.textfield import RichText
from plone.dexterity.interfaces import IDexterityContainer
from plone.dexterity.interfaces import IDexterityContent
from plone.dexterity.interfaces import IDexterityFTI
from plone.dexterity.interfaces import IDexterityItem
from plone.dexterity.utils import getAdditionalSchemata
from plone.restapi.blocks import iter_block_transform_handlers
from plone.restapi.blocks import visit_blocks
from plone.restapi.blocks_linkintegrity import BlocksRetriever as BaseBlocksRetriever
from plone.restapi.blocks_linkintegrity import (
GenericBlockLinksRetriever as BaseGenericBlockLinksRetriever,
)
from plone.restapi.blocks_linkintegrity import (
SlateBlockLinksRetriever as BaseSlateBlockLinksRetriever,
)
from plone.restapi.blocks_linkintegrity import (
TextBlockLinksRetriever as BaseTextBlockLinksRetriever,
)
from plone.restapi.interfaces import IBlockFieldLinkIntegrityRetriever
from redturtle.volto.interfaces import IRedturtleVoltoLayer
from zope.component import adapter
from zope.component import getUtility
from zope.interface import implementer
from zope.schema import getFieldsInOrder


class BaseRTRetriever(BaseBlocksRetriever):
def retrieveLinks(self):
"""
Check links in:
- blocks field
- text fields
- BlocksField fields
"""
# first do plone.restapi links generation
links = super().retrieveLinks()

# then iterate over content schema and check for other references
fti = getUtility(IDexterityFTI, name=self.context.portal_type)
schema = fti.lookupSchema()
additional_schema = getAdditionalSchemata(
context=self.context, portal_type=self.context.portal_type
)
schemas = [i for i in additional_schema] + [schema]
links = set()
for schema in schemas:
for name, field in getFieldsInOrder(schema):
if isinstance(field, RichText):
value = getattr(schema(self.context), name)
if not value or not getattr(value, "raw", None):
continue
links |= set(extractLinks(value.raw))
elif isinstance(field, BlocksField):
value = field.get(self.context)
if not value:
continue
if not isinstance(value, dict):
continue
blocks = value.get("blocks", {})
if not blocks:
continue
for block in visit_blocks(self.context, blocks):
for handler in iter_block_transform_handlers(
self.context, block, IBlockFieldLinkIntegrityRetriever
):
links |= set(handler(block))
return links


@implementer(IRetriever)
@adapter(IDexterityItem)
class BlocksRetrieverItem(BaseRTRetriever):
"""
Retriever for Item contents.
Needed a more specific than IDexterityContent because it's already registered.
"""


@implementer(IRetriever)
@adapter(IDexterityContainer)
class BlocksRetrieverContainer(BaseRTRetriever):
"""
Retriever for Container contents.
Needed a more specific than IDexterityContent because it's already registered.
"""


@adapter(IDexterityContent, IRedturtleVoltoLayer)
@implementer(IBlockFieldLinkIntegrityRetriever)
class TextBlockLinksRetriever(BaseTextBlockLinksRetriever):
"""Retriever for text blocks"""


@adapter(IDexterityContent, IRedturtleVoltoLayer)
@implementer(IBlockFieldLinkIntegrityRetriever)
class SlateBlockLinksRetriever(BaseSlateBlockLinksRetriever):
"""Retriever for slate blocks"""


@adapter(IDexterityContent, IRedturtleVoltoLayer)
@implementer(IBlockFieldLinkIntegrityRetriever)
class GenericBlockLinksRetriever(BaseGenericBlockLinksRetriever):
"""Retriever for generic blocks"""
38 changes: 38 additions & 0 deletions src/redturtle/volto/adapters/configure.zcml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser"
xmlns:zcml="http://namespaces.zope.org/zcml"
>

<adapter
Expand All @@ -17,4 +18,41 @@
name="volto_parent_url"
/>

<!-- blocks link integrity for contenttypes with BlocksFields -->
<configure zcml:condition="installed collective.volto.blocksfield">
<adapter factory=".blocks_linkintegrity.BlocksRetrieverContainer" />
<adapter factory=".blocks_linkintegrity.BlocksRetrieverItem" />


<subscriber
factory=".blocks_linkintegrity.TextBlockLinksRetriever"
provides="plone.restapi.interfaces.IBlockFieldLinkIntegrityRetriever"
/>
<subscriber
factory=".blocks_linkintegrity.GenericBlockLinksRetriever"
provides="plone.restapi.interfaces.IBlockFieldLinkIntegrityRetriever"
/>
<subscriber
factory=".blocks_linkintegrity.SlateBlockLinksRetriever"
provides="plone.restapi.interfaces.IBlockFieldLinkIntegrityRetriever"
/>
</configure>


<adapter
factory=".rss.EventItem"
provides="plone.base.interfaces.syndication.IFeedItem"
for="plone.app.contenttypes.interfaces.IEvent
plone.base.interfaces.syndication.IFeed"
zcml:condition="have plone-60"
/>

<adapter
factory=".rss.EventItem"
provides="Products.CMFPlone.interfaces.syndication.IFeedItem"
for="plone.app.contenttypes.interfaces.IEvent
Products.CMFPlone.interfaces.syndication.IFeed"
zcml:condition="not-have plone-60"
/>

</configure>
24 changes: 24 additions & 0 deletions src/redturtle/volto/adapters/rss.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from DateTime import DateTime
from plone.app.contenttypes.interfaces import IEvent


try:
from plone.base.interfaces.syndication import IFeed
except ModuleNotFoundError:
from Products.CMFPlone.interfaces.syndication import IFeed

from Products.CMFPlone.browser.syndication.adapters import DexterityItem
from zope.component import adapter


@adapter(IEvent, IFeed)
class EventItem(DexterityItem):
@property
def startdate(self):
"""
Same format as other dates in
Products.CMFPlone.browser.syndication.adapters
"""
date = self.context.start.isoformat()
if date:
return DateTime(date)
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
<tal:block tal:repeat="item item/categories">
<dc:subject tal:content="item">Item</dc:subject>
</tal:block>
<dc:date tal:content="item/published/HTML4|item/modified/HTML4">Published or last modified date if no published date</dc:date>
<dc:date tal:content="item/startdate/HTML4|item/published/HTML4|item/modified/HTML4">Published or last modified date if no published date</dc:date>
<dc:type tal:content="item/context/portal_type">Type</dc:type>
</item>
</tal:block>
Expand Down
24 changes: 16 additions & 8 deletions src/redturtle/volto/monkey.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
from plone.event.interfaces import IEventAccessor
from plone.event.interfaces import IRecurrenceSupport
from plone.event.recurrence import recurrence_sequence_ical
from plone.event.utils import pydt

# from plone.event.utils import pydt
from Products.CMFPlone.interfaces import IConstrainTypes
from zope.globalrequest import getRequest

Expand Down Expand Up @@ -75,13 +76,20 @@ def occurrences(self, range_start=None, range_end=None):
# but doing it for backwards compatibility as views/templates
# still rely on acquisition-wrapped objects.
def get_obj(start):
if pydt(event_start.replace(microsecond=0)) == start:
# If the occurrence date is the same as the event object, the
# occurrence is the event itself. return it as such.
# Dates from recurrence_sequence_ical are explicitly without
# microseconds, while event.start may contain it. So we have to
# remove it for a valid comparison.
return self.context
# THIS IS THE PATCH
#
# -- questa parte è stata commentata, altrtimenti se lo start date coincide con la data di inizio dell'evento
# -- la funzione ritorna l'evento stesso, invece che la sua occorrenza e l'indice end non contiene
# -- tutte le date di end, ma solo quella dell'evento stesso
#
# if pydt(event_start.replace(microsecond=0)) == start:
# # If the occurrence date is the same as the event object, the
# # occurrence is the event itself. return it as such.
# # Dates from recurrence_sequence_ical are explicitly without
# # microseconds, while event.start may contain it. So we have to
# # remove it for a valid comparison.
# return self.context
# END OF PATCH
return Occurrence(
id=str(start.date()), start=start, end=start + duration
).__of__(self.context)
Expand Down
2 changes: 1 addition & 1 deletion src/redturtle/volto/profiles/default/metadata.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
<version>4302</version>
<version>4303</version>
<dependencies>
<dependency>profile-plone.volto:default</dependency>
<dependency>profile-plone.app.caching:with-caching-proxy</dependency>
Expand Down
2 changes: 1 addition & 1 deletion src/redturtle/volto/restapi/deserializer/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@


EXCLUDE_KEYS = ["@type", "token", "value", "@id", "query"]
EXCLUDE_TYPES = ["title", "listing", "calendar", "searchEvents"]
EXCLUDE_TYPES = ["title", "listing", "calendar", "searchEvents", "form"]


class GenericResolveUIDDeserializer(object):
Expand Down
2 changes: 1 addition & 1 deletion src/redturtle/volto/restapi/serializer/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@


EXCLUDE_KEYS = ["@type"]
EXCLUDE_TYPES = ["title", "listing"]
EXCLUDE_TYPES = ["title", "listing", "form"]


class GenericResolveUIDSerializer(object):
Expand Down
Loading

0 comments on commit b2a865f

Please sign in to comment.