diff options
| author | Namilskyy <alive6863@gmail.com> | 2025-03-26 21:23:12 +0300 |
|---|---|---|
| committer | Namilskyy <alive6863@gmail.com> | 2025-03-26 21:23:31 +0300 |
| commit | d075958732b9deb6a6f39dd1171144e075f013dc (patch) | |
| tree | 741962f319d6c633d71b932dc56bebc9ce37b236 | |
| parent | 3d642eae40c80b31c5078d4b1d62a0a533f230d2 (diff) | |
Fixing errors, the zsh: command not found: main branch will pushed only after fixing all mistakes and bugs. Now founded 3.]
| -rw-r--r-- | Cargo.lock | 1 | ||||
| -rw-r--r-- | Cargo.toml | 17 | ||||
| -rw-r--r-- | src/configmanager.rs | 36 | ||||
| -rw-r--r-- | src/main.rs | 26 | ||||
| -rw-r--r-- | src/parser.rs | 66 |
5 files changed, 94 insertions, 52 deletions
@@ -2046,6 +2046,7 @@ dependencies = [ "clap 4.5.32", "dirs", "image 0.24.9", + "once_cell", "reqwest", "serde", "termimage", @@ -4,12 +4,13 @@ version = "0.1.0" edition = "2021" [dependencies] -serde = { version = "1.0", features = ["derive"] } -toml = "0.7" -clap = { version = "4.4", features = ["derive"] } -reqwest = { version = "0.11", features = ["json"] } -tokio = { version = "1.0", features = ["full"] } -chrono = "0.4" -dirs = "4.0" +serde = { version = "1.0", features = ["derive"] } +toml = "0.7" +clap = { version = "4.4", features = ["derive"] } +reqwest = { version = "0.11", features = ["json"] } +tokio = { version = "1.0", features = ["full"] } +chrono = "0.4" +dirs = "4.0" termimage = "0.4" -image = "0.24" +image = "0.24" +once_cell = "1.20" diff --git a/src/configmanager.rs b/src/configmanager.rs index c0047a5..c005d2c 100644 --- a/src/configmanager.rs +++ b/src/configmanager.rs @@ -1,22 +1,25 @@ use std::fs; use serde::Deserialize; use dirs::home_dir; -use std::path::PathBuf; -#[derive(Debug, Deserialize)] +#[derive(Debug, Deserialize, Clone)] pub struct Config { - pub lat: String, - pub lon: String, + pub lat: f64, + pub lon: f64, pub exclude: String, - pub appid: String, - pub lang: String, - pub units: String, - pub cache: bool, - pub rain: String, - pub sunny: String, - pub snowy: String, + pub appid: String, + pub lang: String, + pub units: String, + pub cache: bool, + pub rain: String, + pub sunny: String, + pub snowy: String, } +type BoxedError = Box<dyn std::error::Error + Send + Sync>; + + + pub fn handle_config(_config: &Config) -> Result<(), Box<dyn std::error::Error>> { Ok(()) } @@ -24,15 +27,20 @@ pub fn handle_config(_config: &Config) -> Result<(), Box<dyn std::error::Error>> pub fn gen_standard_conf() { // TODO: Implement } - + impl Config { pub fn load() -> Result<Self, Box<dyn std::error::Error>> { let mut path = home_dir().ok_or("Home directory not found")?; path.push(".config/WeatherFetch/Config.toml"); - let config_str = fs::read_to_string(path)?; - let config: Config = toml::from_str(&config_str)?; + let config_str = fs::read_to_string(&path) + .map_err(|e| format!("Failed to read config: {}", e))?; + + let config: Config = toml::from_str(&config_str) + .map_err(|e| format!("Invalid TOML: {}", e))?; + Ok(config) } } + diff --git a/src/main.rs b/src/main.rs index 9f64ca4..acd3ecb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,13 +4,13 @@ extern crate image; use clap::{Arg, Command}; use termimage::{Options}; - mod configmanager; mod parser; use crate::configmanager::{Config, handle_config}; - fn main() -> Result<(), Box<dyn std::error::Error>> { + + let config = Config::load()?; let matches = Command::new("WeatherFetch") .version("0.1") .author("Borisov Alexey <arcanetmodl@gmail.com>") @@ -24,19 +24,29 @@ fn main() -> Result<(), Box<dyn std::error::Error>> { .get_matches(); if matches.contains_id("help") { - println!("Usage: ..."); + println!("Usage:"); + println!("VALUES"); + println!("--img=, -i= image, takees a path to .jpg/.png"); + println!("--lat=, -t=, coordinates: takes f64."); + println!("--lon=, -n=, coordinates: takes f64"); + println!("--cfg=, -c=, takes a path to Config.toml"); + println!("--exclude=, -e=, takes exlude type. See the API docs"); + println!("FUNCTIONS"); + println!("--gen-conf, -g, generating standart config"); + println!("--alerts, -a, show alerts"); + return Ok(()); } - if let Some(img_path) = matches.get_one::<String>("image") { - let _img = Image::from_path(img_path)?; - } + if let Some(img_path) = matches.get_one::<String>("image") { + let _img = image::open(img_path)?; + } + - let config = Config::load()?; handle_config(&config)?; - let opts = Options::parse(); + let _opts = Options::parse(); // Prefix with underscore if not used /* if !opts { opts = configmanager::Config::load(); diff --git a/src/parser.rs b/src/parser.rs index 5a670b1..e97db13 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,8 +1,11 @@ -use reqwest::{Error, Client, get}; +//use clap::error::ErrorKind; +use reqwest::{Client}; use chrono::{DateTime, Utc, prelude::*}; use serde::{Serialize, Deserialize}; +use once_cell::sync::Lazy; +use std::error::Error; -use crate::configmanager; +use crate::configmanager::Config; //API answer struct`s #[derive(Debug, Serialize, Deserialize)] @@ -12,12 +15,11 @@ pub struct WeatherData { pub timezone: String, pub timezone_offset: i32, pub current: Current, - pub minutely: Vec<Minutely>, - pub hourly: Vec<Hourly>, - pub daily: Vec<Daily>, - pub alerts: Vec<Alert>, + pub minutely: Option<Vec<Minutely>>, + pub hourly: Option<Vec<Hourly>>, + pub daily: Option<Vec<Daily>>, + pub alerts: Option<Vec<Alert>>, } - #[derive(Debug, Serialize, Deserialize)] pub struct Current { pub dt: u64, @@ -121,26 +123,46 @@ pub struct Alert { pub tags: Vec<String>, } +type BoxedError = Box<dyn std::error::Error + Send + Sync>; + +const CONF: Lazy<Result<Config, Box<dyn std::error::Error + Send + Sync>>> = Lazy::new(|| { + Config::load().map_err(|e| Box::new(e) as Box<dyn std::error::Error + Send + Sync>) +}); +pub fn get_location(coords_args: bool) -> Result<(), BoxedError> { + let config = CONF + .as_ref() + .map_err(|e| Box::<dyn std::error::Error + Send + Sync>::from(e.to_string()))? + .clone(); -pub fn get_location(coords_args: bool) -> Result<(), String>{ - //Get the lat and lon for API call - let conf: Option<configmanager::load()>; - if conf.lat.is_empty() || conf.lon.is_empty() && !coords_args{ - println!("No coordinates in configuration file or conf not founded."); - println!("HINT: Try create ~/.config/WeatherFetch/Config.toml"); - println!("HINT: And add `lat(<int>)`, `lon(<int>)`."); - println!("HINT: To get more info check https://openweathermap.org/api/one-call-3"); - - Err("No coordinates in config or args.".into()) + if (config.lat == 0.0 || config.lon == 0.0) && !coords_args { + Err("Invalid coordinates in config".into()) } else { Ok(()) } -} - - -pub async fn parse_weather(_config: &Config) -> Result<(), reqwest::Error> { - Ok(()) } + +pub async fn parse_weather() -> Result<WeatherData, Box<dyn std::error::Error>> { + let config = CONF + .as_ref() + .map_err(|e| Box::<dyn std::error::Error>::from(e.to_string()))? + .clone(); + + let client = Client::new(); + let response = client.get("https://api.openweathermap.org/data/3.0/onecall") + .query(&[ + ("lat", config.lat.to_string()), + ("lon", config.lon.to_string()), + ("exclude", config.exclude), + ("appid", config.appid), + ("units", config.units), + ("lang", config.lang), + ]) + .send() + .await?; + + let weather_data: WeatherData = response.json().await?; + Ok(weather_data) +}
\ No newline at end of file |
