Compare commits
No commits in common. "1bb6bd78e6943989291d02d13590cf1ecb2696bc" and "56d7fae43ce96cb3e68d924daad2370b9e5bec83" have entirely different histories.
1bb6bd78e6
...
56d7fae43c
|
@ -133,22 +133,3 @@ 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,7 +11,6 @@ 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},
|
||||||
|
@ -46,6 +45,71 @@ 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>>,
|
||||||
}
|
}
|
||||||
|
@ -231,6 +295,14 @@ 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",
|
||||||
|
@ -247,6 +319,12 @@ 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(
|
||||||
|
@ -293,37 +371,7 @@ pub async fn main() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let thumbnail = warp::path!(String / "tn")
|
let server = warp::serve(root);
|
||||||
.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, Html, HtmlContainer};
|
use build_html::{self, Container, ContainerType, 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.info().id),
|
format!("/file/{}", file.info().id),
|
||||||
Image::new(&format!("{}/tn", file.info().id)).to_html_string(),
|
"<p> paragraph within the link </p>".to_owned(),
|
||||||
);
|
);
|
||||||
container.add_html(tn);
|
container.add_html(tn);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue