forked from avinashkranjan/Amazing-Python-Scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAuto_Backup.py
156 lines (129 loc) · 4.33 KB
/
Auto_Backup.py
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
""" Simple backup script which just creates the root structure in an other
folder and syncs everything which recursively lies within one of the source
folders. For files bigger than a threshold they are first gziped."""
import argparse
import gzip
import os
import shutil
import sys
import threading
def parse_input():
"""
Argument Parser function, for parsing CLI.
Returns: parse_args()
"""
parser = argparse.ArgumentParser()
parser.add_argument('-t',
'--target',
nargs=1,
required=True,
help='Target Backup folder')
parser.add_argument('-s',
'--source',
nargs='+',
required=True,
help='Source Files to be added')
parser.add_argument('-c',
'--compress',
nargs=1,
type=int,
help='Gzip threshold in bytes, Deafault 1024KB',
default=[1024000])
# Default Threshold is 1024KB
# Help is triggered when there is no Input Provided
if len(sys.argv) == 1:
parser.print_help()
sys.exit()
return parser.parse_args()
def size_if_newer(source, target):
"""
If there is a difference in file size, this function reports the difference.
Args:
source: Source Path
target: Target for ZIP file
Returns: The Size difference
"""
src_stat = os.stat(source)
try:
target_ts = os.stat(target).st_mtime
except FileNotFoundError:
try:
target_ts = os.stat(target + '.gz').st_mtime
except FileNotFoundError:
target_ts = 0
# The time difference of one second is necessary since subsecond accuracy
# of os.st_mtime is striped by copy2
return src_stat.st_size if (src_stat.st_mtime - target_ts > 1) else False
def threaded_sync_file(source, target, compress):
"""
Multithreading for Synced files.
Args:
source: Source Path
target: Target for ZIP file
compress: The compression threshold
Returns: The threads
"""
size = size_if_newer(source, target)
if size:
thread = threading.Thread(target=transfer_file,
args=(source, target, size > compress))
thread.start()
return thread
def sync_file(source, target, compress):
"""
Synchronizing files
Args:
source: Source Path
target: Target for ZIP file
compress: The compression threshold
"""
size = size_if_newer(source, target)
if size:
transfer_file(source, target, size > compress)
def transfer_file(source, target, compress):
"""
Transferring files
Args:
source: Source Path
target: Target for ZIP file
compress: The compression threshold
"""
try:
if compress:
with gzip.open(target + '.gz', 'wb') as target_fid:
with open(source, 'rb') as source_fid:
target_fid.writelines(source_fid)
print('Compress {}'.format(source))
else:
shutil.copy2(source, target)
print('Copy {}'.format(source))
except FileNotFoundError:
os.makedirs(os.path.dirname(target))
transfer_file(source, target, compress)
def sync_root(root, arg):
"""
Synchronize Root with Target
"""
target = arg.target[0]
compress = arg.compress[0]
threads = []
for path, _, files in os.walk(root):
for source in files:
source = path + '/' + source
threads.append(
threaded_sync_file(source, target + source, compress))
# sync_file(source, target + source, compress)
for thread in threads:
thread.join()
if __name__ == '__main__':
arg = parse_input()
print('------------------------- Start copy -------------------------')
print('______________________________________________________________')
for root in arg.source:
sync_root(root, arg)
print('______________________________________________________________')
print('------------------------- Done Done! -------------------------')
"""
Example Usage-
> python Auto_Backup.py --target ./Backup_Folder --source ./Source_Folder
"""