Rudimentary avatar updater

This commit is contained in:
Elnu 2025-03-27 23:27:10 -07:00
parent 6f0a4d1316
commit 5e848ffe76
3 changed files with 56 additions and 14 deletions

View file

@ -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![

View file

@ -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)]

View file

@ -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,