Amazing-Python-Scripts
156 строк · 4.3 Кб
1""" Simple backup script which just creates the root structure in an other
2folder and syncs everything which recursively lies within one of the source
3folders. For files bigger than a threshold they are first gziped."""
4
5import argparse
6import gzip
7import os
8import shutil
9import sys
10import threading
11
12
13def parse_input():
14"""
15Argument Parser function, for parsing CLI.
16Returns: parse_args()
17
18"""
19parser = argparse.ArgumentParser()
20parser.add_argument('-t',
21'--target',
22nargs=1,
23required=True,
24help='Target Backup folder')
25parser.add_argument('-s',
26'--source',
27nargs='+',
28required=True,
29help='Source Files to be added')
30parser.add_argument('-c',
31'--compress',
32nargs=1,
33type=int,
34help='Gzip threshold in bytes, Deafault 1024KB',
35default=[1024000])
36# Default Threshold is 1024KB
37
38# Help is triggered when there is no Input Provided
39if len(sys.argv) == 1:
40parser.print_help()
41sys.exit()
42
43return parser.parse_args()
44
45
46def size_if_newer(source, target):
47"""
48If there is a difference in file size, this function reports the difference.
49Args:
50source: Source Path
51target: Target for ZIP file
52
53Returns: The Size difference
54
55"""
56src_stat = os.stat(source)
57try:
58target_ts = os.stat(target).st_mtime
59except FileNotFoundError:
60try:
61target_ts = os.stat(target + '.gz').st_mtime
62except FileNotFoundError:
63target_ts = 0
64
65# The time difference of one second is necessary since subsecond accuracy
66# of os.st_mtime is striped by copy2
67return src_stat.st_size if (src_stat.st_mtime - target_ts > 1) else False
68
69
70def threaded_sync_file(source, target, compress):
71"""
72Multithreading for Synced files.
73Args:
74source: Source Path
75target: Target for ZIP file
76compress: The compression threshold
77
78Returns: The threads
79
80"""
81size = size_if_newer(source, target)
82
83if size:
84thread = threading.Thread(target=transfer_file,
85args=(source, target, size > compress))
86thread.start()
87return thread
88
89
90def sync_file(source, target, compress):
91"""
92Synchronizing files
93Args:
94source: Source Path
95target: Target for ZIP file
96compress: The compression threshold
97"""
98size = size_if_newer(source, target)
99
100if size:
101transfer_file(source, target, size > compress)
102
103
104def transfer_file(source, target, compress):
105"""
106Transferring files
107Args:
108source: Source Path
109target: Target for ZIP file
110compress: The compression threshold
111"""
112try:
113if compress:
114with gzip.open(target + '.gz', 'wb') as target_fid:
115with open(source, 'rb') as source_fid:
116target_fid.writelines(source_fid)
117print('Compress {}'.format(source))
118else:
119shutil.copy2(source, target)
120print('Copy {}'.format(source))
121except FileNotFoundError:
122os.makedirs(os.path.dirname(target))
123transfer_file(source, target, compress)
124
125
126def sync_root(root, arg):
127"""
128Synchronize Root with Target
129
130"""
131target = arg.target[0]
132compress = arg.compress[0]
133threads = []
134
135for path, _, files in os.walk(root):
136for source in files:
137source = path + '/' + source
138threads.append(
139threaded_sync_file(source, target + source, compress))
140# sync_file(source, target + source, compress)
141for thread in threads:
142thread.join()
143
144
145if __name__ == '__main__':
146arg = parse_input()
147print('------------------------- Start copy -------------------------')
148print('______________________________________________________________')
149for root in arg.source:
150sync_root(root, arg)
151print('______________________________________________________________')
152print('------------------------- Done Done! -------------------------')
153"""
154Example Usage-
155> python Auto_Backup.py --target ./Backup_Folder --source ./Source_Folder
156"""
157