This commit is contained in:
2025-11-26 11:00:11 +01:00
parent ce7bc124ed
commit 2c1cc78cb3
8 changed files with 41 additions and 12 deletions

1
.gitignore vendored
View File

@@ -15,6 +15,7 @@ main
*.out *.out
*.zst *.zst
*.gzip *.gzip
*.env
bin/ bin/

Binary file not shown.

View File

@@ -14,3 +14,25 @@ pub fn Crypto.hash_password(password string) !string {
pub fn Crypto.hash_verify(password string, hash string) !bool { pub fn Crypto.hash_verify(password string, hash string) !bool {
return argon2.verify(hash, password.bytes()) or { return error('argon2 verify failed: ${err}') } return argon2.verify(hash, password.bytes()) or { return error('argon2 verify failed: ${err}') }
} }
// db structure
//
// users
// CREATE TABLE users (
// id SERIAL PRIMARY KEY,
// name TEXT UNIQUE NOT NULL,
// password_hash TEXT NOT NULL
// );
//
// logins
// CREATE TABLE login_attempts (
// id SERIAL PRIMARY KEY,
// username TEXT NOT NULL,
// ip TEXT NOT NULL,
// success BOOLEAN NOT NULL,
// attempt_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
// );
//
// files
//
//

View File

@@ -127,8 +127,8 @@ fn populate() (&util.Config, &util.Embedded) {
} }
} }
}, &util.Embedded{ }, &util.Embedded{
style_css: $embed_file('assets/style/style.css', .zlib).to_string() style_css: $embed_file('template/assets/style.css', .zlib).to_string()
error_css: $embed_file('assets/style/error.css', .zlib).to_string() error_css: $embed_file('template/assets/error.css', .zlib).to_string()
} }
} }

View File

@@ -170,7 +170,6 @@ body {
border-bottom: 1px solid var(--border-color); border-bottom: 1px solid var(--border-color);
background-color: var(--bg-secondary); background-color: var(--bg-secondary);
transition: background-color 0.3s ease, border-color 0.3s ease; transition: background-color 0.3s ease, border-color 0.3s ease;
overflow: scroll;
height: 100%; height: 100%;
} }
@@ -244,6 +243,10 @@ body {
-webkit-tap-highlight-color: transparent; -webkit-tap-highlight-color: transparent;
} }
.icon svg {
fill: var(--text-secondary);
}
.file-list { .file-list {
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View File

@@ -12,6 +12,7 @@
<body> <body>
<div class="container"> <div class="container">
<div class="header"> <div class="header">
<div class
<div class="breadcrumbs">Folder Path</div> <div class="breadcrumbs">Folder Path</div>
<div class="path-container"> <div class="path-container">
@{directory} @{directory}

View File

@@ -6,15 +6,16 @@ import time
pub struct Database { pub struct Database {
pub: pub:
host string
port int
username string username string
password string password string
} }
pub struct Config { pub struct Config {
pub mut: pub:
root string root string
port int port int
pub:
database Database database Database
} }
@@ -53,6 +54,8 @@ pub fn Utility.get_icon(ext string, is_dir bool) string {
'zip': '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M640-480v-80h80v80h-80Zm0 80h-80v-80h80v80Zm0 80v-80h80v80h-80ZM447-640l-80-80H160v480h400v-80h80v80h160v-400H640v80h-80v-80H447ZM160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h240l80 80h320q33 0 56.5 23.5T880-640v400q0 33-23.5 56.5T800-160H160Zm0-80v-480 480Z"/></svg>' 'zip': '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M640-480v-80h80v80h-80Zm0 80h-80v-80h80v80Zm0 80v-80h80v80h-80ZM447-640l-80-80H160v480h400v-80h80v80h160v-400H640v80h-80v-80H447ZM160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h240l80 80h320q33 0 56.5 23.5T880-640v400q0 33-23.5 56.5T800-160H160Zm0-80v-480 480Z"/></svg>'
'rar': '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M640-480v-80h80v80h-80Zm0 80h-80v-80h80v80Zm0 80v-80h80v80h-80ZM447-640l-80-80H160v480h400v-80h80v80h160v-400H640v80h-80v-80H447ZM160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h240l80 80h320q33 0 56.5 23.5T880-640v400q0 33-23.5 56.5T800-160H160Zm0-80v-480 480Z"/></svg>' 'rar': '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M640-480v-80h80v80h-80Zm0 80h-80v-80h80v80Zm0 80v-80h80v80h-80ZM447-640l-80-80H160v480h400v-80h80v80h160v-400H640v80h-80v-80H447ZM160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h240l80 80h320q33 0 56.5 23.5T880-640v400q0 33-23.5 56.5T800-160H160Zm0-80v-480 480Z"/></svg>'
'7z': '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M640-480v-80h80v80h-80Zm0 80h-80v-80h80v80Zm0 80v-80h80v80h-80ZM447-640l-80-80H160v480h400v-80h80v80h160v-400H640v80h-80v-80H447ZM160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h240l80 80h320q33 0 56.5 23.5T880-640v400q0 33-23.5 56.5T800-160H160Zm0-80v-480 480Z"/></svg>' '7z': '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M640-480v-80h80v80h-80Zm0 80h-80v-80h80v80Zm0 80v-80h80v80h-80ZM447-640l-80-80H160v480h400v-80h80v80h160v-400H640v80h-80v-80H447ZM160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h240l80 80h320q33 0 56.5 23.5T880-640v400q0 33-23.5 56.5T800-160H160Zm0-80v-480 480Z"/></svg>'
'zst': '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M640-480v-80h80v80h-80Zm0 80h-80v-80h80v80Zm0 80v-80h80v80h-80ZM447-640l-80-80H160v480h400v-80h80v80h160v-400H640v80h-80v-80H447ZM160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h240l80 80h320q33 0 56.5 23.5T880-640v400q0 33-23.5 56.5T800-160H160Zm0-80v-480 480Z"/></svg>'
'gzip': '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M640-480v-80h80v80h-80Zm0 80h-80v-80h80v80Zm0 80v-80h80v80h-80ZM447-640l-80-80H160v480h400v-80h80v80h160v-400H640v80h-80v-80H447ZM160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h240l80 80h320q33 0 56.5 23.5T880-640v400q0 33-23.5 56.5T800-160H160Zm0-80v-480 480Z"/></svg>'
'mp3': '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M430-200q38 0 64-26t26-64v-150h120v-80H480v155q-11-8-23.5-11.5T430-380q-38 0-64 26t-26 64q0 38 26 64t64 26ZM240-80q-33 0-56.5-23.5T160-160v-640q0-33 23.5-56.5T240-880h320l240 240v480q0 33-23.5 56.5T720-80H240Zm280-520v-200H240v640h480v-440H520ZM240-800v200-200 640-640Z"/></svg>' 'mp3': '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M430-200q38 0 64-26t26-64v-150h120v-80H480v155q-11-8-23.5-11.5T430-380q-38 0-64 26t-26 64q0 38 26 64t64 26ZM240-80q-33 0-56.5-23.5T160-160v-640q0-33 23.5-56.5T240-880h320l240 240v480q0 33-23.5 56.5T720-80H240Zm280-520v-200H240v640h480v-440H520ZM240-800v200-200 640-640Z"/></svg>'
'mp4': '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M360-240h160q17 0 28.5-11.5T560-280v-40l80 42v-164l-80 42v-40q0-17-11.5-28.5T520-480H360q-17 0-28.5 11.5T320-440v160q0 17 11.5 28.5T360-240ZM240-80q-33 0-56.5-23.5T160-160v-640q0-33 23.5-56.5T240-880h320l240 240v480q0 33-23.5 56.5T720-80H240Zm280-520v-200H240v640h480v-440H520ZM240-800v200-200 640-640Z"/></svg>' 'mp4': '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M360-240h160q17 0 28.5-11.5T560-280v-40l80 42v-164l-80 42v-40q0-17-11.5-28.5T520-480H360q-17 0-28.5 11.5T320-440v160q0 17 11.5 28.5T360-240ZM240-80q-33 0-56.5-23.5T160-160v-640q0-33 23.5-56.5T240-880h320l240 240v480q0 33-23.5 56.5T720-80H240Zm280-520v-200H240v640h480v-440H520ZM240-800v200-200 640-640Z"/></svg>'
'avi': '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M360-240h160q17 0 28.5-11.5T560-280v-40l80 42v-164l-80 42v-40q0-17-11.5-28.5T520-480H360q-17 0-28.5 11.5T320-440v160q0 17 11.5 28.5T360-240ZM240-80q-33 0-56.5-23.5T160-160v-640q0-33 23.5-56.5T240-880h320l240 240v480q0 33-23.5 56.5T720-80H240Zm280-520v-200H240v640h480v-440H520ZM240-800v200-200 640-640Z"/></svg>' 'avi': '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M360-240h160q17 0 28.5-11.5T560-280v-40l80 42v-164l-80 42v-40q0-17-11.5-28.5T520-480H360q-17 0-28.5 11.5T320-440v160q0 17 11.5 28.5T360-240ZM240-80q-33 0-56.5-23.5T160-160v-640q0-33 23.5-56.5T240-880h320l240 240v480q0 33-23.5 56.5T720-80H240Zm280-520v-200H240v640h480v-440H520ZM240-800v200-200 640-640Z"/></svg>'
@@ -116,7 +119,7 @@ pub fn Utility.list_files(dir_path string, relative string) ![]FileEntry {
entries << FileEntry{ entries << FileEntry{
name: if is_dir { '${file}/' } else { file } name: if is_dir { '${file}/' } else { file }
abs_path: Utility.normalize_path(full_path) abs_path: Utility.normalize_path(full_path)
path: Utility.normalize_path(full_path).split(relative)[1] // if relative != "" { Utility.normalize_path(full_path.split(relative)[1]) } else { Utility.normalize_path(full_path) } path: Utility.normalize_path(full_path).split(relative)[1] or { 'err' }
is_dir: is_dir is_dir: is_dir
size: if !is_dir { file_info.size } else { 0 } size: if !is_dir { file_info.size } else { 0 }
modified: file_info.mtime modified: file_info.mtime
@@ -191,18 +194,17 @@ pub fn HtmlBuilder.generate_file_list(entries []FileEntry, current_path string)
for entry in entries { for entry in entries {
if entry.is_dir { if entry.is_dir {
dir_count++ dir_count++
file_class := 'directory' html += '<div class="file-row directory">'
html += '<div class="file-row ${file_class}">' html += '<div class="icon">${entry.icon}</div>'
html += '<div>${entry.icon}</div>'
html += '<div class="name"><a href="${entry.path}">${entry.name}</a></div>' html += '<div class="name"><a href="${entry.path}">${entry.name}</a></div>'
html += '<div class="size">-</div>' html += '<div class="size">${Utility.format_size(entry.size)}</div>'
html += '<div class="date">${Utility.format_date(entry.modified)}</div>' html += '<div class="date">${Utility.format_date(entry.modified)}</div>'
html += '</div>' html += '</div>'
} else { } else {
file_count++ file_count++
total_size += entry.size total_size += entry.size
html += '<div class="file-row file">' html += '<div class="file-row file">'
html += '<div>${entry.icon}</div>' html += '<div class="icon">${entry.icon}</div>'
html += '<div class="name"><a href="${entry.path}">${entry.name}</a></div>' html += '<div class="name"><a href="${entry.path}">${entry.name}</a></div>'
html += '<div class="size">${Utility.format_size(entry.size)}</div>' html += '<div class="size">${Utility.format_size(entry.size)}</div>'
html += '<div class="date">${Utility.format_date(entry.modified)}</div>' html += '<div class="date">${Utility.format_date(entry.modified)}</div>'