-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patharchive
executable file
·93 lines (75 loc) · 2.68 KB
/
archive
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#!/usr/bin/env python3
# vim: ft=python
import argparse
import os
import shutil
import sys
from datetime import datetime
from pathlib import Path
HOME_DIR = "/home/multisn8"
ARCHIVE_DIR = "~/_archive"
# None means "generate it on-the-fly"
TIME_TAG = None
def archive(subject_path, home_dir=HOME_DIR, archive_dir=ARCHIVE_DIR, time_tag=TIME_TAG, copy_only=False) -> int:
"""
Moves `subject_path` under `backup_dir` after the pattern:
if <time_tag> is None:
subject_path = <home_dir>/A/B/C.txt
=> <backup_dir>/backup/<TIMESTAMP>/A/B/C.txt
else:
subject_path = <home_dir>/A/B/C.txt
=> <backup_dir>/<time_tag>/A/B/C.txt
Essentially generating a timestamp if `time_tag` is None, and archiving
`subject_path` while preserving its subdirectory under `home_path`.
Does nothing if `subject_path` does not exist.
"""
subject_path = Path(subject_path)
if not subject_path.exists():
return 1
if time_tag is None:
time_tag = Path("backup") / datetime.now().isoformat()
archive_dir = Path(str(archive_dir).replace("~", HOME_DIR))
archive_dir /= time_tag
subject_path = subject_path.absolute()
try:
rel_path = subject_path.relative_to(home_dir)
except ValueError:
# not a subpath of home_dir
# in that case just archive it based on its relativeness from root
rel_path = subject_path.relative_to("/")
target_path = archive_dir / rel_path
try:
target_path.parent.mkdir(parents=True, exist_ok=True)
if copy_only:
if subject_path.is_dir():
shutil.copytree(subject_path, target_path)
else:
shutil.copy2(subject_path, target_path)
else:
# assumes they're on the same FS
# which... is not necessarily the case
# but i just care about the atomicity for now
subject_path.rename(target_path)
except PermissionError:
print(
f"Skipping {subject_path} due to missing perms",
file=sys.stderr,
)
return 1
return 0
def parse_args():
parser = argparse.ArgumentParser(
description="quick and dirty archival, ignoring nonexistent dirs"
)
parser.add_argument("path")
parser.add_argument("--home-dir", default=HOME_DIR)
parser.add_argument("--archive-dir", default=ARCHIVE_DIR)
parser.add_argument("--time-tag", default=TIME_TAG)
parser.add_argument("--copy-only", action="store_true", default=False)
return parser.parse_args()
def main():
args = vars(parse_args())
exit_code = archive(args.pop("path"), **args)
sys.exit(exit_code)
if __name__ == "__main__":
main()