use crate::{ util::io::{self, IOError}, {state::ProfilePathId, State}, }; use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Debug)] pub struct Logs { pub datetime_string: String, pub output: Option, } impl Logs { async fn build( profile_subpath: &ProfilePathId, datetime_string: String, clear_contents: Option, ) -> crate::Result { Ok(Self { output: if clear_contents.unwrap_or(false) { None } else { Some( get_output_by_datetime(profile_subpath, &datetime_string) .await?, ) }, datetime_string, }) } } #[tracing::instrument] pub async fn get_logs( profile_path: ProfilePathId, clear_contents: Option, ) -> crate::Result> { let state = State::get().await?; let profile_path = if let Some(p) = crate::profile::get(&profile_path, None).await? { p.profile_id() } else { return Err(crate::ErrorKind::UnmanagedProfileError( profile_path.to_string(), ) .into()); }; let logs_folder = state.directories.profile_logs_dir(&profile_path).await?; let mut logs = Vec::new(); if logs_folder.exists() { for entry in std::fs::read_dir(&logs_folder) .map_err(|e| IOError::with_path(e, &logs_folder))? { let entry = entry.map_err(|e| IOError::with_path(e, &logs_folder))?; let path = entry.path(); if path.is_dir() { if let Some(datetime_string) = path.file_name() { logs.push( Logs::build( &profile_path, datetime_string.to_string_lossy().to_string(), clear_contents, ) .await, ); } } } } let mut logs = logs.into_iter().collect::>>()?; logs.sort_by_key(|x| x.datetime_string.clone()); Ok(logs) } #[tracing::instrument] pub async fn get_logs_by_datetime( profile_path: ProfilePathId, datetime_string: String, ) -> crate::Result { let profile_path = if let Some(p) = crate::profile::get(&profile_path, None).await? { p.profile_id() } else { return Err(crate::ErrorKind::UnmanagedProfileError( profile_path.to_string(), ) .into()); }; Ok(Logs { output: Some( get_output_by_datetime(&profile_path, &datetime_string).await?, ), datetime_string, }) } #[tracing::instrument] pub async fn get_output_by_datetime( profile_subpath: &ProfilePathId, datetime_string: &str, ) -> crate::Result { let state = State::get().await?; let logs_folder = state.directories.profile_logs_dir(profile_subpath).await?; let path = logs_folder.join(datetime_string).join("stdout.log"); Ok(io::read_to_string(&path).await?) } #[tracing::instrument] pub async fn delete_logs(profile_path: ProfilePathId) -> crate::Result<()> { let profile_path = if let Some(p) = crate::profile::get(&profile_path, None).await? { p.profile_id() } else { return Err(crate::ErrorKind::UnmanagedProfileError( profile_path.to_string(), ) .into()); }; let state = State::get().await?; let logs_folder = state.directories.profile_logs_dir(&profile_path).await?; for entry in std::fs::read_dir(&logs_folder) .map_err(|e| IOError::with_path(e, &logs_folder))? { let entry = entry.map_err(|e| IOError::with_path(e, &logs_folder))?; let path = entry.path(); if path.is_dir() { io::remove_dir_all(&path).await?; } } Ok(()) } #[tracing::instrument] pub async fn delete_logs_by_datetime( profile_path: ProfilePathId, datetime_string: &str, ) -> crate::Result<()> { let profile_path = if let Some(p) = crate::profile::get(&profile_path, None).await? { p.profile_id() } else { return Err(crate::ErrorKind::UnmanagedProfileError( profile_path.to_string(), ) .into()); }; let state = State::get().await?; let logs_folder = state.directories.profile_logs_dir(&profile_path).await?; let path = logs_folder.join(datetime_string); io::remove_dir_all(&path).await?; Ok(()) }