Implement /pgen/3
authorMegaBrutal <code+git@megabrutal.com>
Sat, 15 Oct 2022 16:45:45 +0000 (18:45 +0200)
committerMegaBrutal <code+git@megabrutal.com>
Sat, 15 Oct 2022 16:45:45 +0000 (18:45 +0200)
src/main.rs

index 8653ec3d9da8d766f2c7ae43a6088fa52a9cfe2d..5ade30f73af82626af7100dd08d06d66ff51e4c6 100644 (file)
@@ -17,6 +17,9 @@ use image::error::{LimitError, LimitErrorKind};
 use actix_web::cookie::time::OffsetDateTime;
 
 
+const TIMEAVATAR_SIZE_U32: u32 = 6;
+const TIMEAVATAR_SIZE_I64: i64 = TIMEAVATAR_SIZE_U32 as i64;
+
 #[derive(Debug)]
 struct ImageError(image::ImageError);
 
@@ -149,6 +152,7 @@ impl Canvas {
 
 struct Canvas0(Option<Canvas>);
 struct Canvas1(Option<Canvas>);
+struct Canvas2(Option<Canvas>);
 
 #[get("/hello/{name}")]
 async fn greet(name: web::Path<String>, req: HttpRequest) -> impl Responder {
@@ -272,10 +276,11 @@ async fn img_gen3(req: HttpRequest, path: web::Path<u32>) -> Result<impl Respond
         Some(header) => header.to_str().unwrap_or(""),
         _ => ""
     };
-    let rgbimg: RgbImage = rgb_encode(ImageBuffer::new(6, 6), &mut data.bytes())?;
-    let mut resimg: RgbImage = ImageBuffer::new(60 * 6, 24 * 6);
+    let rgbimg: RgbImage = rgb_encode(ImageBuffer::new(TIMEAVATAR_SIZE_U32, TIMEAVATAR_SIZE_U32), &mut data.bytes())?;
+    let mut resimg: RgbImage = ImageBuffer::new(60 * TIMEAVATAR_SIZE_U32, 24 * TIMEAVATAR_SIZE_U32);
     let time = OffsetDateTime::now_utc().time();
-    overlay(&mut resimg, &rgbimg, (time.minute() * 6).into(), (time.hour() * 6).into());
+    let (hour, minute): (i64, i64) = (time.hour().into(), time.minute().into());
+    overlay(&mut resimg, &rgbimg, minute * TIMEAVATAR_SIZE_I64, hour * TIMEAVATAR_SIZE_I64);
     let cursor = image_to_cursor(resimg, scale)?;
     Ok(HttpResponse::build(StatusCode::OK)
        .content_type("image/png")
@@ -327,12 +332,42 @@ async fn img_pgen2(req: HttpRequest, path: web::Path<(u32, u32, u32)>, canvas1:
        .body(cursor.into_inner()))
 }
 
+#[get("/pgen/3/{scale}")]
+async fn img_pgen3(req: HttpRequest, path: web::Path<u32>, canvas2: web::Data<Arc<Mutex<Canvas2>>>) -> Result<impl Responder> {
+    let scale = path.into_inner();
+    let data = match req.headers().get("user-agent") {
+        Some(header) => header.to_str().unwrap_or(""),
+        _ => ""
+    };
+    let time = OffsetDateTime::now_utc().time();
+    let (hour, minute): (i64, i64) = (time.hour().into(), time.minute().into());
+    let rgbimg: RgbImage = rgb_encode(ImageBuffer::new(TIMEAVATAR_SIZE_U32, TIMEAVATAR_SIZE_U32), &mut data.bytes())?;
+    let resimg: RgbImage = ({
+        let canvas_option = &mut *canvas2.lock().unwrap();
+        let mut canvas = match canvas_option.0.take() {
+            Some(canvas) => canvas,
+            None => Canvas::new(60 * TIMEAVATAR_SIZE_U32, 24 * TIMEAVATAR_SIZE_U32)
+        };
+        overlay(&mut canvas.img, &rgbimg, minute * TIMEAVATAR_SIZE_I64, hour * TIMEAVATAR_SIZE_I64);
+        Ok(canvas_option.0.insert(canvas).img.clone())
+    } as Result<RgbImage, CanvasError>)?;
+    let cursor = image_to_cursor(resimg, scale)?;
+    Ok(HttpResponse::build(StatusCode::OK)
+       .content_type("image/png")
+       .body(cursor.into_inner()))
+}
+
 #[get("/pdrop/{canvas_id}")]
-async fn pdrop(canvas_id: web::Path<u8>, canvas0: web::Data<Arc<Mutex<Canvas0>>>, canvas1: web::Data<Arc<Mutex<Canvas1>>>) -> Result<impl Responder> {
+async fn pdrop(canvas_id: web::Path<u8>,
+    canvas0: web::Data<Arc<Mutex<Canvas0>>>,
+    canvas1: web::Data<Arc<Mutex<Canvas1>>>,
+    canvas2: web::Data<Arc<Mutex<Canvas2>>>) -> Result<impl Responder> {
+
     let canvas_id = canvas_id.into_inner();
     match canvas_id {
         0 => canvas0.lock().unwrap().0.take(),
         1 => canvas1.lock().unwrap().0.take(),
+        2 => canvas2.lock().unwrap().0.take(),
         _ => None
     }.ok_or_else( || CanvasError::NotExists )?;
     Ok(HttpResponse::build(StatusCode::OK)
@@ -345,6 +380,7 @@ async fn main() -> std::io::Result<()> {
     env_logger::init();
     let canvas0 = Arc::new(Mutex::new(Canvas0(Some(Canvas::new(32, 32)))));
     let canvas1 = Arc::new(Mutex::new(Canvas1(None)));
+    let canvas2 = Arc::new(Mutex::new(Canvas2(None)));
     HttpServer::new(move || {
         App::new()
             .service(greet)
@@ -355,9 +391,11 @@ async fn main() -> std::io::Result<()> {
             .service(img_pgen0)
             .service(img_pgen1)
             .service(img_pgen2)
+            .service(img_pgen3)
             .service(pdrop)
             .app_data(web::Data::new(canvas0.clone()))
             .app_data(web::Data::new(canvas1.clone()))
+            .app_data(web::Data::new(canvas2.clone()))
     })
     .bind(("127.0.0.1", 8080))?
     .run()