use super::{HandleError, RawResponse, get_pool, handler};
use crate::models::repo::{self, RepoOperation};
use crate::utils::get_rag_path;
use ragit_fs::{
exists,
extension,
file_name,
join3,
join4,
read_bytes,
read_dir,
set_extension,
};
use warp::reply::{Reply, json, with_header};
pub async fn get_image_list(user: String, repo: String, prefix: String, api_key: Option<String>) -> Box<dyn Reply> {
handler(get_image_list_(user, repo, prefix, api_key).await)
}
async fn get_image_list_(user: String, repo: String, prefix: String, api_key: Option<String>) -> RawResponse {
let pool = get_pool().await;
let repo_id = repo::get_id(&user, &repo, pool).await.handle_error(404)?;
repo::check_auth(repo_id, RepoOperation::Read, api_key, pool).await.handle_error(500)?.handle_error(404)?;
let rag_path = get_rag_path(&user, &repo).handle_error(400)?;
if !exists(&rag_path) {
return Err((404, format!("`{user}/{repo}` does not exist")));
}
let image_path = join3(
&rag_path,
"images",
&prefix,
).handle_error(400)?;
let images = read_dir(&image_path, false).unwrap_or(vec![]);
Ok(Box::new(json(
&images.iter().filter_map(
|image| match extension(image) {
Ok(Some(png)) if png == "png" => file_name(image).ok().map(|suffix| format!("{prefix}{suffix}")),
_ => None,
}
).collect::<Vec<String>>(),
)))
}
pub async fn get_image(user: String, repo: String, uid: String, api_key: Option<String>) -> Box<dyn Reply> {
handler(get_image_(user, repo, uid, api_key).await)
}
async fn get_image_(user: String, repo: String, uid: String, api_key: Option<String>) -> RawResponse {
let pool = get_pool().await;
let repo_id = repo::get_id(&user, &repo, pool).await.handle_error(404)?;
repo::check_auth(repo_id, RepoOperation::Read, api_key, pool).await.handle_error(500)?.handle_error(404)?;
let rag_path = get_rag_path(&user, &repo).handle_error(400)?;
let prefix = uid.get(0..2).ok_or_else(|| format!("invalid uid: {uid}")).handle_error(400)?.to_string();
let suffix = uid.get(2..).ok_or_else(|| format!("invalid uid: {uid}")).handle_error(400)?.to_string();
let image_path = join4(
&rag_path,
"images",
&prefix,
&set_extension(&suffix, "png").handle_error(400)?,
).handle_error(400)?;
let bytes = read_bytes(&image_path).handle_error(404)?;
Ok(Box::new(with_header(
bytes,
"Content-Type",
"image/png",
)))
}
pub async fn get_image_desc(user: String, repo: String, uid: String, api_key: Option<String>) -> Box<dyn Reply> {
handler(get_image_desc_(user, repo, uid, api_key).await)
}
async fn get_image_desc_(user: String, repo: String, uid: String, api_key: Option<String>) -> RawResponse {
let pool = get_pool().await;
let repo_id = repo::get_id(&user, &repo, pool).await.handle_error(404)?;
repo::check_auth(repo_id, RepoOperation::Read, api_key, pool).await.handle_error(500)?.handle_error(404)?;
let rag_path = get_rag_path(&user, &repo).handle_error(404)?;
let prefix = uid.get(0..2).ok_or_else(|| format!("invalid uid: {uid}")).handle_error(400)?.to_string();
let suffix = uid.get(2..).ok_or_else(|| format!("invalid uid: {uid}")).handle_error(400)?.to_string();
let image_path = join4(
&rag_path,
"images",
&prefix,
&set_extension(&suffix, "json").handle_error(400)?,
).handle_error(400)?;
let bytes = read_bytes(&image_path).handle_error(404)?;
Ok(Box::new(with_header(
bytes,
"Content-Type",
"application/json",
)))
}