Skip to content

Commit 4f47515

Browse files
committed
Refactor silence mode and exceptions
1 parent 188b728 commit 4f47515

File tree

1 file changed

+68
-43
lines changed

1 file changed

+68
-43
lines changed

cmdint/CmdInterface.py

+68-43
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,16 @@ def __init__(self, command, static_logfile: str = None):
7171
self.__py_function_return = None
7272

7373
self.__nested = False
74+
self.__no_new_log = False
7475
self.__ignore_cmd_retval = False
76+
self.__silent = False
7577

7678
if not self.__is_py_function:
7779
command = command.strip()
7880
if CmdInterface.__use_installer:
7981
command += CmdInterface.__installer_command_suffix
8082
if len(command) == 0 or which(command) is None:
83+
print('Command not found: ' + command)
8184
raise OSError('Command not found: ' + command)
8285

8386
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):
257260
CmdInterface.__git_repos[path]['autocommit'] = autocommit
258261
CmdInterface.__check_repo(path)
259262
else:
263+
print('"' + path + '" is not a directory')
260264
raise NotADirectoryError('"' + path + '" is not a directory')
261265

262266
@staticmethod
@@ -310,6 +314,8 @@ def remove_arg(self, key: str):
310314
self.__check_output.remove(self.__options[key])
311315
del self.__options[key]
312316
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.')
313319
raise ValueError('No argument with specified keyword found! Arguments without keyword cannot be removed. '
314320
'Create a new instance of CmdInterface in this case.')
315321

@@ -333,6 +339,7 @@ def add_arg(self,
333339
return
334340
if self.__is_py_function:
335341
if key is None:
342+
print('Only arguments with keyword are allowed when executing python functions!')
336343
raise ValueError('Only arguments with keyword are allowed when executing python functions!')
337344

338345
if check_input:
@@ -471,17 +478,19 @@ def __log_start(self) -> datetime:
471478
self.__log['command']['time']['start'] = start_time.strftime("%Y-%m-%d %H:%M:%S")
472479
self.__log['command']['time']['utc_offset'] = time.localtime().tm_gmtoff
473480
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:
475482
CmdInterface.send_telegram_message('START ' + self.__log['command']['name'])
476483
return start_time
477484

478-
def __log_end(self, start_time: datetime) -> datetime:
485+
def __log_end(self, start_time: datetime, return_code: int) -> datetime:
479486
"""
480487
Log end time and duration of command execution:
481488
['command']['time']['end']
482489
['command']['time']['duration']
483490
Return end time.
484491
"""
492+
493+
# set times
485494
end_time = datetime.now()
486495
self.__log['command']['time']['end'] = end_time.strftime("%Y-%m-%d %H:%M:%S")
487496

@@ -493,7 +502,22 @@ def __log_end(self, start_time: datetime) -> datetime:
493502
minutes, seconds = divmod(remainder, 60)
494503
duration_formatted = '%d:%02d:%02d' % (hours, minutes, seconds)
495504
self.__log['command']['time']['duration'] = duration_formatted
505+
506+
# log end messages & return code
496507
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+
497521
return end_time
498522

499523
def log_message(self, message: str, via_telegram: bool = False):
@@ -507,15 +531,15 @@ def log_message(self, message: str, via_telegram: bool = False):
507531
if via_telegram:
508532
CmdInterface.send_telegram_message(message)
509533

510-
def __pyfunction_to_log(self, silent: bool = False):
534+
def __pyfunction_to_log(self):
511535
"""
512536
Run python function and store terminal output in log (['command']['text_output']).
513537
"""
514538
original_stdout = sys.stdout
515539
original_stderr = sys.stderr
516540
sys.stdout = sys.stderr = out_string = io.StringIO()
517541

518-
if silent:
542+
if self.__silent:
519543

520544
try:
521545
self.__no_key_options[0](*self.__no_key_options[1:], **self.__options)
@@ -555,11 +579,11 @@ def __pyfunction_to_log(self, silent: bool = False):
555579
if exception is not None:
556580
raise exception
557581

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):
559583
"""
560584
Run command line tool and store output in log.
561585
"""
562-
if silent:
586+
if self.__silent:
563587
retval = subprocess.call(run_string,
564588
shell=True,
565589
stdout=open(os.devnull, 'wb'),
@@ -661,7 +685,7 @@ def update_log(self):
661685
"""
662686
Replace last entry of the json logfile by log of current instance.
663687
"""
664-
if CmdInterface.__logfile_name is None:
688+
if CmdInterface.__logfile_name is None or self.__no_new_log:
665689
return
666690
self.__log['command']['return_code_meaning'] = self.__return_code_meanings[self.__log['command']['return_code']]
667691
self.__log['cmd_interface']['repositories'] = CmdInterface.__git_repos
@@ -682,7 +706,7 @@ def append_log(self):
682706
"""
683707
Append log of current instance to the output json file. Creates new json if it does not exist.
684708
"""
685-
if CmdInterface.__logfile_name is None:
709+
if CmdInterface.__logfile_name is None or self.__no_new_log:
686710
return
687711
self.__log['command']['return_code_meaning'] = self.__return_code_meanings[self.__log['command']['return_code']]
688712
self.__log['cmd_interface']['repositories'] = CmdInterface.__git_repos
@@ -830,9 +854,10 @@ def run(self, version_arg: str = None,
830854

831855
# check if run has been called recoursively (CmdInterface inside of CmdInterface)
832856
self.__nested = False
833-
user_silent = silent
857+
self.__no_new_log = silent
858+
self.__silent = silent
834859
if CmdInterface.__called:
835-
silent = True
860+
self.__no_new_log = True
836861
self.__nested = True
837862
CmdInterface.__called = True
838863

@@ -873,8 +898,7 @@ def run(self, version_arg: str = None,
873898
self.__log['command']['run_string'] = run_string
874899

875900
start_time = self.__log_start()
876-
if not silent:
877-
self.append_log()
901+
self.append_log()
878902

879903
exception = None
880904
if run_necessary and run_possible:
@@ -883,11 +907,10 @@ def run(self, version_arg: str = None,
883907
try:
884908
# run command
885909
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
887911
else:
888912
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
891914

892915
# check if output was produced as expected
893916
missing_output = CmdInterface.check_exist(check_output)
@@ -900,10 +923,33 @@ def run(self, version_arg: str = None,
900923
# everything went as expected
901924
self.__log['command']['output']['found'] = CmdInterface.get_file_hashes(check_output)
902925
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))
903944
except Exception as err:
904945
return_code = -3
905946
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))
907953

908954
elif not run_necessary:
909955
self.log_message('Skipping execution. All output files already present.')
@@ -912,41 +958,20 @@ def run(self, version_arg: str = None,
912958
self.log_message('Skipping execution. Input files missing: ' + str(missing_inputs))
913959
exception = MissingInputError(missing_inputs)
914960

915-
# end logging
916-
self.__log_end(start_time)
917-
918961
if not self.__nested:
919962
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()
925963

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:
932969
if CmdInterface.__throw_on_error or self.__nested:
933970
if exception is not None:
934971
raise exception
935972
else:
936973
raise Exception('Exiting due to error: ' + self.__return_code_meanings[return_code])
937-
if CmdInterface.__exit_on_error:
974+
elif CmdInterface.__exit_on_error:
938975
exit()
939976

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()
952977
return return_code

0 commit comments

Comments
 (0)