mirror of
https://codeberg.org/postscriptum/snac2nex.git
synced 2026-03-31 21:25:28 +00:00
add attachment symlinks option, rename binary option to attachment with export type value
This commit is contained in:
parent
9f24a133ed
commit
20c0aea8f3
6 changed files with 101 additions and 18 deletions
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "snac2nex"
|
||||
version = "0.2.2"
|
||||
version = "0.3.0"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
readme = "README.md"
|
||||
|
|
|
|||
10
README.md
10
README.md
|
|
@ -30,8 +30,14 @@ snac2nex -s /path/to/snac/storage -t /path/to/nex -u user1 -u user2
|
|||
-u, --user <USER>
|
||||
Username to export
|
||||
|
||||
-b, --binary
|
||||
Export binary files (attachments)
|
||||
-a, --attachment <ATTACHMENT>
|
||||
Include attachment files
|
||||
|
||||
Supported values:
|
||||
|
||||
* `c` (`copy`) - copy attachment files export
|
||||
* `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
|
||||
|
|
|
|||
|
|
@ -15,9 +15,15 @@ pub struct Config {
|
|||
#[arg(short, long)]
|
||||
pub user: Vec<String>,
|
||||
|
||||
/// Export binary files (attachments)
|
||||
#[arg(short, long, default_value_t = false)]
|
||||
pub binary: bool,
|
||||
/// Include attachment files export
|
||||
///
|
||||
/// Supported values:
|
||||
///
|
||||
/// * `c` (`copy`) - copy attachment files
|
||||
/// * `h` (`hard`) - create hard links
|
||||
/// * `s` (`soft`) - create soft links (macos, linux, windows only)
|
||||
#[arg(short, long)]
|
||||
pub attachment: Option<String>,
|
||||
|
||||
/// Keep running as the daemon, renew every `n` seconds
|
||||
#[arg(short, long)]
|
||||
|
|
|
|||
13
src/main.rs
13
src/main.rs
|
|
@ -16,17 +16,18 @@ fn main() -> Result<()> {
|
|||
c.format_filename,
|
||||
c.format_updated,
|
||||
c.format_content,
|
||||
c.attachment,
|
||||
&c.user,
|
||||
)?;
|
||||
let s = Snac::init(c.source, c.user)?;
|
||||
|
||||
println!("export begin...");
|
||||
let (mut u, mut t) = sync(&s, &n, c.binary)?;
|
||||
let (mut u, mut t) = sync(&s, &n)?;
|
||||
match c.rotate {
|
||||
Some(r) => loop {
|
||||
println!("queue completed (updated: {u} / total: {t}), await {r} seconds to rotate...");
|
||||
std::thread::sleep(std::time::Duration::from_secs(r));
|
||||
(u, t) = sync(&s, &n, c.binary)?;
|
||||
(u, t) = sync(&s, &n)?;
|
||||
},
|
||||
None => println!("export completed (updated: {u} / total: {t})."),
|
||||
}
|
||||
|
|
@ -34,7 +35,7 @@ fn main() -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn sync(snac: &Snac, nex: &Nex, is_binary: bool) -> Result<(usize, usize)> {
|
||||
fn sync(snac: &Snac, nex: &Nex) -> Result<(usize, usize)> {
|
||||
let mut t = 0; // total
|
||||
let mut u = 0; // updated
|
||||
for user in &snac.users {
|
||||
|
|
@ -55,13 +56,13 @@ fn sync(snac: &Snac, nex: &Nex, is_binary: bool) -> Result<(usize, usize)> {
|
|||
attachments.push((
|
||||
attachment.name,
|
||||
attachment.media_type,
|
||||
if is_binary {
|
||||
if nex.is_attachments_disabled() {
|
||||
Source::Url(attachment.url)
|
||||
} else {
|
||||
Source::File(
|
||||
user.file(attachment.url.split('/').next_back().unwrap())
|
||||
.unwrap(),
|
||||
)
|
||||
} else {
|
||||
Source::Url(attachment.url)
|
||||
},
|
||||
))
|
||||
}
|
||||
|
|
|
|||
18
src/nex.rs
18
src/nex.rs
|
|
@ -1,4 +1,7 @@
|
|||
mod attachment;
|
||||
|
||||
use anyhow::{Result, bail};
|
||||
use attachment::Attachment;
|
||||
use chrono::{DateTime, Utc};
|
||||
use std::{collections::HashMap, fs, path::PathBuf, str::FromStr};
|
||||
|
||||
|
|
@ -8,6 +11,7 @@ pub enum Source {
|
|||
}
|
||||
|
||||
pub struct Nex {
|
||||
attachment: Attachment,
|
||||
filename: String,
|
||||
pattern: String,
|
||||
time_format: String,
|
||||
|
|
@ -20,6 +24,7 @@ impl Nex {
|
|||
filename: String,
|
||||
time_format: String,
|
||||
pattern: String,
|
||||
attachment_mode: Option<String>,
|
||||
user_names: &Vec<String>,
|
||||
) -> Result<Self> {
|
||||
use std::path::MAIN_SEPARATOR;
|
||||
|
|
@ -41,9 +46,10 @@ impl Nex {
|
|||
}
|
||||
|
||||
Ok(Self {
|
||||
attachment: Attachment::init(attachment_mode)?,
|
||||
filename,
|
||||
time_format,
|
||||
pattern,
|
||||
time_format,
|
||||
users,
|
||||
})
|
||||
}
|
||||
|
|
@ -123,11 +129,7 @@ impl Nex {
|
|||
);
|
||||
to.push(&f);
|
||||
if !to.exists() {
|
||||
fs::copy(&from, &to).unwrap();
|
||||
println!(
|
||||
"\t\t\tcopy attachment file `{}`",
|
||||
to.to_string_lossy()
|
||||
)
|
||||
self.attachment.sync(&from, &to).unwrap()
|
||||
}
|
||||
format!("{}/{f}", d.file_name().unwrap().to_string_lossy())
|
||||
}
|
||||
|
|
@ -171,4 +173,8 @@ impl Nex {
|
|||
|
||||
Ok(1)
|
||||
}
|
||||
|
||||
pub fn is_attachments_disabled(&self) -> bool {
|
||||
matches!(self.attachment, Attachment::Disabled)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
64
src/nex/attachment.rs
Normal file
64
src/nex/attachment.rs
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
use anyhow::{Result, bail};
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub enum Attachment {
|
||||
Copy,
|
||||
HardLink,
|
||||
SoftLink,
|
||||
Disabled,
|
||||
}
|
||||
|
||||
impl Attachment {
|
||||
pub fn init(method: Option<String>) -> Result<Self> {
|
||||
Ok(match method {
|
||||
Some(m) => match m.to_lowercase().as_str() {
|
||||
"c" | "copy" => Self::Copy,
|
||||
"h" | "hard" => Self::HardLink,
|
||||
"s" | "soft" => Self::SoftLink,
|
||||
_ => bail!("Unsupported attachment mode!"),
|
||||
},
|
||||
None => Self::Disabled,
|
||||
})
|
||||
}
|
||||
pub fn sync(&self, source: &PathBuf, target: &PathBuf) -> Result<()> {
|
||||
use std::{fs, os};
|
||||
match self {
|
||||
Attachment::Copy => {
|
||||
fs::copy(source, target)?;
|
||||
println!(
|
||||
"\t\t\tcopied attachment file `{}`",
|
||||
target.to_string_lossy()
|
||||
)
|
||||
}
|
||||
Attachment::HardLink => {
|
||||
fs::hard_link(source, target)?;
|
||||
println!(
|
||||
"\t\t\tcreated hard link `{}` to attachment {}",
|
||||
target.to_string_lossy(),
|
||||
source.to_string_lossy(),
|
||||
)
|
||||
}
|
||||
Attachment::SoftLink => {
|
||||
#[cfg(any(target_os = "linux", target_os = "macos"))]
|
||||
{
|
||||
os::unix::fs::symlink(source, target)?
|
||||
}
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
os::windows::fs::symlink_file(source, target)?
|
||||
}
|
||||
#[cfg(not(any(target_os = "windows", target_os = "linux", target_os = "macos",)))]
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
println!(
|
||||
"\t\t\tcreated soft link `{}` to attachment {}",
|
||||
target.to_string_lossy(),
|
||||
source.to_string_lossy(),
|
||||
)
|
||||
}
|
||||
_ => panic!(), // warn as unexpected
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue