feat: introduce streamers that handle the stream and anonymization from github

This commit is contained in:
tdurieux
2024-04-03 11:13:01 +01:00
parent 73019c1b44
commit 4d12641c7e
64 changed files with 419 additions and 257 deletions
+118
View File
@@ -0,0 +1,118 @@
import * as express from "express";
import { getRepo, handleError } from "./route-utils";
import * as path from "path";
import AnonymizedFile from "../../core/AnonymizedFile";
import AnonymousError from "../../core/AnonymousError";
import { Tree, TreeElement } from "../../core/types";
import * as marked from "marked";
import { streamToString } from "../../core/anonymize-utils";
const router = express.Router();
const indexPriority = [
"index.html",
"index.htm",
"index.md",
"index.txt",
"index.org",
"index.1st",
"index",
"readme.md",
"readme.txt",
"readme.org",
"readme.1st",
"readme",
];
async function webView(req: express.Request, res: express.Response) {
const repo = await getRepo(req, res);
if (!repo) return;
try {
if (!repo.options.page || !repo.options.pageSource) {
throw new AnonymousError("page_not_activated", {
httpStatus: 400,
object: repo,
});
}
if (repo.options.pageSource?.branch != repo.model.source.branch) {
throw new AnonymousError("page_not_supported_on_different_branch", {
httpStatus: 400,
object: repo,
});
}
let requestPath = path.join(
repo.options.pageSource?.path,
req.path.substring(
req.path.indexOf(req.params.repoId) + req.params.repoId.length
)
);
let f = new AnonymizedFile({
repository: repo,
anonymizedPath: requestPath,
});
if (requestPath[requestPath.length - 1] == "/") {
// find index file
const paths = f.anonymizedPath.trim().split("/");
let currentAnonymized: TreeElement = await repo.anonymizedFiles({
includeSha: true,
});
for (let i = 0; i < paths.length; i++) {
const fileName = paths[i];
if (fileName == "") {
continue;
}
if (!(currentAnonymized as Tree)[fileName]) {
throw new AnonymousError("file_not_found", {
object: repo,
httpStatus: 404,
});
}
currentAnonymized = (currentAnonymized as Tree)[fileName];
}
let best_match = null;
indexSelector: for (const p of indexPriority) {
for (let filename in currentAnonymized) {
if (filename.toLowerCase() == p) {
best_match = filename;
break indexSelector;
}
}
}
if (best_match) {
requestPath = path.join(requestPath, best_match);
f = new AnonymizedFile({
repository: repo,
anonymizedPath: requestPath,
});
}
}
if (!f.isFileSupported()) {
throw new AnonymousError("file_not_supported", {
httpStatus: 400,
object: f,
});
}
if (f.extension() == "md") {
const content = await streamToString(await f.anonymizedContent());
res
.contentType("html")
.send(marked.marked(content, { headerIds: false, mangle: false }));
} else {
f.send(res);
}
} catch (error) {
handleError(error, res, req);
}
}
router.get("/:repoId/*", webView);
router.get("/:repoId", (req: express.Request, res: express.Response) => {
res.redirect("/w" + req.url + "/");
});
export default router;