imio.smartweb.common 1.2.38__tar.gz → 1.2.40__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/CHANGES.rst +15 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/PKG-INFO +16 -1
- imio_smartweb_common-1.2.40/requirements-6.1.txt +1 -0
- imio_smartweb_common-1.2.40/requirements-coverage.txt +2 -0
- imio_smartweb_common-1.2.40/requirements.txt +1 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/setup.py +1 -1
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/profiles/default/metadata.xml +1 -1
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/profiles/default/registry/tinymce.xml +3 -12
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/rest/endpoint.py +0 -3
- imio_smartweb_common-1.2.40/src/imio/smartweb/common/tests/test_rest_endpoint.py +238 -0
- imio_smartweb_common-1.2.40/src/imio/smartweb/common/tests/test_rest_utils.py +116 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/tests/test_utils.py +16 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/upgrades/configure.zcml +19 -0
- imio_smartweb_common-1.2.40/src/imio/smartweb/common/upgrades/profiles/1033_to_1034/registry/tinymce.xml +70 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/utils.py +13 -1
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio.smartweb.common.egg-info/PKG-INFO +16 -1
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio.smartweb.common.egg-info/SOURCES.txt +3 -0
- imio_smartweb_common-1.2.38/requirements-6.1.txt +0 -1
- imio_smartweb_common-1.2.38/requirements-coverage.txt +0 -2
- imio_smartweb_common-1.2.38/requirements.txt +0 -1
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/CONTRIBUTORS.rst +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/DEVELOP.rst +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/LICENSE.GPL +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/LICENSE.rst +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/MANIFEST.in +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/README.rst +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/docs/conf.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/docs/index.rst +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/requirements-6.0.txt +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/setup.cfg +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/__init__.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/__init__.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/__init__.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/adapters.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/adapters.zcml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/behaviors/__init__.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/behaviors/configure.zcml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/behaviors/iam.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/behaviors/topics.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/browser/__init__.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/browser/collective_taxonomy_controlpanel.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/browser/configure.zcml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/browser/cropping.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/browser/description.pt +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/browser/description.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/browser/edit_taxonomy_data.pt +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/browser/forms.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/browser/overrides/plone.app.z3cform.templates.widget.pt +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/browser/privacy/__init__.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/browser/privacy/configure.zcml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/browser/privacy/form.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/browser/privacy/utils.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/browser/privacy/views.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/browser/scaling.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/browser/static/Makefile +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/browser/static/package.json +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/browser/static/smartweb-common-edit-compiled.css +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/browser/static/smartweb-common-edit-compiled.js +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/browser/static/smartweb-common-view-compiled.css +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/browser/static/smartweb-common-view-compiled.js +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/browser/static/src/edit.js +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/browser/static/src/edit.less +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/browser/static/src/view.js +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/browser/static/src/view.less +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/browser/static/webpack.config.js +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/browser/vocabulary.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/caching.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/caching_overrides.zcml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/config.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/configure.zcml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/contact_utils.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/faceted/__init__.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/faceted/configure.zcml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/faceted/utils.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/faceted/widget.pt +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/faceted/widget.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/indexers.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/indexers.zcml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/interfaces.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/permissions.zcml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/privacy.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/privacy.zcml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/profiles/default/actions.xml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/profiles/default/browserlayer.xml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/profiles/default/catalog.xml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/profiles/default/registry/registry.xml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/profiles/default/rolemap.xml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/profiles/testing/catalog.xml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/profiles/testing/metadata.xml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/profiles/testing/registry.xml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/profiles/testing/types/Collection.xml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/profiles/testing/types/Document.xml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/profiles/testing/types/Folder.xml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/profiles/uninstall/browserlayer.xml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/profiles.zcml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/rest/__init__.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/rest/configure.zcml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/rest/odwb.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/rest/search_filters.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/rest/utils.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/serializers/__init__.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/serializers/configure.zcml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/serializers/summary.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/setuphandlers.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/sharing/__init__.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/sharing/configure.zcml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/sharing/localroles.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/sharing/permissions.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/sharing/permissions.zcml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/subscribers.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/subscribers.zcml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/testing.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/testing.zcml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/tests/__init__.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/tests/resources/image.png +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/tests/resources/image_1400x800.png +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/tests/resources/image_1800x700.png +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/tests/robot/test_example.robot +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/tests/test_cropping.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/tests/test_description.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/tests/test_forms.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/tests/test_indexes.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/tests/test_local_roles.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/tests/test_permissions.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/tests/test_privacy.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/tests/test_rest.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/tests/test_robot.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/tests/test_setup.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/tests/test_subscribers.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/tests/test_taxonomy.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/tests/test_text.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/tests/test_viewlets.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/tests/test_vocabularies.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/tests/test_vocabulary.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/tests/test_widgets.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/upgrades/__init__.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/upgrades/profiles/1007_to_1008/rolemap.xml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/upgrades/profiles/1008_to_1009/actions.xml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/upgrades/profiles/1009_to_1010/registry/tiny_nonbreakingspace.xml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/upgrades/profiles/1010_to_1011/registry/resources.xml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/upgrades/profiles/1010_to_1011/registry/scales.xml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/upgrades/profiles/1010_to_1011/registry/tinymce.xml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/upgrades/profiles/1011_to_1012/registry/bundles.xml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/upgrades/profiles/1013_to_1014/registry/tinymce.xml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/upgrades/profiles/1014_to_1015/registry/syndication.xml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/upgrades/profiles/1015_to_1016/registry/patched-faceted-jquery.xml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/upgrades/profiles/1016_to_1017/registry/scales.xml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/upgrades/profiles/1017_to_1018/registry.xml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/upgrades/profiles/1018_to_1019/registry/scales.xml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/upgrades/profiles/1022_to_1023/registry/scales.xml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/upgrades/profiles/1023_to_1024/registry/scales.xml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/upgrades/profiles/1025_to_1026/registry/scales.xml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/upgrades/profiles/1027_to_1028/restored-faceted-jquery.xml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/upgrades/profiles/1028_to_1029/registry.xml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/upgrades/profiles/1029_to_1030/registry.xml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/upgrades/profiles/1030_to_1031/registry/tinymce.xml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/upgrades/profiles/1031_to_1032/registry/tinymce.xml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/upgrades/profiles/1032_to_1033/registry/tinymce.xml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/upgrades/upgrades.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/utility_overrides.zcml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/viewlets/__init__.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/viewlets/analytics.pt +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/viewlets/colophon.pt +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/viewlets/colophon.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/viewlets/configure.zcml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/viewlets/privacy.pt +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/viewlets/privacy.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/viewlets/skip_to_content.pt +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/viewlets/skip_to_content.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/vocabularies.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/vocabularies.zcml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/widgets/__init__.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/widgets/select.py +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/widgets/templates/ajaxselect_display.pt +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/widgets.zcml +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio.smartweb.common.egg-info/dependency_links.txt +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio.smartweb.common.egg-info/namespace_packages.txt +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio.smartweb.common.egg-info/not-zip-safe +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio.smartweb.common.egg-info/requires.txt +0 -0
- {imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio.smartweb.common.egg-info/top_level.txt +0 -0
|
@@ -2,6 +2,21 @@ Changelog
|
|
|
2
2
|
=========
|
|
3
3
|
|
|
4
4
|
|
|
5
|
+
1.2.40 (2025-11-05)
|
|
6
|
+
-------------------
|
|
7
|
+
|
|
8
|
+
- Catch Exception on geocoding to avoid blocking content creation
|
|
9
|
+
if geopy service is down
|
|
10
|
+
[remdub]
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
1.2.39 (2025-11-03)
|
|
14
|
+
-------------------
|
|
15
|
+
|
|
16
|
+
- Migration to Plone 6.1.3
|
|
17
|
+
[boulch]
|
|
18
|
+
|
|
19
|
+
|
|
5
20
|
1.2.38 (2025-09-10)
|
|
6
21
|
-------------------
|
|
7
22
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: imio.smartweb.common
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.40
|
|
4
4
|
Summary: Common utilities, vocabularies, taxonomies for imio.smartweb & co products
|
|
5
5
|
Home-page: https://github.com/imio/imio.smartweb.common
|
|
6
6
|
Author: iMio
|
|
@@ -178,6 +178,21 @@ Changelog
|
|
|
178
178
|
=========
|
|
179
179
|
|
|
180
180
|
|
|
181
|
+
1.2.40 (2025-11-05)
|
|
182
|
+
-------------------
|
|
183
|
+
|
|
184
|
+
- Catch Exception on geocoding to avoid blocking content creation
|
|
185
|
+
if geopy service is down
|
|
186
|
+
[remdub]
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
1.2.39 (2025-11-03)
|
|
190
|
+
-------------------
|
|
191
|
+
|
|
192
|
+
- Migration to Plone 6.1.3
|
|
193
|
+
[boulch]
|
|
194
|
+
|
|
195
|
+
|
|
181
196
|
1.2.38 (2025-09-10)
|
|
182
197
|
-------------------
|
|
183
198
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
-r https://dist.plone.org/release/6.1.3/requirements.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
-r https://dist.plone.org/release/6.1.3/requirements.txt
|
|
@@ -16,7 +16,7 @@ long_description = "\n\n".join(
|
|
|
16
16
|
|
|
17
17
|
setup(
|
|
18
18
|
name="imio.smartweb.common",
|
|
19
|
-
version="1.2.
|
|
19
|
+
version="1.2.40",
|
|
20
20
|
description="Common utilities, vocabularies, taxonomies for imio.smartweb & co products",
|
|
21
21
|
long_description=long_description,
|
|
22
22
|
# Get more from https://pypi.org/classifiers/
|
|
@@ -53,11 +53,8 @@
|
|
|
53
53
|
<element>code</element>
|
|
54
54
|
<element>charmap</element>
|
|
55
55
|
<element>fullscreen</element>
|
|
56
|
-
<element>hr</element>
|
|
57
56
|
<element>lists</element>
|
|
58
57
|
<element>nonbreaking</element>
|
|
59
|
-
<element>noneditable</element>
|
|
60
|
-
<element>paste</element>
|
|
61
58
|
<element>searchreplace</element>
|
|
62
59
|
<element>table</element>
|
|
63
60
|
<element>visualblocks</element>
|
|
@@ -70,13 +67,7 @@
|
|
|
70
67
|
<record interface="plone.base.interfaces.controlpanel.ITinyMCESchema"
|
|
71
68
|
name="plone.menubar"
|
|
72
69
|
>
|
|
73
|
-
<value purge="true">
|
|
74
|
-
<element>edit</element>
|
|
75
|
-
<element>format</element>
|
|
76
|
-
<element>insert</element>
|
|
77
|
-
<element>table</element>
|
|
78
|
-
<element>view</element>
|
|
79
|
-
</value>
|
|
70
|
+
<value purge="true">edit format insert table view</value>
|
|
80
71
|
</record>
|
|
81
72
|
|
|
82
73
|
<!-- See possible values in https://www.tiny.cloud/docs/tinymce/latest/available-menu-items/ -->
|
|
@@ -106,8 +97,8 @@
|
|
|
106
97
|
"items": ""
|
|
107
98
|
},
|
|
108
99
|
"insert": {
|
|
109
|
-
|
|
110
|
-
|
|
100
|
+
"title": "Insert",
|
|
101
|
+
"items": "hr"
|
|
111
102
|
},
|
|
112
103
|
"table": {
|
|
113
104
|
"title": "Table",
|
|
@@ -25,8 +25,6 @@ class FindEndpointHandler(SearchHandler):
|
|
|
25
25
|
if not types:
|
|
26
26
|
raise Unauthorized("No types found, you are not allowed to search")
|
|
27
27
|
self._constrain_query_by_path(query)
|
|
28
|
-
if not query.get("path"):
|
|
29
|
-
query["path"] = {"query": "/Plone"}
|
|
30
28
|
# query = self._parse_query(query)
|
|
31
29
|
if query.get("type_of_request") == "count_contents_types":
|
|
32
30
|
results = self.count_contents_types(query)
|
|
@@ -164,7 +162,6 @@ class FindEndpointHandler(SearchHandler):
|
|
|
164
162
|
count = counter.get(key, 0)
|
|
165
163
|
percent = (count / total) * 100 if total > 0 else 0
|
|
166
164
|
result[label] = {"count": count, "percent": round(percent, 2)}
|
|
167
|
-
|
|
168
165
|
return result
|
|
169
166
|
|
|
170
167
|
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
from imio.smartweb.common.rest.endpoint import FindEndpointHandler
|
|
3
|
+
from imio.smartweb.common.testing import IMIO_SMARTWEB_COMMON_INTEGRATION_TESTING
|
|
4
|
+
from plone import api
|
|
5
|
+
from plone.app.testing import setRoles
|
|
6
|
+
from plone.app.testing import TEST_USER_ID
|
|
7
|
+
from plone.namedfile.file import NamedBlobFile, NamedBlobImage
|
|
8
|
+
from unittest.mock import patch
|
|
9
|
+
from zExceptions import Unauthorized
|
|
10
|
+
|
|
11
|
+
import unittest
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class TestRestEndpoint(unittest.TestCase):
|
|
15
|
+
layer = IMIO_SMARTWEB_COMMON_INTEGRATION_TESTING
|
|
16
|
+
|
|
17
|
+
def setUp(self):
|
|
18
|
+
self.request = self.layer["request"]
|
|
19
|
+
self.portal = self.layer["portal"]
|
|
20
|
+
|
|
21
|
+
setRoles(self.portal, TEST_USER_ID, ["Manager"])
|
|
22
|
+
# Simule un header d'auth présent dans la requête
|
|
23
|
+
self.request._orig_env = {"HTTP_AUTHORIZATION": "Bearer TEST"}
|
|
24
|
+
self.folder = api.content.create(
|
|
25
|
+
container=self.portal,
|
|
26
|
+
type="Folder",
|
|
27
|
+
title="Folder",
|
|
28
|
+
)
|
|
29
|
+
self.doc1 = api.content.create(
|
|
30
|
+
container=self.folder, type="Document", title="Doc 1"
|
|
31
|
+
)
|
|
32
|
+
self.doc2 = api.content.create(
|
|
33
|
+
container=self.folder, type="Document", title="Doc 2"
|
|
34
|
+
)
|
|
35
|
+
self.page = api.content.create(
|
|
36
|
+
container=self.folder, type="Document", title="Doc 3"
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
def test_no_types(self):
|
|
40
|
+
query = {
|
|
41
|
+
"type_of_request": "count_contents_types",
|
|
42
|
+
"portal_type": "Document",
|
|
43
|
+
"path": {"query": self.portal.absolute_url_path()},
|
|
44
|
+
"operator": "and",
|
|
45
|
+
}
|
|
46
|
+
handler = FindEndpointHandler(self.portal, self.request)
|
|
47
|
+
self.assertRaises(Unauthorized, handler.search, query)
|
|
48
|
+
|
|
49
|
+
# ------------------------------
|
|
50
|
+
# count_contents_types
|
|
51
|
+
# ------------------------------
|
|
52
|
+
@patch("imio.smartweb.common.rest.endpoint.get_json")
|
|
53
|
+
def test_count_contents_types_operator_and(self, mjson):
|
|
54
|
+
mjson.return_value = [
|
|
55
|
+
{
|
|
56
|
+
"@id": f"https://{self.portal.absolute_url()}/@types/Document",
|
|
57
|
+
"addable": "false",
|
|
58
|
+
"id": "Document",
|
|
59
|
+
"immediately_addable": "false",
|
|
60
|
+
"title": "Document",
|
|
61
|
+
}
|
|
62
|
+
]
|
|
63
|
+
handler = FindEndpointHandler(self.portal, self.request)
|
|
64
|
+
query = {
|
|
65
|
+
"type_of_request": "count_contents_types",
|
|
66
|
+
"portal_type": "Document",
|
|
67
|
+
"path": {"query": self.portal.absolute_url_path()},
|
|
68
|
+
"operator": "and",
|
|
69
|
+
}
|
|
70
|
+
res = handler.search(query)
|
|
71
|
+
self.assertEqual(res, {"items": [{"portal_type": "Document", "nb_items": 3}]})
|
|
72
|
+
|
|
73
|
+
# Test without path in query.
|
|
74
|
+
# Path is automaticaly set.
|
|
75
|
+
query = {
|
|
76
|
+
"type_of_request": "count_contents_types",
|
|
77
|
+
"portal_type": "Document",
|
|
78
|
+
"operator": "and",
|
|
79
|
+
}
|
|
80
|
+
res = handler.search(query)
|
|
81
|
+
self.assertEqual(res, {"items": [{"portal_type": "Document", "nb_items": 3}]})
|
|
82
|
+
|
|
83
|
+
@patch("imio.smartweb.common.rest.endpoint.get_json")
|
|
84
|
+
def test_count_contents_types_operator_or_multiple_types(self, mjson):
|
|
85
|
+
mjson.return_value = [
|
|
86
|
+
{
|
|
87
|
+
"@id": f"https://{self.portal.absolute_url()}/@types/Document",
|
|
88
|
+
"addable": "false",
|
|
89
|
+
"id": "Document",
|
|
90
|
+
"immediately_addable": "false",
|
|
91
|
+
"title": "Document",
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"@id": f"https://{self.portal.absolute_url()}/@types/Folder",
|
|
95
|
+
"addable": "false",
|
|
96
|
+
"id": "Folder",
|
|
97
|
+
"immediately_addable": "false",
|
|
98
|
+
"title": "Folder",
|
|
99
|
+
},
|
|
100
|
+
]
|
|
101
|
+
handler = FindEndpointHandler(self.portal, self.request)
|
|
102
|
+
query = {
|
|
103
|
+
"type_of_request": "count_contents_types",
|
|
104
|
+
"portal_type": ["Document", "Folder"],
|
|
105
|
+
"path": {"query": self.portal.absolute_url_path()},
|
|
106
|
+
"operator": "and",
|
|
107
|
+
}
|
|
108
|
+
res = handler.search(query)
|
|
109
|
+
self.assertEqual(
|
|
110
|
+
res, {"items": [{"portal_type": ["Document", "Folder"], "nb_items": 4}]}
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
@patch("imio.smartweb.common.rest.endpoint.get_json")
|
|
114
|
+
def test_get_max_depth(self, mjson):
|
|
115
|
+
mjson.return_value = [
|
|
116
|
+
{
|
|
117
|
+
"@id": f"https://{self.portal.absolute_url()}/@types/Document",
|
|
118
|
+
"addable": "false",
|
|
119
|
+
"id": "Document",
|
|
120
|
+
"immediately_addable": "false",
|
|
121
|
+
"title": "Document",
|
|
122
|
+
}
|
|
123
|
+
]
|
|
124
|
+
handler = FindEndpointHandler(self.portal, self.request)
|
|
125
|
+
res = handler.search({"type_of_request": "get_max_depth"})
|
|
126
|
+
self.assertEqual(res["max_depth"], 3)
|
|
127
|
+
|
|
128
|
+
paths = {i["path"] for i in res["items"]}
|
|
129
|
+
self.assertEqual(
|
|
130
|
+
paths, {"/plone/folder/doc-2", "/plone/folder/doc-3", "/plone/folder/doc-1"}
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
folder2 = api.content.create(
|
|
134
|
+
container=self.folder,
|
|
135
|
+
type="Folder",
|
|
136
|
+
title="Folder 2",
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
api.content.create(
|
|
140
|
+
container=folder2,
|
|
141
|
+
type="Document",
|
|
142
|
+
title="Kamoulox",
|
|
143
|
+
)
|
|
144
|
+
handler = FindEndpointHandler(self.portal, self.request)
|
|
145
|
+
res = handler.search({"type_of_request": "get_max_depth"})
|
|
146
|
+
self.assertEqual(res["max_depth"], 4)
|
|
147
|
+
|
|
148
|
+
paths = {i["path"] for i in res["items"]}
|
|
149
|
+
self.assertEqual(paths, {"/plone/folder/folder-2/kamoulox"})
|
|
150
|
+
|
|
151
|
+
@patch("imio.smartweb.common.rest.endpoint.get_json")
|
|
152
|
+
def test_check_value_of_field_counts_and_percents(self, mjson):
|
|
153
|
+
mjson.return_value = [
|
|
154
|
+
{
|
|
155
|
+
"@id": f"https://{self.portal.absolute_url()}/@types/Document",
|
|
156
|
+
"addable": "false",
|
|
157
|
+
"id": "Document",
|
|
158
|
+
"immediately_addable": "false",
|
|
159
|
+
"title": "Document",
|
|
160
|
+
}
|
|
161
|
+
]
|
|
162
|
+
api.content.create(
|
|
163
|
+
container=self.folder,
|
|
164
|
+
type="Document",
|
|
165
|
+
title="Doc 2",
|
|
166
|
+
)
|
|
167
|
+
handler = FindEndpointHandler(self.portal, self.request)
|
|
168
|
+
q = {
|
|
169
|
+
"type_of_request": "check_value_of_field",
|
|
170
|
+
"portal_type": "Document",
|
|
171
|
+
"field_name": "title",
|
|
172
|
+
"expected_values": ["Doc 1", "Doc 2", "Doc 3"],
|
|
173
|
+
}
|
|
174
|
+
res = handler.search(q)
|
|
175
|
+
# Number
|
|
176
|
+
self.assertEqual(res["Doc 1"]["count"], 1)
|
|
177
|
+
self.assertEqual(res["Doc 2"]["count"], 2)
|
|
178
|
+
self.assertEqual(res["Doc 3"]["count"], 1)
|
|
179
|
+
|
|
180
|
+
# Pourcentages
|
|
181
|
+
self.assertEqual(res["Doc 1"]["percent"], round(1 / 4 * 100, 2)) # 25%
|
|
182
|
+
self.assertEqual(res["Doc 2"]["percent"], round(2 / 4 * 100, 2)) # 50%
|
|
183
|
+
self.assertEqual(res["Doc 3"]["percent"], round(1 / 4 * 100, 2)) # 25%
|
|
184
|
+
|
|
185
|
+
@patch("imio.smartweb.common.rest.endpoint.get_json")
|
|
186
|
+
def test_find_big_files_or_images(self, mjson):
|
|
187
|
+
mjson.return_value = [
|
|
188
|
+
{
|
|
189
|
+
"@id": f"https://{self.portal.absolute_url()}/@types/Image",
|
|
190
|
+
"addable": "false",
|
|
191
|
+
"id": "Image",
|
|
192
|
+
"immediately_addable": "false",
|
|
193
|
+
"title": "Image",
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
"@id": f"https://{self.portal.absolute_url()}/@types/File",
|
|
197
|
+
"addable": "false",
|
|
198
|
+
"id": "File",
|
|
199
|
+
"immediately_addable": "false",
|
|
200
|
+
"title": "File",
|
|
201
|
+
},
|
|
202
|
+
]
|
|
203
|
+
api.content.create(
|
|
204
|
+
container=self.folder,
|
|
205
|
+
type="File",
|
|
206
|
+
id="bigfile",
|
|
207
|
+
title="Big file",
|
|
208
|
+
file=NamedBlobFile(data=b"x" * 2500000, filename="big.pdf"), # 2,5 Mo
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
api.content.create(
|
|
212
|
+
container=self.folder,
|
|
213
|
+
type="Image",
|
|
214
|
+
id="smallimage",
|
|
215
|
+
title="Small image",
|
|
216
|
+
image=NamedBlobImage(data=b"x" * 100000, filename="small.jpg"), # 0,1 Mo
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
api.content.create(
|
|
220
|
+
container=self.folder,
|
|
221
|
+
type="Image",
|
|
222
|
+
id="bigimage",
|
|
223
|
+
title="Big image",
|
|
224
|
+
image=NamedBlobImage(data=b"x" * 3100000, filename="big.jpg"), # 3,1 Mo
|
|
225
|
+
)
|
|
226
|
+
handler = FindEndpointHandler(self.portal, self.request)
|
|
227
|
+
q = {
|
|
228
|
+
"type_of_request": "find_big_files_or_images",
|
|
229
|
+
"portal_type": ["Image", "File"],
|
|
230
|
+
"size": 1000000,
|
|
231
|
+
}
|
|
232
|
+
res = handler.search(q)
|
|
233
|
+
# On attend seulement les gros
|
|
234
|
+
titles = [it["title"] for it in res["items"]]
|
|
235
|
+
self.assertEqual(set(titles), {"Big file", "Big image"})
|
|
236
|
+
# Vérifie calcul Mo arrondi (2_500_000 bytes ≈ 2.38 Mo)
|
|
237
|
+
big_entry = next(i for i in res["items"] if i["title"] == "Big file")
|
|
238
|
+
self.assertAlmostEqual(big_entry["size"], round(2_500_000 / (1024 * 1024), 2))
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
from imio.smartweb.common.testing import IMIO_SMARTWEB_COMMON_ACCEPTANCE_TESTING
|
|
4
|
+
from imio.smartweb.common.rest.utils import batch_results
|
|
5
|
+
from imio.smartweb.common.rest.utils import get_json
|
|
6
|
+
from imio.smartweb.common.rest.utils import hash_md5
|
|
7
|
+
from unittest.mock import patch
|
|
8
|
+
from unittest.mock import Mock
|
|
9
|
+
|
|
10
|
+
import json
|
|
11
|
+
import requests
|
|
12
|
+
import unittest
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class TestRestUtils(unittest.TestCase):
|
|
16
|
+
layer = IMIO_SMARTWEB_COMMON_ACCEPTANCE_TESTING
|
|
17
|
+
|
|
18
|
+
def setUp(self):
|
|
19
|
+
self.request = self.layer["request"]
|
|
20
|
+
self.portal = self.layer["portal"]
|
|
21
|
+
self.portal_url = self.portal.absolute_url()
|
|
22
|
+
self.url = "https://api.kamoulox.test/endpoint"
|
|
23
|
+
|
|
24
|
+
@patch("imio.smartweb.common.rest.utils.requests.get")
|
|
25
|
+
def test_get_json_success(self, mock_get):
|
|
26
|
+
payload = {"ok": True, "items": [1, 2]}
|
|
27
|
+
mock_get.return_value = Mock(status_code=200, text=json.dumps(payload))
|
|
28
|
+
result = get_json(self.url)
|
|
29
|
+
self.assertEqual(result, payload)
|
|
30
|
+
mock_get.assert_called_once()
|
|
31
|
+
(called_url,) = mock_get.call_args[0]
|
|
32
|
+
self.assertEqual(called_url, self.url)
|
|
33
|
+
kwargs = mock_get.call_args.kwargs
|
|
34
|
+
self.assertEqual(kwargs["timeout"], 5)
|
|
35
|
+
self.assertEqual(kwargs["headers"]["Accept"], "application/json")
|
|
36
|
+
self.assertNotIn("Authorization", kwargs["headers"])
|
|
37
|
+
|
|
38
|
+
@patch("imio.smartweb.common.rest.utils.requests.get")
|
|
39
|
+
def test_get_json_non_200_returns_none(self, mock_get):
|
|
40
|
+
mock_get.return_value = Mock(status_code=404, text="Not found")
|
|
41
|
+
result = get_json(self.url)
|
|
42
|
+
self.assertIsNone(result)
|
|
43
|
+
|
|
44
|
+
@patch("imio.smartweb.common.rest.utils.logger")
|
|
45
|
+
@patch("imio.smartweb.common.rest.utils.requests.get")
|
|
46
|
+
def test_get_json_timeout_returns_none_and_logs(self, mock_get, mock_logger):
|
|
47
|
+
mock_get.side_effect = requests.exceptions.Timeout()
|
|
48
|
+
result = get_json(self.url)
|
|
49
|
+
self.assertIsNone(result)
|
|
50
|
+
mock_logger.warning.assert_called_once()
|
|
51
|
+
# check if url is in log
|
|
52
|
+
self.assertIn(self.url, mock_logger.warning.call_args[0][0])
|
|
53
|
+
|
|
54
|
+
@patch("imio.smartweb.common.rest.utils.requests.get")
|
|
55
|
+
def test_get_json_other_exception_returns_none(self, mock_get):
|
|
56
|
+
mock_get.side_effect = RuntimeError("kamoulox")
|
|
57
|
+
result = get_json(self.url)
|
|
58
|
+
self.assertIsNone(result)
|
|
59
|
+
|
|
60
|
+
@patch("imio.smartweb.common.rest.utils.requests.get")
|
|
61
|
+
def test_get_json_sets_auth_header_when_provided(self, mock_get):
|
|
62
|
+
mock_get.return_value = Mock(status_code=200, text="{}")
|
|
63
|
+
auth = "Bearer TOKEN123"
|
|
64
|
+
_ = get_json(self.url, auth=auth, timeout=10)
|
|
65
|
+
mock_get.assert_called_once()
|
|
66
|
+
kwargs = mock_get.call_args.kwargs
|
|
67
|
+
self.assertEqual(kwargs["timeout"], 10)
|
|
68
|
+
self.assertEqual(kwargs["headers"]["Authorization"], auth)
|
|
69
|
+
self.assertEqual(kwargs["headers"]["Accept"], "application/json")
|
|
70
|
+
|
|
71
|
+
@patch("imio.smartweb.common.rest.utils.requests.get")
|
|
72
|
+
def test_get_json_custom_timeout_is_used(self, mock_get):
|
|
73
|
+
mock_get.return_value = Mock(status_code=200, text="{}")
|
|
74
|
+
_ = get_json(self.url, timeout=2.5)
|
|
75
|
+
self.assertEqual(mock_get.call_args.kwargs["timeout"], 2.5)
|
|
76
|
+
|
|
77
|
+
def test_batch_results_exact_division(self):
|
|
78
|
+
data = [1, 2, 3, 4]
|
|
79
|
+
result = batch_results(data, 2)
|
|
80
|
+
self.assertEqual(result, [[1, 2], [3, 4]])
|
|
81
|
+
|
|
82
|
+
def test_batch_results_not_exact(self):
|
|
83
|
+
data = [1, 2, 3, 4, 5]
|
|
84
|
+
result = batch_results(data, 2)
|
|
85
|
+
self.assertEqual(result, [[1, 2], [3, 4], [5]])
|
|
86
|
+
|
|
87
|
+
def test_batch_results_batch_size_larger_than_list(self):
|
|
88
|
+
data = [1, 2, 3]
|
|
89
|
+
result = batch_results(data, 10)
|
|
90
|
+
self.assertEqual(result, [[1, 2, 3]])
|
|
91
|
+
|
|
92
|
+
def test_batch_results_empty_iterable(self):
|
|
93
|
+
data = []
|
|
94
|
+
result = batch_results(data, 3)
|
|
95
|
+
self.assertEqual(result, [])
|
|
96
|
+
|
|
97
|
+
def test_batch_results_with_generator(self):
|
|
98
|
+
gen = (i for i in range(5))
|
|
99
|
+
result = batch_results(gen, 2)
|
|
100
|
+
self.assertEqual(result, [[0, 1], [2, 3], [4]])
|
|
101
|
+
|
|
102
|
+
def test_hash_md5_basic_string(self):
|
|
103
|
+
result = hash_md5("hello")
|
|
104
|
+
self.assertEqual(result, "5d41402abc4b2a76b9719d911017c592")
|
|
105
|
+
|
|
106
|
+
def test_hash_md5_empty_string(self):
|
|
107
|
+
result = hash_md5("")
|
|
108
|
+
self.assertEqual(result, "d41d8cd98f00b204e9800998ecf8427e")
|
|
109
|
+
|
|
110
|
+
def test_hash_md5_unicode_string(self):
|
|
111
|
+
result = hash_md5("éèà")
|
|
112
|
+
# tu peux vérifier avec hashlib directement
|
|
113
|
+
import hashlib
|
|
114
|
+
|
|
115
|
+
expected = hashlib.md5("éèà".encode()).hexdigest()
|
|
116
|
+
self.assertEqual(result, expected)
|
|
@@ -102,6 +102,22 @@ class TestUtils(unittest.TestCase):
|
|
|
102
102
|
self.assertEqual(obj.geolocation.latitude, 1)
|
|
103
103
|
self.assertEqual(obj.geolocation.longitude, 2)
|
|
104
104
|
|
|
105
|
+
def test_geocode_object_geocoder_unavailable(self):
|
|
106
|
+
obj = GeolocatedObject()
|
|
107
|
+
obj.street = "Test Street"
|
|
108
|
+
obj.number = "1"
|
|
109
|
+
obj.complement = ""
|
|
110
|
+
obj.zipcode = "12345"
|
|
111
|
+
obj.city = "Testville"
|
|
112
|
+
obj.country = "be"
|
|
113
|
+
with patch("geopy.geocoders.Nominatim") as mock_nominatim, patch(
|
|
114
|
+
"geopy.exc.GeocoderUnavailable", new=geopy.exc.GeocoderUnavailable
|
|
115
|
+
):
|
|
116
|
+
instance = mock_nominatim.return_value
|
|
117
|
+
instance.geocode.side_effect = geopy.exc.GeocoderUnavailable
|
|
118
|
+
result = geocode_object(obj)
|
|
119
|
+
self.assertFalse(result)
|
|
120
|
+
|
|
105
121
|
def test_get_uncroppable_scales_infos(self):
|
|
106
122
|
folder = api.content.create(
|
|
107
123
|
container=self.portal,
|
|
@@ -165,6 +165,14 @@
|
|
|
165
165
|
directory="profiles/1032_to_1033"
|
|
166
166
|
/>
|
|
167
167
|
|
|
168
|
+
<genericsetup:registerProfile
|
|
169
|
+
name="upgrade_1033_to_1034"
|
|
170
|
+
title="Upgrade common from 1033 to 1034"
|
|
171
|
+
description="Update configuration from TinyMCE 7.7.0 to be TinyMCE 7.9.1"
|
|
172
|
+
provides="Products.GenericSetup.interfaces.EXTENSION"
|
|
173
|
+
directory="profiles/1033_to_1034"
|
|
174
|
+
/>
|
|
175
|
+
|
|
168
176
|
<genericsetup:upgradeStep
|
|
169
177
|
title="Configure first official release"
|
|
170
178
|
description="Run needed registry step"
|
|
@@ -515,4 +523,15 @@
|
|
|
515
523
|
/>
|
|
516
524
|
</genericsetup:upgradeSteps>
|
|
517
525
|
|
|
526
|
+
<genericsetup:upgradeSteps
|
|
527
|
+
profile="imio.smartweb.common:default"
|
|
528
|
+
source="1033"
|
|
529
|
+
destination="1034"
|
|
530
|
+
>
|
|
531
|
+
<genericsetup:upgradeDepends
|
|
532
|
+
title="Update configuration from TinyMCE 7.7.0 to be TinyMCE 7.9.1"
|
|
533
|
+
import_profile="imio.smartweb.common.upgrades:upgrade_1033_to_1034"
|
|
534
|
+
/>
|
|
535
|
+
</genericsetup:upgradeSteps>
|
|
536
|
+
|
|
518
537
|
</configure>
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<registry>
|
|
3
|
+
|
|
4
|
+
<record interface="plone.base.interfaces.controlpanel.ITinyMCESchema"
|
|
5
|
+
name="plone.plugins"
|
|
6
|
+
>
|
|
7
|
+
<value purge="true">
|
|
8
|
+
<element>code</element>
|
|
9
|
+
<element>charmap</element>
|
|
10
|
+
<element>fullscreen</element>
|
|
11
|
+
<element>lists</element>
|
|
12
|
+
<element>nonbreaking</element>
|
|
13
|
+
<element>searchreplace</element>
|
|
14
|
+
<element>table</element>
|
|
15
|
+
<element>visualblocks</element>
|
|
16
|
+
<element>visualchars</element>
|
|
17
|
+
<element>wordcount</element>
|
|
18
|
+
</value>
|
|
19
|
+
</record>
|
|
20
|
+
|
|
21
|
+
<!-- See possible values in https://www.tiny.cloud/docs/tinymce/latest/menus-configuration-options/#menubar -->
|
|
22
|
+
<record interface="plone.base.interfaces.controlpanel.ITinyMCESchema"
|
|
23
|
+
name="plone.menubar">
|
|
24
|
+
<value purge="true">edit format insert table view</value>
|
|
25
|
+
</record>
|
|
26
|
+
|
|
27
|
+
<record interface="plone.base.interfaces.controlpanel.ITinyMCESchema"
|
|
28
|
+
name="plone.menu">
|
|
29
|
+
<value purge="true">
|
|
30
|
+
{
|
|
31
|
+
"file": {
|
|
32
|
+
"title": "File",
|
|
33
|
+
"items": ""
|
|
34
|
+
},
|
|
35
|
+
"tools": {
|
|
36
|
+
"title": "Tools",
|
|
37
|
+
"items": ""
|
|
38
|
+
},
|
|
39
|
+
"edit": {
|
|
40
|
+
"title": "Edit",
|
|
41
|
+
"items": "undo redo | cut copy paste | searchreplace selectall"
|
|
42
|
+
},
|
|
43
|
+
"format": {
|
|
44
|
+
"title": "Format",
|
|
45
|
+
"items": ""
|
|
46
|
+
},
|
|
47
|
+
"insert": {
|
|
48
|
+
"title": "Insert",
|
|
49
|
+
"items": "hr"
|
|
50
|
+
},
|
|
51
|
+
"table": {
|
|
52
|
+
"title": "Table",
|
|
53
|
+
"items": "inserttable deletetable | cell row column"
|
|
54
|
+
},
|
|
55
|
+
"view": {
|
|
56
|
+
"title": "View",
|
|
57
|
+
"items": "visualblocks preview fullscreen"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
</value>
|
|
61
|
+
</record>
|
|
62
|
+
|
|
63
|
+
<!-- See possible values in https://www.tiny.cloud/docs/tinymce/latest/available-toolbar-buttons/ -->
|
|
64
|
+
<record interface="plone.base.interfaces.controlpanel.ITinyMCESchema"
|
|
65
|
+
name="plone.toolbar"
|
|
66
|
+
>
|
|
67
|
+
<value>undo redo | styleselect | bold italic superscript | bullist numlist | nonbreaking | plonelink unlink | fullscreen</value>
|
|
68
|
+
</record>
|
|
69
|
+
|
|
70
|
+
</registry>
|
{imio_smartweb_common-1.2.38 → imio_smartweb_common-1.2.40}/src/imio/smartweb/common/utils.py
RENAMED
|
@@ -14,6 +14,7 @@ from plone.namedfile.field import NamedBlobImage
|
|
|
14
14
|
from plone.namedfile.interfaces import IAvailableSizes
|
|
15
15
|
from urllib.parse import urlparse
|
|
16
16
|
from zope.component import getUtility
|
|
17
|
+
from zope.globalrequest import getRequest
|
|
17
18
|
from zope.i18n import translate
|
|
18
19
|
from zope.schema import getFields
|
|
19
20
|
from zope.schema.interfaces import IVocabularyFactory
|
|
@@ -77,7 +78,18 @@ def geocode_object(obj):
|
|
|
77
78
|
if not address:
|
|
78
79
|
return
|
|
79
80
|
geolocator = geopy.geocoders.Nominatim(user_agent="contact@imio.be", timeout=3)
|
|
80
|
-
location =
|
|
81
|
+
location = None
|
|
82
|
+
try:
|
|
83
|
+
location = geolocator.geocode(address)
|
|
84
|
+
except geopy.exc.GeocoderUnavailable:
|
|
85
|
+
api.portal.show_message(
|
|
86
|
+
_(
|
|
87
|
+
"Error: Geolocation service is unavailable. Your content is not geocoded."
|
|
88
|
+
),
|
|
89
|
+
request=getRequest(),
|
|
90
|
+
type="warning",
|
|
91
|
+
)
|
|
92
|
+
return False
|
|
81
93
|
if location:
|
|
82
94
|
obj.geolocation = Geolocation(
|
|
83
95
|
latitude=location.latitude, longitude=location.longitude
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: imio.smartweb.common
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.40
|
|
4
4
|
Summary: Common utilities, vocabularies, taxonomies for imio.smartweb & co products
|
|
5
5
|
Home-page: https://github.com/imio/imio.smartweb.common
|
|
6
6
|
Author: iMio
|
|
@@ -178,6 +178,21 @@ Changelog
|
|
|
178
178
|
=========
|
|
179
179
|
|
|
180
180
|
|
|
181
|
+
1.2.40 (2025-11-05)
|
|
182
|
+
-------------------
|
|
183
|
+
|
|
184
|
+
- Catch Exception on geocoding to avoid blocking content creation
|
|
185
|
+
if geopy service is down
|
|
186
|
+
[remdub]
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
1.2.39 (2025-11-03)
|
|
190
|
+
-------------------
|
|
191
|
+
|
|
192
|
+
- Migration to Plone 6.1.3
|
|
193
|
+
[boulch]
|
|
194
|
+
|
|
195
|
+
|
|
181
196
|
1.2.38 (2025-09-10)
|
|
182
197
|
-------------------
|
|
183
198
|
|