X-Git-Url: http://git.maemo.org/git/?a=blobdiff_plain;f=src%2Futil%2Fmisc.py;h=cf5c22a63c862cf1102f09af56774938f5dd4dbe;hb=e31b65ea26b238366776d0f9d7d857a5a4775fae;hp=7abecf3ca4724cb3967cdb7544401d027fdcdcd6;hpb=ab4da214c520d763bbbddeb828c8e7c838374fe3;p=theonering diff --git a/src/util/misc.py b/src/util/misc.py index 7abecf3..cf5c22a 100644 --- a/src/util/misc.py +++ b/src/util/misc.py @@ -3,10 +3,10 @@ from __future__ import with_statement import sys +import re import cPickle import functools -import itertools import contextlib import inspect @@ -16,6 +16,45 @@ import warnings import string +_indentationLevel = [0] + + +def log_call(logger): + + def log_call_decorator(func): + + @functools.wraps(func) + def wrapper(*args, **kwds): + logger.debug("%s> %s" % (" " * _indentationLevel[0], func.__name__, )) + _indentationLevel[0] += 1 + try: + return func(*args, **kwds) + finally: + _indentationLevel[0] -= 1 + logger.debug("%s< %s" % (" " * _indentationLevel[0], func.__name__, )) + + return wrapper + + return log_call_decorator + + +def log_exception(logger): + + def log_exception_decorator(func): + + @functools.wraps(func) + def wrapper(*args, **kwds): + try: + return func(*args, **kwds) + except Exception: + logger.exception(func.__name__) + raise + + return wrapper + + return log_exception_decorator + + def printfmt(template): """ This hides having to create the Template object and call substitute/safe_substitute on it. For example: @@ -231,6 +270,7 @@ def deprecated_api(func): def newFunc(*args, **kwargs): warnings.warn("Call to deprecated function %s." % func.__name__, category=DeprecationWarning) return func(*args, **kwargs) + _append_docstring(newFunc, "\n@deprecated") return newFunc @@ -411,6 +451,22 @@ def ExpHandler(handler = print_handler, *exceptions): return wrapper +def into_debugger(func): + """ + >>> validate_decorator(into_debugger) + """ + + @functools.wraps(func) + def newFunc(*args, **kwargs): + try: + return func(*args, **kwargs) + except: + import pdb + pdb.post_mortem() + + return newFunc + + class bindclass(object): """ >>> validate_decorator(bindclass) @@ -624,3 +680,78 @@ def lexical_scope(*args): for key in (x for x in f_locals.keys() if x not in saved): del f_locals[key] del frame + + +def normalize_number(prettynumber): + """ + function to take a phone number and strip out all non-numeric + characters + + >>> normalize_number("+012-(345)-678-90") + '+01234567890' + >>> normalize_number("1-(345)-678-9000") + '+13456789000' + >>> normalize_number("+1-(345)-678-9000") + '+13456789000' + """ + uglynumber = re.sub('[^0-9+]', '', prettynumber) + if uglynumber.startswith("+"): + pass + elif uglynumber.startswith("1") and len(uglynumber) == 11: + uglynumber = "+"+uglynumber + elif len(uglynumber) == 10: + uglynumber = "+1"+uglynumber + else: + pass + + #validateRe = re.compile("^\+?[0-9]{10,}$") + #assert validateRe.match(uglynumber) is not None + + return uglynumber + + +_VALIDATE_RE = re.compile("^\+?[0-9]{10,}$") + + +def is_valid_number(number): + """ + @returns If This number be called ( syntax validation only ) + """ + return _VALIDATE_RE.match(number) is not None + + +def parse_version(versionText): + """ + >>> parse_version("0.5.2") + [0, 5, 2] + """ + return [ + int(number) + for number in versionText.split(".") + ] + + +def compare_versions(leftParsedVersion, rightParsedVersion): + """ + >>> compare_versions([0, 1, 2], [0, 1, 2]) + 0 + >>> compare_versions([0, 1, 2], [0, 1, 3]) + -1 + >>> compare_versions([0, 1, 2], [0, 2, 2]) + -1 + >>> compare_versions([0, 1, 2], [1, 1, 2]) + -1 + >>> compare_versions([0, 1, 3], [0, 1, 2]) + 1 + >>> compare_versions([0, 2, 2], [0, 1, 2]) + 1 + >>> compare_versions([1, 1, 2], [0, 1, 2]) + 1 + """ + for left, right in zip(leftParsedVersion, rightParsedVersion): + if left < right: + return -1 + elif right < left: + return 1 + else: + return 0