Split user and announcer osu clients

This commit is contained in:
Natsu Kagami 2021-01-22 14:08:15 +09:00
parent 901d55814d
commit 145cb01bd0
Signed by: nki
GPG key ID: 7306B3D3C3AD6E51
3 changed files with 108 additions and 89 deletions

View file

@ -1,5 +1,5 @@
use super::db::{OsuSavedUsers, OsuUser}; use super::db::{OsuSavedUsers, OsuUser};
use super::{embeds::score_embed, BeatmapWithMode, OsuClient}; use super::{embeds::score_embed, BeatmapWithMode};
use crate::{ use crate::{
discord::beatmap_cache::BeatmapMetaCache, discord::beatmap_cache::BeatmapMetaCache,
discord::cache::save_beatmap, discord::cache::save_beatmap,
@ -21,7 +21,15 @@ use youmubot_prelude::*;
pub const ANNOUNCER_KEY: &'static str = "osu"; pub const ANNOUNCER_KEY: &'static str = "osu";
/// The announcer struct implementing youmubot_prelude::Announcer /// The announcer struct implementing youmubot_prelude::Announcer
pub struct Announcer; pub struct Announcer {
client: Osu,
}
impl Announcer {
pub fn new(client: Osu) -> Self {
Self { client }
}
}
#[async_trait] #[async_trait]
impl youmubot_prelude::Announcer for Announcer { impl youmubot_prelude::Announcer for Announcer {
@ -39,6 +47,7 @@ impl youmubot_prelude::Announcer for Announcer {
let d = d.clone(); let d = d.clone();
let channels = &channels; let channels = &channels;
let c = c.clone(); let c = c.clone();
let s = &self;
async move { async move {
let channels = channels.channels_of(c.clone(), user_id).await; let channels = channels.channels_of(c.clone(), user_id).await;
if channels.is_empty() { if channels.is_empty() {
@ -47,7 +56,7 @@ impl youmubot_prelude::Announcer for Announcer {
let pp = match (&[Mode::Std, Mode::Taiko, Mode::Catch, Mode::Mania]) let pp = match (&[Mode::Std, Mode::Taiko, Mode::Catch, Mode::Mania])
.into_iter() .into_iter()
.map(|m| { .map(|m| {
handle_user_mode( s.handle_user_mode(
c.clone(), c.clone(),
&osu_user, &osu_user,
user_id, user_id,
@ -86,8 +95,10 @@ impl youmubot_prelude::Announcer for Announcer {
} }
} }
impl Announcer {
/// Handles an user/mode scan, announces all possible new scores, return the new pp value. /// Handles an user/mode scan, announces all possible new scores, return the new pp value.
async fn handle_user_mode( async fn handle_user_mode(
&self,
c: Arc<CacheAndHttp>, c: Arc<CacheAndHttp>,
osu_user: &OsuUser, osu_user: &OsuUser,
user_id: UserId, user_id: UserId,
@ -96,10 +107,9 @@ async fn handle_user_mode(
d: AppData, d: AppData,
) -> Result<Option<f64>, Error> { ) -> Result<Option<f64>, Error> {
let (scores, user) = { let (scores, user) = {
let data = d.read().await; let scores = self.scan_user(osu_user, mode).await?;
let osu = data.get::<OsuClient>().unwrap(); let user = self
let scores = scan_user(osu, osu_user, mode).await?; .client
let user = osu
.user(UserID::ID(osu_user.id), |f| f.mode(mode)) .user(UserID::ID(osu_user.id), |f| f.mode(mode))
.await? .await?
.ok_or(Error::msg("user not found"))?; .ok_or(Error::msg("user not found"))?;
@ -117,7 +127,8 @@ async fn handle_user_mode(
let oppai = data.get::<BeatmapCache>().unwrap(); let oppai = data.get::<BeatmapCache>().unwrap();
let beatmap = cache.get_beatmap_default(score.beatmap_id).await?; let beatmap = cache.get_beatmap_default(score.beatmap_id).await?;
let content = oppai.get_beatmap(beatmap.beatmap_id).await?; let content = oppai.get_beatmap(beatmap.beatmap_id).await?;
let r: Result<_> = Ok((rank, score, BeatmapWithMode(beatmap, mode), content)); let r: Result<_> =
Ok((rank, score, BeatmapWithMode(beatmap, mode), content));
r r
} }
}) })
@ -158,8 +169,9 @@ async fn handle_user_mode(
Ok(pp) Ok(pp)
} }
async fn scan_user(osu: &Osu, u: &OsuUser, mode: Mode) -> Result<Vec<(u8, Score)>, Error> { async fn scan_user(&self, u: &OsuUser, mode: Mode) -> Result<Vec<(u8, Score)>, Error> {
let scores = osu let scores = self
.client
.user_best(UserID::ID(u.id), |f| f.mode(mode).limit(25)) .user_best(UserID::ID(u.id), |f| f.mode(mode).limit(25))
.await?; .await?;
let scores = scores let scores = scores
@ -170,3 +182,4 @@ async fn scan_user(osu: &Osu, u: &OsuUser, mode: Mode) -> Result<Vec<(u8, Score)
.collect(); .collect();
Ok(scores) Ok(scores)
} }
}

View file

@ -66,9 +66,12 @@ pub fn setup(
// API client // API client
let http_client = data.get::<HTTPClient>().unwrap().clone(); let http_client = data.get::<HTTPClient>().unwrap().clone();
let osu_client = Arc::new(OsuHttpClient::new( let make_client = || {
OsuHttpClient::new(
std::env::var("OSU_API_KEY").expect("Please set OSU_API_KEY as osu! api key."), std::env::var("OSU_API_KEY").expect("Please set OSU_API_KEY as osu! api key."),
)); )
};
let osu_client = Arc::new(make_client());
data.insert::<OsuClient>(osu_client.clone()); data.insert::<OsuClient>(osu_client.clone());
data.insert::<oppai_cache::BeatmapCache>(oppai_cache::BeatmapCache::new(http_client)); data.insert::<oppai_cache::BeatmapCache>(oppai_cache::BeatmapCache::new(http_client));
data.insert::<beatmap_cache::BeatmapMetaCache>(beatmap_cache::BeatmapMetaCache::new( data.insert::<beatmap_cache::BeatmapMetaCache>(beatmap_cache::BeatmapMetaCache::new(
@ -76,7 +79,10 @@ pub fn setup(
)); ));
// Announcer // Announcer
announcers.add(announcer::ANNOUNCER_KEY, announcer::Announcer); announcers.add(
announcer::ANNOUNCER_KEY,
announcer::Announcer::new(make_client()),
);
Ok(()) Ok(())
} }

View file

@ -13,7 +13,7 @@ use std::convert::TryInto;
use youmubot_prelude::{ratelimit::Ratelimit, *}; use youmubot_prelude::{ratelimit::Ratelimit, *};
/// The number of requests per minute to the osu! server. /// The number of requests per minute to the osu! server.
const REQUESTS_PER_MINUTE: usize = 200; const REQUESTS_PER_MINUTE: usize = 60;
/// Client is the client that will perform calls to the osu! api server. /// Client is the client that will perform calls to the osu! api server.
pub struct Client { pub struct Client {