use rusqlite::{params, Connection}; use std::path::Path; use std::fs; use crate::Config; use std::env; use chrono::{Local, Datelike}; use pulldown_cmark::{Options, Parser, html}; use regex::Regex;
fn custom_date_format() -> String {
let now = Local::now();
let day = now.day();
let month = now.month();
let year = now.year();
let month_name = match month {
6 => "June".to_string(), 7 => "July".to_string(), _ => now.format("%b").to_string(), };
format!("{:02} {} {}", day, month_name, year)
}
pub fn create_post_php(category_path: &Path, file_name: &str) -> Result<(), Box<dyn std::error::Error>> {
let post_content = format!("<?php $file_name = \"{}\"; include 'chain.php'; ?>", file_name);
let post_php_path = category_path.join(format!("{}.php", file_name));
if !post_php_path.exists() {
fs::write(post_php_path, post_content)?;
println!("Created {}.php", file_name);
}
Ok(())
}
pub fn create_post(config: &Config, category: &str, file_name: &str, header: &str) -> Result<(), Box<dyn std::error::Error>> {
let category_path = Path::new(&config.base_dir).join(category);
if !category_path.exists() {
return Err(format!("Category '{}' does not exist", category).into());
}
create_post_php(&category_path, file_name)?;
let conn = Connection::open(&config.db_path)?;
let exists: bool = conn.query_row(
&format!("SELECT 1 FROM {} WHERE file_name = ?", category),
params![file_name],
|_| Ok(true)
).unwrap_or(false);
if !exists {
conn.execute(
&format!(
"INSERT INTO {} (file_name, date_splash, header, show, tags) VALUES (?, ?, ?, ?, ?)",
category
),
params![file_name, custom_date_format(), header, "", " "],
)?;
println!("Created database entry for '{}'", file_name);
}
Ok(())
}
pub fn markdown_to_html(content: &str) -> String {
let mut options = Options::empty();
options.insert(Options::ENABLE_STRIKETHROUGH);
options.insert(Options::ENABLE_TABLES);
options.insert(Options::ENABLE_FOOTNOTES);
let parser = Parser::new_ext(content, options);
let mut html_output = String::new();
html::push_html(&mut html_output, parser);
html_output
}
pub fn create_preview_html(html_content: &str) -> String {
let re = Regex::new(r"<[^>]+>").unwrap();
let text = re.replace_all(html_content, "").into_owned();
if text.len() > 1500 {
format!("{}...", &text[..1500])
} else {
text
}
}
pub fn process_markdown_file(
config: &Config,
category: &str,
file_name: &str,
) -> Result<(), Box<dyn std::error::Error>> {
let home = "/home/diego".to_string();
let content_dir = config.content_dir.replace("~", &home);
let content_dir = content_dir.replace("$HOME", &home);
let category_path = Path::new(&content_dir).join(category);
println!("Category path: {}", category_path.display());
let file_path = category_path.join(format!("{}.md", file_name));
println!("File path: {}", file_path.display());
if !file_path.exists() {
return Err(format!(
"Markdown file '{}' does not exist",
file_path.display()
)
.into());
}
let conn = Connection::open(&config.db_path)?;
let exists: bool = conn
.query_row(
&format!("SELECT 1 FROM {} WHERE file_name = ?", category),
params![file_name],
|_| Ok(true),
)
.unwrap_or(false);
if !exists {
return Err(format!("No database entry found for '{}'", file_name).into());
}
let markdown_content = fs::read_to_string(file_path)?;
let html_content = markdown_to_html(&markdown_content);
let preview_html = create_preview_html(&html_content);
conn.execute(
&format!(
"UPDATE {} SET text = ?, preview_html = ? WHERE file_name = ?",
category
),
params![html_content, preview_html, file_name],
)?;
let php_path = Path::new(&config.base_dir)
.join(category)
.join(format!("{}.php", file_name));
if !php_path.exists() {
create_post_php(&Path::new(&config.base_dir).join(category), file_name)?;
}
println!("Successfully processed '{}'", file_name);
Ok(())
}