|
5 | 5 | import os |
6 | 6 | import sys |
7 | 7 | BASEPATH = os.path.dirname(os.path.realpath(__file__)) |
8 | | -sys.path = [BASEPATH, '%s/..' %BASEPATH] + sys.path |
| 8 | +sys.path = [BASEPATH, '%s/..' % BASEPATH] + sys.path |
9 | 9 | from yajl import __version__ as yajl_version |
10 | | -from yajl import * |
| 10 | +from yajl import ( |
| 11 | + __version__ as yajl_version, |
| 12 | + YajlContentHandler, YajlGen, YajlParser, |
| 13 | + YajlGenException, |
| 14 | +) |
11 | 15 |
|
12 | 16 | import optparse |
13 | 17 |
|
| 18 | + |
14 | 19 | class ReformatContentHandler(YajlContentHandler): |
15 | 20 | ''' |
16 | 21 | Content handler to reformat a json file using yajl_gen |
17 | 22 | ''' |
18 | | - def __init__(self, beautify=True, indent_string=" "): |
| 23 | + def __init__(self, beautify=True, indent_string=" ", stream=False): |
19 | 24 | self.out = sys.stdout |
20 | 25 | self.beautify = beautify |
21 | 26 | self.indent_string = indent_string |
| 27 | + self.stream = stream |
22 | 28 | def parse_start(self): |
23 | | - self.g = YajlGen(beautify=self.beautify, indent_string=self.indent_string) |
| 29 | + self.g = YajlGen( |
| 30 | + beautify=self.beautify, |
| 31 | + indent_string=self.indent_string, |
| 32 | + ) |
24 | 33 | def parse_buf(self): |
25 | 34 | self.out.write(self.g.yajl_gen_get_buf()) |
26 | 35 | def parse_complete(self): |
27 | | - # not necessary, gc will do this @ python shutdown |
28 | | - del self.g |
| 36 | + if not stream: |
| 37 | + # not necessary, gc will do this @ python shutdown |
| 38 | + del self.g |
| 39 | + def check_and_return(self, func, *args, **kwargs): |
| 40 | + try: |
| 41 | + func(*args, **kwargs) |
| 42 | + except YajlGenException as e: |
| 43 | + if self.stream and e.value == 'yajl_gen_generation_complete': |
| 44 | + self.g.yajl_gen_reset('\n') |
| 45 | + func(*args, **kwargs) |
| 46 | + else: |
| 47 | + raise |
29 | 48 | def yajl_null(self, ctx): |
30 | | - self.g.yajl_gen_null() |
| 49 | + self.check_and_return( |
| 50 | + self.g.yajl_gen_null, |
| 51 | + ) |
31 | 52 | def yajl_boolean(self, ctx, boolVal): |
32 | | - self.g.yajl_gen_bool(boolVal) |
| 53 | + self.check_and_return( |
| 54 | + self.g.yajl_gen_bool, |
| 55 | + boolVal |
| 56 | + ) |
33 | 57 | def yajl_number(self, ctx, stringNum): |
34 | | - self.g.yajl_gen_number(stringNum) |
| 58 | + self.check_and_return( |
| 59 | + self.g.yajl_gen_number, |
| 60 | + stringNum |
| 61 | + ) |
35 | 62 | def yajl_string(self, ctx, stringVal): |
36 | | - self.g.yajl_gen_string(stringVal) |
| 63 | + self.check_and_return( |
| 64 | + self.g.yajl_gen_string, |
| 65 | + stringVal |
| 66 | + ) |
37 | 67 | def yajl_start_map(self, ctx): |
38 | | - self.g.yajl_gen_map_open() |
| 68 | + self.check_and_return( |
| 69 | + self.g.yajl_gen_map_open, |
| 70 | + ) |
39 | 71 | def yajl_map_key(self, ctx, stringVal): |
40 | | - self.g.yajl_gen_string(stringVal) |
| 72 | + self.check_and_return( |
| 73 | + self.g.yajl_gen_string, |
| 74 | + stringVal |
| 75 | + ) |
41 | 76 | def yajl_end_map(self, ctx): |
42 | | - self.g.yajl_gen_map_close() |
| 77 | + self.check_and_return( |
| 78 | + self.g.yajl_gen_map_close, |
| 79 | + ) |
43 | 80 | def yajl_start_array(self, ctx): |
44 | | - self.g.yajl_gen_array_open() |
| 81 | + self.check_and_return( |
| 82 | + self.g.yajl_gen_array_open, |
| 83 | + ) |
45 | 84 | def yajl_end_array(self, ctx): |
46 | | - self.g.yajl_gen_array_close() |
| 85 | + self.check_and_return( |
| 86 | + self.g.yajl_gen_array_close, |
| 87 | + ) |
47 | 88 |
|
48 | 89 |
|
49 | 90 | def main(): |
50 | 91 | opt_parser = optparse.OptionParser( |
51 | 92 | description='reformat json from stdin', |
52 | | - version='Yajl-Py for Yajl %s' %yajl_version) |
| 93 | + version='Yajl-Py for Yajl %s' % yajl_version) |
53 | 94 | opt_parser.add_option("-m", |
54 | 95 | dest="beautify", action="store_false", default=True, |
55 | 96 | help="minimize json rather than beautify (default)") |
56 | 97 | opt_parser.add_option("-u", |
57 | 98 | dest="dont_validate_strings", action='store_true', default=False, |
58 | 99 | help="allow invalid UTF8 inside strings during parsing") |
| 100 | + opt_parser.add_option("-e", |
| 101 | + dest="escape_solidus", action='store_true', default=False, |
| 102 | + help="escape any forward slashes (for embedding in HTML)") |
| 103 | + opt_parser.add_option("-s", |
| 104 | + dest="stream", action='store_true', default=False, |
| 105 | + help="reformat a stream of multiple json entites") |
59 | 106 | (options, args) = opt_parser.parse_args() |
60 | | - ch = ReformatContentHandler(beautify=options.beautify) |
| 107 | + # initialize the content handler (creates a Yajl Gen) |
| 108 | + ch = ReformatContentHandler( |
| 109 | + beautify=options.beautify, |
| 110 | + stream=options.stream, |
| 111 | + ) |
| 112 | + # initialize the parser |
61 | 113 | yajl_parser = YajlParser(ch) |
62 | | - yajl_parser.allow_comments = True # let's allow comments by default |
| 114 | + yajl_parser.allow_comments = True # let's allow comments by default |
63 | 115 | yajl_parser.dont_validate_strings = options.dont_validate_strings |
| 116 | + yajl_parser.allow_multiple_values = options.stream |
64 | 117 | yajl_parser.parse() |
65 | 118 |
|
66 | 119 | if __name__ == "__main__": |
|
0 commit comments