1 from filecmp import dircmp
2 from hashlib import sha256
3 from io import StringIO
7 class WrappedStringIO(StringIO):
8 """A wrapper around StringIO to allow writing str objects"""
10 if isinstance(s, str):
12 super(WrappedStringIO, self).write(s)
14 class UpdateFileWriter:
15 """A file-like context object which will only write to a file if the result would be different
18 filename (str): The name of the file to update
19 stream (WrappedStringIO): The file-like stream provided upon context enter
22 filename (str): Sets the filename attribute
26 def __init__(self, filename):
27 self.filename = filename
31 self.stream = WrappedStringIO()
34 def __exit__(self, exc_type, exc_value, traceback):
36 new_content = self.stream.getvalue()
41 with open(self.filename, 'r') as fstream:
42 cur_hash.update(fstream.read())
48 new_hash.update(new_content)
49 update = new_hash.digest() != cur_hash.digest()
54 with open(self.filename, 'w') as fstream:
55 fstream.write(new_content)
59 def open_for_update(filename):
60 return UpdateFileWriter(filename)
62 def walk_recursively_and_update(dcmp):
63 #for different Files Copy from right to left
64 for name in dcmp.diff_files:
65 srcpath = dcmp.right + "/" + name
66 destpath = dcmp.left + "/" + name
67 print("Updating %s" % (destpath))
68 if os.path.isfile(srcpath):
69 shutil.copyfile(srcpath, destpath)
71 raise Exception("path: " + srcpath + "is neither a file or folder")
73 #copy right only files
74 for name in dcmp.right_only:
75 srcpath = dcmp.right + "/" + name
76 destpath = dcmp.left + "/" + name
77 print("Updating %s" % (destpath))
78 if os.path.isfile(srcpath):
79 shutil.copyfile(srcpath, destpath)
80 elif os.path.isdir(srcpath):
81 shutil.copytree(srcpath, destpath)
83 raise Exception("path: " + srcpath + "is neither a file or folder")
85 #delete left only files
86 for name in dcmp.left_only:
87 path = dcmp.left + "/" + name
88 print("Deleting %s" % (path))
89 if os.path.isfile(path):
91 elif os.path.isdir(path):
94 raise Exception("path: " + path + "is neither a file or folder")
97 for sub_dcmp in dcmp.subdirs.values():
98 walk_recursively_and_update(sub_dcmp)
100 def UpdateDirectory(destpath,srcpath):
102 print("Updating %s with %s" % (destpath,srcpath))
103 if not os.path.exists(destpath):
104 os.makedirs(destpath)
105 dcmp = dircmp(destpath,srcpath)
106 walk_recursively_and_update(dcmp)