My agentic slop goes here. Not intended for anyone else!
1type location_record = {
2 timestamp: string;
3 lat: float;
4 lon: float;
5 alt: float option;
6 acc: float option;
7 batt: int option;
8 tid: string option;
9 tst: int;
10}
11
12let parse_timestamp line =
13 match String.split_on_char '\t' line with
14 | timestamp :: _ -> Some timestamp
15 | [] -> None
16
17let parse_json_payload line =
18 match String.split_on_char '\t' line with
19 | _ :: _ :: json :: _ ->
20 (try Some (Ezjsonm.from_string json) with _ -> None)
21 | _ -> None
22
23let get_string json key =
24 try Some (Ezjsonm.get_string (Ezjsonm.find json [key]))
25 with _ -> None
26
27let get_float json key =
28 try Some (Ezjsonm.get_float (Ezjsonm.find json [key]))
29 with _ -> None
30
31let get_int json key =
32 try Some (Ezjsonm.get_int (Ezjsonm.find json [key]))
33 with _ -> None
34
35let extract_location_from_json json =
36 try
37 let dict = Ezjsonm.get_dict json in
38 match List.assoc_opt "_type" dict with
39 | Some (`String "location") ->
40 let lat = Ezjsonm.get_float (List.assoc "lat" dict) in
41 let lon = Ezjsonm.get_float (List.assoc "lon" dict) in
42 let tst = Ezjsonm.get_int (List.assoc "tst" dict) in
43 Some {
44 timestamp = "";
45 lat;
46 lon;
47 alt = get_float json "alt";
48 acc = get_float json "acc";
49 batt = get_int json "batt";
50 tid = get_string json "tid";
51 tst;
52 }
53 | _ -> None
54 with _ -> None
55
56let parse_line line =
57 match parse_timestamp line, parse_json_payload line with
58 | Some timestamp, Some json ->
59 (match extract_location_from_json json with
60 | Some record -> Some { record with timestamp }
61 | None -> None)
62 | _ -> None
63
64let parse_file path =
65 let ic = open_in path in
66 let rec read_lines acc =
67 try
68 let line = input_line ic in
69 let acc' = match parse_line line with
70 | Some record -> record :: acc
71 | None -> acc
72 in
73 read_lines acc'
74 with End_of_file ->
75 close_in ic;
76 List.rev acc
77 in
78 read_lines []