From 49939f3eaa472a2d04aa9787799444c65a20732d Mon Sep 17 00:00:00 2001 From: Nick Sweeting Date: Tue, 16 Feb 2021 01:20:47 -0500 Subject: [PATCH] only accept stdin if args are not passed, fix stdin hang in docker --- archivebox/cli/archivebox_add.py | 6 +++++- archivebox/cli/archivebox_config.py | 5 ++++- archivebox/cli/archivebox_list.py | 5 ++--- archivebox/cli/archivebox_oneshot.py | 5 ++++- archivebox/cli/archivebox_remove.py | 5 ++++- archivebox/cli/archivebox_update.py | 5 ++++- archivebox/logging_util.py | 29 ++++++++++++++++++++++------ 7 files changed, 46 insertions(+), 14 deletions(-) diff --git a/archivebox/cli/archivebox_add.py b/archivebox/cli/archivebox_add.py index 41c7554d..7266a571 100644 --- a/archivebox/cli/archivebox_add.py +++ b/archivebox/cli/archivebox_add.py @@ -75,7 +75,11 @@ def main(args: Optional[List[str]]=None, stdin: Optional[IO]=None, pwd: Optional ) command = parser.parse_args(args or ()) urls = command.urls - stdin_urls = accept_stdin(stdin) + + stdin_urls = '' + if not urls: + stdin_urls = accept_stdin(stdin) + if (stdin_urls and urls) or (not stdin and not urls): stderr( '[X] You must pass URLs/paths to add via stdin or CLI arguments.\n', diff --git a/archivebox/cli/archivebox_config.py b/archivebox/cli/archivebox_config.py index f81286c6..25621972 100644 --- a/archivebox/cli/archivebox_config.py +++ b/archivebox/cli/archivebox_config.py @@ -45,7 +45,10 @@ def main(args: Optional[List[str]]=None, stdin: Optional[IO]=None, pwd: Optional help='KEY or KEY=VALUE formatted config values to get or set', ) command = parser.parse_args(args or ()) - config_options_str = accept_stdin(stdin) + + config_options_str = '' + if not command.config_options: + config_options_str = accept_stdin(stdin) config( config_options_str=config_options_str, diff --git a/archivebox/cli/archivebox_list.py b/archivebox/cli/archivebox_list.py index 7cfeeb95..1f2ee8c5 100644 --- a/archivebox/cli/archivebox_list.py +++ b/archivebox/cli/archivebox_list.py @@ -24,7 +24,7 @@ from ..index import ( get_corrupted_folders, get_unrecognized_folders, ) -from ..logging_util import SmartFormatter, accept_stdin, stderr +from ..logging_util import SmartFormatter, reject_stdin, stderr @docstring(list_all.__doc__) @@ -111,7 +111,7 @@ def main(args: Optional[List[str]]=None, stdin: Optional[IO]=None, pwd: Optional help='List only URLs matching these filter patterns.' ) command = parser.parse_args(args or ()) - filter_patterns_str = accept_stdin(stdin) + reject_stdin(stdin) if command.with_headers and not (command.json or command.html or command.csv): stderr( @@ -121,7 +121,6 @@ def main(args: Optional[List[str]]=None, stdin: Optional[IO]=None, pwd: Optional raise SystemExit(2) matching_folders = list_all( - filter_patterns_str=filter_patterns_str, filter_patterns=command.filter_patterns, filter_type=command.filter_type, status=command.status, diff --git a/archivebox/cli/archivebox_oneshot.py b/archivebox/cli/archivebox_oneshot.py index af68bac2..411cce8b 100644 --- a/archivebox/cli/archivebox_oneshot.py +++ b/archivebox/cli/archivebox_oneshot.py @@ -50,8 +50,11 @@ def main(args: Optional[List[str]]=None, stdin: Optional[IO]=None, pwd: Optional help= "Path to save the single archive folder to, e.g. ./example.com_archive" ) command = parser.parse_args(args or ()) + stdin_url = None url = command.url - stdin_url = accept_stdin(stdin) + if not url: + stdin_url = accept_stdin(stdin) + if (stdin_url and url) or (not stdin and not url): stderr( '[X] You must pass a URL/path to add via stdin or CLI arguments.\n', diff --git a/archivebox/cli/archivebox_remove.py b/archivebox/cli/archivebox_remove.py index cb073e95..dadf2654 100644 --- a/archivebox/cli/archivebox_remove.py +++ b/archivebox/cli/archivebox_remove.py @@ -61,7 +61,10 @@ def main(args: Optional[List[str]]=None, stdin: Optional[IO]=None, pwd: Optional help='URLs matching this filter pattern will be removed from the index.' ) command = parser.parse_args(args or ()) - filter_str = accept_stdin(stdin) + + filter_str = None + if not command.filter_patterns: + filter_str = accept_stdin(stdin) remove( filter_str=filter_str, diff --git a/archivebox/cli/archivebox_update.py b/archivebox/cli/archivebox_update.py index bf3c15f8..500d4c07 100644 --- a/archivebox/cli/archivebox_update.py +++ b/archivebox/cli/archivebox_update.py @@ -111,7 +111,10 @@ def main(args: Optional[List[str]]=None, stdin: Optional[IO]=None, pwd: Optional default="" ) command = parser.parse_args(args or ()) - filter_patterns_str = accept_stdin(stdin) + + filter_patterns_str = None + if not command.filter_patterns: + filter_patterns_str = accept_stdin(stdin) update( resume=command.resume, diff --git a/archivebox/logging_util.py b/archivebox/logging_util.py index f2b86735..2fbcbb35 100644 --- a/archivebox/logging_util.py +++ b/archivebox/logging_util.py @@ -62,22 +62,40 @@ class SmartFormatter(argparse.HelpFormatter): def reject_stdin(caller: str, stdin: Optional[IO]=sys.stdin) -> None: """Tell the user they passed stdin to a command that doesn't accept it""" - if stdin and not stdin.isatty(): - stdin_raw_text = stdin.read().strip() + if not stdin: + return None + + if IN_DOCKER: + # when TTY is disabled in docker we cant tell if stdin is being piped in or not + # if we try to read stdin when its not piped we will hang indefinitely waiting for it + return None + + if not stdin.isatty(): + # stderr('READING STDIN TO REJECT...') + stdin_raw_text = stdin.read() if stdin_raw_text: + # stderr('GOT STDIN!', len(stdin_str)) stderr(f'[X] The "{caller}" command does not accept stdin.', color='red') stderr(f' Run archivebox "{caller} --help" to see usage and examples.') stderr() raise SystemExit(1) + return None def accept_stdin(stdin: Optional[IO]=sys.stdin) -> Optional[str]: """accept any standard input and return it as a string or None""" + if not stdin: return None - elif stdin and not stdin.isatty(): - stdin_str = stdin.read().strip() - return stdin_str or None + + if not stdin.isatty(): + # stderr('READING STDIN TO ACCEPT...') + stdin_str = stdin.read() + + if stdin_str: + # stderr('GOT STDIN...', len(stdin_str)) + return stdin_str + return None @@ -174,7 +192,6 @@ def progress_bar(seconds: int, prefix: str='') -> None: def log_cli_command(subcommand: str, subcommand_args: List[str], stdin: Optional[str], pwd: str): - from .config import VERSION, ANSI cmd = ' '.join(('archivebox', subcommand, *subcommand_args)) stderr('{black}[i] [{now}] ArchiveBox v{VERSION}: {cmd}{reset}'.format( now=datetime.now().strftime('%Y-%m-%d %H:%M:%S'),