From 984823e6ef2f19939583edcf7ff82508e13d3fab Mon Sep 17 00:00:00 2001 From: boasting-squirrel Date: Sat, 23 Feb 2019 11:06:19 +0100 Subject: Renders file listing using maud --- src/listing.rs | 238 +++++---------------------------------------------------- 1 file changed, 17 insertions(+), 221 deletions(-) (limited to 'src/listing.rs') diff --git a/src/listing.rs b/src/listing.rs index 629a117..9af2992 100644 --- a/src/listing.rs +++ b/src/listing.rs @@ -1,16 +1,15 @@ use actix_web::{fs, HttpRequest, HttpResponse, Result}; use bytesize::ByteSize; -use chrono::{DateTime, Duration, Utc}; -use chrono_humanize::{Accuracy, HumanTime, Tense}; use clap::{_clap_count_exprs, arg_enum}; use htmlescape::encode_minimal as escape_html_entity; use percent_encoding::{utf8_percent_encode, DEFAULT_ENCODE_SET}; use std::cmp::Ordering; -use std::fmt::Write as FmtWrite; use std::io; use std::path::Path; use std::time::SystemTime; +use crate::renderer; + arg_enum! { #[derive(Clone, Copy, Debug)] /// Available sorting methods @@ -35,7 +34,7 @@ arg_enum! { #[derive(PartialEq)] /// Possible entry types -enum EntryType { +pub enum EntryType { /// Entry is a directory Directory, @@ -54,21 +53,21 @@ impl PartialOrd for EntryType { } /// Entry -struct Entry { +pub struct Entry { /// Name of the entry - name: String, + pub name: String, /// Type of the entry - entry_type: EntryType, + pub entry_type: EntryType, /// URL of the entry - link: String, + pub link: String, /// Size in byte of the entry. Only available for EntryType::File - size: Option, + pub size: Option, /// Last modification date - last_modification_date: Option, + pub last_modification_date: Option, } impl Entry { @@ -87,6 +86,10 @@ impl Entry { last_modification_date, } } + + pub fn is_dir(&self) -> bool { + self.entry_type == EntryType::Directory + } } pub fn file_handler(req: &HttpRequest) -> Result { @@ -104,20 +107,11 @@ pub fn directory_listing( sort_method: SortingMethods, reverse_sort: bool, ) -> Result { - let index_of = format!("Index of {}", req.path()); - let mut body = String::new(); + let title = format!("Index of {}", req.path()); let base = Path::new(req.path()); let random_route = format!("/{}", random_route.unwrap_or_default()); - - if let Some(parent) = base.parent() { - if req.path() != random_route { - let _ = write!( - body, - "..", - parent.display() - ); - } - } + let is_root = base.parent().is_none() || req.path() == random_route; + let page_parent = base.parent().map(|p| p.display().to_string()); let mut entries: Vec = Vec::new(); @@ -190,206 +184,8 @@ pub fn directory_listing( if reverse_sort { entries.reverse(); } - for entry in entries { - let (modification_date, modification_time) = convert_to_utc(entry.last_modification_date); - match entry.entry_type { - EntryType::Directory => { - let _ = write!( - body, - "\ - \ - {}/\ - \ - Last modification: {} {}\ - \ - \ - \ - \ - {}\ - {}\ - {}\ - \ - ", - entry.link, - entry.name, - modification_date, - modification_time, - modification_date, - modification_time, - humanize_systemtime(entry.last_modification_date) - ); - } - EntryType::File => { - let _ = write!( - body, - "\ - \ - {}\ - \ - Size: {}\ - \ - \ - Last modification: {} {} ({})\ - \ - \ - \ - {}\ - \ - \ - {}\ - {}\ - {}\ - \ - ", - entry.link, - entry.name, - entry.size.unwrap(), - modification_date, - modification_time, - humanize_systemtime(entry.last_modification_date), - entry.size.unwrap(), - modification_date, - modification_time, - humanize_systemtime(entry.last_modification_date) - ); - } - } - } - - let html = format!( - "\ - \ - {}\ - \ - \ - \ -

{}

\ - \ - \ - \ - {}\ -
NameSizeLast modification
\n", - index_of, index_of, body - ); Ok(HttpResponse::Ok() .content_type("text/html; charset=utf-8") - .body(html)) -} - -/// Converts a SystemTime object to a strings tuple (date, time) -/// Date is formatted as %e %b, e.g. Jul 12 -/// Time is formatted as %R, e.g. 22:34 -/// -/// If no SystemTime was given, returns a tuple containing empty strings -fn convert_to_utc(src_time: Option) -> (String, String) { - src_time - .map(|time| DateTime::::from(time)) - .map(|date_time| { - ( - date_time.format("%e %b").to_string(), - date_time.format("%R").to_string(), - ) - }) - .unwrap_or_default() -} - -/// Converts a SystemTime to a string readable by a human, -/// i.e. calculates the duration between now() and the given SystemTime, -/// and gives a rough approximation of the elapsed time since -/// -/// If no SystemTime was given, returns an empty string -fn humanize_systemtime(src_time: Option) -> String { - src_time - .and_then(|std_time| SystemTime::now().duration_since(std_time).ok()) - .and_then(|from_now| Duration::from_std(from_now).ok()) - .map(|duration| HumanTime::from(duration).to_text_en(Accuracy::Rough, Tense::Past)) - .unwrap_or_default() + .body(renderer::page(&title, entries, is_root, page_parent).into_string())) } -- cgit v1.2.3