borgitory 2.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- borgitory-2.2.0/.gitignore +237 -0
- borgitory-2.2.0/LICENSE +21 -0
- borgitory-2.2.0/PKG-INFO +441 -0
- borgitory-2.2.0/README.md +368 -0
- borgitory-2.2.0/pyproject.toml +224 -0
- borgitory-2.2.0/src/borgitory/__init__.py +0 -0
- borgitory-2.2.0/src/borgitory/alembic/README +1 -0
- borgitory-2.2.0/src/borgitory/alembic/env.py +109 -0
- borgitory-2.2.0/src/borgitory/alembic/script.py.mako +28 -0
- borgitory-2.2.0/src/borgitory/alembic/versions/d930de046be6_migrate_cloud_sync_configs_to_json_.py +131 -0
- borgitory-2.2.0/src/borgitory/alembic.ini +147 -0
- borgitory-2.2.0/src/borgitory/api/__init__.py +0 -0
- borgitory-2.2.0/src/borgitory/api/auth.py +236 -0
- borgitory-2.2.0/src/borgitory/api/backups.py +53 -0
- borgitory-2.2.0/src/borgitory/api/cleanup.py +257 -0
- borgitory-2.2.0/src/borgitory/api/cloud_sync.py +558 -0
- borgitory-2.2.0/src/borgitory/api/debug.py +42 -0
- borgitory-2.2.0/src/borgitory/api/jobs.py +421 -0
- borgitory-2.2.0/src/borgitory/api/notifications.py +326 -0
- borgitory-2.2.0/src/borgitory/api/repositories.py +694 -0
- borgitory-2.2.0/src/borgitory/api/repository_check_configs.py +340 -0
- borgitory-2.2.0/src/borgitory/api/repository_stats.py +175 -0
- borgitory-2.2.0/src/borgitory/api/schedules.py +330 -0
- borgitory-2.2.0/src/borgitory/api/shared.py +32 -0
- borgitory-2.2.0/src/borgitory/api/tabs.py +176 -0
- borgitory-2.2.0/src/borgitory/cli.py +165 -0
- borgitory-2.2.0/src/borgitory/config.py +18 -0
- borgitory-2.2.0/src/borgitory/dependencies.py +552 -0
- borgitory-2.2.0/src/borgitory/main.py +276 -0
- borgitory-2.2.0/src/borgitory/models/__init__.py +0 -0
- borgitory-2.2.0/src/borgitory/models/database.py +453 -0
- borgitory-2.2.0/src/borgitory/models/enums.py +47 -0
- borgitory-2.2.0/src/borgitory/models/repository_dtos.py +216 -0
- borgitory-2.2.0/src/borgitory/models/schemas.py +791 -0
- borgitory-2.2.0/src/borgitory/py.typed +1 -0
- borgitory-2.2.0/src/borgitory/services/__init__.py +0 -0
- borgitory-2.2.0/src/borgitory/services/archives/archive_manager.py +365 -0
- borgitory-2.2.0/src/borgitory/services/archives/archive_mount_manager.py +398 -0
- borgitory-2.2.0/src/borgitory/services/backups/backup_executor.py +514 -0
- borgitory-2.2.0/src/borgitory/services/backups/backup_service.py +441 -0
- borgitory-2.2.0/src/borgitory/services/borg_command_builder.py +362 -0
- borgitory-2.2.0/src/borgitory/services/borg_service.py +747 -0
- borgitory-2.2.0/src/borgitory/services/cleanup_service.py +260 -0
- borgitory-2.2.0/src/borgitory/services/cloud_providers/__init__.py +57 -0
- borgitory-2.2.0/src/borgitory/services/cloud_providers/config_service.py +126 -0
- borgitory-2.2.0/src/borgitory/services/cloud_providers/orchestration.py +226 -0
- borgitory-2.2.0/src/borgitory/services/cloud_providers/registry.py +391 -0
- borgitory-2.2.0/src/borgitory/services/cloud_providers/registry_factory.py +117 -0
- borgitory-2.2.0/src/borgitory/services/cloud_providers/service.py +300 -0
- borgitory-2.2.0/src/borgitory/services/cloud_providers/storage/__init__.py +45 -0
- borgitory-2.2.0/src/borgitory/services/cloud_providers/storage/base.py +98 -0
- borgitory-2.2.0/src/borgitory/services/cloud_providers/storage/s3_storage.py +275 -0
- borgitory-2.2.0/src/borgitory/services/cloud_providers/storage/sftp_storage.py +267 -0
- borgitory-2.2.0/src/borgitory/services/cloud_providers/storage/smb_storage.py +320 -0
- borgitory-2.2.0/src/borgitory/services/cloud_providers/types.py +109 -0
- borgitory-2.2.0/src/borgitory/services/cloud_sync_service.py +355 -0
- borgitory-2.2.0/src/borgitory/services/configuration_service.py +87 -0
- borgitory-2.2.0/src/borgitory/services/cron_description_service.py +65 -0
- borgitory-2.2.0/src/borgitory/services/debug_service.py +394 -0
- borgitory-2.2.0/src/borgitory/services/jobs/broadcaster/event_type.py +19 -0
- borgitory-2.2.0/src/borgitory/services/jobs/broadcaster/job_event.py +67 -0
- borgitory-2.2.0/src/borgitory/services/jobs/broadcaster/job_event_broadcaster.py +303 -0
- borgitory-2.2.0/src/borgitory/services/jobs/job_database_manager.py +360 -0
- borgitory-2.2.0/src/borgitory/services/jobs/job_executor.py +587 -0
- borgitory-2.2.0/src/borgitory/services/jobs/job_manager.py +1884 -0
- borgitory-2.2.0/src/borgitory/services/jobs/job_output_manager.py +242 -0
- borgitory-2.2.0/src/borgitory/services/jobs/job_queue_manager.py +391 -0
- borgitory-2.2.0/src/borgitory/services/jobs/job_render_service.py +566 -0
- borgitory-2.2.0/src/borgitory/services/jobs/job_service.py +376 -0
- borgitory-2.2.0/src/borgitory/services/jobs/job_stream_service.py +442 -0
- borgitory-2.2.0/src/borgitory/services/notifications/notification_config_service.py +235 -0
- borgitory-2.2.0/src/borgitory/services/notifications/pushover_service.py +212 -0
- borgitory-2.2.0/src/borgitory/services/rclone_service.py +1268 -0
- borgitory-2.2.0/src/borgitory/services/recovery_service.py +163 -0
- borgitory-2.2.0/src/borgitory/services/repositories/repository_check_config_service.py +231 -0
- borgitory-2.2.0/src/borgitory/services/repositories/repository_parser.py +543 -0
- borgitory-2.2.0/src/borgitory/services/repositories/repository_service.py +592 -0
- borgitory-2.2.0/src/borgitory/services/repositories/repository_stats_service.py +644 -0
- borgitory-2.2.0/src/borgitory/services/scheduling/schedule_service.py +285 -0
- borgitory-2.2.0/src/borgitory/services/scheduling/scheduler_service.py +316 -0
- borgitory-2.2.0/src/borgitory/services/simple_command_runner.py +137 -0
- borgitory-2.2.0/src/borgitory/services/task_definition_builder.py +347 -0
- borgitory-2.2.0/src/borgitory/services/upcoming_backups_service.py +98 -0
- borgitory-2.2.0/src/borgitory/services/volumes/file_system_interface.py +26 -0
- borgitory-2.2.0/src/borgitory/services/volumes/os_file_system.py +23 -0
- borgitory-2.2.0/src/borgitory/services/volumes/volume_service.py +64 -0
- borgitory-2.2.0/src/borgitory/static/css/modern-components.css +284 -0
- borgitory-2.2.0/src/borgitory/static/favicon/android-chrome-192x192.png +0 -0
- borgitory-2.2.0/src/borgitory/static/favicon/android-chrome-512x512.png +0 -0
- borgitory-2.2.0/src/borgitory/static/favicon/apple-touch-icon.png +0 -0
- borgitory-2.2.0/src/borgitory/static/favicon/favicon-16x16.png +0 -0
- borgitory-2.2.0/src/borgitory/static/favicon/favicon-32x32.png +0 -0
- borgitory-2.2.0/src/borgitory/static/favicon/favicon.ico +0 -0
- borgitory-2.2.0/src/borgitory/static/favicon/site.webmanifest +19 -0
- borgitory-2.2.0/src/borgitory/static/js/app.js +259 -0
- borgitory-2.2.0/src/borgitory/static/js/components/jobs.js +61 -0
- borgitory-2.2.0/src/borgitory/static/js/components/navigation.js +43 -0
- borgitory-2.2.0/src/borgitory/templates/base.html +241 -0
- borgitory-2.2.0/src/borgitory/templates/index.html +47 -0
- borgitory-2.2.0/src/borgitory/templates/login.html +188 -0
- borgitory-2.2.0/src/borgitory/templates/partials/archives/contents_modal.html +28 -0
- borgitory-2.2.0/src/borgitory/templates/partials/archives/directory_contents.html +119 -0
- borgitory-2.2.0/src/borgitory/templates/partials/archives/directory_loading_state.html +12 -0
- borgitory-2.2.0/src/borgitory/templates/partials/archives/directory_loading_with_trigger.html +15 -0
- borgitory-2.2.0/src/borgitory/templates/partials/archives/empty_state.html +6 -0
- borgitory-2.2.0/src/borgitory/templates/partials/archives/error_message.html +11 -0
- borgitory-2.2.0/src/borgitory/templates/partials/archives/list_content.html +61 -0
- borgitory-2.2.0/src/borgitory/templates/partials/archives/loading_state.html +10 -0
- borgitory-2.2.0/src/borgitory/templates/partials/archives/loading_with_trigger.html +13 -0
- borgitory-2.2.0/src/borgitory/templates/partials/archives/repository_selector.html +32 -0
- borgitory-2.2.0/src/borgitory/templates/partials/archives/tab.html +29 -0
- borgitory-2.2.0/src/borgitory/templates/partials/auth/login_error.html +6 -0
- borgitory-2.2.0/src/borgitory/templates/partials/auth/login_form_active.html +58 -0
- borgitory-2.2.0/src/borgitory/templates/partials/auth/login_success.html +13 -0
- borgitory-2.2.0/src/borgitory/templates/partials/auth/register_error.html +6 -0
- borgitory-2.2.0/src/borgitory/templates/partials/auth/register_form_active.html +56 -0
- borgitory-2.2.0/src/borgitory/templates/partials/auth/register_success.html +10 -0
- borgitory-2.2.0/src/borgitory/templates/partials/backups/manual_form.html +87 -0
- borgitory-2.2.0/src/borgitory/templates/partials/backups/operations.html +10 -0
- borgitory-2.2.0/src/borgitory/templates/partials/backups/tab.html +19 -0
- borgitory-2.2.0/src/borgitory/templates/partials/cloud_sync/action_error.html +6 -0
- borgitory-2.2.0/src/borgitory/templates/partials/cloud_sync/action_success.html +6 -0
- borgitory-2.2.0/src/borgitory/templates/partials/cloud_sync/add_form.html +42 -0
- borgitory-2.2.0/src/borgitory/templates/partials/cloud_sync/config_list_content.html +70 -0
- borgitory-2.2.0/src/borgitory/templates/partials/cloud_sync/create_error.html +6 -0
- borgitory-2.2.0/src/borgitory/templates/partials/cloud_sync/create_success.html +13 -0
- borgitory-2.2.0/src/borgitory/templates/partials/cloud_sync/edit_form.html +55 -0
- borgitory-2.2.0/src/borgitory/templates/partials/cloud_sync/list.html +10 -0
- borgitory-2.2.0/src/borgitory/templates/partials/cloud_sync/provider_fields.html +14 -0
- borgitory-2.2.0/src/borgitory/templates/partials/cloud_sync/providers/s3_fields.html +32 -0
- borgitory-2.2.0/src/borgitory/templates/partials/cloud_sync/providers/s3_fields_edit.html +32 -0
- borgitory-2.2.0/src/borgitory/templates/partials/cloud_sync/providers/sftp_fields.html +38 -0
- borgitory-2.2.0/src/borgitory/templates/partials/cloud_sync/providers/sftp_fields_edit.html +39 -0
- borgitory-2.2.0/src/borgitory/templates/partials/cloud_sync/providers/smb_fields.html +74 -0
- borgitory-2.2.0/src/borgitory/templates/partials/cloud_sync/providers/smb_fields_edit.html +74 -0
- borgitory-2.2.0/src/borgitory/templates/partials/cloud_sync/tab.html +13 -0
- borgitory-2.2.0/src/borgitory/templates/partials/cloud_sync/test_error.html +6 -0
- borgitory-2.2.0/src/borgitory/templates/partials/cloud_sync/test_success.html +6 -0
- borgitory-2.2.0/src/borgitory/templates/partials/cloud_sync/test_warning.html +6 -0
- borgitory-2.2.0/src/borgitory/templates/partials/cloud_sync/update_error.html +6 -0
- borgitory-2.2.0/src/borgitory/templates/partials/cloud_sync/update_success.html +13 -0
- borgitory-2.2.0/src/borgitory/templates/partials/common/error_message.html +2 -0
- borgitory-2.2.0/src/borgitory/templates/partials/debug/debug_panel.html +291 -0
- borgitory-2.2.0/src/borgitory/templates/partials/debug/tab.html +44 -0
- borgitory-2.2.0/src/borgitory/templates/partials/jobs/backup_error.html +6 -0
- borgitory-2.2.0/src/borgitory/templates/partials/jobs/backup_success.html +14 -0
- borgitory-2.2.0/src/borgitory/templates/partials/jobs/current_jobs_list.html +23 -0
- borgitory-2.2.0/src/borgitory/templates/partials/jobs/empty_state.html +4 -0
- borgitory-2.2.0/src/borgitory/templates/partials/jobs/error_state.html +4 -0
- borgitory-2.2.0/src/borgitory/templates/partials/jobs/job_details_static.html +33 -0
- borgitory-2.2.0/src/borgitory/templates/partials/jobs/job_details_streaming.html +45 -0
- borgitory-2.2.0/src/borgitory/templates/partials/jobs/job_item.html +45 -0
- borgitory-2.2.0/src/borgitory/templates/partials/jobs/tab.html +12 -0
- borgitory-2.2.0/src/borgitory/templates/partials/jobs/task_item_static.html +76 -0
- borgitory-2.2.0/src/borgitory/templates/partials/jobs/task_item_streaming.html +106 -0
- borgitory-2.2.0/src/borgitory/templates/partials/navigation.html +29 -0
- borgitory-2.2.0/src/borgitory/templates/partials/navigation_nav.html +166 -0
- borgitory-2.2.0/src/borgitory/templates/partials/notifications/action_error.html +6 -0
- borgitory-2.2.0/src/borgitory/templates/partials/notifications/action_success.html +6 -0
- borgitory-2.2.0/src/borgitory/templates/partials/notifications/add_form.html +49 -0
- borgitory-2.2.0/src/borgitory/templates/partials/notifications/config_list_content.html +67 -0
- borgitory-2.2.0/src/borgitory/templates/partials/notifications/create_error.html +6 -0
- borgitory-2.2.0/src/borgitory/templates/partials/notifications/create_success.html +13 -0
- borgitory-2.2.0/src/borgitory/templates/partials/notifications/edit_form.html +58 -0
- borgitory-2.2.0/src/borgitory/templates/partials/notifications/list.html +10 -0
- borgitory-2.2.0/src/borgitory/templates/partials/notifications/tab.html +19 -0
- borgitory-2.2.0/src/borgitory/templates/partials/notifications/test_error.html +6 -0
- borgitory-2.2.0/src/borgitory/templates/partials/notifications/test_success.html +6 -0
- borgitory-2.2.0/src/borgitory/templates/partials/notifications/update_error.html +15 -0
- borgitory-2.2.0/src/borgitory/templates/partials/notifications/update_success.html +15 -0
- borgitory-2.2.0/src/borgitory/templates/partials/prune/action_error.html +6 -0
- borgitory-2.2.0/src/borgitory/templates/partials/prune/action_success.html +6 -0
- borgitory-2.2.0/src/borgitory/templates/partials/prune/config_form.html +95 -0
- borgitory-2.2.0/src/borgitory/templates/partials/prune/config_form_error.html +134 -0
- borgitory-2.2.0/src/borgitory/templates/partials/prune/config_form_success.html +118 -0
- borgitory-2.2.0/src/borgitory/templates/partials/prune/config_list_content.html +57 -0
- borgitory-2.2.0/src/borgitory/templates/partials/prune/create_error.html +6 -0
- borgitory-2.2.0/src/borgitory/templates/partials/prune/create_form.html +37 -0
- borgitory-2.2.0/src/borgitory/templates/partials/prune/create_success.html +13 -0
- borgitory-2.2.0/src/borgitory/templates/partials/prune/delete_error.html +6 -0
- borgitory-2.2.0/src/borgitory/templates/partials/prune/delete_success.html +13 -0
- borgitory-2.2.0/src/borgitory/templates/partials/prune/edit_form.html +47 -0
- borgitory-2.2.0/src/borgitory/templates/partials/prune/policies.html +21 -0
- borgitory-2.2.0/src/borgitory/templates/partials/prune/prune_error.html +11 -0
- borgitory-2.2.0/src/borgitory/templates/partials/prune/prune_success.html +6 -0
- borgitory-2.2.0/src/borgitory/templates/partials/prune/strategy_fields.html +29 -0
- borgitory-2.2.0/src/borgitory/templates/partials/prune/tab.html +19 -0
- borgitory-2.2.0/src/borgitory/templates/partials/prune/update_error.html +6 -0
- borgitory-2.2.0/src/borgitory/templates/partials/prune/update_success.html +13 -0
- borgitory-2.2.0/src/borgitory/templates/partials/repositories/delete_success.html +13 -0
- borgitory-2.2.0/src/borgitory/templates/partials/repositories/form_create.html +46 -0
- borgitory-2.2.0/src/borgitory/templates/partials/repositories/form_create_error.html +6 -0
- borgitory-2.2.0/src/borgitory/templates/partials/repositories/form_create_success.html +13 -0
- borgitory-2.2.0/src/borgitory/templates/partials/repositories/form_import.html +97 -0
- borgitory-2.2.0/src/borgitory/templates/partials/repositories/form_import_error.html +6 -0
- borgitory-2.2.0/src/borgitory/templates/partials/repositories/form_import_inner.html +93 -0
- borgitory-2.2.0/src/borgitory/templates/partials/repositories/form_import_success.html +20 -0
- borgitory-2.2.0/src/borgitory/templates/partials/repositories/import_form_clear.html +1 -0
- borgitory-2.2.0/src/borgitory/templates/partials/repositories/import_form_dynamic.html +76 -0
- borgitory-2.2.0/src/borgitory/templates/partials/repositories/import_form_loading.html +16 -0
- borgitory-2.2.0/src/borgitory/templates/partials/repositories/import_form_simple.html +55 -0
- borgitory-2.2.0/src/borgitory/templates/partials/repositories/list.html +10 -0
- borgitory-2.2.0/src/borgitory/templates/partials/repositories/list_content.html +39 -0
- borgitory-2.2.0/src/borgitory/templates/partials/repositories/scan_results.html +23 -0
- borgitory-2.2.0/src/borgitory/templates/partials/repositories/tab.html +35 -0
- borgitory-2.2.0/src/borgitory/templates/partials/repository_check/action_error.html +6 -0
- borgitory-2.2.0/src/borgitory/templates/partials/repository_check/action_success.html +6 -0
- borgitory-2.2.0/src/borgitory/templates/partials/repository_check/check_error.html +11 -0
- borgitory-2.2.0/src/borgitory/templates/partials/repository_check/check_success.html +6 -0
- borgitory-2.2.0/src/borgitory/templates/partials/repository_check/config_list_content.html +66 -0
- borgitory-2.2.0/src/borgitory/templates/partials/repository_check/create_error.html +6 -0
- borgitory-2.2.0/src/borgitory/templates/partials/repository_check/create_form.html +105 -0
- borgitory-2.2.0/src/borgitory/templates/partials/repository_check/create_success.html +13 -0
- borgitory-2.2.0/src/borgitory/templates/partials/repository_check/custom_options.html +31 -0
- borgitory-2.2.0/src/borgitory/templates/partials/repository_check/delete_error.html +6 -0
- borgitory-2.2.0/src/borgitory/templates/partials/repository_check/delete_success.html +13 -0
- borgitory-2.2.0/src/borgitory/templates/partials/repository_check/dynamic_options.html +73 -0
- borgitory-2.2.0/src/borgitory/templates/partials/repository_check/edit_form.html +119 -0
- borgitory-2.2.0/src/borgitory/templates/partials/repository_check/form.html +67 -0
- borgitory-2.2.0/src/borgitory/templates/partials/repository_check/tab.html +59 -0
- borgitory-2.2.0/src/borgitory/templates/partials/repository_check/update_error.html +6 -0
- borgitory-2.2.0/src/borgitory/templates/partials/repository_check/update_success.html +13 -0
- borgitory-2.2.0/src/borgitory/templates/partials/repository_stats/stats_panel.html +134 -0
- borgitory-2.2.0/src/borgitory/templates/partials/schedules/create_error.html +6 -0
- borgitory-2.2.0/src/borgitory/templates/partials/schedules/create_form.html +99 -0
- borgitory-2.2.0/src/borgitory/templates/partials/schedules/create_success.html +33 -0
- borgitory-2.2.0/src/borgitory/templates/partials/schedules/cron_description.html +10 -0
- borgitory-2.2.0/src/borgitory/templates/partials/schedules/cron_expression_form.html +31 -0
- borgitory-2.2.0/src/borgitory/templates/partials/schedules/delete_error.html +6 -0
- borgitory-2.2.0/src/borgitory/templates/partials/schedules/delete_success.html +13 -0
- borgitory-2.2.0/src/borgitory/templates/partials/schedules/edit_form.html +118 -0
- borgitory-2.2.0/src/borgitory/templates/partials/schedules/list.html +14 -0
- borgitory-2.2.0/src/borgitory/templates/partials/schedules/schedule_list_content.html +63 -0
- borgitory-2.2.0/src/borgitory/templates/partials/schedules/tab.html +23 -0
- borgitory-2.2.0/src/borgitory/templates/partials/schedules/upcoming.html +15 -0
- borgitory-2.2.0/src/borgitory/templates/partials/schedules/upcoming_backups_content.html +20 -0
- borgitory-2.2.0/src/borgitory/templates/partials/schedules/update_error.html +6 -0
- borgitory-2.2.0/src/borgitory/templates/partials/schedules/update_success.html +13 -0
- borgitory-2.2.0/src/borgitory/templates/partials/shared/notification.html +109 -0
- borgitory-2.2.0/src/borgitory/templates/partials/shared/path_autocomplete.html +30 -0
- borgitory-2.2.0/src/borgitory/templates/partials/shared/path_autocomplete_dropdown.html +42 -0
- borgitory-2.2.0/src/borgitory/templates/partials/statistics/empty_state.html +9 -0
- borgitory-2.2.0/src/borgitory/templates/partials/statistics/loading_state.html +51 -0
- borgitory-2.2.0/src/borgitory/templates/partials/statistics/repository_selector.html +22 -0
- borgitory-2.2.0/src/borgitory/templates/partials/statistics/tab.html +34 -0
- borgitory-2.2.0/src/borgitory/utils/__init__.py +1 -0
- borgitory-2.2.0/src/borgitory/utils/db_session.py +37 -0
- borgitory-2.2.0/src/borgitory/utils/migrations.py +66 -0
- borgitory-2.2.0/src/borgitory/utils/path_prefix.py +99 -0
- borgitory-2.2.0/src/borgitory/utils/secure_path.py +440 -0
- borgitory-2.2.0/src/borgitory/utils/security.py +239 -0
- borgitory-2.2.0/src/borgitory/utils/template_paths.py +113 -0
- borgitory-2.2.0/src/borgitory/utils/template_responses.py +166 -0
- borgitory-2.2.0/tests/__init__.py +1 -0
- borgitory-2.2.0/tests/archives/test_archive_browser_htmx.py +623 -0
- borgitory-2.2.0/tests/archives/test_archive_manager.py +575 -0
- borgitory-2.2.0/tests/archives/test_archive_mount_manager.py +781 -0
- borgitory-2.2.0/tests/auth/test_auth_htmx.py +134 -0
- borgitory-2.2.0/tests/auth/test_auth_redirect_flow.py +97 -0
- borgitory-2.2.0/tests/auth/test_main_login_page.py +167 -0
- borgitory-2.2.0/tests/backups/test_backup_executor.py +912 -0
- borgitory-2.2.0/tests/backups/test_backup_service.py +921 -0
- borgitory-2.2.0/tests/borg/test_borg_command_builder.py +588 -0
- borgitory-2.2.0/tests/borg/test_borg_service.py +999 -0
- borgitory-2.2.0/tests/borg/test_borg_service_core.py +395 -0
- borgitory-2.2.0/tests/cloud_providers/__init__.py +1 -0
- borgitory-2.2.0/tests/cloud_providers/test_config_service.py +449 -0
- borgitory-2.2.0/tests/cloud_providers/test_display_details.py +203 -0
- borgitory-2.2.0/tests/cloud_providers/test_job_executor.py +516 -0
- borgitory-2.2.0/tests/cloud_providers/test_orchestration.py +565 -0
- borgitory-2.2.0/tests/cloud_providers/test_provider_validation.py +256 -0
- borgitory-2.2.0/tests/cloud_providers/test_rclone_integration.py +441 -0
- borgitory-2.2.0/tests/cloud_providers/test_registry.py +326 -0
- borgitory-2.2.0/tests/cloud_providers/test_registry_integration.py +302 -0
- borgitory-2.2.0/tests/cloud_providers/test_schema_validation.py +260 -0
- borgitory-2.2.0/tests/cloud_providers/test_service.py +829 -0
- borgitory-2.2.0/tests/cloud_providers/test_smb_storage.py +365 -0
- borgitory-2.2.0/tests/cloud_providers/test_storage.py +720 -0
- borgitory-2.2.0/tests/cloud_providers/test_types.py +301 -0
- borgitory-2.2.0/tests/cloud_sync/test_cloud_sync_api.py +342 -0
- borgitory-2.2.0/tests/cloud_sync/test_cloud_sync_service.py +488 -0
- borgitory-2.2.0/tests/conftest.py +242 -0
- borgitory-2.2.0/tests/fixtures/__init__.py +5 -0
- borgitory-2.2.0/tests/fixtures/job_fixtures.py +259 -0
- borgitory-2.2.0/tests/fixtures/registry_fixtures.py +151 -0
- borgitory-2.2.0/tests/jobs/test_job_database_manager.py +421 -0
- borgitory-2.2.0/tests/jobs/test_job_event_broadcaster.py +257 -0
- borgitory-2.2.0/tests/jobs/test_job_executor.py +204 -0
- borgitory-2.2.0/tests/jobs/test_job_executor_cloud_sync_integration.py +600 -0
- borgitory-2.2.0/tests/jobs/test_job_executor_comprehensive.py +632 -0
- borgitory-2.2.0/tests/jobs/test_job_manager.py +456 -0
- borgitory-2.2.0/tests/jobs/test_job_manager_comprehensive.py +1026 -0
- borgitory-2.2.0/tests/jobs/test_job_output_manager.py +245 -0
- borgitory-2.2.0/tests/jobs/test_job_render_service.py +992 -0
- borgitory-2.2.0/tests/jobs/test_job_service.py +469 -0
- borgitory-2.2.0/tests/jobs/test_job_stream_service.py +533 -0
- borgitory-2.2.0/tests/jobs/test_jobs_api_sse.py +51 -0
- borgitory-2.2.0/tests/notifications/test_notification_config_service.py +442 -0
- borgitory-2.2.0/tests/notifications/test_notification_configs_api.py +560 -0
- borgitory-2.2.0/tests/notifications/test_pushover_service.py +421 -0
- borgitory-2.2.0/tests/repositories/test_repositories_api.py +1584 -0
- borgitory-2.2.0/tests/repositories/test_repository_check_config_service.py +412 -0
- borgitory-2.2.0/tests/repositories/test_repository_check_configs_api.py +567 -0
- borgitory-2.2.0/tests/repositories/test_repository_parser.py +1328 -0
- borgitory-2.2.0/tests/repositories/test_repository_service.py +335 -0
- borgitory-2.2.0/tests/repositories/test_repository_stats_service.py +460 -0
- borgitory-2.2.0/tests/schedules/test_cron_description_api.py +239 -0
- borgitory-2.2.0/tests/schedules/test_cron_description_htmx_api.py +265 -0
- borgitory-2.2.0/tests/schedules/test_schedule_creation_api.py +380 -0
- borgitory-2.2.0/tests/schedules/test_schedule_service.py +518 -0
- borgitory-2.2.0/tests/schedules/test_schedule_validation_service.py +319 -0
- borgitory-2.2.0/tests/schedules/test_scheduler_service.py +301 -0
- borgitory-2.2.0/tests/schedules/test_schedules_api.py +502 -0
- borgitory-2.2.0/tests/test_backups_api.py +347 -0
- borgitory-2.2.0/tests/test_basic.py +23 -0
- borgitory-2.2.0/tests/test_cleanup_api.py +464 -0
- borgitory-2.2.0/tests/test_cleanup_service.py +416 -0
- borgitory-2.2.0/tests/test_cron_description_service.py +136 -0
- borgitory-2.2.0/tests/test_database_models.py +519 -0
- borgitory-2.2.0/tests/test_debug_service.py +428 -0
- borgitory-2.2.0/tests/test_dependencies.py +216 -0
- borgitory-2.2.0/tests/test_jobs_api.py +886 -0
- borgitory-2.2.0/tests/test_path_prefix_utils.py +193 -0
- borgitory-2.2.0/tests/test_progress_streaming.py +321 -0
- borgitory-2.2.0/tests/test_rclone_service.py +1257 -0
- borgitory-2.2.0/tests/test_recovery_service.py +434 -0
- borgitory-2.2.0/tests/test_secure_path_comprehensive.py +681 -0
- borgitory-2.2.0/tests/test_security.py +826 -0
- borgitory-2.2.0/tests/test_simple_command_runner.py +286 -0
- borgitory-2.2.0/tests/test_streaming_edge_cases.py +339 -0
- borgitory-2.2.0/tests/test_streaming_fixes.py +341 -0
- borgitory-2.2.0/tests/test_tabs_api.py +304 -0
- borgitory-2.2.0/tests/test_task_definition_builder.py +479 -0
- borgitory-2.2.0/tests/test_volume_service.py +178 -0
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[codz]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py.cover
|
|
50
|
+
.hypothesis/
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
cover/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
.pybuilder/
|
|
76
|
+
target/
|
|
77
|
+
|
|
78
|
+
# Jupyter Notebook
|
|
79
|
+
.ipynb_checkpoints
|
|
80
|
+
|
|
81
|
+
# IPython
|
|
82
|
+
profile_default/
|
|
83
|
+
ipython_config.py
|
|
84
|
+
|
|
85
|
+
# pyenv
|
|
86
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
87
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
88
|
+
# .python-version
|
|
89
|
+
|
|
90
|
+
# pipenv
|
|
91
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
92
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
93
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
94
|
+
# install all needed dependencies.
|
|
95
|
+
#Pipfile.lock
|
|
96
|
+
|
|
97
|
+
# UV
|
|
98
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
|
99
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
100
|
+
# commonly ignored for libraries.
|
|
101
|
+
#uv.lock
|
|
102
|
+
|
|
103
|
+
# poetry
|
|
104
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
105
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
106
|
+
# commonly ignored for libraries.
|
|
107
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
108
|
+
#poetry.lock
|
|
109
|
+
#poetry.toml
|
|
110
|
+
|
|
111
|
+
# pdm
|
|
112
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
113
|
+
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
|
114
|
+
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
|
115
|
+
#pdm.lock
|
|
116
|
+
#pdm.toml
|
|
117
|
+
.pdm-python
|
|
118
|
+
.pdm-build/
|
|
119
|
+
|
|
120
|
+
# pixi
|
|
121
|
+
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
|
122
|
+
#pixi.lock
|
|
123
|
+
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
|
124
|
+
# in the .venv directory. It is recommended not to include this directory in version control.
|
|
125
|
+
.pixi
|
|
126
|
+
|
|
127
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
128
|
+
__pypackages__/
|
|
129
|
+
|
|
130
|
+
# Celery stuff
|
|
131
|
+
celerybeat-schedule
|
|
132
|
+
celerybeat.pid
|
|
133
|
+
|
|
134
|
+
# SageMath parsed files
|
|
135
|
+
*.sage.py
|
|
136
|
+
|
|
137
|
+
# Environments
|
|
138
|
+
.env
|
|
139
|
+
.envrc
|
|
140
|
+
.venv
|
|
141
|
+
env/
|
|
142
|
+
venv/
|
|
143
|
+
ENV/
|
|
144
|
+
env.bak/
|
|
145
|
+
venv.bak/
|
|
146
|
+
|
|
147
|
+
# Spyder project settings
|
|
148
|
+
.spyderproject
|
|
149
|
+
.spyproject
|
|
150
|
+
|
|
151
|
+
# Rope project settings
|
|
152
|
+
.ropeproject
|
|
153
|
+
|
|
154
|
+
# mkdocs documentation
|
|
155
|
+
/site
|
|
156
|
+
|
|
157
|
+
# mypy
|
|
158
|
+
.mypy_cache/
|
|
159
|
+
.dmypy.json
|
|
160
|
+
dmypy.json
|
|
161
|
+
|
|
162
|
+
# Pyre type checker
|
|
163
|
+
.pyre/
|
|
164
|
+
|
|
165
|
+
# pytype static type analyzer
|
|
166
|
+
.pytype/
|
|
167
|
+
|
|
168
|
+
# Cython debug symbols
|
|
169
|
+
cython_debug/
|
|
170
|
+
|
|
171
|
+
# PyCharm
|
|
172
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
173
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
174
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
175
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
176
|
+
#.idea/
|
|
177
|
+
|
|
178
|
+
# Abstra
|
|
179
|
+
# Abstra is an AI-powered process automation framework.
|
|
180
|
+
# Ignore directories containing user credentials, local state, and settings.
|
|
181
|
+
# Learn more at https://abstra.io/docs
|
|
182
|
+
.abstra/
|
|
183
|
+
|
|
184
|
+
# Visual Studio Code
|
|
185
|
+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
|
186
|
+
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
|
187
|
+
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
|
188
|
+
# you could uncomment the following to ignore the entire vscode folder
|
|
189
|
+
# .vscode/
|
|
190
|
+
|
|
191
|
+
# Ruff stuff:
|
|
192
|
+
.ruff_cache/
|
|
193
|
+
|
|
194
|
+
# PyPI configuration file
|
|
195
|
+
.pypirc
|
|
196
|
+
|
|
197
|
+
# Cursor
|
|
198
|
+
# Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
|
|
199
|
+
# exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
|
|
200
|
+
# refer to https://docs.cursor.com/context/ignore-files
|
|
201
|
+
.cursorignore
|
|
202
|
+
.cursorindexingignore
|
|
203
|
+
|
|
204
|
+
# Marimo
|
|
205
|
+
marimo/_static/
|
|
206
|
+
marimo/_lsp/
|
|
207
|
+
__marimo__/
|
|
208
|
+
|
|
209
|
+
# Project specific ignores
|
|
210
|
+
backup-sources/
|
|
211
|
+
borg-repos/
|
|
212
|
+
.claude/
|
|
213
|
+
data/
|
|
214
|
+
local-data/**
|
|
215
|
+
*.db
|
|
216
|
+
*.sqlite
|
|
217
|
+
*.sqlite3
|
|
218
|
+
|
|
219
|
+
# Docker
|
|
220
|
+
.dockerignore
|
|
221
|
+
|
|
222
|
+
# Local configuration
|
|
223
|
+
.env.local
|
|
224
|
+
.env.production
|
|
225
|
+
|
|
226
|
+
# Runtime files
|
|
227
|
+
*.pid
|
|
228
|
+
*.log
|
|
229
|
+
|
|
230
|
+
# OS generated files
|
|
231
|
+
.DS_Store
|
|
232
|
+
.DS_Store?
|
|
233
|
+
._*
|
|
234
|
+
.Spotlight-V100
|
|
235
|
+
.Trashes
|
|
236
|
+
ehthumbs.db
|
|
237
|
+
Thumbs.db
|
borgitory-2.2.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Matt LaPaglia
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
borgitory-2.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: borgitory
|
|
3
|
+
Version: 2.2.0
|
|
4
|
+
Summary: A comprehensive web-based management interface for BorgBackup repositories with real-time monitoring, automated scheduling, and cloud synchronization capabilities.
|
|
5
|
+
Project-URL: Homepage, https://github.com/mlapaglia/Borgitory
|
|
6
|
+
Project-URL: Repository, https://github.com/mlapaglia/Borgitory
|
|
7
|
+
Project-URL: Issues, https://github.com/mlapaglia/Borgitory/issues
|
|
8
|
+
Author-email: mlapaglia <mlapaglia@users.noreply.github.com>
|
|
9
|
+
License: MIT License
|
|
10
|
+
|
|
11
|
+
Copyright (c) 2025 Matt LaPaglia
|
|
12
|
+
|
|
13
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
14
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
15
|
+
in the Software without restriction, including without limitation the rights
|
|
16
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
17
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
18
|
+
furnished to do so, subject to the following conditions:
|
|
19
|
+
|
|
20
|
+
The above copyright notice and this permission notice shall be included in all
|
|
21
|
+
copies or substantial portions of the Software.
|
|
22
|
+
|
|
23
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
24
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
25
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
26
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
27
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
28
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
29
|
+
SOFTWARE.
|
|
30
|
+
License-File: LICENSE
|
|
31
|
+
Keywords: archive-management,backup,borgbackup,cloud-sync,scheduling,web-interface
|
|
32
|
+
Classifier: Development Status :: 4 - Beta
|
|
33
|
+
Classifier: Intended Audience :: System Administrators
|
|
34
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
35
|
+
Classifier: Operating System :: OS Independent
|
|
36
|
+
Classifier: Programming Language :: Python :: 3
|
|
37
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
38
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
39
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
40
|
+
Classifier: Topic :: System :: Archiving :: Backup
|
|
41
|
+
Classifier: Topic :: System :: Systems Administration
|
|
42
|
+
Requires-Python: >=3.11
|
|
43
|
+
Requires-Dist: aiofiles>=24.1.0
|
|
44
|
+
Requires-Dist: aiohttp>=3.9.0
|
|
45
|
+
Requires-Dist: alembic>=1.16.5
|
|
46
|
+
Requires-Dist: apscheduler>=3.10.4
|
|
47
|
+
Requires-Dist: bcrypt<5.0.0,>=4.0.0
|
|
48
|
+
Requires-Dist: cron-descriptor>=2.0.5
|
|
49
|
+
Requires-Dist: cryptography>=45.0.0
|
|
50
|
+
Requires-Dist: docker>=7.1.0
|
|
51
|
+
Requires-Dist: fastapi>=0.115.0
|
|
52
|
+
Requires-Dist: jinja2>=3.1.4
|
|
53
|
+
Requires-Dist: passlib[bcrypt]>=1.7.4
|
|
54
|
+
Requires-Dist: pydantic>=2.9.0
|
|
55
|
+
Requires-Dist: pyfuse3>=3.4.0; sys_platform != 'win32'
|
|
56
|
+
Requires-Dist: python-dotenv>=1.0.1
|
|
57
|
+
Requires-Dist: python-multipart>=0.0.12
|
|
58
|
+
Requires-Dist: sqlalchemy>=2.0.35
|
|
59
|
+
Requires-Dist: sse-starlette>=2.1.3
|
|
60
|
+
Requires-Dist: uvicorn[standard]>=0.30.0
|
|
61
|
+
Provides-Extra: dev
|
|
62
|
+
Requires-Dist: httpx>=0.25.0; extra == 'dev'
|
|
63
|
+
Requires-Dist: mypy>=1.8.0; extra == 'dev'
|
|
64
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
|
|
65
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
|
|
66
|
+
Requires-Dist: pytest>=7.4.0; extra == 'dev'
|
|
67
|
+
Requires-Dist: ruff>=0.12.11; extra == 'dev'
|
|
68
|
+
Requires-Dist: sqlalchemy[mypy]>=2.0.35; extra == 'dev'
|
|
69
|
+
Requires-Dist: types-aiofiles>=23.2.0.20240106; extra == 'dev'
|
|
70
|
+
Requires-Dist: types-passlib>=1.7.7.20240327; extra == 'dev'
|
|
71
|
+
Requires-Dist: types-python-dateutil>=2.8.19.20240106; extra == 'dev'
|
|
72
|
+
Description-Content-Type: text/markdown
|
|
73
|
+
|
|
74
|
+
# Borgitory
|
|
75
|
+
|
|
76
|
+
[](https://codecov.io/gh/mlapaglia/Borgitory)
|
|
77
|
+
[](https://github.com/mlapaglia/Borgitory/actions/workflows/release.yml)
|
|
78
|
+
[](https://github.com/sponsors/mlapaglia)
|
|
79
|
+
[](https://hub.docker.com/r/mlapaglia/borgitory)
|
|
80
|
+
|
|
81
|
+
<img alt="borgitory logo" src="./assets/logo.png" width="400">
|
|
82
|
+
|
|
83
|
+
A comprehensive web-based management interface for BorgBackup repositories with real-time monitoring, automated scheduling, and cloud synchronization capabilities.
|
|
84
|
+
|
|
85
|
+
## Features
|
|
86
|
+
|
|
87
|
+
### Core Functionality
|
|
88
|
+
|
|
89
|
+
- **Repository Management**: Add, configure, and manage multiple Borg repositories
|
|
90
|
+
- **Manual Backups**: Create backups on-demand with configurable compression and source paths
|
|
91
|
+
- **Real-time Progress**: Monitor backup progress with live updates
|
|
92
|
+
- **Archive Browser**: Interactive directory-based archive exploration with file downloads
|
|
93
|
+
- **Job History**: Track all backup operations with detailed logs and expandable task views
|
|
94
|
+
|
|
95
|
+
- **Automated Scheduling**: Set up cron-based backup schedules with integrated cleanup and notifications
|
|
96
|
+
- **Archive Pruning**: Configure automated pruning policies with simple or advanced retention strategies
|
|
97
|
+
- **Cloud Sync**: Synchronize repositories to S3-compatible storage using Rclone
|
|
98
|
+
- **Push Notifications**: Pushover integration for job completion alerts
|
|
99
|
+
- **User Authentication**: Secure username/password authentication
|
|
100
|
+
- **Template System**: Modern Jinja2-based UI with reusable components
|
|
101
|
+
- **Mobile Responsive**: HTMX + Alpine.js + Tailwind CSS interface
|
|
102
|
+
|
|
103
|
+
## Quick Start
|
|
104
|
+
|
|
105
|
+
### Prerequisites
|
|
106
|
+
|
|
107
|
+
- **Docker Installation (Recommended)**: Docker with Docker Compose for containerized deployment
|
|
108
|
+
- **PyPI Installation**: Python 3.11+ for direct installation from PyPI
|
|
109
|
+
|
|
110
|
+
### Installation
|
|
111
|
+
|
|
112
|
+
#### Option 1: PyPI Installation (New!)
|
|
113
|
+
|
|
114
|
+
Install Borgitory directly from PyPI:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
# Install stable release from PyPI
|
|
118
|
+
pip install borgitory
|
|
119
|
+
|
|
120
|
+
# Or install pre-release from TestPyPI (for testing new features)
|
|
121
|
+
pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ borgitory
|
|
122
|
+
|
|
123
|
+
# Start the server
|
|
124
|
+
borgitory serve
|
|
125
|
+
|
|
126
|
+
# Or run with custom settings
|
|
127
|
+
borgitory serve --host 0.0.0.0 --port 8000
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**PyPI Installation Requirements:**
|
|
131
|
+
|
|
132
|
+
- Python 3.11 or higher
|
|
133
|
+
- BorgBackup installed and available in PATH
|
|
134
|
+
- Rclone (optional, for cloud sync features)
|
|
135
|
+
|
|
136
|
+
**Note**: Pre-release versions are published to [TestPyPI](https://test.pypi.org/project/borgitory/) for testing before stable release.
|
|
137
|
+
|
|
138
|
+
#### Option 2: Docker Installation
|
|
139
|
+
|
|
140
|
+
1. **Pull and run the Docker image**
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# Using Docker directly
|
|
144
|
+
docker run -d \
|
|
145
|
+
-p 8000:8000 \
|
|
146
|
+
-v ./data:/app/data \
|
|
147
|
+
-v /path/to/backup/sources:/mnt/backup/sources:ro \
|
|
148
|
+
-v /path/to/borg/repos:/mnt/repos \
|
|
149
|
+
--cap-add SYS_ADMIN \
|
|
150
|
+
--device /dev/fuse \
|
|
151
|
+
--name borgitory \
|
|
152
|
+
mlapaglia/borgitory:latest
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**Or using Docker Compose** (create a `docker-compose.yml`):
|
|
156
|
+
|
|
157
|
+
```yaml
|
|
158
|
+
version: '3.8'
|
|
159
|
+
services:
|
|
160
|
+
borgitory:
|
|
161
|
+
image: mlapaglia/borgitory:latest
|
|
162
|
+
ports:
|
|
163
|
+
- "8000:8000"
|
|
164
|
+
volumes:
|
|
165
|
+
- ./data:/app/data
|
|
166
|
+
- /path/to/backup/sources:/mnt/backup/sources:ro
|
|
167
|
+
- /path/to/borg/repos:/mnt/repos
|
|
168
|
+
cap_add:
|
|
169
|
+
- SYS_ADMIN
|
|
170
|
+
devices:
|
|
171
|
+
- /dev/fuse
|
|
172
|
+
restart: unless-stopped
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
docker-compose up -d
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
2. **Access the web interface**
|
|
180
|
+
- Open <http://localhost:8000> in your browser
|
|
181
|
+
- Create your first admin account on initial setup
|
|
182
|
+
|
|
183
|
+
**Docker Hub**: Available at [mlapaglia/borgitory](https://hub.docker.com/r/mlapaglia/borgitory)
|
|
184
|
+
|
|
185
|
+
### Docker Volumes
|
|
186
|
+
|
|
187
|
+
```yaml
|
|
188
|
+
volumes:
|
|
189
|
+
- ./data:/app/data # Persistent application data (required)
|
|
190
|
+
- /path/to/backup/sources:/mnt/backup/sources:ro # Source directories to backup (read-only)
|
|
191
|
+
- /path/to/borg/repos:/mnt/repos # Borg repository storage (read-write)
|
|
192
|
+
- /additional/source:/mnt/additional:ro # Additional source directories as needed
|
|
193
|
+
- /another/repo/location:/mnt/alt-repos # Additional repository locations as needed
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
**Volume Strategy:**
|
|
197
|
+
|
|
198
|
+
- **Important**: All volumes must be mounted under `/mnt/` to be visible in the application
|
|
199
|
+
- Mount as many volumes as necessary to access all your backup sources and repository locations
|
|
200
|
+
- Source directories can be mounted read-only (`:ro`) for safety
|
|
201
|
+
- Repository directories need read-write access for Borg operations
|
|
202
|
+
- Each volume can be mapped to any convenient path under `/mnt/` inside the container
|
|
203
|
+
- Supports distributed setups where repositories and sources are in different locations
|
|
204
|
+
|
|
205
|
+
## Usage
|
|
206
|
+
|
|
207
|
+
### 1. Repository Setup
|
|
208
|
+
|
|
209
|
+
1. Navigate to the main dashboard
|
|
210
|
+
2. Add a new repository:
|
|
211
|
+
- **Name**: Friendly identifier
|
|
212
|
+
- **Path**: Repository location (local or remote)
|
|
213
|
+
- **Passphrase**: Encryption password
|
|
214
|
+
3. The system will validate the repository connection
|
|
215
|
+
|
|
216
|
+
### 2. Creating Backups
|
|
217
|
+
|
|
218
|
+
**Manual Backup:**
|
|
219
|
+
|
|
220
|
+
1. Select repository from dropdown
|
|
221
|
+
2. Configure source path and compression
|
|
222
|
+
3. Click "Start Backup"
|
|
223
|
+
4. Monitor progress in real-time
|
|
224
|
+
|
|
225
|
+
**Scheduled Backup:**
|
|
226
|
+
|
|
227
|
+
1. Go to Schedules section
|
|
228
|
+
2. Create new schedule with cron expression
|
|
229
|
+
3. Enable/disable schedules as needed
|
|
230
|
+
|
|
231
|
+
### 3. Archive Pruning
|
|
232
|
+
|
|
233
|
+
1. Create pruning policies:
|
|
234
|
+
- **Simple Strategy**: Keep archives within X days
|
|
235
|
+
- **Advanced Strategy**: Granular retention (daily/weekly/monthly/yearly)
|
|
236
|
+
2. Configure options:
|
|
237
|
+
- Show detailed prune lists
|
|
238
|
+
- Display space savings statistics
|
|
239
|
+
- Force prune execution
|
|
240
|
+
3. Attach policies to schedules or manual backups
|
|
241
|
+
|
|
242
|
+
### 4. Archive Browsing
|
|
243
|
+
|
|
244
|
+
**Exploring Archives:**
|
|
245
|
+
|
|
246
|
+
1. Click "View Contents" on any archive to open the browser
|
|
247
|
+
2. Navigate through directories by clicking folder names
|
|
248
|
+
3. View file details including size and modification dates
|
|
249
|
+
4. Real-time directory exploration using FUSE-mounted archive filesystems
|
|
250
|
+
|
|
251
|
+
**Downloading Files:**
|
|
252
|
+
|
|
253
|
+
1. Click the download button (⬇) next to any file
|
|
254
|
+
2. Files stream directly from the mounted archive without temporary storage
|
|
255
|
+
3. Works efficiently with large files and slow connections
|
|
256
|
+
4. Multiple downloads can run simultaneously
|
|
257
|
+
5. Uses FUSE mounting for fast, direct file access
|
|
258
|
+
|
|
259
|
+
**Requirements:**
|
|
260
|
+
|
|
261
|
+
- Docker container must run with `--cap-add SYS_ADMIN` and `--device /dev/fuse`
|
|
262
|
+
- Without FUSE support, archive browsing will be disabled
|
|
263
|
+
|
|
264
|
+
### 5. Cloud Sync
|
|
265
|
+
|
|
266
|
+
1. Configure S3 remote:
|
|
267
|
+
- Access Key ID and Secret
|
|
268
|
+
2. Test connection
|
|
269
|
+
3. Set up automatic sync after backups or manual sync
|
|
270
|
+
|
|
271
|
+
### 6. Push Notifications
|
|
272
|
+
|
|
273
|
+
1. Configure Pushover notifications:
|
|
274
|
+
- User Key and API Token
|
|
275
|
+
2. Choose notification triggers:
|
|
276
|
+
- Success, failure, or both
|
|
277
|
+
3. Attach to schedules for automated alerts
|
|
278
|
+
|
|
279
|
+
## API Documentation
|
|
280
|
+
|
|
281
|
+
The application provides a RESTful API with automatic OpenAPI documentation:
|
|
282
|
+
|
|
283
|
+
- **Swagger UI**: <http://localhost:8000/docs>
|
|
284
|
+
- **ReDoc**: <http://localhost:8000/redoc>
|
|
285
|
+
|
|
286
|
+
## Deployment
|
|
287
|
+
|
|
288
|
+
### Docker Compose (Recommended)
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
# Production deployment
|
|
292
|
+
docker-compose -f docker-compose.yml up -d
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### Manual Docker
|
|
296
|
+
|
|
297
|
+
```bash
|
|
298
|
+
# Build image
|
|
299
|
+
docker build -t borgitory .
|
|
300
|
+
|
|
301
|
+
# Run container with FUSE support for archive browsing
|
|
302
|
+
docker run -d \
|
|
303
|
+
-p 8000:8000 \
|
|
304
|
+
-v ./data:/app/data \
|
|
305
|
+
-v /path/to/backup/sources:/mnt/backup/sources:ro \
|
|
306
|
+
-v /path/to/borg/repos:/mnt/repos \
|
|
307
|
+
--cap-add SYS_ADMIN \
|
|
308
|
+
--device /dev/fuse \
|
|
309
|
+
--name borgitory \
|
|
310
|
+
borgitory
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
**Required Docker Parameters:**
|
|
314
|
+
|
|
315
|
+
- `--cap-add SYS_ADMIN`: Required for FUSE filesystem mounting to enable archive browsing
|
|
316
|
+
- `--device /dev/fuse`: Provides access to FUSE device for archive file system mounting
|
|
317
|
+
|
|
318
|
+
**FUSE Requirements:**
|
|
319
|
+
|
|
320
|
+
- FUSE mounting enables the interactive archive browser feature
|
|
321
|
+
- Allows real-time exploration of backup archives without extraction
|
|
322
|
+
- Supports direct file downloads from mounted archive filesystems
|
|
323
|
+
- Without FUSE support, archive browsing will be disabled
|
|
324
|
+
|
|
325
|
+
## Project Dependencies
|
|
326
|
+
|
|
327
|
+
This project uses modern Python packaging standards with all dependencies defined in `pyproject.toml`:
|
|
328
|
+
|
|
329
|
+
> Install with `pip install -e .[dev]` to include development tools.
|
|
330
|
+
|
|
331
|
+
## Architecture
|
|
332
|
+
|
|
333
|
+
### Backend Stack
|
|
334
|
+
|
|
335
|
+
- **FastAPI**: Modern Python web framework with automatic OpenAPI docs
|
|
336
|
+
- **SQLite**: Lightweight database for configuration and job history
|
|
337
|
+
- **APScheduler**: Advanced job scheduling and cron support
|
|
338
|
+
- **Jinja2**: Powerful template engine for dynamic HTML generation
|
|
339
|
+
- **Passlib**: Secure password hashing and verification
|
|
340
|
+
- **Pushover**: Push notification service integration
|
|
341
|
+
|
|
342
|
+
### Frontend Stack
|
|
343
|
+
|
|
344
|
+
- **HTMX**: Dynamic HTML updates without JavaScript frameworks
|
|
345
|
+
- **Alpine.js**: Lightweight JavaScript reactivity
|
|
346
|
+
- **Tailwind CSS**: Utility-first styling with responsive design
|
|
347
|
+
- **Server-Sent Events**: Real-time progress updates and live job monitoring
|
|
348
|
+
|
|
349
|
+
### Job Management System
|
|
350
|
+
|
|
351
|
+
- **Real-time Monitoring**: Live job output streaming with expandable task details
|
|
352
|
+
- **Progress Tracking**: Detailed progress indicators for each job stage
|
|
353
|
+
- **Job History**: Persistent storage of job results with searchable history
|
|
354
|
+
- **Task Management**: Individual task tracking within jobs
|
|
355
|
+
|
|
356
|
+
### Security Features
|
|
357
|
+
|
|
358
|
+
- Username/password authentication with bcrypt hashing
|
|
359
|
+
- Secure session management
|
|
360
|
+
- Encrypted credential storage (Fernet)
|
|
361
|
+
|
|
362
|
+
## Troubleshooting
|
|
363
|
+
|
|
364
|
+
### Logs
|
|
365
|
+
|
|
366
|
+
```bash
|
|
367
|
+
# View application logs
|
|
368
|
+
docker-compose logs -f borgitory
|
|
369
|
+
|
|
370
|
+
# Check specific container logs
|
|
371
|
+
docker logs <container-id>
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
## Contributing
|
|
375
|
+
|
|
376
|
+
1. Fork the repository
|
|
377
|
+
2. Create feature branch (`git checkout -b feature/amazing-feature`)
|
|
378
|
+
3. Run lint (`python lint.py all`)
|
|
379
|
+
4. Run tests (`pytest`)
|
|
380
|
+
5. Commit changes (`git commit -m 'Add amazing feature'`)
|
|
381
|
+
6. Push to branch (`git push origin feature/amazing-feature`)
|
|
382
|
+
7. Open Pull Request
|
|
383
|
+
|
|
384
|
+
### Adding additional cloud destinations
|
|
385
|
+
|
|
386
|
+
- Refer to [CLOUD_PROVIDERS.md](https://github.com/mlapaglia/borgitory/blob/main/CLOUD_PROVIDERS.md) for adding additional cloud destinations.
|
|
387
|
+
|
|
388
|
+
### Development Setup
|
|
389
|
+
|
|
390
|
+
1. **Set up Python virtual environment**
|
|
391
|
+
|
|
392
|
+
```bash
|
|
393
|
+
# Create virtual environment
|
|
394
|
+
python -m venv .env_borg
|
|
395
|
+
|
|
396
|
+
# Activate virtual environment
|
|
397
|
+
# On Windows:
|
|
398
|
+
.env_borg\Scripts\activate
|
|
399
|
+
# On macOS/Linux:
|
|
400
|
+
source .env_borg/bin/activate
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
2. **Install Python dependencies**
|
|
404
|
+
|
|
405
|
+
```bash
|
|
406
|
+
# Install runtime dependencies only
|
|
407
|
+
pip install -e .
|
|
408
|
+
|
|
409
|
+
# Install with development dependencies (testing, linting, etc.)
|
|
410
|
+
pip install -e .[dev]
|
|
411
|
+
|
|
412
|
+
# Or install stable release from PyPI for testing
|
|
413
|
+
pip install borgitory
|
|
414
|
+
|
|
415
|
+
# Or install pre-release from TestPyPI for testing new features
|
|
416
|
+
pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ borgitory
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
> **Note**: This project uses modern Python packaging with `pyproject.toml` following PEP 518 standards and is available on PyPI. All dependencies and project metadata are defined in a single configuration file.
|
|
420
|
+
|
|
421
|
+
3. **Install Rclone** (for cloud sync)
|
|
422
|
+
|
|
423
|
+
```bash
|
|
424
|
+
# On Ubuntu/Debian
|
|
425
|
+
curl https://rclone.org/install.sh | sudo bash
|
|
426
|
+
|
|
427
|
+
# On macOS
|
|
428
|
+
brew install rclone
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
4. **Run development server**
|
|
432
|
+
|
|
433
|
+
```bash
|
|
434
|
+
python run.py
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
5. **Run tests**
|
|
438
|
+
|
|
439
|
+
```bash
|
|
440
|
+
pytest
|
|
441
|
+
```
|