Basic file upload

This commit is contained in:
jaina heartles 2022-12-02 23:44:27 -08:00
parent 2bcef49e5e
commit a45ccfe0e4
7 changed files with 38 additions and 7 deletions

1
.gitignore vendored
View File

@ -2,3 +2,4 @@
**/zig-cache
**.db
/config.json
/files

View File

@ -9,6 +9,7 @@ const services = struct {
const communities = @import("./services/communities.zig");
const actors = @import("./services/actors.zig");
const auth = @import("./services/auth.zig");
const drive = @import("./services/files.zig").files;
const invites = @import("./services/invites.zig");
const notes = @import("./services/notes.zig");
const follows = @import("./services/follows.zig");
@ -509,5 +510,10 @@ fn ApiConn(comptime DbConn: type) type {
self.allocator,
);
}
pub fn uploadFile(self: *Self, filename: []const u8, body: []const u8) !void {
const user_id = self.user_id orelse return error.NoToken;
try services.drive.create(self.db, .{ .user_id = user_id }, filename, body, self.allocator);
}
};
}

View File

@ -26,8 +26,10 @@ pub const files = struct {
db.insert("drive_file", .{
.id = id,
.filename = filename,
.owner = owner,
.account_owner_id = if (owner == .user_id) owner.user_id else null,
.community_owner_id = if (owner == .community_id) owner.community_id else null,
.created_at = now,
.size = data.len,
}, alloc) catch return error.DatabaseFailure;
// Assume the previous statement succeeded and is not stuck in a transaction
errdefer {
@ -41,10 +43,10 @@ pub const files = struct {
const data_root = "./files";
fn saveFile(id: Uuid, data: []const u8) !void {
var dir = try std.fs.cwd().openDir(data_root);
var dir = try std.fs.cwd().openDir(data_root, .{});
defer dir.close();
var file = try dir.createFile(id.toCharArray(), .{ .exclusive = true });
var file = try dir.createFile(&id.toCharArray(), .{ .exclusive = true });
defer file.close();
try file.writer().writeAll(data);
@ -52,14 +54,14 @@ pub const files = struct {
}
pub fn deref(alloc: std.mem.Allocator, id: Uuid) ![]const u8 {
var dir = try std.fs.cwd().openDir(data_root);
var dir = try std.fs.cwd().openDir(data_root, .{});
defer dir.close();
return dir.readFileAlloc(alloc, id.toCharArray(), 1 << 32);
return dir.readFileAlloc(alloc, &id.toCharArray(), 1 << 32);
}
pub fn delete(db: anytype, alloc: std.mem.Allocator, id: Uuid) !void {
var dir = try std.fs.cwd().openDir(data_root);
var dir = try std.fs.cwd().openDir(data_root, .{});
defer dir.close();
try dir.deleteFile(id.toCharArray());

View File

@ -5,6 +5,7 @@ const server = @import("./server.zig");
pub const urlencode = @import("./urlencode.zig");
pub const socket = @import("./socket.zig");
const json = @import("./json.zig");
const multipart = @import("./multipart.zig");
pub const fields = @import("./fields.zig");
pub const Method = std.http.Method;
@ -19,6 +20,8 @@ pub const middleware = @import("./middleware.zig");
pub const Fields = fields.Fields;
pub const FormFile = multipart.FormFile;
pub const Protocol = enum {
http_1_0,
http_1_1,

View File

@ -110,7 +110,7 @@ const MultipartFormField = struct {
content_type: ?[]const u8 = null,
};
const FormFile = struct {
pub const FormFile = struct {
data: []const u8,
filename: []const u8,
};

View File

@ -2,6 +2,7 @@ const controllers = @import("../controllers.zig");
const auth = @import("./api/auth.zig");
const communities = @import("./api/communities.zig");
const drive = @import("./api/drive.zig");
const invites = @import("./api/invites.zig");
const users = @import("./api/users.zig");
const follows = @import("./api/users/follows.zig");
@ -26,4 +27,5 @@ pub const routes = .{
controllers.apiEndpoint(follows.delete),
controllers.apiEndpoint(follows.query_followers),
controllers.apiEndpoint(follows.query_following),
controllers.apiEndpoint(drive.upload),
};

View File

@ -0,0 +1,17 @@
pub const http = @import("http");
pub const upload = struct {
pub const method = .POST;
pub const path = "/drive/:path*";
pub const Body = struct {
file: http.FormFile,
};
pub fn handler(req: anytype, res: anytype, srv: anytype) !void {
const f = req.body.file;
try srv.uploadFile(f.filename, f.data);
try res.json(.created, .{});
}
};