[FIX] account: it fills taxes from product as well as account in invoice line
[odoo/odoo.git] / openerp / loglevels.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
6 #
7 #    This program is free software: you can redistribute it and/or modify
8 #    it under the terms of the GNU Affero General Public License as
9 #    published by the Free Software Foundation, either version 3 of the
10 #    License, or (at your option) any later version.
11 #
12 #    This program is distributed in the hope that it will be useful,
13 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 #    GNU Affero General Public License for more details.
16 #
17 #    You should have received a copy of the GNU Affero General Public License
18 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 #
20 ##############################################################################
21
22 import sys
23 import logging
24
25 LOG_NOTSET = 'notset'
26 LOG_DEBUG = 'debug'
27 LOG_TEST = 'test'
28 LOG_INFO = 'info'
29 LOG_WARNING = 'warn'
30 LOG_ERROR = 'error'
31 LOG_CRITICAL = 'critical'
32
33 logging.TEST = logging.INFO - 5
34 logging.addLevelName(logging.TEST, 'TEST')
35
36 _logger = logging.getLogger(__name__)
37
38 class Logger(object):
39     def __init__(self):
40         _logger.warning(
41             "The netsvc.Logger API shouldn't be used anymore, please "
42             "use the standard `logging.getLogger` API instead.")
43         super(Logger, self).__init__()
44
45     def notifyChannel(self, name, level, msg):
46         _logger.warning(
47             "notifyChannel API shouldn't be used anymore, please use "
48             "the standard `logging` module instead.")
49         from service.web_services import common
50
51         log = logging.getLogger(__name__ + '.deprecated.' + ustr(name))
52
53         if level in [LOG_TEST] and not hasattr(log, level):
54             fct = lambda msg, *args, **kwargs: log.log(getattr(logging, level.upper()), msg, *args, **kwargs)
55             setattr(log, level, fct)
56
57
58         level_method = getattr(log, level)
59
60         if isinstance(msg, Exception):
61             msg = exception_to_unicode(msg)
62
63         try:
64             msg = ustr(msg).strip()
65             if level in (LOG_ERROR, LOG_CRITICAL): # and tools.config.get_misc('debug','env_info',False):
66                 msg = common().exp_get_server_environment() + "\n" + msg
67
68             result = msg.split('\n')
69         except UnicodeDecodeError:
70             result = msg.strip().split('\n')
71         try:
72             if len(result)>1:
73                 for idx, s in enumerate(result):
74                     level_method('[%02d]: %s' % (idx+1, s,))
75             elif result:
76                 level_method(result[0])
77         except IOError:
78             # TODO: perhaps reset the logger streams?
79             #if logrotate closes our files, we end up here..
80             pass
81         except Exception:
82             # better ignore the exception and carry on..
83             pass
84
85     def set_loglevel(self, level, logger=None):
86         if logger is not None:
87             log = logging.getLogger(str(logger))
88         else:
89             log = logging.getLogger()
90         log.setLevel(logging.INFO) # make sure next msg is printed
91         log.info("Log level changed to %s" % logging.getLevelName(level))
92         log.setLevel(level)
93
94     def shutdown(self):
95         logging.shutdown()
96
97 # TODO get_encodings, ustr and exception_to_unicode were originally from tools.misc.
98 # There are here until we refactor tools so that this module doesn't depends on tools.
99
100 def get_encodings(hint_encoding='utf-8'):
101     fallbacks = {
102         'latin1': 'latin9',
103         'iso-8859-1': 'iso8859-15',
104         'cp1252': '1252',
105     }
106     if hint_encoding:
107         yield hint_encoding
108         if hint_encoding.lower() in fallbacks:
109             yield fallbacks[hint_encoding.lower()]
110
111     # some defaults (also taking care of pure ASCII)
112     for charset in ['utf8','latin1']:
113         if not (hint_encoding) or (charset.lower() != hint_encoding.lower()):
114             yield charset
115
116     from locale import getpreferredencoding
117     prefenc = getpreferredencoding()
118     if prefenc and prefenc.lower() != 'utf-8':
119         yield prefenc
120         prefenc = fallbacks.get(prefenc.lower())
121         if prefenc:
122             yield prefenc
123
124 def ustr(value, hint_encoding='utf-8', errors='strict'):
125     """This method is similar to the builtin `str` method, except
126        it will return unicode() string.
127
128     :param value: the value to convert
129     :param hint_encoding: an optional encoding that was detected
130                           upstream and should be tried first to
131                           decode ``value``.
132     :param errors: specifies the treatment of characters which are
133         invalid in the input encoding (see ``unicode()`` constructor)
134
135     :rtype: unicode
136     :return: unicode string
137     """
138     if isinstance(value, Exception):
139         return exception_to_unicode(value)
140
141     if isinstance(value, unicode):
142         return value
143
144     if not isinstance(value, basestring):
145         try:
146             return unicode(value)
147         except Exception:
148             raise UnicodeError('unable to convert %r' % (value,))
149
150     for ln in get_encodings(hint_encoding):
151         try:
152             return unicode(value, ln, errors=errors)
153         except Exception:
154             pass
155     raise UnicodeError('unable to convert %r' % (value,))
156
157
158 def exception_to_unicode(e):
159     if (sys.version_info[:2] < (2,6)) and hasattr(e, 'message'):
160         return ustr(e.message)
161     if hasattr(e, 'args'):
162         return "\n".join((ustr(a) for a in e.args))
163     try:
164         return unicode(e)
165     except Exception:
166         return u"Unknown message"
167
168 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: