Skip to content

Commit

Permalink
Update to serenity 0.12.2 and slight refactor of redis mappings
Browse files Browse the repository at this point in the history
  • Loading branch information
fatfingers23 committed Oct 20, 2024
1 parent 5f6bbca commit eba2d3e
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 79 deletions.
2 changes: 1 addition & 1 deletion trackscape-discord-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
shuttle-actix-web = "0.48.0"
shuttle-runtime = "0.48.0"
serenity = { version = "0.12.0", default-features = false, features = [
serenity = { version = "0.12.2", default-features = false, features = [
"http",
"rustls_backend",
"model",
Expand Down
16 changes: 7 additions & 9 deletions trackscape-discord-api/src/controllers/chat_controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,15 @@ use serenity::http::Http;
use std::sync::Arc;
use tokio::task::spawn_local;
use trackscape_discord_shared::database::BotMongoDb;
use trackscape_discord_shared::ge_api::ge_api::GeItemMapping;
use trackscape_discord_shared::ge_api::ge_api::get_item_mapping;
use trackscape_discord_shared::helpers::hash_string;
use trackscape_discord_shared::jobs::job_helpers::get_redis_client;
use trackscape_discord_shared::jobs::redis_helpers::fetch_redis_json_object;
use trackscape_discord_shared::jobs::CeleryJobQueue;
use trackscape_discord_shared::osrs_broadcast_extractor::osrs_broadcast_extractor::{
get_wiki_clan_rank_image_url, ClanMessage,
};
use trackscape_discord_shared::osrs_broadcast_handler::OSRSBroadcastHandler;
use trackscape_discord_shared::wiki_api::wiki_api::WikiQuest;
use trackscape_discord_shared::wiki_api::wiki_api::get_quests_and_difficulties;
use web::Json;

#[derive(Debug)]
Expand Down Expand Up @@ -215,10 +214,9 @@ async fn new_clan_chats(
// TODO: Load this from Redis
let mut redis_connection = get_redis_client().unwrap();

let item_mapping_from_redis =
fetch_redis_json_object::<GeItemMapping>(&mut redis_connection, "mapping").await;
let quests_from_redis =
fetch_redis_json_object::<Vec<WikiQuest>>(&mut redis_connection, "quests").await;
let item_mapping_from_redis = get_item_mapping(&mut redis_connection).await;

let quests_from_redis = get_quests_and_difficulties(&mut redis_connection).await;

let cloned_celery = Arc::clone(&**celery);
let celery_job_queue = Arc::new(CeleryJobQueue {
Expand All @@ -227,8 +225,8 @@ async fn new_clan_chats(

let handler = OSRSBroadcastHandler::new(
chat.clone(),
Ok::<GeItemMapping, ()>(item_mapping_from_redis),
Ok::<Vec<WikiQuest>, ()>(quests_from_redis),
item_mapping_from_redis,
quests_from_redis,
registered_guild.clone(),
league_world,
mongodb.drop_logs.clone(),
Expand Down
45 changes: 21 additions & 24 deletions trackscape-discord-api/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,8 @@ use std::sync::Mutex;
use std::time::Duration;
use tokio::spawn;
use trackscape_discord_shared::database::{BotMongoDb, MongoDb};
use trackscape_discord_shared::ge_api::ge_api::{get_item_mapping, GeItemMapping};
use trackscape_discord_shared::ge_api::ge_api::get_item_mapping;
use trackscape_discord_shared::jobs::job_helpers::get_redis_client;
use trackscape_discord_shared::jobs::redis_helpers::write_to_cache_with_seconds;

use uuid::Uuid;

pub use self::websocket_server::{ChatServer, ChatServerHandle};
Expand All @@ -33,7 +31,7 @@ use crate::controllers::drop_log_controller::drop_log_controller;
use actix_files::{Files, NamedFile};
use log::{error, info};
use trackscape_discord_shared::jobs::get_celery_caller;
use trackscape_discord_shared::wiki_api::wiki_api::{get_quests_and_difficulties, WikiQuest};
use trackscape_discord_shared::wiki_api::wiki_api::get_quests_and_difficulties;

/// Connection ID.
pub type ConnId = Uuid;
Expand All @@ -56,37 +54,36 @@ async fn actix_web() -> ShuttleActixWeb<impl FnOnce(&mut ServiceConfig) + Send +
let discord_token = env::var("DISCORD_TOKEN").expect("DISCORD_TOKEN not set!");
let mongodb_url = env::var("MONGO_DB_URL").expect("MONGO_DB_URL not set!");
let production_env = env::var("PRODUCTION");
let mut is_production = false;
let mut _is_production = false;
match production_env {
Ok(env) => is_production = env == "true",
Ok(env) => _is_production = env == "true",
Err(_) => {}
}

let db = BotMongoDb::new_db_instance(mongodb_url).await;
let mut redis_conn = get_redis_client().unwrap();

if is_production {
info!("Loading startup data from the web");
let ge_mapping_request = get_item_mapping().await;
match ge_mapping_request {
Ok(ge_mapping) => {
write_to_cache_with_seconds(&mut redis_conn, "mapping", ge_mapping, 604800).await;
}
Err(error) => {
info!("Error getting ge mapping: {}", error)
}
info!("Loading startup data from the web");
let ge_mapping_request = get_item_mapping(&mut redis_conn).await;
match ge_mapping_request {
Ok(_) => {
info!("GE mapping was out of date, updating cache");
}
Err(error) => {
info!("Error getting ge mapping: {}", error)
}
}

let possible_quests = get_quests_and_difficulties().await;
match possible_quests {
Ok(quests) => {
write_to_cache_with_seconds(&mut redis_conn, "quests", quests, 604800).await;
}
Err(e) => {
error!("Error getting quests: {}", e)
}
let possible_quests = get_quests_and_difficulties(&mut redis_conn).await;
match possible_quests {
Ok(_) => {
info!("Quest mapping was out of date, updating cache");
}
Err(e) => {
error!("Error getting quests: {}", e)
}
}

let mut cache = Cache::new(Duration::from_secs(10));
let cache_clone = cache.clone();
spawn(async move {
Expand Down
45 changes: 34 additions & 11 deletions trackscape-discord-shared/src/ge_api.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
pub mod ge_api {
use redis::Connection;
use serde::{Deserialize, Serialize};
use serde_json::Value;

use crate::redis_helpers::{fetch_redis_json_object, write_to_cache_with_seconds};

const CACHE_KEY: &str = "ge_mapping";

static APP_USER_AGENT: &str = concat!(
env!("CARGO_PKG_NAME"),
"/",
Expand All @@ -11,18 +16,36 @@ pub mod ge_api {
);
const BASE_URL: &str = "https://prices.runescape.wiki/api/v1/";

pub async fn get_item_mapping() -> Result<GeItemMapping, reqwest::Error> {
let client = reqwest::Client::builder()
.user_agent(APP_USER_AGENT)
.build()?;
let resp = client
.get(format!("{}{}", BASE_URL, "osrs/mapping").as_str())
.send()
.await?
.json::<GeItemMapping>()
.await?;
pub async fn get_item_mapping(
redis_connection: &mut Connection,
) -> Result<GeItemMapping, anyhow::Error> {
let cached_result =
fetch_redis_json_object::<GeItemMapping>(redis_connection, CACHE_KEY).await;

Ok(resp)
match cached_result {
Ok(ge_mapping) => {
return Ok(ge_mapping);
}
Err(_) => {
let client = reqwest::Client::builder()
.user_agent(APP_USER_AGENT)
.build()?;
let ge_mapping = client
.get(format!("{}{}", BASE_URL, "osrs/mapping").as_str())
.send()
.await?
.json::<GeItemMapping>()
.await?;
write_to_cache_with_seconds(
redis_connection,
CACHE_KEY,
ge_mapping.clone(),
604800,
)
.await;
Ok(ge_mapping)
}
}
}

pub async fn get_item_value_by_id(id: i64) -> Result<GeItemPrice, reqwest::Error> {
Expand Down
1 change: 0 additions & 1 deletion trackscape-discord-shared/src/jobs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ pub mod job_helpers;
pub mod name_change_job;
pub mod new_pb_job;
pub mod parse_rl_chat_command;
pub mod redis_helpers;
pub mod remove_clanmate_job;
mod runelite_commands;
pub mod update_create_clanmate_job;
Expand Down
1 change: 1 addition & 0 deletions trackscape-discord-shared/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ pub mod helpers;
pub mod jobs;
pub mod osrs_broadcast_extractor;
pub mod osrs_broadcast_handler;
pub mod redis_helpers;
pub mod wiki_api;
pub mod wom;
4 changes: 2 additions & 2 deletions trackscape-discord-shared/src/osrs_broadcast_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ impl<T: DropLogs, CL: ClanMateCollectionLogTotals, CM: ClanMates, J: JobQueue>
{
pub fn new(
clan_message: ClanMessage,
item_mapping_from_state: Result<GeItemMapping, ()>,
quests_from_state: Result<Vec<WikiQuest>, ()>,
item_mapping_from_state: Result<GeItemMapping, anyhow::Error>,
quests_from_state: Result<Vec<WikiQuest>, anyhow::Error>,
register_guild: RegisteredGuildModel,
leagues_message: bool,
drop_log_db: T,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use log::error;
use redis::{Connection, RedisResult};
use serde::{Deserialize, Serialize};

Expand Down Expand Up @@ -28,13 +29,24 @@ pub async fn write_to_cache_with_seconds<T: Serialize>(
pub async fn fetch_redis_json_object<T: for<'a> Deserialize<'a>>(
redis_connection: &mut Connection,
redis_key: &str,
) -> T {
) -> Result<T, RedisFetchErrors> {
let val = redis::cmd("GET")
.arg(redis_key)
.query::<String>(redis_connection)
.unwrap();
.map_err(|err| {
error!("Error fetching from redis: {}", err);
RedisFetchErrors::FromDbError
})?;

let val: T = serde_json::from_str(&val).unwrap();
let val: T = serde_json::from_str(&val).map_err(|err| {
error!("Error parsing redis data: {}", err);
RedisFetchErrors::ParseError
})?;

val
Ok(val)
}

pub enum RedisFetchErrors {
FromDbError,
ParseError,
}
79 changes: 52 additions & 27 deletions trackscape-discord-shared/src/wiki_api.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
pub mod wiki_api {
use crate::osrs_broadcast_extractor::osrs_broadcast_extractor::QuestDifficulty;
use crate::{
osrs_broadcast_extractor::osrs_broadcast_extractor::QuestDifficulty,
redis_helpers::{fetch_redis_json_object, write_to_cache_with_seconds},
};
use redis::Connection;
use serde::{Deserialize, Serialize};
use serde_json::Value;

const BASE_URL: &str = "https://oldschool.runescape.wiki/api.php";

const QUEST_CACHE_KEY: &str = "quests";

static APP_USER_AGENT: &str = concat!(
env!("CARGO_PKG_NAME"),
"/",
Expand All @@ -27,41 +33,60 @@ pub mod wiki_api {
)
}

pub async fn get_quests_and_difficulties() -> Result<Vec<WikiQuest>, reqwest::Error> {
let mut quests: Vec<WikiQuest> = Vec::new();
let client = reqwest::Client::builder()
.user_agent(APP_USER_AGENT)
.build()?;
for difficulty in QuestDifficulty::iter() {
let url = build_quest_url(difficulty.clone());
println!("Getting quests from {}", url.as_str());
let resp = client.get(url.as_str()).send().await;
match resp {
Ok(ok_resp) => {
let possible_json_body = ok_resp.json::<Root>().await;
match possible_json_body {
Ok(wiki_result) => {
wiki_result.parse.links.iter().for_each(|link| {
if link.ns == 0 {
quests.push(WikiQuest {
name: link.field.clone(),
difficulty: difficulty.clone(),
pub async fn get_quests_and_difficulties(
redis_connection: &mut Connection,
) -> Result<Vec<WikiQuest>, anyhow::Error> {
let cached_result =
fetch_redis_json_object::<Vec<WikiQuest>>(redis_connection, QUEST_CACHE_KEY).await;
match cached_result {
Ok(ge_mapping) => {
return Ok(ge_mapping);
}
Err(_) => {
let mut quests: Vec<WikiQuest> = Vec::new();
let client = reqwest::Client::builder()
.user_agent(APP_USER_AGENT)
.build()?;
for difficulty in QuestDifficulty::iter() {
let url = build_quest_url(difficulty.clone());
println!("Getting quests from {}", url.as_str());
let resp = client.get(url.as_str()).send().await;
match resp {
Ok(ok_resp) => {
let possible_json_body = ok_resp.json::<Root>().await;
match possible_json_body {
Ok(wiki_result) => {
wiki_result.parse.links.iter().for_each(|link| {
if link.ns == 0 {
quests.push(WikiQuest {
name: link.field.clone(),
difficulty: difficulty.clone(),
});
}
});
}
});
Err(e) => {
println!("Failed to parse quests from wiki: {}", e);
return Err(e.into());
}
}
}
Err(e) => {
println!("Failed to parse quests from wiki: {}", e);
return Err(e);
return Err(e.into());
}
}
}
Err(e) => {
return Err(e);
}
write_to_cache_with_seconds(
redis_connection,
QUEST_CACHE_KEY,
quests.clone(),
604800,
)
.await;

Ok(quests)
}
}
Ok(quests)
}

#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
Expand Down

0 comments on commit eba2d3e

Please sign in to comment.