]> git.lizzy.rs Git - nhentai.git/blob - nhentai/logger.py
Merge pull request #5 from navrudh/master
[nhentai.git] / nhentai / logger.py
1 #
2 # Copyright (C) 2010-2012 Vinay Sajip. All rights reserved. Licensed under the new BSD license.
3 #
4 import logging
5 import os
6 import re
7 import sys
8
9
10 class ColorizingStreamHandler(logging.StreamHandler):
11     # color names to indices
12     color_map = {
13         'black': 0,
14         'red': 1,
15         'green': 2,
16         'yellow': 3,
17         'blue': 4,
18         'magenta': 5,
19         'cyan': 6,
20         'white': 7,
21     }
22
23     # levels to (background, foreground, bold/intense)
24     if os.name == 'nt':
25         level_map = {
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)
31         }
32     else:
33         level_map = {
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)
39         }
40     csi = '\x1b['
41     reset = '\x1b[0m'
42     disable_coloring = False
43
44     @property
45     def is_tty(self):
46         isatty = getattr(self.stream, 'isatty', None)
47         return isatty and isatty() and not self.disable_coloring
48
49     if os.name != 'nt':
50         def output_colorized(self, message):
51             self.stream.write(message)
52     else:
53         ansi_esc = re.compile(r'\x1b\[((?:\d+)(?:;(?:\d+))*)m')
54
55         nt_color_map = {
56             0: 0x00,    # black
57             1: 0x04,    # red
58             2: 0x02,    # green
59             3: 0x06,    # yellow
60             4: 0x01,    # blue
61             5: 0x05,    # magenta
62             6: 0x03,    # cyan
63             7: 0x07,    # white
64         }
65
66         def output_colorized(self, message):
67             import ctypes
68
69             parts = self.ansi_esc.split(message)
70             write = self.stream.write
71             h = None
72             fd = getattr(self.stream, 'fileno', None)
73
74             if fd is not None:
75                 fd = fd()
76
77                 if fd in (1, 2):  # stdout or stderr
78                     h = ctypes.windll.kernel32.GetStdHandle(-10 - fd)
79
80             while parts:
81                 text = parts.pop(0)
82
83                 if text:
84                     write(text)
85
86                 if parts:
87                     params = parts.pop(0)
88
89                     if h is not None:
90                         params = [int(p) for p in params.split(';')]
91                         color = 0
92
93                         for p in params:
94                             if 40 <= p <= 47:
95                                 color |= self.nt_color_map[p - 40] << 4
96                             elif 30 <= p <= 37:
97                                 color |= self.nt_color_map[p - 30]
98                             elif p == 1:
99                                 color |= 0x08  # foreground intensity on
100                             elif p == 0:  # reset to default color
101                                 color = 0x07
102                             else:
103                                 pass  # error condition ignored
104
105                         ctypes.windll.kernel32.SetConsoleTextAttribute(h, color)
106
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]
110             params = []
111
112             if bg in self.color_map:
113                 params.append(str(self.color_map[bg] + 40))
114
115             if fg in self.color_map:
116                 params.append(str(self.color_map[fg] + 30))
117
118             if bold:
119                 params.append('1')
120
121             if params and message:
122                 if message.lstrip() != message:
123                     prefix = re.search(r"\s+", message).group(0)
124                     message = message[len(prefix):]
125                 else:
126                     prefix = ""
127
128                 message = "%s%s" % (prefix, ''.join((self.csi, ';'.join(params),
129                                     'm', message, self.reset)))
130
131         return message
132
133     def format(self, record):
134         message = logging.StreamHandler.format(self, record)
135         return self.colorize(message, record)
136
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)
145
146
147 if __name__ == '__main__':
148     logger.log(15, 'nhentai')
149     logger.info('info')
150     logger.warn('warn')
151     logger.debug('debug')
152     logger.error('error')
153     logger.critical('critical')