Tweak discord formatting
ci/woodpecker/push/woodpecker Pipeline was successful
Details
ci/woodpecker/push/woodpecker Pipeline was successful
Details
+ Created Formatter to handle geoffrey formatting + using Serenity's discord message builder to help with formatting + Added message sanitation + Clippy + Fmtmain
parent
a8f5f5d87b
commit
5fcb021fe0
|
@ -11,10 +11,11 @@ use geoffrey_models::models::response::api_error::GeoffreyAPIError;
|
||||||
|
|
||||||
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;
|
use crate::bot::commands::BotCommand;
|
||||||
use crate::bot::formatters::display_loc_full;
|
use crate::bot::formatters::GeoffreyFormatter;
|
||||||
use crate::bot::lang::{PLAYER_ALREADY_SELLS_ITEM, PLAYER_DOES_NOT_HAVE_MATCHING_SHOP};
|
use crate::bot::lang::{PLAYER_ALREADY_SELLS_ITEM, PLAYER_DOES_NOT_HAVE_MATCHING_SHOP};
|
||||||
use crate::context::GeoffreyContext;
|
use crate::context::GeoffreyContext;
|
||||||
use crate::error::BotError;
|
use crate::error::BotError;
|
||||||
|
use serenity::utils::MessageBuilder;
|
||||||
|
|
||||||
pub struct AddItemCommand;
|
pub struct AddItemCommand;
|
||||||
|
|
||||||
|
@ -93,11 +94,15 @@ impl BotCommand for AddItemCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_response(ctx: &GeoffreyContext, resp: Self::ApiResp, req: Self::ApiParams) -> String {
|
fn build_response(ctx: &GeoffreyContext, resp: Self::ApiResp, req: Self::ApiParams) -> String {
|
||||||
format!(
|
GeoffreyFormatter::new(ctx.settings.clone())
|
||||||
"**{}** has been added to {} :\n{}",
|
.push(
|
||||||
req.item_name,
|
&MessageBuilder::new()
|
||||||
resp.name,
|
.push_bold_safe(req.item_name)
|
||||||
display_loc_full(&resp, &ctx.settings)
|
.push(" has been added to ")
|
||||||
)
|
.push_line(&resp.name)
|
||||||
|
.build(),
|
||||||
|
)
|
||||||
|
.push_loc_full(&resp)
|
||||||
|
.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,9 +14,10 @@ use crate::bot::arg_parse::{
|
||||||
add_z_position_argument, option_to_dim, option_to_i64, option_to_loc_type, option_to_string,
|
add_z_position_argument, option_to_dim, option_to_i64, option_to_loc_type, option_to_string,
|
||||||
};
|
};
|
||||||
use crate::bot::commands::BotCommand;
|
use crate::bot::commands::BotCommand;
|
||||||
use crate::bot::formatters::display_loc_full;
|
use crate::bot::formatters::GeoffreyFormatter;
|
||||||
use crate::context::GeoffreyContext;
|
use crate::context::GeoffreyContext;
|
||||||
use crate::error::BotError;
|
use crate::error::BotError;
|
||||||
|
use serenity::utils::MessageBuilder;
|
||||||
|
|
||||||
pub struct AddLocationCommand;
|
pub struct AddLocationCommand;
|
||||||
|
|
||||||
|
@ -80,10 +81,14 @@ impl BotCommand for AddLocationCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_response(ctx: &GeoffreyContext, resp: Self::ApiResp, _: Self::ApiParams) -> String {
|
fn build_response(ctx: &GeoffreyContext, resp: Self::ApiResp, _: Self::ApiParams) -> String {
|
||||||
format!(
|
GeoffreyFormatter::new(ctx.settings.clone())
|
||||||
"**{}** has been added to Geoffrey:\n{}",
|
.push(
|
||||||
resp.name,
|
&MessageBuilder::new()
|
||||||
display_loc_full(&resp, &ctx.settings)
|
.push_bold_safe(&resp.name)
|
||||||
)
|
.push_line(" has been added to geoffrey:")
|
||||||
|
.build(),
|
||||||
|
)
|
||||||
|
.push_loc_full(&resp)
|
||||||
|
.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ use crate::bot::commands::BotCommand;
|
||||||
use crate::bot::lang::PLAYER_DOES_NOT_HAVE_MATCHING_LOC;
|
use crate::bot::lang::PLAYER_DOES_NOT_HAVE_MATCHING_LOC;
|
||||||
use crate::context::GeoffreyContext;
|
use crate::context::GeoffreyContext;
|
||||||
use crate::error::BotError;
|
use crate::error::BotError;
|
||||||
|
use serenity::utils::MessageBuilder;
|
||||||
|
|
||||||
pub struct DeleteCommand;
|
pub struct DeleteCommand;
|
||||||
|
|
||||||
|
@ -62,9 +63,9 @@ impl BotCommand for DeleteCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_response(_: &GeoffreyContext, resp: Self::ApiResp, _: Self::ApiParams) -> String {
|
fn build_response(_: &GeoffreyContext, resp: Self::ApiResp, _: Self::ApiParams) -> String {
|
||||||
format!(
|
MessageBuilder::new()
|
||||||
"**{}** has been been removed from Geoffrey, good riddance!",
|
.push_bold_safe(resp.name)
|
||||||
resp.name
|
.push(" has been removed from Geoffrey, good riddance!")
|
||||||
)
|
.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ use crate::bot::arg_parse::option_to_string;
|
||||||
use crate::bot::commands::BotCommand;
|
use crate::bot::commands::BotCommand;
|
||||||
use crate::context::GeoffreyContext;
|
use crate::context::GeoffreyContext;
|
||||||
use crate::error::BotError;
|
use crate::error::BotError;
|
||||||
|
use serenity::utils::MessageBuilder;
|
||||||
|
|
||||||
//TODO: Combine edit commands into one class once I figure out why subcommand are not working
|
//TODO: Combine edit commands into one class once I figure out why subcommand are not working
|
||||||
pub struct EditNameCommand;
|
pub struct EditNameCommand;
|
||||||
|
@ -63,6 +64,11 @@ impl BotCommand for EditNameCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_response(_: &GeoffreyContext, resp: Self::ApiResp, args: Self::ApiParams) -> String {
|
fn build_response(_: &GeoffreyContext, resp: Self::ApiResp, args: Self::ApiParams) -> String {
|
||||||
format!("**{}** has been renamed to {}", args.loc_name, resp.name,)
|
MessageBuilder::new()
|
||||||
|
.push_bold_safe(&args.loc_name)
|
||||||
|
.push(" has been renamed to ")
|
||||||
|
.push_bold_safe(&resp.name)
|
||||||
|
.push(".")
|
||||||
|
.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ use crate::bot::arg_parse::{
|
||||||
use crate::bot::commands::BotCommand;
|
use crate::bot::commands::BotCommand;
|
||||||
use crate::context::GeoffreyContext;
|
use crate::context::GeoffreyContext;
|
||||||
use crate::error::BotError;
|
use crate::error::BotError;
|
||||||
|
use serenity::utils::MessageBuilder;
|
||||||
|
|
||||||
//TODO: Combine edit commands into one class once I figure out why subcommand are not working
|
//TODO: Combine edit commands into one class once I figure out why subcommand are not working
|
||||||
pub struct EditPosCommand;
|
pub struct EditPosCommand;
|
||||||
|
@ -70,6 +71,11 @@ impl BotCommand for EditPosCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_response(_: &GeoffreyContext, resp: Self::ApiResp, _: Self::ApiParams) -> String {
|
fn build_response(_: &GeoffreyContext, resp: Self::ApiResp, _: Self::ApiParams) -> String {
|
||||||
format!("**{}** has been moved to {}", resp.name, resp.position)
|
MessageBuilder::new()
|
||||||
|
.push_bold_safe(resp.name)
|
||||||
|
.push(" has been moved to ")
|
||||||
|
.push_bold_safe(&resp.position)
|
||||||
|
.push(".")
|
||||||
|
.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use std::fmt::Write;
|
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use reqwest::Method;
|
use reqwest::Method;
|
||||||
use serenity::builder::CreateApplicationCommand;
|
use serenity::builder::CreateApplicationCommand;
|
||||||
|
@ -12,7 +10,7 @@ use geoffrey_models::models::parameters::find_params::FindParams;
|
||||||
|
|
||||||
use crate::bot::arg_parse::option_to_string;
|
use crate::bot::arg_parse::option_to_string;
|
||||||
use crate::bot::commands::BotCommand;
|
use crate::bot::commands::BotCommand;
|
||||||
use crate::bot::formatters::display_loc;
|
use crate::bot::formatters::GeoffreyFormatter;
|
||||||
use crate::context::GeoffreyContext;
|
use crate::context::GeoffreyContext;
|
||||||
use crate::error::BotError;
|
use crate::error::BotError;
|
||||||
|
|
||||||
|
@ -53,16 +51,26 @@ impl BotCommand for FindCommand {
|
||||||
Ok(FindParams::new(query))
|
Ok(FindParams::new(query))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_response(ctx: &GeoffreyContext, resp: Self::ApiResp, _: Self::ApiParams) -> String {
|
fn build_response(
|
||||||
|
ctx: &GeoffreyContext,
|
||||||
|
resp: Self::ApiResp,
|
||||||
|
params: 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 {
|
||||||
let mut resp_str = String::new();
|
let mut formatter = GeoffreyFormatter::new(ctx.settings.clone());
|
||||||
writeln!(resp_str, "The following locations match:").unwrap();
|
|
||||||
for loc in resp {
|
formatter
|
||||||
writeln!(resp_str, "{}", display_loc(&loc, &ctx.settings)).unwrap();
|
.push("The following locations match '")
|
||||||
|
.push(¶ms.query)
|
||||||
|
.push("'");
|
||||||
|
|
||||||
|
for loc in &resp {
|
||||||
|
formatter.push_loc(loc).push_new_line().push_new_line();
|
||||||
}
|
}
|
||||||
resp_str
|
|
||||||
|
formatter.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ use geoffrey_models::models::response::api_error::GeoffreyAPIError;
|
||||||
|
|
||||||
use crate::bot::arg_parse::option_to_string;
|
use crate::bot::arg_parse::option_to_string;
|
||||||
use crate::bot::commands::BotCommand;
|
use crate::bot::commands::BotCommand;
|
||||||
use crate::bot::formatters::display_loc_full;
|
use crate::bot::formatters::GeoffreyFormatter;
|
||||||
use crate::bot::lang::NO_LOCATION_FOUND;
|
use crate::bot::lang::NO_LOCATION_FOUND;
|
||||||
use crate::context::GeoffreyContext;
|
use crate::context::GeoffreyContext;
|
||||||
use crate::error::BotError;
|
use crate::error::BotError;
|
||||||
|
@ -63,6 +63,8 @@ impl BotCommand for InfoCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_response(ctx: &GeoffreyContext, resp: Self::ApiResp, _: Self::ApiParams) -> String {
|
fn build_response(ctx: &GeoffreyContext, resp: Self::ApiResp, _: Self::ApiParams) -> String {
|
||||||
display_loc_full(&resp, &ctx.settings)
|
GeoffreyFormatter::new(ctx.settings.clone())
|
||||||
|
.push_loc_full(&resp)
|
||||||
|
.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ use crate::bot::commands::BotCommand;
|
||||||
use crate::bot::lang::ACCOUNT_LINK_INVALID;
|
use crate::bot::lang::ACCOUNT_LINK_INVALID;
|
||||||
use crate::context::GeoffreyContext;
|
use crate::context::GeoffreyContext;
|
||||||
use crate::error::BotError;
|
use crate::error::BotError;
|
||||||
|
use serenity::utils::MessageBuilder;
|
||||||
|
|
||||||
pub struct RegisterCommand;
|
pub struct RegisterCommand;
|
||||||
|
|
||||||
|
@ -72,9 +73,9 @@ impl BotCommand for RegisterCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_response(_: &GeoffreyContext, resp: Self::ApiResp, _: Self::ApiParams) -> String {
|
fn build_response(_: &GeoffreyContext, resp: Self::ApiResp, _: Self::ApiParams) -> String {
|
||||||
format!(
|
MessageBuilder::new()
|
||||||
"**{}**, you have been registered for the Geoffrey bot!",
|
.push_bold_safe(resp.name)
|
||||||
resp.name
|
.push_line(", you have been registered for the Geoffrey bot!")
|
||||||
)
|
.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ use crate::bot::commands::BotCommand;
|
||||||
use crate::bot::lang::PLAYER_DOES_NOT_HAVE_MATCHING_SHOP;
|
use crate::bot::lang::PLAYER_DOES_NOT_HAVE_MATCHING_SHOP;
|
||||||
use crate::context::GeoffreyContext;
|
use crate::context::GeoffreyContext;
|
||||||
use crate::error::BotError;
|
use crate::error::BotError;
|
||||||
|
use serenity::utils::MessageBuilder;
|
||||||
|
|
||||||
pub struct RemoveItemCommand;
|
pub struct RemoveItemCommand;
|
||||||
|
|
||||||
|
@ -71,9 +72,11 @@ impl BotCommand for RemoveItemCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_response(_: &GeoffreyContext, resp: Self::ApiResp, args: Self::ApiParams) -> String {
|
fn build_response(_: &GeoffreyContext, resp: Self::ApiResp, args: Self::ApiParams) -> String {
|
||||||
format!(
|
MessageBuilder::new()
|
||||||
"**{}** has been removed from **{}**",
|
.push_bold_safe(&args.item_name)
|
||||||
args.item_name, resp.name
|
.push(" has been removed from ")
|
||||||
)
|
.push_bold_safe(resp.name)
|
||||||
|
.push_line("")
|
||||||
|
.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ use crate::bot::commands::BotCommand;
|
||||||
use crate::bot::lang::NO_LOCATION_FOUND;
|
use crate::bot::lang::NO_LOCATION_FOUND;
|
||||||
use crate::context::GeoffreyContext;
|
use crate::context::GeoffreyContext;
|
||||||
use crate::error::BotError;
|
use crate::error::BotError;
|
||||||
|
use serenity::utils::MessageBuilder;
|
||||||
|
|
||||||
pub struct ReportOutOfStockCommand;
|
pub struct ReportOutOfStockCommand;
|
||||||
|
|
||||||
|
@ -71,9 +72,11 @@ impl BotCommand for ReportOutOfStockCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_response(_: &GeoffreyContext, resp: Self::ApiResp, args: Self::ApiParams) -> String {
|
fn build_response(_: &GeoffreyContext, resp: Self::ApiResp, args: Self::ApiParams) -> String {
|
||||||
format!(
|
MessageBuilder::new()
|
||||||
"**{}** has been reported out of stock at {}",
|
.push_bold_safe(&args.item_name)
|
||||||
args.item_name, resp.name
|
.push(" has been reported out of stock at ")
|
||||||
)
|
.push_bold_safe(resp.name)
|
||||||
|
.push_line("")
|
||||||
|
.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ use crate::bot::commands::BotCommand;
|
||||||
use crate::bot::lang::PLAYER_DOES_NOT_HAVE_MATCHING_SHOP;
|
use crate::bot::lang::PLAYER_DOES_NOT_HAVE_MATCHING_SHOP;
|
||||||
use crate::context::GeoffreyContext;
|
use crate::context::GeoffreyContext;
|
||||||
use crate::error::BotError;
|
use crate::error::BotError;
|
||||||
|
use serenity::utils::MessageBuilder;
|
||||||
|
|
||||||
pub struct RestockCommand;
|
pub struct RestockCommand;
|
||||||
|
|
||||||
|
@ -71,9 +72,11 @@ impl BotCommand for RestockCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_response(_: &GeoffreyContext, resp: Self::ApiResp, args: Self::ApiParams) -> String {
|
fn build_response(_: &GeoffreyContext, resp: Self::ApiResp, args: Self::ApiParams) -> String {
|
||||||
format!(
|
MessageBuilder::new()
|
||||||
"**{}** has been restocked at **{}**",
|
.push_bold_safe(&args.item_name)
|
||||||
args.item_name, resp.name
|
.push(" has been restocked at ")
|
||||||
)
|
.push_bold_safe(resp.name)
|
||||||
|
.push_line("")
|
||||||
|
.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use std::fmt::Write;
|
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use reqwest::Method;
|
use reqwest::Method;
|
||||||
use serenity::builder::CreateApplicationCommand;
|
use serenity::builder::CreateApplicationCommand;
|
||||||
|
@ -12,9 +10,10 @@ 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;
|
use crate::bot::commands::BotCommand;
|
||||||
use crate::bot::formatters::display_item_listing;
|
use crate::bot::formatters::GeoffreyFormatter;
|
||||||
use crate::context::GeoffreyContext;
|
use crate::context::GeoffreyContext;
|
||||||
use crate::error::BotError;
|
use crate::error::BotError;
|
||||||
|
use serenity::utils::MessageBuilder;
|
||||||
|
|
||||||
pub struct SellingCommand;
|
pub struct SellingCommand;
|
||||||
|
|
||||||
|
@ -73,23 +72,31 @@ impl BotCommand for SellingCommand {
|
||||||
Ok(SellingParams::new(query, sort, order))
|
Ok(SellingParams::new(query, sort, order))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_response(_: &GeoffreyContext, resp: Self::ApiResp, args: Self::ApiParams) -> String {
|
fn build_response(ctx: &GeoffreyContext, 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 formatter = GeoffreyFormatter::new(ctx.settings.clone());
|
||||||
writeln!(resp_str, "The following items match \"{}\":", args.query).unwrap();
|
|
||||||
|
formatter.push(
|
||||||
|
&MessageBuilder::new()
|
||||||
|
.push("The following items match '")
|
||||||
|
.push_bold_safe(args.query)
|
||||||
|
.push_line("':")
|
||||||
|
.build(),
|
||||||
|
);
|
||||||
|
|
||||||
for item in resp {
|
for item in resp {
|
||||||
writeln!(
|
formatter
|
||||||
resp_str,
|
.push_item_listing(&item.listing)
|
||||||
"{} @ {} {}",
|
.push(" @ ")
|
||||||
display_item_listing(&item.listing),
|
.push(&item.shop_name)
|
||||||
item.shop_name,
|
.push(" ")
|
||||||
item.shop_loc
|
.push(&item.shop_loc.to_string())
|
||||||
)
|
.push_new_line();
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
resp_str
|
|
||||||
|
formatter.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ use crate::bot::commands::BotCommand;
|
||||||
use crate::bot::lang::PLAYER_DOES_NOT_HAVE_MATCHING_LOC;
|
use crate::bot::lang::PLAYER_DOES_NOT_HAVE_MATCHING_LOC;
|
||||||
use crate::context::GeoffreyContext;
|
use crate::context::GeoffreyContext;
|
||||||
use crate::error::BotError;
|
use crate::error::BotError;
|
||||||
|
use serenity::utils::MessageBuilder;
|
||||||
|
|
||||||
pub struct SetPortalCommand;
|
pub struct SetPortalCommand;
|
||||||
|
|
||||||
|
@ -90,13 +91,17 @@ impl BotCommand for SetPortalCommand {
|
||||||
Some(p) => p,
|
Some(p) => p,
|
||||||
};
|
};
|
||||||
|
|
||||||
format!(
|
MessageBuilder::new()
|
||||||
"**{}** has had its portal set to {} {} (x={}, z={})",
|
.push_bold_safe(&resp.name)
|
||||||
resp.name,
|
.push(format!(
|
||||||
portal.direction(),
|
" has had its portal set to {} {} (x={}, z={})",
|
||||||
portal.tunnel_addr(),
|
portal.direction(),
|
||||||
portal.x,
|
portal.tunnel_addr(),
|
||||||
portal.z
|
portal.x,
|
||||||
)
|
portal.z
|
||||||
|
))
|
||||||
|
.push_bold_safe(resp.name)
|
||||||
|
.push_line("")
|
||||||
|
.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,100 +4,163 @@ use geoffrey_models::models::locations::{Location, LocationData};
|
||||||
use geoffrey_models::models::player::Player;
|
use geoffrey_models::models::player::Player;
|
||||||
use geoffrey_models::models::settings::GeoffreySettings;
|
use geoffrey_models::models::settings::GeoffreySettings;
|
||||||
use geoffrey_models::models::Portal;
|
use geoffrey_models::models::Portal;
|
||||||
|
use serenity::client::Cache;
|
||||||
|
use serenity::utils::{content_safe, ContentSafeOptions, MessageBuilder};
|
||||||
|
|
||||||
pub fn display_owners(owners: &[Player], settings: &GeoffreySettings) -> String {
|
pub struct GeoffreyFormatter {
|
||||||
let mut plural = "";
|
msg: String,
|
||||||
let mut ellipses = "";
|
settings: GeoffreySettings,
|
||||||
|
|
||||||
if owners.len() > 1 {
|
|
||||||
plural = "s"
|
|
||||||
}
|
|
||||||
|
|
||||||
let range = if owners.len() > settings.max_owners_to_display as usize {
|
|
||||||
ellipses = "...";
|
|
||||||
settings.max_owners_to_display as usize
|
|
||||||
} else {
|
|
||||||
owners.len()
|
|
||||||
};
|
|
||||||
|
|
||||||
format!(
|
|
||||||
"Owner{}: {}{}",
|
|
||||||
plural,
|
|
||||||
owners[0..range]
|
|
||||||
.iter()
|
|
||||||
.map(|owner| owner.name.clone())
|
|
||||||
.collect::<Vec<String>>()
|
|
||||||
.join(", "),
|
|
||||||
ellipses
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn display_portal(portal: &Portal) -> String {
|
impl GeoffreyFormatter {
|
||||||
format!(
|
pub fn new(settings: GeoffreySettings) -> Self {
|
||||||
"Portal: {} {} (x={}, z={})",
|
Self {
|
||||||
portal.direction(),
|
msg: String::new(),
|
||||||
portal.tunnel_addr(),
|
settings,
|
||||||
portal.x,
|
|
||||||
portal.z
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn display_loc(loc: &Location, settings: &GeoffreySettings) -> String {
|
|
||||||
let portal_str = match &loc.portal {
|
|
||||||
None => "".to_string(),
|
|
||||||
Some(p) => format!("{}, ", display_portal(p)),
|
|
||||||
};
|
|
||||||
|
|
||||||
format!(
|
|
||||||
"**{}**, {}, {}{}",
|
|
||||||
loc.name,
|
|
||||||
loc.position,
|
|
||||||
portal_str,
|
|
||||||
display_owners(&loc.owners, settings),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn display_item_listing(listing: &ItemListing) -> String {
|
|
||||||
let stocked_diff = Utc::now() - listing.restocked_time;
|
|
||||||
|
|
||||||
let time_str = if stocked_diff < Duration::days(1) {
|
|
||||||
"today".to_string()
|
|
||||||
} else if stocked_diff < Duration::days(2) {
|
|
||||||
"1 day ago".to_string()
|
|
||||||
} else {
|
|
||||||
format!("{} days ago", stocked_diff.num_days())
|
|
||||||
};
|
|
||||||
|
|
||||||
let item_listing = format!(
|
|
||||||
"**{}**, {} for {}D. Restocked {}.",
|
|
||||||
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, settings: &GeoffreySettings) -> String {
|
|
||||||
let info = match &loc.loc_data {
|
|
||||||
LocationData::Shop(shop) => {
|
|
||||||
if !shop.item_listings.is_empty() {
|
|
||||||
format!(
|
|
||||||
"\n**Inventory**:\n{}",
|
|
||||||
shop.item_listings
|
|
||||||
.iter()
|
|
||||||
.map(display_item_listing)
|
|
||||||
.collect::<Vec<String>>()
|
|
||||||
.join("\n")
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
"".to_string()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => "".to_string(),
|
}
|
||||||
};
|
|
||||||
|
|
||||||
format!("{}\n{}", display_loc(loc, settings), info)
|
pub fn build(&mut self) -> String {
|
||||||
|
self.msg.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn push(&mut self, string: &str) -> &mut Self {
|
||||||
|
self.msg.push_str(string);
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn push_new_line(&mut self) -> &mut Self {
|
||||||
|
self.push("\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn push_owners(&mut self, owners: &[Player]) -> &mut Self {
|
||||||
|
let mut plural = "";
|
||||||
|
let mut ellipses = "";
|
||||||
|
|
||||||
|
if owners.len() > 1 {
|
||||||
|
plural = "s"
|
||||||
|
}
|
||||||
|
|
||||||
|
let range = if owners.len() > self.settings.max_owners_to_display as usize {
|
||||||
|
ellipses = "...";
|
||||||
|
self.settings.max_owners_to_display as usize
|
||||||
|
} else {
|
||||||
|
owners.len()
|
||||||
|
};
|
||||||
|
|
||||||
|
self.msg = MessageBuilder::new()
|
||||||
|
.push(self.msg.clone())
|
||||||
|
.push("Owner")
|
||||||
|
.push(plural)
|
||||||
|
.push(": ")
|
||||||
|
.push(
|
||||||
|
owners[0..range]
|
||||||
|
.iter()
|
||||||
|
.map(|owner| owner.name.clone())
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join(", "),
|
||||||
|
)
|
||||||
|
.push(ellipses)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn push_portal(&mut self, portal: &Portal) -> &mut Self {
|
||||||
|
self.push(&format!(
|
||||||
|
"Portal: {} {} (x={}, z={})",
|
||||||
|
portal.direction(),
|
||||||
|
portal.tunnel_addr(),
|
||||||
|
portal.x,
|
||||||
|
portal.z
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn push_loc(&mut self, loc: &Location) -> &mut Self {
|
||||||
|
self.push(
|
||||||
|
&MessageBuilder::new()
|
||||||
|
.push_bold_safe(&loc.name)
|
||||||
|
.push(", ")
|
||||||
|
.push(&loc.position)
|
||||||
|
.push(", ")
|
||||||
|
.build(),
|
||||||
|
);
|
||||||
|
|
||||||
|
match &loc.portal {
|
||||||
|
None => {}
|
||||||
|
Some(p) => {
|
||||||
|
self.push_portal(p).push(", ");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
self.push_owners(&loc.owners)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn push_item_listing(&mut self, listing: &ItemListing) -> &mut Self {
|
||||||
|
let stocked_diff = Utc::now() - listing.restocked_time;
|
||||||
|
|
||||||
|
let time_str = if stocked_diff < Duration::days(1) {
|
||||||
|
"today".to_string()
|
||||||
|
} else if stocked_diff < Duration::days(2) {
|
||||||
|
"1 day ago".to_string()
|
||||||
|
} else {
|
||||||
|
format!("{} days ago", stocked_diff.num_days())
|
||||||
|
};
|
||||||
|
|
||||||
|
let msg = MessageBuilder::new()
|
||||||
|
.push_bold_safe(&listing.item.name)
|
||||||
|
.push(", ")
|
||||||
|
.push(&listing.count_per_price)
|
||||||
|
.push(" for ")
|
||||||
|
.push(listing.price)
|
||||||
|
.push("D. Restocked ")
|
||||||
|
.push(time_str)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let msg = if listing.is_out_of_stock(self.settings.min_out_of_stock_votes) {
|
||||||
|
MessageBuilder::new().push_strike_safe(msg).to_string()
|
||||||
|
} else {
|
||||||
|
msg
|
||||||
|
};
|
||||||
|
|
||||||
|
self.push(&msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn push_loc_full(&mut self, loc: &Location) -> &mut Self {
|
||||||
|
self.push_loc(loc);
|
||||||
|
|
||||||
|
match &loc.loc_data {
|
||||||
|
LocationData::Shop(shop) => {
|
||||||
|
if !shop.item_listings.is_empty() {
|
||||||
|
self.push_new_line()
|
||||||
|
.push(&MessageBuilder::new().push_bold("Inventory:").to_string())
|
||||||
|
.push_new_line();
|
||||||
|
|
||||||
|
for listing in &shop.item_listings {
|
||||||
|
self.push_item_listing(listing).push_new_line();
|
||||||
|
}
|
||||||
|
|
||||||
|
self
|
||||||
|
} else {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => self,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn clean_message(cache: impl AsRef<Cache>, msg: &str) -> String {
|
||||||
|
content_safe(
|
||||||
|
cache,
|
||||||
|
msg,
|
||||||
|
&ContentSafeOptions::new()
|
||||||
|
.clean_channel(true)
|
||||||
|
.clean_user(true)
|
||||||
|
.clean_everyone(true)
|
||||||
|
.clean_here(true)
|
||||||
|
.clean_role(true),
|
||||||
|
)
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use reqwest::Method;
|
use reqwest::Method;
|
||||||
use serenity::utils::{content_safe, ContentSafeOptions};
|
|
||||||
use serenity::{
|
use serenity::{
|
||||||
async_trait,
|
async_trait,
|
||||||
model::{
|
model::{
|
||||||
|
@ -18,6 +17,7 @@ use geoffrey_models::models::player::UserID;
|
||||||
use geoffrey_models::models::settings::GeoffreySettings;
|
use geoffrey_models::models::settings::GeoffreySettings;
|
||||||
|
|
||||||
use crate::api::run_api_query;
|
use crate::api::run_api_query;
|
||||||
|
use crate::bot::formatters::clean_message;
|
||||||
use crate::bot::{build_commands, CommandRunner};
|
use crate::bot::{build_commands, CommandRunner};
|
||||||
use crate::configs::GeoffreyBotConfig;
|
use crate::configs::GeoffreyBotConfig;
|
||||||
use crate::context::GeoffreyContext;
|
use crate::context::GeoffreyContext;
|
||||||
|
@ -128,15 +128,13 @@ impl EventHandler for Handler {
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(msg) => msg,
|
Ok(msg) => clean_message(ctx.cache, &msg).await,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::warn!("Error running command '{}': {:?}", command_name, e);
|
log::warn!("Error running command '{}': {:?}", command_name, e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let msg = content_safe(&ctx.cache, &msg, &ContentSafeOptions::default()).await;
|
|
||||||
|
|
||||||
command
|
command
|
||||||
.create_interaction_response(&ctx.http, |resp| {
|
.create_interaction_response(&ctx.http, |resp| {
|
||||||
resp.kind(InteractionResponseType::ChannelMessageWithSource)
|
resp.kind(InteractionResponseType::ChannelMessageWithSource)
|
||||||
|
|
|
@ -9,6 +9,10 @@ impl QueryBuilder<LocationDb> {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn with_name_regex_case_insensitive(self, exp: &str) -> Result<Self> {
|
||||||
|
self.with_name_regex(&format!(r"(?i){}", exp))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn with_name_regex(self, exp: &str) -> Result<Self> {
|
pub fn with_name_regex(self, exp: &str) -> Result<Self> {
|
||||||
let filter = regex::Regex::new(exp)?;
|
let filter = regex::Regex::new(exp)?;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue