Added report_out_of_stock command to bot
ci/woodpecker/push/woodpecker Pipeline was successful Details

+ Added params to the build_response function
+ Updated some commands with more helpful responses
+ Fixed issue with v4 migration
+ clippy + fmt
main
Joey Hines 2022-01-06 18:49:49 -07:00
parent c6ec8467c1
commit 51d6ffb7be
No known key found for this signature in database
GPG Key ID: 80F567B5C968F91B
22 changed files with 202 additions and 109 deletions

110
Cargo.lock generated
View File

@ -115,9 +115,9 @@ dependencies = [
[[package]] [[package]]
name = "bumpalo" name = "bumpalo"
version = "3.8.0" version = "3.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c" checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899"
[[package]] [[package]]
name = "byteorder" name = "byteorder"
@ -158,7 +158,7 @@ dependencies = [
"libc", "libc",
"num-integer", "num-integer",
"num-traits 0.2.14", "num-traits 0.2.14",
"serde 1.0.132", "serde 1.0.133",
"time", "time",
"winapi", "winapi",
] ]
@ -198,7 +198,7 @@ dependencies = [
"lazy_static", "lazy_static",
"nom", "nom",
"rust-ini", "rust-ini",
"serde 1.0.132", "serde 1.0.133",
"serde-hjson", "serde-hjson",
"serde_json", "serde_json",
"toml", "toml",
@ -409,9 +409,9 @@ dependencies = [
[[package]] [[package]]
name = "generic-array" name = "generic-array"
version = "0.14.4" version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803"
dependencies = [ dependencies = [
"typenum", "typenum",
"version_check", "version_check",
@ -428,7 +428,7 @@ dependencies = [
"log", "log",
"rand 0.8.4", "rand 0.8.4",
"regex", "regex",
"serde 1.0.132", "serde 1.0.133",
"serde_json", "serde_json",
"simple_logger", "simple_logger",
"structopt", "structopt",
@ -446,7 +446,7 @@ dependencies = [
"geoffrey_models", "geoffrey_models",
"log", "log",
"reqwest", "reqwest",
"serde 1.0.132", "serde 1.0.133",
"serde_json", "serde_json",
"serde_plain", "serde_plain",
"serenity", "serenity",
@ -465,7 +465,7 @@ dependencies = [
"lazy_static", "lazy_static",
"log", "log",
"regex", "regex",
"serde 1.0.132", "serde 1.0.133",
"serde_json", "serde_json",
"sled", "sled",
] ]
@ -476,7 +476,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"chrono", "chrono",
"log", "log",
"serde 1.0.132", "serde 1.0.133",
"serde_json", "serde_json",
] ]
@ -504,9 +504,9 @@ dependencies = [
[[package]] [[package]]
name = "h2" name = "h2"
version = "0.3.9" version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f072413d126e57991455e0a922b31e4c8ba7c2ffbebf6b78b4f8521397d65cd" checksum = "0c9de88456263e249e241fcd211d3954e2c9b0ef7ccfc235a444eb367cae3689"
dependencies = [ dependencies = [
"bytes 1.1.0", "bytes 1.1.0",
"fnv", "fnv",
@ -572,13 +572,13 @@ dependencies = [
[[package]] [[package]]
name = "http" name = "http"
version = "0.2.5" version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1323096b05d41827dadeaee54c9981958c0f94e670bc94ed80037d1a7b8b186b" checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03"
dependencies = [ dependencies = [
"bytes 1.1.0", "bytes 1.1.0",
"fnv", "fnv",
"itoa 0.4.8", "itoa 1.0.1",
] ]
[[package]] [[package]]
@ -930,9 +930,9 @@ dependencies = [
[[package]] [[package]]
name = "num_cpus" name = "num_cpus"
version = "1.13.0" version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
dependencies = [ dependencies = [
"hermit-abi", "hermit-abi",
"libc", "libc",
@ -1016,18 +1016,18 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
[[package]] [[package]]
name = "pin-project" name = "pin-project"
version = "1.0.8" version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "576bc800220cc65dac09e99e97b08b358cfab6e17078de8dc5fee223bd2d0c08" checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e"
dependencies = [ dependencies = [
"pin-project-internal", "pin-project-internal",
] ]
[[package]] [[package]]
name = "pin-project-internal" name = "pin-project-internal"
version = "1.0.8" version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e8fe8163d14ce7f0cdac2e040116f22eac817edabff0be91e8aff7e9accf389" checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -1036,9 +1036,9 @@ dependencies = [
[[package]] [[package]]
name = "pin-project-lite" name = "pin-project-lite"
version = "0.2.7" version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c"
[[package]] [[package]]
name = "pin-utils" name = "pin-utils"
@ -1054,9 +1054,9 @@ checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe"
[[package]] [[package]]
name = "ppv-lite86" name = "ppv-lite86"
version = "0.2.15" version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba" checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
[[package]] [[package]]
name = "proc-macro-error" name = "proc-macro-error"
@ -1084,9 +1084,9 @@ dependencies = [
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.34" version = "1.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f84e92c0f7c9d58328b85a78557813e4bd845130db68d7184635344399423b1" checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
dependencies = [ dependencies = [
"unicode-xid", "unicode-xid",
] ]
@ -1099,9 +1099,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.10" version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
@ -1224,9 +1224,9 @@ dependencies = [
[[package]] [[package]]
name = "reqwest" name = "reqwest"
version = "0.11.7" version = "0.11.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07bea77bc708afa10e59905c3d4af7c8fd43c9214251673095ff8b14345fcbc5" checksum = "7c4e0a76dc12a116108933f6301b95e83634e0c47b0afbed6abbaa0601e99258"
dependencies = [ dependencies = [
"base64 0.13.0", "base64 0.13.0",
"bytes 1.1.0", "bytes 1.1.0",
@ -1249,7 +1249,7 @@ dependencies = [
"pin-project-lite", "pin-project-lite",
"rustls 0.20.2", "rustls 0.20.2",
"rustls-pemfile", "rustls-pemfile",
"serde 1.0.132", "serde 1.0.133",
"serde_json", "serde_json",
"serde_urlencoded", "serde_urlencoded",
"tokio", "tokio",
@ -1260,7 +1260,7 @@ dependencies = [
"wasm-bindgen", "wasm-bindgen",
"wasm-bindgen-futures", "wasm-bindgen-futures",
"web-sys", "web-sys",
"webpki-roots 0.21.1", "webpki-roots 0.22.2",
"winreg", "winreg",
] ]
@ -1404,9 +1404,9 @@ checksum = "9dad3f759919b92c3068c696c15c3d17238234498bbdcc80f2c469606f948ac8"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.132" version = "1.0.133"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b9875c23cf305cd1fd7eb77234cbb705f21ea6a72c637a5c6db5fe4b8e7f008" checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
@ -1425,9 +1425,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.132" version = "1.0.133"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ecc0db5cb2556c0e558887d9bbdcf6ac4471e83ff66cf696e5419024d1606276" checksum = "ed201699328568d8d08208fdd080e3ff594e6c422e438b6705905da01005d537"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -1436,13 +1436,13 @@ dependencies = [
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.73" version = "1.0.74"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcbd0344bc6533bc7ec56df11d42fb70f1b912351c0825ccb7211b59d8af7cf5" checksum = "ee2bb9cd061c5865d345bb02ca49fcef1391741b672b54a0bf7b679badec3142"
dependencies = [ dependencies = [
"itoa 1.0.1", "itoa 1.0.1",
"ryu", "ryu",
"serde 1.0.132", "serde 1.0.133",
] ]
[[package]] [[package]]
@ -1451,7 +1451,7 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95455e7e29fada2052e72170af226fbe368a4ca33dee847875325d9fdb133858" checksum = "95455e7e29fada2052e72170af226fbe368a4ca33dee847875325d9fdb133858"
dependencies = [ dependencies = [
"serde 1.0.132", "serde 1.0.133",
] ]
[[package]] [[package]]
@ -1463,13 +1463,13 @@ dependencies = [
"form_urlencoded", "form_urlencoded",
"itoa 0.4.8", "itoa 0.4.8",
"ryu", "ryu",
"serde 1.0.132", "serde 1.0.133",
] ]
[[package]] [[package]]
name = "serenity" name = "serenity"
version = "0.10.9" version = "0.10.9"
source = "git+https://github.com/serenity-rs/serenity.git#04fc541b0e34d0e16c99039ce94cfe3cb79881b8" source = "git+https://github.com/serenity-rs/serenity.git#7b89775858d92a1c8be05f213b92fbe72b083980"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"async-tungstenite", "async-tungstenite",
@ -1481,7 +1481,7 @@ dependencies = [
"futures", "futures",
"percent-encoding", "percent-encoding",
"reqwest", "reqwest",
"serde 1.0.132", "serde 1.0.133",
"serde_json", "serde_json",
"tokio", "tokio",
"tracing", "tracing",
@ -1605,9 +1605,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.82" version = "1.0.85"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59" checksum = "a684ac3dcd8913827e18cd09a68384ee66c1de24157e3c556c9ab16d85695fb7"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -1789,7 +1789,7 @@ version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
dependencies = [ dependencies = [
"serde 1.0.132", "serde 1.0.133",
] ]
[[package]] [[package]]
@ -1892,9 +1892,9 @@ checksum = "ed5b74f0a24b5454580a79abb6994393b09adf0ab8070f15827cb666255de155"
[[package]] [[package]]
name = "typenum" name = "typenum"
version = "1.14.0" version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
[[package]] [[package]]
name = "unicase" name = "unicase"
@ -1976,9 +1976,9 @@ checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]] [[package]]
name = "version_check" name = "version_check"
version = "0.9.3" version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]] [[package]]
name = "want" name = "want"
@ -2009,7 +2009,7 @@ dependencies = [
"percent-encoding", "percent-encoding",
"pin-project", "pin-project",
"scoped-tls", "scoped-tls",
"serde 1.0.132", "serde 1.0.133",
"serde_json", "serde_json",
"serde_urlencoded", "serde_urlencoded",
"tokio", "tokio",
@ -2139,11 +2139,11 @@ dependencies = [
[[package]] [[package]]
name = "webpki-roots" name = "webpki-roots"
version = "0.21.1" version = "0.22.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940" checksum = "552ceb903e957524388c4d3475725ff2c8b7960922063af6ce53c9a43da07449"
dependencies = [ dependencies = [
"webpki 0.21.4", "webpki 0.22.0",
] ]
[[package]] [[package]]

View File

@ -95,7 +95,7 @@ pub fn handle_command<T: Command>(
req: CommandRequest<T::Req>, req: CommandRequest<T::Req>,
) -> Result<T::Resp> { ) -> Result<T::Resp> {
log::info!("Running command {}", T::command_name()); log::info!("Running command {}", T::command_name());
log::debug!("Request: {:?}", req); log::debug!("User: {:?} Request params: {:?}", req.user_id, req.params);
let user = get_player_from_req::<T::Req>(&ctx.db, &req)?; let user = get_player_from_req::<T::Req>(&ctx.db, &req)?;
let token = get_token_from_req::<T::Req>(&ctx.db, &req)?; let token = get_token_from_req::<T::Req>(&ctx.db, &req)?;

View File

@ -90,9 +90,10 @@ impl BotCommand for AddItemCommand {
)) ))
} }
fn build_response(resp: Self::ApiResp) -> String { fn build_response(resp: Self::ApiResp, req: Self::ApiParams) -> String {
format!( format!(
"**{}** has been updated:\n{}", "**{}** has been added to {} :\n{}",
req.item_name,
resp.name, resp.name,
display_loc_full(&resp) display_loc_full(&resp)
) )

View File

@ -76,7 +76,7 @@ impl BotCommand for AddLocationCommand {
Ok(Self::ApiParams::new(name, position, loc_type, None)) Ok(Self::ApiParams::new(name, position, loc_type, None))
} }
fn build_response(resp: Self::ApiResp) -> String { fn build_response(resp: Self::ApiResp, _: Self::ApiParams) -> String {
format!( format!(
"**{}** has been added to Geoffrey:\n{}", "**{}** has been added to Geoffrey:\n{}",
resp.name, resp.name,

View File

@ -58,7 +58,7 @@ impl BotCommand for DeleteCommand {
Ok(Self::ApiParams::new(loc_name)) Ok(Self::ApiParams::new(loc_name))
} }
fn build_response(resp: Self::ApiResp) -> String { fn build_response(resp: Self::ApiResp, _: Self::ApiParams) -> String {
format!( format!(
"**{}** has been been removed from Geoffrey, good riddance!", "**{}** has been been removed from Geoffrey, good riddance!",
resp.name resp.name

View File

@ -7,7 +7,6 @@ use serenity::model::interactions::application_command::{
use crate::bot::arg_parse::option_to_string; use crate::bot::arg_parse::option_to_string;
use crate::bot::commands::{BotCommand, CommandError}; use crate::bot::commands::{BotCommand, CommandError};
use crate::bot::formatters::display_loc;
use geoffrey_models::models::parameters::edit_params::EditParams; use geoffrey_models::models::parameters::edit_params::EditParams;
use serenity::builder::CreateApplicationCommand; use serenity::builder::CreateApplicationCommand;
@ -60,11 +59,7 @@ impl BotCommand for EditNameCommand {
Ok(Self::ApiParams::new(name, None, Some(new_name))) Ok(Self::ApiParams::new(name, None, Some(new_name)))
} }
fn build_response(resp: Self::ApiResp) -> String { fn build_response(resp: Self::ApiResp, args: Self::ApiParams) -> String {
format!( format!("**{}** has been renamed to {}", args.loc_name, resp.name,)
"**{}** has been updated:\n{}",
resp.name,
display_loc(&resp)
)
} }
} }

View File

@ -11,7 +11,6 @@ use crate::bot::arg_parse::{
add_z_position_argument, option_to_dim, option_to_i64, option_to_string, add_z_position_argument, option_to_dim, option_to_i64, option_to_string,
}; };
use crate::bot::commands::{BotCommand, CommandError}; use crate::bot::commands::{BotCommand, CommandError};
use crate::bot::formatters::display_loc;
use geoffrey_models::models::parameters::edit_params::EditParams; use geoffrey_models::models::parameters::edit_params::EditParams;
use serenity::builder::CreateApplicationCommand; use serenity::builder::CreateApplicationCommand;
@ -67,11 +66,7 @@ impl BotCommand for EditPosCommand {
Ok(Self::ApiParams::new(name, Some(position), None)) Ok(Self::ApiParams::new(name, Some(position), None))
} }
fn build_response(resp: Self::ApiResp) -> String { fn build_response(resp: Self::ApiResp, _: Self::ApiParams) -> String {
format!( format!("**{}** has been moved to {}", resp.name, resp.position)
"**{}** has been updated:\n{}",
resp.name,
display_loc(&resp)
)
} }
} }

View File

@ -50,7 +50,7 @@ impl BotCommand for FindCommand {
Ok(FindParams::new(query)) Ok(FindParams::new(query))
} }
fn build_response(resp: Self::ApiResp) -> String { fn build_response(resp: Self::ApiResp, _: Self::ApiParams) -> String {
if resp.is_empty() { if resp.is_empty() {
"No locations match that query, try better next time ding dong".to_string() "No locations match that query, try better next time ding dong".to_string()
} else { } else {

View File

@ -60,7 +60,7 @@ impl BotCommand for InfoCommand {
Ok(Self::ApiParams::new(location_name)) Ok(Self::ApiParams::new(location_name))
} }
fn build_response(resp: Self::ApiResp) -> String { fn build_response(resp: Self::ApiResp, _: Self::ApiParams) -> String {
display_loc_full(&resp) display_loc_full(&resp)
} }
} }

View File

@ -26,6 +26,7 @@ pub mod find;
pub mod info; pub mod info;
pub mod register; pub mod register;
pub mod remove_item; pub mod remove_item;
pub mod report_out_of_stock;
pub mod restock; pub mod restock;
pub mod selling; pub mod selling;
pub mod set_portal; pub mod set_portal;
@ -176,13 +177,13 @@ pub trait BotCommand: Send + 'static {
let request = CommandRequest { let request = CommandRequest {
token: ctx.cfg.api.token.clone(), token: ctx.cfg.api.token.clone(),
user_id: Some(user_id), user_id: Some(user_id),
params: args, params: args.clone(),
}; };
let resp = Self::run_api_query(ctx, request).await?; let resp = Self::run_api_query(ctx, request).await?;
match resp { match resp {
APIResponse::Response(resp) => Ok(Self::build_response(resp)), APIResponse::Response(resp) => Ok(Self::build_response(resp, args)),
APIResponse::Error { error: err, .. } => Err(CommandError::GeoffreyApi(err)), APIResponse::Error { error: err, .. } => Err(CommandError::GeoffreyApi(err)),
} }
} }
@ -198,5 +199,5 @@ pub trait BotCommand: Send + 'static {
} }
} }
fn build_response(resp: Self::ApiResp) -> String; fn build_response(resp: Self::ApiResp, req: Self::ApiParams) -> String;
} }

View File

@ -68,7 +68,7 @@ impl BotCommand for RegisterCommand {
Ok(register) Ok(register)
} }
fn build_response(resp: Self::ApiResp) -> String { fn build_response(resp: Self::ApiResp, _: Self::ApiParams) -> String {
format!( format!(
"**{}**, you have been registered for the Geoffrey bot!", "**{}**, you have been registered for the Geoffrey bot!",
resp.name resp.name

View File

@ -9,7 +9,6 @@ use geoffrey_models::models::parameters::item_command_params::ItemCommandParams;
use crate::bot::arg_parse::option_to_string; use crate::bot::arg_parse::option_to_string;
use crate::bot::commands::{BotCommand, CommandError}; use crate::bot::commands::{BotCommand, CommandError};
use crate::bot::formatters::display_loc_full;
use crate::bot::lang::PLAYER_DOES_NOT_HAVE_MATCHING_SHOP; use crate::bot::lang::PLAYER_DOES_NOT_HAVE_MATCHING_SHOP;
use geoffrey_models::models::response::api_error::GeoffreyAPIError; use geoffrey_models::models::response::api_error::GeoffreyAPIError;
use serenity::builder::CreateApplicationCommand; use serenity::builder::CreateApplicationCommand;
@ -69,11 +68,10 @@ impl BotCommand for RemoveItemCommand {
)) ))
} }
fn build_response(resp: Self::ApiResp) -> String { fn build_response(resp: Self::ApiResp, args: Self::ApiParams) -> String {
format!( format!(
"**{}** has been updated:\n{}", "**{}** has been removed from **{}**",
resp.name, args.item_name, resp.name
display_loc_full(&resp)
) )
} }
} }

View File

@ -0,0 +1,77 @@
use async_trait::async_trait;
use reqwest::Method;
use serenity::model::interactions::application_command::{
ApplicationCommandInteraction, ApplicationCommandOptionType,
};
use geoffrey_models::models::locations::Location;
use crate::bot::arg_parse::option_to_string;
use crate::bot::commands::{BotCommand, CommandError};
use crate::bot::lang::NO_LOCATION_FOUND;
use geoffrey_models::models::parameters::item_command_params::ItemCommandParams;
use geoffrey_models::models::response::api_error::GeoffreyAPIError;
use serenity::builder::CreateApplicationCommand;
pub struct ReportOutOfStockCommand;
#[async_trait]
impl BotCommand for ReportOutOfStockCommand {
type ApiParams = ItemCommandParams;
type ApiResp = Location;
fn command_name() -> String {
"report_out_of_stock".to_string()
}
fn request_type() -> Method {
Method::POST
}
fn custom_err_resp(e: &CommandError) -> Option<String> {
match e {
CommandError::GeoffreyApi(GeoffreyAPIError::EntryNotFound) => {
Some(NO_LOCATION_FOUND.to_string())
}
_ => None,
}
}
fn create_app_command(command: &mut CreateApplicationCommand) -> &mut CreateApplicationCommand {
command
.name(Self::command_name())
.description("Report an item as out stock ")
.create_option(|option| {
option
.name("shop_name")
.description("Shop to report the item missing att")
.kind(ApplicationCommandOptionType::String)
.required(true)
})
.create_option(|option| {
option
.name("item_name")
.description("Item to report out of stock")
.kind(ApplicationCommandOptionType::String)
.required(true)
})
}
async fn process_arguments(
command_interaction: ApplicationCommandInteraction,
) -> Result<Self::ApiParams, CommandError> {
let options = command_interaction.data.options;
Ok(Self::ApiParams::new(
option_to_string(options.get(0), "shop_name")?,
option_to_string(options.get(1), "item_name")?,
))
}
fn build_response(resp: Self::ApiResp, args: Self::ApiParams) -> String {
format!(
"**{}** has been reported out of stock at {}",
args.item_name, resp.name
)
}
}

View File

@ -8,7 +8,6 @@ use geoffrey_models::models::locations::Location;
use crate::bot::arg_parse::option_to_string; use crate::bot::arg_parse::option_to_string;
use crate::bot::commands::{BotCommand, CommandError}; use crate::bot::commands::{BotCommand, CommandError};
use crate::bot::formatters::display_loc_full;
use crate::bot::lang::PLAYER_DOES_NOT_HAVE_MATCHING_SHOP; use crate::bot::lang::PLAYER_DOES_NOT_HAVE_MATCHING_SHOP;
use geoffrey_models::models::parameters::item_command_params::ItemCommandParams; use geoffrey_models::models::parameters::item_command_params::ItemCommandParams;
use geoffrey_models::models::response::api_error::GeoffreyAPIError; use geoffrey_models::models::response::api_error::GeoffreyAPIError;
@ -69,11 +68,10 @@ impl BotCommand for RestockCommand {
)) ))
} }
fn build_response(resp: Self::ApiResp) -> String { fn build_response(resp: Self::ApiResp, args: Self::ApiParams) -> String {
format!( format!(
"**{}** has been updated:\n{}", "**{}** has been restocked at **{}**",
resp.name, args.item_name, resp.name
display_loc_full(&resp)
) )
} }
} }

View File

@ -11,6 +11,7 @@ use geoffrey_models::models::response::selling_listing::SellingListing;
use crate::bot::arg_parse::{option_to_order, option_to_sort, option_to_string}; use crate::bot::arg_parse::{option_to_order, option_to_sort, option_to_string};
use crate::bot::commands::{BotCommand, CommandError}; use crate::bot::commands::{BotCommand, CommandError};
use crate::bot::formatters::display_item_listing;
use serenity::builder::CreateApplicationCommand; use serenity::builder::CreateApplicationCommand;
pub struct SellingCommand; pub struct SellingCommand;
@ -70,19 +71,17 @@ impl BotCommand for SellingCommand {
Ok(SellingParams::new(query, sort, order)) Ok(SellingParams::new(query, sort, order))
} }
fn build_response(resp: Self::ApiResp) -> String { fn build_response(resp: Self::ApiResp, args: Self::ApiParams) -> String {
if resp.is_empty() { if resp.is_empty() {
"No shops were found selling that, maybe I should start selling it...".to_string() "No shops were found selling that, maybe I should start selling it...".to_string()
} else { } else {
let mut resp_str = String::new(); let mut resp_str = String::new();
writeln!(resp_str, "The following items match:").unwrap(); writeln!(resp_str, "The following items match \"{}\":", args.query).unwrap();
for item in resp { for item in resp {
writeln!( writeln!(
resp_str, resp_str,
"**{}**, {} for {}D: {} {}", "{} @ {} {}",
item.listing.item.name, display_item_listing(&item.listing),
item.listing.count_per_price,
item.listing.price,
item.shop_name, item.shop_name,
item.shop_loc item.shop_loc
) )

View File

@ -8,7 +8,6 @@ use serenity::model::interactions::application_command::{
use crate::bot::arg_parse::{option_to_i64, option_to_string}; use crate::bot::arg_parse::{option_to_i64, option_to_string};
use crate::bot::commands::{BotCommand, CommandError}; use crate::bot::commands::{BotCommand, CommandError};
use crate::bot::formatters::display_loc;
use crate::bot::lang::PLAYER_DOES_NOT_HAVE_MATCHING_LOC; use crate::bot::lang::PLAYER_DOES_NOT_HAVE_MATCHING_LOC;
use geoffrey_models::models::parameters::set_portal_params::SetPortalParams; use geoffrey_models::models::parameters::set_portal_params::SetPortalParams;
use geoffrey_models::models::response::api_error::GeoffreyAPIError; use geoffrey_models::models::response::api_error::GeoffreyAPIError;
@ -82,11 +81,19 @@ impl BotCommand for SetPortalCommand {
Ok(Self::ApiParams::new(loc_name, portal)) Ok(Self::ApiParams::new(loc_name, portal))
} }
fn build_response(resp: Self::ApiResp) -> String { fn build_response(resp: Self::ApiResp, _: Self::ApiParams) -> String {
let portal = match resp.portal {
None => return "Portal could not be set, try again!".to_string(),
Some(p) => p,
};
format!( format!(
"**{}** has been updated:\n{}", "**{}** has had its portal set to {} {} (x={}, z={})",
resp.name, resp.name,
display_loc(&resp) portal.direction(),
portal.tunnel_addr(),
portal.x,
portal.z
) )
} }
} }

View File

@ -67,10 +67,16 @@ pub fn display_item_listing(listing: &ItemListing) -> String {
format!("{} days ago", stocked_diff.num_days()) format!("{} days ago", stocked_diff.num_days())
}; };
format!( let item_listing = format!(
"**{}**, {} for {}D. Restocked {}.", "**{}**, {} for {}D. Restocked {}.",
listing.item.name, listing.count_per_price, listing.price, time_str listing.item.name, listing.count_per_price, listing.price, time_str
) );
if listing.is_out_of_stock(1) {
format!("~~{}~~", item_listing)
} else {
item_listing
}
} }
pub fn display_loc_full(loc: &Location) -> String { pub fn display_loc_full(loc: &Location) -> String {

View File

@ -7,6 +7,7 @@ use crate::bot::commands::edit_pos::EditPosCommand;
use crate::bot::commands::info::InfoCommand; use crate::bot::commands::info::InfoCommand;
use crate::bot::commands::register::RegisterCommand; use crate::bot::commands::register::RegisterCommand;
use crate::bot::commands::remove_item::RemoveItemCommand; use crate::bot::commands::remove_item::RemoveItemCommand;
use crate::bot::commands::report_out_of_stock::ReportOutOfStockCommand;
use crate::bot::commands::restock::RestockCommand; use crate::bot::commands::restock::RestockCommand;
use crate::bot::commands::GeoffreyCommandFn; use crate::bot::commands::GeoffreyCommandFn;
use crate::context::GeoffreyContext; use crate::context::GeoffreyContext;
@ -104,6 +105,8 @@ pub async fn build_commands(
.add_command::<InfoCommand>(ctx) .add_command::<InfoCommand>(ctx)
.await? .await?
.add_command::<RestockCommand>(ctx) .add_command::<RestockCommand>(ctx)
.await?
.add_command::<ReportOutOfStockCommand>(ctx)
.await?; .await?;
Ok(()) Ok(())

View File

@ -105,7 +105,7 @@ impl EventHandler for Handler {
.interaction_response_data(|message| message.content(msg)) .interaction_response_data(|message| message.content(msg))
}) })
.await .await
.unwrap(); .unwrap()
} else if let Interaction::Autocomplete(auto_complete) = interaction { } else if let Interaction::Autocomplete(auto_complete) = interaction {
auto_complete auto_complete
.create_autocomplete_response(&ctx.http, |resp| resp) .create_autocomplete_response(&ctx.http, |resp| resp)

View File

@ -101,7 +101,16 @@ impl Database {
Ok(tree.iter().filter_map(move |e| { Ok(tree.iter().filter_map(move |e| {
if let Ok((id, data)) = e { if let Ok((id, data)) = e {
let id = u64::from_be_bytes(id.to_vec().try_into().unwrap()); let id = u64::from_be_bytes(id.to_vec().try_into().unwrap());
let data = T::try_from_bytes(&data).unwrap(); let data = match T::try_from_bytes(&data) {
Ok(data) => data,
Err(err) => {
log::debug!(
"Invalid data: {}",
String::from_utf8(data.to_vec()).unwrap_or_default()
);
panic!("Unable to parse {} model from bytes: {}", T::tree(), err);
}
};
if f(id, &data) { if f(id, &data) {
Some(data) Some(data)

View File

@ -13,8 +13,10 @@ impl Migration for OutOfStockVoting {
let (id, loc_ivec) = entry?; let (id, loc_ivec) = entry?;
let mut loc = json::parse(std::str::from_utf8(&loc_ivec).unwrap()).unwrap(); let mut loc = json::parse(std::str::from_utf8(&loc_ivec).unwrap()).unwrap();
for item in loc["loc_data"]["Shop"]["item_listings"].members_mut() { if !loc["loc_data"]["shop"].is_empty() {
item["out_of_stock_votes"] = json::JsonValue::Array(Vec::new()); for item in loc["loc_data"]["Shop"]["item_listings"].members_mut() {
item["out_of_stock_votes"] = json::JsonValue::Array(Vec::new());
}
} }
loc_tree.insert(id, loc.to_string().as_bytes()).unwrap(); loc_tree.insert(id, loc.to_string().as_bytes()).unwrap();
@ -30,8 +32,10 @@ impl Migration for OutOfStockVoting {
let (id, loc_ivec) = entry?; let (id, loc_ivec) = entry?;
let mut loc = json::parse(std::str::from_utf8(&loc_ivec).unwrap()).unwrap(); let mut loc = json::parse(std::str::from_utf8(&loc_ivec).unwrap()).unwrap();
for item in &mut loc["loc_data"]["Shop"]["item_listings"].members_mut() { if !loc["loc_data"]["shop"].is_empty() {
item["out_of_stock_votes"].clear() for item in &mut loc["loc_data"]["Shop"]["item_listings"].members_mut() {
item["out_of_stock_votes"].clear()
}
} }
loc_tree.insert(id, loc.to_string().as_bytes()).unwrap(); loc_tree.insert(id, loc.to_string().as_bytes()).unwrap();

View File

@ -64,7 +64,7 @@ impl ItemListing {
} }
pub fn is_out_of_stock(&self, report_limit: u32) -> bool { pub fn is_out_of_stock(&self, report_limit: u32) -> bool {
self.out_of_stock_votes.len() > report_limit as usize self.out_of_stock_votes.len() >= report_limit as usize
} }
pub fn restock(&mut self) { pub fn restock(&mut self) {