Implement logging utilities and log file path management
This commit is contained in:
@@ -3,11 +3,12 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use std::fs::{self, File};
|
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::path::{Path, PathBuf};
|
||||||
use std::process::{Command, Stdio};
|
use std::process::{Command, Stdio};
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
use tauri::{async_runtime, Env, State, Window};
|
use tauri::{async_runtime, Env, State, Window};
|
||||||
|
|
||||||
#[derive(Default, Clone)]
|
#[derive(Default, Clone)]
|
||||||
@@ -28,6 +29,7 @@ struct MapInfo {
|
|||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
struct GenerateResult {
|
struct GenerateResult {
|
||||||
output_path: String,
|
output_path: String,
|
||||||
|
log_path: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Default)]
|
#[derive(Debug, Deserialize, Default)]
|
||||||
@@ -62,6 +64,13 @@ fn output_dir(root: &Path) -> Result<PathBuf, String> {
|
|||||||
Ok(dir)
|
Ok(dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn logs_dir(root: &Path) -> Result<PathBuf, String> {
|
||||||
|
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<PathBuf, String> {
|
fn script_path(root: &Path) -> Result<PathBuf, String> {
|
||||||
let candidate = root.join("generate_equirect.py");
|
let candidate = root.join("generate_equirect.py");
|
||||||
if candidate.exists() {
|
if candidate.exists() {
|
||||||
@@ -79,6 +88,67 @@ fn python_binary(root: &Path) -> PathBuf {
|
|||||||
PathBuf::from("python3")
|
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<PathBuf, String> {
|
||||||
|
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<str>) {
|
||||||
|
let _ = writeln!(log_file, "{}", line.as_ref());
|
||||||
|
let _ = log_file.flush();
|
||||||
|
}
|
||||||
|
|
||||||
fn decode_latin1(bytes: &[u8]) -> String {
|
fn decode_latin1(bytes: &[u8]) -> String {
|
||||||
bytes.iter().map(|&byte| byte as char).collect()
|
bytes.iter().map(|&byte| byte as char).collect()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user