From db628efba8171bf1e5688a7d890012ae4dfec3e0 Mon Sep 17 00:00:00 2001 From: Guus Waals <_@guusw.nl> Date: Fri, 24 Oct 2025 19:56:24 +0800 Subject: [PATCH] Small update --- posts/hello-world-2.md | 2 +- src/post_manager.rs | 69 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/posts/hello-world-2.md b/posts/hello-world-2.md index 6bdad65..42e5a28 100644 --- a/posts/hello-world-2.md +++ b/posts/hello-world-2.md @@ -4,7 +4,7 @@ Welcome to my blog! This is my first post written in Markdown and served by a cu ## Features -This blog supports: +This blogew supports: - **CommonMark** markdown parsing - Git-based cache invalidation diff --git a/src/post_manager.rs b/src/post_manager.rs index f47759a..a00c60a 100644 --- a/src/post_manager.rs +++ b/src/post_manager.rs @@ -4,6 +4,7 @@ use pulldown_cmark::{html, Options, Parser}; use std::collections::HashMap; use std::fs; use std::path::PathBuf; +use std::process::Command; #[derive(Debug, Clone)] pub struct Post { @@ -65,6 +66,74 @@ impl PostManager { } } + fn get_post_timestamps(&self) -> Result>, String> { + let output = Command::new("git") + .arg("whatchanged") + .arg("--pretty=%h - %cd - %s") + .arg("--date=unix") + .arg("--") + .arg("posts") + .current_dir(&self.git_dir) + .output() + .map_err(|e| format!("Failed to execute git whatchanged: {}", e))?; + + if !output.status.success() { + return Err(format!( + "Git whatchanged command failed: {}", + String::from_utf8_lossy(&output.stderr) + )); + } + + let log_output = String::from_utf8_lossy(&output.stdout); + let mut timestamps: HashMap> = HashMap::new(); + + let mut current_timestamp: Option> = None; + + for line in log_output.lines() { + let line = line.trim(); + + // Skip empty lines + if line.is_empty() { + continue; + } + + // Parse commit header line: "f4fcf0e - 1761305168 - New post" + if !line.starts_with(':') { + if let Some(dash_pos) = line.find(" - ") { + let after_first_dash = &line[dash_pos + 3..]; + if let Some(second_dash_pos) = after_first_dash.find(" - ") { + let timestamp_str = after_first_dash[..second_dash_pos].trim(); + if let Ok(timestamp) = timestamp_str.parse::() { + current_timestamp = DateTime::from_timestamp(timestamp, 0); + } + } + } + } + // Parse file change line: ":000000 100644 0000000 6bdad65 A posts/hello-world-2.md" + else if line.starts_with(':') { + if let Some(timestamp) = current_timestamp { + let parts: Vec<&str> = line.split_whitespace().collect(); + if parts.len() >= 6 { + let status = parts[4]; // A (add), D (delete), M (modify) + let file_path = parts[5]; + + // Only process existing files (not deleted ones) + if status != "D" && file_path.starts_with("posts/") { + if let Some(file_name) = file_path.strip_prefix("posts/") { + if let Some(name) = file_name.strip_suffix(".md") { + // Only update if we don't have a timestamp yet (latest commit wins) + timestamps.entry(name.to_string()).or_insert(timestamp); + } + } + } + } + } + } + } + + Ok(timestamps) + } + fn refresh_posts(&mut self) -> Result<(), String> { self.posts.clear();