Completed
Push — master ( ff259f...fab5c0 )
by Bjorn
01:06
created

digest()   B

Complexity

Conditions 5

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
dl 0
loc 14
rs 8.5454
c 1
b 0
f 0
1
# -*- coding: utf-8 -*-
2
"""Check if contents of directory has changed.
3
"""
4
import argparse
5
import os
6
import hashlib
7
from .listfiles import list_files
8
from .path import Path
9
10
11
def digest(dirname, glob=None):
12
    """Returns the md5 digest of all interesting files (or glob) in `dirname`.
13
    """
14
    md5 = hashlib.md5()
15
    if glob is None:
16
        fnames = [fname for _, fname in list_files(Path(dirname))]
17
        for fname in sorted(fnames):
18
            fname = os.path.join(dirname, fname)
19
            md5.update(open(fname, 'rb').read())
20
    else:
21
        fnames = Path(dirname).glob(glob)
22
        for fname in sorted(fnames):
23
            md5.update(fname.open('rb').read())
24
    return md5.hexdigest()
25
26
27
def changed(dirname, filename='.md5', args=None, glob=None):
28
    """Has `glob` changed in `dirname`
29
30
    Args:
31
        dirname: directory to measure
32
        filename: filename to store checksum
33
    """
34
    root = Path(dirname)
35
    if not root.exists():
36
        # if dirname doesn't exist it is changed (by definition)
37
        return True
38
39
    cachefile = root / filename
40
    current_digest = cachefile.open().read() if cachefile.exists() else ""
41
    
42
    _digest = digest(dirname, glob=glob)
43
    if args and args.verbose:  # pragma: nocover
44
        print "md5:", _digest
45
    has_changed = current_digest != _digest
46
47
    if has_changed:
48
        with open(os.path.join(dirname, filename), 'w') as fp:
49
            fp.write(_digest)
50
51
    return has_changed
52
53
54
class Directory(Path):
55
    def changed(self, filename='.md5', glob=None):
56
        if glob is not None:
57
            filename += '.glob-' + ''.join(ch.lower()
58
                                           for ch in glob if ch.isalpha())
59
        return changed(self, filename, glob=glob)
60
61
62
def main():  # pragma: nocover
63
    p = argparse.ArgumentParser()
64
    p.add_argument(
65
        'directory',
66
        help="Directory to check"
67
    )
68
    p.add_argument(
69
        '--verbose', '-v', action='store_true',
70
        help="increase verbosity"
71
    )
72
    args = p.parse_args()
73
74
    import sys
75
    _changed = changed(sys.argv[1], args=args)
76
    sys.exit(_changed)
77
78
79
if __name__ == "__main__":  # pragma: nocover
80
    main()
81