Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Branch: refs/heads/master Date: 2019-08-06T12:12:37+02:00 Author: Robert Kuzma (balavec) <robert@balavec.com> Commit: plone/plone.app.event@cdc83d5 Fix Python2 vs. Python3 text and bytes handling in the calendar portlet. Files changed: A news/308.bugfix M plone/app/event/portlets/portlet_calendar.py Repository: plone.app.event Branch: refs/heads/master Date: 2019-11-06T18:49:20+01:00 Author: Jens W. Klein (jensens) <jk@kleinundpartner.at> Commit: plone/plone.app.event@753869b Merge pull request #309 from plone/python3-text-bytes Fix Python2 vs. Python3 text and bytes handling in the calendar portlet Files changed: A news/308.bugfix M plone/app/event/portlets/portlet_calendar.py
- Loading branch information
Showing
1 changed file
with
26 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,34 @@ | ||
Repository: plone.restapi | ||
Repository: plone.app.event | ||
|
||
|
||
Branch: refs/heads/master | ||
Date: 2019-11-06T15:01:01+01:00 | ||
Author: Lukas Graf (lukasgraf) <lukas.graf@4teamwork.ch> | ||
Commit: https://github.com/plone/plone.restapi/commit/9f86fbf860229fb20db9ea724b411660887a0d30 | ||
Date: 2019-08-06T12:12:37+02:00 | ||
Author: Robert Kuzma (balavec) <robert@balavec.com> | ||
Commit: https://github.com/plone/plone.app.event/commit/cdc83d52bc90e378779d09a684b03f81e5678dd7 | ||
|
||
Fix filtering vocabs and sources by non-ASCII title (#826) | ||
Fix Python2 vs. Python3 text and bytes handling in the calendar portlet. | ||
|
||
* Assign IBasic behavior to our DXTestDocument to get a proper title attribute. | ||
|
||
* Fix filtering vocabs and sources by title with non-ASCII characters. | ||
Files changed: | ||
A news/308.bugfix | ||
M plone/app/event/portlets/portlet_calendar.py | ||
|
||
b'diff --git a/news/308.bugfix b/news/308.bugfix\nnew file mode 100644\nindex 00000000..f709a607\n--- /dev/null\n+++ b/news/308.bugfix\n@@ -0,0 +1 @@\n+Fix Python2 vs. Python3 text and bytes handling in the calendar portlet.\ndiff --git a/plone/app/event/portlets/portlet_calendar.py b/plone/app/event/portlets/portlet_calendar.py\nindex 3b1c471b..fbf9dd60 100644\n--- a/plone/app/event/portlets/portlet_calendar.py\n+++ b/plone/app/event/portlets/portlet_calendar.py\n@@ -279,12 +279,16 @@ def cal_data(self):\n return caldata\n \n def nav_pattern_options(self, year, month):\n+ val = self.hash\n+ if isinstance(val, bytes):\n+ val = val.decode("utf-8")\n+\n return json.dumps({\n \'url\': \'%s/@@render-portlet?portlethash=%s&year=%s&month=%s\' % (\n getSite().absolute_url(),\n- self.hash,\n+ val,\n year, month),\n- \'target\': \'#portletwrapper-%s > *\' % self.hash\n+ \'target\': \'#portletwrapper-%s > *\' % val\n })\n \n @property\n' | ||
|
||
Repository: plone.app.event | ||
|
||
|
||
Branch: refs/heads/master | ||
Date: 2019-11-06T18:49:20+01:00 | ||
Author: Jens W. Klein (jensens) <jk@kleinundpartner.at> | ||
Commit: https://github.com/plone/plone.app.event/commit/753869bdf2d4ad9dfc482f9eb8f392cb39492d6c | ||
|
||
Merge pull request #309 from plone/python3-text-bytes | ||
|
||
Fix Python2 vs. Python3 text and bytes handling in the calendar portlet | ||
|
||
Files changed: | ||
A news/825.bugfix | ||
M src/plone/restapi/profiles/testing/types/DXTestDocument.xml | ||
M src/plone/restapi/serializer/vocabularies.py | ||
M src/plone/restapi/tests/dxtypes.py | ||
M src/plone/restapi/tests/helpers.py | ||
M src/plone/restapi/tests/test_services_sources.py | ||
M src/plone/restapi/tests/test_services_vocabularies.py | ||
|
||
b'diff --git a/news/825.bugfix b/news/825.bugfix\nnew file mode 100644\nindex 00000000..8a5bc107\n--- /dev/null\n+++ b/news/825.bugfix\n@@ -0,0 +1,2 @@\n+Fix filtering vocabs and sources by title with non-ASCII characters.\n+[lgraf]\ndiff --git a/src/plone/restapi/profiles/testing/types/DXTestDocument.xml b/src/plone/restapi/profiles/testing/types/DXTestDocument.xml\nindex e673eee2..07813f7b 100644\n--- a/src/plone/restapi/profiles/testing/types/DXTestDocument.xml\n+++ b/src/plone/restapi/profiles/testing/types/DXTestDocument.xml\n@@ -22,6 +22,7 @@\n <property name="behaviors">\n <element value="plone.restapi.tests.dxtypes.ITestBehavior"/>\n <element value="plone.restapi.tests.dxtypes.ITestAnnotationsBehavior"/>\n+ <element value="plone.app.dexterity.behaviors.metadata.IBasic"/>\n </property>\n \n <!-- View information -->\ndiff --git a/src/plone/restapi/serializer/vocabularies.py b/src/plone/restapi/serializer/vocabularies.py\nindex 4e1ebab8..ac63d18e 100644\n--- a/src/plone/restapi/serializer/vocabularies.py\n+++ b/src/plone/restapi/serializer/vocabularies.py\n@@ -1,6 +1,7 @@\n # -*- coding: utf-8 -*-\n from plone.restapi.batching import HypermediaBatch\n from plone.restapi.interfaces import ISerializeToJson\n+from Products.CMFPlone.utils import safe_unicode\n from zope.component import adapter\n from zope.component import getMultiAdapter\n from zope.i18n import translate\n@@ -27,7 +28,7 @@ def __init__(self, context, request):\n \n def __call__(self, vocabulary_id):\n vocabulary = self.context\n- title = self.request.form.get("title", "")\n+ title = safe_unicode(self.request.form.get("title", ""))\n token = self.request.form.get("token", "")\n \n terms = []\n@@ -46,7 +47,7 @@ def __call__(self, vocabulary_id):\n continue\n terms.append(term)\n else:\n- term_title = getattr(term, "title", None) or ""\n+ term_title = safe_unicode(getattr(term, "title", None) or "")\n if title.lower() not in term_title.lower():\n continue\n terms.append(term)\ndiff --git a/src/plone/restapi/tests/dxtypes.py b/src/plone/restapi/tests/dxtypes.py\nindex 606aec01..20bc8608 100644\n--- a/src/plone/restapi/tests/dxtypes.py\n+++ b/src/plone/restapi/tests/dxtypes.py\n@@ -9,6 +9,7 @@\n from plone.autoform.interfaces import IFormFieldProvider\n from plone.dexterity.content import Item\n from plone.namedfile import field as namedfile\n+from plone.restapi.tests.helpers import ascii_token\n from plone.supermodel import model\n from Products.CMFCore.utils import getToolByName\n from pytz import timezone\n@@ -84,9 +85,10 @@ def __init__(self, context):\n self.context = context\n \n title_words = self.context.title.split()\n- self.terms = [\n- SimpleTerm(value=w.lower(), token=w.lower(), title=w) for w in title_words\n- ]\n+ self.terms = [SimpleTerm(value=w.lower(),\n+ token=ascii_token(w.lower()),\n+ title=w)\n+ for w in title_words]\n \n def __contains__(self, value):\n return value in [t.value for t in self.terms]\n@@ -101,9 +103,10 @@ def __init__(self, context):\n self.context = context\n \n title_words = self.context.title.split()\n- self.terms = [\n- SimpleTerm(value=w.lower(), token=w.lower(), title=w) for w in title_words\n- ]\n+ self.terms = [SimpleTerm(value=w.lower(),\n+ token=ascii_token(w.lower()),\n+ title=w)\n+ for w in title_words]\n \n def __contains__(self, value):\n return value in [t.value for t in self.terms]\ndiff --git a/src/plone/restapi/tests/helpers.py b/src/plone/restapi/tests/helpers.py\nindex 92ba3339..eba05f74 100644\n--- a/src/plone/restapi/tests/helpers.py\n+++ b/src/plone/restapi/tests/helpers.py\n@@ -2,6 +2,8 @@\n from Products.CMFCore.utils import getToolByName\n from six.moves.urllib.parse import urlparse\n \n+import quopri\n+\n \n def result_paths(results):\n """Helper function to make it easier to write list-based assertions on\n@@ -35,3 +37,10 @@ def add_catalog_indexes(portal, indexes):\n indexables.append(name)\n if len(indexables) > 0:\n catalog.manage_reindexIndex(ids=indexables)\n+\n+\n+def ascii_token(text):\n+ """Turn a text (unicode in Py2, str in Py3) into a ASCII-only\n+ bytestring that is safe to use in term tokens.\n+ """\n+ return quopri.encodestring(text.encode(\'utf-8\'))\ndiff --git a/src/plone/restapi/tests/test_services_sources.py b/src/plone/restapi/tests/test_services_sources.py\nindex fa79ec88..898dfe8b 100644\n--- a/src/plone/restapi/tests/test_services_sources.py\n+++ b/src/plone/restapi/tests/test_services_sources.py\n@@ -179,7 +179,7 @@ def test_get_source_for_unknown_field(self):\n )\n \n def test_context_source(self):\n- self.doc.title = "Foo Bar Baz"\n+ self.doc.title = u\'Foo Bar Baz\'\n transaction.commit()\n \n response = self.api_session.get(\n@@ -201,5 +201,26 @@ def test_context_source(self):\n },\n )\n \n+ def test_source_filtered_by_non_ascii_title(self):\n+ self.doc.title = u\'B\xc3\xa4r\'\n+ transaction.commit()\n+\n+ response = self.api_session.get(\n+ "%s/@sources/test_choice_with_context_source?title=b%%C3%%A4r" % self.doc.absolute_url()\n+ )\n+\n+ self.assertEqual(response.status_code, 200)\n+ self.assertEqual(\n+ response.json(),\n+ {\n+ u"@id": self.portal_url\n+ + u"/testdoc/@sources/test_choice_with_context_source?title=b%C3%A4r", # noqa\n+ u"items": [\n+ {u\'token\': u\'b=C3=A4r\', u\'title\': u\'B\\xe4r\'},\n+ ],\n+ u"items_total": 1,\n+ },\n+ )\n+\n def tearDown(self):\n self.api_session.close()\ndiff --git a/src/plone/restapi/tests/test_services_vocabularies.py b/src/plone/restapi/tests/test_services_vocabularies.py\nindex f391c9d0..6fdcbd44 100644\n--- a/src/plone/restapi/tests/test_services_vocabularies.py\n+++ b/src/plone/restapi/tests/test_services_vocabularies.py\n@@ -136,6 +136,24 @@ def test_get_vocabulary_filtered_by_title(self):\n },\n )\n \n+ def test_get_vocabulary_filtered_by_non_ascii_title(self):\n+ response = self.api_session.get(\n+ "/@vocabularies/plone.restapi.tests.test_vocabulary?title=t%C3%B6tle"\n+ )\n+\n+ self.assertEqual(200, response.status_code)\n+ response = response.json()\n+ self.assertEqual(\n+ response,\n+ {\n+ u"@id": self.portal_url\n+ + u"/@vocabularies/plone.restapi.tests.test_vocabulary?title=t%C3%B6tle", # noqa\n+ u"items": [{u"title": u"T\\xf6tle 5", u"token": u"token5"},\n+ {u"title": u"T\\xf6tle 6", u"token": u"token6"}],\n+ u"items_total": 2,\n+ },\n+ )\n+\n def test_get_vocabulary_filtered_by_token(self):\n response = self.api_session.get(\n "/@vocabularies/plone.restapi.tests.test_vocabulary?token=token1"\n' | ||
A news/308.bugfix | ||
M plone/app/event/portlets/portlet_calendar.py | ||
|
||
b'diff --git a/news/308.bugfix b/news/308.bugfix\nnew file mode 100644\nindex 00000000..f709a607\n--- /dev/null\n+++ b/news/308.bugfix\n@@ -0,0 +1 @@\n+Fix Python2 vs. Python3 text and bytes handling in the calendar portlet.\ndiff --git a/plone/app/event/portlets/portlet_calendar.py b/plone/app/event/portlets/portlet_calendar.py\nindex 3b1c471b..fbf9dd60 100644\n--- a/plone/app/event/portlets/portlet_calendar.py\n+++ b/plone/app/event/portlets/portlet_calendar.py\n@@ -279,12 +279,16 @@ def cal_data(self):\n return caldata\n \n def nav_pattern_options(self, year, month):\n+ val = self.hash\n+ if isinstance(val, bytes):\n+ val = val.decode("utf-8")\n+\n return json.dumps({\n \'url\': \'%s/@@render-portlet?portlethash=%s&year=%s&month=%s\' % (\n getSite().absolute_url(),\n- self.hash,\n+ val,\n year, month),\n- \'target\': \'#portletwrapper-%s > *\' % self.hash\n+ \'target\': \'#portletwrapper-%s > *\' % val\n })\n \n @property\n' | ||
|