@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.
- package/docker/310.Dockerfile +4 -3
- package/docker/Dockerfile +5 -4
- package/package.json +7 -5
- package/sample/config.sample.sh +8 -0
- package/sample/notify.js +1 -1
- package/shell/api.sh +9 -9
- package/shell/otask.sh +19 -3
- package/shell/preload/sitecustomize.js +23 -12
- package/shell/preload/sitecustomize.py +17 -15
- package/shell/rmlog.sh +20 -18
- package/shell/share.sh +3 -3
- package/shell/start.sh +2 -1
- package/shell/task.sh +6 -8
- package/static/build/api/subscription.js +3 -3
- package/static/build/api/system.js +18 -2
- package/static/build/app.js +1 -1
- package/static/build/config/index.js +2 -0
- package/static/build/config/util.js +1 -1
- package/static/build/loaders/express.js +1 -1
- package/static/build/loaders/initData.js +6 -0
- package/static/build/loaders/initTask.js +4 -7
- package/static/build/loaders/sentry.js +20 -22
- package/static/build/loaders/sock.js +0 -4
- package/static/build/public.js +0 -1
- package/static/build/schedule/addCron.js +3 -3
- package/static/build/services/cron.js +4 -1
- package/static/build/services/notify.js +20 -8
- package/static/build/services/schedule.js +33 -8
- package/static/build/services/script.js +3 -1
- package/static/build/services/subscription.js +7 -4
- package/static/build/services/system.js +29 -5
- package/static/build/services/user.js +4 -1
- package/static/build/shared/interface.js +3 -0
- package/static/build/shared/pLimit.js +48 -1
- package/static/build/shared/runCron.js +6 -4
- package/static/dist/{2393.c35a1174.async.js → 2393.3d8adf53.async.js} +1 -1
- package/static/dist/2796.9a52d80e.async.js +1 -0
- package/static/dist/2899.03668225.async.js +1 -0
- package/static/dist/4039.badd6267.async.js +1 -0
- package/static/dist/{4124.b86154ed.async.js → 4124.980265f2.async.js} +1 -1
- package/static/dist/{4163.1781a549.async.js → 4163.17026fe1.async.js} +1 -1
- package/static/dist/4645.d909733e.async.js +1 -0
- package/static/dist/641.f0614d96.async.js +1 -0
- package/static/dist/6712.05e15d48.async.js +1 -0
- package/static/dist/6805.ae3d4019.async.js +1 -0
- package/static/dist/{7393.341d9643.async.js → 7393.ea2d5ba3.async.js} +1 -1
- package/static/dist/7787.b041d555.async.js +1 -0
- package/static/dist/8298.978b54ae.async.js +1 -0
- package/static/dist/9631.042017c3.async.js +1 -0
- package/static/dist/index.html +1 -1
- package/static/dist/layouts__index.2f94d49c.async.js +1 -0
- package/static/dist/layouts__index.fee54067.chunk.css +1 -0
- package/static/dist/src__pages__crontab__detail.34c9ca68.async.js +1 -0
- package/static/dist/src__pages__crontab__index.7d67660b.async.js +1 -0
- package/static/dist/src__pages__crontab__modal.ac728c12.async.js +1 -0
- package/static/dist/src__pages__crontab__viewCreateModal.1fe0e251.async.js +1 -0
- package/static/dist/src__pages__crontab__viewManageModal.c6dcfcf8.async.js +1 -0
- package/static/dist/src__pages__dependence__index.f30d6cf9.async.js +1 -0
- package/static/dist/src__pages__dependence__logModal.4826a923.async.js +1 -0
- package/static/dist/src__pages__error__index.e5c6d102.async.js +1 -0
- package/static/dist/src__pages__script__editModal.be12c9e5.async.js +1 -0
- package/static/dist/src__pages__script__index.6afda14d.async.js +1 -0
- package/static/dist/src__pages__setting__about.d7cea886.async.js +1 -0
- package/static/dist/src__pages__setting__checkUpdate.0dd2f8d5.async.js +1 -0
- package/static/dist/src__pages__setting__index.d9ba61cd.async.js +1 -0
- package/static/dist/src__pages__setting__loginLog.2f5ce1e4.async.js +1 -0
- package/static/dist/src__pages__setting__progress.57907231.async.js +1 -0
- package/static/dist/{src__pages__setting__security.b5ead1c3.async.js → src__pages__setting__security.cbf8e0b7.async.js} +1 -1
- package/static/dist/src__pages__setting__systemLog.1b30b79c.async.js +1 -0
- package/static/dist/src__pages__subscription__logModal.5bf23b06.async.js +1 -0
- package/static/dist/umi.3f48f15a.js +1 -0
- package/version.yaml +10 -6
- package/static/dist/4378.59be202f.async.js +0 -1
- package/static/dist/5207.4d5f0a6d.async.js +0 -1
- package/static/dist/7708.27674f3a.async.js +0 -1
- package/static/dist/7787.2fcf966f.async.js +0 -1
- package/static/dist/8297.0c80e09a.async.js +0 -1
- package/static/dist/8722.408e3112.async.js +0 -1
- package/static/dist/9525.b2007159.async.js +0 -1
- package/static/dist/layouts__index.308c5e5e.chunk.css +0 -1
- package/static/dist/layouts__index.a51b2768.async.js +0 -1
- package/static/dist/src__pages__crontab__detail.f691fe2e.async.js +0 -1
- package/static/dist/src__pages__crontab__index.06bb5925.async.js +0 -1
- package/static/dist/src__pages__crontab__modal.2fc5acc5.async.js +0 -1
- package/static/dist/src__pages__crontab__viewCreateModal.a29322e7.async.js +0 -1
- package/static/dist/src__pages__crontab__viewManageModal.c026d403.async.js +0 -1
- package/static/dist/src__pages__dependence__index.52fca7ba.async.js +0 -1
- package/static/dist/src__pages__dependence__logModal.39bc29eb.async.js +0 -1
- package/static/dist/src__pages__error__index.8ca01b97.async.js +0 -1
- package/static/dist/src__pages__script__editModal.3a322b87.async.js +0 -1
- package/static/dist/src__pages__script__index.8c311439.async.js +0 -1
- package/static/dist/src__pages__setting__about.40dce429.async.js +0 -1
- package/static/dist/src__pages__setting__checkUpdate.43e62d05.async.js +0 -1
- package/static/dist/src__pages__setting__index.d655075d.async.js +0 -1
- package/static/dist/src__pages__setting__loginLog.fe7238b5.async.js +0 -1
- package/static/dist/src__pages__setting__progress.7d65aebf.async.js +0 -1
- package/static/dist/src__pages__setting__systemLog.751cc94d.async.js +0 -1
- package/static/dist/src__pages__subscription__logModal.fce8a9b4.async.js +0 -1
- package/static/dist/umi.5e777fc4.js +0 -1
package/docker/310.Dockerfile
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
FROM node:20-slim
|
|
1
|
+
FROM node:20-slim AS nodebuilder
|
|
2
2
|
|
|
3
|
-
FROM python:3.10-slim-bullseye
|
|
3
|
+
FROM python:3.10-slim-bullseye AS builder
|
|
4
4
|
COPY package.json .npmrc pnpm-lock.yaml /tmp/build/
|
|
5
5
|
COPY --from=nodebuilder /usr/local/bin/node /usr/local/bin/
|
|
6
6
|
COPY --from=nodebuilder /usr/local/lib/node_modules/. /usr/local/lib/node_modules/
|
|
@@ -59,7 +59,8 @@ RUN set -x && \
|
|
|
59
59
|
rm -rf /root/.local/share/pnpm/store && \
|
|
60
60
|
rm -rf /root/.cache && \
|
|
61
61
|
rm -rf /root/.npm && \
|
|
62
|
-
ulimit -c 0
|
|
62
|
+
ulimit -c 0 && \
|
|
63
|
+
pip3 install requests
|
|
63
64
|
|
|
64
65
|
ARG SOURCE_COMMIT
|
|
65
66
|
RUN git clone --depth=1 -b ${QL_BRANCH} ${QL_URL} ${QL_DIR} && \
|
package/docker/Dockerfile
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
FROM node:20-slim
|
|
1
|
+
FROM node:20-slim AS nodebuilder
|
|
2
2
|
|
|
3
|
-
FROM python:3.11-slim-bullseye
|
|
3
|
+
FROM python:3.11-slim-bullseye AS builder
|
|
4
4
|
COPY package.json .npmrc pnpm-lock.yaml /tmp/build/
|
|
5
5
|
COPY --from=nodebuilder /usr/local/bin/node /usr/local/bin/
|
|
6
6
|
COPY --from=nodebuilder /usr/local/lib/node_modules/. /usr/local/lib/node_modules/
|
|
@@ -20,7 +20,7 @@ ARG QL_URL=https://github.com/${QL_MAINTAINER}/qinglong.git
|
|
|
20
20
|
ARG QL_BRANCH=develop
|
|
21
21
|
|
|
22
22
|
ENV PNPM_HOME=/root/.local/share/pnpm \
|
|
23
|
-
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/.local/share/pnpm:/root/.local/share/pnpm/global/5/node_modules
|
|
23
|
+
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/.local/share/pnpm:/root/.local/share/pnpm/global/5/node_modules \
|
|
24
24
|
NODE_PATH=/usr/local/bin:/usr/local/pnpm-global/5/node_modules:/usr/local/lib/node_modules:/root/.local/share/pnpm/global/5/node_modules \
|
|
25
25
|
LANG=C.UTF-8 \
|
|
26
26
|
SHELL=/bin/bash \
|
|
@@ -60,7 +60,8 @@ RUN set -x && \
|
|
|
60
60
|
rm -rf /root/.local/share/pnpm/store && \
|
|
61
61
|
rm -rf /root/.cache && \
|
|
62
62
|
rm -rf /root/.npm && \
|
|
63
|
-
ulimit -c 0
|
|
63
|
+
ulimit -c 0 && \
|
|
64
|
+
pip3 install requests
|
|
64
65
|
|
|
65
66
|
ARG SOURCE_COMMIT
|
|
66
67
|
RUN git clone --depth=1 -b ${QL_BRANCH} ${QL_URL} ${QL_DIR} && \
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@whyour/qinglong",
|
|
3
|
-
"version": "2.17.
|
|
3
|
+
"version": "2.17.10-rc.2",
|
|
4
4
|
"description": "Timed task management platform supporting Python3, JavaScript, Shell, Typescript",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -13,11 +13,11 @@
|
|
|
13
13
|
},
|
|
14
14
|
"scripts": {
|
|
15
15
|
"start": "concurrently -n w: npm:start:*",
|
|
16
|
-
"start:front": "max dev",
|
|
17
|
-
"start:back": "nodemon",
|
|
18
16
|
"start:update": "ts-node -P tsconfig.back.json ./back/update.ts",
|
|
19
17
|
"start:public": "ts-node -P tsconfig.back.json ./back/public.ts",
|
|
20
18
|
"start:rpc": "ts-node -P tsconfig.back.json ./back/schedule/index.ts",
|
|
19
|
+
"start:back": "nodemon",
|
|
20
|
+
"start:front": "max dev",
|
|
21
21
|
"build:front": "max build",
|
|
22
22
|
"build:back": "tsc -p tsconfig.back.json",
|
|
23
23
|
"panel": "npm run build:back && node static/build/app.js",
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
"dependencies": {
|
|
76
76
|
"@grpc/grpc-js": "^1.8.13",
|
|
77
77
|
"@otplib/preset-default": "^12.0.1",
|
|
78
|
-
"@sentry/node": "^
|
|
78
|
+
"@sentry/node": "^8.26.0",
|
|
79
79
|
"body-parser": "^1.19.2",
|
|
80
80
|
"celebrate": "^15.0.1",
|
|
81
81
|
"chokidar": "^3.5.3",
|
|
@@ -119,11 +119,13 @@
|
|
|
119
119
|
"ip2region": "2.3.0"
|
|
120
120
|
},
|
|
121
121
|
"devDependencies": {
|
|
122
|
+
"moment": "2.30.1",
|
|
122
123
|
"@ant-design/icons": "^4.7.0",
|
|
123
124
|
"@ant-design/pro-layout": "6.38.22",
|
|
124
125
|
"@monaco-editor/react": "4.2.1",
|
|
125
126
|
"@react-hook/resize-observer": "^1.2.6",
|
|
126
|
-
"
|
|
127
|
+
"react-router-dom": "6.26.1",
|
|
128
|
+
"@sentry/react": "^8.26.0",
|
|
127
129
|
"@types/body-parser": "^1.19.2",
|
|
128
130
|
"@types/cors": "^2.8.12",
|
|
129
131
|
"@types/cross-spawn": "^6.0.2",
|
package/sample/config.sample.sh
CHANGED
|
@@ -175,8 +175,16 @@ export CHRONOCAT_QQ=""
|
|
|
175
175
|
export CHRONOCAT_TOKEN=""
|
|
176
176
|
|
|
177
177
|
## 16. SMTP
|
|
178
|
+
## JavaScript 参数
|
|
178
179
|
## 邮箱服务名称,比如126、163、Gmail、QQ等,支持列表 https://github.com/nodemailer/nodemailer/blob/master/lib/well-known/services.json
|
|
179
180
|
export SMTP_SERVICE=""
|
|
181
|
+
|
|
182
|
+
## Python 参数
|
|
183
|
+
## SMTP 发送邮件服务器,形如 smtp.exmail.qq.com:465
|
|
184
|
+
export SMTP_SERVER=""
|
|
185
|
+
## SMTP 发送邮件服务器是否使用 SSL,填写 true 或 false
|
|
186
|
+
export SMTP_SSL=""
|
|
187
|
+
|
|
180
188
|
## smtp_email 填写 SMTP 收发件邮箱,通知将会由自己发给自己
|
|
181
189
|
export SMTP_EMAIL=""
|
|
182
190
|
## smtp_password 填写 SMTP 登录密码,也可能为特殊口令,视具体邮件服务商说明而定
|
package/sample/notify.js
CHANGED
|
@@ -817,7 +817,7 @@ function wePlusBotNotify(text, desp) {
|
|
|
817
817
|
const { WE_PLUS_BOT_TOKEN, WE_PLUS_BOT_RECEIVER, WE_PLUS_BOT_VERSION } =
|
|
818
818
|
push_config;
|
|
819
819
|
if (WE_PLUS_BOT_TOKEN) {
|
|
820
|
-
|
|
820
|
+
let template = 'txt';
|
|
821
821
|
if (desp.length > 800) {
|
|
822
822
|
desp = desp.replace(/[\n\r]/g, '<br>');
|
|
823
823
|
template = 'html';
|
package/shell/api.sh
CHANGED
|
@@ -6,12 +6,12 @@ create_token() {
|
|
|
6
6
|
if [[ -f $token_file ]]; then
|
|
7
7
|
token_command="node ${token_file}"
|
|
8
8
|
fi
|
|
9
|
-
|
|
9
|
+
__ql_token__=$(eval "$token_command")
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
get_token() {
|
|
13
13
|
if [[ -f $file_auth_token ]]; then
|
|
14
|
-
|
|
14
|
+
__ql_token__=$(cat $file_auth_token | jq -r .value)
|
|
15
15
|
local expiration=$(cat $file_auth_token | jq -r .expiration)
|
|
16
16
|
local currentTimeStamp=$(date +%s)
|
|
17
17
|
if [[ $currentTimeStamp -ge $expiration ]]; then
|
|
@@ -43,7 +43,7 @@ add_cron_api() {
|
|
|
43
43
|
local api=$(
|
|
44
44
|
curl -s --noproxy "*" "http://0.0.0.0:5600/open/crons?t=$currentTimeStamp" \
|
|
45
45
|
-H "Accept: application/json" \
|
|
46
|
-
-H "Authorization: Bearer $
|
|
46
|
+
-H "Authorization: Bearer ${__ql_token__}" \
|
|
47
47
|
-H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36" \
|
|
48
48
|
-H "Content-Type: application/json;charset=UTF-8" \
|
|
49
49
|
-H "Origin: http://0.0.0.0:5700" \
|
|
@@ -79,7 +79,7 @@ update_cron_api() {
|
|
|
79
79
|
curl -s --noproxy "*" "http://0.0.0.0:5600/open/crons?t=$currentTimeStamp" \
|
|
80
80
|
-X 'PUT' \
|
|
81
81
|
-H "Accept: application/json" \
|
|
82
|
-
-H "Authorization: Bearer $
|
|
82
|
+
-H "Authorization: Bearer ${__ql_token__}" \
|
|
83
83
|
-H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36" \
|
|
84
84
|
-H "Content-Type: application/json;charset=UTF-8" \
|
|
85
85
|
-H "Origin: http://0.0.0.0:5700" \
|
|
@@ -111,7 +111,7 @@ update_cron_command_api() {
|
|
|
111
111
|
curl -s --noproxy "*" "http://0.0.0.0:5600/open/crons?t=$currentTimeStamp" \
|
|
112
112
|
-X 'PUT' \
|
|
113
113
|
-H "Accept: application/json" \
|
|
114
|
-
-H "Authorization: Bearer $
|
|
114
|
+
-H "Authorization: Bearer ${__ql_token__}" \
|
|
115
115
|
-H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36" \
|
|
116
116
|
-H "Content-Type: application/json;charset=UTF-8" \
|
|
117
117
|
-H "Origin: http://0.0.0.0:5700" \
|
|
@@ -136,7 +136,7 @@ del_cron_api() {
|
|
|
136
136
|
curl -s --noproxy "*" "http://0.0.0.0:5600/open/crons?t=$currentTimeStamp" \
|
|
137
137
|
-X 'DELETE' \
|
|
138
138
|
-H "Accept: application/json" \
|
|
139
|
-
-H "Authorization: Bearer $
|
|
139
|
+
-H "Authorization: Bearer ${__ql_token__}" \
|
|
140
140
|
-H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36" \
|
|
141
141
|
-H "Content-Type: application/json;charset=UTF-8" \
|
|
142
142
|
-H "Origin: http://0.0.0.0:5700" \
|
|
@@ -166,7 +166,7 @@ update_cron() {
|
|
|
166
166
|
curl -s --noproxy "*" "http://0.0.0.0:5600/open/crons/status?t=$currentTimeStamp" \
|
|
167
167
|
-X 'PUT' \
|
|
168
168
|
-H "Accept: application/json" \
|
|
169
|
-
-H "Authorization: Bearer $
|
|
169
|
+
-H "Authorization: Bearer ${__ql_token__}" \
|
|
170
170
|
-H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36" \
|
|
171
171
|
-H "Content-Type: application/json;charset=UTF-8" \
|
|
172
172
|
-H "Origin: http://0.0.0.0:5700" \
|
|
@@ -190,7 +190,7 @@ notify_api() {
|
|
|
190
190
|
curl -s --noproxy "*" "http://0.0.0.0:5600/open/system/notify?t=$currentTimeStamp" \
|
|
191
191
|
-X 'PUT' \
|
|
192
192
|
-H "Accept: application/json" \
|
|
193
|
-
-H "Authorization: Bearer $
|
|
193
|
+
-H "Authorization: Bearer ${__ql_token__}" \
|
|
194
194
|
-H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36" \
|
|
195
195
|
-H "Content-Type: application/json;charset=UTF-8" \
|
|
196
196
|
-H "Origin: http://0.0.0.0:5700" \
|
|
@@ -214,7 +214,7 @@ find_cron_api() {
|
|
|
214
214
|
local api=$(
|
|
215
215
|
curl -s --noproxy "*" "http://0.0.0.0:5600/open/crons/detail?$params&t=$currentTimeStamp" \
|
|
216
216
|
-H "Accept: application/json" \
|
|
217
|
-
-H "Authorization: Bearer $
|
|
217
|
+
-H "Authorization: Bearer ${__ql_token__}" \
|
|
218
218
|
-H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36" \
|
|
219
219
|
-H "Content-Type: application/json;charset=UTF-8" \
|
|
220
220
|
-H "Origin: http://0.0.0.0:5700" \
|
package/shell/otask.sh
CHANGED
|
@@ -210,14 +210,19 @@ run_else() {
|
|
|
210
210
|
|
|
211
211
|
check_file() {
|
|
212
212
|
isJsOrPythonFile="false"
|
|
213
|
-
if [[ $1 == *.js ]] || [[ $1 == *.py ]] || [[ $1 == *.pyc ]] || [[ $1 == *.ts ]]; then
|
|
213
|
+
if [[ $1 == *.js ]] || [[ $1 == *.mjs ]] || [[ $1 == *.py ]] || [[ $1 == *.pyc ]] || [[ $1 == *.ts ]]; then
|
|
214
214
|
isJsOrPythonFile="true"
|
|
215
215
|
fi
|
|
216
216
|
if [[ -f $file_env ]]; then
|
|
217
217
|
get_env_array
|
|
218
218
|
if [[ $isJsOrPythonFile == 'true' ]]; then
|
|
219
|
-
|
|
220
|
-
|
|
219
|
+
PREV_NODE_OPTIONS="${NODE_OPTIONS:=}"
|
|
220
|
+
PREV_PYTHONPATH="${PYTHONPATH:=}"
|
|
221
|
+
if [[ $1 == *.js ]] || [[ $1 == *.ts ]] || [[ $1 == *.mjs ]]; then
|
|
222
|
+
export NODE_OPTIONS="${NODE_OPTIONS} -r ${file_preload_js}"
|
|
223
|
+
else
|
|
224
|
+
export PYTHONPATH="${PYTHONPATH}:${dir_preload}:${dir_config}"
|
|
225
|
+
fi
|
|
221
226
|
else
|
|
222
227
|
. $file_env
|
|
223
228
|
fi
|
|
@@ -264,7 +269,18 @@ check_file "${task_shell_params[@]}"
|
|
|
264
269
|
if [[ $isJsOrPythonFile == 'false' ]]; then
|
|
265
270
|
run_task_before "${task_shell_params[@]}"
|
|
266
271
|
fi
|
|
272
|
+
if set -o | grep -q 'nounset.*on'; then
|
|
273
|
+
set_u_on="true"
|
|
274
|
+
set +u
|
|
275
|
+
fi
|
|
267
276
|
main "${task_shell_params[@]}"
|
|
277
|
+
if [[ "$set_u_on" == 'true' ]]; then
|
|
278
|
+
set -u
|
|
279
|
+
fi
|
|
280
|
+
if [[ $isJsOrPythonFile == 'true' ]]; then
|
|
281
|
+
export NODE_OPTIONS="${PREV_NODE_OPTIONS}"
|
|
282
|
+
export PYTHONPATH="${PREV_PYTHONPATH}"
|
|
283
|
+
fi
|
|
268
284
|
run_task_after "${task_shell_params[@]}"
|
|
269
285
|
clear_env
|
|
270
286
|
handle_task_end "${task_shell_params[@]}"
|
|
@@ -1,13 +1,5 @@
|
|
|
1
1
|
const { execSync } = require('child_process');
|
|
2
|
-
const { sendNotify } = require('./notify.js');
|
|
3
2
|
require(`./env.js`);
|
|
4
|
-
|
|
5
|
-
function initGlobal() {
|
|
6
|
-
global.QLAPI = {
|
|
7
|
-
notify: sendNotify,
|
|
8
|
-
};
|
|
9
|
-
}
|
|
10
|
-
|
|
11
3
|
function expandRange(rangeStr, max) {
|
|
12
4
|
const tempRangeStr = rangeStr
|
|
13
5
|
.trim()
|
|
@@ -18,7 +10,11 @@ function expandRange(rangeStr, max) {
|
|
|
18
10
|
const rangeMatch = part.match(/^(\d+)([-~_])(\d+)$/);
|
|
19
11
|
if (rangeMatch) {
|
|
20
12
|
const [, start, , end] = rangeMatch.map(Number);
|
|
21
|
-
|
|
13
|
+
const step = start < end ? 1 : -1;
|
|
14
|
+
return Array.from(
|
|
15
|
+
{ length: Math.abs(end - start) + 1 },
|
|
16
|
+
(_, i) => start + i * step,
|
|
17
|
+
);
|
|
22
18
|
}
|
|
23
19
|
return Number(part);
|
|
24
20
|
});
|
|
@@ -41,10 +37,14 @@ function run() {
|
|
|
41
37
|
const fileName = process.argv[1].replace(`${dir_scripts}/`, '');
|
|
42
38
|
let command = `bash -c "source ${file_task_before} ${fileName}`;
|
|
43
39
|
if (task_before) {
|
|
44
|
-
|
|
40
|
+
const escapeTaskBefore = task_before
|
|
41
|
+
.replace(/"/g, '\\"')
|
|
42
|
+
.replace(/\$/g, '\\$');
|
|
43
|
+
command = `${command} && eval '${escapeTaskBefore}'`;
|
|
44
|
+
console.log('执行前置命令\n');
|
|
45
45
|
}
|
|
46
46
|
const res = execSync(
|
|
47
|
-
`${command} && echo
|
|
47
|
+
`${command} && echo -e '${splitStr}' && NODE_OPTIONS= node -p 'JSON.stringify(process.env)'"`,
|
|
48
48
|
{
|
|
49
49
|
encoding: 'utf-8',
|
|
50
50
|
},
|
|
@@ -55,6 +55,9 @@ function run() {
|
|
|
55
55
|
process.env[key] = newEnvObject[key];
|
|
56
56
|
}
|
|
57
57
|
console.log(output);
|
|
58
|
+
if (task_before) {
|
|
59
|
+
console.log('执行前置命令结束\n');
|
|
60
|
+
}
|
|
58
61
|
} catch (error) {
|
|
59
62
|
if (!error.message.includes('spawnSync /bin/sh E2BIG')) {
|
|
60
63
|
console.log(`run task before error: `, error);
|
|
@@ -71,8 +74,16 @@ function run() {
|
|
|
71
74
|
}
|
|
72
75
|
|
|
73
76
|
try {
|
|
74
|
-
|
|
77
|
+
if (!process.argv[1]) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
75
81
|
run();
|
|
82
|
+
|
|
83
|
+
const { sendNotify } = require('./notify.js');
|
|
84
|
+
global.QLAPI = {
|
|
85
|
+
notify: sendNotify,
|
|
86
|
+
};
|
|
76
87
|
} catch (error) {
|
|
77
88
|
console.log(`run builtin code error: `, error, '\n');
|
|
78
89
|
}
|
|
@@ -5,17 +5,6 @@ import json
|
|
|
5
5
|
import builtins
|
|
6
6
|
import sys
|
|
7
7
|
import env
|
|
8
|
-
from notify import send
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class BaseApi:
|
|
12
|
-
def notify(self, *args, **kwargs):
|
|
13
|
-
return send(*args, **kwargs)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
def init_global():
|
|
17
|
-
QLAPI = BaseApi()
|
|
18
|
-
builtins.QLAPI = QLAPI
|
|
19
8
|
|
|
20
9
|
|
|
21
10
|
def try_parse_int(value):
|
|
@@ -37,7 +26,8 @@ def expand_range(range_str, max_value):
|
|
|
37
26
|
range_match = re.match(r"^(\d+)([-~_])(\d+)$", part)
|
|
38
27
|
if range_match:
|
|
39
28
|
start, _, end = map(try_parse_int, range_match.groups())
|
|
40
|
-
|
|
29
|
+
step = 1 if start < end else -1
|
|
30
|
+
result.extend(range(start, end + step, step))
|
|
41
31
|
else:
|
|
42
32
|
result.append(int(part))
|
|
43
33
|
|
|
@@ -54,10 +44,12 @@ def run():
|
|
|
54
44
|
task_before = os.getenv("task_before")
|
|
55
45
|
|
|
56
46
|
if task_before:
|
|
57
|
-
|
|
47
|
+
escape_task_before = task_before.replace('"', '\\"').replace("$", "\\$")
|
|
48
|
+
command += f" && eval '{escape_task_before}'"
|
|
49
|
+
print("执行前置命令\n")
|
|
58
50
|
|
|
59
51
|
python_command = "PYTHONPATH= python3 -c 'import os, json; print(json.dumps(dict(os.environ)))'"
|
|
60
|
-
command += f
|
|
52
|
+
command += f" && echo -e '{split_str}' && {python_command}\""
|
|
61
53
|
|
|
62
54
|
res = subprocess.check_output(command, shell=True, encoding="utf-8")
|
|
63
55
|
output, env_str = res.split(split_str)
|
|
@@ -68,6 +60,8 @@ def run():
|
|
|
68
60
|
os.environ[key] = value
|
|
69
61
|
|
|
70
62
|
print(output)
|
|
63
|
+
if task_before:
|
|
64
|
+
print("执行前置命令结束")
|
|
71
65
|
|
|
72
66
|
except subprocess.CalledProcessError as error:
|
|
73
67
|
print(f"run task before error: {error}")
|
|
@@ -90,7 +84,15 @@ def run():
|
|
|
90
84
|
|
|
91
85
|
|
|
92
86
|
try:
|
|
93
|
-
init_global()
|
|
94
87
|
run()
|
|
88
|
+
|
|
89
|
+
from notify import send
|
|
90
|
+
|
|
91
|
+
class BaseApi:
|
|
92
|
+
def notify(self, *args, **kwargs):
|
|
93
|
+
return send(*args, **kwargs)
|
|
94
|
+
|
|
95
|
+
QLAPI = BaseApi()
|
|
96
|
+
builtins.QLAPI = QLAPI
|
|
95
97
|
except Exception as error:
|
|
96
98
|
print(f"run builtin code error: {error}\n")
|
package/shell/rmlog.sh
CHANGED
|
@@ -2,34 +2,37 @@
|
|
|
2
2
|
|
|
3
3
|
days=$1
|
|
4
4
|
|
|
5
|
-
## 删除运行脚本的旧日志
|
|
6
5
|
remove_js_log() {
|
|
7
|
-
local log_full_path_list=$(find $dir_log
|
|
6
|
+
local log_full_path_list=$(find $dir_log -name "*.log")
|
|
8
7
|
local diff_time
|
|
9
8
|
for log in $log_full_path_list; do
|
|
10
|
-
local log_date=$(echo $log | awk -F "/" '{print $NF}' | cut -c1-10)
|
|
11
|
-
if [[ $
|
|
9
|
+
local log_date=$(echo $log | awk -F "/" '{print $NF}' | cut -c1-10)
|
|
10
|
+
if ! [[ $log_date =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]; then
|
|
12
11
|
if [[ $is_macos -eq 1 ]]; then
|
|
13
|
-
|
|
12
|
+
log_date=$(stat -f %Sm -t "%Y-%m-%d" "$log")
|
|
14
13
|
else
|
|
15
|
-
|
|
14
|
+
log_date=$(stat -c %y "$log" | cut -d ' ' -f 1)
|
|
16
15
|
fi
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
16
|
+
fi
|
|
17
|
+
if [[ $is_macos -eq 1 ]]; then
|
|
18
|
+
diff_time=$(($(date +%s) - $(date -j -f "%Y-%m-%d" "$log_date" +%s)))
|
|
19
|
+
else
|
|
20
|
+
diff_time=$(($(date +%s) - $(date +%s -d "$log_date")))
|
|
21
|
+
fi
|
|
22
|
+
if [[ $diff_time -gt $((${days} * 86400)) ]]; then
|
|
23
|
+
local log_path=$(echo "$log" | sed "s,${dir_log}/,,g")
|
|
24
|
+
local result=$(find_cron_api "log_path=$log_path")
|
|
25
|
+
echo -e "查询文件 $log_path"
|
|
26
|
+
if [[ -z $result ]]; then
|
|
27
|
+
echo -e "删除中~"
|
|
28
|
+
rm -vf $log
|
|
29
|
+
else
|
|
30
|
+
echo -e "正在被 $result 使用,跳过~"
|
|
27
31
|
fi
|
|
28
32
|
fi
|
|
29
33
|
done
|
|
30
34
|
}
|
|
31
35
|
|
|
32
|
-
## 删除空文件夹
|
|
33
36
|
remove_empty_dir() {
|
|
34
37
|
cd $dir_log
|
|
35
38
|
for dir in $(ls); do
|
|
@@ -39,7 +42,6 @@ remove_empty_dir() {
|
|
|
39
42
|
done
|
|
40
43
|
}
|
|
41
44
|
|
|
42
|
-
## 运行
|
|
43
45
|
if [[ ${days} ]]; then
|
|
44
46
|
echo -e "查找旧日志文件中...\n"
|
|
45
47
|
remove_js_log
|
package/shell/share.sh
CHANGED
|
@@ -5,7 +5,7 @@ export dir_root=$QL_DIR
|
|
|
5
5
|
export dir_tmp=$dir_root/.tmp
|
|
6
6
|
export dir_data=$dir_root/data
|
|
7
7
|
|
|
8
|
-
if [[ $QL_DATA_DIR ]]; then
|
|
8
|
+
if [[ ${QL_DATA_DIR:=} ]]; then
|
|
9
9
|
export dir_data="${QL_DATA_DIR%/}"
|
|
10
10
|
fi
|
|
11
11
|
|
|
@@ -84,7 +84,7 @@ import_config() {
|
|
|
84
84
|
command_timeout_time=${CommandTimeoutTime:-""}
|
|
85
85
|
file_extensions=${RepoFileExtensions:-"js py"}
|
|
86
86
|
proxy_url=${ProxyUrl:-""}
|
|
87
|
-
current_branch=${QL_BRANCH}
|
|
87
|
+
current_branch=${QL_BRANCH:-""}
|
|
88
88
|
|
|
89
89
|
if [[ -n "${DefaultCronRule}" ]]; then
|
|
90
90
|
default_cron="${DefaultCronRule}"
|
|
@@ -461,7 +461,7 @@ run_task_before() {
|
|
|
461
461
|
run_task_after() {
|
|
462
462
|
. $file_task_after "$@"
|
|
463
463
|
|
|
464
|
-
if [[ $task_after ]]; then
|
|
464
|
+
if [[ ${task_after:=} ]]; then
|
|
465
465
|
echo -e "\n执行后置命令\n"
|
|
466
466
|
eval "$task_after" "$@"
|
|
467
467
|
echo -e "\n执行后置命令结束"
|
package/shell/start.sh
CHANGED
|
@@ -67,10 +67,11 @@ cd ${QL_DIR}
|
|
|
67
67
|
cp -f .env.example .env
|
|
68
68
|
chmod 777 ${QL_DIR}/shell/*.sh
|
|
69
69
|
|
|
70
|
-
. ${QL_DIR}/shell/env.sh
|
|
71
70
|
. ${QL_DIR}/shell/share.sh
|
|
71
|
+
. ${QL_DIR}/shell/env.sh
|
|
72
72
|
|
|
73
73
|
echo -e "======================1. 检测配置文件========================\n"
|
|
74
|
+
import_config "$@"
|
|
74
75
|
make_dir /etc/nginx/conf.d
|
|
75
76
|
make_dir /run/nginx
|
|
76
77
|
init_nginx
|
package/shell/task.sh
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
|
|
3
|
-
## 导入通用变量与函数
|
|
4
3
|
dir_shell=$QL_DIR/shell
|
|
5
4
|
. $dir_shell/share.sh
|
|
6
5
|
. $dir_shell/api.sh
|
|
@@ -11,7 +10,6 @@ single_hanle() {
|
|
|
11
10
|
exit 1
|
|
12
11
|
}
|
|
13
12
|
|
|
14
|
-
## 选择python3还是node
|
|
15
13
|
define_program() {
|
|
16
14
|
local file_param=$1
|
|
17
15
|
if [[ $file_param == *.js ]] || [[ $file_param == *.mjs ]]; then
|
|
@@ -34,7 +32,7 @@ handle_log_path() {
|
|
|
34
32
|
file_param="task"
|
|
35
33
|
fi
|
|
36
34
|
|
|
37
|
-
if [[ -z $ID ]]; then
|
|
35
|
+
if [[ -z ${ID:=} ]]; then
|
|
38
36
|
ID=$(cat $list_crontab_user | grep -E "$cmd_task.* $file_param" | perl -pe "s|.*ID=(.*) $cmd_task.* $file_param\.*|\1|" | head -1 | awk -F " " '{print $1}')
|
|
39
37
|
fi
|
|
40
38
|
local suffix=""
|
|
@@ -62,17 +60,17 @@ handle_log_path() {
|
|
|
62
60
|
log_dir="${log_dir_tmp%.*}${suffix}"
|
|
63
61
|
log_path="$log_dir/$log_time.log"
|
|
64
62
|
|
|
65
|
-
if [[ $real_log_path ]]; then
|
|
63
|
+
if [[ ${real_log_path:=} ]]; then
|
|
66
64
|
log_path="$real_log_path"
|
|
67
65
|
fi
|
|
68
66
|
|
|
69
67
|
cmd="2>&1 | tee -a $dir_log/$log_path"
|
|
70
68
|
make_dir "$dir_log/$log_dir"
|
|
71
|
-
if [[ "$no_tee" == "true" ]]; then
|
|
69
|
+
if [[ "${no_tee:=}" == "true" ]]; then
|
|
72
70
|
cmd=">> $dir_log/$log_path 2>&1"
|
|
73
71
|
fi
|
|
74
72
|
|
|
75
|
-
if [[ "$real_time" == "true" ]]; then
|
|
73
|
+
if [[ "${real_time:=}" == "true" ]]; then
|
|
76
74
|
cmd=""
|
|
77
75
|
fi
|
|
78
76
|
}
|
|
@@ -124,8 +122,8 @@ while getopts ":lm:" opt; do
|
|
|
124
122
|
;;
|
|
125
123
|
esac
|
|
126
124
|
done
|
|
127
|
-
[[ $show_log ]] && shift $(($OPTIND - 1))
|
|
128
|
-
if [[ $max_time ]]; then
|
|
125
|
+
[[ ${show_log:=} ]] && shift $(($OPTIND - 1))
|
|
126
|
+
if [[ ${max_time:=} ]]; then
|
|
129
127
|
shift $(($OPTIND - 1))
|
|
130
128
|
command_timeout_time="$max_time"
|
|
131
129
|
fi
|
|
@@ -15,7 +15,7 @@ exports.default = (app) => {
|
|
|
15
15
|
const logger = typedi_1.Container.get('logger');
|
|
16
16
|
try {
|
|
17
17
|
const subscriptionService = typedi_1.Container.get(subscription_1.default);
|
|
18
|
-
const data = await subscriptionService.list(req.query.searchValue);
|
|
18
|
+
const data = await subscriptionService.list(req.query.searchValue, req.query.ids);
|
|
19
19
|
return res.send({ code: 200, data });
|
|
20
20
|
}
|
|
21
21
|
catch (e) {
|
|
@@ -180,8 +180,8 @@ exports.default = (app) => {
|
|
|
180
180
|
body: celebrate_1.Joi.array().items(celebrate_1.Joi.number().required()),
|
|
181
181
|
query: celebrate_1.Joi.object({
|
|
182
182
|
force: celebrate_1.Joi.boolean().optional(),
|
|
183
|
-
t: celebrate_1.Joi.number()
|
|
184
|
-
})
|
|
183
|
+
t: celebrate_1.Joi.number(),
|
|
184
|
+
}),
|
|
185
185
|
}), async (req, res, next) => {
|
|
186
186
|
const logger = typedi_1.Container.get('logger');
|
|
187
187
|
try {
|
|
@@ -296,10 +296,26 @@ exports.default = (app) => {
|
|
|
296
296
|
return next(e);
|
|
297
297
|
}
|
|
298
298
|
});
|
|
299
|
-
route.get('/log',
|
|
299
|
+
route.get('/log', (0, celebrate_1.celebrate)({
|
|
300
|
+
query: {
|
|
301
|
+
startTime: celebrate_1.Joi.string().allow('').optional(),
|
|
302
|
+
endTime: celebrate_1.Joi.string().allow('').optional(),
|
|
303
|
+
t: celebrate_1.Joi.string().optional(),
|
|
304
|
+
},
|
|
305
|
+
}), async (req, res, next) => {
|
|
306
|
+
try {
|
|
307
|
+
const systemService = typedi_1.Container.get(system_1.default);
|
|
308
|
+
await systemService.getSystemLog(res, req.query);
|
|
309
|
+
}
|
|
310
|
+
catch (e) {
|
|
311
|
+
return next(e);
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
route.delete('/log', async (req, res, next) => {
|
|
300
315
|
try {
|
|
301
316
|
const systemService = typedi_1.Container.get(system_1.default);
|
|
302
|
-
await systemService.
|
|
317
|
+
await systemService.deleteSystemLog();
|
|
318
|
+
res.send({ code: 200 });
|
|
303
319
|
}
|
|
304
320
|
catch (e) {
|
|
305
321
|
return next(e);
|
package/static/build/app.js
CHANGED
|
@@ -3,6 +3,7 @@ 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
|
+
require("./loaders/sentry");
|
|
6
7
|
require("reflect-metadata"); // We need this in order to use @Decorators
|
|
7
8
|
const config_1 = __importDefault(require("./config"));
|
|
8
9
|
const express_1 = __importDefault(require("express"));
|
|
@@ -11,7 +12,6 @@ async function startServer() {
|
|
|
11
12
|
const app = (0, express_1.default)();
|
|
12
13
|
await require('./loaders/db').default();
|
|
13
14
|
await require('./loaders/initFile').default();
|
|
14
|
-
await require('./loaders/sentry').default({ expressApp: app });
|
|
15
15
|
await require('./loaders/app').default({ expressApp: app });
|
|
16
16
|
const server = app
|
|
17
17
|
.listen(config_1.default.port, '0.0.0.0', () => {
|
|
@@ -47,6 +47,7 @@ const extraFile = path_1.default.join(configPath, 'extra.sh');
|
|
|
47
47
|
const confBakDir = path_1.default.join(dataPath, 'config/bak/');
|
|
48
48
|
const sampleFile = path_1.default.join(samplePath, 'config.sample.sh');
|
|
49
49
|
const sqliteFile = path_1.default.join(samplePath, 'database.sqlite');
|
|
50
|
+
const systemNotifyFile = path_1.default.join(preloadPath, 'system-notify.json');
|
|
50
51
|
const authError = '错误的用户名密码,请重试';
|
|
51
52
|
const loginFaild = '请先登录!';
|
|
52
53
|
const configString = 'config sample crontab shareCode diy';
|
|
@@ -126,5 +127,6 @@ exports.default = {
|
|
|
126
127
|
sqliteFile,
|
|
127
128
|
sshdPath,
|
|
128
129
|
systemLogPath,
|
|
130
|
+
systemNotifyFile,
|
|
129
131
|
};
|
|
130
132
|
//# sourceMappingURL=index.js.map
|
|
@@ -431,7 +431,7 @@ async function parseVersion(path) {
|
|
|
431
431
|
return (0, js_yaml_1.load)(await fs.readFile(path, 'utf8'));
|
|
432
432
|
}
|
|
433
433
|
exports.parseVersion = parseVersion;
|
|
434
|
-
|
|
434
|
+
function parseContentVersion(content) {
|
|
435
435
|
return (0, js_yaml_1.load)(content);
|
|
436
436
|
}
|
|
437
437
|
exports.parseContentVersion = parseContentVersion;
|
|
@@ -135,6 +135,7 @@ exports.default = ({ app }) => {
|
|
|
135
135
|
next(err);
|
|
136
136
|
});
|
|
137
137
|
app.use((0, celebrate_1.errors)());
|
|
138
|
+
Sentry.setupExpressErrorHandler(app);
|
|
138
139
|
app.use((err, req, res, next) => {
|
|
139
140
|
if (err.name === 'UnauthorizedError') {
|
|
140
141
|
return res
|
|
@@ -158,7 +159,6 @@ exports.default = ({ app }) => {
|
|
|
158
159
|
return next(err);
|
|
159
160
|
});
|
|
160
161
|
app.use((err, req, res, next) => {
|
|
161
|
-
Sentry.captureException(err);
|
|
162
162
|
res.status(err.status || 500);
|
|
163
163
|
res.json({
|
|
164
164
|
code: err.status || 500,
|