2 # Copyright (C) 2010-2012 Vinay Sajip. All rights reserved. Licensed under the new BSD license.
10 class ColorizingStreamHandler(logging.StreamHandler):
11 # color names to indices
23 # levels to (background, foreground, bold/intense)
26 logging.DEBUG: (None, 'white', False),
27 logging.INFO: (None, 'green', False),
28 logging.WARNING: (None, 'yellow', False),
29 logging.ERROR: (None, 'red', False),
30 logging.CRITICAL: ('red', 'white', False)
34 logging.DEBUG: (None, 'white', False),
35 logging.INFO: (None, 'green', False),
36 logging.WARNING: (None, 'yellow', False),
37 logging.ERROR: (None, 'red', False),
38 logging.CRITICAL: ('red', 'white', False)
42 disable_coloring = False
46 isatty = getattr(self.stream, 'isatty', None)
47 return isatty and isatty() and not self.disable_coloring
50 def output_colorized(self, message):
51 self.stream.write(message)
53 ansi_esc = re.compile(r'\x1b\[((?:\d+)(?:;(?:\d+))*)m')
66 def output_colorized(self, message):
69 parts = self.ansi_esc.split(message)
70 write = self.stream.write
72 fd = getattr(self.stream, 'fileno', None)
77 if fd in (1, 2): # stdout or stderr
78 h = ctypes.windll.kernel32.GetStdHandle(-10 - fd)
90 params = [int(p) for p in params.split(';')]
95 color |= self.nt_color_map[p - 40] << 4
97 color |= self.nt_color_map[p - 30]
99 color |= 0x08 # foreground intensity on
100 elif p == 0: # reset to default color
103 pass # error condition ignored
105 ctypes.windll.kernel32.SetConsoleTextAttribute(h, color)
107 def colorize(self, message, record):
108 if record.levelno in self.level_map and self.is_tty:
109 bg, fg, bold = self.level_map[record.levelno]
112 if bg in self.color_map:
113 params.append(str(self.color_map[bg] + 40))
115 if fg in self.color_map:
116 params.append(str(self.color_map[fg] + 30))
121 if params and message:
122 if message.lstrip() != message:
123 prefix = re.search(r"\s+", message).group(0)
124 message = message[len(prefix):]
128 message = "%s%s" % (prefix, ''.join((self.csi, ';'.join(params),
129 'm', message, self.reset)))
133 def format(self, record):
134 message = logging.StreamHandler.format(self, record)
135 return self.colorize(message, record)
137 logging.addLevelName(15, "INFO")
138 logger = logging.getLogger('nhentai')
139 LOGGER_HANDLER = ColorizingStreamHandler(sys.stdout)
140 FORMATTER = logging.Formatter("\r[%(asctime)s] [%(levelname)s] %(message)s", "%H:%M:%S")
141 LOGGER_HANDLER.setFormatter(FORMATTER)
142 LOGGER_HANDLER.level_map[logging.getLevelName("INFO")] = (None, "cyan", False)
143 logger.addHandler(LOGGER_HANDLER)
144 logger.setLevel(logging.DEBUG)
147 if __name__ == '__main__':
148 logger.log(15, 'nhentai')
151 logger.debug('debug')
152 logger.error('error')
153 logger.critical('critical')