Beispiel #1
0
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()
Beispiel #2
0
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)