~vpec/maus/tof_calib_read

« back to all changes in this revision

Viewing changes to bin/utilities/json_browser.py

reverse merge from trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
 
 
3
#pylint: disable = C0111
 
4
 
 
5
import json
 
6
import argparse
 
7
import sys
 
8
import subprocess
 
9
import os
 
10
 
 
11
TEMP_FILE = 'json_to_human_readable_out.tmp'
 
12
 
 
13
DESCRIPTION = \
 
14
"""
 
15
Convert json output to human readable format. 
 
16
 
 
17
By default, output is written to """+TEMP_FILE+""" and piped to 'less'; then
 
18
deleted at the end of the session. Optionally can save the output to a
 
19
user-specified file for browsing in your favourite text editor.
 
20
"""
 
21
 
 
22
# Dynamically set the docstring
 
23
__doc__ = DESCRIPTION #pylint: disable = W0622
 
24
 
 
25
def arg_parser():
 
26
    """
 
27
    Parse command line arguments.
 
28
 
 
29
    Use -h switch at the command line for information on command line args used.
 
30
    """
 
31
    parser = argparse.ArgumentParser(description=DESCRIPTION)
 
32
    parser.add_argument('--input-file', dest='input_file', \
 
33
                        help='Read in json file with this name', required=True)
 
34
    parser.add_argument('--output-file', dest='output_file', \
 
35
                        help='Write reformatted output to file with this'+\
 
36
                             ' name, overwriting any existing files', \
 
37
                        default=TEMP_FILE)
 
38
    parser.add_argument('--indent', dest='indent', \
 
39
                        help='Specify the number of spaces to indent each '+\
 
40
                             'level of the data tree', \
 
41
                        default=2, type=int)
 
42
    parser.add_argument('-L', '--less', help='Run less on output file after '+\
 
43
                        'parsing', dest='less', action='store_true',
 
44
                        default=True)
 
45
    parser.add_argument('-l', '--no-less', help="Don't run less on output '+\
 
46
                        'file after parsing", dest='less', action='store_false',
 
47
                        default=True)
 
48
    parser.add_argument('--start-line', help="First line to parse, counting "+\
 
49
                        "from 1. Issues an error if --start-line is > number "+\
 
50
                        "of lines", type=int, default=1)
 
51
    parser.add_argument('--end-line', help="Last line to parse, counting "+\
 
52
                        'from 1. Ignored if < 1', type=int, default=0)
 
53
    return parser
 
54
 
 
55
def write_json(sys_args):
 
56
    """
 
57
    Reformat the input json file then write to output file
 
58
 
 
59
    Skips the required number of lines to start_line, and loops until end_line.
 
60
    If the line is not empty or EOF, but can't be parsed into json format,
 
61
    raise an IOError. Closes the output file after writing
 
62
    """
 
63
    line = '1'
 
64
    line_number = 1
 
65
    fin = open(sys_args.input_file)
 
66
    fout = open(sys_args.output_file, 'w')
 
67
    while line_number < sys_args.start_line:
 
68
        line = fin.readline()
 
69
        line_number += 1
 
70
        if line == "":
 
71
            raise IOError("File finished before reaching start_line at "+\
 
72
                          "line "+str(line_number))
 
73
    line = fin.readline()
 
74
    while (line_number <= sys_args.end_line or sys_args.end_line < 1) \
 
75
          and line != '':
 
76
        try:
 
77
            json_in = json.loads(line)
 
78
            json_out = json.dumps(json_in, indent=sys_args.indent)
 
79
        except ValueError:
 
80
            if line != "\n" and line != "":
 
81
                raise IOError("Input file could not be parsed into json "+\
 
82
                              "format at line "+str(line_number))  
 
83
        print >> fout, json_out
 
84
        line_number += 1
 
85
        line = fin.readline()
 
86
    fout.close() # force to clear any buffer
 
87
 
 
88
def main(argv):
 
89
    """
 
90
    Main loop. Parse any input arguments, then reformat and write the input
 
91
    file to some output file. Run less if required. if no output filename was
 
92
    specified assume the output isn't for keeping so delete it.
 
93
    """
 
94
    args = arg_parser()
 
95
    args_in = args.parse_args(argv)
 
96
    write_json(args_in)
 
97
    if args_in.less:
 
98
        less_proc = subprocess.Popen(['less', args_in.output_file],
 
99
                                     stdout=sys.stdout)
 
100
        less_proc.wait()
 
101
    if args_in.output_file == TEMP_FILE:
 
102
        os.remove(args_in.output_file)
 
103
 
 
104
if __name__ == "__main__":
 
105
    main(sys.argv[1:])
 
106