diff options
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 79 |
1 files changed, 65 insertions, 14 deletions
diff --git a/src/main.rs b/src/main.rs index 627a5c8..45ae5e9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,19 @@ -use std::path::{Path, PathBuf}; - -use anyhow::Result; +use std::{ + fs::{self, File}, + io::{BufWriter, Write}, + path::{Path, PathBuf}, + sync::mpsc::channel, + time::Duration, +}; + +use anyhow::{anyhow, Result}; use clap::Clap; use evtclib::{Boss, Compression, Log}; -use log::{error, info}; +use log::{debug, error, info}; +use notify::{self, DebouncedEvent, RecursiveMode, Watcher}; +use regex::Regex; use serde::Deserialize; +use zip::{CompressionMethod, ZipWriter}; mod categories; use categories::Categorizable; @@ -12,20 +21,18 @@ use categories::Categorizable; mod discord; const DPS_REPORT_API: &str = "https://dps.report/uploadContent"; +const WATCH_DELAY_SECONDS: u64 = 2; #[derive(Clap, Debug, Clone, PartialEq, Eq, Hash)] #[clap(version = "0.1")] struct Opts { - /// The filename to upload. - filename: PathBuf, - /// The configuration file to use. - #[clap(short, long, default_value = "ezau.toml")] - config: PathBuf, + /// The directory name to watch. + dirname: PathBuf, /// The Discord auth token for the bot account. - #[clap(short, long)] + #[clap(long)] discord_token: String, /// The channel ID where the log message should be posted. - #[clap(short, long)] + #[clap(long)] channel_id: u64, } @@ -39,7 +46,52 @@ fn main() { } fn inner_main(opts: &Opts) -> Result<()> { - let log = load_log(&opts.filename)?; + let raw_evtc_re = Regex::new(r"\d{8}-\d{6}(\.evtc)?$").unwrap(); + let zip_evtc_re = Regex::new(r"(\.zip|\.zevtc)$").unwrap(); + + let (tx, rx) = channel(); + let mut watcher = notify::watcher(tx, Duration::from_secs(WATCH_DELAY_SECONDS))?; + watcher.watch(&opts.dirname, RecursiveMode::Recursive)?; + loop { + let event = rx.recv()?; + debug!("Event: {:?}", event); + if let DebouncedEvent::Create(path) = event { + let path_str = path.to_str().unwrap(); + // Check if we need to zip it first. + if raw_evtc_re.is_match(path_str) { + info!("Zipping up {}", path_str); + zip_file(&path)?; + } else if zip_evtc_re.is_match(path_str) { + handle_file(opts, &path)?; + } + } + } +} + +fn zip_file(filepath: &Path) -> Result<()> { + let evtc_content = fs::read(filepath)?; + + let filename = filepath + .file_name() + .ok_or_else(|| anyhow!("Path does not have a file name"))? + .to_str() + .ok_or_else(|| anyhow!("Filename is invalid utf-8"))?; + let outname = filepath.with_extension("zevtc"); + let outfile = BufWriter::new(File::create(&outname)?); + let mut zip = ZipWriter::new(outfile); + let options = + zip::write::FileOptions::default().compression_method(CompressionMethod::Deflated); + + zip.start_file(filename, options)?; + zip.write_all(&evtc_content)?; + zip.finish()?; + + fs::remove_file(filepath)?; + Ok(()) +} + +fn handle_file(opts: &Opts, filename: &Path) -> Result<()> { + let log = load_log(filename)?; info!("Loaded log from category {}", log.category()); if !should_upload(&log) { @@ -47,12 +99,11 @@ fn inner_main(opts: &Opts) -> Result<()> { return Ok(()); } - let permalink = upload_log(&opts.filename)?; + let permalink = upload_log(filename)?; info!("Uploaded log, available at {}", permalink); discord::post_link(&opts.discord_token, opts.channel_id, log, permalink)?; - info!("We done bois, wrapping it up!"); Ok(()) } |