Revert "Revert "Removing deprecated/unused/outdated code""
[osm/RO.git] / RO / osm_ro / utils.py
diff --git a/RO/osm_ro/utils.py b/RO/osm_ro/utils.py
deleted file mode 100644 (file)
index ac291c1..0000000
+++ /dev/null
@@ -1,429 +0,0 @@
-# -*- coding: utf-8 -*-
-
-##
-# Copyright 2015 Telefonica Investigacion y Desarrollo, S.A.U.
-# This file is part of openmano
-# 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.
-#
-# For those usages not covered by the Apache License, Version 2.0 please
-# contact with: nfvlabs@tid.es
-##
-
-'''
-utils is a module that implements functions that are used by all openmano modules,
-dealing with aspects such as reading/writing files, formatting inputs/outputs for quick translation
-from dictionaries to appropriate database dictionaries, etc.
-'''
-__author__="Alfonso Tierno, Gerardo Garcia"
-__date__ ="$08-sep-2014 12:21:22$"
-
-import datetime
-import time
-import warnings
-from functools import reduce, partial, wraps
-from itertools import tee
-
-from itertools import filterfalse
-
-from jsonschema import exceptions as js_e
-from jsonschema import validate as js_v
-
-from inspect import getfullargspec as getspec
-
-#from bs4 import BeautifulSoup
-
-def read_file(file_to_read):
-    """Reads a file specified by 'file_to_read' and returns (True,<its content as a string>) in case of success or (False, <error message>) in case of failure"""
-    try:
-        f = open(file_to_read, 'r')
-        read_data = f.read()
-        f.close()
-    except Exception as e:
-        return (False, str(e))
-
-    return (True, read_data)
-
-def write_file(file_to_write, text):
-    """Write a file specified by 'file_to_write' and returns (True,NOne) in case of success or (False, <error message>) in case of failure"""
-    try:
-        f = open(file_to_write, 'w')
-        f.write(text)
-        f.close()
-    except Exception as e:
-        return (False, str(e))
-
-    return (True, None)
-
-def format_in(http_response, schema):
-    try:
-        client_data = http_response.json()
-        js_v(client_data, schema)
-        #print "Input data: ", str(client_data)
-        return True, client_data
-    except js_e.ValidationError as exc:
-        print("validate_in error, jsonschema exception ", exc.message, "at", exc.path)
-        return False, ("validate_in error, jsonschema exception ", exc.message, "at", exc.path)
-
-def remove_extra_items(data, schema):
-    deleted = []
-    if isinstance(data, (tuple, list)):
-        for d in data:
-            a = remove_extra_items(d, schema['items'])
-            if a:
-                deleted.append(a)
-    elif isinstance(data, dict):
-        # TODO deal with patternProperties
-        if 'properties' not in schema:
-            return None
-        to_delete = []
-        for k in data.keys():
-            if k in schema['properties']:
-                a = remove_extra_items(data[k], schema['properties'][k])
-                if a:
-                    deleted.append({k: a})
-            elif not schema.get('additionalProperties'):
-                to_delete.append(k)
-                deleted.append(k)
-        for k in to_delete:
-            del data[k]
-    if len(deleted) == 0:
-        return None
-    elif len(deleted) == 1:
-        return deleted[0]
-
-    return deleted
-
-#def format_html2text(http_content):
-#    soup=BeautifulSoup(http_content)
-#    text = soup.p.get_text() + " " + soup.pre.get_text()
-#    return text
-
-
-def delete_nulls(var):
-    if isinstance(var, dict):
-        to_delete = []
-        for k in var.keys():
-            if var[k] is None:
-                to_delete.append([k])
-            elif isinstance(var[k], (dict, list, tuple)):
-                if delete_nulls(var[k]):
-                    to_delete.append(k)
-        for k in to_delete:
-            del var[k]
-        if len(var) == 0:
-            return True
-    elif isinstance(var, (list, tuple)):
-        for k in var:
-            if isinstance(k, dict):
-                delete_nulls(k)
-        if len(var) == 0:
-            return True
-    return False
-
-
-def convert_bandwidth(data, reverse=False):
-    '''Check the field bandwidth recursivelly and when found, it removes units and convert to number
-    It assumes that bandwidth is well formed
-    Attributes:
-        'data': dictionary bottle.FormsDict variable to be checked. None or empty is consideted valid
-        'reverse': by default convert form str to int (Mbps), if True it convert from number to units
-    Return:
-        None
-    '''
-    if isinstance(data, dict):
-        for k in data.keys():
-            if isinstance(data[k], (dict, tuple, list)):
-                convert_bandwidth(data[k], reverse)
-        if "bandwidth" in data:
-            try:
-                value=str(data["bandwidth"])
-                if not reverse:
-                    pos = value.find("bps")
-                    if pos>0:
-                        if value[pos-1]=="G":
-                            data["bandwidth"] = int(data["bandwidth"][:pos-1]) * 1000
-                        elif value[pos-1]=="k":
-                            data["bandwidth"]= int(data["bandwidth"][:pos-1]) // 1000
-                        else:
-                            data["bandwidth"]= int(data["bandwidth"][:pos])
-                else:
-                    value = int(data["bandwidth"])
-                    if value % 1000 == 0 and value > 1000:
-                        data["bandwidth"] = str(value // 1000) + " Gbps"
-                    else:
-                        data["bandwidth"] = str(value) + " Mbps"
-            except:
-                print("convert_bandwidth exception for type", type(data["bandwidth"]), " data", data["bandwidth"])
-                return
-    if isinstance(data, (tuple, list)):
-        for k in data:
-            if isinstance(k, (dict, tuple, list)):
-                convert_bandwidth(k, reverse)
-
-def convert_float_timestamp2str(var):
-    '''Converts timestamps (created_at, modified_at fields) represented as float
-    to a string with the format '%Y-%m-%dT%H:%i:%s'
-    It enters recursively in the dict var finding this kind of variables
-    '''
-    if type(var) is dict:
-        for k,v in var.items():
-            if type(v) is float and k in ("created_at", "modified_at"):
-                var[k] = time.strftime("%Y-%m-%dT%H:%M:%S", time.localtime(v) )
-            elif type(v) is dict or type(v) is list or type(v) is tuple:
-                convert_float_timestamp2str(v)
-        if len(var) == 0: return True
-    elif type(var) is list or type(var) is tuple:
-        for v in var:
-            convert_float_timestamp2str(v)
-
-def convert_datetime2str(var):
-    '''Converts a datetime variable to a string with the format '%Y-%m-%dT%H:%i:%s'
-    It enters recursively in the dict var finding this kind of variables
-    '''
-    if type(var) is dict:
-        for k,v in var.items():
-            if type(v) is datetime.datetime:
-                var[k]= v.strftime('%Y-%m-%dT%H:%M:%S')
-            elif type(v) is dict or type(v) is list or type(v) is tuple:
-                convert_datetime2str(v)
-        if len(var) == 0: return True
-    elif type(var) is list or type(var) is tuple:
-        for v in var:
-            convert_datetime2str(v)
-
-def convert_str2boolean(data, items):
-    '''Check recursively the content of data, and if there is an key contained in items, convert value from string to boolean
-    Done recursively
-    Attributes:
-        'data': dictionary variable to be checked. None or empty is considered valid
-        'items': tuple of keys to convert
-    Return:
-        None
-    '''
-    if type(data) is dict:
-        for k in data.keys():
-            if type(data[k]) is dict or type(data[k]) is tuple or type(data[k]) is list:
-                convert_str2boolean(data[k], items)
-            if k in items:
-                if type(data[k]) is str:
-                    if   data[k]=="false" or data[k]=="False": data[k]=False
-                    elif data[k]=="true"  or data[k]=="True":  data[k]=True
-    if type(data) is tuple or type(data) is list:
-        for k in data:
-            if type(k) is dict or type(k) is tuple or type(k) is list:
-                convert_str2boolean(k, items)
-
-def check_valid_uuid(uuid):
-    id_schema = {"type" : "string", "pattern": "^[a-fA-F0-9]{8}(-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}$"}
-    id_schema2 = {"type" : "string", "pattern": "^[a-fA-F0-9]{32}$"}
-    try:
-        js_v(uuid, id_schema)
-        return True
-    except js_e.ValidationError:
-        try:
-            js_v(uuid, id_schema2)
-            return True
-        except js_e.ValidationError:
-            return False
-    return False
-
-
-def expand_brackets(text):
-    """
-    Change a text with TEXT[ABC..] into a list with [TEXTA, TEXTB, TEXC, ...
-    if no bracket is used it just return the a list with the single text
-    It uses recursivity to allow several [] in the text
-    :param text:
-    :return:
-    """
-    if text is None:
-        return (None, )
-    start = text.find("[")
-    end = text.find("]")
-    if start < 0 or end < 0:
-        return [text]
-    text_list = []
-    for char in text[start+1:end]:
-        text_list += expand_brackets(text[:start] + char + text[end+1:])
-    return text_list
-
-def deprecated(message):
-  def deprecated_decorator(func):
-      def deprecated_func(*args, **kwargs):
-          warnings.warn("{} is a deprecated function. {}".format(func.__name__, message),
-                        category=DeprecationWarning,
-                        stacklevel=2)
-          warnings.simplefilter('default', DeprecationWarning)
-          return func(*args, **kwargs)
-      return deprecated_func
-  return deprecated_decorator
-
-
-def truncate(text, max_length=1024):
-    """Limit huge texts in number of characters"""
-    text = str(text)
-    if text and len(text) >= max_length:
-        return text[:max_length//2-3] + " ... " + text[-max_length//2+3:]
-    return text
-
-
-def merge_dicts(*dicts, **kwargs):
-    """Creates a new dict merging N others and keyword arguments.
-    Right-most dicts take precedence.
-    Keyword args take precedence.
-    """
-    return reduce(
-        lambda acc, x: acc.update(x) or acc,
-        list(dicts) + [kwargs], {})
-
-
-def remove_none_items(adict):
-    """Return a similar dict without keys associated to None values"""
-    return {k: v for k, v in adict.items() if v is not None}
-
-
-def filter_dict_keys(adict, allow):
-    """Return a similar dict, but just containing the explicitly allowed keys
-
-    Arguments:
-        adict (dict): Simple python dict data struct
-        allow (list): Explicits allowed keys
-    """
-    return {k: v for k, v in adict.items() if k in allow}
-
-
-def filter_out_dict_keys(adict, deny):
-    """Return a similar dict, but not containing the explicitly denied keys
-
-    Arguments:
-        adict (dict): Simple python dict data struct
-        deny (list): Explicits denied keys
-    """
-    return {k: v for k, v in adict.items() if k not in deny}
-
-
-def expand_joined_fields(record):
-    """Given a db query result, explode the fields that contains `.` (join
-    operations).
-
-    Example
-        >> expand_joined_fiels({'wim.id': 2})
-        # {'wim': {'id': 2}}
-    """
-    result = {}
-    for field, value in record.items():
-        keys = field.split('.')
-        target = result
-        target = reduce(lambda target, key: target.setdefault(key, {}),
-                        keys[:-1], result)
-        target[keys[-1]] = value
-
-    return result
-
-
-def ensure(condition, exception):
-    """Raise an exception if condition is not met"""
-    if not condition:
-        raise exception
-
-
-def partition(predicate, iterable):
-    """Create two derived iterators from a single one
-    The first iterator created will loop thought the values where the function
-    predicate is True, the second one will iterate over the values where it is
-    false.
-    """
-    iterable1, iterable2 = tee(iterable)
-    return filter(predicate, iterable2), filterfalse(predicate, iterable1)
-
-
-def pipe(*functions):
-    """Compose functions of one argument in the opposite order,
-    So pipe(f, g)(x) = g(f(x))
-    """
-    return lambda x: reduce(lambda acc, f: f(acc), functions, x)
-
-
-def compose(*functions):
-    """Compose functions of one argument,
-    So compose(f, g)(x) = f(g(x))
-    """
-    return lambda x: reduce(lambda acc, f: f(acc), functions[::-1], x)
-
-
-def safe_get(target, key_path, default=None):
-    """Given a path of keys (eg.: "key1.key2.key3"), return a nested value in
-    a nested dict if present, or the default value
-    """
-    keys = key_path.split('.')
-    target = reduce(lambda acc, key: acc.get(key) or {}, keys[:-1], target)
-    return target.get(keys[-1], default)
-
-
-class Attempt(object):
-    """Auxiliary class to be used in an attempt to retry executing a failing
-    procedure
-
-    Attributes:
-        count (int): 0-based "retries" counter
-        max_attempts (int): maximum number of "retries" allowed
-        info (dict): extra information about the specific attempt
-            (can be used to produce more meaningful error messages)
-    """
-    __slots__ = ('count', 'max', 'info')
-
-    MAX = 3
-
-    def __init__(self, count=0, max_attempts=MAX, info=None):
-        self.count = count
-        self.max = max_attempts
-        self.info = info or {}
-
-    @property
-    def countdown(self):
-        """Like count, but in the opposite direction"""
-        return self.max - self.count
-
-    @property
-    def number(self):
-        """1-based counter"""
-        return self.count + 1
-
-
-def inject_args(fn=None, **args):
-    """Partially apply keyword arguments in a function, but only if the function
-    define them in the first place
-    """
-    if fn is None:  # Allows calling the decorator directly or with parameters
-        return partial(inject_args, **args)
-
-    spec = getspec(fn)
-    return wraps(fn)(partial(fn, **filter_dict_keys(args, spec.args)))
-
-
-def get_arg(name, fn, args, kwargs):
-    """Find the value of an argument for a function, given its argument list.
-
-    This function can be used to display more meaningful errors for debugging
-    """
-    if name in kwargs:
-        return kwargs[name]
-
-    spec = getspec(fn)
-    if name in spec.args:
-        i = spec.args.index(name)
-        return args[i] if i < len(args) else None
-
-    return None