From 022706d970de0f65f87d4889b3f9a3632e5cb2e2 Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Mon, 28 Aug 2023 14:41:07 +0200 Subject: [PATCH 1/5] Use plone.volto uid_to_url method to convert resolveuid links in summary --- CHANGES.rst | 3 ++- .../volto/restapi/serializer/summary.py | 25 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 8915e4d8..46ded1aa 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,8 @@ Changelog 5.2.1 (unreleased) ------------------ -- Nothing changed yet. +- Use plone.volto uid_to_url method to convert resolveuid links in summary. + [cekk] 5.2.0 (2023-08-21) diff --git a/src/redturtle/volto/restapi/serializer/summary.py b/src/redturtle/volto/restapi/serializer/summary.py index fcffe63e..01ab923f 100644 --- a/src/redturtle/volto/restapi/serializer/summary.py +++ b/src/redturtle/volto/restapi/serializer/summary.py @@ -13,6 +13,11 @@ from zope.component import adapter from zope.interface import implementer from zope.interface import Interface +from plone.app.uuid.utils import uuidToCatalogBrain +from plone.restapi.interfaces import IObjectPrimaryFieldTarget +from zope.component import queryMultiAdapter +from plone.restapi.serializer.utils import uid_to_url + import re @@ -89,19 +94,13 @@ def get_remote_url(self): # it isn't an internal link, so we can return it return value path = replace_link_variables_by_paths(context=self.context, url=value) - match = RESOLVEUID_RE.match(path) - if match: - uid, suffix = match.groups() - return uuidToURL(uid) - else: - portal = api.portal.get() - try: - ref_obj = portal.restrictedTraverse(path, None) - if ref_obj: - return ref_obj.absolute_url() - except Exception: - return "" - return "" + + url = uid_to_url(path) + + if url == path: + # something wrong with the path, maybe a missing object? + return "" + return url def __call__(self, force_all_metadata=False): if force_all_metadata: From c9738aab28f87b797647ddced8a602b96197cba4 Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Mon, 28 Aug 2023 15:14:56 +0200 Subject: [PATCH 2/5] Patch plone.restapi RESOLVEUID_RE regexp to catch more urls. --- CHANGES.rst | 3 ++- src/redturtle/volto/__init__.py | 7 +++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 46ded1aa..4b87dbae 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -6,7 +6,8 @@ Changelog - Use plone.volto uid_to_url method to convert resolveuid links in summary. [cekk] - +- Patch plone.restapi RESOLVEUID_RE regexp to catch more urls. + [cekk] 5.2.0 (2023-08-21) ------------------ diff --git a/src/redturtle/volto/__init__.py b/src/redturtle/volto/__init__.py index be7550d8..a6c1363b 100644 --- a/src/redturtle/volto/__init__.py +++ b/src/redturtle/volto/__init__.py @@ -7,10 +7,10 @@ from zope.i18nmessageid import MessageFactory from ZTUtils.Lazy import LazyCat from ZTUtils.Lazy import LazyMap - +from plone.restapi.serializer import utils import logging - +import re logger = logging.getLogger(__name__) @@ -76,3 +76,6 @@ 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/([^/]*)/?(.*)$") From 7bed40872cb89bc8c23dcf1d3c273a751c2e978d Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Mon, 28 Aug 2023 15:38:26 +0200 Subject: [PATCH 3/5] add tests --- .../volto/tests/test_resolveuid_re_patch.py | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/redturtle/volto/tests/test_resolveuid_re_patch.py diff --git a/src/redturtle/volto/tests/test_resolveuid_re_patch.py b/src/redturtle/volto/tests/test_resolveuid_re_patch.py new file mode 100644 index 00000000..96f6b141 --- /dev/null +++ b/src/redturtle/volto/tests/test_resolveuid_re_patch.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +from DateTime import DateTime +from plone import api +from plone.app.testing import setRoles +from plone.app.testing import SITE_OWNER_NAME +from plone.app.testing import SITE_OWNER_PASSWORD +from plone.app.testing import TEST_USER_ID +from plone.restapi.serializer.utils import uid_to_url +from plone.restapi.testing import RelativeSession +from redturtle.volto.interfaces import IRedTurtleVoltoSettings +from redturtle.volto.testing import REDTURTLE_VOLTO_FUNCTIONAL_TESTING +from transaction import commit + +import unittest + + +class TestRESOLVEUIDREPatch(unittest.TestCase): + layer = REDTURTLE_VOLTO_FUNCTIONAL_TESTING + + def setUp(self): + self.app = self.layer["app"] + self.portal = self.layer["portal"] + self.portal_url = self.portal.absolute_url() + + setRoles(self.portal, TEST_USER_ID, ["Manager"]) + + self.document = api.content.create( + container=self.portal, + type="Document", + title="Document", + ) + + def test_uuid_to_url_with_link_pattern(self): + path = f"/Plone/resolveuid/{self.document.UID()}" + + res = uid_to_url(path) + self.assertEqual(res, self.document.absolute_url()) + + def test_uuid_to_url_with_link_pattern_with_suffix(self): + path = f"/Plone/resolveuid/{self.document.UID()}/@@download/file" + + res = uid_to_url(path) + self.assertEqual(res, f"{self.document.absolute_url()}/@@download/file") From d2b1fc4b6d3c49be99d4fb0122f22516fec79791 Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Mon, 28 Aug 2023 15:45:03 +0200 Subject: [PATCH 4/5] add tests --- src/redturtle/volto/restapi/serializer/summary.py | 11 +---------- src/redturtle/volto/tests/test_resolveuid_re_patch.py | 6 ------ 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/src/redturtle/volto/restapi/serializer/summary.py b/src/redturtle/volto/restapi/serializer/summary.py index 01ab923f..f1b49bb8 100644 --- a/src/redturtle/volto/restapi/serializer/summary.py +++ b/src/redturtle/volto/restapi/serializer/summary.py @@ -2,27 +2,18 @@ from plone import api from plone.app.contenttypes.interfaces import ILink from plone.app.contenttypes.utils import replace_link_variables_by_paths -from plone.outputfilters.browser.resolveuid import uuidToURL from plone.restapi.deserializer import json_body from plone.restapi.imaging import get_scale_infos from plone.restapi.interfaces import ISerializeToJsonSummary from plone.restapi.serializer.summary import ( DefaultJSONSummarySerializer as BaseSerializer, ) +from plone.restapi.serializer.utils import uid_to_url from redturtle.volto.interfaces import IRedturtleVoltoLayer from zope.component import adapter from zope.interface import implementer from zope.interface import Interface -from plone.app.uuid.utils import uuidToCatalogBrain -from plone.restapi.interfaces import IObjectPrimaryFieldTarget -from zope.component import queryMultiAdapter -from plone.restapi.serializer.utils import uid_to_url - - -import re - -RESOLVEUID_RE = re.compile(".*?/resolve[Uu]id/([^/]*)/?(.*)$") EMPTY_STRINGS = ["None"] diff --git a/src/redturtle/volto/tests/test_resolveuid_re_patch.py b/src/redturtle/volto/tests/test_resolveuid_re_patch.py index 96f6b141..ec916706 100644 --- a/src/redturtle/volto/tests/test_resolveuid_re_patch.py +++ b/src/redturtle/volto/tests/test_resolveuid_re_patch.py @@ -1,15 +1,9 @@ # -*- coding: utf-8 -*- -from DateTime import DateTime from plone import api from plone.app.testing import setRoles -from plone.app.testing import SITE_OWNER_NAME -from plone.app.testing import SITE_OWNER_PASSWORD from plone.app.testing import TEST_USER_ID from plone.restapi.serializer.utils import uid_to_url -from plone.restapi.testing import RelativeSession -from redturtle.volto.interfaces import IRedTurtleVoltoSettings from redturtle.volto.testing import REDTURTLE_VOLTO_FUNCTIONAL_TESTING -from transaction import commit import unittest From f756427f3d81d597ec251a283c14dad07740b642 Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Tue, 29 Aug 2023 09:12:37 +0200 Subject: [PATCH 5/5] also fix Link serializer --- .../volto/restapi/serializer/dxfields.py | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/src/redturtle/volto/restapi/serializer/dxfields.py b/src/redturtle/volto/restapi/serializer/dxfields.py index 2eb9f939..2d623186 100644 --- a/src/redturtle/volto/restapi/serializer/dxfields.py +++ b/src/redturtle/volto/restapi/serializer/dxfields.py @@ -3,17 +3,17 @@ from plone.app.contenttypes.utils import replace_link_variables_by_paths from plone.app.dexterity.behaviors.metadata import IPublication from plone.dexterity.interfaces import IDexterityContent -from plone.outputfilters.browser.resolveuid import uuidToURL from plone.restapi.interfaces import IFieldSerializer from plone.restapi.serializer.converters import json_compatible from plone.restapi.serializer.dxfields import DefaultFieldSerializer +from plone.restapi.serializer.utils import uid_to_url from redturtle.volto.interfaces import IRedturtleVoltoLayer from zope.component import adapter -from zope.component import getMultiAdapter from zope.interface import implementer from zope.schema.interfaces import IDatetime from zope.schema.interfaces import ITextLine + import re @@ -26,21 +26,10 @@ def __call__(self): if self.field.getName() != "remoteUrl": return super(TextLineFieldSerializer, self).__call__() value = self.get_value() - path = replace_link_variables_by_paths(context=self.context, url=value) - match = RESOLVEUID_RE.match(path) - if match: - uid, suffix = match.groups() - value = uuidToURL(uid) - else: - portal = getMultiAdapter( - (self.context, self.context.REQUEST), name="plone_portal_state" - ).portal() - ref_obj = portal.restrictedTraverse(path, None) - if ref_obj: - value = ref_obj.absolute_url() + url = uid_to_url(path) - return json_compatible(value) + return json_compatible(url) @adapter(IDatetime, IDexterityContent, IRedturtleVoltoLayer)