Merge "Replace utils.to_bytes() with strutils.to_bytes()"

This commit is contained in:
Jenkins
2013-06-19 02:11:55 +00:00
committed by Gerrit Code Review
2 changed files with 78 additions and 40 deletions

View File

@@ -19,18 +19,33 @@
System-level utilities and helper functions. System-level utilities and helper functions.
""" """
import re
import sys import sys
import unicodedata
from nova.openstack.common.gettextutils import _ from nova.openstack.common.gettextutils import _
# Used for looking up extensions of text
# to their 'multiplied' byte amount
BYTE_MULTIPLIERS = {
'': 1,
't': 1024 ** 4,
'g': 1024 ** 3,
'm': 1024 ** 2,
'k': 1024,
}
BYTE_REGEX = re.compile(r'(^-?\d+)(\D*)')
TRUE_STRINGS = ('1', 't', 'true', 'on', 'y', 'yes') TRUE_STRINGS = ('1', 't', 'true', 'on', 'y', 'yes')
FALSE_STRINGS = ('0', 'f', 'false', 'off', 'n', 'no') FALSE_STRINGS = ('0', 'f', 'false', 'off', 'n', 'no')
SLUGIFY_STRIP_RE = re.compile(r"[^\w\s-]")
SLUGIFY_HYPHENATE_RE = re.compile(r"[-\s]+")
def int_from_bool_as_string(subject): def int_from_bool_as_string(subject):
""" """Interpret a string as a boolean and return either 1 or 0.
Interpret a string as a boolean and return either 1 or 0.
Any string value in: Any string value in:
@@ -44,8 +59,7 @@ def int_from_bool_as_string(subject):
def bool_from_string(subject, strict=False): def bool_from_string(subject, strict=False):
""" """Interpret a string as a boolean.
Interpret a string as a boolean.
A case-insensitive match is performed such that strings matching 't', A case-insensitive match is performed such that strings matching 't',
'true', 'on', 'y', 'yes', or '1' are considered True and, when 'true', 'on', 'y', 'yes', or '1' are considered True and, when
@@ -78,9 +92,7 @@ def bool_from_string(subject, strict=False):
def safe_decode(text, incoming=None, errors='strict'): def safe_decode(text, incoming=None, errors='strict'):
""" """Decodes incoming str using `incoming` if they're not already unicode.
Decodes incoming str using `incoming` if they're
not already unicode.
:param incoming: Text's current encoding :param incoming: Text's current encoding
:param errors: Errors handling policy. See here for valid :param errors: Errors handling policy. See here for valid
@@ -119,11 +131,10 @@ def safe_decode(text, incoming=None, errors='strict'):
def safe_encode(text, incoming=None, def safe_encode(text, incoming=None,
encoding='utf-8', errors='strict'): encoding='utf-8', errors='strict'):
""" """Encodes incoming str/unicode using `encoding`.
Encodes incoming str/unicode using `encoding`. If
incoming is not specified, text is expected to If incoming is not specified, text is expected to be encoded with
be encoded with current python's default encoding. current python's default encoding. (`sys.getdefaultencoding`)
(`sys.getdefaultencoding`)
:param incoming: Text's current encoding :param incoming: Text's current encoding
:param encoding: Expected encoding for text (Default UTF-8) :param encoding: Expected encoding for text (Default UTF-8)
@@ -148,3 +159,58 @@ def safe_encode(text, incoming=None,
return text.encode(encoding, errors) return text.encode(encoding, errors)
return text return text
def to_bytes(text, default=0):
"""Converts a string into an integer of bytes.
Looks at the last characters of the text to determine
what conversion is needed to turn the input text into a byte number.
Supports "B, K(B), M(B), G(B), and T(B)". (case insensitive)
:param text: String input for bytes size conversion.
:param default: Default return value when text is blank.
"""
match = BYTE_REGEX.search(text)
if match:
magnitude = int(match.group(1))
mult_key_org = match.group(2)
if not mult_key_org:
return magnitude
elif text:
msg = _('Invalid string format: %s') % text
raise TypeError(msg)
else:
return default
mult_key = mult_key_org.lower().replace('b', '', 1)
multiplier = BYTE_MULTIPLIERS.get(mult_key)
if multiplier is None:
msg = _('Unknown byte multiplier: %s') % mult_key_org
raise TypeError(msg)
return magnitude * multiplier
def to_slug(value, incoming=None, errors="strict"):
"""Normalize string.
Convert to lowercase, remove non-word characters, and convert spaces
to hyphens.
Inspired by Django's `slugify` filter.
:param value: Text to slugify
:param incoming: Text's current encoding
:param errors: Errors handling policy. See here for valid
values http://docs.python.org/2/library/codecs.html
:returns: slugified unicode representation of `value`
:raises TypeError: If text is not an instance of basestring
"""
value = safe_decode(value, incoming, errors)
# NOTE(aababilov): no need to use safe_(encode|decode) here:
# encodings are always "ascii", error handling is always "ignore"
# and types are always known (first: unicode; second: str)
value = unicodedata.normalize("NFKD", value).encode(
"ascii", "ignore").decode("ascii")
value = SLUGIFY_STRIP_RE.sub("", value).strip().lower()
return SLUGIFY_HYPHENATE_RE.sub("-", value)

View File

@@ -411,34 +411,6 @@ def utf8(value):
return value return value
def to_bytes(text, default=0):
"""Try to turn a string into a number of bytes. Looks at the last
characters of the text to determine what conversion is needed to
turn the input text into a byte number.
Supports: B/b, K/k, M/m, G/g, T/t (or the same with b/B on the end)
"""
# Take off everything not number 'like' (which should leave
# only the byte 'identifier' left)
mult_key_org = text.lstrip('-1234567890')
mult_key = mult_key_org.lower()
mult_key_len = len(mult_key)
if mult_key.endswith("b"):
mult_key = mult_key[0:-1]
try:
multiplier = BYTE_MULTIPLIERS[mult_key]
if mult_key_len:
# Empty cases shouldn't cause text[0:-0]
text = text[0:-mult_key_len]
return int(text) * multiplier
except KeyError:
msg = _('Unknown byte multiplier: %s') % mult_key_org
raise TypeError(msg)
except ValueError:
return default
def get_from_path(items, path): def get_from_path(items, path):
"""Returns a list of items matching the specified path. """Returns a list of items matching the specified path.