#!/usr/bin/env python
# fpdir.py -- fingerprint whole directories with MD5 (later: and SHA1)

import os, os.path
import re
import fingerprint

md5fname = "md5.txt"
sha1fname = "sha1.txt"
matcher = re.compile(r'MD5 \((.*)\) = (.*)')

def make_fingerprints(path, verbose=None):
    for root, dirs, files in os.walk(path):
        if "TRANS.TBL" in files: files.remove("TRANS.TBL")
        if md5fname in files: files.remove(md5fname)
        files.sort()
        if len(files) != 0:
            # If we have some files, then (and only then) create md5fname
            md5file = open(os.path.join(root, md5fname), "w")
            for file in files:
                md5file.write("MD5 (%s) = %s\n" %
                              (file,
                               fingerprint.compute_md5(
                    open(os.path.join(root, file), "rb"))))
            md5file.close()
            if verbose is not None: print "Checksummed: %s" % root

def check_fingerprints(path, verbose=None):
    for root, dirs, files in os.walk(path):
        if md5fname in files:
            # There's a checksum file here. check its contents:
            md5file = open(os.path.join(root, md5fname))
            for line in md5file.readlines():
                # Line is in the form MD5 (fname) = cksum
                mo = matcher.match(line)
                if mo is not None:
                    fname, recorded_md5sum = mo.group(1), mo.group(2)
                    # fname is always relative to root
                    computed_md5sum = fingerprint.compute_md5(
                        open(os.path.join(root, fname), "rb"))
                    if recorded_md5sum != computed_md5sum:
                        print "< MD5 (%s) = %s" % (os.path.join(root, fname),
                                                   recorded_md5sum)
                        print "> MD5 (%s) = %s" % (os.path.join(root, fname),
                                                   computed_md5sum)
            md5file.close()
            if verbose is not None: print "Verified: %s" % root

if __name__ == '__main__':
    import sys, getopt
    try:
        opts, args = getopt.getopt(sys.argv[1:], "mcv",
                                   ["make", "check", "verbose"])
    except getopt.GetoptError:
        print "Usage: %s [-m | -c] [-v] [path ...]" % sys.argv[0]
        sys.exit(0)

    m, c, v = None, None, None
    for o, a in opts:
        if o in ("-m", "--make"): m = True
        if o in ("-c", "--check"): c = True
        if o in ("-v", "--verbose"): v = True
    if m is None and c is None: c = True;      # Default is checking

    if len(args) == 0: args.append(".")

    for pname in args:
        if m == True: make_fingerprints(pname, v)
        if c == True: check_fingerprints(pname, v)
