From 54c6521875e2860e34766c84f80802642809b655 Mon Sep 17 00:00:00 2001 From: Victor Giers Date: Thu, 7 May 2026 11:16:11 +0200 Subject: [PATCH] Implement logging utilities and log file path management --- src-tauri/src/main.rs | 72 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 1c7b3c6..d78934e 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -3,11 +3,12 @@ use serde::{Deserialize, Serialize}; use serde_json::Value; use std::fs::{self, File}; -use std::io::{BufRead, BufReader, Read, Seek, SeekFrom}; +use std::io::{BufRead, BufReader, Read, Seek, SeekFrom, Write}; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Mutex}; +use std::time::{SystemTime, UNIX_EPOCH}; use tauri::{async_runtime, Env, State, Window}; #[derive(Default, Clone)] @@ -28,6 +29,7 @@ struct MapInfo { #[derive(Serialize)] struct GenerateResult { output_path: String, + log_path: String, } #[derive(Debug, Deserialize, Default)] @@ -62,6 +64,13 @@ fn output_dir(root: &Path) -> Result { Ok(dir) } +fn logs_dir(root: &Path) -> Result { + let mut dir = root.to_path_buf(); + dir.push("logs"); + fs::create_dir_all(&dir).map_err(|e| format!("Failed to create logs dir: {e}"))?; + Ok(dir) +} + fn script_path(root: &Path) -> Result { let candidate = root.join("generate_equirect.py"); if candidate.exists() { @@ -79,6 +88,67 @@ fn python_binary(root: &Path) -> PathBuf { PathBuf::from("python3") } +fn unix_timestamp_millis() -> u128 { + SystemTime::now() + .duration_since(UNIX_EPOCH) + .map(|duration| duration.as_millis()) + .unwrap_or(0) +} + +fn log_slug(prompt: &str) -> String { + let mut slug = String::new(); + let mut last_was_separator = false; + + for ch in prompt.chars().flat_map(char::to_lowercase) { + if ch.is_ascii_alphanumeric() { + slug.push(ch); + last_was_separator = false; + } else if !last_was_separator && !slug.is_empty() { + slug.push('_'); + last_was_separator = true; + } + + if slug.len() >= 64 { + break; + } + } + + while slug.ends_with('_') { + slug.pop(); + } + + if slug.is_empty() { + "generation".to_string() + } else { + slug + } +} + +fn generation_log_path(root: &Path, prompt: &str) -> Result { + let dir = logs_dir(root)?; + let timestamp = unix_timestamp_millis(); + let slug = log_slug(prompt); + let mut index = 0; + + loop { + let filename = if index == 0 { + format!("{timestamp}-{slug}.log") + } else { + format!("{timestamp}-{slug}-{index}.log") + }; + let path = dir.join(filename); + if !path.exists() { + return Ok(path); + } + index += 1; + } +} + +fn write_log_line(log_file: &mut File, line: impl AsRef) { + let _ = writeln!(log_file, "{}", line.as_ref()); + let _ = log_file.flush(); +} + fn decode_latin1(bytes: &[u8]) -> String { bytes.iter().map(|&byte| byte as char).collect() }