2 # vim: ai ts=4 sts=4 et sw=4
4 # Copyright (c) 2009, 2010, 2011 Intel, Inc.
6 # This program is free software; you can redistribute it and/or modify it
7 # under the terms of the GNU General Public License as published by the Free
8 # Software Foundation; version 2 of the License
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 # You should have received a copy of the GNU General Public License along
16 # with this program; if not, write to the Free Software Foundation, Inc., 59
17 # Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 from datetime import datetime
23 __ALL__ = ['set_mode',
38 INFO_COLOR = 32 # green
39 WARN_COLOR = 33 # yellow
44 PREFIX_RE = re.compile('^<(.*?)>\s*(.*)', re.S)
59 CATCHERR_BUFFILE_FD = -1
60 CATCHERR_BUFFILE_PATH = None
63 def _general_print(head, color, msg = None, stream = None, level = 'normal'):
68 if LOG_LEVELS[level] > LOG_LEVEL:
73 if CATCHERR_BUFFILE_FD > 0:
74 size = os.lseek(CATCHERR_BUFFILE_FD , 0, os.SEEK_END)
75 os.lseek(CATCHERR_BUFFILE_FD, 0, os.SEEK_SET)
76 errormsg = os.read(CATCHERR_BUFFILE_FD, size)
77 os.ftruncate(CATCHERR_BUFFILE_FD, 0)
81 LOG_CONTENT += errormsg
83 save_msg = msg.strip()
85 timestr = datetime.now().strftime('[%m/%d %H:%M:%S] ')
86 LOG_CONTENT += timestr + save_msg + '\n'
89 _color_print('', NO_COLOR, errormsg, stream, level)
91 _color_print(head, color, msg, stream, level)
93 def _color_print(head, color, msg, stream, level):
95 if color == NO_COLOR or \
96 not stream.isatty() or \
97 os.getenv('ANSI_COLORS_DISABLED') is not None:
100 if head.startswith('\r'):
101 # need not \n at last
107 head = '\033[%dm%s:\033[0m ' %(color, head)
109 # ESC cmd to clear line
110 head = '\033[2K' + head
114 if head.startswith('\r'):
119 stream.write('%s%s' % (head, msg))
125 def _color_perror(head, color, msg, level = 'normal'):
126 if CATCHERR_BUFFILE_FD > 0:
127 _general_print(head, color, msg, sys.stdout, level)
129 _general_print(head, color, msg, sys.stderr, level)
131 def _split_msg(head, msg):
132 if isinstance(msg, list):
133 msg = '\n'.join(map(str, msg))
135 if msg.startswith('\n'):
136 # means print \n at first
140 elif msg.startswith('\r'):
141 # means print \r at first
145 m = PREFIX_RE.match(msg)
147 head += ' <%s>' % m.group(1)
153 return (k for k,v in LOG_LEVELS.items() if v==LOG_LEVEL).next()
155 def set_loglevel(level):
157 if level not in LOG_LEVELS:
161 LOG_LEVEL = LOG_LEVELS[level]
163 def set_interactive(mode=True):
171 _general_print('', NO_COLOR, msg)
174 head, msg = _split_msg('Info', msg)
175 _general_print(head, INFO_COLOR, msg)
178 head, msg = _split_msg('Verbose', msg)
179 _general_print(head, INFO_COLOR, msg, level = 'verbose')
182 head, msg = _split_msg('Warning', msg)
183 _color_perror(head, WARN_COLOR, msg)
186 head, msg = _split_msg('Debug', msg)
187 _color_perror(head, ERR_COLOR, msg, level = 'debug')
190 head, msg = _split_msg('Error', msg)
191 _color_perror(head, ERR_COLOR, msg)
194 def ask(msg, default=True):
195 _general_print('\rQ', ASK_COLOR, '')
203 repl = raw_input(msg)
204 if repl.lower() == 'y':
206 elif repl.lower() == 'n':
208 elif not repl.strip():
218 _general_print('', NO_COLOR, msg)
221 except KeyboardInterrupt:
222 sys.stdout.write('\n')
227 _general_print('\rQ', ASK_COLOR, '')
229 msg = 'press <ENTER> to continue ...'
232 def set_logfile(fpath):
237 if not os.path.exists(os.path.dirname(LOG_FILE_FP)):
238 os.makedirs(os.path.dirname(LOG_FILE_FP))
239 fp = open(LOG_FILE_FP, 'w')
240 fp.write(LOG_CONTENT)
243 if LOG_FILE_FP is not None:
244 warning('duplicate log file configuration')
246 LOG_FILE_FP = os.path.abspath(os.path.expanduser(fpath))
249 atexit.register(_savelogf)
251 def enable_logstderr(fpath):
252 global CATCHERR_BUFFILE_FD
253 global CATCHERR_BUFFILE_PATH
254 global CATCHERR_SAVED_2
256 if os.path.exists(fpath):
258 CATCHERR_BUFFILE_PATH = fpath
259 CATCHERR_BUFFILE_FD = os.open(CATCHERR_BUFFILE_PATH, os.O_RDWR|os.O_CREAT)
260 CATCHERR_SAVED_2 = os.dup(2)
261 os.dup2(CATCHERR_BUFFILE_FD, 2)
263 def disable_logstderr():
264 global CATCHERR_BUFFILE_FD
265 global CATCHERR_BUFFILE_PATH
266 global CATCHERR_SAVED_2
268 os.dup2(CATCHERR_SAVED_2, 2)
269 os.close(CATCHERR_SAVED_2)
270 os.close(CATCHERR_BUFFILE_FD)
271 os.unlink(CATCHERR_BUFFILE_PATH)
272 CATCHERR_BUFFILE_FD = -1
273 CATCHERR_BUFFILE_PATH = None
274 CATCHERR_SAVED_2 = -1