-
Notifications
You must be signed in to change notification settings - Fork 0
/
hashtool.py
executable file
·142 lines (108 loc) · 4.58 KB
/
hashtool.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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# hashtool - hashing of entire trees of files
# Copyright (C) 2015 - Felipe Machado
#
#
# Python standard library
import os.path
import argparse
import hashlib
# Local imports
from build import buildTreeHash
from duplicates import findDuplicates
from compare import compare
###############################################################################
# Helper functions #
####################
def inexistentFile(x):
if os.path.exists(x):
raise argparse.ArgumentTypeError( "{0} already exists".format(x) )
return os.path.abspath(x)
def isFolder(x):
if os.path.exists(x) and os.path.isdir(x):
return os.path.abspath(x)
raise argparse.ArgumentTypeError(
"{0} is not an existing folder".format(x) )
def isFile(x):
if os.path.exists(x) and os.path.isfile(x):
return os.path.abspath(x)
raise argparse.ArgumentTypeError(
"{0} is not an existing file".format(x) )
def commaSplitString( x ):
hash_functions = x.split(',')
for hash_function in hash_functions:
if hash_function not in hashlib.algorithms_available:
raise argparse.ArgumentTypeError(
"Invalid hash function {0}".format( hash_function ) )
return hash_functions
# Argument parsing function
def parseArgs():
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers( dest='command' )
# build command options
parser_build = subparsers.add_parser( 'build' )
parser_build.add_argument( 'path', type=isFolder, nargs='+' )
parser_build.add_argument( '-o', '--out', metavar='OUTPUT_FILE',
type=inexistentFile )
parser_build.add_argument( '-p', '--partial', metavar='INPUT_FILE',
type=isFile )
parser_build.add_argument( '-H', '--hashes', metavar='HASHES',
type=commaSplitString, default=["sha1"] )
parser_build.set_defaults( func=buildTreeHash )
# find_duplicates command options
parser_duplicates = subparsers.add_parser( 'find_duplicates' )
parser_duplicates.add_argument( 'hash_db', type=isFile )
parser_duplicates.add_argument( '-p', '--print-single-files',
action="store_true",
default=False )
parser_duplicates.add_argument( '--print-folders-with-both',
action="store_true",
default=False )
parser_duplicates.add_argument( '--print-folders-with-originals',
action="store_true",
default=False )
parser_duplicates.add_argument( '--dont-print-folders-with-duplicates',
action="store_true",
default=False )
parser_duplicates.add_argument( '-x', '--prefix', metavar='PREFIX',
type=str, default=None )
parser_duplicates.set_defaults( func=findDuplicates )
# compare command options
parser_compare = subparsers.add_parser( 'compare' )
parser_compare.add_argument( 'hash_db1', type=isFile )
parser_compare.add_argument( 'hash_db2', type=isFile )
parser_compare.add_argument( '--db1-path', type=str )
parser_compare.add_argument( '--db2-path', type=str )
parser_compare.add_argument( '--print-single-files',
action="store_true",
default=False )
parser_compare.add_argument( '--print-all-folders',
action="store_true",
default=False )
parser_compare.add_argument( '--two-way',
action="store_true",
default=False )
parser_compare.set_defaults( func=compare )
args = parser.parse_args()
if not args.command:
parser.print_usage()
exit(1)
return args
###############################################################################
###############################################################################
# __ __ _ ___ _ _
#| \/ | / \ |_ _| \ | |
#| |\/| | / _ \ | || \| |
#| | | |/ ___ \ | || |\ |
#|_| |_/_/ \_\___|_| \_|
#
def main():
args = parseArgs()
args.func(args)
###############################################################################
###############################################################################
if __name__ == '__main__':
main()
###############################################################################