This commit is contained in:
2025-05-23 09:20:08 -04:00
parent ed98140d22
commit 6ad2afe6dd
16 changed files with 5180 additions and 177 deletions

View File

@@ -4,6 +4,8 @@ use crate::http_client::HttpClient;
use crate::metars::MetarCheck;
use crate::{db, error::ApiResult};
use chrono::{DateTime, Datelike, NaiveDate, Utc};
use flate2::read::GzDecoder;
use reqwest::header::ETAG;
use serde::{Deserialize, Serialize};
use std::collections::HashSet;
use std::env;
@@ -11,8 +13,6 @@ use std::fmt::Display;
use std::io::{Cursor, Read};
use std::str::FromStr;
use std::sync::OnceLock;
use flate2::read::GzDecoder;
use reqwest::header::ETAG;
use utoipa::ToSchema;
static TIME_OFFSET: OnceLock<i64> = OnceLock::new();
@@ -921,12 +921,17 @@ impl Metar {
),
)
})?;
let candidate_date = match candidate_date.and_hms_opt(observation_hour, observation_minute, 0) {
let candidate_date = match candidate_date.and_hms_opt(observation_hour, observation_minute, 0) {
Some(date) => date,
None => return Err(Error::new(
500,
format!("Invalid time for time '{}': hour {}, minute {}",
observation_time, observation_hour, observation_minute)))
None => {
return Err(Error::new(
500,
format!(
"Invalid time for time '{}': hour {}, minute {}",
observation_time, observation_hour, observation_minute
),
));
}
};
let obs_datetime = if candidate_date > current_time {
@@ -956,9 +961,11 @@ impl Metar {
Ok(obs_datetime.format("%Y-%m-%dT%H:%M:00Z").to_string())
}
pub async fn get_cached_remote_metars(client: &HttpClient, etag: Option<String>) -> ApiResult<(Vec<Self>, String)> {
let base_url = env::var("AVIATION_WEATHER_URL")
.expect("AVIATION_WEATHER_URL must be set");
pub async fn get_cached_remote_metars(
client: &HttpClient,
etag: Option<String>,
) -> ApiResult<(Vec<Self>, String)> {
let base_url = env::var("AVIATION_WEATHER_URL").expect("AVIATION_WEATHER_URL must be set");
let url = format!("{}/data/cache/metars.cache.csv.gz", base_url);
match client.get(&url, etag.clone()).await {
@@ -991,8 +998,8 @@ impl Metar {
Some(etag) => Ok((output, etag)),
None => match etag {
Some(etag) => Ok((output, etag)),
None => Ok((output, String::new()))
}
None => Ok((output, String::new())),
},
}
}
Err(err) => Err(err.into()),
@@ -1000,8 +1007,7 @@ impl Metar {
}
pub async fn get_remote_metars(client: &HttpClient, icaos: &Vec<String>) -> ApiResult<Vec<Self>> {
let base_url = env::var("AVIATION_WEATHER_URL")
.expect("AVIATION_WEATHER_URL must be set");
let base_url = env::var("AVIATION_WEATHER_URL").expect("AVIATION_WEATHER_URL must be set");
// Query the remote API for the missing METAR data 10 at a time
let icao_chunks = icaos
.chunks(10)
@@ -1014,22 +1020,20 @@ impl Metar {
base_url, icao_chunk
);
let mut m = match client.get(&url, None).await {
Ok(r) => {
match r.text().await {
Ok(r) => {
let metar_chunk = r
.trim()
.split("\n")
.filter(|m| !m.trim().is_empty())
.collect();
match Self::parse_multiple(&metar_chunk) {
Ok(m) => m,
Err(err) => return Err(err),
}
Ok(r) => match r.text().await {
Ok(r) => {
let metar_chunk = r
.trim()
.split("\n")
.filter(|m| !m.trim().is_empty())
.collect();
match Self::parse_multiple(&metar_chunk) {
Ok(m) => m,
Err(err) => return Err(err),
}
Err(err) => return Err(Error::new(500, format!("METAR parse failed: {}", err))),
}
}
Err(err) => return Err(Error::new(500, format!("METAR parse failed: {}", err))),
},
Err(err) => return Err(err.into()),
};
metars.append(&mut m);