예제 #1
0
def json_flatten(a, prefix=''):
    """Flatten a JSON structure into a dict with str paths as keys.

    For example,
    `json_flatten(json.loads('{"a": {"b": "v"}}'))` will return
    `{'.a.b': u'v'}`;
    `json_flatten(json.loads('{"a": [1, 2, 3]}'))` returns
    `{'.a[0]': 1, '.a[2]': 3, '.a[1]': 2}`, etc.
    """

    def add_flat(dict_, key, elem):
        """If `elem` is itself a dict, merge it with `dict_`.
        Otherwise, store it in `dict_` under `key`.
        """

        if isinstance(elem, dict):
            dict_.update(elem)
        else:
            dict_[key] = elem

    res = {}
    if isinstance(a, list):
        for n, elem in enumerate(a):
            add_flat(res, prefix, json_flatten(elem, \
                                               prefix + "[{0}]".format(n)))
    elif isinstance(a, dict):
        for key in a.keys():
            new_prefix = prefix
            # Use a different syntax for keys with spaces.
            if ' ' in key:
                new_prefix += "['{0}']".format(key)
            else:
                new_prefix += ".{0}".format(key)
            add_flat(res, prefix, json_flatten(a[key], new_prefix))
    # If a is not processable by json_flatten (e.g., it's a str) then store
    # it in res. However, at the top level we don't want to store such an a
    # as {'': a}. We also don't store None in res; we return it instead.
    elif a is not None and prefix != '':
        res[prefix] = a
    else:
        res = a

    return res
예제 #2
0
def json_flatten(a, prefix=''):
    """Flatten a JSON structure into a dict with str paths as keys.

    For example,
    `json_flatten(json.loads('{"a": {"b": "v"}}'))` will return
    `{'.a.b': u'v'}`;
    `json_flatten(json.loads('{"a": [1, 2, 3]}'))` returns
    `{'.a[0]': 1, '.a[2]': 3, '.a[1]': 2}`, etc.
    """
    def add_flat(dict_, key, elem):
        """If `elem` is itself a dict, merge it with `dict_`.
        Otherwise, store it in `dict_` under `key`.
        """

        if isinstance(elem, dict):
            dict_.update(elem)
        else:
            dict_[key] = elem

    res = {}
    if isinstance(a, list):
        for n, elem in enumerate(a):
            add_flat(res, prefix, json_flatten(elem, \
                                               prefix + "[{0}]".format(n)))
    elif isinstance(a, dict):
        for key in a.keys():
            new_prefix = prefix
            # Use a different syntax for keys with spaces.
            if ' ' in key:
                new_prefix += "['{0}']".format(key)
            else:
                new_prefix += ".{0}".format(key)
            add_flat(res, prefix, json_flatten(a[key], new_prefix))
    # If a is not processable by json_flatten (e.g., it's a str) then store
    # it in res. However, at the top level we don't want to store such an a
    # as {'': a}. We also don't store None in res; we return it instead.
    elif a is not None and prefix != '':
        res[prefix] = a
    else:
        res = a

    return res
예제 #3
0
def poll_loop(interval, req, date=True, initial_values=True):
    """Perform requests for JSON data. Print out changes when they occur."""

    prev_output = None
    output = None
    try:
        output = req.perform()
        if initial_values:
            json_print(output)
        output = json_flatten(output)
    except (subprocess.CalledProcessError,
            urllib.error.HTTPError,
            ValueError) as e:
        print(traceback.format_exc(), file=sys.stderr)
    while True:
        try:
            time.sleep(interval)
            try:
                prev_output, output = output, json_flatten(req.perform())
                diff = json_flat_diff(prev_output, output)
                if diff is not None:
                    msg = json_diff_str(diff)
                    msg.sort()
                    # If msg is multi-line print each difference on a new line
                    # with indentation.
                    prefix = ''
                    if date:
                        prefix += datetime.datetime.now().isoformat()
                    if len(msg) > 1:
                        print(prefix, \
                              "\n   ", "\n    ".join(msg))
                    else:
                        print(prefix, msg[0])
            except (subprocess.CalledProcessError,
                    urllib.HTTPError,
                    ValueError) as e:
                print(traceback.format_exc(), file=sys.stderr)
        except KeyboardInterrupt:
            sys.exit(0)
예제 #4
0
def poll_loop(interval, req, date=True, initial_values=True):
    """Perform requests for JSON data. Print out changes when they occur."""

    prev_output = None
    output = None
    try:
        output = req.perform()
        if initial_values:
            json_print(output)
        output = json_flatten(output)
    except (subprocess.CalledProcessError, urllib.error.HTTPError,
            ValueError) as e:
        print(traceback.format_exc(), file=sys.stderr)
    while True:
        try:
            time.sleep(interval)
            try:
                prev_output, output = output, json_flatten(req.perform())
                diff = json_flat_diff(prev_output, output)
                if diff is not None:
                    msg = json_diff_str(diff)
                    msg.sort()
                    # If msg is multi-line print each difference on a new line
                    # with indentation.
                    prefix = ''
                    if date:
                        prefix += datetime.datetime.now().isoformat()
                    if len(msg) > 1:
                        print(prefix, \
                              "\n   ", "\n    ".join(msg))
                    else:
                        print(prefix, msg[0])
            except (subprocess.CalledProcessError, urllib.HTTPError,
                    ValueError) as e:
                print(traceback.format_exc(), file=sys.stderr)
        except KeyboardInterrupt:
            sys.exit(0)