Skip to content
srccircumflex edited this page Apr 21, 2024 · 15 revisions

Getting started with the VT-Python

(Everything) around the ANSI-Escape-Sequences

packet iodata

Work with SGR-styled strings

Import needed things:

>>> from vtframework.iodata.sgr import SGRWrap, Fore, Ground, BOLD
>>> from vtframework.iodata.esccontainer import EscSegment
module sgrmodule esccontainer

These modifications to the emulator are mostly required by the Windows cmd and have no effect under Linux:

>>> from vtframework.iosys.vtermios import mod_ansiout
>>> mod_ansiout()
module vtermios

Wrap string components and join them together:

>>> seq =  SGRWrap("< ", Fore.red_rel)
<SGRWrap ('\x1b[31m':'< ':'\x1b[m') l/el=2:8>
>>> seq += SGRWrap("VT", Fore.blue + Ground.hex("FFCE51"))
>>> seq += "-"
>>> seq += SGRWrap("Python", Fore.name("PaleGreen") + Ground.blue + BOLD)
>>> seq += SGRWrap(" > ", Fore.red_rel)
>>> seq += " chars written: "
<EscContainer: [<SGRWrap ('\x1b[31m':'< ':'\x1b[m') l/el=2:8>, <SGRWrap ('\x1b[38;2;0;0;255;48;2;255;206;81m':'VT':'\x1b[m') l/el=2:34>, <EscSegment ('':'-':'') l/el=1:0>, <SGRWrap ('\x1b[38;2;152;251;152;48;2;0;0;255;1m':'Python':'\x1b[m') l/el=6:37>, <SGRWrap ('\x1b[31m':' > ':'\x1b[m') l/el=3:8>, <EscSegment ('':' chars written: ':'') l/el=16:0>]>
>>> from sys import stdout
>>> stdout.write(seq)
printed_sgr1.png
>>> len(seq)
30

Slice and modify the styled string:

>>> stdout.write(seq[:3] + "ideo" + seq[3:4] + "erminal" + seq[4:])
printed_sgr2.png

Framing:

>>> from vtframework.iodata.esccontainer import EscContainer
>>> seq = EscSegment("|%+42s| ") % seq
>>> # WARNING: Properties of EscContainer will be finally lost during fstring formatting!
>>> len(seq)
132
>>> isinstance(seq, (EscSegment, EscContainer))
False
>>> stdout.write(seq)
printed_sgr3.png

Simply create hidden inputs

module vtermios
>>> def password_input():
...     mod = mod_nonecho()
...     password = input("Enter your password: ")
...     mod.reset()
...     print(password)
...
>>> password_input()
Enter your password: ░
...
Enter your password: my super secure password
>>> █

Use the power of ANSI escape sequences to hypnotize

SGRHypno.gif

examples

First, we want to

Find out the current color configurations of the color table entries

[ ! ] Curiously, these sequences are not processed by the Windows cmd, nor the reset sequences, although the sequences for changing a color entry are officially supported.

Importing the required things from the framework:

>>> from vtframework.iodata.requests import RequestOSColor
>>> from vtframework.iodata.replies import ReplyOSColor
>>> from vtframework.io import Input
>>> from vtframework.iosys.vtermios import mod_ansiout, mod_ansiin
module requestsmodule repliesmodule iomodule vtermios

Now we modify the emulator,

>>> mod_ansiout()
>>> mod_ansiin()

create a container for the replies,

>>> color_slot_replies: dict[str, str | ReplyOSColor] = {
...     "*env*fore": "",
...     "*env*ground": "",
...     "|env|cursor": "",
...     "black": "",
...     "red": "",
...     "green": "",
...     "yellow": "",
...     "blue": "",
...     "magenta": "",
...     "cyan": "",
...     "white": "",
...     "#black": "",
...     "#red": "",
...     "#green": "",
...     "#yellow": "",
...     "#blue": "",
...     "#magenta": "",
...     "#cyan": "",
...     "#white": "",
... }

and iterate through the values:

>>> with Input() as _input_:
...
...     for slot in color_slot_replies:
...         if slot[0] == "*":
...             RequestOSColor.environment(fore=slot.endswith("fore")).out()
...         elif slot[0] == "|":
...             RequestOSColor.cursor().out()
...         elif slot[0] == "#":
...             RequestOSColor.rel(slot[1:], bright_version=True).out()
...         else:
...             RequestOSColor.rel(slot).out()
...
...         color_slot_replies[slot] = _input_.read(block=False, smoothness=.04, flush_io=True)

Let's display the results:

>>> for i in color_slot_replies.items():
...    print("%-16s%r" % i)
*env*fore       <ReplyOSColor('\x1b]10;rgb:d3d3/d7d7/cfcf\x1b\\', TARGET=10, R=211, G=215, B=207)>
*env*ground     <ReplyOSColor('\x1b]11;rgb:2e2e/3434/3636\x1b\\', TARGET=11, R=46, G=52, B=54)>
|env|cursor     <ReplyOSColor('\x1b]12;rgb:d3d3/d7d7/cfcf\x1b\\', TARGET=12, R=211, G=215, B=207)>
black           <ReplyOSColor('\x1b]4;0;rgb:0000/0000/0000\x1b\\', TARGET=0, R=0, G=0, B=0)>
red             <ReplyOSColor('\x1b]4;1;rgb:cdcd/0000/0000\x1b\\', TARGET=-1, R=205, G=0, B=0)>
green           <ReplyOSColor('\x1b]4;2;rgb:0000/cdcd/0000\x1b\\', TARGET=-2, R=0, G=205, B=0)>
yellow          <ReplyOSColor('\x1b]4;3;rgb:cdcd/cdcd/0000\x1b\\', TARGET=-3, R=205, G=205, B=0)>
blue            <ReplyOSColor('\x1b]4;4;rgb:0000/0000/eeee\x1b\\', TARGET=-4, R=0, G=0, B=238)>
magenta         <ReplyOSColor('\x1b]4;5;rgb:cdcd/0000/cdcd\x1b\\', TARGET=-5, R=205, G=0, B=205)>
cyan            <ReplyOSColor('\x1b]4;6;rgb:0000/cdcd/cdcd\x1b\\', TARGET=-6, R=0, G=205, B=205)>
white           <ReplyOSColor('\x1b]4;7;rgb:e5e5/e5e5/e5e5\x1b\\', TARGET=-7, R=229, G=229, B=229)>
#black          <ReplyOSColor('\x1b]4;8;rgb:7f7f/7f7f/7f7f\x1b\\', TARGET=-8, R=127, G=127, B=127)>
#red            <ReplyOSColor('\x1b]4;9;rgb:ffff/0000/0000\x1b\\', TARGET=-9, R=255, G=0, B=0)>
#green          <ReplyOSColor('\x1b]4;10;rgb:0000/ffff/0000\x1b\\', TARGET=-10, R=0, G=255, B=0)>
#yellow         <ReplyOSColor('\x1b]4;11;rgb:ffff/ffff/0000\x1b\\', TARGET=-11, R=255, G=255, B=0)>
#blue           <ReplyOSColor('\x1b]4;12;rgb:5c5c/5c5c/ffff\x1b\\', TARGET=-12, R=92, G=92, B=255)>
#magenta        <ReplyOSColor('\x1b]4;13;rgb:ffff/0000/ffff\x1b\\', TARGET=-13, R=255, G=0, B=255)>
#cyan           <ReplyOSColor('\x1b]4;14;rgb:0000/ffff/ffff\x1b\\', TARGET=-14, R=0, G=255, B=255)>
#white          <ReplyOSColor('\x1b]4;15;rgb:ffff/ffff/ffff\x1b\\', TARGET=-15, R=255, G=255, B=255)>

Now we start the

Hypnotizing Algorithm

First we need a few things from the standard library,

>>> from time import sleep
>>> import atexit
>>> from random import shuffle, randint

from the framework,

>>> from vtframework.iodata.decpm import ScreenAlternateBuffer
>>> from vtframework.iodata.cursor import CursorNavigate, CursorStyle
>>> from vtframework.iodata.os import OSColorControl, WindowManipulation
module decpmmodule cursormodule os

and the demo package.

>>> from _demo.sgr_lookup_tui import SGRLookUp
demo sgr_lookup_tui

The emulator is still modified accordingly, but can be run again.

>>> mod_ansiout()
>>> mod_ansiin()

We choose a collection of colors and shuffle them.

>>> colors = [
>>>     "MediumSpringGreen",
>>>     "#CCFF00",
>>>     (12, 234, 22),
>>>     "DeepPink1",
>>>     "LightGoldenrodYellow",
>>>     (12, 234, 22),
>>>     "MediumOrchid",
>>>     "#0035FF",
>>>     "#FF2900",
>>>     (12, 234, 22),
>>> ]
>>> shuffle(colors)

The colors of the emulator environment and the color table are to be changed with each step of a spiral cursor movement.

For this we write a function,

>>> colors_max_index = len(colors) - 1
>>> def change_colors():
...     _ = OSColorControl.set_environment_color(
...         fore=colors[randint(0, colors_max_index)],
...         back=colors[randint(0, colors_max_index)]
...     ).out()
...     for slot in (
...             "black",
...             "red",
...             "green",
...             "yellow",
...             "blue",
...             "magenta",
...             "cyan",
...             "white"
...     ):
...         _ = OSColorControl.set_rel_color(slot, colors[randint(0, colors_max_index)]).out()
...     sleep(.01)

and a main loop:

>>> def main_loop(iterations):
...     for cur_col in colors[:iterations]:
...         _ = OSColorControl.set_cursor_color(cur_col).out()
...         CursorNavigate.position(13, 4).out()
...         for i in range(1, 9):
...             change_colors()
...             if i % 2:
...                 for _ in range(i * 2):
...                     _ = CursorNavigate.forward().out()
...                     change_colors()
...                 for _ in range(i):
...                     _ = CursorNavigate.down().out()
...                     change_colors()
...             else:
...                 for _ in range(i * 2):
...                     _ = CursorNavigate.back().out()
...                     change_colors()
...                 for _ in range(i):
...                     _ = CursorNavigate.up().out()
...                     change_colors()

And now, let's enter the alternative buffer and start the gibberish.

>>> try:
...     alt_buffer = ScreenAlternateBuffer()
...     alt_buffer.highout()
...     _ = CursorStyle.steady_block().out()
...     _ = atexit.register(lambda *_: CursorStyle.blinking_block().out())
...     _ = CursorNavigate.position().out()
...     for rcs in SGRLookUp.lookup_rel():
...         print(rcs)
...     sleep(2)
...     _ = WindowManipulation.resize(30, 10).out()
...     main_loop(3)
... finally:
...     _ = OSColorControl.reset_cursor_color().out()
...     _ = OSColorControl.reset_environment_color().out()
...     _ = OSColorControl.reset_rel_color().out()
...     _ = CursorNavigate.position(0, 9).out()
...     sleep(.2)
...     _ = WindowManipulation.resize(80, 24).out()
...     sleep(2)
...     alt_buffer.lowout()
Clone this wiki locally