mirror of
https://github.com/natsukagami/youmubot.git
synced 2025-04-20 01:08:55 +00:00
osu: Asyncify oppai cache
This commit is contained in:
parent
da2997d8f9
commit
bfe12d3946
2 changed files with 45 additions and 40 deletions
|
@ -128,12 +128,14 @@ fn handle_old_links<'a>(
|
||||||
.map(|v| Mods::from_str(v.as_str()).ok())
|
.map(|v| Mods::from_str(v.as_str()).ok())
|
||||||
.flatten()
|
.flatten()
|
||||||
.unwrap_or(Mods::NOMOD);
|
.unwrap_or(Mods::NOMOD);
|
||||||
let info = mode.unwrap_or(b.mode).to_oppai_mode().and_then(|mode| {
|
let info = match mode.unwrap_or(b.mode).to_oppai_mode() {
|
||||||
cache
|
Some(mode) => cache
|
||||||
.get_beatmap(b.beatmap_id)
|
.get_beatmap(b.beatmap_id)
|
||||||
|
.await
|
||||||
.and_then(|b| b.get_info_with(Some(mode), mods))
|
.and_then(|b| b.get_info_with(Some(mode), mods))
|
||||||
.ok()
|
.ok(),
|
||||||
});
|
None => None,
|
||||||
|
};
|
||||||
Some(ToPrint {
|
Some(ToPrint {
|
||||||
embed: EmbedType::Beatmap(b, info, mods),
|
embed: EmbedType::Beatmap(b, info, mods),
|
||||||
link: capture.get(0).unwrap().as_str(),
|
link: capture.get(0).unwrap().as_str(),
|
||||||
|
@ -198,15 +200,14 @@ fn handle_new_links<'a>(
|
||||||
.name("mods")
|
.name("mods")
|
||||||
.and_then(|v| Mods::from_str(v.as_str()).ok())
|
.and_then(|v| Mods::from_str(v.as_str()).ok())
|
||||||
.unwrap_or(Mods::NOMOD);
|
.unwrap_or(Mods::NOMOD);
|
||||||
let info = mode
|
let info = match mode.unwrap_or(beatmap.mode).to_oppai_mode() {
|
||||||
.unwrap_or(beatmap.mode)
|
Some(mode) => cache
|
||||||
.to_oppai_mode()
|
|
||||||
.and_then(|mode| {
|
|
||||||
cache
|
|
||||||
.get_beatmap(beatmap.beatmap_id)
|
.get_beatmap(beatmap.beatmap_id)
|
||||||
|
.await
|
||||||
.and_then(|b| b.get_info_with(Some(mode), mods))
|
.and_then(|b| b.get_info_with(Some(mode), mods))
|
||||||
.ok()
|
.ok(),
|
||||||
});
|
None => None,
|
||||||
|
};
|
||||||
Some(ToPrint {
|
Some(ToPrint {
|
||||||
embed: EmbedType::Beatmap(beatmap, info, mods),
|
embed: EmbedType::Beatmap(beatmap, info, mods),
|
||||||
link,
|
link,
|
||||||
|
@ -265,15 +266,14 @@ fn handle_short_links<'a>(
|
||||||
.name("mods")
|
.name("mods")
|
||||||
.and_then(|v| Mods::from_str(v.as_str()).ok())
|
.and_then(|v| Mods::from_str(v.as_str()).ok())
|
||||||
.unwrap_or(Mods::NOMOD);
|
.unwrap_or(Mods::NOMOD);
|
||||||
let info = mode
|
let info = match mode.unwrap_or(beatmap.mode).to_oppai_mode() {
|
||||||
.unwrap_or(beatmap.mode)
|
Some(mode) => cache
|
||||||
.to_oppai_mode()
|
|
||||||
.and_then(|mode| {
|
|
||||||
cache
|
|
||||||
.get_beatmap(beatmap.beatmap_id)
|
.get_beatmap(beatmap.beatmap_id)
|
||||||
|
.await
|
||||||
.and_then(|b| b.get_info_with(Some(mode), mods))
|
.and_then(|b| b.get_info_with(Some(mode), mods))
|
||||||
.ok()
|
.ok(),
|
||||||
});
|
None => None,
|
||||||
|
};
|
||||||
let r: Result<_> = Ok(ToPrint {
|
let r: Result<_> = Ok(ToPrint {
|
||||||
embed: EmbedType::Beatmap(beatmap, info, mods),
|
embed: EmbedType::Beatmap(beatmap, info, mods),
|
||||||
link: capture.get(0).unwrap().as_str(),
|
link: capture.get(0).unwrap().as_str(),
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
use serenity::framework::standard::CommandError;
|
use serenity::framework::standard::CommandError;
|
||||||
use std::{ffi::CString, sync::Arc};
|
use std::ffi::CString;
|
||||||
use youmubot_prelude::TypeMapKey;
|
use youmubot_prelude::*;
|
||||||
|
|
||||||
/// the information collected from a download/Oppai request.
|
/// the information collected from a download/Oppai request.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Debug)]
|
||||||
pub struct BeatmapContent {
|
pub struct BeatmapContent {
|
||||||
id: u64,
|
id: u64,
|
||||||
content: Arc<CString>,
|
content: CString,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// the output of "one" oppai run.
|
/// the output of "one" oppai run.
|
||||||
|
@ -56,39 +56,44 @@ impl BeatmapContent {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A central cache for the beatmaps.
|
/// A central cache for the beatmaps.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Debug)]
|
||||||
pub struct BeatmapCache {
|
pub struct BeatmapCache {
|
||||||
client: reqwest::blocking::Client,
|
client: reqwest::Client,
|
||||||
cache: Arc<dashmap::DashMap<u64, BeatmapContent>>,
|
cache: dashmap::DashMap<u64, BeatmapContent>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BeatmapCache {
|
impl BeatmapCache {
|
||||||
/// Create a new cache.
|
/// Create a new cache.
|
||||||
pub fn new(client: reqwest::blocking::Client) -> Self {
|
pub fn new(client: reqwest::Client) -> Self {
|
||||||
BeatmapCache {
|
BeatmapCache {
|
||||||
client,
|
client,
|
||||||
cache: Arc::new(dashmap::DashMap::new()),
|
cache: dashmap::DashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn download_beatmap(&self, id: u64) -> Result<BeatmapContent, CommandError> {
|
async fn download_beatmap(&self, id: u64) -> Result<BeatmapContent> {
|
||||||
let content = self
|
let content = self
|
||||||
.client
|
.client
|
||||||
.get(&format!("https://osu.ppy.sh/osu/{}", id))
|
.get(&format!("https://osu.ppy.sh/osu/{}", id))
|
||||||
.send()?
|
.send()
|
||||||
.bytes()?;
|
.await?
|
||||||
|
.bytes()
|
||||||
|
.await?;
|
||||||
Ok(BeatmapContent {
|
Ok(BeatmapContent {
|
||||||
id,
|
id,
|
||||||
content: Arc::new(CString::new(content.into_iter().collect::<Vec<_>>())?),
|
content: CString::new(content.into_iter().collect::<Vec<_>>())?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a beatmap from the cache.
|
/// Get a beatmap from the cache.
|
||||||
pub fn get_beatmap(&self, id: u64) -> Result<BeatmapContent, CommandError> {
|
pub async fn get_beatmap<'a>(
|
||||||
self.cache
|
&'a self,
|
||||||
.entry(id)
|
id: u64,
|
||||||
.or_try_insert_with(|| self.download_beatmap(id))
|
) -> Result<impl std::ops::Deref<Target = BeatmapContent> + 'a, CommandError> {
|
||||||
.map(|v| v.clone())
|
if !self.cache.contains_key(&id) {
|
||||||
|
self.cache.insert(id, self.download_beatmap(id).await?);
|
||||||
|
}
|
||||||
|
Ok(self.cache.get(&id).unwrap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue