diff --git a/src/config.rs b/src/config.rs index 1f0179e..87a8ada 100644 --- a/src/config.rs +++ b/src/config.rs @@ -2,7 +2,7 @@ use std::path::Path; use serde::{Serialize, Deserialize}; -use crate::{util::read_file_utf8, web::discord::request::model::Webhook}; +use crate::{filesystem::file::read_file_utf8, web::discord::request::model::Webhook}; /// Configure the stats collection /// - ```save_period_seconds```: periodically save to disc diff --git a/src/filesystem/file.rs b/src/filesystem/file.rs new file mode 100644 index 0000000..3604edb --- /dev/null +++ b/src/filesystem/file.rs @@ -0,0 +1,51 @@ +use std::{fs::File, io::{Read, Write}}; + +pub fn write_file(path: &str, data: &[u8]) +{ + let mut file = File::create(path).unwrap(); + file.write_all(data).unwrap(); +} + +pub fn read_file_utf8(path: &str) -> Option +{ + let mut file = match File::open(path) { + Err(why) => + { + crate::debug(format!("error reading file to utf8, {}", why), None); + return None + }, + Ok(file) => file, + }; + + let mut s = String::new(); + match file.read_to_string(&mut s) { + Err(why) => + { + crate::debug(format!("error reading file to utf8, {}", why), None); + None + }, + Ok(_) => Some(s) + } +} + +pub fn read_file_bytes(path: &str) -> Option> +{ + let mut file = match File::open(path) { + Err(why) => + { + crate::debug(format!("error reading file to utf8, {}", why), None); + return None + }, + Ok(file) => file, + }; + + let mut s: Vec = vec![]; + match file.read_to_end(&mut s) { + Err(why) => + { + crate::debug(format!("error reading file to utf8, {}", why), None); + None + }, + Ok(_) => Some(s) + } +} \ No newline at end of file diff --git a/src/filesystem/folder.rs b/src/filesystem/folder.rs new file mode 100644 index 0000000..a2ec6a8 --- /dev/null +++ b/src/filesystem/folder.rs @@ -0,0 +1,151 @@ +use core::fmt; +use std::fs::DirEntry; + +use regex::Regex; + +#[derive(Debug, Clone)] +pub struct ListDirError +{ + pub why: String +} + +impl fmt::Display for ListDirError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.why) + } +} + +pub fn list_dir(path: String) -> Result +{ + match std::fs::read_dir(path) + { + Ok(files) => + { + Ok(files) + }, + Err(why) => + { + Err(ListDirError { why: format!("{}", why)}) + } + } +} + +pub fn dir_entry_to_path(d: DirEntry) -> Option +{ + let file_os_string = d.file_name(); + + match file_os_string.to_str() + { + Some(name) => Some(name.to_string()), + None => + { + crate::debug(format!("could not load file name: {:?}", file_os_string), None); + None + } + } +} + +pub fn list_sub_dirs(path: String) -> Vec +{ + let mut found_dirs: Vec = vec![]; + match std::fs::read_dir(path.clone()) + { + Ok(files) => + { + + for file in files + { + let name = match file + { + Ok(d) => dir_entry_to_path(d), + Err(e) => + { + crate::debug(format!("could not load file name: {}", e), None); + continue + } + }; + + match name + { + Some(n) => + { + let p = path.clone()+"/"+&n; + match std::fs::metadata(p.clone()) + { + Ok(md) => + { + match md.is_dir() + { + true => {found_dirs.push(p.clone()); crate::debug(format!("found folder: {}", p), None)}, + false => {continue} + } + }, + Err(e) => + { + crate::debug(format!("error getting file: {}", e), None); + continue + } + } + }, + None => continue + } + } + }, + Err(why) => + { + crate::debug(format!("Error reading dir {}\n {}", path, why), None); + } + } + + found_dirs +} + +pub fn list_dir_by(pattern: Option, path: String) -> Vec +{ + match std::fs::read_dir(path.clone()) + { + Ok(files) => + { + let mut found_files: Vec = vec![]; + for file in files + { + + let file_name = match file + { + Ok(d) => dir_entry_to_path(d), + Err(e) => + { + crate::debug(format!("could not load file name: {}", e), None); + continue + } + }; + + let file_path = match file_name + { + Some(name) => path.clone() + "/" + &name, + None => continue + }; + + if pattern.clone().is_some() + { + match pattern.clone().unwrap().captures(&file_path) + { + Some(_caps) => {found_files.push(file_path.to_string())}, + None => {continue} + } + } + else + { + found_files.push(file_path.to_string()) + } + } + + return found_files + }, + Err(why) => + { + crate::debug(format!("Error reading dir {}\n {}", path, why), None); + } + } + vec![] +} \ No newline at end of file diff --git a/src/filesystem/mod.rs b/src/filesystem/mod.rs new file mode 100644 index 0000000..19676bc --- /dev/null +++ b/src/filesystem/mod.rs @@ -0,0 +1,2 @@ +pub mod file; +pub mod folder; \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 7cad46f..7e2fcbc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,6 +6,7 @@ pub mod util; pub mod pages; pub mod resources; pub mod config; +pub mod filesystem; const MAJOR: &str = env!("CARGO_PKG_VERSION_MAJOR"); const MINOR: &str = env!("CARGO_PKG_VERSION_MINOR"); diff --git a/src/pages/mod.rs b/src/pages/mod.rs index d0c4354..466a2b5 100644 --- a/src/pages/mod.rs +++ b/src/pages/mod.rs @@ -1,7 +1,6 @@ use regex::Regex; -use crate::{util::{list_dir_by, list_sub_dirs, read_file_utf8}, HTML_REGEX}; - +use crate::{filesystem::folder::{list_dir_by, list_sub_dirs}, HTML_REGEX, filesystem::file::read_file_utf8}; use self::page::Page; pub mod page; diff --git a/src/pages/page.rs b/src/pages/page.rs index 5a98a3e..cca2815 100644 --- a/src/pages/page.rs +++ b/src/pages/page.rs @@ -4,7 +4,7 @@ use axum::response::{IntoResponse, Response, Html}; use regex::Regex; use serde::{Serialize, Deserialize}; -use crate::util::read_file_utf8; +use crate::filesystem::file::read_file_utf8; /// An HTML webpage with a uri and body /// diff --git a/src/resources/mod.rs b/src/resources/mod.rs index a6f447b..c11ccd8 100644 --- a/src/resources/mod.rs +++ b/src/resources/mod.rs @@ -2,7 +2,7 @@ pub mod resource; use regex::Regex; -use crate::{util::{list_dir_by, list_sub_dirs, read_file_bytes}, HTML_REGEX, RESOURCE_REGEX}; +use crate::{filesystem::folder::{list_dir_by, list_sub_dirs}, HTML_REGEX, RESOURCE_REGEX, filesystem::file::read_file_bytes}; use self::resource::{content_type, Resource}; diff --git a/src/util.rs b/src/util.rs index a7f6375..7cdc707 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,5 +1,5 @@ use core::fmt; -use std::{fmt::Write, fs::{DirEntry, File}, io::{Read, Write as ioWrite}}; +use std::{fmt::Write, io::{Read, Write as ioWrite}}; use libflate::deflate::{Encoder, Decoder}; use regex::Regex; @@ -29,203 +29,6 @@ pub fn strip_control_characters(s: String) -> String return re.to_string() } -pub fn write_file(path: &str, data: &[u8]) -{ - let mut file = File::create(path).unwrap(); - file.write_all(data).unwrap(); -} - -pub fn read_file_utf8(path: &str) -> Option -{ - let mut file = match File::open(path) { - Err(why) => - { - crate::debug(format!("error reading file to utf8, {}", why), None); - return None - }, - Ok(file) => file, - }; - - let mut s = String::new(); - match file.read_to_string(&mut s) { - Err(why) => - { - crate::debug(format!("error reading file to utf8, {}", why), None); - None - }, - Ok(_) => Some(s) - } -} - -pub fn read_file_bytes(path: &str) -> Option> -{ - let mut file = match File::open(path) { - Err(why) => - { - crate::debug(format!("error reading file to utf8, {}", why), None); - return None - }, - Ok(file) => file, - }; - - let mut s: Vec = vec![]; - match file.read_to_end(&mut s) { - Err(why) => - { - crate::debug(format!("error reading file to utf8, {}", why), None); - None - }, - Ok(_) => Some(s) - } -} - -#[derive(Debug, Clone)] -pub struct ListDirError -{ - pub why: String -} - -impl fmt::Display for ListDirError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.why) - } -} - -pub fn list_dir(path: String) -> Result -{ - match std::fs::read_dir(path) - { - Ok(files) => - { - Ok(files) - }, - Err(why) => - { - Err(ListDirError { why: format!("{}", why)}) - } - } -} - -pub fn dir_entry_to_path(d: DirEntry) -> Option -{ - let file_os_string = d.file_name(); - - match file_os_string.to_str() - { - Some(name) => Some(name.to_string()), - None => - { - crate::debug(format!("could not load file name: {:?}", file_os_string), None); - None - } - } -} - -pub fn list_sub_dirs(path: String) -> Vec -{ - let mut found_dirs: Vec = vec![]; - match std::fs::read_dir(path.clone()) - { - Ok(files) => - { - - for file in files - { - let name = match file - { - Ok(d) => dir_entry_to_path(d), - Err(e) => - { - crate::debug(format!("could not load file name: {}", e), None); - continue - } - }; - - match name - { - Some(n) => - { - let p = path.clone()+"/"+&n; - match std::fs::metadata(p.clone()) - { - Ok(md) => - { - match md.is_dir() - { - true => {found_dirs.push(p.clone()); crate::debug(format!("found folder: {}", p), None)}, - false => {continue} - } - }, - Err(e) => - { - crate::debug(format!("error getting file: {}", e), None); - continue - } - } - }, - None => continue - } - } - }, - Err(why) => - { - crate::debug(format!("Error reading dir {}\n {}", path, why), None); - } - } - - found_dirs -} - -pub fn list_dir_by(pattern: Option, path: String) -> Vec -{ - match std::fs::read_dir(path.clone()) - { - Ok(files) => - { - let mut found_files: Vec = vec![]; - for file in files - { - - let file_name = match file - { - Ok(d) => dir_entry_to_path(d), - Err(e) => - { - crate::debug(format!("could not load file name: {}", e), None); - continue - } - }; - - let file_path = match file_name - { - Some(name) => path.clone() + "/" + &name, - None => continue - }; - - if pattern.clone().is_some() - { - match pattern.clone().unwrap().captures(&file_path) - { - Some(_caps) => {found_files.push(file_path.to_string())}, - None => {continue} - } - } - else - { - found_files.push(file_path.to_string()) - } - } - - return found_files - }, - Err(why) => - { - crate::debug(format!("Error reading dir {}\n {}", path, why), None); - } - } - vec![] -} - pub fn matches_one(uri: &str, patterns: &Vec) -> bool { let mut ignore = false; diff --git a/src/web/stats.rs b/src/web/stats.rs index b76a4ac..b6c9b0b 100644 --- a/src/web/stats.rs +++ b/src/web/stats.rs @@ -4,11 +4,8 @@ use std::fs::create_dir; use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use std::sync::Arc; use std::time::Instant; -use axum::middleware::from_fn; use chrono::{DateTime, Datelike, TimeZone, Timelike}; -use openssl::conf; use openssl::sha::sha512; -use regex::Regex; use tokio::sync::{Mutex, MutexGuard}; use serde::{Deserialize, Serialize}; @@ -23,7 +20,17 @@ use axum:: use crate::config::read_config; use crate::pages::page::is_page; -use crate::util::{compress, dump_bytes, list_dir_by, matches_one, read_file_utf8, write_file}; +use crate:: +{ + filesystem::file::{read_file_utf8, write_file}, + util:: + { + compress, + dump_bytes, + matches_one + }, + filesystem::folder::list_dir_by +}; use crate::web::discord::request::post::post; @@ -330,7 +337,7 @@ impl Stats all_hitters.sort_by(|a: &(String, u16), b: &(String, u16)| a.1.cmp(&b.1)); all_hitters.reverse(); - digest.top_hitters = (0..n).map(|i| ("".to_string(), 0)).collect(); + digest.top_hitters = (0..n).map(|_i| ("".to_string(), 0)).collect(); for i in 0..n { @@ -350,8 +357,8 @@ impl Stats all_resources.sort_by(|a: &(String, u16), b: &(String, u16)| a.1.cmp(&b.1)); all_resources.reverse(); - digest.top_pages = (0..n).map(|i| ("".to_string(), 0)).collect(); - digest.top_resources = (0..n).map(|i| ("".to_string(), 0)).collect(); + digest.top_pages = (0..n).map(|_i| ("".to_string(), 0)).collect(); + digest.top_resources = (0..n).map(|_i| ("".to_string(), 0)).collect(); for i in 0..n {