Files
2025-04-30 08:48:49 -05:00

297 lines
11 KiB
Python

# uncompyle6 version 3.9.2
# Python bytecode version base 3.7.0 (3394)
# Decompiled from: Python 3.8.19 (default, Mar 20 2024, 15:27:52)
# [Clang 14.0.6 ]
# Embedded file name: /var/user/app/device_supervisorbak/device_supervisor/lib/jsonpath.py
# Compiled at: 2024-04-18 03:12:55
# Size of source mod 2**32: 11901 bytes
"""
An XPath for JSON
A port of the Perl, and JavaScript versions of JSONPath
see http://goessner.net/articles/JsonPath/
Based on on JavaScript version by Stefan Goessner at:
https://goessner.net/articles/JsonPath/
http://code.google.com/p/jsonpath/
and Perl version by Kate Rhodes at:
http://github.com/masukomi/jsonpath-perl/tree/master
Python3 compatibily by Per J. Sandstrom
"""
from __future__ import print_function
__author__ = "Phil Budne"
__revision__ = "$Revision: 1.17 $"
__version__ = "0.82"
import re, sys
__all__ = [
"jsonpath"]
if sys.version_info[0] == 3:
xrange = range
def normalize(x):
"""normalize the path expression; outside jsonpath to allow testing"""
subx = []
def f1(m):
n = len(subx)
g1 = m.group(1)
subx.append(g1)
ret = "[#%d]" % n
return ret
x = re.sub("[\\['](\\??\\(.*?\\))[\\]']", f1, x)
x = re.sub("'?(?<!@)\\.'?|\\['?", ";", x)
x = re.sub(";;;|;;", ";..;", x)
x = re.sub(";$|'?\\]|'$", "", x)
def f2(m):
g1 = m.group(1)
return subx[int(g1)]
x = re.sub("#([0-9]+)", f2, x)
return x
def jsonpath(obj, expr, result_type='VALUE', debug=0, use_eval=True):
"""traverse JSON object using jsonpath expr, returning values or paths"""
def s(x, y):
"""concatenate path elements"""
return str(x) + ";" + str(y)
def isint(x):
"""check if argument represents a decimal integer"""
return x.isdigit()
def as_path(path):
"""convert internal path representation to
"full bracket notation" for PATH output"""
p = "$"
for piece in path.split(";")[1[:None]]:
if isint(piece):
p += "[%s]" % piece
else:
p += "['%s']" % piece
return p
def store(path, object):
if result_type == "VALUE":
result.append(object)
else:
if result_type == "IPATH":
result.append(path.split(";")[1[:None]])
else:
result.append(as_path(path))
return path
def trace(expr, obj, path):
if debug:
print("trace", expr, "/", path)
elif expr:
x = expr.split(";")
loc = x[0]
x = ";".join(x[1[:None]])
if debug:
print("\t", loc, type(obj))
if loc == "*":
def f03(key, loc, expr, obj, path):
if debug > 1:
print("\tf03", key, loc, expr, path)
trace(s(key, expr), obj, path)
walk(loc, x, obj, path, f03)
else:
if loc == "..":
trace(x, obj, path)
def f04(key, loc, expr, obj, path):
if debug > 1:
print("\tf04", key, loc, expr, path)
elif isinstance(obj, dict):
if key in obj:
trace(s("..", expr), obj[key], s(path, key))
elif key < len(obj):
trace(s("..", expr), obj[key], s(path, key))
walk(loc, x, obj, path, f04)
else:
if loc == "!":
def f06(key, loc, expr, obj, path):
if isinstance(obj, dict):
trace(expr, key, path)
walk(loc, x, obj, path, f06)
else:
if isinstance(obj, dict) and loc in obj:
trace(x, obj[loc], s(path, loc))
else:
if isinstance(obj, list) and isint(loc):
iloc = int(loc)
if debug:
print("----->", iloc, len(obj))
if len(obj) > iloc:
trace(x, obj[iloc], s(path, loc))
else:
if loc.startswith("("):
if loc.endswith(")"):
if debug > 1:
print("index", loc)
e = evalx(loc, obj)
trace(s(e, x), obj, path)
return
elif loc.startswith("?("):
if loc.endswith(")"):
if debug > 1:
print("filter", loc)
def f05(key, loc, expr, obj, path):
if debug > 1:
print("f05", key, loc, expr, path)
elif isinstance(obj, dict):
eval_result = evalx(loc, obj[key])
else:
eval_result = evalx(loc, obj[int(key)])
if eval_result:
trace(s(key, expr), obj, path)
loc = loc[2[:-1]]
walk(loc, x, obj, path, f05)
return
m = re.match("(-?[0-9]*):(-?[0-9]*):?(-?[0-9]*)$", loc)
if m:
if isinstance(obj, (dict, list)):
def max(x, y):
if x > y:
return x
return y
def min(x, y):
if x < y:
return x
return y
objlen = len(obj)
s0 = m.group(1)
s1 = m.group(2)
s2 = m.group(3)
start = int(s0) if s0 else 0
end = int(s1) if s1 else objlen
step = int(s2) if s2 else 1
if start < 0:
start = max(0, start + objlen)
else:
start = min(objlen, start)
if end < 0:
end = max(0, end + objlen)
else:
end = min(objlen, end)
for i in xrange(start, end, step):
trace(s(i, x), obj, path)
else:
return
if loc.find(",") >= 0:
for piece in re.split("'?,'?", loc):
if debug > 1:
print("piece", piece)
trace(s(piece, x), obj, path)
else:
store(path, obj)
def walkParse error at or near `COME_FROM' instruction at offset 92_2
def evalx(loc, obj):
"""eval expression"""
if debug:
print("evalx", loc)
else:
loc = loc.replace("@.length", "len(__obj)")
loc = loc.replace("&&", " and ").replace("||", " or ")
def notvar(m):
return "'%s' not in __obj" % m.group(1)
loc = re.sub("!@\\.([a-zA-Z@_0-9-]*)", notvar, loc)
def varmatch(m):
def brackets(elts):
ret = "__obj"
for e in elts:
if isint(e):
ret += "[%s]" % e
else:
ret += "['%s']" % e
return ret
g1 = m.group(1)
elts = g1.split(".")
if elts[-1] == "length":
return "len(%s)" % brackets(elts[1[:-1]])
return brackets(elts[1[:None]])
loc = re.sub("(?<!\\\\)(@\\.[a-zA-Z@_.0-9]+)", varmatch, loc)
loc = re.sub("(?<!\\\\)@", "__obj", loc).replace("\\@", "@")
if not use_eval:
if debug:
print("eval disabled")
raise Exception("eval disabled")
if debug:
print("eval", loc)
try:
v = eval(loc, caller_globals, {"__obj": obj})
except Exception as e:
try:
if debug:
print(repr(e))
return False
finally:
e = None
del e
if debug:
print("->", v)
return v
caller_globals = sys._getframe(1).f_globals
result = []
if expr:
if obj:
cleaned_expr = normalize(expr)
if cleaned_expr.startswith("$;"):
cleaned_expr = cleaned_expr[2[:None]]
trace(cleaned_expr, obj, "$")
if len(result) > 0:
return result
return False
if __name__ == "__main__":
try:
import json
except ImportError:
import simplejson as json
import sys
if len(sys.argv) < 3 or len(sys.argv) > 4:
sys.stdout.write("Usage: jsonpath.py FILE PATH [OUTPUT_TYPE]\n")
sys.exit(1)
object = json.load(file(sys.argv[1]))
path = sys.argv[2]
format = "VALUE"
if len(sys.argv) > 3:
format = sys.argv[3]
value = jsonpath(object, path, format)
if not value:
sys.exit(1)
f = sys.stdout
json.dump(value, f, sort_keys=True, indent=1)
f.write("\n")
sys.exit(0)