Rudimentary avatar updater
This commit is contained in:
parent
6f0a4d1316
commit
5e848ffe76
3 changed files with 56 additions and 14 deletions
|
@ -77,6 +77,8 @@ fn http() -> Http {
|
|||
|
||||
async fn rocket() -> Result<Rocket<Ignite>, rocket::Error> {
|
||||
let http = http();
|
||||
let database = load_database();
|
||||
database.refresh_users(&http).await.unwrap();
|
||||
|
||||
let config = rocket::Config::figment().merge(("port", 1313)).merge((
|
||||
"secret_key",
|
||||
|
@ -87,7 +89,7 @@ async fn rocket() -> Result<Rocket<Ignite>, rocket::Error> {
|
|||
rocket::custom(config)
|
||||
.manage(Settings::new(&http).await.unwrap())
|
||||
.manage(http)
|
||||
.manage(load_database())
|
||||
.manage(database)
|
||||
.mount(
|
||||
"/",
|
||||
routes![
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
use std::collections::HashSet;
|
||||
use std::result;
|
||||
use std::{collections::HashMap, fs::File, io::Read, path::Path};
|
||||
|
||||
use derive_more::From;
|
||||
use poise::serenity_prelude::{Http, SerenityError};
|
||||
use poise::serenity_prelude::http::error::ErrorResponse;
|
||||
use poise::serenity_prelude::{Http, HttpError, SerenityError, StatusCode};
|
||||
use r2d2::{Pool, PooledConnection};
|
||||
use r2d2_sqlite::rusqlite::{self, params};
|
||||
use r2d2_sqlite::SqliteConnectionManager;
|
||||
use rocket::error;
|
||||
|
||||
use crate::{models::User, utils::get_challenge_number};
|
||||
|
||||
|
@ -26,7 +29,7 @@ pub enum DatabaseError {
|
|||
}
|
||||
|
||||
#[derive(From, Debug)]
|
||||
pub enum LoadLegacyError {
|
||||
pub enum GenericError {
|
||||
Database(DatabaseError),
|
||||
Serenity(SerenityError),
|
||||
}
|
||||
|
@ -82,7 +85,7 @@ impl Database {
|
|||
.is_ok())
|
||||
}
|
||||
|
||||
pub async fn load_legacy(&self, http: &Http) -> std::result::Result<(), LoadLegacyError> {
|
||||
pub async fn load_legacy(&self, http: &Http) -> std::result::Result<(), GenericError> {
|
||||
let latest_challenge = get_challenge_number();
|
||||
// HashMap of archived users that are no longer sharing a server with 字ちゃん
|
||||
// Their historical usernames and discriminators will be used
|
||||
|
@ -124,12 +127,7 @@ impl Database {
|
|||
},
|
||||
);
|
||||
}
|
||||
Ok(user) => {
|
||||
conn.execute(
|
||||
"INSERT INTO User(id, name, discriminator, avatar, deleted) VALUES (?1, ?2, ?3, ?4, ?5)",
|
||||
params![user.id, user.name, user.discriminator, user.avatar, user.deleted]
|
||||
).map_err(DatabaseError::Rusqlite)?;
|
||||
}
|
||||
Ok(user) => self.insert_user(&user)?,
|
||||
Err(error) if error.to_string().eq("Unknown User") => {
|
||||
// This will also be called in the case of an invalid user ID
|
||||
println!("Failed to fetch user {id}, adding to archive");
|
||||
|
@ -143,7 +141,7 @@ impl Database {
|
|||
},
|
||||
);
|
||||
}
|
||||
Err(error) => return Err(LoadLegacyError::Serenity(error)),
|
||||
Err(error) => return Err(GenericError::Serenity(error)),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -265,11 +263,53 @@ impl Database {
|
|||
.collect()
|
||||
}
|
||||
|
||||
fn get_all_users(&self) -> Result<Vec<User>> {
|
||||
let conn = self.conn()?;
|
||||
let mut stmt = conn.prepare("SELECT id, name, discriminator, avatar, deleted FROM User")?;
|
||||
let result: Vec<Result<User>> = stmt.query_map([], |row| Ok(User {
|
||||
id: row.get(0)?,
|
||||
name: row.get(1)?,
|
||||
discriminator: row.get(2)?,
|
||||
avatar: row.get(3)?,
|
||||
deleted: row.get(4)?,
|
||||
}))?.map(|result| match result {
|
||||
Ok(user) => Ok(user),
|
||||
Err(err) => Err(DatabaseError::Rusqlite(err)),
|
||||
}).collect();
|
||||
result.into_iter().collect()
|
||||
}
|
||||
|
||||
pub fn insert_user(&self, user: &User) -> Result<()> {
|
||||
self.conn()?.execute(
|
||||
"INSERT OR REPLACE INTO User(id, name, discriminator, avatar, deleted) VALUES (?1, ?2, ?3, ?4, ?5)",
|
||||
params![user.id, user.name, user.discriminator, user.avatar, user.deleted]
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn refresh_users(&self) -> rusqlite::Result<()> {
|
||||
pub async fn refresh_users(&self, http: &Http) -> std::result::Result<(), GenericError> {
|
||||
// Periodically refresh all changable user data (name, discriminator, avatar)
|
||||
// Ideally this should run periodically.
|
||||
todo!()
|
||||
let all_users = self.get_all_users()?;
|
||||
for (i, user) in all_users.iter().enumerate() {
|
||||
print!("User {i}/{}, ", all_users.len());
|
||||
let updated = match User::fetch(http, user.id).await {
|
||||
Ok(user) => user,
|
||||
Err(SerenityError::Http(error)) if error.status_code().eq(&Some(StatusCode::NOT_FOUND)) => {
|
||||
println!("not found");
|
||||
continue;
|
||||
},
|
||||
Err(error) => panic!("{error}"),
|
||||
};
|
||||
if user.eq(&updated) {
|
||||
println!("no change");
|
||||
continue;
|
||||
}
|
||||
println!("updated");
|
||||
self.insert_user(&updated)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(dead_code, unused_variables)]
|
||||
|
|
|
@ -19,7 +19,7 @@ pub trait Username {
|
|||
fn username(&self) -> String;
|
||||
}
|
||||
|
||||
#[derive(Default, Deserialize, Debug)]
|
||||
#[derive(Default, Deserialize, Debug, PartialEq, Eq)]
|
||||
pub struct User {
|
||||
#[serde(deserialize_with = "deserialize_id")]
|
||||
pub id: u64,
|
||||
|
|
Loading…
Add table
Reference in a new issue