diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/config.rs | 31 | ||||
-rw-r--r-- | src/main.rs | 71 |
2 files changed, 87 insertions, 15 deletions
diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..e4203de --- /dev/null +++ b/src/config.rs @@ -0,0 +1,31 @@ +use std::{fs, path::Path}; + +use anyhow::Result; +use serde::Deserialize; + +/// The main configuration. +#[derive(Debug, Clone, Deserialize, Default)] +pub struct Config { + /// Flag indicating whether logs should be uploaded or not. + pub upload: bool, + /// Flag indicating whether logs with an unknown boss should be uploaded. + #[serde(default)] + pub upload_unknown: bool, + /// Option Discord information for bot postings. + pub discord: Option<Discord>, +} + +/// Configuration pertaining to the Discord posting. +#[derive(Debug, Clone, Deserialize)] +pub struct Discord { + /// Auth token for the Discord bot. + pub auth_token: String, + /// Channel ID in which logs should be posted. + pub channel_id: u64, +} + +/// Attempt to load the configuration from the given file. +pub fn load<P: AsRef<Path>>(path: P) -> Result<Config> { + let content = fs::read(path)?; + Ok(toml::from_slice(&content)?) +} diff --git a/src/main.rs b/src/main.rs index 45ae5e9..199cd9d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,7 +17,8 @@ use zip::{CompressionMethod, ZipWriter}; mod categories; use categories::Categorizable; - +mod config; +use config::Config; mod discord; const DPS_REPORT_API: &str = "https://dps.report/uploadContent"; @@ -26,14 +27,33 @@ const WATCH_DELAY_SECONDS: u64 = 2; #[derive(Clap, Debug, Clone, PartialEq, Eq, Hash)] #[clap(version = "0.1")] struct Opts { - /// The directory name to watch. + /// The configuration file path. + #[clap(short, long, default_value = "ezau.toml")] + config: PathBuf, + #[clap(subcommand)] + subcmd: SubCommand, +} + +#[derive(Clap, Debug, Clone, PartialEq, Eq, Hash)] +enum SubCommand { + Watch(Watch), + Upload(Upload), +} + +/// Use the watch mode to automatically handle new logs. +/// +/// This watches the given directory for new files and then zips and uploads them. +#[derive(Clap, Debug, Clone, PartialEq, Eq, Hash)] +struct Watch { + /// The directory to watch. dirname: PathBuf, - /// The Discord auth token for the bot account. - #[clap(long)] - discord_token: String, - /// The channel ID where the log message should be posted. - #[clap(long)] - channel_id: u64, +} + +/// Upload a single log, as it would be done by the automatic watcher. +#[derive(Clap, Debug, Clone, PartialEq, Eq, Hash)] +struct Upload { + /// The log to upload. + path: PathBuf, } fn main() { @@ -46,12 +66,28 @@ fn main() { } fn inner_main(opts: &Opts) -> Result<()> { + let config = config::load(&opts.config)?; + match &opts.subcmd { + SubCommand::Watch(w) => watch(w, &config)?, + SubCommand::Upload(u) => { + let permalink = upload_log(&u.path)?; + println!("{}", permalink); + if let Some(d) = &config.discord { + let log = load_log(&u.path)?; + discord::post_link(&d.auth_token, d.channel_id, log, permalink)?; + } + } + } + Ok(()) +} + +fn watch(watch: &Watch, config: &Config) -> Result<()> { 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)?; + watcher.watch(&watch.dirname, RecursiveMode::Recursive)?; loop { let event = rx.recv()?; debug!("Event: {:?}", event); @@ -62,7 +98,7 @@ fn inner_main(opts: &Opts) -> Result<()> { info!("Zipping up {}", path_str); zip_file(&path)?; } else if zip_evtc_re.is_match(path_str) { - handle_file(opts, &path)?; + handle_file(config, &path)?; } } } @@ -90,11 +126,14 @@ fn zip_file(filepath: &Path) -> Result<()> { Ok(()) } -fn handle_file(opts: &Opts, filename: &Path) -> Result<()> { +fn handle_file(config: &Config, filename: &Path) -> Result<()> { + if !config.upload { + return Ok(()); + } let log = load_log(filename)?; info!("Loaded log from category {}", log.category()); - if !should_upload(&log) { + if !should_upload(config, &log) { info!("Skipping log, not uploading"); return Ok(()); } @@ -102,14 +141,16 @@ fn handle_file(opts: &Opts, filename: &Path) -> Result<()> { let permalink = upload_log(filename)?; info!("Uploaded log, available at {}", permalink); - discord::post_link(&opts.discord_token, opts.channel_id, log, permalink)?; + if let Some(d) = &config.discord { + discord::post_link(&d.auth_token, d.channel_id, log, permalink)?; + } Ok(()) } -fn should_upload(log: &Log) -> bool { +fn should_upload(config: &Config, log: &Log) -> bool { // Only upload known logs - if log.encounter().is_none() { + if log.encounter().is_none() && !config.upload_unknown { return false; } // Only upload Skorvald if it actually was in 100 CM (and not in in lower-tier or non-CM). |