@whyour/qinglong 0.3.2 → 0.4.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 (173) hide show
  1. package/README-en.md +47 -88
  2. package/README.md +48 -87
  3. package/package.json +5 -1
  4. package/sample/notify.js +19 -9
  5. package/sample/notify.py +89 -47
  6. package/shell/api.sh +15 -15
  7. package/shell/otask.sh +1 -1
  8. package/shell/update.sh +12 -13
  9. package/static/build/api/system.js +1 -2
  10. package/static/build/api/user.js +5 -1
  11. package/static/build/config/serverEnv.js +1 -1
  12. package/static/build/data/dependence.js +1 -1
  13. package/static/build/data/notify.js +2 -0
  14. package/static/build/data/open.js +1 -8
  15. package/static/build/loaders/express.js +1 -9
  16. package/static/build/loaders/initFile.js +24 -6
  17. package/static/build/loaders/sentry.js +7 -1
  18. package/static/build/schedule/addCron.js +2 -2
  19. package/static/build/schedule/health.js +2 -2
  20. package/static/build/services/cron.js +50 -44
  21. package/static/build/services/dependence.js +82 -79
  22. package/static/build/services/env.js +1 -1
  23. package/static/build/services/notify.js +5 -5
  24. package/static/build/services/open.js +1 -1
  25. package/static/build/services/schedule.js +42 -40
  26. package/static/build/services/subscription.js +7 -13
  27. package/static/build/services/system.js +2 -2
  28. package/static/build/shared/pLimit.js +16 -0
  29. package/static/build/shared/runCron.js +29 -0
  30. package/static/dist/{1571.a97c18af.async.js → 1571.68121491.async.js} +3 -3
  31. package/static/dist/{9371.27629d57.async.js → 1654.e06fbac5.async.js} +1 -1
  32. package/static/dist/2260.d9fbd460.async.js +1 -0
  33. package/static/dist/2536.a60b8e3c.async.js +1 -0
  34. package/static/dist/{2618.2d258f44.async.js → 2618.1484edc2.async.js} +2 -2
  35. package/static/dist/2715.80e099e1.async.js +1 -0
  36. package/static/dist/{3490.8aaeafbb.async.js → 3490.8d2d9399.async.js} +1 -1
  37. package/static/dist/3639.58c3a3f1.async.js +5 -0
  38. package/static/dist/3800.5488ae14.async.js +2 -0
  39. package/static/dist/3820.faa46a6a.async.js +1 -0
  40. package/static/dist/4124.8cba8410.async.js +1 -0
  41. package/static/dist/4163.a1d279c3.async.js +1 -0
  42. package/static/dist/4346.5ab6fdc1.async.js +1 -0
  43. package/static/dist/{4378.70f18b85.async.js → 4378.70083a42.async.js} +2 -2
  44. package/static/dist/4491.96ee9a9f.async.js +4 -0
  45. package/static/dist/4804.183d71af.async.js +27 -0
  46. package/static/dist/4925.eca85085.async.js +1 -0
  47. package/static/dist/5008.c612bbdb.async.js +11 -0
  48. package/static/dist/5035.2489750b.async.js +67 -0
  49. package/static/dist/5310.6c4eff46.async.js +1 -0
  50. package/static/dist/5484.826c5ee3.async.js +1 -0
  51. package/static/dist/5969.87aeb075.async.js +1 -0
  52. package/static/dist/6304.51c52839.async.js +1 -0
  53. package/static/dist/6433.69941426.async.js +22 -0
  54. package/static/dist/6661.5cda5ce0.async.js +1 -0
  55. package/static/dist/6805.798ec30a.async.js +1 -0
  56. package/static/dist/{412.7e4d2d42.async.js → 7382.305c10b2.async.js} +2 -2
  57. package/static/dist/{7393.b7603b10.async.js → 7393.d9ed4b3a.async.js} +1 -1
  58. package/static/dist/7567.a224d0a6.async.js +5 -0
  59. package/static/dist/{7742.eec663d7.async.js → 7742.dd8a0112.async.js} +2 -2
  60. package/static/dist/8037.386b415d.async.js +1 -0
  61. package/static/dist/8297.e6ac1ce9.async.js +1 -0
  62. package/static/dist/8432.5bbc2cdd.async.js +1 -0
  63. package/static/dist/858.d51fc4e2.async.js +1 -0
  64. package/static/dist/8612.84caf0a5.async.js +1 -0
  65. package/static/dist/{8966.d92806db.async.js → 8657.805a96f7.async.js} +2 -2
  66. package/static/dist/8844.8525fd2e.async.js +81 -0
  67. package/static/dist/9065.6684b5d0.async.js +1 -0
  68. package/static/dist/921.198cefa6.async.js +6 -0
  69. package/static/dist/{9504.06cb7ea5.async.js → 9504.6d4e29e7.async.js} +1 -1
  70. package/static/dist/9673.18a70227.async.js +3 -0
  71. package/static/dist/986.ab6a48a4.async.js +1 -0
  72. package/static/dist/index.html +1 -1
  73. package/static/dist/layouts__index.285d8505.chunk.css +1 -0
  74. package/static/dist/layouts__index.3db43e0b.async.js +1 -0
  75. package/static/dist/src__pages__404.8794c158.async.js +1 -0
  76. package/static/dist/{src__pages__config__index.b5bde963.async.js → src__pages__config__index.7fb61af5.async.js} +3 -3
  77. package/static/dist/{src__pages__crontab__index.be4295e5.async.js → src__pages__crontab__index.5cfa7d5b.async.js} +2 -2
  78. package/static/dist/src__pages__crontab__logModal.44ad577c.async.js +2 -0
  79. package/static/dist/src__pages__crontab__modal.6d17fdcf.async.js +5 -0
  80. package/static/dist/src__pages__crontab__viewCreateModal.3db14204.async.js +4 -0
  81. package/static/dist/src__pages__crontab__viewManageModal.9f899650.async.js +4 -0
  82. package/static/dist/src__pages__dependence__index.3b140a79.async.js +2 -0
  83. package/static/dist/src__pages__dependence__logModal.e49658d5.async.js +4 -0
  84. package/static/dist/src__pages__dependence__modal.94ff002a.async.js +5 -0
  85. package/static/dist/{src__pages__diff__index.200be0dc.async.js → src__pages__diff__index.240e4991.async.js} +3 -3
  86. package/static/dist/{src__pages__env__editNameModal.9898b16a.async.js → src__pages__env__editNameModal.047bb3ba.async.js} +2 -2
  87. package/static/dist/src__pages__env__index.48602d18.async.js +2 -0
  88. package/static/dist/src__pages__env__modal.8b48ffa4.async.js +5 -0
  89. package/static/dist/src__pages__error__index.c0477141.async.js +4 -0
  90. package/static/dist/{src__pages__initialization__index.bcf87634.chunk.css → src__pages__initialization__index.66819338.chunk.css} +1 -1
  91. package/static/dist/src__pages__initialization__index.978a7f09.async.js +21 -0
  92. package/static/dist/src__pages__log__index.ae245070.async.js +1 -0
  93. package/static/dist/src__pages__login__index.8eb4df8e.async.js +2 -0
  94. package/static/dist/{src__pages__script__editModal.9a8934a1.async.js → src__pages__script__editModal.02b12902.async.js} +2 -2
  95. package/static/dist/{src__pages__script__editNameModal.42003a2f.async.js → src__pages__script__editNameModal.2773cb7b.async.js} +2 -2
  96. package/static/dist/{src__pages__script__index.670d9577.async.js → src__pages__script__index.679510cd.async.js} +3 -3
  97. package/static/dist/{src__pages__script__renameModal.3b9285b0.async.js → src__pages__script__renameModal.ea3b6689.async.js} +2 -2
  98. package/static/dist/{src__pages__script__saveModal.475c369d.async.js → src__pages__script__saveModal.312a0beb.async.js} +2 -2
  99. package/static/dist/{src__pages__script__setting.d41d33ae.async.js → src__pages__script__setting.11abc6ae.async.js} +2 -2
  100. package/static/dist/src__pages__setting__about.1460b7fa.async.js +1 -0
  101. package/static/dist/{src__pages__setting__appModal.4edca962.async.js → src__pages__setting__appModal.74267529.async.js} +2 -2
  102. package/static/dist/src__pages__setting__checkUpdate.ce2e30bb.async.js +4 -0
  103. package/static/dist/src__pages__setting__index.9fcd6dc2.async.js +2 -0
  104. package/static/dist/src__pages__setting__loginLog.0708083b.async.js +18 -0
  105. package/static/dist/src__pages__setting__notification.15a286d0.async.js +21 -0
  106. package/static/dist/src__pages__setting__other.00a69cf4.async.js +1 -0
  107. package/static/dist/src__pages__setting__security.62b6b562.async.js +4 -0
  108. package/static/dist/src__pages__subscription__index.708b6c8f.async.js +2 -0
  109. package/static/dist/src__pages__subscription__logModal.3a1a8e58.async.js +2 -0
  110. package/static/dist/src__pages__subscription__modal.c034f25a.async.js +4 -0
  111. package/static/dist/umi.cb44a99a.js +11 -0
  112. package/version.yaml +10 -5
  113. package/static/dist/1655.37556417.async.js +0 -4
  114. package/static/dist/1766.e0c12c07.async.js +0 -27
  115. package/static/dist/2260.04ae2823.async.js +0 -1
  116. package/static/dist/2715.30714799.async.js +0 -1
  117. package/static/dist/3639.62e1ddf6.async.js +0 -5
  118. package/static/dist/3820.ad340d47.async.js +0 -1
  119. package/static/dist/4011.3a02258a.async.js +0 -22
  120. package/static/dist/4124.6a5a1531.async.js +0 -1
  121. package/static/dist/4163.5180a456.async.js +0 -1
  122. package/static/dist/4180.e830b6e6.async.js +0 -2
  123. package/static/dist/4925.4425d963.async.js +0 -1
  124. package/static/dist/5008.8fcc2d24.async.js +0 -11
  125. package/static/dist/5310.9c3e0c09.async.js +0 -1
  126. package/static/dist/5319.dd84246e.async.js +0 -1
  127. package/static/dist/5484.ac83d6b4.async.js +0 -1
  128. package/static/dist/5544.6baaab99.async.js +0 -81
  129. package/static/dist/6304.613145ef.async.js +0 -1
  130. package/static/dist/6661.f5843bf4.async.js +0 -1
  131. package/static/dist/6794.4c503d6d.async.js +0 -5
  132. package/static/dist/6805.f5be6007.async.js +0 -1
  133. package/static/dist/7461.ed40fa5f.async.js +0 -1
  134. package/static/dist/7466.15597d4f.async.js +0 -1
  135. package/static/dist/7938.4e3377e7.async.js +0 -67
  136. package/static/dist/8037.61d0095e.async.js +0 -1
  137. package/static/dist/8297.3d6c376d.async.js +0 -1
  138. package/static/dist/8352.e0fbb494.async.js +0 -1
  139. package/static/dist/8432.30267db1.async.js +0 -1
  140. package/static/dist/8447.d0f63993.async.js +0 -1
  141. package/static/dist/9065.0806f3e5.async.js +0 -1
  142. package/static/dist/9280.aacaa172.async.js +0 -6
  143. package/static/dist/9673.a1545ea3.async.js +0 -3
  144. package/static/dist/986.c108246f.async.js +0 -1
  145. package/static/dist/layouts__index.3de47467.chunk.css +0 -1
  146. package/static/dist/layouts__index.a6451a2c.async.js +0 -1
  147. package/static/dist/src__pages__404.b5140a4b.async.js +0 -1
  148. package/static/dist/src__pages__crontab__logModal.0f6a4945.async.js +0 -2
  149. package/static/dist/src__pages__crontab__modal.cb176c70.async.js +0 -5
  150. package/static/dist/src__pages__crontab__viewCreateModal.f2b8a69a.async.js +0 -4
  151. package/static/dist/src__pages__crontab__viewManageModal.b86bbb79.async.js +0 -4
  152. package/static/dist/src__pages__dependence__index.c17201d7.async.js +0 -2
  153. package/static/dist/src__pages__dependence__logModal.42c56e18.async.js +0 -4
  154. package/static/dist/src__pages__dependence__modal.58620a62.async.js +0 -5
  155. package/static/dist/src__pages__env__index.c79218f4.async.js +0 -2
  156. package/static/dist/src__pages__env__modal.07f411f1.async.js +0 -5
  157. package/static/dist/src__pages__error__index.2f9d7c50.async.js +0 -4
  158. package/static/dist/src__pages__initialization__index.af82f7e1.async.js +0 -21
  159. package/static/dist/src__pages__log__index.5e63a6b7.async.js +0 -1
  160. package/static/dist/src__pages__login__index.44d624a7.async.js +0 -2
  161. package/static/dist/src__pages__setting__about.7ca2707b.async.js +0 -1
  162. package/static/dist/src__pages__setting__checkUpdate.dd497877.async.js +0 -4
  163. package/static/dist/src__pages__setting__index.4a85066e.async.js +0 -2
  164. package/static/dist/src__pages__setting__loginLog.c8ddd712.async.js +0 -18
  165. package/static/dist/src__pages__setting__notification.e124b7ae.async.js +0 -21
  166. package/static/dist/src__pages__setting__other.a58b5fae.async.js +0 -1
  167. package/static/dist/src__pages__setting__security.aabc2d21.async.js +0 -4
  168. package/static/dist/src__pages__subscription__index.04531731.async.js +0 -2
  169. package/static/dist/src__pages__subscription__logModal.b86a5c9b.async.js +0 -2
  170. package/static/dist/src__pages__subscription__modal.ea198f81.async.js +0 -4
  171. package/static/dist/umi.29bfaff2.js +0 -11
  172. /package/static/dist/{8352.d2d0a2c7.chunk.css → 8612.d2d0a2c7.chunk.css} +0 -0
  173. /package/static/dist/{7394.59dcf306.chunk.css → 9439.59dcf306.chunk.css} +0 -0
package/README-en.md CHANGED
@@ -1,30 +1,29 @@
1
- <p align="center">
2
- <a href="https://github.com/whyour/qinglong">
3
- <img width="150" src="https://user-images.githubusercontent.com/22700758/191449379-f9f56204-0e31-4a16-be5a-331f52696a73.png">
4
- </a>
5
- </p>
1
+ <div align="center">
2
+ <img width="100" src="https://user-images.githubusercontent.com/22700758/191449379-f9f56204-0e31-4a16-be5a-331f52696a73.png">
6
3
 
7
- <h1 align="center">Green Dragon</h1>
4
+ <h1 align="center">Qinglong</h1>
8
5
 
9
- <div align="center">
6
+ [简体中文](./README.md) | English
10
7
 
11
8
  Timed task management platform supporting Python3, JavaScript, Shell, Typescript
12
9
 
13
- [![docker version][docker-version-image]][docker-version-url] [![docker pulls][docker-pulls-image]][docker-pulls-url] [![docker stars][docker-stars-image]][docker-stars-url] [![docker image size][docker-image-size-image]][docker-image-size-url]
10
+ [![npm version][npm-version-image]][npm-version-url] [![docker pulls][docker-pulls-image]][docker-pulls-url] [![docker stars][docker-stars-image]][docker-stars-url] [![docker image size][docker-image-size-image]][docker-image-size-url]
14
11
 
12
+ [npm-version-image]: https://img.shields.io/npm/v/@whyour/qinglong?style=flat
13
+ [npm-version-url]: https://www.npmjs.com/package/@whyour/qinglong?activeTab=readme
15
14
  [docker-pulls-image]: https://img.shields.io/docker/pulls/whyour/qinglong?style=flat
16
15
  [docker-pulls-url]: https://hub.docker.com/r/whyour/qinglong
17
- [docker-version-image]: https://img.shields.io/docker/v/whyour/qinglong?style=flat
18
- [docker-version-url]: https://hub.docker.com/r/whyour/qinglong/tags?page=1&ordering=last_updated
19
16
  [docker-stars-image]: https://img.shields.io/docker/stars/whyour/qinglong?style=flat
20
17
  [docker-stars-url]: https://hub.docker.com/r/whyour/qinglong
21
18
  [docker-image-size-image]: https://img.shields.io/docker/image-size/whyour/qinglong?style=flat
22
19
  [docker-image-size-url]: https://hub.docker.com/r/whyour/qinglong
23
- </div>
24
20
 
25
- [![](https://user-images.githubusercontent.com/22700758/229290661-03aabe84-8780-4ef0-8e75-2146f4636130.jpeg)](https://whyour.cn)
21
+ [Demo](http://demo.dlww.cc:4433/) / [Issues](https://github.com/whyour/qinglong/issues) / [Telegram Channel](https://t.me/jiao_long) / [Buy Me a Coffee](https://www.buymeacoffee.com/qinglong)
26
22
 
27
- [简体中文](./README.md) | English
23
+ [演示](http://demo.dlww.cc:4433/) / [反馈](https://github.com/whyour/qinglong/issues) / [Telegram 频道](https://t.me/jiao_long) / [打赏开发者](https://user-images.githubusercontent.com/22700758/244744295-29cd0cd1-c8bb-4ea1-adf6-29bd390ad4dd.jpg)
24
+ </div>
25
+
26
+ ![cover](https://user-images.githubusercontent.com/22700758/244847235-8dc1ca21-e03f-4606-9458-0541fab60413.png)
28
27
 
29
28
  ## Features
30
29
 
@@ -38,95 +37,59 @@ Timed task management platform supporting Python3, JavaScript, Shell, Typescript
38
37
 
39
38
  ## Deployment
40
39
 
41
- ### Local Deployment
42
-
43
- ```bash
44
- # To be refined, see the development steps first (not supported on windows yet)
45
- ```
46
-
47
- ### Podman Deployment
48
-
49
- 1. podman installation
40
+ ### Docker (Recommended)
50
41
 
51
42
  ```bash
52
- https://podman.io/getting-started/installation
53
- ```
54
-
55
- 2. start the container
56
-
57
- ```bash
58
- podman run -dit \
59
- --network bridge \
43
+ # curl -sSL get.docker.com | sh
44
+ docker run -dit \
60
45
  -v $PWD/ql/data:/ql/data \
61
46
  -p 5700:5700 \
62
47
  --name qinglong \
63
48
  --hostname qinglong \
64
- docker.io/whyour/qinglong:latest
49
+ --restart unless-stopped \
50
+ whyour/qinglong:latest
65
51
  ```
66
52
 
67
- ### Docker Deployment
68
-
69
- 1. docker installation
53
+ ### Docker-compose (Recommended)
70
54
 
71
55
  ```bash
72
- sudo curl -sSL get.docker.com | sh
73
- ```
74
-
75
- 2. configure domestic mirror sources
56
+ # curl -L https://github.com/docker/compose/releases/download/1.16.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
57
+ mkdir qinglong
58
+ wget https://raw.githubusercontent.com/whyour/qinglong/master/docker/docker-compose.yml
76
59
 
77
- ```bash
78
- mkdir -p /etc/docker
79
- tee /etc/docker/daemon.json <<-'EOF'
80
- {
81
- "registry-mirrors": [
82
- "https://0b27f0a81a00f3560fbdc00ddd2f99e0.mirror.swr.myhuaweicloud.com",
83
- "https://ypzju6vq.mirror.aliyuncs.com",
84
- "https://registry.docker-cn.com",
85
- "http://hub-mirror.c.163.com",
86
- "https://docker.mirrors.ustc.edu.cn"
87
- ]
88
- }
89
- EOF
90
- systemctl daemon-reload
91
- systemctl restart docker
60
+ # start
61
+ docker-compose up -d
62
+ # stop
63
+ docker-compose down
92
64
  ```
93
65
 
94
- 3. start the container
66
+ ### Podman (Recommended)
95
67
 
96
68
  ```bash
97
- docker run -dit \
69
+ # https://podman.io/getting-started/installation
70
+ podman run -dit \
71
+ --network bridge \
98
72
  -v $PWD/ql/data:/ql/data \
99
73
  -p 5700:5700 \
100
74
  --name qinglong \
101
75
  --hostname qinglong \
102
- --restart unless-stopped \
103
- whyour/qinglong:latest
76
+ docker.io/whyour/qinglong:latest
104
77
  ```
105
78
 
106
- ### Docker-compose Deployment
79
+ ### Local
107
80
 
108
- 1. docker-compose installation
81
+ It is recommended to use a pure system installation to avoid losing the original system data, you need to install node/npm/python3/pip3 yourself
109
82
 
110
83
  ```bash
111
- sudo curl -L https://github.com/docker/compose/releases/download/1.16.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
84
+ npm install -g @whyour/qinglong
85
+ qinglong
86
+ # Add the environment variables QL_DIR and QL_DATA_DIR when prompted
87
+ export QL_DIR=""
88
+ export QL_DATA_DIR=""
89
+ # Run again
90
+ qinglong
112
91
  ```
113
92
 
114
- 2. start the container
115
-
116
- ```bash
117
- mkdir qinglong
118
- wget https://raw.githubusercontent.com/whyour/qinglong/master/docker/docker-compose.yml
119
-
120
- # start
121
- docker-compose up -d
122
- # stop
123
- docker-compose down
124
- ```
125
-
126
- 3. access
127
-
128
- Open your browser and visit http://{ip}:5700
129
-
130
93
  ## Use
131
94
 
132
95
  1. built-in commands
@@ -181,16 +144,6 @@ task -l <file_path>
181
144
  * account_number: Specify the account number of an environment variable to be executed when the task is executed
182
145
  * max_time: Timeout, suffix "s" for seconds (default), "m" for minutes, "h" for hours, "d" for days
183
146
 
184
- ## Links
185
-
186
- - [nevinee](https://gitee.com/evine)
187
- - [crontab-ui](https://github.com/alseambusher/crontab-ui)
188
- - [Ant Design](https://ant.design)
189
- - [Ant Design Pro](https://pro.ant.design/)
190
- - [Umijs](https://umijs.org)
191
- - [darkreader](https://github.com/darkreader/darkreader)
192
- - [admin-server](https://github.com/sunpu007/admin-server)
193
-
194
147
  ## Development
195
148
 
196
149
  ```bash
@@ -205,9 +158,15 @@ $ pnpm start
205
158
 
206
159
  Open your browser and visit http://127.0.0.1:5700
207
160
 
208
- ## Communication
161
+ ## Links
209
162
 
210
- [telegram channel](https://t.me/jiao_long)
163
+ - [nevinee](https://gitee.com/evine)
164
+ - [crontab-ui](https://github.com/alseambusher/crontab-ui)
165
+ - [Ant Design](https://ant.design)
166
+ - [Ant Design Pro](https://pro.ant.design/)
167
+ - [Umijs](https://umijs.org)
168
+ - [darkreader](https://github.com/darkreader/darkreader)
169
+ - [admin-server](https://github.com/sunpu007/admin-server)
211
170
 
212
171
  ## Name Origin
213
172
 
package/README.md CHANGED
@@ -1,30 +1,31 @@
1
- <p align="center">
2
- <a href="https://github.com/whyour/qinglong">
3
- <img width="150" src="https://user-images.githubusercontent.com/22700758/191449379-f9f56204-0e31-4a16-be5a-331f52696a73.png">
4
- </a>
5
- </p>
1
+ <div align="center">
2
+ <img width="100" src="https://user-images.githubusercontent.com/22700758/191449379-f9f56204-0e31-4a16-be5a-331f52696a73.png">
6
3
 
7
4
  <h1 align="center">青龙</h1>
8
5
 
9
- <div align="center">
6
+ 简体中文 | [English](./README-en.md)
10
7
 
11
8
  支持 Python3、JavaScript、Shell、Typescript 的定时任务管理平台
12
9
 
13
- [![docker version][docker-version-image]][docker-version-url] [![docker pulls][docker-pulls-image]][docker-pulls-url] [![docker stars][docker-stars-image]][docker-stars-url] [![docker image size][docker-image-size-image]][docker-image-size-url]
10
+ Timed task management platform supporting Python3, JavaScript, Shell, Typescript
14
11
 
12
+ [![npm version][npm-version-image]][npm-version-url] [![docker pulls][docker-pulls-image]][docker-pulls-url] [![docker stars][docker-stars-image]][docker-stars-url] [![docker image size][docker-image-size-image]][docker-image-size-url]
13
+
14
+ [npm-version-image]: https://img.shields.io/npm/v/@whyour/qinglong?style=flat
15
+ [npm-version-url]: https://www.npmjs.com/package/@whyour/qinglong?activeTab=readme
15
16
  [docker-pulls-image]: https://img.shields.io/docker/pulls/whyour/qinglong?style=flat
16
17
  [docker-pulls-url]: https://hub.docker.com/r/whyour/qinglong
17
- [docker-version-image]: https://img.shields.io/docker/v/whyour/qinglong?style=flat
18
- [docker-version-url]: https://hub.docker.com/r/whyour/qinglong/tags?page=1&ordering=last_updated
19
18
  [docker-stars-image]: https://img.shields.io/docker/stars/whyour/qinglong?style=flat
20
19
  [docker-stars-url]: https://hub.docker.com/r/whyour/qinglong
21
20
  [docker-image-size-image]: https://img.shields.io/docker/image-size/whyour/qinglong?style=flat
22
21
  [docker-image-size-url]: https://hub.docker.com/r/whyour/qinglong
23
- </div>
24
22
 
25
- [![](https://user-images.githubusercontent.com/22700758/229290661-03aabe84-8780-4ef0-8e75-2146f4636130.jpeg)](https://whyour.cn)
23
+ [Demo](http://demo.dlww.cc:4433/) / [Issues](https://github.com/whyour/qinglong/issues) / [Telegram Channel](https://t.me/jiao_long) / [Buy Me a Coffee](https://www.buymeacoffee.com/qinglong)
26
24
 
27
- 简体中文 | [English](./README-en.md)
25
+ [演示](http://demo.dlww.cc:4433/) / [反馈](https://github.com/whyour/qinglong/issues) / [Telegram 频道](https://t.me/jiao_long) / [打赏开发者](https://user-images.githubusercontent.com/22700758/244744295-29cd0cd1-c8bb-4ea1-adf6-29bd390ad4dd.jpg)
26
+ </div>
27
+
28
+ ![cover](https://user-images.githubusercontent.com/22700758/244847235-8dc1ca21-e03f-4606-9458-0541fab60413.png)
28
29
 
29
30
  ## 功能
30
31
 
@@ -38,99 +39,63 @@
38
39
 
39
40
  ## 部署
40
41
 
41
- ### 本机部署
42
-
43
- ```bash
44
- # 待完善,可先参考开发步骤 (windows暂时不支持)
45
- ```
46
-
47
- ### podman 部署
48
-
49
- 1. podman 安装
42
+ ### docker (推荐)
50
43
 
51
44
  ```bash
52
- https://podman.io/getting-started/installation
53
- ```
54
-
55
- 2. 启动容器
56
-
57
- ```bash
58
- podman run -dit \
59
- --network bridge \
45
+ # curl -sSL get.docker.com | sh
46
+ docker run -dit \
60
47
  -v $PWD/ql/data:/ql/data \
61
48
  -p 5700:5700 \
62
49
  # 部署路径非必须,以斜杠开头和结尾,比如 /test/
63
50
  -e QlBaseUrl="/" \
64
51
  --name qinglong \
65
52
  --hostname qinglong \
66
- docker.io/whyour/qinglong:latest
53
+ --restart unless-stopped \
54
+ whyour/qinglong:latest
67
55
  ```
68
56
 
69
- ### docker 部署
70
-
71
- 1. docker 安装
57
+ ### docker-compose (推荐)
72
58
 
73
59
  ```bash
74
- sudo curl -sSL get.docker.com | sh
75
- ```
76
-
77
- 2. 配置国内镜像源
60
+ # curl -L https://github.com/docker/compose/releases/download/1.16.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
61
+ mkdir qinglong
62
+ wget https://raw.githubusercontent.com/whyour/qinglong/master/docker/docker-compose.yml
78
63
 
79
- ```bash
80
- mkdir -p /etc/docker
81
- tee /etc/docker/daemon.json <<-'EOF'
82
- {
83
- "registry-mirrors": [
84
- "https://0b27f0a81a00f3560fbdc00ddd2f99e0.mirror.swr.myhuaweicloud.com",
85
- "https://ypzju6vq.mirror.aliyuncs.com",
86
- "https://registry.docker-cn.com",
87
- "http://hub-mirror.c.163.com",
88
- "https://docker.mirrors.ustc.edu.cn"
89
- ]
90
- }
91
- EOF
92
- systemctl daemon-reload
93
- systemctl restart docker
64
+ # 启动
65
+ docker-compose up -d
66
+ # 停止
67
+ docker-compose down
94
68
  ```
95
69
 
96
- 3. 启动容器
70
+ ### podman (推荐)
97
71
 
98
72
  ```bash
99
- docker run -dit \
73
+ # https://podman.io/getting-started/installation
74
+ podman run -dit \
75
+ --network bridge \
100
76
  -v $PWD/ql/data:/ql/data \
101
77
  -p 5700:5700 \
102
78
  # 部署路径非必须,以斜杠开头和结尾,比如 /test/
103
79
  -e QlBaseUrl="/" \
104
80
  --name qinglong \
105
81
  --hostname qinglong \
106
- --restart unless-stopped \
107
- whyour/qinglong:latest
82
+ docker.io/whyour/qinglong:latest
108
83
  ```
109
84
 
110
- ### docker-compose 部署
85
+ ### 本机
111
86
 
112
- 1. docker-compose 安装
87
+ 建议使用纯净系统安装,避免系统原有数据丢失,需要自己安装 node/npm/python3/pip3
113
88
 
114
89
  ```bash
115
- sudo curl -L https://github.com/docker/compose/releases/download/1.16.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
116
- ```
117
-
118
- 2. 启动容器
119
-
120
- ```bash
121
- mkdir qinglong
122
- wget https://raw.githubusercontent.com/whyour/qinglong/master/docker/docker-compose.yml
123
-
124
- # 启动
125
- docker-compose up -d
126
- # 停止
127
- docker-compose down
90
+ npm install -g @whyour/qinglong
91
+ qinglong
92
+ # 根据提示增加环境变量 QL_DIR 和 QL_DATA_DIR
93
+ export QL_DIR=""
94
+ export QL_DATA_DIR=""
95
+ # 再次执行
96
+ qinglong
128
97
  ```
129
98
 
130
- 3. 访问
131
-
132
- 打开你的浏览器,访问 http://{ip}:5700
133
-
134
99
  ## 使用
135
100
 
136
101
  1. 内置命令
@@ -184,16 +149,6 @@ task -l <file_path>
184
149
  * account_number: 任务执行时指定某个环境变量需要执行的账号序号
185
150
  * max_time: 超时时间,后缀"s"代表秒(默认值), "m"代表分, "h"代表小时, "d"代表天
186
151
 
187
- ## 链接
188
-
189
- - [nevinee](https://gitee.com/evine)
190
- - [crontab-ui](https://github.com/alseambusher/crontab-ui)
191
- - [Ant Design](https://ant.design)
192
- - [Ant Design Pro](https://pro.ant.design/)
193
- - [Umijs](https://umijs.org)
194
- - [darkreader](https://github.com/darkreader/darkreader)
195
- - [admin-server](https://github.com/sunpu007/admin-server)
196
-
197
152
  ## 开发
198
153
 
199
154
  ```bash
@@ -208,9 +163,15 @@ $ pnpm start
208
163
 
209
164
  打开你的浏览器,访问 http://127.0.0.1:5700
210
165
 
211
- ## 交流
166
+ ## 链接
212
167
 
213
- [telegram频道](https://t.me/jiao_long)
168
+ - [nevinee](https://gitee.com/evine)
169
+ - [crontab-ui](https://github.com/alseambusher/crontab-ui)
170
+ - [Ant Design](https://ant.design)
171
+ - [Ant Design Pro](https://pro.ant.design/)
172
+ - [Umijs](https://umijs.org)
173
+ - [darkreader](https://github.com/darkreader/darkreader)
174
+ - [admin-server](https://github.com/sunpu007/admin-server)
214
175
 
215
176
  ## 名称来源
216
177
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@whyour/qinglong",
3
- "version": "0.3.2",
3
+ "version": "0.4.0",
4
4
  "description": "Timed task management platform supporting Python3, JavaScript, Shell, Typescript",
5
5
  "repository": {
6
6
  "type": "git",
@@ -80,10 +80,12 @@
80
80
  "chokidar": "^3.5.3",
81
81
  "cors": "^2.8.5",
82
82
  "cron-parser": "^4.2.1",
83
+ "cross-spawn": "^7.0.3",
83
84
  "dayjs": "^1.11.2",
84
85
  "dotenv": "^16.0.0",
85
86
  "express": "^4.17.3",
86
87
  "express-jwt": "^6.1.1",
88
+ "express-rate-limit": "^6.7.0",
87
89
  "express-urlrewrite": "^1.4.0",
88
90
  "form-data": "^4.0.0",
89
91
  "got": "^11.8.2",
@@ -97,6 +99,7 @@
97
99
  "nedb": "^1.8.0",
98
100
  "node-schedule": "^2.1.0",
99
101
  "nodemailer": "^6.7.2",
102
+ "p-limit": "3.1.0",
100
103
  "protobufjs": "^7.2.3",
101
104
  "pstree.remy": "^1.1.8",
102
105
  "reflect-metadata": "^0.1.13",
@@ -118,6 +121,7 @@
118
121
  "@sentry/react": "^7.12.1",
119
122
  "@types/body-parser": "^1.19.2",
120
123
  "@types/cors": "^2.8.12",
124
+ "@types/cross-spawn": "^6.0.2",
121
125
  "@types/express": "^4.17.13",
122
126
  "@types/express-jwt": "^6.0.4",
123
127
  "@types/js-yaml": "^4.0.5",
package/sample/notify.js CHANGED
@@ -76,6 +76,10 @@ let DD_BOT_TOKEN = '';
76
76
  //密钥,机器人安全设置页面,加签一栏下面显示的SEC开头的字符串
77
77
  let DD_BOT_SECRET = '';
78
78
 
79
+ // =======================================企业微信基础设置===========================================
80
+ // 企业微信反向代理地址
81
+ //(环境变量名 QYWX_ORIGIN)
82
+ let QYWX_ORIGIN = '';
79
83
  // =======================================企业微信机器人通知设置区域===========================================
80
84
  //此处填你企业微信机器人的 webhook(详见文档 https://work.weixin.qq.com/api/doc/90000/90136/91770),例如:693a91f6-7xxx-4bc4-97a0-0ec2sifa5aaa
81
85
  //(环境变量名 QYWX_KEY)
@@ -230,6 +234,12 @@ if (process.env.DD_BOT_TOKEN) {
230
234
  }
231
235
  }
232
236
 
237
+ if (process.env.QYWX_ORIGIN) {
238
+ QYWX_ORIGIN = process.env.QYWX_ORIGIN;
239
+ } else {
240
+ QYWX_ORIGIN = 'https://qyapi.weixin.qq.com';
241
+ }
242
+
233
243
  if (process.env.QYWX_KEY) {
234
244
  QYWX_KEY = process.env.QYWX_KEY;
235
245
  }
@@ -298,11 +308,11 @@ async function sendNotify(
298
308
  desp += author; //增加作者信息,防止被贩卖等
299
309
 
300
310
  // 根据标题跳过一些消息推送,环境变量:SKIP_PUSH_TITLE 用回车分隔
301
- let skipTitle = process.env.SKIP_PUSH_TITLE
302
- if(skipTitle) {
303
- if(skipTitle.split('\n').includes(text)) {
304
- console.info(text + "在SKIP_PUSH_TITLE环境变量内,跳过推送!");
305
- return
311
+ let skipTitle = process.env.SKIP_PUSH_TITLE;
312
+ if (skipTitle) {
313
+ if (skipTitle.split('\n').includes(text)) {
314
+ console.info(text + '在SKIP_PUSH_TITLE环境变量内,跳过推送!');
315
+ return;
306
316
  }
307
317
  }
308
318
 
@@ -692,7 +702,7 @@ function ddBotNotify(text, desp) {
692
702
  function qywxBotNotify(text, desp) {
693
703
  return new Promise((resolve) => {
694
704
  const options = {
695
- url: `https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=${QYWX_KEY}`,
705
+ url: `${QYWX_ORIGIN}/cgi-bin/webhook/send?key=${QYWX_KEY}`,
696
706
  json: {
697
707
  msgtype: 'text',
698
708
  text: {
@@ -754,7 +764,7 @@ function qywxamNotify(text, desp) {
754
764
  if (QYWX_AM) {
755
765
  const QYWX_AM_AY = QYWX_AM.split(',');
756
766
  const options_accesstoken = {
757
- url: `https://qyapi.weixin.qq.com/cgi-bin/gettoken`,
767
+ url: `${QYWX_ORIGIN}/cgi-bin/gettoken`,
758
768
  json: {
759
769
  corpid: `${QYWX_AM_AY[0]}`,
760
770
  corpsecret: `${QYWX_AM_AY[1]}`,
@@ -819,7 +829,7 @@ function qywxamNotify(text, desp) {
819
829
  };
820
830
  }
821
831
  options = {
822
- url: `https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=${accesstoken}`,
832
+ url: `${QYWX_ORIGIN}/cgi-bin/message/send?access_token=${accesstoken}`,
823
833
  json: {
824
834
  touser: `${ChangeUserId(desp)}`,
825
835
  agentid: `${QYWX_AM_AY[3]}`,
@@ -1113,4 +1123,4 @@ module.exports = {
1113
1123
  };
1114
1124
 
1115
1125
  // prettier-ignore
1116
- function Env(t,s){return new class{constructor(t,s){this.name=t,this.data=null,this.dataFile="box.dat",this.logs=[],this.logSeparator="\n",this.startTime=(new Date).getTime(),Object.assign(this,s),this.log("",`\ud83d\udd14${this.name}, \u5f00\u59cb!`)}isNode(){return"undefined"!=typeof module&&!!module.exports}isQuanX(){return"undefined"!=typeof $task}isSurge(){return"undefined"!=typeof $httpClient&&"undefined"==typeof $loon}isLoon(){return"undefined"!=typeof $loon}getScript(t){return new Promise(s=>{$.get({url:t},(t,e,i)=>s(i))})}runScript(t,s){return new Promise(e=>{let i=this.getdata("@chavy_boxjs_userCfgs.httpapi");i=i?i.replace(/\n/g,"").trim():i;let o=this.getdata("@chavy_boxjs_userCfgs.httpapi_timeout");o=o?1*o:20,o=s&&s.timeout?s.timeout:o;const[h,a]=i.split("@"),r={url:`http://${a}/v1/scripting/evaluate`,body:{script_text:t,mock_type:"cron",timeout:o},headers:{"X-Key":h,Accept:"*/*"}};$.post(r,(t,s,i)=>e(i))}).catch(t=>this.logErr(t))}loaddata(){if(!this.isNode())return{};{this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),s=this.path.resolve(process.cwd(),this.dataFile),e=this.fs.existsSync(t),i=!e&&this.fs.existsSync(s);if(!e&&!i)return{};{const i=e?t:s;try{return JSON.parse(this.fs.readFileSync(i))}catch(t){return{}}}}}writedata(){if(this.isNode()){this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),s=this.path.resolve(process.cwd(),this.dataFile),e=this.fs.existsSync(t),i=!e&&this.fs.existsSync(s),o=JSON.stringify(this.data);e?this.fs.writeFileSync(t,o):i?this.fs.writeFileSync(s,o):this.fs.writeFileSync(t,o)}}lodash_get(t,s,e){const i=s.replace(/\[(\d+)\]/g,".$1").split(".");let o=t;for(const t of i)if(o=Object(o)[t],void 0===o)return e;return o}lodash_set(t,s,e){return Object(t)!==t?t:(Array.isArray(s)||(s=s.toString().match(/[^.[\]]+/g)||[]),s.slice(0,-1).reduce((t,e,i)=>Object(t[e])===t[e]?t[e]:t[e]=Math.abs(s[i+1])>>0==+s[i+1]?[]:{},t)[s[s.length-1]]=e,t)}getdata(t){let s=this.getval(t);if(/^@/.test(t)){const[,e,i]=/^@(.*?)\.(.*?)$/.exec(t),o=e?this.getval(e):"";if(o)try{const t=JSON.parse(o);s=t?this.lodash_get(t,i,""):s}catch(t){s=""}}return s}setdata(t,s){let e=!1;if(/^@/.test(s)){const[,i,o]=/^@(.*?)\.(.*?)$/.exec(s),h=this.getval(i),a=i?"null"===h?null:h||"{}":"{}";try{const s=JSON.parse(a);this.lodash_set(s,o,t),e=this.setval(JSON.stringify(s),i)}catch(s){const h={};this.lodash_set(h,o,t),e=this.setval(JSON.stringify(h),i)}}else e=$.setval(t,s);return e}getval(t){return this.isSurge()||this.isLoon()?$persistentStore.read(t):this.isQuanX()?$prefs.valueForKey(t):this.isNode()?(this.data=this.loaddata(),this.data[t]):this.data&&this.data[t]||null}setval(t,s){return this.isSurge()||this.isLoon()?$persistentStore.write(t,s):this.isQuanX()?$prefs.setValueForKey(t,s):this.isNode()?(this.data=this.loaddata(),this.data[s]=t,this.writedata(),!0):this.data&&this.data[s]||null}initGotEnv(t){this.got=this.got?this.got:require("got"),this.cktough=this.cktough?this.cktough:require("tough-cookie"),this.ckjar=this.ckjar?this.ckjar:new this.cktough.CookieJar,t&&(t.headers=t.headers?t.headers:{},void 0===t.headers.Cookie&&void 0===t.cookieJar&&(t.cookieJar=this.ckjar))}get(t,s=(()=>{})){t.headers&&(delete t.headers["Content-Type"],delete t.headers["Content-Length"]),this.isSurge()||this.isLoon()?$httpClient.get(t,(t,e,i)=>{!t&&e&&(e.body=i,e.statusCode=e.status),s(t,e,i)}):this.isQuanX()?$task.fetch(t).then(t=>{const{statusCode:e,statusCode:i,headers:o,body:h}=t;s(null,{status:e,statusCode:i,headers:o,body:h},h)},t=>s(t)):this.isNode()&&(this.initGotEnv(t),this.got(t).on("redirect",(t,s)=>{try{const e=t.headers["set-cookie"].map(this.cktough.Cookie.parse).toString();this.ckjar.setCookieSync(e,null),s.cookieJar=this.ckjar}catch(t){this.logErr(t)}}).then(t=>{const{statusCode:e,statusCode:i,headers:o,body:h}=t;s(null,{status:e,statusCode:i,headers:o,body:h},h)},t=>s(t)))}post(t,s=(()=>{})){if(t.body&&t.headers&&!t.headers["Content-Type"]&&(t.headers["Content-Type"]="application/x-www-form-urlencoded"),delete t.headers["Content-Length"],this.isSurge()||this.isLoon())$httpClient.post(t,(t,e,i)=>{!t&&e&&(e.body=i,e.statusCode=e.status),s(t,e,i)});else if(this.isQuanX())t.method="POST",$task.fetch(t).then(t=>{const{statusCode:e,statusCode:i,headers:o,body:h}=t;s(null,{status:e,statusCode:i,headers:o,body:h},h)},t=>s(t));else if(this.isNode()){this.initGotEnv(t);const{url:e,...i}=t;this.got.post(e,i).then(t=>{const{statusCode:e,statusCode:i,headers:o,body:h}=t;s(null,{status:e,statusCode:i,headers:o,body:h},h)},t=>s(t))}}time(t){let s={"M+":(new Date).getMonth()+1,"d+":(new Date).getDate(),"H+":(new Date).getHours(),"m+":(new Date).getMinutes(),"s+":(new Date).getSeconds(),"q+":Math.floor(((new Date).getMonth()+3)/3),S:(new Date).getMilliseconds()};/(y+)/.test(t)&&(t=t.replace(RegExp.$1,((new Date).getFullYear()+"").substr(4-RegExp.$1.length)));for(let e in s)new RegExp("("+e+")").test(t)&&(t=t.replace(RegExp.$1,1==RegExp.$1.length?s[e]:("00"+s[e]).substr((""+s[e]).length)));return t}msg(s=t,e="",i="",o){const h=t=>!t||!this.isLoon()&&this.isSurge()?t:"string"==typeof t?this.isLoon()?t:this.isQuanX()?{"open-url":t}:void 0:"object"==typeof t&&(t["open-url"]||t["media-url"])?this.isLoon()?t["open-url"]:this.isQuanX()?t:void 0:void 0;$.isMute||(this.isSurge()||this.isLoon()?$notification.post(s,e,i,h(o)):this.isQuanX()&&$notify(s,e,i,h(o))),this.logs.push("","==============\ud83d\udce3\u7cfb\u7edf\u901a\u77e5\ud83d\udce3=============="),this.logs.push(s),e&&this.logs.push(e),i&&this.logs.push(i)}log(...t){t.length>0?this.logs=[...this.logs,...t]:console.log(this.logs.join(this.logSeparator))}logErr(t,s){const e=!this.isSurge()&&!this.isQuanX()&&!this.isLoon();e?$.log("",`\u2757\ufe0f${this.name}, \u9519\u8bef!`,t.stack):$.log("",`\u2757\ufe0f${this.name}, \u9519\u8bef!`,t)}wait(t){return new Promise(s=>setTimeout(s,t))}done(t={}){const s=(new Date).getTime(),e=(s-this.startTime)/1e3;this.log("",`\ud83d\udd14${this.name}, \u7ed3\u675f! \ud83d\udd5b ${e} \u79d2`),this.log(),(this.isSurge()||this.isQuanX()||this.isLoon())&&$done(t)}}(t,s)}
1126
+ function Env(t, s) { return new class { constructor(t, s) { this.name = t, this.data = null, this.dataFile = "box.dat", this.logs = [], this.logSeparator = "\n", this.startTime = (new Date).getTime(), Object.assign(this, s), this.log("", `\ud83d\udd14${this.name}, \u5f00\u59cb!`) } isNode() { return "undefined" != typeof module && !!module.exports } isQuanX() { return "undefined" != typeof $task } isSurge() { return "undefined" != typeof $httpClient && "undefined" == typeof $loon } isLoon() { return "undefined" != typeof $loon } getScript(t) { return new Promise(s => { $.get({ url: t }, (t, e, i) => s(i)) }) } runScript(t, s) { return new Promise(e => { let i = this.getdata("@chavy_boxjs_userCfgs.httpapi"); i = i ? i.replace(/\n/g, "").trim() : i; let o = this.getdata("@chavy_boxjs_userCfgs.httpapi_timeout"); o = o ? 1 * o : 20, o = s && s.timeout ? s.timeout : o; const [h, a] = i.split("@"), r = { url: `http://${a}/v1/scripting/evaluate`, body: { script_text: t, mock_type: "cron", timeout: o }, headers: { "X-Key": h, Accept: "*/*" } }; $.post(r, (t, s, i) => e(i)) }).catch(t => this.logErr(t)) } loaddata() { if (!this.isNode()) return {}; { this.fs = this.fs ? this.fs : require("fs"), this.path = this.path ? this.path : require("path"); const t = this.path.resolve(this.dataFile), s = this.path.resolve(process.cwd(), this.dataFile), e = this.fs.existsSync(t), i = !e && this.fs.existsSync(s); if (!e && !i) return {}; { const i = e ? t : s; try { return JSON.parse(this.fs.readFileSync(i)) } catch (t) { return {} } } } } writedata() { if (this.isNode()) { this.fs = this.fs ? this.fs : require("fs"), this.path = this.path ? this.path : require("path"); const t = this.path.resolve(this.dataFile), s = this.path.resolve(process.cwd(), this.dataFile), e = this.fs.existsSync(t), i = !e && this.fs.existsSync(s), o = JSON.stringify(this.data); e ? this.fs.writeFileSync(t, o) : i ? this.fs.writeFileSync(s, o) : this.fs.writeFileSync(t, o) } } lodash_get(t, s, e) { const i = s.replace(/\[(\d+)\]/g, ".$1").split("."); let o = t; for (const t of i) if (o = Object(o)[t], void 0 === o) return e; return o } lodash_set(t, s, e) { return Object(t) !== t ? t : (Array.isArray(s) || (s = s.toString().match(/[^.[\]]+/g) || []), s.slice(0, -1).reduce((t, e, i) => Object(t[e]) === t[e] ? t[e] : t[e] = Math.abs(s[i + 1]) >> 0 == +s[i + 1] ? [] : {}, t)[s[s.length - 1]] = e, t) } getdata(t) { let s = this.getval(t); if (/^@/.test(t)) { const [, e, i] = /^@(.*?)\.(.*?)$/.exec(t), o = e ? this.getval(e) : ""; if (o) try { const t = JSON.parse(o); s = t ? this.lodash_get(t, i, "") : s } catch (t) { s = "" } } return s } setdata(t, s) { let e = !1; if (/^@/.test(s)) { const [, i, o] = /^@(.*?)\.(.*?)$/.exec(s), h = this.getval(i), a = i ? "null" === h ? null : h || "{}" : "{}"; try { const s = JSON.parse(a); this.lodash_set(s, o, t), e = this.setval(JSON.stringify(s), i) } catch (s) { const h = {}; this.lodash_set(h, o, t), e = this.setval(JSON.stringify(h), i) } } else e = $.setval(t, s); return e } getval(t) { return this.isSurge() || this.isLoon() ? $persistentStore.read(t) : this.isQuanX() ? $prefs.valueForKey(t) : this.isNode() ? (this.data = this.loaddata(), this.data[t]) : this.data && this.data[t] || null } setval(t, s) { return this.isSurge() || this.isLoon() ? $persistentStore.write(t, s) : this.isQuanX() ? $prefs.setValueForKey(t, s) : this.isNode() ? (this.data = this.loaddata(), this.data[s] = t, this.writedata(), !0) : this.data && this.data[s] || null } initGotEnv(t) { this.got = this.got ? this.got : require("got"), this.cktough = this.cktough ? this.cktough : require("tough-cookie"), this.ckjar = this.ckjar ? this.ckjar : new this.cktough.CookieJar, t && (t.headers = t.headers ? t.headers : {}, void 0 === t.headers.Cookie && void 0 === t.cookieJar && (t.cookieJar = this.ckjar)) } get(t, s = (() => { })) { t.headers && (delete t.headers["Content-Type"], delete t.headers["Content-Length"]), this.isSurge() || this.isLoon() ? $httpClient.get(t, (t, e, i) => { !t && e && (e.body = i, e.statusCode = e.status), s(t, e, i) }) : this.isQuanX() ? $task.fetch(t).then(t => { const { statusCode: e, statusCode: i, headers: o, body: h } = t; s(null, { status: e, statusCode: i, headers: o, body: h }, h) }, t => s(t)) : this.isNode() && (this.initGotEnv(t), this.got(t).on("redirect", (t, s) => { try { const e = t.headers["set-cookie"].map(this.cktough.Cookie.parse).toString(); this.ckjar.setCookieSync(e, null), s.cookieJar = this.ckjar } catch (t) { this.logErr(t) } }).then(t => { const { statusCode: e, statusCode: i, headers: o, body: h } = t; s(null, { status: e, statusCode: i, headers: o, body: h }, h) }, t => s(t))) } post(t, s = (() => { })) { if (t.body && t.headers && !t.headers["Content-Type"] && (t.headers["Content-Type"] = "application/x-www-form-urlencoded"), delete t.headers["Content-Length"], this.isSurge() || this.isLoon()) $httpClient.post(t, (t, e, i) => { !t && e && (e.body = i, e.statusCode = e.status), s(t, e, i) }); else if (this.isQuanX()) t.method = "POST", $task.fetch(t).then(t => { const { statusCode: e, statusCode: i, headers: o, body: h } = t; s(null, { status: e, statusCode: i, headers: o, body: h }, h) }, t => s(t)); else if (this.isNode()) { this.initGotEnv(t); const { url: e, ...i } = t; this.got.post(e, i).then(t => { const { statusCode: e, statusCode: i, headers: o, body: h } = t; s(null, { status: e, statusCode: i, headers: o, body: h }, h) }, t => s(t)) } } time(t) { let s = { "M+": (new Date).getMonth() + 1, "d+": (new Date).getDate(), "H+": (new Date).getHours(), "m+": (new Date).getMinutes(), "s+": (new Date).getSeconds(), "q+": Math.floor(((new Date).getMonth() + 3) / 3), S: (new Date).getMilliseconds() }; /(y+)/.test(t) && (t = t.replace(RegExp.$1, ((new Date).getFullYear() + "").substr(4 - RegExp.$1.length))); for (let e in s) new RegExp("(" + e + ")").test(t) && (t = t.replace(RegExp.$1, 1 == RegExp.$1.length ? s[e] : ("00" + s[e]).substr(("" + s[e]).length))); return t } msg(s = t, e = "", i = "", o) { const h = t => !t || !this.isLoon() && this.isSurge() ? t : "string" == typeof t ? this.isLoon() ? t : this.isQuanX() ? { "open-url": t } : void 0 : "object" == typeof t && (t["open-url"] || t["media-url"]) ? this.isLoon() ? t["open-url"] : this.isQuanX() ? t : void 0 : void 0; $.isMute || (this.isSurge() || this.isLoon() ? $notification.post(s, e, i, h(o)) : this.isQuanX() && $notify(s, e, i, h(o))), this.logs.push("", "==============\ud83d\udce3\u7cfb\u7edf\u901a\u77e5\ud83d\udce3=============="), this.logs.push(s), e && this.logs.push(e), i && this.logs.push(i) } log(...t) { t.length > 0 ? this.logs = [...this.logs, ...t] : console.log(this.logs.join(this.logSeparator)) } logErr(t, s) { const e = !this.isSurge() && !this.isQuanX() && !this.isLoon(); e ? $.log("", `\u2757\ufe0f${this.name}, \u9519\u8bef!`, t.stack) : $.log("", `\u2757\ufe0f${this.name}, \u9519\u8bef!`, t) } wait(t) { return new Promise(s => setTimeout(s, t)) } done(t = {}) { const s = (new Date).getTime(), e = (s - this.startTime) / 1e3; this.log("", `\ud83d\udd14${this.name}, \u7ed3\u675f! \ud83d\udd5b ${e} \u79d2`), this.log(), (this.isSurge() || this.isQuanX() || this.isLoon()) && $done(t) } }(t, s) }