Skip to content

Commit 376a535

Browse files
committed
refractoring
1 parent 0891da2 commit 376a535

11 files changed

+388
-472
lines changed

build.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@
66

77
# enum34 needs to be uninstalled on python3.7 in order to make pyinstaller work
88

9-
ls_commands = ['pyinstaller --onefile fp_files.py -y',
10-
'pyinstaller --onefile fp_files_diff.py -y']
9+
ls_commands = ['pyinstaller --onefile fp.py -y']
1110

1211
for s_command in ls_commands:
1312
response = run_command(s_command)

fp.py

+318
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,318 @@
1+
import argparse
2+
import click
3+
from fp_conf import fp_conf, fp_files_conf, fp_diff_files_conf
4+
import lib_diff_files
5+
import lib_fingerprint_files
6+
import lib_helper_functions
7+
import logging
8+
import multiprocessing
9+
import os
10+
import sys
11+
import time
12+
13+
logger = logging.getLogger()
14+
CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])
15+
16+
@click.group(context_settings=CONTEXT_SETTINGS)
17+
@click.version_option(version=fp_conf.version)
18+
def fp():
19+
pass
20+
21+
@fp.command()
22+
@click.option('--fp_dir', type=click.Path(), default='', help='path to the directory to fingerprint, e.g. c:\\test\\')
23+
@click.option('--f_output', type=click.Path(), default='', help='path to the output file, e.g. c:\\results\\fp_files_result1.csv')
24+
@click.option('--batchmode', is_flag=True, help='no user interactions')
25+
@click.option('--no_admin', is_flag=True, help='do not force admin rights, not recommended')
26+
@click.option('--no_hashing', is_flag=True, help='do not calculate file hashes, not recommended')
27+
@click.option('--no_mp', is_flag=True, help='no multiprocessing - preserves ordering of files in the result')
28+
def files(**kwargs):
29+
"""
30+
(fp files --help for more help on that command)
31+
"""
32+
33+
"""
34+
>>> import test
35+
>>> import lib_doctest
36+
>>> lib_doctest.setup_doctest_logger()
37+
>>> timestamp = time.time()
38+
>>> test.create_testfiles_fingerprint_1(timestamp)
39+
>>> kwargs=dict()
40+
>>> kwargs['fp_dir'] = './testfiles/'
41+
>>> kwargs['f_output'] = './testresults/fp_files_result1.csv'
42+
>>> kwargs['batchmode'] = True
43+
>>> kwargs['no_admin'] = True
44+
>>> kwargs['no_mp'] = False
45+
>>> kwargs['no_hashing'] = False
46+
47+
>>> logger.level=logging.ERROR
48+
>>> files(**kwargs) # +ELLIPSIS, +NORMALIZE_WHITESPACE
49+
50+
>>> test.modify_testfiles_fingerprint_2(timestamp)
51+
>>> kwargs['f_output'] = './testresults/fp_files_result2.csv'
52+
>>> logger.level=logging.ERROR
53+
>>> files() # +ELLIPSIS, +NORMALIZE_WHITESPACE
54+
55+
>>> kwargs['no_mp'] = True
56+
>>> logger.level=logging.ERROR
57+
>>> files() # +ELLIPSIS, +NORMALIZE_WHITESPACE
58+
59+
>>> kwargs['no_hashing'] = True
60+
>>> logger.level=logging.ERROR
61+
>>> files() # +ELLIPSIS, +NORMALIZE_WHITESPACE
62+
63+
64+
"""
65+
files_save_commandline_options_to_conf(**kwargs)
66+
lib_helper_functions.config_console_logger()
67+
lib_helper_functions.inform_if_not_run_as_admin(exit_if_not_admin=fp_files_conf.exit_if_not_admin, interactive=fp_conf.interactive)
68+
logger.info('create files fingerprint {}'.format(fp_conf.version))
69+
70+
check_fp_dir()
71+
check_f_output()
72+
lib_helper_functions.SetupFileLogging(f_output=fp_files_conf.f_output)
73+
74+
logger.info('fingerprinting directory : {}'.format(fp_files_conf.fp_dir))
75+
logger.info('results filename : {}'.format(fp_files_conf.f_output))
76+
logger.info('file hashing : {}'.format(fp_files_conf.hash_files))
77+
logger.info('multiprocessing : {}'.format(fp_files_conf.multiprocessing))
78+
79+
with lib_fingerprint_files.FingerPrintFiles() as fingerprint_files:
80+
if fp_files_conf.multiprocessing: # test c:\windows : 66 seconds
81+
fingerprint_files.create_fp_mp()
82+
else:
83+
fingerprint_files.create_fp() # test c:\windows : 124 seconds
84+
85+
logger.info('Finished\n\n')
86+
lib_helper_functions.logger_flush_all_handlers()
87+
if fp_conf.interactive:
88+
input('enter for exit, check the logfile')
89+
90+
@fp.command()
91+
@click.option('--fp1', type=click.Path(), default='', help='path to the first fingerprint, e.g. c:\\results\\fp_files_result1.csv')
92+
@click.option('--fp2', type=click.Path(), default='', help='path to the second fingerprint, e.g. c:\\results\\fp_files_result2.csv')
93+
@click.option('--f_output', type=click.Path(), default='', help='path to the diff file, e.g. c:\\results\\fp_files_diff_1_2.csv')
94+
@click.option('--batchmode', is_flag=True, help='no user interactions')
95+
def files_diff(**kwargs):
96+
"""
97+
(fp files_diff --help for more help on that command)
98+
"""
99+
100+
"""
101+
>>> import lib_doctest
102+
>>> kwargs = dict()
103+
>>> kwargs['fp1'] = './testfiles_source/fp_files_result1_difftest.csv'
104+
>>> kwargs['fp2'] = './testfiles_source/fp_files_result2_difftest.csv'
105+
>>> kwargs['f_output'] = './testresults/fp_files_diff_1_2.csv'
106+
>>> kwargs['batchmode'] = True
107+
>>> logger.level=logging.ERROR
108+
>>> files_diff(**kwargs) # +ELLIPSIS, +NORMALIZE_WHITESPACE
109+
110+
"""
111+
112+
diff_files_save_commandline_options_to_conf(**kwargs)
113+
lib_helper_functions.config_console_logger()
114+
logger.info('create file fingerprint diff {}'.format(fp_conf.version))
115+
116+
fp_diff_files_conf.fp1_path = check_fp_file(f_input_file=fp_diff_files_conf.fp1_path, file_number=1)
117+
fp_diff_files_conf.fp2_path = check_fp_file(f_input_file=fp_diff_files_conf.fp2_path, file_number=2)
118+
check_f_output()
119+
120+
lib_helper_functions.SetupFileLogging(f_output=fp_diff_files_conf.f_output)
121+
122+
logger.info('fingerprint_1 : {}'.format(fp_diff_files_conf.fp1_path))
123+
logger.info('fingerprint_2 : {}'.format(fp_diff_files_conf.fp2_path))
124+
logger.info('results filename : {}'.format(fp_diff_files_conf.f_output))
125+
126+
with lib_diff_files.FileDiff() as file_diff:
127+
file_diff.create_diff_file()
128+
129+
logger.info('Finished\n\n')
130+
lib_helper_functions.logger_flush_all_handlers()
131+
if fp_conf.interactive:
132+
input('enter for exit, check the logfile')
133+
134+
135+
def files_save_commandline_options_to_conf(**kwargs):
136+
fp_files_conf.fp_dir = kwargs['fp_dir']
137+
fp_files_conf.f_output = kwargs['f_output']
138+
fp_conf.interactive = not kwargs['batchmode']
139+
fp_files_conf.exit_if_not_admin = not kwargs['no_admin']
140+
fp_files_conf.hash_files = not kwargs['no_hashing']
141+
fp_files_conf.multiprocessing = not kwargs['no_mp']
142+
143+
def diff_files_save_commandline_options_to_conf(**kwargs):
144+
fp_diff_files_conf.fp1_path = kwargs['fp1']
145+
fp_diff_files_conf.fp2_path = kwargs['fp2']
146+
fp_diff_files_conf.f_output = kwargs['f_output']
147+
fp_conf.interactive = not kwargs['batchmode']
148+
149+
def check_fp_file(f_input_file:str, file_number:int, test_input:str= '')->str:
150+
"""
151+
>>> fp_conf.interactive = True
152+
>>> check_fp_file(f_input_file='./testfiles/', file_number=1,test_input='./testfiles_source/fp_files_result1_difftest.csv')
153+
'./testfiles_source/fp_files_result1_difftest.csv'
154+
155+
>>> fp_conf.interactive = False
156+
>>> check_fp_file(f_input_file='./testfiles/', file_number=1) # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
157+
Traceback (most recent call last):
158+
...
159+
SystemExit: 1
160+
161+
>>> fp_conf.interactive = False
162+
>>> check_fp_file(f_input_file='./testfiles_source/fp_files_result1_difftest.csv', file_number=1)
163+
'./testfiles_source/fp_files_result1_difftest.csv'
164+
165+
166+
"""
167+
while not is_fp_input_file_ok(f_input_file):
168+
if fp_conf.interactive:
169+
if test_input:
170+
f_input_file = test_input
171+
else:
172+
f_input_file = input('file {} to fingerprint (e.g. c:\\test\\ ): '.format(file_number))
173+
if not is_fp_input_file_ok(f_input_file):
174+
logger.info('can not read file {}, try again'.format(f_input_file))
175+
lib_helper_functions.logger_flush_all_handlers()
176+
else:
177+
break
178+
else:
179+
logger.info('can not read file {}'.format(f_input_file))
180+
lib_helper_functions.logger_flush_all_handlers()
181+
sys.exit(1)
182+
return f_input_file
183+
184+
def is_fp_input_file_ok(f_path:str)->bool:
185+
"""
186+
>>> is_fp_input_file_ok(f_path='./testfiles/')
187+
False
188+
>>> is_fp_input_file_ok(f_path='./testfiles')
189+
False
190+
>>> is_fp_input_file_ok(f_path='./not_exist/')
191+
False
192+
>>> is_fp_input_file_ok(f_path='./testfiles_source/fp_files_result1_difftest.csv')
193+
True
194+
195+
"""
196+
# noinspection PyBroadException
197+
try:
198+
if os.path.isfile(f_path):
199+
return True
200+
else:
201+
return False
202+
except Exception:
203+
return False
204+
205+
206+
def check_f_output(test_input:str=''):
207+
"""
208+
>>> fp_conf.interactive = False
209+
>>> fp_files_conf.f_output='./testresults/fp_files_result1.csv'
210+
>>> check_f_output()
211+
212+
>>> fp_files_conf.f_output='x:/testresults/fp_files_result_test'
213+
>>> check_f_output() # +ELLIPSIS, +NORMALIZE_WHITESPACE
214+
Traceback (most recent call last):
215+
...
216+
SystemExit: 1
217+
>>> fp_conf.interactive = True
218+
>>> check_f_output(test_input='./testresults/fp_files_result1.csv')
219+
220+
can not write to x:/testresults/fp_files_result_test.csv, probably access rights
221+
222+
"""
223+
fp_files_conf.f_output = lib_helper_functions.strip_extension(fp_files_conf.f_output) + '.csv'
224+
while not is_f_output_ok(f_path=fp_files_conf.f_output):
225+
if fp_conf.interactive:
226+
if test_input:
227+
fp_files_conf.f_output = test_input
228+
else:
229+
fp_files_conf.f_output = input('result filename (e.g. c:\\results\\<f_out>.csv ): ')
230+
fp_files_conf.f_output = lib_helper_functions.strip_extension(fp_files_conf.f_output) + '.csv'
231+
if not is_f_output_ok(f_path=fp_files_conf.f_output):
232+
logger.info('can not write to {}, probably access rights'.format(fp_files_conf.f_output))
233+
else:
234+
break
235+
else:
236+
logger.info('can not write to {}, probably access rights'.format(fp_files_conf.f_output))
237+
sys.exit(1)
238+
239+
def check_fp_dir(test_input:str= ''):
240+
"""
241+
>>> import test
242+
>>> import lib_doctest
243+
>>> lib_doctest.setup_doctest_logger()
244+
>>> timestamp = time.time()
245+
>>> test.create_testfiles_fingerprint_1(timestamp)
246+
247+
>>> fp_conf.interactive = False
248+
>>> fp_files_conf.fp_dir = './testfiles/'
249+
>>> check_fp_dir()
250+
>>> fp_files_conf.fp_dir = './not_exist/'
251+
>>> check_fp_dir() # +ELLIPSIS, +NORMALIZE_WHITESPACE
252+
Traceback (most recent call last):
253+
...
254+
SystemExit: 1
255+
>>> fp_conf.interactive = True
256+
>>> check_fp_dir(test_input='./testfiles/') # +ELLIPSIS, +NORMALIZE_WHITESPACE
257+
258+
can not read directory ./not_exist/
259+
260+
"""
261+
while not is_fp_dir_ok():
262+
if fp_conf.interactive:
263+
if test_input:
264+
fp_files_conf.fp_dir = test_input
265+
else:
266+
fp_files_conf.fp_dir = input('directory to fingerprint (e.g. c:\\test\\ ): ')
267+
if not is_fp_dir_ok():
268+
logger.info('can not read directory {}, try again'.format(fp_files_conf.fp_dir))
269+
lib_helper_functions.logger_flush_all_handlers()
270+
else:
271+
break
272+
else:
273+
logger.info('can not read directory {}'.format(fp_files_conf.fp_dir))
274+
lib_helper_functions.logger_flush_all_handlers()
275+
sys.exit(1)
276+
277+
def is_fp_dir_ok()->bool:
278+
"""
279+
>>> fp_files_conf.fp_dir = './testfiles/'
280+
>>> is_fp_dir_ok()
281+
True
282+
>>> fp_files_conf.fp_dir = './testfiles'
283+
>>> is_fp_dir_ok()
284+
True
285+
>>> fp_files_conf.fp_dir = './not_exist/'
286+
>>> is_fp_dir_ok()
287+
False
288+
"""
289+
# noinspection PyBroadException
290+
try:
291+
lib_fingerprint_files.format_fp_files_dir()
292+
return True
293+
except Exception:
294+
return False
295+
296+
def is_f_output_ok(f_path:str)->bool:
297+
"""
298+
>>> is_f_output_ok(f_path='./testresults/fp_files_result_test.csv')
299+
True
300+
>>> is_f_output_ok(f_path='./testresults/fp_files_result_test')
301+
True
302+
>>> is_f_output_ok(f_path='x:/testresults/fp_files_result_test')
303+
can not create x:/testresults/fp_files_result_test, probably not enough rights
304+
False
305+
"""
306+
# noinspection PyBroadException
307+
try:
308+
lib_helper_functions.create_path_and_check_permission(f_path=f_path)
309+
return True
310+
except Exception:
311+
return False
312+
313+
314+
if __name__ == '__main__':
315+
# Hack for multiprocessing.freeze_support() to work from a
316+
# setuptools-generated entry point.
317+
multiprocessing.freeze_support()
318+
fp()

fp_conf.py

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
class FPConf(object):
2+
def __init__(self):
3+
self.version:str = '2.0.0'
4+
self.interactive: bool = True
5+
6+
class FPFilesConf(object):
7+
def __init__(self):
8+
self.fp_dir:str = ''
9+
self.f_output:str = ''
10+
self.exit_if_not_admin:bool = True
11+
self.hash_files:bool = True
12+
self.multiprocessing:bool = True
13+
14+
class FPDiffFilesConf(object):
15+
def __init__(self):
16+
self.fp1_path:str = ''
17+
self.fp2_path: str = ''
18+
self.f_output:str = ''
19+
self.logfile_fullpath:str = ''
20+
21+
22+
fp_conf = FPConf()
23+
fp_files_conf = FPFilesConf()
24+
fp_diff_files_conf = FPDiffFilesConf()

0 commit comments

Comments
 (0)