django-whiteneuron 0.2.48.5__tar.gz → 0.3.0.3__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_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/PKG-INFO +41 -11
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/README.md +38 -8
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/django_whiteneuron.egg-info/PKG-INFO +41 -11
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/django_whiteneuron.egg-info/SOURCES.txt +4 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/django_whiteneuron.egg-info/requires.txt +2 -2
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/pyproject.toml +8 -3
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/urls.py +1 -0
- django_whiteneuron-0.3.0.3/whiteneuron/base/utils.py +165 -0
- django_whiteneuron-0.3.0.3/whiteneuron/file_management/admin.py +163 -0
- django_whiteneuron-0.3.0.3/whiteneuron/file_management/migrations/0004_excelfile_hash_pdffile_hash.py +23 -0
- django_whiteneuron-0.3.0.3/whiteneuron/file_management/models.py +121 -0
- django_whiteneuron-0.3.0.3/whiteneuron/file_management/urls.py +7 -0
- django_whiteneuron-0.3.0.3/whiteneuron/file_management/views.py +50 -0
- django_whiteneuron-0.3.0.3/whiteneuron/locale/vi/LC_MESSAGES/django.mo +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/locale/vi/LC_MESSAGES/django.po +56 -0
- django_whiteneuron-0.3.0.3/whiteneuron/static/base/css/styles.css +2 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/static/base/js/loading.js +0 -10
- {django_whiteneuron-0.2.48.5/whiteneuron/file_management → django_whiteneuron-0.3.0.3/whiteneuron/synchronization}/views.py +0 -0
- django_whiteneuron-0.2.48.5/whiteneuron/base/utils.py → django_whiteneuron-0.3.0.3/whiteneuron/templates/admin/signature.html +15 -158
- django_whiteneuron-0.3.0.3/whiteneuron/templates/file_management/widgets/clearable_file_input_no_download.html +20 -0
- django_whiteneuron-0.2.48.5/whiteneuron/file_management/admin.py +0 -32
- django_whiteneuron-0.2.48.5/whiteneuron/file_management/models.py +0 -65
- django_whiteneuron-0.2.48.5/whiteneuron/locale/vi/LC_MESSAGES/django.mo +0 -0
- django_whiteneuron-0.2.48.5/whiteneuron/static/base/css/styles.css +0 -2
- django_whiteneuron-0.2.48.5/whiteneuron/synchronization/views.py +0 -3
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/LICENSE +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/django_whiteneuron.egg-info/dependency_links.txt +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/django_whiteneuron.egg-info/top_level.txt +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/setup.cfg +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/__init__.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/__init__.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/admin.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/apps.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/asgi.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/ckeditor.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/filters.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/forms.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/management/__init__.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/management/commands/__init__.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/management/commands/init_admin.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/management/commands/init_groupuser.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/management/commands/init_guest.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/middleware.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/migrations/0001_initial.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/migrations/0002_imagemodel_userprofile_user_avatar_user_biography_and_more.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/migrations/0003_notification_obj_link.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/migrations/0004_delete_notification.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/migrations/0005_user_show_softdelete.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/migrations/0006_user_is_bot.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/migrations/0007_app.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/migrations/0008_app_created_at_app_created_by_app_deleted_at_and_more.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/migrations/0009_alter_app_table.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/migrations/0010_app_category.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/migrations/0011_alter_app_options.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/migrations/0012_app_permission.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/migrations/0013_app_thumbnail_url.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/migrations/0014_alter_app_created_at_alter_app_updated_at_and_more.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/migrations/0015_ipblacklist.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/migrations/0016_uablacklist.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/migrations/0017_alter_uablacklist_pattern.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/migrations/__init__.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/modeladmin.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/models.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/resources.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/settings.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/sites.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/tasks.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/templatetags/__init__.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/templatetags/unfold_list_custom.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/templatetags/wn_filters.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/tests.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/thread_local.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/views.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/base/widgets.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/contrib/__init__.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/contrib/wn_import_export/__init__.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/contrib/wn_import_export/admin.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/contrib/wn_import_export/constants.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/contrib/wn_import_export/mixins.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/contrib/wn_import_export/tasks.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/contrib/wn_import_export/utils.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/contrib/wn_modeltranslation/__init__.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/contrib/wn_modeltranslation/admin.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/contrib/wn_modeltranslation/utils.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/dashboard/__init__.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/dashboard/admin.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/dashboard/apps.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/dashboard/migrations/__init__.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/dashboard/models.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/dashboard/tests.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/dashboard/views.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/feedbacks/__init__.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/feedbacks/admin.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/feedbacks/apps.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/feedbacks/migrations/0001_initial.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/feedbacks/migrations/0002_feedbackdata_created_by_feedbackdata_deleted_at_and_more.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/feedbacks/migrations/0003_feedbackdata_note.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/feedbacks/migrations/0004_alter_feedbackdata_object_id.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/feedbacks/migrations/0005_feedbackdata_field.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/feedbacks/migrations/0006_alter_feedbackdata_created_at_and_more.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/feedbacks/migrations/__init__.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/feedbacks/models.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/feedbacks/tests.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/feedbacks/urls.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/feedbacks/utils.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/feedbacks/views.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/file_management/__init__.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/file_management/apps.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/file_management/migrations/0001_initial.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/file_management/migrations/0002_alter_excelfile_options_alter_pdffile_options_and_more.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/file_management/migrations/0003_alter_excelfile_created_at_and_more.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/file_management/migrations/__init__.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/file_management/tests.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/file_management/utils.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/manage.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/notification/__init__.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/notification/admin.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/notification/apps.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/notification/consumers.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/notification/management/__init__.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/notification/management/commands/__init__.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/notification/management/commands/call_demo_noti.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/notification/migrations/0001_initial.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/notification/migrations/0002_alter_notificationconfig_event_type.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/notification/migrations/0003_notification.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/notification/migrations/0004_alter_notification_flag.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/notification/migrations/0005_notification_keywords.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/notification/migrations/0006_remove_notification_keywords.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/notification/migrations/0007_notification_changed_data.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/notification/migrations/0008_alter_notification_changed_data.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/notification/migrations/0009_notification_action_by_alter_notification_user.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/notification/migrations/0010_alter_notification_user.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/notification/migrations/0011_alter_notification_user.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/notification/migrations/0012_alter_notification_action_and_more.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/notification/migrations/__init__.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/notification/models.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/notification/routing.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/notification/tests.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/notification/utils.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/notification/views.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/static/base/css/btn-styles.css +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/static/base/css/ckeditor5.css +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/static/base/css/loading.css +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/static/base/forms/css/html-editor.css +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/static/base/forms/js/format.html.js +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/static/base/forms/js/trix.config.js +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/static/base/images/delete.svg +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/static/base/images/edit.svg +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/static/base/images/icon-viewlink.svg +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/static/base/images/loading.gif +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/static/base/images/login-bg.jpg +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/static/base/images/login_bg.jpg +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/static/base/images/logo/WhiteNeuron.png +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/static/base/js/chart.min.js +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/static/base/js/d3.v7.min.js +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/static/base/js/whiteneuron.js +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/synchronization/__init__.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/synchronization/admin.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/synchronization/apps.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/synchronization/migrations/__init__.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/synchronization/models.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/synchronization/tests.py +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/templates/400.html +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/templates/403.html +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/templates/404.html +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/templates/429.html +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/templates/500.html +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/templates/admin/auth/user/add_form.html +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/templates/admin/base/app_change_list.html +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/templates/admin/base/image_change_form.html +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/templates/admin/base/userprofile_change_form.html +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/templates/admin/base.html +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/templates/admin/change_list.html +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/templates/admin/feedbacks/feedback_change_form.html +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/templates/admin/grid_view_results.html +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/templates/admin/header.html +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/templates/admin/index.html +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/templates/admin/login.html +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/templates/admin/login_after.html +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/templates/admin/search_form.html +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/templates/admin/submit_line.html +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/templates/admin/wn_change_form.html +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/templates/admin/wn_history_panel.html +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/templates/base/forms/helpers/toolbar.html +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/templates/base/forms/wysiwyg.html +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/templates/base.html +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/templates/unfold/helpers/account_links.html +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/templates/unfold/helpers/app_list_badge.html +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/templates/unfold/helpers/field_password.html +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/templates/unfold/helpers/navigation_user.html +0 -0
- {django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/whiteneuron/templates/unfold/helpers/pagination.html +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: django-whiteneuron
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0.3
|
|
4
4
|
Summary: A modern Django Admin extension with enhanced UI/UX, dashboard, feedback, file management, rate limiting, IP blacklisting, and advanced admin integrations built on django-unfold.
|
|
5
5
|
Author-email: White Neuron <anhnt@whiteneuron.ai>
|
|
6
6
|
License: MIT License
|
|
@@ -58,7 +58,7 @@ Requires-Dist: markdown>=3.7
|
|
|
58
58
|
Requires-Dist: openai>=1.58.1
|
|
59
59
|
Requires-Dist: openpyxl>=3.1.5
|
|
60
60
|
Requires-Dist: pandas>=2.2.3
|
|
61
|
-
Requires-Dist: pillow>=12.
|
|
61
|
+
Requires-Dist: pillow>=12.2.0
|
|
62
62
|
Requires-Dist: python-dotenv>=1.0.1
|
|
63
63
|
Requires-Dist: redis>=5.2.1
|
|
64
64
|
Requires-Dist: sentry-sdk==2.28.0
|
|
@@ -74,7 +74,7 @@ Requires-Dist: django-ckeditor-5>=0.2.18
|
|
|
74
74
|
Requires-Dist: django-cors-headers>=4.3.0
|
|
75
75
|
Requires-Dist: django-unfold>=0.85.0
|
|
76
76
|
Requires-Dist: djangoql>=0.18.1
|
|
77
|
-
Requires-Dist: cryptography>=46.0.
|
|
77
|
+
Requires-Dist: cryptography>=46.0.7
|
|
78
78
|
Requires-Dist: pyopenssl==26.0.0
|
|
79
79
|
Provides-Extra: dev
|
|
80
80
|
Requires-Dist: pytest; extra == "dev"
|
|
@@ -96,7 +96,7 @@ A modern Django Admin extension focused on UI/UX, dashboard, feedback, file mana
|
|
|
96
96
|
|
|
97
97
|
## Current Version
|
|
98
98
|
|
|
99
|
-
- 0.
|
|
99
|
+
- 0.3.0.2
|
|
100
100
|
|
|
101
101
|
## Compatibility
|
|
102
102
|
|
|
@@ -107,10 +107,40 @@ A modern Django Admin extension focused on UI/UX, dashboard, feedback, file mana
|
|
|
107
107
|
|
|
108
108
|
## Changelog
|
|
109
109
|
|
|
110
|
-
### v0.
|
|
111
|
-
**
|
|
112
|
-
- **
|
|
113
|
-
- **
|
|
110
|
+
### v0.3.0.3 (2026-04-14) — latest
|
|
111
|
+
**Dependency: Upgrade pillow ≥12.2.0, cryptography ≥46.0.7**
|
|
112
|
+
- **Updated**: `pillow` minimum version bumped from `12.1.1` to `12.2.0` — latest upstream patch.
|
|
113
|
+
- **Updated**: `cryptography` minimum version bumped from `46.0.5` to `46.0.7` — security and bug-fix release.
|
|
114
|
+
|
|
115
|
+
### v0.3.0.2 (2026-04-13)
|
|
116
|
+
**Hotfix: Loading overlay no longer auto-hides after timeout**
|
|
117
|
+
- **Fixed**: `loading.js` — removed the auto-hide logic that dismissed the overlay after 45 seconds. The overlay now only hides when the server sends back the `wn_loading_done` cookie, or via `pageshow`/`visibilitychange`/`focus` events.
|
|
118
|
+
|
|
119
|
+
### v0.3.0.1 (2026-04-13)
|
|
120
|
+
**Hotfix: Email signature extracted to standalone file; exclude signature_ceo.html from build**
|
|
121
|
+
- **Fixed**: `TEMPLATE` in `base/utils.py` — replaced hardcoded inline HTML signature with a `{signature}` placeholder; content is now read from `templates/admin/signature.html` at the time `send_email_login` is called.
|
|
122
|
+
- **Added**: `_load_signature()` helper — reads `signature.html` relative to `utils.py`.
|
|
123
|
+
- **Added**: `templates/admin/signature.html` — standalone HTML email signature (CTO).
|
|
124
|
+
- **Added**: `templates/admin/signature_ceo.html` — CEO email signature (local-only, excluded from package build).
|
|
125
|
+
- **Config**: `pyproject.toml` — added `[tool.setuptools.exclude-package-data]` to exclude `signature_ceo.html` from wheel/sdist.
|
|
126
|
+
|
|
127
|
+
### v0.3.0 (2026-04-13)
|
|
128
|
+
**Feature: File integrity protection — SHA-256 hash verification for ExcelFile & PDFFile**
|
|
129
|
+
- **Added**: `compute_file_hash()` function — computes SHA-256 of a `FieldFile` via direct `storage.open()` to avoid Django internal state issues (works for both in-memory uploads and committed storage files).
|
|
130
|
+
- **Added**: `BaseFile.save()` override — automatically computes and stores SHA-256 hash on every new upload; resets `status='done'` when file is replaced after an error; backfills hash for existing files with no hash.
|
|
131
|
+
- **Added**: `BaseFile.verify_integrity()` — compares live storage hash against stored hash; returns `False` if missing or mismatched.
|
|
132
|
+
- **Added**: `download_file` view — `@login_required` endpoint at `file-management/download/<type>/<pk>/`; enrolls legacy records on first download, blocks tampered files with `403 Forbidden`, marks them `status='error'`.
|
|
133
|
+
- **Added**: `file_management/urls.py` — wired into `base/urls.py`.
|
|
134
|
+
- **Added**: `FileInputNoDownload` widget — extends `UnfoldAdminFileFieldWidget` with a custom template that removes the direct download button; adds `accepted_file_types` support per admin subclass (`.xlsx,.xls,.csv` for Excel; `.pdf` for PDF).
|
|
135
|
+
- **Added**: `BaseFileAdmin` enhancements — `integrity_status`, `hash_display`, `current_hash_display` readonly fields; `verified_download` smart button (primary button when OK, error badge when tampered/missing); `change_view` shows Django error message banner on integrity failure; `get_fieldsets` context-aware layout (auto/upload/new).
|
|
136
|
+
- **Fixed**: `status_view` / `method_view` XSS — replaced f-string + `format_html` pattern with proper `format_html(template, *args)` escaping.
|
|
137
|
+
- **Fixed**: `file.delete(save=False)` in `BaseFile.delete()` — prevents extra `save()` call after file deletion.
|
|
138
|
+
- **Improved**: `accepted_file_types` class attribute on admin subclasses — browser-level file type filtering in upload dialog.
|
|
139
|
+
|
|
140
|
+
### v0.2.48.4 (2026-04-11)
|
|
141
|
+
**Security: Upgrade cbor2 5.9.0 and ujson 5.12.0**
|
|
142
|
+
- **Security**: `cbor2` upgraded from `v5.8.0` to `v5.9.0` — patch release with bug fixes and improved CBOR encoding/decoding.
|
|
143
|
+
- **Security**: `ujson` upgraded from `v5.11.0` to `v5.12.0` — security patch and improved JSON serialization performance.
|
|
114
144
|
|
|
115
145
|
### v0.2.48.3 (2026-04-10)
|
|
116
146
|
**Improve: Notification list — DaisyUI badge display, search field verbose names**
|
|
@@ -119,9 +149,9 @@ A modern Django Admin extension focused on UI/UX, dashboard, feedback, file mana
|
|
|
119
149
|
- **Fixed**: `get_verbose_name_field` now traverses `__`-separated lookup paths (e.g. `user__username`) to resolve proper verbose names for all search fields in `search_help_text`.
|
|
120
150
|
|
|
121
151
|
### v0.2.48.2 (2026-04-10)
|
|
122
|
-
**Security:
|
|
123
|
-
- **Security**: `django` lower bound
|
|
124
|
-
- **Security**: `pyopenssl==26.0.0`
|
|
152
|
+
**Security: Upgrade django 5.2.13 and add pyOpenSSL 26.0.0**
|
|
153
|
+
- **Security**: `django` lower bound raised from `>=5.2.12` to `>=5.2.13` — latest Django security patch.
|
|
154
|
+
- **Security**: `pyopenssl==26.0.0` added as an explicit dependency — ensures the latest version of pyOpenSSL is used, patching potential vulnerabilities in TLS/SSL handling.
|
|
125
155
|
|
|
126
156
|
### v0.2.48.1 (2026-04-06)
|
|
127
157
|
**Fix: Duplicate history entries in change history panel**
|
|
@@ -11,7 +11,7 @@ A modern Django Admin extension focused on UI/UX, dashboard, feedback, file mana
|
|
|
11
11
|
|
|
12
12
|
## Current Version
|
|
13
13
|
|
|
14
|
-
- 0.
|
|
14
|
+
- 0.3.0.2
|
|
15
15
|
|
|
16
16
|
## Compatibility
|
|
17
17
|
|
|
@@ -22,10 +22,40 @@ A modern Django Admin extension focused on UI/UX, dashboard, feedback, file mana
|
|
|
22
22
|
|
|
23
23
|
## Changelog
|
|
24
24
|
|
|
25
|
-
### v0.
|
|
26
|
-
**
|
|
27
|
-
- **
|
|
28
|
-
- **
|
|
25
|
+
### v0.3.0.3 (2026-04-14) — latest
|
|
26
|
+
**Dependency: Upgrade pillow ≥12.2.0, cryptography ≥46.0.7**
|
|
27
|
+
- **Updated**: `pillow` minimum version bumped from `12.1.1` to `12.2.0` — latest upstream patch.
|
|
28
|
+
- **Updated**: `cryptography` minimum version bumped from `46.0.5` to `46.0.7` — security and bug-fix release.
|
|
29
|
+
|
|
30
|
+
### v0.3.0.2 (2026-04-13)
|
|
31
|
+
**Hotfix: Loading overlay no longer auto-hides after timeout**
|
|
32
|
+
- **Fixed**: `loading.js` — removed the auto-hide logic that dismissed the overlay after 45 seconds. The overlay now only hides when the server sends back the `wn_loading_done` cookie, or via `pageshow`/`visibilitychange`/`focus` events.
|
|
33
|
+
|
|
34
|
+
### v0.3.0.1 (2026-04-13)
|
|
35
|
+
**Hotfix: Email signature extracted to standalone file; exclude signature_ceo.html from build**
|
|
36
|
+
- **Fixed**: `TEMPLATE` in `base/utils.py` — replaced hardcoded inline HTML signature with a `{signature}` placeholder; content is now read from `templates/admin/signature.html` at the time `send_email_login` is called.
|
|
37
|
+
- **Added**: `_load_signature()` helper — reads `signature.html` relative to `utils.py`.
|
|
38
|
+
- **Added**: `templates/admin/signature.html` — standalone HTML email signature (CTO).
|
|
39
|
+
- **Added**: `templates/admin/signature_ceo.html` — CEO email signature (local-only, excluded from package build).
|
|
40
|
+
- **Config**: `pyproject.toml` — added `[tool.setuptools.exclude-package-data]` to exclude `signature_ceo.html` from wheel/sdist.
|
|
41
|
+
|
|
42
|
+
### v0.3.0 (2026-04-13)
|
|
43
|
+
**Feature: File integrity protection — SHA-256 hash verification for ExcelFile & PDFFile**
|
|
44
|
+
- **Added**: `compute_file_hash()` function — computes SHA-256 of a `FieldFile` via direct `storage.open()` to avoid Django internal state issues (works for both in-memory uploads and committed storage files).
|
|
45
|
+
- **Added**: `BaseFile.save()` override — automatically computes and stores SHA-256 hash on every new upload; resets `status='done'` when file is replaced after an error; backfills hash for existing files with no hash.
|
|
46
|
+
- **Added**: `BaseFile.verify_integrity()` — compares live storage hash against stored hash; returns `False` if missing or mismatched.
|
|
47
|
+
- **Added**: `download_file` view — `@login_required` endpoint at `file-management/download/<type>/<pk>/`; enrolls legacy records on first download, blocks tampered files with `403 Forbidden`, marks them `status='error'`.
|
|
48
|
+
- **Added**: `file_management/urls.py` — wired into `base/urls.py`.
|
|
49
|
+
- **Added**: `FileInputNoDownload` widget — extends `UnfoldAdminFileFieldWidget` with a custom template that removes the direct download button; adds `accepted_file_types` support per admin subclass (`.xlsx,.xls,.csv` for Excel; `.pdf` for PDF).
|
|
50
|
+
- **Added**: `BaseFileAdmin` enhancements — `integrity_status`, `hash_display`, `current_hash_display` readonly fields; `verified_download` smart button (primary button when OK, error badge when tampered/missing); `change_view` shows Django error message banner on integrity failure; `get_fieldsets` context-aware layout (auto/upload/new).
|
|
51
|
+
- **Fixed**: `status_view` / `method_view` XSS — replaced f-string + `format_html` pattern with proper `format_html(template, *args)` escaping.
|
|
52
|
+
- **Fixed**: `file.delete(save=False)` in `BaseFile.delete()` — prevents extra `save()` call after file deletion.
|
|
53
|
+
- **Improved**: `accepted_file_types` class attribute on admin subclasses — browser-level file type filtering in upload dialog.
|
|
54
|
+
|
|
55
|
+
### v0.2.48.4 (2026-04-11)
|
|
56
|
+
**Security: Upgrade cbor2 5.9.0 and ujson 5.12.0**
|
|
57
|
+
- **Security**: `cbor2` upgraded from `v5.8.0` to `v5.9.0` — patch release with bug fixes and improved CBOR encoding/decoding.
|
|
58
|
+
- **Security**: `ujson` upgraded from `v5.11.0` to `v5.12.0` — security patch and improved JSON serialization performance.
|
|
29
59
|
|
|
30
60
|
### v0.2.48.3 (2026-04-10)
|
|
31
61
|
**Improve: Notification list — DaisyUI badge display, search field verbose names**
|
|
@@ -34,9 +64,9 @@ A modern Django Admin extension focused on UI/UX, dashboard, feedback, file mana
|
|
|
34
64
|
- **Fixed**: `get_verbose_name_field` now traverses `__`-separated lookup paths (e.g. `user__username`) to resolve proper verbose names for all search fields in `search_help_text`.
|
|
35
65
|
|
|
36
66
|
### v0.2.48.2 (2026-04-10)
|
|
37
|
-
**Security:
|
|
38
|
-
- **Security**: `django` lower bound
|
|
39
|
-
- **Security**: `pyopenssl==26.0.0`
|
|
67
|
+
**Security: Upgrade django 5.2.13 and add pyOpenSSL 26.0.0**
|
|
68
|
+
- **Security**: `django` lower bound raised from `>=5.2.12` to `>=5.2.13` — latest Django security patch.
|
|
69
|
+
- **Security**: `pyopenssl==26.0.0` added as an explicit dependency — ensures the latest version of pyOpenSSL is used, patching potential vulnerabilities in TLS/SSL handling.
|
|
40
70
|
|
|
41
71
|
### v0.2.48.1 (2026-04-06)
|
|
42
72
|
**Fix: Duplicate history entries in change history panel**
|
{django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/django_whiteneuron.egg-info/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: django-whiteneuron
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0.3
|
|
4
4
|
Summary: A modern Django Admin extension with enhanced UI/UX, dashboard, feedback, file management, rate limiting, IP blacklisting, and advanced admin integrations built on django-unfold.
|
|
5
5
|
Author-email: White Neuron <anhnt@whiteneuron.ai>
|
|
6
6
|
License: MIT License
|
|
@@ -58,7 +58,7 @@ Requires-Dist: markdown>=3.7
|
|
|
58
58
|
Requires-Dist: openai>=1.58.1
|
|
59
59
|
Requires-Dist: openpyxl>=3.1.5
|
|
60
60
|
Requires-Dist: pandas>=2.2.3
|
|
61
|
-
Requires-Dist: pillow>=12.
|
|
61
|
+
Requires-Dist: pillow>=12.2.0
|
|
62
62
|
Requires-Dist: python-dotenv>=1.0.1
|
|
63
63
|
Requires-Dist: redis>=5.2.1
|
|
64
64
|
Requires-Dist: sentry-sdk==2.28.0
|
|
@@ -74,7 +74,7 @@ Requires-Dist: django-ckeditor-5>=0.2.18
|
|
|
74
74
|
Requires-Dist: django-cors-headers>=4.3.0
|
|
75
75
|
Requires-Dist: django-unfold>=0.85.0
|
|
76
76
|
Requires-Dist: djangoql>=0.18.1
|
|
77
|
-
Requires-Dist: cryptography>=46.0.
|
|
77
|
+
Requires-Dist: cryptography>=46.0.7
|
|
78
78
|
Requires-Dist: pyopenssl==26.0.0
|
|
79
79
|
Provides-Extra: dev
|
|
80
80
|
Requires-Dist: pytest; extra == "dev"
|
|
@@ -96,7 +96,7 @@ A modern Django Admin extension focused on UI/UX, dashboard, feedback, file mana
|
|
|
96
96
|
|
|
97
97
|
## Current Version
|
|
98
98
|
|
|
99
|
-
- 0.
|
|
99
|
+
- 0.3.0.2
|
|
100
100
|
|
|
101
101
|
## Compatibility
|
|
102
102
|
|
|
@@ -107,10 +107,40 @@ A modern Django Admin extension focused on UI/UX, dashboard, feedback, file mana
|
|
|
107
107
|
|
|
108
108
|
## Changelog
|
|
109
109
|
|
|
110
|
-
### v0.
|
|
111
|
-
**
|
|
112
|
-
- **
|
|
113
|
-
- **
|
|
110
|
+
### v0.3.0.3 (2026-04-14) — latest
|
|
111
|
+
**Dependency: Upgrade pillow ≥12.2.0, cryptography ≥46.0.7**
|
|
112
|
+
- **Updated**: `pillow` minimum version bumped from `12.1.1` to `12.2.0` — latest upstream patch.
|
|
113
|
+
- **Updated**: `cryptography` minimum version bumped from `46.0.5` to `46.0.7` — security and bug-fix release.
|
|
114
|
+
|
|
115
|
+
### v0.3.0.2 (2026-04-13)
|
|
116
|
+
**Hotfix: Loading overlay no longer auto-hides after timeout**
|
|
117
|
+
- **Fixed**: `loading.js` — removed the auto-hide logic that dismissed the overlay after 45 seconds. The overlay now only hides when the server sends back the `wn_loading_done` cookie, or via `pageshow`/`visibilitychange`/`focus` events.
|
|
118
|
+
|
|
119
|
+
### v0.3.0.1 (2026-04-13)
|
|
120
|
+
**Hotfix: Email signature extracted to standalone file; exclude signature_ceo.html from build**
|
|
121
|
+
- **Fixed**: `TEMPLATE` in `base/utils.py` — replaced hardcoded inline HTML signature with a `{signature}` placeholder; content is now read from `templates/admin/signature.html` at the time `send_email_login` is called.
|
|
122
|
+
- **Added**: `_load_signature()` helper — reads `signature.html` relative to `utils.py`.
|
|
123
|
+
- **Added**: `templates/admin/signature.html` — standalone HTML email signature (CTO).
|
|
124
|
+
- **Added**: `templates/admin/signature_ceo.html` — CEO email signature (local-only, excluded from package build).
|
|
125
|
+
- **Config**: `pyproject.toml` — added `[tool.setuptools.exclude-package-data]` to exclude `signature_ceo.html` from wheel/sdist.
|
|
126
|
+
|
|
127
|
+
### v0.3.0 (2026-04-13)
|
|
128
|
+
**Feature: File integrity protection — SHA-256 hash verification for ExcelFile & PDFFile**
|
|
129
|
+
- **Added**: `compute_file_hash()` function — computes SHA-256 of a `FieldFile` via direct `storage.open()` to avoid Django internal state issues (works for both in-memory uploads and committed storage files).
|
|
130
|
+
- **Added**: `BaseFile.save()` override — automatically computes and stores SHA-256 hash on every new upload; resets `status='done'` when file is replaced after an error; backfills hash for existing files with no hash.
|
|
131
|
+
- **Added**: `BaseFile.verify_integrity()` — compares live storage hash against stored hash; returns `False` if missing or mismatched.
|
|
132
|
+
- **Added**: `download_file` view — `@login_required` endpoint at `file-management/download/<type>/<pk>/`; enrolls legacy records on first download, blocks tampered files with `403 Forbidden`, marks them `status='error'`.
|
|
133
|
+
- **Added**: `file_management/urls.py` — wired into `base/urls.py`.
|
|
134
|
+
- **Added**: `FileInputNoDownload` widget — extends `UnfoldAdminFileFieldWidget` with a custom template that removes the direct download button; adds `accepted_file_types` support per admin subclass (`.xlsx,.xls,.csv` for Excel; `.pdf` for PDF).
|
|
135
|
+
- **Added**: `BaseFileAdmin` enhancements — `integrity_status`, `hash_display`, `current_hash_display` readonly fields; `verified_download` smart button (primary button when OK, error badge when tampered/missing); `change_view` shows Django error message banner on integrity failure; `get_fieldsets` context-aware layout (auto/upload/new).
|
|
136
|
+
- **Fixed**: `status_view` / `method_view` XSS — replaced f-string + `format_html` pattern with proper `format_html(template, *args)` escaping.
|
|
137
|
+
- **Fixed**: `file.delete(save=False)` in `BaseFile.delete()` — prevents extra `save()` call after file deletion.
|
|
138
|
+
- **Improved**: `accepted_file_types` class attribute on admin subclasses — browser-level file type filtering in upload dialog.
|
|
139
|
+
|
|
140
|
+
### v0.2.48.4 (2026-04-11)
|
|
141
|
+
**Security: Upgrade cbor2 5.9.0 and ujson 5.12.0**
|
|
142
|
+
- **Security**: `cbor2` upgraded from `v5.8.0` to `v5.9.0` — patch release with bug fixes and improved CBOR encoding/decoding.
|
|
143
|
+
- **Security**: `ujson` upgraded from `v5.11.0` to `v5.12.0` — security patch and improved JSON serialization performance.
|
|
114
144
|
|
|
115
145
|
### v0.2.48.3 (2026-04-10)
|
|
116
146
|
**Improve: Notification list — DaisyUI badge display, search field verbose names**
|
|
@@ -119,9 +149,9 @@ A modern Django Admin extension focused on UI/UX, dashboard, feedback, file mana
|
|
|
119
149
|
- **Fixed**: `get_verbose_name_field` now traverses `__`-separated lookup paths (e.g. `user__username`) to resolve proper verbose names for all search fields in `search_help_text`.
|
|
120
150
|
|
|
121
151
|
### v0.2.48.2 (2026-04-10)
|
|
122
|
-
**Security:
|
|
123
|
-
- **Security**: `django` lower bound
|
|
124
|
-
- **Security**: `pyopenssl==26.0.0`
|
|
152
|
+
**Security: Upgrade django 5.2.13 and add pyOpenSSL 26.0.0**
|
|
153
|
+
- **Security**: `django` lower bound raised from `>=5.2.12` to `>=5.2.13` — latest Django security patch.
|
|
154
|
+
- **Security**: `pyopenssl==26.0.0` added as an explicit dependency — ensures the latest version of pyOpenSSL is used, patching potential vulnerabilities in TLS/SSL handling.
|
|
125
155
|
|
|
126
156
|
### v0.2.48.1 (2026-04-06)
|
|
127
157
|
**Fix: Duplicate history entries in change history panel**
|
{django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/django_whiteneuron.egg-info/SOURCES.txt
RENAMED
|
@@ -91,11 +91,13 @@ whiteneuron/file_management/admin.py
|
|
|
91
91
|
whiteneuron/file_management/apps.py
|
|
92
92
|
whiteneuron/file_management/models.py
|
|
93
93
|
whiteneuron/file_management/tests.py
|
|
94
|
+
whiteneuron/file_management/urls.py
|
|
94
95
|
whiteneuron/file_management/utils.py
|
|
95
96
|
whiteneuron/file_management/views.py
|
|
96
97
|
whiteneuron/file_management/migrations/0001_initial.py
|
|
97
98
|
whiteneuron/file_management/migrations/0002_alter_excelfile_options_alter_pdffile_options_and_more.py
|
|
98
99
|
whiteneuron/file_management/migrations/0003_alter_excelfile_created_at_and_more.py
|
|
100
|
+
whiteneuron/file_management/migrations/0004_excelfile_hash_pdffile_hash.py
|
|
99
101
|
whiteneuron/file_management/migrations/__init__.py
|
|
100
102
|
whiteneuron/locale/vi/LC_MESSAGES/django.mo
|
|
101
103
|
whiteneuron/locale/vi/LC_MESSAGES/django.po
|
|
@@ -163,6 +165,7 @@ whiteneuron/templates/admin/index.html
|
|
|
163
165
|
whiteneuron/templates/admin/login.html
|
|
164
166
|
whiteneuron/templates/admin/login_after.html
|
|
165
167
|
whiteneuron/templates/admin/search_form.html
|
|
168
|
+
whiteneuron/templates/admin/signature.html
|
|
166
169
|
whiteneuron/templates/admin/submit_line.html
|
|
167
170
|
whiteneuron/templates/admin/wn_change_form.html
|
|
168
171
|
whiteneuron/templates/admin/wn_history_panel.html
|
|
@@ -173,6 +176,7 @@ whiteneuron/templates/admin/base/userprofile_change_form.html
|
|
|
173
176
|
whiteneuron/templates/admin/feedbacks/feedback_change_form.html
|
|
174
177
|
whiteneuron/templates/base/forms/wysiwyg.html
|
|
175
178
|
whiteneuron/templates/base/forms/helpers/toolbar.html
|
|
179
|
+
whiteneuron/templates/file_management/widgets/clearable_file_input_no_download.html
|
|
176
180
|
whiteneuron/templates/unfold/helpers/account_links.html
|
|
177
181
|
whiteneuron/templates/unfold/helpers/app_list_badge.html
|
|
178
182
|
whiteneuron/templates/unfold/helpers/field_password.html
|
{django_whiteneuron-0.2.48.5 → django_whiteneuron-0.3.0.3}/django_whiteneuron.egg-info/requires.txt
RENAMED
|
@@ -13,7 +13,7 @@ markdown>=3.7
|
|
|
13
13
|
openai>=1.58.1
|
|
14
14
|
openpyxl>=3.1.5
|
|
15
15
|
pandas>=2.2.3
|
|
16
|
-
pillow>=12.
|
|
16
|
+
pillow>=12.2.0
|
|
17
17
|
python-dotenv>=1.0.1
|
|
18
18
|
redis>=5.2.1
|
|
19
19
|
sentry-sdk==2.28.0
|
|
@@ -29,7 +29,7 @@ django-ckeditor-5>=0.2.18
|
|
|
29
29
|
django-cors-headers>=4.3.0
|
|
30
30
|
django-unfold>=0.85.0
|
|
31
31
|
djangoql>=0.18.1
|
|
32
|
-
cryptography>=46.0.
|
|
32
|
+
cryptography>=46.0.7
|
|
33
33
|
pyopenssl==26.0.0
|
|
34
34
|
|
|
35
35
|
[dev]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "django-whiteneuron"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.3.0.3"
|
|
4
4
|
description = "A modern Django Admin extension with enhanced UI/UX, dashboard, feedback, file management, rate limiting, IP blacklisting, and advanced admin integrations built on django-unfold."
|
|
5
5
|
authors = [
|
|
6
6
|
{name = "White Neuron", email = "anhnt@whiteneuron.ai"}
|
|
@@ -24,7 +24,7 @@ dependencies = [
|
|
|
24
24
|
"openai>=1.58.1",
|
|
25
25
|
"openpyxl>=3.1.5",
|
|
26
26
|
"pandas>=2.2.3",
|
|
27
|
-
"pillow>=12.
|
|
27
|
+
"pillow>=12.2.0",
|
|
28
28
|
"python-dotenv>=1.0.1",
|
|
29
29
|
"redis>=5.2.1",
|
|
30
30
|
"sentry-sdk==2.28.0",
|
|
@@ -40,7 +40,7 @@ dependencies = [
|
|
|
40
40
|
'django-cors-headers>=4.3.0',
|
|
41
41
|
"django-unfold>=0.85.0",
|
|
42
42
|
"djangoql>=0.18.1",
|
|
43
|
-
"cryptography>=46.0.
|
|
43
|
+
"cryptography>=46.0.7",
|
|
44
44
|
"pyopenssl==26.0.0",
|
|
45
45
|
]
|
|
46
46
|
requires-python = ">=3.11"
|
|
@@ -75,6 +75,11 @@ include = ["whiteneuron*"]
|
|
|
75
75
|
"locale/**/*",
|
|
76
76
|
]
|
|
77
77
|
|
|
78
|
+
[tool.setuptools.exclude-package-data]
|
|
79
|
+
"whiteneuron" = [
|
|
80
|
+
"templates/admin/signature_ceo.html",
|
|
81
|
+
]
|
|
82
|
+
|
|
78
83
|
[project.optional-dependencies]
|
|
79
84
|
dev = ["pytest", "black", "flake8", "pre-commit"]
|
|
80
85
|
|
|
@@ -24,4 +24,5 @@ urlpatterns += [
|
|
|
24
24
|
path("base/guest-login/", GuestLoginView.as_view(), name="guest_login"),
|
|
25
25
|
# path("i18n/", include("django.conf.urls.i18n")),
|
|
26
26
|
path("ckeditor5/", include('django_ckeditor_5.urls')),
|
|
27
|
+
path("file-management/", include('whiteneuron.file_management.urls')),
|
|
27
28
|
]
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
from django.utils import timezone
|
|
2
|
+
from .models import User, UserActivity
|
|
3
|
+
from django.contrib.auth.models import Group
|
|
4
|
+
|
|
5
|
+
# count time run function
|
|
6
|
+
def timeit(func):
|
|
7
|
+
import time
|
|
8
|
+
def wrapper(*args, **kwargs):
|
|
9
|
+
start = time.time()
|
|
10
|
+
result = func(*args, **kwargs)
|
|
11
|
+
# print(f"{func.__name__} run in {time.time()-start} seconds")
|
|
12
|
+
return result
|
|
13
|
+
return wrapper
|
|
14
|
+
|
|
15
|
+
from django.utils import timezone
|
|
16
|
+
from django.core.exceptions import FieldDoesNotExist
|
|
17
|
+
|
|
18
|
+
def base_badge_callback(request, model, filter_kwargs=None):
|
|
19
|
+
today = timezone.localtime().replace(hour=0, minute=0, second=0, microsecond=0)
|
|
20
|
+
|
|
21
|
+
# try:
|
|
22
|
+
# model._meta.get_field("is_deleted")
|
|
23
|
+
# model._meta.get_field("deleted_at")
|
|
24
|
+
# has_soft_delete = True
|
|
25
|
+
# except FieldDoesNotExist:
|
|
26
|
+
# has_soft_delete = False
|
|
27
|
+
|
|
28
|
+
# if has_soft_delete:
|
|
29
|
+
# number_update = model.objects.filter(
|
|
30
|
+
# is_deleted=False,
|
|
31
|
+
# updated_at__gte=today,
|
|
32
|
+
# ).count()
|
|
33
|
+
|
|
34
|
+
# number_delete= getattr(model, 'objects_all', model.objects).filter(is_deleted=True,deleted_at__gte= timezone.localtime().replace(hour=0, minute=0, second=0, microsecond=0)).count()
|
|
35
|
+
# print("model:",model.__name__,"number_delete:",number_delete)
|
|
36
|
+
|
|
37
|
+
# c = number_update - number_delete
|
|
38
|
+
# else:
|
|
39
|
+
# c = model.objects.filter(
|
|
40
|
+
# updated_at__gte=today,
|
|
41
|
+
# ).count()
|
|
42
|
+
|
|
43
|
+
c = getattr(model, 'objects_all', model.objects)
|
|
44
|
+
if hasattr(model, 'updated_at'):
|
|
45
|
+
c = c.filter(
|
|
46
|
+
updated_at__gte=today,
|
|
47
|
+
)
|
|
48
|
+
elif hasattr(model, 'created_at'):
|
|
49
|
+
c = c.filter(
|
|
50
|
+
created_at__gte=today,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
if filter_kwargs:
|
|
54
|
+
c = c.filter(**filter_kwargs).count()
|
|
55
|
+
else:
|
|
56
|
+
c = c.count()
|
|
57
|
+
return c
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def user_badge_callback(request):
|
|
61
|
+
return base_badge_callback(request, User)
|
|
62
|
+
|
|
63
|
+
def useractivity_badge_callback(request):
|
|
64
|
+
c= UserActivity.objects.filter(timestamp__gte= timezone.now().replace(hour=0, minute=0, second=0, microsecond=0)).count()
|
|
65
|
+
if c==0:
|
|
66
|
+
return ''
|
|
67
|
+
return f"{c}"
|
|
68
|
+
|
|
69
|
+
def user_badge_callback(request):
|
|
70
|
+
return base_badge_callback(request, User)
|
|
71
|
+
|
|
72
|
+
def group_badge_callback(request):
|
|
73
|
+
return 0
|
|
74
|
+
|
|
75
|
+
def app_badge_callback(request):
|
|
76
|
+
from django.conf import settings
|
|
77
|
+
try:
|
|
78
|
+
navigation = settings.UNFOLD.get('SIDEBAR', {}).get('navigation', [])
|
|
79
|
+
return sum(
|
|
80
|
+
1 for section in navigation for item in section.get('items', [])
|
|
81
|
+
if item.get('title') and item.get('link') and '/base/app/' not in str(item.get('link'))
|
|
82
|
+
)
|
|
83
|
+
except Exception:
|
|
84
|
+
return 0
|
|
85
|
+
|
|
86
|
+
def is_guest_user(user):
|
|
87
|
+
if not user or not user.is_authenticated:
|
|
88
|
+
return True
|
|
89
|
+
if user.username.lower() == "guest":
|
|
90
|
+
return True
|
|
91
|
+
return user.groups.filter(name__in=["Khách thăm", "Guest", "guest"]).exists()
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def permission_callback(request):
|
|
95
|
+
return False
|
|
96
|
+
|
|
97
|
+
def permission_superuser_callback(request):
|
|
98
|
+
return request.user.is_superuser
|
|
99
|
+
|
|
100
|
+
def permission_admin_callback(request):
|
|
101
|
+
if request.user.is_superuser:
|
|
102
|
+
return True
|
|
103
|
+
return request.user.groups.filter(name='Quản trị viên').exists()
|
|
104
|
+
|
|
105
|
+
def permission_non_guest_callback(request):
|
|
106
|
+
return not is_guest_user(request.user)
|
|
107
|
+
|
|
108
|
+
def permission_viewer_callback(request):
|
|
109
|
+
return True
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
import os as _os
|
|
113
|
+
|
|
114
|
+
def _load_signature():
|
|
115
|
+
sig_path = _os.path.normpath(
|
|
116
|
+
_os.path.join(_os.path.dirname(__file__), '..', 'templates', 'admin', 'signature.html')
|
|
117
|
+
)
|
|
118
|
+
with open(sig_path, 'r', encoding='utf-8') as f:
|
|
119
|
+
return f.read()
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
TEMPLATE="""
|
|
123
|
+
Chào {username},
|
|
124
|
+
<br />
|
|
125
|
+
Bạn đã được cấp quyền truy cập vào <b>{system_name}</b>. Dưới đây là thông tin
|
|
126
|
+
đăng nhập của bạn:
|
|
127
|
+
<br />
|
|
128
|
+
<b> Tên đăng nhập: {username} </b>
|
|
129
|
+
<br />
|
|
130
|
+
<b> Mật khẩu tạm thời: {password} </b>
|
|
131
|
+
<br />
|
|
132
|
+
<b> Lưu ý: </b> Bạn sẽ được yêu cầu thay đổi mật khẩu sau lần đăng nhập đầu tiên
|
|
133
|
+
để đảm bảo an toàn cho thông tin cá nhân và tài khoản của bạn.
|
|
134
|
+
<br />
|
|
135
|
+
<br />
|
|
136
|
+
Để đăng nhập, vui lòng truy cập <a href="{url}">đường dẫn trang đăng nhập</a> và
|
|
137
|
+
nhập thông tin trên.
|
|
138
|
+
<br />
|
|
139
|
+
Nếu bạn gặp bất kỳ vấn đề nào trong quá trình đăng nhập, đừng ngần ngại liên hệ
|
|
140
|
+
với bộ phận hỗ trợ kỹ thuật của chúng tôi.
|
|
141
|
+
<br />
|
|
142
|
+
Trân trọng,
|
|
143
|
+
<br />
|
|
144
|
+
{signature}
|
|
145
|
+
"""
|
|
146
|
+
|
|
147
|
+
from django.conf import settings
|
|
148
|
+
from .models import Mail
|
|
149
|
+
def send_email_login(username, password, receiver, is_reset=False):
|
|
150
|
+
global TEMPLATE
|
|
151
|
+
SUBJECT = "Đặt lại mật khẩu hệ thống" if is_reset else "Thông tin đăng nhập hệ thống"
|
|
152
|
+
SYSTEM_NAME= settings.NAME
|
|
153
|
+
URL= settings.URL
|
|
154
|
+
subject= SUBJECT
|
|
155
|
+
template= TEMPLATE
|
|
156
|
+
system_name= SYSTEM_NAME
|
|
157
|
+
context= template.format(username= username, password= password, url= URL, system_name= system_name, signature= _load_signature())
|
|
158
|
+
mail= Mail.objects.create(subject= subject, content= context, receiver= receiver)
|
|
159
|
+
mail.send()
|
|
160
|
+
return mail.is_sent()
|
|
161
|
+
|
|
162
|
+
def make_random_password():
|
|
163
|
+
import random
|
|
164
|
+
import string
|
|
165
|
+
return ''.join(random.choices(string.ascii_letters + string.digits, k=8))
|