aboutsummaryrefslogtreecommitdiffstats
path: root/rencon
blob: 1a2640a1f297efdf1df7c499d7cbb8e2f2237603 (plain)
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
#!/usr/bin/env python3
from __future__ import absolute_import, print_function, unicode_literals

import argparse
import hashlib
import os
import sys
from string import Template


def hashfile(hasher, fp, bs=2**16):
    h = hasher()
    buf = fp.read(bs)
    while len(buf):
        h.update(buf)
        buf = fp.read(bs)
    return h


def rename(fpath, mask, algorithm, abbrev=None, out=sys.stdout, err=sys.stderr):
    print("Renaming with mask: %s" % args.mask, file=out)
    if not os.path.exists(fpath):
        print("File %s does not exists." % fpath, file=err)
    else:
        with open(fpath, 'rb') as fp:
            hasher = getattr(hashlib, algorithm)
            hsh = hashfile(hasher, fp).hexdigest()
            if abbrev:
                hsh = hsh[0:abbrev]
        ext = os.path.splitext(fpath)[1][1:]
        name = mask.substitute(hash=hsh, ext=ext)
        dest = os.path.join(os.path.dirname(fpath), name)
        if os.path.basename(fpath) == name:
            print("OK %s" % name, file=out)
        else:
            print("`%s' -> `%s'" % (fpath, dest), file=out)
            if os.path.exists(dest):
                print("Destination %s already exists." % dest, file=err)
            elif not args.pretend:
                os.rename(fpath, dest)


if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        description="Rename files based on their content.",
        formatter_class=argparse.ArgumentDefaultsHelpFormatter)

    def abbrev(arg):
        arg = int(arg)
        if arg == 0:
            return None
        if arg < 4:
            raise argparse.ArgumentTypeError("You should use at least 4 digits.")
        return arg

    parser.add_argument('files', metavar='FILE', nargs='+',
                        help="files to rename")
    parser.add_argument('-m', '--mask',
                        help="file destination mask", default='${hash}.${ext}')
    parser.add_argument('-p', '--pretend', action='store_true',
                        help="do not rename, just print")
    parser.add_argument('-a', '--algorithm',
                        help="hash algorithm", choices=hashlib.algorithms_available, default='sha1')
    parser.add_argument('-b', '--abbrev', metavar='N', type=abbrev,
                        help="use the first N digits", default=None)

    args = parser.parse_args()
    for fpath in args.files:
        rename(fpath, Template(args.mask), args.algorithm, args.abbrev)