create-schematic-gen-site/source/app.d

75 lines
2.6 KiB
D

import handy_httpd;
import handy_httpd.handlers.path_delegating_handler;
import handy_httpd.handlers.file_resolving_handler;
import slf4d;
import slf4d.default_provider;
import std.path;
import std.file;
const EXTRACTS_DIR = "extracts";
const EXTRACT_FILENAME = "__EXTRACT__.json";
const EXTRACT_COMMAND = ["java", "-jar", "materials-extractor-v1.0.0.jar"];
void main() {
auto provider = new shared DefaultProvider(true, Levels.INFO);
configureLoggingProvider(provider);
ServerConfig config = ServerConfig.defaultValues();
config.workerPoolSize = 3;
config.connectionQueueSize = 10;
config.port = 8100;
PathDelegatingHandler handler = new PathDelegatingHandler();
handler.addMapping("POST", "/extracts", &handleExtract);
handler.addMapping("GET", "/extracts/{extractId}", &getExtract);
FileResolvingHandler fileHandler = new FileResolvingHandler("site", DirectoryResolutionStrategies.serveIndexFiles);
handler.addMapping("/**", fileHandler);
new HttpServer(handler, config).start();
}
void handleExtract(ref HttpRequestContext ctx) {
import std.json;
import std.uuid;
import std.process;
import std.stdio;
immutable UUID extractId = randomUUID();
MultipartFormData data = ctx.request.readBodyAsMultipartFormData();
// TODO: Validate data (unique filenames, no non-file elements, etc.)
const extractDir = buildPath(EXTRACTS_DIR, extractId.toString());
if (!exists(extractDir)) {
mkdirRecurse(extractDir);
}
string[] filenames;
foreach (MultipartElement element; data.elements) {
if (element.filename.isNull) continue;
const filePath = buildPath(extractDir, element.filename.get());
std.file.write(filePath, element.content);
filenames ~= filePath;
}
const extractJsonPath = buildPath(extractDir, EXTRACT_FILENAME);
infoF!"Running extract process on files: %s"(filenames);
Pid pid = spawnProcess(EXTRACT_COMMAND ~ filenames, std.stdio.stdin, File(extractJsonPath, "w"));
int exitCode = wait(pid);
infoF!"Exit code: %d"(exitCode);
if (exitCode != 0) {
ctx.response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR);
ctx.response.writeBodyString(readText(extractJsonPath));
} else {
JSONValue result = JSONValue.emptyObject;
result.object["extractId"] = JSONValue(extractId.toString());
ctx.response.writeBodyString(result.toJSON(), "application/json");
// Remove schematic files after we are done.
foreach (string schematicFile; filenames) {
std.file.remove(schematicFile);
}
}
}
void getExtract(ref HttpRequestContext ctx) {
string extractId = ctx.request.getPathParamAs!string("extractId");
const extractFile = buildPath(EXTRACTS_DIR, extractId, EXTRACT_FILENAME);
fileResponse(ctx.response, extractFile, "application/json");
}