@whyour/qinglong 0.15.6 → 0.17.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.
Files changed (51) hide show
  1. package/.env.example +1 -0
  2. package/docker/310.Dockerfile +6 -1
  3. package/docker/Dockerfile +2 -1
  4. package/docker/docker-entrypoint.sh +1 -0
  5. package/docker/front.conf +16 -0
  6. package/other.config.js +13 -0
  7. package/package.json +3 -3
  8. package/sample/config.sample.sh +19 -8
  9. package/sample/notify.js +49 -32
  10. package/sample/notify.py +286 -145
  11. package/shell/check.sh +1 -0
  12. package/shell/share.sh +13 -1
  13. package/shell/update.sh +34 -22
  14. package/static/build/api/dependence.js +12 -0
  15. package/static/build/config/index.js +1 -0
  16. package/static/build/config/util.js +26 -23
  17. package/static/build/data/dependence.js +1 -0
  18. package/static/build/loaders/server.js +0 -21
  19. package/static/build/loaders/update.js +79 -0
  20. package/static/build/services/dependence.js +35 -4
  21. package/static/build/services/notify.js +4 -13
  22. package/static/build/services/system.js +17 -32
  23. package/static/build/shared/pLimit.js +18 -5
  24. package/static/build/update.js +29 -0
  25. package/static/dist/{419.f9258e2f.async.js → 419.71c3c9c2.async.js} +1 -1
  26. package/static/dist/{833.c59c5023.async.js → 833.ea0fd669.async.js} +1 -1
  27. package/static/dist/8430.0291dda0.async.js +1 -0
  28. package/static/dist/index.html +1 -1
  29. package/static/dist/{layouts__index.817c948a.async.js → layouts__index.a51b2768.async.js} +1 -1
  30. package/static/dist/{src__pages__crontab__detail.7d1c2d15.async.js → src__pages__crontab__detail.2ab4f3e8.async.js} +1 -1
  31. package/static/dist/{src__pages__crontab__index.5aece157.async.js → src__pages__crontab__index.719429ac.async.js} +1 -1
  32. package/static/dist/src__pages__dependence__index.52fca7ba.async.js +1 -0
  33. package/static/dist/src__pages__dependence__logModal.baba01d6.async.js +1 -0
  34. package/static/dist/src__pages__dependence__type.860703e8.async.js +1 -0
  35. package/static/dist/{src__pages__log__index.757b3471.async.js → src__pages__log__index.44c6a008.async.js} +1 -1
  36. package/static/dist/{src__pages__script__index.ed44bc1b.async.js → src__pages__script__index.2a8d8477.async.js} +1 -1
  37. package/static/dist/src__pages__setting__checkUpdate.43e62d05.async.js +1 -0
  38. package/static/dist/src__pages__setting__dependence.28193e94.async.js +1 -0
  39. package/static/dist/src__pages__setting__index.7ab054fb.async.js +1 -0
  40. package/static/dist/src__pages__setting__other.2c4534ef.async.js +1 -0
  41. package/static/dist/src__pages__setting__progress.7d65aebf.async.js +1 -0
  42. package/static/dist/{umi.889d3656.js → umi.3bb00f35.js} +1 -1
  43. package/version.yaml +8 -12
  44. package/static/dist/8008.89ba3d06.async.js +0 -1
  45. package/static/dist/src__pages__dependence__index.27d29203.async.js +0 -1
  46. package/static/dist/src__pages__dependence__logModal.b44459a9.async.js +0 -1
  47. package/static/dist/src__pages__setting__checkUpdate.42020a45.async.js +0 -1
  48. package/static/dist/src__pages__setting__dependence.2efb8ee3.async.js +0 -1
  49. package/static/dist/src__pages__setting__index.3e2ad723.async.js +0 -1
  50. package/static/dist/src__pages__setting__other.a029d99a.async.js +0 -1
  51. package/static/dist/src__pages__setting__progress.65e2e878.async.js +0 -1
package/.env.example CHANGED
@@ -1,3 +1,4 @@
1
+ UPDATE_PORT=5300
1
2
  PUBLIC_PORT=5400
2
3
  CRON_PORT=5500
3
4
  BACK_PORT=5600
@@ -58,7 +58,8 @@ RUN set -x && \
58
58
  rm -rf /root/.pnpm-store && \
59
59
  rm -rf /root/.local/share/pnpm/store && \
60
60
  rm -rf /root/.cache && \
61
- rm -rf /root/.npm
61
+ rm -rf /root/.npm && \
62
+ ulimit -c 0
62
63
 
63
64
  ARG SOURCE_COMMIT
64
65
  RUN git clone --depth=1 -b ${QL_BRANCH} ${QL_URL} ${QL_DIR} && \
@@ -79,3 +80,7 @@ HEALTHCHECK --interval=5s --timeout=2s --retries=20 \
79
80
  CMD curl -sf --noproxy '*' http://127.0.0.1:5400/api/health || exit 1
80
81
 
81
82
  ENTRYPOINT ["./docker/docker-entrypoint.sh"]
83
+
84
+ VOLUME /ql/data
85
+
86
+ EXPOSE 5700
package/docker/Dockerfile CHANGED
@@ -59,7 +59,8 @@ RUN set -x && \
59
59
  rm -rf /root/.pnpm-store && \
60
60
  rm -rf /root/.local/share/pnpm/store && \
61
61
  rm -rf /root/.cache && \
62
- rm -rf /root/.npm
62
+ rm -rf /root/.npm && \
63
+ ulimit -c 0
63
64
 
64
65
  ARG SOURCE_COMMIT
65
66
  RUN git clone --depth=1 -b ${QL_BRANCH} ${QL_URL} ${QL_DIR} && \
@@ -21,6 +21,7 @@ nginx -s reload 2>/dev/null || nginx -c /etc/nginx/nginx.conf
21
21
  echo -e "nginx启动成功...\n"
22
22
 
23
23
  echo -e "======================4. 启动pm2服务========================\n"
24
+ reload_update
24
25
  reload_pm2
25
26
 
26
27
  if [[ $AutoStartBot == true ]]; then
package/docker/front.conf CHANGED
@@ -6,6 +6,10 @@ upstream publicApi {
6
6
  server 0.0.0.0:5400;
7
7
  }
8
8
 
9
+ upstream updateApi {
10
+ server 0.0.0.0:5300;
11
+ }
12
+
9
13
  map $http_upgrade $connection_upgrade {
10
14
  default keep-alive;
11
15
  'websocket' upgrade;
@@ -16,6 +20,18 @@ server {
16
20
  IPV6_CONFIG
17
21
  ssl_session_timeout 5m;
18
22
 
23
+ location QL_BASE_URLapi/update/ {
24
+ proxy_set_header Host $http_host;
25
+ proxy_set_header X-Real-IP $remote_addr;
26
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
27
+ proxy_pass http://updateApi/api/;
28
+ proxy_buffering off;
29
+ proxy_redirect default;
30
+ proxy_connect_timeout 1800;
31
+ proxy_send_timeout 1800;
32
+ proxy_read_timeout 1800;
33
+ }
34
+
19
35
  location QL_BASE_URLapi/public/ {
20
36
  proxy_set_header Host $http_host;
21
37
  proxy_set_header X-Real-IP $remote_addr;
@@ -0,0 +1,13 @@
1
+ module.exports = {
2
+ apps: [
3
+ {
4
+ name: 'update',
5
+ max_restarts: 10,
6
+ kill_timeout: 15000,
7
+ wait_ready: true,
8
+ listen_timeout: 10000,
9
+ time: true,
10
+ script: 'static/build/update.js',
11
+ },
12
+ ],
13
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@whyour/qinglong",
3
- "version": "0.15.6",
3
+ "version": "0.17.0",
4
4
  "description": "Timed task management platform supporting Python3, JavaScript, Shell, Typescript",
5
5
  "repository": {
6
6
  "type": "git",
@@ -15,6 +15,7 @@
15
15
  "start": "concurrently -n w: npm:start:*",
16
16
  "start:front": "max dev",
17
17
  "start:back": "nodemon",
18
+ "start:update": "ts-node -P tsconfig.back.json ./back/update.ts",
18
19
  "start:public": "ts-node -P tsconfig.back.json ./back/public.ts",
19
20
  "start:rpc": "ts-node -P tsconfig.back.json ./back/schedule/index.ts",
20
21
  "build:front": "max build",
@@ -22,6 +23,7 @@
22
23
  "panel": "npm run build:back && node static/build/app.js",
23
24
  "schedule": "npm run build:back && node static/build/schedule/index.js",
24
25
  "public": "npm run build:back && node static/build/public.js",
26
+ "update": "npm run build:back && node static/build/update.js",
25
27
  "gen:proto": "protoc --experimental_allow_proto3_optional --plugin=./node_modules/.bin/protoc-gen-ts_proto ./back/protos/*.proto --ts_proto_out=./ --ts_proto_opt=outputServices=grpc-js,env=node,esModuleInterop=true",
26
28
  "prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'",
27
29
  "postinstall": "max setup 2>/dev/null || true",
@@ -106,7 +108,6 @@
106
108
  "serve-handler": "^6.1.3",
107
109
  "sockjs": "^0.3.24",
108
110
  "sqlite3": "git+https://github.com/whyour/node-sqlite3.git#v1.0.3",
109
- "tar": "^6.1.15",
110
111
  "toad-scheduler": "^1.6.0",
111
112
  "typedi": "^0.10.0",
112
113
  "uuid": "^8.3.2",
@@ -144,7 +145,6 @@
144
145
  "@types/serve-handler": "^6.1.1",
145
146
  "@types/sockjs": "^0.3.33",
146
147
  "@types/sockjs-client": "^1.5.1",
147
- "@types/tar": "^6.1.5",
148
148
  "@types/uuid": "^8.3.4",
149
149
  "@types/request-ip": "0.0.41",
150
150
  "@uiw/codemirror-extensions-langs": "^4.21.9",
@@ -148,6 +148,15 @@ export AIBOTK_TYPE=""
148
148
  ## aibotk_name (必填)填写群名或用户昵称,和上面的type类型要对应
149
149
  export AIBOTK_NAME=""
150
150
 
151
+ ## 13. CHRONOCAT
152
+ ## CHRONOCAT_URL 推送 http://127.0.0.1:16530
153
+ ## CHRONOCAT_TOKEN 填写在CHRONOCAT文件生成的访问密钥
154
+ ## CHRONOCAT_QQ 个人:user_id=个人QQ 群则填入group_id=QQ群 多个用英文;隔开同时支持个人和群 如:user_id=xxx;group_id=xxxx;group_id=xxxxx
155
+ ## CHRONOCAT相关API https://chronocat.vercel.app/install/docker/official/
156
+ export CHRONOCAT_URL=""
157
+ export CHRONOCAT_QQ=""
158
+ export CHRONOCAT_TOKEN=""
159
+
151
160
  ## 14. SMTP
152
161
  ## 邮箱服务名称,比如126、163、Gmail、QQ等,支持列表 https://github.com/nodemailer/nodemailer/blob/master/lib/well-known/services.json
153
162
  export SMTP_SERVICE=""
@@ -163,13 +172,15 @@ export SMTP_NAME=""
163
172
  ## PUSHME_KEY (必填)填写PushMe APP上获取的push_key
164
173
  export PUSHME_KEY=""
165
174
 
166
- ## 13. CHRONOCAT
167
- ## CHRONOCAT_URL 推送 http://127.0.0.1:16530
168
- ## CHRONOCAT_TOKEN 填写在CHRONOCAT文件生成的访问密钥
169
- ## CHRONOCAT_QQ 个人:user_id=个人QQ 群则填入group_id=QQ群 多个用英文;隔开同时支持个人和群 如:user_id=xxx;group_id=xxxx;group_id=xxxxx
170
- ## CHRONOCAT相关API https://chronocat.vercel.app/install/docker/official/
171
- export CHRONOCAT_URL=""
172
- export CHRONOCAT_QQ=""
173
- export CHRONOCAT_TOKEN=""
175
+ ## 15. 自定义通知
176
+ ## 自定义通知 接收回调的URL
177
+ export WEBHOOK_URL=""
178
+ ## WEBHOOK_BODY WEBHOOK_HEADERS 多个参数时,直接换行或者使用 $'\n' 连接多行字符串,比如 export dd="line 1"$'\n'"line 2"
179
+ export WEBHOOK_BODY=""
180
+ export WEBHOOK_HEADERS=""
181
+ ## 支持 GET/POST/PUT
182
+ export WEBHOOK_METHOD=""
183
+ ## 支持 text/plain、application/json、multipart/form-data、application/x-www-form-urlencoded
184
+ export WEBHOOK_CONTENT_TYPE=""
174
185
 
175
186
  ## 其他需要的变量,脚本中需要的变量使用 export 变量名= 声明即可
package/sample/notify.js CHANGED
@@ -816,7 +816,18 @@ function ChangeUserId(desp) {
816
816
  }
817
817
  }
818
818
 
819
- function qywxamNotify(text, desp) {
819
+ async function qywxamNotify(text, desp) {
820
+ const MAX_LENGTH = 900;
821
+ if (desp.length > MAX_LENGTH) {
822
+ let d = desp.substr(0, MAX_LENGTH) + '\n==More==';
823
+ await do_qywxamNotify(text, d);
824
+ await qywxamNotify(text, desp.substr(MAX_LENGTH));
825
+ } else {
826
+ return await do_qywxamNotify(text, desp);
827
+ }
828
+ }
829
+
830
+ function do_qywxamNotify(text, desp) {
820
831
  return new Promise((resolve) => {
821
832
  if (QYWX_AM) {
822
833
  const QYWX_AM_AY = QYWX_AM.split(',');
@@ -1273,18 +1284,15 @@ function chronocatNotify(title, desp) {
1273
1284
 
1274
1285
  function webhookNotify(text, desp) {
1275
1286
  return new Promise((resolve) => {
1276
- const { formatBody, formatUrl } = formatNotifyContentFun(
1277
- WEBHOOK_URL,
1278
- WEBHOOK_BODY,
1279
- text,
1280
- desp,
1281
- );
1282
- if (!formatUrl && !formatBody) {
1287
+ if (!WEBHOOK_URL.includes('$title') && !WEBHOOK_BODY.includes('$title')) {
1283
1288
  resolve();
1284
1289
  return;
1285
1290
  }
1291
+
1286
1292
  const headers = parseHeaders(WEBHOOK_HEADERS);
1287
- const body = parseBody(formatBody, WEBHOOK_CONTENT_TYPE);
1293
+ const body = parseBody(WEBHOOK_BODY, WEBHOOK_CONTENT_TYPE, (v) =>
1294
+ v?.replaceAll('$title', text)?.replaceAll('$content', desp),
1295
+ );
1288
1296
  const bodyParam = formatBodyFun(WEBHOOK_CONTENT_TYPE, body);
1289
1297
  const options = {
1290
1298
  method: WEBHOOK_METHOD,
@@ -1296,6 +1304,10 @@ function webhookNotify(text, desp) {
1296
1304
  };
1297
1305
 
1298
1306
  if (WEBHOOK_METHOD) {
1307
+ const formatUrl = WEBHOOK_URL.replaceAll(
1308
+ '$title',
1309
+ encodeURIComponent(text),
1310
+ ).replaceAll('$content', encodeURIComponent(desp));
1299
1311
  got(formatUrl, options).then((resp) => {
1300
1312
  try {
1301
1313
  if (resp.statusCode !== 200) {
@@ -1315,6 +1327,32 @@ function webhookNotify(text, desp) {
1315
1327
  });
1316
1328
  }
1317
1329
 
1330
+ function parseString(input, valueFormatFn) {
1331
+ const regex = /(\w+):\s*((?:(?!\n\w+:).)*)/g;
1332
+ const matches = {};
1333
+
1334
+ let match;
1335
+ while ((match = regex.exec(input)) !== null) {
1336
+ const [, key, value] = match;
1337
+ const _key = key.trim();
1338
+ if (!_key || matches[_key]) {
1339
+ continue;
1340
+ }
1341
+
1342
+ let _value = value.trim();
1343
+
1344
+ try {
1345
+ _value = valueFormatFn ? valueFormatFn(_value) : _value;
1346
+ const jsonValue = JSON.parse(_value);
1347
+ matches[_key] = jsonValue;
1348
+ } catch (error) {
1349
+ matches[_key] = _value;
1350
+ }
1351
+ }
1352
+
1353
+ return matches;
1354
+ }
1355
+
1318
1356
  function parseHeaders(headers) {
1319
1357
  if (!headers) return {};
1320
1358
 
@@ -1339,33 +1377,12 @@ function parseHeaders(headers) {
1339
1377
  return parsed;
1340
1378
  }
1341
1379
 
1342
- function parseBody(body, contentType) {
1380
+ function parseBody(body, contentType, valueFormatFn) {
1343
1381
  if (contentType === 'text/plain' || !body) {
1344
1382
  return body;
1345
1383
  }
1346
1384
 
1347
- const parsed = {};
1348
- let key;
1349
- let val;
1350
- let i;
1351
-
1352
- body &&
1353
- body.split('\n').forEach(function parser(line) {
1354
- i = line.indexOf(':');
1355
- key = line.substring(0, i).trim();
1356
- val = line.substring(i + 1).trim();
1357
-
1358
- if (!key || parsed[key]) {
1359
- return;
1360
- }
1361
-
1362
- try {
1363
- const jsonValue = JSON.parse(val);
1364
- parsed[key] = jsonValue;
1365
- } catch (error) {
1366
- parsed[key] = val;
1367
- }
1368
- });
1385
+ const parsed = parseString(body, valueFormatFn);
1369
1386
 
1370
1387
  switch (contentType) {
1371
1388
  case 'multipart/form-data':