aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/config.rs31
-rw-r--r--src/main.rs71
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).