From c57ab8210f0c1ef5e5a066fd089b6afe5c30e606 Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Wed, 26 Jan 2011 17:50:30 +0100 Subject: [PATCH] [REVERT] revisions 3324, 3325, 3326, to be merged globally after complete cleanup This corresponds to revids: - vmt@openerp.com-20110126142219-18j842m60diwsdph (3324) - vmt@openerp.com-20110126144255-t8p6g1ggjb7f1dmt (3325) - vmt@openerp.com-20110126151717-tf0q2mx2inj21jls (3326) bzr revid: odo@openerp.com-20110126165030-su3zeobaj7v9d95f --- bin/loglevels.py | 172 --------------------------------- bin/netsvc.py | 86 ++++++++++++++++- bin/openerp-server.py | 1 - bin/tools/__init__.py | 2 +- bin/tools/amount_to_text_en.py | 4 +- bin/tools/config.py | 9 +- bin/tools/convert.py | 13 ++- bin/tools/misc.py | 16 +-- bin/tools/translate.py | 2 +- bin/tools/yaml_import.py | 2 +- 10 files changed, 108 insertions(+), 199 deletions(-) delete mode 100644 bin/loglevels.py diff --git a/bin/loglevels.py b/bin/loglevels.py deleted file mode 100644 index 1b41714c3b8..00000000000 --- a/bin/loglevels.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2009 Tiny SPRL (). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## - -import logging -import warnings - -LOG_NOTSET = 'notset' -LOG_DEBUG_SQL = 'debug_sql' -LOG_DEBUG_RPC_ANSWER = 'debug_rpc_answer' -LOG_DEBUG_RPC = 'debug_rpc' -LOG_DEBUG = 'debug' -LOG_TEST = 'test' -LOG_INFO = 'info' -LOG_WARNING = 'warn' -LOG_ERROR = 'error' -LOG_CRITICAL = 'critical' - -logging.DEBUG_RPC_ANSWER = logging.DEBUG - 4 -logging.addLevelName(logging.DEBUG_RPC_ANSWER, 'DEBUG_RPC_ANSWER') -logging.DEBUG_RPC = logging.DEBUG - 2 -logging.addLevelName(logging.DEBUG_RPC, 'DEBUG_RPC') -logging.DEBUG_SQL = logging.DEBUG_RPC - 3 -logging.addLevelName(logging.DEBUG_SQL, 'DEBUG_SQL') - -logging.TEST = logging.INFO - 5 -logging.addLevelName(logging.TEST, 'TEST') - -class Logger(object): - def __init__(self): - warnings.warn("The netsvc.Logger API shouldn't be used anymore, please " - "use the standard `logging.getLogger` API instead", - PendingDeprecationWarning, stacklevel=2) - super(Logger, self).__init__() - - def notifyChannel(self, name, level, msg): - warnings.warn("notifyChannel API shouldn't be used anymore, please use " - "the standard `logging` module instead", - PendingDeprecationWarning, stacklevel=2) - from service.web_services import common - - log = logging.getLogger(ustr(name)) - - if level in [LOG_DEBUG_RPC, LOG_TEST] and not hasattr(log, level): - fct = lambda msg, *args, **kwargs: log.log(getattr(logging, level.upper()), msg, *args, **kwargs) - setattr(log, level, fct) - - - level_method = getattr(log, level) - - if isinstance(msg, Exception): - msg = exception_to_unicode(msg) - - try: - msg = ustr(msg).strip() - if level in (LOG_ERROR, LOG_CRITICAL): # and tools.config.get_misc('debug','env_info',False): - msg = common().exp_get_server_environment() + "\n" + msg - - result = msg.split('\n') - except UnicodeDecodeError: - result = msg.strip().split('\n') - try: - if len(result)>1: - for idx, s in enumerate(result): - level_method('[%02d]: %s' % (idx+1, s,)) - elif result: - level_method(result[0]) - except IOError: - # TODO: perhaps reset the logger streams? - #if logrotate closes our files, we end up here.. - pass - except Exception: - # better ignore the exception and carry on.. - pass - - def set_loglevel(self, level, logger=None): - if logger is not None: - log = logging.getLogger(str(logger)) - else: - log = logging.getLogger() - log.setLevel(logging.INFO) # make sure next msg is printed - log.info("Log level changed to %s" % logging.getLevelName(level)) - log.setLevel(level) - - def shutdown(self): - logging.shutdown() - -# TODO get_encodings, ustr and exception_to_unicode are taken from tools.misc -# but we don't want to depend on tools. - -def get_encodings(hint_encoding='utf-8'): - fallbacks = { - 'latin1': 'latin9', - 'iso-8859-1': 'iso8859-15', - 'cp1252': '1252', - } - if hint_encoding: - yield hint_encoding - if hint_encoding.lower() in fallbacks: - yield fallbacks[hint_encoding.lower()] - - # some defaults (also taking care of pure ASCII) - for charset in ['utf8','latin1']: - if not (hint_encoding) or (charset.lower() != hint_encoding.lower()): - yield charset - - from locale import getpreferredencoding - prefenc = getpreferredencoding() - if prefenc and prefenc.lower() != 'utf-8': - yield prefenc - prefenc = fallbacks.get(prefenc.lower()) - if prefenc: - yield prefenc - -def ustr(value, hint_encoding='utf-8'): - """This method is similar to the builtin `str` method, except - it will return unicode() string. - - @param value: the value to convert - @param hint_encoding: an optional encoding that was detected - upstream and should be tried first to - decode ``value``. - - @rtype: unicode - @return: unicode string - """ - if isinstance(value, Exception): - return exception_to_unicode(value) - - if isinstance(value, unicode): - return value - - if not isinstance(value, basestring): - try: - return unicode(value) - except Exception: - raise UnicodeError('unable to convert %r' % (value,)) - - for ln in get_encodings(hint_encoding): - try: - return unicode(value, ln) - except Exception: - pass - raise UnicodeError('unable to convert %r' % (value,)) - - -def exception_to_unicode(e): - if (sys.version_info[:2] < (2,6)) and hasattr(e, 'message'): - return ustr(e.message) - if hasattr(e, 'args'): - return "\n".join((ustr(a) for a in e.args)) - try: - return ustr(e) - except Exception: - return u"Unknown message" diff --git a/bin/netsvc.py b/bin/netsvc.py index 696d225c4af..c2360ae5ee7 100644 --- a/bin/netsvc.py +++ b/bin/netsvc.py @@ -37,10 +37,6 @@ from pprint import pformat import warnings import heapq -# TODO modules that import netsvc only for things from loglevels must be changed to use loglevels. -from loglevels import * -import tools - class Service(object): """ Base class for *Local* services @@ -134,6 +130,27 @@ class ExportService(object): else: raise +LOG_NOTSET = 'notset' +LOG_DEBUG_SQL = 'debug_sql' +LOG_DEBUG_RPC_ANSWER = 'debug_rpc_answer' +LOG_DEBUG_RPC = 'debug_rpc' +LOG_DEBUG = 'debug' +LOG_TEST = 'test' +LOG_INFO = 'info' +LOG_WARNING = 'warn' +LOG_ERROR = 'error' +LOG_CRITICAL = 'critical' + +logging.DEBUG_RPC_ANSWER = logging.DEBUG - 4 +logging.addLevelName(logging.DEBUG_RPC_ANSWER, 'DEBUG_RPC_ANSWER') +logging.DEBUG_RPC = logging.DEBUG - 2 +logging.addLevelName(logging.DEBUG_RPC, 'DEBUG_RPC') +logging.DEBUG_SQL = logging.DEBUG_RPC - 3 +logging.addLevelName(logging.DEBUG_SQL, 'DEBUG_SQL') + +logging.TEST = logging.INFO - 5 +logging.addLevelName(logging.TEST, 'TEST') + BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, _NOTHING, DEFAULT = range(10) #The background is set with 40 plus the number of the color, and the foreground with 30 #These are the sequences need to get colored ouput @@ -212,6 +229,67 @@ def init_logger(): logger.addHandler(handler) logger.setLevel(int(tools.config['log_level'] or '0')) + +class Logger(object): + def __init__(self): + warnings.warn("The netsvc.Logger API shouldn't be used anymore, please " + "use the standard `logging.getLogger` API instead", + PendingDeprecationWarning, stacklevel=2) + super(Logger, self).__init__() + + def notifyChannel(self, name, level, msg): + warnings.warn("notifyChannel API shouldn't be used anymore, please use " + "the standard `logging` module instead", + PendingDeprecationWarning, stacklevel=2) + from service.web_services import common + + log = logging.getLogger(tools.ustr(name)) + + if level in [LOG_DEBUG_RPC, LOG_TEST] and not hasattr(log, level): + fct = lambda msg, *args, **kwargs: log.log(getattr(logging, level.upper()), msg, *args, **kwargs) + setattr(log, level, fct) + + + level_method = getattr(log, level) + + if isinstance(msg, Exception): + msg = tools.exception_to_unicode(msg) + + try: + msg = tools.ustr(msg).strip() + if level in (LOG_ERROR, LOG_CRITICAL) and tools.config.get_misc('debug','env_info',False): + msg = common().exp_get_server_environment() + "\n" + msg + + result = msg.split('\n') + except UnicodeDecodeError: + result = msg.strip().split('\n') + try: + if len(result)>1: + for idx, s in enumerate(result): + level_method('[%02d]: %s' % (idx+1, s,)) + elif result: + level_method(result[0]) + except IOError: + # TODO: perhaps reset the logger streams? + #if logrotate closes our files, we end up here.. + pass + except Exception: + # better ignore the exception and carry on.. + pass + + def set_loglevel(self, level, logger=None): + if logger is not None: + log = logging.getLogger(str(logger)) + else: + log = logging.getLogger() + log.setLevel(logging.INFO) # make sure next msg is printed + log.info("Log level changed to %s" % logging.getLevelName(level)) + log.setLevel(level) + + def shutdown(self): + logging.shutdown() + +import tools init_logger() class Agent(object): diff --git a/bin/openerp-server.py b/bin/openerp-server.py index 20849f6e3c0..a3f8ed84b34 100755 --- a/bin/openerp-server.py +++ b/bin/openerp-server.py @@ -62,7 +62,6 @@ logger = logging.getLogger('server') # import the tools module so that the commandline parameters are parsed #----------------------------------------------------------------------- import tools -tools.config.parse_config() logger.info("OpenERP version - %s", release.version) for name, value in [('addons_path', tools.config['addons_path']), ('database hostname', tools.config['db_host'] or 'localhost'), diff --git a/bin/tools/__init__.py b/bin/tools/__init__.py index 16042841b6e..f1a0faf0f8f 100644 --- a/bin/tools/__init__.py +++ b/bin/tools/__init__.py @@ -21,7 +21,7 @@ import copy import win32 -from config import config +from config import * from misc import * from convert import * from translate import * diff --git a/bin/tools/amount_to_text_en.py b/bin/tools/amount_to_text_en.py index 1b452d50ccb..66d749e5fb3 100644 --- a/bin/tools/amount_to_text_en.py +++ b/bin/tools/amount_to_text_en.py @@ -99,13 +99,13 @@ def amount_to_text(nbr, lang='en', currency='euro'): Example: 1654: thousands six cent cinquante-quatre. """ - import loglevels + import netsvc # if nbr > 10000000: # netsvc.Logger().notifyChannel('translate', netsvc.LOG_WARNING, _("Number too large '%d', can not translate it")) # return str(nbr) if not _translate_funcs.has_key(lang): - loglevels.Logger().notifyChannel('translate', loglevels.LOG_WARNING, _("no translation function found for lang: '%s'" % (lang,))) + netsvc.Logger().notifyChannel('translate', netsvc.LOG_WARNING, _("no translation function found for lang: '%s'" % (lang,))) #TODO: (default should be en) same as above lang = 'en' return _translate_funcs[lang](abs(nbr), currency) diff --git a/bin/tools/config.py b/bin/tools/config.py index 76522bfcd76..bc9229e0b72 100644 --- a/bin/tools/config.py +++ b/bin/tools/config.py @@ -23,7 +23,7 @@ import ConfigParser import optparse import os import sys -import loglevels +import netsvc import logging import release @@ -102,7 +102,7 @@ class configmanager(object): self.config_file = fname self.has_ssl = check_ssl() - self._LOGLEVELS = dict([(getattr(loglevels, 'LOG_%s' % x), getattr(logging, x)) + self._LOGLEVELS = dict([(getattr(netsvc, 'LOG_%s' % x), getattr(logging, x)) for x in ('CRITICAL', 'ERROR', 'WARNING', 'INFO', 'TEST', 'DEBUG', 'DEBUG_RPC', 'DEBUG_SQL', 'DEBUG_RPC_ANSWER','NOTSET')]) version = "%s %s" % (release.description, release.version) @@ -496,3 +496,8 @@ class configmanager(object): config = configmanager() +# FIXME:following line should be called explicitly by the server +# when it starts, to allow doing 'import tools.config' from +# other python executables without parsing *their* args. +config.parse_config() + diff --git a/bin/tools/convert.py b/bin/tools/convert.py index 538c79eff3d..db8d71843ba 100644 --- a/bin/tools/convert.py +++ b/bin/tools/convert.py @@ -41,7 +41,8 @@ except: from datetime import datetime, timedelta from lxml import etree import misc -import loglevels +import netsvc +import osv import pooler from config import config from tools.translate import _ @@ -540,7 +541,6 @@ form: module.record_id""" % (xml_id,) id = _eval_xml(self, rec[0], self.pool, cr, self.uid, self.idref) uid = self.get_uid(cr, self.uid, data_node, rec) - import netsvc wf_service = netsvc.LocalService("workflow") wf_service.trg_validate(uid, model, id, @@ -688,7 +688,7 @@ form: module.record_id""" % (xml_id,) rec_src = rec.get("search",'').encode('utf8') rec_src_count = rec.get("count") - severity = rec.get("severity",'').encode('ascii') or loglevels.LOG_ERROR + severity = rec.get("severity",'').encode('ascii') or netsvc.LOG_ERROR rec_string = rec.get("string",'').encode('utf8') or 'unknown' ids = None @@ -825,7 +825,6 @@ form: module.record_id""" % (xml_id,) else: f_val = _eval_xml(self,field, self.pool, cr, self.uid, self.idref) if model._columns.has_key(f_name): - import osv if isinstance(model._columns[f_name], osv.fields.integer): f_val = int(f_val) res[f_name] = f_val @@ -965,9 +964,9 @@ def convert_xml_import(cr, module, xmlfile, idref=None, mode='init', noupdate=Fa try: relaxng.assert_(doc) except Exception: - logger = loglevels.Logger() - logger.notifyChannel('init', loglevels.LOG_ERROR, 'The XML file does not fit the required schema !') - logger.notifyChannel('init', loglevels.LOG_ERROR, misc.ustr(relaxng.error_log.last_error)) + logger = netsvc.Logger() + logger.notifyChannel('init', netsvc.LOG_ERROR, 'The XML file does not fit the required schema !') + logger.notifyChannel('init', netsvc.LOG_ERROR, misc.ustr(relaxng.error_log.last_error)) raise if idref is None: diff --git a/bin/tools/misc.py b/bin/tools/misc.py index 26ed090edc8..615893ef238 100644 --- a/bin/tools/misc.py +++ b/bin/tools/misc.py @@ -55,7 +55,7 @@ try: except ImportError: html2text = None -import loglevels +import netsvc from config import config from lru import LRU @@ -434,10 +434,10 @@ def _email_send(smtp_from, smtp_to_list, message, openobject_id=None, ssl=False, """ class WriteToLogger(object): def __init__(self): - self.logger = loglevels.Logger() + self.logger = netsvc.Logger() def write(self, s): - self.logger.notifyChannel('email_send', loglevels.LOG_DEBUG, s) + self.logger.notifyChannel('email_send', netsvc.LOG_DEBUG, s) if openobject_id: message['Message-Id'] = generate_tracking_message_id(openobject_id) @@ -1094,7 +1094,7 @@ def logged(f): vector.append(' result: %s' % pformat(res)) vector.append(' time delta: %s' % (time.time() - timeb4)) - loglevels.Logger().notifyChannel('logged', loglevels.LOG_DEBUG, '\n'.join(vector)) + netsvc.Logger().notifyChannel('logged', netsvc.LOG_DEBUG, '\n'.join(vector)) return res return wrapper @@ -1300,7 +1300,7 @@ def detect_server_timezone(): try: import pytz except Exception: - loglevels.Logger().notifyChannel("detect_server_timezone", loglevels.LOG_WARNING, + netsvc.Logger().notifyChannel("detect_server_timezone", netsvc.LOG_WARNING, "Python pytz module is not available. Timezone will be set to UTC by default.") return 'UTC' @@ -1334,14 +1334,14 @@ def detect_server_timezone(): if value: try: tz = pytz.timezone(value) - loglevels.Logger().notifyChannel("detect_server_timezone", loglevels.LOG_INFO, + netsvc.Logger().notifyChannel("detect_server_timezone", netsvc.LOG_INFO, "Using timezone %s obtained from %s." % (tz.zone,source)) return value except pytz.UnknownTimeZoneError: - loglevels.Logger().notifyChannel("detect_server_timezone", loglevels.LOG_WARNING, + netsvc.Logger().notifyChannel("detect_server_timezone", netsvc.LOG_WARNING, "The timezone specified in %s (%s) is invalid, ignoring it." % (source,value)) - loglevels.Logger().notifyChannel("detect_server_timezone", loglevels.LOG_WARNING, + netsvc.Logger().notifyChannel("detect_server_timezone", netsvc.LOG_WARNING, "No valid timezone could be detected, using default UTC timezone. You can specify it explicitly with option 'timezone' in the server configuration.") return 'UTC' diff --git a/bin/tools/translate.py b/bin/tools/translate.py index e63de663a73..510ae71ab1f 100644 --- a/bin/tools/translate.py +++ b/bin/tools/translate.py @@ -38,6 +38,7 @@ from datetime import datetime from lxml import etree import tools +import netsvc from tools.misc import UpdateableStr from tools.misc import SKIPPED_ELEMENT_TYPES @@ -586,7 +587,6 @@ def trans_generate(lang, modules, cr): push_translation(module, 'view', encode(obj.model), 0, t) elif model=='ir.actions.wizard': service_name = 'wizard.'+encode(obj.wiz_name) - import netsvc if netsvc.Service._services.get(service_name): obj2 = netsvc.Service._services[service_name] for state_name, state_def in obj2.states.iteritems(): diff --git a/bin/tools/yaml_import.py b/bin/tools/yaml_import.py index 53bcebacabc..2b5c982ca7b 100644 --- a/bin/tools/yaml_import.py +++ b/bin/tools/yaml_import.py @@ -5,6 +5,7 @@ from datetime import datetime, timedelta import logging import pooler +import netsvc import misc from config import config import yaml_tag @@ -447,7 +448,6 @@ class YamlInterpreter(object): signals=[x['signal'] for x in self.cr.dictfetchall()] if workflow.action not in signals: raise YamlImportException('Incorrect action %s. No such action defined' % workflow.action) - import netsvc wf_service = netsvc.LocalService("workflow") wf_service.trg_validate(uid, workflow.model, id, workflow.action, self.cr)