forked from dtcooper/python-fitparse
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfitdump
More file actions
executable file
·121 lines (100 loc) · 3.57 KB
/
fitdump
File metadata and controls
executable file
·121 lines (100 loc) · 3.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#!/usr/bin/env python
from __future__ import print_function
import argparse
import codecs
import datetime
import json
import sys
import types
# Python 2 compat
try:
BrokenPipeError
except NameError:
import socket
BrokenPipeError = socket.error
import fitparse
def format_message(num, message, options):
s = ["{}. {}".format(num, message.name)]
if options.with_defs:
s.append(' [{}]'.format(message.type))
s.append('\n')
if message.type == 'data':
for field_data in message:
s.append(' * {}: {}'.format(field_data.name, field_data.value))
if field_data.units:
s.append(' [{}]'.format(field_data.units))
s.append('\n')
s.append('\n')
return "".join(s)
def parse_args(args=None):
parser = argparse.ArgumentParser(
description='Dump .FIT files to various formats',
epilog='python-fitparse version %s' % fitparse.__version__,
)
parser.add_argument('-v', '--verbose', action='count', default=0)
parser.add_argument(
'-o', '--output', type=argparse.FileType(mode='w'), default="-",
help='File to output data into (defaults to stdout)',
)
parser.add_argument(
# TODO: csv
'-t', '--type', choices=('readable', 'json'), default='readable',
help='File type to output. (DEFAULT: %(default)s)',
)
parser.add_argument(
'-n', '--name', action='append', help='Message name (or number) to filter',
)
parser.add_argument(
'infile', metavar='FITFILE', type=argparse.FileType(mode='rb'),
help='Input .FIT file (Use - for stdin)',
)
parser.add_argument(
'--ignore-crc', action='store_const', const=True, help='Some devices seem to write invalid crc\'s, ignore these.'
)
options = parser.parse_args(args)
# Work around argparse.FileType not accepting an `encoding` kwarg in
# Python < 3.4 by closing and reopening the file (unless it's stdout)
if options.output is not sys.stdout:
options.output.close()
options.output = codecs.open(options.output.name, 'w', encoding='UTF-8')
options.verbose = options.verbose >= 1
options.with_defs = (options.type == "readable" and options.verbose)
options.as_dict = (options.type != "readable" and options.verbose)
return options
class RecordJSONEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, types.GeneratorType):
return list(obj)
if isinstance(obj, datetime.datetime):
return obj.isoformat()
if isinstance(obj, fitparse.DataMessage):
return {
"type": obj.name,
"data": {
data.name: data.value for data in obj
}
}
# Fall back to original to raise a TypeError
return super(RecordJSONEncoder, self).default(obj)
def main(args=None):
options = parse_args(args)
fitfile = fitparse.FitFile(
options.infile,
data_processor=fitparse.StandardUnitsDataProcessor(),
check_crc = not(options.ignore_crc),
)
records = fitfile.get_messages(
name=options.name,
with_definitions=options.with_defs,
as_dict=options.as_dict
)
if options.type == "json":
json.dump(records, fp=options.output, cls=RecordJSONEncoder)
elif options.type == "readable":
options.output.writelines(format_message(n, record, options)
for n, record in enumerate(records, 1))
if __name__ == '__main__':
try:
main()
except BrokenPipeError:
pass