koishi-plugin-share-links-analysis 0.8.2 → 0.8.3

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.js CHANGED
@@ -133,21 +133,6 @@ async function reportMetric(ctx, config, payload) {
133
133
  }
134
134
  });
135
135
  }
136
- async function sendResult(ctx, session, config, result, logger) {
137
- if (!session.channel) {
138
- return await (0, utils_1.sendResult_plain)(ctx, session, config, result, logger);
139
- }
140
- switch (config.useForward) {
141
- case "plain":
142
- return await (0, utils_1.sendResult_plain)(ctx, session, config, result, logger);
143
- case 'forward':
144
- return await (0, utils_1.sendResult_forward)(ctx, session, config, result, logger, false);
145
- case "mixed":
146
- return await (0, utils_1.sendResult_forward)(ctx, session, config, result, logger, true);
147
- default:
148
- return { downloadTime: 0, sendTime: 0 };
149
- }
150
- }
151
136
  function apply(ctx, config) {
152
137
  // 数据库模型定义
153
138
  ctx.model.extend('sla_cookie_cache', {
@@ -335,9 +320,8 @@ function apply(ctx, config) {
335
320
  }
336
321
  // === 性能统计变量 ===
337
322
  const startTotal = Date.now();
323
+ const timeStats = { downloadTime: 0, sendTime: 0 };
338
324
  let parseTime = 0;
339
- let downloadTime = 0;
340
- let sendTime = 0;
341
325
  let isCache = false;
342
326
  let status = "success";
343
327
  let errorMsg = "";
@@ -417,9 +401,7 @@ function apply(ctx, config) {
417
401
  // === 逻辑结束 ===
418
402
  if (result) {
419
403
  lastProcessedUrls[channelId][link.url] = Date.now();
420
- const stats = await sendResult(ctx, session, config, result, logger);
421
- downloadTime = stats.downloadTime;
422
- sendTime = stats.sendTime;
404
+ await (0, utils_1.sendResult)(ctx, session, config, result, logger, timeStats);
423
405
  }
424
406
  else {
425
407
  status = "failed";
@@ -465,8 +447,8 @@ function apply(ctx, config) {
465
447
  // === Metrics (数值/指标) ===
466
448
  time_total_ms: totalTime,
467
449
  time_parse_ms: parseTime,
468
- time_download_ms: downloadTime,
469
- time_send_ms: sendTime,
450
+ time_download_ms: timeStats.downloadTime,
451
+ time_send_ms: timeStats.sendTime,
470
452
  // 系统负载指标
471
453
  memory_rss_mb: parseFloat(rssMB), // 当前进程内存占用
472
454
  concurrent_tasks: pendingChecks.size, // 当前正在进行的并发解析数
@@ -8,11 +8,11 @@ const utils_1 = require("../utils");
8
8
  exports.name = "bilibili";
9
9
  const linkRules = [
10
10
  {
11
- pattern: /(?:https?:\/\/)?(?:www\.bilibili\.com\/video\/)(([ab]v[0-9a-zA-Z]+))/gi,
11
+ pattern: /(?:https?:\/\/)?www\.bilibili\.com\/video\/([ab]v[0-9a-zA-Z]+)/gi,
12
12
  type: "video",
13
13
  },
14
14
  {
15
- pattern: /(?:https?:\/\/)?(?:b23\.tv\/([0-9a-zA-Z]+))/gi,
15
+ pattern: /(?:https?:\/\/)?b23\.tv\/([0-9a-zA-Z]+)/gi,
16
16
  type: "short",
17
17
  },
18
18
  ];
@@ -151,7 +151,7 @@ async function process(ctx, config, link, session) {
151
151
  const mainContent = container.querySelector('.image-text__content')?.textContent?.trim() || '';
152
152
  contentBlocks.push({ type: 'text', content: mainContent });
153
153
  // 图片(轮播图)
154
- container.querySelectorAll('.header-image__item-image img').forEach((img, index) => {
154
+ container.querySelectorAll('.header-image__item-image img').forEach((img) => {
155
155
  const src = img.src.replace(/\?.*$/, '');
156
156
  contentBlocks.push({ type: 'image', content: src });
157
157
  });
@@ -11,15 +11,15 @@ const utils_1 = require("../utils");
11
11
  exports.name = "xiaohongshu";
12
12
  const linkRules = [
13
13
  {
14
- pattern: /(?:https?:\/\/)?(?:www\.xiaohongshu\.com\/discovery\/item\/)([\w?=&\-.%]+)/gi,
14
+ pattern: /(?:https?:\/\/)?www\.xiaohongshu\.com\/discovery\/item\/([\w?=&\-.%]+)/gi,
15
15
  type: "discovery",
16
16
  },
17
17
  {
18
- pattern: /(?:https?:\/\/)?(?:www\.xiaohongshu\.com\/explore\/)([\w?=&\-.%]+)/gi,
18
+ pattern: /(?:https?:\/\/)?www\.xiaohongshu\.com\/explore\/([\w?=&\-.%]+)/gi,
19
19
  type: "explore",
20
20
  },
21
21
  {
22
- pattern: /(?:https?:\/\/)?(?:xhslink\.com\/(?:\w\/)?)([0-9a-zA-Z]+)/gi,
22
+ pattern: /(?:https?:\/\/)?xhslink\.com\/(?:\w\/)?([0-9a-zA-Z]+)/gi,
23
23
  type: "short",
24
24
  },
25
25
  ];
package/lib/types.d.ts CHANGED
@@ -46,10 +46,6 @@ export interface PluginConfig {
46
46
  reportEnabled: boolean;
47
47
  reportUrl: string;
48
48
  }
49
- export interface SendResultStats {
50
- downloadTime: number;
51
- sendTime: number;
52
- }
53
49
  export interface BilibiliVideoInfo {
54
50
  data: {
55
51
  bvid: string;
package/lib/types.js CHANGED
@@ -1,4 +1,3 @@
1
1
  "use strict";
2
2
  // src/types.ts
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- let session_global;
package/lib/utils.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ParsedInfo, PluginConfig, SendResultStats } from './types';
1
+ import { ParsedInfo, PluginConfig } from './types';
2
2
  import { Context, Logger, Session } from "koishi";
3
3
  import { Agent as HttpAgent } from 'http';
4
4
  import { Agent as HttpsAgent } from 'https';
@@ -19,5 +19,15 @@ export declare function getEffectiveSettings(ctx: Context, guildId: string | und
19
19
  nsfw: boolean;
20
20
  }>;
21
21
  export declare function isUserAdmin(session: Session, userId: string): Promise<boolean>;
22
- export declare function sendResult_plain(ctx: Context, session: Session, config: PluginConfig, result: ParsedInfo, logger: Logger): Promise<SendResultStats>;
23
- export declare function sendResult_forward(ctx: Context, session: Session, config: PluginConfig, result: ParsedInfo, logger: Logger, mixed_sending?: boolean): Promise<SendResultStats>;
22
+ export declare function sendResult(ctx: Context, session: Session, config: PluginConfig, result: ParsedInfo, logger: Logger, statsRef: {
23
+ downloadTime: number;
24
+ sendTime: number;
25
+ }): Promise<void>;
26
+ export declare function sendResult_plain(ctx: Context, session: Session, config: PluginConfig, result: ParsedInfo, logger: Logger, statsRef: {
27
+ downloadTime: number;
28
+ sendTime: number;
29
+ }): Promise<void>;
30
+ export declare function sendResult_forward(ctx: Context, session: Session, config: PluginConfig, result: ParsedInfo, logger: Logger, mixed_sending: boolean | undefined, statsRef: {
31
+ downloadTime: number;
32
+ sendTime: number;
33
+ }): Promise<void>;
package/lib/utils.js CHANGED
@@ -43,6 +43,7 @@ exports.getProxyAgent = getProxyAgent;
43
43
  exports.getFileSize = getFileSize;
44
44
  exports.getEffectiveSettings = getEffectiveSettings;
45
45
  exports.isUserAdmin = isUserAdmin;
46
+ exports.sendResult = sendResult;
46
47
  exports.sendResult_plain = sendResult_plain;
47
48
  exports.sendResult_forward = sendResult_forward;
48
49
  const koishi_1 = require("koishi");
@@ -261,7 +262,6 @@ async function tryHeadRequest(url, proxy, userAgent, logger) {
261
262
  timeout: 10000,
262
263
  headers: {
263
264
  'User-Agent': userAgent,
264
- 'Referer': 'https://www.bilibili.com/'
265
265
  }
266
266
  }, (res) => {
267
267
  const len = res.headers['content-length'];
@@ -286,7 +286,6 @@ async function tryHeadRequest(url, proxy, userAgent, logger) {
286
286
  });
287
287
  }
288
288
  async function tryGetRequestForSize(url, proxy, userAgent, logger) {
289
- proxy = undefined;
290
289
  return new Promise((resolve) => {
291
290
  const u = new url_1.URL(url);
292
291
  const agent = getProxyAgent(proxy, url);
@@ -372,10 +371,27 @@ async function isUserAdmin(session, userId) {
372
371
  return true;
373
372
  }
374
373
  }
375
- async function sendResult_plain(ctx, session, config, result, logger) {
374
+ async function sendResult(ctx, session, config, result, logger, statsRef // 新增参数
375
+ ) {
376
+ if (!session.channel) {
377
+ await sendResult_plain(ctx, session, config, result, logger, statsRef);
378
+ return;
379
+ }
380
+ switch (config.useForward) {
381
+ case "plain":
382
+ await sendResult_plain(ctx, session, config, result, logger, statsRef);
383
+ break;
384
+ case 'forward':
385
+ await sendResult_forward(ctx, session, config, result, logger, false, statsRef);
386
+ break;
387
+ case "mixed":
388
+ await sendResult_forward(ctx, session, config, result, logger, true, statsRef);
389
+ break;
390
+ }
391
+ }
392
+ // 2. 修改 sendResult_plain
393
+ async function sendResult_plain(ctx, session, config, result, logger, statsRef) {
376
394
  logger.debug('进入普通发送');
377
- let downloadTime = 0; // 下载耗时计时
378
- let sendTime = 0; // 发送耗时计时
379
395
  const localDownloadDir = config.localDownloadDir;
380
396
  const onebotReadDir = config.onebotReadDir;
381
397
  let mediaCoverUrl = result.coverUrl;
@@ -397,7 +413,7 @@ async function sendResult_plain(ctx, session, config, result, logger) {
397
413
  logger.warn(`封面下载失败: ${result.coverUrl}`, e);
398
414
  mediaCoverUrl = result.coverUrl;
399
415
  }
400
- downloadTime += Date.now() - t; // 累加耗时
416
+ statsRef.downloadTime += Date.now() - t; // 累加耗时
401
417
  }
402
418
  else {
403
419
  mediaCoverUrl = result.coverUrl;
@@ -424,7 +440,7 @@ async function sendResult_plain(ctx, session, config, result, logger) {
424
440
  urlMap[remoteUrl] = remoteUrl;
425
441
  }
426
442
  }));
427
- downloadTime += Date.now() - t; // 累加耗时
443
+ statsRef.downloadTime += Date.now() - t; // 累加耗时
428
444
  mediaMainbody = result.mainbody;
429
445
  for (const [remote, local] of Object.entries(urlMap)) {
430
446
  const escaped = remote.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
@@ -457,7 +473,7 @@ async function sendResult_plain(ctx, session, config, result, logger) {
457
473
  if (config.Max_size !== undefined) {
458
474
  const t = Date.now();
459
475
  const sizeBytes = await getFileSize(remoteUrl, proxy, config.userAgent, logger);
460
- downloadTime += Date.now() - t;
476
+ statsRef.downloadTime += Date.now() - t;
461
477
  const maxBytes = config.Max_size * 1024 * 1024;
462
478
  if (sizeBytes !== null && sizeBytes > maxBytes) {
463
479
  shouldSend = false;
@@ -474,7 +490,7 @@ async function sendResult_plain(ctx, session, config, result, logger) {
474
490
  if (config.usingLocal) {
475
491
  const t = Date.now();
476
492
  localUrl = await downloadAndMapUrl(ctx, remoteUrl, proxy, config.userAgent, localDownloadDir, onebotReadDir, logger, config.enableCache);
477
- downloadTime += Date.now() - t;
493
+ statsRef.downloadTime += Date.now() - t;
478
494
  }
479
495
  if (!localUrl)
480
496
  continue;
@@ -506,13 +522,11 @@ async function sendResult_plain(ctx, session, config, result, logger) {
506
522
  }
507
523
  const tSend = Date.now(); // 发送计时开始
508
524
  await Promise.all(sendPromises);
509
- sendTime = Date.now() - tSend; // 计算发送耗时
510
- return { downloadTime, sendTime }; // 返回统计
525
+ statsRef.sendTime = Date.now() - tSend; // 计算发送耗时
511
526
  }
512
- async function sendResult_forward(ctx, session, config, result, logger, mixed_sending = false) {
527
+ async function sendResult_forward(ctx, session, config, result, logger, mixed_sending = false, statsRef // 接收引用
528
+ ) {
513
529
  logger.debug(mixed_sending ? '进入混合发送' : '进入合并发送');
514
- let downloadTime = 0;
515
- let sendTime = 0;
516
530
  const localDownloadDir = config.localDownloadDir;
517
531
  const onebotReadDir = config.onebotReadDir;
518
532
  let mediaCoverUrl = result.coverUrl;
@@ -533,7 +547,7 @@ async function sendResult_forward(ctx, session, config, result, logger, mixed_se
533
547
  logger.warn('封面下载失败', e);
534
548
  mediaCoverUrl = '';
535
549
  }
536
- downloadTime += Date.now() - t;
550
+ statsRef.downloadTime += Date.now() - t;
537
551
  }
538
552
  else {
539
553
  mediaCoverUrl = result.coverUrl;
@@ -552,7 +566,7 @@ async function sendResult_forward(ctx, session, config, result, logger, mixed_se
552
566
  catch (e) {
553
567
  logger.warn(`正文图片下载失败: ${url}`, e);
554
568
  }
555
- downloadTime += Date.now() - t;
569
+ statsRef.downloadTime += Date.now() - t;
556
570
  }
557
571
  else {
558
572
  urlMap[url] = url;
@@ -623,7 +637,7 @@ async function sendResult_forward(ctx, session, config, result, logger, mixed_se
623
637
  if (config.Max_size !== undefined) {
624
638
  const t = Date.now();
625
639
  const sizeBytes = await getFileSize(remoteUrl, proxy, config.userAgent, logger);
626
- downloadTime += Date.now() - t;
640
+ statsRef.downloadTime += Date.now() - t;
627
641
  const maxBytes = config.Max_size * 1024 * 1024;
628
642
  if (sizeBytes !== null && sizeBytes > maxBytes) {
629
643
  shouldInclude = false;
@@ -650,7 +664,7 @@ async function sendResult_forward(ctx, session, config, result, logger, mixed_se
650
664
  if (config.usingLocal) {
651
665
  const t = Date.now();
652
666
  localUrl = await downloadAndMapUrl(ctx, remoteUrl, proxy, config.userAgent, localDownloadDir, onebotReadDir, logger, config.enableCache);
653
- downloadTime += Date.now() - t;
667
+ statsRef.downloadTime += Date.now() - t;
654
668
  }
655
669
  if (!localUrl)
656
670
  continue;
@@ -712,9 +726,8 @@ async function sendResult_forward(ctx, session, config, result, logger, mixed_se
712
726
  });
713
727
  }
714
728
  }
715
- if (forwardNodes.length === 0 && extraSendPromises.length === 0) {
716
- return { downloadTime, sendTime };
717
- }
729
+ if (forwardNodes.length === 0 && extraSendPromises.length === 0)
730
+ return;
718
731
  logger.debug(`解析结果: \n ${JSON.stringify(result, null, 2)}`);
719
732
  if (!(session.onebot && session.onebot._request))
720
733
  throw new Error("Onebot is not defined");
@@ -736,7 +749,6 @@ async function sendResult_forward(ctx, session, config, result, logger, mixed_se
736
749
  if (promises.length > 0) {
737
750
  const tSend = Date.now();
738
751
  await Promise.all(promises);
739
- sendTime = Date.now() - tSend;
752
+ statsRef.sendTime = Date.now() - tSend;
740
753
  }
741
- return { downloadTime, sendTime };
742
754
  }
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "koishi-plugin-share-links-analysis",
3
3
  "description": "自用插件",
4
4
  "license": "MIT",
5
- "version": "0.8.2",
5
+ "version": "0.8.3",
6
6
  "main": "lib/index.js",
7
7
  "typings": "lib/index.d.ts",
8
8
  "files": [