@whyour/qinglong 0.5.0 → 0.5.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 (44) hide show
  1. package/package.json +1 -1
  2. package/sample/config.sample.sh +4 -0
  3. package/shell/share.sh +1 -1
  4. package/shell/update.sh +6 -14
  5. package/static/build/api/system.js +6 -5
  6. package/static/build/data/auth.js +1 -0
  7. package/static/build/data/cron.js +3 -3
  8. package/static/build/loaders/initData.js +1 -1
  9. package/static/build/loaders/initFile.js +11 -0
  10. package/static/build/loaders/initTask.js +1 -1
  11. package/static/build/services/cron.js +3 -3
  12. package/static/build/services/dependence.js +2 -2
  13. package/static/build/services/schedule.js +2 -2
  14. package/static/build/services/system.js +22 -16
  15. package/static/build/shared/pLimit.js +29 -14
  16. package/static/build/shared/runCron.js +2 -2
  17. package/static/dist/2725.7b01466d.async.js +1 -0
  18. package/static/dist/2880.dc09d317.async.js +2 -0
  19. package/static/dist/4491.3c2d8653.async.js +4 -0
  20. package/static/dist/6923.906d60ab.async.js +6 -0
  21. package/static/dist/7192.64073afb.async.js +4 -0
  22. package/static/dist/index.html +1 -1
  23. package/static/dist/src__pages__crontab__index.7fcb35da.async.js +2 -0
  24. package/static/dist/{src__pages__error__index.c0477141.async.js → src__pages__error__index.a4305d27.async.js} +1 -1
  25. package/static/dist/src__pages__error__index.b047bb77.chunk.css +1 -0
  26. package/static/dist/src__pages__setting__index.9bed13e4.async.js +2 -0
  27. package/static/dist/src__pages__setting__loginLog.600363ba.async.js +18 -0
  28. package/static/dist/src__pages__subscription__index.ee4ae33c.async.js +1 -0
  29. package/static/dist/{umi.8ac0a928.js → umi.4ebd8373.js} +9 -9
  30. package/version.yaml +5 -10
  31. package/static/dist/4491.96ee9a9f.async.js +0 -4
  32. package/static/dist/5969.87aeb075.async.js +0 -1
  33. package/static/dist/7567.a224d0a6.async.js +0 -5
  34. package/static/dist/8037.386b415d.async.js +0 -1
  35. package/static/dist/921.198cefa6.async.js +0 -6
  36. package/static/dist/9504.6d4e29e7.async.js +0 -1
  37. package/static/dist/986.ab6a48a4.async.js +0 -1
  38. package/static/dist/src__pages__crontab__index.5cfa7d5b.async.js +0 -2
  39. package/static/dist/src__pages__crontab__viewCreateModal.3db14204.async.js +0 -4
  40. package/static/dist/src__pages__crontab__viewManageModal.9f899650.async.js +0 -4
  41. package/static/dist/src__pages__error__index.bc39e943.chunk.css +0 -1
  42. package/static/dist/src__pages__setting__index.0bfefeff.async.js +0 -2
  43. package/static/dist/src__pages__setting__loginLog.0708083b.async.js +0 -18
  44. package/static/dist/src__pages__subscription__index.708b6c8f.async.js +0 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@whyour/qinglong",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "Timed task management platform supporting Python3, JavaScript, Shell, Typescript",
5
5
  "repository": {
6
6
  "type": "git",
@@ -91,6 +91,10 @@ export TG_API_HOST=""
91
91
  export DD_BOT_TOKEN=""
92
92
  export DD_BOT_SECRET=""
93
93
 
94
+ ## 企业微信反向代理地址
95
+ ## (环境变量名 QYWX_ORIGIN)
96
+ export QYWX_ORIGIN=""
97
+
94
98
  ## 5. 企业微信机器人
95
99
  ## 官方说明文档:https://work.weixin.qq.com/api/doc/90000/90136/91770
96
100
  ## 下方填写密钥,企业微信推送 webhook 后面的 key
package/shell/share.sh CHANGED
@@ -305,7 +305,7 @@ git_clone_scripts() {
305
305
  local branch="$3"
306
306
  local proxy="$4"
307
307
  [[ $branch ]] && local part_cmd="-b $branch "
308
- echo -e "开始克隆仓库 $url 到 $dir\n"
308
+ echo -e "开始拉取 $url 到 $dir\n"
309
309
 
310
310
  set_proxy "$proxy"
311
311
 
package/shell/update.sh CHANGED
@@ -130,13 +130,9 @@ update_repo() {
130
130
  make_dir "${dir_scripts}/${uniq_path}"
131
131
 
132
132
  local formatUrl="$url"
133
- if [[ -d ${repo_path}/.git ]]; then
134
- reset_romote_url ${repo_path} "${formatUrl}" "${branch}"
135
- git_pull_scripts ${repo_path} "${branch}" "${proxy}"
136
- else
137
- rm -rf ${repo_path} &>/dev/null
138
- git_clone_scripts "${formatUrl}" ${repo_path} "${branch}" "${proxy}"
139
- fi
133
+ rm -rf ${repo_path} &>/dev/null
134
+ git_clone_scripts "${formatUrl}" ${repo_path} "${branch}" "${proxy}"
135
+
140
136
  if [[ $exit_status -eq 0 ]]; then
141
137
  echo -e "\n更新${repo_path}成功...\n"
142
138
  diff_scripts "$repo_path" "$author" "$path" "$blackword" "$dependence" "$extensions" "$autoAddCron" "$autoDelCron"
@@ -269,13 +265,9 @@ update_qinglong_static() {
269
265
  local no_restart="$1"
270
266
  local primary_branch="$2"
271
267
  local url="https://${mirror}.com/whyour/qinglong-static.git"
272
- if [[ -d ${ql_static_repo}/.git ]]; then
273
- reset_romote_url ${ql_static_repo} ${url} ${primary_branch}
274
- git_pull_scripts ${ql_static_repo} ${primary_branch}
275
- else
276
- rm -rf ${ql_static_repo} &>/dev/null
277
- git_clone_scripts ${url} ${ql_static_repo} ${primary_branch}
278
- fi
268
+ rm -rf ${ql_static_repo} &>/dev/null
269
+ git_clone_scripts ${url} ${ql_static_repo} ${primary_branch}
270
+
279
271
  if [[ $exit_status -eq 0 ]]; then
280
272
  echo -e "\n更新青龙静态资源成功...\n"
281
273
 
@@ -73,26 +73,27 @@ exports.default = (app) => {
73
73
  return next(e);
74
74
  }
75
75
  });
76
- route.get('/log/remove', async (req, res, next) => {
76
+ route.get('/config', async (req, res, next) => {
77
77
  const logger = typedi_1.Container.get('logger');
78
78
  try {
79
79
  const systemService = typedi_1.Container.get(system_1.default);
80
- const data = await systemService.getLogRemoveFrequency();
80
+ const data = await systemService.getSystemConfig();
81
81
  res.send({ code: 200, data });
82
82
  }
83
83
  catch (e) {
84
84
  return next(e);
85
85
  }
86
86
  });
87
- route.put('/log/remove', (0, celebrate_1.celebrate)({
87
+ route.put('/config', (0, celebrate_1.celebrate)({
88
88
  body: celebrate_1.Joi.object({
89
- frequency: celebrate_1.Joi.number().required(),
89
+ logRemoveFrequency: celebrate_1.Joi.number().optional().allow(null),
90
+ cronConcurrency: celebrate_1.Joi.number().optional().allow(null),
90
91
  }),
91
92
  }), async (req, res, next) => {
92
93
  const logger = typedi_1.Container.get('logger');
93
94
  try {
94
95
  const systemService = typedi_1.Container.get(system_1.default);
95
- const result = await systemService.updateLogRemoveFrequency(req.body.frequency);
96
+ const result = await systemService.updateSystemConfig(req.body);
96
97
  res.send(result);
97
98
  }
98
99
  catch (e) {
@@ -23,6 +23,7 @@ var AuthDataType;
23
23
  AuthDataType["authToken"] = "authToken";
24
24
  AuthDataType["notification"] = "notification";
25
25
  AuthDataType["removeLogFrequency"] = "removeLogFrequency";
26
+ AuthDataType["systemConfig"] = "systemConfig";
26
27
  })(AuthDataType = exports.AuthDataType || (exports.AuthDataType = {}));
27
28
  exports.AuthModel = _1.sequelize.define('Auth', {
28
29
  ip: sequelize_1.DataTypes.STRING,
@@ -30,9 +30,9 @@ exports.Crontab = Crontab;
30
30
  var CrontabStatus;
31
31
  (function (CrontabStatus) {
32
32
  CrontabStatus[CrontabStatus["running"] = 0] = "running";
33
- CrontabStatus[CrontabStatus["idle"] = 1] = "idle";
34
- CrontabStatus[CrontabStatus["disabled"] = 2] = "disabled";
35
- CrontabStatus[CrontabStatus["queued"] = 3] = "queued";
33
+ CrontabStatus[CrontabStatus["queued"] = 1] = "queued";
34
+ CrontabStatus[CrontabStatus["idle"] = 2] = "idle";
35
+ CrontabStatus[CrontabStatus["disabled"] = 3] = "disabled";
36
36
  })(CrontabStatus = exports.CrontabStatus || (exports.CrontabStatus = {}));
37
37
  exports.CrontabModel = _1.sequelize.define('Crontab', {
38
38
  name: {
@@ -32,7 +32,7 @@ exports.default = async () => {
32
32
  }
33
33
  });
34
34
  // 初始化更新所有任务状态为空闲
35
- await cron_1.CrontabModel.update({ status: cron_1.CrontabStatus.idle }, { where: { status: [cron_1.CrontabStatus.running, cron_1.CrontabStatus.queued] } });
35
+ await cron_1.CrontabModel.update({ status: cron_1.CrontabStatus.idle }, { where: { status: { [sequelize_1.Op.ne]: cron_1.CrontabStatus.disabled } } });
36
36
  // 初始化时安装所有处于安装中,安装成功,安装失败的依赖
37
37
  dependence_2.DependenceModel.findAll({
38
38
  where: {},
@@ -25,10 +25,13 @@ const confFile = path_1.default.join(configPath, 'config.sh');
25
25
  const authConfigFile = path_1.default.join(configPath, 'auth.json');
26
26
  const sampleConfigFile = path_1.default.join(samplePath, 'config.sample.sh');
27
27
  const sampleAuthFile = path_1.default.join(samplePath, 'auth.sample.json');
28
+ const sampleTaskShellFile = path_1.default.join(samplePath, 'task.sample.sh');
28
29
  const sampleNotifyJsFile = path_1.default.join(samplePath, 'notify.js');
29
30
  const sampleNotifyPyFile = path_1.default.join(samplePath, 'notify.py');
30
31
  const scriptNotifyJsFile = path_1.default.join(scriptPath, 'sendNotify.js');
31
32
  const scriptNotifyPyFile = path_1.default.join(scriptPath, 'notify.py');
33
+ const TaskBeforeFile = path_1.default.join(configPath, 'task_before.sh');
34
+ const TaskAfterFile = path_1.default.join(configPath, 'task_after.sh');
32
35
  const homedir = os_1.default.homedir();
33
36
  const sshPath = path_1.default.resolve(homedir, '.ssh');
34
37
  const sshdPath = path_1.default.join(dataPath, 'ssh.d');
@@ -45,6 +48,8 @@ exports.default = async () => {
45
48
  const tmpDirExist = await (0, util_1.fileExist)(tmpPath);
46
49
  const scriptNotifyJsFileExist = await (0, util_1.fileExist)(scriptNotifyJsFile);
47
50
  const scriptNotifyPyFileExist = await (0, util_1.fileExist)(scriptNotifyPyFile);
51
+ const TaskBeforeFileExist = await (0, util_1.fileExist)(TaskBeforeFile);
52
+ const TaskAfterFileExist = await (0, util_1.fileExist)(TaskAfterFile);
48
53
  if (!configDirExist) {
49
54
  fs_1.default.mkdirSync(configPath);
50
55
  }
@@ -82,6 +87,12 @@ exports.default = async () => {
82
87
  if (!scriptNotifyPyFileExist) {
83
88
  fs_1.default.writeFileSync(scriptNotifyPyFile, fs_1.default.readFileSync(sampleNotifyPyFile));
84
89
  }
90
+ if (!TaskBeforeFileExist) {
91
+ fs_1.default.writeFileSync(TaskBeforeFile, fs_1.default.readFileSync(sampleTaskShellFile));
92
+ }
93
+ if (!TaskAfterFileExist) {
94
+ fs_1.default.writeFileSync(TaskAfterFile, fs_1.default.readFileSync(sampleTaskShellFile));
95
+ }
85
96
  dotenv_1.default.config({ path: confFile });
86
97
  logger_1.default.info('✌️ Init file down');
87
98
  };
@@ -30,7 +30,7 @@ exports.default = async () => {
30
30
  days: 28,
31
31
  });
32
32
  // 运行删除日志任务
33
- const data = await systemService.getLogRemoveFrequency();
33
+ const data = await systemService.getSystemConfig();
34
34
  if (data && data.info && data.info.frequency) {
35
35
  const rmlogCron = {
36
36
  id: data.id,
@@ -28,7 +28,7 @@ const sequelize_1 = require("sequelize");
28
28
  const path_1 = __importDefault(require("path"));
29
29
  const const_1 = require("../config/const");
30
30
  const client_1 = __importDefault(require("../schedule/client"));
31
- const pLimit_1 = require("../shared/pLimit");
31
+ const pLimit_1 = __importDefault(require("../shared/pLimit"));
32
32
  const cross_spawn_1 = require("cross-spawn");
33
33
  let CronService = class CronService {
34
34
  constructor(logger) {
@@ -240,7 +240,7 @@ let CronService = class CronService {
240
240
  if (!filterQuery[key])
241
241
  continue;
242
242
  if (key === 'status') {
243
- if (filterQuery[key].includes(2)) {
243
+ if (filterQuery[key].includes(cron_1.CrontabStatus.disabled)) {
244
244
  q = { [sequelize_1.Op.or]: [{ [key]: filterQuery[key] }, { isDisabled: 1 }] };
245
245
  }
246
246
  else {
@@ -336,7 +336,7 @@ let CronService = class CronService {
336
336
  await cron_1.CrontabModel.update({ status: cron_1.CrontabStatus.idle, pid: undefined }, { where: { id: ids } });
337
337
  }
338
338
  async runSingle(cronId) {
339
- return (0, pLimit_1.runWithCpuLimit)(() => {
339
+ return pLimit_1.default.runWithCpuLimit(() => {
340
340
  return new Promise(async (resolve) => {
341
341
  const cron = await this.getDb({ id: cronId });
342
342
  if (cron.status !== cron_1.CrontabStatus.queued) {
@@ -33,7 +33,7 @@ const cross_spawn_1 = require("cross-spawn");
33
33
  const sock_1 = __importDefault(require("./sock"));
34
34
  const sequelize_1 = require("sequelize");
35
35
  const dayjs_1 = __importDefault(require("dayjs"));
36
- const pLimit_1 = require("../shared/pLimit");
36
+ const pLimit_1 = __importDefault(require("../shared/pLimit"));
37
37
  let DependenceService = class DependenceService {
38
38
  constructor(logger, sockService) {
39
39
  this.logger = logger;
@@ -121,7 +121,7 @@ let DependenceService = class DependenceService {
121
121
  await dependence_1.DependenceModel.update({ log: newLog }, { where: { id: ids } });
122
122
  }
123
123
  installOrUninstallDependency(dependency, isInstall = true, force = false) {
124
- return (0, pLimit_1.runOneByOne)(() => {
124
+ return pLimit_1.default.runOneByOne(() => {
125
125
  return new Promise(async (resolve) => {
126
126
  const depIds = [dependency.id];
127
127
  const status = isInstall
@@ -20,7 +20,7 @@ const winston_1 = __importDefault(require("winston"));
20
20
  const node_schedule_1 = __importDefault(require("node-schedule"));
21
21
  const toad_scheduler_1 = require("toad-scheduler");
22
22
  const dayjs_1 = __importDefault(require("dayjs"));
23
- const pLimit_1 = require("../shared/pLimit");
23
+ const pLimit_1 = __importDefault(require("../shared/pLimit"));
24
24
  const cross_spawn_1 = require("cross-spawn");
25
25
  let ScheduleService = class ScheduleService {
26
26
  constructor(logger) {
@@ -30,7 +30,7 @@ let ScheduleService = class ScheduleService {
30
30
  this.maxBuffer = 200 * 1024 * 1024;
31
31
  }
32
32
  async runTask(command, callbacks = {}, completionTime = 'end') {
33
- return (0, pLimit_1.runWithCpuLimit)(() => {
33
+ return pLimit_1.default.runWithCpuLimit(() => {
34
34
  return new Promise(async (resolve, reject) => {
35
35
  var _a, _b, _c;
36
36
  try {
@@ -26,14 +26,15 @@ const sock_1 = __importDefault(require("./sock"));
26
26
  const got_1 = __importDefault(require("got"));
27
27
  const util_1 = require("../config/util");
28
28
  const const_1 = require("../config/const");
29
+ const pLimit_1 = __importDefault(require("../shared/pLimit"));
29
30
  let SystemService = class SystemService {
30
31
  constructor(logger, scheduleService, sockService) {
31
32
  this.logger = logger;
32
33
  this.scheduleService = scheduleService;
33
34
  this.sockService = sockService;
34
35
  }
35
- async getLogRemoveFrequency() {
36
- const doc = await this.getDb({ type: auth_1.AuthDataType.removeLogFrequency });
36
+ async getSystemConfig() {
37
+ const doc = await this.getDb({ type: auth_1.AuthDataType.systemConfig });
37
38
  return doc || {};
38
39
  }
39
40
  async updateAuthDb(payload) {
@@ -59,21 +60,26 @@ let SystemService = class SystemService {
59
60
  return { code: 400, message: '通知发送失败,请检查参数' };
60
61
  }
61
62
  }
62
- async updateLogRemoveFrequency(frequency) {
63
- const oDoc = await this.getLogRemoveFrequency();
64
- const result = await this.updateAuthDb(Object.assign(Object.assign({}, oDoc), { type: auth_1.AuthDataType.removeLogFrequency, info: { frequency } }));
65
- const cron = {
66
- id: result.id,
67
- name: '删除日志',
68
- command: `ql rmlog ${frequency}`,
69
- };
70
- await this.scheduleService.cancelIntervalTask(cron);
71
- if (frequency > 0) {
72
- this.scheduleService.createIntervalTask(cron, {
73
- days: frequency,
74
- });
63
+ async updateSystemConfig(info) {
64
+ const oDoc = await this.getSystemConfig();
65
+ const result = await this.updateAuthDb(Object.assign(Object.assign({}, oDoc), { type: auth_1.AuthDataType.systemConfig, info }));
66
+ if (info.logRemoveFrequency) {
67
+ const cron = {
68
+ id: result.id,
69
+ name: '删除日志',
70
+ command: `ql rmlog ${info.logRemoveFrequency}`,
71
+ };
72
+ await this.scheduleService.cancelIntervalTask(cron);
73
+ if (info.logRemoveFrequency > 0) {
74
+ this.scheduleService.createIntervalTask(cron, {
75
+ days: info.logRemoveFrequency,
76
+ });
77
+ }
78
+ }
79
+ if (info.cronConcurrency) {
80
+ await pLimit_1.default.setCustomLimit(info.cronConcurrency);
75
81
  }
76
- return { code: 200, data: Object.assign({}, cron) };
82
+ return { code: 200, data: info };
77
83
  }
78
84
  async checkUpdate() {
79
85
  try {
@@ -3,21 +3,36 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.runOneByOne = exports.runWithCpuLimit = void 0;
7
6
  const p_limit_1 = __importDefault(require("p-limit"));
8
7
  const os_1 = __importDefault(require("os"));
9
- const cpuLimit = (0, p_limit_1.default)(os_1.default.cpus().length);
10
- const oneLimit = (0, p_limit_1.default)(1);
11
- function runWithCpuLimit(fn) {
12
- return cpuLimit(() => {
13
- return fn();
14
- });
8
+ const auth_1 = require("../data/auth");
9
+ class TaskLimit {
10
+ constructor() {
11
+ this.oneLimit = (0, p_limit_1.default)(1);
12
+ this.cpuLimit = (0, p_limit_1.default)(Math.max(os_1.default.cpus().length, 4));
13
+ this.setCustomLimit();
14
+ }
15
+ async setCustomLimit(limit) {
16
+ var _a, _b;
17
+ if (limit) {
18
+ this.cpuLimit = (0, p_limit_1.default)(limit);
19
+ return;
20
+ }
21
+ const doc = await auth_1.AuthModel.findOne({ where: { type: auth_1.AuthDataType.systemConfig } });
22
+ if ((_a = doc === null || doc === void 0 ? void 0 : doc.info) === null || _a === void 0 ? void 0 : _a.cronConcurrency) {
23
+ this.cpuLimit = (0, p_limit_1.default)((_b = doc === null || doc === void 0 ? void 0 : doc.info) === null || _b === void 0 ? void 0 : _b.cronConcurrency);
24
+ }
25
+ }
26
+ runWithCpuLimit(fn) {
27
+ return this.cpuLimit(() => {
28
+ return fn();
29
+ });
30
+ }
31
+ runOneByOne(fn) {
32
+ return this.oneLimit(() => {
33
+ return fn();
34
+ });
35
+ }
15
36
  }
16
- exports.runWithCpuLimit = runWithCpuLimit;
17
- function runOneByOne(fn) {
18
- return oneLimit(() => {
19
- return fn();
20
- });
21
- }
22
- exports.runOneByOne = runOneByOne;
37
+ exports.default = new TaskLimit();
23
38
  //# sourceMappingURL=pLimit.js.map
@@ -5,10 +5,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.runCron = void 0;
7
7
  const cross_spawn_1 = require("cross-spawn");
8
- const pLimit_1 = require("./pLimit");
8
+ const pLimit_1 = __importDefault(require("./pLimit"));
9
9
  const logger_1 = __importDefault(require("../loaders/logger"));
10
10
  function runCron(cmd) {
11
- return (0, pLimit_1.runWithCpuLimit)(() => {
11
+ return pLimit_1.default.runWithCpuLimit(() => {
12
12
  return new Promise(async (resolve) => {
13
13
  logger_1.default.silly('运行命令: ' + cmd);
14
14
  const cp = (0, cross_spawn_1.spawn)(cmd, { shell: '/bin/bash' });