chris-website/source/watcher.d

122 lines
3.3 KiB
D

import std.array;
import std.algorithm;
import std.experimental.logger;
import std.file;
import std.stdio;
import vibe.d;
import app;
import page;
/**
* Loads pages into memory and sets up a "watcher" to watch a directory for file changes.
*/
void initPages(T, string sortPred)(ref T[string] array, ref T*[] sortedRange, const string directory) {
bool addPage(string path) {
try {
T newPage = new T(path);
logf("Added %s", newPage.slug);
array[newPage.slug] = newPage;
return true;
} catch (page.ArticleParseException e) {
logf("Could not parse %s", path);
return false;
}
}
// Initial scan
void scan(NativePath path, int level = 0) {
logf("Scanning %s", path.toString());
foreach(file; iterateDirectory(path)) {
if (file.isDirectory) {
scan(path ~ file.name, level + 1);
} else {
addPage((path ~ file.name).toString());
}
}
}
void sortThings() {
sortedRange = sort!(sortPred)(array.values)
.filter!(x => !x.isHidden)
.map!"&a".array;
logf("sorted: %s", sortedRange);
}
if (!existsFile(getWorkingDirectory() ~ directory)) {
createDirectory(getWorkingDirectory() ~ directory);
}
scan(getWorkingDirectory() ~ directory);
sortThings();
DirectoryWatcher watcher = watchDirectory(getWorkingDirectory() ~ directory, true);
//auto watcher = FileWatch((getWorkingDirectory() ~ directory).toString(), true);
bool shouldStop = false;
while (!shouldStop) {
// Try to reduce changes to only one DirectoryChangeType per change
DirectoryChange[] changes;
shouldStop = !watcher.readChanges(changes);
foreach(change; changes) {
logf("=======[New changes]======");
string[] changeTypes = ["added", "removed", "modified"];
logf("Path: %s, type: %s", change.path.toString(), changeTypes[change.type]);
if (endsWith(change.path.toString(), ".kate-swp")) continue;
switch (change.type) with (DirectoryChangeType){
case added:
try {
addPage(change.path.toString());
} catch(Exception e) {
warningf("Error while updating %s: %s", change.path.toString(), e.msg);
}
break;
case modified:
T newPage;
try {
newPage = new T(change.path.toString());
log(newPage.slug);
if (newPage.slug in array) {
log("Slug not changed");
array[newPage.slug] = newPage;
} else {
log("Slug changed");
foreach(item; array) {
if (item.name == change.path.toString()) {
logf("Removed %s, which is the old slug of %s", newPage.slug, item.slug);
array.remove(item.slug);
}
}
}
logf("%s modified: %s", typeid(T).stringof, newPage.slug);
array[newPage.slug] = newPage;
} catch(page.ArticleParseException e) {
warningf("Could not parse %s", change.path.toString());
} catch (Exception e) {
warningf("Error while updating %s: %s", change.path.toString(), e.msg);
}
break;
case removed:
try {
foreach(item; array.byValue) {
logf(" - %s", item.name);
if (item.name == change.path.toString()) {
logf("Removed %s", item.slug);
array.remove(item.slug);
}
}
} catch(Exception e) {}
break;
default: break;
}
log("Current state:");
//sortedRange = sort!("a."~sortProp~" < b."~sortProp)(array.values);
sortThings();
foreach (item; array) {
logf("%s - %s", item.name, item.slug);
}
}
}
}