generate avatar for users with identicon, cache them

This commit is contained in:
Philippe Loctaux 2023-03-08 00:16:40 +01:00
parent 7ab34825ad
commit 2d714f4220
6 changed files with 358 additions and 3 deletions

View file

@ -10,6 +10,7 @@ rocket_dyn_templates = { version = "0.1.0-rc.2", features = ["tera"] }
infer = { version = "0.12.0", default-features = false }
erased-serde = "0.3"
url = { workspace = true }
identicon-rs = "4.0.1"
# local crates
database_pool = { path = "../database_pool" }

View file

@ -15,7 +15,7 @@ impl Default for CacheControl {
// 60 secs * 60 minutes
duration_secs: 60 * 60,
types: vec![ContentType::CSS, ContentType::JavaScript],
routes: vec!["/logo"],
routes: vec!["/logo", "/avatar/"],
}
}
}

View file

@ -11,6 +11,12 @@ impl From<&[u8]> for FileFromBytes {
}
}
impl From<Vec<u8>> for FileFromBytes {
fn from(value: Vec<u8>) -> Self {
Self(value)
}
}
#[rocket::async_trait]
impl<'r> Responder<'r, 'static> for FileFromBytes {
fn respond_to(self, _: &'r Request<'_>) -> response::Result<'static> {

View file

@ -1,9 +1,10 @@
use super::prelude::*;
use rocket::get;
use settings::Settings;
use users::User;
pub fn routes() -> Vec<Route> {
routes![logo, homepage, redirect_to_setup]
routes![logo, avatar, homepage, redirect_to_setup]
}
#[get("/logo")]
@ -39,6 +40,34 @@ mod test {
}
}
#[get("/avatar/<user_id>?<size>")]
async fn avatar(
mut db: Connection<Database>,
user_id: RocketUserID,
size: Option<u32>,
) -> Result<FileFromBytes> {
// Verify existence of user
let _user = User::get_by_id(&mut *db, &user_id.0).await?;
// Generate avatar
let avatar = task::spawn_blocking(move || {
let mut avatar = identicon_rs::Identicon::new(user_id.0);
// Set optional size
if let Some(size) = size {
avatar.set_scale(size)?;
}
avatar.export_png_data()
})
.await?;
// HTTP response
avatar
.map(FileFromBytes::from)
.map_err(Error::internal_server_error)
}
pub mod content {
use rocket::serde::Serialize;

View file

@ -1,5 +1,18 @@
{% extends "base" %}
{% block content %}
<body>homepage goes here {{ abc }}</body>
<body>
<div class="text-center mb-4">
<a href="/" class="navbar-brand navbar-brand-autodark">
<img src="/logo" height="96" alt="logo">
</a>
</div>
<div>
homepage goes here {{ abc }}
</div>
<div>
<span class="avatar" style="background-image: url(/avatar/8tamxHnWFctAeV7)"></span>
<span class="avatar" style="background-image: url(/avatar/8tamxHnWFctAeV7?size=300)"></span>
</div>
</body>
{% endblock content %}