@@ -71,13 +71,16 @@ def __init__(self, command, static_logfile: str = None):
71
71
self .__py_function_return = None
72
72
73
73
self .__nested = False
74
+ self .__no_new_log = False
74
75
self .__ignore_cmd_retval = False
76
+ self .__silent = False
75
77
76
78
if not self .__is_py_function :
77
79
command = command .strip ()
78
80
if CmdInterface .__use_installer :
79
81
command += CmdInterface .__installer_command_suffix
80
82
if len (command ) == 0 or which (command ) is None :
83
+ print ('Command not found: ' + command )
81
84
raise OSError ('Command not found: ' + command )
82
85
83
86
if not self .__is_py_function and self .__no_key_options [0 ][:4 ] == 'Mitk' :
@@ -257,6 +260,7 @@ def add_repo_path(path: str, autocommit: bool = False):
257
260
CmdInterface .__git_repos [path ]['autocommit' ] = autocommit
258
261
CmdInterface .__check_repo (path )
259
262
else :
263
+ print ('"' + path + '" is not a directory' )
260
264
raise NotADirectoryError ('"' + path + '" is not a directory' )
261
265
262
266
@staticmethod
@@ -310,6 +314,8 @@ def remove_arg(self, key: str):
310
314
self .__check_output .remove (self .__options [key ])
311
315
del self .__options [key ]
312
316
else :
317
+ print ('No argument with specified keyword found! Arguments without keyword cannot be removed. '
318
+ 'Create a new instance of CmdInterface in this case.' )
313
319
raise ValueError ('No argument with specified keyword found! Arguments without keyword cannot be removed. '
314
320
'Create a new instance of CmdInterface in this case.' )
315
321
@@ -333,6 +339,7 @@ def add_arg(self,
333
339
return
334
340
if self .__is_py_function :
335
341
if key is None :
342
+ print ('Only arguments with keyword are allowed when executing python functions!' )
336
343
raise ValueError ('Only arguments with keyword are allowed when executing python functions!' )
337
344
338
345
if check_input :
@@ -471,17 +478,19 @@ def __log_start(self) -> datetime:
471
478
self .__log ['command' ]['time' ]['start' ] = start_time .strftime ("%Y-%m-%d %H:%M:%S" )
472
479
self .__log ['command' ]['time' ]['utc_offset' ] = time .localtime ().tm_gmtoff
473
480
self .log_message (start_time .strftime ("%Y-%m-%d %H:%M:%S" ) + ' >> ' + self .__log ['command' ]['name' ] + ' START' )
474
- if CmdInterface .__send_start :
481
+ if CmdInterface .__send_start and not self . __silent :
475
482
CmdInterface .send_telegram_message ('START ' + self .__log ['command' ]['name' ])
476
483
return start_time
477
484
478
- def __log_end (self , start_time : datetime ) -> datetime :
485
+ def __log_end (self , start_time : datetime , return_code : int ) -> datetime :
479
486
"""
480
487
Log end time and duration of command execution:
481
488
['command']['time']['end']
482
489
['command']['time']['duration']
483
490
Return end time.
484
491
"""
492
+
493
+ # set times
485
494
end_time = datetime .now ()
486
495
self .__log ['command' ]['time' ]['end' ] = end_time .strftime ("%Y-%m-%d %H:%M:%S" )
487
496
@@ -493,7 +502,22 @@ def __log_end(self, start_time: datetime) -> datetime:
493
502
minutes , seconds = divmod (remainder , 60 )
494
503
duration_formatted = '%d:%02d:%02d' % (hours , minutes , seconds )
495
504
self .__log ['command' ]['time' ]['duration' ] = duration_formatted
505
+
506
+ # log end messages & return code
496
507
self .log_message (end_time .strftime ("%Y-%m-%d %H:%M:%S" ) + ' >> ' + self .__log ['command' ]['name' ] + ' END' )
508
+ if (CmdInterface .__throw_on_error or CmdInterface .__exit_on_error ) and return_code <= 0 :
509
+ self .log_message ('Exiting due to error: ' + self .__return_code_meanings [return_code ])
510
+ self .__log ['command' ]['return_code' ] = return_code
511
+ self .update_log ()
512
+
513
+ if not self .__silent :
514
+ if CmdInterface .__send_log :
515
+ CmdInterface .send_telegram_logfile (
516
+ message = 'END ' + self .__log ['command' ]['name' ] + '\n ' + self .__return_code_meanings [return_code ])
517
+ elif CmdInterface .__send_end :
518
+ CmdInterface .send_telegram_message (
519
+ message = 'END ' + self .__log ['command' ]['name' ] + '\n ' + self .__return_code_meanings [return_code ])
520
+
497
521
return end_time
498
522
499
523
def log_message (self , message : str , via_telegram : bool = False ):
@@ -507,15 +531,15 @@ def log_message(self, message: str, via_telegram: bool = False):
507
531
if via_telegram :
508
532
CmdInterface .send_telegram_message (message )
509
533
510
- def __pyfunction_to_log (self , silent : bool = False ):
534
+ def __pyfunction_to_log (self ):
511
535
"""
512
536
Run python function and store terminal output in log (['command']['text_output']).
513
537
"""
514
538
original_stdout = sys .stdout
515
539
original_stderr = sys .stderr
516
540
sys .stdout = sys .stderr = out_string = io .StringIO ()
517
541
518
- if silent :
542
+ if self . __silent :
519
543
520
544
try :
521
545
self .__no_key_options [0 ](* self .__no_key_options [1 :], ** self .__options )
@@ -555,11 +579,11 @@ def __pyfunction_to_log(self, silent: bool = False):
555
579
if exception is not None :
556
580
raise exception
557
581
558
- def __cmd_to_log (self , run_string : str , version_arg : str = None , silent : bool = False ):
582
+ def __cmd_to_log (self , run_string : str , version_arg : str = None ):
559
583
"""
560
584
Run command line tool and store output in log.
561
585
"""
562
- if silent :
586
+ if self . __silent :
563
587
retval = subprocess .call (run_string ,
564
588
shell = True ,
565
589
stdout = open (os .devnull , 'wb' ),
@@ -661,7 +685,7 @@ def update_log(self):
661
685
"""
662
686
Replace last entry of the json logfile by log of current instance.
663
687
"""
664
- if CmdInterface .__logfile_name is None :
688
+ if CmdInterface .__logfile_name is None or self . __no_new_log :
665
689
return
666
690
self .__log ['command' ]['return_code_meaning' ] = self .__return_code_meanings [self .__log ['command' ]['return_code' ]]
667
691
self .__log ['cmd_interface' ]['repositories' ] = CmdInterface .__git_repos
@@ -682,7 +706,7 @@ def append_log(self):
682
706
"""
683
707
Append log of current instance to the output json file. Creates new json if it does not exist.
684
708
"""
685
- if CmdInterface .__logfile_name is None :
709
+ if CmdInterface .__logfile_name is None or self . __no_new_log :
686
710
return
687
711
self .__log ['command' ]['return_code_meaning' ] = self .__return_code_meanings [self .__log ['command' ]['return_code' ]]
688
712
self .__log ['cmd_interface' ]['repositories' ] = CmdInterface .__git_repos
@@ -830,9 +854,10 @@ def run(self, version_arg: str = None,
830
854
831
855
# check if run has been called recoursively (CmdInterface inside of CmdInterface)
832
856
self .__nested = False
833
- user_silent = silent
857
+ self .__no_new_log = silent
858
+ self .__silent = silent
834
859
if CmdInterface .__called :
835
- silent = True
860
+ self . __no_new_log = True
836
861
self .__nested = True
837
862
CmdInterface .__called = True
838
863
@@ -873,8 +898,7 @@ def run(self, version_arg: str = None,
873
898
self .__log ['command' ]['run_string' ] = run_string
874
899
875
900
start_time = self .__log_start ()
876
- if not silent :
877
- self .append_log ()
901
+ self .append_log ()
878
902
879
903
exception = None
880
904
if run_necessary and run_possible :
@@ -883,11 +907,10 @@ def run(self, version_arg: str = None,
883
907
try :
884
908
# run command
885
909
if self .__is_py_function :
886
- self .__pyfunction_to_log (silent = user_silent ) # command is python function
910
+ self .__pyfunction_to_log () # command is python function
887
911
else :
888
912
self .__cmd_to_log (run_string = run_string ,
889
- version_arg = version_arg ,
890
- silent = user_silent ) # command is external tool
913
+ version_arg = version_arg ) # command is external tool
891
914
892
915
# check if output was produced as expected
893
916
missing_output = CmdInterface .check_exist (check_output )
@@ -900,10 +923,33 @@ def run(self, version_arg: str = None,
900
923
# everything went as expected
901
924
self .__log ['command' ]['output' ]['found' ] = CmdInterface .get_file_hashes (check_output )
902
925
return_code = 1
926
+ except MissingOutputError as err :
927
+ return_code = - 1
928
+ exception = err
929
+
930
+ exc_type , exc_obj , exc_tb = sys .exc_info ()
931
+ fname = os .path .split (exc_tb .tb_frame .f_code .co_filename )[1 ]
932
+ self .log_message ('Exception: ' + exc_type .__name__ )
933
+ self .log_message ('In file: ' + fname )
934
+ self .log_message ('Line: ' + str (exc_tb .tb_lineno ))
935
+ except MissingInputError as err :
936
+ return_code = - 2
937
+ exception = err
938
+
939
+ exc_type , exc_obj , exc_tb = sys .exc_info ()
940
+ fname = os .path .split (exc_tb .tb_frame .f_code .co_filename )[1 ]
941
+ self .log_message ('Exception: ' + exc_type .__name__ )
942
+ self .log_message ('In file: ' + fname )
943
+ self .log_message ('Line: ' + str (exc_tb .tb_lineno ))
903
944
except Exception as err :
904
945
return_code = - 3
905
946
exception = err
906
- self .log_message ('Exception: ' + str (err ))
947
+
948
+ exc_type , exc_obj , exc_tb = sys .exc_info ()
949
+ fname = os .path .split (exc_tb .tb_frame .f_code .co_filename )[1 ]
950
+ self .log_message ('Exception: ' + exc_type .__name__ )
951
+ self .log_message ('In file: ' + fname )
952
+ self .log_message ('Line: ' + str (exc_tb .tb_lineno ))
907
953
908
954
elif not run_necessary :
909
955
self .log_message ('Skipping execution. All output files already present.' )
@@ -912,41 +958,20 @@ def run(self, version_arg: str = None,
912
958
self .log_message ('Skipping execution. Input files missing: ' + str (missing_inputs ))
913
959
exception = MissingInputError (missing_inputs )
914
960
915
- # end logging
916
- self .__log_end (start_time )
917
-
918
961
if not self .__nested :
919
962
CmdInterface .__called = False
920
- if (CmdInterface .__throw_on_error or CmdInterface .__exit_on_error ) and return_code <= 0 :
921
- self .log_message ('Exiting due to error: ' + self .__return_code_meanings [return_code ])
922
- self .__log ['command' ]['return_code' ] = return_code
923
- if not silent :
924
- self .update_log ()
925
963
926
- if CmdInterface .__send_log :
927
- CmdInterface .send_telegram_logfile (
928
- message = 'END ' + self .__log ['command' ]['name' ] + '\n ' + self .__return_code_meanings [return_code ])
929
- elif CmdInterface .__send_end :
930
- CmdInterface .send_telegram_message (
931
- message = 'END ' + self .__log ['command' ]['name' ] + '\n ' + self .__return_code_meanings [return_code ])
964
+ # end logging
965
+ self .__log_end (start_time , return_code = return_code )
966
+
967
+ self .__log = CmdLog ()
968
+ if (CmdInterface .__throw_on_error or CmdInterface .__exit_on_error ) and return_code <= 0 :
932
969
if CmdInterface .__throw_on_error or self .__nested :
933
970
if exception is not None :
934
971
raise exception
935
972
else :
936
973
raise Exception ('Exiting due to error: ' + self .__return_code_meanings [return_code ])
937
- if CmdInterface .__exit_on_error :
974
+ elif CmdInterface .__exit_on_error :
938
975
exit ()
939
976
940
- self .__log ['command' ]['return_code' ] = return_code
941
- if not silent :
942
- self .update_log ()
943
-
944
- if CmdInterface .__send_log :
945
- CmdInterface .send_telegram_logfile (
946
- message = 'END ' + self .__log ['command' ]['name' ] + '\n ' + self .__return_code_meanings [return_code ])
947
- elif CmdInterface .__send_end :
948
- CmdInterface .send_telegram_message (
949
- message = 'END ' + self .__log ['command' ]['name' ] + '\n ' + self .__return_code_meanings [return_code ])
950
-
951
- self .__log = CmdLog ()
952
977
return return_code
0 commit comments