file-backuper 1.3.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.
Files changed (31) hide show
  1. file_backuper-1.3.0/.github/workflows/publish.yml +50 -0
  2. file_backuper-1.3.0/.gitignore +57 -0
  3. file_backuper-1.3.0/PKG-INFO +4 -0
  4. file_backuper-1.3.0/PLAN.md +35 -0
  5. file_backuper-1.3.0/README.md +397 -0
  6. file_backuper-1.3.0/backuper_app/__init__.py +0 -0
  7. file_backuper-1.3.0/backuper_app/backup/__init__.py +6 -0
  8. file_backuper-1.3.0/backuper_app/backup/analyzer.py +99 -0
  9. file_backuper-1.3.0/backuper_app/backup/archive.py +63 -0
  10. file_backuper-1.3.0/backuper_app/backup/backuper.py +181 -0
  11. file_backuper-1.3.0/backuper_app/backup/compression.py +38 -0
  12. file_backuper-1.3.0/backuper_app/backup/filter_engine.py +59 -0
  13. file_backuper-1.3.0/backuper_app/backup/initializer.py +95 -0
  14. file_backuper-1.3.0/backuper_app/backup/manifest.py +44 -0
  15. file_backuper-1.3.0/backuper_app/backup/restore.py +57 -0
  16. file_backuper-1.3.0/backuper_app/backup/retention.py +37 -0
  17. file_backuper-1.3.0/backuper_app/backup/verify.py +29 -0
  18. file_backuper-1.3.0/backuper_app/cli.py +270 -0
  19. file_backuper-1.3.0/backuper_app/config/__init__.py +1 -0
  20. file_backuper-1.3.0/backuper_app/config/config.py +80 -0
  21. file_backuper-1.3.0/backuper_app/dto.py +28 -0
  22. file_backuper-1.3.0/backuper_app/exception.py +14 -0
  23. file_backuper-1.3.0/backuper_app/main.py +62 -0
  24. file_backuper-1.3.0/backuper_app/utils/__init__.py +4 -0
  25. file_backuper-1.3.0/backuper_app/utils/archive_resolver.py +39 -0
  26. file_backuper-1.3.0/backuper_app/utils/capacity.py +41 -0
  27. file_backuper-1.3.0/backuper_app/utils/checksum.py +58 -0
  28. file_backuper-1.3.0/backuper_app/utils/logger.py +11 -0
  29. file_backuper-1.3.0/config.toml +25 -0
  30. file_backuper-1.3.0/pyproject.toml +15 -0
  31. file_backuper-1.3.0/uv.lock +8 -0
@@ -0,0 +1,50 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ jobs:
9
+ build:
10
+ runs-on: ubuntu-latest
11
+
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+
15
+ - uses: actions/setup-python@v6
16
+ with:
17
+ python-version: "3.x"
18
+
19
+ - name: Install build
20
+ run: python -m pip install build
21
+
22
+ - name: Build package
23
+ run: python -m build
24
+
25
+ - name: Upload artifacts
26
+ uses: actions/upload-artifact@v4
27
+ with:
28
+ name: python-package
29
+ path: dist/
30
+
31
+ publish:
32
+ needs: build
33
+ runs-on: ubuntu-latest
34
+
35
+ environment:
36
+ name: pypi
37
+ url: https://pypi.org/p/file-backuper
38
+
39
+ permissions:
40
+ id-token: write
41
+
42
+ steps:
43
+ - name: Download artifacts
44
+ uses: actions/download-artifact@v4
45
+ with:
46
+ name: python-package
47
+ path: dist/
48
+
49
+ - name: Publish to PyPI
50
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,57 @@
1
+ # --- Python ---
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ env/
8
+ venv/
9
+ .venv/
10
+ pip-log.txt
11
+ pip-delete-this-directory.txt
12
+ .tox/
13
+ .coverage
14
+ .coverage.*
15
+ .cache
16
+ nosetests.xml
17
+ coverage.xml
18
+ *.cover
19
+ *.log
20
+ .hypothesis/
21
+ .pytest_cache/
22
+ .mypy_cache/
23
+
24
+ # --- Editor / IDE ---
25
+ .vscode/
26
+ .idea/
27
+ *.swp
28
+ *.swo
29
+ *.swn
30
+ .DS_Store
31
+
32
+ # --- OS / Arch Linux / Environment ---
33
+ # File sistem atau file konfigurasi lokal
34
+ .directory
35
+ Desktop.ini
36
+ Thumbs.db
37
+ *.sublime-*
38
+ .env
39
+ .env.*
40
+
41
+ # --- Security & Recon Files (Opsional) ---
42
+ # Kalau kamu simpan hasil scan/recon, jangan sampai ikut ke-push!
43
+ *.dumpcap
44
+ *.pcap
45
+ *.txt
46
+ results/
47
+ scans/
48
+ wordlists/
49
+
50
+ # --- Project ---
51
+ # Tambahkan folder hasil build atau output spesifikmu di sini
52
+ dist/
53
+ build/
54
+ *.egg-info/
55
+ systemd/
56
+ test/
57
+ test_config.toml
@@ -0,0 +1,4 @@
1
+ Metadata-Version: 2.5
2
+ Name: file-backuper
3
+ Version: 1.3.0
4
+ Requires-Python: >=3.14
@@ -0,0 +1,35 @@
1
+ # Nama Project
2
+
3
+ ## Problem
4
+ Program backup yang otomatis ignore unnecessary file,
5
+ membutuhkan path target dan peth destination untuk menjalankan program,
6
+ otomatis men copy file kecuali ignore ke folder destination
7
+
8
+ ## Features
9
+ - 🔴 Input path target and dst
10
+ - 🔴 Copy file 1 per satu dan buat directory nya
11
+ - 🔴 Check eksistensi directory dan cek jika bukan file
12
+ - 🟡 copy file menggunakan loop dan melakukan filtering untuk ignore list
13
+ - 🟢 default nama backup = _backup
14
+ - 🟢
15
+
16
+ ## Struktur
17
+ - File_Backuper
18
+ - .venv
19
+ - app
20
+ - main.py
21
+ - ignore
22
+ - PLAN.md
23
+ - .gitignore
24
+
25
+ ## Alur
26
+ - User memasukan input manual untuk target dan destination path
27
+ - Program mengecek eksistensi target
28
+ - Program mengecek eksistensi destination, jika dst ada tapi file akan error, jika tidak ada maka akan dibuat otomatis
29
+ - memetakan isi di dalam target
30
+ - melakukan looping untuk setiap item, jika ignore maka skip, jika directory, masuk ke dalamnya
31
+
32
+ ## Pseudocode
33
+
34
+
35
+ ## Catatan / Ideas
@@ -0,0 +1,397 @@
1
+ # File Backuper
2
+
3
+ [![Release](https://img.shields.io/badge/release-v1.2.0-blue)](https://github.com/Finsa-SC/backup-service/releases/tag/v1.2.0)
4
+ [![Python](https://img.shields.io/badge/python-3.14%2B-blue)](https://www.python.org/)
5
+ [![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)
6
+
7
+ A powerful, modular CLI backup utility for creating, restoring, and verifying file backups with advanced features like compression, retention policies, and data integrity verification.
8
+
9
+ > **Latest Release:** v1.2.0 — Now supports setting default file config during initialization!
10
+
11
+ ## Features
12
+
13
+ - **Flexible Backup Creation** - Backup files and directories with include/exclude filtering
14
+ - **Multiple Compression Methods** - Support for gzip and zstd compression algorithms
15
+ - **Retention Policies** - Automatically manage backup rotation and keep only the last N backups
16
+ - **Data Integrity** - Built-in checksum verification for backup validation
17
+ - **Restore Capabilities** - Extract backups by file path or date with integrity checking
18
+ - **Symbolic Link Handling** - Choose how to handle symlinks (ignore, follow, or preserve)
19
+ - **Archive Support** - Automatically archive expired backups to a separate location
20
+ - **Dry-Run Mode** - Preview backup operations before execution
21
+ - **Configuration-Based** - TOML-based configuration for easy management
22
+ - **Detailed Logging** - Comprehensive logging for monitoring and troubleshooting
23
+
24
+ ## What's New in v1.2.0
25
+
26
+ - ✨ **Default File Config in Init** - Set default configuration file during initialization
27
+ - 🔧 Improved configuration workflow
28
+ - 📋 [Full Changelog](https://github.com/Finsa-SC/backup-service/releases/tag/v1.2.0)
29
+
30
+ ## Installation
31
+
32
+ ### Requirements
33
+ - Python >= 3.14
34
+ - pip or uv
35
+
36
+ ### From GitHub Releases
37
+
38
+ Download and install the latest release:
39
+
40
+ ```bash
41
+ # Extract the release
42
+ unzip file-backuper-1.2.0.tar.gz
43
+ cd backup-service
44
+
45
+ # Install
46
+ pip install .
47
+ ```
48
+
49
+ ### From Source
50
+
51
+ ```bash
52
+ git clone https://github.com/Finsa-SC/backup-service.git
53
+ cd backup-service
54
+ pip install -e .
55
+ ```
56
+
57
+ ### Using uv (recommended)
58
+ ```bash
59
+ uv pip install -e .
60
+ ```
61
+
62
+ This creates the `backuper` command available in your PATH.
63
+
64
+ ## Quick Start
65
+
66
+ ### 1. Initialize Configuration
67
+
68
+ ```bash
69
+ backuper init --target /path/to/backup --destination /path/to/backups
70
+ ```
71
+
72
+ Or with all options:
73
+ ```bash
74
+ backuper init /etc/backuper/config.toml \
75
+ --target /home/user/documents \
76
+ --destination /mnt/backups \
77
+ --retention 5 \
78
+ --compression zstd \
79
+ --link-mode preserve
80
+ ```
81
+
82
+ ### 2. Create a Backup
83
+
84
+ ```bash
85
+ backuper backup --config /etc/backuper/config.toml
86
+ ```
87
+
88
+ Preview before executing:
89
+ ```bash
90
+ backuper backup --config /etc/backuper/config.toml --dry-run
91
+ ```
92
+
93
+ ### 3. Restore from Backup
94
+
95
+ Restore a specific file:
96
+ ```bash
97
+ backuper restore --file /path/to/backup/file.tar.gz --destination /tmp/restore
98
+ ```
99
+
100
+ Restore a backup by date:
101
+ ```bash
102
+ backuper restore --date "2024-01-15" --archive-path /mnt/backups --destination /tmp/restore
103
+ ```
104
+
105
+ ### 4. Verify Backup Integrity
106
+
107
+ Verify a specific backup file:
108
+ ```bash
109
+ backuper verify --file /path/to/backup/file.tar.gz
110
+ ```
111
+
112
+ Verify a backup by date:
113
+ ```bash
114
+ backuper verify --date "2024-01-15" --archive-path /mnt/backups
115
+ ```
116
+
117
+ ## Configuration
118
+
119
+ Configuration is managed through a TOML file (default: `config.toml`).
120
+
121
+ ### Example Configuration
122
+
123
+ ```toml
124
+ [backup]
125
+ backup_name = "my_backup"
126
+ target = "/home/user/documents"
127
+ destination = "/mnt/backups"
128
+ compression = "zstd" # or "gzip"
129
+ keep_last = 5
130
+ link_mode = "preserve" # options: ignore, follow, preserve
131
+ archive_enable = true
132
+ archive_path = "/mnt/backups/archive"
133
+
134
+ [filter]
135
+ include = ["*.txt", "*.pdf"]
136
+ exclude = ["*.tmp", "*.cache"]
137
+ ```
138
+
139
+ ### Configuration Options
140
+
141
+ | Option | Type | Description |
142
+ |--------|------|-------------|
143
+ | `backup_name` | string | Name identifier for this backup job |
144
+ | `target` | path | Source directory/file to backup |
145
+ | `destination` | path | Directory where backups are stored |
146
+ | `compression` | string | Compression method: `gzip` or `zstd` |
147
+ | `keep_last` | integer | Number of backups to retain (0 = keep all) |
148
+ | `link_mode` | string | Symlink handling: `ignore`, `follow`, or `preserve` |
149
+ | `archive_enable` | boolean | Archive expired backups instead of deleting |
150
+ | `archive_path` | path | Directory for archived backups (if enabled) |
151
+ | `include` | array | File patterns to include (optional) |
152
+ | `exclude` | array | File patterns to exclude (optional) |
153
+
154
+ ## Command Reference
155
+
156
+ ### backup
157
+ Create a new backup with retention and archival support.
158
+
159
+ ```bash
160
+ backuper backup --config CONFIG_PATH [--dry-run]
161
+ ```
162
+
163
+ **Options:**
164
+ - `--config CONFIG_PATH` (required): Path to configuration file
165
+ - `--dry-run`: Preview without actually creating backup
166
+
167
+ ### restore
168
+ Extract backup data by file path or date with integrity verification.
169
+
170
+ ```bash
171
+ backuper restore [--file FILE_PATH | --date DATE] --destination DEST_PATH [--archive-path ARCHIVE_PATH]
172
+ ```
173
+
174
+ **Options:**
175
+ - `--file FILE_PATH`: Path to specific backup file to restore
176
+ - `--date DATE`: Date of backup to restore (requires `--archive-path`)
177
+ - `--destination DEST_PATH`: Where to extract files (default: `/tmp/backup_restore`)
178
+ - `--archive-path ARCHIVE_PATH`: Path to archive directory (required when using `--date`)
179
+
180
+ ### verify
181
+ Verify backup integrity using stored checksums.
182
+
183
+ ```bash
184
+ backuper verify [--file FILE_PATH | --date DATE] [--archive-path ARCHIVE_PATH]
185
+ ```
186
+
187
+ **Options:**
188
+ - `--file FILE_PATH`: Path to backup file to verify
189
+ - `--date DATE`: Date of backup to verify (requires `--archive-path`)
190
+ - `--archive-path ARCHIVE_PATH`: Path to archive directory
191
+
192
+ ### init
193
+ Create an initial configuration file from template.
194
+
195
+ ```bash
196
+ backuper init [CONFIG_PATH] [--target TARGET] [--destination DEST] [--retention N] [--compression METHOD] [--link-mode MODE]
197
+ ```
198
+
199
+ **Options:**
200
+ - `CONFIG_PATH`: Configuration file path (default: `/etc/backuper/config.toml`)
201
+ - `--target`: Source directory to backup
202
+ - `--destination`: Backup destination directory
203
+ - `--retention`: Number of backups to keep
204
+ - `--compression`: Compression method (`gzip` or `zstd`)
205
+ - `--link-mode`: Symlink handling mode
206
+
207
+ ## Architecture
208
+
209
+ ```
210
+ backuper_app/
211
+ ├── backup/ # Core backup functionality
212
+ │ ├── backuper.py # Main backup engine
213
+ │ ├── compression.py # Compression handling
214
+ │ ├── retention.py # Backup rotation & cleanup
215
+ │ ├── archive.py # Archive management
216
+ │ ├── restore.py # Restore operations
217
+ │ ├── verify.py # Integrity verification
218
+ │ ├── analyzer.py # File analysis & filtering
219
+ │ ├── filter_engine.py # Include/exclude filtering
220
+ │ ├── manifest.py # Backup metadata
221
+ │ └── initializer.py # Config initialization
222
+ ├── config/ # Configuration handling
223
+ │ └── config.py # Config parsing & validation
224
+ ├── utils/ # Utility functions
225
+ │ ├── checksum.py # Hash & verification
226
+ │ ├── logger.py # Logging setup
227
+ │ ├── capacity.py # Size calculations
228
+ │ └── archive_resolver.py # Archive path resolution
229
+ └── main.py # CLI entry point
230
+ ```
231
+
232
+ ## Workflow
233
+
234
+ ### Backup Workflow
235
+ 1. Load configuration from TOML file
236
+ 2. Analyze source directory with filtering
237
+ 3. Create compressed archive (gzip or zstd)
238
+ 4. Generate checksum for integrity verification
239
+ 5. Check retention policy
240
+ 6. Archive or delete old backups based on retention settings
241
+
242
+ ### Restore Workflow
243
+ 1. Validate backup file checksum
244
+ 2. Extract archive to destination
245
+ 3. Restore file permissions and metadata
246
+
247
+ ### Verification Workflow
248
+ 1. Calculate checksum of backup file
249
+ 2. Compare with stored checksum
250
+ 3. Report integrity status
251
+
252
+ ## Examples
253
+
254
+ ### Backup with retention
255
+
256
+ ```bash
257
+ # Create initial config
258
+ backuper init my_backup.toml \
259
+ --target /home/user/documents \
260
+ --destination /mnt/backups \
261
+ --retention 7 \
262
+ --compression zstd
263
+
264
+ # Create backup (keeps last 7 backups)
265
+ backuper backup --config my_backup.toml
266
+ ```
267
+
268
+ ### Backup with filtering
269
+
270
+ ```toml
271
+ [backup]
272
+ backup_name = "selective_backup"
273
+ target = "/home/user"
274
+ destination = "/mnt/backups"
275
+ compression = "zstd"
276
+
277
+ [filter]
278
+ include = ["*.txt", "*.pdf", "Documents/**"]
279
+ exclude = ["*.tmp", ".git/**", "node_modules/**"]
280
+ ```
281
+
282
+ ### Scheduled backups with systemd
283
+
284
+ ```ini
285
+ # /etc/systemd/system/backuper.service
286
+ [Unit]
287
+ Description=File Backuper Service
288
+ After=network.target
289
+
290
+ [Service]
291
+ Type=oneshot
292
+ ExecStart=/usr/local/bin/backuper backup --config /etc/backuper/config.toml
293
+ User=backup
294
+ StandardOutput=journal
295
+
296
+ # /etc/systemd/system/backuper.timer
297
+ [Unit]
298
+ Description=Daily Backup Timer
299
+ Requires=backuper.service
300
+
301
+ [Timer]
302
+ OnCalendar=daily
303
+ OnCalendar=00:02
304
+ Persistent=true
305
+
306
+ [Install]
307
+ WantedBy=timers.target
308
+ ```
309
+
310
+ ## Error Handling
311
+
312
+ The tool provides clear error messages for common issues:
313
+
314
+ - **Invalid config**: Check TOML syntax and required fields
315
+ - **Permission denied**: Verify read/write permissions on source and destination
316
+ - **Checksum mismatch**: Backup may be corrupted, re-create backup
317
+ - **Insufficient space**: Ensure destination has enough free space
318
+
319
+ ## Performance Notes
320
+
321
+ - **Compression**: zstd typically offers better compression ratios than gzip
322
+ - **Retention**: Archiving is preferred over deletion for safety
323
+ - **Symbolic links**: Use `preserve` mode to maintain symlink structure
324
+ - **Large files**: Dry-run mode helps preview operations before execution
325
+
326
+ ## Development
327
+
328
+ ### Project Structure
329
+ - Modular design with clear separation of concerns
330
+ - Type hints for better IDE support
331
+ - Comprehensive logging throughout
332
+ - Exception handling with custom `BackuperError`
333
+
334
+ ### Running Tests
335
+ ```bash
336
+ python -m pytest test/
337
+ ```
338
+
339
+ ## License
340
+
341
+ [Add your license here]
342
+
343
+ ## Contributing
344
+
345
+ Contributions are welcome! Please ensure:
346
+ - Code follows the existing style
347
+ - New features include tests
348
+ - Documentation is updated
349
+ - Commit messages are descriptive
350
+
351
+ ## Support & Resources
352
+
353
+ - 📖 [Documentation](https://github.com/Finsa-SC/backup-service)
354
+ - 🐛 [Issue Tracker](https://github.com/Finsa-SC/backup-service/issues)
355
+ - 📝 [Releases](https://github.com/Finsa-SC/backup-service/releases)
356
+ - 💬 For questions, open an issue on GitHub
357
+
358
+ ## Troubleshooting
359
+
360
+ **Backup stuck or slow?**
361
+ - Use `--dry-run` to check what's being processed
362
+ - Check exclude patterns if too many files
363
+ - Monitor disk I/O with `iostat`
364
+
365
+ **Restore fails?**
366
+ - Verify backup file exists and is accessible
367
+ - Check checksum: `backuper verify --file <backup>`
368
+ - Ensure destination has write permissions
369
+
370
+ **Config errors?**
371
+ - Validate TOML syntax at https://www.toml-lint.com/
372
+ - Ensure all paths are absolute and exist
373
+ - Check file permissions for config file
374
+
375
+ ## Release History
376
+
377
+ ### v1.2.0 (Current)
378
+ **Released:** Recently
379
+ - ✨ Feature to set default file config in init
380
+ - 🔧 Enhanced configuration initialization workflow
381
+ - 📚 Improved documentation
382
+
383
+ [View Release](https://github.com/Finsa-SC/backup-service/releases/tag/v1.2.0)
384
+
385
+ ### v1.0.1
386
+ - Previous stable release
387
+
388
+ ### v1.0.0
389
+ - Initial release
390
+
391
+ ---
392
+
393
+ ## Version Info
394
+
395
+ **Current version:** 1.2.0
396
+ **Python requirement:** >= 3.14
397
+ **Latest release:** [v1.2.0](https://github.com/Finsa-SC/backup-service/releases/tag/v1.2.0)
File without changes
@@ -0,0 +1,6 @@
1
+ from .retention import Retention
2
+ from .backuper import Backuper
3
+ from .archive import Archive
4
+ from .verify import Verify
5
+ from .restore import Restore
6
+ from .initializer import Initializer
@@ -0,0 +1,99 @@
1
+ from pathlib import Path
2
+ from backuper_app.utils import get_logger, format_size
3
+
4
+ logger = get_logger(__name__)
5
+
6
+ class Analyzer:
7
+ def __init__(
8
+ self,
9
+ target_path: Path,
10
+ destination: Path,
11
+ files: list[Path],
12
+ backup_total: int,
13
+ compression_type: str,
14
+ link_mode: str,
15
+ archive_enabled: bool,
16
+ archive_path: Path|None,
17
+ include: list[str],
18
+ exclude: list[str],
19
+ retention: int | None,
20
+ ):
21
+ self.target = target_path
22
+ self.destination = destination
23
+ self.files = files
24
+ self.backup_total = backup_total
25
+ self.compression = compression_type
26
+ self.link_mode = link_mode
27
+ self.archive_enabled = archive_enabled
28
+ self.archive_path = archive_path
29
+ self.include = include
30
+ self.exclude = exclude
31
+ self.retention = retention
32
+
33
+ def get_file_statistic(self) -> dict[str, int]:
34
+ mapping = dict(file=0, directory=0, symlink=0, socket=0, unknown=0)
35
+ for file in self.files:
36
+ if file.is_file():
37
+ mapping['file'] += 1
38
+ elif file.is_dir():
39
+ mapping['directory'] += 1
40
+ elif file.is_symlink():
41
+ mapping['symlink'] += 1
42
+ elif file.is_socket():
43
+ mapping['socket'] += 1
44
+ else:
45
+ mapping['unknown'] += 1
46
+
47
+ return mapping
48
+
49
+ def show_statistic(self, file_statistic: dict[str, int]) -> None:
50
+ from backuper_app.utils import analyze_estimate_size, format_size
51
+
52
+ logger.info("Starting dry run...")
53
+
54
+ #Backup info
55
+ logger.info(f"""
56
+ Backup
57
+ Target : {self.target if self.target.exists() else '-'}
58
+ Destination : {self.destination if self.destination.exists() else '-'}
59
+ Compression : {self.compression}
60
+ Link mode : {self.link_mode}
61
+ """)
62
+
63
+ #Filter
64
+ logger.info(f"""
65
+ Filter
66
+ Include : {self.include}
67
+ exclude : {self.exclude}
68
+ """)
69
+
70
+ #File statistic
71
+ matched_file = ["\n\tStatistics"]
72
+ for type_file, value in file_statistic.items():
73
+ matched_file.append(f"\t{type_file:<12}: {value}")
74
+ matched_file.append(f"\t{'Filtered':<12}: {self.backup_total}")
75
+
76
+ estimated_size = analyze_estimate_size(self.files)
77
+ matched_file.append(f"\tEstimate size: {format_size(estimated_size)}")
78
+
79
+ logger.info("\n".join(matched_file))
80
+
81
+ #Action
82
+ logger.info(f"""
83
+ Action
84
+ Manifest : Yes
85
+ Checksum : Yes
86
+ Archive : {self.archive_enabled}
87
+ Archive Path: {self.archive_path if self.archive_enabled and self.archive_path.is_dir() else "-"}
88
+ Keep last : {self.retention if self.retention else '-'}
89
+ """)
90
+
91
+ logger.info("""
92
+ Result
93
+ Dry run completed successfully
94
+ No filesystem changes were made
95
+ """)
96
+
97
+ def analyze_statistic(self):
98
+ mapping = self.get_file_statistic()
99
+ self.show_statistic(mapping)