create-schematic-gen-site/source/csgs/task.d

115 lines
3.8 KiB
D

module csgs.task;
import slf4d;
import scheduled;
import scheduled.taskpool_scheduler;
import std.datetime;
import std.typecons;
import std.json;
import std.string;
import std.file;
import std.stdio;
import csgs.extract;
void startScheduledTasks() {
JobScheduler scheduler = new TaskPoolScheduler();
Job cleanJob = new FunctionJob(&cleanOldExtracts);
scheduler.addJob(cleanJob, new FixedIntervalSchedule(days(1)));
Job updateCheckJob = new FunctionJob(&checkForExtractorUpdate);
scheduler.addJob(updateCheckJob, new FixedIntervalSchedule(hours(1)));
scheduler.start();
}
private void cleanOldExtracts() {
import std.file;
immutable MAX_AGE = days(5);
info("Cleaning old extracts.");
if (!exists(EXTRACTS_DIR)) return;
immutable SysTime now = Clock.currTime();
foreach (DirEntry entry; dirEntries(EXTRACTS_DIR, SpanMode.shallow, false)) {
if (entry.isDir) {
infoF!"Removing directory %s."(entry.name);
rmdirRecurse(entry.name);
} else if (entry.isFile) {
immutable Duration age = now - entry.timeLastModified();
if (age > MAX_AGE) {
infoF!"Removing extract %s because it's too old."(entry.name);
std.file.remove(entry.name);
}
}
}
}
private void checkForExtractorUpdate() {
import requests;
import std.json;
import std.stdio;
import std.string;
import std.file;
info("Checking for MaterialsExtractor program updates.");
// First request the latest release from GitHub API:
Request req = Request();
req.addHeaders(["Accept": "application/vnd.github+json"]);
Response resp = req.get("https://api.github.com/repos/andrewlalis/MaterialsExtractor/releases/latest");
if (resp.code() != 200) {
warnF!"Failed to get the latest MaterialsExtractor release. Status code %d."(resp.code);
return;
}
JSONValue responseJson = parseJSON(resp.responseBody.toString());
// Get the release's version, compare it with our current version.
immutable string releaseVersion = responseJson.object["tag_name"].str;
infoF!"Found release version %s"(releaseVersion);
Nullable!string currentVersion = getCurrentExtractorVersion();
if (!currentVersion.isNull && currentVersion.get() >= releaseVersion) {
infoF!"Skipping this version since it's not newer than the current %s."(currentVersion.get);
return;
}
// Find the release's asset, and download it.
Nullable!JSONValue nullableAsset = findJarAsset(responseJson);
if (nullableAsset.isNull) {
warn("Latest release has no asset. Ignoring.");
return;
}
JSONValue asset = nullableAsset.get();
immutable string filename = asset.object["name"].str;
immutable string downloadUrl = asset.object["browser_download_url"].str;
infoF!"Found asset: %s. Downloading from %s."(filename, downloadUrl);
if (exists(filename)) {
std.file.remove(filename);
}
Request downloadRequest = Request();
downloadRequest.useStreaming = true;
Response downloadResponse = downloadRequest.get(downloadUrl);
File f = File(filename, "wb");
auto stream = downloadResponse.receiveAsRange();
while (!stream.empty) {
f.rawWrite(stream.front);
stream.popFront();
}
f.close();
infoF!"Downloaded file to %s"(f.name);
}
private Nullable!JSONValue findJarAsset(ref JSONValue response) {
foreach (JSONValue asset; response.object["assets"].array) {
immutable string name = asset.object["name"].str;
if (
startsWith(name, "materials-extractor") &&
endsWith(name, ".jar") &&
asset.object["content_type"].str == "application/java-archive"
) {
return nullable(asset);
}
}
return Nullable!JSONValue.init;
}