implement argument option to Keep Nex entry on Snac post was removed (disables cleanup action)

This commit is contained in:
postscriptum 2025-07-03 12:30:51 +03:00
parent 499a78004a
commit d8dac50cb6
5 changed files with 66 additions and 24 deletions

View file

@ -35,9 +35,7 @@ snac2nex -s /path/to/snac/storage -t /path/to/nex -u user1 -u user2
Supported values:
* `c` (`copy`) - copy files
* `h` (`hard`) - create hard links
* `s` (`soft`) - create soft links (macos, linux, windows only)
* `c` (`copy`) - copy files * `h` (`hard`) - create hard links * `s` (`soft`) - create soft links (macos, linux, windows only)
-r, --rotate <ROTATE>
Keep running as the daemon, renew every `n` seconds
@ -61,6 +59,9 @@ snac2nex -s /path/to/snac/storage -t /path/to/nex -u user1 -u user2
[default: "%Y/%m/%d %H:%M:%S"]
-k, --keep
Keep Nex entry on Snac post was removed
-h, --help
Print help (see a summary with '-h')

View file

@ -44,4 +44,8 @@ pub struct Config {
/// * escaped with `%%`
#[arg(long, default_value_t = String::from("%Y/%m/%d %H:%M:%S"))]
pub format_updated: String,
/// Keep Nex entry on Snac post was removed
#[arg(short, long, default_value_t = false)]
pub keep: bool,
}

View file

@ -19,6 +19,7 @@ fn main() -> Result<()> {
c.format_updated,
c.format_content,
c.attachment,
!c.keep,
&c.user,
)?;
let s = Snac::init(c.source, c.user)?;
@ -48,7 +49,11 @@ fn sync(snac: &Snac, nex: &Nex) -> Result<Response> {
let mut r = Response::default();
for user in &snac.users {
println!("\tsync profile for `{}`...", user.name);
let mut keep = HashSet::with_capacity(100); // @TODO estimated
let mut keep = if nex.is_cleanup() {
Some(HashSet::with_capacity(100)) // @TODO estimated
} else {
None
};
for post in user.public()? {
r.total += 1;
// make sure post entry has expected content type
@ -106,15 +111,21 @@ fn sync(snac: &Snac, nex: &Nex) -> Result<Response> {
println!("\t\t\tpost file `{f}` update with new content.")
}
}
for i in response.keep {
keep.insert(i);
if let Some(ref mut k) = keep
&& let Some(r) = response.keep
{
for i in r {
k.insert(i);
}
}
}
}
// cleanup removed post entries
let d = nex.clean(&user.name, keep)?;
r.deleted.directories += d.directories;
r.deleted.files += d.files;
if let Some(k) = keep {
let d = nex.clean(&user.name, k)?;
r.deleted.directories += d.directories;
r.deleted.files += d.files;
}
}
Ok(r)
}

View file

@ -17,6 +17,7 @@ use std::{
pub struct Nex {
attachment: Attachment,
filename: String,
is_cleanup: bool,
pattern: String,
time_format: String,
users: HashMap<String, PathBuf>,
@ -29,6 +30,7 @@ impl Nex {
time_format: String,
pattern: String,
attachment_mode: Option<String>,
is_cleanup: bool,
user_names: &Vec<String>,
) -> Result<Self> {
use std::path::MAIN_SEPARATOR;
@ -52,16 +54,15 @@ impl Nex {
Ok(Self {
attachment: Attachment::init(attachment_mode)?,
filename,
is_cleanup,
pattern,
time_format,
users,
})
}
// @TODO: This function requires the following improvements:
// * validate attachments before updating
// * apply the post time to the files
/// Update destination with given data (typically received from Snac)
// Sync the Snac post with the Nex entry
// * @TODO apply the post time to the files
pub fn sync(
&self,
name: &str,
@ -72,21 +73,33 @@ impl Nex {
(published, updated): (DateTime<Utc>, Option<DateTime<Utc>>),
) -> Result<Sync> {
// collect existing entries to ignore on cleanup
let mut i = Vec::with_capacity(10); // includes est. attachments len
let mut index = if self.is_cleanup {
Some(Vec::with_capacity(10)) // includes est. attachments len
} else {
None
};
// prepare destination
let root = PathBuf::from(self.users.get(name).unwrap());
let mut p = PathBuf::from(&root);
i.push(root);
if let Some(ref mut i) = index {
i.push(root);
}
p.push(published.format("%Y").to_string());
i.push(p.clone());
if let Some(ref mut i) = index {
i.push(p.clone());
}
p.push(published.format("%m").to_string());
i.push(p.clone());
if let Some(ref mut i) = index {
i.push(p.clone());
}
p.push(published.format("%d").to_string());
i.push(p.clone());
if let Some(ref mut i) = index {
i.push(p.clone());
}
fs::create_dir_all(&p)?;
@ -114,10 +127,12 @@ impl Nex {
fs::create_dir_all(&d)?;
fs::write(&s, updated.unwrap_or(published).to_string())?
} else {
i.extend([d, f, p, s]); // move all paths processed to cleanup ignore
if let Some(ref mut i) = index {
i.extend([d, f, p, s]);
}
return Ok(Sync {
change: Change::Ignored,
keep: i,
keep: index,
});
}
@ -157,7 +172,9 @@ impl Nex {
if !to.exists() {
self.attachment.sync(&from, &to).unwrap()
}
i.push(to);
if let Some(ref mut i) = index {
i.push(to);
}
format!("{}/{f}", d.file_name().unwrap().to_string_lossy())
}
}
@ -197,9 +214,14 @@ impl Nex {
fs::write(&f, c)?;
// move all paths processed to cleanup ignore
i.extend([d, f, p, s]);
if let Some(ref mut i) = index {
i.extend([d, f, p, s]);
}
Ok(Sync { change, keep: i })
Ok(Sync {
change,
keep: index,
})
}
pub fn clean(&self, name: &str, ignore: HashSet<PathBuf>) -> Result<Clean> {
@ -233,4 +255,8 @@ impl Nex {
pub fn is_attachments_disabled(&self) -> bool {
matches!(self.attachment, Attachment::Disabled)
}
pub fn is_cleanup(&self) -> bool {
self.is_cleanup
}
}

View file

@ -2,7 +2,7 @@ pub mod change;
pub struct Sync {
pub change: change::Change,
pub keep: Vec<std::path::PathBuf>,
pub keep: Option<Vec<std::path::PathBuf>>,
}
#[derive(Default)]