@@ -2,7 +2,7 @@ use axum::Json;
22use axum:: extract:: State ;
33use axum:: http:: StatusCode ;
44use chrono:: Utc ;
5- use log:: error;
5+ use log:: { error, warn } ;
66use serde:: { Deserialize , Deserializer , Serialize } ;
77use std:: sync:: Arc ;
88use tokio:: io:: { AsyncBufReadExt , AsyncWriteExt , BufReader } ;
@@ -47,14 +47,22 @@ pub struct GpsRecord {
4747 pub lon : f64 ,
4848}
4949
50- /// Reads all GPS records from a sidecar NDJSON file, skipping malformed lines.
50+ /// Reads all GPS records from a sidecar NDJSON file, logging and skipping malformed lines.
5151pub async fn load_gps_records ( file : tokio:: fs:: File ) -> Vec < GpsRecord > {
5252 let reader = BufReader :: new ( file) ;
5353 let mut lines = reader. lines ( ) ;
5454 let mut records = Vec :: new ( ) ;
55- while let Ok ( Some ( line) ) = lines. next_line ( ) . await {
56- if let Ok ( record) = serde_json:: from_str :: < GpsRecord > ( & line) {
57- records. push ( record) ;
55+ loop {
56+ match lines. next_line ( ) . await {
57+ Ok ( Some ( line) ) => match serde_json:: from_str :: < GpsRecord > ( & line) {
58+ Ok ( record) => records. push ( record) ,
59+ Err ( e) => warn ! ( "skipping malformed GPS sidecar line: {e}" ) ,
60+ } ,
61+ Ok ( None ) => break ,
62+ Err ( e) => {
63+ error ! ( "error reading GPS sidecar file: {e}" ) ;
64+ break ;
65+ }
5866 }
5967 }
6068 records
@@ -67,29 +75,47 @@ pub async fn post_gps(
6775 if state. config . gps_mode != GpsMode :: Api {
6876 return Err ( (
6977 StatusCode :: FORBIDDEN ,
70- "GPS API endpoint is disabled. Set gps_mode to 2 in configuration." . to_string ( ) ,
78+ "GPS API endpoint is disabled. Set gps_mode to API endpoint in configuration."
79+ . to_string ( ) ,
7180 ) ) ;
7281 }
7382 let mut gps = state. gps_state . write ( ) . await ;
7483 * gps = Some ( gps_data. clone ( ) ) ;
7584 drop ( gps) ;
7685
7786 let qmdl_store = state. qmdl_store_lock . read ( ) . await ;
78- if let Some ( ( entry_idx, _) ) = qmdl_store. get_current_entry ( )
79- && let Ok ( mut file) = qmdl_store. open_entry_gps_for_append ( entry_idx) . await
80- {
81- let record = GpsRecord {
82- unix_ts : Utc :: now ( ) . timestamp ( ) ,
83- lat : gps_data. latitude ,
84- lon : gps_data. longitude ,
85- } ;
86- match serde_json:: to_string ( & record) {
87- Ok ( json) => {
88- if let Err ( e) = file. write_all ( format ! ( "{json}\n " ) . as_bytes ( ) ) . await {
89- error ! ( "failed to write GPS record to sidecar: {e}" ) ;
90- }
87+ if let Some ( ( entry_idx, _) ) = qmdl_store. get_current_entry ( ) {
88+ match qmdl_store. open_entry_gps_for_append ( entry_idx) . await {
89+ Ok ( Some ( mut file) ) => {
90+ let record = GpsRecord {
91+ unix_ts : Utc :: now ( ) . timestamp ( ) ,
92+ lat : gps_data. latitude ,
93+ lon : gps_data. longitude ,
94+ } ;
95+ let json = serde_json:: to_string ( & record) . map_err ( |e| {
96+ error ! ( "failed to serialize GPS record: {e}" ) ;
97+ (
98+ StatusCode :: INTERNAL_SERVER_ERROR ,
99+ format ! ( "failed to serialize GPS record: {e}" ) ,
100+ )
101+ } ) ?;
102+ file. write_all ( format ! ( "{json}\n " ) . as_bytes ( ) )
103+ . await
104+ . map_err ( |e| {
105+ error ! ( "failed to write GPS record to sidecar: {e}" ) ;
106+ (
107+ StatusCode :: INTERNAL_SERVER_ERROR ,
108+ format ! ( "failed to write GPS record to sidecar: {e}" ) ,
109+ )
110+ } ) ?;
111+ }
112+ Ok ( None ) => error ! ( "GPS sidecar directory not found, cannot write GPS record" ) ,
113+ Err ( e) => {
114+ return Err ( (
115+ StatusCode :: INTERNAL_SERVER_ERROR ,
116+ format ! ( "failed to open GPS sidecar: {e}" ) ,
117+ ) ) ;
91118 }
92- Err ( e) => error ! ( "failed to serialize GPS record: {e}" ) ,
93119 }
94120 }
95121
0 commit comments