1*4882a593Smuzhiyun# Copyright (c) 2016 Google, Inc 2*4882a593Smuzhiyun# 3*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0+ 4*4882a593Smuzhiyun# 5*4882a593Smuzhiyun# Terminal output logging. 6*4882a593Smuzhiyun# 7*4882a593Smuzhiyun 8*4882a593Smuzhiyunimport sys 9*4882a593Smuzhiyun 10*4882a593Smuzhiyunimport terminal 11*4882a593Smuzhiyun 12*4882a593Smuzhiyun# Output verbosity levels that we support 13*4882a593SmuzhiyunERROR = 0 14*4882a593SmuzhiyunWARNING = 1 15*4882a593SmuzhiyunNOTICE = 2 16*4882a593SmuzhiyunINFO = 3 17*4882a593SmuzhiyunDEBUG = 4 18*4882a593Smuzhiyun 19*4882a593Smuzhiyun""" 20*4882a593SmuzhiyunThis class handles output of progress and other useful information 21*4882a593Smuzhiyunto the user. It provides for simple verbosity level control and can 22*4882a593Smuzhiyunoutput nothing but errors at verbosity zero. 23*4882a593Smuzhiyun 24*4882a593SmuzhiyunThe idea is that modules set up an Output object early in their years and pass 25*4882a593Smuzhiyunit around to other modules that need it. This keeps the output under control 26*4882a593Smuzhiyunof a single class. 27*4882a593Smuzhiyun 28*4882a593SmuzhiyunPublic properties: 29*4882a593Smuzhiyun verbose: Verbosity level: 0=silent, 1=progress, 3=full, 4=debug 30*4882a593Smuzhiyun""" 31*4882a593Smuzhiyundef __enter__(): 32*4882a593Smuzhiyun return 33*4882a593Smuzhiyun 34*4882a593Smuzhiyundef __exit__(unused1, unused2, unused3): 35*4882a593Smuzhiyun """Clean up and remove any progress message.""" 36*4882a593Smuzhiyun ClearProgress() 37*4882a593Smuzhiyun return False 38*4882a593Smuzhiyun 39*4882a593Smuzhiyundef UserIsPresent(): 40*4882a593Smuzhiyun """This returns True if it is likely that a user is present. 41*4882a593Smuzhiyun 42*4882a593Smuzhiyun Sometimes we want to prompt the user, but if no one is there then this 43*4882a593Smuzhiyun is a waste of time, and may lock a script which should otherwise fail. 44*4882a593Smuzhiyun 45*4882a593Smuzhiyun Returns: 46*4882a593Smuzhiyun True if it thinks the user is there, and False otherwise 47*4882a593Smuzhiyun """ 48*4882a593Smuzhiyun return stdout_is_tty and verbose > 0 49*4882a593Smuzhiyun 50*4882a593Smuzhiyundef ClearProgress(): 51*4882a593Smuzhiyun """Clear any active progress message on the terminal.""" 52*4882a593Smuzhiyun if verbose > 0 and stdout_is_tty: 53*4882a593Smuzhiyun _stdout.write('\r%s\r' % (" " * len (_progress))) 54*4882a593Smuzhiyun _stdout.flush() 55*4882a593Smuzhiyun 56*4882a593Smuzhiyundef Progress(msg, warning=False, trailer='...'): 57*4882a593Smuzhiyun """Display progress information. 58*4882a593Smuzhiyun 59*4882a593Smuzhiyun Args: 60*4882a593Smuzhiyun msg: Message to display. 61*4882a593Smuzhiyun warning: True if this is a warning.""" 62*4882a593Smuzhiyun ClearProgress() 63*4882a593Smuzhiyun if verbose > 0: 64*4882a593Smuzhiyun _progress = msg + trailer 65*4882a593Smuzhiyun if stdout_is_tty: 66*4882a593Smuzhiyun col = _color.YELLOW if warning else _color.GREEN 67*4882a593Smuzhiyun _stdout.write('\r' + _color.Color(col, _progress)) 68*4882a593Smuzhiyun _stdout.flush() 69*4882a593Smuzhiyun else: 70*4882a593Smuzhiyun _stdout.write(_progress + '\n') 71*4882a593Smuzhiyun 72*4882a593Smuzhiyundef _Output(level, msg, color=None): 73*4882a593Smuzhiyun """Output a message to the terminal. 74*4882a593Smuzhiyun 75*4882a593Smuzhiyun Args: 76*4882a593Smuzhiyun level: Verbosity level for this message. It will only be displayed if 77*4882a593Smuzhiyun this as high as the currently selected level. 78*4882a593Smuzhiyun msg; Message to display. 79*4882a593Smuzhiyun error: True if this is an error message, else False. 80*4882a593Smuzhiyun """ 81*4882a593Smuzhiyun if verbose >= level: 82*4882a593Smuzhiyun ClearProgress() 83*4882a593Smuzhiyun if color: 84*4882a593Smuzhiyun msg = _color.Color(color, msg) 85*4882a593Smuzhiyun _stdout.write(msg + '\n') 86*4882a593Smuzhiyun 87*4882a593Smuzhiyundef DoOutput(level, msg): 88*4882a593Smuzhiyun """Output a message to the terminal. 89*4882a593Smuzhiyun 90*4882a593Smuzhiyun Args: 91*4882a593Smuzhiyun level: Verbosity level for this message. It will only be displayed if 92*4882a593Smuzhiyun this as high as the currently selected level. 93*4882a593Smuzhiyun msg; Message to display. 94*4882a593Smuzhiyun """ 95*4882a593Smuzhiyun _Output(level, msg) 96*4882a593Smuzhiyun 97*4882a593Smuzhiyundef Error(msg): 98*4882a593Smuzhiyun """Display an error message 99*4882a593Smuzhiyun 100*4882a593Smuzhiyun Args: 101*4882a593Smuzhiyun msg; Message to display. 102*4882a593Smuzhiyun """ 103*4882a593Smuzhiyun _Output(0, msg, _color.RED) 104*4882a593Smuzhiyun 105*4882a593Smuzhiyundef Warning(msg): 106*4882a593Smuzhiyun """Display a warning message 107*4882a593Smuzhiyun 108*4882a593Smuzhiyun Args: 109*4882a593Smuzhiyun msg; Message to display. 110*4882a593Smuzhiyun """ 111*4882a593Smuzhiyun _Output(1, msg, _color.YELLOW) 112*4882a593Smuzhiyun 113*4882a593Smuzhiyundef Notice(msg): 114*4882a593Smuzhiyun """Display an important infomation message 115*4882a593Smuzhiyun 116*4882a593Smuzhiyun Args: 117*4882a593Smuzhiyun msg; Message to display. 118*4882a593Smuzhiyun """ 119*4882a593Smuzhiyun _Output(2, msg) 120*4882a593Smuzhiyun 121*4882a593Smuzhiyundef Info(msg): 122*4882a593Smuzhiyun """Display an infomation message 123*4882a593Smuzhiyun 124*4882a593Smuzhiyun Args: 125*4882a593Smuzhiyun msg; Message to display. 126*4882a593Smuzhiyun """ 127*4882a593Smuzhiyun _Output(3, msg) 128*4882a593Smuzhiyun 129*4882a593Smuzhiyundef Debug(msg): 130*4882a593Smuzhiyun """Display a debug message 131*4882a593Smuzhiyun 132*4882a593Smuzhiyun Args: 133*4882a593Smuzhiyun msg; Message to display. 134*4882a593Smuzhiyun """ 135*4882a593Smuzhiyun _Output(4, msg) 136*4882a593Smuzhiyun 137*4882a593Smuzhiyundef UserOutput(msg): 138*4882a593Smuzhiyun """Display a message regardless of the current output level. 139*4882a593Smuzhiyun 140*4882a593Smuzhiyun This is used when the output was specifically requested by the user. 141*4882a593Smuzhiyun Args: 142*4882a593Smuzhiyun msg; Message to display. 143*4882a593Smuzhiyun """ 144*4882a593Smuzhiyun _Output(0, msg) 145*4882a593Smuzhiyun 146*4882a593Smuzhiyundef Init(_verbose=WARNING, stdout=sys.stdout): 147*4882a593Smuzhiyun """Initialize a new output object. 148*4882a593Smuzhiyun 149*4882a593Smuzhiyun Args: 150*4882a593Smuzhiyun verbose: Verbosity level (0-4). 151*4882a593Smuzhiyun stdout: File to use for stdout. 152*4882a593Smuzhiyun """ 153*4882a593Smuzhiyun global verbose, _progress, _color, _stdout, stdout_is_tty 154*4882a593Smuzhiyun 155*4882a593Smuzhiyun verbose = _verbose 156*4882a593Smuzhiyun _progress = '' # Our last progress message 157*4882a593Smuzhiyun _color = terminal.Color() 158*4882a593Smuzhiyun _stdout = stdout 159*4882a593Smuzhiyun 160*4882a593Smuzhiyun # TODO(sjg): Move this into Chromite libraries when we have them 161*4882a593Smuzhiyun stdout_is_tty = hasattr(sys.stdout, 'isatty') and sys.stdout.isatty() 162*4882a593Smuzhiyun 163*4882a593Smuzhiyundef Uninit(): 164*4882a593Smuzhiyun ClearProgress() 165*4882a593Smuzhiyun 166*4882a593SmuzhiyunInit() 167