Compare commits
2 Commits
56d7fae43c
...
1bb6bd78e6
Author | SHA1 | Date |
---|---|---|
Savanni D'Gerinel | 1bb6bd78e6 | |
Savanni D'Gerinel | f4b3e811fc |
|
@ -133,3 +133,22 @@ impl Html for Button {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct Image {
|
||||||
|
path: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Image {
|
||||||
|
pub fn new(path: &str) -> Self {
|
||||||
|
Self {
|
||||||
|
path: path.to_owned(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Html for Image {
|
||||||
|
fn to_html_string(&self) -> String {
|
||||||
|
format!("<img src={path} />", path = self.path,)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ use http::status::StatusCode;
|
||||||
// use orizentic::{Permissions, ResourceName, Secret};
|
// use orizentic::{Permissions, ResourceName, Secret};
|
||||||
use build_html::Html;
|
use build_html::Html;
|
||||||
use std::{
|
use std::{
|
||||||
|
io::Read,
|
||||||
net::{IpAddr, Ipv4Addr, SocketAddr},
|
net::{IpAddr, Ipv4Addr, SocketAddr},
|
||||||
path::Path,
|
path::Path,
|
||||||
sync::{Arc, RwLock},
|
sync::{Arc, RwLock},
|
||||||
|
@ -45,71 +46,6 @@ pub fn compare_etags(info: FileInfo, etag_list: &headers::IfNoneMatch) -> bool {
|
||||||
mod files {
|
mod files {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub struct IndexHandler {
|
|
||||||
pub app: Arc<RwLock<App>>,
|
|
||||||
pub template: Template,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize)]
|
|
||||||
pub enum TemplateFile {
|
|
||||||
#[serde(rename = "error")]
|
|
||||||
Error { error: String },
|
|
||||||
#[serde(rename = "file")]
|
|
||||||
File {
|
|
||||||
id: String,
|
|
||||||
size: u64,
|
|
||||||
date: String,
|
|
||||||
type_: String,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize)]
|
|
||||||
pub struct IndexTemplateParams {
|
|
||||||
files: Vec<TemplateFile>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Handler for IndexHandler {
|
|
||||||
fn handle(&self, req: &mut Request) -> IronResult<Response> {
|
|
||||||
let app = self.app.read().unwrap();
|
|
||||||
let m_token = req.extensions.get::<Authentication>();
|
|
||||||
match m_token {
|
|
||||||
Some(token) => {
|
|
||||||
if token.check_authorizations(is_admin) {
|
|
||||||
let files: Vec<TemplateFile> = app
|
|
||||||
.list_files()
|
|
||||||
.into_iter()
|
|
||||||
.map(|entry| match entry {
|
|
||||||
Ok(file) => TemplateFile::File {
|
|
||||||
id: file.info().id,
|
|
||||||
size: file.info().size,
|
|
||||||
date: format!(
|
|
||||||
"{}",
|
|
||||||
file.info().created.format("%Y-%m-%d %H:%M:%S")
|
|
||||||
),
|
|
||||||
type_: file.info().file_type,
|
|
||||||
},
|
|
||||||
Err(err) => TemplateFile::Error {
|
|
||||||
error: format!("{}", err),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
Ok(Response::with((
|
|
||||||
status::Ok,
|
|
||||||
Header(headers::ContentType::html()),
|
|
||||||
Header(headers::SetCookie(vec![format!("auth={}", token.text)])),
|
|
||||||
self.template
|
|
||||||
.render_to_string(&IndexTemplateParams { files })
|
|
||||||
.expect("the template to render"),
|
|
||||||
)))
|
|
||||||
} else {
|
|
||||||
Ok(Response::with(status::Forbidden))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => Ok(Response::with(status::Forbidden)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct GetHandler {
|
pub struct GetHandler {
|
||||||
pub app: Arc<RwLock<App>>,
|
pub app: Arc<RwLock<App>>,
|
||||||
}
|
}
|
||||||
|
@ -295,14 +231,6 @@ pub async fn main() {
|
||||||
let auth_middleware = Authentication::new(secret, auth_db_path);
|
let auth_middleware = Authentication::new(secret, auth_db_path);
|
||||||
|
|
||||||
let mut router = Router::new();
|
let mut router = Router::new();
|
||||||
router.get(
|
|
||||||
"/",
|
|
||||||
files::IndexHandler {
|
|
||||||
app: app.clone(),
|
|
||||||
template: compile_path("templates/index.html").expect("the template to compile"),
|
|
||||||
},
|
|
||||||
"index",
|
|
||||||
);
|
|
||||||
|
|
||||||
router.get(
|
router.get(
|
||||||
"/:id",
|
"/:id",
|
||||||
|
@ -319,12 +247,6 @@ pub async fn main() {
|
||||||
"get-file",
|
"get-file",
|
||||||
);
|
);
|
||||||
|
|
||||||
router.get(
|
|
||||||
"/:id/tn",
|
|
||||||
files::GetThumbnailHandler { app: app.clone() },
|
|
||||||
"get-thumbnail",
|
|
||||||
);
|
|
||||||
|
|
||||||
router.post("/", files::PostHandler { app: app.clone() }, "upload-file");
|
router.post("/", files::PostHandler { app: app.clone() }, "upload-file");
|
||||||
|
|
||||||
router.delete(
|
router.delete(
|
||||||
|
@ -371,7 +293,37 @@ pub async fn main() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let server = warp::serve(root);
|
let thumbnail = warp::path!(String / "tn")
|
||||||
|
.and(warp::header::optional::<String>("if-none-match"))
|
||||||
|
.map({
|
||||||
|
let app = app.clone();
|
||||||
|
move |id: String, old_etags: Option<String>| {
|
||||||
|
let mut content = Vec::new();
|
||||||
|
match app.read().unwrap().get_thumbnail(&id) {
|
||||||
|
Ok((info, mut stream)) => match old_etags {
|
||||||
|
Some(old_etags) if old_etags != info.hash => {
|
||||||
|
warp::http::Response::builder()
|
||||||
|
.header("content-type", info.file_type)
|
||||||
|
.status(StatusCode::NOT_MODIFIED)
|
||||||
|
.body(content)
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let _ = stream.read_to_end(&mut content);
|
||||||
|
warp::http::Response::builder()
|
||||||
|
.header("content-type", info.file_type)
|
||||||
|
.header("etag", info.hash)
|
||||||
|
.status(StatusCode::OK)
|
||||||
|
.body(content)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(_err) => warp::http::Response::builder()
|
||||||
|
.status(StatusCode::NOT_FOUND)
|
||||||
|
.body(content),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let server = warp::serve(root.or(thumbnail));
|
||||||
server
|
server
|
||||||
.run(SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 8002))
|
.run(SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 8002))
|
||||||
.await;
|
.await;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::{html::*, File, FileError};
|
use crate::{html::*, File, FileError};
|
||||||
use build_html::{self, Container, ContainerType, HtmlContainer};
|
use build_html::{self, Container, ContainerType, Html, HtmlContainer};
|
||||||
|
|
||||||
pub fn index(files: Vec<Result<File, FileError>>) -> build_html::HtmlPage {
|
pub fn index(files: Vec<Result<File, FileError>>) -> build_html::HtmlPage {
|
||||||
let mut page = build_html::HtmlPage::new()
|
let mut page = build_html::HtmlPage::new()
|
||||||
|
@ -25,8 +25,8 @@ pub fn index(files: Vec<Result<File, FileError>>) -> build_html::HtmlPage {
|
||||||
let tn = Container::new(ContainerType::Div)
|
let tn = Container::new(ContainerType::Div)
|
||||||
.with_attributes(vec![("class", "thumbnail")])
|
.with_attributes(vec![("class", "thumbnail")])
|
||||||
.with_link(
|
.with_link(
|
||||||
format!("/file/{}", file.info().id),
|
format!("/{}", file.info().id),
|
||||||
"<p> paragraph within the link </p>".to_owned(),
|
Image::new(&format!("{}/tn", file.info().id)).to_html_string(),
|
||||||
);
|
);
|
||||||
container.add_html(tn);
|
container.add_html(tn);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue