Implement last beatmap saving for later queries

This commit is contained in:
Natsu Kagami 2020-01-13 20:34:35 -05:00
parent c7da9526e6
commit 6ebf23ae3c
4 changed files with 60 additions and 4 deletions

View file

@ -0,0 +1,36 @@
use super::BeatmapWithMode;
use crate::db::{DBWriteGuard, OsuLastBeatmap};
use serenity::{
framework::standard::{CommandError as Error, CommandResult},
model::id::ChannelId,
prelude::*,
};
use youmubot_osu::models::Mode;
/// Save the beatmap into the server data storage.
pub(crate) fn save_beatmap(
data: &mut ShareMap,
channel_id: ChannelId,
bm: &BeatmapWithMode,
) -> CommandResult {
let mut db: DBWriteGuard<_> = data
.get_mut::<OsuLastBeatmap>()
.expect("DB is implemented")
.into();
let mut db = db.borrow_mut()?;
db.insert(channel_id, (bm.0.beatmap_id, bm.mode()));
Ok(())
}
/// Get the last beatmap requested from this channel.
pub(crate) fn get_beatmap(
data: &ShareMap,
channel_id: ChannelId,
) -> Result<Option<(u64, Mode)>, Error> {
let db = data.get::<OsuLastBeatmap>().expect("DB is implemented");
let db = db.borrow_data()?;
Ok(db.get(&channel_id).cloned())
}

View file

@ -30,14 +30,26 @@ pub fn hook(ctx: &mut Context, msg: &Message) -> () {
let mut v = move || -> CommandResult {
let old_links = handle_old_links(ctx, &msg.content)?;
let new_links = handle_new_links(ctx, &msg.content)?;
let mut last_beatmap = None;
for l in old_links.into_iter().chain(new_links.into_iter()) {
if let Err(v) = msg.channel_id.send_message(&ctx, |m| match l.embed {
EmbedType::Beatmap(b) => handle_beatmap(b, l.link, l.mode, l.mods, m),
EmbedType::Beatmap(b) => {
let t = handle_beatmap(&b, l.link, l.mode, l.mods, m);
let mode = l.mode.unwrap_or(b.mode);
last_beatmap = Some(super::BeatmapWithMode(b, mode));
t
}
EmbedType::Beatmapset(b) => handle_beatmapset(b, l.link, l.mode, l.mods, m),
}) {
println!("Error in osu! hook: {:?}", v)
}
}
// Save the beatmap for query later.
if let Some(t) = last_beatmap {
if let Err(v) = super::cache::save_beatmap(&mut *ctx.data.write(), msg.channel_id, &t) {
dbg!(v);
}
}
Ok(())
};
if let Err(v) = v() {
@ -159,7 +171,7 @@ fn handle_new_links<'a>(ctx: &mut Context, content: &'a str) -> Result<Vec<ToPri
}
fn handle_beatmap<'a, 'b>(
beatmap: Beatmap,
beatmap: &Beatmap,
link: &'_ str,
mode: Option<Mode>,
mods: Option<&'_ str>,
@ -171,7 +183,7 @@ fn handle_beatmap<'a, 'b>(
.push_mono_safe(link)
.build(),
)
.embed(|b| beatmap_embed(&beatmap, mode.unwrap_or(beatmap.mode), b))
.embed(|b| beatmap_embed(beatmap, mode.unwrap_or(beatmap.mode), b))
}
fn handle_beatmapset<'a, 'b>(

View file

@ -209,6 +209,9 @@ pub fn recent(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult
.embed(|m| score_embed(&recent_play, &beatmap, &user, None, m))
})?;
// Save the beatmap...
cache::save_beatmap(&mut *data, msg.channel_id, &beatmap)?;
Ok(())
}

View file

@ -5,11 +5,12 @@ use serde::{de::DeserializeOwned, Deserialize, Serialize};
use serenity::{
client::Client,
framework::standard::CommandError as Error,
model::id::{GuildId, RoleId, UserId},
model::id::{ChannelId, GuildId, RoleId, UserId},
prelude::*,
};
use std::collections::HashMap;
use std::path::{Path, PathBuf};
use youmubot_osu::models::Mode;
/// GuildMap defines the guild-map type.
/// It is basically a HashMap from a GuildId to a data structure.
@ -38,6 +39,9 @@ pub type SoftBans = DB<GuildMap<ServerSoftBans>>;
/// Save the user IDs.
pub type OsuSavedUsers = DB<HashMap<UserId, u64>>;
/// Save each channel's last requested beatmap.
pub type OsuLastBeatmap = DB<HashMap<ChannelId, (u64, Mode)>>;
/// Sets up all databases in the client.
pub fn setup_db(client: &mut Client) -> Result<(), Error> {
let path: PathBuf = var("DBPATH").map(|v| PathBuf::from(v)).unwrap_or_else(|e| {
@ -47,6 +51,7 @@ pub fn setup_db(client: &mut Client) -> Result<(), Error> {
let mut data = client.data.write();
SoftBans::insert_into(&mut *data, &path.join("soft_bans.ron"))?;
OsuSavedUsers::insert_into(&mut *data, &path.join("osu_saved_users.ron"))?;
OsuLastBeatmap::insert_into(&mut *data, &path.join("last_beatmaps.ron"))?;
Ok(())
}