Compare commits
6 Commits
Author | SHA1 | Date | |
---|---|---|---|
9950f41ba4 | |||
765884f79f | |||
2435a5728f | |||
19c2ad1a85 | |||
389c61e44e | |||
1375505011 |
21
Dockerfile
Normal file
21
Dockerfile
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
FROM rust:1.59 as builder
|
||||||
|
|
||||||
|
WORKDIR /build
|
||||||
|
|
||||||
|
COPY ./src/ /build/src
|
||||||
|
COPY ./Cargo.toml /build/Cargo.toml
|
||||||
|
|
||||||
|
RUN rustup update nightly && rustup default nightly && \
|
||||||
|
cargo clean && cargo build --release
|
||||||
|
|
||||||
|
|
||||||
|
FROM debian:buster-slim
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY --from=builder /build/target/release/fastcloud /app/fastcloud
|
||||||
|
RUN mkdir /app/service
|
||||||
|
COPY ./templates/ /app/templates
|
||||||
|
ENV FASTCLOUD_DIR /app/service
|
||||||
|
|
||||||
|
CMD [ "/app/fastcloud" ]
|
59
src/main.rs
59
src/main.rs
@ -5,16 +5,17 @@ extern crate rocket;
|
|||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
use std::path::{PathBuf, Path};
|
use std::collections::HashMap;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
use std::collections::HashMap;
|
use std::panic;
|
||||||
use rocket::response::{NamedFile, Redirect};
|
use std::path::{PathBuf, Path};
|
||||||
use rocket::http::{Cookie, Cookies, ContentType, Status};
|
use rocket::http::{Cookie, Cookies, ContentType, Status};
|
||||||
|
use rocket::response::{NamedFile, Redirect};
|
||||||
use rocket::request::{self, Request, Form, FromRequest};
|
use rocket::request::{self, Request, Form, FromRequest};
|
||||||
use rocket_contrib::templates::Template;
|
use rocket_contrib::templates::Template;
|
||||||
use rocket_upload::MultipartDatas;
|
use rocket_upload::{FilePart, MultipartDatas};
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
@ -168,8 +169,11 @@ fn delete(path: PathBuf, _guard: AdminUser) -> Redirect {
|
|||||||
|
|
||||||
fn directory_structure(path: String) -> HashMap<&'static str, HashMap<i32, DirPath>> {
|
fn directory_structure(path: String) -> HashMap<&'static str, HashMap<i32, DirPath>> {
|
||||||
let dir = Path::new(path.as_str());
|
let dir = Path::new(path.as_str());
|
||||||
let paths = fs::read_dir(dir).unwrap()
|
let mut sort = fs::read_dir(dir).unwrap()
|
||||||
.map(|x| x.unwrap().path().into_os_string().into_string().unwrap())
|
.map(|x| x.unwrap().path().into_os_string().into_string().unwrap())
|
||||||
|
.collect::<Vec<String>>();
|
||||||
|
sort.sort_by_key(|a| a.to_lowercase());
|
||||||
|
let paths = sort.into_iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|x| (x.0 as i32, DirPath {
|
.map(|x| (x.0 as i32, DirPath {
|
||||||
is_file: Path::new(&x.1).is_file(),
|
is_file: Path::new(&x.1).is_file(),
|
||||||
@ -206,37 +210,42 @@ fn file_get(path: PathBuf, _guard: GenericUser) -> Option<NamedFile> {
|
|||||||
rocket::response::NamedFile::open(dir.as_path()).ok()
|
rocket::response::NamedFile::open(dir.as_path()).ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/upload/<path..>", data = "<data>")]
|
fn upload(dir: PathBuf, data:MultipartDatas) {
|
||||||
fn upload_file(path: PathBuf, _content_type: &ContentType, data:MultipartDatas, _guard: AdminUser) -> Redirect {
|
let prev_hook = panic::take_hook();
|
||||||
let dir = DIR.as_path().join(path.clone());
|
panic::set_hook(Box::new(|_| {}));
|
||||||
|
let _ = panic::catch_unwind(||
|
||||||
for f in data.files {
|
for f in data.files {
|
||||||
if !Path::new(&format!("{}/{}", dir.to_str().unwrap(), f.filename)).exists() {
|
if !Path::new(&format!("{}/{}", dir.to_str().unwrap(), f.filename)).exists() {
|
||||||
f.persist(&dir);
|
f.persist(&dir);
|
||||||
}
|
}
|
||||||
for i in 0.. {
|
else {
|
||||||
if !Path::new(&format!("{}/{}.{}", dir.to_str().unwrap(), f.filename, i)).exists() {
|
for i in 0.. {
|
||||||
f.persist(&dir);
|
if !Path::new(&format!("{}/{}.{}", dir.to_str().unwrap(), f.filename, i)).exists() {
|
||||||
break
|
let file = FilePart {
|
||||||
|
name: f.name.to_string(),
|
||||||
|
path: f.path.to_string(),
|
||||||
|
filename: format!("{}.{}", f.filename, i)
|
||||||
|
};
|
||||||
|
file.persist(&dir);
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
panic::set_hook(prev_hook);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[post("/upload/<path..>", data = "<data>")]
|
||||||
|
fn upload_file(path: PathBuf, _content_type: &ContentType, data:MultipartDatas, _guard: AdminUser) -> Redirect {
|
||||||
|
let dir = DIR.as_path().join(path.clone());
|
||||||
|
upload(dir, data);
|
||||||
Redirect::to(uri!(get_dir_entry: path))
|
Redirect::to(uri!(get_dir_entry: path))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/upload", data = "<data>")]
|
#[post("/upload", data = "<data>")]
|
||||||
fn upload_root(_content_type: &ContentType, data:MultipartDatas, _guard: AdminUser) -> Redirect {
|
fn upload_root(_content_type: &ContentType, data:MultipartDatas, _guard: AdminUser) -> Redirect {
|
||||||
let dir = DIR.as_path();
|
let dir = DIR.as_path().to_path_buf();
|
||||||
for f in data.files {
|
upload(dir, data);
|
||||||
if !Path::new(&format!("{}/{}", dir.to_str().unwrap(), f.filename)).exists() {
|
|
||||||
f.persist(dir);
|
|
||||||
}
|
|
||||||
for i in 0.. {
|
|
||||||
if !Path::new(&format!("{}/{}.{}", dir.to_str().unwrap(), f.filename, i)).exists() {
|
|
||||||
f.persist(dir);
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Redirect::to(uri!(get_root))
|
Redirect::to(uri!(get_root))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,12 +25,12 @@
|
|||||||
{{#each ctx}}
|
{{#each ctx}}
|
||||||
<div class="d-flex flex-row">
|
<div class="d-flex flex-row">
|
||||||
{{#if is_file}}
|
{{#if is_file}}
|
||||||
<a type="button" class="btn btn-outline-secondary text-start col-sm-3" href="/file/{{path}}" role="button">
|
<a type="button" class="btn btn-outline-secondary text-start col-sm-3" href="/file/{{path}}" role="button" style="overflow: hidden;">
|
||||||
<i class="bi bi-file-earmark"></i>
|
<i class="bi bi-file-earmark"></i>
|
||||||
{{name}}
|
{{name}}
|
||||||
</a>
|
</a>
|
||||||
{{else}}
|
{{else}}
|
||||||
<a type="button" class="btn btn-outline-secondary text-start col-sm-3" href="/serve/{{path}}" role="button">
|
<a type="button" class="btn btn-outline-secondary text-start col-sm-3" href="/serve/{{path}}" role="button" style="overflow: hidden;">
|
||||||
<i class="bi bi-folder-fill"></i>
|
<i class="bi bi-folder-fill"></i>
|
||||||
{{name}}
|
{{name}}
|
||||||
</a>
|
</a>
|
||||||
|
@ -19,12 +19,12 @@
|
|||||||
{{#each ctx}}
|
{{#each ctx}}
|
||||||
<div class="d-flex flex-row">
|
<div class="d-flex flex-row">
|
||||||
{{#if is_file}}
|
{{#if is_file}}
|
||||||
<a type="button" class="btn btn-outline-secondary text-start col-sm-3" href="/file/{{path}}" role="button">
|
<a type="button" class="btn btn-outline-secondary text-start col-sm-3" href="/file/{{path}}" role="button" style="overflow: hidden;">
|
||||||
<i class="bi bi-file-earmark"></i>
|
<i class="bi bi-file-earmark"></i>
|
||||||
{{name}}
|
{{name}}
|
||||||
</a>
|
</a>
|
||||||
{{else}}
|
{{else}}
|
||||||
<a type="button" class="btn btn-outline-secondary text-start col-sm-3" href="/serve/{{path}}" role="button">
|
<a type="button" class="btn btn-outline-secondary text-start col-sm-3" href="/serve/{{path}}" role="button" style="overflow: hidden;">
|
||||||
<i class="bi bi-folder-fill"></i>
|
<i class="bi bi-folder-fill"></i>
|
||||||
{{name}}
|
{{name}}
|
||||||
</a>
|
</a>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user