Compare commits
No commits in common. "951bb90ad8e7ff424ce0317ba054c402ee08a8df" and "d4703a2127517bf9fad4e82f9ead1bd531d64641" have entirely different histories.
951bb90ad8
...
d4703a2127
4 changed files with 2 additions and 139 deletions
|
@ -233,7 +233,6 @@ const user_details = struct {
|
||||||
|
|
||||||
const drive = struct {
|
const drive = struct {
|
||||||
const dir_tmpl = @embedFile("./web/drive/directory.tmpl.html");
|
const dir_tmpl = @embedFile("./web/drive/directory.tmpl.html");
|
||||||
const file_tmpl = @embedFile("./web/drive/file.tmpl.html");
|
|
||||||
fn servePage(req: anytype, res: anytype, srv: anytype) !void {
|
fn servePage(req: anytype, res: anytype, srv: anytype) !void {
|
||||||
const info = try srv.driveGet(req.args.path);
|
const info = try srv.driveGet(req.args.path);
|
||||||
defer util.deepFree(srv.allocator, info);
|
defer util.deepFree(srv.allocator, info);
|
||||||
|
@ -247,14 +246,6 @@ const drive = struct {
|
||||||
try breadcrumbs.append(if (p.len != 0) p else continue);
|
try breadcrumbs.append(if (p.len != 0) p else continue);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: put this into the db layer
|
|
||||||
const FileClass = enum {
|
|
||||||
image,
|
|
||||||
video,
|
|
||||||
audio,
|
|
||||||
other,
|
|
||||||
};
|
|
||||||
|
|
||||||
switch (info) {
|
switch (info) {
|
||||||
.dir => |dir| try res.template(.ok, srv, dir_tmpl, .{
|
.dir => |dir| try res.template(.ok, srv, dir_tmpl, .{
|
||||||
.dir = dir,
|
.dir = dir,
|
||||||
|
@ -262,16 +253,7 @@ const drive = struct {
|
||||||
.mount_path = req.mount_path,
|
.mount_path = req.mount_path,
|
||||||
.base_drive_path = "drive",
|
.base_drive_path = "drive",
|
||||||
}),
|
}),
|
||||||
.file => |file| try res.template(.ok, srv, file_tmpl, .{
|
else => unreachable,
|
||||||
.file = file,
|
|
||||||
.breadcrumbs = breadcrumbs.items,
|
|
||||||
.mount_path = req.mount_path,
|
|
||||||
.base_drive_path = "drive",
|
|
||||||
.class = if (std.mem.eql(u8, file.meta.content_type orelse "", "image/jpeg"))
|
|
||||||
FileClass.image
|
|
||||||
else
|
|
||||||
FileClass.other,
|
|
||||||
}),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,7 +281,6 @@ const drive = struct {
|
||||||
const Action = enum {
|
const Action = enum {
|
||||||
mkdir,
|
mkdir,
|
||||||
delete,
|
delete,
|
||||||
upload,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const body_tag_from_query_param = "action";
|
pub const body_tag_from_query_param = "action";
|
||||||
|
@ -308,15 +289,9 @@ const drive = struct {
|
||||||
name: []const u8,
|
name: []const u8,
|
||||||
},
|
},
|
||||||
delete: struct {},
|
delete: struct {},
|
||||||
upload: struct {
|
|
||||||
file: http.FormFile,
|
|
||||||
sensitive: bool = false,
|
|
||||||
description: []const u8 = "",
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn handler(req: anytype, res: anytype, srv: anytype) !void {
|
pub fn handler(req: anytype, res: anytype, srv: anytype) !void {
|
||||||
const trimmed_path = std.mem.trim(u8, req.args.path, "/");
|
|
||||||
switch (req.body) {
|
switch (req.body) {
|
||||||
.mkdir => |body| {
|
.mkdir => |body| {
|
||||||
_ = try srv.driveMkdir(req.args.path, body.name);
|
_ = try srv.driveMkdir(req.args.path, body.name);
|
||||||
|
@ -325,6 +300,7 @@ const drive = struct {
|
||||||
try servePage(req, res, srv);
|
try servePage(req, res, srv);
|
||||||
},
|
},
|
||||||
.delete => {
|
.delete => {
|
||||||
|
const trimmed_path = std.mem.trim(u8, req.args.path, "/");
|
||||||
_ = try srv.driveDelete(trimmed_path);
|
_ = try srv.driveDelete(trimmed_path);
|
||||||
|
|
||||||
const dir = trimmed_path[0 .. std.mem.lastIndexOfScalar(u8, trimmed_path, '/') orelse trimmed_path.len];
|
const dir = trimmed_path[0 .. std.mem.lastIndexOfScalar(u8, trimmed_path, '/') orelse trimmed_path.len];
|
||||||
|
@ -336,27 +312,6 @@ const drive = struct {
|
||||||
try res.headers.put("Location", url);
|
try res.headers.put("Location", url);
|
||||||
return res.status(.see_other);
|
return res.status(.see_other);
|
||||||
},
|
},
|
||||||
.upload => |body| {
|
|
||||||
const entry = try srv.driveUpload(
|
|
||||||
.{
|
|
||||||
.filename = body.file.filename,
|
|
||||||
.dir = trimmed_path,
|
|
||||||
.description = body.description,
|
|
||||||
.content_type = body.file.content_type,
|
|
||||||
.sensitive = body.sensitive,
|
|
||||||
},
|
|
||||||
body.file.data,
|
|
||||||
);
|
|
||||||
defer util.deepFree(srv.allocator, entry);
|
|
||||||
|
|
||||||
const url = try std.fmt.allocPrint(srv.allocator, "{s}/drive/{s}", .{
|
|
||||||
req.mount_path,
|
|
||||||
std.mem.trim(u8, entry.file.path, "/"),
|
|
||||||
});
|
|
||||||
defer srv.allocator.free(url);
|
|
||||||
try res.headers.put("Location", url);
|
|
||||||
return res.status(.see_other);
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -37,30 +37,6 @@
|
||||||
<button type="submit">Create</button>
|
<button type="submit">Create</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="popup" id="upload">
|
|
||||||
<a class="button popup-open" href="#upload">
|
|
||||||
<i class="fa-solid fa-cloud-arrow-up"></i>
|
|
||||||
</a>
|
|
||||||
<a class="button popup-close" href="#">
|
|
||||||
<i class="fa-solid fa-xmark"></i>
|
|
||||||
</a>
|
|
||||||
<form class="popup-dialog" action="?action=upload" method="post" enctype="multipart/form-data">
|
|
||||||
<div>Upload</div>
|
|
||||||
<label>
|
|
||||||
<div>Select file</div>
|
|
||||||
<input type="file" name="file" />
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
<div>Description</div>
|
|
||||||
<input type="text" name="description" />
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
<div>Sensitive?</div>
|
|
||||||
<input type="checkbox" name="sensitive" />
|
|
||||||
</label>
|
|
||||||
<button type="submit">Upload</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<table class="directory-listing">
|
<table class="directory-listing">
|
||||||
{#for .dir.children.? |$child| =}
|
{#for .dir.children.? |$child| =}
|
||||||
|
|
|
@ -1,67 +0,0 @@
|
||||||
<div class="drive">
|
|
||||||
<ol class="breadcrumbs">
|
|
||||||
<li>
|
|
||||||
<a href="{.mount_path}/{.base_drive_path}/">
|
|
||||||
<i class="fa-solid fa-cloud"></i>
|
|
||||||
<span class="directory">/</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{#for .breadcrumbs |$crumb, $i| =}
|
|
||||||
<i class="fa-solid fa-chevron-right"></i>
|
|
||||||
<li>
|
|
||||||
<a href="{.mount_path}/{.base_drive_path}
|
|
||||||
{= #for @slice(.breadcrumbs, 0, $i) |$c|}/{$c}{/for =}
|
|
||||||
/{$crumb}">
|
|
||||||
{$crumb}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{/for =}
|
|
||||||
</ol>
|
|
||||||
|
|
||||||
<div class="popup-buttons">
|
|
||||||
<div class="popup" id="delete-{.file.name.?}">
|
|
||||||
<a href="#delete-{.file.name.?}">
|
|
||||||
<i class="fa-solid fa-trash"></i>
|
|
||||||
</a>
|
|
||||||
<form class="popup-dialog" action="?action=delete" method="post">
|
|
||||||
<div>Are you sure you want to delete this file?</div>
|
|
||||||
<input type="hidden" name="action" value="delete" />
|
|
||||||
<button type="submit">Yes, Delete</button>
|
|
||||||
<a href="#">No, Cancel</a>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="details">
|
|
||||||
<h2>{.file.name.?}</h2>
|
|
||||||
<div class="content">
|
|
||||||
{#if @isTag(.class, image) =}
|
|
||||||
<img src="/media/{.file.meta.id}" />
|
|
||||||
{#elif @isTag(.class, video) =}
|
|
||||||
<video src="/media/{.file.meta.id}" />
|
|
||||||
{#elif @isTag(.class, audio) =}
|
|
||||||
<audio src="/media/{.file.meta.id}" />
|
|
||||||
{#else =}
|
|
||||||
<a download href="/media/{.file.meta.id}"><i class="fa-solid fa-download"></i>{.file.name.?}</a>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
<div class="meta">
|
|
||||||
<h3>Metadata</h3>
|
|
||||||
|
|
||||||
<h4>Drive Path</h4>
|
|
||||||
<div>{.file.path}</div>
|
|
||||||
|
|
||||||
<h4>Filename</h4>
|
|
||||||
<div>{.file.meta.filename}</div>
|
|
||||||
|
|
||||||
<h4>Content Type</h4>
|
|
||||||
<div>{.file.meta.content_type}</div>
|
|
||||||
|
|
||||||
<h4>Sensitive?</h4>
|
|
||||||
<div>{.file.meta.sensitive}</div>
|
|
||||||
|
|
||||||
<h4>Description</h4>
|
|
||||||
<div>{.file.meta.description}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -210,7 +210,6 @@ fn print(writer: anytype, arg: anytype) !void {
|
||||||
if (T == void) return;
|
if (T == void) return;
|
||||||
if (comptime std.meta.trait.isZigString(T)) return htmlEscape(writer, arg);
|
if (comptime std.meta.trait.isZigString(T)) return htmlEscape(writer, arg);
|
||||||
if (comptime std.meta.trait.isNumber(T)) return std.fmt.format(writer, "{}", .{arg});
|
if (comptime std.meta.trait.isNumber(T)) return std.fmt.format(writer, "{}", .{arg});
|
||||||
if (comptime std.meta.trait.is(.Optional)(T)) return if (arg) |a| try print(writer, a);
|
|
||||||
try std.fmt.format(writer, "{}", .{arg});
|
try std.fmt.format(writer, "{}", .{arg});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue