generate avatar for users with identicon, cache them
This commit is contained in:
parent
7ab34825ad
commit
2d714f4220
6 changed files with 358 additions and 3 deletions
|
|
@ -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" }
|
||||
|
|
|
|||
|
|
@ -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/"],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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> {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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 %}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue