All checks were successful
Build and Test / cache-mii (push) Successful in 3m1s
147 lines
5.3 KiB
Rust
147 lines
5.3 KiB
Rust
use dotenvy::dotenv;
|
|
use rocket::fs::NamedFile;
|
|
use rocket::State;
|
|
use rocket::http::Status;
|
|
use reqwest::Client;
|
|
use bytes::Bytes;
|
|
|
|
static MII_RENDERER_URL: &str = "https://mii-renderer.bloxerhd.co.uk";
|
|
|
|
async fn request_mii_render(client: &State<Client>, mii_data: &str, ext: &str) -> Result<Bytes, (Status, String)> {
|
|
let req_str = format!("{MII_RENDERER_URL}/miis/image.{ext}?data={mii_data}");
|
|
|
|
let response = client.get(req_str)
|
|
.send()
|
|
.await;
|
|
|
|
match response {
|
|
Ok(res) => {
|
|
let status = res.status();
|
|
|
|
if !status.is_success() {
|
|
let text = res.text().await.unwrap_or_default();
|
|
println!("Error Returned from Renderer: ({}) {text}", status.as_u16());
|
|
return Err((Status::new(status.as_u16()), format!("Error Returned from Renderer: {text}")))
|
|
}
|
|
|
|
let bytes = res.bytes().await;
|
|
match bytes {
|
|
Ok(bytes) => {
|
|
Ok(bytes)
|
|
},
|
|
Err(e) => {
|
|
println!("Error Parsing Response Bytes: {e}");
|
|
Err((Status::new(e.status().unwrap().as_u16()), "Error Parsing Response Bytes".into()))
|
|
}
|
|
}
|
|
},
|
|
Err(e) => {
|
|
println!("Transport Error getting Render: {e}");
|
|
Err((Status::new(e.status().unwrap().as_u16()), "Transport Error getting Render".into()))
|
|
}
|
|
}
|
|
}
|
|
|
|
#[rocket::get("/<pid>/<path>")]
|
|
pub async fn mii_render(pid: i32, path: &str, client: &State<Client>) -> Result<NamedFile, (Status, String)> {
|
|
let ext = path.splitn(2, ".").nth(1).unwrap_or(".png");
|
|
|
|
let mii_data = {
|
|
let route = format!("https://account.spfn.net/api/v2/users/{pid}/mii");
|
|
let response = client.get(route)
|
|
.send()
|
|
.await;
|
|
|
|
let response = match response {
|
|
Ok(res) => {
|
|
let status = res.status();
|
|
|
|
if !status.is_success() {
|
|
let text = res.text().await.unwrap_or_default();
|
|
|
|
return Err((Status::new(status.as_u16()), format!("Error Returned from Renderer: {text}")))
|
|
}
|
|
|
|
res
|
|
},
|
|
Err(e) => {
|
|
println!("Transport Error fetching Mii Data: {e}");
|
|
return Err(((Status::new(e.status().unwrap().as_u16())), "Transport Error fetching Mii Data".into()))
|
|
}
|
|
};
|
|
|
|
let data: String = match response.json().await {
|
|
Ok(data) => data,
|
|
Err(e) => return Err((Status::new(e.status().unwrap().as_u16()), "Error Parsing Json Response when fetching Mii Data".into())),
|
|
};
|
|
|
|
data
|
|
};
|
|
|
|
let cache_path = std::path::Path::new("miis/").join(pid.to_string());
|
|
let img_path = cache_path.clone().join(path);
|
|
let data_path = cache_path.clone().join("data");
|
|
|
|
// Update Cache
|
|
if cache_path.exists() && cache_path.is_dir() { // Mii data was previously cached - Verify it is correct
|
|
if data_path.exists() && data_path.is_file() { // Data exists - Check if it's the same
|
|
let cache_data = std::fs::read_to_string(&data_path);
|
|
|
|
match cache_data {
|
|
Ok(hash) => {
|
|
if hash == mii_data { // Cached images are correct
|
|
if !img_path.exists() || !img_path.is_file() { // File type was not found - Request data
|
|
let img_data = request_mii_render(client, &mii_data, ext).await?;
|
|
let _ = std::fs::write(&img_path, &img_data);
|
|
}
|
|
} else { // Cached images are outdated - Update data
|
|
let img_data = request_mii_render(client, &mii_data, ext).await?;
|
|
let _ = std::fs::write(&img_path, &img_data);
|
|
};
|
|
}
|
|
|
|
Err(_) => { // Data cannot be read - Request data
|
|
let _ = std::fs::write(data_path, &mii_data);
|
|
|
|
let img_data = request_mii_render(client, &mii_data, ext).await?;
|
|
let _ = std::fs::write(&img_path, &img_data);
|
|
}
|
|
}
|
|
} else { // Data isn't saved - Request data
|
|
let _ = std::fs::write(data_path, &mii_data);
|
|
|
|
let img_file = request_mii_render(client, &mii_data, ext).await?;
|
|
let _ = std::fs::write(&img_path, &img_file);
|
|
}
|
|
} else { // Mii data was never cached - Request data
|
|
let _ = std::fs::create_dir(format!("miis/{}", pid.to_string()));
|
|
|
|
let _ = std::fs::write(data_path, &mii_data);
|
|
|
|
let img_data = request_mii_render(client, &mii_data, ext).await?;
|
|
let _ = std::fs::write(&img_path, &img_data);
|
|
};
|
|
|
|
let img = match NamedFile::open(img_path).await {
|
|
Ok(img) => img,
|
|
Err(_) => return Err((Status::InternalServerError, "Failed to Open Image File".into())),
|
|
};
|
|
|
|
Ok(img)
|
|
}
|
|
|
|
#[rocket::launch]
|
|
async fn launch() -> _ {
|
|
dotenv().ok();
|
|
|
|
let client = Client::new();
|
|
|
|
let mii_path = std::path::Path::new("miis");
|
|
if !mii_path.exists() || !mii_path.is_dir() {
|
|
let _ = std::fs::create_dir("miis");
|
|
}
|
|
|
|
rocket::build()
|
|
.manage(client)
|
|
.mount("/", rocket::routes![mii_render])
|
|
}
|