e-app 0.2.8

MII - Machine Internal Inspection
Documentation
use crate::share::{cmd_res, CmdRes};

use super::{Opts, OptsApi};
use e_utils::{Error, Result};
use serde_json::json;

/// # Input api 统一接口
///
/// # Rust
///```rust
/// fn main() -> e_utils::Result<()> {
///   if e_app::input::Opts::check_empty() {
///     let _ = app::MyApp::launch()?;
///   } else {
///     let opts = e_app::input::Opts::new(None as Option<Vec<String>>)?;
///     let res = e_app::input::api(opts)?;
///     println!("{}", res.to_str()?);
///   }
///   Ok(())
/// }
/// ```
pub fn api(opts: Opts) -> Result<CmdRes> {
  let mut new = cmd_res(opts);
  let ref op = new.opts;
  #[allow(unused)]
  let _ = match op.api {
    OptsApi::None => return Err(Error::String("Api cannot eq None".to_string())),
    OptsApi::Os => {
      #[cfg(not(feature = "os"))]
      return Err(Error::String("Feature not support os".to_string()));
      #[cfg(feature = "os")]
      {
        match &*op.task {
          "check" => new.merge(crate::os::check_os_active()),
          "active" => {
            if op.command.len() > 1 {
              new.merge(crate::os::active_os(
                &op.command[0],
                crate::os::ActiveLocalType::Temp(op.command[1].clone()),
              ))
            } else {
              return Err(Error::String("Command Error must > 0 ".to_string()));
            }
          }
          "deactive" => new.merge(crate::os::deactivate_os()),
          "rkms" => {
            if op.command.len() > 0 {
              new.merge(crate::os::register_kms(&op.command[0]))
            } else {
              return Err(Error::String("Command Error must > 0 ".to_string()));
            }
          }
          "ckms" => new.merge(crate::os::clear_kms()),
          "clean_cache" => {
            if op.command.len() > 0 {
              new.merge(crate::os::clean_cache(crate::os::ActiveLocalType::Temp(
                op.command[0].clone(),
              )))
            } else {
              return Err(Error::String("Command Error must > 0 ".to_string()));
            }
          }
          "query_cache" => {
            if op.command.len() > 0 {
              new.merge(crate::os::query_cache(crate::os::ActiveLocalType::Temp(
                op.command[0].clone(),
              )))
            } else {
              return Err(Error::String("Command Error must > 0 ".to_string()));
            }
          }
          _ => return Err(Error::String("Task Error".to_string())),
        }
      }
    }
    OptsApi::Office => match &*op.task {
      // "check" => m_opts(check_office(), opts),
      // "rkms" => {
      //     if op.command.len() > 0 {
      //         m_opts(register_office_kms(&op.command[0]), opts)
      //     } else {
      //         return Err(Error::String("Command Error must > 0 ".to_string()));
      //     }
      // }
      _ => return Err(Error::String("Task Error".to_string())),
    },
    OptsApi::Clean => {
      #[cfg(not(feature = "clean"))]
      return Err(Error::String("Feature not support Clean".to_string()));
      #[cfg(feature = "clean")]
      {
        match &*op.task {
          "empty_recycle_bin" => new.merge(crate::clean::empty_recycle_bin()),
          "empty_access_log" => new.merge(crate::clean::empty_access_log()),
          "empty_netshare" => new.merge(crate::clean::empty_netshare("*")),
          // 待校验
          "empty_activity_history" => new.merge(crate::clean::empty_activity_history()),
          // 待校验
          "empty_run_history" => new.merge(crate::clean::empty_run_history()),
          _ => return Err(Error::String("Task Error".to_string())),
        }
      }
    }
    OptsApi::Drive => {
      #[cfg(not(feature = "drive"))]
      return Err(Error::String("Feature not support Drive".to_string()));
      #[cfg(feature = "drive")]
      {
        match &*op.task {
          "scan" => new.merge(crate::drive::pnputil_scan()),
          "add-file" => {
            let args: Vec<&str> = op.args.iter().map(|x| x.as_ref()).collect();
            let mut outres = crate::share::default_cmd_res();
            for x in e_utils::fs::tree_folder(&args[0])?
              .into_iter()
              .filter(|x| std::path::Path::new(x).extension().unwrap_or_default() == "inf")
            {
              let mut new_args = args.clone();
              if let Some(v) = new_args.get_mut(0) {
                *v = &x;
              }
              let res = crate::drive::pnputil_add_driver(new_args);
              outres.content += &format!("{:?};;", res.content);
            }
            outres.status = true;
            new.merge(outres)
          }
          "add" => {
            let args: Vec<&str> = op.args.iter().map(|x| x.as_ref()).collect();
            let res = crate::drive::pnputil_add_driver(args);
            // 待优化判断添加驱动
            new.merge(res)
          }
          "delete" => {
            let args_src: Vec<&str> = op.args.iter().map(|x| x.as_ref()).collect();
            new.merge(crate::drive::pnputil_delete_driver(args_src))
          }
          "delete-find" => {
            let mut res = crate::share::default_cmd_res();
            let commands = op.command.iter().map(|x| x.as_ref()).collect::<Vec<&str>>();
            let devcon_node_list = crate::drive::findnodes(&op, commands);
            let args_src: Vec<&str> = op.args.iter().map(|x| x.as_ref()).collect();
            for node in &devcon_node_list {
              let inf_path: std::path::PathBuf = (&node.inf_file).into();
              if let Some(fname) = inf_path.file_name().and_then(|x| x.to_str()) {
                let mut args = args_src.clone();
                args.insert(0, fname);
                let dres = crate::drive::pnputil_delete_driver(args);
                let status = crate::drive::devcon_status(&node.id);
                if status.status != crate::drive::DriveStatusType::None {
                  res.status = false;
                }
              } else {
                res.status = false;
              }
              if !res.status {
                res.content = serde_json::to_string(&vec![node]).unwrap_or_default();
                return Ok(res);
              }
            }
            if let Ok(x) = serde_json::to_string(&devcon_node_list) {
              res.content = x;
              res.status = true;
            }
            new.merge(res)
          }
          "findnodes" => {
            let mut res = crate::share::default_cmd_res();
            let commands = op.command.iter().map(|x| x.as_ref()).collect::<Vec<&str>>();
            let devcon_node_list = crate::drive::findnodes(&op, commands);
            if let Ok(x) = serde_json::to_string(&devcon_node_list) {
              res.content = x;
              res.status = true;
            }
            new.merge(res)
          }
          "restart" => {
            let mut res = crate::share::default_cmd_res();
            let status_list = crate::drive::find_with_run(&op, crate::drive::pnputil_restart);
            for status in &status_list {
              if status.status == crate::drive::DriveStatusType::Runing {
                res.status = true;
                break;
              }
            }
            if let Ok(x) = serde_json::to_string(&status_list) {
              res.content = x;
            }
            new.merge(res)
          }
          "enable" => {
            let mut res = crate::share::default_cmd_res();
            let args_src: Vec<&str> = op.args.iter().map(|x| x.as_ref()).collect();
            let status_list = crate::drive::find_with_run(&op, crate::drive::pnputil_enable);
            res.status = true;
            for status in &status_list {
              if status.status != crate::drive::DriveStatusType::Runing {
                res.status = false;
                break;
              }
            }
            if let Ok(x) = serde_json::to_string(&status_list) {
              res.content = x;
            }
            new.merge(res)
          }
          "disable" => {
            let mut res = crate::share::default_cmd_res();
            let args_src: Vec<&str> = op.args.iter().map(|x| x.as_ref()).collect();
            let status_list = crate::drive::find_with_run(&op, crate::drive::pnputil_disable);
            res.status = true;
            for status in &status_list {
              if status.status != crate::drive::DriveStatusType::Disabled {
                res.status = false;
                break;
              }
            }
            if let Ok(x) = serde_json::to_string(&status_list) {
              res.content = x;
            }
            new.merge(res)
          }
          "remove" => {
            let mut res = crate::share::default_cmd_res();
            let args_src: Vec<&str> = op.args.iter().map(|x| x.as_ref()).collect();
            let status_list = crate::drive::find_with_run(&op, crate::drive::pnputil_remove);
            res.status = true;
            for status in &status_list {
              if status.status != crate::drive::DriveStatusType::None {
                res.status = false;
                break;
              }
            }
            if let Ok(x) = serde_json::to_string(&status_list) {
              res.content = x;
            }
            new.merge(res)
          }
          "export" => {
            let args_src: Vec<&str> = op.args.iter().map(|x| x.as_ref()).collect();
            let res = crate::drive::pnputil_export_driver(args_src);
            new.merge(res)
          }
          _ => {
            let commands = op.command.iter().map(|x| x.as_ref()).collect::<Vec<&str>>();
            new.merge(crate::drive::devcon(commands))
          }
        }
      }
    }
    OptsApi::Net => {
      #[cfg(not(all(feature = "net-info", feature = "net-manage")))]
      return Err(Error::String("Feature not support Net".to_string()));
      #[cfg(all(feature = "net-info", feature = "net-manage"))]
      {
        match &*op.task {
          "interfaces" => new.set_status(true).set_content(
            serde_json::to_string(&crate::net::get_interfaces()).unwrap_or_else(|e| e.to_string()),
          ),
          "interfaces_print" => {
            let ifaces = crate::net::get_interfaces();
            new
              .set_status(true)
              .set_content(format!("数量: {}", ifaces.len()));
            for iface in ifaces {
              println!("{:#?}", iface)
            }
            &mut new
          }
          "auto_dhcp" => {
            let args: Vec<&str> = op.args.iter().map(|x| x.as_ref()).collect();
            let mut len = 0;
            if args.len() == 0 {
              for iface in crate::net::get_interfaces() {
                if let Some(ref name) = iface.friendly_name {
                  match iface.if_type {
                    crate::net::InterfaceType::Wireless80211
                    | crate::net::InterfaceType::GigabitEthernet
                    | crate::net::InterfaceType::FastEthernetFx
                    | crate::net::InterfaceType::FastEthernetT
                    | crate::net::InterfaceType::Ethernet
                    | crate::net::InterfaceType::TokenRing => {
                      let ip_res = crate::net::set_ip_dhcp(name)?;
                      let dns_res = crate::net::set_dns_dhcp(name)?;

                      new.opts.command.push(
                        json!({
                          "name": name,
                          "type": iface.if_type,
                          "dnsRes": dns_res,
                          "ipRes": ip_res
                        })
                        .to_string(),
                      );
                      len += 1;
                    }
                    _ => {}
                  }
                }
              }
            } else {
              let ip_res = crate::net::set_ip_dhcp(args[0])?;
              let dns_res = crate::net::set_dns_dhcp(args[0])?;
              new.opts.command.push(
                json!({
                  "name": args[0],
                  "type": "Unknow",
                  "dnsRes": dns_res,
                  "ipRes": ip_res
                })
                .to_string(),
              );
              len = 1;
            }
            new.set_status(true).set_content(format!("数量: {}", len))
          }
          _ => return Err(Error::String("Task Error".to_string())),
        }
      }
    }
  };
  #[allow(unreachable_code)]
  Ok(new)
}

/// 初始化
pub fn drive_init() -> Result<()> {
  #[cfg(target_os = "windows")]
  {
    #[cfg(feature = "drive")]
    crate::share::write_bytes_file(
      crate::drive::get_drive_path().join(crate::drive::EDRIVE_NAME),
      crate::drive::EDRIVE_EXE,
    )?;
  }
  Ok(())
}