I needed to synchronize two folders, and I came up with this:
def sync_dirs(source,dest):
if not os.path.exists(dest):
os.makedirs(dest)
def _file_retriever(where):
dir_ac = []
file_ac = []
for root,dirs,files in os.walk(where):
for dir in dirs:
abs_dir = os.path.join(root,dir)
dir_ac.append((abs_dir,os.path.relpath(abs_dir,where)))
for file in files:
abs_f = os.path.join(root,file)
file_ac.append((abs_f,os.path.relpath(abs_f,where)))
return (dir_ac,file_ac)
left_dirs,left_files = _file_retriever(source)
right_dirs,right_files = _file_retriever(dest)
for left_dir in left_dirs:
rel_path = left_dir[1]
equivalent_right_dir = filter(lambda e:e[1] == rel_path,right_dirs)
# it's not in the right side, copy it
if len(equivalent_right_dir) == 0:
os.makedirs(os.path.join(dest,rel_path))
# check if only in the right side
for right_dir in right_dirs:
rel_path = right_dir[1]
equivalent_left_dir = filter(lambda e:e[1] == rel_path,left_dirs)
if(len(equivalent_left_dir) == 0) and (os.path.exists(right_dir[0])):
shutil.rmtree(right_dir[0])
for left_file in left_files:
rel_path = left_file[1]
equivalent_right_file = filter(lambda e:e[1] == rel_path,right_files)
# file doesn't exist in right side
if len(equivalent_right_file) == 0:
shutil.copyfile(left_file[0],os.path.join(dest,rel_path))
else:
left_content = open(left_file[0],"rb").read()
right_content= open(equivalent_right_file[0][0],"rb").read()
if left_content != right_content:
shutil.copyfile(left_file[0],os.path.join(dest,rel_path))
for right_file in right_files:
rel_path = right_file[1]
equivalent_left_file = filter(lambda e:e[1] == rel_path,left_files)
if (len(equivalent_left_file) == 0) and (os.path.exists(right_file[0])):
os.unlink(right_file[0])