Periodically refresh user list every hour
This commit is contained in:
parent
5e848ffe76
commit
c202e4e250
7 changed files with 35 additions and 25 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -3358,6 +3358,7 @@ dependencies = [
|
||||||
"dotenv",
|
"dotenv",
|
||||||
"gettext",
|
"gettext",
|
||||||
"gh-emoji",
|
"gh-emoji",
|
||||||
|
"lazy_static",
|
||||||
"poise",
|
"poise",
|
||||||
"r2d2",
|
"r2d2",
|
||||||
"r2d2_sqlite",
|
"r2d2_sqlite",
|
||||||
|
|
|
@ -14,6 +14,7 @@ derive_more = { version = "2.0", features = ["full"] }
|
||||||
dotenv = "0.15"
|
dotenv = "0.15"
|
||||||
gettext = "0.4"
|
gettext = "0.4"
|
||||||
gh-emoji = "1.0"
|
gh-emoji = "1.0"
|
||||||
|
lazy_static = "1.5.0"
|
||||||
poise = "0.5" # TODO: update to 0.6
|
poise = "0.5" # TODO: update to 0.6
|
||||||
r2d2 = "0.8"
|
r2d2 = "0.8"
|
||||||
r2d2_sqlite = "0.27"
|
r2d2_sqlite = "0.27"
|
||||||
|
|
|
@ -4,11 +4,12 @@ extern crate rocket;
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
use poise::serenity_prelude::Http;
|
use poise::serenity_prelude::Http;
|
||||||
use rocket::{
|
use rocket::{
|
||||||
fs::{relative, FileServer},
|
fs::{relative, FileServer}, futures::task, Ignite, Rocket
|
||||||
Ignite, Rocket,
|
|
||||||
};
|
};
|
||||||
use rocket_dyn_templates::{tera, Template};
|
use rocket_dyn_templates::{tera, Template};
|
||||||
use std::{collections::HashMap, env};
|
use tokio::time;
|
||||||
|
use std::{collections::HashMap, env, time::Duration};
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
mod models;
|
mod models;
|
||||||
use models::{Database, Settings};
|
use models::{Database, Settings};
|
||||||
|
@ -61,6 +62,15 @@ async fn main() {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
|
tokio::task::spawn(async {
|
||||||
|
let mut interval = time::interval(Duration::from_millis(60 * 60 * 1000)); // every hour
|
||||||
|
loop {
|
||||||
|
if let Err(err) = DATABASE.refresh_users(&HTTP).await {
|
||||||
|
error!("{:?}", err);
|
||||||
|
}
|
||||||
|
interval.tick().await;
|
||||||
|
}
|
||||||
|
});
|
||||||
rocket().await.expect("Failed to launch rocket");
|
rocket().await.expect("Failed to launch rocket");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,11 +85,12 @@ fn http() -> Http {
|
||||||
Http::new(&token)
|
Http::new(&token)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn rocket() -> Result<Rocket<Ignite>, rocket::Error> {
|
lazy_static! {
|
||||||
let http = http();
|
static ref DATABASE: Database = load_database();
|
||||||
let database = load_database();
|
static ref HTTP: Http = http();
|
||||||
database.refresh_users(&http).await.unwrap();
|
}
|
||||||
|
|
||||||
|
async fn rocket() -> Result<Rocket<Ignite>, rocket::Error> {
|
||||||
let config = rocket::Config::figment().merge(("port", 1313)).merge((
|
let config = rocket::Config::figment().merge(("port", 1313)).merge((
|
||||||
"secret_key",
|
"secret_key",
|
||||||
env::var("SECRET")
|
env::var("SECRET")
|
||||||
|
@ -87,9 +98,8 @@ async fn rocket() -> Result<Rocket<Ignite>, rocket::Error> {
|
||||||
));
|
));
|
||||||
|
|
||||||
rocket::custom(config)
|
rocket::custom(config)
|
||||||
.manage(Settings::new(&http).await.unwrap())
|
.manage(Settings::new(&HTTP).await.unwrap())
|
||||||
.manage(http)
|
// .manage(http)
|
||||||
.manage(database)
|
|
||||||
.mount(
|
.mount(
|
||||||
"/",
|
"/",
|
||||||
routes![
|
routes![
|
||||||
|
|
|
@ -6,8 +6,8 @@ use rocket_dyn_templates::{context, Template};
|
||||||
use crate::{
|
use crate::{
|
||||||
cookies::LANG_COOKIE,
|
cookies::LANG_COOKIE,
|
||||||
i18n::DEFAULT as DEFAULT_LANG,
|
i18n::DEFAULT as DEFAULT_LANG,
|
||||||
models::{Challenge, Database, SessionUser, Settings},
|
models::{Challenge, SessionUser, Settings},
|
||||||
utils::AcceptLanguage,
|
utils::AcceptLanguage, DATABASE,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[get("/<challenge>")]
|
#[get("/<challenge>")]
|
||||||
|
@ -15,10 +15,9 @@ pub async fn get_challenge(
|
||||||
challenge: u32,
|
challenge: u32,
|
||||||
cookies: &CookieJar<'_>,
|
cookies: &CookieJar<'_>,
|
||||||
settings: &State<Settings>,
|
settings: &State<Settings>,
|
||||||
database: &State<Database>,
|
|
||||||
accept_language: AcceptLanguage,
|
accept_language: AcceptLanguage,
|
||||||
) -> Template {
|
) -> Template {
|
||||||
let (submissions, users) = database.get_challenge_user_data(challenge).unwrap();
|
let (submissions, users) = DATABASE.get_challenge_user_data(challenge).unwrap();
|
||||||
Template::render(
|
Template::render(
|
||||||
"challenge",
|
"challenge",
|
||||||
context! {
|
context! {
|
||||||
|
|
|
@ -2,6 +2,7 @@ use poise::serenity_prelude::Http;
|
||||||
use rocket::response::stream::{Event, EventStream};
|
use rocket::response::stream::{Event, EventStream};
|
||||||
use rocket::{http::CookieJar, State};
|
use rocket::{http::CookieJar, State};
|
||||||
|
|
||||||
|
use crate::HTTP;
|
||||||
use crate::{cookies::user::USER_ID_COOKIE, models::Settings};
|
use crate::{cookies::user::USER_ID_COOKIE, models::Settings};
|
||||||
|
|
||||||
// TODO: Incrementally send guilds
|
// TODO: Incrementally send guilds
|
||||||
|
@ -9,7 +10,6 @@ use crate::{cookies::user::USER_ID_COOKIE, models::Settings};
|
||||||
pub async fn get_guilds<'a>(
|
pub async fn get_guilds<'a>(
|
||||||
cookies: &'a CookieJar<'_>,
|
cookies: &'a CookieJar<'_>,
|
||||||
settings: &'a State<Settings>,
|
settings: &'a State<Settings>,
|
||||||
http: &'a State<Http>,
|
|
||||||
) -> EventStream![Event + 'a] {
|
) -> EventStream![Event + 'a] {
|
||||||
// EventStream![] is shorthand for EventStream[Event],
|
// EventStream![] is shorthand for EventStream[Event],
|
||||||
// but we need to pass in a lifetime parameter.
|
// but we need to pass in a lifetime parameter.
|
||||||
|
@ -28,7 +28,7 @@ pub async fn get_guilds<'a>(
|
||||||
if guild.hidden {
|
if guild.hidden {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
yield Event::data(format!("{},{}", guild.id, http.get_member(guild.id, user_id).await.is_ok()));
|
yield Event::data(format!("{},{}", guild.id, HTTP.get_member(guild.id, user_id).await.is_ok()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,8 @@ use rocket_dyn_templates::{context, Template};
|
||||||
use crate::{
|
use crate::{
|
||||||
cookies::LANG_COOKIE,
|
cookies::LANG_COOKIE,
|
||||||
i18n::DEFAULT as DEFAULT_LANG,
|
i18n::DEFAULT as DEFAULT_LANG,
|
||||||
models::{Database, DatabaseError, SessionUser, Settings},
|
models::{DatabaseError, SessionUser, Settings},
|
||||||
utils::AcceptLanguage,
|
utils::AcceptLanguage, DATABASE,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[get("/users/<user>")]
|
#[get("/users/<user>")]
|
||||||
|
@ -18,10 +18,9 @@ pub async fn get_user(
|
||||||
user: String,
|
user: String,
|
||||||
cookies: &CookieJar<'_>,
|
cookies: &CookieJar<'_>,
|
||||||
settings: &State<Settings>,
|
settings: &State<Settings>,
|
||||||
database: &State<Database>,
|
|
||||||
accept_language: AcceptLanguage,
|
accept_language: AcceptLanguage,
|
||||||
) -> Result<Template, Status> {
|
) -> Result<Template, Status> {
|
||||||
let profile_user = match database.get_user_by_name(&user) {
|
let profile_user = match DATABASE.get_user_by_name(&user) {
|
||||||
Ok(profile_user) => profile_user,
|
Ok(profile_user) => profile_user,
|
||||||
Err(DatabaseError::Rusqlite(rusqlite::Error::QueryReturnedNoRows)) => {
|
Err(DatabaseError::Rusqlite(rusqlite::Error::QueryReturnedNoRows)) => {
|
||||||
return Err(Status::NotFound)
|
return Err(Status::NotFound)
|
||||||
|
@ -35,7 +34,7 @@ pub async fn get_user(
|
||||||
"user",
|
"user",
|
||||||
context! {
|
context! {
|
||||||
profile_user,
|
profile_user,
|
||||||
submissions: database.get_submissions_by_user_name(&user).unwrap(),
|
submissions: DATABASE.get_submissions_by_user_name(&user).unwrap(),
|
||||||
settings: settings.deref(),
|
settings: settings.deref(),
|
||||||
lang: cookies
|
lang: cookies
|
||||||
.get(LANG_COOKIE)
|
.get(LANG_COOKIE)
|
||||||
|
|
|
@ -3,18 +3,18 @@ use std::ops::Deref;
|
||||||
use poise::serenity_prelude::Http;
|
use poise::serenity_prelude::Http;
|
||||||
use rocket::{http::CookieJar, State};
|
use rocket::{http::CookieJar, State};
|
||||||
|
|
||||||
use crate::models::SessionUser;
|
use crate::{models::SessionUser, HTTP};
|
||||||
|
|
||||||
#[get("/testing")]
|
#[get("/testing")]
|
||||||
pub async fn testing(cookies: &CookieJar<'_>, http: &State<Http>) -> String {
|
pub async fn testing(cookies: &CookieJar<'_>) -> String {
|
||||||
// Get logged in user's join date in 字ちゃん server
|
// Get logged in user's join date in 字ちゃん server
|
||||||
format!(
|
format!(
|
||||||
"{:?}",
|
"{:?}",
|
||||||
http.get_guild(814700630958276649)
|
HTTP.get_guild(814700630958276649)
|
||||||
.await
|
.await
|
||||||
.expect("Failed to get testing guild")
|
.expect("Failed to get testing guild")
|
||||||
.member(
|
.member(
|
||||||
http.deref(),
|
HTTP.deref(),
|
||||||
SessionUser::get(cookies)
|
SessionUser::get(cookies)
|
||||||
.await
|
.await
|
||||||
.expect("Failed to get logged in user data")
|
.expect("Failed to get logged in user data")
|
||||||
|
|
Loading…
Add table
Reference in a new issue