summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main.rs181
-rw-r--r--src/parser.rs58
2 files changed, 189 insertions, 50 deletions
diff --git a/src/main.rs b/src/main.rs
index 3d741ae..057588b 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -29,59 +29,154 @@ SOFTWARE.
*/
-use clap::{Cli, Command, Subcommand};
-use termimage;
+use std::fs::{self, File};
+use std::path::PathBuf;
+
+use clap::{Parser, Subcommand};
+use termimage::Options;
mod parser;
-use parser::{get_config, Config};
+mod shared;
+
+use parser::{get_config, parse_weather, generate_config, Config};
+use shared::WeatherData;
+
+#[derive(Parser)]
+#[command(name = "wfetch")]
+#[command(about = "Weather fetch tool")]
+struct Cli {
+ #[command(subcommand)]
+ command: Option<Commands>,
+}
-// use crate::configmanager::{Config, handle_config};
#[derive(Subcommand)]
enum Commands {
- Config,
- Fetch,
- Clean,
- Help,
- Today,
- Tomorrow,
- RebuildCache
+ Config,
+ Fetch,
+ Clean,
+ Today,
+ Tomorrow,
+ RebuildCache,
+ CheckCfg
}
-fn process_config() -> Result<Config, Box<dyn std::error::Error>> {
- let cfg: Config = get_config().unwrap();
- Ok(cfg);
+fn process_config() -> Result<(), Box<dyn std::error::Error>> {
+ let _cfg: Config = get_config()?;
+ println!("Config is valid");
+ Ok(())
}
-fn main() -> Result<(), Box<dyn std::error::Error>> {
-
- let config = process_config()?;
- let cli: Cli = Cli::parse();
+fn parse_cached() -> Result<WeatherData, Box<dyn std::error::Error>> {
+ let home = std::env::var("HOME")?;
+ let cache_path = format!("{}/.cache/WeatherFetch/weather.json", home);
+
+ if !PathBuf::from(&cache_path).exists() {
+ return Err("Cache file not found".into());
+ }
+
+ let cache_data = fs::read_to_string(&cache_path)?;
+ let weather_data: WeatherData = serde_json::from_str(&cache_data)?;
+ Ok(weather_data)
+}
- match cli.command {
- Commands::Config => {
- println!("Testing config."); // Заглушкии
- // let test_result: bool = handle_config(config);
- }
- Commands::Fetch => {
- println!("Fetching weather data.");
-
- }
- Commands::Clean => {
- println!("Clean");
- }
- Commands::Help => {
- println!("Help");
- }
- Commands::Today => {
- println!("Today");
- }
- Commands::Tomorrow => {
- println!("Tomorrow");
- }
- Commands::RebuildCache => {
- }
- }
+fn print_help() -> Result<(), Box<dyn std::error::Error>> {
+ println!("Help command");
+ println!("Usage: wfetch <command>");
+ println!("Commands:");
+ println!(" config - Check config");
+ println!(" fetch - Fetch weather-data");
+ println!(" clean - Clean cache");
+ println!(" help - Print help");
+ println!(" today - Print today weather");
+ println!(" tomorrow - Print tomorrow weather");
+ println!(" rebuild-cache - Rebuild cache");
+ Ok(())
+}
- }
+fn clean_cache() -> Result<(), Box<dyn std::error::Error>> {
+ let home = std::env::var("HOME")?;
+ let cache_path = format!("{}/.cache/WeatherFetch/weather.json", home);
+ if PathBuf::from(&cache_path).exists() {
+ fs::remove_file(&cache_path)?;
+ println!("Cache cleaned successfully");
+ } else {
+ println!("Cache file not found");
+ }
+ Ok(())
+}
+fn rebuild_cache() -> Result<(), Box<dyn std::error::Error>> {
+ let rt = tokio::runtime::Runtime::new()?;
+ let weather_data = rt.block_on(parse_weather())?;
+
+ let home = std::env::var("HOME")?;
+ let cache_dir = format!("{}/.cache/WeatherFetch", home);
+ fs::create_dir_all(&cache_dir)?;
+
+ let cache_path = format!("{}/weather.json", cache_dir);
+ let json_data = serde_json::to_string_pretty(&weather_data)?;
+ fs::write(&cache_path, json_data)?;
+
+ println!("Cache rebuilt successfully");
+ Ok(())
+}
+fn main() -> Result<(), Box<dyn std::error::Error>> {
+ let cli = Cli::parse();
+
+ match cli.command {
+ Some(Commands::Config) => {
+ println!("Config checker command");
+ let home = std::env::var("HOME")?;
+ let config_path = format!("{}/.config/WeatherFetch/Config.toml", home);
+ if File::open(&config_path).is_err() {
+ generate_config()?;
+ println!("Config generated successfully");
+ } else {
+ process_config()?;
+ println!("Config already exists and is valid.");
+ }
+ Ok(())
+ },
+ Some(Commands::Fetch) => {
+ println!("Fetch weather-data command");
+ let rt = tokio::runtime::Runtime::new()?;
+ let weather_data = rt.block_on(parse_weather())?;
+ let home = std::env::var("HOME")?;
+ println!("Weather data fetched to: {}", format!("{}/.cache/WeatherFetch", home));
+ Ok(())
+ },
+ Some(Commands::Clean) => {
+ println!("Clean cache command");
+ clean_cache()?;
+ Ok(())
+ },
+ Some(Commands::Today) => {
+ println!("Today weather command");
+ Ok(())
+ },
+ Some(Commands::Tomorrow) => {
+ println!("Tomorrow weather command");
+ Ok(())
+ },
+ Some(Commands::RebuildCache) => {
+ println!("Rebuild cache command");
+ rebuild_cache()?;
+ Ok(())
+ },
+ Some(Commands::CheckCfg) => {
+ println!("Validating cfg...");
+ let home = std::env::var("HOME")?;
+ let config_path = format!("{}/.config/WeatherFetch/Config.toml", home);
+ if File::open(&config_path).is_ok() {
+ process_config()?;
+ } else {
+ println!("Config file not found, try `wfetch config`, its will generate default cfg.");
+ }
+ Ok(())
+ }
+ None => {
+ print_help()
+ },
+ }
+} \ No newline at end of file
diff --git a/src/parser.rs b/src/parser.rs
index 14fe992..f4fd2da 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -1,14 +1,19 @@
use reqwest::Client;
-use std::fs::File;
+use std::fs::{self, File};
use std::io::Read;
use toml;
+use serde::Deserialize;
+use serde_json;
// use crate::configmanager::Config;
use crate::shared::*;
pub type BoxedError = Box<dyn std::error::Error + Send + Sync>;
-const DEFAULT_PATH: &str = "/home/$USER/.config/WeatherFetch/Config.toml";
+fn get_config_path() -> Result<String, Box<dyn std::error::Error>> {
+ let home = std::env::var("HOME")?;
+ Ok(format!("{}/.config/WeatherFetch/Config.toml", home))
+}
/*
const CONF: Lazy<Result<Config, Box<dyn std::error::Error + Send + Sync>>> = Lazy::new(|| {
@@ -17,7 +22,7 @@ const CONF: Lazy<Result<Config, Box<dyn std::error::Error + Send + Sync>>> = Laz
*/
pub fn get_location(coords_args: bool) -> Result<(), BoxedError> {
- let config = get_config()?;
+ let config = get_config().unwrap();
if (config.lat == 0.0 || config.lon == 0.0) && !coords_args {
@@ -39,17 +44,29 @@ pub async fn parse_weather() -> Result<WeatherData, Box<dyn std::error::Error>>
.query(&[
("latitude", config.lat.to_string()),
("longitude", config.lon.to_string()),
- ("current", "temperature_2m,wind_speed_10m"),
- ("hourly", "temperature_2m,relative_humidity_2m,wind_speed_10m"),
+ ("current", "temperature_2m,wind_speed_10m".to_string()),
+ ("hourly", "temperature_2m,relative_humidity_2m,wind_speed_10m".to_string()),
])
.send()
.await?;
- let weather_data: WeatherData = response.json().await?;
+ let response_text = response.text().await?;
+
+ let weather_data: WeatherData = serde_json::from_str(&response_text)?;
+
+ let home = std::env::var("HOME")?;
+ let cache_dir = format!("{}/.cache/WeatherFetch", home);
+ fs::create_dir_all(&cache_dir)?;
+
+ let cache_path = format!("{}/weather.json", cache_dir);
+ let json_data = serde_json::to_string_pretty(&weather_data)?;
+ fs::write(&cache_path, json_data)?;
+
Ok(weather_data)
}
+#[derive(Debug, Deserialize)]
pub struct Config {
lat: f64,
lon: f64,
@@ -60,11 +77,38 @@ pub struct Config {
}
pub fn get_config() -> Result<Config, Box<dyn std::error::Error>> {
- let mut file = File::open(DEFAULT_PATH)?;
+ let config_path = get_config_path()?;
+
+ if File::open(&config_path).is_err() {
+ generate_config()?;
+ }
+
+ let mut file = File::open(&config_path)?;
let mut content = String::new();
file.read_to_string(&mut content)?;
let config: Config = toml::from_str(&content)?;
Ok(config)
+}
+
+pub fn generate_cachedir() -> Result<(), Box<dyn std::error::Error>> {
+ let home = std::env::var("HOME")?;
+ let cache_path = format!("{}/.cache/WeatherFetch/", home);
+
+ let _ = fs::create_dir(cache_path);
+
+ Ok(())
+}
+
+pub fn generate_config() -> Result<(), Box<dyn std::error::Error>> {
+ let config_path = get_config_path()?;
+ let config = "lat = 55.75\nlon = 37.62\nexclude = \"\"\nappid = \"\"\nunits = \"metric\"\nlang = \"ru\"";
+ let path = std::path::Path::new(&config_path);
+ if let Some(parent) = path.parent() {
+ fs::create_dir_all(parent)?;
+ }
+ fs::write(path, config)?;
+ println!("Config file generated at: {}", config_path);
+ Ok(())
} \ No newline at end of file