From aec9cd130d8962a85278b0e31b6c3aca9f57e249 Mon Sep 17 00:00:00 2001 From: Natsu Kagami Date: Wed, 5 Feb 2020 17:25:34 -0500 Subject: [PATCH] Split youmubot-osu --- Cargo.lock | 8 +-- youmubot-osu/Cargo.toml | 6 +++ .../src/discord}/announcer.rs | 14 ++--- .../osu => youmubot-osu/src/discord}/cache.rs | 2 +- youmubot-osu/src/discord/db.rs | 22 ++++++++ .../src/discord}/embeds.rs | 4 +- .../osu => youmubot-osu/src/discord}/hook.rs | 9 ++-- .../osu => youmubot-osu/src/discord}/mod.rs | 52 +++++++++++++++++-- youmubot-osu/src/lib.rs | 2 +- youmubot-prelude/src/lib.rs | 7 --- youmubot-prelude/src/setup.rs | 3 +- youmubot/Cargo.toml | 3 -- youmubot/src/commands/mod.rs | 4 -- youmubot/src/db.rs | 31 ++--------- youmubot/src/main.rs | 27 +++------- 15 files changed, 108 insertions(+), 86 deletions(-) rename {youmubot/src/commands/osu => youmubot-osu/src/discord}/announcer.rs (96%) rename {youmubot/src/commands/osu => youmubot-osu/src/discord}/cache.rs (96%) create mode 100644 youmubot-osu/src/discord/db.rs rename {youmubot/src/commands/osu => youmubot-osu/src/discord}/embeds.rs (99%) rename {youmubot/src/commands/osu => youmubot-osu/src/discord}/hook.rs (99%) rename {youmubot/src/commands/osu => youmubot-osu/src/discord}/mod.rs (90%) diff --git a/Cargo.lock b/Cargo.lock index 8828ed8..f3fabf8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1679,10 +1679,7 @@ version = "0.1.0" dependencies = [ "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)", - "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)", - "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)", "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)", @@ -1710,10 +1707,15 @@ version = "0.1.0" dependencies = [ "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)", + "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)", "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)", "serenity 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "youmubot-db 0.1.0", + "youmubot-prelude 0.1.0", ] [[package]] diff --git a/youmubot-osu/Cargo.toml b/youmubot-osu/Cargo.toml index 5aa5545..d851508 100644 --- a/youmubot-osu/Cargo.toml +++ b/youmubot-osu/Cargo.toml @@ -12,6 +12,12 @@ chrono = "0.4.10" reqwest = "0.10.1" serde = { version = "1.0", features = ["derive"] } bitflags = "1" +rayon = "1.1" +lazy_static = "1" +regex = "1" + +youmubot-db = { path = "../youmubot-db" } +youmubot-prelude = { path = "../youmubot-prelude" } [dev-dependencies] serde_json = "1" diff --git a/youmubot/src/commands/osu/announcer.rs b/youmubot-osu/src/discord/announcer.rs similarity index 96% rename from youmubot/src/commands/osu/announcer.rs rename to youmubot-osu/src/discord/announcer.rs index 781a105..8ab7e8c 100644 --- a/youmubot/src/commands/osu/announcer.rs +++ b/youmubot-osu/src/discord/announcer.rs @@ -1,16 +1,16 @@ -use super::{embeds::score_embed, BeatmapWithMode}; -use crate::db::{OsuSavedUsers, OsuUser}; +use super::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 serenity::{ framework::standard::{CommandError as Error, CommandResult}, http::Http, model::id::{ChannelId, UserId}, }; -use youmubot_osu::{ - models::{Mode, Score}, - request::{BeatmapRequestKind, UserID}, - Client as Osu, -}; use youmubot_prelude::*; /// Announce osu! top scores. diff --git a/youmubot/src/commands/osu/cache.rs b/youmubot-osu/src/discord/cache.rs similarity index 96% rename from youmubot/src/commands/osu/cache.rs rename to youmubot-osu/src/discord/cache.rs index 8e3af26..9dc2d63 100644 --- a/youmubot/src/commands/osu/cache.rs +++ b/youmubot-osu/src/discord/cache.rs @@ -1,5 +1,5 @@ +use super::db::OsuLastBeatmap; use super::BeatmapWithMode; -use crate::db::OsuLastBeatmap; use serenity::{ framework::standard::{CommandError as Error, CommandResult}, model::id::ChannelId, diff --git a/youmubot-osu/src/discord/db.rs b/youmubot-osu/src/discord/db.rs new file mode 100644 index 0000000..a24d23b --- /dev/null +++ b/youmubot-osu/src/discord/db.rs @@ -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>; + +/// Save each channel's last requested beatmap. +pub type OsuLastBeatmap = DB>; + +/// An osu! saved user. +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct OsuUser { + pub id: u64, + pub last_update: DateTime, +} diff --git a/youmubot/src/commands/osu/embeds.rs b/youmubot-osu/src/discord/embeds.rs similarity index 99% rename from youmubot/src/commands/osu/embeds.rs rename to youmubot-osu/src/discord/embeds.rs index 2afa35f..d2318a7 100644 --- a/youmubot/src/commands/osu/embeds.rs +++ b/youmubot-osu/src/discord/embeds.rs @@ -1,8 +1,8 @@ use super::BeatmapWithMode; -use crate::commands::args::Duration; +use crate::models::{Beatmap, Mode, Rank, Score, User}; use chrono::Utc; 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 { if actual == original { diff --git a/youmubot/src/commands/osu/hook.rs b/youmubot-osu/src/discord/hook.rs similarity index 99% rename from youmubot/src/commands/osu/hook.rs rename to youmubot-osu/src/discord/hook.rs index 0f1b8f0..62c2bcf 100644 --- a/youmubot/src/commands/osu/hook.rs +++ b/youmubot-osu/src/discord/hook.rs @@ -1,3 +1,8 @@ +use super::OsuClient; +use crate::{ + models::{Beatmap, Mode}, + request::BeatmapRequestKind, +}; use lazy_static::lazy_static; use regex::Regex; use serenity::{ @@ -6,10 +11,6 @@ use serenity::{ model::channel::Message, utils::MessageBuilder, }; -use youmubot_osu::{ - models::{Beatmap, Mode}, - request::BeatmapRequestKind, -}; use youmubot_prelude::*; use super::embeds::{beatmap_embed, beatmapset_embed}; diff --git a/youmubot/src/commands/osu/mod.rs b/youmubot-osu/src/discord/mod.rs similarity index 90% rename from youmubot/src/commands/osu/mod.rs rename to youmubot-osu/src/discord/mod.rs index d33892a..9d29fd8 100644 --- a/youmubot/src/commands/osu/mod.rs +++ b/youmubot-osu/src/discord/mod.rs @@ -1,4 +1,8 @@ -use crate::db::{OsuSavedUsers, OsuUser}; +use crate::{ + models::{Beatmap, Mode, User}, + request::{BeatmapRequestKind, UserID}, + Client as OsuHttpClient, +}; use serenity::{ framework::standard::{ macros::{command, group}, @@ -8,21 +12,59 @@ use serenity::{ utils::MessageBuilder, }; use std::str::FromStr; -use youmubot_osu::{ - models::{Beatmap, Mode, User}, - request::{BeatmapRequestKind, UserID}, -}; use youmubot_prelude::*; mod announcer; mod cache; +mod db; pub(crate) mod embeds; mod hook; pub use announcer::OsuAnnouncer; +use db::OsuUser; +use db::{OsuLastBeatmap, OsuSavedUsers}; use embeds::{beatmap_embed, score_embed, user_embed}; 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::(); + data.insert::(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] #[prefix = "osu"] #[description = "osu! related commands."] diff --git a/youmubot-osu/src/lib.rs b/youmubot-osu/src/lib.rs index fa62543..035cfea 100644 --- a/youmubot-osu/src/lib.rs +++ b/youmubot-osu/src/lib.rs @@ -1,5 +1,5 @@ +pub mod discord; pub mod models; - pub mod request; #[cfg(test)] diff --git a/youmubot-prelude/src/lib.rs b/youmubot-prelude/src/lib.rs index c391553..1b73b8c 100644 --- a/youmubot-prelude/src/lib.rs +++ b/youmubot-prelude/src/lib.rs @@ -18,13 +18,6 @@ impl TypeMapKey for HTTPClient { 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. pub trait GetCloned { /// Gets an item from the store, cloned. diff --git a/youmubot-prelude/src/setup.rs b/youmubot-prelude/src/setup.rs index 4aadd37..f503922 100644 --- a/youmubot-prelude/src/setup.rs +++ b/youmubot-prelude/src/setup.rs @@ -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")) .expect("Announcers DB set up"); - data.insert::(reqwest::blocking::Client::new()) - .expect("Should be able to insert"); + data.insert::(reqwest::blocking::Client::new()); } diff --git a/youmubot/Cargo.toml b/youmubot/Cargo.toml index 40b31d1..f263819 100644 --- a/youmubot/Cargo.toml +++ b/youmubot/Cargo.toml @@ -14,10 +14,7 @@ chrono = "0.4.9" rand = "0.7.2" static_assertions = "1.1.0" reqwest = "0.10.1" -regex = "1" -lazy_static = "1" youmubot-osu = { path = "../youmubot-osu" } -rayon = "1.1" youmubot-db = { path = "../youmubot-db" } youmubot-prelude = { path = "../youmubot-prelude" } diff --git a/youmubot/src/commands/mod.rs b/youmubot/src/commands/mod.rs index 3506467..4562bc5 100644 --- a/youmubot/src/commands/mod.rs +++ b/youmubot/src/commands/mod.rs @@ -10,14 +10,10 @@ use youmubot_prelude::*; pub mod admin; pub mod community; pub mod fun; -pub mod osu; pub use admin::ADMIN_GROUP; pub use community::COMMUNITY_GROUP; pub use fun::FUN_GROUP; -pub use osu::OSU_GROUP; - -pub use announcer::Announcer; // A help command #[help] diff --git a/youmubot/src/db.rs b/youmubot/src/db.rs index 21ec47a..cb2250d 100644 --- a/youmubot/src/db.rs +++ b/youmubot/src/db.rs @@ -1,37 +1,21 @@ use chrono::{DateTime, Utc}; -use dotenv::var; use serde::{Deserialize, Serialize}; use serenity::{ - client::Client, framework::standard::CommandError as Error, - model::id::{ChannelId, RoleId, UserId}, + model::id::{RoleId, UserId}, }; use std::collections::HashMap; -use std::path::PathBuf; +use std::path::Path; use youmubot_db::{GuildMap, DB}; -use youmubot_osu::models::{Beatmap, Mode}; +use youmubot_prelude::*; /// A list of SoftBans for all servers. pub type SoftBans = DB>; -/// Save the user IDs. -pub type OsuSavedUsers = DB>; - -/// Save each channel's last requested beatmap. -pub type OsuLastBeatmap = DB>; - /// 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| { - println!("No DBPATH set up ({:?}), using `/data`", e); - PathBuf::from("data") - }); - let mut data = client.data.write(); +pub fn setup_db(path: &Path, data: &mut ShareMap) -> Result<(), Error> { 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(()) } @@ -62,10 +46,3 @@ pub struct ImplementedSoftBans { /// List of all to-unban people. pub periodical_bans: HashMap>, } - -/// An osu! saved user. -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct OsuUser { - pub id: u64, - pub last_update: DateTime, -} diff --git a/youmubot/src/main.rs b/youmubot/src/main.rs index c8c3f9a..e156192 100644 --- a/youmubot/src/main.rs +++ b/youmubot/src/main.rs @@ -4,15 +4,13 @@ use serenity::{ framework::standard::{DispatchError, StandardFramework}, model::{channel::Message, gateway}, }; -use youmubot_osu::Client as OsuApiClient; +use youmubot_osu::discord::{setup as setup_osu, OSU_GROUP}; use youmubot_prelude::*; mod commands; mod db; -use commands::osu::OsuAnnouncer; - -const MESSAGE_HOOKS: [fn(&mut Context, &Message) -> (); 1] = [commands::osu::hook]; +const MESSAGE_HOOKS: [fn(&mut Context, &Message) -> (); 1] = [youmubot_osu::discord::hook]; struct Handler; @@ -53,26 +51,15 @@ fn main() { std::path::PathBuf::from("data") }); youmubot_prelude::setup::setup_prelude(&db_path, &mut data, &mut fw); - } - - // Setup initial data - db::setup_db(&mut client).expect("Setup db should succeed"); - // Setup shared instances of things - { - let mut data = client.data.write(); - let http_client = data.get_cloned::(); - data.insert::(OsuApiClient::new( - http_client.clone(), - var("OSU_API_KEY").expect("Please set OSU_API_KEY as osu! api key."), - )); + // Setup initial data + db::setup_db(&db_path, &mut data).expect("Setup db should succeed"); + // osu! + setup_osu(&db_path, &client, &mut data).expect("osu! is initialized"); } // Create handler threads std::thread::spawn(commands::admin::watch_soft_bans(&mut client)); - // Announcers - OsuAnnouncer::scan(&client, std::time::Duration::from_secs(300)); - println!("Starting..."); if let Err(v) = client.start() { panic!(v) @@ -150,5 +137,5 @@ fn setup_framework(client: &Client) -> StandardFramework { .group(&commands::ADMIN_GROUP) .group(&commands::FUN_GROUP) .group(&commands::COMMUNITY_GROUP) - .group(&commands::OSU_GROUP) + .group(&OSU_GROUP) }