Potato.py

Check-in [0cbc3d8d14]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Merged changes to the output module from roster.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 0cbc3d8d14b32aba922ecd6b6975ea2ba19b211a2a4c747fed79a9d29d36f57b
User & Date: andy 2024-03-11 22:25:29
Context
2024-03-11
22:25
Added the abiltiy to "tryout" specific sample sites. check-in: 6ea4dd529e user: andy tags: trunk
22:25
Merged changes to the output module from roster. check-in: 0cbc3d8d14 user: andy tags: trunk
2024-02-27
00:44
Added a TODO about what needs to be done when printing site info. check-in: e4fc3f067a user: andy tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to potato/output.py.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97

98
99
100
101

102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
















117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
###
### output.py
### Printing fancy(er) output to stdout, stderr.
###
import shutil, sys, textwrap, time

class ANSIEscapeSeq():
    def __init__(self, seq):
        self.seq = seq

    def __str__(self):        
        return self.seq

class Colors():
    """
        Colors
        ~~~~~~

        Contains definitions of various ANSI colors sequences.
    """

    # Reset to default
    RESET = ANSIEscapeSeq("\u001b[0m")

    # Regular colors
    BLACK =   ANSIEscapeSeq("\u001b[0;30m")    
    RED =     ANSIEscapeSeq("\u001b[0;31m")
    GREEN =   ANSIEscapeSeq("\u001b[0;32m")
    YELLOW =  ANSIEscapeSeq("\u001b[0;33m")
    BLUE =    ANSIEscapeSeq("\u001b[0;34m")
    MAGENTA = ANSIEscapeSeq("\u001b[0;35m")
    CYAN =    ANSIEscapeSeq("\u001b[0;36m")
    WHITE =   ANSIEscapeSeq("\u001b[0;37m")

    # Bold colors/text
    BOLD_BLACK =   ANSIEscapeSeq("\u001b[1;30m")
    BOLD_RED =     ANSIEscapeSeq("\u001b[1;31m")
    BOLD_GREEN =   ANSIEscapeSeq("\u001b[1;32m")
    BOLD_YELLOW =  ANSIEscapeSeq("\u001b[1;33m")
    BOLD_BLUE =    ANSIEscapeSeq("\u001b[1;34m")
    BOLD_MAGENTA = ANSIEscapeSeq("\u001b[1;35m")
    BOLD_CYAN =    ANSIEscapeSeq("\u001b[1;36m")
    BOLD_WHITE =   ANSIEscapeSeq("\u001b[1;37m")

    # Underline color/text
    UL_BLACK =   ANSIEscapeSeq("\u001b[4;30m")
    UL_RED =     ANSIEscapeSeq("\u001b[4;31m")
    UL_GREEN =   ANSIEscapeSeq("\u001b[4;32m")
    UL_YELLOW =  ANSIEscapeSeq("\u001b[4;33m")
    UL_BLUE =    ANSIEscapeSeq("\u001b[4;34m")
    UL_MAGENTA = ANSIEscapeSeq("\u001b[4;35m")
    UL_CYAN =    ANSIEscapeSeq("\u001b[4;36m")
    UL_WHITE =   ANSIEscapeSeq("\u001b[4;37m")

    # High-intensity color/text
    HI_BLACK =   ANSIEscapeSeq("\u001b[0;90m")
    HI_RED =     ANSIEscapeSeq("\u001b[0;91m")
    HI_GREEN =   ANSIEscapeSeq("\u001b[0;92m")
    HI_YELLOW =  ANSIEscapeSeq("\u001b[0;93m")
    HI_BLUE =    ANSIEscapeSeq("\u001b[0;94m")
    HI_MAGENTA = ANSIEscapeSeq("\u001b[0;95m")
    HI_CYAN =    ANSIEscapeSeq("\u001b[0;96m")
    HI_WHITE =   ANSIEscapeSeq("\u001b[0;97m")

# Like _print_to_stream, but doesn't do any wrapping.
def _print_to_stream_raw(stream, *text, **kwargs):
    ttyoutput = stream.isatty()
    def get_text(t):
        if isinstance(t, ANSIEscapeSeq) and ttyoutput:
            return t.seq
        elif isinstance(t, ANSIEscapeSeq) and not ttyoutput:
            return ""
        else:
            # Allow use of %(BLACK), etc. in strings.
            kwargs.update(Colors.__dict__)
            return str(t).format(**kwargs)

    stream.write("".join([get_text(t) for t in text]))


def _print_to_stream(stream, *text, **kwargs):

    # Special-case the situation where we're just printing a newline.
    # Normally, textwrap.fill would eat up the newline.
    if len(text) == 1 and text[0] == "\n":
        stream.write('\n')
        stream.flush()
        return

    ttyoutput = stream.isatty()

    # Get the "text" of an element `t`. If `t` is an ANSIEscapeSeq this does the
    # right thing.
    def get_text(t):
        if isinstance(t, ANSIEscapeSeq) and ttyoutput:
            return t.seq
        elif isinstance(t, ANSIEscapeSeq) and not ttyoutput:

            return ""
        else:
            # Allow use of %(BLACK), etc. in strings.
            kwargs.update(Colors.__dict__)

            return str(t).format(**kwargs)


    s = "".join([get_text(t) for t in text])

    if(ttyoutput):        
        stream.write( textwrap.fill( s, shutil.get_terminal_size().columns ) )

        # textwrap.fill will eat up any trailing newline, so we print one if
        # there was one originally.
        if len(text) > 0 and isinstance(text[-1], str) and len(text[-1]) > 0 and text[-1][-1] == '\n':
            stream.write('\n')            
    else:
        # Not a TTY, don't bother to wrap, print as is.
        stream.write(s)

















def stdout(*text, **kwargs):
    """
        stdout(...)
        ~~~~~~~~~~~~

        Print all arguments to stdout, followed by a newline. Resets text 
        attributes to defaults after printing. 
        TTY.
    """
    stdout_n(*text, Colors.RESET, '\n', **kwargs)

def stderr(*text, **kwargs):
    """
        stderr(...)
        ~~~~~~~~~~~~

        Print all arguments to stdout, followed by a newline. Resets text 
        attributes to defaults after printing.
    """
    stderr_n(*text, Colors.RESET, '\n', **kwargs)

def stdout_n(*text, **kwargs):
    """
        stdout_n(...)
        ~~~~~~~~~~~~~

        Prints all arguments to stdout, *without* wrapping, adding a newline, or






<
<
<
<
<
<
<
<
<
|
<

<
<
<

|


|
|
|
|
|
|
|
|


|
|
|
|
|
|
|
|


|
|
|
|
|
|
|
|


|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
|
<

|
|















|
<
|
>
|

|
|
>
|




|









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>










|









|







1
2
3
4
5
6









7

8



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54







55

56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
###
### output.py
### Printing fancy(er) output to stdout, stderr.
###
import shutil, sys, textwrap, time










_colors = {





    # Reset to default
    "RESET" : ("\u001b[0m"),

    # Regular colors
    "BLACK" :   ("\u001b[0;30m"),    
    "RED" :     ("\u001b[0;31m"),
    "GREEN" :   ("\u001b[0;32m"),
    "YELLOW" :  ("\u001b[0;33m"),
    "BLUE" :    ("\u001b[0;34m"),
    "MAGENTA" : ("\u001b[0;35m"),
    "CYAN" :    ("\u001b[0;36m"),
    "WHITE" :   ("\u001b[0;37m"),

    # Bold colors/text
    "BOLD_BLACK" :   ("\u001b[1;30m"),
    "BOLD_RED" :     ("\u001b[1;31m"),
    "BOLD_GREEN" :   ("\u001b[1;32m"),
    "BOLD_YELLOW" :  ("\u001b[1;33m"),
    "BOLD_BLUE" :    ("\u001b[1;34m"),
    "BOLD_MAGENTA" : ("\u001b[1;35m"),
    "BOLD_CYAN" :    ("\u001b[1;36m"),
    "BOLD_WHITE" :   ("\u001b[1;37m"),

    # Underline color/text
    "UL_BLACK" :   ("\u001b[4;30m"),
    "UL_RED" :     ("\u001b[4;31m"),
    "UL_GREEN" :   ("\u001b[4;32m"),
    "UL_YELLOW" :  ("\u001b[4;33m"),
    "UL_BLUE" :    ("\u001b[4;34m"),
    "UL_MAGENTA" : ("\u001b[4;35m"),
    "UL_CYAN" :    ("\u001b[4;36m"),
    "UL_WHITE" :   ("\u001b[4;37m"),

    # High-intensity color/text
    "HI_BLACK" :   ("\u001b[0;90m"),
    "HI_RED" :     ("\u001b[0;91m"),
    "HI_GREEN" :   ("\u001b[0;92m"),
    "HI_YELLOW" :  ("\u001b[0;93m"),
    "HI_BLUE" :    ("\u001b[0;94m"),
    "HI_MAGENTA" : ("\u001b[0;95m"),
    "HI_CYAN" :    ("\u001b[0;96m"),
    "HI_WHITE" :   ("\u001b[0;97m"),
}

# A copy of the above with the values all set to the empty string, used when
# the output device is not a TTY.







_safe_colors = {}


for c in _colors:
    _safe_colors[c] = ""

def _print_to_stream(stream, *text, **kwargs):

    # Special-case the situation where we're just printing a newline.
    # Normally, textwrap.fill would eat up the newline.
    if len(text) == 1 and text[0] == "\n":
        stream.write('\n')
        stream.flush()
        return

    ttyoutput = stream.isatty()

    # Get the "text" of an element `t`. If `t` is an ANSIEscapeSeq this does the
    # right thing.
    def get_text(t):
        nonlocal ttyoutput

        if not ttyoutput:
            # Make {BLACK}, etc. be replaced with ""
            kwargs.update(**_safe_colors)
        else:
            # Allow use of {BLACK}, etc. in strings.
            kwargs.update(**_colors)

        return str(t).format(**kwargs)


    s = "".join([get_text(t) for t in text])

    if ttyoutput:        
        stream.write( textwrap.fill( s, shutil.get_terminal_size().columns ) )

        # textwrap.fill will eat up any trailing newline, so we print one if
        # there was one originally.
        if len(text) > 0 and isinstance(text[-1], str) and len(text[-1]) > 0 and text[-1][-1] == '\n':
            stream.write('\n')            
    else:
        # Not a TTY, don't bother to wrap, print as is.
        stream.write(s)

# Like _print_to_stream, but doesn't do any wrapping.
def _print_to_stream_raw(stream, *text, **kwargs):
    ttyoutput = stream.isatty()
    def get_text(t):
        nonlocal ttyoutput

        if ttyoutput:
            return str(t).format(**_colors)
        else:
            return str(t).format(**_safe_colors)

    stream.write("".join([get_text(t) for t in text]))




def stdout(*text, **kwargs):
    """
        stdout(...)
        ~~~~~~~~~~~~

        Print all arguments to stdout, followed by a newline. Resets text 
        attributes to defaults after printing. 
        TTY.
    """
    stdout_n(*text, "{RESET}", '\n', **kwargs)

def stderr(*text, **kwargs):
    """
        stderr(...)
        ~~~~~~~~~~~~

        Print all arguments to stdout, followed by a newline. Resets text 
        attributes to defaults after printing.
    """
    stderr_n(*text, "{RESET}", '\n', **kwargs)

def stdout_n(*text, **kwargs):
    """
        stdout_n(...)
        ~~~~~~~~~~~~~

        Prints all arguments to stdout, *without* wrapping, adding a newline, or