diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..d054af1 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,56 @@ +# Generated from: +# https://github.com/plone/meta/tree/main/src/plone/meta/default +# See the inline comments on how to expand/tweak this configuration file +# +# EditorConfig Configuration file, for more details see: +# http://EditorConfig.org +# EditorConfig is a convention description, that could be interpreted +# by multiple editors to enforce common coding conventions for specific +# file types + +# top-most EditorConfig file: +# Will ignore other EditorConfig files in Home directory or upper tree level. +root = true + + +[*] +# Default settings for all files. +# Unix-style newlines with a newline ending every file +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +# Set default charset +charset = utf-8 +# Indent style default +indent_style = space +# Max Line Length - a hard line wrap, should be disabled +max_line_length = off + +[*.{py,cfg,ini}] +# 4 space indentation +indent_size = 4 + +[*.{yml,zpt,pt,dtml,zcml,html,xml}] +# 2 space indentation +indent_size = 2 + +[*.{json,jsonl,js,jsx,ts,tsx,css,less,scss}] +# Frontend development +# 2 space indentation +indent_size = 2 +max_line_length = 80 + +[{Makefile,.gitmodules}] +# Tab indentation (no size specified, but view as 4 spaces) +indent_style = tab +indent_size = unset +tab_width = unset + + +## +# Add extra configuration options in .meta.toml: +# [editorconfig] +# extra_lines = """ +# _your own configuration lines_ +# """ +## diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..3e2d35f --- /dev/null +++ b/.flake8 @@ -0,0 +1,22 @@ +# Generated from: +# https://github.com/plone/meta/tree/main/src/plone/meta/default +# See the inline comments on how to expand/tweak this configuration file +[flake8] +doctests = 1 +ignore = + # black takes care of line length + E501, + # black takes care of where to break lines + W503, + # black takes care of spaces within slicing (list[:]) + E203, + # black takes care of spaces after commas + E231, + +## +# Add extra configuration options in .meta.toml: +# [flake8] +# extra_lines = """ +# _your own configuration lines_ +# """ +## diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..e5e4522 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +# Generated from: +# https://github.com/plone/meta/tree/main/src/plone/meta/default +# See the inline comments on how to expand/tweak this configuration file +version: 2 +updates: + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + # Check for updates to GitHub Actions every week + interval: "weekly" diff --git a/.github/workflows/meta.yml b/.github/workflows/meta.yml new file mode 100644 index 0000000..f9a346f --- /dev/null +++ b/.github/workflows/meta.yml @@ -0,0 +1,65 @@ +# Generated from: +# https://github.com/plone/meta/tree/main/src/plone/meta/default +# See the inline comments on how to expand/tweak this configuration file +name: Meta +on: + push: + branches: + - master + - main + pull_request: + branches: + - master + - main + workflow_dispatch: + +## +# To set environment variables for all jobs, add in .meta.toml: +# [github] +# env = """ +# debug: 1 +# image-name: 'org/image' +# image-tag: 'latest' +# """ +## + +jobs: + qa: + uses: plone/meta/.github/workflows/qa.yml@2.x + coverage: + uses: plone/meta/.github/workflows/coverage.yml@2.x + dependencies: + uses: plone/meta/.github/workflows/dependencies.yml@2.x + release_ready: + uses: plone/meta/.github/workflows/release_ready.yml@2.x + circular: + uses: plone/meta/.github/workflows/circular.yml@2.x + +## +# To modify the list of default jobs being created add in .meta.toml: +# [github] +# jobs = [ +# "qa", +# "coverage", +# "dependencies", +# "release_ready", +# "circular", +# ] +## + +## +# To request that some OS level dependencies get installed +# when running tests/coverage jobs, add in .meta.toml: +# [github] +# os_dependencies = "git libxml2 libxslt" +## + + +## +# Specify additional jobs in .meta.toml: +# [github] +# extra_lines = """ +# another: +# uses: org/repo/.github/workflows/file.yml@main +# """ +## diff --git a/.github/workflows/test-matrix.yml b/.github/workflows/test-matrix.yml new file mode 100644 index 0000000..8b2da2b --- /dev/null +++ b/.github/workflows/test-matrix.yml @@ -0,0 +1,72 @@ +# Generated from: +# https://github.com/plone/meta/tree/main/src/plone/meta/default +# See the inline comments on how to expand/tweak this configuration file +name: Tests + +on: + push: + +jobs: + build: + permissions: + contents: read + pull-requests: write + strategy: + # We want to see all failures: + fail-fast: false + matrix: + os: + - ["ubuntu", "ubuntu-latest"] + config: + # [Python version, visual name, tox env] + - ["3.14", "6.2 on py3.14", "py314-plone62"] + - ["3.10", "6.2 on py3.10", "py310-plone62"] + + runs-on: ${{ matrix.os[1] }} + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name + name: ${{ matrix.config[1] }} + steps: + - uses: actions/checkout@v6 + with: + persist-credentials: false + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: ${{ matrix.config[0] }} + allow-prereleases: true + +## +# Add extra configuration options in .meta.toml: +# [github] +# extra_lines_after_os_dependencies = """ +# _your own configuration lines_ +# """ +## + - name: Pip cache + uses: actions/cache@v5 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ matrix.config[0] }}-${{ hashFiles('setup.*', 'tox.ini') }} + restore-keys: | + ${{ runner.os }}-pip-${{ matrix.config[0] }}- + ${{ runner.os }}-pip- + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install tox + - name: Initialize tox + # the bash one-liner below does not work on Windows + if: contains(matrix.os, 'ubuntu') + run: | + if [ `tox list --no-desc -f init|wc -l` = 1 ]; then tox -e init;else true; fi + - name: Test + run: tox -e ${{ matrix.config[2] }} + + +## +# Add extra configuration options in .meta.toml: +# [github] +# extra_lines = """ +# _your own configuration lines_ +# """ +## diff --git a/.gitignore b/.gitignore index 2f45716..a602abe 100644 --- a/.gitignore +++ b/.gitignore @@ -1,23 +1,58 @@ -# Buildout +# Generated from: +# https://github.com/plone/meta/tree/main/src/plone/meta/default +# See the inline comments on how to expand/tweak this configuration file +# python related +*.egg-info *.pyc *.pyo -*.tmp* + +# translation related *.mo -*.egg -*.EGG -*.egg-info -*.EGG-INFO -.*.cfg -bin/ + +# tools related build/ +.coverage +.*project +coverage.xml +dist/ +docs/_build +__pycache__/ +.tox +.vscode/ +node_modules/ +forest.dot +forest.json + +# venv / buildout related +bin/ develop-eggs/ -downloads/ eggs/ -fake-eggs/ +.eggs/ +etc/ +.installed.cfg +include/ +lib/ +lib64 +.mr.developer.cfg parts/ -dist/ +pyvenv.cfg var/ -venv/ +local.cfg + +# mxdev +/instance/ +/.make-sentinels/ +/*-mxdev.txt +/reports/ +/sources/ +/venv/ +.installed.txt + -# Visual Code -*.code-workspace +## +# Add extra configuration options in .meta.toml: +# [gitignore] +# extra_lines = """ +# _your own configuration lines_ +# """ +## diff --git a/.meta.toml b/.meta.toml new file mode 100644 index 0000000..2351631 --- /dev/null +++ b/.meta.toml @@ -0,0 +1,13 @@ +# Generated from: +# https://github.com/plone/meta/tree/main/src/plone/meta/default +# See the inline comments on how to expand/tweak this configuration file +[meta] +template = "default" +commit-id = "2.5.1" + +[tox] +test_matrix = { "6.2" = ["*"] } +skip_test_extra = true + +[pyproject] +dependencies_ignores = "['plone.app.multilingual']" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..2e8482b --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,94 @@ +# Generated from: +# https://github.com/plone/meta/tree/main/src/plone/meta/default +# See the inline comments on how to expand/tweak this configuration file +ci: + autofix_prs: false + autoupdate_schedule: monthly + +repos: +- repo: https://github.com/asottile/pyupgrade + rev: v3.21.2 + hooks: + - id: pyupgrade + args: [--py310-plus] +- repo: https://github.com/pycqa/isort + rev: 8.0.1 + hooks: + - id: isort +- repo: https://github.com/psf/black-pre-commit-mirror + rev: 26.1.0 + hooks: + - id: black +- repo: https://github.com/collective/zpretty + rev: 3.1.1 + hooks: + - id: zpretty + +## +# Add extra configuration options in .meta.toml: +# [pre_commit] +# zpretty_extra_lines = """ +# _your own configuration lines_ +# """ +## +- repo: https://github.com/PyCQA/flake8 + rev: 7.3.0 + hooks: + - id: flake8 + +## +# Add extra configuration options in .meta.toml: +# [pre_commit] +# flake8_extra_lines = """ +# _your own configuration lines_ +# """ +## +- repo: https://github.com/codespell-project/codespell + rev: v2.4.1 + hooks: + - id: codespell + additional_dependencies: + - tomli + +## +# Add extra configuration options in .meta.toml: +# [pre_commit] +# codespell_extra_lines = """ +# _your own configuration lines_ +# """ +## +- repo: https://github.com/mgedmin/check-manifest + rev: "0.51" + hooks: + - id: check-manifest +- repo: https://github.com/regebro/pyroma + rev: "5.0.1" + hooks: + - id: pyroma +- repo: https://github.com/mgedmin/check-python-versions + rev: "0.24.0" + hooks: + - id: check-python-versions + args: ['--only', 'setup.py,pyproject.toml'] +- repo: https://github.com/collective/i18ndude + rev: "6.3.0" + hooks: + - id: i18ndude + + +## +# Add extra configuration options in .meta.toml: +# [pre_commit] +# i18ndude_extra_lines = """ +# _your own configuration lines_ +# """ +## + + +## +# Add extra configuration options in .meta.toml: +# [pre_commit] +# extra_lines = """ +# _your own configuration lines_ +# """ +## diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index c5eb893..0000000 --- a/.travis.yml +++ /dev/null @@ -1,51 +0,0 @@ -language: python -sudo: false -addons: - chrome: stable -matrix: - include: - - python: "2.7" - env: PLONE_VERSION=5.1.x - - python: "2.7" - env: PLONE_VERSION=5.2.x - - python: "3.6" - env: PLONE_VERSION=5.2.x - - python: "3.7" - env: PLONE_VERSION=5.2.x - dist: xenial - sudo: true -cache: - pip: true - directories: - - eggs - - downloads -before_install: -# install chrome webdriver - - mkdir webdriver; - wget https://chromedriver.storage.googleapis.com/2.40/chromedriver_linux64.zip; - unzip chromedriver_linux64.zip -d webdriver; - export PATH=$PATH:$(pwd)/webdriver; - - mkdir -p $HOME/buildout-cache/{eggs,downloads} - - mkdir $HOME/.buildout - - echo "[buildout]" > $HOME/.buildout/default.cfg - - echo "download-cache = $HOME/buildout-cache/downloads" >> $HOME/.buildout/default.cfg - - echo "eggs-directory = $HOME/buildout-cache/eggs" >> $HOME/.buildout/default.cfg - - pip install zc.buildout - - sed -ie "s#5.1.x.cfg#$PLONE_VERSION.cfg#" buildout.cfg -install: - - buildout -N annotate - - buildout -N -before_script: - - 'export DISPLAY=:99.0' - - Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & - - sleep 3 -script: -# Run code-analysis, except on Python 3.6, which mysteriously fails to find zc.buildout. - - python --version 2> /dev/stdout | grep 3.6 || bin/code-analysis - - bin/test -after_success: - - bin/createcoverage -t "--layer=!Robot" - - pip install --upgrade coveralls - - coveralls -notifications: - irc: irc.freenode.org#plone-testing diff --git a/CHANGES.rst b/CHANGES.rst index 1556ca5..6692fc3 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,9 +2,18 @@ Changelog ========= -1.7.3 (unreleased) +3.0.0 (unreleased) ------------------ +- Breaking: Plone 6.2 only + [erral] + +- src-layout, native-namespaces + [erral] + +- configure with plone.meta + [erral] + - Add Spanish translation [macagua] @@ -58,7 +67,7 @@ Changelog 1.5.1 (2017-04-04) ------------------ -- Explicitly include necessary zcml dependencies to avoid having to explictly doing that in tests. +- Explicitly include necessary zcml dependencies to avoid having to explicitly doing that in tests. plone.app.testing disables z3c.autoinclude. [thet] @@ -67,7 +76,7 @@ Changelog ---------------- - Register the ``collective.geolocationbehavior.geolocation.IGeolocatable`` behavior under the name ``geolocatable``. - Do not bind ``for`` because its superfluos. + Do not bind ``for`` because its superfluous. [thet, jensens] - Code cleanup, remove BBB classes. diff --git a/MANIFEST.in b/MANIFEST.in index fe925e8..53c338d 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,4 +1,4 @@ -recursive-include collective * +recursive-include src * recursive-include docs * include * global-exclude *.pyc diff --git a/README.rst b/README.rst index 736b6d5..660522d 100644 --- a/README.rst +++ b/README.rst @@ -63,7 +63,44 @@ This product has been translated into: Installation ============ -Install ``collective.geolocationbehavior`` by adding it to your buildout: +If you installed Plone with `Cookieplone`_, you can install ``collective.geolocationbehavior`` add-on +from a source control system such as GitHub. + +Add a line with ``collective.geolocationbehavior`` in the ``backend/requirements.txt`` file. + +:: + + collective.geolocationbehavior + +Next add the add-on to ``zcml_package_includes`` in the file ``backend/instance.yaml`` so +that its configuration will load. + +:: + + default_context: + zcml_package_includes: project_title, collective.geolocationbehavior + +Finally, add the package's source to the ``mx.ini`` file. + +:: + + [collective.geolocationbehavior] + url = https://github.com/collective/collective.geolocationbehavior.git + pushurl = git@github.com:collective/collective.geolocationbehavior.git + branch = master + +To actually download and install the new add-on, run the following command. + +:: + + make backend-build + +Now restart the backend. + +---- + +If you installed Plone with `buildout`_, you can install ``collective.geolocationbehavior`` add-on +by adding it to your ``buildout`` eggs list like so: :: @@ -75,7 +112,9 @@ Install ``collective.geolocationbehavior`` by adding it to your buildout: collective.geolocationbehavior -and then running "bin/buildout". +and then running ``bin/buildout`` + +Now restart the instance. Contribute @@ -95,3 +134,6 @@ License ======= The project is licensed under the `GPLv2 `_. + +.. _Cookieplone: https://github.com/plone/cookieplone +.. _buildout: https://6.docs.plone.org/admin-guide/add-ons.html#buildout diff --git a/collective/__init__.py b/collective/__init__.py deleted file mode 100644 index de40ea7..0000000 --- a/collective/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__import__('pkg_resources').declare_namespace(__name__) diff --git a/collective/geolocationbehavior/__init__.py b/collective/geolocationbehavior/__init__.py deleted file mode 100644 index 53685c4..0000000 --- a/collective/geolocationbehavior/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from zope.i18nmessageid import MessageFactory - -_ = MessageFactory('collective.geolocationbehavior') diff --git a/collective/geolocationbehavior/profiles/default/catalog.xml b/collective/geolocationbehavior/profiles/default/catalog.xml deleted file mode 100644 index a85cb15..0000000 --- a/collective/geolocationbehavior/profiles/default/catalog.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..122c701 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,132 @@ +# Generated from: +# https://github.com/plone/meta/tree/main/src/plone/meta/default +# See the inline comments on how to expand/tweak this configuration file +[build-system] +requires = ["setuptools>=68.2,<83", "wheel"] + +## +# Add extra configuration options in .meta.toml: +# [pyproject] +# towncrier_extra_lines = """ +# extra_configuration +# """ +## + +[tool.isort] +profile = "plone" + +## +# Add extra configuration options in .meta.toml: +# [pyproject] +# isort_extra_lines = """ +# extra_configuration +# """ +## + +[tool.black] +target-version = ["py310"] + +## +# Add extra configuration options in .meta.toml: +# [pyproject] +# black_extra_lines = """ +# extra_configuration +# """ +## + +[tool.codespell] +ignore-words-list = "discreet,assertin,thet," +skip = "*.po," +## +# Add extra configuration options in .meta.toml: +# [pyproject] +# codespell_ignores = "foo,bar" +# codespell_skip = "*.po,*.map,package-lock.json" +## + +[tool.dependencychecker] +Zope = [ + # Zope own provided namespaces + 'App', 'OFS', 'Products.Five', 'Products.OFSP', 'Products.PageTemplates', + 'Products.SiteAccess', 'Shared', 'Testing', 'ZPublisher', 'ZTUtils', + 'Zope2', 'webdav', 'zmi', + # ExtensionClass own provided namespaces + 'ExtensionClass', 'ComputedAttribute', 'MethodObject', + # Zope dependencies + 'AccessControl', 'Acquisition', 'AuthEncoding', 'beautifulsoup4', 'BTrees', + 'cffi', 'Chameleon', 'DateTime', 'DocumentTemplate', + 'MultiMapping', 'multipart', 'PasteDeploy', 'Persistence', 'persistent', + 'pycparser', 'python-gettext', 'pytz', 'RestrictedPython', 'roman', + 'soupsieve', 'transaction', 'waitress', 'WebOb', 'WebTest', 'WSGIProxy2', + 'z3c.pt', 'zc.lockfile', 'ZConfig', 'zExceptions', 'ZODB', 'zodbpickle', + 'zope.annotation', 'zope.browser', 'zope.browsermenu', 'zope.browserpage', + 'zope.browserresource', 'zope.cachedescriptors', 'zope.component', + 'zope.configuration', 'zope.container', 'zope.contentprovider', + 'zope.contenttype', 'zope.datetime', 'zope.deferredimport', + 'zope.deprecation', 'zope.dottedname', 'zope.event', 'zope.exceptions', + 'zope.filerepresentation', 'zope.globalrequest', 'zope.hookable', + 'zope.i18n', 'zope.i18nmessageid', 'zope.interface', 'zope.lifecycleevent', + 'zope.location', 'zope.pagetemplate', 'zope.processlifetime', 'zope.proxy', + 'zope.ptresource', 'zope.publisher', 'zope.schema', 'zope.security', + 'zope.sequencesort', 'zope.site', 'zope.size', 'zope.structuredtext', + 'zope.tal', 'zope.tales', 'zope.testbrowser', 'zope.testing', + 'zope.traversing', 'zope.viewlet' +] +'Products.CMFCore' = [ + 'docutils', 'five.localsitemanager', 'Missing', 'Products.BTreeFolder2', + 'Products.GenericSetup', 'Products.MailHost', 'Products.PythonScripts', + 'Products.StandardCacheManagers', 'Products.ZCatalog', 'Record', + 'zope.sendmail', 'Zope' +] +'plone.base' = [ + 'plone.batching', 'plone.registry', 'plone.schema','plone.z3cform', + 'Products.CMFCore', 'Products.CMFDynamicViewFTI', +] +python-dateutil = ['dateutil'] +pytest-plone = ['pytest', 'zope.pytestlayer', 'plone.testing', 'plone.app.testing'] +ignore-packages = ['plone.app.multilingual'] + +## +# Add extra configuration options in .meta.toml: +# [pyproject] +# dependencies_ignores = "['zestreleaser.towncrier']" +# dependencies_mappings = [ +# "gitpython = ['git']", +# "pygithub = ['github']", +# ] +## + +[tool.check-manifest] +ignore = [ + ".editorconfig", + ".flake8", + ".meta.toml", + ".pre-commit-config.yaml", + "dependabot.yml", + "mx.ini", + "tox.ini", + +] + +## +# Add extra configuration options in .meta.toml: +# [pyproject] +# check_manifest_ignores = """ +# "*.map.js", +# "*.pyc", +# """ +# check_manifest_extra_lines = """ +# ignore-bad-ideas = [ +# "some/test/file/PKG-INFO", +# ] +# """ +## + + +## +# Add extra configuration options in .meta.toml: +# [pyproject] +# extra_lines = """ +# _your own configuration lines_ +# """ +## diff --git a/setup.py b/setup.py index 20fc23a..3fd1480 100644 --- a/setup.py +++ b/setup.py @@ -1,52 +1,54 @@ -from setuptools import setup, find_packages +from setuptools import setup - -version = '1.7.3.dev0' +version = "3.0.0.dev0" setup( - name='collective.geolocationbehavior', + name="collective.geolocationbehavior", version=version, description="Dexterity behavior to add geographic locations to contents.", - long_description="{0}\n{1}".format( - open("README.rst").read(), - open("CHANGES.rst").read() + long_description="{}\n{}".format( + open("README.rst").read(), open("CHANGES.rst").read() ), classifiers=[ "Framework :: Plone", - "Framework :: Plone :: 5.1", - "Framework :: Plone :: 5.2", - "Framework :: Plone :: 6.0", + "Framework :: Plone :: 6.2", "Framework :: Plone :: Addon", "Programming Language :: Python", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Topic :: Software Development :: Libraries :: Python Modules", "Development Status :: 5 - Production/Stable", "License :: OSI Approved :: GNU General Public License v2 (GPLv2)", ], - keywords='plone dexterity behavior geographic locations contents', - author='Jesse Snyder, davisagli et al', - url='https://github.com/collective/collective.geolocationbehavior/', - license='GPL', - packages=find_packages(exclude=['ez_setup']), - namespace_packages=['collective'], + keywords="plone dexterity behavior geographic locations contents", + author="Jesse Snyder, davisagli et al", + author_email="collective@plone.org", + url="https://github.com/collective/collective.geolocationbehavior/", + license="GPL", include_package_data=True, zip_safe=False, + python_requires=">=3.10", install_requires=[ - 'setuptools', # Dependencies for the behavior and form - 'plone.app.dexterity', # remove this one to get a generic behavior - 'plone.autoform', - 'plone.behavior', - 'plone.dexterity', - 'plone.formwidget.geolocation', - 'plone.supermodel', + "plone.app.dexterity", # remove this one to get a generic behavior + "plone.autoform", + "plone.behavior", + "plone.formwidget.geolocation", + "plone.supermodel", # Framework dependencies - 'zope.annotation', - 'zope.component', - 'zope.interface', + "zope.annotation", + "zope.component", + "zope.interface", + "Products.CMFCore", + "Products.GenericSetup", + "plone.browserlayer", + "plone.indexer", + "plone.uuid", + "zope.i18nmessageid", + "zope.lifecycleevent", + "zope.event", ], entry_points=""" [z3c.autoinclude.plugin] diff --git a/src/collective/geolocationbehavior/__init__.py b/src/collective/geolocationbehavior/__init__.py new file mode 100644 index 0000000..4c929fb --- /dev/null +++ b/src/collective/geolocationbehavior/__init__.py @@ -0,0 +1,3 @@ +from zope.i18nmessageid import MessageFactory + +_ = MessageFactory("collective.geolocationbehavior") diff --git a/collective/geolocationbehavior/configure.zcml b/src/collective/geolocationbehavior/configure.zcml similarity index 87% rename from collective/geolocationbehavior/configure.zcml rename to src/collective/geolocationbehavior/configure.zcml index 876676b..583ea14 100644 --- a/collective/geolocationbehavior/configure.zcml +++ b/src/collective/geolocationbehavior/configure.zcml @@ -3,12 +3,16 @@ xmlns:genericsetup="http://namespaces.zope.org/genericsetup" xmlns:i18n="http://namespaces.zope.org/i18n" xmlns:plone="http://namespaces.plone.org/plone" - i18n_domain="collective.geolocationbehavior"> + i18n_domain="collective.geolocationbehavior" + > - - + + diff --git a/collective/geolocationbehavior/geolocation.py b/src/collective/geolocationbehavior/geolocation.py similarity index 67% rename from collective/geolocationbehavior/geolocation.py rename to src/collective/geolocationbehavior/geolocation.py index fc26781..d42299d 100644 --- a/collective/geolocationbehavior/geolocation.py +++ b/src/collective/geolocationbehavior/geolocation.py @@ -8,44 +8,51 @@ from zope.interface import implementer from zope.interface import Interface from zope.interface import provider + import pkg_resources + try: - pkg_resources.get_distribution('plone.app.multilingual') + pkg_resources.get_distribution("plone.app.multilingual") except pkg_resources.DistributionNotFound: HAS_PAM = False else: - from zope.interface import alsoProvides from plone.app.multilingual.dx.interfaces import ILanguageIndependentField + from zope.interface import alsoProvides + HAS_PAM = True @provider(IFormFieldProvider) class IGeolocatable(model.Schema): """Form field for geolocation behavior""" + geolocation = GeolocationField( - title=_('label_geolocation', default=u'Geolocation'), - description=_('help_geolocation', - default=u'Click on the map to select a location, or ' - u'use the text input to search by address.'), - required=False) + title=_("label_geolocation", default="Geolocation"), + description=_( + "help_geolocation", + default="Click on the map to select a location, or " + "use the text input to search by address.", + ), + required=False, + ) if HAS_PAM: - alsoProvides(IGeolocatable['geolocation'], ILanguageIndependentField) + alsoProvides(IGeolocatable["geolocation"], ILanguageIndependentField) @adapter(Interface) @implementer(IGeoJSONProperties) -class GeoJSONProperties(object): +class GeoJSONProperties: def __init__(self, context): self.context = context @property def popup(self): - return u""" -
{1}
-

{2}

""".format( + return """ +
{}
+

{}

""".format( self.context.absolute_url(), self.context.Title(), self.context.Description(), @@ -53,8 +60,8 @@ def popup(self): @property def color(self): - return 'green' + return "green" @property def extraClasses(self): - return 'uuid-{0}'.format(IUUID(self.context)) + return f"uuid-{IUUID(self.context)}" diff --git a/collective/geolocationbehavior/indexer.py b/src/collective/geolocationbehavior/indexer.py similarity index 100% rename from collective/geolocationbehavior/indexer.py rename to src/collective/geolocationbehavior/indexer.py diff --git a/collective/geolocationbehavior/interfaces.py b/src/collective/geolocationbehavior/interfaces.py similarity index 68% rename from collective/geolocationbehavior/interfaces.py rename to src/collective/geolocationbehavior/interfaces.py index 81a28b0..1e3e868 100644 --- a/collective/geolocationbehavior/interfaces.py +++ b/src/collective/geolocationbehavior/interfaces.py @@ -3,9 +3,10 @@ class IGeoJSONProperties(Interface): - """Adapter adapting an content object for determining geojson properties. - """ + """Adapter adapting an content object for determining geojson properties.""" popup = Attribute("Return a string to display in the marker popup.") color = Attribute("Return the marker color.") - extraClasses = Attribute("Return a string of extra css classes to be added to the marker icon.") # noqa + extraClasses = Attribute( + "Return a string of extra css classes to be added to the marker icon." + ) # noqa diff --git a/collective/geolocationbehavior/locales/collective.geolocationbehavior.pot b/src/collective/geolocationbehavior/locales/collective.geolocationbehavior.pot similarity index 100% rename from collective/geolocationbehavior/locales/collective.geolocationbehavior.pot rename to src/collective/geolocationbehavior/locales/collective.geolocationbehavior.pot diff --git a/collective/geolocationbehavior/locales/de/LC_MESSAGES/collective.geolocationbehavior.po b/src/collective/geolocationbehavior/locales/de/LC_MESSAGES/collective.geolocationbehavior.po similarity index 100% rename from collective/geolocationbehavior/locales/de/LC_MESSAGES/collective.geolocationbehavior.po rename to src/collective/geolocationbehavior/locales/de/LC_MESSAGES/collective.geolocationbehavior.po diff --git a/collective/geolocationbehavior/locales/es/LC_MESSAGES/collective.geolocationbehavior.po b/src/collective/geolocationbehavior/locales/es/LC_MESSAGES/collective.geolocationbehavior.po similarity index 100% rename from collective/geolocationbehavior/locales/es/LC_MESSAGES/collective.geolocationbehavior.po rename to src/collective/geolocationbehavior/locales/es/LC_MESSAGES/collective.geolocationbehavior.po diff --git a/collective/geolocationbehavior/locales/fr/LC_MESSAGES/collective.geolocationbehavior.po b/src/collective/geolocationbehavior/locales/fr/LC_MESSAGES/collective.geolocationbehavior.po similarity index 100% rename from collective/geolocationbehavior/locales/fr/LC_MESSAGES/collective.geolocationbehavior.po rename to src/collective/geolocationbehavior/locales/fr/LC_MESSAGES/collective.geolocationbehavior.po diff --git a/collective/geolocationbehavior/locales/it/LC_MESSAGES/collective.geolocationbehavior.po b/src/collective/geolocationbehavior/locales/it/LC_MESSAGES/collective.geolocationbehavior.po similarity index 100% rename from collective/geolocationbehavior/locales/it/LC_MESSAGES/collective.geolocationbehavior.po rename to src/collective/geolocationbehavior/locales/it/LC_MESSAGES/collective.geolocationbehavior.po diff --git a/src/collective/geolocationbehavior/profiles/default/catalog.xml b/src/collective/geolocationbehavior/profiles/default/catalog.xml new file mode 100644 index 0000000..309da60 --- /dev/null +++ b/src/collective/geolocationbehavior/profiles/default/catalog.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + diff --git a/collective/geolocationbehavior/profiles/default/metadata.xml b/src/collective/geolocationbehavior/profiles/default/metadata.xml similarity index 84% rename from collective/geolocationbehavior/profiles/default/metadata.xml rename to src/collective/geolocationbehavior/profiles/default/metadata.xml index 48f4e69..37de93f 100644 --- a/collective/geolocationbehavior/profiles/default/metadata.xml +++ b/src/collective/geolocationbehavior/profiles/default/metadata.xml @@ -1,4 +1,4 @@ - + 5 diff --git a/collective/geolocationbehavior/profiles/uninstall/metadata.xml b/src/collective/geolocationbehavior/profiles/uninstall/metadata.xml similarity index 54% rename from collective/geolocationbehavior/profiles/uninstall/metadata.xml rename to src/collective/geolocationbehavior/profiles/uninstall/metadata.xml index cf4492a..08b37b6 100644 --- a/collective/geolocationbehavior/profiles/uninstall/metadata.xml +++ b/src/collective/geolocationbehavior/profiles/uninstall/metadata.xml @@ -1,4 +1,4 @@ - + 1 diff --git a/collective/geolocationbehavior/upgrades/__init__.py b/src/collective/geolocationbehavior/upgrades/__init__.py similarity index 60% rename from collective/geolocationbehavior/upgrades/__init__.py rename to src/collective/geolocationbehavior/upgrades/__init__.py index 751f4cd..5914b4a 100644 --- a/collective/geolocationbehavior/upgrades/__init__.py +++ b/src/collective/geolocationbehavior/upgrades/__init__.py @@ -1,51 +1,57 @@ -from Products.CMFCore.utils import getToolByName from collective.geolocationbehavior.geolocation import IGeolocatable +from plone.browserlayer.utils import unregister_layer +from Products.CMFCore.utils import getToolByName from zope.annotation.interfaces import IAnnotatable from zope.annotation.interfaces import IAnnotations from zope.component.hooks import getSite from zope.event import notify from zope.lifecycleevent import ObjectModifiedEvent + import logging -from plone.browserlayer.utils import unregister_layer log = logging.getLogger(__name__) -GEO_ANNOTATION_KEY = 'collective.geolocationbehavior.geolocation.GeolocatableAnnotation' # noqa +GEO_ANNOTATION_KEY = ( + "collective.geolocationbehavior.geolocation.GeolocatableAnnotation" # noqa +) def upgrade_attribute_storage(context): portal = getSite() - catalog = getToolByName(portal, 'portal_catalog') + catalog = getToolByName(portal, "portal_catalog") query = {} - query['object_provides'] = 'collective.geolocationbehavior.geolocation.IGeolocatableMarker' # noqa + query["object_provides"] = ( + "collective.geolocationbehavior.geolocation.IGeolocatableMarker" # noqa + ) results = catalog(**query) - log.info('There are {0} in total, stating migration...'.format( - len(results))) + log.info(f"There are {len(results)} in total, stating migration...") for result in results: try: obj = result.getObject() except Exception: log.warning( - 'Not possible to fetch object from catalog result for ' - 'item: {0}.'.format(result.getPath())) + "Not possible to fetch object from catalog result for " + "item: {}.".format(result.getPath()) + ) continue if not IAnnotatable.providedBy(obj): log.warning( - 'The object at {0} does provide annotation capabilities, ' - 'skipping.'.format(obj.absolute_url())) + "The object at {} does provide annotation capabilities, " + "skipping.".format(obj.absolute_url()) + ) continue annotations = IAnnotations(obj) oldvalue = annotations.get(GEO_ANNOTATION_KEY, None) - geolocation = getattr(oldvalue, 'geolocation', None) + geolocation = getattr(oldvalue, "geolocation", None) if geolocation and not IGeolocatable(obj).geolocation: # Only write the old value if there is no new value yet IGeolocatable(obj).geolocation = geolocation notify(ObjectModifiedEvent(obj)) - log.info('Set geolocation lat: {0}, lng: {1} for {2}'.format( - geolocation.latitude, - geolocation.longitude, - obj.absolute_url()) + log.info( + "Set geolocation lat: {}, lng: {} for {}".format( + geolocation.latitude, geolocation.longitude, obj.absolute_url() + ) ) if oldvalue: del annotations[GEO_ANNOTATION_KEY] @@ -54,7 +60,7 @@ def upgrade_attribute_storage(context): def remove_browserlayer(context): try: - unregister_layer(name=u"collective.geolocationbehavior") + unregister_layer(name="collective.geolocationbehavior") except KeyError: # No browser layer with name collective.geolocationbehavior registered pass diff --git a/collective/geolocationbehavior/upgrades/configure.zcml b/src/collective/geolocationbehavior/upgrades/configure.zcml similarity index 99% rename from collective/geolocationbehavior/upgrades/configure.zcml rename to src/collective/geolocationbehavior/upgrades/configure.zcml index c0b1f93..4a4e9be 100644 --- a/collective/geolocationbehavior/upgrades/configure.zcml +++ b/src/collective/geolocationbehavior/upgrades/configure.zcml @@ -1,29 +1,30 @@ + xmlns:genericsetup="http://namespaces.zope.org/genericsetup" + > diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..838dd1d --- /dev/null +++ b/tox.ini @@ -0,0 +1,236 @@ +# Generated from: +# https://github.com/plone/meta/tree/main/src/plone/meta/default +# See the inline comments on how to expand/tweak this configuration file +[tox] +# We need 4.4.0 for constrain_package_deps. +min_version = 4.4.0 +envlist = + lint + test + py314-plone62 + py313-plone62 + py312-plone62 + py311-plone62 + py310-plone62 + dependencies + + +## +# Add extra configuration options in .meta.toml: +# - to specify a custom testing combination of Plone and python versions, use `test_matrix` +# Use ["*"] to use all supported Python versions for this Plone version. +# - to disable the test matrix entirely, set `use_test_matrix = false` +# - to specify extra custom environments, use `envlist_lines` +# - to specify extra `tox` top-level options, use `config_lines` +# [tox] +# test_matrix = {"6.2" = ["3.13", "3.12"], "6.1" = ["*"]} +# envlist_lines = """ +# my_other_environment +# """ +# config_lines = """ +# my_extra_top_level_tox_configuration_lines +# """ +## + +[testenv:init] +description = Prepare environment +skip_install = true +allowlist_externals = + echo +commands = + echo "Initial setup complete" + +[testenv:format] +description = automatically reformat code +skip_install = true +deps = + pre-commit +commands = + pre-commit run -a pyupgrade + pre-commit run -a isort + pre-commit run -a black + pre-commit run -a zpretty + +[testenv:lint] +description = run linters that will help improve the code style +skip_install = true +deps = + pre-commit +commands = + pre-commit run -a + +[testenv:dependencies] +description = check if the package defines all its dependencies +skip_install = true +deps = + build + setuptools<82.0.0 + z3c.dependencychecker==2.14.3 +commands = + python -m build --sdist + dependencychecker + +[testenv:dependencies-graph] +description = generate a graph out of the dependencies of the package +skip_install = false +allowlist_externals = + sh +deps = + pipdeptree==2.5.1 + graphviz # optional dependency of pipdeptree +commands = + sh -c 'pipdeptree --exclude setuptools,wheel,pipdeptree,zope.interface,zope.component --graph-output svg > dependencies.svg' + + +[test_runner] +deps = zope.testrunner +test = + zope-testrunner --all --test-path={toxinidir}/src -s collective.geolocationbehavior {posargs} +coverage = + coverage run --branch --source collective.geolocationbehavior {envbindir}/zope-testrunner --quiet --all --test-path={toxinidir}/src -s collective.geolocationbehavior {posargs} + coverage report -m --format markdown + coverage xml + coverage html + +[base] +description = shared configuration for tests and coverage +use_develop = true +skip_install = false +constrain_package_deps = true +set_env = + ROBOT_BROWSER=headlesschrome + +## +# Specify extra test environment variables in .meta.toml: +# [tox] +# test_environment_variables = """ +# PIP_EXTRA_INDEX_URL=https://my-pypi.my-server.com/ +# """ +# +# Set constrain_package_deps .meta.toml: +# [tox] +# constrain_package_deps = false +## +deps = + {[test_runner]deps} + plone62: -c https://dist.plone.org/release/6.2-dev/constraints.txt + +## +# Specify additional deps in .meta.toml: +# [tox] +# test_deps_additional = """ +# -esources/plonegovbr.portal_base[test] +# """ +# +# Specify a custom constraints file in .meta.toml: +# [tox] +# constraints_file = "https://my-server.com/constraints.txt" +## +extras = + + +## +# Add extra configuration options in .meta.toml: +# [tox] +# skip_test_extra = true +# test_extras = """ +# tests +# widgets +# """ +# +# Add extra configuration options in .meta.toml: +# [tox] +# testenv_options = """ +# basepython = /usr/bin/python3.8 +# """ +## + +[testenv:test] +description = run the distribution tests +use_develop = {[base]use_develop} +skip_install = {[base]skip_install} +constrain_package_deps = {[base]constrain_package_deps} +set_env = {[base]set_env} +deps = + {[test_runner]deps} + -c https://dist.plone.org/release/6.2-dev/constraints.txt + +commands = {[test_runner]test} +extras = {[base]extras} + + +[testenv] +description = run the distribution tests (generative environments) +use_develop = {[base]use_develop} +skip_install = {[base]skip_install} +constrain_package_deps = {[base]constrain_package_deps} +set_env = {[base]set_env} +deps = {[base]deps} +commands = {[test_runner]test} +extras = {[base]extras} + + +[testenv:coverage] +description = get a test coverage report +use_develop = {[base]use_develop} +skip_install = {[base]skip_install} +constrain_package_deps = {[base]constrain_package_deps} +set_env = {[base]set_env} +deps = + {[test_runner]deps} + coverage + -c https://dist.plone.org/release/6.2-dev/constraints.txt + +commands = {[test_runner]coverage} +extras = {[base]extras} + + +[testenv:release-check] +description = ensure that the distribution is ready to release +skip_install = true +deps = + twine + build + -c https://dist.plone.org/release/6.2-dev/constraints.txt +commands = + python -m build --sdist + twine check dist/* + +[testenv:circular] +description = ensure there are no cyclic dependencies +use_develop = true +skip_install = false +# Here we must always constrain the package deps to what is already installed, +# otherwise we simply get the latest from PyPI, which may not work. +constrain_package_deps = true +set_env = + +## +# Specify extra test environment variables in .meta.toml: +# [tox] +# test_environment_variables = """ +# PIP_EXTRA_INDEX_URL=https://my-pypi.my-server.com/ +# """ +## +allowlist_externals = + sh +deps = + pipdeptree + pipforester + -c https://dist.plone.org/release/6.2-dev/constraints.txt +commands = + # Generate the full dependency tree + sh -c 'pipdeptree -j > forest.json' + # Generate a DOT graph with the circular dependencies, if any + pipforester -i forest.json -o forest.dot --cycles + # Report if there are any circular dependencies, i.e. error if there are any + pipforester -i forest.json --check-cycles -o /dev/null + + +## +# Add extra configuration options in .meta.toml: +# [tox] +# extra_lines = """ +# _your own configuration lines_ +# """ +##