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