dar-backup 0.6.5__py3-none-any.whl → 0.6.7__py3-none-any.whl

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.
dar_backup/__about__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.6.5"
1
+ __version__ = "0.6.7"
dar_backup/cleanup.py CHANGED
@@ -22,17 +22,22 @@ import sys
22
22
 
23
23
  from datetime import datetime, timedelta
24
24
  from time import time
25
+ from typing import Dict, List, NamedTuple
25
26
 
26
27
  from . import __about__ as about
27
28
  from dar_backup.config_settings import ConfigSettings
28
29
  from dar_backup.util import extract_error_lines
29
30
  from dar_backup.util import list_backups
31
+ from dar_backup.util import run_command
30
32
  from dar_backup.util import setup_logging
31
33
 
34
+ from dar_backup.util import CommandResult
35
+
36
+
32
37
 
33
38
  logger = None
34
39
 
35
- def delete_old_backups(backup_dir, age, backup_type, backup_definition=None):
40
+ def delete_old_backups(backup_dir, age, backup_type, args, backup_definition=None):
36
41
  """
37
42
  Delete backups older than the specified age in days.
38
43
  Only .dar and .par2 files are considered for deletion.
@@ -46,6 +51,8 @@ def delete_old_backups(backup_dir, age, backup_type, backup_definition=None):
46
51
  now = datetime.now()
47
52
  cutoff_date = now - timedelta(days=age)
48
53
 
54
+ archives_deleted = {}
55
+
49
56
  for filename in sorted(os.listdir(backup_dir)):
50
57
  if not (filename.endswith('.dar') or filename.endswith('.par2')):
51
58
  continue
@@ -64,11 +71,18 @@ def delete_old_backups(backup_dir, age, backup_type, backup_definition=None):
64
71
  try:
65
72
  os.remove(file_path)
66
73
  logger.info(f"Deleted {backup_type} backup: {file_path}")
74
+ archive_name = filename.split('.')[0]
75
+ if not archive_name in archives_deleted:
76
+ logger.debug(f"Archive name: '{archive_name}' added to catalog deletion list")
77
+ archives_deleted[archive_name] = True
67
78
  except Exception as e:
68
79
  logger.error(f"Error deleting file {file_path}: {e}")
69
80
 
81
+ for archive_name in archives_deleted.keys():
82
+ delete_catalog(archive_name, args)
83
+
70
84
 
71
- def delete_archive(backup_dir, archive_name):
85
+ def delete_archive(backup_dir, archive_name, args):
72
86
  """
73
87
  Delete all .dar and .par2 files in the backup directory for the given archive name.
74
88
 
@@ -90,7 +104,9 @@ def delete_archive(backup_dir, archive_name):
90
104
  except Exception as e:
91
105
  logger.error(f"Error deleting archive slice {file_path}: {e}")
92
106
 
93
- if not files_deleted:
107
+ if files_deleted:
108
+ delete_catalog(archive_name, args)
109
+ else:
94
110
  logger.info("No .dar files matched the regex for deletion.")
95
111
 
96
112
  # Delete associated .par2 files
@@ -110,6 +126,29 @@ def delete_archive(backup_dir, archive_name):
110
126
  logger.info("No .par2 matched the regex for deletion.")
111
127
 
112
128
 
129
+ def delete_catalog(catalog_name: str, args: NamedTuple) -> bool:
130
+ """
131
+ Call `manager.py` to delete the specified catalog in it's database
132
+ """
133
+ command = [f"manager", "--remove-specific-archive", catalog_name, "--config-file", args.config_file, '--log-level', 'debug', '--log-stdout']
134
+ logger.info(f"Deleting catalog '{catalog_name}' using config file: '{args.config_file}'")
135
+ try:
136
+ result:CommandResult = run_command(command)
137
+ if result.returncode == 0:
138
+ logger.info(f"Deleted catalog '{catalog_name}', using config file: '{args.config_file}'")
139
+ logger.debug(f"Stdout: manager.py --remove-specific-archive output:\n{result.stdout}")
140
+ return True
141
+ elif result.returncode == 2:
142
+ logger.warning(f"catalog '{catalog_name}' not found in the database, skipping deletion")
143
+ return True
144
+ else:
145
+ logger.error(f"Error deleting catalog {catalog_name}: {result.stderr}")
146
+ return False
147
+ except Exception as e:
148
+ logger.error(f"Error deleting catalog {catalog_name}: {e}")
149
+ return False
150
+
151
+
113
152
  def show_version():
114
153
  script_name = os.path.basename(sys.argv[0])
115
154
  print(f"{script_name} {about.__version__}")
@@ -118,8 +157,6 @@ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW,
118
157
  See section 15 and section 16 in the supplied "LICENSE" file.''')
119
158
 
120
159
  def main():
121
-
122
-
123
160
  global logger
124
161
 
125
162
  parser = argparse.ArgumentParser(description="Cleanup old archives according to AGE configuration.")
@@ -127,9 +164,11 @@ def main():
127
164
  parser.add_argument('-c', '--config-file', '-c', type=str, help="Path to 'dar-backup.conf'", default='~/.config/dar-backup/dar-backup.conf')
128
165
  parser.add_argument('-v', '--version', action='store_true', help="Show version information.")
129
166
  parser.add_argument('--alternate-archive-dir', type=str, help="Cleanup in this directory instead of the default one.")
130
- parser.add_argument('--cleanup-specific-archive', type=str, help="List of archives to cleanup")
167
+ parser.add_argument('--cleanup-specific-archives', type=str, help="Commas separated list of archives to cleanup")
131
168
  parser.add_argument('-l', '--list', action='store_true', help="List available archives.")
132
169
  parser.add_argument('--verbose', action='store_true', help="Print various status messages to screen")
170
+ parser.add_argument('--log-level', type=str, help="`debug` or `trace`, default is `info`", default="info")
171
+ parser.add_argument('--log-stdout', action='store_true', help='also print log messages to stdout')
133
172
  args = parser.parse_args()
134
173
 
135
174
  args.config_file = os.path.expanduser(args.config_file)
@@ -142,7 +181,8 @@ def main():
142
181
  config_settings = ConfigSettings(args.config_file)
143
182
 
144
183
  start_time=int(time())
145
- logger = setup_logging(config_settings.logfile_location, logging.INFO)
184
+ logger = setup_logging(config_settings.logfile_location, args.log_level, args.log_stdout)
185
+
146
186
  logger.info(f"=====================================")
147
187
  logger.info(f"cleanup.py started, version: {about.__version__}")
148
188
 
@@ -156,7 +196,7 @@ def main():
156
196
  args.verbose and (print(f"Backup dir: {config_settings.backup_dir}"))
157
197
  args.verbose and (print(f"Logfile location: {config_settings.logfile_location}"))
158
198
  args.verbose and (print(f"--alternate-archive-dir: {args.alternate_archive_dir}"))
159
- args.verbose and (print(f"--cleanup-specific-archive: {args.cleanup_specific_archive}"))
199
+ args.verbose and (print(f"--cleanup-specific-archives:{args.cleanup_specific_archives}"))
160
200
 
161
201
  # run PREREQ scripts
162
202
  if 'PREREQ' in config_settings.config:
@@ -175,15 +215,21 @@ def main():
175
215
 
176
216
 
177
217
  if args.alternate_archive_dir:
218
+ if not os.path.exists(args.alternate_archive_dir):
219
+ logger.error(f"Alternate archive directory does not exist: {args.alternate_archive_dir}, exiting")
220
+ sys.exit(1)
221
+ if not os.path.isdir(args.alternate_archive_dir):
222
+ logger.error(f"Alternate archive directory is not a directory, exiting")
223
+ sys.exit(1)
178
224
  config_settings.backup_dir = args.alternate_archive_dir
179
225
 
180
226
 
181
- if args.cleanup_specific_archive:
182
- print(f"Cleaning up specific archives: {args.cleanup_specific_archive}")
183
- archive_names = args.cleanup_specific_archive.split(',')
227
+ if args.cleanup_specific_archives:
228
+ logger.info(f"Cleaning up specific archives: {args.cleanup_specific_archives}")
229
+ archive_names = args.cleanup_specific_archives.split(',')
184
230
  for archive_name in archive_names:
185
- print(f"Deleting archive: {archive_name}")
186
- delete_archive(config_settings.backup_dir, archive_name.strip())
231
+ logger.info(f"Deleting archive: {archive_name}")
232
+ delete_archive(config_settings.backup_dir, archive_name.strip(), args)
187
233
  elif args.list:
188
234
  list_backups(config_settings.backup_dir, args.backup_definition)
189
235
  else:
@@ -196,22 +242,22 @@ def main():
196
242
  backup_definitions.append(file.split('.')[0])
197
243
 
198
244
  for definition in backup_definitions:
199
- delete_old_backups(config_settings.backup_dir, config_settings.diff_age, 'DIFF', definition)
200
- delete_old_backups(config_settings.backup_dir, config_settings.incr_age, 'INCR', definition)
245
+ delete_old_backups(config_settings.backup_dir, config_settings.diff_age, 'DIFF', args, definition)
246
+ delete_old_backups(config_settings.backup_dir, config_settings.incr_age, 'INCR', args, definition)
201
247
 
202
248
 
203
249
  end_time=int(time())
204
250
  logger.info(f"END TIME: {end_time}")
205
251
 
206
- error_lines = extract_error_lines(config_settings.logfile_location, start_time, end_time)
207
- if len(error_lines) > 0:
208
- args.verbose and print("\033[1m\033[31mErrors\033[0m encountered")
209
- for line in error_lines:
210
- args.verbose and print(line)
211
- sys.exit(1)
212
- else:
213
- args.verbose and print("\033[1m\033[32mSUCCESS\033[0m No errors encountered")
214
- sys.exit(0)
252
+ # error_lines = extract_error_lines(config_settings.logfile_location, start_time, end_time)
253
+ # if len(error_lines) > 0:
254
+ # args.verbose and print("\033[1m\033[31mErrors\033[0m encountered")
255
+ # for line in error_lines:
256
+ # args.verbose and print(line)
257
+ # sys.exit(1)
258
+ # else:
259
+ # args.verbose and print("\033[1m\033[32mSUCCESS\033[0m No errors encountered")
260
+ # sys.exit(0)
215
261
 
216
262
  if __name__ == "__main__":
217
263
  main()
dar_backup/dar_backup.py CHANGED
@@ -30,7 +30,7 @@ from dar_backup.util import RestoreError
30
30
 
31
31
  logger = None
32
32
 
33
- def generic_backup(type: str, command: List[str], backup_file: str, backup_definition: str, darrc: str, config_settings: ConfigSettings):
33
+ def generic_backup(type: str, command: List[str], backup_file: str, backup_definition: str, darrc: str, config_settings: ConfigSettings, args: argparse.Namespace):
34
34
  """
35
35
  Performs a backup using the 'dar' command.
36
36
 
@@ -64,6 +64,15 @@ def generic_backup(type: str, command: List[str], backup_file: str, backup_defin
64
64
  logger.warning("Backup completed with some files not backed up, this can happen if files are changed/deleted during the backup.")
65
65
  else:
66
66
  raise Exception(str(process))
67
+
68
+ if process.returncode == 0 or process.returncode == 5:
69
+ add_catalog_command = ['manager', '--add-specific-archive' ,backup_file, '--config-file', args.config_file, '--log-level', "debug", "--log-stdout"]
70
+ command_result = run_command(add_catalog_command, config_settings.command_timeout_secs)
71
+ if command_result.returncode == 0:
72
+ logger.info(f"Catalog for archive '{backup_file}' added successfully to its manager.")
73
+ else:
74
+ logger.error(f"Catalog for archive '{backup_file}' not added.")
75
+
67
76
  except subprocess.CalledProcessError as e:
68
77
  logger.error(f"Backup command failed: {e}")
69
78
  raise BackupError(f"Backup command failed: {e}") from e
@@ -409,19 +418,22 @@ def perform_backup(args: argparse.Namespace, config_settings: ConfigSettings, ba
409
418
  command = create_backup_command(backup_type, backup_file, args.darrc, backup_definition_path, latest_base_backup)
410
419
 
411
420
  # Perform backup
412
- generic_backup(backup_type, command, backup_file, backup_definition_path, args.darrc, config_settings)
421
+ generic_backup(backup_type, command, backup_file, backup_definition_path, args.darrc, config_settings, args)
413
422
 
414
423
  logger.info("Starting verification...")
415
- result = verify(args, backup_file, backup_definition_path, config_settings)
416
- if result:
424
+ verify_result = verify(args, backup_file, backup_definition_path, config_settings)
425
+ if verify_result:
417
426
  logger.info("Verification completed successfully.")
418
427
  else:
419
428
  logger.error("Verification failed.")
420
429
 
421
- if config_settings.par2_enabled:
430
+
431
+ if verify_result and config_settings.par2_enabled:
422
432
  logger.info("Generate par2 redundancy files.")
423
433
  generate_par2_files(backup_file, config_settings, args)
424
434
  logger.info("par2 files completed successfully.")
435
+
436
+
425
437
  except Exception as e:
426
438
  logger.exception(f"Error during {backup_type} backup process, continuing to next backup definition.")
427
439
 
@@ -461,16 +473,14 @@ def generate_par2_files(backup_file: str, config_settings: ConfigSettings, args)
461
473
  for slice_file in dar_slices:
462
474
  file_path = os.path.join(config_settings.backup_dir, slice_file)
463
475
 
464
- if args.verbose or args.log_level == "debug" or args.log_level == "trace":
465
- logger.info(f"{counter}/{number_of_slices}: Now generating par2 files for {file_path}")
476
+ logger.info(f"{counter}/{number_of_slices}: Now generating par2 files for {file_path}")
466
477
 
467
478
  # Run the par2 command to generate redundancy files with error correction
468
479
  command = ['par2', 'create', f'-r{config_settings.error_correction_percent}', '-q', '-q', file_path]
469
480
  process = run_command(command, config_settings.command_timeout_secs)
470
481
 
471
482
  if process.returncode == 0:
472
- if args.verbose or args.log_level == "debug" or args.log_level == "trace":
473
- logger.info(f"{counter}/{number_of_slices}: Done")
483
+ logger.info(f"{counter}/{number_of_slices}: Done")
474
484
  else:
475
485
  logger.error(f"Error generating par2 files for {file_path}")
476
486
  raise subprocess.CalledProcessError(process.returncode, command)
dar_backup/manager.py CHANGED
@@ -31,6 +31,8 @@ from . import __about__ as about
31
31
  from dar_backup.config_settings import ConfigSettings
32
32
  from dar_backup.util import run_command
33
33
  from dar_backup.util import setup_logging
34
+ from dar_backup.util import CommandResult
35
+
34
36
  from datetime import datetime
35
37
  from time import time
36
38
  from typing import Dict, List, NamedTuple
@@ -60,6 +62,7 @@ def create_db(backup_def: str, config_settings: ConfigSettings):
60
62
 
61
63
  if os.path.exists(database_path):
62
64
  logger.warning(f'"{database_path}" already exists, skipping creation')
65
+ return 0
63
66
  else:
64
67
  logger.info(f'Create catalog database: "{database_path}"')
65
68
  command = ['dar_manager', '--create' , database_path]
@@ -90,8 +93,16 @@ def list_catalogs(backup_def: str, config_settings: ConfigSettings) -> NamedTupl
90
93
  database = f"{backup_def}{DB_SUFFIX}"
91
94
  database_path = os.path.join(config_settings.backup_dir, database)
92
95
  if not os.path.exists(database_path):
93
- logger.error(f'Database not found: "{database_path}"')
94
- return 1
96
+ error_msg = f'Database not found: "{database_path}"'
97
+ logger.error(error_msg)
98
+ commandResult = CommandResult(
99
+ process=None,
100
+ stdout='',
101
+ stderr=error_msg,
102
+ returncode=1,
103
+ timeout=1,
104
+ command=[])
105
+ return commandResult
95
106
  command = ['dar_manager', '--base', database_path, '--list']
96
107
  process = run_command(command)
97
108
  stdout, stderr = process.stdout, process.stderr
@@ -277,32 +288,44 @@ def backup_def_from_archive(archive: str) -> str:
277
288
  """
278
289
  return the backup definition from archive name
279
290
  """
291
+ logger.debug(f"Get backup definition from archive: '{archive}'")
280
292
  search = re.search("(.*?)_", archive)
281
- backup_def = search.group(1)
282
- logger.debug(f"backup definition: '{backup_def}' from given archive '{archive}'")
283
- return backup_def
293
+ if search:
294
+ backup_def = search.group(1)
295
+ logger.debug(f"backup definition: '{backup_def}' from given archive '{archive}'")
296
+ return backup_def
297
+ logger.error(f"Could not find backup definition from archive name: '{archive}'")
298
+ return None
284
299
 
285
300
 
286
301
 
287
302
  def remove_specific_archive(archive: str, config_settings: ConfigSettings) -> int:
303
+ """
304
+
305
+ Returns:
306
+ - 0 if the archive was removed from it's catalog
307
+ - 1 if there was an error removing the archive
308
+ - 2 if the archive was not found in the catalog
309
+
310
+ """
288
311
  backup_def = backup_def_from_archive(archive)
289
312
  database_path = os.path.join(config_settings.backup_dir, f"{backup_def}{DB_SUFFIX}")
290
313
  cat_no = cat_no_for_name(archive, config_settings)
291
314
  if cat_no >= 0:
292
315
  command = ['dar_manager', '--base', database_path, "--delete", str(cat_no)]
293
- process = run_command(command)
316
+ process: CommandResult = run_command(command)
317
+ logger.info(f"CommandResult: {process}")
294
318
  else:
295
- logger.error(f"archive: '{archive}' not found in in't catalog database: {database_path}")
296
- return cat_no
319
+ logger.warning(f"archive: '{archive}' not found in it's catalog database: {database_path}")
320
+ return 2
297
321
 
298
322
  if process.returncode == 0:
299
323
  logger.info(f"'{archive}' removed from it's catalog")
324
+ return 0
300
325
  else:
301
326
  logger.error(process.stdout)
302
327
  logger.error(process.sterr)
303
-
304
- return process.returncode
305
-
328
+ return 1
306
329
 
307
330
 
308
331
 
@@ -322,7 +345,7 @@ def main():
322
345
  parser.add_argument('-d', '--backup-def', type=str, help='Restrict to work only on this backup definition')
323
346
  parser.add_argument('--add-specific-archive', type=str, help='Add this archive to catalog database')
324
347
  parser.add_argument('--remove-specific-archive', type=str, help='Remove this archive from catalog database')
325
- parser.add_argument('--list-catalog', action='store_true', help='List catalogs in databases for all backup definitions')
348
+ parser.add_argument('-l', '--list-catalogs', action='store_true', help='List catalogs in databases for all backup definitions')
326
349
  parser.add_argument('--list-catalog-contents', type=int, help="List contents of a catalog. Argument is the 'archive #', '-d <definition>' argument is also required")
327
350
  parser.add_argument('--find-file', type=str, help="List catalogs containing <path>/file. '-d <definition>' argument is also required")
328
351
  parser.add_argument('--verbose', action='store_true', help='Be more verbose')
@@ -430,15 +453,11 @@ See section 15 and section 16 in the supplied "LICENSE" file.''')
430
453
 
431
454
 
432
455
  if args.remove_specific_archive:
433
-
434
- if remove_specific_archive(args.remove_specific_archive, config_settings) == 0:
435
- sys.exit(0)
436
- else:
437
- sys.exit(1)
456
+ return remove_specific_archive(args.remove_specific_archive, config_settings)
438
457
 
439
458
 
440
459
 
441
- if args.list_catalog:
460
+ if args.list_catalogs:
442
461
  if args.backup_def:
443
462
  process = list_catalogs(args.backup_def, config_settings)
444
463
  result = process.returncode
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dar-backup
3
- Version: 0.6.5
3
+ Version: 0.6.7
4
4
  Summary: A script to do full, differential and incremental backups using dar. Some files are restored from the backups during verification, after which par2 redundancy files are created. The script also has a cleanup feature to remove old backups and par2 files.
5
- Project-URL: Homepage, https://github.com/per2jensen/dar-backup
5
+ Project-URL: Homepage, https://github.com/per2jensen/dar-backup/tree/main/v2
6
6
  Project-URL: Changelog, https://github.com/per2jensen/dar-backup/blob/main/v2/Changelog.md
7
7
  Project-URL: Issues, https://github.com/per2jensen/dar-backup/issues
8
8
  Author-email: dar-backup <per2jensen@gmail.com>
@@ -845,6 +845,7 @@ Example of backup definition for a home directory
845
845
  Installation is currently in a venv. These commands are installed in the venv:
846
846
  - dar-back
847
847
  - cleanup
848
+ - manager
848
849
 
849
850
  To install, create a venv and run pip:
850
851
  ````
@@ -911,22 +912,36 @@ options:
911
912
  --log-stdout also print log messages to stdout
912
913
  --do-not-compare do not compare restores to file system
913
914
  -v, --version Show version and license information.
914
-
915
915
  ````
916
916
 
917
917
  ## 4
918
+ Generate the archive catalog database(s).
919
+ `dar-backup` expects the catalog databases to be in place, it does not automatically create them (by design)
920
+
921
+ ````
922
+ manager --create-db --config-file <path to config file> --log-level debug --log-stdout
923
+ ````
924
+
925
+
926
+
927
+
928
+ ## 5
918
929
  You are ready to do backups of all your backup definitions, if your backup definitions are
919
930
  in place in BACKUP.D_DIR (see config file)
920
931
  ````
921
932
  dar-backup --full-backup
922
933
  ````
934
+ If you want to see dar-backup's log entries in the terminal, use the `--log-stdout` option. This is also useful if dar-backup is started by systemd.
935
+
936
+ If you want more log messages, use the `--log-level debug` option.
937
+
923
938
 
924
- or a backup of a single definition
939
+ If you want a backup of a single definition, use the `-d <backup definition>` option. The definition's name is the filename of the definition in the `backup.d` config directory.
925
940
  ````
926
941
  dar-backup --full-backup -d <your backup definition>
927
942
  ````
928
943
 
929
- ## 5
944
+ ## 6
930
945
 
931
946
  Deactivate the virtual environment
932
947
  ````
@@ -0,0 +1,13 @@
1
+ dar_backup/.darrc,sha256=3d9opAnnZGU9XLyQpTDsLtgo6hqsvZ3JU-yMLz-7_f0,2110
2
+ dar_backup/__about__.py,sha256=0ouks3vBIBYQpXQLGG2c_DveClXKjoOTb3ZY9LRV9Xw,21
3
+ dar_backup/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ dar_backup/cleanup.py,sha256=9yEdRR84XPtEvBGc2QfwGBQl2tdTPttjetHeiSc_TsM,11419
5
+ dar_backup/config_settings.py,sha256=CBMUhLOOZ-x7CRdS3vBDk4TYaGqC4N1Ot8IMH-qPaI0,3617
6
+ dar_backup/dar_backup.py,sha256=oUlGCLeYwkJKSqn1qzKqkhpoQVTp-fCWyJcpmkSnLjc,32703
7
+ dar_backup/manager.py,sha256=S66gC6m-xaMMZR3MtaB0VGYEaGPohAO0DNMSSXvimM4,19869
8
+ dar_backup/util.py,sha256=SSSJYM9lQZfubhTUBlX1xDGWmCpYEF3ePARmlY544xM,11283
9
+ dar_backup-0.6.7.dist-info/METADATA,sha256=QB3M9KzbnyRUhRBbljmYFN5rYEhvzVBB2EbOD6QWsTs,64452
10
+ dar_backup-0.6.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
11
+ dar_backup-0.6.7.dist-info/entry_points.txt,sha256=x9vnW-JEl8mpDJC69f_XBcn0mBSkV1U0cyvFV-NAP1g,126
12
+ dar_backup-0.6.7.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
13
+ dar_backup-0.6.7.dist-info/RECORD,,
@@ -1,13 +0,0 @@
1
- dar_backup/.darrc,sha256=3d9opAnnZGU9XLyQpTDsLtgo6hqsvZ3JU-yMLz-7_f0,2110
2
- dar_backup/__about__.py,sha256=_f8whmZJ36ZCTk0Zldzy3KONxDBm0bxyKt7pCSHC3cE,21
3
- dar_backup/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- dar_backup/cleanup.py,sha256=DgmxSUwKrLLIQuYSIY_yTRhIuOMgI6ivjlQuH4u3wX4,9057
5
- dar_backup/config_settings.py,sha256=CBMUhLOOZ-x7CRdS3vBDk4TYaGqC4N1Ot8IMH-qPaI0,3617
6
- dar_backup/dar_backup.py,sha256=YZoVu9NJX3_WIkQIG8EMLSK3-VWdslI0c2XKrM2Un38,32214
7
- dar_backup/manager.py,sha256=2qTcn1HiDrejc6S7dLpkylURGzMQ0QqTaSl2KQQ58Uw,19198
8
- dar_backup/util.py,sha256=SSSJYM9lQZfubhTUBlX1xDGWmCpYEF3ePARmlY544xM,11283
9
- dar_backup-0.6.5.dist-info/METADATA,sha256=z0xQGBCg2sGMi93gtNCK0DXINE1ZgsohQbQh0zutlD4,63802
10
- dar_backup-0.6.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
11
- dar_backup-0.6.5.dist-info/entry_points.txt,sha256=x9vnW-JEl8mpDJC69f_XBcn0mBSkV1U0cyvFV-NAP1g,126
12
- dar_backup-0.6.5.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
13
- dar_backup-0.6.5.dist-info/RECORD,,