Download folder as a tar working

This commit is contained in:
boasting-squirrel 2019-03-08 19:59:59 +01:00
parent 6340e9e565
commit 9857f26bdd
6 changed files with 247 additions and 32 deletions

85
Cargo.lock generated
View File

@ -7,7 +7,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"actix_derive 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -35,7 +35,7 @@ version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"actix 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
@ -64,7 +64,7 @@ dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"brotli2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"cookie 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -243,7 +243,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bytes"
version = "0.4.11"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -477,6 +477,16 @@ dependencies = [
"synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "filetime"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "flate2"
version = "1.0.6"
@ -532,7 +542,7 @@ version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
"http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
@ -570,7 +580,7 @@ name = "http"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -752,10 +762,12 @@ dependencies = [
"actix-web 0.7.18 (registry+https://github.com/rust-lang/crates.io-index)",
"alphanumeric-sort 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"bytesize 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono-humanize 0.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
"htmlescape 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"maud 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
"nanoid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -763,6 +775,8 @@ dependencies = [
"serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
"simplelog 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"structopt 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"tar 0.4.21 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 3.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"yansi 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1137,6 +1151,14 @@ dependencies = [
"ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "remove_dir_all"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "resolv-conf"
version = "0.6.2"
@ -1343,6 +1365,30 @@ dependencies = [
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tar"
version = "0.4.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
"xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tempfile"
version = "3.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
"remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "term"
version = "0.5.1"
@ -1393,7 +1439,7 @@ name = "tokio"
version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1416,7 +1462,7 @@ name = "tokio-codec"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1454,7 +1500,7 @@ name = "tokio-io"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1505,7 +1551,7 @@ name = "tokio-tcp"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1546,7 +1592,7 @@ name = "tokio-udp"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1560,7 +1606,7 @@ name = "tokio-uds"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1824,6 +1870,14 @@ dependencies = [
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "xattr"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "yansi"
version = "0.5.0"
@ -1851,7 +1905,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum brotli2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0cb036c3eade309815c15ddbacec5b22c4d1f3983a774ab2eac2e3e9ea85568e"
"checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39"
"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb"
"checksum bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "40ade3d27603c2cb345eb0912aec461a6dec7e06a4ae48589904e808335c7afa"
"checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c"
"checksum bytesize 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "716960a18f978640f25101b5cbf1c6f6b0d3192fab36a2d98ca96f0ecbe41010"
"checksum cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)" = "4390a3b5f4f6bce9c1d0c00128379df433e53777fdd30e92f16a529332baec4e"
"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4"
@ -1878,6 +1932,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum error-chain 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6930e04918388a9a2e41d518c25cf679ccafe26733fb4127dbf21993f2575d46"
"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1"
"checksum filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a2df5c1a8c4be27e7707789dc42ae65976e60b394afd293d1419ab915833e646"
"checksum flate2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2291c165c8e703ee54ef3055ad6188e3d51108e2ded18e9f2476e774fc5ad3d4"
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
@ -1955,6 +2010,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
"checksum regex 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53ee8cfdddb2e0291adfb9f13d31d3bbe0a03c9a402c01b1e24188d86c35b24f"
"checksum regex-syntax 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8c2f35eedad5295fdf00a63d7d4b238135723f92b434ec06774dad15c7ab0861"
"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"
"checksum resolv-conf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b263b4aa1b5de9ffc0054a2386f96992058bb6870aab516f8cdeb8a667d56dcb"
"checksum ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2c4db68a2e35f3497146b7e4563df7d4773a2433230c5e4b448328e31740458a"
"checksum rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "adacaae16d02b6ec37fdc7acfcddf365978de76d1983d3ee22afc260e1ca9619"
@ -1982,6 +2038,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum structopt-derive 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "ef98172b1a00b0bec738508d3726540edcbd186d50dfd326f2b1febbb3559f04"
"checksum syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)" = "f92e629aa1d9c827b2bb8297046c1ccffc57c99b947a680d3ccff1f136a3bee9"
"checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015"
"checksum tar 0.4.21 (registry+https://github.com/rust-lang/crates.io-index)" = "904b43da53c99b929c4484fa281e5535f2eb86b3040de3e3e5b69708e2a8bd65"
"checksum tempfile 3.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b86c784c88d98c801132806dadd3819ed29d8600836c4088e855cdf3e178ed8a"
"checksum term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e6b677dd1e8214ea1ef4297f85dbcbed8e8cdddb561040cc998ca2551c37561"
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6"
@ -2031,4 +2089,5 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum winreg 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a27a759395c1195c4cc5cda607ef6f8f6498f64e78f7900f5de0a127a424704a"
"checksum winutil 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7daf138b6b14196e3830a588acf1e86966c694d3e8fb026fb105b8b5dca07e6e"
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
"checksum xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c"
"checksum yansi 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9fc79f4a1e39857fc00c3f662cbf2651c771f00e9c15fe2abc341806bd46bd71"

View File

@ -37,3 +37,7 @@ chrono = "0.4.6"
chrono-humanize = "0.0.11"
maud = { version = "0.20.0", features = ["actix-web"] }
serde = { version = "1.0.89", features = ["derive"] }
tar = "0.4"
tempfile = "3.0.7"
bytes = "0.4.12"
futures = "0.1.25"

80
src/archive.rs Normal file
View File

@ -0,0 +1,80 @@
use bytes::Bytes;
use serde::Deserialize;
use std::fs::{File, OpenOptions};
use std::io::Read;
use std::path::PathBuf;
use tar::Builder;
use tempfile::tempdir;
#[derive(Debug)]
pub enum CompressionError {
IOError(std::io::Error),
NoneError(std::option::NoneError),
}
impl From<std::option::NoneError> for CompressionError {
fn from(err: std::option::NoneError) -> CompressionError {
CompressionError::NoneError(err)
}
}
impl From<std::io::Error> for CompressionError {
fn from(err: std::io::Error) -> CompressionError {
CompressionError::IOError(err)
}
}
/// Available compression methods
#[derive(Debug, Deserialize, Clone)]
pub enum CompressionMethod {
/// ZIP
#[serde(alias = "targz")]
TarGz,
}
impl CompressionMethod {
pub fn to_string(&self) -> String {
match &self {
CompressionMethod::TarGz => "targz",
}
.to_string()
}
pub fn extension(&self) -> String {
match &self {
CompressionMethod::TarGz => "tar.gz",
}
.to_string()
}
}
pub fn create_archive_file(
method: &CompressionMethod,
dir: &PathBuf,
) -> Result<(String, usize, Bytes), CompressionError> {
match method {
CompressionMethod::TarGz => tgz_compress(&dir),
}
}
fn tgz_compress(dir: &PathBuf) -> Result<(String, usize, Bytes), CompressionError> {
let src_dir = dir.display().to_string();
let inner_folder = dir.file_name()?.to_str()?;
let dst_filename = format!("{}.tar", inner_folder);
let tmp_dir = tempdir()?;
let dst_filepath = tmp_dir.path().join(dst_filename.clone());
let tar_file = File::create(&dst_filepath)?;
let mut tar_builder = Builder::new(&tar_file);
tar_builder.append_dir_all(inner_folder, src_dir)?;
tar_builder.finish()?;
let mut tar_file = OpenOptions::new().read(true).open(&dst_filepath)?;
let mut contents = Vec::new();
let content_length = tar_file.read_to_end(&mut contents).unwrap();
let mut data = Bytes::new();
data.extend_from_slice(&contents);
Ok((dst_filename, content_length, data))
}

View File

@ -1,12 +1,15 @@
use actix_web::{fs, FromRequest, HttpRequest, HttpResponse, Query, Result};
use actix_web::{fs, http, Body, FromRequest, HttpRequest, HttpResponse, Query, Result};
use bytesize::ByteSize;
use futures::stream::once;
use htmlescape::encode_minimal as escape_html_entity;
use percent_encoding::{utf8_percent_encode, DEFAULT_ENCODE_SET};
use serde::Deserialize;
use std::io;
use std::path::Path;
use std::time::SystemTime;
use yansi::Paint;
use crate::archive;
use crate::renderer;
/// Query parameters
@ -14,6 +17,7 @@ use crate::renderer;
struct QueryParameters {
sort: Option<SortingMethod>,
order: Option<SortingOrder>,
download: Option<archive::CompressionMethod>,
}
/// Available sorting methods
@ -134,11 +138,16 @@ pub fn directory_listing<S>(
let is_root = base.parent().is_none() || req.path() == random_route;
let page_parent = base.parent().map(|p| p.display().to_string());
let (sort_method, sort_order) = if let Ok(query) = Query::<QueryParameters>::extract(req) {
(query.sort.clone(), query.order.clone())
} else {
(None, None)
};
let (sort_method, sort_order, download) =
if let Ok(query) = Query::<QueryParameters>::extract(req) {
(
query.sort.clone(),
query.order.clone(),
query.download.clone(),
)
} else {
(None, None, None)
};
let mut entries: Vec<Entry> = Vec::new();
@ -218,17 +227,43 @@ pub fn directory_listing<S>(
}
}
Ok(HttpResponse::Ok()
.content_type("text/html; charset=utf-8")
.body(
renderer::page(
&title,
entries,
is_root,
page_parent,
sort_method,
sort_order,
)
.into_string(),
))
if let Some(compression_method) = &download {
match archive::create_archive_file(&compression_method, &dir.path) {
Ok((filename, content_length, content)) => Ok(HttpResponse::Ok()
.content_type("application/tar")
.content_length(content_length as u64)
.header("Content-Transfer-Encoding", "binary")
.header(
"Content-Disposition",
format!("attachment; filename={:?}", filename),
)
.chunked()
.body(Body::Streaming(Box::new(once(Ok(content)))))),
Err(err) => {
println!(
"{error} an error occured while compressing {folder}: {err:?}",
error = Paint::red("error:").bold(),
folder = dir.path.display(),
err = err
);
Ok(HttpResponse::Ok()
.status(http::StatusCode::INTERNAL_SERVER_ERROR)
.body(""))
}
}
} else {
Ok(HttpResponse::Ok()
.content_type("text/html; charset=utf-8")
.body(
renderer::page(
&title,
entries,
is_root,
page_parent,
sort_method,
sort_order,
)
.into_string(),
))
}
}

View File

@ -1,4 +1,5 @@
#![feature(proc_macro_hygiene)]
#![feature(try_trait)]
use actix_web::{fs, middleware, server, App};
use clap::crate_version;
@ -9,6 +10,7 @@ use std::thread;
use std::time::Duration;
use yansi::{Color, Paint};
mod archive;
mod args;
mod auth;
mod listing;

View File

@ -3,6 +3,7 @@ use chrono_humanize::{Accuracy, HumanTime, Tense};
use maud::{html, Markup, PreEscaped, DOCTYPE};
use std::time::SystemTime;
use crate::archive;
use crate::listing;
/// Renders the file listing
@ -19,6 +20,9 @@ pub fn page(
body {
span #top { }
h1 { (page_title) }
div.download {
(archive_button(archive::CompressionMethod::TarGz))
}
table {
thead {
th { (build_link("name", "Name", &sort_method, &sort_order)) }
@ -50,6 +54,18 @@ pub fn page(
}
}
/// Partial: archive button
fn archive_button(compress_method: archive::CompressionMethod) -> Markup {
let link = format!("?download={}", compress_method.to_string());
let text = format!("Download .{}", compress_method.extension());
html! {
a href=(link) {
(text)
}
}
}
/// Partial: table header link
fn build_link(
name: &str,
@ -259,6 +275,25 @@ fn css() -> Markup {
color: #3498db;
text-decoration: none;
}
.download {
display: flex;
justify-content: flex-end;
padding: 0.125rem;
}
.download a, .download a:visited {
color: #3498db;
}
.download a {
background: #efefef;
padding: 0.5rem;
border-radius: 0.2rem;
}
.download a:hover {
background: #deeef7a6;
}
.download a:not(:last-of-type) {
margin-right: 1rem;
}
@media (max-width: 600px) {
h1 {
font-size: 1.375em;