chore: group API endpoints
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
parent
b6ca760a58
commit
25ac4c2fa3
3 changed files with 105 additions and 103 deletions
|
@ -5,7 +5,7 @@ function onClick() {
|
|||
Util.paused = !Util.paused;
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", Util.resolveUrl("set_paused"));
|
||||
xhr.open("POST", Util.resolveUrl("api/set_paused"));
|
||||
xhr.send(Std.string(Util.paused));
|
||||
|
||||
updateDisplay();
|
||||
|
|
|
@ -140,10 +140,10 @@ fn tryHandleRequest(state: *State, res_: std.http.Server.Response) !void {
|
|||
|
||||
if (std.mem.eql(u8, path, "/") or std.mem.eql(u8, path, "/index.html")) {
|
||||
try routes.indexRoute(state, &res);
|
||||
} else if (std.mem.eql(u8, path, "/index.json")) {
|
||||
try routes.indexJsonRoute(state, &res);
|
||||
} else if (std.mem.eql(u8, path, "/set_paused")) {
|
||||
try routes.setPausedRoute(state, &res);
|
||||
} else if (std.mem.eql(u8, path, "/api/index.json")) {
|
||||
try routes.api.indexJsonRoute(state, &res);
|
||||
} else if (std.mem.eql(u8, path, "/api/set_paused")) {
|
||||
try routes.api.setPausedRoute(state, &res);
|
||||
} else if (std.mem.eql(u8, path, "/static/index.js")) {
|
||||
try routes.static(&res, assets.@"index.js", "application/javascript");
|
||||
} else if (std.mem.eql(u8, path, "/static/index.css")) {
|
||||
|
|
198
src/routes.zig
198
src/routes.zig
|
@ -31,6 +31,106 @@ pub fn static(res: *std.http.Server.Response, data: []const u8, mime: ?[]const u
|
|||
try res.finish();
|
||||
}
|
||||
|
||||
pub const api = struct {
|
||||
pub fn indexJsonRoute(
|
||||
state: *State,
|
||||
res: *std.http.Server.Response,
|
||||
) !void {
|
||||
const alloc = res.allocator;
|
||||
|
||||
const Response = struct {
|
||||
active_task: ?DownloadQueue.Task,
|
||||
tasks: []DownloadQueue.Task,
|
||||
vids: [][]u8,
|
||||
paused: bool,
|
||||
};
|
||||
|
||||
var arena = std.heap.ArenaAllocator.init(alloc);
|
||||
defer arena.deinit();
|
||||
const arena_alloc = arena.allocator();
|
||||
|
||||
// TODO: optimize
|
||||
const tasks = try alloc.alloc(DownloadQueue.Task, state.downloads.tasks.len());
|
||||
defer alloc.free(tasks);
|
||||
|
||||
var cur_task = state.downloads.tasks.first;
|
||||
var i: usize = 0;
|
||||
while (cur_task) |t| : (i += 1) {
|
||||
tasks[i] = t.data;
|
||||
cur_task = t.next;
|
||||
}
|
||||
|
||||
const vids_dir_path = try std.fs.path.join(alloc, &.{ state.conf.data_dir, "vids" });
|
||||
defer alloc.free(vids_dir_path);
|
||||
|
||||
var vids_dir = try std.fs.cwd().openIterableDir(vids_dir_path, .{});
|
||||
defer vids_dir.close();
|
||||
|
||||
var iter = vids_dir.iterate();
|
||||
|
||||
var vids = std.ArrayList([]u8).init(alloc);
|
||||
defer vids.deinit();
|
||||
while (try iter.next()) |ent| {
|
||||
if (ent.kind != .file)
|
||||
continue;
|
||||
|
||||
const quote = try std.Uri.escapeString(arena_alloc, ent.name);
|
||||
|
||||
try vids.append(try std.fmt.allocPrint(
|
||||
alloc,
|
||||
"{s}/vids/{s}",
|
||||
.{ state.conf.base_url, quote },
|
||||
));
|
||||
}
|
||||
|
||||
try res.headers.append("Content-Type", "application/json");
|
||||
// Streaming serialization to HTTP!
|
||||
res.transfer_encoding = .chunked;
|
||||
|
||||
const data = Response{
|
||||
.active_task = state.downloads.active_task,
|
||||
.tasks = tasks,
|
||||
.vids = vids.items,
|
||||
.paused = state.downloads.paused,
|
||||
};
|
||||
|
||||
try res.do();
|
||||
var buf_writer = std.io.bufferedWriter(res.writer());
|
||||
try std.json.stringify(data, .{}, buf_writer.writer());
|
||||
try buf_writer.flush();
|
||||
try res.finish();
|
||||
}
|
||||
|
||||
pub fn setPausedRoute(
|
||||
state: *State,
|
||||
res: *std.http.Server.Response,
|
||||
) !void {
|
||||
const alloc = res.allocator;
|
||||
|
||||
if (res.request.method != .POST) {
|
||||
try status_response.sendJsonResponseText(res, .method_not_allowed);
|
||||
return;
|
||||
}
|
||||
|
||||
const data = try res.reader().readAllAlloc(alloc, 1024);
|
||||
defer alloc.free(data);
|
||||
|
||||
const paused = if (std.mem.eql(u8, data, "true"))
|
||||
true
|
||||
else if (std.mem.eql(u8, data, "false"))
|
||||
false
|
||||
else {
|
||||
try status_response.sendJsonResponseText(res, .bad_request);
|
||||
return;
|
||||
};
|
||||
|
||||
std.log.info("setting paused state to {}", .{paused});
|
||||
state.downloads.setPaused(paused);
|
||||
|
||||
try status_response.sendJsonResponseText(res, .ok);
|
||||
}
|
||||
};
|
||||
|
||||
pub fn indexRoute(
|
||||
state: *State,
|
||||
res: *std.http.Server.Response,
|
||||
|
@ -180,75 +280,6 @@ pub fn indexRoute(
|
|||
try res.finish();
|
||||
}
|
||||
|
||||
pub fn indexJsonRoute(
|
||||
state: *State,
|
||||
res: *std.http.Server.Response,
|
||||
) !void {
|
||||
const alloc = res.allocator;
|
||||
|
||||
const Response = struct {
|
||||
active_task: ?DownloadQueue.Task,
|
||||
tasks: []DownloadQueue.Task,
|
||||
vids: [][]u8,
|
||||
paused: bool,
|
||||
};
|
||||
|
||||
var arena = std.heap.ArenaAllocator.init(alloc);
|
||||
defer arena.deinit();
|
||||
const arena_alloc = arena.allocator();
|
||||
|
||||
// TODO: optimize
|
||||
const tasks = try alloc.alloc(DownloadQueue.Task, state.downloads.tasks.len());
|
||||
defer alloc.free(tasks);
|
||||
|
||||
var cur_task = state.downloads.tasks.first;
|
||||
var i: usize = 0;
|
||||
while (cur_task) |t| : (i += 1) {
|
||||
tasks[i] = t.data;
|
||||
cur_task = t.next;
|
||||
}
|
||||
|
||||
const vids_dir_path = try std.fs.path.join(alloc, &.{ state.conf.data_dir, "vids" });
|
||||
defer alloc.free(vids_dir_path);
|
||||
|
||||
var vids_dir = try std.fs.cwd().openIterableDir(vids_dir_path, .{});
|
||||
defer vids_dir.close();
|
||||
|
||||
var iter = vids_dir.iterate();
|
||||
|
||||
var vids = std.ArrayList([]u8).init(alloc);
|
||||
defer vids.deinit();
|
||||
while (try iter.next()) |ent| {
|
||||
if (ent.kind != .file)
|
||||
continue;
|
||||
|
||||
const quote = try std.Uri.escapeString(arena_alloc, ent.name);
|
||||
|
||||
try vids.append(try std.fmt.allocPrint(
|
||||
alloc,
|
||||
"{s}/vids/{s}",
|
||||
.{ state.conf.base_url, quote },
|
||||
));
|
||||
}
|
||||
|
||||
try res.headers.append("Content-Type", "application/json");
|
||||
// Streaming serialization to HTTP!
|
||||
res.transfer_encoding = .chunked;
|
||||
|
||||
const data = Response{
|
||||
.active_task = state.downloads.active_task,
|
||||
.tasks = tasks,
|
||||
.vids = vids.items,
|
||||
.paused = state.downloads.paused,
|
||||
};
|
||||
|
||||
try res.do();
|
||||
var buf_writer = std.io.bufferedWriter(res.writer());
|
||||
try std.json.stringify(data, .{}, buf_writer.writer());
|
||||
try buf_writer.flush();
|
||||
try res.finish();
|
||||
}
|
||||
|
||||
pub const ApiTask = struct {
|
||||
url: []const u8,
|
||||
outname: ?[]const u8,
|
||||
|
@ -366,32 +397,3 @@ pub fn vidsRoute(
|
|||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn setPausedRoute(
|
||||
state: *State,
|
||||
res: *std.http.Server.Response,
|
||||
) !void {
|
||||
const alloc = res.allocator;
|
||||
|
||||
if (res.request.method != .POST) {
|
||||
try status_response.sendJsonResponseText(res, .method_not_allowed);
|
||||
return;
|
||||
}
|
||||
|
||||
const data = try res.reader().readAllAlloc(alloc, 1024);
|
||||
defer alloc.free(data);
|
||||
|
||||
const paused = if (std.mem.eql(u8, data, "true"))
|
||||
true
|
||||
else if (std.mem.eql(u8, data, "false"))
|
||||
false
|
||||
else {
|
||||
try status_response.sendJsonResponseText(res, .bad_request);
|
||||
return;
|
||||
};
|
||||
|
||||
std.log.info("setting paused state to {}", .{paused});
|
||||
state.downloads.setPaused(paused);
|
||||
|
||||
try status_response.sendJsonResponseText(res, .ok);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue