forked from tools/josh
1
0
Fork 0

Read directory structure from nav API

Fixes #128.
This commit is contained in:
Florine W. Dekker 2020-09-30 14:53:18 +02:00
parent ef49ed1c8f
commit 6901f5a02c
Signed by: FWDekker
GPG Key ID: B1B567AF58D6EE0F
4 changed files with 88 additions and 62 deletions

BIN
package-lock.json generated

Binary file not shown.

View File

@ -1,6 +1,6 @@
{
"name": "fwdekker.com",
"version": "0.37.5",
"version": "0.38.0",
"description": "The source code of [my personal website](https://fwdekker.com/).",
"author": "Felix W. Dekker",
"browser": "dist/bundle.js",
@ -36,12 +36,12 @@
"grunt-webpack": "^4.0.2",
"jsdom": "^16.4.0",
"jsdom-global": "^3.0.2",
"mocha": "^8.1.1",
"mocha": "^8.1.3",
"nyc": "^15.1.0",
"ts-loader": "^8.0.3",
"ts-loader": "^8.0.4",
"ts-node": "^9.0.0",
"typescript": "^4.0.2",
"webpack": "^4.44.1",
"typescript": "^4.0.3",
"webpack": "^4.44.2",
"webpack-cli": "^3.3.12"
}
}

View File

@ -8,75 +8,89 @@ import {HashProvider, User} from "./UserList";
* A file system.
*/
export class FileSystem {
static navRoot: Directory;
/**
* The root directory.
*/
readonly root: Directory;
/**
* Loads the contents of my home directory based on the navigation API of fwdekker.com.
*
* @return an empty promise :'(
*/
static async loadNavApi(): Promise<any> {
await fetch("https://fwdekker.com/api/nav/")
.then(it => it.json())
.then(json => this.navRoot = this.unpack(json)[1] as Directory)
.catch(e => {
console.error("Failed to fetch navigation elements", e);
this.navRoot = new Directory();
});
}
/**
* Unpacks the given entry from the navigation API.
*
* @param entry the entry to unpack
* @return the name and the (traversed and filled) node unpacked from the given entry
* @private
*/
private static unpack(entry: any): [string, Node] {
const name = entry.name?.toLowerCase()?.replace(/ /g, "-") ?? "";
if (entry.entries.length === 0)
return [`${name}.lnk`, new File(entry.link)];
const dir = new Directory();
entry.entries.forEach((child: any) => dir.add(...(this.unpack(child))))
return [name, dir];
}
/**
* Constructs a new file system.
*
* @param root the directory to set as the root
*/
constructor(root: Directory | undefined = undefined) {
if (root === undefined)
this.root =
new Directory({
"bin": Object.keys(commandBinaries)
.reduce((acc, key) => {
acc.add(key, new File(commandBinaries[key]));
return acc;
}, new Directory()),
"dev": new Directory({
"null": new NullFile()
}),
"etc": new Directory({
"passwd": new File(
[
new User("root", HashProvider.default.hashPassword("g9PjKu"), "/root",
"You're a hacker, Harry!"),
new User("felix", HashProvider.default.hashPassword("password"), undefined,
"Who are <i>you</i>?")
].map(it => User.toString(it)).join("\n") + "\n"
)
}),
"home": new Directory({
"felix": new Directory({
"personal": new Directory({
"blog.lnk": new File("https://blog.fwdekker.com/"),
"nukapedia.lnk": new File("https://fallout.wikia.com/wiki/User:FDekker"),
"steam.lnk": new File("https://steamcommunity.com/id/Waflix"),
}),
"projects": new Directory({
"converter.lnk": new File("https://fwdekker.com/tools/converter/"),
"dice.lnk": new File("https://fwdekker.com/tools/dice/"),
"doomsday.lnk": new File("https://fwdekker.com/tools/doomsday/"),
"fo76-dumps.lnk": new File("https://github.com/FWDekker/fo76-dumps"),
"josh.lnk": new File("https://git.fwdekker.com/FWDekker/fwdekker.com"),
"random-fo76.lnk": new File("https://fwdekker.com/tools/random-fo76/"),
"randomness.lnk": new File("https://github.com/FWDekker/intellij-randomness"),
"schaapi.lnk": new File("https://cafejojo.org/schaapi"),
"simplify-fractions.lnk": new File("https://fwdekker.com/tools/simplify-fractions/"),
}),
"social": new Directory({
"gitea.lnk": new File("https://git.fwdekker.com/explore/"),
"github.lnk": new File("https://github.com/FWDekker/"),
"stackoverflow.lnk": new File("https://stackoverflow.com/u/3307872"),
"linkedin.lnk": new File("https://www.linkedin.com/in/fwdekker/"),
}),
"me_irl.jpg": new File("https://static.fwdekker.com/img/avatar.jpg", "lnk"),
"pgp.pub": new File("https://static.fwdekker.com/misc/pgp.pub.txt", "lnk"),
"privacy-policy.html": new File("https://fwdekker.com/privacy/", "lnk"),
"resume.pdf": new File("https://static.fwdekker.com/misc/resume.pdf", "lnk"),
})
}),
"root": new Directory({
"password.txt": new File("root: g9PjKu")
})
});
else
if (root !== undefined) {
this.root = root;
return;
}
this.root = new Directory({
"bin": Object.keys(commandBinaries)
.reduce((acc, key) => {
acc.add(key, new File(commandBinaries[key]));
return acc;
}, new Directory()),
"dev": new Directory({
"null": new NullFile(),
}),
"etc": new Directory({
"passwd": new File(
[
new User("root", HashProvider.default.hashPassword("g9PjKu"), "/root",
"You're a hacker, Harry!"),
new User("felix", HashProvider.default.hashPassword("password"), undefined,
"Who are <i>you</i>?")
].map(it => User.toString(it)).join("\n") + "\n"
),
}),
"home": new Directory({
"felix": new Directory({
"pgp.pub": new File("https://static.fwdekker.com/misc/pgp.pub.txt", "lnk"),
"privacy-policy.html": new File("https://fwdekker.com/privacy/", "lnk"),
"resume.pdf": new File("https://static.fwdekker.com/misc/resume.pdf", "lnk"),
}),
}),
"root": new Directory({
"password.txt": new File("root: g9PjKu"),
}),
});
(this.get(new Path("home", "felix")) as Directory).addAll(FileSystem.navRoot);
}
@ -563,6 +577,15 @@ export class Directory extends Node {
this._nodes[name] = node;
}
/**
* Adds (references to) all files in the given directory to this directory.
*
* @param directory the directory of which to add the children to this directory
*/
addAll(directory: Directory): void {
Object.keys(directory.nodes).forEach(name => this.add(name, directory.get(name)!));
}
/**
* Removes the node with the given name.
*

View File

@ -1,4 +1,5 @@
import * as semver from "semver";
import {FileSystem} from "./FileSystem";
import {Persistence} from "./Persistence";
import {addOnLoad, ExpectedGoodbyeError, q} from "./Shared";
import {Terminal} from "./Terminal";
@ -58,7 +59,9 @@ addOnLoad(() => {
/**
* Initializes the application.
*/
addOnLoad(() => {
addOnLoad(async () => {
await FileSystem.loadNavApi();
window.terminal = new Terminal(
q("#terminal"),
q("#terminalInputField"),