fediglam/src/main/controllers/api/drive.zig

145 lines
3.8 KiB
Zig

const api = @import("api");
const http = @import("http");
const util = @import("util");
const controller_utils = @import("../../controllers.zig").helpers;
const Uuid = util.Uuid;
const DateTime = util.DateTime;
pub const drive_path = "/drive/:path*";
pub const DriveArgs = struct {
path: []const u8,
};
pub const query = struct {
pub const method = .GET;
pub const path = drive_path;
pub const Args = DriveArgs;
pub const Query = struct {
const OrderBy = enum {
created_at,
filename,
};
max_items: usize = 20,
like: ?[]const u8 = null,
order_by: OrderBy = .created_at,
direction: api.Direction = .descending,
prev: ?struct {
id: Uuid,
order_val: union(OrderBy) {
created_at: DateTime,
filename: []const u8,
},
} = null,
page_direction: api.PageDirection = .forward,
};
pub fn handler(req: anytype, res: anytype, srv: anytype) !void {
const result = srv.driveQuery(req.args.path, req.query) catch |err| switch (err) {
error.NotADirectory => {
const meta = try srv.getFile(path);
try res.json(.ok, meta);
return;
},
else => |e| return e,
};
try controller_utils.paginate(result, res, req.allocator);
}
};
pub const upload = struct {
pub const method = .POST;
pub const path = drive_path;
pub const Args = DriveArgs;
pub const Body = struct {
file: http.FormFile,
description: ?[]const u8 = null,
sensitive: bool = false,
};
pub fn handler(req: anytype, res: anytype, srv: anytype) !void {
const f = req.body.file;
try srv.uploadFile(.{
.dir = req.args.path,
.filename = f.filename,
.description = req.body.description,
.content_type = f.content_type,
.sensitive = req.body.sensitive,
}, f.data);
// TODO: print meta
try res.json(.created, .{});
}
};
pub const delete = struct {
pub const method = .DELETE;
pub const path = drive_path;
pub const Args = DriveArgs;
pub fn handler(req: anytype, res: anytype, srv: anytype) !void {
const info = try srv.driveLookup(req.args.path);
if (info == .dir)
try srv.driveRmdir(req.args.path)
else if (info == .file)
try srv.deleteFile(req.args.path);
return res.json(.ok, .{});
}
};
pub const mkdir = struct {
pub const method = .MKCOL;
pub const path = drive_path;
pub const Args = DriveArgs;
pub fn handler(req: anytype, res: anytype, srv: anytype) !void {
try srv.driveMkdir(req.args.path);
return res.json(.created, .{});
}
};
pub const update = struct {
pub const method = .PUT;
pub const path = drive_path;
pub const Args = DriveArgs;
pub const Body = struct {
description: ?[]const u8 = null,
content_type: ?[]const u8 = null,
sensitive: ?bool = null,
};
pub fn handler(req: anytype, res: anytype, srv: anytype) !void {
const info = try srv.driveLookup(req.args.path);
if (info != .file) return error.NotFile;
const new_info = try srv.updateFile(path, req.body);
try res.json(.ok, new_info);
}
};
pub const move = struct {
pub const method = .MOVE;
pub const path = drive_path;
pub const Args = DriveArgs;
pub fn handler(req: anytype, res: anytype, srv: anytype) !void {
const destination = req.fields.get("Destination") orelse return error.NoDestination;
try srv.driveMove(req.args.path, destination);
try res.fields.put("Location", destination);
try srv.json(.created, .{});
}
};