aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Schadt <kingdread@gmx.de>2020-06-08 15:35:47 +0200
committerDaniel Schadt <kingdread@gmx.de>2020-06-08 15:35:47 +0200
commitd55d1634c2073768f1781652bb9f15ebe74be697 (patch)
treed14df97fee5bd166760ec1763cd42b6527668c3a
parent3bd2201e51b8899305e4c4370a04389611d7d22e (diff)
downloadezau-d55d1634c2073768f1781652bb9f15ebe74be697.tar.gz
ezau-d55d1634c2073768f1781652bb9f15ebe74be697.tar.bz2
ezau-d55d1634c2073768f1781652bb9f15ebe74be697.zip
add config and subcommands
ezau having the watching functionality is nice, but sometimes for scripts you might want to have the old "upload this single log and post it to discord" functionality. As such, ezau has now been split into two subcommands (which use the same core): ezau watch runs the inotify-based directory watcher to zip and upload new logs. Additionally, it now respects the "upload = ..." config settings, which means you can also use it as a zipper only, without having every log uploaded. ezau upload performs a single-shot upload with the discord notification. Furthermore, the discord auth token/channel id have been moved to a configuration file. Switches to override this for single runs might be provided in the future, but for now, it seems more sensible to have it in a persistent configuration.
-rw-r--r--Cargo.lock10
-rw-r--r--Cargo.toml1
-rw-r--r--src/config.rs31
-rw-r--r--src/main.rs71
4 files changed, 98 insertions, 15 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 2d46550..f50387e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -308,6 +308,7 @@ dependencies = [
"reqwest",
"serde",
"serenity",
+ "toml",
"zip",
]
@@ -1687,6 +1688,15 @@ dependencies = [
]
[[package]]
+name = "toml"
+version = "0.5.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a"
+dependencies = [
+ "serde",
+]
+
+[[package]]
name = "tower-service"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 6bd3845..f40a041 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -20,3 +20,4 @@ chrono = "0.4.11"
notify = "4.0.15"
regex = "1.3.9"
zip = "0.5.5"
+toml = "0.5.6"
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).