Updated randoms to be less repeaty
This commit is contained in:
parent
a65fdfdd4d
commit
93975f463c
@ -1,7 +1,7 @@
|
||||
use crate::album_manager::{Album, AlbumQuery, ImageQuery, ImageSort};
|
||||
use crate::error::Error;
|
||||
use crate::models::insult_compliment::{RandomResponseTemplate, ResponseType};
|
||||
use crate::models::random::RandomConfig;
|
||||
use crate::models::random::{Random, RandomConfig};
|
||||
use crate::{command, group, GlobalData, BAD_APPLE};
|
||||
use reqwest::Client;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -106,7 +106,7 @@ pub async fn random(ctx: &Context, msg: &Message, random_name: &str) -> CommandR
|
||||
Some(r) => r,
|
||||
};
|
||||
|
||||
let response_template_str = match random.get_response()? {
|
||||
let response_template_str = match random.get_response(&global_data.db)? {
|
||||
None => {
|
||||
msg.reply(&ctx, format!("I'm all out of material for {}", random_name))
|
||||
.await?;
|
||||
@ -125,7 +125,7 @@ pub async fn random(ctx: &Context, msg: &Message, random_name: &str) -> CommandR
|
||||
let reply = render_random(
|
||||
guild_member.display_name(),
|
||||
global_data,
|
||||
response_template_str,
|
||||
&response_template_str,
|
||||
)
|
||||
.await?;
|
||||
|
||||
@ -189,10 +189,16 @@ pub async fn list_random(ctx: &Context, msg: &Message, args: Args) -> CommandRes
|
||||
let dm_channel = msg.author.id.create_dm_channel(&ctx.http).await?;
|
||||
if let Some(random) = random {
|
||||
let mut msg_builder = MessageBuilder::new();
|
||||
msg_builder.push_line(format!("All possible responses for {}:", random_name));
|
||||
msg_builder.push_line(format!(
|
||||
"All possible responses for {} all {} of them..:",
|
||||
random_name,
|
||||
random.responses.len()
|
||||
));
|
||||
|
||||
for resp in random.responses {
|
||||
let line_msg = format!("* {}", resp);
|
||||
let random = global_data.db.get::<Random>(resp)?;
|
||||
|
||||
let line_msg = format!("* ({}) ({}) {}", resp, random.score, random.response);
|
||||
|
||||
if (msg_builder.0.len() + line_msg.len()) > MESSAGE_CODE_LIMIT {
|
||||
dm_channel.say(&ctx.http, msg_builder.build()).await?;
|
||||
|
||||
57
src/migrations/migration_4_update_random.rs
Normal file
57
src/migrations/migration_4_update_random.rs
Normal file
@ -0,0 +1,57 @@
|
||||
use crate::models::random::{Random, RandomConfig};
|
||||
use j_db::database::Database;
|
||||
use j_db::error::JDbError;
|
||||
use j_db::migration::Migration;
|
||||
use j_db::model::JdbModel;
|
||||
use json::number::Number;
|
||||
use json::JsonValue;
|
||||
|
||||
pub struct Migration4UpdateRandoms {}
|
||||
|
||||
impl Migration for Migration4UpdateRandoms {
|
||||
fn up(&self, db: &Database) -> j_db::error::Result<()> {
|
||||
let random_config_tree = db.db.open_tree(RandomConfig::tree())?;
|
||||
|
||||
for config in random_config_tree.iter() {
|
||||
let (id, config) = config?;
|
||||
let mut config = json::parse(std::str::from_utf8(&config).unwrap()).unwrap();
|
||||
|
||||
let mut responses: Vec<u64> = Vec::new();
|
||||
for random in config["responses"].members() {
|
||||
let random = Random::new(&random.to_string());
|
||||
|
||||
let random = db.insert(random);
|
||||
|
||||
let random = match random {
|
||||
Ok(r) => r,
|
||||
Err(err) => match err {
|
||||
JDbError::NotUnique => continue,
|
||||
_ => return Err(err),
|
||||
},
|
||||
};
|
||||
|
||||
responses.push(random.id().unwrap());
|
||||
}
|
||||
|
||||
config.remove("responses");
|
||||
|
||||
let responses: Vec<JsonValue> = responses
|
||||
.iter()
|
||||
.map(|id| JsonValue::Number(Number::from(*id)))
|
||||
.collect();
|
||||
config["responses"] = JsonValue::Array(responses);
|
||||
|
||||
random_config_tree.insert(id, config.to_string().as_bytes())?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn down(&self, _db: &Database) -> j_db::error::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn version(&self) -> u64 {
|
||||
4
|
||||
}
|
||||
}
|
||||
@ -1,13 +1,15 @@
|
||||
use crate::migrations::migration2_remove_imgur::Migration2RemoveImgur;
|
||||
use crate::migrations::migration3_remove_img::Migration3RemoveImage;
|
||||
use crate::migrations::migration_4_update_random::Migration4UpdateRandoms;
|
||||
use j_db::database::Database;
|
||||
use j_db::migration;
|
||||
use j_db::migration::Direction;
|
||||
use crate::migrations::migration3_remove_img::Migration3RemoveImage;
|
||||
|
||||
mod migration2_remove_imgur;
|
||||
mod migration3_remove_img;
|
||||
mod migration_4_update_random;
|
||||
|
||||
const CURRENT_DB_VERSION: u64 = 3;
|
||||
const CURRENT_DB_VERSION: u64 = 4;
|
||||
|
||||
#[allow(clippy::single_match)]
|
||||
pub fn do_migration(db: &Database) {
|
||||
@ -30,6 +32,14 @@ pub fn do_migration(db: &Database) {
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
4 => {
|
||||
migration::do_migration::<Migration4UpdateRandoms>(
|
||||
db,
|
||||
Migration4UpdateRandoms {},
|
||||
Direction::Up,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,15 +1,53 @@
|
||||
use crate::error::Error;
|
||||
use j_db::database::Database;
|
||||
use j_db::model::JdbModel;
|
||||
use rand::prelude::SliceRandom;
|
||||
use rand::distributions::WeightedIndex;
|
||||
use rand::prelude::Distribution;
|
||||
use rand::thread_rng;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashSet;
|
||||
|
||||
const MAX_SCORE: u16 = 10;
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
pub struct Random {
|
||||
id: Option<u64>,
|
||||
pub response: String,
|
||||
pub score: u16,
|
||||
}
|
||||
|
||||
impl Random {
|
||||
pub fn new(response: &str) -> Self {
|
||||
Self {
|
||||
id: None,
|
||||
response: response.to_string(),
|
||||
score: MAX_SCORE,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl JdbModel for Random {
|
||||
fn id(&self) -> Option<u64> {
|
||||
self.id
|
||||
}
|
||||
|
||||
fn set_id(&mut self, id: u64) {
|
||||
self.id = Some(id)
|
||||
}
|
||||
|
||||
fn tree() -> String {
|
||||
"random_opt".to_string()
|
||||
}
|
||||
|
||||
fn check_unique(&self, other: &Self) -> bool {
|
||||
!self.response.eq_ignore_ascii_case(&other.response)
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
pub struct RandomConfig {
|
||||
id: Option<u64>,
|
||||
pub name: String,
|
||||
pub responses: Vec<String>,
|
||||
pub responses: HashSet<u64>,
|
||||
}
|
||||
|
||||
impl JdbModel for RandomConfig {
|
||||
@ -32,18 +70,22 @@ impl JdbModel for RandomConfig {
|
||||
|
||||
impl RandomConfig {
|
||||
pub fn add_random(db: &Database, name: &str, response: &str) -> Result<(), Error> {
|
||||
let mut random = match Self::get_random(db, name)? {
|
||||
let mut randoms = match Self::get_random(db, name)? {
|
||||
None => db.insert::<RandomConfig>(Self {
|
||||
id: None,
|
||||
name: name.to_string(),
|
||||
responses: vec![],
|
||||
responses: HashSet::new(),
|
||||
})?,
|
||||
Some(random) => random,
|
||||
};
|
||||
|
||||
random.responses.push(response.to_string());
|
||||
let random = Random::new(response);
|
||||
|
||||
db.insert::<RandomConfig>(random)?;
|
||||
let random = db.insert(random)?;
|
||||
|
||||
randoms.responses.insert(random.id().unwrap());
|
||||
|
||||
db.insert::<RandomConfig>(randoms)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -54,7 +96,31 @@ impl RandomConfig {
|
||||
.next())
|
||||
}
|
||||
|
||||
pub fn get_response(&self) -> Result<Option<&String>, Error> {
|
||||
Ok(self.responses.choose(&mut thread_rng()))
|
||||
pub fn get_response(&self, db: &Database) -> Result<Option<String>, Error> {
|
||||
let mut responses: Vec<Random> = db
|
||||
.filter(|_, random: &Random| self.responses.contains(&random.id().unwrap()))?
|
||||
.collect();
|
||||
|
||||
if !responses.iter().any(|r| r.score > 0) {
|
||||
for response in &mut responses {
|
||||
response.score = MAX_SCORE;
|
||||
|
||||
db.insert(response.clone())?;
|
||||
}
|
||||
}
|
||||
|
||||
if responses.is_empty() {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let dist = WeightedIndex::new(responses.iter().map(|r| r.score)).unwrap();
|
||||
|
||||
let mut resp = responses[dist.sample(&mut thread_rng())].clone();
|
||||
|
||||
resp.score = resp.score.saturating_sub(1);
|
||||
|
||||
let resp = db.insert(resp)?;
|
||||
|
||||
Ok(Some(resp.response))
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user