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::album_manager::{Album, AlbumQuery, ImageQuery, ImageSort};
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::models::insult_compliment::{RandomResponseTemplate, ResponseType};
|
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 crate::{command, group, GlobalData, BAD_APPLE};
|
||||||
use reqwest::Client;
|
use reqwest::Client;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -106,7 +106,7 @@ pub async fn random(ctx: &Context, msg: &Message, random_name: &str) -> CommandR
|
|||||||
Some(r) => r,
|
Some(r) => r,
|
||||||
};
|
};
|
||||||
|
|
||||||
let response_template_str = match random.get_response()? {
|
let response_template_str = match random.get_response(&global_data.db)? {
|
||||||
None => {
|
None => {
|
||||||
msg.reply(&ctx, format!("I'm all out of material for {}", random_name))
|
msg.reply(&ctx, format!("I'm all out of material for {}", random_name))
|
||||||
.await?;
|
.await?;
|
||||||
@ -125,7 +125,7 @@ pub async fn random(ctx: &Context, msg: &Message, random_name: &str) -> CommandR
|
|||||||
let reply = render_random(
|
let reply = render_random(
|
||||||
guild_member.display_name(),
|
guild_member.display_name(),
|
||||||
global_data,
|
global_data,
|
||||||
response_template_str,
|
&response_template_str,
|
||||||
)
|
)
|
||||||
.await?;
|
.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?;
|
let dm_channel = msg.author.id.create_dm_channel(&ctx.http).await?;
|
||||||
if let Some(random) = random {
|
if let Some(random) = random {
|
||||||
let mut msg_builder = MessageBuilder::new();
|
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 {
|
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 {
|
if (msg_builder.0.len() + line_msg.len()) > MESSAGE_CODE_LIMIT {
|
||||||
dm_channel.say(&ctx.http, msg_builder.build()).await?;
|
dm_channel.say(&ctx.http, msg_builder.build()).await?;
|
||||||
|
|||||||
@ -17,4 +17,4 @@ impl Migration for Migration3RemoveImage {
|
|||||||
fn version(&self) -> u64 {
|
fn version(&self) -> u64 {
|
||||||
3
|
3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
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::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::database::Database;
|
||||||
use j_db::migration;
|
use j_db::migration;
|
||||||
use j_db::migration::Direction;
|
use j_db::migration::Direction;
|
||||||
use crate::migrations::migration3_remove_img::Migration3RemoveImage;
|
|
||||||
|
|
||||||
mod migration2_remove_imgur;
|
mod migration2_remove_imgur;
|
||||||
mod migration3_remove_img;
|
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)]
|
#[allow(clippy::single_match)]
|
||||||
pub fn do_migration(db: &Database) {
|
pub fn do_migration(db: &Database) {
|
||||||
@ -28,7 +30,15 @@ pub fn do_migration(db: &Database) {
|
|||||||
Migration3RemoveImage {},
|
Migration3RemoveImage {},
|
||||||
Direction::Up,
|
Direction::Up,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
}
|
||||||
|
4 => {
|
||||||
|
migration::do_migration::<Migration4UpdateRandoms>(
|
||||||
|
db,
|
||||||
|
Migration4UpdateRandoms {},
|
||||||
|
Direction::Up,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,15 +1,53 @@
|
|||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use j_db::database::Database;
|
use j_db::database::Database;
|
||||||
use j_db::model::JdbModel;
|
use j_db::model::JdbModel;
|
||||||
use rand::prelude::SliceRandom;
|
use rand::distributions::WeightedIndex;
|
||||||
|
use rand::prelude::Distribution;
|
||||||
use rand::thread_rng;
|
use rand::thread_rng;
|
||||||
use serde::{Deserialize, Serialize};
|
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)]
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||||
pub struct RandomConfig {
|
pub struct RandomConfig {
|
||||||
id: Option<u64>,
|
id: Option<u64>,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub responses: Vec<String>,
|
pub responses: HashSet<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl JdbModel for RandomConfig {
|
impl JdbModel for RandomConfig {
|
||||||
@ -32,18 +70,22 @@ impl JdbModel for RandomConfig {
|
|||||||
|
|
||||||
impl RandomConfig {
|
impl RandomConfig {
|
||||||
pub fn add_random(db: &Database, name: &str, response: &str) -> Result<(), Error> {
|
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 {
|
None => db.insert::<RandomConfig>(Self {
|
||||||
id: None,
|
id: None,
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
responses: vec![],
|
responses: HashSet::new(),
|
||||||
})?,
|
})?,
|
||||||
Some(random) => random,
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -54,7 +96,31 @@ impl RandomConfig {
|
|||||||
.next())
|
.next())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_response(&self) -> Result<Option<&String>, Error> {
|
pub fn get_response(&self, db: &Database) -> Result<Option<String>, Error> {
|
||||||
Ok(self.responses.choose(&mut thread_rng()))
|
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