This patch adds some utility routines needed for new 'api' module in spacecmd.
Its all doctests look OK as far as I tested. Here is a test log: $ PYTHONPATH=spacecmd/src/lib nosetests --with-doctest -vv \ > spacecmd/src/lib/utils.py Doctest: utils.parse_api_args ... ok Doctest: utils.parse_list_str ... ok Doctest: utils.parse_str ... ok ---------------------------------------------------------------------- Ran 3 tests in 0.020s OK $ Signed-Off-By: Satoru SATOH <ss...@redhat.com> --- spacecmd/src/lib/utils.py | 101 +++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 101 insertions(+), 0 deletions(-) diff --git a/spacecmd/src/lib/utils.py b/spacecmd/src/lib/utils.py index 3768647..a8fd5ee 100644 --- a/spacecmd/src/lib/utils.py +++ b/spacecmd/src/lib/utils.py @@ -26,6 +26,12 @@ from optparse import OptionParser from tempfile import mkstemp from textwrap import wrap +try: + import json +except ImportError: + import simplejson as json # python < 2.6 + + __EDITORS = ['vim', 'vi', 'nano', 'emacs'] def parse_arguments(args, options = []): @@ -462,4 +468,99 @@ def read_file(filename): return contents + +def parse_str(s, type_to=None): + """ + Similar to 'read :: Read a => String -> a' in Haskell. + + >>> parse_str('1234567', int) + 1234567 + >>> parse_str('1234567') + 1234567 + >>> parse_str('abcXYZ012') + 'abcXYZ012' + >>> d = dict(channelLabel="foo-i386-5") + >>> d = parse_str('{"channelLabel": "foo-i386-5"}') + >>> assert d["channelLabel"] == 'foo-i386-5' + + """ + try: + if type_to is not None and isinstance(type_to, type): + return type_to(s) + + elif re.match(r'[1-9]\d*', s): + return int(s) + + elif re.match(r'{.*}', s): + return json.loads(s) # retry with json module + + else: + return str(s) + + except ValueError: + return str(s) + + +def parse_list_str(list_s, sep=","): + """ + simple parser for a list of items separated with "," (comma) or given + separator chars. + + >>> assert parse_list_str("") == [] + >>> assert parse_list_str("a,b") == ["a", "b"] + >>> assert parse_list_str("a,b,") == ["a", "b"] + >>> assert parse_list_str("a:b:", ":") == ["a", "b"] + """ + return [p for p in list_s.split(sep) if p] + + +def parse_api_args(args, sep=','): + """ + Simple JSON-like expression parser. + + :param args: a list of strings may be separated with sep, and each + string represents parameters passed to API later. + :type args: `str` + + :param sep: A char to separate paramters in `args` + :type sep: `str` + + :rtype: rpc arg objects, [arg] :: [string] + + >>> parse_api_args('') + [] + >>> parse_api_args('1234567') + [1234567] + >>> parse_api_args('abcXYZ012') + ['abcXYZ012'] + + >>> assert parse_api_args('{"channelLabel": "foo-i386-5"}')[0]["channelLabel"] == "foo-i386-5" + + >>> (i, s, d) = parse_api_args('1234567,abcXYZ012,{"channelLabel": "foo-i386-5"}') + >>> assert i == 1234567 + >>> assert s == "abcXYZ012" + >>> assert d["channelLabel"] == "foo-i386-5" + + >>> (i, s, d) = parse_api_args('[1234567,"abcXYZ012",{"channelLabel": "foo-i386-5"}]') + >>> assert i == 1234567 + >>> assert s == "abcXYZ012" + >>> assert d["channelLabel"] == "foo-i386-5" + """ + if not args: + return [] + + try: + x = json.loads(args) + ret = isinstance(x, list) and x or [x] + + except ValueError: + ret = [parse_str(a) for a in parse_list_str(args, sep)] + + return ret + + +def json_dump(obj, fp, indent=2, **kwargs): + json.dump(obj, fp, ensure_ascii=False, indent=indent, **kwargs) + + # vim:ts=4:expandtab: -- 1.7.6 _______________________________________________ Spacewalk-devel mailing list Spacewalk-devel@redhat.com https://www.redhat.com/mailman/listinfo/spacewalk-devel