1use crate::SyncError;
8use sioul_core::weather::{self, Forecast, Place};
9use std::time::Duration;
10
11fn get(url: &str) -> Result<String, SyncError> {
12 let agent: ureq::Agent = ureq::Agent::config_builder().timeout_global(Some(Duration::from_secs(20))).http_status_as_error(false).build().into();
13 let mut response = agent
14 .get(url)
15 .header("User-Agent", concat!("Sioul/", env!("CARGO_PKG_VERSION"), " (desktop mail and contacts client)"))
16 .call()
17 .map_err(|e| SyncError::Network(e.to_string()))?;
18 let status = response.status().as_u16();
19 let text = response.body_mut().read_to_string().unwrap_or_default();
20 if status != 200 {
21 return Err(SyncError::Server(format!("Open-Meteo: {status}")));
22 }
23 Ok(text)
24}
25
26pub fn forecast(latitude: f64, longitude: f64, now: i64) -> Result<Forecast, SyncError> {
28 weather::parse(&get(&weather::query(latitude, longitude))?, now).map_err(SyncError::Server)
29}
30
31pub fn places(name: &str, language: &str) -> Result<Vec<Place>, SyncError> {
33 weather::parse_places(&get(&weather::place_query(name, language))?).map_err(SyncError::Server)
34}