@whyour/qinglong 2.17.9 → 2.17.10-rc.2

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.
Files changed (99) hide show
  1. package/docker/310.Dockerfile +4 -3
  2. package/docker/Dockerfile +5 -4
  3. package/package.json +7 -5
  4. package/sample/config.sample.sh +8 -0
  5. package/sample/notify.js +1 -1
  6. package/shell/api.sh +9 -9
  7. package/shell/otask.sh +19 -3
  8. package/shell/preload/sitecustomize.js +23 -12
  9. package/shell/preload/sitecustomize.py +17 -15
  10. package/shell/rmlog.sh +20 -18
  11. package/shell/share.sh +3 -3
  12. package/shell/start.sh +2 -1
  13. package/shell/task.sh +6 -8
  14. package/static/build/api/subscription.js +3 -3
  15. package/static/build/api/system.js +18 -2
  16. package/static/build/app.js +1 -1
  17. package/static/build/config/index.js +2 -0
  18. package/static/build/config/util.js +1 -1
  19. package/static/build/loaders/express.js +1 -1
  20. package/static/build/loaders/initData.js +6 -0
  21. package/static/build/loaders/initTask.js +4 -7
  22. package/static/build/loaders/sentry.js +20 -22
  23. package/static/build/loaders/sock.js +0 -4
  24. package/static/build/public.js +0 -1
  25. package/static/build/schedule/addCron.js +3 -3
  26. package/static/build/services/cron.js +4 -1
  27. package/static/build/services/notify.js +20 -8
  28. package/static/build/services/schedule.js +33 -8
  29. package/static/build/services/script.js +3 -1
  30. package/static/build/services/subscription.js +7 -4
  31. package/static/build/services/system.js +29 -5
  32. package/static/build/services/user.js +4 -1
  33. package/static/build/shared/interface.js +3 -0
  34. package/static/build/shared/pLimit.js +48 -1
  35. package/static/build/shared/runCron.js +6 -4
  36. package/static/dist/{2393.c35a1174.async.js → 2393.3d8adf53.async.js} +1 -1
  37. package/static/dist/2796.9a52d80e.async.js +1 -0
  38. package/static/dist/2899.03668225.async.js +1 -0
  39. package/static/dist/4039.badd6267.async.js +1 -0
  40. package/static/dist/{4124.b86154ed.async.js → 4124.980265f2.async.js} +1 -1
  41. package/static/dist/{4163.1781a549.async.js → 4163.17026fe1.async.js} +1 -1
  42. package/static/dist/4645.d909733e.async.js +1 -0
  43. package/static/dist/641.f0614d96.async.js +1 -0
  44. package/static/dist/6712.05e15d48.async.js +1 -0
  45. package/static/dist/6805.ae3d4019.async.js +1 -0
  46. package/static/dist/{7393.341d9643.async.js → 7393.ea2d5ba3.async.js} +1 -1
  47. package/static/dist/7787.b041d555.async.js +1 -0
  48. package/static/dist/8298.978b54ae.async.js +1 -0
  49. package/static/dist/9631.042017c3.async.js +1 -0
  50. package/static/dist/index.html +1 -1
  51. package/static/dist/layouts__index.2f94d49c.async.js +1 -0
  52. package/static/dist/layouts__index.fee54067.chunk.css +1 -0
  53. package/static/dist/src__pages__crontab__detail.34c9ca68.async.js +1 -0
  54. package/static/dist/src__pages__crontab__index.7d67660b.async.js +1 -0
  55. package/static/dist/src__pages__crontab__modal.ac728c12.async.js +1 -0
  56. package/static/dist/src__pages__crontab__viewCreateModal.1fe0e251.async.js +1 -0
  57. package/static/dist/src__pages__crontab__viewManageModal.c6dcfcf8.async.js +1 -0
  58. package/static/dist/src__pages__dependence__index.f30d6cf9.async.js +1 -0
  59. package/static/dist/src__pages__dependence__logModal.4826a923.async.js +1 -0
  60. package/static/dist/src__pages__error__index.e5c6d102.async.js +1 -0
  61. package/static/dist/src__pages__script__editModal.be12c9e5.async.js +1 -0
  62. package/static/dist/src__pages__script__index.6afda14d.async.js +1 -0
  63. package/static/dist/src__pages__setting__about.d7cea886.async.js +1 -0
  64. package/static/dist/src__pages__setting__checkUpdate.0dd2f8d5.async.js +1 -0
  65. package/static/dist/src__pages__setting__index.d9ba61cd.async.js +1 -0
  66. package/static/dist/src__pages__setting__loginLog.2f5ce1e4.async.js +1 -0
  67. package/static/dist/src__pages__setting__progress.57907231.async.js +1 -0
  68. package/static/dist/{src__pages__setting__security.b5ead1c3.async.js → src__pages__setting__security.cbf8e0b7.async.js} +1 -1
  69. package/static/dist/src__pages__setting__systemLog.1b30b79c.async.js +1 -0
  70. package/static/dist/src__pages__subscription__logModal.5bf23b06.async.js +1 -0
  71. package/static/dist/umi.3f48f15a.js +1 -0
  72. package/version.yaml +10 -6
  73. package/static/dist/4378.59be202f.async.js +0 -1
  74. package/static/dist/5207.4d5f0a6d.async.js +0 -1
  75. package/static/dist/7708.27674f3a.async.js +0 -1
  76. package/static/dist/7787.2fcf966f.async.js +0 -1
  77. package/static/dist/8297.0c80e09a.async.js +0 -1
  78. package/static/dist/8722.408e3112.async.js +0 -1
  79. package/static/dist/9525.b2007159.async.js +0 -1
  80. package/static/dist/layouts__index.308c5e5e.chunk.css +0 -1
  81. package/static/dist/layouts__index.a51b2768.async.js +0 -1
  82. package/static/dist/src__pages__crontab__detail.f691fe2e.async.js +0 -1
  83. package/static/dist/src__pages__crontab__index.06bb5925.async.js +0 -1
  84. package/static/dist/src__pages__crontab__modal.2fc5acc5.async.js +0 -1
  85. package/static/dist/src__pages__crontab__viewCreateModal.a29322e7.async.js +0 -1
  86. package/static/dist/src__pages__crontab__viewManageModal.c026d403.async.js +0 -1
  87. package/static/dist/src__pages__dependence__index.52fca7ba.async.js +0 -1
  88. package/static/dist/src__pages__dependence__logModal.39bc29eb.async.js +0 -1
  89. package/static/dist/src__pages__error__index.8ca01b97.async.js +0 -1
  90. package/static/dist/src__pages__script__editModal.3a322b87.async.js +0 -1
  91. package/static/dist/src__pages__script__index.8c311439.async.js +0 -1
  92. package/static/dist/src__pages__setting__about.40dce429.async.js +0 -1
  93. package/static/dist/src__pages__setting__checkUpdate.43e62d05.async.js +0 -1
  94. package/static/dist/src__pages__setting__index.d655075d.async.js +0 -1
  95. package/static/dist/src__pages__setting__loginLog.fe7238b5.async.js +0 -1
  96. package/static/dist/src__pages__setting__progress.7d65aebf.async.js +0 -1
  97. package/static/dist/src__pages__setting__systemLog.751cc94d.async.js +0 -1
  98. package/static/dist/src__pages__subscription__logModal.fce8a9b4.async.js +0 -1
  99. package/static/dist/umi.5e777fc4.js +0 -1
@@ -16,15 +16,21 @@ const cronView_1 = require("../data/cronView");
16
16
  const env_2 = require("../data/env");
17
17
  const system_1 = require("../data/system");
18
18
  const system_2 = __importDefault(require("../services/system"));
19
+ const user_1 = __importDefault(require("../services/user"));
20
+ const promises_1 = require("fs/promises");
19
21
  exports.default = async () => {
20
22
  var _a, _b, _c, _d, _e, _f;
21
23
  const cronService = typedi_1.Container.get(cron_2.default);
22
24
  const envService = typedi_1.Container.get(env_1.default);
23
25
  const dependenceService = typedi_1.Container.get(dependence_1.default);
24
26
  const systemService = typedi_1.Container.get(system_2.default);
27
+ const userService = typedi_1.Container.get(user_1.default);
25
28
  // 初始化增加系统配置
26
29
  await system_1.SystemModel.upsert({ type: system_1.AuthDataType.systemConfig });
27
30
  await system_1.SystemModel.upsert({ type: system_1.AuthDataType.notification });
31
+ // 初始化通知配置
32
+ const notifyConfig = await userService.getNotificationMode();
33
+ await (0, promises_1.writeFile)(config_1.default.systemNotifyFile, JSON.stringify(notifyConfig));
28
34
  const installDependencies = () => {
29
35
  // 初始化时安装所有处于安装中,安装成功,安装失败的依赖
30
36
  dependence_2.DependenceModel.findAll({
@@ -24,11 +24,12 @@ exports.default = async () => {
24
24
  id: NaN,
25
25
  name: '生成token',
26
26
  command: tokenCommand,
27
+ runOrigin: 'system',
27
28
  };
28
29
  await scheduleService.cancelIntervalTask(cron);
29
30
  scheduleService.createIntervalTask(cron, {
30
31
  days: 28,
31
- });
32
+ }, true);
32
33
  // 运行删除日志任务
33
34
  const data = await systemService.getSystemConfig();
34
35
  if (data && data.info && data.info.logRemoveFrequency) {
@@ -36,17 +37,13 @@ exports.default = async () => {
36
37
  id: data.id,
37
38
  name: '删除日志',
38
39
  command: `ql rmlog ${data.info.logRemoveFrequency}`,
40
+ runOrigin: 'system',
39
41
  };
40
42
  await scheduleService.cancelIntervalTask(rmlogCron);
41
43
  scheduleService.createIntervalTask(rmlogCron, {
42
44
  days: data.info.logRemoveFrequency,
43
- });
45
+ }, true);
44
46
  }
45
- // 运行所有订阅
46
47
  await subscriptionService.setSshConfig();
47
- const subs = await subscriptionService.list();
48
- for (const sub of subs) {
49
- subscriptionService.handleTask(sub, !sub.is_disabled, !sub.is_disabled);
50
- }
51
48
  };
52
49
  //# sourceMappingURL=initTask.js.map
@@ -28,28 +28,26 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
29
  const Sentry = __importStar(require("@sentry/node"));
30
30
  const logger_1 = __importDefault(require("./logger"));
31
+ const fs_1 = __importDefault(require("fs"));
31
32
  const config_1 = __importDefault(require("../config"));
32
33
  const util_1 = require("../config/util");
33
- exports.default = async ({ expressApp }) => {
34
- const { version } = await (0, util_1.parseVersion)(config_1.default.versionFile);
35
- Sentry.init({
36
- ignoreErrors: [
37
- /SequelizeUniqueConstraintError/i,
38
- /Validation error/i,
39
- /UnauthorizedError/i,
40
- /celebrate request validation failed/i,
41
- ],
42
- dsn: 'https://8b5c84cfef3e22541bc84de0ed00497b@o1098464.ingest.sentry.io/6122819',
43
- integrations: [
44
- new Sentry.Integrations.Http({ tracing: true }),
45
- new Sentry.Integrations.Express({ app: expressApp }),
46
- ],
47
- tracesSampleRate: 0.8,
48
- release: version,
49
- });
50
- expressApp.use(Sentry.Handlers.requestHandler());
51
- expressApp.use(Sentry.Handlers.tracingHandler());
52
- logger_1.default.info('✌️ Sentry loaded');
53
- console.log('✌️ Sentry loaded');
54
- };
34
+ let version = '1.0.0';
35
+ try {
36
+ const content = fs_1.default.readFileSync(config_1.default.versionFile, 'utf-8');
37
+ ({ version } = (0, util_1.parseContentVersion)(content));
38
+ }
39
+ catch (error) { }
40
+ Sentry.init({
41
+ ignoreErrors: [
42
+ /SequelizeUniqueConstraintError/i,
43
+ /Validation error/i,
44
+ /UnauthorizedError/i,
45
+ /celebrate request validation failed/i,
46
+ ],
47
+ dsn: 'https://8b5c84cfef3e22541bc84de0ed00497b@o1098464.ingest.sentry.io/6122819',
48
+ tracesSampleRate: 0.5,
49
+ release: version,
50
+ });
51
+ logger_1.default.info('✌️ Sentry loaded');
52
+ console.log('✌️ Sentry loaded');
55
53
  //# sourceMappingURL=sentry.js.map
@@ -22,7 +22,6 @@ exports.default = async ({ server }) => {
22
22
  if (data) {
23
23
  const { token = '', tokens = {} } = (0, util_1.safeJSONParse)(data);
24
24
  if (headerToken === token || tokens[platform] === headerToken) {
25
- conn.write(JSON.stringify({ type: 'ping', message: 'hanhh' }));
26
25
  sockService.addClient(conn);
27
26
  conn.on('data', (message) => {
28
27
  conn.write(message);
@@ -32,9 +31,6 @@ exports.default = async ({ server }) => {
32
31
  });
33
32
  return;
34
33
  }
35
- else {
36
- conn.write(JSON.stringify({ type: 'ping', message: 'whyour' }));
37
- }
38
34
  }
39
35
  conn.close('404');
40
36
  });
@@ -21,7 +21,6 @@ app.get('/api/health', (req, res) => {
21
21
  app
22
22
  .listen(config_1.default.publicPort, '0.0.0.0', async () => {
23
23
  var _a;
24
- await require('./loaders/sentry').default({ expressApp: app });
25
24
  await require('./loaders/db').default();
26
25
  logger_1.default.debug(`✌️ 公共服务启动成功!`);
27
26
  console.debug(`✌️ 公共服务启动成功!`);
@@ -17,19 +17,19 @@ const addCron = (call, callback) => {
17
17
  }
18
18
  logger_1.default.info('[schedule][创建定时任务], 任务ID: %s, 名称: %s, cron: %s, 执行命令: %s', id, name, schedule, command);
19
19
  if (extraSchedules === null || extraSchedules === void 0 ? void 0 : extraSchedules.length) {
20
- extraSchedules.forEach(x => {
20
+ extraSchedules.forEach((x) => {
21
21
  logger_1.default.info('[schedule][创建定时任务], 任务ID: %s, 名称: %s, cron: %s, 执行命令: %s', id, name, x.schedule, command);
22
22
  });
23
23
  }
24
24
  data_1.scheduleStacks.set(id, [
25
25
  node_schedule_1.default.scheduleJob(id, schedule, async () => {
26
26
  logger_1.default.info(`[schedule][准备运行任务] 命令: ${command}`);
27
- (0, runCron_1.runCron)(command, { name, schedule, extraSchedules });
27
+ (0, runCron_1.runCron)(command, item);
28
28
  }),
29
29
  ...((extraSchedules === null || extraSchedules === void 0 ? void 0 : extraSchedules.length)
30
30
  ? extraSchedules.map((x) => node_schedule_1.default.scheduleJob(id, x.schedule, async () => {
31
31
  logger_1.default.info(`[schedule][准备运行任务] 命令: ${command}`);
32
- (0, runCron_1.runCron)(command, { name, schedule, extraSchedules });
32
+ (0, runCron_1.runCron)(command, item);
33
33
  }))
34
34
  : []),
35
35
  ]);
@@ -370,7 +370,7 @@ let CronService = class CronService {
370
370
  resolve(params);
371
371
  return;
372
372
  }
373
- this.logger.info(`[panel][开始执行任务] 参数 ${JSON.stringify(params)}`);
373
+ this.logger.info(`[panel][开始执行任务] 参数: ${JSON.stringify(params)}`);
374
374
  let { id, command, log_path } = cron;
375
375
  const uniqPath = await (0, util_1.getUniqPath)(command, `${id}`);
376
376
  const logTime = (0, dayjs_1.default)().format('YYYY-MM-DD-HH-mm-ss-SSS');
@@ -386,12 +386,15 @@ let CronService = class CronService {
386
386
  await promises_1.default.appendFile(absolutePath, data.toString());
387
387
  });
388
388
  cp.stderr.on('data', async (data) => {
389
+ this.logger.info('[panel][执行任务失败] 命令: %s, 错误信息: %j', command, data.toString());
389
390
  await promises_1.default.appendFile(absolutePath, data.toString());
390
391
  });
391
392
  cp.on('error', async (err) => {
393
+ this.logger.error('[panel][创建任务失败] 命令: %s, 错误信息: %j', command, err);
392
394
  await promises_1.default.appendFile(absolutePath, JSON.stringify(err));
393
395
  });
394
396
  cp.on('exit', async (code) => {
397
+ this.logger.info('[panel][执行任务结束] 参数: %s, 退出码: %j', JSON.stringify(params), code);
395
398
  await cron_1.CrontabModel.update({ status: cron_1.CrontabStatus.idle, pid: undefined }, { where: { id } });
396
399
  resolve(Object.assign(Object.assign({}, params), { pid: cp.pid, code }));
397
400
  });
@@ -8,9 +8,6 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
8
8
  var __metadata = (this && this.__metadata) || function (k, v) {
9
9
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
10
  };
11
- var __param = (this && this.__param) || function (paramIndex, decorator) {
12
- return function (target, key) { decorator(target, key, paramIndex); }
13
- };
14
11
  var __rest = (this && this.__rest) || function (s, e) {
15
12
  var t = {};
16
13
  for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
@@ -31,12 +28,12 @@ const got_1 = __importDefault(require("got"));
31
28
  const hpagent_1 = require("hpagent");
32
29
  const nodemailer_1 = __importDefault(require("nodemailer"));
33
30
  const typedi_1 = require("typedi");
34
- const winston_1 = __importDefault(require("winston"));
35
31
  const util_1 = require("../config/util");
36
32
  const user_1 = __importDefault(require("./user"));
33
+ const promises_1 = require("fs/promises");
34
+ const config_1 = __importDefault(require("../config"));
37
35
  let NotificationService = class NotificationService {
38
- constructor(logger) {
39
- this.logger = logger;
36
+ constructor() {
40
37
  this.modeMap = new Map([
41
38
  ['gotify', this.gotify],
42
39
  ['goCqHttpBot', this.goCqHttpBot],
@@ -65,6 +62,22 @@ let NotificationService = class NotificationService {
65
62
  retry: 1,
66
63
  };
67
64
  }
65
+ async externalNotify(title, content) {
66
+ const _a = (0, util_1.safeJSONParse)(await (0, promises_1.readFile)(config_1.default.systemNotifyFile, 'utf-8')), { type } = _a, rest = __rest(_a, ["type"]);
67
+ if (type) {
68
+ this.title = title;
69
+ this.content = content;
70
+ this.params = rest;
71
+ const notificationModeAction = this.modeMap.get(type);
72
+ try {
73
+ return await (notificationModeAction === null || notificationModeAction === void 0 ? void 0 : notificationModeAction.call(this));
74
+ }
75
+ catch (error) {
76
+ throw error;
77
+ }
78
+ }
79
+ return false;
80
+ }
68
81
  async notify(title, content) {
69
82
  const _a = await this.userService.getNotificationMode(), { type } = _a, rest = __rest(_a, ["type"]);
70
83
  if (type) {
@@ -648,8 +661,7 @@ __decorate([
648
661
  ], NotificationService.prototype, "userService", void 0);
649
662
  NotificationService = __decorate([
650
663
  (0, typedi_1.Service)(),
651
- __param(0, (0, typedi_1.Inject)('logger')),
652
- __metadata("design:paramtypes", [winston_1.default.Logger])
664
+ __metadata("design:paramtypes", [])
653
665
  ], NotificationService);
654
666
  exports.default = NotificationService;
655
667
  //# sourceMappingURL=notify.js.map
@@ -11,6 +11,17 @@ var __metadata = (this && this.__metadata) || function (k, v) {
11
11
  var __param = (this && this.__param) || function (paramIndex, decorator) {
12
12
  return function (target, key) { decorator(target, key, paramIndex); }
13
13
  };
14
+ var __rest = (this && this.__rest) || function (s, e) {
15
+ var t = {};
16
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
17
+ t[p] = s[p];
18
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
19
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
20
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
21
+ t[p[i]] = s[p[i]];
22
+ }
23
+ return t;
24
+ };
14
25
  var __importDefault = (this && this.__importDefault) || function (mod) {
15
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
16
27
  };
@@ -27,13 +38,18 @@ let ScheduleService = class ScheduleService {
27
38
  this.logger = logger;
28
39
  this.scheduleStacks = new Map();
29
40
  this.intervalSchedule = new toad_scheduler_1.ToadScheduler();
30
- this.maxBuffer = 200 * 1024 * 1024;
41
+ this.taskLimitMap = {
42
+ system: 'runWithSystemLimit',
43
+ script: 'runWithScriptLimit',
44
+ subscription: 'runWithSubscriptionLimit',
45
+ };
31
46
  }
32
47
  async runTask(command, callbacks = {}, params, completionTime = 'end') {
33
- return pLimit_1.default.runWithCronLimit(() => {
48
+ const { runOrigin } = params, others = __rest(params, ["runOrigin"]);
49
+ return pLimit_1.default[this.taskLimitMap[runOrigin]](others, () => {
34
50
  return new Promise(async (resolve, reject) => {
35
51
  var _a, _b, _c;
36
- this.logger.info(`[panel][开始执行任务] 参数 ${JSON.stringify(Object.assign(Object.assign({}, params), { command }))}`);
52
+ this.logger.info(`[panel][开始执行任务] 参数: ${JSON.stringify(Object.assign(Object.assign({}, others), { command }))}`);
37
53
  try {
38
54
  const startTime = (0, dayjs_1.default)();
39
55
  await ((_a = callbacks.onBefore) === null || _a === void 0 ? void 0 : _a.call(callbacks, startTime));
@@ -56,9 +72,10 @@ let ScheduleService = class ScheduleService {
56
72
  });
57
73
  cp.on('exit', async (code) => {
58
74
  var _a;
75
+ this.logger.info('[panel][执行任务结束] 参数: %s, 退出码: %j', JSON.stringify(Object.assign(Object.assign({}, others), { command })), code);
59
76
  const endTime = (0, dayjs_1.default)();
60
77
  await ((_a = callbacks.onEnd) === null || _a === void 0 ? void 0 : _a.call(callbacks, cp, endTime, endTime.diff(startTime, 'seconds')));
61
- resolve(Object.assign(Object.assign({}, params), { pid: cp.pid, code }));
78
+ resolve(Object.assign(Object.assign({}, others), { pid: cp.pid, code }));
62
79
  });
63
80
  }
64
81
  catch (error) {
@@ -68,7 +85,7 @@ let ScheduleService = class ScheduleService {
68
85
  });
69
86
  });
70
87
  }
71
- async createCronTask({ id = 0, command, name, schedule = '' }, callbacks, runImmediately = false) {
88
+ async createCronTask({ id = 0, command, name, schedule = '', runOrigin }, callbacks, runImmediately = false) {
72
89
  const _id = this.formatId(id);
73
90
  this.logger.info('[panel][创建cron任务], 任务ID: %s, cron: %s, 任务名: %s, 执行命令: %s', _id, schedule, name, command);
74
91
  this.scheduleStacks.set(_id, node_schedule_1.default.scheduleJob(_id, schedule, async () => {
@@ -76,6 +93,8 @@ let ScheduleService = class ScheduleService {
76
93
  name,
77
94
  schedule,
78
95
  command,
96
+ id: _id,
97
+ runOrigin,
79
98
  });
80
99
  }));
81
100
  if (runImmediately) {
@@ -83,6 +102,8 @@ let ScheduleService = class ScheduleService {
83
102
  name,
84
103
  schedule,
85
104
  command,
105
+ id: _id,
106
+ runOrigin,
86
107
  });
87
108
  }
88
109
  }
@@ -95,16 +116,18 @@ let ScheduleService = class ScheduleService {
95
116
  this.scheduleStacks.delete(_id);
96
117
  }
97
118
  }
98
- async createIntervalTask({ id = 0, command, name = '' }, schedule, runImmediately = true, callbacks) {
119
+ async createIntervalTask({ id = 0, command, name = '', runOrigin }, schedule, runImmediately = true, callbacks) {
99
120
  const _id = this.formatId(id);
100
121
  this.logger.info('[panel][创建interval任务], 任务ID: %s, 任务名: %s, 执行命令: %s', _id, name, command);
101
122
  const task = new toad_scheduler_1.Task(name, () => {
102
123
  this.runTask(command, callbacks, {
103
124
  name,
104
125
  command,
126
+ id: _id,
127
+ runOrigin,
105
128
  });
106
129
  }, (err) => {
107
- this.logger.error('[执行任务失败] 命令: %s, 错误信息: %j', command, err);
130
+ this.logger.error('[panel][执行任务失败] 命令: %s, 错误信息: %j', command, err);
108
131
  });
109
132
  const job = new toad_scheduler_1.LongIntervalJob(Object.assign({ runImmediately: false }, schedule), task, _id);
110
133
  this.intervalSchedule.addIntervalJob(job);
@@ -112,12 +135,14 @@ let ScheduleService = class ScheduleService {
112
135
  this.runTask(command, callbacks, {
113
136
  name,
114
137
  command,
138
+ id: _id,
139
+ runOrigin,
115
140
  });
116
141
  }
117
142
  }
118
143
  async cancelIntervalTask({ id = 0, name }) {
119
144
  const _id = this.formatId(id);
120
- this.logger.info('[取消interval任务], 任务ID: %s, 任务名: %s', _id, name);
145
+ this.logger.info('[panel][取消interval任务], 任务ID: %s, 任务名: %s', _id, name);
121
146
  this.intervalSchedule.removeById(_id);
122
147
  }
123
148
  formatId(id) {
@@ -47,6 +47,7 @@ const schedule_1 = __importDefault(require("./schedule"));
47
47
  const config_1 = __importDefault(require("../config"));
48
48
  const const_1 = require("../config/const");
49
49
  const util_1 = require("../config/util");
50
+ const pLimit_1 = __importDefault(require("../shared/pLimit"));
50
51
  let ScriptService = class ScriptService {
51
52
  constructor(logger, sockService, cronService, scheduleService) {
52
53
  this.logger = logger;
@@ -76,12 +77,13 @@ let ScriptService = class ScriptService {
76
77
  async runScript(filePath) {
77
78
  const relativePath = path_1.default.relative(config_1.default.scriptPath, filePath);
78
79
  const command = `${const_1.TASK_COMMAND} ${relativePath} now`;
79
- const pid = await this.scheduleService.runTask(`real_time=true ${command}`, this.taskCallbacks(filePath), { command }, 'start');
80
+ const pid = await this.scheduleService.runTask(`real_time=true ${command}`, this.taskCallbacks(filePath), { command, id: relativePath.replace(/ /g, '-'), runOrigin: 'script' }, 'start');
80
81
  return { code: 200, data: pid };
81
82
  }
82
83
  async stopScript(filePath, pid) {
83
84
  if (!pid) {
84
85
  const relativePath = path_1.default.relative(config_1.default.scriptPath, filePath);
86
+ pLimit_1.default.removeQueuedCron(relativePath.replace(/ /g, '-'));
85
87
  pid = (await (0, util_1.getPid)(`${const_1.TASK_COMMAND} ${relativePath} now`));
86
88
  }
87
89
  try {
@@ -61,8 +61,9 @@ let SubscriptionService = class SubscriptionService {
61
61
  this.sshKeyService = sshKeyService;
62
62
  this.crontabService = crontabService;
63
63
  }
64
- async list(searchText) {
64
+ async list(searchText, ids) {
65
65
  let query = {};
66
+ const subIds = JSON.parse(ids || '[]');
66
67
  if (searchText) {
67
68
  const reg = {
68
69
  [sequelize_1.Op.or]: [
@@ -83,7 +84,7 @@ let SubscriptionService = class SubscriptionService {
83
84
  }
84
85
  try {
85
86
  const result = await subscription_1.SubscriptionModel.findAll({
86
- where: query,
87
+ where: Object.assign(Object.assign({}, query), (ids ? { id: subIds } : undefined)),
87
88
  order: [
88
89
  ['is_disabled', 'ASC'],
89
90
  ['createdAt', 'DESC'],
@@ -101,13 +102,13 @@ let SubscriptionService = class SubscriptionService {
101
102
  if (doc.schedule_type === 'crontab') {
102
103
  this.scheduleService.cancelCronTask(doc);
103
104
  needCreate &&
104
- (await this.scheduleService.createCronTask(doc, this.taskCallbacks(doc), runImmediately));
105
+ (await this.scheduleService.createCronTask(Object.assign(Object.assign({}, doc), { runOrigin: 'subscription' }), this.taskCallbacks(doc), runImmediately));
105
106
  }
106
107
  else if (doc.interval_schedule) {
107
108
  this.scheduleService.cancelIntervalTask(doc);
108
109
  const { type, value } = doc.interval_schedule;
109
110
  needCreate &&
110
- (await this.scheduleService.createIntervalTask(doc, { [type]: value }, runImmediately, this.taskCallbacks(doc)));
111
+ (await this.scheduleService.createIntervalTask(Object.assign(Object.assign({}, doc), { runOrigin: 'subscription' }), { [type]: value }, runImmediately, this.taskCallbacks(doc)));
111
112
  }
112
113
  }
113
114
  async setSshConfig() {
@@ -272,6 +273,8 @@ let SubscriptionService = class SubscriptionService {
272
273
  name: subscription.name,
273
274
  schedule: subscription.schedule,
274
275
  command,
276
+ id: String(subscription.id),
277
+ runOrigin: 'subscription',
275
278
  });
276
279
  }
277
280
  async disabled(ids) {
@@ -32,6 +32,7 @@ const notify_1 = __importDefault(require("./notify"));
32
32
  const schedule_1 = __importDefault(require("./schedule"));
33
33
  const sock_1 = __importDefault(require("./sock"));
34
34
  const os_1 = __importDefault(require("os"));
35
+ const dayjs_1 = __importDefault(require("dayjs"));
35
36
  const util_2 = require("../config/util");
36
37
  let SystemService = class SystemService {
37
38
  constructor(logger, scheduleService, sockService) {
@@ -74,9 +75,10 @@ let SystemService = class SystemService {
74
75
  const oDoc = await this.getSystemConfig();
75
76
  const result = await this.updateAuthDb(Object.assign(Object.assign({}, oDoc), { info: Object.assign(Object.assign({}, oDoc.info), info) }));
76
77
  const cron = {
77
- id: result.id || NaN,
78
+ id: result.id,
78
79
  name: '删除日志',
79
80
  command: `ql rmlog ${info.logRemoveFrequency}`,
81
+ runOrigin: 'system',
80
82
  };
81
83
  if ((_a = oDoc.info) === null || _a === void 0 ? void 0 : _a.logRemoveFrequency) {
82
84
  await this.scheduleService.cancelIntervalTask(cron);
@@ -84,7 +86,7 @@ let SystemService = class SystemService {
84
86
  if (info.logRemoveFrequency && info.logRemoveFrequency > 0) {
85
87
  this.scheduleService.createIntervalTask(cron, {
86
88
  days: info.logRemoveFrequency,
87
- });
89
+ }, true);
88
90
  }
89
91
  return { code: 200, data: info };
90
92
  }
@@ -143,6 +145,8 @@ let SystemService = class SystemService {
143
145
  },
144
146
  }, {
145
147
  command,
148
+ id: 'update-node-mirror',
149
+ runOrigin: 'system',
146
150
  });
147
151
  }
148
152
  async updatePythonMirror(info) {
@@ -186,6 +190,8 @@ let SystemService = class SystemService {
186
190
  },
187
191
  }, {
188
192
  command,
193
+ id: 'update-linux-mirror',
194
+ runOrigin: 'system',
189
195
  });
190
196
  }
191
197
  async checkUpdate() {
@@ -196,7 +202,7 @@ let SystemService = class SystemService {
196
202
  const result = await got_1.default.get(`${config_1.default.lastVersionFile}?t=${Date.now()}`, {
197
203
  timeout: 30000,
198
204
  });
199
- lastVersionContent = await (0, util_1.parseContentVersion)(result.body);
205
+ lastVersionContent = (0, util_1.parseContentVersion)(result.body);
200
206
  }
201
207
  catch (error) { }
202
208
  if (!lastVersionContent) {
@@ -278,6 +284,8 @@ let SystemService = class SystemService {
278
284
  }
279
285
  this.scheduleService.runTask(`real_time=true ${command}`, callback, {
280
286
  command,
287
+ id: command.replace(/ /g, '-'),
288
+ runOrigin: 'system',
281
289
  });
282
290
  }
283
291
  async stop({ command, pid }) {
@@ -319,9 +327,18 @@ let SystemService = class SystemService {
319
327
  return { code: 400, message: error.message };
320
328
  }
321
329
  }
322
- async getSystemLog(res) {
330
+ async getSystemLog(res, query) {
331
+ const startTime = (0, dayjs_1.default)(query.startTime || undefined)
332
+ .startOf('d')
333
+ .valueOf();
334
+ const endTime = (0, dayjs_1.default)(query.endTime || undefined)
335
+ .endOf('d')
336
+ .valueOf();
323
337
  const result = await (0, util_1.readDirs)(config_1.default.systemLogPath, config_1.default.systemLogPath);
324
- const logs = result.reverse().filter((x) => x.title.endsWith('.log'));
338
+ const logs = result
339
+ .reverse()
340
+ .filter((x) => x.title.endsWith('.log'))
341
+ .filter((x) => x.mtime >= startTime && x.mtime <= endTime);
325
342
  res.set({
326
343
  'Content-Length': (0, sum_1.default)(logs.map((x) => x.size)),
327
344
  });
@@ -340,6 +357,13 @@ let SystemService = class SystemService {
340
357
  }
341
358
  })(res, logs);
342
359
  }
360
+ async deleteSystemLog() {
361
+ const result = await (0, util_1.readDirs)(config_1.default.systemLogPath, config_1.default.systemLogPath);
362
+ const logs = result.reverse().filter((x) => x.title.endsWith('.log'));
363
+ for (const log of logs) {
364
+ await (0, util_1.rmPath)(path_1.default.join(config_1.default.systemLogPath, log.title));
365
+ }
366
+ }
343
367
  };
344
368
  __decorate([
345
369
  (0, typedi_1.Inject)((type) => notify_1.default),
@@ -135,6 +135,7 @@ let UserService = class UserService {
135
135
  status: system_1.LoginStatus.success,
136
136
  },
137
137
  });
138
+ this.getLoginLog();
138
139
  return {
139
140
  code: 200,
140
141
  data: { token, lastip, lastaddr, lastlogon, retries, platform },
@@ -159,6 +160,7 @@ let UserService = class UserService {
159
160
  status: system_1.LoginStatus.fail,
160
161
  },
161
162
  });
163
+ this.getLoginLog();
162
164
  if (retries > 2) {
163
165
  const waitTime = Math.round(Math.pow(3, retries + 1));
164
166
  return {
@@ -190,8 +192,9 @@ let UserService = class UserService {
190
192
  if (docs && docs.length > 0) {
191
193
  const result = docs.sort((a, b) => b.info.timestamp - a.info.timestamp);
192
194
  if (result.length > 100) {
195
+ const ids = result.slice(0, result.length - 100).map((x) => x.id);
193
196
  await system_1.SystemModel.destroy({
194
- where: { id: result[result.length - 1].id },
197
+ where: { id: ids },
195
198
  });
196
199
  }
197
200
  return result.map((x) => x.info);
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=interface.js.map
@@ -7,6 +7,7 @@ const p_queue_cjs_1 = __importDefault(require("p-queue-cjs"));
7
7
  const os_1 = __importDefault(require("os"));
8
8
  const system_1 = require("../data/system");
9
9
  const logger_1 = __importDefault(require("../loaders/logger"));
10
+ const notify_1 = __importDefault(require("../services/notify"));
10
11
  class TaskLimit {
11
12
  get cronLimitActiveCount() {
12
13
  return this.cronLimit.pending;
@@ -20,6 +21,8 @@ class TaskLimit {
20
21
  constructor() {
21
22
  this.dependenyLimit = new p_queue_cjs_1.default({ concurrency: 1 });
22
23
  this.queuedDependencyIds = new Set([]);
24
+ this.queuedCrons = new Map();
25
+ this.repeatCronNotifyMap = new Map();
23
26
  this.updateLogLimit = new p_queue_cjs_1.default({ concurrency: 1 });
24
27
  this.cronLimit = new p_queue_cjs_1.default({
25
28
  concurrency: Math.max(os_1.default.cpus().length, 4),
@@ -27,6 +30,16 @@ class TaskLimit {
27
30
  this.manualCronoLimit = new p_queue_cjs_1.default({
28
31
  concurrency: Math.max(os_1.default.cpus().length, 4),
29
32
  });
33
+ this.subscriptionLimit = new p_queue_cjs_1.default({
34
+ concurrency: Math.max(os_1.default.cpus().length, 4),
35
+ });
36
+ this.scriptLimit = new p_queue_cjs_1.default({
37
+ concurrency: Math.max(os_1.default.cpus().length, 4),
38
+ });
39
+ this.systemLimit = new p_queue_cjs_1.default({
40
+ concurrency: Math.max(os_1.default.cpus().length, 4),
41
+ });
42
+ this.notificationService = new notify_1.default();
30
43
  this.setCustomLimit();
31
44
  this.handleEvents();
32
45
  }
@@ -55,6 +68,15 @@ class TaskLimit {
55
68
  this.queuedDependencyIds.delete(dependency.id);
56
69
  }
57
70
  }
71
+ removeQueuedCron(id) {
72
+ if (this.queuedCrons.has(id)) {
73
+ const runs = this.queuedCrons.get(id);
74
+ if (runs && runs.length > 0) {
75
+ runs.pop();
76
+ this.queuedCrons.set(id, runs);
77
+ }
78
+ }
79
+ }
58
80
  async setCustomLimit(limit) {
59
81
  var _a;
60
82
  if (limit) {
@@ -71,12 +93,37 @@ class TaskLimit {
71
93
  this.manualCronoLimit.concurrency = doc.info.cronConcurrency;
72
94
  }
73
95
  }
74
- async runWithCronLimit(fn, options) {
96
+ async runWithCronLimit(cron, fn, options) {
97
+ fn.cron = cron;
98
+ let runs = this.queuedCrons.get(cron.id);
99
+ const result = (runs === null || runs === void 0 ? void 0 : runs.length) ? [...runs, fn] : [fn];
100
+ const repeatTimes = this.repeatCronNotifyMap.get(cron.id) || 0;
101
+ if ((result === null || result === void 0 ? void 0 : result.length) > 5) {
102
+ if (repeatTimes < 3) {
103
+ this.repeatCronNotifyMap.set(cron.id, repeatTimes + 1);
104
+ this.notificationService.externalNotify('任务重复运行', `任务:${cron.name},命令:${cron.command},定时:${cron.schedule},处于运行中的超过 5 个,请检查定时设置`);
105
+ }
106
+ logger_1.default.warn(`[schedule][任务重复运行] 参数 ${JSON.stringify(cron)}`);
107
+ return;
108
+ }
109
+ this.queuedCrons.set(cron.id, result);
75
110
  return this.cronLimit.add(fn, options);
76
111
  }
77
112
  async manualRunWithCronLimit(fn, options) {
78
113
  return this.manualCronoLimit.add(fn, options);
79
114
  }
115
+ async runWithSubscriptionLimit(schedule, fn, options) {
116
+ fn.schedule = schedule;
117
+ return this.subscriptionLimit.add(fn, options);
118
+ }
119
+ async runWithSystemLimit(schedule, fn, options) {
120
+ fn.schedule = schedule;
121
+ return this.systemLimit.add(fn, options);
122
+ }
123
+ async runWithScriptLimit(schedule, fn, options) {
124
+ fn.schedule = schedule;
125
+ return this.scriptLimit.add(fn, options);
126
+ }
80
127
  runDependeny(dependency, fn, options) {
81
128
  this.queuedDependencyIds.add(dependency.id);
82
129
  fn.dependency = dependency;