Skip to content

Commit 50449aa

Browse files
committed
Convert timeline-notes, dnd-plugin, apiCache to TS
also fix bugs in existing TS. + utils.ts
1 parent 3992086 commit 50449aa

9 files changed

Lines changed: 599 additions & 27 deletions

File tree

http2-webserver/dnd-plugin.ts

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import { spellInfo, Spells as spells } from "dnd-api";
2+
import ApiWrapper from "./foreign-api-cache";
3+
4+
const spellsWrapper = new ApiWrapper(spells, "dnd-api-spells");
5+
6+
function replaceRange(
7+
s: string,
8+
start: number,
9+
end: number,
10+
substitute: string
11+
) {
12+
return s.substring(0, start) + substitute + s.substring(end);
13+
}
14+
15+
/**
16+
*
17+
* @param {String} htmlStr
18+
*/
19+
async function insertSpellTooltips(htmlStr: string) {
20+
const regex = /\{\{spell\:(.+?)\}\}/;
21+
let match = htmlStr.match(regex);
22+
const tooltips: { [key: string]: string } = {};
23+
while (match && match.length > 0) {
24+
const matchStr = match[1];
25+
console.log(matchStr);
26+
const tooltip = await createSpellTooltip(matchStr);
27+
tooltips[tooltip.replace] = tooltip.end;
28+
29+
if (match.index) {
30+
htmlStr = replaceRange(
31+
htmlStr,
32+
match.index,
33+
match.index + match[0].length,
34+
tooltip.replace
35+
);
36+
}
37+
38+
match = htmlStr.match(regex);
39+
}
40+
41+
for (const elem of Object.values(tooltips)) {
42+
htmlStr += elem;
43+
}
44+
45+
htmlStr += `<script src="https://static.jpcode.dev/js/dnd-tooltips.js"></script>`;
46+
47+
return htmlStr;
48+
}
49+
50+
/**
51+
*
52+
* @param {String} match
53+
*/
54+
async function createSpellTooltip(match: string) {
55+
let out = match;
56+
const id = match.toLowerCase().trim();
57+
const data = (await spellsWrapper.get(match)) as spellInfo;
58+
59+
let outData = null;
60+
if (data.name) {
61+
// console.log(data)
62+
// out = `<b class="spell">${match}</b>`
63+
out = `<a href="https://www.aidedd.org/dnd/sorts.php?vo=${data.name.replace(
64+
" ",
65+
"-"
66+
)}" class="spell" data-desc-id="${id + "-desc"}">
67+
${match}</a>`;
68+
69+
outData = {
70+
replace: out,
71+
end: `<div id="${id + "-desc"}" class="spell_desc">
72+
<b class="name">${data.name}</b>
73+
<span class="spell_meta">Level ${data.level} ${
74+
data.school.name
75+
}</span>
76+
<span class="cast_time">${data.casting_time}</span>
77+
<p class="desc">${escapeHtmlArr(data.desc)}</p>
78+
</div>`,
79+
id: id,
80+
};
81+
} else {
82+
outData = {
83+
replace: match,
84+
end: `<div class="spell_desc">${match}</div>`,
85+
id: id,
86+
};
87+
}
88+
89+
return outData;
90+
// <span class="level">${data.level}</span>
91+
// <span class="school">${data.school.name}</span>
92+
}
93+
94+
//TODO make the tooltip go towards the center of the screen
95+
96+
function escapeHtmlArr(unsafe: string[]) {
97+
let out = "";
98+
for (const str of unsafe) {
99+
out += `<p>${escapeHtml(str)}</p>`;
100+
}
101+
return out;
102+
}
103+
function escapeHtml(htmlStr: string) {
104+
return (htmlStr ?? "")
105+
.replace(/&/g, "&amp;")
106+
.replace(/</g, "&lt;")
107+
.replace(/>/g, "&gt;")
108+
.replace(/"/g, "&quot;")
109+
.replace(/'/g, "&#039;");
110+
}
111+
exports.insertSpellTooltips = insertSpellTooltips;

http2-webserver/files-manager.ts

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,25 @@ import dir from "node-dir";
55
import Path from "path";
66
import pug from "pug";
77
import DirectoryMap from "./directory-map";
8-
import { JPServerOptions } from "./http2server";
9-
import widgets from "./timeline-notes";
8+
import { JPServerOptions } from "./http2server2.1";
9+
import * as widgets from "./timeline-notes";
1010
import { Logger } from "./node_modules/log4js/types/log4js";
1111

1212
const {
13-
HTTP2_HEADER_METHOD,
14-
HTTP2_HEADER_PATH,
15-
HTTP2_HEADER_STATUS,
13+
// HTTP2_HEADER_METHOD,
14+
// HTTP2_HEADER_PATH,
15+
// HTTP2_HEADER_STATUS,
1616
HTTP2_HEADER_CONTENT_TYPE,
17-
HTTP2_HEADER_LINK,
18-
HTTP2_HEADER_ACCEPT_ENCODING,
17+
// HTTP2_HEADER_LINK,
18+
// HTTP2_HEADER_ACCEPT_ENCODING,
1919
HTTP2_HEADER_CONTENT_LENGTH,
2020
HTTP2_HEADER_LAST_MODIFIED,
2121
HTTP2_HEADER_CACHE_CONTROL,
22-
HTTP2_HEADER_CONTENT_ENCODING,
22+
// HTTP2_HEADER_CONTENT_ENCODING,
2323
} = http2.constants;
2424

2525
let logger: Logger;
2626
let runOpts: JPServerOptions;
27-
let exec_dirname: PathLike;
2827
let pugOptions: pug.Options & pug.LocalsObject;
2928
let defaultHeaders: OutgoingHttpHeaders;
3029
let isLogVerbose = false;
@@ -38,23 +37,9 @@ const init = (
3837
logger = lgr;
3938
pugOptions = pugOpts;
4039
defaultHeaders = defHeaders;
41-
exec_dirname = Path.basename(runOpts.pubpath);
4240
isLogVerbose = runOpts.log === "verbose";
4341
};
4442

45-
async function runWith(
46-
fileDescriptor: number,
47-
func: (fileDescriptor: number) => void
48-
) {
49-
try {
50-
func(fileDescriptor);
51-
} catch (e) {
52-
logger.error(e);
53-
} finally {
54-
fs.close(fileDescriptor);
55-
}
56-
}
57-
5843
type JpPugConfig = {
5944
template: string;
6045
data: object;
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import fs from "fs";
2+
import path from "path";
3+
4+
type CachedResponseData = {
5+
id: string;
6+
data?: {};
7+
};
8+
9+
type BaseApi = {
10+
get: (str: string) => {};
11+
list: () => {};
12+
};
13+
14+
export default class ApiWrapper<SourceApi extends BaseApi> {
15+
static cacheDir = path.join(__dirname, "foreign-api-cache");
16+
getter: SourceApi;
17+
cacheFile: string;
18+
cacheMap: { [key: string]: CachedResponseData };
19+
constructor(getter: SourceApi, apiName: string) {
20+
this.getter = getter;
21+
this.cacheFile = path.join(ApiWrapper.cacheDir, `${apiName}.json`);
22+
try {
23+
fs.mkdirSync(ApiWrapper.cacheDir);
24+
} catch (error) {
25+
console.warn(error);
26+
}
27+
this.cacheMap = {};
28+
}
29+
30+
async loadCache() {
31+
try {
32+
this.cacheMap = JSON.parse(
33+
fs.readFileSync(this.cacheFile).toString()
34+
);
35+
} catch (error) {
36+
console.error(error);
37+
}
38+
}
39+
40+
async get(queryStr: string) {
41+
queryStr = queryStr.toLowerCase();
42+
return this.cacheMap[queryStr]?.data ?? (await this._get(queryStr));
43+
}
44+
45+
/**
46+
* Get & cache data form foreign repo.
47+
*
48+
* DO NOT CALL THIS METHOD. Use `get` instead.
49+
* Will automatically be called when needed.
50+
*
51+
* @param {string} queryStr
52+
* @returns {ResponseData}
53+
*/
54+
async _get(queryStr: string) {
55+
let data = null;
56+
try {
57+
data = await this.getter.get(queryStr);
58+
this.cacheMap[queryStr] = {
59+
id: queryStr,
60+
data: data,
61+
};
62+
this.saveCache();
63+
} catch (error) {
64+
console.error(error);
65+
}
66+
return data;
67+
}
68+
69+
async saveCache() {
70+
fs.writeFileSync(this.cacheFile, JSON.stringify(this.cacheMap), {
71+
encoding: "utf8",
72+
flag: "w",
73+
});
74+
}
75+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import log4js from "log4js";
1010
import commandLineArgs from "command-line-args";
1111
import pug from "pug";
1212

13-
import widgets from "./timeline-notes";
13+
import * as widgets from "./timeline-notes";
1414
import * as fm from "./files-manager";
1515
import imgDir from "./img_dir";
1616
import { IncomingHttpHeaders } from "http";

http2-webserver/package-lock.json

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

http2-webserver/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
"@types/json-stable-stringify": "^1.0.33",
4141
"@types/mime": "^2.0.3",
4242
"@types/node": "^16.7.1",
43+
"@types/showdown": "^1.9.4",
4344
"@typescript-eslint/eslint-plugin": "^4.29.2",
4445
"concurrently": "^6.2.1",
4546
"eslint": "^7.32.0",

0 commit comments

Comments
 (0)