def main(args: List[str] = sys.argv) -> None: global can_transfer_with_files cli_opts, items_ = parse_args(args[1:], options_spec, usage, help_text, f'{appname} +kitten icat', result_class=IcatCLIOptions) items: List[Union[str, bytes]] = list(items_) if cli_opts.print_window_size: screen_size_function.cache_clear() with open(os.ctermid()) as tty: try: fd = tty.fileno() except AttributeError: # use default value for fd if ctermid is not available fd = None ss = screen_size_function(fd)() print(f'{ss.width}x{ss.height}', end='') raise SystemExit(0) if not sys.stdout.isatty(): sys.stdout = open(os.ctermid(), 'w') stdin_data = None if cli_opts.stdin == 'yes' or (cli_opts.stdin == 'detect' and sys.stdin is not None and not sys.stdin.isatty()): stdin_data = sys.stdin.buffer.read() if stdin_data: items.insert(0, stdin_data) sys.stdin.close() sys.stdin = open(os.ctermid()) screen_size = get_screen_size_function() signal.signal(signal.SIGWINCH, lambda signum, frame: setattr(screen_size, 'changed', True)) if screen_size().width == 0: if cli_opts.detect_support: raise SystemExit(1) raise SystemExit( 'Terminal does not support reporting screen sizes via the TIOCGWINSZ ioctl' ) parsed_opts = ParsedOpts() if cli_opts.place: try: parsed_opts.place = parse_place(cli_opts.place) except Exception: raise SystemExit( f'Not a valid place specification: {cli_opts.place}') try: parsed_opts.z_index = parse_z_index(cli_opts.z_index) except Exception: raise SystemExit( f'Not a valid z-index specification: {cli_opts.z_index}') if cli_opts.background != 'none': ra = to_color(cli_opts.background) if ra is None: raise SystemExit( f'Not a valid color specification: {cli_opts.background}') parsed_opts.remove_alpha = ra.as_sharp parsed_opts.flip = cli_opts.mirror in ('both', 'vertical') parsed_opts.flop = cli_opts.mirror in ('both', 'horizontal') if cli_opts.detect_support: if not detect_support(wait_for=cli_opts.detection_timeout, silent=True): raise SystemExit(1) print('file' if can_transfer_with_files else 'stream', end='', file=sys.stderr) return if cli_opts.transfer_mode == 'detect': if not detect_support(wait_for=cli_opts.detection_timeout, silent=cli_opts.silent): raise SystemExit( 'This terminal emulator does not support the graphics protocol, use a terminal emulator such as kitty that does support it' ) else: can_transfer_with_files = cli_opts.transfer_mode == 'file' errors = [] if cli_opts.clear: sys.stdout.write(clear_images_on_screen(delete_data=True)) if not items: return if not items: raise SystemExit('You must specify at least one file to cat') if parsed_opts.place: if len(items) > 1 or (isinstance(items[0], str) and os.path.isdir(items[0])): raise SystemExit( f'The --place option can only be used with a single image, not {items}' ) sys.stdout.buffer.write(b'\0337') # save cursor url_pat = re.compile(r'(?:https?|ftp)://', flags=re.I) def hold_if_needed(exit_code_or_msg: Union[int, str]) -> None: if cli_opts.hold: if isinstance(exit_code_or_msg, str): print(exit_code_or_msg, file=sys.stderr, flush=True) exit_code_or_msg = 1 with open(os.ctermid()) as tty, raw_mode(tty.fileno()): tty.buffer.read(1) raise SystemExit(exit_code_or_msg) for item in items: try: process_single_item(item, cli_opts, parsed_opts, url_pat) except NoImageMagick as e: hold_if_needed(str(e)) except OutdatedImageMagick as e: print(e.detailed_error, file=sys.stderr) hold_if_needed(str(e)) except ConvertFailed as e: hold_if_needed(str(e)) except OpenFailed as e: errors.append(e) if parsed_opts.place: sys.stdout.buffer.write(b'\0338') # restore cursor if errors: for err in errors: print(err, file=sys.stderr) hold_if_needed(1 if errors else 0) raise SystemExit()
def main(args: List[str] = sys.argv) -> None: global can_transfer_with_files cli_opts, items_ = parse_args(args[1:], options_spec, usage, help_text, '{} +kitten icat'.format(appname), result_class=IcatCLIOptions) items: List[Union[str, bytes]] = list(items_) if cli_opts.print_window_size: screen_size_function.cache_clear() with open(os.ctermid()) as tty: ss = screen_size_function(tty)() print('{}x{}'.format(ss.width, ss.height), end='') raise SystemExit(0) if not sys.stdout.isatty(): sys.stdout = open(os.ctermid(), 'w') stdin_data = None if cli_opts.stdin == 'yes' or (not sys.stdin.isatty() and cli_opts.stdin == 'detect'): stdin_data = sys.stdin.buffer.read() if stdin_data: items.insert(0, stdin_data) sys.stdin.close() sys.stdin = open(os.ctermid(), 'r') screen_size = get_screen_size_function() signal.signal(signal.SIGWINCH, lambda signum, frame: setattr(screen_size, 'changed', True)) if screen_size().width == 0: if cli_opts.detect_support: raise SystemExit(1) raise SystemExit( 'Terminal does not support reporting screen sizes via the TIOCGWINSZ ioctl' ) parsed_opts = ParsedOpts() if cli_opts.place: try: parsed_opts.place = parse_place(cli_opts.place) except Exception: raise SystemExit('Not a valid place specification: {}'.format( cli_opts.place)) try: parsed_opts.z_index = parse_z_index(cli_opts.z_index) except Exception: raise SystemExit('Not a valid z-index specification: {}'.format( cli_opts.z_index)) if cli_opts.detect_support: if not detect_support(wait_for=cli_opts.detection_timeout, silent=True): raise SystemExit(1) print('file' if can_transfer_with_files else 'stream', end='', file=sys.stderr) return if cli_opts.transfer_mode == 'detect': if not detect_support(wait_for=cli_opts.detection_timeout, silent=cli_opts.silent): raise SystemExit( 'This terminal emulator does not support the graphics protocol, use a terminal emulator such as kitty that does support it' ) else: can_transfer_with_files = cli_opts.transfer_mode == 'file' errors = [] if cli_opts.clear: sys.stdout.write(clear_images_on_screen(delete_data=True)) if not items: return if not items: raise SystemExit('You must specify at least one file to cat') if parsed_opts.place: if len(items) > 1 or (isinstance(items[0], str) and os.path.isdir(items[0])): raise SystemExit( f'The --place option can only be used with a single image, not {items}' ) sys.stdout.buffer.write(b'\0337') # save cursor url_pat = re.compile(r'(?:https?|ftp)://', flags=re.I) for item in items: try: process_single_item(item, cli_opts, parsed_opts, url_pat) except NoImageMagick as e: raise SystemExit(str(e)) except ConvertFailed as e: raise SystemExit(str(e)) except OpenFailed as e: errors.append(e) if parsed_opts.place: sys.stdout.buffer.write(b'\0338') # restore cursor if errors: for err in errors: print(err, file=sys.stderr) if cli_opts.hold: with open(os.ctermid()) as tty: with raw_mode(tty.fileno()): tty.buffer.read(1) raise SystemExit(1 if errors else 0)