aboutsummaryrefslogtreecommitdiffstats
path: root/src/listing.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/listing.rs')
-rw-r--r--src/listing.rs83
1 files changed, 64 insertions, 19 deletions
diff --git a/src/listing.rs b/src/listing.rs
index 57bef17..a9f0f19 100644
--- a/src/listing.rs
+++ b/src/listing.rs
@@ -1,12 +1,16 @@
-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::Color;
+use crate::archive;
+use crate::errors;
use crate::renderer;
/// Query parameters
@@ -14,6 +18,7 @@ use crate::renderer;
struct QueryParameters {
sort: Option<SortingMethod>,
order: Option<SortingOrder>,
+ download: Option<archive::CompressionMethod>,
}
/// Available sorting methods
@@ -134,11 +139,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 +228,52 @@ 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 {
+ println!(
+ "{info} Creating an archive ({extension}) of {path}...",
+ info = Color::Blue.paint("info:").bold(),
+ extension = Color::White.paint(compression_method.extension()).bold(),
+ path = Color::White.paint(&dir.path.display().to_string()).bold()
+ );
+ match archive::create_archive_file(&compression_method, &dir.path) {
+ Ok((filename, content)) => {
+ println!(
+ "{success} {file} successfully created !",
+ success = Color::Green.paint("success:").bold(),
+ file = Color::White.paint(&filename).bold(),
+ );
+ Ok(HttpResponse::Ok()
+ .content_type(compression_method.content_type())
+ .content_length(content.len() as u64)
+ .content_encoding(compression_method.content_encoding())
+ .header("Content-Transfer-Encoding", "binary")
+ .header(
+ "Content-Disposition",
+ format!("attachment; filename={:?}", filename),
+ )
+ .chunked()
+ .body(Body::Streaming(Box::new(once(Ok(content))))))
+ }
+ Err(err) => {
+ errors::print_error_chain(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(),
+ ))
+ }
}