-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsync_dir.py
163 lines (129 loc) · 5.45 KB
/
sync_dir.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
157
158
159
160
161
162
163
"""
A program that synchronizes two directories: source and replica;
Features:
> Periodically one-way synchronization, identical copy of source directory is maintained in replica directory;
> File creation/copying/removal operations are logged to a file and to the console output;
> Directory path, synchronization interval and log file path are provided using the command line arguments;
"""
# Import required dependencies
import hashlib
import os
import shutil
import sys
import time
import logging
# Configure logging
try:
logging.basicConfig(filename=sys.argv[1], level=logging.INFO, format='%(asctime)s:%(levelname)s:%(message)s',
datefmt='%Y-%m-%d,%H:%M:%S')
except IsADirectoryError as e:
print(f'{e}\nNot a valid file path')
sys.exit()
# Get logs in console output
logging.getLogger().addHandler(logging.StreamHandler())
# Compare files in source and replica directories using md5 hash
def compare_files(file_src, file_replica):
# compare 2 files with hash
with open(file_src, 'rb') as f1:
with open(file_replica, 'rb') as f2:
if hashlib.md5(f1.read()).hexdigest() == hashlib.md5(f2.read()).hexdigest():
return True
else:
return False
# Compare source and replica directories
def compare_directories(file_src, file_replica):
# Get all files from source directory
files_source = os.listdir(file_src)
# Get all files from replica directory
files_repl = os.listdir(file_replica)
# Compare src/replica files list
if len(files_source) != len(files_repl):
return False
# Return false if any file is different
for files in files_source:
if files in files_repl:
if not compare_files(file_src + '/' + files, file_replica + '/' + files):
return False
else:
return False
# Return True if all files are same
return True
# Input source/replica directories path
source_path = input("Enter source directory path\n")
replica_path = input("Enter replica directory path\n")
# Directories name
source_dirname = "source"
replica_dirname = "replica"
# Check for valid path
is_dirpath1 = os.path.isdir(source_path)
is_dirpath2 = os.path.isdir(replica_path)
# Join path with source/replica directory names
src_dirpath = os.path.join(source_path, source_dirname)
replica_dirpath = os.path.join(replica_path, replica_dirname)
if is_dirpath1 and is_dirpath2:
# Make source directory if path is valid
if not os.path.isdir(src_dirpath):
os.mkdir(src_dirpath)
print("source directory created")
else:
print(f"source directory exist")
# Make replica directory if path is valid
if not os.path.isdir(replica_dirpath):
os.mkdir(replica_dirpath)
print("replica directory created")
else:
print(f"replica directory exist")
# Exit when not valid path is provided in input
else:
print("Not a valid directory path\nExiting...")
sys.exit()
# Perform periodic file creation/copying/removal operations
while True:
# Check source directory existence
if os.path.isdir(src_dirpath):
logging.info('source directory status -> ONLINE')
# Delete replica directory if source directory is deleted manually
else:
logging.info('source directory deleted on current path\nDeleting existing replica directory\nExiting...\n')
shutil.rmtree(replica_dirpath, ignore_errors=True)
break
# Check replica directory existence
if os.path.isdir(replica_dirpath):
logging.info('replica directory status -> ONLINE')
# Create replica directory if replica directory is deleted manually
else:
logging.info('replica directory does not exist\nCreating replica directory...')
os.mkdir(replica_dirpath)
# Check if source directory is in sync with replica
if compare_directories(src_dirpath, replica_dirpath):
logging.info('replica directory is in sync with source directory')
else:
# Get source directory files
files_src = os.listdir(src_dirpath)
# Get replica directory files
files_replica = os.listdir(replica_dirpath)
# Compare source and replica directory files
for file in files_replica:
if file in files_src:
if compare_files(src_dirpath + '/' + file, replica_dirpath + '/' + file):
logging.info(f'{file} in replica directory is up to date with {file} in source directory')
else:
# Copy files from source to replica directory
os.remove(replica_dirpath + '/' + file)
os.system('cp ' + src_dirpath + '/' + file + ' ' + replica_dirpath)
logging.info(f'File {file} is updated in replica directory')
if file not in files_src:
# Delete files from replica directory
os.remove(replica_dirpath + '/' + file)
logging.info(f'File {file} is deleted from replica directory')
for file in files_src:
if file not in files_replica:
# Copy files from source to replica directory
os.system('cp ' + src_dirpath + '/' + file + ' ' + replica_dirpath)
logging.info(f'File {file} is copied to replica directory')
# Provide synchronization interval
try:
time.sleep(int(sys.argv[2]))
except ValueError as e1:
print(f'{e1}\n Not a valid synchronization interval value')
sys.exit()