use rocket::{get, State}; use crate::Pool; use crate::xml::{Xml, YesNoVal}; use crate::error::Errors; use crate::mii_util::MII_PROVIDER_SERVER_URL; use serde::Serialize; use gxhash::gxhash32; #[derive(Serialize)] pub struct MiiImage { pub cached_url: String, pub id: u32, pub url: String, #[serde(rename = "type")] pub image_type: String, } #[derive(Serialize)] pub struct MiiImages { pub image: Vec, } #[derive(Serialize)] pub struct MiiEntry { pub data: String, pub id: u32, pub images: MiiImages, pub name: String, pub pid: i32, pub primary: YesNoVal, pub user_id: String, } #[derive(Serialize)] #[serde(rename = "miis")] pub struct MiisResponse { #[serde(rename = "mii")] pub miis: Vec, } #[get("/v1/api/miis?")] pub async fn get_miis( database: &State, pids: Option, ) -> Result, Option>> { let db = database.inner(); let input = pids.filter(|s| !s.is_empty()).ok_or(None)?; let pid_list: Vec = input .split(',') .filter_map(|s| s.parse::().ok()) .collect(); if pid_list.is_empty() { return Err(None); } let rows = sqlx::query!( "SELECT pid, username, mii_data FROM users WHERE pid = ANY($1)", &pid_list ) .fetch_all(db) .await .map_err(|_| None)?; if rows.is_empty() { return Err(None); } let mut miis = Vec::new(); for row in rows { let clean_mii_data = row.mii_data .replace(['\r', '\n', '\t', ' '], ""); let mii_id = gxhash32(clean_mii_data.as_bytes(), 0); let expression_types = [ ("normal_face.png", "standard"), ("frustrated.png", "frustrated_face"), ("smile_open_mouth.png", "happy_face"), ("wink_left.png", "like_face"), ("normal_face.png", "normal_face"), // pretendo had this duplicated, and i'm not taking any chances ("sorrow.png", "puzzled_face"), ("surprised_open_mouth.png", "surprised_face"), ("body.png", "whole_body"), ]; let images = MiiImages { image: expression_types .iter() .map(|(file, img_type)| { // dummy URL for now let url = format!("{}/{}/{}", &*MII_PROVIDER_SERVER_URL, row.pid, file); MiiImage { cached_url: url.clone(), id: mii_id, url, image_type: img_type.to_string(), } }) .collect(), }; miis.push(MiiEntry { data: clean_mii_data, id: mii_id, images, name: mii::MiiData::read(&row.mii_data) .map(|v| v.name) .unwrap_or_else(|| "Mii".to_string()), pid: row.pid, primary: YesNoVal(true), //assuming true here user_id: row.username, }); } Ok(Xml(MiisResponse { miis })) }