sbackup-cli 1.0.0__tar.gz → 2.0.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.
- sbackup_cli-2.0.0/PKG-INFO +692 -0
- sbackup_cli-2.0.0/README.md +665 -0
- {sbackup_cli-1.0.0 → sbackup_cli-2.0.0}/pyproject.toml +15 -3
- sbackup_cli-2.0.0/sbackup/__init__.py +5 -0
- sbackup_cli-2.0.0/sbackup/audit.py +290 -0
- sbackup_cli-2.0.0/sbackup/auto_save.py +2294 -0
- sbackup_cli-2.0.0/sbackup/benchmark.py +264 -0
- sbackup_cli-2.0.0/sbackup/chunked_backup.py +152 -0
- sbackup_cli-2.0.0/sbackup/cli.py +2593 -0
- sbackup_cli-2.0.0/sbackup/cloud_storage.py +103 -0
- sbackup_cli-2.0.0/sbackup/completion.py +386 -0
- sbackup_cli-2.0.0/sbackup/compression.py +1742 -0
- sbackup_cli-2.0.0/sbackup/config.py +634 -0
- sbackup_cli-2.0.0/sbackup/cross_search.py +296 -0
- sbackup_cli-2.0.0/sbackup/dedup.py +157 -0
- sbackup_cli-2.0.0/sbackup/diskcheck.py +327 -0
- sbackup_cli-2.0.0/sbackup/dryrun.py +441 -0
- sbackup_cli-2.0.0/sbackup/export.py +226 -0
- sbackup_cli-2.0.0/sbackup/handlers.py +624 -0
- sbackup_cli-2.0.0/sbackup/hooks.py +165 -0
- {sbackup_cli-1.0.0 → sbackup_cli-2.0.0}/sbackup/i18n.py +35 -0
- sbackup_cli-2.0.0/sbackup/integrity.py +220 -0
- sbackup_cli-2.0.0/sbackup/keychain.py +293 -0
- sbackup_cli-2.0.0/sbackup/locales/de_DE.json +677 -0
- sbackup_cli-2.0.0/sbackup/locales/en_US.json +667 -0
- sbackup_cli-2.0.0/sbackup/locales/es_ES.json +667 -0
- sbackup_cli-2.0.0/sbackup/locales/fr_FR.json +667 -0
- sbackup_cli-2.0.0/sbackup/locales/ja_JP.json +667 -0
- sbackup_cli-2.0.0/sbackup/locales/ko_KR.json +667 -0
- sbackup_cli-2.0.0/sbackup/locales/pt_BR.json +667 -0
- sbackup_cli-2.0.0/sbackup/locales/ru_RU.json +667 -0
- sbackup_cli-2.0.0/sbackup/locales/zh_CN.json +667 -0
- sbackup_cli-2.0.0/sbackup/lock.py +135 -0
- sbackup_cli-2.0.0/sbackup/monitor.py +160 -0
- sbackup_cli-2.0.0/sbackup/multi_dest.py +417 -0
- sbackup_cli-2.0.0/sbackup/parity.py +89 -0
- sbackup_cli-2.0.0/sbackup/profile.py +313 -0
- sbackup_cli-2.0.0/sbackup/ratelimiter.py +40 -0
- sbackup_cli-2.0.0/sbackup/retry.py +72 -0
- sbackup_cli-2.0.0/sbackup/rotation.py +209 -0
- sbackup_cli-2.0.0/sbackup/schema.py +251 -0
- sbackup_cli-2.0.0/sbackup/selective.py +313 -0
- sbackup_cli-2.0.0/sbackup/sftp.py +391 -0
- sbackup_cli-2.0.0/sbackup/task_queue.py +313 -0
- sbackup_cli-2.0.0/sbackup/webdav.py +320 -0
- sbackup_cli-2.0.0/sbackup/wizard.py +200 -0
- sbackup_cli-2.0.0/sbackup_cli.egg-info/PKG-INFO +692 -0
- sbackup_cli-2.0.0/sbackup_cli.egg-info/SOURCES.txt +53 -0
- sbackup_cli-2.0.0/sbackup_cli.egg-info/requires.txt +7 -0
- sbackup_cli-1.0.0/PKG-INFO +0 -444
- sbackup_cli-1.0.0/README.md +0 -421
- sbackup_cli-1.0.0/sbackup/__init__.py +0 -193
- sbackup_cli-1.0.0/sbackup/auto_save.py +0 -336
- sbackup_cli-1.0.0/sbackup/compression.py +0 -555
- sbackup_cli-1.0.0/sbackup/config.py +0 -134
- sbackup_cli-1.0.0/sbackup_cli.egg-info/PKG-INFO +0 -444
- sbackup_cli-1.0.0/sbackup_cli.egg-info/SOURCES.txt +0 -15
- sbackup_cli-1.0.0/sbackup_cli.egg-info/requires.txt +0 -3
- {sbackup_cli-1.0.0 → sbackup_cli-2.0.0}/LICENSE +0 -0
- {sbackup_cli-1.0.0 → sbackup_cli-2.0.0}/sbackup/__main__.py +0 -0
- {sbackup_cli-1.0.0 → sbackup_cli-2.0.0}/sbackup_cli.egg-info/dependency_links.txt +0 -0
- {sbackup_cli-1.0.0 → sbackup_cli-2.0.0}/sbackup_cli.egg-info/entry_points.txt +0 -0
- {sbackup_cli-1.0.0 → sbackup_cli-2.0.0}/sbackup_cli.egg-info/top_level.txt +0 -0
- {sbackup_cli-1.0.0 → sbackup_cli-2.0.0}/setup.cfg +0 -0
|
@@ -0,0 +1,692 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sbackup-cli
|
|
3
|
+
Version: 2.0.0
|
|
4
|
+
Summary: 智能文件夹备份工具,支持增量备份和自定义配置
|
|
5
|
+
Author-email: xiatianxuan <xiatianxuan2025@163.com>
|
|
6
|
+
License: GPL-3.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/xiatianxuan/sbackup
|
|
8
|
+
Project-URL: Repository, https://github.com/xiatianxuan/sbackup
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Environment :: Console
|
|
11
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
12
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Topic :: System :: Archiving :: Backup
|
|
16
|
+
Requires-Python: >=3.10
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
License-File: LICENSE
|
|
19
|
+
Requires-Dist: minio>=7.2.20
|
|
20
|
+
Requires-Dist: paramiko>=4.0.0
|
|
21
|
+
Requires-Dist: py7zr>=1.1.0
|
|
22
|
+
Requires-Dist: reedsolo>=1.7.0
|
|
23
|
+
Requires-Dist: tqdm>=4.67.3
|
|
24
|
+
Requires-Dist: watchdog>=6.0.0
|
|
25
|
+
Requires-Dist: zstandard>=0.25.0
|
|
26
|
+
Dynamic: license-file
|
|
27
|
+
|
|
28
|
+
# Sbackup
|
|
29
|
+
|
|
30
|
+
[](https://www.python.org/)
|
|
31
|
+
[](LICENSE)
|
|
32
|
+
[](https://pypi.org/project/sbackup-cli/)
|
|
33
|
+
[](.github/workflows/ci.yml)
|
|
34
|
+
[]()
|
|
35
|
+
|
|
36
|
+
> A lightweight, efficient folder backup tool with CLI support for managing backup strategies.
|
|
37
|
+
|
|
38
|
+
[English](README.md) | [Deutsch](docs/readme/README_de.md) | [Espanol](docs/readme/README_es.md) | [Francais](docs/readme/README_fr.md) | [Portugues](docs/readme/README_pt.md) | [Pycckuu](docs/readme/README_ru.md) | [日本語](docs/readme/README_ja.md) | [한국어](docs/readme/README_ko.md) | [中文](docs/readme/README_zh.md)
|
|
39
|
+
|
|
40
|
+
- [Introduction](#introduction)
|
|
41
|
+
- [Features](#features)
|
|
42
|
+
- [Getting Started](#getting-started)
|
|
43
|
+
- [Installation](#installation)
|
|
44
|
+
- [Usage](#usage)
|
|
45
|
+
- [Configuration](#configuration)
|
|
46
|
+
- [Example Configuration](#example-configuration)
|
|
47
|
+
- [SFTP Remote Backup](#sftp-remote-backup)
|
|
48
|
+
- [WebDAV Remote Backup](#webdav-remote-backup)
|
|
49
|
+
- [How It Works](#how-it-works)
|
|
50
|
+
- [Development Guide](#development-guide)
|
|
51
|
+
- [Running Tests](#running-tests)
|
|
52
|
+
- [Code Structure](#code-structure)
|
|
53
|
+
- [FAQ](#faq)
|
|
54
|
+
- [Contributing](#contributing)
|
|
55
|
+
- [License](#license)
|
|
56
|
+
- [Author](#author)
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Introduction
|
|
61
|
+
|
|
62
|
+
Sbackup is a lightweight folder backup tool that lets you add, remove, and manage backup strategies from the command line. It uses each folder's last-modified timestamp to determine whether a backup is needed, keeping your data up to date.
|
|
63
|
+
|
|
64
|
+
## Features
|
|
65
|
+
|
|
66
|
+
- **Incremental backup** -- only folders that have changed are backed up, saving time and storage
|
|
67
|
+
- **Multi-format support** -- ZIP, tar, tar.gz, tar.bz2, tar.xz, tar.zst, 7z; both global and per-entry format overrides
|
|
68
|
+
- **SFTP remote backup** -- built on paramiko with password/SSH key authentication and auto-detection of default keys
|
|
69
|
+
- **WebDAV remote backup** -- uses Python's standard library urllib with zero extra dependencies; works with Jianguoyun, NextCloud, and Synology
|
|
70
|
+
- **S3 cloud storage** -- powered by minio, supports all S3-compatible backends (AWS, MinIO, Alibaba Cloud OSS, etc.)
|
|
71
|
+
- **Multi-destination parallel backup** -- back up to local and multiple remote targets simultaneously
|
|
72
|
+
- **Restore** -- extract backups to a target directory with optional selective recovery
|
|
73
|
+
- **Backup cleanup** -- automatically delete old backups by count, age, or daily retention policy
|
|
74
|
+
- **Encrypted backup** -- 7z password encryption plus PBKDF2 encryption for all formats
|
|
75
|
+
- **Scheduled backup** -- run backups on a fixed interval or monitor the filesystem in real time with watchdog
|
|
76
|
+
- **Backup history** -- timestamps, file sizes, and SHA256 checksums recorded for every backup
|
|
77
|
+
- **Audit log** -- audit events for all backup and restore operations
|
|
78
|
+
- **Pre/Post hooks** -- run custom commands before or after backups
|
|
79
|
+
- **Configuration profiles** -- save, switch, import, and export multiple configuration profiles
|
|
80
|
+
- **Cross-archive search** -- search for matching filenames across multiple backup archives
|
|
81
|
+
- **Data integrity** -- SHA256 checksum generation and verification, Reed-Solomon error correction codes
|
|
82
|
+
- **Config validation** -- automatic validation of configuration parameters with tamper detection
|
|
83
|
+
- **Task queue** -- manage backup tasks with add, execute, and cancel operations
|
|
84
|
+
- **Compression benchmark** -- compare compression performance across formats and levels
|
|
85
|
+
- **Disk space estimation** -- estimate backup size by file type and check destination space
|
|
86
|
+
- **Internationalization** -- nine languages: Chinese, English, French, Spanish, Russian, German, Japanese, Portuguese, Korean
|
|
87
|
+
- **Shell completion** -- auto-completion for bash, zsh, fish, and PowerShell
|
|
88
|
+
- **Lightweight and efficient** -- small footprint, fast startup, low resource usage
|
|
89
|
+
- **Cross-platform** -- Windows, macOS, and Linux
|
|
90
|
+
|
|
91
|
+
## Getting Started
|
|
92
|
+
|
|
93
|
+
### Installation
|
|
94
|
+
|
|
95
|
+
#### Install with pip
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
pip install sbackup-cli
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
After installation, use the `sbackup` command (PyPI package name is `sbackup-cli`, CLI command is `sbackup`).
|
|
102
|
+
|
|
103
|
+
#### Install from source
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
git clone https://github.com/xiatianxuan/sbackup.git
|
|
107
|
+
cd sbackup
|
|
108
|
+
uv sync
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Usage
|
|
112
|
+
|
|
113
|
+
#### Basic syntax
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
uv run python main.py <command> [options]
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
#### Available commands
|
|
120
|
+
|
|
121
|
+
| Command | Description |
|
|
122
|
+
|---------|-------------|
|
|
123
|
+
| `add` | Add a backup strategy |
|
|
124
|
+
| `rm` / `remove` | Remove a backup strategy |
|
|
125
|
+
| `edit` | Edit an existing backup strategy |
|
|
126
|
+
| `all` | List all backup strategies |
|
|
127
|
+
| `save` | Run backup |
|
|
128
|
+
| `watch` | Run backup on a schedule |
|
|
129
|
+
| `restore` | Restore from a backup file |
|
|
130
|
+
| `info` | View backup file details |
|
|
131
|
+
| `diff` | Compare source directory against backup |
|
|
132
|
+
| `verify` | Verify backup file integrity |
|
|
133
|
+
| `search` | Search for files inside a backup |
|
|
134
|
+
| `xsearch` | Search across multiple backup archives |
|
|
135
|
+
| `versions` | View backup version history |
|
|
136
|
+
| `sftp` | SFTP remote backup management |
|
|
137
|
+
| `webdav` | WebDAV remote backup management |
|
|
138
|
+
| `remote` | Remote file management (list/rm) |
|
|
139
|
+
| `task` | Backup task queue management |
|
|
140
|
+
| `audit` | Audit log queries |
|
|
141
|
+
| `hooks` | Manually run Pre/Post hooks |
|
|
142
|
+
| `profile` | Configuration profile management |
|
|
143
|
+
| `rotate` | Backup rotation cleanup |
|
|
144
|
+
| `clean` | Clean old backups |
|
|
145
|
+
| `diskcheck` | Disk space estimation |
|
|
146
|
+
| `benchmark` | Compression format benchmark |
|
|
147
|
+
| `integrity` | Backup directory integrity check |
|
|
148
|
+
| `dry-run` | Preview backup file selection |
|
|
149
|
+
| `export` / `import` | Export/import backup strategies |
|
|
150
|
+
| `ignore` | Generate .sbackupignore file |
|
|
151
|
+
| `schedule` | Export scheduled task configuration |
|
|
152
|
+
| `webhook` | Configure webhook presets |
|
|
153
|
+
| `config` | Configuration encryption/validation |
|
|
154
|
+
| `report` | Generate backup report |
|
|
155
|
+
| `completion` | Generate shell completion scripts |
|
|
156
|
+
| `wizard` | Interactive configuration wizard |
|
|
157
|
+
| `status` | Backup status dashboard |
|
|
158
|
+
| `version` | Show version information |
|
|
159
|
+
| `help` | Show help information |
|
|
160
|
+
|
|
161
|
+
#### Global options
|
|
162
|
+
|
|
163
|
+
| Option | Description |
|
|
164
|
+
|--------|-------------|
|
|
165
|
+
| `--lang zh_CN` / `en_US` / `fr_FR` / `es_ES` / `ru_RU` / `de_DE` / `ja_JP` / `pt_BR` / `ko_KR` | Set UI language (persisted in config.json) |
|
|
166
|
+
| `--format zip` / `tar` / `tar.gz` / `tar.bz2` / `tar.xz` / `tar.zst` / `7z` | Set archive format (persisted in config.json) |
|
|
167
|
+
| `--debug` | Enable debug logging |
|
|
168
|
+
|
|
169
|
+
#### Adding a backup strategy
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
uv run python main.py add <source> <dest> [-i ignore_patterns]
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Parameters:
|
|
176
|
+
- **source** -- path to the folder to back up
|
|
177
|
+
- **dest** -- path where backup files are stored
|
|
178
|
+
- **-i, --ignore** -- comma-separated names of files or folders to skip (default: `.git,__pycache__`)
|
|
179
|
+
- **--format** -- per-entry archive format (overrides the global default for this strategy only): `zip` / `tar` / `tar.gz` / `tar.bz2` / `tar.xz` / `tar.zst` / `7z`
|
|
180
|
+
|
|
181
|
+
Examples:
|
|
182
|
+
```bash
|
|
183
|
+
# Add strategy using the global default format
|
|
184
|
+
uv run python main.py add F:/my_folder F:/backup -i node_modules,.git
|
|
185
|
+
|
|
186
|
+
# Specify tar.gz for this strategy (every backup of this folder uses tar.gz)
|
|
187
|
+
uv run python main.py add F:/my_folder F:/backup --format tar.gz
|
|
188
|
+
|
|
189
|
+
# Specify 7z for this folder only
|
|
190
|
+
uv run python main.py add F:/my_folder F:/backup --format 7z
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
#### Removing a backup strategy
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
uv run python main.py rm <path>
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Parameters:
|
|
200
|
+
- **path** -- source folder path of the strategy to remove
|
|
201
|
+
|
|
202
|
+
Example:
|
|
203
|
+
```bash
|
|
204
|
+
uv run python main.py rm F:/my_folder
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
#### Listing all backup strategies
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
uv run python main.py all
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Displays all currently configured backup strategies.
|
|
214
|
+
|
|
215
|
+
#### Running a backup
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
# Use default format (ZIP)
|
|
219
|
+
uv run python main.py save
|
|
220
|
+
|
|
221
|
+
# Use tar.gz format
|
|
222
|
+
uv run python main.py --format tar.gz save
|
|
223
|
+
|
|
224
|
+
# Keep only the 5 most recent backups, auto-clean old ones
|
|
225
|
+
uv run python main.py save --keep 5
|
|
226
|
+
|
|
227
|
+
# Use 7z format with encryption
|
|
228
|
+
uv run python main.py --format 7z save --password mysecret
|
|
229
|
+
|
|
230
|
+
# English UI + tar.xz format
|
|
231
|
+
uv run python main.py --lang en_US --format tar.xz save
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
**save options:**
|
|
235
|
+
|
|
236
|
+
| Option | Default | Description |
|
|
237
|
+
|--------|---------|-------------|
|
|
238
|
+
| `--keep N` | `0` | Keep the N most recent backup files; 0 means no cleanup |
|
|
239
|
+
| `--password PASSWORD` | `""` | Encryption password (7z format only) |
|
|
240
|
+
| `--sftp` | `false` | Upload to SFTP server after backup |
|
|
241
|
+
| `--webdav` | `false` | Upload to WebDAV server after backup |
|
|
242
|
+
|
|
243
|
+
Backs up changed folders automatically according to the configured strategies.
|
|
244
|
+
|
|
245
|
+
#### Scheduled backup
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
# Back up every 60 minutes
|
|
249
|
+
uv run python main.py watch --interval 60
|
|
250
|
+
|
|
251
|
+
# Back up every 2 hours, keep the 10 most recent files
|
|
252
|
+
uv run python main.py watch --interval 120 --keep 10
|
|
253
|
+
|
|
254
|
+
# Scheduled backup + 7z encryption
|
|
255
|
+
uv run python main.py --format 7z watch --interval 60 --password mysecret
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
**watch options:**
|
|
259
|
+
|
|
260
|
+
| Option | Default | Description |
|
|
261
|
+
|--------|---------|-------------|
|
|
262
|
+
| `--interval MINUTES` | `60` | Backup interval in minutes |
|
|
263
|
+
| `--keep N` | `0` | Keep the N most recent backup files |
|
|
264
|
+
| `--password PASSWORD` | `""` | Encryption password (7z format only) |
|
|
265
|
+
| `--sftp` | `false` | Upload to SFTP server after each backup |
|
|
266
|
+
| `--webdav` | `false` | Upload to WebDAV server after each backup |
|
|
267
|
+
|
|
268
|
+
Press `Ctrl+C` to stop scheduled backup.
|
|
269
|
+
|
|
270
|
+
#### Restoring a backup
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
uv run python main.py restore <backup_file> <target_dir>
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
Parameters:
|
|
277
|
+
- **backup_file** -- path to the backup file (supports .zip / .tar / .tar.gz / .tar.bz2 / .tar.xz / .tar.zst / .7z)
|
|
278
|
+
- **target_dir** -- directory to restore into
|
|
279
|
+
|
|
280
|
+
Examples:
|
|
281
|
+
```bash
|
|
282
|
+
uv run python main.py restore F:/backup/my_folder.tar.gz F:/restored
|
|
283
|
+
uv run python main.py restore F:/backup/my_folder.7z F:/restored
|
|
284
|
+
uv run python main.py restore F:/backup/my_folder.tar.zst F:/restored
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
#### SFTP remote backup
|
|
288
|
+
|
|
289
|
+
```bash
|
|
290
|
+
# ============ Quick start (recommended) ============
|
|
291
|
+
# 1. Configure SFTP (auto-detects SSH private key, no manual setup needed)
|
|
292
|
+
sbackup sftp config --host 192.168.1.100 --user admin --remote-path /backups
|
|
293
|
+
|
|
294
|
+
# 2. Test connection
|
|
295
|
+
sbackup sftp test
|
|
296
|
+
|
|
297
|
+
# 3. Run backup and upload
|
|
298
|
+
sbackup save --sftp
|
|
299
|
+
|
|
300
|
+
# ============ Authentication methods ============
|
|
301
|
+
|
|
302
|
+
# Method 1: Auto-detect private key (recommended)
|
|
303
|
+
# Automatically tries ~/.ssh/id_ed25519 -> id_rsa -> id_ecdsa
|
|
304
|
+
sbackup sftp config --host 192.168.1.100 --user admin
|
|
305
|
+
|
|
306
|
+
# Method 2: Password authentication
|
|
307
|
+
sbackup sftp config --host 192.168.1.100 --user admin --password secret
|
|
308
|
+
|
|
309
|
+
# Method 3: Specify private key
|
|
310
|
+
sbackup sftp config --host 192.168.1.100 --user admin --key-file ~/.ssh/id_rsa
|
|
311
|
+
|
|
312
|
+
# Method 4: Private key + passphrase (interactive input)
|
|
313
|
+
sbackup sftp config --host 192.168.1.100 --user admin --key-file ~/.ssh/id_rsa
|
|
314
|
+
|
|
315
|
+
# Method 5: Private key + passphrase (command line)
|
|
316
|
+
sbackup sftp config --host 192.168.1.100 --user admin --key-file ~/.ssh/id_rsa --key-passphrase mykeypass
|
|
317
|
+
|
|
318
|
+
# ============ Use cases ============
|
|
319
|
+
|
|
320
|
+
# One-time backup with upload
|
|
321
|
+
sbackup save --sftp
|
|
322
|
+
|
|
323
|
+
# Scheduled backup with auto-upload (every 60 minutes)
|
|
324
|
+
sbackup watch --interval 60 --sftp
|
|
325
|
+
|
|
326
|
+
# Specify format + upload
|
|
327
|
+
sbackup --format tar.gz save --sftp
|
|
328
|
+
|
|
329
|
+
# Encrypted backup + upload
|
|
330
|
+
sbackup --format 7z save --password mysecret --sftp
|
|
331
|
+
|
|
332
|
+
# Keep 5 most recent backups + upload
|
|
333
|
+
sbackup save --keep 5 --sftp
|
|
334
|
+
|
|
335
|
+
# ============ Advanced usage ============
|
|
336
|
+
|
|
337
|
+
# Interactive configuration (step-by-step input)
|
|
338
|
+
sbackup sftp config
|
|
339
|
+
|
|
340
|
+
# Non-interactive configuration (all parameters on command line)
|
|
341
|
+
sbackup sftp config --host 192.168.1.100 --port 22 --user admin --password secret --remote-path /backups
|
|
342
|
+
|
|
343
|
+
# Test connection with verbose logging
|
|
344
|
+
sbackup --debug sftp test
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
**sftp subcommands:**
|
|
348
|
+
|
|
349
|
+
| Subcommand | Description | Example |
|
|
350
|
+
|------------|-------------|---------|
|
|
351
|
+
| `sftp config` | Configure SFTP connection (host/port/user/password/key_file/key_passphrase/remote_path) | `sbackup sftp config --host 192.168.1.100 --user admin` |
|
|
352
|
+
| `sftp test` | Test whether the SFTP connection works | `sbackup sftp test` |
|
|
353
|
+
|
|
354
|
+
**Authentication methods:**
|
|
355
|
+
|
|
356
|
+
| Method | Parameters | Description | Example |
|
|
357
|
+
|--------|-----------|-------------|---------|
|
|
358
|
+
| **Auto-detect** | (none) | Automatically tries `~/.ssh/id_ed25519` -> `id_rsa` -> `id_ecdsa` (recommended) | `sbackup sftp config --host ... --user ...` |
|
|
359
|
+
| Password | `--password` | Log in with a password | `sbackup sftp config --host ... --user ... --password secret` |
|
|
360
|
+
| Private key | `--key-file` | Log in with a specific SSH private key | `sbackup sftp config --host ... --user ... --key-file ~/.ssh/id_rsa` |
|
|
361
|
+
| Private key + passphrase | `--key-file` + `--key-passphrase` | When the private key requires a passphrase | `sbackup sftp config --host ... --user ... --key-file ~/.ssh/id_rsa --key-passphrase mypass` |
|
|
362
|
+
|
|
363
|
+
Supported key formats: RSA, Ed25519, ECDSA.
|
|
364
|
+
|
|
365
|
+
**Cross-platform path support:**
|
|
366
|
+
|
|
367
|
+
| Platform | Key path example | Description |
|
|
368
|
+
|----------|-----------------|-------------|
|
|
369
|
+
| Linux/macOS | `~/.ssh/id_rsa` | Expands to `/home/user/.ssh/id_rsa` |
|
|
370
|
+
| Windows | `~/.ssh/id_rsa` | Expands to `C:\Users\username\.ssh\id_rsa` |
|
|
371
|
+
| All platforms | Absolute path | Use the full path directly |
|
|
372
|
+
|
|
373
|
+
SFTP configuration is stored in the `sftp` field of `config.json` and can be set via command line or interactive input.
|
|
374
|
+
|
|
375
|
+
#### Viewing version information
|
|
376
|
+
|
|
377
|
+
```bash
|
|
378
|
+
sbackup version
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
## Configuration
|
|
382
|
+
|
|
383
|
+
Sbackup supports customization through a `config.json` file placed in the project root directory.
|
|
384
|
+
|
|
385
|
+
### Configuration options
|
|
386
|
+
|
|
387
|
+
```json
|
|
388
|
+
{
|
|
389
|
+
"compression_format": "ZIP",
|
|
390
|
+
"compression": {
|
|
391
|
+
"algorithm": "ZIP_DEFLATED",
|
|
392
|
+
"level": 6
|
|
393
|
+
},
|
|
394
|
+
"skip_patterns": [".git", "__pycache__"],
|
|
395
|
+
"data_file": "sbackup.json",
|
|
396
|
+
"lang": "zh_CN",
|
|
397
|
+
"password": "",
|
|
398
|
+
"sftp": {
|
|
399
|
+
"host": "",
|
|
400
|
+
"port": 22,
|
|
401
|
+
"user": "",
|
|
402
|
+
"password": "",
|
|
403
|
+
"key_file": "",
|
|
404
|
+
"key_passphrase": "",
|
|
405
|
+
"remote_path": "/",
|
|
406
|
+
"enabled": false
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
| Key | Type | Default | Description |
|
|
412
|
+
|-----|------|---------|-------------|
|
|
413
|
+
| `compression_format` | string | `"ZIP"` | Archive format: `ZIP`, `TAR`, `TAR_GZ`, `TAR_BZ2`, `TAR_XZ`, `TAR_ZST`, `7Z` |
|
|
414
|
+
| `compression.algorithm` | string | `"ZIP_DEFLATED"` | ZIP compression algorithm: `ZIP_DEFLATED`, `ZIP_STORED`, `ZIP_BZIP2`, `ZIP_LZMA` |
|
|
415
|
+
| `compression.level` | int | `6` | Compression level 0-9 (0 = no compression, 9 = maximum) |
|
|
416
|
+
| `skip_patterns` | list | `[".git", "__pycache__"]` | File/folder patterns to skip (supports fnmatch wildcards and path matching) |
|
|
417
|
+
| `data_file` | string | Platform default | Path to the backup strategy data file |
|
|
418
|
+
| `lang` | string | `"zh_CN"` | UI language: `zh_CN`, `en_US`, `fr_FR`, `es_ES`, `ru_RU`, `de_DE`, `ja_JP`, `pt_BR`, `ko_KR` |
|
|
419
|
+
| `password` | string | `""` | 7z encryption password |
|
|
420
|
+
| `sftp.host` | string | `""` | SFTP server address |
|
|
421
|
+
| `sftp.port` | int | `22` | SFTP port |
|
|
422
|
+
| `sftp.user` | string | `""` | SFTP username |
|
|
423
|
+
| `sftp.password` | string | `""` | SFTP password (for password authentication) |
|
|
424
|
+
| `sftp.key_file` | string | `""` | SSH private key file path (for key-based authentication) |
|
|
425
|
+
| `sftp.key_passphrase` | string | `""` | Private key passphrase (if required) |
|
|
426
|
+
| `sftp.remote_path` | string | `"/"` | Remote destination path |
|
|
427
|
+
| `sftp.enabled` | bool | `false` | Whether SFTP is enabled |
|
|
428
|
+
|
|
429
|
+
### Example configuration
|
|
430
|
+
|
|
431
|
+
Using tar.bz2 format for high-compression backups:
|
|
432
|
+
|
|
433
|
+
```json
|
|
434
|
+
{
|
|
435
|
+
"compression_format": "TAR_BZ2",
|
|
436
|
+
"compression_level": 9,
|
|
437
|
+
"skip_patterns": [".git", "__pycache__", "node_modules", "*.log"],
|
|
438
|
+
"data_file": "backup_strategies.json",
|
|
439
|
+
"lang": "en_US"
|
|
440
|
+
}
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
### Archive format comparison
|
|
444
|
+
|
|
445
|
+
| Format | Extension | Compression | Speed | Dependencies | Best for |
|
|
446
|
+
|--------|-----------|-------------|-------|--------------|----------|
|
|
447
|
+
| ZIP | .zip | Medium | Fast | stdlib | General purpose, best Windows compatibility |
|
|
448
|
+
| tar | .tar | None | Very fast | stdlib | Archive only, pair with external compression |
|
|
449
|
+
| tar.gz | .tar.gz | Medium | Fast | stdlib | General Linux/macOS use |
|
|
450
|
+
| tar.bz2 | .tar.bz2 | High | Medium | stdlib | High-compression archives |
|
|
451
|
+
| tar.xz | .tar.xz | Highest | Slow | stdlib | Long-term archiving, space-sensitive |
|
|
452
|
+
| tar.zst | .tar.zst | Medium-high | Very fast | zstandard | Modern workloads, speed/size balance |
|
|
453
|
+
| 7z | .7z | Very high | Slow | py7zr | Maximum compression, encryption support |
|
|
454
|
+
|
|
455
|
+
#### WebDAV remote backup
|
|
456
|
+
|
|
457
|
+
WebDAV is an HTTP-based file protocol supported by Jianguoyun, NextCloud, Synology, and other popular cloud drives. Uses Python's standard library `urllib` with **zero extra dependencies**.
|
|
458
|
+
|
|
459
|
+
```bash
|
|
460
|
+
# ============ Quick start ============
|
|
461
|
+
# 1. Configure WebDAV
|
|
462
|
+
sbackup webdav config --url https://dav.jianguoyun.com/dav/ --user user@example.com --password secret
|
|
463
|
+
|
|
464
|
+
# 2. Test connection
|
|
465
|
+
sbackup webdav test
|
|
466
|
+
|
|
467
|
+
# 3. Run backup and upload
|
|
468
|
+
sbackup save --webdav
|
|
469
|
+
|
|
470
|
+
# ============ Use cases ============
|
|
471
|
+
|
|
472
|
+
# One-time backup with upload
|
|
473
|
+
sbackup save --webdav
|
|
474
|
+
|
|
475
|
+
# Scheduled backup with auto-upload (every 60 minutes)
|
|
476
|
+
sbackup watch --interval 60 --webdav
|
|
477
|
+
|
|
478
|
+
# Specify remote subdirectory
|
|
479
|
+
sbackup webdav config --url https://dav.jianguoyun.com/dav/ --user user@example.com --remote-path /backups/sbackup
|
|
480
|
+
|
|
481
|
+
# Upload to SFTP and WebDAV simultaneously
|
|
482
|
+
sbackup save --sftp --webdav
|
|
483
|
+
|
|
484
|
+
# ============ Common WebDAV service URLs ============
|
|
485
|
+
# Jianguoyun: https://dav.jianguoyun.com/dav/
|
|
486
|
+
# NextCloud: https://your-server/remote.php/dav/files/username/
|
|
487
|
+
# Synology: https://your-synology:5006/webdav/
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
**webdav subcommands:**
|
|
491
|
+
|
|
492
|
+
| Subcommand | Description | Example |
|
|
493
|
+
|------------|-------------|---------|
|
|
494
|
+
| `webdav config` | Configure WebDAV connection (url/user/password/remote_path) | `sbackup webdav config --url ... --user ...` |
|
|
495
|
+
| `webdav test` | Test whether the WebDAV connection works | `sbackup webdav test` |
|
|
496
|
+
|
|
497
|
+
| Option | Default | Description |
|
|
498
|
+
|--------|---------|-------------|
|
|
499
|
+
| `--url URL` | `""` | WebDAV server URL (e.g. `https://dav.jianguoyun.com/dav/`) |
|
|
500
|
+
| `--user USER` | `""` | WebDAV username (usually an email address) |
|
|
501
|
+
| `--password PASS` | `""` | WebDAV password (Jianguoyun requires generating an app password in settings) |
|
|
502
|
+
| `--remote-path PATH` | `/` | Remote destination path |
|
|
503
|
+
|
|
504
|
+
## How It Works
|
|
505
|
+
|
|
506
|
+
Sbackup implements backup through the following mechanisms:
|
|
507
|
+
|
|
508
|
+
1. **Strategy storage** -- backup strategies are stored in a JSON file containing folder paths, last-modified timestamps, target paths, ignore patterns, and per-entry archive formats.
|
|
509
|
+
2. **Incremental backup** -- by comparing each folder's last-modified timestamp, only changed folders are backed up.
|
|
510
|
+
3. **Multi-format compression** -- uses Python's built-in `zipfile` and `tarfile` modules, plus `zstandard` and `py7zr` third-party libraries, supporting seven archive formats.
|
|
511
|
+
4. **Per-entry format** -- each strategy can specify its own archive format (`add --format`), which takes priority over the global `--format` setting; when not specified, the global default is used.
|
|
512
|
+
5. **Backup cleanup** -- after a successful backup, the target directory is scanned, sorted by modification time, and older files exceeding the retention count are deleted.
|
|
513
|
+
6. **Encrypted backup** -- the 7z format supports LZMA2 encryption via the `--password` parameter or the `password` field in `config.json`.
|
|
514
|
+
7. **Scheduled backup** -- the `watch` command runs backups in a loop at the specified interval; `Ctrl+C` exits safely.
|
|
515
|
+
8. **Backup history** -- each backup records a timestamp, file size, and file count, keeping the 100 most recent entries.
|
|
516
|
+
9. **SFTP remote backup** -- an SFTP client built on paramiko with connection testing, automatic remote directory creation, and progress-bar file uploads.
|
|
517
|
+
|
|
518
|
+
### Data file format
|
|
519
|
+
|
|
520
|
+
```json
|
|
521
|
+
{
|
|
522
|
+
"/path/to/source/folder": [
|
|
523
|
+
1719235200.0,
|
|
524
|
+
"/path/to/target/folder",
|
|
525
|
+
[".git", "__pycache__"],
|
|
526
|
+
""
|
|
527
|
+
],
|
|
528
|
+
"/path/to/another/folder": [
|
|
529
|
+
1719235200.0,
|
|
530
|
+
"/path/to/another/target",
|
|
531
|
+
[".git"],
|
|
532
|
+
"TAR_GZ"
|
|
533
|
+
],
|
|
534
|
+
"_history": [
|
|
535
|
+
{
|
|
536
|
+
"time": "2026-05-01T12:00:00",
|
|
537
|
+
"source": "/path/to/source/folder",
|
|
538
|
+
"size_mb": 12.5,
|
|
539
|
+
"files_count": 150
|
|
540
|
+
}
|
|
541
|
+
]
|
|
542
|
+
}
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
Each backup strategy entry is a 4-element list: `[mtime, target, skip_patterns, compression_format]`
|
|
546
|
+
|
|
547
|
+
| Field | Description |
|
|
548
|
+
|-------|-------------|
|
|
549
|
+
| `mtime` | Last-modified timestamp of the source folder (used for incremental backup decisions) |
|
|
550
|
+
| `target` | Target path where backup files are stored |
|
|
551
|
+
| `skip_patterns` | List of file/folder patterns to skip |
|
|
552
|
+
| `compression_format` | Per-entry archive format (empty string means use the global default) |
|
|
553
|
+
|
|
554
|
+
## Development Guide
|
|
555
|
+
|
|
556
|
+
### Running tests
|
|
557
|
+
|
|
558
|
+
```bash
|
|
559
|
+
uv run coverage run -m unittest discover -s tests -t . && uv run coverage report -m
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
### Code structure
|
|
563
|
+
|
|
564
|
+
```
|
|
565
|
+
sbackup/
|
|
566
|
+
├── main.py # Entry point
|
|
567
|
+
├── sbackup/
|
|
568
|
+
│ ├── __init__.py # Core function exports
|
|
569
|
+
│ ├── __main__.py # python -m sbackup entry point
|
|
570
|
+
│ ├── cli.py # CLI argument parsing and command dispatch (30+ commands)
|
|
571
|
+
│ ├── config.py # Configuration loading, encryption, webhook/SMTP config
|
|
572
|
+
│ ├── auto_save.py # BackupManager core engine
|
|
573
|
+
│ ├── compression.py # 7-format compression/decompression engine
|
|
574
|
+
│ ├── i18n.py # Internationalization (9 languages)
|
|
575
|
+
│ ├── sftp.py # SFTP remote backup client (paramiko)
|
|
576
|
+
│ ├── webdav.py # WebDAV remote backup client (zero dependencies)
|
|
577
|
+
│ ├── cloud_storage.py # S3 cloud storage client (minio)
|
|
578
|
+
│ ├── multi_dest.py # Multi-destination parallel backup
|
|
579
|
+
│ ├── handlers.py # SFTP/WebDAV/Remote/Schedule command handlers
|
|
580
|
+
│ ├── hooks.py # Pre/Post hook execution
|
|
581
|
+
│ ├── audit.py # Audit log system
|
|
582
|
+
│ ├── profile.py # Configuration profile management
|
|
583
|
+
│ ├── selective.py # Selective restore
|
|
584
|
+
│ ├── cross_search.py # Cross-archive search
|
|
585
|
+
│ ├── integrity.py # SHA256 checksums
|
|
586
|
+
│ ├── rotation.py # Backup rotation policies
|
|
587
|
+
│ ├── dryrun.py # Dry-run preview
|
|
588
|
+
│ ├── diskcheck.py # Disk space estimation
|
|
589
|
+
│ ├── task_queue.py # Task queue system
|
|
590
|
+
│ ├── schema.py # Configuration validator
|
|
591
|
+
│ ├── benchmark.py # Compression benchmarks
|
|
592
|
+
│ ├── chunked_backup.py# Block-level incremental backup
|
|
593
|
+
│ ├── dedup.py # File-level SHA256 deduplication
|
|
594
|
+
│ ├── export.py # Metadata export (CSV/JSON)
|
|
595
|
+
│ ├── monitor.py # watchdog filesystem monitor
|
|
596
|
+
│ ├── lock.py # Cross-platform process lock
|
|
597
|
+
│ ├── retry.py # Exponential backoff retry
|
|
598
|
+
│ ├── ratelimiter.py # Token bucket rate limiter
|
|
599
|
+
│ ├── keychain.py # System keychain integration
|
|
600
|
+
│ ├── parity.py # Reed-Solomon error correction
|
|
601
|
+
│ ├── completion.py # Shell auto-completion
|
|
602
|
+
│ ├── wizard.py # Interactive configuration wizard
|
|
603
|
+
│ └── locales/ # Translation files for 9 languages
|
|
604
|
+
└── tests/
|
|
605
|
+
└── sbackup/
|
|
606
|
+
└── test_*.py # 30 test files covering all modules
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
### Adding new features
|
|
610
|
+
|
|
611
|
+
1. Create a new module file under `sbackup/`
|
|
612
|
+
2. Import the new functions in `sbackup/__init__.py`
|
|
613
|
+
3. Add command-line command handling in the `run()` function
|
|
614
|
+
4. Add corresponding test files under `tests/`
|
|
615
|
+
|
|
616
|
+
## FAQ
|
|
617
|
+
|
|
618
|
+
### Q: What if the backup strategy file is accidentally deleted?
|
|
619
|
+
|
|
620
|
+
A: Backup strategies are stored in the data file. If accidentally deleted, you can re-add them by running the `add` command again.
|
|
621
|
+
|
|
622
|
+
### Q: How do I modify an existing backup strategy?
|
|
623
|
+
|
|
624
|
+
A: Use the `sbackup edit` command: `sbackup edit <source> --dest <new_dest> --ignore <patterns> --format <fmt>`.
|
|
625
|
+
|
|
626
|
+
### Q: Is remote backup supported?
|
|
627
|
+
|
|
628
|
+
A: Yes! Three remote backup methods are available:
|
|
629
|
+
- **SFTP**: configure with `sbackup sftp config`, upload with `sbackup save --sftp`
|
|
630
|
+
- **WebDAV**: configure with `sbackup webdav config`, upload with `sbackup save --webdav` (supports Jianguoyun, NextCloud, Synology)
|
|
631
|
+
- **S3 cloud storage**: configure the `cloud` field in `config.json`, upload with `sbackup save --cloud`
|
|
632
|
+
- Multiple can be combined: `sbackup save --sftp --webdav --cloud`
|
|
633
|
+
|
|
634
|
+
### Q: What is the difference between tar.gz and ZIP?
|
|
635
|
+
|
|
636
|
+
A: tar.gz is more common on Linux/macOS with slightly better compression; ZIP is more universal on Windows with the best compatibility. tar.bz2 and tar.xz offer higher compression but are slower. tar.zst is a modern algorithm that is extremely fast with good compression. 7z has the highest compression and supports encryption.
|
|
637
|
+
|
|
638
|
+
### Q: How do I encrypt a backup?
|
|
639
|
+
|
|
640
|
+
A: Use the 7z format with a password: `uv run python main.py --format 7z save --password yourpassword`. The password can also be set in the `password` field of `config.json`.
|
|
641
|
+
|
|
642
|
+
### Q: How do I automatically clean old backups?
|
|
643
|
+
|
|
644
|
+
A: Use the `--keep` parameter: `uv run python main.py save --keep 5` keeps only the 5 most recent backup files. This also works with scheduled backups: `uv run python main.py watch --interval 60 --keep 10`.
|
|
645
|
+
|
|
646
|
+
### Q: How do I set up scheduled backups?
|
|
647
|
+
|
|
648
|
+
A: Use the `watch` command: `uv run python main.py watch --interval 60` backs up every 60 minutes. Press `Ctrl+C` to stop.
|
|
649
|
+
|
|
650
|
+
### Q: Is password storage secure?
|
|
651
|
+
|
|
652
|
+
A: SFTP passwords and 7z encryption passwords in `config.json` are stored in **plain text**. Ensure that the `config.json` file is accessible only to trusted users (e.g. `chmod 600 config.json`). Do not commit `config.json` containing passwords to version control.
|
|
653
|
+
|
|
654
|
+
## Contributing
|
|
655
|
+
|
|
656
|
+
Issues and Pull Requests are welcome!
|
|
657
|
+
|
|
658
|
+
1. Fork the repository
|
|
659
|
+
2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
|
|
660
|
+
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
|
|
661
|
+
4. Push to the branch (`git push origin feature/AmazingFeature`)
|
|
662
|
+
5. Open a Pull Request
|
|
663
|
+
|
|
664
|
+
### Code style
|
|
665
|
+
|
|
666
|
+
This project follows PEP 8 and the Google Python Style Guide. Please ensure your code:
|
|
667
|
+
- Uses type annotations
|
|
668
|
+
- Follows Google-style docstrings
|
|
669
|
+
- Passes all unit tests
|
|
670
|
+
|
|
671
|
+
## License
|
|
672
|
+
|
|
673
|
+
This project is licensed under the GNU GPL v3.0 License. See the [LICENSE](LICENSE) file for details.
|
|
674
|
+
|
|
675
|
+
## Author
|
|
676
|
+
|
|
677
|
+
**xiatianxuan** (CodeSeed)
|
|
678
|
+
|
|
679
|
+
- [Gitee](https://gitee.com/xiatianxuan)
|
|
680
|
+
- [Homepage](https://xnors-codeseed.pages.dev/)
|
|
681
|
+
|
|
682
|
+
## Special Thanks
|
|
683
|
+
|
|
684
|
+
- [Xnors Studio](https://xnors.github.io/)
|
|
685
|
+
|
|
686
|
+
## Contact
|
|
687
|
+
|
|
688
|
+
For questions or suggestions, please email: xiatianxuan2025@163.com
|
|
689
|
+
|
|
690
|
+
---
|
|
691
|
+
|
|
692
|
+
*Last updated: June 19, 2026*
|