bobashare_web/api/v1/
info.rsuse axum::{
extract::{Path, State},
response::{IntoResponse, Response},
Json,
};
use bobashare::storage::file::OpenUploadError;
use chrono::{DateTime, Utc};
use displaydoc::Display;
use hyper::StatusCode;
use serde::Serialize;
use thiserror::Error;
use tracing::{event, instrument, Level};
use super::ApiErrorExt;
use crate::AppState;
#[derive(Debug, Clone, Serialize)]
pub struct InfoResponse {
pub id: String,
pub url: String,
pub direct_url: String,
pub filename: String,
pub mimetype: String,
pub creation_date: DateTime<Utc>,
pub expiry_date: Option<DateTime<Utc>>,
}
#[derive(Debug, Error, Display)]
pub enum InfoError {
NotFound,
InternalServer(#[from] anyhow::Error),
}
impl IntoResponse for InfoError {
fn into_response(self) -> Response {
let code = match self {
Self::NotFound => StatusCode::NOT_FOUND,
Self::InternalServer(_) => StatusCode::INTERNAL_SERVER_ERROR,
};
self.into_response_with_code(code)
}
}
#[instrument(skip(state))]
pub async fn info(
state: State<&'static AppState>,
Path(id): Path<String>,
) -> Result<impl IntoResponse, InfoError> {
event!(Level::DEBUG, id, "reading upload metadata");
let metadata = state
.backend
.read_upload_metadata(&id)
.await
.map_err(|e| match e {
OpenUploadError::NotFound(_) => InfoError::NotFound,
e => InfoError::InternalServer(
anyhow::Error::new(e).context("error reading upload metadata"),
),
})?;
let url = state.base_url.join(&id).unwrap().to_string();
let direct_url = state.raw_url.join(&id).unwrap().to_string();
event!(Level::INFO, "successfully queried upload metadata");
Ok(Json(InfoResponse {
id,
url,
direct_url,
filename: metadata.filename,
mimetype: metadata.mimetype.to_string(),
creation_date: metadata.creation_date,
expiry_date: metadata.expiry_date,
}))
}