From 28a253104a1c6e4d584930257e3067ae74995808 Mon Sep 17 00:00:00 2001 From: ZhiQiang Fan Date: Sun, 30 Nov 2014 17:25:16 +0800 Subject: [PATCH] Port to graduated library oslo.i18n log_handler is not used any more by Ceilometer project, but still listed on openstack-common.conf, this patch fixes it. Note: oslo-incubator.timeutils is not used by oslo-incubator modules any more after we do code sync, this patch removes it too. gettextutils has graduated from oslo-incubator, we should port our project to use oslo.i18n. To use oslo.i18n conveniently, this patch introduces a helper module ceilometer.i18n, which is stolen from Nova. Note: gettextutils.install is deprecated, see: http://docs.openstack.org/developer/oslo.i18n/usage.html#creating-an-integration-module Note: _ is removed from builtins in tox.ini since we're not using install any more. Change-Id: I829f9faf97c825422b395bf9c01ae5c17c86d9fb Closes-Bug: #1389546 --- ceilometer/agent.py | 2 +- ceilometer/alarm/evaluator/__init__.py | 2 +- ceilometer/alarm/evaluator/combination.py | 2 +- ceilometer/alarm/evaluator/threshold.py | 2 +- ceilometer/alarm/notifier/log.py | 2 +- ceilometer/alarm/notifier/rest.py | 2 +- ceilometer/alarm/partition/coordination.py | 2 +- ceilometer/alarm/rpc.py | 2 +- ceilometer/alarm/service.py | 2 +- ceilometer/alarm/storage/impl_hbase.py | 2 +- ceilometer/alarm/storage/models.py | 2 +- ceilometer/api/app.py | 1 + ceilometer/api/controllers/v2.py | 2 +- ceilometer/api/middleware.py | 16 +- ceilometer/central/discovery.py | 2 +- ceilometer/central/plugin.py | 2 +- ceilometer/cmd/storage.py | 1 + ceilometer/collector.py | 3 +- ceilometer/compute/notifications/cpu.py | 2 +- ceilometer/compute/nova_notifier.py | 2 +- ceilometer/compute/pollsters/cpu.py | 2 +- ceilometer/compute/pollsters/disk.py | 2 +- ceilometer/compute/pollsters/memory.py | 2 +- ceilometer/compute/pollsters/net.py | 2 +- ceilometer/compute/virt/hyperv/utilsv2.py | 2 +- ceilometer/compute/virt/inspector.py | 2 +- ceilometer/compute/virt/libvirt/inspector.py | 2 +- ceilometer/compute/virt/vmware/inspector.py | 2 +- ceilometer/compute/virt/xenapi/inspector.py | 2 +- ceilometer/coordination.py | 2 +- ceilometer/dispatcher/__init__.py | 2 +- ceilometer/dispatcher/database.py | 2 +- ceilometer/dispatcher/http.py | 2 +- ceilometer/energy/kwapi.py | 2 +- ceilometer/event/converter.py | 2 +- ceilometer/event/endpoint.py | 2 +- ceilometer/event/storage/impl_hbase.py | 2 +- ceilometer/event/storage/impl_sqlalchemy.py | 2 +- ceilometer/event/storage/pymongo_base.py | 2 +- ceilometer/hardware/discovery.py | 2 +- ceilometer/hardware/plugin.py | 2 +- ceilometer/i18n.py | 46 ++ .../ipmi/platform/intel_node_manager.py | 2 +- ceilometer/ipmi/platform/ipmi_sensor.py | 2 +- ceilometer/ipmi/platform/ipmitool.py | 2 +- ceilometer/network/floatingip.py | 2 +- ceilometer/network/notifications.py | 2 +- ceilometer/network/services/fwaas.py | 2 +- ceilometer/network/services/lbaas.py | 2 +- ceilometer/network/services/vpnaas.py | 2 +- .../network/statistics/opencontrail/client.py | 2 +- .../network/statistics/opendaylight/client.py | 2 +- .../network/statistics/opendaylight/driver.py | 2 +- ceilometer/notification.py | 2 +- ceilometer/notifier.py | 2 +- ceilometer/objectstore/swift.py | 2 +- ceilometer/openstack/common/gettextutils.py | 479 ------------------ ceilometer/openstack/common/timeutils.py | 210 -------- ceilometer/pipeline.py | 2 +- ceilometer/plugin.py | 2 +- ceilometer/publisher/file.py | 2 +- ceilometer/publisher/messaging.py | 2 +- ceilometer/publisher/udp.py | 2 +- ceilometer/service.py | 7 +- ceilometer/storage/__init__.py | 2 +- ceilometer/storage/hbase/base.py | 2 +- ceilometer/storage/hbase/inmemory.py | 2 +- ceilometer/storage/hbase/utils.py | 2 +- ceilometer/storage/impl_hbase.py | 2 +- ceilometer/storage/impl_log.py | 2 +- ceilometer/storage/impl_mongodb.py | 1 + ceilometer/storage/impl_sqlalchemy.py | 2 +- ceilometer/storage/mongo/utils.py | 2 +- ceilometer/tests/api/v2/test_app.py | 8 +- .../statistics/opendaylight/test_client.py | 2 +- ceilometer/transformer/arithmetic.py | 2 +- ceilometer/transformer/conversions.py | 2 +- openstack-common.conf | 2 - requirements-py3.txt | 1 + requirements.txt | 1 + tox.ini | 3 +- 81 files changed, 134 insertions(+), 779 deletions(-) create mode 100644 ceilometer/i18n.py delete mode 100644 ceilometer/openstack/common/gettextutils.py delete mode 100644 ceilometer/openstack/common/timeutils.py diff --git a/ceilometer/agent.py b/ceilometer/agent.py index e8cbd651..de9d5f07 100644 --- a/ceilometer/agent.py +++ b/ceilometer/agent.py @@ -27,8 +27,8 @@ from six.moves.urllib import parse as urlparse from stevedore import extension from ceilometer import coordination +from ceilometer.i18n import _ from ceilometer.openstack.common import context -from ceilometer.openstack.common.gettextutils import _ from ceilometer.openstack.common import log from ceilometer.openstack.common import service as os_service from ceilometer import pipeline as publish_pipeline diff --git a/ceilometer/alarm/evaluator/__init__.py b/ceilometer/alarm/evaluator/__init__.py index af816010..0e308361 100644 --- a/ceilometer/alarm/evaluator/__init__.py +++ b/ceilometer/alarm/evaluator/__init__.py @@ -26,7 +26,7 @@ from oslo.utils import timeutils import pytz import six -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log diff --git a/ceilometer/alarm/evaluator/combination.py b/ceilometer/alarm/evaluator/combination.py index 551dc884..10cf5f3e 100644 --- a/ceilometer/alarm/evaluator/combination.py +++ b/ceilometer/alarm/evaluator/combination.py @@ -19,7 +19,7 @@ import itertools from ceilometer.alarm import evaluator -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log LOG = log.getLogger(__name__) diff --git a/ceilometer/alarm/evaluator/threshold.py b/ceilometer/alarm/evaluator/threshold.py index a15f9370..c4901f24 100644 --- a/ceilometer/alarm/evaluator/threshold.py +++ b/ceilometer/alarm/evaluator/threshold.py @@ -23,7 +23,7 @@ from oslo.utils import timeutils from ceilometer.alarm import evaluator from ceilometer.alarm.evaluator import utils -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log LOG = log.getLogger(__name__) diff --git a/ceilometer/alarm/notifier/log.py b/ceilometer/alarm/notifier/log.py index 00e323ec..9777f111 100644 --- a/ceilometer/alarm/notifier/log.py +++ b/ceilometer/alarm/notifier/log.py @@ -17,7 +17,7 @@ """Log alarm notifier.""" from ceilometer.alarm import notifier -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log LOG = log.getLogger(__name__) diff --git a/ceilometer/alarm/notifier/rest.py b/ceilometer/alarm/notifier/rest.py index 43c8d827..44dc986b 100644 --- a/ceilometer/alarm/notifier/rest.py +++ b/ceilometer/alarm/notifier/rest.py @@ -23,8 +23,8 @@ import requests import six.moves.urllib.parse as urlparse from ceilometer.alarm import notifier +from ceilometer.i18n import _ from ceilometer.openstack.common import context -from ceilometer.openstack.common.gettextutils import _ from ceilometer.openstack.common import log LOG = log.getLogger(__name__) diff --git a/ceilometer/alarm/partition/coordination.py b/ceilometer/alarm/partition/coordination.py index e8635895..cf36cc30 100644 --- a/ceilometer/alarm/partition/coordination.py +++ b/ceilometer/alarm/partition/coordination.py @@ -22,7 +22,7 @@ import uuid from oslo.utils import timeutils from ceilometer.alarm import rpc as rpc_alarm -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log diff --git a/ceilometer/alarm/rpc.py b/ceilometer/alarm/rpc.py index 16d88f5d..6509a232 100644 --- a/ceilometer/alarm/rpc.py +++ b/ceilometer/alarm/rpc.py @@ -19,9 +19,9 @@ from oslo.config import cfg import six from ceilometer.alarm.storage import models +from ceilometer.i18n import _ from ceilometer import messaging from ceilometer.openstack.common import context -from ceilometer.openstack.common.gettextutils import _ from ceilometer.openstack.common import log OPTS = [ diff --git a/ceilometer/alarm/service.py b/ceilometer/alarm/service.py index c13e738e..9b2d3496 100644 --- a/ceilometer/alarm/service.py +++ b/ceilometer/alarm/service.py @@ -28,8 +28,8 @@ from stevedore import extension from ceilometer.alarm.partition import coordination as alarm_coordination from ceilometer.alarm import rpc as rpc_alarm from ceilometer import coordination as coordination +from ceilometer.i18n import _ from ceilometer import messaging -from ceilometer.openstack.common.gettextutils import _ from ceilometer.openstack.common import log from ceilometer.openstack.common import service as os_service diff --git a/ceilometer/alarm/storage/impl_hbase.py b/ceilometer/alarm/storage/impl_hbase.py index 8a237afc..7332a85f 100644 --- a/ceilometer/alarm/storage/impl_hbase.py +++ b/ceilometer/alarm/storage/impl_hbase.py @@ -17,7 +17,7 @@ import operator import ceilometer from ceilometer.alarm.storage import base from ceilometer.alarm.storage import models -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log from ceilometer.storage.hbase import base as hbase_base from ceilometer.storage.hbase import migration as hbase_migration diff --git a/ceilometer/alarm/storage/models.py b/ceilometer/alarm/storage/models.py index eaf85594..620161b3 100644 --- a/ceilometer/alarm/storage/models.py +++ b/ceilometer/alarm/storage/models.py @@ -19,7 +19,7 @@ import datetime -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.storage import base diff --git a/ceilometer/api/app.py b/ceilometer/api/app.py index 31ce7d4b..cd03c846 100644 --- a/ceilometer/api/app.py +++ b/ceilometer/api/app.py @@ -28,6 +28,7 @@ import pecan from ceilometer.api import config as api_config from ceilometer.api import hooks from ceilometer.api import middleware +from ceilometer.i18n import _ from ceilometer.openstack.common import log from ceilometer import storage diff --git a/ceilometer/api/controllers/v2.py b/ceilometer/api/controllers/v2.py index a1a0429f..8bcccc37 100644 --- a/ceilometer/api/controllers/v2.py +++ b/ceilometer/api/controllers/v2.py @@ -52,9 +52,9 @@ from ceilometer.alarm import service as alarm_service from ceilometer.alarm.storage import models as alarm_models from ceilometer.api import acl from ceilometer.event.storage import models as event_models +from ceilometer.i18n import _ from ceilometer import messaging from ceilometer.openstack.common import context -from ceilometer.openstack.common.gettextutils import _ from ceilometer.openstack.common import log from ceilometer import sample from ceilometer import storage diff --git a/ceilometer/api/middleware.py b/ceilometer/api/middleware.py index 9d6fc282..66465ff5 100644 --- a/ceilometer/api/middleware.py +++ b/ceilometer/api/middleware.py @@ -27,8 +27,8 @@ from lxml import etree import webob from ceilometer.api import hooks -from ceilometer.openstack.common import gettextutils -from ceilometer.openstack.common.gettextutils import _ +from ceilometer import i18n +from ceilometer.i18n import _ from ceilometer.openstack.common import log LOG = log.getLogger(__name__) @@ -46,7 +46,7 @@ class ParsableErrorMiddleware(object): """ if not accept_language: return None - all_languages = gettextutils.get_available_languages('ceilometer') + all_languages = i18n.get_available_languages() return accept_language.best_match(all_languages) def __init__(self, app): @@ -99,9 +99,8 @@ class ParsableErrorMiddleware(object): # Add the translated error to the xml data if error is not None: for fault_string in fault.findall('faultstring'): - fault_string.text = ( - gettextutils.translate( - error, user_locale)) + fault_string.text = i18n.translate(error, + user_locale) body = ['' + etree.tostring(fault) + ''] except etree.XMLSyntaxError as err: @@ -113,9 +112,8 @@ class ParsableErrorMiddleware(object): try: fault = json.loads('\n'.join(app_iter)) if error is not None and 'faultstring' in fault: - fault['faultstring'] = ( - gettextutils.translate( - error, user_locale)) + fault['faultstring'] = i18n.translate(error, + user_locale) body = [json.dumps({'error_message': fault})] except ValueError as err: body = [json.dumps({'error_message': '\n'.join(app_iter)})] diff --git a/ceilometer/central/discovery.py b/ceilometer/central/discovery.py index 1e3ccb3f..eee1595b 100644 --- a/ceilometer/central/discovery.py +++ b/ceilometer/central/discovery.py @@ -17,7 +17,7 @@ from oslo.config import cfg -from ceilometer.openstack.common.gettextutils import _LW +from ceilometer.i18n import _LW from ceilometer.openstack.common import log from ceilometer import plugin diff --git a/ceilometer/central/plugin.py b/ceilometer/central/plugin.py index 941b5063..17a38a1c 100644 --- a/ceilometer/central/plugin.py +++ b/ceilometer/central/plugin.py @@ -19,7 +19,7 @@ from keystoneclient.v2_0 import client as ksclient from oslo.config import cfg -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log from ceilometer import plugin diff --git a/ceilometer/cmd/storage.py b/ceilometer/cmd/storage.py index f7f95ef5..a4d85069 100644 --- a/ceilometer/cmd/storage.py +++ b/ceilometer/cmd/storage.py @@ -18,6 +18,7 @@ import logging from oslo.config import cfg +from ceilometer.i18n import _ from ceilometer import service from ceilometer import storage diff --git a/ceilometer/collector.py b/ceilometer/collector.py index 0d0fcdee..d715f72f 100644 --- a/ceilometer/collector.py +++ b/ceilometer/collector.py @@ -24,8 +24,7 @@ from oslo.utils import units from ceilometer import dispatcher from ceilometer import messaging -from ceilometer.openstack.common.gettextutils import _ -from ceilometer.openstack.common.gettextutils import _LE +from ceilometer.i18n import _, _LE from ceilometer.openstack.common import log from ceilometer.openstack.common import service as os_service diff --git a/ceilometer/compute/notifications/cpu.py b/ceilometer/compute/notifications/cpu.py index f4cd2c07..75c1f5ed 100644 --- a/ceilometer/compute/notifications/cpu.py +++ b/ceilometer/compute/notifications/cpu.py @@ -20,7 +20,7 @@ events. from oslo.utils import timeutils from ceilometer.compute import notifications -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log from ceilometer import sample diff --git a/ceilometer/compute/nova_notifier.py b/ceilometer/compute/nova_notifier.py index 70771b66..5bdd3800 100644 --- a/ceilometer/compute/nova_notifier.py +++ b/ceilometer/compute/nova_notifier.py @@ -32,7 +32,7 @@ from stevedore import extension # use the real ceilometer base package import ceilometer # noqa from ceilometer.compute.virt import inspector -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ for name in ['openstack', 'openstack.common', 'openstack.common.log']: sys.modules['ceilometer.' + name] = sys.modules['nova.' + name] diff --git a/ceilometer/compute/pollsters/cpu.py b/ceilometer/compute/pollsters/cpu.py index 4a187603..bf30f8c1 100644 --- a/ceilometer/compute/pollsters/cpu.py +++ b/ceilometer/compute/pollsters/cpu.py @@ -20,7 +20,7 @@ import ceilometer from ceilometer.compute import plugin from ceilometer.compute.pollsters import util from ceilometer.compute.virt import inspector as virt_inspector -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log from ceilometer import sample diff --git a/ceilometer/compute/pollsters/disk.py b/ceilometer/compute/pollsters/disk.py index c8057dd2..5990ce25 100644 --- a/ceilometer/compute/pollsters/disk.py +++ b/ceilometer/compute/pollsters/disk.py @@ -27,7 +27,7 @@ import ceilometer from ceilometer.compute import plugin from ceilometer.compute.pollsters import util from ceilometer.compute.virt import inspector as virt_inspector -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log from ceilometer import sample diff --git a/ceilometer/compute/pollsters/memory.py b/ceilometer/compute/pollsters/memory.py index f8d8001e..569a08f8 100644 --- a/ceilometer/compute/pollsters/memory.py +++ b/ceilometer/compute/pollsters/memory.py @@ -16,7 +16,7 @@ import ceilometer from ceilometer.compute import plugin from ceilometer.compute.pollsters import util from ceilometer.compute.virt import inspector as virt_inspector -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log from ceilometer import sample diff --git a/ceilometer/compute/pollsters/net.py b/ceilometer/compute/pollsters/net.py index 8056bdae..dd545872 100644 --- a/ceilometer/compute/pollsters/net.py +++ b/ceilometer/compute/pollsters/net.py @@ -26,7 +26,7 @@ from ceilometer.compute import plugin from ceilometer.compute.pollsters import util from ceilometer.compute import util as compute_util from ceilometer.compute.virt import inspector as virt_inspector -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log from ceilometer import sample diff --git a/ceilometer/compute/virt/hyperv/utilsv2.py b/ceilometer/compute/virt/hyperv/utilsv2.py index e06beb7e..b448b5b4 100644 --- a/ceilometer/compute/virt/hyperv/utilsv2.py +++ b/ceilometer/compute/virt/hyperv/utilsv2.py @@ -28,7 +28,7 @@ if sys.platform == 'win32': from oslo.config import cfg from ceilometer.compute.virt import inspector -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log as logging CONF = cfg.CONF diff --git a/ceilometer/compute/virt/inspector.py b/ceilometer/compute/virt/inspector.py index 28aa904c..901eb4eb 100644 --- a/ceilometer/compute/virt/inspector.py +++ b/ceilometer/compute/virt/inspector.py @@ -23,7 +23,7 @@ from oslo.config import cfg from stevedore import driver import ceilometer -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log diff --git a/ceilometer/compute/virt/libvirt/inspector.py b/ceilometer/compute/virt/libvirt/inspector.py index e9f423e2..1e842e09 100644 --- a/ceilometer/compute/virt/libvirt/inspector.py +++ b/ceilometer/compute/virt/libvirt/inspector.py @@ -23,7 +23,7 @@ import six from ceilometer.compute.pollsters import util from ceilometer.compute.virt import inspector as virt_inspector -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log as logging libvirt = None diff --git a/ceilometer/compute/virt/vmware/inspector.py b/ceilometer/compute/virt/vmware/inspector.py index b38f868b..be61b316 100644 --- a/ceilometer/compute/virt/vmware/inspector.py +++ b/ceilometer/compute/virt/vmware/inspector.py @@ -21,7 +21,7 @@ from oslo.vmware import api from ceilometer.compute.virt import inspector as virt_inspector from ceilometer.compute.virt.vmware import vsphere_operations -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ opt_group = cfg.OptGroup(name='vmware', diff --git a/ceilometer/compute/virt/xenapi/inspector.py b/ceilometer/compute/virt/xenapi/inspector.py index a9e6573b..00f1dd1d 100644 --- a/ceilometer/compute/virt/xenapi/inspector.py +++ b/ceilometer/compute/virt/xenapi/inspector.py @@ -25,7 +25,7 @@ except ImportError: from ceilometer.compute.pollsters import util from ceilometer.compute.virt import inspector as virt_inspector -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ opt_group = cfg.OptGroup(name='xenapi', title='Options for XenAPI') diff --git a/ceilometer/coordination.py b/ceilometer/coordination.py index 59365a9f..db3c82f0 100644 --- a/ceilometer/coordination.py +++ b/ceilometer/coordination.py @@ -20,7 +20,7 @@ import uuid from oslo.config import cfg import tooz.coordination -from ceilometer.openstack.common.gettextutils import _LE, _LI +from ceilometer.i18n import _LE, _LI from ceilometer.openstack.common import log from ceilometer import utils diff --git a/ceilometer/dispatcher/__init__.py b/ceilometer/dispatcher/__init__.py index a7baf5e7..86d2b013 100644 --- a/ceilometer/dispatcher/__init__.py +++ b/ceilometer/dispatcher/__init__.py @@ -21,7 +21,7 @@ from oslo.config import cfg import six from stevedore import named -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log diff --git a/ceilometer/dispatcher/database.py b/ceilometer/dispatcher/database.py index 85a2831c..f21c799c 100644 --- a/ceilometer/dispatcher/database.py +++ b/ceilometer/dispatcher/database.py @@ -17,7 +17,7 @@ from oslo.utils import timeutils from ceilometer import dispatcher -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log from ceilometer.publisher import utils as publisher_utils from ceilometer import storage diff --git a/ceilometer/dispatcher/http.py b/ceilometer/dispatcher/http.py index ec858e15..ba8627c0 100755 --- a/ceilometer/dispatcher/http.py +++ b/ceilometer/dispatcher/http.py @@ -20,7 +20,7 @@ from oslo.config import cfg import requests from ceilometer import dispatcher -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log from ceilometer.publisher import utils as publisher_utils diff --git a/ceilometer/energy/kwapi.py b/ceilometer/energy/kwapi.py index 4a73d147..e6439c1b 100644 --- a/ceilometer/energy/kwapi.py +++ b/ceilometer/energy/kwapi.py @@ -22,7 +22,7 @@ import requests import six from ceilometer.central import plugin -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log from ceilometer import sample diff --git a/ceilometer/event/converter.py b/ceilometer/event/converter.py index 2326806e..fc27575c 100644 --- a/ceilometer/event/converter.py +++ b/ceilometer/event/converter.py @@ -25,7 +25,7 @@ import six import yaml from ceilometer.event.storage import models -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log OPTS = [ diff --git a/ceilometer/event/endpoint.py b/ceilometer/event/endpoint.py index c50daf6e..cdd9a42a 100644 --- a/ceilometer/event/endpoint.py +++ b/ceilometer/event/endpoint.py @@ -25,8 +25,8 @@ import ceilometer from ceilometer import dispatcher from ceilometer.event import converter as event_converter from ceilometer.event.storage import models +from ceilometer.i18n import _ from ceilometer import messaging -from ceilometer.openstack.common.gettextutils import _ LOG = logging.getLogger(__name__) diff --git a/ceilometer/event/storage/impl_hbase.py b/ceilometer/event/storage/impl_hbase.py index 61dae71c..80ca62a3 100644 --- a/ceilometer/event/storage/impl_hbase.py +++ b/ceilometer/event/storage/impl_hbase.py @@ -15,7 +15,7 @@ import operator from ceilometer.event.storage import base from ceilometer.event.storage import models -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log from ceilometer.storage.hbase import base as hbase_base from ceilometer.storage.hbase import utils as hbase_utils diff --git a/ceilometer/event/storage/impl_sqlalchemy.py b/ceilometer/event/storage/impl_sqlalchemy.py index 3a6e5de7..5b683bbe 100644 --- a/ceilometer/event/storage/impl_sqlalchemy.py +++ b/ceilometer/event/storage/impl_sqlalchemy.py @@ -25,7 +25,7 @@ import sqlalchemy as sa from ceilometer.event.storage import base from ceilometer.event.storage import models as api_models -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log from ceilometer.storage.sqlalchemy import models from ceilometer.storage.sqlalchemy import utils as sql_utils diff --git a/ceilometer/event/storage/pymongo_base.py b/ceilometer/event/storage/pymongo_base.py index bac948b2..461db6b1 100644 --- a/ceilometer/event/storage/pymongo_base.py +++ b/ceilometer/event/storage/pymongo_base.py @@ -16,7 +16,7 @@ import pymongo from ceilometer.event.storage import base from ceilometer.event.storage import models -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log from ceilometer.storage.mongo import utils as pymongo_utils from ceilometer import utils diff --git a/ceilometer/hardware/discovery.py b/ceilometer/hardware/discovery.py index cbcd5aa7..15bb1740 100644 --- a/ceilometer/hardware/discovery.py +++ b/ceilometer/hardware/discovery.py @@ -14,8 +14,8 @@ from oslo.config import cfg +from ceilometer.i18n import _ from ceilometer import nova_client -from ceilometer.openstack.common.gettextutils import _ from ceilometer.openstack.common import log from ceilometer import plugin diff --git a/ceilometer/hardware/plugin.py b/ceilometer/hardware/plugin.py index fb6740f3..5b42ba2b 100644 --- a/ceilometer/hardware/plugin.py +++ b/ceilometer/hardware/plugin.py @@ -27,7 +27,7 @@ import six from ceilometer.central import plugin from ceilometer.hardware import inspector as insloader -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log LOG = log.getLogger(__name__) diff --git a/ceilometer/i18n.py b/ceilometer/i18n.py new file mode 100644 index 00000000..e9ad5bbf --- /dev/null +++ b/ceilometer/i18n.py @@ -0,0 +1,46 @@ +# Copyright 2014 Huawei Technologies Co., Ltd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""oslo.i18n integration module. + +See http://docs.openstack.org/developer/oslo.i18n/usage.html + +""" + +from oslo import i18n + +DOMAIN = 'ceilometer' + +_translators = i18n.TranslatorFactory(domain=DOMAIN) + +# The primary translation function using the well-known name "_" +_ = _translators.primary + +# Translators for log levels. +# +# The abbreviated names are meant to reflect the usual use of a short +# name like '_'. The "L" is for "log" and the other letter comes from +# the level. +_LI = _translators.log_info +_LW = _translators.log_warning +_LE = _translators.log_error +_LC = _translators.log_critical + + +def translate(value, user_locale): + return i18n.translate(value, user_locale) + + +def get_available_languages(): + return i18n.get_available_languages(DOMAIN) diff --git a/ceilometer/ipmi/platform/intel_node_manager.py b/ceilometer/ipmi/platform/intel_node_manager.py index 6743ccf9..85b81d51 100644 --- a/ceilometer/ipmi/platform/intel_node_manager.py +++ b/ceilometer/ipmi/platform/intel_node_manager.py @@ -31,9 +31,9 @@ import time from oslo.config import cfg +from ceilometer.i18n import _ from ceilometer.ipmi.platform import exception as nmexcept from ceilometer.ipmi.platform import ipmitool -from ceilometer.openstack.common.gettextutils import _ OPTS = [ diff --git a/ceilometer/ipmi/platform/ipmi_sensor.py b/ceilometer/ipmi/platform/ipmi_sensor.py index 9749c485..ce7ed31a 100644 --- a/ceilometer/ipmi/platform/ipmi_sensor.py +++ b/ceilometer/ipmi/platform/ipmi_sensor.py @@ -16,9 +16,9 @@ """IPMI sensor to collect various sensor data of compute node""" +from ceilometer.i18n import _ from ceilometer.ipmi.platform import exception as ipmiexcept from ceilometer.ipmi.platform import ipmitool -from ceilometer.openstack.common.gettextutils import _ IPMICMD = {"sdr_dump": "sdr dump", "sdr_info": "sdr info", diff --git a/ceilometer/ipmi/platform/ipmitool.py b/ceilometer/ipmi/platform/ipmitool.py index fa8222b3..928b91fd 100644 --- a/ceilometer/ipmi/platform/ipmitool.py +++ b/ceilometer/ipmi/platform/ipmitool.py @@ -18,8 +18,8 @@ """Utils to run ipmitool for data collection""" from oslo_concurrency import processutils +from ceilometer.i18n import _ from ceilometer.ipmi.platform import exception as ipmiexcept -from ceilometer.openstack.common.gettextutils import _ from ceilometer import utils diff --git a/ceilometer/network/floatingip.py b/ceilometer/network/floatingip.py index 132e0fe7..6bfebc1f 100644 --- a/ceilometer/network/floatingip.py +++ b/ceilometer/network/floatingip.py @@ -22,8 +22,8 @@ from oslo.config import cfg from oslo.utils import timeutils from ceilometer.central import plugin +from ceilometer.i18n import _ from ceilometer import nova_client -from ceilometer.openstack.common.gettextutils import _ from ceilometer.openstack.common import log from ceilometer import sample diff --git a/ceilometer/network/notifications.py b/ceilometer/network/notifications.py index 1fdf4b7a..dd8c6b90 100644 --- a/ceilometer/network/notifications.py +++ b/ceilometer/network/notifications.py @@ -22,7 +22,7 @@ from oslo.config import cfg import oslo.messaging -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log from ceilometer import plugin from ceilometer import sample diff --git a/ceilometer/network/services/fwaas.py b/ceilometer/network/services/fwaas.py index 813cc38f..ed6a1ab5 100644 --- a/ceilometer/network/services/fwaas.py +++ b/ceilometer/network/services/fwaas.py @@ -16,8 +16,8 @@ # under the License. from oslo.utils import timeutils +from ceilometer.i18n import _ from ceilometer.network.services import base -from ceilometer.openstack.common.gettextutils import _ from ceilometer.openstack.common import log from ceilometer import sample diff --git a/ceilometer/network/services/lbaas.py b/ceilometer/network/services/lbaas.py index 24ccdd28..9663eb8b 100644 --- a/ceilometer/network/services/lbaas.py +++ b/ceilometer/network/services/lbaas.py @@ -21,8 +21,8 @@ import collections from oslo.utils import timeutils import six +from ceilometer.i18n import _ from ceilometer.network.services import base -from ceilometer.openstack.common.gettextutils import _ from ceilometer.openstack.common import log from ceilometer import sample diff --git a/ceilometer/network/services/vpnaas.py b/ceilometer/network/services/vpnaas.py index e855b9a3..0c9e7dbf 100644 --- a/ceilometer/network/services/vpnaas.py +++ b/ceilometer/network/services/vpnaas.py @@ -16,8 +16,8 @@ # under the License. from oslo.utils import timeutils +from ceilometer.i18n import _ from ceilometer.network.services import base -from ceilometer.openstack.common.gettextutils import _ from ceilometer.openstack.common import log from ceilometer import sample diff --git a/ceilometer/network/statistics/opencontrail/client.py b/ceilometer/network/statistics/opencontrail/client.py index 0e0b9e9c..9d9f7c45 100644 --- a/ceilometer/network/statistics/opencontrail/client.py +++ b/ceilometer/network/statistics/opencontrail/client.py @@ -19,7 +19,7 @@ import requests import six from six.moves.urllib import parse as urlparse -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log diff --git a/ceilometer/network/statistics/opendaylight/client.py b/ceilometer/network/statistics/opendaylight/client.py index 6bc963fb..d5c9beb8 100644 --- a/ceilometer/network/statistics/opendaylight/client.py +++ b/ceilometer/network/statistics/opendaylight/client.py @@ -20,7 +20,7 @@ import requests from requests import auth import six -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log diff --git a/ceilometer/network/statistics/opendaylight/driver.py b/ceilometer/network/statistics/opendaylight/driver.py index e46c3124..9b974b1f 100644 --- a/ceilometer/network/statistics/opendaylight/driver.py +++ b/ceilometer/network/statistics/opendaylight/driver.py @@ -17,9 +17,9 @@ import six from six import moves from six.moves.urllib import parse as urlparse +from ceilometer.i18n import _ from ceilometer.network.statistics import driver from ceilometer.network.statistics.opendaylight import client -from ceilometer.openstack.common.gettextutils import _ from ceilometer.openstack.common import log from ceilometer import utils diff --git a/ceilometer/notification.py b/ceilometer/notification.py index 33f24be9..274b363d 100644 --- a/ceilometer/notification.py +++ b/ceilometer/notification.py @@ -19,8 +19,8 @@ from oslo.config import cfg from stevedore import extension from ceilometer.event import endpoint as event_endpoint +from ceilometer.i18n import _ from ceilometer import messaging -from ceilometer.openstack.common.gettextutils import _ from ceilometer.openstack.common import log from ceilometer.openstack.common import service as os_service from ceilometer import pipeline diff --git a/ceilometer/notifier.py b/ceilometer/notifier.py index 53e06643..a8946f84 100644 --- a/ceilometer/notifier.py +++ b/ceilometer/notifier.py @@ -17,8 +17,8 @@ from stevedore import extension +from ceilometer.i18n import _ from ceilometer.openstack.common import context as req_context -from ceilometer.openstack.common.gettextutils import _ from ceilometer.openstack.common import log as logging from ceilometer import pipeline from ceilometer import transformer diff --git a/ceilometer/objectstore/swift.py b/ceilometer/objectstore/swift.py index 3abc763d..c16f65e8 100644 --- a/ceilometer/objectstore/swift.py +++ b/ceilometer/objectstore/swift.py @@ -26,7 +26,7 @@ import six.moves.urllib.parse as urlparse from swiftclient import client as swift from ceilometer.central import plugin -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log from ceilometer import sample diff --git a/ceilometer/openstack/common/gettextutils.py b/ceilometer/openstack/common/gettextutils.py deleted file mode 100644 index 68747cc2..00000000 --- a/ceilometer/openstack/common/gettextutils.py +++ /dev/null @@ -1,479 +0,0 @@ -# Copyright 2012 Red Hat, Inc. -# Copyright 2013 IBM Corp. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -""" -gettext for openstack-common modules. - -Usual usage in an openstack.common module: - - from ceilometer.openstack.common.gettextutils import _ -""" - -import copy -import gettext -import locale -from logging import handlers -import os - -from babel import localedata -import six - -_AVAILABLE_LANGUAGES = {} - -# FIXME(dhellmann): Remove this when moving to oslo.i18n. -USE_LAZY = False - - -class TranslatorFactory(object): - """Create translator functions - """ - - def __init__(self, domain, localedir=None): - """Establish a set of translation functions for the domain. - - :param domain: Name of translation domain, - specifying a message catalog. - :type domain: str - :param lazy: Delays translation until a message is emitted. - Defaults to False. - :type lazy: Boolean - :param localedir: Directory with translation catalogs. - :type localedir: str - """ - self.domain = domain - if localedir is None: - localedir = os.environ.get(domain.upper() + '_LOCALEDIR') - self.localedir = localedir - - def _make_translation_func(self, domain=None): - """Return a new translation function ready for use. - - Takes into account whether or not lazy translation is being - done. - - The domain can be specified to override the default from the - factory, but the localedir from the factory is always used - because we assume the log-level translation catalogs are - installed in the same directory as the main application - catalog. - - """ - if domain is None: - domain = self.domain - t = gettext.translation(domain, - localedir=self.localedir, - fallback=True) - # Use the appropriate method of the translation object based - # on the python version. - m = t.gettext if six.PY3 else t.ugettext - - def f(msg): - """oslo.i18n.gettextutils translation function.""" - if USE_LAZY: - return Message(msg, domain=domain) - return m(msg) - return f - - @property - def primary(self): - "The default translation function." - return self._make_translation_func() - - def _make_log_translation_func(self, level): - return self._make_translation_func(self.domain + '-log-' + level) - - @property - def log_info(self): - "Translate info-level log messages." - return self._make_log_translation_func('info') - - @property - def log_warning(self): - "Translate warning-level log messages." - return self._make_log_translation_func('warning') - - @property - def log_error(self): - "Translate error-level log messages." - return self._make_log_translation_func('error') - - @property - def log_critical(self): - "Translate critical-level log messages." - return self._make_log_translation_func('critical') - - -# NOTE(dhellmann): When this module moves out of the incubator into -# oslo.i18n, these global variables can be moved to an integration -# module within each application. - -# Create the global translation functions. -_translators = TranslatorFactory('ceilometer') - -# The primary translation function using the well-known name "_" -_ = _translators.primary - -# Translators for log levels. -# -# The abbreviated names are meant to reflect the usual use of a short -# name like '_'. The "L" is for "log" and the other letter comes from -# the level. -_LI = _translators.log_info -_LW = _translators.log_warning -_LE = _translators.log_error -_LC = _translators.log_critical - -# NOTE(dhellmann): End of globals that will move to the application's -# integration module. - - -def enable_lazy(): - """Convenience function for configuring _() to use lazy gettext - - Call this at the start of execution to enable the gettextutils._ - function to use lazy gettext functionality. This is useful if - your project is importing _ directly instead of using the - gettextutils.install() way of importing the _ function. - """ - global USE_LAZY - USE_LAZY = True - - -def install(domain): - """Install a _() function using the given translation domain. - - Given a translation domain, install a _() function using gettext's - install() function. - - The main difference from gettext.install() is that we allow - overriding the default localedir (e.g. /usr/share/locale) using - a translation-domain-specific environment variable (e.g. - NOVA_LOCALEDIR). - - Note that to enable lazy translation, enable_lazy must be - called. - - :param domain: the translation domain - """ - from six import moves - tf = TranslatorFactory(domain) - moves.builtins.__dict__['_'] = tf.primary - - -class Message(six.text_type): - """A Message object is a unicode object that can be translated. - - Translation of Message is done explicitly using the translate() method. - For all non-translation intents and purposes, a Message is simply unicode, - and can be treated as such. - """ - - def __new__(cls, msgid, msgtext=None, params=None, - domain='ceilometer', *args): - """Create a new Message object. - - In order for translation to work gettext requires a message ID, this - msgid will be used as the base unicode text. It is also possible - for the msgid and the base unicode text to be different by passing - the msgtext parameter. - """ - # If the base msgtext is not given, we use the default translation - # of the msgid (which is in English) just in case the system locale is - # not English, so that the base text will be in that locale by default. - if not msgtext: - msgtext = Message._translate_msgid(msgid, domain) - # We want to initialize the parent unicode with the actual object that - # would have been plain unicode if 'Message' was not enabled. - msg = super(Message, cls).__new__(cls, msgtext) - msg.msgid = msgid - msg.domain = domain - msg.params = params - return msg - - def translate(self, desired_locale=None): - """Translate this message to the desired locale. - - :param desired_locale: The desired locale to translate the message to, - if no locale is provided the message will be - translated to the system's default locale. - - :returns: the translated message in unicode - """ - - translated_message = Message._translate_msgid(self.msgid, - self.domain, - desired_locale) - if self.params is None: - # No need for more translation - return translated_message - - # This Message object may have been formatted with one or more - # Message objects as substitution arguments, given either as a single - # argument, part of a tuple, or as one or more values in a dictionary. - # When translating this Message we need to translate those Messages too - translated_params = _translate_args(self.params, desired_locale) - - translated_message = translated_message % translated_params - - return translated_message - - @staticmethod - def _translate_msgid(msgid, domain, desired_locale=None): - if not desired_locale: - system_locale = locale.getdefaultlocale() - # If the system locale is not available to the runtime use English - if not system_locale[0]: - desired_locale = 'en_US' - else: - desired_locale = system_locale[0] - - locale_dir = os.environ.get(domain.upper() + '_LOCALEDIR') - lang = gettext.translation(domain, - localedir=locale_dir, - languages=[desired_locale], - fallback=True) - if six.PY3: - translator = lang.gettext - else: - translator = lang.ugettext - - translated_message = translator(msgid) - return translated_message - - def __mod__(self, other): - # When we mod a Message we want the actual operation to be performed - # by the parent class (i.e. unicode()), the only thing we do here is - # save the original msgid and the parameters in case of a translation - params = self._sanitize_mod_params(other) - unicode_mod = super(Message, self).__mod__(params) - modded = Message(self.msgid, - msgtext=unicode_mod, - params=params, - domain=self.domain) - return modded - - def _sanitize_mod_params(self, other): - """Sanitize the object being modded with this Message. - - - Add support for modding 'None' so translation supports it - - Trim the modded object, which can be a large dictionary, to only - those keys that would actually be used in a translation - - Snapshot the object being modded, in case the message is - translated, it will be used as it was when the Message was created - """ - if other is None: - params = (other,) - elif isinstance(other, dict): - # Merge the dictionaries - # Copy each item in case one does not support deep copy. - params = {} - if isinstance(self.params, dict): - for key, val in self.params.items(): - params[key] = self._copy_param(val) - for key, val in other.items(): - params[key] = self._copy_param(val) - else: - params = self._copy_param(other) - return params - - def _copy_param(self, param): - try: - return copy.deepcopy(param) - except Exception: - # Fallback to casting to unicode this will handle the - # python code-like objects that can't be deep-copied - return six.text_type(param) - - def __add__(self, other): - msg = _('Message objects do not support addition.') - raise TypeError(msg) - - def __radd__(self, other): - return self.__add__(other) - - if six.PY2: - def __str__(self): - # NOTE(luisg): Logging in python 2.6 tries to str() log records, - # and it expects specifically a UnicodeError in order to proceed. - msg = _('Message objects do not support str() because they may ' - 'contain non-ascii characters. ' - 'Please use unicode() or translate() instead.') - raise UnicodeError(msg) - - -def get_available_languages(domain): - """Lists the available languages for the given translation domain. - - :param domain: the domain to get languages for - """ - if domain in _AVAILABLE_LANGUAGES: - return copy.copy(_AVAILABLE_LANGUAGES[domain]) - - localedir = '%s_LOCALEDIR' % domain.upper() - find = lambda x: gettext.find(domain, - localedir=os.environ.get(localedir), - languages=[x]) - - # NOTE(mrodden): en_US should always be available (and first in case - # order matters) since our in-line message strings are en_US - language_list = ['en_US'] - # NOTE(luisg): Babel <1.0 used a function called list(), which was - # renamed to locale_identifiers() in >=1.0, the requirements master list - # requires >=0.9.6, uncapped, so defensively work with both. We can remove - # this check when the master list updates to >=1.0, and update all projects - list_identifiers = (getattr(localedata, 'list', None) or - getattr(localedata, 'locale_identifiers')) - locale_identifiers = list_identifiers() - - for i in locale_identifiers: - if find(i) is not None: - language_list.append(i) - - # NOTE(luisg): Babel>=1.0,<1.3 has a bug where some OpenStack supported - # locales (e.g. 'zh_CN', and 'zh_TW') aren't supported even though they - # are perfectly legitimate locales: - # https://github.com/mitsuhiko/babel/issues/37 - # In Babel 1.3 they fixed the bug and they support these locales, but - # they are still not explicitly "listed" by locale_identifiers(). - # That is why we add the locales here explicitly if necessary so that - # they are listed as supported. - aliases = {'zh': 'zh_CN', - 'zh_Hant_HK': 'zh_HK', - 'zh_Hant': 'zh_TW', - 'fil': 'tl_PH'} - for (locale_, alias) in six.iteritems(aliases): - if locale_ in language_list and alias not in language_list: - language_list.append(alias) - - _AVAILABLE_LANGUAGES[domain] = language_list - return copy.copy(language_list) - - -def translate(obj, desired_locale=None): - """Gets the translated unicode representation of the given object. - - If the object is not translatable it is returned as-is. - If the locale is None the object is translated to the system locale. - - :param obj: the object to translate - :param desired_locale: the locale to translate the message to, if None the - default system locale will be used - :returns: the translated object in unicode, or the original object if - it could not be translated - """ - message = obj - if not isinstance(message, Message): - # If the object to translate is not already translatable, - # let's first get its unicode representation - message = six.text_type(obj) - if isinstance(message, Message): - # Even after unicoding() we still need to check if we are - # running with translatable unicode before translating - return message.translate(desired_locale) - return obj - - -def _translate_args(args, desired_locale=None): - """Translates all the translatable elements of the given arguments object. - - This method is used for translating the translatable values in method - arguments which include values of tuples or dictionaries. - If the object is not a tuple or a dictionary the object itself is - translated if it is translatable. - - If the locale is None the object is translated to the system locale. - - :param args: the args to translate - :param desired_locale: the locale to translate the args to, if None the - default system locale will be used - :returns: a new args object with the translated contents of the original - """ - if isinstance(args, tuple): - return tuple(translate(v, desired_locale) for v in args) - if isinstance(args, dict): - translated_dict = {} - for (k, v) in six.iteritems(args): - translated_v = translate(v, desired_locale) - translated_dict[k] = translated_v - return translated_dict - return translate(args, desired_locale) - - -class TranslationHandler(handlers.MemoryHandler): - """Handler that translates records before logging them. - - The TranslationHandler takes a locale and a target logging.Handler object - to forward LogRecord objects to after translating them. This handler - depends on Message objects being logged, instead of regular strings. - - The handler can be configured declaratively in the logging.conf as follows: - - [handlers] - keys = translatedlog, translator - - [handler_translatedlog] - class = handlers.WatchedFileHandler - args = ('/var/log/api-localized.log',) - formatter = context - - [handler_translator] - class = openstack.common.log.TranslationHandler - target = translatedlog - args = ('zh_CN',) - - If the specified locale is not available in the system, the handler will - log in the default locale. - """ - - def __init__(self, locale=None, target=None): - """Initialize a TranslationHandler - - :param locale: locale to use for translating messages - :param target: logging.Handler object to forward - LogRecord objects to after translation - """ - # NOTE(luisg): In order to allow this handler to be a wrapper for - # other handlers, such as a FileHandler, and still be able to - # configure it using logging.conf, this handler has to extend - # MemoryHandler because only the MemoryHandlers' logging.conf - # parsing is implemented such that it accepts a target handler. - handlers.MemoryHandler.__init__(self, capacity=0, target=target) - self.locale = locale - - def setFormatter(self, fmt): - self.target.setFormatter(fmt) - - def emit(self, record): - # We save the message from the original record to restore it - # after translation, so other handlers are not affected by this - original_msg = record.msg - original_args = record.args - - try: - self._translate_and_log_record(record) - finally: - record.msg = original_msg - record.args = original_args - - def _translate_and_log_record(self, record): - record.msg = translate(record.msg, self.locale) - - # In addition to translating the message, we also need to translate - # arguments that were passed to the log method that were not part - # of the main message e.g., log.info(_('Some message %s'), this_one)) - record.args = _translate_args(record.args, self.locale) - - self.target.emit(record) diff --git a/ceilometer/openstack/common/timeutils.py b/ceilometer/openstack/common/timeutils.py deleted file mode 100644 index c48da95f..00000000 --- a/ceilometer/openstack/common/timeutils.py +++ /dev/null @@ -1,210 +0,0 @@ -# Copyright 2011 OpenStack Foundation. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -""" -Time related utilities and helper functions. -""" - -import calendar -import datetime -import time - -import iso8601 -import six - - -# ISO 8601 extended time format with microseconds -_ISO8601_TIME_FORMAT_SUBSECOND = '%Y-%m-%dT%H:%M:%S.%f' -_ISO8601_TIME_FORMAT = '%Y-%m-%dT%H:%M:%S' -PERFECT_TIME_FORMAT = _ISO8601_TIME_FORMAT_SUBSECOND - - -def isotime(at=None, subsecond=False): - """Stringify time in ISO 8601 format.""" - if not at: - at = utcnow() - st = at.strftime(_ISO8601_TIME_FORMAT - if not subsecond - else _ISO8601_TIME_FORMAT_SUBSECOND) - tz = at.tzinfo.tzname(None) if at.tzinfo else 'UTC' - st += ('Z' if tz == 'UTC' else tz) - return st - - -def parse_isotime(timestr): - """Parse time from ISO 8601 format.""" - try: - return iso8601.parse_date(timestr) - except iso8601.ParseError as e: - raise ValueError(six.text_type(e)) - except TypeError as e: - raise ValueError(six.text_type(e)) - - -def strtime(at=None, fmt=PERFECT_TIME_FORMAT): - """Returns formatted utcnow.""" - if not at: - at = utcnow() - return at.strftime(fmt) - - -def parse_strtime(timestr, fmt=PERFECT_TIME_FORMAT): - """Turn a formatted time back into a datetime.""" - return datetime.datetime.strptime(timestr, fmt) - - -def normalize_time(timestamp): - """Normalize time in arbitrary timezone to UTC naive object.""" - offset = timestamp.utcoffset() - if offset is None: - return timestamp - return timestamp.replace(tzinfo=None) - offset - - -def is_older_than(before, seconds): - """Return True if before is older than seconds.""" - if isinstance(before, six.string_types): - before = parse_strtime(before).replace(tzinfo=None) - else: - before = before.replace(tzinfo=None) - - return utcnow() - before > datetime.timedelta(seconds=seconds) - - -def is_newer_than(after, seconds): - """Return True if after is newer than seconds.""" - if isinstance(after, six.string_types): - after = parse_strtime(after).replace(tzinfo=None) - else: - after = after.replace(tzinfo=None) - - return after - utcnow() > datetime.timedelta(seconds=seconds) - - -def utcnow_ts(): - """Timestamp version of our utcnow function.""" - if utcnow.override_time is None: - # NOTE(kgriffs): This is several times faster - # than going through calendar.timegm(...) - return int(time.time()) - - return calendar.timegm(utcnow().timetuple()) - - -def utcnow(): - """Overridable version of utils.utcnow.""" - if utcnow.override_time: - try: - return utcnow.override_time.pop(0) - except AttributeError: - return utcnow.override_time - return datetime.datetime.utcnow() - - -def iso8601_from_timestamp(timestamp): - """Returns an iso8601 formatted date from timestamp.""" - return isotime(datetime.datetime.utcfromtimestamp(timestamp)) - - -utcnow.override_time = None - - -def set_time_override(override_time=None): - """Overrides utils.utcnow. - - Make it return a constant time or a list thereof, one at a time. - - :param override_time: datetime instance or list thereof. If not - given, defaults to the current UTC time. - """ - utcnow.override_time = override_time or datetime.datetime.utcnow() - - -def advance_time_delta(timedelta): - """Advance overridden time using a datetime.timedelta.""" - assert utcnow.override_time is not None - try: - for dt in utcnow.override_time: - dt += timedelta - except TypeError: - utcnow.override_time += timedelta - - -def advance_time_seconds(seconds): - """Advance overridden time by seconds.""" - advance_time_delta(datetime.timedelta(0, seconds)) - - -def clear_time_override(): - """Remove the overridden time.""" - utcnow.override_time = None - - -def marshall_now(now=None): - """Make an rpc-safe datetime with microseconds. - - Note: tzinfo is stripped, but not required for relative times. - """ - if not now: - now = utcnow() - return dict(day=now.day, month=now.month, year=now.year, hour=now.hour, - minute=now.minute, second=now.second, - microsecond=now.microsecond) - - -def unmarshall_time(tyme): - """Unmarshall a datetime dict.""" - return datetime.datetime(day=tyme['day'], - month=tyme['month'], - year=tyme['year'], - hour=tyme['hour'], - minute=tyme['minute'], - second=tyme['second'], - microsecond=tyme['microsecond']) - - -def delta_seconds(before, after): - """Return the difference between two timing objects. - - Compute the difference in seconds between two date, time, or - datetime objects (as a float, to microsecond resolution). - """ - delta = after - before - return total_seconds(delta) - - -def total_seconds(delta): - """Return the total seconds of datetime.timedelta object. - - Compute total seconds of datetime.timedelta, datetime.timedelta - doesn't have method total_seconds in Python2.6, calculate it manually. - """ - try: - return delta.total_seconds() - except AttributeError: - return ((delta.days * 24 * 3600) + delta.seconds + - float(delta.microseconds) / (10 ** 6)) - - -def is_soon(dt, window): - """Determines if time is going to happen in the next window seconds. - - :param dt: the time - :param window: minimum seconds to remain to consider the time not soon - - :return: True if expiration is within the given duration - """ - soon = (utcnow() + datetime.timedelta(seconds=window)) - return normalize_time(dt) <= soon diff --git a/ceilometer/pipeline.py b/ceilometer/pipeline.py index 62a8f5ab..ee721029 100644 --- a/ceilometer/pipeline.py +++ b/ceilometer/pipeline.py @@ -25,7 +25,7 @@ import os from oslo.config import cfg import yaml -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log from ceilometer import publisher from ceilometer import transformer as xformer diff --git a/ceilometer/plugin.py b/ceilometer/plugin.py index f84c3bdc..9c391d06 100644 --- a/ceilometer/plugin.py +++ b/ceilometer/plugin.py @@ -24,9 +24,9 @@ import fnmatch import oslo.messaging import six +from ceilometer.i18n import _ from ceilometer import messaging from ceilometer.openstack.common import context -from ceilometer.openstack.common.gettextutils import _ from ceilometer.openstack.common import log LOG = log.getLogger(__name__) diff --git a/ceilometer/publisher/file.py b/ceilometer/publisher/file.py index 2d1169a1..af0971bd 100644 --- a/ceilometer/publisher/file.py +++ b/ceilometer/publisher/file.py @@ -20,7 +20,7 @@ import logging.handlers from six.moves.urllib import parse as urlparse -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log from ceilometer import publisher diff --git a/ceilometer/publisher/messaging.py b/ceilometer/publisher/messaging.py index 8513bb1e..9f783557 100644 --- a/ceilometer/publisher/messaging.py +++ b/ceilometer/publisher/messaging.py @@ -26,8 +26,8 @@ import oslo.messaging import six import six.moves.urllib.parse as urlparse +from ceilometer.i18n import _ from ceilometer import messaging -from ceilometer.openstack.common.gettextutils import _ from ceilometer.openstack.common import log from ceilometer import publisher from ceilometer.publisher import utils diff --git a/ceilometer/publisher/udp.py b/ceilometer/publisher/udp.py index 46797a1a..9b387f5a 100644 --- a/ceilometer/publisher/udp.py +++ b/ceilometer/publisher/udp.py @@ -24,7 +24,7 @@ import msgpack from oslo.config import cfg from oslo.utils import netutils -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log from ceilometer import publisher from ceilometer.publisher import utils diff --git a/ceilometer/service.py b/ceilometer/service.py index 9f75fd51..734fa550 100644 --- a/ceilometer/service.py +++ b/ceilometer/service.py @@ -21,10 +21,10 @@ import socket import sys from oslo.config import cfg +from oslo import i18n +from ceilometer.i18n import _ from ceilometer import messaging -from ceilometer.openstack.common import gettextutils -from ceilometer.openstack.common.gettextutils import _ from ceilometer.openstack.common import log from ceilometer import utils @@ -113,8 +113,7 @@ def get_workers(name): def prepare_service(argv=None): - gettextutils.install('ceilometer') - gettextutils.enable_lazy() + i18n.enable_lazy() log_levels = (cfg.CONF.default_log_levels + ['stevedore=INFO', 'keystoneclient=INFO']) cfg.set_defaults(log.log_opts, diff --git a/ceilometer/storage/__init__.py b/ceilometer/storage/__init__.py index e7197cee..258d14ff 100644 --- a/ceilometer/storage/__init__.py +++ b/ceilometer/storage/__init__.py @@ -24,7 +24,7 @@ import six import six.moves.urllib.parse as urlparse from stevedore import driver -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log from ceilometer import utils diff --git a/ceilometer/storage/hbase/base.py b/ceilometer/storage/hbase/base.py index 1e64def0..bd10d307 100644 --- a/ceilometer/storage/hbase/base.py +++ b/ceilometer/storage/hbase/base.py @@ -17,7 +17,7 @@ import happybase from oslo.utils import netutils from six.moves.urllib import parse as urlparse -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log from ceilometer.storage.hbase import inmemory as hbase_inmemory diff --git a/ceilometer/storage/hbase/inmemory.py b/ceilometer/storage/hbase/inmemory.py index 83bde82c..bb305c06 100644 --- a/ceilometer/storage/hbase/inmemory.py +++ b/ceilometer/storage/hbase/inmemory.py @@ -20,7 +20,7 @@ import re import six import ceilometer -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log LOG = log.getLogger(__name__) diff --git a/ceilometer/storage/hbase/utils.py b/ceilometer/storage/hbase/utils.py index b3c35cc6..342c62b5 100644 --- a/ceilometer/storage/hbase/utils.py +++ b/ceilometer/storage/hbase/utils.py @@ -20,7 +20,7 @@ import bson.json_util from happybase.hbase import ttypes import six -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log from ceilometer import utils diff --git a/ceilometer/storage/impl_hbase.py b/ceilometer/storage/impl_hbase.py index b20a0330..fcb089aa 100644 --- a/ceilometer/storage/impl_hbase.py +++ b/ceilometer/storage/impl_hbase.py @@ -18,7 +18,7 @@ import time from oslo.utils import timeutils import ceilometer -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log from ceilometer.storage import base from ceilometer.storage.hbase import base as hbase_base diff --git a/ceilometer/storage/impl_log.py b/ceilometer/storage/impl_log.py index 3cf1d0d1..00306405 100644 --- a/ceilometer/storage/impl_log.py +++ b/ceilometer/storage/impl_log.py @@ -17,7 +17,7 @@ """Simple logging storage backend. """ -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log from ceilometer.storage import base diff --git a/ceilometer/storage/impl_mongodb.py b/ceilometer/storage/impl_mongodb.py index 3b48d186..9afce8b5 100644 --- a/ceilometer/storage/impl_mongodb.py +++ b/ceilometer/storage/impl_mongodb.py @@ -35,6 +35,7 @@ import pymongo import six import ceilometer +from ceilometer.i18n import _ from ceilometer.openstack.common import log from ceilometer import storage from ceilometer.storage import base diff --git a/ceilometer/storage/impl_sqlalchemy.py b/ceilometer/storage/impl_sqlalchemy.py index 8cc587fa..515b9d1a 100644 --- a/ceilometer/storage/impl_sqlalchemy.py +++ b/ceilometer/storage/impl_sqlalchemy.py @@ -34,7 +34,7 @@ from sqlalchemy import func from sqlalchemy.orm import aliased import ceilometer -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log from ceilometer import storage from ceilometer.storage import base diff --git a/ceilometer/storage/mongo/utils.py b/ceilometer/storage/mongo/utils.py index cb6b6b9b..25043a77 100644 --- a/ceilometer/storage/mongo/utils.py +++ b/ceilometer/storage/mongo/utils.py @@ -27,7 +27,7 @@ import pymongo import six from six.moves.urllib import parse -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log LOG = log.getLogger(__name__) diff --git a/ceilometer/tests/api/v2/test_app.py b/ceilometer/tests/api/v2/test_app.py index f1cf5935..cc769a19 100644 --- a/ceilometer/tests/api/v2/test_app.py +++ b/ceilometer/tests/api/v2/test_app.py @@ -22,7 +22,7 @@ import json import mock import wsme -from ceilometer.openstack.common import gettextutils +from ceilometer import i18n from ceilometer.tests.api import v2 @@ -88,7 +88,7 @@ class TestApiMiddleware(v2.FunctionalTest): def test_json_parsable_error_middleware_translation_400(self): # Ensure translated messages get placed properly into json faults - with mock.patch.object(gettextutils, 'translate', + with mock.patch.object(i18n, 'translate', side_effect=self._fake_translate): response = self.post_json('/alarms', params={'name': 'foobar', 'type': 'threshold'}, @@ -123,7 +123,7 @@ class TestApiMiddleware(v2.FunctionalTest): def test_xml_parsable_error_middleware_translation_400(self): # Ensure translated messages get placed properly into xml faults - with mock.patch.object(gettextutils, 'translate', + with mock.patch.object(i18n, 'translate', side_effect=self._fake_translate): response = self.post_json('/alarms', params={'name': 'foobar', 'type': 'threshold'}, @@ -140,7 +140,7 @@ class TestApiMiddleware(v2.FunctionalTest): def test_best_match_language(self): # Ensure that we are actually invoking language negotiation - with mock.patch.object(gettextutils, 'translate', + with mock.patch.object(i18n, 'translate', side_effect=self._fake_translate): response = self.post_json('/alarms', params={'name': 'foobar', 'type': 'threshold'}, diff --git a/ceilometer/tests/network/statistics/opendaylight/test_client.py b/ceilometer/tests/network/statistics/opendaylight/test_client.py index 32d507b7..9af8b012 100644 --- a/ceilometer/tests/network/statistics/opendaylight/test_client.py +++ b/ceilometer/tests/network/statistics/opendaylight/test_client.py @@ -18,8 +18,8 @@ from requests import auth as req_auth import six from six.moves.urllib import parse as urlparse +from ceilometer.i18n import _ from ceilometer.network.statistics.opendaylight import client -from ceilometer.openstack.common.gettextutils import _ class TestClientHTTPBasicAuth(base.BaseTestCase): diff --git a/ceilometer/transformer/arithmetic.py b/ceilometer/transformer/arithmetic.py index 22688e55..2dbc5c93 100644 --- a/ceilometer/transformer/arithmetic.py +++ b/ceilometer/transformer/arithmetic.py @@ -22,7 +22,7 @@ import re import six -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log from ceilometer import sample from ceilometer import transformer diff --git a/ceilometer/transformer/conversions.py b/ceilometer/transformer/conversions.py index ec26b621..f9344757 100644 --- a/ceilometer/transformer/conversions.py +++ b/ceilometer/transformer/conversions.py @@ -21,7 +21,7 @@ import re from oslo.utils import timeutils import six -from ceilometer.openstack.common.gettextutils import _ +from ceilometer.i18n import _ from ceilometer.openstack.common import log from ceilometer import sample from ceilometer import transformer diff --git a/openstack-common.conf b/openstack-common.conf index 342d7242..98fe4c74 100644 --- a/openstack-common.conf +++ b/openstack-common.conf @@ -2,9 +2,7 @@ # The list of modules to copy from oslo-incubator module=context -module=gettextutils module=log -module=log_handler module=policy module=service diff --git a/requirements-py3.txt b/requirements-py3.txt index fb546e5c..b9ce27d3 100644 --- a/requirements-py3.txt +++ b/requirements-py3.txt @@ -17,6 +17,7 @@ netaddr>=0.7.12 oslo.concurrency>=0.3.0 # Apache-2.0 oslo.config>=1.4.0 # Apache-2.0 oslo.db>=1.1.0 # Apache-2.0 +oslo.i18n>=1.0.0 # Apache-2.0 PasteDeploy>=1.5.0 pbr>=0.6,!=0.7,<1.0 pecan>=0.8.0 diff --git a/requirements.txt b/requirements.txt index f7bb423a..cd1010e9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -20,6 +20,7 @@ netaddr>=0.7.12 oslo.db>=1.1.0 # Apache-2.0 oslo.concurrency>=0.3.0 # Apache-2.0 oslo.config>=1.4.0 # Apache-2.0 +oslo.i18n>=1.0.0 # Apache-2.0 oslo.rootwrap>=1.3.0 oslo.vmware>=0.6.0 # Apache-2.0 PasteDeploy>=1.5.0 diff --git a/tox.ini b/tox.ini index 6ca13c6b..052db877 100644 --- a/tox.ini +++ b/tox.ini @@ -69,10 +69,9 @@ commands = [flake8] ignore = -builtins = _ exclude=.venv,.git,.tox,dist,doc,./ceilometer/openstack/common,*lib/python*,*egg,nova_tests,build,tools/lintstack.head.py show-source = True [hacking] import_exceptions = - ceilometer.openstack.common.gettextutils + ceilometer.i18n