Skip to content

Commit

Permalink
support preview for flists in server
Browse files Browse the repository at this point in the history
  • Loading branch information
rawdaGastan committed Aug 19, 2024
1 parent f867407 commit 74679fa
Show file tree
Hide file tree
Showing 5 changed files with 209 additions and 141 deletions.
4 changes: 2 additions & 2 deletions fl-server/src/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ use serde::{Deserialize, Serialize};
use crate::auth::{SignInBody, SignInResponse, __path_sign_in_handler};
use crate::{
config::{self, Job},
response::{ResponseError, ResponseResult},
serve_flists::{visit_dir_one_level, FileInfo},
response::{FileInfo, ResponseError, ResponseResult},
serve_flists::visit_dir_one_level,
};
use rfs::fungi::Writer;
use utoipa::{OpenApi, ToSchema};
Expand Down
116 changes: 111 additions & 5 deletions fl-server/src/response.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
use std::collections::HashMap;

use askama::Template;
use axum::{
body::Body,
http::StatusCode,
response::{IntoResponse, Response},
response::{Html, IntoResponse, Response},
Json,
};
use serde::{Deserialize, Serialize};
use serde::Serialize;
use utoipa::ToSchema;

use crate::{auth::SignInResponse, config::Job, handlers::FlistState, serve_flists::FileInfo};
use crate::{auth::SignInResponse, config::Job, handlers::FlistState};

#[derive(Serialize, Deserialize, ToSchema)]
#[derive(Serialize, ToSchema)]
pub enum ResponseError {
InternalServerError,
Conflict(String),
NotFound(String),
Unauthorized(String),
BadRequest(String),
Forbidden(String),
TemplateError(ErrorTemplate),
}

impl IntoResponse for ResponseError {
Expand All @@ -32,17 +34,51 @@ impl IntoResponse for ResponseError {
ResponseError::Unauthorized(msg) => (StatusCode::UNAUTHORIZED, msg).into_response(),
ResponseError::BadRequest(msg) => (StatusCode::BAD_REQUEST, msg).into_response(),
ResponseError::Forbidden(msg) => (StatusCode::FORBIDDEN, msg).into_response(),
ResponseError::TemplateError(t) => match t.render() {
Ok(html) => {
let mut resp = Html(html).into_response();
match t.err {
TemplateErr::NotFound(reason) => {
*resp.status_mut() = StatusCode::NOT_FOUND;
resp.headers_mut()
.insert(FAIL_REASON_HEADER_NAME, reason.parse().unwrap());
}
TemplateErr::BadRequest(reason) => {
*resp.status_mut() = StatusCode::BAD_REQUEST;
resp.headers_mut()
.insert(FAIL_REASON_HEADER_NAME, reason.parse().unwrap());
}
TemplateErr::InternalServerError(reason) => {
*resp.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
resp.headers_mut()
.insert(FAIL_REASON_HEADER_NAME, reason.parse().unwrap());
}
}
resp
}
Err(err) => {
tracing::error!("template render failed, err={}", err);
(
StatusCode::INTERNAL_SERVER_ERROR,
format!("Failed to render template. Error: {}", err),
)
.into_response()
}
},
}
}
}

#[derive(Serialize, ToSchema)]
#[derive(ToSchema)]
pub enum ResponseResult {
Health,
FlistCreated(Job),
FlistState(FlistState),
Flists(HashMap<String, Vec<FileInfo>>),
PreviewFlist(Vec<String>),
SignedIn(SignInResponse),
DirTemplate(DirListTemplate),
Res(hyper::Response<tower_http::services::fs::ServeFileSystemResponseBody>),
}

impl IntoResponse for ResponseResult {
Expand All @@ -69,6 +105,76 @@ impl IntoResponse for ResponseResult {
ResponseResult::Flists(flists) => {
(StatusCode::OK, Json(serde_json::json!(flists))).into_response()
}
ResponseResult::PreviewFlist(content) => {
(StatusCode::OK, Json(serde_json::json!(content))).into_response()
}
ResponseResult::DirTemplate(t) => match t.render() {
Ok(html) => Html(html).into_response(),
Err(err) => {
tracing::error!("template render failed, err={}", err);
(
StatusCode::INTERNAL_SERVER_ERROR,
format!("Failed to render template. Error: {}", err),
)
.into_response()
}
},
ResponseResult::Res(res) => res.map(axum::body::Body::new),
}
}
}

//////// TEMPLATES ////////

#[derive(Serialize, ToSchema)]
pub struct FileInfo {
pub name: String,
pub path_uri: String,
pub is_file: bool,
pub size: u64,
pub last_modified: i64,
pub progress: f32,
}

#[derive(Serialize, ToSchema)]
pub struct DirLister {
pub files: Vec<FileInfo>,
}

#[derive(Template, Serialize, ToSchema)]
#[template(path = "index.html")]
pub struct DirListTemplate {
pub lister: DirLister,
pub cur_path: String,
}

mod filters {
pub(crate) fn datetime(ts: &i64) -> ::askama::Result<String> {
if let Ok(format) =
time::format_description::parse("[year]-[month]-[day] [hour]:[minute]:[second] UTC")
{
return Ok(time::OffsetDateTime::from_unix_timestamp(*ts)
.unwrap()
.format(&format)
.unwrap());
}
Err(askama::Error::Fmt(std::fmt::Error))
}
}

#[derive(Template, Serialize, ToSchema)]
#[template(path = "error.html")]
pub struct ErrorTemplate {
pub err: TemplateErr,
pub cur_path: String,
pub message: String,
}

const FAIL_REASON_HEADER_NAME: &str = "fl-server-fail-reason";

#[derive(Serialize, ToSchema)]
pub enum TemplateErr {
BadRequest(String),
NotFound(String),
InternalServerError(String),
}
Loading

0 comments on commit 74679fa

Please sign in to comment.