Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
a452759
Set buildout config files
chris-adam Apr 23, 2026
27fc908
Added github action file
chris-adam Apr 23, 2026
c65fad3
Added Plone 6 config files
chris-adam Apr 24, 2026
84cb817
Add Plone 6 dependency checkouts and fix version conflicts
chris-adam Apr 24, 2026
2580820
Migrate Plone 6 WIP
chris-adam Apr 24, 2026
1e6594f
Fix Plone 4.3 buildout: use collective.dms.scanbehavior from PyPI
chris-adam Oct 8, 2026
3b785de
Lint: isort and flake8
chris-adam Oct 8, 2026
1e344ad
Add unit and robot tests
chris-adam Oct 8, 2026
3ec07a6
Make the code Python 2 and 3 compatible
chris-adam Oct 8, 2026
333ce57
Format with black
chris-adam Oct 8, 2026
b4d4588
Use the default branch of plone.formwidget.masterselect
chris-adam Oct 8, 2026
81ad788
Set the next version to 3.0.0
chris-adam Oct 8, 2026
679d0ad
Migrate to Plone 6.2
chris-adam Oct 8, 2026
5945cf1
Fix coverage report paths
chris-adam Oct 8, 2026
1ad3867
Replace the Travis badge with GitHub Actions and Coveralls badges
chris-adam Oct 9, 2026
f1aee3c
Run GitHub Actions on Ubuntu 26.04
chris-adam Oct 14, 2026
dbe8e7e
Apply CodeRabbit review: keep Plone's listing types
chris-adam Oct 28, 2026
1210fee
The conversion queue patch targets collective.documentviewer 6
duchenean Nov 3, 2026
f431ab7
The annex batch actions import PloneMeeting from plonemeeting.core
duchenean Nov 3, 2026
b13db95
The quick upload works without a session
duchenean Nov 3, 2026
d3552f3
The documentviewer tests run against collective.documentviewer 6
duchenean Nov 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[report]
include =
src/imio/annex/*
omit =
*/tests/*
96 changes: 96 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions

name: Push tests
# run-name: ${{ github.actor }} push tests

on:
push:
pull_request:
workflow_dispatch:

jobs:
test:
runs-on: ubuntu-26.04
strategy:
fail-fast: false
matrix:
include:
- python: 3.13.1
plone: "6.2"
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install system packages
run: |
sudo apt-get update
sudo apt-get install -y libjpeg-dev libbz2-dev
- name: Set up pyenv and Python
uses: "gabrielfalcao/pyenv-action@v18"
Comment thread
chris-adam marked this conversation as resolved.
Resolved
with:
default: "${{ matrix.python }}"
- name: Setup Env
run: |
pip install --upgrade pip
pip install -r requirements-${{ matrix.plone }}.txt
- name: Cache eggs
uses: actions/cache@v4
env:
cache-name: cache-eggs
with:
path: ~/buildout-cache/eggs
key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ matrix.python }}-${{ matrix.plone }}
- name: buildout
run: |
sed -ie "s#test.cfg#test-${{matrix.plone}}.cfg#" gha.cfg
buildout -c gha.cfg annotate
buildout -c gha.cfg
- name: test
run: |
bin/test -t !robot
coverage:
runs-on: ubuntu-26.04
strategy:
fail-fast: false
matrix:
include:
- python: 3.13.1
plone: "6.2"
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install system packages
run: |
sudo apt-get update
sudo apt-get install -y libjpeg-dev libbz2-dev
- name: Set up pyenv and Python
uses: "gabrielfalcao/pyenv-action@v18"
with:
default: "${{ matrix.python }}"
- name: Setup Env
run: |
pip install --upgrade pip
pip install -r requirements-${{matrix.plone}}.txt
pip install -U coveralls coverage
- name: Cache eggs
uses: actions/cache@v4
env:
cache-name: cache-eggs
with:
path: ~/buildout-cache/eggs
key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ matrix.python }}-${{ matrix.plone }}
- name: buildout
run: |
sed -ie "s#test.cfg#test-${{matrix.plone}}.cfg#" gha.cfg
buildout -c gha.cfg
- name: code-analysis
run: |
bin/code-analysis
- name: test coverage
run: |
coverage run bin/test -t !robot
- name: Publish to Coveralls
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
coveralls --service=github
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,11 @@ output.xml
*.swp
include
lib
.plone-version
.plone*
checkversion*.html
pyvenv.cfg
.python-version
CACHEDIR.TAG
local/
dist/
11 changes: 11 additions & 0 deletions .isort.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[settings]
# black compatible (profile = black, spelled out for isort 4 on Python 2.7)
force_alphabetical_sort = True
force_single_line = True
lines_after_imports = 2
line_length = 88
multi_line_output = 3
include_trailing_comma = True
force_grid_wrap = 0
use_parentheses = True
ensure_newline_before_comments = True
16 changes: 13 additions & 3 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,20 @@ Changelog
=========


2.27.2 (unreleased)
-------------------
3.0.0 (unreleased)
------------------

- Nothing changed yet.
- Migrated to Plone 6.2 and Python 3, dropped Plone 4 support, added unit and robot tests.
collective.documentviewer is optional: without it, no annex preview.
[chris-adam]
- Fixed the patch of the conversion queue for collective.documentviewer 6:
it patches `async_utils.CeleryJobRunner`, because documentviewer 6 has no `async` module.
[duchenean]
- Fixed the imports of the annexes batch actions: the widget comes from `plonemeeting.core`
(PloneMeeting on Plone 6) and `PdfReadError` from `PyPDF2.errors`.
[duchenean]
- Fixed the quick upload when the request has no session (`REQUEST.SESSION` is `None`).
[duchenean]


2.27.1 (2026-01-15)
Expand Down
107 changes: 107 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#!/usr/bin/make
# pyenv is a requirement, with the 3.13 python version, and virtualenv installed in it
# plone parameter must be passed to create environment 'make setup plone=6.2' or after a make cleanall
# The original Makefile can be found on https://github.com/IMIO/scripts-buildout

SHELL=/bin/bash
plones=6.2
b_o=
old_plone=$(shell [ -e .plone-version ] && cat .plone-version)
ZSERVER_PORT ?= 55001
LISTENER_PORT ?= 55002

ifeq (, $(shell which pyenv))
$(error "pyenv command not found! Aborting")
endif

ifndef plone
ifeq (,$(filter setup,$(MAKECMDGOALS)))
plone=$(old_plone)
endif
endif

ifneq ($(wildcard bin/instance),)
b_o=-N
endif

ifndef python
ifeq ($(plone),6.2)
python=3.13
endif
endif

all: buildout

.PHONY: help
help:
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n\nTargets:\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-10s\033[0m %s\n", $$1, $$2 }' $(MAKEFILE_LIST)

.python-version: ## Setups pyenv version
@pyenv local `pyenv versions |grep " $(python)" |tail -1 |xargs`
@echo "Local pyenv version is `cat .python-version`"
@ if [[ `pyenv which virtualenv` != `pyenv prefix`* ]] ; then echo "You need to install virtualenv in `cat .python-version` pyenv python (pip install virtualenv)"; exit 1; fi

bin/buildout: .python-version ## Setups environment
virtualenv .
./bin/pip install --upgrade pip
./bin/pip install -r requirements-$(plone).txt
@echo "$(plone)" > .plone-version

.PHONY: setup
setup: oneof-plone backup cleanall bin/buildout restore ## Setups environment

.PHONY: buildout
buildout: oneof-plone bin/buildout ## Runs setup and buildout
rm -f .installed.cfg .mr.developer.cfg
bin/buildout -t 5 -c test-$(plone).cfg ${b_o}

.PHONY: test
test: oneof-plone bin/buildout ## run bin/test without robot
# can be run by example with: make test opt='-t "settings"'
bin/test -t \!robot ${opt}

.PHONY: robot
robot: oneof-plone bin/buildout ## run robot tests in headless firefox
# can be run by example with: make robot opt='-t "Add an annex*"'
MOZ_HEADLESS=1 ZSERVER_HOST=localhost ZSERVER_PORT=$(ZSERVER_PORT) LISTENER_PORT=$(LISTENER_PORT) bin/test --all -t robot ${opt}

.PHONY: robot-server
robot-server: ## Starts robot server (layer=<layer name in testing.py>, default ACCEPTANCE)
# run a robot file against it with: ZSERVER_HOST=localhost ZSERVER_PORT=$(ZSERVER_PORT) LISTENER_PORT=$(LISTENER_PORT) bin/robot -v PLONE_MAJOR:$(firstword $(subst ., ,$(plone))) src/imio/annex/tests/robot/test_<feature>.robot
# --no-reload: the reload watchdog restarts the server when a template is read
env ZSERVER_HOST=localhost ZSERVER_PORT=$(ZSERVER_PORT) LISTENER_PORT=$(LISTENER_PORT) bin/robot-server --no-reload -v imio.annex.testing.$(or $(layer),ACCEPTANCE)

.PHONY: cleanall
cleanall: ## Cleans all installed buildout files
rm -fr bin include lib local share develop-eggs downloads eggs parts .installed.cfg .mr.developer.cfg .python-version pyvenv.cfg

.PHONY: backup
backup: ## Backups db files
@if [ '$(old_plone)' != '' ] && [ -f var/filestorage/Data.fs ]; then mv var/filestorage/Data.fs var/filestorage/Data.fs.$(old_plone); mv var/blobstorage var/blobstorage.$(old_plone); fi

.PHONY: restore
restore: ## Restores db files
@if [ '$(plone)' != '' ] && [ -f var/filestorage/Data.fs.$(plone) ]; then mv var/filestorage/Data.fs.$(plone) var/filestorage/Data.fs; mv var/blobstorage.$(plone) var/blobstorage; fi

.PHONY: which-python
which-python: oneof-plone ## Displays versions information
@echo "current plone = $(old_plone)"
@echo "current python = `cat .python-version`"
@echo "plone var = $(plone)"
@echo "python var = $(python)"

.PHONY: vcr
vcr: ## Shows requirements in checkversion-r.html
@bin/versioncheck -rbo checkversion-r-$(plone).html test-$(plone).cfg

.PHONY: vcn
vcn: ## Shows newer packages in checkversion-n.html
@bin/versioncheck -npbo checkversion-n-$(plone).html test-$(plone).cfg

.PHONY: guard-%
guard-%:
@ if [ "${${*}}" = "" ]; then echo "You must give a value for variable '$*' : like $*=xxx"; exit 1; fi

.PHONY: oneof-%
oneof-%:
@ if ! echo "${${*}s}" | tr " " '\n' |grep -Fqx "${${*}}"; then echo "Invalid '$*' parameter ('${${*}}') : must be one of '${${*}s}'"; exit 1; fi
5 changes: 5 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
.. image:: https://github.com/IMIO/imio.annex/actions/workflows/main.yml/badge.svg
:target: https://github.com/IMIO/imio.annex/actions/workflows/main.yml
.. image:: https://coveralls.io/repos/github/IMIO/imio.annex/badge.svg
:target: https://coveralls.io/github/IMIO/imio.annex

.. This README is meant for consumption by humans and pypi. Pypi can render rst files so please do not use Sphinx features.
If you want to learn more about writing documentation, please check out: http://docs.plone.org/about/documentation_styleguide_addons.html
This text does not appear on pypi or github. It is a comment.
Expand Down
117 changes: 117 additions & 0 deletions base.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
[buildout]
package-name = imio.annex
package-extras = [test]

extends =
https://raw.githubusercontent.com/collective/buildout.plonetest/master/qa.cfg
checkouts.cfg

extensions =
mr.developer
plone.versioncheck

parts +=
instance
omelette
ploneversioncheck
createcoverage
robot
releaser
i18ndude
# coverage
# test-coverage
# plone-helper-scripts

develop = .

eggs +=
Plone
Pillow
# Products.PDBDebugMode
# collective.profiler
# ipdb
pdbp
# plone.reload

package-extras +=
pdbp

always-checkout = force

[instance]
environment-vars +=
PYTHONBREAKPOINT pdbp.set_trace
eggs +=
${buildout:eggs}
zcml +=

[test]
environment = testenv
initialization +=
os.environ['PYTHONBREAKPOINT'] = 'pdbp.set_trace'

[testenv]
zope_i18n_compile_mo_files = true

[omelette]
recipe = collective.recipe.omelette
eggs = ${test:eggs}

[ploneversioncheck]
recipe = zc.recipe.egg
eggs = plone.versioncheck

[code-analysis]
recipe = plone.recipe.codeanalysis
pre-commit-hook = True
return-status-codes = True
directory = ${buildout:directory}/src/imio
flake8-ignore = E123,E124,E203,E501,E126,E127,E128,W391,C901,W503,W504
flake8-extensions =
flake8-isort

[robot]
recipe = zc.recipe.egg
eggs =
Pillow
${test:eggs}
plone.app.robotframework[reload, debug]

[coverage]
recipe = zc.recipe.egg
eggs = coverage

[test-coverage]
recipe = collective.recipe.template
input = inline:
#!/bin/bash
export TZ=UTC
${buildout:directory}/bin/coverage run bin/test $*
${buildout:directory}/bin/coverage html
${buildout:directory}/bin/coverage report -m --fail-under=90
# Fail (exit status 1) if coverage returns exit status 2 (this happens
# when test coverage is below 100%.
output = ${buildout:directory}/bin/test-coverage
mode = 755

[plone-helper-scripts]
recipe = zc.recipe.egg
eggs =
Products.CMFPlone
${instance:eggs}
interpreter = zopepy
scripts =
zopepy
plone-compile-resources

[releaser]
recipe = zc.recipe.egg
eggs = zest.releaser

[i18ndude]
recipe = zc.recipe.egg
eggs = i18ndude

[versions]
# Don't use a released version of imio.annex
imio.annex =
Loading
Loading