koishi-plugin-nmc-radar 1.3.2 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.d.ts +2 -2
- package/lib/index.js +36 -17
- package/package.json +1 -1
package/lib/index.d.ts
CHANGED
|
@@ -6,9 +6,9 @@ export declare const inject: {
|
|
|
6
6
|
};
|
|
7
7
|
interface Product {
|
|
8
8
|
url: string;
|
|
9
|
-
|
|
9
|
+
slug: string;
|
|
10
10
|
}
|
|
11
|
-
type Resolver = (products: Product[],
|
|
11
|
+
type Resolver = (products: Product[], options: Dict) => Awaitable<h>;
|
|
12
12
|
declare const resolvers: Record<string, Resolver>;
|
|
13
13
|
export interface Config {
|
|
14
14
|
defaultResolver: keyof typeof resolvers;
|
package/lib/index.js
CHANGED
|
@@ -36,6 +36,7 @@ __export(src_exports, {
|
|
|
36
36
|
name: () => name
|
|
37
37
|
});
|
|
38
38
|
module.exports = __toCommonJS(src_exports);
|
|
39
|
+
var import_node_buffer = require("node:buffer");
|
|
39
40
|
var import_promises = require("node:fs/promises");
|
|
40
41
|
var import_node_path = __toESM(require("node:path"));
|
|
41
42
|
var import_jsdom = require("jsdom");
|
|
@@ -332,35 +333,53 @@ var Config = import_koishi.Schema.object({
|
|
|
332
333
|
defaultResolver: import_koishi.Schema.union(Object.keys(resolvers)).default("img").description("默认输出类型。")
|
|
333
334
|
});
|
|
334
335
|
function apply(ctx, config) {
|
|
335
|
-
const command = ctx.command("radar <name:string>", "查看雷达图", { checkUnknown: true }).alias("雷达").option("
|
|
336
|
+
const command = ctx.command("radar <name:string>", "查看雷达图", { checkUnknown: true }).alias("雷达").option("name", "--name <name:string> 雷达站名称").option("count", "-n <count:number> 最大输出数量").option("reverse", "-R 反转顺序").option("type", "--type <type:string> 输出类型", { type: Object.keys(resolvers) }).option("type", "--img 输出图片", { value: "img" }).option("type", "--url 输出 URL", { value: "url" }).action(async ({ session, options = {} }, name2) => {
|
|
337
|
+
options.name ??= name2;
|
|
336
338
|
if (!(name2 in radars_default))
|
|
337
339
|
return void session?.send("雷达站不存在,可使用 radar.list 查看所有雷达站。");
|
|
338
|
-
const url = radars_default[
|
|
340
|
+
const url = radars_default[options.name];
|
|
339
341
|
const { window: { document } } = new import_jsdom.JSDOM(await ctx.http.get(url));
|
|
340
342
|
const nodes = document.querySelectorAll("div[data-img]");
|
|
341
343
|
options.type ??= config.defaultResolver;
|
|
342
344
|
options.count ??= options.type === "img" ? 1 : void 0;
|
|
343
345
|
const products = Array.from(nodes).slice(0, options.count).map((node) => ({
|
|
344
346
|
url: node.dataset.img,
|
|
345
|
-
|
|
346
|
-
// MM/DD HH:mm
|
|
347
|
+
slug: node.dataset.time.replaceAll(/[/ :]/g, "")
|
|
347
348
|
}));
|
|
348
349
|
options.reverse || products.reverse();
|
|
349
|
-
return await resolvers[options.type](products,
|
|
350
|
+
return await resolvers[options.type](products, options);
|
|
350
351
|
});
|
|
351
352
|
ctx.inject(["ffmpeg"], async (ctx2) => {
|
|
352
|
-
command.option("type", "--gif 输出 GIF 动画", { value: "gif" }).option("fps", "--fps <fps:number> 帧率", { fallback: 10 });
|
|
353
|
-
resolvers.gif = async (products,
|
|
354
|
-
const baseDir = import_node_path.default.join(ctx2.baseDir, "
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
await (0, import_promises.
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
|
|
353
|
+
command.option("type", "--gif 输出 GIF 动画", { value: "gif" }).option("fps", "--fps <fps:number> 帧率", { fallback: 10 }).option("loop", "--loop <loop:number> 循环次数", { fallback: -1 });
|
|
354
|
+
resolvers.gif = async (products, options) => {
|
|
355
|
+
const baseDir = import_node_path.default.join(ctx2.baseDir, "cache", name, options.name);
|
|
356
|
+
const outputPath = import_node_path.default.join(baseDir, [
|
|
357
|
+
`${products[0].slug}+${products[products.length - 1].slug}`,
|
|
358
|
+
`-${options.fps}@${options.loop}.gif`
|
|
359
|
+
].join(""));
|
|
360
|
+
try {
|
|
361
|
+
await (0, import_promises.access)(outputPath);
|
|
362
|
+
} catch {
|
|
363
|
+
await (0, import_promises.mkdir)(baseDir, { recursive: true });
|
|
364
|
+
const filePaths = await Promise.all(products.map(async ({ url, slug }) => {
|
|
365
|
+
const filePath = import_node_path.default.join(baseDir, `${slug}.png`);
|
|
366
|
+
try {
|
|
367
|
+
await (0, import_promises.access)(filePath);
|
|
368
|
+
} catch {
|
|
369
|
+
try {
|
|
370
|
+
const response = await ctx2.http.get(url, { responseType: "stream" });
|
|
371
|
+
await (0, import_promises.writeFile)(filePath, response);
|
|
372
|
+
} catch {
|
|
373
|
+
return void await (0, import_promises.unlink)(filePath);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
return filePath;
|
|
377
|
+
}));
|
|
378
|
+
const buffer = [
|
|
379
|
+
...filePaths.filter(Boolean).flatMap((filePath) => `file '${filePath.replaceAll("\\", "/")}'`)
|
|
380
|
+
].join("\n");
|
|
381
|
+
await ctx2.ffmpeg.builder().input(import_node_buffer.Buffer.from(buffer)).inputOption("-f", "concat").inputOption("-safe", "0").inputOption("-protocol_whitelist", "file,fd").inputOption("-r", options.fps).outputOption("-loop", options.loop).run("file", outputPath);
|
|
382
|
+
}
|
|
364
383
|
return import_koishi.h.img(`file://${outputPath}`);
|
|
365
384
|
};
|
|
366
385
|
});
|