Basic file upload
This commit is contained in:
parent
2bcef49e5e
commit
a45ccfe0e4
7 changed files with 38 additions and 7 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -2,3 +2,4 @@
|
||||||
**/zig-cache
|
**/zig-cache
|
||||||
**.db
|
**.db
|
||||||
/config.json
|
/config.json
|
||||||
|
/files
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
|
@ -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),
|
||||||
};
|
};
|
||||||
|
|
17
src/main/controllers/api/drive.zig
Normal file
17
src/main/controllers/api/drive.zig
Normal 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, .{});
|
||||||
|
}
|
||||||
|
};
|
Loading…
Reference in a new issue