Exemple #1
0
    def update(self, *data) -> None:
        di.instances = {}
        original(*data)
        screen = self.screen
        blocks = list(
            filter(lambda b: b.get("val") is not None, [{
                **block,
                **{
                    "val": di.get(block.get("val"))
                }
            } for block in self.status_blocks]))

        status_len = sum(
            [len(b.get('del')) + len(b.get('val')) + 2 for b in blocks])
        self.screen.cursor.bg = as_rgb(color_as_int(self.draw_data.default_bg))
        self.screen.draw(' ' * (screen.columns - screen.cursor.x - status_len))

        for block in blocks:
            bg = color_as_int(to_color(block.get('bg')))
            self.screen.cursor.fg = screen.cursor.bg
            self.screen.cursor.bg = as_rgb(bg)
            screen.draw(block.get("del"))
            fg = color_as_int(to_color(block.get("fg")))
            self.screen.cursor.fg = as_rgb(fg)
            screen.draw(" " + block.get("val") + " ")
Exemple #2
0
def set_default_colors(fg=None, bg=None):
    ans = ''
    if fg is None:
        ans += '\x1b]110\x1b\\'
    else:
        ans += '\x1b]10;{}\x1b\\'.format(color_as_sharp(to_color(fg)))
    if bg is None:
        ans += '\x1b]111\x1b\\'
    else:
        ans += '\x1b]11;{}\x1b\\'.format(color_as_sharp(to_color(bg)))
    return ans
Exemple #3
0
def set_default_colors(fg=None, bg=None) -> str:
    ans = ''
    if fg is None:
        ans += '\x1b]110\x1b\\'
    else:
        ans += '\x1b]10;{}\x1b\\'.format(
            color_as_sharp(fg if isinstance(fg, Color) else to_color(fg)))
    if bg is None:
        ans += '\x1b]111\x1b\\'
    else:
        ans += '\x1b]11;{}\x1b\\'.format(
            color_as_sharp(bg if isinstance(bg, Color) else to_color(bg)))
    return ans
Exemple #4
0
    def test_to_color(self):
        for x in 'xxx #12 #1234 rgb:a/b'.split():
            self.assertIsNone(to_color(x))

        def c(spec, r=0, g=0, b=0, a=0):
            c = to_color(spec)
            self.ae(c.red, r)
            self.ae(c.green, g)
            self.ae(c.blue, b)
            self.ae(c.alpha, a)

        c('#eee', 0xee, 0xee, 0xee)
        c('#234567', 0x23, 0x45, 0x67)
        c('#abcabcdef', 0xab, 0xab, 0xde)
        c('rgb:e/e/e', 0xee, 0xee, 0xee)
        c('rgb:23/45/67', 0x23, 0x45, 0x67)
        c('rgb:abc/abc/def', 0xab, 0xab, 0xde)
        c('red', 0xff)
        self.ae(int(Color(1, 2, 3)), 0x10203)
        base = Color(12, 12, 12)
        a = Color(23, 23, 23)
        b = Color(100, 100, 100)
        self.assertLess(base.contrast(a), base.contrast(b))
        self.ae(Color(1, 2, 3).as_sgr, ':2:1:2:3')
        self.ae(Color(1, 2, 3).as_sharp, '#010203')
        self.ae(Color(1, 2, 3, 4).as_sharp, '#04010203')
        self.ae(Color(1, 2, 3, 4).rgb, 0x10203)
Exemple #5
0
 def item(which, num):
     nonlocal ans
     if which is None:
         ans += '\x1b]1{}\x1b\\'.format(num)
     else:
         ans += '\x1b]{};{}\x1b\\'.format(
             num,
             color_as_sharp(
                 which if isinstance(which, Color) else to_color(which)))
Exemple #6
0
 def item(which: Optional[Union[Color, str]], num: int) -> None:
     nonlocal ans
     if which is None:
         ans += '\x1b]1{}\x1b\\'.format(num)
     else:
         if isinstance(which, Color):
             q = color_as_sharp(which)
         else:
             x = to_color(which)
             assert x is not None
             q = color_as_sharp(x)
         ans += '\x1b]{};{}\x1b\\'.format(num, q)
Exemple #7
0
    def test_to_color(self):
        for x in 'xxx #12 #1234 rgb:a/b'.split():
            self.assertIsNone(to_color(x))

        def c(spec, r=0, g=0, b=0):
            self.ae(tuple(to_color(spec)), (r, g, b))

        c('#eee', 0xee, 0xee, 0xee)
        c('#234567', 0x23, 0x45, 0x67)
        c('#abcabcdef', 0xab, 0xab, 0xde)
        c('rgb:e/e/e', 0xee, 0xee, 0xee)
        c('rgb:23/45/67', 0x23, 0x45, 0x67)
        c('rgb:abc/abc/def', 0xab, 0xab, 0xde)
        c('red', 0xff)
Exemple #8
0
def parse_colors(args: ArgsType) -> Dict[str, Optional[int]]:
    ans: Dict[str, Optional[int]] = {}
    for spec in args:
        key, val = spec.split('=', 1)
        key = key.lower()
        if key.lower() not in valid_color_names:
            raise KeyError(f'{key} is not a valid color name')
        if val.lower() == 'none':
            col: Optional[int] = None
        else:
            q = to_color(val, validate=True)
            if q is not None:
                col = int(q)
        ans[key.lower()] = col
    return ans
Exemple #9
0
 def c(spec, r=0, g=0, b=0):
     self.ae(tuple(to_color(spec)), (r, g, b))
Exemple #10
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()
Exemple #11
0
 def c(spec, r=0, g=0, b=0, a=0):
     c = to_color(spec)
     self.ae(c.red, r)
     self.ae(c.green, g)
     self.ae(c.blue, b)
     self.ae(c.alpha, a)