-
Notifications
You must be signed in to change notification settings - Fork 0
/
diff-dir.py
100 lines (87 loc) · 2.86 KB
/
diff-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
# -*- coding: utf-8 -*-
#!/usr/bin/python
import sys
import getopt
import hashlib
import os
DEBUGGING = False
BINARY = ['.ico', '.png', '.gif', '.jpg', '.jpeg', '.pdf', '.docx']
def cmp(odir, cdir, linebyline):
ohashes = checksums(odir)
chashes = checksums(cdir)
result = {}
for f in chashes:
if f not in ohashes:
result[f] = '-'
elif chashes[f] != ohashes[f]:
result[f] = '*'
for f in sorted(result):
if linebyline:
opath = os.path.join(odir, f)
cpath = os.path.join(cdir, f)
fname, fext = os.path.splitext(opath)
if os.path.exists(opath) and os.path.exists(cpath) and (fext not in BINARY) and cmpbylines(opath, cpath):
continue
yield (f, result[f])
def checksums(targetdir):
result = {}
for root, dirs, files in os.walk(targetdir):
if DEBUGGING:
print(root, dirs, files)
for f in files:
fpath = os.path.join(root, f)
frelpath = os.path.relpath(fpath, targetdir)
result[frelpath] = md5(fpath)
return result
def md5(fname):
hash_md5 = hashlib.md5()
with open(fname, "rb") as f:
for chunk in iter(lambda: f.read(4096), b""):
hash_md5.update(chunk)
return hash_md5.hexdigest()
def cmpbylines(path1, path2):
with open(path1, 'r') as file1, open(path2, 'r') as file2:
lines1 = file1.read().splitlines()
lines2 = file2.read().splitlines()
if len(lines1) != len(lines2):
return False
it1 = iter(lines1)
it2 = iter(lines2)
while True:
try:
line1 = next(it1)
line2 = next(it2)
if line1 != line2:
return False
except StopIteration:
break
return True
def main(argv):
origindir = ''
clonedir = ''
linebyline = False
try:
opts, args = getopt.getopt(argv, "o:c:lh", ["odir=", "cdir=", "line-by-line", "help"])
except getopt.GetoptError:
print('diff-dir.py -o <origindir> -c <clonedir> -l')
sys.exit(2)
for opt, arg in opts:
if opt == "-h":
print('diff-dir.py -o <origindir> -c <clonedir> -l')
sys.exit()
elif opt == "--help":
print('diff-dir.py --odir <origindir> --cdir <clonedir> --line-by-line')
sys.exit()
elif opt in ("-l", "--line-by-line"):
linebyline = True
elif opt in ("-o", "--odir"):
origindir = arg
elif opt in ("-c", "--cdir"):
clonedir = arg
if DEBUGGING:
print('Origin dir is "{}"'.format(origindir))
print('Clone dir is "{}"'.format(clonedir))
for path, status in cmp(origindir, clonedir, linebyline):
print("{} {}".format(status, path))
if __name__ == "__main__":
main(sys.argv[1:])