From 7e18b24495888f24f62f02c8658a49f8097bd762 Mon Sep 17 00:00:00 2001 From: JesusPerez Date: Thu, 7 Oct 2021 22:59:31 +0100 Subject: [PATCH] chore: add code --- src/lib.rs | 289 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 289 insertions(+) create mode 100644 src/lib.rs diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..9b52e00 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,289 @@ +/*! Zterton +*/ +// Copyright 2021, Jesús Pérez Lorenzo +// +// Make rustc's built-in lints more strict and set clippy into a whitelist-based configuration so +// we see new lints as they get written, then opt out of ones we have seen and don't want +// #![allow(warnings, unused)] +#![allow(warnings, unused)] +// #![warn(warnings, rust_2018_idioms)] +#![warn(clippy::all, clippy::pedantic)] +#![allow( + clippy::float_arithmetic, + clippy::implicit_return, + clippy::needless_return, + clippy::print_stdout, + clippy::multiple_inherent_impl +)] +#![forbid(unsafe_code)] // Enforce my policy of only allowing it in my own code as a last resort + +#[allow(unused_imports)] + +#[macro_use] +extern crate serde_derive; +use dotenv::dotenv; +use glob::glob; +use std::fs; +use std::net::{IpAddr, Ipv4Addr, SocketAddr, ToSocketAddrs}; +use std::env; +// use warp::Filter; + +// use salvo::prelude::*; +// use tracing_subscriber; +// use tracing_subscriber::fmt::format::FmtSpan; +use app_errors::AppError; + +use app_env::{ + appenv::AppEnv, + module::Module, + config::Config, + AppRunMode, BxDynResult, Zterton +}; +// use crate::auth::defs::AuthStore; + +/// [`AppEnv`](models/struct.AppEnv.html) init with default, __`main_store`__ is set to [slab](../slab/index.html): +/// ``` +/// Some(Storage::default()); +/// ``` +#[allow(clippy::print_stdout)] +async fn load_app_env(app_env: &mut AppEnv,verbose: isize) -> BxDynResult<()> { + let args: Vec = std::env::args().collect(); + let mut arg_cfg_path = String::from(""); + let mut arg_env_path = String::from(""); + args.iter().enumerate().for_each(|(idx,arg)| { + if arg == "-c" { + arg_cfg_path=args[idx+1].to_owned(); + } else if arg == "-e" { + arg_env_path=args[idx+1].to_owned(); + } + }); + let config_content = Config::load_file_content(verbose,&arg_cfg_path); + #[allow(unused_assignments)] + if !config_content.contains("run_mode") { + let e = format!( + "App config load error {}: {}", + &app_env.info.appmode, + AppError::RunningModeError + ); + return Err(e.into()); + } + // println!("content: {}",&config_content); + app_env.config = Config::new(config_content,verbose); + if app_env.get_curr_websrvr_config().srv_host.is_empty() { + let e = format!( + "App config error, check config APP_CONFIG_PATH: {}", + &envmnt::get_or("APP_CONFIG_PATH", "config.toml") + ); + return Err(e.into()); + } + // Load app_msg from file + let app_msg = fs::read_to_string(format!("{}/{}/.app_msg",&envmnt::get_or("APP_HOME", "."),app_env.get_curr_websrvr_config().home_path)) + .unwrap_or_else(|e|{ + eprintln!("{}",e); + String::from("") + }); + if check_running_mode(app_env).is_ok() { + println!( + "\n{} {}\n(c) {}\n\n{}", + &app_env.info.name, &app_env.info.version, &app_env.info.author, &app_env.info.about + ); + println!("Web: {}",&app_env.get_curr_websrvr_config().name); + println!( + "\nRunning mode: {} {}\n{}", + &app_env.info.appmode, &app_env.info.usedata, app_msg + ) + } else { + println!( + "Error checking running mode: {}", + app_env.config.run_mode.to_owned() + ); + let e = format!( + "App load error {}: {}", + &app_env.info.appmode, + AppError::RunningModeError + ); + return Err(e.into()); + // return Err(Box::new(e.into())); + } + // dbg!(&app_env); + // load_colls_def(app_env).await?; + load_module_def(app_env, verbose).await?; + Ok(()) +} + +/// load collections definiton from resources +// #[allow(clippy::print_stdout)] +// async fn load_colls_def(app_env: &mut AppEnv) -> BxDynResult<()> { +// let pattern = format!("{}/collections/*.toml", &app_env.config.resources_path); +// for item in glob(&pattern).expect("Failed to find coll defs") { +// if let Ok(path) = item { +// let content = Collection::load_fs_content(&path); +// let coll_defs: toml::Value = toml::from_str(&content)?; +// if ! &content.is_empty() { +// let coll_def: Collection::new(&content); +// if let Some(name) = coll_defs["name"].as_str() { +// println!("Collection: {} from {:#?}", &name, &path.display()); +// app_env.collections.insert(name.to_string(), coll_defs); +// } +// } +// } +// } +// Ok(()) +// } + +/// load modules definiton from resources +#[allow(clippy::print_stdout)] +async fn load_module_def(app_env: &mut AppEnv, verbose: isize) -> BxDynResult<()> { + let pattern = format!("{}/modules/*.toml",&app_env.get_curr_websrvr_config().resources_path); + for item in glob(&pattern).expect("Failed to find coll defs") { + if let Ok(path) = item { + let content = Module::load_fs_content(&path); + if ! &content.is_empty() { + let module_def = Module::new(content, verbose); + if ! module_def.key.is_empty() { + if verbose > 0 { + println!("Module: {} from {:#?}", &module_def.name, &path.display()); + } + app_env.modules.insert(module_def.key.to_owned(), module_def); + } + } + } + } + Ok(()) +} + +#[allow(clippy::missing_errors_doc)] +pub fn check_running_mode(app_env: &mut AppEnv) -> BxDynResult<()> { + app_env.info = app_env.info.load_data(app_env); + // TODO check mode license ? + app_env.info.appmode = AppRunMode::get_from(&app_env.config.run_mode); + if app_env.info.usedata.is_empty() && app_env.info.appmode != AppRunMode::Basic { + app_env.checked = false; + let e = format!("Running mode load error {}", &app_env.info.appmode); + Err(e.into()) + } else { + if app_env.info.appmode == AppRunMode::Basic { + app_env.info.usedata = String::from(""); + } + app_env.checked = true; + Ok(()) + } +} + +/// # Zterton app is a backend services +// static DB: Lazy = Lazy::new(|| models::blank_db()); + +#[allow(clippy::missing_errors_doc,clippy::dbg_macro)] +pub async fn init_app(app_env: &mut AppEnv,verbose: isize) -> std::io::Result<()> { + dotenv().ok(); + + let matches = clap::App::new(&app_env.info.name.to_owned()) + .version(app_env.info.version.as_str()) + .author(app_env.info.author.as_str()) + .about(app_env.info.about.as_str()) + .arg( + clap::Arg::with_name("debug") + .short("d") + .long("debug") + .takes_value(true) + .help("Debug level"), + ) + .arg( + clap::Arg::with_name("config") + .short("c") + .long("config") + .takes_value(true) + .help("config"), + ) + .arg( + clap::Arg::with_name("env") + .short("e") + .long("env") + .takes_value(true) + .help("environment"), + ) + .get_matches(); + + if let Some(dbg_lvl) = matches.value_of("debug") { + app_env.debug_level = dbg_lvl.to_string(); + println!("Debug level: {}", &app_env.debug_level); + } + + match load_app_env(app_env,verbose).await { + Ok(_) => { + if verbose > 0 { + println!("Config & Environment loaded !"); + } + if app_env.debug_level.as_str() == "trace" { + dbg!(&app_env); + } + } + Err(e) => { + if app_env.debug_level.as_str() == "trace" { + dbg!(&app_env); + } + eprintln!("Evironment load error: {}", AppError::NoAppEnvLoaded); + return Ok(()); + // panic!("No App Env loaded"); + } + }; + let config = app_env.get_curr_websrvr_config(); + /* + let mut db_appdata = DB.lock().await; + db_appdata.push(AppData::new(app_env.to_owned())); + drop(db_appdata); // End lock + */ + +// env_logger::init(); + if verbose > 0 { + println!("WebServices dist path: {}", &config.dist_path); + println!("WebServices Html path: {}", &config.html_path); + } + let resources_path = &config.resources_path.to_owned(); + if verbose > 0 { + println!("Services Resources path: {}", &resources_path); + + // dbg!(&app_env); + if app_env.has_appkey() { + println!("Auth App key: Loaded !"); + } + if app_env.info.appmode == AppRunMode::Pro || app_env.info.appmode == AppRunMode::Premium { + println!("WebServices Upload path: {}", &config.upload_path); + // println!("DataServices Main store: {}", &app_env.main_store); + } + } + async_std::fs::create_dir_all(&config.upload_path.as_str()).await?; + Ok(()) +} + +// pub async fn start_web(app_env: &mut AppEnv, fltrs: impl warp::Filter + Clone) { +pub async fn start_web(app_env: &mut AppEnv) -> (Zterton, SocketAddr) { + if env::var_os("RUST_LOG").is_none() { + // Set `RUST_LOG=todos=debug` to see debug logs, + // this only shows access logs. + env::set_var("RUST_LOG", "kloud=info"); + } + let config = app_env.get_curr_websrvr_config(); + let app = Zterton::new( + config.srv_protocol.to_owned(), + config.srv_host.to_owned(), + config.srv_port, + ); + // let filter = std::env::var("RUST_LOG").unwrap_or_else(|_| "hello_world=debug,salvo=debug".to_owned()); + // tracing_subscriber::fmt().with_env_filter(filter).with_span_events(FmtSpan::CLOSE).init(); + // (app.to_owned(), SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), app.port.to_owned())) + let url = format!("{}:{}",&config.srv_host,&config.srv_port); + match url.to_socket_addrs() { + Ok(addrs_op) => if let Some(addr) = addrs_op.to_owned().next() { + (app.to_owned(), addr) + } else { + (app.to_owned(), SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), app.port.to_owned())) + } + Err(e) => { + eprintln!("Evironment load error: {} {}", e, AppError::NoAppEnvLoaded); + (app.to_owned(), SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), app.port.to_owned())) + } + } + +} +