mirror of
https://codeberg.org/postscriptum/snac2nex.git
synced 2026-03-31 21:25:28 +00:00
initial commit
This commit is contained in:
commit
63f53528dc
10 changed files with 443 additions and 0 deletions
110
src/nex.rs
Normal file
110
src/nex.rs
Normal 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(())
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue