aird 0.4.23.dev17__tar.gz → 0.4.23.dev18__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.
- {aird-0.4.23.dev17/aird.egg-info → aird-0.4.23.dev18}/PKG-INFO +2 -1
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/constants/__init__.py +1 -1
- aird-0.4.23.dev18/aird/event_loop.py +34 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/handlers/file_op_handlers.py +1 -1
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/main.py +4 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/static/js/browse/app.js +5 -6
- aird-0.4.23.dev18/aird/static/js/file-transfer-http.js +98 -0
- aird-0.4.23.dev18/aird/static/js/file-transfer.js +55 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/templates/browse.html +2 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18/aird.egg-info}/PKG-INFO +2 -1
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird.egg-info/SOURCES.txt +3 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird.egg-info/requires.txt +3 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/setup.py +2 -1
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/LICENSE +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/MANIFEST.in +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/README.md +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/__init__.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/__main__.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/app_context.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/cli/__init__.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/cli/__main__.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/cli/authelia.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/cli/config.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/cli/main.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/cli/session.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/cloud/__init__.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/config.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/constants/admin.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/constants/file_ops.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/constants/input_limits.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/constants/media.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/core/__init__.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/core/events.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/core/file_operations.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/core/filter_expression.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/core/folder_size.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/core/input_validation.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/core/mmap_handler.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/core/security.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/core/share_root.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/core/websocket_manager.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/core/zip_download.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/database/__init__.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/database/db.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/database/feature_flags.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/database/ldap.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/db/__init__.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/db/audit.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/db/config.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/db/favorites.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/db/network_shares.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/db/policies.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/db/policy_decisions.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/db/policy_seeds.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/db/quota.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/db/resource_tags.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/db/schema.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/db/shares.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/db/user_attributes.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/db/users.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/domain/__init__.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/domain/contracts.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/domain/models.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/email/__init__.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/email/brevo.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/email/resolve.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/handlers/__init__.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/handlers/abac_handlers.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/handlers/admin_handlers.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/handlers/api_handlers.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/handlers/auth_handlers.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/handlers/base_handler.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/handlers/constants.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/handlers/health_handler.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/handlers/p2p_handlers.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/handlers/share_handlers.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/handlers/transfer_ws_handlers.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/handlers/view_handlers.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/network_share_manager.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/server_runtime.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/services/__init__.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/services/audit_service.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/services/config_service.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/services/email_service.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/services/email_subscriber.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/services/event_subscribers.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/services/favorites_service.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/services/network_share_service.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/services/p2p_service.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/services/policy_service.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/services/quota_service.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/services/share_service.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/services/tag_service.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/services/user_service.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/sql_identifiers.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/static/css/app.css +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/static/favicon.png +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/static/favicon.svg +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/static/img/logo-icon.png +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/static/img/logo-mark.svg +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/static/img/logo-text.png +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/static/img/logo.png +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/static/js/aird-core.js +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/static/js/bg-canvas.js +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/static/js/common/command-palette.js +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/static/js/components/folder-picker.js +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/static/js/download-manager.js +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/static/js/feature-flags-live.js +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/static/js/file-transfer-ws.js +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/static/js/folder-size-scan.js +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/static/js/login-ui.js +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/static/js/media-view.js +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/static/js/p2p/app.js +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/static/js/p2p/mediator.js +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/static/js/p2p/qr-adapter.js +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/static/js/p2p/signaling-service.js +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/static/js/p2p/state-machine.js +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/static/js/p2p/transfer-service.js +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/static/js/pages/p2p-page.js +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/static/js/pages/super-search.js +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/static/js/share/app.js +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/static/js/theme.js +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/static/js/transfer-tracker.js +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/static/js/vendor/pdf.min.js +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/static/js/vendor/pdf.worker.min.js +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/static/js/vendor/qrcode-browser.js +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/templates/_admin_tabs.html +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/templates/_app_nav_header.html +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/templates/_bg_canvas.html +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/templates/_theme_early.html +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/templates/_theme_login_corner.html +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/templates/admin.html +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/templates/admin_audit.html +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/templates/admin_ldap.html +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/templates/admin_login.html +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/templates/admin_network_shares.html +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/templates/admin_policies.html +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/templates/admin_tags.html +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/templates/admin_user_attributes.html +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/templates/admin_users.html +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/templates/directory.html +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/templates/edit.html +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/templates/error.html +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/templates/file.html +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/templates/ldap_config_create.html +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/templates/ldap_config_edit.html +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/templates/login.html +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/templates/media_view.html +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/templates/p2p_transfer.html +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/templates/profile.html +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/templates/share.html +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/templates/shared_list.html +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/templates/super_search.html +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/templates/tagged_files.html +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/templates/token_verification.html +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/templates/user_create.html +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/templates/user_edit.html +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/utils/__init__.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird/utils/util.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird.egg-info/dependency_links.txt +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird.egg-info/entry_points.txt +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/aird.egg-info/top_level.txt +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/setup.cfg +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/__init__.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/conftest.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/handler_helpers.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_admin_handlers.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_api_handlers.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_architecture_conformance.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_auth_handlers.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_auth_handlers_extended.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_base_handler.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_base_handler_pep.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_cli.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_cloud.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_config.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_core_file_operations.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_database_db.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_database_feature_flags.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_database_ldap.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_database_shares.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_database_users.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_database_users_hashing.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_db.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_email_service.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_file_op_handlers.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_filter_expression.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_folder_size.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_main.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_mmap_handler.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_multi_user.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_network_shares.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_p2p_handlers.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_password_hashing.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_policy_service.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_rate_limit.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_security.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_security_comprehensive.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_server_runtime.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_share_handlers.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_share_ownership.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_super_search_handler.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_tag_service.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_transfer_ws_handlers.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_util.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_view_handlers.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_websocket_manager.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_wheel_static_assets.py +0 -0
- {aird-0.4.23.dev17 → aird-0.4.23.dev18}/tests/test_zip_download.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aird
|
|
3
|
-
Version: 0.4.23.
|
|
3
|
+
Version: 0.4.23.dev18
|
|
4
4
|
Summary: Aird - A lightweight web-based file browser, editor, and streamer with real-time capabilities
|
|
5
5
|
Home-page: https://github.com/blinkerbit/aird
|
|
6
6
|
Author: Viswantha Srinivas P
|
|
@@ -13,6 +13,7 @@ Requires-Python: >=3.10
|
|
|
13
13
|
Description-Content-Type: text/markdown
|
|
14
14
|
License-File: LICENSE
|
|
15
15
|
Requires-Dist: tornado>=6.5.1
|
|
16
|
+
Requires-Dist: uvloop>=0.19.0; sys_platform == "linux"
|
|
16
17
|
Requires-Dist: ldap3>=2.9.1
|
|
17
18
|
Requires-Dist: aiofiles>=23.0.0
|
|
18
19
|
Requires-Dist: argon2-cffi>=23.1.0
|
|
@@ -63,7 +63,7 @@ UPLOAD_CONFIG = {
|
|
|
63
63
|
|
|
64
64
|
# File operation constants (derived from UPLOAD_CONFIG at startup)
|
|
65
65
|
MAX_FILE_SIZE = UPLOAD_CONFIG["max_file_size_mb"] * 1024 * 1024
|
|
66
|
-
# HTTP /upload body limit (browser uploads
|
|
66
|
+
# HTTP /upload body limit (browser uploads stream POST /upload; CLI may POST whole file)
|
|
67
67
|
UPLOAD_REQUEST_MAX_BODY_SIZE = MAX_FILE_SIZE + (1024 * 1024)
|
|
68
68
|
MAX_READABLE_FILE_SIZE = 50 * 1024 * 1024 # 50 MB
|
|
69
69
|
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""Optional asyncio event loop tuning (Linux uvloop)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
import sys
|
|
7
|
+
|
|
8
|
+
logger = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
_uvloop_installed = False
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def install_uvloop_if_linux() -> bool:
|
|
14
|
+
"""Use libuv-backed asyncio on Linux when uvloop is installed."""
|
|
15
|
+
global _uvloop_installed
|
|
16
|
+
if _uvloop_installed:
|
|
17
|
+
return True
|
|
18
|
+
if not sys.platform.startswith("linux"):
|
|
19
|
+
return False
|
|
20
|
+
try:
|
|
21
|
+
import asyncio
|
|
22
|
+
|
|
23
|
+
import uvloop
|
|
24
|
+
|
|
25
|
+
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
|
|
26
|
+
_uvloop_installed = True
|
|
27
|
+
logger.info("Using uvloop event loop (Linux)")
|
|
28
|
+
return True
|
|
29
|
+
except ImportError:
|
|
30
|
+
logger.debug("uvloop not installed; using default asyncio loop")
|
|
31
|
+
return False
|
|
32
|
+
except Exception:
|
|
33
|
+
logger.warning("Failed to enable uvloop; using default asyncio loop", exc_info=True)
|
|
34
|
+
return False
|
|
@@ -349,7 +349,7 @@ def _process_bulk_action(
|
|
|
349
349
|
|
|
350
350
|
@tornado.web.stream_request_body
|
|
351
351
|
class UploadHandler(BaseHandler):
|
|
352
|
-
"""
|
|
352
|
+
"""Streamed HTTP upload (browser, CLI, reverse proxy, or direct origin)."""
|
|
353
353
|
|
|
354
354
|
def check_xsrf_cookie(self) -> None:
|
|
355
355
|
"""Streamed uploads send raw body; accept X-XSRFToken header or ?_xsrf= query param."""
|
|
@@ -258,7 +258,7 @@
|
|
|
258
258
|
const raw = (err && err.message) ? String(err.message).trim() : "";
|
|
259
259
|
if (!raw || raw === "cancelled") return raw;
|
|
260
260
|
const lower = raw.toLowerCase();
|
|
261
|
-
if (lower.includes("network") || lower.includes("websocket")) {
|
|
261
|
+
if (lower.includes("network") || lower.includes("websocket") || lower.includes("http")) {
|
|
262
262
|
return "Upload interrupted. Check your connection and try again.";
|
|
263
263
|
}
|
|
264
264
|
if (lower.includes("403") || lower.includes("access denied")) {
|
|
@@ -271,16 +271,15 @@
|
|
|
271
271
|
}
|
|
272
272
|
|
|
273
273
|
async function uploadFile(item) {
|
|
274
|
-
const
|
|
275
|
-
if (!
|
|
276
|
-
throw new Error("
|
|
274
|
+
const FT = globalThis.AirdFileTransfer;
|
|
275
|
+
if (!FT?.uploadFile) {
|
|
276
|
+
throw new Error("Upload unavailable. Hard-refresh the page.");
|
|
277
277
|
}
|
|
278
278
|
const dir = item.uploadDir ?? document.getElementById('currentPath')?.value ?? '';
|
|
279
279
|
const fname = item.uploadName ?? item.file.name;
|
|
280
280
|
item.uploadSignal = { aborted: false };
|
|
281
|
-
const TT = globalThis.AirdTransferTracker;
|
|
282
281
|
const cancelFn = () => abortActiveUploads(item);
|
|
283
|
-
await
|
|
282
|
+
await FT.uploadFile(item.file, {
|
|
284
283
|
uploadDir: dir,
|
|
285
284
|
filename: fname,
|
|
286
285
|
signal: item.uploadSignal,
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP streaming upload (POST /upload). Works via Cloudflare HTTP/3 or direct to origin.
|
|
3
|
+
*/
|
|
4
|
+
(function (global) {
|
|
5
|
+
'use strict';
|
|
6
|
+
|
|
7
|
+
function getXSRFToken() {
|
|
8
|
+
if (global.AirdCore?.getXSRFToken) {
|
|
9
|
+
return global.AirdCore.getXSRFToken();
|
|
10
|
+
}
|
|
11
|
+
const match = document.cookie.match(/\b_xsrf=([^;]*)/);
|
|
12
|
+
return match ? decodeURIComponent(match[1]) : '';
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @param {File|Blob} file
|
|
17
|
+
* @param {{ uploadDir?: string, filename?: string, onProgress?: Function, signal?: { aborted: boolean }, onCancel?: Function }} options
|
|
18
|
+
*/
|
|
19
|
+
function uploadFile(file, options) {
|
|
20
|
+
options = options || {};
|
|
21
|
+
const uploadDir = options.uploadDir ?? '';
|
|
22
|
+
const filename = options.filename ?? (file.name || 'upload');
|
|
23
|
+
const onProgress = options.onProgress || function () {};
|
|
24
|
+
const signal = options.signal;
|
|
25
|
+
const totalSize = file.size;
|
|
26
|
+
|
|
27
|
+
const TT = global.AirdTransferTracker;
|
|
28
|
+
const ttId = TT
|
|
29
|
+
? TT.addTransfer(filename, totalSize, 'upload', { onCancel: options.onCancel })
|
|
30
|
+
: null;
|
|
31
|
+
if (TT && ttId && options.onCancel) {
|
|
32
|
+
TT.setCancelHandler(ttId, options.onCancel);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return new Promise((resolve, reject) => {
|
|
36
|
+
const xhr = new XMLHttpRequest();
|
|
37
|
+
let abortPoll = null;
|
|
38
|
+
|
|
39
|
+
function cleanup() {
|
|
40
|
+
if (abortPoll !== null) {
|
|
41
|
+
clearInterval(abortPoll);
|
|
42
|
+
abortPoll = null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function fail(err, httpStatus) {
|
|
47
|
+
cleanup();
|
|
48
|
+
const msg = err?.message || String(err);
|
|
49
|
+
const error = err instanceof Error ? err : new Error(msg);
|
|
50
|
+
error.httpStatus = httpStatus ?? 0;
|
|
51
|
+
if (TT && ttId) TT.failTransfer(ttId, msg);
|
|
52
|
+
reject(error);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
xhr.upload.addEventListener('progress', (ev) => {
|
|
56
|
+
if (!ev.lengthComputable) return;
|
|
57
|
+
const loaded = ev.loaded;
|
|
58
|
+
const pct = totalSize > 0 ? Math.round((loaded / totalSize) * 100) : 0;
|
|
59
|
+
onProgress(pct, loaded, totalSize);
|
|
60
|
+
if (TT && ttId) TT.updateProgress(ttId, loaded, totalSize);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
xhr.addEventListener('load', () => {
|
|
64
|
+
cleanup();
|
|
65
|
+
if (xhr.status >= 200 && xhr.status < 300) {
|
|
66
|
+
onProgress(100, totalSize, totalSize);
|
|
67
|
+
if (TT && ttId) TT.completeTransfer(ttId);
|
|
68
|
+
resolve({ message: xhr.responseText || 'Upload successful' });
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const body = (xhr.responseText || '').trim();
|
|
72
|
+
fail(new Error(body || `Upload failed (HTTP ${xhr.status})`), xhr.status);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
xhr.addEventListener('error', () => fail(new Error('Network error during upload'), 0));
|
|
76
|
+
xhr.addEventListener('abort', () => fail(new Error('cancelled'), 0));
|
|
77
|
+
|
|
78
|
+
if (signal) {
|
|
79
|
+
abortPoll = setInterval(() => {
|
|
80
|
+
if (signal.aborted) {
|
|
81
|
+
xhr.abort();
|
|
82
|
+
}
|
|
83
|
+
}, 100);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
xhr.open('POST', '/upload');
|
|
87
|
+
xhr.setRequestHeader('X-Upload-Dir', uploadDir);
|
|
88
|
+
xhr.setRequestHeader('X-Upload-Filename', filename);
|
|
89
|
+
xhr.setRequestHeader('X-XSRFToken', getXSRFToken());
|
|
90
|
+
xhr.setRequestHeader('Content-Type', 'application/octet-stream');
|
|
91
|
+
xhr.send(file);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
global.AirdFileTransferHttp = {
|
|
96
|
+
uploadFile: uploadFile,
|
|
97
|
+
};
|
|
98
|
+
})(typeof globalThis !== 'undefined' ? globalThis : window);
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Upload facade: HTTP first (CF or direct origin), WebSocket fallback when needed.
|
|
3
|
+
*/
|
|
4
|
+
(function (global) {
|
|
5
|
+
'use strict';
|
|
6
|
+
|
|
7
|
+
function isCancelled(err) {
|
|
8
|
+
const msg = (err && err.message) ? String(err.message).toLowerCase() : '';
|
|
9
|
+
return msg === 'cancelled';
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/** Use WS when HTTP is blocked, proxied limits apply, or the connection failed. */
|
|
13
|
+
function shouldFallbackToWs(err) {
|
|
14
|
+
if (!err || isCancelled(err)) return false;
|
|
15
|
+
const status = err.httpStatus ?? 0;
|
|
16
|
+
if (status === 401 || status === 403 || status === 400) return false;
|
|
17
|
+
if (status === 413 || status === 0 || status === 502 || status === 503 || status === 504) {
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
const msg = String(err.message || '').toLowerCase();
|
|
21
|
+
return msg.includes('network error');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @param {File|Blob} file
|
|
26
|
+
* @param {object} options passed to HTTP/WS upload helpers
|
|
27
|
+
*/
|
|
28
|
+
async function uploadFile(file, options) {
|
|
29
|
+
options = options || {};
|
|
30
|
+
const http = global.AirdFileTransferHttp;
|
|
31
|
+
const ws = global.AirdFileTransferWs;
|
|
32
|
+
|
|
33
|
+
if (http?.uploadFile) {
|
|
34
|
+
try {
|
|
35
|
+
return await http.uploadFile(file, options);
|
|
36
|
+
} catch (err) {
|
|
37
|
+
if (ws?.uploadFile && shouldFallbackToWs(err)) {
|
|
38
|
+
return ws.uploadFile(file, options);
|
|
39
|
+
}
|
|
40
|
+
throw err;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (ws?.uploadFile) {
|
|
45
|
+
return ws.uploadFile(file, options);
|
|
46
|
+
}
|
|
47
|
+
throw new Error('No upload transport available. Hard-refresh the page.');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
global.AirdFileTransfer = {
|
|
51
|
+
uploadFile: uploadFile,
|
|
52
|
+
saveBlob: global.AirdFileTransferWs?.saveBlob,
|
|
53
|
+
downloadFile: global.AirdFileTransferWs?.downloadFile,
|
|
54
|
+
};
|
|
55
|
+
})(typeof globalThis !== 'undefined' ? globalThis : window);
|
|
@@ -342,6 +342,8 @@
|
|
|
342
342
|
<input type="hidden" id="currentPath" value="{{ current_path or '' }}" />
|
|
343
343
|
<script src="/static/js/aird-core.js?v={{ static_version }}"></script>
|
|
344
344
|
<script src="/static/js/file-transfer-ws.js?v={{ static_version }}"></script>
|
|
345
|
+
<script src="/static/js/file-transfer-http.js?v={{ static_version }}"></script>
|
|
346
|
+
<script src="/static/js/file-transfer.js?v={{ static_version }}"></script>
|
|
345
347
|
<script src="/static/js/download-manager.js?v={{ static_version }}"></script>
|
|
346
348
|
<script src="/static/js/components/folder-picker.js?v={{ static_version }}"></script>
|
|
347
349
|
<script nonce="{{ csp_nonce }}">
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aird
|
|
3
|
-
Version: 0.4.23.
|
|
3
|
+
Version: 0.4.23.dev18
|
|
4
4
|
Summary: Aird - A lightweight web-based file browser, editor, and streamer with real-time capabilities
|
|
5
5
|
Home-page: https://github.com/blinkerbit/aird
|
|
6
6
|
Author: Viswantha Srinivas P
|
|
@@ -13,6 +13,7 @@ Requires-Python: >=3.10
|
|
|
13
13
|
Description-Content-Type: text/markdown
|
|
14
14
|
License-File: LICENSE
|
|
15
15
|
Requires-Dist: tornado>=6.5.1
|
|
16
|
+
Requires-Dist: uvloop>=0.19.0; sys_platform == "linux"
|
|
16
17
|
Requires-Dist: ldap3>=2.9.1
|
|
17
18
|
Requires-Dist: aiofiles>=23.0.0
|
|
18
19
|
Requires-Dist: argon2-cffi>=23.1.0
|
|
@@ -6,6 +6,7 @@ aird/__init__.py
|
|
|
6
6
|
aird/__main__.py
|
|
7
7
|
aird/app_context.py
|
|
8
8
|
aird/config.py
|
|
9
|
+
aird/event_loop.py
|
|
9
10
|
aird/main.py
|
|
10
11
|
aird/network_share_manager.py
|
|
11
12
|
aird/server_runtime.py
|
|
@@ -101,7 +102,9 @@ aird/static/js/aird-core.js
|
|
|
101
102
|
aird/static/js/bg-canvas.js
|
|
102
103
|
aird/static/js/download-manager.js
|
|
103
104
|
aird/static/js/feature-flags-live.js
|
|
105
|
+
aird/static/js/file-transfer-http.js
|
|
104
106
|
aird/static/js/file-transfer-ws.js
|
|
107
|
+
aird/static/js/file-transfer.js
|
|
105
108
|
aird/static/js/folder-size-scan.js
|
|
106
109
|
aird/static/js/login-ui.js
|
|
107
110
|
aird/static/js/media-view.js
|
|
@@ -2,6 +2,7 @@ from setuptools import setup, find_packages
|
|
|
2
2
|
|
|
3
3
|
install_requires = [
|
|
4
4
|
"tornado>=6.5.1",
|
|
5
|
+
"uvloop>=0.19.0; sys_platform == 'linux'",
|
|
5
6
|
"ldap3>=2.9.1",
|
|
6
7
|
"aiofiles>=23.0.0",
|
|
7
8
|
"argon2-cffi>=23.1.0",
|
|
@@ -15,7 +16,7 @@ install_requires = [
|
|
|
15
16
|
|
|
16
17
|
setup(
|
|
17
18
|
name="aird",
|
|
18
|
-
version="0.4.23.
|
|
19
|
+
version="0.4.23.dev18",
|
|
19
20
|
packages=find_packages(),
|
|
20
21
|
include_package_data=True,
|
|
21
22
|
package_data={"aird": [
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|