
These functions are basic ones but were not able to be imported from message.py since other functions in utils were causing cyclic imports. Isolate it to avoid that problem. Signed-off-by: Lucio Correia <luciojhc@linux.vnet.ibm.com> --- src/wok/control/base.py | 3 +- src/wok/reqlogger.py | 3 +- src/wok/stringutils.py | 154 ++++++++++++++++++++++++++++++++++++++++++++++++ src/wok/utils.py | 136 +----------------------------------------- 4 files changed, 159 insertions(+), 137 deletions(-) create mode 100644 src/wok/stringutils.py IMPORTANT: apply this along with ginger and gingerbase patches. diff --git a/src/wok/control/base.py b/src/wok/control/base.py index 69541b1..6dfc977 100644 --- a/src/wok/control/base.py +++ b/src/wok/control/base.py @@ -33,7 +33,8 @@ from wok.control.utils import validate_params from wok.exception import InvalidOperation, UnauthorizedError, WokException from wok.message import WokMessage from wok.reqlogger import RequestRecord -from wok.utils import get_plugin_from_request, utf8_dict, wok_log, encode_value +from wok.stringutils import encode_value, utf8_dict +from wok.utils import get_plugin_from_request, wok_log # Default request log messages diff --git a/src/wok/reqlogger.py b/src/wok/reqlogger.py index 8fadbcf..fd02382 100644 --- a/src/wok/reqlogger.py +++ b/src/wok/reqlogger.py @@ -30,7 +30,8 @@ from tempfile import NamedTemporaryFile from wok.config import config, get_log_download_path from wok.exception import InvalidParameter, OperationFailed -from wok.utils import ascii_dict, remove_old_files +from wok.stringutils import ascii_dict +from wok.utils import remove_old_files # Log search setup diff --git a/src/wok/stringutils.py b/src/wok/stringutils.py new file mode 100644 index 0000000..8f0160b --- /dev/null +++ b/src/wok/stringutils.py @@ -0,0 +1,154 @@ +# +# Project Wok +# +# Copyright IBM Corp, 2016 +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +import copy +import locale + + +def ascii_dict(base, overlay=None): + result = copy.deepcopy(base) + result.update(overlay or {}) + + for key, value in result.iteritems(): + if isinstance(value, unicode): + result[key] = str(value.decode('utf-8')) + + return result + + +def utf8_dict(base, overlay=None): + result = copy.deepcopy(base) + result.update(overlay or {}) + + for key, value in result.iteritems(): + if isinstance(value, unicode): + result[key] = value.encode('utf-8') + + return result + + +def encode_value(val): + """ + Convert the value to string. + If its unicode, use encode otherwise str. + """ + if isinstance(val, unicode): + return val.encode('utf-8') + return str(val) + + +def decode_value(val): + """ + Converts value to unicode, + if its not an instance of unicode. + For doing so convert the val to string, + if its not instance of basestring. + """ + if not isinstance(val, basestring): + val = str(val) + if not isinstance(val, unicode): + val = val.decode('utf-8') + return val + + +def formatMeasurement(number, settings): + ''' + Refer to "Units of information" ( + http://en.wikipedia.org/wiki/Units_of_information + ) for more information about measurement units. + + @param number The number to be normalized. + @param settings + base Measurement base, accepts 2 or 10. defaults to 2. + unit The unit of the measurement, e.g., B, Bytes/s, bps, etc. + fixed The number of digits after the decimal point. + locale The locale for formating the number if not passed + format is done as per current locale. + @returns [object] + v The number part of the measurement. + s The suffix part of the measurement including multiple and unit. + e.g., kB/s means 1000B/s, KiB/s for 1024B/s. + ''' + unitBaseMapping = {2: [{"us": 'Ki', "v": 1024}, + {"us": 'Mi', "v": 1048576}, + {"us": 'Gi', "v": 1073741824}, + {"us": 'Ti', "v": 1099511627776}, + {"us": 'Pi', "v": 1125899906842624}], + 10: [{"us": 'k', "v": 1000}, + {"us": 'M', "v": 1000000}, + {"us": 'G', "v": 1000000000}, + {"us": 'T', "v": 1000000000000}, + {"us": 'P', "v": 1000000000000000}]} + + if(not number): + return number + settings = settings or {} + unit = settings['unit'] if 'unit' in settings else 'B' + base = settings['base'] if 'base' in settings else 2 + + new_locale = settings['locale'] if 'locale' in settings else '' + + if(base != 2 and base != 10): + return encode_value(number) + unit + + fixed = settings['fixed'] + + unitMapping = unitBaseMapping[base] + for mapping in reversed(unitMapping): + suffix = mapping['us'] + startingValue = mapping['v'] + if(number < startingValue): + continue + + formatted = float(number) / startingValue + formatted = formatNumber(formatted, fixed, new_locale) + return formatted + suffix + unit + + formatted_number = formatNumber(number, fixed, new_locale) + return formatted_number+unit + + +def formatNumber(number, fixed, format_locale): + ''' + Format the number based on format_locale passed. + ''' + + # get the current locale + current_locale = locale.getlocale() + new_locale = '' + # set passed locale and set new_locale to same value. + if format_locale: + new_locale = locale.setlocale(locale.LC_ALL, format_locale) + + # Based on type of number use the correct formatter + if isinstance(number, float): + if fixed: + formatted = locale.format('%' + '.%df' % fixed, number, True) + else: + formatted = locale.format('%f', number, True) + if isinstance(number, int): + formatted = locale.format('%d', number, True) + # After formatting is done as per locale, reset the locale if changed. + if (new_locale and not current_locale[0] and not current_locale[1]): + locale.setlocale(locale.LC_ALL, 'C') + elif (new_locale): + locale.setlocale(locale.LC_ALL, current_locale[0] + "." + + current_locale[1]) + + return formatted diff --git a/src/wok/utils.py b/src/wok/utils.py index c78a77a..d6bdf0a 100644 --- a/src/wok/utils.py +++ b/src/wok/utils.py @@ -21,7 +21,6 @@ # import cherrypy -import copy import glob import grp import os @@ -33,7 +32,6 @@ import subprocess import sys import traceback import xml.etree.ElementTree as ET -import locale from cherrypy.lib.reprconf import Parser from datetime import datetime, timedelta @@ -43,6 +41,7 @@ from threading import Timer from wok.asynctask import AsyncTask from wok.config import paths, PluginPaths from wok.exception import InvalidParameter, TimeoutExpired +from wok.stringutils import decode_value wok_log = cherrypy.log.error_log @@ -137,28 +136,6 @@ def get_plugin_from_request(): return 'wok' -def ascii_dict(base, overlay=None): - result = copy.deepcopy(base) - result.update(overlay or {}) - - for key, value in result.iteritems(): - if isinstance(value, unicode): - result[key] = str(value.decode('utf-8')) - - return result - - -def utf8_dict(base, overlay=None): - result = copy.deepcopy(base) - result.update(overlay or {}) - - for key, value in result.iteritems(): - if isinstance(value, unicode): - result[key] = value.encode('utf-8') - - return result - - def import_class(class_path): module_name, class_name = class_path.rsplit('.', 1) try: @@ -610,114 +587,3 @@ def upgrade_objectstore_schema(objstore=None, field=None): wok_log.error("Cannot upgrade objectstore schema: %s" % e.args[0]) return False return True - - -def encode_value(val): - """ - Convert the value to string. - If its unicode, use encode otherwise str. - """ - if isinstance(val, unicode): - return val.encode('utf-8') - return str(val) - - -def decode_value(val): - """ - Converts value to unicode, - if its not an instance of unicode. - For doing so convert the val to string, - if its not instance of basestring. - """ - if not isinstance(val, basestring): - val = str(val) - if not isinstance(val, unicode): - val = val.decode('utf-8') - return val - - -def formatMeasurement(number, settings): - ''' - Refer to "Units of information" ( - http://en.wikipedia.org/wiki/Units_of_information - ) for more information about measurement units. - - @param number The number to be normalized. - @param settings - base Measurement base, accepts 2 or 10. defaults to 2. - unit The unit of the measurement, e.g., B, Bytes/s, bps, etc. - fixed The number of digits after the decimal point. - locale The locale for formating the number if not passed - format is done as per current locale. - @returns [object] - v The number part of the measurement. - s The suffix part of the measurement including multiple and unit. - e.g., kB/s means 1000B/s, KiB/s for 1024B/s. - ''' - unitBaseMapping = {2: [{"us": 'Ki', "v": 1024}, - {"us": 'Mi', "v": 1048576}, - {"us": 'Gi', "v": 1073741824}, - {"us": 'Ti', "v": 1099511627776}, - {"us": 'Pi', "v": 1125899906842624}], - 10: [{"us": 'k', "v": 1000}, - {"us": 'M', "v": 1000000}, - {"us": 'G', "v": 1000000000}, - {"us": 'T', "v": 1000000000000}, - {"us": 'P', "v": 1000000000000000}]} - - if(not number): - return number - settings = settings or {} - unit = settings['unit'] if 'unit' in settings else 'B' - base = settings['base'] if 'base' in settings else 2 - - new_locale = settings['locale'] if 'locale' in settings else '' - - if(base != 2 and base != 10): - return encode_value(number) + unit - - fixed = settings['fixed'] - - unitMapping = unitBaseMapping[base] - for mapping in reversed(unitMapping): - suffix = mapping['us'] - startingValue = mapping['v'] - if(number < startingValue): - continue - - formatted = float(number) / startingValue - formatted = formatNumber(formatted, fixed, new_locale) - return formatted + suffix + unit - - formatted_number = formatNumber(number, fixed, new_locale) - return formatted_number+unit - - -def formatNumber(number, fixed, format_locale): - ''' - Format the number based on format_locale passed. - ''' - - # get the current locale - current_locale = locale.getlocale() - new_locale = '' - # set passed locale and set new_locale to same value. - if format_locale: - new_locale = locale.setlocale(locale.LC_ALL, format_locale) - - # Based on type of number use the correct formatter - if isinstance(number, float): - if fixed: - formatted = locale.format('%' + '.%df' % fixed, number, True) - else: - formatted = locale.format('%f', number, True) - if isinstance(number, int): - formatted = locale.format('%d', number, True) - # After formatting is done as per locale, reset the locale if changed. - if (new_locale and not current_locale[0] and not current_locale[1]): - locale.setlocale(locale.LC_ALL, 'C') - elif (new_locale): - locale.setlocale(locale.LC_ALL, current_locale[0] + "." + - current_locale[1]) - - return formatted -- 1.9.1