From 87b9958d28be90b67d7534d751f58967b000c02c Mon Sep 17 00:00:00 2001 From: h Date: Sun, 29 Oct 2023 02:36:20 -0400 Subject: [PATCH] ye --- Dockerfile | 4 ++-- src/main.rs | 4 ++-- src/writer.rs | 36 +++++++++++++++++++++++++++++------- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/Dockerfile b/Dockerfile index 89d5fa2..4681185 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,8 +18,8 @@ RUN apt-get update && apt-get install libssl-dev -y RUN mkdir /store -RUN touch /store/store.xmlfrag +RUN touch /store/store.xmlfrag && touch /store/tmpfile.xmlfrag COPY ./templates/ /app/templates -CMD [ "/app/linky", "/store/store.xmlfrag" ] +CMD [ "/app/linky", "/store/store.xmlfrag", "/store/tmpfile.xmlfrag" ] diff --git a/src/main.rs b/src/main.rs index 850a7a1..ca188da 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,12 +27,12 @@ static SECRET_KEY: LazyLock = LazyLock::new(Key::generate); #[tokio::main] async fn main() { let args: Vec = env::args().collect(); - if args.len() < 2 { + if args.len() < 3 { println!("Need file argument."); exit(1); } - let store = Arc::new(Mutex::new(LinkFile::new(&args[1]))); + let store = Arc::new(Mutex::new(LinkFile::new(&args[1], &args[2]))); let authenticated = Router::new() .route("/rss.xml", get(get_rss)) diff --git a/src/writer.rs b/src/writer.rs index bb1ff00..6f49e26 100644 --- a/src/writer.rs +++ b/src/writer.rs @@ -2,7 +2,9 @@ use anyhow::{Context, Result}; use minijinja::{context, Environment}; use quick_xml::escape::escape; use reqwest::Client; -use std::fs::{File, OpenOptions}; +use std::fs; +use std::fs::File; +use std::io; use std::io::Write; use std::path::{Path, PathBuf}; use std::time::Duration; @@ -17,9 +19,9 @@ const TEMPLATE_STRING: &str = " "; pub struct LinkFile { - file: File, client: Client, path: PathBuf, + copy_path: PathBuf, } async fn get_link_title(client: &Client, link: &str) -> Result { @@ -40,14 +42,31 @@ async fn get_link_title(client: &Client, link: &str) -> Result { Ok(node.inner_text(dom.parser()).to_string()) } +fn prepend_file( + data: &[u8], + file_path: impl AsRef, + copy_path: impl AsRef, +) -> io::Result<()> { + let mut tmp = File::create(©_path)?; + let mut src = File::open(&file_path)?; + + tmp.write_all(data)?; + + io::copy(&mut src, &mut tmp)?; + + fs::remove_file(&file_path)?; + fs::rename(©_path, &file_path)?; + + Ok(()) +} + impl LinkFile { - pub fn new(path: impl AsRef + Clone) -> Self { - let file = OpenOptions::new().append(true).open(path.clone()).unwrap(); + pub fn new(path: impl AsRef + Clone, tempfile: impl AsRef + Clone) -> Self { let client = Client::new(); Self { - file, client, path: path.as_ref().to_path_buf(), + copy_path: tempfile.as_ref().to_path_buf(), } } @@ -61,14 +80,17 @@ impl LinkFile { env.add_template("rss_fragment", TEMPLATE_STRING)?; let template = env.get_template("rss_fragment")?; - self.file.write_all( + prepend_file( template .render(context! { title => title, link => escape(link).to_string(), })? .as_bytes(), + self.path.clone(), + self.copy_path.clone(), )?; + Ok(()) } @@ -84,7 +106,7 @@ mod tests { #[test] fn test_linkfile() { - let mut linkfile = LinkFile::new("./store.xmlfrag"); + let mut linkfile = LinkFile::new("./store.xmlfrag", "./copy_store.xmlfrag"); linkfile.add_link("https://evilmuff.in").unwrap(); } }