django-pfx 1.7.3.dev4__tar.gz → 1.7.3.dev6__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.
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/.pre-commit-config.yaml +8 -8
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/PKG-INFO +4 -1
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/django_pfx.egg-info/PKG-INFO +4 -1
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/django_pfx.egg-info/SOURCES.txt +24 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/django_pfx.egg-info/requires.txt +4 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/doc/conf.py +3 -1
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/make_messages +1 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/__init__.py +0 -2
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/apps.py +15 -1
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/default_settings.py +7 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/fields/media_field.py +19 -1
- django_pfx-1.7.3.dev6/pfx/pfxcore/locale/fr/LC_MESSAGES/django.mo +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/locale/fr/LC_MESSAGES/django.po +26 -12
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/models/__init__.py +1 -0
- django_pfx-1.7.3.dev6/pfx/pfxcore/models/attachment_mixin.py +78 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/models/ordered_model_mixin.py +2 -1
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/shortcuts.py +5 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/templates/registration/otp_code_email.txt +1 -1
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/templates/registration/password_reset_email.txt +2 -2
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/templates/registration/welcome_email.txt +1 -1
- django_pfx-1.7.3.dev6/pfx/settings/dev.py +34 -0
- django_pfx-1.7.3.dev6/pfx/userjobs/__init__.py +1 -0
- django_pfx-1.7.3.dev6/pfx/userjobs/apps.py +22 -0
- django_pfx-1.7.3.dev6/pfx/userjobs/locale/fr/LC_MESSAGES/django.mo +0 -0
- django_pfx-1.7.3.dev6/pfx/userjobs/locale/fr/LC_MESSAGES/django.po +154 -0
- django_pfx-1.7.3.dev6/pfx/userjobs/migrations/0001_initial.py +76 -0
- django_pfx-1.7.3.dev6/pfx/userjobs/migrations/0002_alter_userjob_options_alter_userjob_auto_queued_and_more.py +100 -0
- django_pfx-1.7.3.dev6/pfx/userjobs/models/__init__.py +2 -0
- django_pfx-1.7.3.dev6/pfx/userjobs/models/user_job.py +217 -0
- django_pfx-1.7.3.dev6/pfx/userjobs/models/user_job_attachment.py +32 -0
- django_pfx-1.7.3.dev6/pfx/userjobs/providers/__init__.py +4 -0
- django_pfx-1.7.3.dev6/pfx/userjobs/providers/user_job_django_q_executor.py +29 -0
- django_pfx-1.7.3.dev6/pfx/userjobs/providers/user_job_websocket_channel_provider.py +30 -0
- django_pfx-1.7.3.dev6/pfx/userjobs/tasks.py +93 -0
- django_pfx-1.7.3.dev6/pfx/userjobs/urls.py +14 -0
- django_pfx-1.7.3.dev6/pfx/userjobs/views/__init__.py +3 -0
- django_pfx-1.7.3.dev6/pfx/userjobs/views/user_job_attachment_view.py +17 -0
- django_pfx-1.7.3.dev6/pfx/userjobs/views/user_job_view.py +63 -0
- django_pfx-1.7.3.dev6/pfx/userjobs/views/user_websocket_consumer.py +65 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/requirements.txt +7 -1
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/setup.cfg +1 -0
- django_pfx-1.7.3.dev6/tests/channel_group_send_calls.py +21 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/settings/common.py +28 -1
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/tests/__init__.py +3 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/tests/test_auth_api.py +17 -14
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/tests/test_profiling_middleware.py +0 -1
- django_pfx-1.7.3.dev6/tests/tests/test_user_job_api.py +574 -0
- django_pfx-1.7.3.dev6/tests/tests/test_user_job_messages.py +128 -0
- django_pfx-1.7.3.dev6/tests/tests/test_user_job_model.py +302 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/urls.py +2 -1
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests_base_user/settings/common.py +26 -0
- django_pfx-1.7.3.dev6/tests_custom_user/settings/__init__.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests_custom_user/settings/common.py +26 -0
- django_pfx-1.7.3.dev4/pfx/pfxcore/locale/fr/LC_MESSAGES/django.mo +0 -0
- django_pfx-1.7.3.dev4/pfx/settings/dev.py +0 -8
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/.gitignore +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/.gitlab-ci.yml +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/LICENSE +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/MANIFEST.in +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/README.md +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/django_pfx.egg-info/dependency_links.txt +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/django_pfx.egg-info/top_level.txt +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/doc/Makefile +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/doc/index.rst +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/doc/source/api.views.rst +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/doc/source/authentication.md +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/doc/source/decorator.md +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/doc/source/generate_openapi.md +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/doc/source/getting_started.md +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/doc/source/internationalisation.md +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/doc/source/model.md +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/doc/source/pfx_views.md +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/doc/source/profiling.md +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/doc/source/settings.md +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/doc/source/testing.md +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/img/pfx.png +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/img/pfx.svg +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/manage.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/__init__.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/apidoc/__init__.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/apidoc/parameters.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/apidoc/schema.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/apidoc/tags.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/decorator/__init__.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/decorator/rest.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/exceptions.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/fields/__init__.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/fields/decimal_field.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/fields/minutes_duration_field.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/fields/rich_text_field.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/http/__init__.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/http/json_response.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/management/__init__.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/management/commands/__init__.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/management/commands/makeapidoc.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/management/commands/profile.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/middleware/__init__.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/middleware/authentication.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/middleware/locale.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/middleware/profiling.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/migrations/0001_initial.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/migrations/0002_pfxpermissionsuser.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/migrations/0003_delete_pfxpermissionsuser.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/migrations/0004_alter_loginban_failed_counter_and_more.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/migrations/__init__.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/migrations/operations/__init__.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/migrations/operations/permissions.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/models/abstract_pfx_base_user.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/models/cache_mixins.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/models/login_ban.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/models/mfa_user_mixin.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/models/not_null_fields.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/models/pfx_models.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/models/pfx_user.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/models/user_filtered_queryset_mixin.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/serializers/__init__.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/serializers/json.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/settings.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/sms/__init__.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/sms/backends/__init__.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/sms/backends/base.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/sms/backends/console.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/storage/__init__.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/storage/exceptions.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/storage/local_storage.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/storage/s3_storage.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/templates/registration/otp_code_subject.txt +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/templates/registration/password_reset_subject.txt +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/templates/registration/welcome_subject.txt +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/test.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/urls.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/views/__init__.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/views/authentication_views.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/views/fields.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/views/filters_views.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/views/locale_views.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/views/media_rest_view_mixin.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/views/ordered_rest_view_mixin.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/views/parameters/__init__.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/views/parameters/date_format.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/views/parameters/groups.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/views/parameters/list_count.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/views/parameters/list_items.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/views/parameters/list_mode.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/views/parameters/list_order.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/views/parameters/list_search.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/views/parameters/media_redirect.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/views/parameters/meta_fields.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/views/parameters/meta_filters.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/views/parameters/meta_orders.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/views/parameters/subset.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/views/parameters/subset_limit.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/views/parameters/subset_offset.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/views/parameters/subset_page.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/views/parameters/subset_page_size.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/views/parameters/subset_page_subset.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/views/rest_views.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/settings/__init__.py +0 -0
- {django_pfx-1.7.3.dev4/tests → django_pfx-1.7.3.dev6/pfx/userjobs/migrations}/__init__.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pyproject.toml +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/serve-doc +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/setup.py +0 -0
- {django_pfx-1.7.3.dev4/tests/migrations → django_pfx-1.7.3.dev6/tests}/__init__.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/apps.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/locale/fr/LC_MESSAGES/django.po +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/migrations/0001_initial.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/migrations/0002_alter_book_cover.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/migrations/0003_book_local_file.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/migrations/0004_mfausermixin_fields.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/migrations/0005_mfausermixin_fields_fix.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/migrations/0006_rename_otp_enabled_user_mfa_authenticator_enabled_and_more.py +0 -0
- {django_pfx-1.7.3.dev4/tests/settings → django_pfx-1.7.3.dev6/tests/migrations}/__init__.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/models.py +0 -0
- {django_pfx-1.7.3.dev4/tests_base_user → django_pfx-1.7.3.dev6/tests/settings}/__init__.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/settings/ci.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/settings/dev.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/settings/dev_custom_example.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/settings/dev_default.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/tests/basic_api_errors.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/tests/basic_api_test.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/tests/test_api_doc.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/tests/test_api_doc_search.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/tests/test_body_mixin.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/tests/test_cache.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/tests/test_client.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/tests/test_fields_choices.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/tests/test_fields_date.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/tests/test_fields_decimal.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/tests/test_fields_minutes_duration.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/tests/test_fields_one2many.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/tests/test_fields_rich_text.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/tests/test_fields_time.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/tests/test_filters.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/tests/test_locale_api.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/tests/test_ordered_rest_view_mixin.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/tests/test_perm_tests.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/tests/test_permissions.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/tests/test_perms_api.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/tests/test_post_migrate_groups_update.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/tests/test_settings.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/tests/test_shortcuts.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/tests/test_timezone_middleware.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/tests/test_tools.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/tests/test_user_queryset.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/tests/test_view_decorators.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/tests/test_view_fields.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests/views.py +0 -0
- {django_pfx-1.7.3.dev4/tests_base_user/migrations → django_pfx-1.7.3.dev6/tests_base_user}/__init__.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests_base_user/migrations/0001_initial.py +0 -0
- {django_pfx-1.7.3.dev4/tests_base_user/settings → django_pfx-1.7.3.dev6/tests_base_user/migrations}/__init__.py +0 -0
- {django_pfx-1.7.3.dev4/tests_custom_user → django_pfx-1.7.3.dev6/tests_base_user/settings}/__init__.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests_base_user/settings/ci.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests_base_user/settings/dev.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests_base_user/settings/dev_custom_example.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests_base_user/settings/dev_default.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests_base_user/tests/__init__.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests_base_user/tests/test_api.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests_base_user/tests/test_auth_api.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests_base_user/urls.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests_base_user/views.py +0 -0
- {django_pfx-1.7.3.dev4/tests_custom_user/migrations → django_pfx-1.7.3.dev6/tests_custom_user}/__init__.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests_custom_user/migrations/0001_initial.py +0 -0
- {django_pfx-1.7.3.dev4/tests_custom_user/settings → django_pfx-1.7.3.dev6/tests_custom_user/migrations}/__init__.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests_custom_user/models.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests_custom_user/settings/ci.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests_custom_user/settings/dev.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests_custom_user/settings/dev_custom_example.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests_custom_user/settings/dev_default.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests_custom_user/tests/__init__.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests_custom_user/tests/test_api.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests_custom_user/tests/test_auth_api.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests_custom_user/urls.py +0 -0
- {django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/tests_custom_user/views.py +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
repos:
|
|
2
|
-
-
|
|
2
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
3
3
|
rev: v4.3.0
|
|
4
4
|
hooks:
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
-
|
|
5
|
+
- id: check-yaml
|
|
6
|
+
- id: end-of-file-fixer
|
|
7
|
+
- id: trailing-whitespace
|
|
8
|
+
- repo: local
|
|
9
9
|
hooks:
|
|
10
10
|
- id: flake8
|
|
11
11
|
name: flake8
|
|
@@ -13,17 +13,17 @@ repos:
|
|
|
13
13
|
language: system
|
|
14
14
|
types: [python]
|
|
15
15
|
args: [--config=./setup.cfg]
|
|
16
|
-
-
|
|
16
|
+
- repo: local
|
|
17
17
|
hooks:
|
|
18
18
|
- id: isort
|
|
19
19
|
name: isort
|
|
20
20
|
entry: isort
|
|
21
21
|
language: system
|
|
22
22
|
types: [python]
|
|
23
|
-
-
|
|
23
|
+
- repo: local
|
|
24
24
|
hooks:
|
|
25
25
|
- id: make-messages
|
|
26
26
|
name: make messages
|
|
27
27
|
entry: ./make_messages
|
|
28
28
|
language: system
|
|
29
|
-
|
|
29
|
+
pass_filenames: false
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: django-pfx
|
|
3
|
-
Version: 1.7.3.
|
|
3
|
+
Version: 1.7.3.dev6
|
|
4
4
|
Summary: Django PFX is a toolkit designed to streamline the development of RESTful APIs using the Django framework.
|
|
5
5
|
Author: Hervé Martinet
|
|
6
6
|
Author-email: herve.martinet@gmail.com
|
|
@@ -37,6 +37,9 @@ Requires-Dist: dill
|
|
|
37
37
|
Requires-Dist: nh3
|
|
38
38
|
Provides-Extra: otp
|
|
39
39
|
Requires-Dist: pyotp; extra == "otp"
|
|
40
|
+
Provides-Extra: heic-converter
|
|
41
|
+
Requires-Dist: python-magic; extra == "heic-converter"
|
|
42
|
+
Requires-Dist: pillow-heif; extra == "heic-converter"
|
|
40
43
|
Dynamic: license-file
|
|
41
44
|
|
|
42
45
|
# Django PFX
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: django-pfx
|
|
3
|
-
Version: 1.7.3.
|
|
3
|
+
Version: 1.7.3.dev6
|
|
4
4
|
Summary: Django PFX is a toolkit designed to streamline the development of RESTful APIs using the Django framework.
|
|
5
5
|
Author: Hervé Martinet
|
|
6
6
|
Author-email: herve.martinet@gmail.com
|
|
@@ -37,6 +37,9 @@ Requires-Dist: dill
|
|
|
37
37
|
Requires-Dist: nh3
|
|
38
38
|
Provides-Extra: otp
|
|
39
39
|
Requires-Dist: pyotp; extra == "otp"
|
|
40
|
+
Provides-Extra: heic-converter
|
|
41
|
+
Requires-Dist: python-magic; extra == "heic-converter"
|
|
42
|
+
Requires-Dist: pillow-heif; extra == "heic-converter"
|
|
40
43
|
Dynamic: license-file
|
|
41
44
|
|
|
42
45
|
# Django PFX
|
|
@@ -73,6 +73,7 @@ pfx/pfxcore/migrations/operations/__init__.py
|
|
|
73
73
|
pfx/pfxcore/migrations/operations/permissions.py
|
|
74
74
|
pfx/pfxcore/models/__init__.py
|
|
75
75
|
pfx/pfxcore/models/abstract_pfx_base_user.py
|
|
76
|
+
pfx/pfxcore/models/attachment_mixin.py
|
|
76
77
|
pfx/pfxcore/models/cache_mixins.py
|
|
77
78
|
pfx/pfxcore/models/login_ban.py
|
|
78
79
|
pfx/pfxcore/models/mfa_user_mixin.py
|
|
@@ -125,8 +126,28 @@ pfx/pfxcore/views/parameters/subset_page_size.py
|
|
|
125
126
|
pfx/pfxcore/views/parameters/subset_page_subset.py
|
|
126
127
|
pfx/settings/__init__.py
|
|
127
128
|
pfx/settings/dev.py
|
|
129
|
+
pfx/userjobs/__init__.py
|
|
130
|
+
pfx/userjobs/apps.py
|
|
131
|
+
pfx/userjobs/tasks.py
|
|
132
|
+
pfx/userjobs/urls.py
|
|
133
|
+
pfx/userjobs/locale/fr/LC_MESSAGES/django.mo
|
|
134
|
+
pfx/userjobs/locale/fr/LC_MESSAGES/django.po
|
|
135
|
+
pfx/userjobs/migrations/0001_initial.py
|
|
136
|
+
pfx/userjobs/migrations/0002_alter_userjob_options_alter_userjob_auto_queued_and_more.py
|
|
137
|
+
pfx/userjobs/migrations/__init__.py
|
|
138
|
+
pfx/userjobs/models/__init__.py
|
|
139
|
+
pfx/userjobs/models/user_job.py
|
|
140
|
+
pfx/userjobs/models/user_job_attachment.py
|
|
141
|
+
pfx/userjobs/providers/__init__.py
|
|
142
|
+
pfx/userjobs/providers/user_job_django_q_executor.py
|
|
143
|
+
pfx/userjobs/providers/user_job_websocket_channel_provider.py
|
|
144
|
+
pfx/userjobs/views/__init__.py
|
|
145
|
+
pfx/userjobs/views/user_job_attachment_view.py
|
|
146
|
+
pfx/userjobs/views/user_job_view.py
|
|
147
|
+
pfx/userjobs/views/user_websocket_consumer.py
|
|
128
148
|
tests/__init__.py
|
|
129
149
|
tests/apps.py
|
|
150
|
+
tests/channel_group_send_calls.py
|
|
130
151
|
tests/models.py
|
|
131
152
|
tests/urls.py
|
|
132
153
|
tests/views.py
|
|
@@ -172,6 +193,9 @@ tests/tests/test_settings.py
|
|
|
172
193
|
tests/tests/test_shortcuts.py
|
|
173
194
|
tests/tests/test_timezone_middleware.py
|
|
174
195
|
tests/tests/test_tools.py
|
|
196
|
+
tests/tests/test_user_job_api.py
|
|
197
|
+
tests/tests/test_user_job_messages.py
|
|
198
|
+
tests/tests/test_user_job_model.py
|
|
175
199
|
tests/tests/test_user_queryset.py
|
|
176
200
|
tests/tests/test_view_decorators.py
|
|
177
201
|
tests/tests/test_view_fields.py
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import inspect
|
|
2
2
|
import logging
|
|
3
|
+
import os
|
|
3
4
|
from pathlib import Path
|
|
4
5
|
|
|
5
6
|
from django import apps
|
|
@@ -88,9 +89,22 @@ class PfxAppConfig(AppConfig):
|
|
|
88
89
|
|
|
89
90
|
def ready(self):
|
|
90
91
|
post_migrate.connect(update_groups_permissions_action, sender=self)
|
|
91
|
-
|
|
92
|
+
super().ready()
|
|
92
93
|
|
|
93
94
|
|
|
94
95
|
class PfxCoreConfig(AppConfig):
|
|
95
96
|
name = 'pfx.pfxcore'
|
|
96
97
|
default = True
|
|
98
|
+
|
|
99
|
+
def ready(self):
|
|
100
|
+
if os.environ.get("RUN_MAIN") == "true":
|
|
101
|
+
try:
|
|
102
|
+
from pillow_heif import register_heif_opener
|
|
103
|
+
register_heif_opener()
|
|
104
|
+
logger.info("PFX HEIC opener registered.")
|
|
105
|
+
except Exception:
|
|
106
|
+
logger.warning(
|
|
107
|
+
"PFX HEIC opener not registered "
|
|
108
|
+
"(use `pip install django-pfx[heic-converter]` "
|
|
109
|
+
"to use it.)")
|
|
110
|
+
super().ready()
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from django.utils.translation import gettext_lazy as _
|
|
2
|
+
|
|
1
3
|
PFX_TOKEN_SHORT_VALIDITY = {'hours': 12}
|
|
2
4
|
PFX_TOKEN_LONG_VALIDITY = {'days': 30}
|
|
3
5
|
PFX_TOKEN_OTP_VALIDITY = {'minutes': 15}
|
|
@@ -42,3 +44,8 @@ PFX_MFA_BACKENDS = ["authenticator", "email"]
|
|
|
42
44
|
PFX_MFA_FORCE = False
|
|
43
45
|
|
|
44
46
|
PFX_SMS_BACKEND = 'pfx.pfxcore.sms.backends.console.ConsoleSMSBackend'
|
|
47
|
+
|
|
48
|
+
# PFX assume you have a log monitoring system (like Sentry), but
|
|
49
|
+
# you can adapt the message to your use case.
|
|
50
|
+
PFX_SYSTEM_ERROR_USER_MESSAGE = _(
|
|
51
|
+
"A system error occurred. Our support team has been notified.")
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import io
|
|
1
2
|
import logging
|
|
2
3
|
from importlib import import_module
|
|
3
4
|
from urllib.request import urlopen
|
|
@@ -42,7 +43,8 @@ def validate_media_json(value):
|
|
|
42
43
|
class MediaField(models.JSONField):
|
|
43
44
|
def __init__(
|
|
44
45
|
self, *args, max_length=255, get_key=None, storage=None,
|
|
45
|
-
auto_delete=False, extra_keys=None,
|
|
46
|
+
auto_delete=False, extra_keys=None,
|
|
47
|
+
convert_heic=False, **kwargs):
|
|
46
48
|
self.get_key = get_key or self.get_default_key
|
|
47
49
|
if not storage and not settings.STORAGE_DEFAULT:
|
|
48
50
|
raise Exception(
|
|
@@ -51,6 +53,7 @@ class MediaField(models.JSONField):
|
|
|
51
53
|
self.storage = storage or get_storage_class(settings.STORAGE_DEFAULT)
|
|
52
54
|
self.auto_delete = auto_delete
|
|
53
55
|
self.allowed_keys = DEFAULT_KEYS.union(extra_keys or set())
|
|
56
|
+
self.convert_heic = convert_heic
|
|
54
57
|
self._db_value = None
|
|
55
58
|
|
|
56
59
|
# Inject default validator if empty
|
|
@@ -107,9 +110,24 @@ class MediaField(models.JSONField):
|
|
|
107
110
|
request, self.value_from_object(obj)['key'])
|
|
108
111
|
|
|
109
112
|
def upload(self, obj, file, filename, **kwargs):
|
|
113
|
+
if self.convert_heic:
|
|
114
|
+
file, filename = self.convert_heic_file(file, filename)
|
|
110
115
|
key = self.get_key(obj, filename)
|
|
111
116
|
return self.to_python(self.storage.upload(key, file, **kwargs))
|
|
112
117
|
|
|
118
|
+
def convert_heic_file(self, file, filename):
|
|
119
|
+
import magic
|
|
120
|
+
from PIL import Image
|
|
121
|
+
mime_type = magic.from_buffer(file, mime=True)
|
|
122
|
+
if mime_type in ('image/heic', 'image/heif'):
|
|
123
|
+
img = Image.open(io.BytesIO(file))
|
|
124
|
+
buf = io.BytesIO()
|
|
125
|
+
img.convert("RGB").save(buf, format="PNG")
|
|
126
|
+
|
|
127
|
+
file = buf.getvalue()
|
|
128
|
+
filename = filename.rsplit(".", 1)[0] + '.png'
|
|
129
|
+
return file, filename
|
|
130
|
+
|
|
113
131
|
def delete(self, value):
|
|
114
132
|
return self.storage.delete(value)
|
|
115
133
|
|
|
Binary file
|
|
@@ -7,7 +7,7 @@ msgid ""
|
|
|
7
7
|
msgstr ""
|
|
8
8
|
"Project-Id-Version: \n"
|
|
9
9
|
"Report-Msgid-Bugs-To: \n"
|
|
10
|
-
"POT-Creation-Date: 2026-05-
|
|
10
|
+
"POT-Creation-Date: 2026-05-21 16:23+0200\n"
|
|
11
11
|
"PO-Revision-Date: 2021-06-22 23:31+0200\n"
|
|
12
12
|
"Last-Translator: \n"
|
|
13
13
|
"Language-Team: \n"
|
|
@@ -22,6 +22,12 @@ msgstr ""
|
|
|
22
22
|
msgid "An internal server error occured."
|
|
23
23
|
msgstr "Une erreur interne du serveur est survenue."
|
|
24
24
|
|
|
25
|
+
#: default_settings.py:51
|
|
26
|
+
msgid "A system error occurred. Our support team has been notified."
|
|
27
|
+
msgstr ""
|
|
28
|
+
"Une erreur système s’est produite. "
|
|
29
|
+
"Notre équipe d’assistance en a été informée."
|
|
30
|
+
|
|
25
31
|
#: exceptions.py:53 exceptions.py:76
|
|
26
32
|
#, python-brace-format
|
|
27
33
|
msgid "{model} not found."
|
|
@@ -67,6 +73,10 @@ msgstr "utilisateur"
|
|
|
67
73
|
msgid "users"
|
|
68
74
|
msgstr "utilisateurs"
|
|
69
75
|
|
|
76
|
+
#: models/attachment_mixin.py:25
|
|
77
|
+
msgid "File"
|
|
78
|
+
msgstr "Fichier"
|
|
79
|
+
|
|
70
80
|
#: models/login_ban.py:54
|
|
71
81
|
msgid "Username"
|
|
72
82
|
msgstr "Nom d’utilisateur"
|
|
@@ -139,10 +149,14 @@ msgstr "Configuration MFA requise"
|
|
|
139
149
|
msgid "Is MFA forced"
|
|
140
150
|
msgstr "MFA est forcé"
|
|
141
151
|
|
|
152
|
+
#: models/ordered_model_mixin.py:10
|
|
153
|
+
msgid "Sequence"
|
|
154
|
+
msgstr "Séquence"
|
|
155
|
+
|
|
142
156
|
#: models/pfx_models.py:14
|
|
143
157
|
#, python-format
|
|
144
158
|
msgid "%(model_name)s with this %(field_labels)s already exists."
|
|
145
|
-
msgstr "%(model_name)s avec ce/cette %(field_labels)s
|
|
159
|
+
msgstr "%(model_name)s avec ce/cette %(field_labels)s existe déjà."
|
|
146
160
|
|
|
147
161
|
#: shortcuts.py:52
|
|
148
162
|
#, python-brace-format
|
|
@@ -172,7 +186,7 @@ msgstr "{key} doit être « true », « false », « 1 », « 0
|
|
|
172
186
|
#: templates/registration/otp_code_email.txt:2
|
|
173
187
|
#, python-format
|
|
174
188
|
msgid ""
|
|
175
|
-
"You
|
|
189
|
+
"You’re receiving this email because you requested an authentication code at "
|
|
176
190
|
"%(site_name)s."
|
|
177
191
|
msgstr ""
|
|
178
192
|
"Vous recevez cet e-mail parce que vous avez demandé un code d’authentication "
|
|
@@ -191,14 +205,14 @@ msgstr "Ce code est valable durant %(otp_validity)s minutes."
|
|
|
191
205
|
#: templates/registration/password_reset_email.txt:10
|
|
192
206
|
#: templates/registration/welcome_email.txt:10
|
|
193
207
|
msgid "Thanks for using our site!"
|
|
194
|
-
msgstr "Merci d
|
|
208
|
+
msgstr "Merci d’utiliser notre site !"
|
|
195
209
|
|
|
196
210
|
#: templates/registration/otp_code_email.txt:10
|
|
197
211
|
#: templates/registration/password_reset_email.txt:12
|
|
198
212
|
#: templates/registration/welcome_email.txt:12
|
|
199
213
|
#, python-format
|
|
200
214
|
msgid "The %(site_name)s team"
|
|
201
|
-
msgstr "L
|
|
215
|
+
msgstr "L’équipe de %(site_name)s"
|
|
202
216
|
|
|
203
217
|
#: templates/registration/otp_code_subject.txt:2
|
|
204
218
|
#, python-format
|
|
@@ -208,7 +222,7 @@ msgstr "Nouveau code d’authentication pour %(site_name)s"
|
|
|
208
222
|
#: templates/registration/password_reset_email.txt:2
|
|
209
223
|
#, python-format
|
|
210
224
|
msgid ""
|
|
211
|
-
"You
|
|
225
|
+
"You’re receiving this email because you requested a password reset for your "
|
|
212
226
|
"user account at %(site_name)s."
|
|
213
227
|
msgstr ""
|
|
214
228
|
"Vous recevez cet e-mail parce que vous avez demandé une réinitialisation du "
|
|
@@ -223,8 +237,8 @@ msgstr ""
|
|
|
223
237
|
|
|
224
238
|
#: templates/registration/password_reset_email.txt:8
|
|
225
239
|
#: templates/registration/welcome_email.txt:8
|
|
226
|
-
msgid "Your username, in case you
|
|
227
|
-
msgstr "Votre nom d
|
|
240
|
+
msgid "Your username, in case you’ve forgotten:"
|
|
241
|
+
msgstr "Votre nom d’utilisateur, au cas où vous l’auriez oublié :"
|
|
228
242
|
|
|
229
243
|
#: templates/registration/password_reset_subject.txt:2
|
|
230
244
|
#, python-format
|
|
@@ -281,11 +295,11 @@ msgstr "Un mot de passe vide n’est pas autorisé"
|
|
|
281
295
|
|
|
282
296
|
#: views/authentication_views.py:557
|
|
283
297
|
msgid "User and token are valid"
|
|
284
|
-
msgstr "L
|
|
298
|
+
msgstr "L’utilisateur et le token sont valides"
|
|
285
299
|
|
|
286
300
|
#: views/authentication_views.py:559
|
|
287
301
|
msgid "User or token is invalid"
|
|
288
|
-
msgstr "L
|
|
302
|
+
msgstr "L’utilisateur ou le token est invalide"
|
|
289
303
|
|
|
290
304
|
#: views/authentication_views.py:671
|
|
291
305
|
msgid "OTP is already enabled"
|
|
@@ -314,7 +328,7 @@ msgstr ""
|
|
|
314
328
|
|
|
315
329
|
#: views/authentication_views.py:1082
|
|
316
330
|
msgid "A new authentication code has been sent by email."
|
|
317
|
-
msgstr "Un nouveau code d
|
|
331
|
+
msgstr "Un nouveau code d’authentification a été envoyé par e-mail."
|
|
318
332
|
|
|
319
333
|
#: views/filters_views.py:81
|
|
320
334
|
#, python-brace-format
|
|
@@ -333,7 +347,7 @@ msgstr "Le paramètre object est requis pour move={move}."
|
|
|
333
347
|
#: views/ordered_rest_view_mixin.py:39
|
|
334
348
|
#, python-brace-format
|
|
335
349
|
msgid "object {pk} does not exists in this move context."
|
|
336
|
-
msgstr "object {pk} n
|
|
350
|
+
msgstr "object {pk} n’existe pas dans ce contexte de déplacement."
|
|
337
351
|
|
|
338
352
|
#: views/rest_views.py:228 views/rest_views.py:385
|
|
339
353
|
#, python-brace-format
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from .abstract_pfx_base_user import AbstractPFXBaseUser, AbstractPFXUser
|
|
2
|
+
from .attachment_mixin import AttachmentMixin
|
|
2
3
|
from .cache_mixins import CacheableMixin, CacheDependsMixin
|
|
3
4
|
from .login_ban import LoginBan
|
|
4
5
|
from .mfa_user_mixin import MFAUserMixin, OtpUserMixin
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
from django.conf import settings
|
|
4
|
+
from django.db import models
|
|
5
|
+
from django.utils.module_loading import import_string
|
|
6
|
+
from django.utils.translation import gettext_lazy as _
|
|
7
|
+
|
|
8
|
+
from pfx.pfxcore.fields import MediaField
|
|
9
|
+
|
|
10
|
+
logger = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
file_field_overrides_error = (
|
|
13
|
+
"PFX_ATTACHMENT_FILE_FIELD_OVERRIDES must be:\n"
|
|
14
|
+
"- a dict.\n"
|
|
15
|
+
"- a callable returning a dict.\n"
|
|
16
|
+
"- a dotted import path to a callable returning a dict.\n")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _get_file_key(obj, filename):
|
|
20
|
+
return obj.get_file_key(filename)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _get_attachment_file_field_kwargs():
|
|
24
|
+
kwargs = dict(
|
|
25
|
+
verbose_name=_("File"), get_key=_get_file_key,
|
|
26
|
+
auto_delete=True, blank=True, null=True)
|
|
27
|
+
|
|
28
|
+
try:
|
|
29
|
+
func_path = getattr(
|
|
30
|
+
settings, 'PFX_ATTACHMENT_FILE_FIELD_OVERRIDES', None)
|
|
31
|
+
custom_kwargs = {}
|
|
32
|
+
if func_path:
|
|
33
|
+
if isinstance(func_path, dict):
|
|
34
|
+
custom_kwargs = func_path
|
|
35
|
+
elif callable(func_path):
|
|
36
|
+
custom_kwargs = func_path()
|
|
37
|
+
else:
|
|
38
|
+
custom_kwargs = import_string(func_path)()
|
|
39
|
+
if custom_kwargs:
|
|
40
|
+
kwargs.update(custom_kwargs)
|
|
41
|
+
except Exception as e:
|
|
42
|
+
raise TypeError(
|
|
43
|
+
"PFX_ATTACHMENT_FILE_FIELD_OVERRIDES must be:\n"
|
|
44
|
+
"- a dict.\n"
|
|
45
|
+
"- a callable returning a dict.\n"
|
|
46
|
+
"- a dotted import path to a callable returning a dict.\n"
|
|
47
|
+
) from e
|
|
48
|
+
|
|
49
|
+
return kwargs
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class AttachmentMixin(models.Model):
|
|
53
|
+
file = MediaField(**_get_attachment_file_field_kwargs())
|
|
54
|
+
|
|
55
|
+
class Meta:
|
|
56
|
+
abstract = True
|
|
57
|
+
|
|
58
|
+
def get_file_key(self, filename):
|
|
59
|
+
raise NotImplementedError()
|
|
60
|
+
|
|
61
|
+
def __str__(self):
|
|
62
|
+
return (self.file or {}).get('name', '')
|
|
63
|
+
|
|
64
|
+
@property
|
|
65
|
+
def url(self):
|
|
66
|
+
if not getattr(self, 'api', None):
|
|
67
|
+
raise RuntimeError(
|
|
68
|
+
f"api attribute is not defined on {self.__class__}")
|
|
69
|
+
return f'{self.api}/{self.pk}/file'
|
|
70
|
+
|
|
71
|
+
def json_repr(self, **values):
|
|
72
|
+
return super().json_repr(
|
|
73
|
+
file={
|
|
74
|
+
'url': self.url,
|
|
75
|
+
'name': (self.file or {}).get('name'),
|
|
76
|
+
'content-type': (self.file or {}).get('content-type'),
|
|
77
|
+
'content-length': (self.file or {}).get('content-length')},
|
|
78
|
+
**values)
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
from django.db import models
|
|
2
2
|
from django.db.models import F, Max, Min
|
|
3
|
+
from django.utils.translation import gettext_lazy as _
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
class OrderedModelMixin(models.Model):
|
|
6
7
|
ordered_by = []
|
|
7
8
|
ordered_default = 'last'
|
|
8
9
|
|
|
9
|
-
seq = models.PositiveBigIntegerField("
|
|
10
|
+
seq = models.PositiveBigIntegerField(_("Sequence"))
|
|
10
11
|
|
|
11
12
|
class Meta:
|
|
12
13
|
abstract = True
|
|
@@ -167,3 +167,8 @@ def file_extension(filename):
|
|
|
167
167
|
return ''.join(suffixes[-2:])
|
|
168
168
|
else:
|
|
169
169
|
return suffixes[-1]
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def get_system_error_user_message(context=None):
|
|
173
|
+
# use str() to force lazy gettext string to be translated.
|
|
174
|
+
return str(settings.PFX_SYSTEM_ERROR_USER_MESSAGE)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{% load i18n %}{% autoescape off %}
|
|
2
|
-
{% blocktrans %}You
|
|
2
|
+
{% blocktrans %}You’re receiving this email because you requested an authentication code at {{ site_name }}.{% endblocktrans %}
|
|
3
3
|
|
|
4
4
|
{% trans "Authentication code:" %} {{ otp_code }}
|
|
5
5
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{% load i18n %}{% autoescape off %}
|
|
2
|
-
{% blocktrans %}You
|
|
2
|
+
{% blocktrans %}You’re receiving this email because you requested a password reset for your user account at {{ site_name }}.{% endblocktrans %}
|
|
3
3
|
|
|
4
4
|
{% trans "Please go to the following page and choose a new password:" %}
|
|
5
5
|
{% block reset_link %}
|
|
6
6
|
{{ reset_url }}
|
|
7
7
|
{% endblock %}
|
|
8
|
-
{% trans "Your username, in case you
|
|
8
|
+
{% trans "Your username, in case you’ve forgotten:" %} {{ user.get_username }}
|
|
9
9
|
|
|
10
10
|
{% trans "Thanks for using our site!" %}
|
|
11
11
|
|
{django_pfx-1.7.3.dev4 → django_pfx-1.7.3.dev6}/pfx/pfxcore/templates/registration/welcome_email.txt
RENAMED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
{% block reset_link %}
|
|
6
6
|
{{ reset_url }}
|
|
7
7
|
{% endblock %}
|
|
8
|
-
{% trans "Your username, in case you
|
|
8
|
+
{% trans "Your username, in case you’ve forgotten:" %} {{ user.get_username }}
|
|
9
9
|
|
|
10
10
|
{% trans "Thanks for using our site!" %}
|
|
11
11
|
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
SECRET_KEY = 'fake-key'
|
|
2
|
+
INSTALLED_APPS = [
|
|
3
|
+
'django.contrib.auth',
|
|
4
|
+
'django.contrib.contenttypes',
|
|
5
|
+
'django.contrib.postgres',
|
|
6
|
+
'pfx.pfxcore',
|
|
7
|
+
'pfx.userjobs',
|
|
8
|
+
]
|
|
9
|
+
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
|
10
|
+
STORAGE_DEFAULT = 'pfx.pfxcore.storage.LocalStorage'
|
|
11
|
+
|
|
12
|
+
CACHE_MEMORY = {
|
|
13
|
+
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
|
|
14
|
+
'LOCATION': 'unique-snowflake',
|
|
15
|
+
}
|
|
16
|
+
CACHES = {
|
|
17
|
+
'default': CACHE_MEMORY,
|
|
18
|
+
'django-q': CACHE_MEMORY
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
CHANNEL_LAYERS = {
|
|
22
|
+
"default": {
|
|
23
|
+
"BACKEND": "channels.layers.InMemoryChannelLayer"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
Q_CLUSTER = {
|
|
28
|
+
'retry': 600,
|
|
29
|
+
'timeout': 300,
|
|
30
|
+
'sync': True,
|
|
31
|
+
'catch_up': False,
|
|
32
|
+
'max_attempts': 5,
|
|
33
|
+
'orm': 'default'
|
|
34
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .apps import UserJobsConfig
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from django.apps import AppConfig
|
|
2
|
+
from django.db.models.signals import post_migrate
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def register_periodic_tasks(sender, **kwargs):
|
|
6
|
+
from . import tasks
|
|
7
|
+
tasks.register_periodic_tasks()
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class UserJobsConfig(AppConfig):
|
|
11
|
+
name = 'pfx.userjobs'
|
|
12
|
+
default = True
|
|
13
|
+
|
|
14
|
+
def ready(self):
|
|
15
|
+
from pfx.userjobs.models.user_job import (
|
|
16
|
+
get_executor,
|
|
17
|
+
get_websocket_provider,
|
|
18
|
+
)
|
|
19
|
+
get_executor().validate_setup()
|
|
20
|
+
get_websocket_provider().validate_setup()
|
|
21
|
+
post_migrate.connect(register_periodic_tasks, sender=self)
|
|
22
|
+
super().ready()
|
|
Binary file
|