mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-04 19:25:51 +00:00
Stream generated JSON.
This commit is contained in:
committed by
Nik Bougalis
parent
c65fb91878
commit
95c1c5f54e
@@ -7,6 +7,7 @@ import os
|
||||
from ripple.ledger import LedgerNumber
|
||||
from ripple.util import File
|
||||
from ripple.util import Log
|
||||
from ripple.util import PrettyPrint
|
||||
from ripple.util import Range
|
||||
from ripple.util.Function import Function
|
||||
|
||||
@@ -159,6 +160,8 @@ if ARGS.window < 0:
|
||||
raise ValueError('Window cannot be negative: --window=%d' %
|
||||
ARGS.window)
|
||||
|
||||
PrettyPrint.INDENT = (ARGS.indent * ' ')
|
||||
|
||||
_loaders = bool(ARGS.server) + bool(ARGS.rippled)
|
||||
|
||||
if not _loaders:
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
|
||||
from ripple.ledger.Args import ARGS
|
||||
|
||||
from functools import wraps
|
||||
import json
|
||||
|
||||
def pretty_print(item):
|
||||
return json.dumps(item,
|
||||
sort_keys=True,
|
||||
indent=ARGS.indent,
|
||||
separators=(',', ': '))
|
||||
|
||||
def pretty(f):
|
||||
""""A decorator on a function that makes its results pretty """
|
||||
@wraps(f)
|
||||
def wrapper(*args, **kwds):
|
||||
result = list(f(*args, **kwds))
|
||||
return pretty_print(result)
|
||||
|
||||
return wrapper
|
||||
@@ -1,9 +1,9 @@
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
|
||||
from ripple.ledger.Args import ARGS
|
||||
from ripple.ledger.PrettyPrint import pretty_print
|
||||
from ripple.util import Log
|
||||
from ripple.util import Range
|
||||
from ripple.util.PrettyPrint import pretty_print
|
||||
|
||||
SAFE = True
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
|
||||
from ripple.ledger.Args import ARGS
|
||||
from ripple.ledger.PrettyPrint import pretty_print
|
||||
from ripple.util import Log
|
||||
from ripple.util import Range
|
||||
from ripple.util.PrettyPrint import pretty_print
|
||||
|
||||
SAFE = True
|
||||
|
||||
|
||||
@@ -12,5 +12,4 @@ HELP = """print
|
||||
Print the ledgers to stdout. The default command."""
|
||||
|
||||
def run_print(server):
|
||||
for x in ARGS.display(server, SearchLedgers.search(server)):
|
||||
print(x)
|
||||
ARGS.display(print, server, SearchLedgers.search(server))
|
||||
|
||||
@@ -5,11 +5,11 @@ from functools import wraps
|
||||
import jsonpath_rw
|
||||
|
||||
from ripple.ledger.Args import ARGS
|
||||
from ripple.ledger.PrettyPrint import pretty_print
|
||||
from ripple.util import Dict
|
||||
from ripple.util import Log
|
||||
from ripple.util import Range
|
||||
from ripple.util.Decimal import Decimal
|
||||
from ripple.util.PrettyPrint import pretty_print, Streamer
|
||||
|
||||
TRANSACT_FIELDS = (
|
||||
'accepted',
|
||||
@@ -33,33 +33,30 @@ LEDGER_FIELDS = (
|
||||
def _dict_filter(d, keys):
|
||||
return dict((k, v) for (k, v) in d.items() if k in keys)
|
||||
|
||||
def ledger_number(server, numbers):
|
||||
yield Range.to_string(numbers)
|
||||
def ledger_number(print, server, numbers):
|
||||
print(Range.to_string(numbers))
|
||||
|
||||
def display(f):
|
||||
"""A decorator for displays that just print JSON"""
|
||||
@wraps(f)
|
||||
def wrapper(server, numbers, *args, **kwds):
|
||||
def wrapper(printer, server, numbers, *args):
|
||||
streamer = Streamer(printer=printer)
|
||||
for number in numbers:
|
||||
ledger = server.get_ledger(number, ARGS.full)
|
||||
if ledger:
|
||||
yield pretty_print(f(ledger, *args, **kwds))
|
||||
streamer.add(number, f(ledger, *args))
|
||||
streamer.finish()
|
||||
return wrapper
|
||||
|
||||
def json(f):
|
||||
"""A decorator for displays that print JSON, extracted by a path"""
|
||||
def extractor(f):
|
||||
@wraps(f)
|
||||
def wrapper(server, numbers, path, *args, **kwds):
|
||||
def wrapper(printer, server, numbers, *paths):
|
||||
try:
|
||||
path_expr = jsonpath_rw.parse(path)
|
||||
find = jsonpath_rw.parse('|'.join(paths)).find
|
||||
except:
|
||||
raise ValueError("Can't understand jsonpath '%s'." % path)
|
||||
|
||||
for number in numbers:
|
||||
ledger = server.get_ledger(number, ARGS.full)
|
||||
if ledger:
|
||||
finds = path_expr.find(ledger)
|
||||
yield pretty_print(f(finds, *args, **kwds))
|
||||
def fn(ledger, *args):
|
||||
return f(find(ledger), *args)
|
||||
display(fn)(printer, server, numbers)
|
||||
return wrapper
|
||||
|
||||
@display
|
||||
@@ -67,6 +64,7 @@ def ledger(ledger, full=False):
|
||||
if ARGS.full:
|
||||
if full:
|
||||
return ledger
|
||||
|
||||
ledger = Dict.prune(ledger, 1, False)
|
||||
|
||||
return _dict_filter(ledger, LEDGER_FIELDS)
|
||||
@@ -79,11 +77,11 @@ def prune(ledger, level=1):
|
||||
def transact(ledger):
|
||||
return _dict_filter(ledger, TRANSACT_FIELDS)
|
||||
|
||||
@json
|
||||
@extractor
|
||||
def extract(finds):
|
||||
return dict((str(f.full_path), str(f.value)) for f in finds)
|
||||
|
||||
@json
|
||||
@extractor
|
||||
def sum(finds):
|
||||
d = Decimal()
|
||||
for f in finds:
|
||||
|
||||
@@ -52,10 +52,10 @@ class Function(object):
|
||||
default_path += '.'
|
||||
self.function = default_path + self.function
|
||||
p, m = self.function.rsplit('.', 1)
|
||||
try:
|
||||
mod = importlib.import_module(p)
|
||||
except:
|
||||
raise ValueError('Can\'t find Python module "%s"' % p)
|
||||
mod = importlib.import_module(p)
|
||||
# Errors in modules are swallowed here.
|
||||
# except:
|
||||
# raise ValueError('Can\'t find Python module "%s"' % p)
|
||||
|
||||
try:
|
||||
self.function = getattr(mod, m)
|
||||
|
||||
42
bin/ripple/util/PrettyPrint.py
Normal file
42
bin/ripple/util/PrettyPrint.py
Normal file
@@ -0,0 +1,42 @@
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
|
||||
from functools import wraps
|
||||
import json
|
||||
|
||||
SEPARATORS = ',', ': '
|
||||
INDENT = ' '
|
||||
|
||||
def pretty_print(item):
|
||||
return json.dumps(item,
|
||||
sort_keys=True,
|
||||
indent=len(INDENT),
|
||||
separators=SEPARATORS)
|
||||
|
||||
class Streamer(object):
|
||||
def __init__(self, printer=print):
|
||||
# No automatic spacing or carriage returns.
|
||||
self.printer = lambda *args: printer(*args, end='', sep='')
|
||||
self.first_key = True
|
||||
|
||||
def add(self, key, value):
|
||||
if self.first_key:
|
||||
self.first_key = False
|
||||
self.printer('{')
|
||||
else:
|
||||
self.printer(',')
|
||||
|
||||
self.printer('\n', INDENT, '"', str(key), '": ')
|
||||
|
||||
pp = pretty_print(value).splitlines()
|
||||
if len(pp) > 1:
|
||||
for i, line in enumerate(pp):
|
||||
if i > 0:
|
||||
self.printer('\n', INDENT)
|
||||
self.printer(line)
|
||||
else:
|
||||
self.printer(pp[0])
|
||||
|
||||
def finish(self):
|
||||
if not self.first_key:
|
||||
self.first_key = True
|
||||
self.printer('\n}')
|
||||
56
bin/ripple/util/test_PrettyPrint.py
Normal file
56
bin/ripple/util/test_PrettyPrint.py
Normal file
@@ -0,0 +1,56 @@
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
|
||||
from ripple.util import PrettyPrint
|
||||
|
||||
from unittest import TestCase
|
||||
|
||||
class test_PrettyPrint(TestCase):
|
||||
def setUp(self):
|
||||
self._results = []
|
||||
self.printer = PrettyPrint.Streamer(printer=self.printer)
|
||||
|
||||
def printer(self, *args, **kwds):
|
||||
self._results.extend(args)
|
||||
|
||||
def run_test(self, expected, *args):
|
||||
for i in range(0, len(args), 2):
|
||||
self.printer.add(args[i], args[i + 1])
|
||||
self.printer.finish()
|
||||
self.assertEquals(''.join(self._results), expected)
|
||||
|
||||
def test_simple_printer(self):
|
||||
self.run_test(
|
||||
'{\n "foo": "bar"\n}',
|
||||
'foo', 'bar')
|
||||
|
||||
def test_multiple_lines(self):
|
||||
self.run_test(
|
||||
'{\n "foo": "bar",\n "baz": 5\n}',
|
||||
'foo', 'bar', 'baz', 5)
|
||||
|
||||
def test_multiple_lines(self):
|
||||
self.run_test(
|
||||
"""
|
||||
{
|
||||
"foo": {
|
||||
"bar": 1,
|
||||
"baz": true
|
||||
},
|
||||
"bang": "bing"
|
||||
}
|
||||
""".strip(), 'foo', {'bar': 1, 'baz': True}, 'bang', 'bing')
|
||||
|
||||
def test_multiple_lines_with_list(self):
|
||||
self.run_test(
|
||||
"""
|
||||
{
|
||||
"foo": [
|
||||
"bar",
|
||||
1
|
||||
],
|
||||
"baz": [
|
||||
23,
|
||||
42
|
||||
]
|
||||
}
|
||||
""".strip(), 'foo', ['bar', 1], 'baz', [23, 42])
|
||||
Reference in New Issue
Block a user