openmodule 13.2.0__tar.gz → 13.3.0__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.
- {openmodule-13.2.0 → openmodule-13.3.0}/ChangeLog +5 -6
- {openmodule-13.2.0/openmodule.egg-info → openmodule-13.3.0}/PKG-INFO +2 -1
- {openmodule-13.2.0 → openmodule-13.3.0}/README.md +1 -0
- openmodule-13.3.0/docs/cleanup.md +42 -0
- openmodule-13.3.0/openmodule/utils/cleanup.py +40 -0
- {openmodule-13.2.0 → openmodule-13.3.0/openmodule.egg-info}/PKG-INFO +2 -1
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule.egg-info/SOURCES.txt +3 -0
- openmodule-13.3.0/openmodule.egg-info/pbr.json +1 -0
- openmodule-13.3.0/tests/test_utils_cleanup.py +107 -0
- openmodule-13.2.0/openmodule.egg-info/pbr.json +0 -1
- {openmodule-13.2.0 → openmodule-13.3.0}/.gitlab-ci.yml +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/AUTHORS +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/LICENSE +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/docs/access_service.md +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/docs/anonymization.md +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/docs/coding_standard.md +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/docs/commands.md +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/docs/connection_status_listener.md +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/docs/csv_export.md +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/docs/database.md +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/docs/deprecated.md +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/docs/deprecated_code/README.md +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/docs/deprecated_code/access_service/openmodule/models/access_service.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/docs/deprecated_code/access_service/openmodule/utils/access_service.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/docs/deprecated_code/access_service/openmodule_test/access_service.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/docs/deprecated_code/access_service/tests/test_utils_access_service.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/docs/deprecated_code/api/openmodule/utils/api.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/docs/deprecated_code/api/openmodule_test/api.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/docs/deprecated_code/api/tests/test_utils_api.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/docs/deprecated_code/package_reader/openmodule/utils/package_reader.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/docs/deprecated_code/package_reader/openmodule_test/fake_package_creator.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/docs/deprecated_code/package_reader/tests/test_package_reader.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/docs/event_sending.md +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/docs/getting_started.md +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/docs/health.md +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/docs/images/broker.drawio.png +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/docs/known_issues.md +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/docs/migrations.md +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/docs/package_reader.md +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/docs/rpc.md +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/docs/settings.md +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/docs/settings_provider.md +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/docs/testing.md +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/docs/translation.md +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/docs/utils.md +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/__init__.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/alert.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/checks.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/config.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/connection_status.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/core.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/database/custom_types.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/database/database.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/database/env.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/dispatcher.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/health.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/logging.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/messaging.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/models/__init__.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/models/access_service.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/models/alert.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/models/base.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/models/io.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/models/kv_store.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/models/presence.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/models/privacy.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/models/rpc.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/models/settings.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/models/validation.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/models/vehicle.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/rpc/__init__.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/rpc/client.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/rpc/common.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/rpc/server.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/sentry.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/threading.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/utils/__init__.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/utils/access_service.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/utils/charset.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/utils/csv_export.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/utils/databox.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/utils/db_helper.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/utils/eventlog.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/utils/io.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/utils/kv_store.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/utils/matching.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/utils/misc_functions.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/utils/package_reader.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/utils/presence.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/utils/schema.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/utils/settings.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/utils/translation.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule/utils/validation.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule.egg-info/dependency_links.txt +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule.egg-info/not-zip-safe +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule.egg-info/requires.txt +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule.egg-info/top_level.txt +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule_commands/__init__.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule_commands/setup.cfg +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule_commands/setup.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule_commands/translate.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule_test/__init__.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule_test/alert.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule_test/connection_status.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule_test/core.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule_test/database.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule_test/eventlistener.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule_test/files.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule_test/gate.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule_test/health.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule_test/interrupt.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule_test/io_simulator.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule_test/package_reader.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule_test/presence.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule_test/requirements.txt +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule_test/rpc.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule_test/settings.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule_test/setup.cfg +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule_test/setup.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule_test/utils.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/openmodule_test/zeromq.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/requirements.txt +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/setup.cfg +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/setup.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/test-requirements.txt +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/__init__.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/config.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/database_models_migration.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/database_models_test.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/invalid_database/alembic/README +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/invalid_database/alembic/__init__.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/invalid_database/alembic/env.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/invalid_database/alembic/script.py.mako +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/invalid_database/alembic/versions/ff26e54332f9_datetime_models.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/invalid_database/alembic.ini +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/invalid_database/makemigration.sh +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/migration_test_database/__init__.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/migration_test_database/alembic/__init__.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/migration_test_database/alembic/env.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/migration_test_database/alembic/script.py.mako +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/migration_test_database/alembic/versions/19789aa5361c_initial.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/migration_test_database/alembic/versions/19d887929ae7_alter.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/migration_test_database/alembic/versions/__init__.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/migration_test_database/alembic.ini +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/migration_test_database/alembic_migration_test_database.sqlite3 +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/migration_test_database/makemigration.sh +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/resources/configs/config.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/resources/configs/test_config.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/resources/configs/test_config_1.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/resources/standard_schemes/DEFAULT-10.yml +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/resources/standard_schemes/DEFAULT-20.yml +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/resources/standard_schemes/LEGACY-0.yml +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/resources/translation/locale/de/LC_MESSAGES/translation.mo +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/resources/translation/locale/de/LC_MESSAGES/translation.po +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/resources/translation/locale/en/LC_MESSAGES/translation.mo +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/resources/translation/locale/en/LC_MESSAGES/translation.po +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/resources/translation/locale/translation.pot +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/resources/translation/translate.sh +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/resources/utils_matching/A-10.yml +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/resources/utils_matching/A-20.yml +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/resources/utils_matching/DEFAULT-10.yml +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/resources/utils_matching/DEFAULT-20.yml +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/resources/utils_matching/DEFAULT-30.yml +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/resources/utils_matching/LEGACY-0.yml +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/resources/utils_matching/TEST-10.yml +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/resources/utils_matching/TEST-20.yml +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/resources/utils_matching/TEST-30.yml +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/resources/utils_matching/TEST-40.yml +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_access_service_database/alembic/__init__.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_access_service_database/alembic/env.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_access_service_database/alembic/script.py.mako +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_access_service_database/alembic/versions/7bd4fcd38fde_removed_nfc_and_pin.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_access_service_database/alembic/versions/9ca98a2e5674_added_parksettings_id.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_access_service_database/alembic/versions/c821971f9230_initial.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_access_service_database/alembic.ini +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_access_service_database/makemigration.sh +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_alembic_migrations.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_alert.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_checks.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_config.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_connection_status.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_core.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_database/alembic/__init__.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_database/alembic/env.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_database/alembic/script.py.mako +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_database/alembic/versions/32b8c728abbf_initial.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_database/alembic.ini +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_database/makemigration.sh +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_database.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_dispatcher.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_health.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_interrupt.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_io_listen.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_kv_store_database/alembic/__init__.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_kv_store_database/alembic/env.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_kv_store_database/alembic/script.py.mako +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_kv_store_database/alembic/versions/9c5c944221f4_deprecated_kv_entry_example.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_kv_store_database/alembic/versions/c55a69026a25_initial.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_kv_store_database/alembic.ini +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_kv_store_database/makemigration.sh +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_kv_store_multiple_database/alembic/README +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_kv_store_multiple_database/alembic/__init__.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_kv_store_multiple_database/alembic/env.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_kv_store_multiple_database/alembic/script.py.mako +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_kv_store_multiple_database/alembic/versions/cdb3214131a9_initial.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_kv_store_multiple_database/alembic.ini +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_kv_store_multiple_database/makemigration.sh +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_messaging.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_mockrpcclient.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_model.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_rpc.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_schema.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_sentry.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_test_alert.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_test_gate.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_test_zeromq.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_utils_access_service.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_utils_charset.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_utils_csv_export.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_utils_databox.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_utils_eventlog.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_utils_kv_store.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_utils_kv_store_multiple.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_utils_matching.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_utils_misc_functions.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_utils_package_reader.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_utils_presence.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_utils_settings.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_utils_validation.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tests/test_utils_vehicle.py +0 -0
- {openmodule-13.2.0 → openmodule-13.3.0}/tox.ini +0 -0
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
CHANGES
|
|
2
2
|
=======
|
|
3
3
|
|
|
4
|
+
v13.3.0
|
|
5
|
+
-------
|
|
6
|
+
|
|
7
|
+
* [OM-359] cleanup helper function
|
|
8
|
+
|
|
4
9
|
v13.2.0
|
|
5
10
|
-------
|
|
6
11
|
|
|
@@ -153,11 +158,6 @@ v11.1.0.rc4
|
|
|
153
158
|
|
|
154
159
|
* arivo-schedule in public pip
|
|
155
160
|
* use temporary arivo-schedule package
|
|
156
|
-
|
|
157
|
-
v11.1.0.rc3
|
|
158
|
-
-----------
|
|
159
|
-
|
|
160
|
-
* changed docs and requirements for schedule library until its a pip package
|
|
161
161
|
* removed mock rpcs from schema
|
|
162
162
|
|
|
163
163
|
v11.0.3
|
|
@@ -218,4 +218,3 @@ v10.0.1
|
|
|
218
218
|
v10.0.0
|
|
219
219
|
-------
|
|
220
220
|
|
|
221
|
-
* v10
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: openmodule
|
|
3
|
-
Version: 13.
|
|
3
|
+
Version: 13.3.0
|
|
4
4
|
Summary: Libraries for developing the arivo openmodule
|
|
5
5
|
Home-page: https://gitlab.com/arivo-public/device-python/openmodule.git
|
|
6
6
|
Author: ARIVO
|
|
@@ -123,6 +123,7 @@ pip install -e <path_to_openmodule_root>/openmodule_commands/
|
|
|
123
123
|
- [Utils](docs/utils.md)
|
|
124
124
|
- [Deprecated Features](docs/deprecated.md)
|
|
125
125
|
- [Testing](docs/testing.md)
|
|
126
|
+
- [File Cleanup](docs/cleanup.md)
|
|
126
127
|
|
|
127
128
|
### Openmodule Commands
|
|
128
129
|
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# File cleanup
|
|
2
|
+
|
|
3
|
+
With the exception for some globally defined file_patterns (e.g. debug images, log rotation files) every service is responsible for the cleanup of its files.
|
|
4
|
+
The helper function `schedule_file_cleanup` schedules a file cleanup at 2:xx local time, where xx is service name dependent to avoid that all services delete at the same time.
|
|
5
|
+
Important notes:
|
|
6
|
+
* only files will be deleted, directories are kept
|
|
7
|
+
* files are only deleted once per day
|
|
8
|
+
* files are deleted based on modified timestamp
|
|
9
|
+
* a scheduler must be used which does `.run_pending()` regularly
|
|
10
|
+
* as glob is only inclusive, an exclude regex can be specified for special cases
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
## Examples
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
import time
|
|
17
|
+
import re
|
|
18
|
+
import schedule
|
|
19
|
+
from datetime import timedelta
|
|
20
|
+
from openmodule.utils.cleanup import schedule_file_cleanup
|
|
21
|
+
|
|
22
|
+
scheduler = schedule.Scheduler()
|
|
23
|
+
|
|
24
|
+
# delete specific file after 30 days
|
|
25
|
+
schedule_file_cleanup(scheduler, "/data/file_to_keep_30_days.txt", timedelta(days=30))
|
|
26
|
+
|
|
27
|
+
# delete png files in folder after 1 day
|
|
28
|
+
schedule_file_cleanup(scheduler, "/data/images/*.png", timedelta(days=1))
|
|
29
|
+
|
|
30
|
+
# delete jpg files in subfolders after 30 days
|
|
31
|
+
schedule_file_cleanup(scheduler, "/data/*/*.jpg", timedelta(days=30))
|
|
32
|
+
|
|
33
|
+
# delete jpg files in subfolders recursively after 30 days (e.g. /data/a.jpg, /data/d1/a.jpg, /data/d1/d2/a.jpg)
|
|
34
|
+
schedule_file_cleanup(scheduler, "/data/**/*.jpg", timedelta(days=30))
|
|
35
|
+
|
|
36
|
+
# delete jpg files in subfolders, except if regex matches, recursively after 30 days (e.g. /data/d1/a.jpg, but not /data/vehicle_images/a.jpg)
|
|
37
|
+
schedule_file_cleanup(scheduler, "/data/**/*.jpg", timedelta(days=30), re.compile('.*/vehicle_images/.*'))
|
|
38
|
+
|
|
39
|
+
while True:
|
|
40
|
+
scheduler.run_pending()
|
|
41
|
+
time.sleep(1.0)
|
|
42
|
+
```
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import glob
|
|
2
|
+
import hashlib
|
|
3
|
+
import os
|
|
4
|
+
import re
|
|
5
|
+
import time
|
|
6
|
+
from datetime import timedelta
|
|
7
|
+
from typing import Optional
|
|
8
|
+
|
|
9
|
+
from schedule import Scheduler
|
|
10
|
+
|
|
11
|
+
from openmodule.config import settings
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _file_cleanup(file_pattern: str, retention_time: timedelta, exclude_regex: Optional[re.Pattern] = None):
|
|
15
|
+
"""
|
|
16
|
+
removes files matching file_mask and older than retention_time and not matching exclude_regex if given
|
|
17
|
+
"""
|
|
18
|
+
min_keep_time = time.time() - retention_time.total_seconds()
|
|
19
|
+
fns = glob.glob(file_pattern, recursive=True)
|
|
20
|
+
for fn in fns:
|
|
21
|
+
if os.path.getmtime(fn) < min_keep_time and os.path.isfile(fn) \
|
|
22
|
+
and not (exclude_regex and exclude_regex.match(fn)):
|
|
23
|
+
os.remove(fn)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def schedule_file_cleanup(scheduler: Scheduler, file_pattern: str, retention_time: timedelta,
|
|
27
|
+
exclude_regex: Optional[re.Pattern] = None):
|
|
28
|
+
"""
|
|
29
|
+
schedules cleanup of files matching file_mask and older than retention_time at every day at 02:xx
|
|
30
|
+
where xx is a service name dependent offset
|
|
31
|
+
:param scheduler: scheduler where file cleanup is scheduled
|
|
32
|
+
:param file_pattern: pattern for files (glob syntax) that files must match to be deleted
|
|
33
|
+
:param retention_time: minimum age of file before its deleted
|
|
34
|
+
:param exclude_regex: files matching exclude_regex are excluded even if they match file_pattern
|
|
35
|
+
"""
|
|
36
|
+
service_name_hash = hashlib.sha256(settings.NAME.encode("utf-8")).hexdigest()
|
|
37
|
+
random_offset = int(service_name_hash, 16) % 60
|
|
38
|
+
|
|
39
|
+
scheduler.every().day.at(f"02:{random_offset:02}", settings.TIMEZONE).do(_file_cleanup, file_pattern,
|
|
40
|
+
retention_time, exclude_regex)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: openmodule
|
|
3
|
-
Version: 13.
|
|
3
|
+
Version: 13.3.0
|
|
4
4
|
Summary: Libraries for developing the arivo openmodule
|
|
5
5
|
Home-page: https://gitlab.com/arivo-public/device-python/openmodule.git
|
|
6
6
|
Author: ARIVO
|
|
@@ -123,6 +123,7 @@ pip install -e <path_to_openmodule_root>/openmodule_commands/
|
|
|
123
123
|
- [Utils](docs/utils.md)
|
|
124
124
|
- [Deprecated Features](docs/deprecated.md)
|
|
125
125
|
- [Testing](docs/testing.md)
|
|
126
|
+
- [File Cleanup](docs/cleanup.md)
|
|
126
127
|
|
|
127
128
|
### Openmodule Commands
|
|
128
129
|
|
|
@@ -10,6 +10,7 @@ test-requirements.txt
|
|
|
10
10
|
tox.ini
|
|
11
11
|
docs/access_service.md
|
|
12
12
|
docs/anonymization.md
|
|
13
|
+
docs/cleanup.md
|
|
13
14
|
docs/coding_standard.md
|
|
14
15
|
docs/commands.md
|
|
15
16
|
docs/connection_status_listener.md
|
|
@@ -81,6 +82,7 @@ openmodule/rpc/server.py
|
|
|
81
82
|
openmodule/utils/__init__.py
|
|
82
83
|
openmodule/utils/access_service.py
|
|
83
84
|
openmodule/utils/charset.py
|
|
85
|
+
openmodule/utils/cleanup.py
|
|
84
86
|
openmodule/utils/csv_export.py
|
|
85
87
|
openmodule/utils/databox.py
|
|
86
88
|
openmodule/utils/db_helper.py
|
|
@@ -145,6 +147,7 @@ tests/test_test_gate.py
|
|
|
145
147
|
tests/test_test_zeromq.py
|
|
146
148
|
tests/test_utils_access_service.py
|
|
147
149
|
tests/test_utils_charset.py
|
|
150
|
+
tests/test_utils_cleanup.py
|
|
148
151
|
tests/test_utils_csv_export.py
|
|
149
152
|
tests/test_utils_databox.py
|
|
150
153
|
tests/test_utils_eventlog.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"git_version": "4623c40", "is_release": true}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import glob
|
|
2
|
+
import os
|
|
3
|
+
import re
|
|
4
|
+
import shutil
|
|
5
|
+
from datetime import datetime, timedelta
|
|
6
|
+
from unittest import TestCase
|
|
7
|
+
|
|
8
|
+
import freezegun
|
|
9
|
+
import schedule
|
|
10
|
+
from dateutil.tz import UTC, gettz, tzlocal
|
|
11
|
+
|
|
12
|
+
from openmodule.config import settings
|
|
13
|
+
from openmodule.utils.cleanup import _file_cleanup, schedule_file_cleanup
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class CleanupTest(TestCase):
|
|
17
|
+
test_dir = "/tmp/cleanup_test/"
|
|
18
|
+
|
|
19
|
+
def setUp(self):
|
|
20
|
+
super().setUp()
|
|
21
|
+
try:
|
|
22
|
+
shutil.rmtree(self.test_dir)
|
|
23
|
+
except OSError:
|
|
24
|
+
pass
|
|
25
|
+
os.makedirs(self.test_dir)
|
|
26
|
+
|
|
27
|
+
def test_cleanup_file_pattern_and_retention_time(self):
|
|
28
|
+
open(os.path.join(self.test_dir, "a.png"), 'w').close()
|
|
29
|
+
open(os.path.join(self.test_dir, "a2.png"), 'w').close()
|
|
30
|
+
open(os.path.join(self.test_dir, "b.png"), 'w').close()
|
|
31
|
+
current_time = datetime.utcnow()
|
|
32
|
+
|
|
33
|
+
# 1 minute less than retention time old -> no delete
|
|
34
|
+
delta = timedelta(days=3)
|
|
35
|
+
with freezegun.freeze_time(current_time + delta - timedelta(minutes=1)):
|
|
36
|
+
_file_cleanup("/tmp/cleanup_test/a*.png", delta)
|
|
37
|
+
self.assertEqual(3, len(glob.glob("/tmp/cleanup_test/*.png")))
|
|
38
|
+
|
|
39
|
+
# older than retention time old -> delete according to pattern -> only b.png left
|
|
40
|
+
with freezegun.freeze_time(current_time + delta + timedelta(minutes=1)):
|
|
41
|
+
_file_cleanup("/tmp/cleanup_test/a*.png", delta)
|
|
42
|
+
self.assertEqual(["/tmp/cleanup_test/b.png"], glob.glob("/tmp/cleanup_test/*.png"))
|
|
43
|
+
|
|
44
|
+
def test_recursive(self):
|
|
45
|
+
os.makedirs("/tmp/cleanup_test/d1/d2/d3/d4")
|
|
46
|
+
open(os.path.join(self.test_dir, "/tmp/cleanup_test/a.png"), 'w').close()
|
|
47
|
+
open(os.path.join(self.test_dir, "/tmp/cleanup_test/d1/a.png"), 'w').close()
|
|
48
|
+
open(os.path.join(self.test_dir, "/tmp/cleanup_test/d1/d2/a.png"), 'w').close()
|
|
49
|
+
open(os.path.join(self.test_dir, "/tmp/cleanup_test/d1/d2/d3/a.png"), 'w').close()
|
|
50
|
+
open(os.path.join(self.test_dir, "/tmp/cleanup_test/d1/d2/d3/d4/a.png"), 'w').close()
|
|
51
|
+
|
|
52
|
+
self.assertEqual(5, len(glob.glob("/tmp/cleanup_test/**/*.png", recursive=True)))
|
|
53
|
+
with freezegun.freeze_time(datetime.utcnow() + timedelta(days=2)):
|
|
54
|
+
_file_cleanup("/tmp/cleanup_test/*/a.png", timedelta(days=1)) # delete only .../d1/a.png
|
|
55
|
+
self.assertEqual(4, len(glob.glob("/tmp/cleanup_test/**/*.png", recursive=True)))
|
|
56
|
+
|
|
57
|
+
_file_cleanup("/tmp/cleanup_test/**/a.png", timedelta(days=1)) # delete all
|
|
58
|
+
self.assertEqual(0, len(glob.glob("/tmp/cleanup_test/**/*.png", recursive=True)))
|
|
59
|
+
|
|
60
|
+
def test_exclude_regex(self):
|
|
61
|
+
os.makedirs("/tmp/cleanup_test/vehicle_images/")
|
|
62
|
+
os.makedirs("/tmp/cleanup_test/vehicle_loop/")
|
|
63
|
+
os.makedirs("/tmp/cleanup_test/new_track/")
|
|
64
|
+
open(os.path.join(self.test_dir, "/tmp/cleanup_test/vehicle_images/a.jpg"), 'w').close()
|
|
65
|
+
open(os.path.join(self.test_dir, "/tmp/cleanup_test/vehicle_loop/b.jpg"), 'w').close()
|
|
66
|
+
open(os.path.join(self.test_dir, "/tmp/cleanup_test/new_track/c.jpg"), 'w').close()
|
|
67
|
+
|
|
68
|
+
with freezegun.freeze_time(datetime.utcnow() + timedelta(days=2)):
|
|
69
|
+
_file_cleanup("/tmp/cleanup_test/*/*.jpg", timedelta(days=1), re.compile('.*/vehicle_images/.*'))
|
|
70
|
+
self.assertEqual(["/tmp/cleanup_test/vehicle_images/a.jpg"],
|
|
71
|
+
glob.glob("/tmp/cleanup_test/*/*.jpg", recursive=True))
|
|
72
|
+
|
|
73
|
+
def test_scheduling(self):
|
|
74
|
+
scheduler = schedule.Scheduler()
|
|
75
|
+
open(os.path.join(self.test_dir, "1.png"), 'w').close()
|
|
76
|
+
open(os.path.join(self.test_dir, "2.png"), 'w').close()
|
|
77
|
+
|
|
78
|
+
# 2 days to ensure we delete even if we hit an unlucky race condition when testcase is run
|
|
79
|
+
base_time = (datetime.utcnow() + timedelta(days=2))\
|
|
80
|
+
.replace(hour=0, minute=0, second=0, microsecond=0, tzinfo=gettz(settings.TIMEZONE))\
|
|
81
|
+
.astimezone(UTC)
|
|
82
|
+
with freezegun.freeze_time(base_time, tz_offset=datetime.now(tz=tzlocal()).utcoffset()):
|
|
83
|
+
settings.NAME = "om_service_test_1" # offset 17 minutes
|
|
84
|
+
schedule_file_cleanup(scheduler, "/tmp/cleanup_test/1.png", timedelta(0))
|
|
85
|
+
settings.NAME = "om_service_test_2" # offset 1 minute
|
|
86
|
+
schedule_file_cleanup(scheduler, "/tmp/cleanup_test/2.png", timedelta(0))
|
|
87
|
+
|
|
88
|
+
# 2:00 -> no job should be run -> 2 files present
|
|
89
|
+
with freezegun.freeze_time(base_time + timedelta(hours=2),
|
|
90
|
+
tz_offset=datetime.now(tz=tzlocal()).utcoffset()):
|
|
91
|
+
scheduler.run_pending()
|
|
92
|
+
self.assertEqual(2, len(glob.glob("/tmp/cleanup_test/*.png")))
|
|
93
|
+
# 2:01 -> 2.png should be deleted because job ran
|
|
94
|
+
with freezegun.freeze_time(base_time + timedelta(hours=2, minutes=1),
|
|
95
|
+
tz_offset=datetime.now(tz=tzlocal()).utcoffset()):
|
|
96
|
+
scheduler.run_pending()
|
|
97
|
+
self.assertEqual(["/tmp/cleanup_test/1.png"], glob.glob("/tmp/cleanup_test/*.png"))
|
|
98
|
+
# 2:16 -> no more deletions
|
|
99
|
+
with freezegun.freeze_time(base_time + timedelta(hours=2, minutes=16),
|
|
100
|
+
tz_offset=datetime.now(tz=tzlocal()).utcoffset()):
|
|
101
|
+
scheduler.run_pending()
|
|
102
|
+
self.assertEqual(["/tmp/cleanup_test/1.png"], glob.glob("/tmp/cleanup_test/*.png"))
|
|
103
|
+
# 2:17 -> 1.png should be deleted because job ran
|
|
104
|
+
with freezegun.freeze_time(base_time + timedelta(hours=2, minutes=17),
|
|
105
|
+
tz_offset=datetime.now(tz=tzlocal()).utcoffset()):
|
|
106
|
+
scheduler.run_pending()
|
|
107
|
+
self.assertEqual([], glob.glob("/tmp/cleanup_test/*.png"))
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"git_version": "0bcec3c", "is_release": true}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|