From 8e4b4d6ceb6965bbfa45553fc91a607d6edfcef6 Mon Sep 17 00:00:00 2001
From: Volkor <me@volkor.me>
Date: Mon, 26 Jun 2023 08:04:21 +1000
Subject: [PATCH] fix: list the files in a more sensible way it even generates
 an nice error!

---
 src/handlers/list_files.rs | 84 +++++++++++++++++++++++++-------------
 src/handlers/mod.rs        | 12 +++++-
 2 files changed, 66 insertions(+), 30 deletions(-)

diff --git a/src/handlers/list_files.rs b/src/handlers/list_files.rs
index 54cdc79..942735b 100644
--- a/src/handlers/list_files.rs
+++ b/src/handlers/list_files.rs
@@ -1,6 +1,6 @@
 use salvo::{handler, Request, Response, hyper::header::HOST, prelude::StatusCode};
 
-use crate::{db, SQLITE, handlers::{TemplateStruct, render_template, convert_file_size, convert_unix_timestamp}};
+use crate::{db, SQLITE, handlers::{TemplateStruct, render_template, convert_file_size, convert_unix_timestamp, count_file_metrics}};
 
 use super::guess_ip;
 
@@ -24,40 +24,66 @@ pub async fn list_files(req: &mut Request, res: &mut Response) {
 
     let mut html = String::new();
     // For each file in the list, add the html to the rendered string
-    for f in files.unwrap() {
-        // Change the filename to a file url
-        let fileurl = format!("/{}", &f.filename);
-
-        // Change the filesize to a human readable value
-        let human_size = convert_file_size(f.filesize);
-
-        // Change the expiry to a human readable value
-        let human_time = convert_unix_timestamp(f.expiry);
-
-        // If isDeleted, change colour to red, else green
-        let mut colour: String = String::new();
-        if f.is_deleted {
-            colour = "background-color: #ff00000a;".to_string()
-        } else {
-            colour = "background-color: #00ff100a;".to_string()
+    match files.as_ref() {
+        Ok(file_metrics) => {
+            for f in file_metrics {
+                // Change the filename to a file url
+                let fileurl = format!("/{}", &f.filename);
+
+                // Change the filesize to a human readable value
+                let human_size = convert_file_size(f.filesize);
+
+                // Change the expiry to a human readable value
+                let human_time = convert_unix_timestamp(f.expiry);
+
+                // If isDeleted, change colour to red, else green
+                let mut colour: String = String::new();
+                if f.is_deleted {
+                    colour = "background-color: #ff00000a;".to_string()
+                } else {
+                    colour = "background-color: #00ff100a;".to_string()
+                }
+
+                // Add a new file to the rendered string
+                html.push_str(&format!("<tr style='{}'><td><a href={}>{}</a></td><td data-sort='{}'>{}</td><td>{}</td><td>{}</td><td data-sort='{}'>{}</td></tr>",
+                    colour,
+                    fileurl.as_str(),
+                    f.filename.as_str(),
+                    f.filesize,
+                    human_size.as_str(),
+                    f.mimetype.as_str(),
+                    f.views.to_owned(),
+                    f.expiry.to_owned(),
+                    human_time.to_owned(),
+                ));
+            }
         }
+        Err(err) => {
+            // Log error to console
+            tracing::error!("Error retrieving file metrics: {:?}", err);
 
-        // Add a new file to the rendered string
-        html.push_str(&format!("<tr style='{}'><td><a href={}>{}</a></td><td data-sort='{}'>{}</td><td>{}</td><td>{}</td><td data-sort='{}'>{}</td></tr>",
-            colour,
-            fileurl.as_str(),
-            f.filename.as_str(),
-            f.filesize,
-            human_size.as_str(),
-            f.mimetype.as_str(),
-            f.views.to_owned(),
-            f.expiry.to_owned(),
-            human_time.to_owned(),
-        ));
+            // Render a nice error page for the poor user
+            let template_filename = "error.html";
+            let template = TemplateStruct {
+                domain: String::from(headers[HOST].to_str().unwrap()),
+                message1: String::from("Error 500: Internal Server Error"),
+                message2: String::from(
+                    "Something went wrong while reading the result from the database, uh oh :(",
+                ),
+                ..Default::default()
+            };
+
+            let status_code = StatusCode::INTERNAL_SERVER_ERROR;
+            render_template(res, headers, template_filename, template, status_code).await;
+        }
     }
+    
     // Close the table when all files are 'rendered'
     html.push_str("</table>");
 
+    // Log this to the server console  
+    tracing::info!("New Request: /my_files ({} Files", count_file_metrics(&files) );
+
     let template_filename = "my_files.html";
     let template = TemplateStruct {
         domain: String::from(headers[HOST].to_str().unwrap()),
diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs
index 549bda9..eca8f94 100644
--- a/src/handlers/mod.rs
+++ b/src/handlers/mod.rs
@@ -10,8 +10,9 @@ use salvo::{
 };
 use chrono::{DateTime, Utc};
 use chrono_humanize::Humanize;
+use sqlx::Error;
 
-use crate::CONFIG;
+use crate::{CONFIG, db::FileMetric};
 
 // Submodules for each request handler
 pub mod delete_file;
@@ -197,4 +198,13 @@ fn convert_unix_timestamp(unix_timestamp: i64) -> String {
     let relative_date = datetime.humanize();
 
     relative_date.to_string()
+}
+
+/// Calculate the number of files in the FileMetric result
+// I'm lazy so this doesn't really need to be it's own function but it was easier to do this.
+fn count_file_metrics(file_metrics: &Result<Vec<FileMetric>, Error>) -> usize {
+    match file_metrics {
+        Ok(metrics) => metrics.len(),
+        Err(_) => 0,
+    }
 }
\ No newline at end of file
-- 
GitLab