From d71ef882be35adb2f32ef8cb13e56c508a41a5a2 Mon Sep 17 00:00:00 2001 From: rabite Date: Wed, 19 Jun 2019 22:40:43 +0200 Subject: [PATCH] added missing file config_installer.rs --- src/config_installer.rs | 151 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 src/config_installer.rs diff --git a/src/config_installer.rs b/src/config_installer.rs new file mode 100644 index 0000000..5ca9282 --- /dev/null +++ b/src/config_installer.rs @@ -0,0 +1,151 @@ +use std::fs::*; +use std::io::Write; +use std::process::Command; +use std::ffi::OsStr; +use std::path::Path; + +use crate::fail::{HError, HResult}; +use crate::widget::WidgetCore; + + +pub fn ensure_config(core: WidgetCore) -> HResult<()> { + if has_config()? { + let previewers_path = crate::paths::previewers_path()?; + let actions_path = crate::paths::actions_path()?; + + if !previewers_path.exists() { + core.show_status("Coulnd't find previewers in config dir! Adding!")?; + install_config_previewers() + .or_else(|_| + core.show_status("Error installing previewers! Check log!"))?; + } + + if !actions_path.exists() { + core.show_status("Coulnd't find actions in config dir! Adding!")?; + install_config_actions() + .or_else(|_| + core.show_status("Error installing actions! Check log!"))?; + } + + return Ok(()); + } + + let msg = match install_config_all() { + Ok(_) => format!("Config installed in: {}", + crate::paths::hunter_path()?.to_string_lossy()), + Err(_) => format!("{}Problems with installation of default configuration! Look inside log.", + crate::term::color_red()), + }; + core.show_status(&msg)?; + + Ok(()) +} + + +fn default_config_archive() -> &'static [u8] { + let default_config = include_bytes!("../config.tar.gz"); + default_config +} + +fn has_config() -> HResult { + let config_dir = crate::paths::hunter_path()?; + + if config_dir.exists() { + return Ok(true); + } else { + return Ok(false); + } +} + + +fn install_config_all() -> HResult<()> { + let hunter_dir = crate::paths::hunter_path()?; + let config_dir = hunter_dir.parent()?; + + if !hunter_dir.exists() { + // create if non-existing + std::fs::create_dir(&hunter_dir) + .or_else(|_| HError::log(&format!("Couldn't create directory: {}", + hunter_dir.as_os_str() + .to_string_lossy())))?; + } + + let archive_path = create_archive()?; + extract_archive(config_dir, &archive_path)?; + delete_archive(archive_path)?; + + Ok(()) +} + +fn move_dir(from: &str, to: &Path) -> HResult<()> { + let success = Command::new("mv") + .arg(from) + .arg(to.as_os_str()) + .status() + .map(|s| s.success()); + + if success.is_err() || !success.unwrap() { + HError::log(&format!("Couldn't move {} to {} !", + from, + to.to_string_lossy())) + } else { + Ok(()) + } +} + +fn install_config_previewers() -> HResult<()> { + let hunter_dir = crate::paths::hunter_path()?; + let archive_path = create_archive()?; + extract_archive(Path::new("/tmp"), &archive_path)?; + move_dir("/tmp/hunter/previewers", &hunter_dir)?; + delete_archive(&archive_path) +} + +fn install_config_actions() -> HResult<()> { + let hunter_dir = crate::paths::hunter_path()?; + let archive_path = create_archive()?; + extract_archive(Path::new("/tmp"), &archive_path)?; + move_dir("/tmp/hunter/actions", &hunter_dir)?; + delete_archive(&archive_path) +} + +fn create_archive() -> HResult<&'static str> { + let archive_path = "/tmp/hunter-config.tar.gz"; + let def_config = default_config_archive(); + + File::create(archive_path) + .and_then(|mut f| { + f.write_all(def_config).map(|_| f) + }) + .and_then(|mut f| f.flush()) + .or_else(|_| { + HError::log(&format!("Failed to write config archive to: {}", + archive_path)) + })?; + Ok(archive_path) +} + + +fn extract_archive(to: &Path, archive_path: &str) -> HResult<()> { + let success = Command::new("tar") + .args(&[OsStr::new("-C"), + to.as_os_str(), + OsStr::new("-xf"), + OsStr::new(archive_path)]) + .status() + .or_else(|_| HError::log(&format!("Couldn't run tar!"))) + .map(|s| s.success())?; + + if !success { + HError::log(&format!("Extraction of archive failed! Archive: {}", + archive_path))? + } + + Ok(()) +} + +fn delete_archive(archive_path: &str) -> HResult<()> { + std::fs::remove_file(archive_path) + .or_else(|_| HError::log(&format!("Deletion of archive failed! Archive: {}", + archive_path))) +}