mirror of
https://github.com/Radiquum/AniX.git
synced 2025-09-05 22:15:36 +05:00
refactor/api-prox: preload and watch hooks at startup
This commit is contained in:
parent
d23703b212
commit
3762e7e58f
2 changed files with 65 additions and 72 deletions
|
@ -55,7 +55,7 @@ export async function get(data: Toggles, url: URL) {
|
||||||
data.lastVersionCode = 25062200;
|
data.lastVersionCode = 25062200;
|
||||||
|
|
||||||
data.impMessageEnabled = true;
|
data.impMessageEnabled = true;
|
||||||
data.impMessageText = "разработчик AniX / Api-Prox-Svc";
|
data.impMessageText = "разработчик AniX / Api-Prox-Service";
|
||||||
data.impMessageLink = "https://wah.su/radiquum";
|
data.impMessageLink = "https://wah.su/radiquum";
|
||||||
data.impMessageBackgroundColor = "ffb3d0";
|
data.impMessageBackgroundColor = "ffb3d0";
|
||||||
data.impMessageTextColor = "ffffff";
|
data.impMessageTextColor = "ffffff";
|
||||||
|
|
|
@ -14,14 +14,54 @@ import { MediaChromeTheme } from "./media-chrome";
|
||||||
import { Iframe } from "./iframe";
|
import { Iframe } from "./iframe";
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
app.use(express.raw({ inflate: true, limit: "50mb", type: "multipart/form-data" }));
|
app.use(
|
||||||
|
express.raw({ inflate: true, limit: "50mb", type: "multipart/form-data" })
|
||||||
|
);
|
||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
app.use(express.urlencoded({ extended: true }));
|
app.use(express.urlencoded({ extended: true }));
|
||||||
|
|
||||||
const host = "0.0.0.0";
|
const host = "0.0.0.0";
|
||||||
const port = 7001;
|
const port = 7001;
|
||||||
|
|
||||||
const loadedHooks: LoadedHook[] = [];
|
let hooks: string[] = [];
|
||||||
|
|
||||||
|
async function loadHooks() {
|
||||||
|
let hooksDir: string[] = [];
|
||||||
|
try {
|
||||||
|
hooksDir = await fs.readdir("./hooks");
|
||||||
|
} catch (err) {
|
||||||
|
logger.error("'hooks' directory not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < hooksDir.length; i++) {
|
||||||
|
const name = hooksDir[i];
|
||||||
|
if (
|
||||||
|
!name.endsWith(".ts") ||
|
||||||
|
name.includes("example") ||
|
||||||
|
name.includes("disabled")
|
||||||
|
)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
require(`./hooks/${name}`);
|
||||||
|
logger.infoHook(`Loaded "./hooks/${name}"`);
|
||||||
|
hooks.push(name);
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
const watcher = fs.watch(`./hooks/${name}`);
|
||||||
|
for await (const event of watcher) {
|
||||||
|
if (event.eventType === "change") {
|
||||||
|
logger.infoHook(`Updated "./hooks/${event.filename}"`);
|
||||||
|
delete require.cache[require.resolve(`./hooks/${event.filename}`)];
|
||||||
|
require(`./hooks/${event.filename}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
app.get("/player", async (req, res) => {
|
app.get("/player", async (req, res) => {
|
||||||
let url = req.query.url || null;
|
let url = req.query.url || null;
|
||||||
|
@ -90,9 +130,9 @@ app.get("/player", async (req, res) => {
|
||||||
res.send(Iframe(url.toString()));
|
res.send(Iframe(url.toString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (url.toString().endsWith("mp4")) {
|
} else if (url.toString().toLowerCase().endsWith("mp4")) {
|
||||||
player = "mp4";
|
player = "mp4";
|
||||||
} else if (url.toString().endsWith(".m3u8")) {
|
} else if (url.toString().toLowerCase().endsWith(".m3u8")) {
|
||||||
player = "hls";
|
player = "hls";
|
||||||
} else {
|
} else {
|
||||||
res.send(Iframe(url.toString()));
|
res.send(Iframe(url.toString()));
|
||||||
|
@ -191,46 +231,12 @@ app.get("/*path", async (req, res) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
let data = await apiResponse.json();
|
let data = await apiResponse.json();
|
||||||
let hooks: string[] = [];
|
|
||||||
|
|
||||||
try {
|
|
||||||
hooks = await fs.readdir("./hooks");
|
|
||||||
} catch (err) {
|
|
||||||
logger.error("'hooks' directory not found");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < hooks.length; i++) {
|
for (let i = 0; i < hooks.length; i++) {
|
||||||
const name = hooks[i];
|
const name = hooks[i];
|
||||||
if (
|
|
||||||
!name.endsWith(".ts") ||
|
|
||||||
name.includes("example") ||
|
|
||||||
name.includes("disabled")
|
|
||||||
)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const isHookLoaded = loadedHooks.find(
|
|
||||||
(item) => item.path == `./hooks/${name}`
|
|
||||||
);
|
|
||||||
const stat = await fs.stat(`./hooks/${name}`);
|
|
||||||
|
|
||||||
if (isHookLoaded && isHookLoaded.mtime != stat.mtime.toISOString()) {
|
|
||||||
logger.infoHook(`Updated "./hooks/${name}"`);
|
|
||||||
delete require.cache[require.resolve(`./hooks/${name}`)];
|
|
||||||
isHookLoaded.mtime = stat.mtime.toISOString();
|
|
||||||
}
|
|
||||||
|
|
||||||
const hook: GetHook = require(`./hooks/${name}`);
|
const hook: GetHook = require(`./hooks/${name}`);
|
||||||
if (!isHookLoaded) {
|
|
||||||
logger.infoHook(`Loaded "./hooks/${name}"`);
|
|
||||||
loadedHooks.push({
|
|
||||||
path: `./hooks/${name}`,
|
|
||||||
mtime: stat.mtime.toISOString(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hook.hasOwnProperty("match") || !hook.hasOwnProperty("get")) continue;
|
if (!hook.hasOwnProperty("match") || !hook.hasOwnProperty("get")) continue;
|
||||||
if (!hook.match(req.path)) continue;
|
if (!hook.match(req.path)) continue;
|
||||||
|
|
||||||
data = await hook.get(data, url);
|
data = await hook.get(data, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,12 +270,30 @@ app.post("/*path", async (req, res) => {
|
||||||
req.headers["content-type"] ?
|
req.headers["content-type"] ?
|
||||||
req.headers["content-type"].split(";")[0]
|
req.headers["content-type"].split(";")[0]
|
||||||
: "application/json";
|
: "application/json";
|
||||||
|
|
||||||
|
const supportedContentTypes = [
|
||||||
|
"application/json",
|
||||||
|
"application/x-www-form-urlencoded",
|
||||||
|
"multipart/form-data",
|
||||||
|
];
|
||||||
|
const isSupported = supportedContentTypes.some((type) =>
|
||||||
|
reqContentType.toLowerCase().startsWith(type)
|
||||||
|
);
|
||||||
|
if (!isSupported) {
|
||||||
|
res.status(500).json({
|
||||||
|
code: 99,
|
||||||
|
error: "Unsupported Media Type",
|
||||||
|
reason: `Content-Type '${reqContentType}' is not supported.`,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (reqContentType) {
|
switch (reqContentType) {
|
||||||
case "multipart/form-data":
|
case "multipart/form-data":
|
||||||
apiResponse = await fetch(url.toString(), {
|
apiResponse = await fetch(url.toString(), {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: apiHeaders,
|
headers: apiHeaders,
|
||||||
body: req.body
|
body: req.body,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case "application/x-www-form-urlencoded":
|
case "application/x-www-form-urlencoded":
|
||||||
|
@ -288,11 +312,6 @@ app.post("/*path", async (req, res) => {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// logger.console("debug", ` ↳ [REQ BODY]`, req.body);
|
|
||||||
// logger.console("debug", ` ↳ [REQ HEADERS]`, req.headers);
|
|
||||||
// logger.console("debug", " ↳ [RES TEXT]", await apiResponse.text());
|
|
||||||
// logger.console("debug", " ↳ [RES HEADERS]", apiResponse.headers);
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!apiResponse ||
|
!apiResponse ||
|
||||||
!apiResponse.ok ||
|
!apiResponse.ok ||
|
||||||
|
@ -327,36 +346,9 @@ app.post("/*path", async (req, res) => {
|
||||||
|
|
||||||
for (let i = 0; i < hooks.length; i++) {
|
for (let i = 0; i < hooks.length; i++) {
|
||||||
const name = hooks[i];
|
const name = hooks[i];
|
||||||
if (
|
|
||||||
!name.endsWith(".ts") ||
|
|
||||||
name.includes("example") ||
|
|
||||||
name.includes("disabled")
|
|
||||||
)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const isHookLoaded = loadedHooks.find(
|
|
||||||
(item) => item.path == `./hooks/${name}`
|
|
||||||
);
|
|
||||||
const stat = await fs.stat(`./hooks/${name}`);
|
|
||||||
|
|
||||||
if (isHookLoaded && isHookLoaded.mtime != stat.mtime.toISOString()) {
|
|
||||||
logger.infoHook(`Updated "./hooks/${name}"`);
|
|
||||||
delete require.cache[require.resolve(`./hooks/${name}`)];
|
|
||||||
isHookLoaded.mtime = stat.mtime.toISOString();
|
|
||||||
}
|
|
||||||
|
|
||||||
const hook: PostHook = require(`./hooks/${name}`);
|
const hook: PostHook = require(`./hooks/${name}`);
|
||||||
if (!isHookLoaded) {
|
|
||||||
logger.infoHook(`Loaded "./hooks/${name}"`);
|
|
||||||
loadedHooks.push({
|
|
||||||
path: `./hooks/${name}`,
|
|
||||||
mtime: stat.mtime.toISOString(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hook.hasOwnProperty("match") || !hook.hasOwnProperty("post")) continue;
|
if (!hook.hasOwnProperty("match") || !hook.hasOwnProperty("post")) continue;
|
||||||
if (!hook.match(req.path)) continue;
|
if (!hook.match(req.path)) continue;
|
||||||
|
|
||||||
data = await hook.post(data, url);
|
data = await hook.post(data, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,5 +357,6 @@ app.post("/*path", async (req, res) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
app.listen(port, host, function () {
|
app.listen(port, host, function () {
|
||||||
|
loadHooks();
|
||||||
logger.info(`Server listen: http://${host}:${port}`);
|
logger.info(`Server listen: http://${host}:${port}`);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue