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 **/zig-cache
**.db **.db
/config.json /config.json
/files

View file

@ -9,6 +9,7 @@ const services = struct {
const communities = @import("./services/communities.zig"); const communities = @import("./services/communities.zig");
const actors = @import("./services/actors.zig"); const actors = @import("./services/actors.zig");
const auth = @import("./services/auth.zig"); const auth = @import("./services/auth.zig");
const drive = @import("./services/files.zig").files;
const invites = @import("./services/invites.zig"); const invites = @import("./services/invites.zig");
const notes = @import("./services/notes.zig"); const notes = @import("./services/notes.zig");
const follows = @import("./services/follows.zig"); const follows = @import("./services/follows.zig");
@ -509,5 +510,10 @@ fn ApiConn(comptime DbConn: type) type {
self.allocator, 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", .{ db.insert("drive_file", .{
.id = id, .id = id,
.filename = filename, .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, .created_at = now,
.size = data.len,
}, alloc) catch return error.DatabaseFailure; }, alloc) catch return error.DatabaseFailure;
// Assume the previous statement succeeded and is not stuck in a transaction // Assume the previous statement succeeded and is not stuck in a transaction
errdefer { errdefer {
@ -41,10 +43,10 @@ pub const files = struct {
const data_root = "./files"; const data_root = "./files";
fn saveFile(id: Uuid, data: []const u8) !void { 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(); defer dir.close();
var file = try dir.createFile(id.toCharArray(), .{ .exclusive = true }); var file = try dir.createFile(&id.toCharArray(), .{ .exclusive = true });
defer file.close(); defer file.close();
try file.writer().writeAll(data); try file.writer().writeAll(data);
@ -52,14 +54,14 @@ pub const files = struct {
} }
pub fn deref(alloc: std.mem.Allocator, id: Uuid) ![]const u8 { 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(); 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 { 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(); defer dir.close();
try dir.deleteFile(id.toCharArray()); try dir.deleteFile(id.toCharArray());

View file

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

View file

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

View file

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