diff options
-rw-r--r-- | Cargo.lock | 110 | ||||
-rw-r--r-- | Cargo.toml | 3 | ||||
-rw-r--r-- | src/main.rs | 79 |
3 files changed, 178 insertions, 14 deletions
@@ -302,10 +302,13 @@ dependencies = [ "clap", "evtclib", "log", + "notify", "pretty_env_logger", + "regex", "reqwest", "serde", "serenity", + "zip", ] [[package]] @@ -315,6 +318,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" [[package]] +name = "filetime" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "affc17579b132fc2461adf7c575cc6e8b134ebca52c51f5411388965227dc695" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "winapi 0.3.8", +] + +[[package]] name = "flate2" version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -348,6 +363,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] +name = "fsevent" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6" +dependencies = [ + "bitflags", + "fsevent-sys", +] + +[[package]] +name = "fsevent-sys" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f41b048a94555da0f42f1d632e2e19510084fb8e303b0daa2816e733fb3644a0" +dependencies = [ + "libc", +] + +[[package]] name = "fuchsia-zircon" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -619,6 +653,26 @@ dependencies = [ ] [[package]] +name = "inotify" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4816c66d2c8ae673df83366c18341538f234a26d65a9ecea5c348b453ac1d02f" +dependencies = [ + "bitflags", + "inotify-sys", + "libc", +] + +[[package]] +name = "inotify-sys" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e74a1aa87c59aeff6ef2cc2fa62d41bc43f54952f55652656b18a02fd5e356c0" +dependencies = [ + "libc", +] + +[[package]] name = "input_buffer" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -668,6 +722,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] +name = "lazycell" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" + +[[package]] name = "libc" version = "0.2.71" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -754,6 +814,18 @@ dependencies = [ ] [[package]] +name = "mio-extras" +version = "2.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" +dependencies = [ + "lazycell", + "log", + "mio", + "slab", +] + +[[package]] name = "miow" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -795,6 +867,24 @@ dependencies = [ ] [[package]] +name = "notify" +version = "4.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80ae4a7688d1fab81c5bf19c64fc8db920be8d519ce6336ed4e7efe024724dbd" +dependencies = [ + "bitflags", + "filetime", + "fsevent", + "fsevent-sys", + "inotify", + "libc", + "mio", + "mio-extras", + "walkdir", + "winapi 0.3.8", +] + +[[package]] name = "num-derive" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1235,6 +1325,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] name = "schannel" version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1741,6 +1840,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" [[package]] +name = "walkdir" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" +dependencies = [ + "same-file", + "winapi 0.3.8", + "winapi-util", +] + +[[package]] name = "want" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -16,3 +16,6 @@ evtclib = "0.3.3" reqwest = { version = "0.10.6", features = ["json"] } serde = "1.0.111" chrono = "0.4.11" +notify = "4.0.15" +regex = "1.3.9" +zip = "0.5.5" 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(()) } |