initial commit

This commit is contained in:
postscriptum 2025-07-01 17:39:30 +03:00
commit 63f53528dc
10 changed files with 443 additions and 0 deletions

110
src/nex.rs Normal file
View file

@ -0,0 +1,110 @@
use anyhow::{Result, bail};
use chrono::{DateTime, Utc};
use std::{collections::HashMap, path::PathBuf, str::FromStr};
pub struct Nex {
filename: String,
pattern: String,
time_format: String,
users: HashMap<String, PathBuf>,
}
impl Nex {
pub fn init(
target_dir: String,
filename: String,
time_format: String,
pattern: String,
user_names: &Vec<String>,
) -> Result<Self> {
// init data export location
let target = PathBuf::from_str(&target_dir)?.canonicalize()?;
if !target.is_dir() {
bail!("Target location is not directory!");
}
// init locations for each user
let mut users = HashMap::with_capacity(user_names.len());
for u in user_names {
let mut p = PathBuf::from(&target);
p.push(u);
std::fs::create_dir_all(&p)?;
users.insert(u.clone(), p);
}
Ok(Self {
filename,
time_format,
pattern,
users,
})
}
pub fn sync(
&self,
name: &str,
content: String,
link: String,
attachments: Option<Vec<(String, String, String)>>,
tags: Option<Vec<String>>,
(published, updated): (DateTime<Utc>, Option<DateTime<Utc>>),
) -> Result<()> {
// format content pattern
let c = self
.pattern
.replace(
"{content}",
&if self.pattern.contains("{tags}") {
content.replace("#", "")
} else {
content
},
)
.replace(
"{attachments}",
&attachments
.map(|a| {
let mut b = Vec::with_capacity(a.len());
b.push("\n".to_string());
for (name, media_type, link) in a {
let mut t = Vec::with_capacity(3);
t.push(format!("=> {link}"));
if !name.is_empty() {
t.push(name)
}
if !media_type.is_empty() {
t.push(format!("({media_type})"))
}
b.push(t.join(" "))
}
b.join("\n")
})
.unwrap_or_default(),
)
.replace(
"{tags}",
&tags
.map(|t| format!("\n\n{}", t.join(", ")))
.unwrap_or_default(),
)
.replace("{link}", &format!("\n\n=> {link}"))
.replace(
"{updated}",
&updated
.map(|t| format!("\n\n{}", t.format(&self.time_format)))
.unwrap_or_default(),
);
// prepare destination
let mut p = PathBuf::from(self.users.get(name).unwrap());
p.push(published.format("%Y").to_string());
p.push(published.format("%m").to_string());
p.push(published.format("%d").to_string());
std::fs::create_dir_all(&p)?;
// write the data
p.push(published.format(&self.filename).to_string());
std::fs::write(p, c)?; // @TODO skip overwrite operations
Ok(())
}
}