mirror of
https://github.com/natsukagami/youmubot.git
synced 2025-04-18 16:28:55 +00:00
Split youmubot-osu
This commit is contained in:
parent
03be1a4acc
commit
aec9cd130d
15 changed files with 108 additions and 86 deletions
8
Cargo.lock
generated
8
Cargo.lock
generated
|
@ -1679,10 +1679,7 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"dotenv 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"dotenv 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"reqwest 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"reqwest 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serenity 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serenity 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1710,10 +1707,15 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"reqwest 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"reqwest 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serenity 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serenity 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"youmubot-db 0.1.0",
|
||||||
|
"youmubot-prelude 0.1.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -12,6 +12,12 @@ chrono = "0.4.10"
|
||||||
reqwest = "0.10.1"
|
reqwest = "0.10.1"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
bitflags = "1"
|
bitflags = "1"
|
||||||
|
rayon = "1.1"
|
||||||
|
lazy_static = "1"
|
||||||
|
regex = "1"
|
||||||
|
|
||||||
|
youmubot-db = { path = "../youmubot-db" }
|
||||||
|
youmubot-prelude = { path = "../youmubot-prelude" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
use super::{embeds::score_embed, BeatmapWithMode};
|
use super::db::{OsuSavedUsers, OsuUser};
|
||||||
use crate::db::{OsuSavedUsers, OsuUser};
|
use super::{embeds::score_embed, BeatmapWithMode, OsuClient};
|
||||||
|
use crate::{
|
||||||
|
models::{Mode, Score},
|
||||||
|
request::{BeatmapRequestKind, UserID},
|
||||||
|
Client as Osu,
|
||||||
|
};
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use serenity::{
|
use serenity::{
|
||||||
framework::standard::{CommandError as Error, CommandResult},
|
framework::standard::{CommandError as Error, CommandResult},
|
||||||
http::Http,
|
http::Http,
|
||||||
model::id::{ChannelId, UserId},
|
model::id::{ChannelId, UserId},
|
||||||
};
|
};
|
||||||
use youmubot_osu::{
|
|
||||||
models::{Mode, Score},
|
|
||||||
request::{BeatmapRequestKind, UserID},
|
|
||||||
Client as Osu,
|
|
||||||
};
|
|
||||||
use youmubot_prelude::*;
|
use youmubot_prelude::*;
|
||||||
|
|
||||||
/// Announce osu! top scores.
|
/// Announce osu! top scores.
|
|
@ -1,5 +1,5 @@
|
||||||
|
use super::db::OsuLastBeatmap;
|
||||||
use super::BeatmapWithMode;
|
use super::BeatmapWithMode;
|
||||||
use crate::db::OsuLastBeatmap;
|
|
||||||
use serenity::{
|
use serenity::{
|
||||||
framework::standard::{CommandError as Error, CommandResult},
|
framework::standard::{CommandError as Error, CommandResult},
|
||||||
model::id::ChannelId,
|
model::id::ChannelId,
|
22
youmubot-osu/src/discord/db.rs
Normal file
22
youmubot-osu/src/discord/db.rs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serenity::{
|
||||||
|
model::id::{ChannelId, UserId},
|
||||||
|
};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use youmubot_db::{DB};
|
||||||
|
use crate::models::{Beatmap, Mode};
|
||||||
|
|
||||||
|
/// Save the user IDs.
|
||||||
|
pub type OsuSavedUsers = DB<HashMap<UserId, OsuUser>>;
|
||||||
|
|
||||||
|
/// Save each channel's last requested beatmap.
|
||||||
|
pub type OsuLastBeatmap = DB<HashMap<ChannelId, (Beatmap, Mode)>>;
|
||||||
|
|
||||||
|
/// An osu! saved user.
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
|
pub struct OsuUser {
|
||||||
|
pub id: u64,
|
||||||
|
pub last_update: DateTime<Utc>,
|
||||||
|
}
|
|
@ -1,8 +1,8 @@
|
||||||
use super::BeatmapWithMode;
|
use super::BeatmapWithMode;
|
||||||
use crate::commands::args::Duration;
|
use crate::models::{Beatmap, Mode, Rank, Score, User};
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use serenity::{builder::CreateEmbed, utils::MessageBuilder};
|
use serenity::{builder::CreateEmbed, utils::MessageBuilder};
|
||||||
use youmubot_osu::models::{Beatmap, Mode, Rank, Score, User};
|
use youmubot_prelude::*;
|
||||||
|
|
||||||
fn format_mode(actual: Mode, original: Mode) -> String {
|
fn format_mode(actual: Mode, original: Mode) -> String {
|
||||||
if actual == original {
|
if actual == original {
|
|
@ -1,3 +1,8 @@
|
||||||
|
use super::OsuClient;
|
||||||
|
use crate::{
|
||||||
|
models::{Beatmap, Mode},
|
||||||
|
request::BeatmapRequestKind,
|
||||||
|
};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use serenity::{
|
use serenity::{
|
||||||
|
@ -6,10 +11,6 @@ use serenity::{
|
||||||
model::channel::Message,
|
model::channel::Message,
|
||||||
utils::MessageBuilder,
|
utils::MessageBuilder,
|
||||||
};
|
};
|
||||||
use youmubot_osu::{
|
|
||||||
models::{Beatmap, Mode},
|
|
||||||
request::BeatmapRequestKind,
|
|
||||||
};
|
|
||||||
use youmubot_prelude::*;
|
use youmubot_prelude::*;
|
||||||
|
|
||||||
use super::embeds::{beatmap_embed, beatmapset_embed};
|
use super::embeds::{beatmap_embed, beatmapset_embed};
|
|
@ -1,4 +1,8 @@
|
||||||
use crate::db::{OsuSavedUsers, OsuUser};
|
use crate::{
|
||||||
|
models::{Beatmap, Mode, User},
|
||||||
|
request::{BeatmapRequestKind, UserID},
|
||||||
|
Client as OsuHttpClient,
|
||||||
|
};
|
||||||
use serenity::{
|
use serenity::{
|
||||||
framework::standard::{
|
framework::standard::{
|
||||||
macros::{command, group},
|
macros::{command, group},
|
||||||
|
@ -8,21 +12,59 @@ use serenity::{
|
||||||
utils::MessageBuilder,
|
utils::MessageBuilder,
|
||||||
};
|
};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use youmubot_osu::{
|
|
||||||
models::{Beatmap, Mode, User},
|
|
||||||
request::{BeatmapRequestKind, UserID},
|
|
||||||
};
|
|
||||||
use youmubot_prelude::*;
|
use youmubot_prelude::*;
|
||||||
|
|
||||||
mod announcer;
|
mod announcer;
|
||||||
mod cache;
|
mod cache;
|
||||||
|
mod db;
|
||||||
pub(crate) mod embeds;
|
pub(crate) mod embeds;
|
||||||
mod hook;
|
mod hook;
|
||||||
|
|
||||||
pub use announcer::OsuAnnouncer;
|
pub use announcer::OsuAnnouncer;
|
||||||
|
use db::OsuUser;
|
||||||
|
use db::{OsuLastBeatmap, OsuSavedUsers};
|
||||||
use embeds::{beatmap_embed, score_embed, user_embed};
|
use embeds::{beatmap_embed, score_embed, user_embed};
|
||||||
pub use hook::hook;
|
pub use hook::hook;
|
||||||
|
|
||||||
|
/// The osu! client.
|
||||||
|
pub(crate) struct OsuClient;
|
||||||
|
|
||||||
|
impl TypeMapKey for OsuClient {
|
||||||
|
type Value = OsuHttpClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets up the osu! command handling section.
|
||||||
|
///
|
||||||
|
/// This automatically enables:
|
||||||
|
/// - Related databases
|
||||||
|
/// - An announcer system (that will eventually be revamped)
|
||||||
|
/// - The osu! API client.
|
||||||
|
///
|
||||||
|
/// This does NOT automatically enable:
|
||||||
|
/// - Commands on the "osu" prefix
|
||||||
|
/// - Hooks. Hooks are completely opt-in.
|
||||||
|
///
|
||||||
|
pub fn setup(
|
||||||
|
path: &std::path::Path,
|
||||||
|
client: &serenity::client::Client,
|
||||||
|
data: &mut ShareMap,
|
||||||
|
) -> CommandResult {
|
||||||
|
// Databases
|
||||||
|
OsuSavedUsers::insert_into(&mut *data, &path.join("osu_saved_users.yaml"))?;
|
||||||
|
OsuLastBeatmap::insert_into(&mut *data, &path.join("last_beatmaps.yaml"))?;
|
||||||
|
|
||||||
|
// API client
|
||||||
|
let http_client = data.get_cloned::<HTTPClient>();
|
||||||
|
data.insert::<OsuClient>(OsuHttpClient::new(
|
||||||
|
http_client,
|
||||||
|
std::env::var("OSU_API_KEY").expect("Please set OSU_API_KEY as osu! api key."),
|
||||||
|
));
|
||||||
|
|
||||||
|
// Announcer
|
||||||
|
OsuAnnouncer::scan(&client, std::time::Duration::from_secs(300));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[group]
|
#[group]
|
||||||
#[prefix = "osu"]
|
#[prefix = "osu"]
|
||||||
#[description = "osu! related commands."]
|
#[description = "osu! related commands."]
|
|
@ -1,5 +1,5 @@
|
||||||
|
pub mod discord;
|
||||||
pub mod models;
|
pub mod models;
|
||||||
|
|
||||||
pub mod request;
|
pub mod request;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -18,13 +18,6 @@ impl TypeMapKey for HTTPClient {
|
||||||
type Value = reqwest::blocking::Client;
|
type Value = reqwest::blocking::Client;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The osu! client.
|
|
||||||
// pub(crate) struct OsuClient;
|
|
||||||
|
|
||||||
// impl TypeMapKey for OsuClient {
|
|
||||||
// type Value = OsuHttpClient;
|
|
||||||
// }
|
|
||||||
|
|
||||||
/// The TypeMap trait that allows TypeMaps to quickly get a clonable item.
|
/// The TypeMap trait that allows TypeMaps to quickly get a clonable item.
|
||||||
pub trait GetCloned {
|
pub trait GetCloned {
|
||||||
/// Gets an item from the store, cloned.
|
/// Gets an item from the store, cloned.
|
||||||
|
|
|
@ -9,6 +9,5 @@ pub fn setup_prelude(db_path: &Path, data: &mut ShareMap, _: &mut StandardFramew
|
||||||
crate::announcer::AnnouncerChannels::insert_into(data, db_path.join("announcers.yaml"))
|
crate::announcer::AnnouncerChannels::insert_into(data, db_path.join("announcers.yaml"))
|
||||||
.expect("Announcers DB set up");
|
.expect("Announcers DB set up");
|
||||||
|
|
||||||
data.insert::<crate::HTTPClient>(reqwest::blocking::Client::new())
|
data.insert::<crate::HTTPClient>(reqwest::blocking::Client::new());
|
||||||
.expect("Should be able to insert");
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,10 +14,7 @@ chrono = "0.4.9"
|
||||||
rand = "0.7.2"
|
rand = "0.7.2"
|
||||||
static_assertions = "1.1.0"
|
static_assertions = "1.1.0"
|
||||||
reqwest = "0.10.1"
|
reqwest = "0.10.1"
|
||||||
regex = "1"
|
|
||||||
lazy_static = "1"
|
|
||||||
youmubot-osu = { path = "../youmubot-osu" }
|
youmubot-osu = { path = "../youmubot-osu" }
|
||||||
rayon = "1.1"
|
|
||||||
youmubot-db = { path = "../youmubot-db" }
|
youmubot-db = { path = "../youmubot-db" }
|
||||||
youmubot-prelude = { path = "../youmubot-prelude" }
|
youmubot-prelude = { path = "../youmubot-prelude" }
|
||||||
|
|
||||||
|
|
|
@ -10,14 +10,10 @@ use youmubot_prelude::*;
|
||||||
pub mod admin;
|
pub mod admin;
|
||||||
pub mod community;
|
pub mod community;
|
||||||
pub mod fun;
|
pub mod fun;
|
||||||
pub mod osu;
|
|
||||||
|
|
||||||
pub use admin::ADMIN_GROUP;
|
pub use admin::ADMIN_GROUP;
|
||||||
pub use community::COMMUNITY_GROUP;
|
pub use community::COMMUNITY_GROUP;
|
||||||
pub use fun::FUN_GROUP;
|
pub use fun::FUN_GROUP;
|
||||||
pub use osu::OSU_GROUP;
|
|
||||||
|
|
||||||
pub use announcer::Announcer;
|
|
||||||
|
|
||||||
// A help command
|
// A help command
|
||||||
#[help]
|
#[help]
|
||||||
|
|
|
@ -1,37 +1,21 @@
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use dotenv::var;
|
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serenity::{
|
use serenity::{
|
||||||
client::Client,
|
|
||||||
framework::standard::CommandError as Error,
|
framework::standard::CommandError as Error,
|
||||||
model::id::{ChannelId, RoleId, UserId},
|
model::id::{RoleId, UserId},
|
||||||
};
|
};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::path::PathBuf;
|
use std::path::Path;
|
||||||
use youmubot_db::{GuildMap, DB};
|
use youmubot_db::{GuildMap, DB};
|
||||||
use youmubot_osu::models::{Beatmap, Mode};
|
use youmubot_prelude::*;
|
||||||
|
|
||||||
/// A list of SoftBans for all servers.
|
/// A list of SoftBans for all servers.
|
||||||
pub type SoftBans = DB<GuildMap<ServerSoftBans>>;
|
pub type SoftBans = DB<GuildMap<ServerSoftBans>>;
|
||||||
|
|
||||||
/// Save the user IDs.
|
|
||||||
pub type OsuSavedUsers = DB<HashMap<UserId, OsuUser>>;
|
|
||||||
|
|
||||||
/// Save each channel's last requested beatmap.
|
|
||||||
pub type OsuLastBeatmap = DB<HashMap<ChannelId, (Beatmap, Mode)>>;
|
|
||||||
|
|
||||||
/// Sets up all databases in the client.
|
/// Sets up all databases in the client.
|
||||||
pub fn setup_db(client: &mut Client) -> Result<(), Error> {
|
pub fn setup_db(path: &Path, data: &mut ShareMap) -> Result<(), Error> {
|
||||||
let path: PathBuf = var("DBPATH").map(|v| PathBuf::from(v)).unwrap_or_else(|e| {
|
|
||||||
println!("No DBPATH set up ({:?}), using `/data`", e);
|
|
||||||
PathBuf::from("data")
|
|
||||||
});
|
|
||||||
let mut data = client.data.write();
|
|
||||||
SoftBans::insert_into(&mut *data, &path.join("soft_bans.yaml"))?;
|
SoftBans::insert_into(&mut *data, &path.join("soft_bans.yaml"))?;
|
||||||
OsuSavedUsers::insert_into(&mut *data, &path.join("osu_saved_users.yaml"))?;
|
|
||||||
OsuLastBeatmap::insert_into(&mut *data, &path.join("last_beatmaps.yaml"))?;
|
|
||||||
// AnnouncerChannels::insert_into(&mut *data, &path.join("announcers.yaml"))?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -62,10 +46,3 @@ pub struct ImplementedSoftBans {
|
||||||
/// List of all to-unban people.
|
/// List of all to-unban people.
|
||||||
pub periodical_bans: HashMap<UserId, DateTime<Utc>>,
|
pub periodical_bans: HashMap<UserId, DateTime<Utc>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An osu! saved user.
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
||||||
pub struct OsuUser {
|
|
||||||
pub id: u64,
|
|
||||||
pub last_update: DateTime<Utc>,
|
|
||||||
}
|
|
||||||
|
|
|
@ -4,15 +4,13 @@ use serenity::{
|
||||||
framework::standard::{DispatchError, StandardFramework},
|
framework::standard::{DispatchError, StandardFramework},
|
||||||
model::{channel::Message, gateway},
|
model::{channel::Message, gateway},
|
||||||
};
|
};
|
||||||
use youmubot_osu::Client as OsuApiClient;
|
use youmubot_osu::discord::{setup as setup_osu, OSU_GROUP};
|
||||||
use youmubot_prelude::*;
|
use youmubot_prelude::*;
|
||||||
|
|
||||||
mod commands;
|
mod commands;
|
||||||
mod db;
|
mod db;
|
||||||
|
|
||||||
use commands::osu::OsuAnnouncer;
|
const MESSAGE_HOOKS: [fn(&mut Context, &Message) -> (); 1] = [youmubot_osu::discord::hook];
|
||||||
|
|
||||||
const MESSAGE_HOOKS: [fn(&mut Context, &Message) -> (); 1] = [commands::osu::hook];
|
|
||||||
|
|
||||||
struct Handler;
|
struct Handler;
|
||||||
|
|
||||||
|
@ -53,26 +51,15 @@ fn main() {
|
||||||
std::path::PathBuf::from("data")
|
std::path::PathBuf::from("data")
|
||||||
});
|
});
|
||||||
youmubot_prelude::setup::setup_prelude(&db_path, &mut data, &mut fw);
|
youmubot_prelude::setup::setup_prelude(&db_path, &mut data, &mut fw);
|
||||||
}
|
// Setup initial data
|
||||||
|
db::setup_db(&db_path, &mut data).expect("Setup db should succeed");
|
||||||
// Setup initial data
|
// osu!
|
||||||
db::setup_db(&mut client).expect("Setup db should succeed");
|
setup_osu(&db_path, &client, &mut data).expect("osu! is initialized");
|
||||||
// Setup shared instances of things
|
|
||||||
{
|
|
||||||
let mut data = client.data.write();
|
|
||||||
let http_client = data.get_cloned::<HTTPClient>();
|
|
||||||
data.insert::<OsuClient>(OsuApiClient::new(
|
|
||||||
http_client.clone(),
|
|
||||||
var("OSU_API_KEY").expect("Please set OSU_API_KEY as osu! api key."),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create handler threads
|
// Create handler threads
|
||||||
std::thread::spawn(commands::admin::watch_soft_bans(&mut client));
|
std::thread::spawn(commands::admin::watch_soft_bans(&mut client));
|
||||||
|
|
||||||
// Announcers
|
|
||||||
OsuAnnouncer::scan(&client, std::time::Duration::from_secs(300));
|
|
||||||
|
|
||||||
println!("Starting...");
|
println!("Starting...");
|
||||||
if let Err(v) = client.start() {
|
if let Err(v) = client.start() {
|
||||||
panic!(v)
|
panic!(v)
|
||||||
|
@ -150,5 +137,5 @@ fn setup_framework(client: &Client) -> StandardFramework {
|
||||||
.group(&commands::ADMIN_GROUP)
|
.group(&commands::ADMIN_GROUP)
|
||||||
.group(&commands::FUN_GROUP)
|
.group(&commands::FUN_GROUP)
|
||||||
.group(&commands::COMMUNITY_GROUP)
|
.group(&commands::COMMUNITY_GROUP)
|
||||||
.group(&commands::OSU_GROUP)
|
.group(&OSU_GROUP)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue