Compare commits

...

2077 Commits
init ... py2

Author SHA1 Message Date
0c44305a01 Update requirements.txt 2021-05-01 11:11:22 +08:00
9c4d482471 Update requirements.txt 2021-05-01 11:07:11 +08:00
713f77c1ad up 2021-05-01 10:56:12 +08:00
db2b71582b Update requirements.txt 2021-05-01 10:14:01 +08:00
ccc750cce3 Update simdht_delta.conf 2021-04-30 21:59:14 +08:00
0dc26232b6 Update simdht_delta.conf 2021-04-30 21:58:36 +08:00
fa0fc8eefe Update requirements.txt 2021-04-30 18:41:05 +08:00
1cadcde740 Update requirements.txt 2021-04-30 18:40:13 +08:00
a602cad2db Update requirements.txt 2021-04-30 18:36:05 +08:00
0a400aeda9 Update requirements.txt 2021-04-30 18:35:13 +08:00
aaca85bc7e Update requirements.txt 2021-04-30 18:27:06 +08:00
fcba8a9269 Update requirements.txt 2021-04-30 18:19:47 +08:00
8931a28286 Update install_centos.sh 2021-04-30 18:02:09 +08:00
8d4d72e14d Update zimg.tpl 2021-04-26 17:21:46 +08:00
fa40d1dc92 Update phplib.conf 2021-04-24 09:51:59 +08:00
4007d14517 Create openssl.sh 2021-04-24 09:51:09 +08:00
389db5404c up 2021-04-24 09:22:39 +08:00
763065e7ab Update install.sh 2021-04-24 09:19:30 +08:00
c697f016aa 更新memcached版本 2021-04-24 09:19:12 +08:00
1df3b8efd0 更新版本 2021-04-24 09:08:53 +08:00
bfce862180 up 2021-04-22 04:08:30 +08:00
3f0cc58bdc up 2021-04-22 04:00:01 +08:00
710482e9ed Update index.py 2021-04-13 15:21:10 +08:00
49dc230feb Update zimg.tpl 2021-04-13 15:15:03 +08:00
bf6cca7b95 up 2021-04-13 13:15:20 +08:00
6281e7ae2d up 2021-04-13 12:57:58 +08:00
4f488ba75f Update zimg.tpl 2021-04-13 12:56:45 +08:00
1fa59d0a08 Update index.py 2021-04-13 12:55:28 +08:00
ccc9bd26c5 up 2021-04-13 12:54:01 +08:00
1436a508a5 up 2021-04-13 12:51:56 +08:00
a9aabdfa0c Update install.sh 2021-04-13 12:43:18 +08:00
a6d2081d22 Update install.sh 2021-04-13 12:23:26 +08:00
88dba0e876 Update install.sh 2021-04-13 12:16:56 +08:00
88c9680682 Update install.sh 2021-04-13 12:10:49 +08:00
1e1157159a up 2021-04-13 12:00:48 +08:00
b2fe48e1f2 up 2021-04-11 18:38:52 +08:00
e1b5d6f8b1 Update phplib.conf 2021-04-11 18:34:22 +08:00
003a0bfacc Create openssl.sh 2021-04-11 18:32:26 +08:00
08b73394ee Update index.py 2021-04-11 12:19:26 +08:00
ec9d4c050f Update index.py 2021-04-11 12:13:21 +08:00
6460a0d7db up 2021-04-11 12:12:36 +08:00
f709a033a5 up 2021-04-11 12:05:31 +08:00
851d6829ee up 2021-04-11 11:51:30 +08:00
8b5f2aec6b Update index.py 2021-04-11 11:46:20 +08:00
32f911c3cf Update index.py 2021-04-11 11:37:09 +08:00
ef74376c21 Update index.py 2021-04-11 11:36:26 +08:00
2752d758b5 up 2021-04-11 11:25:02 +08:00
296d4fb96d Update install.sh 2021-04-11 11:02:26 +08:00
69f8a492c8 Delete api_login.txt 2021-04-11 10:47:19 +08:00
21cf32852b aria2 2021-04-11 10:46:53 +08:00
5eff5e7b1a Create check-ssh.sh 2021-03-09 22:49:59 +08:00
9edd79e5f1 up 2021-02-21 15:56:10 +08:00
4c2a42fc48 Update init.lua 2021-02-21 12:51:46 +08:00
10446a1934 Update luawaf.conf 2021-02-21 12:51:39 +08:00
3aeb2b0959 up 2021-02-21 12:34:58 +08:00
e9807280d5 Update init.lua 2021-02-21 12:05:38 +08:00
395f8b456a up 2021-02-21 11:28:46 +08:00
ef7c9d4e47 Update info.json 2021-02-21 11:06:14 +08:00
f8bea1c812 Update info.json 2021-02-19 21:52:02 +08:00
4a83cfba83 Update info.json 2021-02-19 21:51:37 +08:00
199aec01ca Update phplib.conf 2021-02-19 21:50:57 +08:00
65d6b5e360 Create seaslog.sh 2021-02-19 21:50:39 +08:00
dac412ad4e up 2021-02-19 21:42:51 +08:00
0f3aaf015a up 2021-02-19 21:39:41 +08:00
d48be332ca Update README.md 2021-02-19 21:31:05 +08:00
c943034145 up 2021-02-19 21:28:24 +08:00
e453a8fa79 Update phplib.conf 2021-02-19 21:21:41 +08:00
b84b7ec0d0 Update redis.sh 2021-02-19 21:19:04 +08:00
22b3b1e90f up 2021-02-19 21:18:19 +08:00
d1eb61bb84 Create mongodb.sh 2021-02-19 21:13:17 +08:00
aba61490d4 Update yaf.sh 2021-02-19 21:09:23 +08:00
298023f283 Update phplib.conf 2021-02-19 21:03:52 +08:00
e5e55431ed Create redis.sh 2021-02-19 21:03:33 +08:00
13c3a20e84 Update swoole.sh 2021-02-19 21:00:51 +08:00
b5a15244b3 up 2021-02-17 11:39:08 +08:00
cb446ae89c Update install.sh 2021-02-17 11:37:25 +08:00
83ccf6ff24 up 2021-02-16 15:05:53 +08:00
1eb20f7cb6 Update index.py 2021-02-16 14:46:09 +08:00
34574a36f1 up 2021-02-16 14:20:34 +08:00
91c8d1f47a up 2021-02-16 14:10:06 +08:00
0e5760eaa2 Update index.py 2021-02-16 13:45:36 +08:00
81a25eeedf Update my8.0.cnf 2021-02-16 12:57:22 +08:00
627c9efb44 Update my8.0.cnf 2021-02-16 12:55:39 +08:00
e76db6c669 Update my.cnf 2021-02-16 12:55:05 +08:00
c44e901992 Update install.sh 2021-02-16 11:56:59 +08:00
b88d03f316 Update my.cnf 2021-02-15 22:41:40 +08:00
ede3872627 Update my.cnf 2021-02-15 22:40:31 +08:00
29b50e057c Update index.py 2021-02-15 21:12:22 +08:00
ff75e0440f up 2021-02-15 17:58:57 +08:00
4ab8d5854b Update mysql.js 2021-02-15 15:32:08 +08:00
d555cdacb8 up 2021-02-15 15:27:32 +08:00
c704184884 up 2021-02-15 15:08:45 +08:00
9e58352fad Update mysql.js 2021-02-15 12:42:22 +08:00
0c7a32f372 up 2021-02-15 12:36:26 +08:00
604c5bc8a0 Update index.py 2021-02-06 14:01:10 +08:00
87c97694f7 Update index.py 2021-02-06 13:49:01 +08:00
aee7c53729 Update index.py 2021-02-05 22:05:55 +08:00
22e0ba7043 Update index.py 2021-02-05 21:44:26 +08:00
280de58a54 up 2021-02-05 21:43:07 +08:00
b6774d8656 up 2021-02-05 21:05:32 +08:00
268eb0eb2d Update my.cnf 2021-02-05 18:30:39 +08:00
fac0e1179b Update index.py 2021-02-05 17:49:31 +08:00
985c6f0a67 Update index.py 2021-02-05 16:57:54 +08:00
db1d9320bd Update index.py 2021-02-05 16:52:05 +08:00
0a110c4afa Update index.py 2021-02-05 16:36:08 +08:00
e436375090 Update index.py 2021-02-05 16:35:20 +08:00
8723ad9577 up 2021-02-05 16:09:41 +08:00
f8693c8cc3 up 2021-02-05 15:22:45 +08:00
1a1b0a59ee Update index.py 2021-02-05 14:39:30 +08:00
af22a68540 Update index.py 2021-02-05 14:37:21 +08:00
696df06794 up 2021-02-05 11:43:05 +08:00
9886e43335 up 2021-02-05 11:37:49 +08:00
3bd5886a6c up 2021-02-05 11:35:36 +08:00
aa071bfb15 up 2021-02-05 11:26:47 +08:00
98d3001861 Update mysql.js 2021-02-05 10:59:11 +08:00
36b55cc73c Update mysql.js 2021-02-05 02:25:13 +08:00
80f64066a7 Update mysql.js 2021-02-05 02:06:25 +08:00
a5ce95d831 Update config.inc.php 2021-02-04 20:31:28 +08:00
b07409050a Update mysql.js 2021-02-04 19:26:05 +08:00
a2ee7c9092 Update index.py 2021-02-04 19:18:29 +08:00
f9c9c91490 Update index.py 2021-02-04 19:04:35 +08:00
dca43f812d Update index.py 2021-02-04 18:59:50 +08:00
d93329478d Update crontab_api.py 2021-02-04 17:49:36 +08:00
3d296e4099 up 2021-02-04 02:49:43 +08:00
b7f9485ff6 up 2021-02-04 02:26:10 +08:00
65bd3fefa9 Update requirements.txt 2021-02-04 02:20:42 +08:00
5a4c831809 Update index.py 2021-02-04 02:09:47 +08:00
3c6ce19b3a Update index.py 2021-02-03 23:44:44 +08:00
cdb6966455 up 2021-02-03 23:20:52 +08:00
27c8142602 Update index.py 2021-02-03 23:00:17 +08:00
c04779efe2 mysql 主从可配置化end 2021-02-03 22:52:16 +08:00
be5a9f7b4b Update index.py 2021-02-03 21:26:09 +08:00
1564047a26 up 2021-02-03 21:20:39 +08:00
e561a909e7 up 2021-02-03 19:26:31 +08:00
3e06062784 Update install.sh 2021-02-03 14:19:09 +08:00
65a2af748b Update install.sh 2021-02-03 14:17:43 +08:00
febd9de71b Update index.py 2021-02-03 14:15:11 +08:00
870808b31b Update install.sh 2021-02-03 14:13:07 +08:00
debfdabde9 Update install.sh 2021-02-03 14:09:29 +08:00
6cf7152478 up 2021-02-03 14:02:12 +08:00
f75d121a59 up 2021-02-03 14:00:55 +08:00
407b5a619a Update mysql.js 2021-02-03 02:17:11 +08:00
b46bc89cb9 Update index.html 2021-02-03 02:17:06 +08:00
cb587b18bd Update index.py 2021-02-03 00:49:17 +08:00
8b67421c0c Update index.py 2021-02-03 00:37:16 +08:00
64f882c6b8 Update index.py 2021-02-03 00:32:06 +08:00
eb6590a275 Update mysql.js 2021-02-02 23:19:04 +08:00
595c238fb5 up 2021-02-02 22:26:50 +08:00
80d1e4efe7 Update index.py 2021-02-02 22:06:49 +08:00
8ee6f9d190 up 2021-02-02 21:30:48 +08:00
94a2f88633 Update index.py 2021-02-02 20:49:41 +08:00
605cf36e9c Update my.cnf 2021-02-02 17:42:08 +08:00
21194aa285 up 2021-02-02 17:31:39 +08:00
e3876de3d2 Update my.cnf 2021-02-02 15:34:45 +08:00
1e054f9801 up 2021-02-02 15:33:07 +08:00
df048c6bd6 up 2021-02-02 15:32:06 +08:00
3056fb9ceb up 2021-02-02 15:21:37 +08:00
bb655b55e5 Update index.py 2021-02-02 03:59:06 +08:00
97ab18a771 Update index.html 2021-02-02 03:58:58 +08:00
26760502d0 mysql init.d 2021-02-02 03:50:30 +08:00
126c7e08e3 mysql conf 2021-02-02 03:49:06 +08:00
5e55cf753e Update install.sh 2021-02-02 01:37:06 +08:00
da8b0ccbfc Update task.py 2021-02-02 01:33:42 +08:00
c746e8e139 Update task.py 2021-02-02 01:31:37 +08:00
0e2df5620e up 2021-02-02 00:29:10 +08:00
b1b43120ea Update info.json 2021-02-01 22:31:10 +08:00
e854cc083f up 2021-02-01 22:26:55 +08:00
791f2b8ec9 up 2021-02-01 22:13:59 +08:00
0c6b293337 Update info.json 2021-02-01 21:16:55 +08:00
da9b3bf435 update mysql version 2021-02-01 20:54:27 +08:00
301086faa1 up 2021-02-01 20:49:55 +08:00
3b6b54103b web ssh opt 2021-02-01 20:13:14 +08:00
6dda90b64f Update mw.py 2021-02-01 19:55:21 +08:00
d28fcce8b6 Update info.json 2021-01-30 16:24:37 +08:00
ba2da974c9 Update __init__.py 2021-01-30 15:05:44 +08:00
024f8bd62f Update __init__.py 2021-01-30 14:54:37 +08:00
fe7853781b Update __init__.py 2021-01-30 13:56:08 +08:00
d92010bfe0 Update __init__.py 2021-01-30 13:33:11 +08:00
2631f1771c Update __init__.py 2021-01-30 13:32:26 +08:00
4cf7a6b8fe Update __init__.py 2021-01-30 13:18:50 +08:00
af460ffed6 Update index.py 2021-01-29 19:59:49 +08:00
a7982c4df3 Update index.py 2021-01-29 19:54:32 +08:00
0850654da8 Update install.sh 2021-01-29 19:34:58 +08:00
086e050914 Update index.html 2021-01-29 19:32:44 +08:00
4c57b9a2e6 Update index.py 2021-01-29 19:26:09 +08:00
ca7095c65a Update index.html 2021-01-29 19:22:45 +08:00
2c3f2e797d Update swap.tpl 2021-01-29 19:21:41 +08:00
cccd3ff7fc Update index.py 2021-01-29 19:13:38 +08:00
effc3ba296 yp 2021-01-29 19:13:11 +08:00
e96fdea003 Update index.py 2021-01-29 18:51:38 +08:00
00a43549a2 Update index.py 2021-01-29 18:48:32 +08:00
ebd09842a2 up 2021-01-29 18:42:39 +08:00
1eccc9cb7c Update index.py 2021-01-29 18:13:05 +08:00
a44df8dd9a Update swap.tpl 2021-01-29 18:07:59 +08:00
58d78d5c5d swap 2021-01-29 18:05:43 +08:00
9babeb4373 Update socket5.js 2021-01-29 17:15:53 +08:00
8345bd8bb5 up 2021-01-29 17:06:53 +08:00
9106246891 up 2021-01-29 17:03:34 +08:00
21209a75d8 Update index.py 2021-01-29 16:52:54 +08:00
3b6d50661b up 2021-01-29 16:50:39 +08:00
295cc70e0a Update index.py 2021-01-29 16:46:59 +08:00
c7fa266ae1 Update index.py 2021-01-29 16:46:38 +08:00
8788afc35f o 2021-01-29 16:26:56 +08:00
44c55ee923 up 2021-01-29 16:13:40 +08:00
2073fbd680 up 2021-01-29 15:46:36 +08:00
1b876d4cac Update install.sh 2021-01-29 15:35:31 +08:00
0961b233e0 socket5 2021-01-29 15:27:08 +08:00
184bcf88d7 Update install.sh 2021-01-12 13:13:30 +08:00
3f07a11b53 Update gunicorn.conf 2021-01-05 17:59:28 +08:00
aa3a66cf01 Create gunicorn.conf 2021-01-05 17:39:58 +08:00
0bc8f670f5 Update index.py 2020-10-13 11:57:36 +08:00
63cb8f0e84 Update install.sh 2020-10-13 11:54:36 +08:00
5a17df7c5c Update install.sh 2020-10-13 11:51:43 +08:00
3ce9735ff8 Update install.sh 2020-10-13 11:47:55 +08:00
1819b814a3 Update install.sh 2020-10-13 11:45:30 +08:00
f5c5bd03e6 Update eaccelerator.sh 2020-09-30 09:28:27 +08:00
04c6d4b3cc Update index.py 2020-09-30 03:11:10 +08:00
7e5116ba59 Update index.py 2020-09-30 03:10:48 +08:00
44d254415e Update index.py 2020-09-30 03:03:48 +08:00
0efba47c53 Update index.py 2020-09-30 02:53:59 +08:00
c7be9b7230 Update index.py 2020-09-30 02:53:39 +08:00
311310e04c Update index.py 2020-09-30 02:52:21 +08:00
59ca997372 Update index.py 2020-09-30 02:50:47 +08:00
27a96495ae up 2020-09-30 02:48:16 +08:00
cd1662761b Update php-fpm-52.conf 2020-09-30 02:41:35 +08:00
4995131e24 Update php-fpm-52.conf 2020-09-30 02:39:08 +08:00
ae9989a13f 兼容php5.2 2020-09-30 02:22:31 +08:00
db143ea39f xhporf 52 2020-09-30 02:06:04 +08:00
7582b0e6ba php mysql 2020-09-28 17:13:15 +08:00
1ce6cbef51 Update install.sh 2020-09-28 12:52:11 +08:00
e136330e36 Update install.sh 2020-09-28 11:27:12 +08:00
346f09dabd Update install.sh 2020-09-28 10:57:29 +08:00
0d56f1ab5f Update redis.sh 2020-09-27 11:49:11 +08:00
2f771b1f05 Update redis.sh 2020-09-27 11:44:32 +08:00
1862e68c52 Update phplib.conf 2020-09-27 11:42:04 +08:00
aaca9cc654 Create redis.sh 2020-09-27 11:40:17 +08:00
bda83eb434 up 2020-09-27 00:15:39 +08:00
6f5838306d Update phplib.conf 2020-09-26 23:41:56 +08:00
615e1b60b7 up 2020-09-26 23:40:25 +08:00
4300a532ba Create memcache.sh 2020-09-26 22:45:41 +08:00
52c92183f5 Update install.sh 2020-09-26 22:27:13 +08:00
feda58b8c4 Update install.sh 2020-09-26 20:48:43 +08:00
a41d0b4553 Update install.sh 2020-09-26 20:46:39 +08:00
68e9fa157d Update install.sh 2020-09-26 20:44:07 +08:00
81f79582b5 Update zendguardloader.sh 2020-09-26 20:42:21 +08:00
552aa85eb6 Update install.sh 2020-09-26 20:29:32 +08:00
5119e522d4 Update zendoptimizer.sh 2020-09-26 20:16:19 +08:00
46f112fe7f up 2020-09-26 20:10:07 +08:00
2215c1bd38 Update zendguardloader.sh 2020-09-26 20:09:08 +08:00
aa38037087 Update index.py 2020-09-26 20:01:27 +08:00
b48efb4607 up 2020-09-26 19:59:16 +08:00
3c22dd6380 up 2020-09-26 19:54:17 +08:00
9127ed5220 Update index.py 2020-09-26 19:50:40 +08:00
a04c6b46af Update index.py 2020-09-26 19:43:04 +08:00
ed7bc1cdf3 up 2020-09-26 19:39:12 +08:00
6d191fc162 Update install.sh 2020-09-26 19:33:12 +08:00
b14f22a0cf Update install.sh 2020-09-26 19:29:39 +08:00
bb9fe44a0f up 2020-09-26 19:13:55 +08:00
ee6adfa83c Update install.sh 2020-09-26 19:06:42 +08:00
8d990b3f96 Update install.sh 2020-09-26 19:04:52 +08:00
9b0b5d1504 Update install.sh 2020-09-26 19:01:27 +08:00
aac1cc30a5 Update install.sh 2020-09-26 18:58:56 +08:00
e8f1cb4e02 Update install.sh 2020-09-26 18:54:30 +08:00
f973794e4a Update install.sh 2020-09-26 18:50:06 +08:00
062a8917cb Update install.sh 2020-09-26 18:48:21 +08:00
3c412c91f7 Update install.sh 2020-09-26 18:45:56 +08:00
b3f338e4e0 Update install.sh 2020-09-26 18:37:50 +08:00
78f422c64a Update install.sh 2020-09-26 18:37:26 +08:00
6f76846497 up 2020-09-26 18:32:37 +08:00
638426b81b Update config_api.py
优化计划任务管理
2020-09-19 20:27:09 +08:00
a982e8a0e2 up 2020-09-19 16:03:09 +08:00
79a2954486 up 2020-09-19 16:01:46 +08:00
3e73314cb1 up 2020-09-19 15:36:56 +08:00
92e94ab4e9 Update solr.js 2020-09-15 13:26:01 +08:00
1e0ec8e17e Update redis.conf 2020-09-14 01:04:44 +08:00
a1e0e95925 Update index.py 2020-08-04 21:51:10 +08:00
ceb1a7828a Update qbittorrent.tpl 2020-08-04 21:42:05 +08:00
02beb55896 Update qbittorrent.tpl 2020-08-04 19:24:01 +08:00
f53377cc7d Update qbittorrent.tpl 2020-08-04 18:56:54 +08:00
02fbb7cdcf Update commit.tpl 2020-07-31 00:22:01 +08:00
58059111c1 Update qbittorrent_worker.py 2020-07-25 17:35:48 +08:00
f51cc16500 Update qbittorrent_worker.py 2020-07-25 13:38:40 +08:00
1d6fa13a94 Update qbittorrent_worker.py 2020-07-25 13:25:23 +08:00
6924adbda3 Update qbittorrent_worker.py 2020-07-25 13:22:50 +08:00
983dde38d2 Update qbittorrent_worker.py 2020-07-25 12:21:08 +08:00
bda0753b77 Update qb.sql 2020-07-25 11:08:14 +08:00
93d9dbfd20 Update qb.sql 2020-07-25 11:07:52 +08:00
0a277b7e52 Update qbittorrent_worker.py 2020-07-25 11:03:36 +08:00
4825a1ca09 Update qbittorrent_worker.py 2020-07-23 11:20:31 +08:00
21dd6f39a8 Update qbittorrent_worker.py 2020-07-23 00:17:27 +08:00
261b85dbda Update install.sh 2020-07-22 23:59:34 +08:00
4716cff256 Update qbittorrent_worker.py 2020-07-22 23:03:02 +08:00
d86c6ad6ee Update qbittorrent_worker.py 2020-07-22 22:52:48 +08:00
bd7906595a Update qb.conf 2020-07-22 22:16:45 +08:00
f00478cf17 Update qbittorrent_worker.py 2020-07-22 20:59:24 +08:00
1a24d11137 Update install.sh 2020-07-22 20:10:02 +08:00
b8185e042f Update install.sh 2020-07-22 20:07:50 +08:00
318cc79b8e Update install.sh 2020-07-22 19:53:02 +08:00
389abf794f Update install.sh 2020-07-22 19:50:28 +08:00
1d37ec38ee Update qbittorrent_worker.py 2020-07-22 19:46:34 +08:00
fd2a9223ff Update qbittorrent_worker.py 2020-07-22 19:46:17 +08:00
84e7da76b5 Update install.sh 2020-07-22 17:49:06 +08:00
90d30df686 Update qbittorrent_worker.py 2020-07-22 17:32:52 +08:00
9fa9ed9f6e Update qb.conf 2020-07-22 17:32:09 +08:00
c26867c80b Update index.py 2020-07-22 17:31:35 +08:00
221a005fc7 Update install.sh 2020-07-22 17:20:07 +08:00
7fb61a5121 Delete ss1.jpg 2020-07-21 16:08:26 +08:00
6eadbcd53e up 2020-07-16 16:30:00 +08:00
b43da4eea8 Update yaf.sh 2020-07-15 18:24:03 +08:00
1590e1061c update 2020-07-15 17:39:07 +08:00
3ac32665b8 Update pcntl.sh 2020-07-15 17:36:36 +08:00
97f01aeb74 up 2020-07-15 17:34:57 +08:00
92e3bd82ef Update phplib.conf 2020-07-15 17:33:05 +08:00
ad2ce68a49 up 2020-07-15 17:28:18 +08:00
75f212bec7 up 2020-07-15 17:00:53 +08:00
13f6ee18f9 Update system_api.py 2020-07-15 12:38:32 +08:00
571d2056fb Update system_api.py 2020-07-15 12:34:48 +08:00
08ef87c77e Update system_api.py 2020-07-15 12:29:45 +08:00
5d2e7acc95 Update system_api.py 2020-07-15 12:29:07 +08:00
58e18e3ebb Update system_api.py 2020-07-15 12:23:57 +08:00
a4731e0053 Update system_api.py 2020-07-15 12:15:15 +08:00
db22749219 Update system_api.py 2020-07-15 12:13:44 +08:00
942c0023fb Update system_api.py 2020-07-15 12:12:18 +08:00
0b4fa3ea5c Update system_api.py 2020-07-15 11:59:05 +08:00
e23b15ccd1 Update system_api.py 2020-07-15 11:54:15 +08:00
0f515829fe up 2020-07-15 11:36:30 +08:00
95a3de24b3 up 2020-07-15 11:07:09 +08:00
154b543f82 up op 2020-07-15 10:43:10 +08:00
3b3f22f4fa up 2020-07-15 09:40:02 +08:00
6cce72c966 Update phplib.conf 2020-07-15 08:52:46 +08:00
2309d07d26 up 2020-07-15 08:49:30 +08:00
3617eb6028 opcache update 2020-07-15 08:42:24 +08:00
9ce4de6237 yaf 2020-07-14 16:30:44 +08:00
02e8c98de0 up 2020-07-14 16:28:21 +08:00
566c6d3b24 up 2020-07-14 16:21:56 +08:00
0b8d662be1 Create mongodb.sh 2020-07-14 16:20:46 +08:00
71602d2440 Update phplib.conf 2020-07-14 16:20:33 +08:00
212aea1fc3 Update phplib.conf 2020-07-14 16:12:19 +08:00
8a5d8236e9 Update mongodb.sh 2020-07-14 16:11:51 +08:00
ad484adf2a Update mongodb.sh 2020-07-14 15:48:20 +08:00
04c2f9d155 Update lib.sh 2020-07-14 15:48:16 +08:00
d387e0ef22 Update zendguardloader.sh 2020-07-14 15:25:03 +08:00
dc74db0313 Update phplib.conf 2020-07-14 15:24:03 +08:00
2bc336ea7d Create zendguardloader.sh 2020-07-14 15:17:12 +08:00
5b13be2dd9 Update imagemagick.sh 2020-07-14 15:05:43 +08:00
f94db9bcdc Update imagemagick.sh 2020-07-14 15:05:23 +08:00
da599b3947 Update imagemagick.sh 2020-07-14 15:04:54 +08:00
f559e19da8 Update imagemagick.sh 2020-07-14 15:04:29 +08:00
866fc68a81 Update imagemagick.sh 2020-07-14 15:04:02 +08:00
546bd4f577 Update lib.sh 2020-07-14 14:54:10 +08:00
37bc9a71b3 Update lib.sh 2020-07-14 14:15:18 +08:00
fab204143a up 2020-07-14 14:05:08 +08:00
46a7f8d754 Update memcached.sh 2020-07-14 14:02:52 +08:00
e0b1f8b622 up 2020-07-14 14:01:35 +08:00
ebf63d0fae up 2020-07-14 14:01:10 +08:00
53ed086f84 Update memcached.sh 2020-07-14 13:58:05 +08:00
44555af3da Update memcached.sh 2020-07-14 13:16:57 +08:00
042880b115 Update imagemagick.sh 2020-07-14 13:14:20 +08:00
eb99b18bd3 Update apc.sh 2020-07-14 13:10:36 +08:00
eda0911a2e Update apc.sh 2020-07-14 13:09:29 +08:00
4a92866138 Update eaccelerator.sh 2020-07-14 13:02:09 +08:00
32f64b3dab Update eaccelerator.sh 2020-07-14 13:01:35 +08:00
3f94905735 Update apc.sh 2020-07-14 12:57:02 +08:00
e7b69c46a3 Update apc.sh 2020-07-14 12:55:43 +08:00
f1695efa6e Update apc.sh 2020-07-14 12:53:52 +08:00
cd4996477b Update opcache.sh 2020-07-14 12:53:03 +08:00
6490610c30 Update site_api.py 2020-07-14 12:46:26 +08:00
49e2eb47ef Create php8.ini 2020-07-14 12:43:59 +08:00
34504e80a8 Update index.py 2020-07-14 12:36:08 +08:00
dccf70fef9 Update install.sh 2020-07-14 12:22:13 +08:00
d74ed17e9e up 2020-07-14 12:12:54 +08:00
72b2da6558 Update info.json 2020-07-14 12:09:55 +08:00
7cbc4e0d38 Create install.sh 2020-07-14 12:06:13 +08:00
23889fbe29 up 2020-07-14 11:48:22 +08:00
c44d9b4a52 Update lib.sh 2020-07-14 09:22:04 +08:00
1f00ebeefb Update lib.sh 2020-07-14 09:18:29 +08:00
a06d55531e up 2020-07-14 09:08:19 +08:00
7f5dcc2667 Update install.sh 2020-07-14 09:02:10 +08:00
f1ec8ad714 Update install.sh 2020-07-14 08:46:30 +08:00
b1a03e50b2 Update install.sh 2020-07-14 08:44:31 +08:00
85c80cfe28 Update install.sh 2020-07-14 08:38:10 +08:00
89d15a2f10 Create wmcms.conf 2020-07-13 18:17:46 +08:00
6225e77eb8 up 2020-07-13 00:21:30 +08:00
a1f03de98d up 2020-07-13 00:14:56 +08:00
c8105363df Update install.sh 2020-07-13 00:09:24 +08:00
5f416ba2d4 xhprof update 2020-07-13 00:01:08 +08:00
bd6cb8f029 Update index.py 2020-07-12 23:54:01 +08:00
03e2b95305 Update index.py 2020-07-12 23:51:18 +08:00
a9a26a3b84 Update index.py 2020-07-12 23:50:30 +08:00
c89c4963a2 Update index.py 2020-07-12 23:47:46 +08:00
ec83257a27 Update index.py 2020-07-12 23:43:34 +08:00
853234c4b6 Update lib.sh 2020-07-12 23:37:23 +08:00
29f2a3ce7e Update php7.ini 2020-07-12 23:37:12 +08:00
6da5641263 Update php5.ini 2020-07-12 23:37:10 +08:00
2b7514c5b4 Update install.sh 2020-07-12 18:37:13 +08:00
65ba422c77 Create app_start.php 2020-07-12 18:15:03 +08:00
5edf8b8dda xhprof 2020-07-12 18:14:56 +08:00
6384c1bd13 Update lib.sh 2020-07-12 15:27:25 +08:00
53398031b1 up 2020-07-12 15:10:39 +08:00
060b2160aa up 2020-07-12 14:46:16 +08:00
b0d1586d78 Update index.html 2020-07-12 14:32:17 +08:00
0838f759a1 php73 2020-07-12 00:22:04 +08:00
d3a539638e PHP 72 2020-07-12 00:18:46 +08:00
59abf77572 PHP 74 2020-07-12 00:15:16 +08:00
1467efa015 PHP 55 2020-07-12 00:12:41 +08:00
56dca95325 Update apc.sh 2020-07-12 00:06:31 +08:00
5d705246b9 PHP 54 2020-07-12 00:03:50 +08:00
5423046937 php 70 2020-07-11 23:58:39 +08:00
3068007aa8 Update imagemagick.sh 2020-07-11 23:53:19 +08:00
a8f8e84ae3 up 2020-07-11 23:51:07 +08:00
3d66bb47bd up 2020-07-11 23:50:34 +08:00
cc3757e869 Update redis.sh 2020-07-11 23:49:51 +08:00
f6b9e2da54 php 53,56,71修复版。 2020-07-11 23:47:58 +08:00
f752d99e8b Update memcached.sh 2020-07-11 23:29:49 +08:00
69947f5353 Update memcached.sh 2020-07-11 23:27:57 +08:00
4d73843e00 Update memcached.sh 2020-07-11 23:18:16 +08:00
f882c85e83 Update memcached.sh 2020-07-11 23:04:06 +08:00
d9c886ce95 up 2020-07-11 23:02:03 +08:00
200bf07644 Update memcached.sh 2020-07-11 22:55:30 +08:00
b981d89077 up 2020-07-11 22:52:40 +08:00
8ab69bf40f Update memcached.sh 2020-07-11 22:47:46 +08:00
b7a2b6cbf8 Update lib.sh 2020-07-11 22:11:37 +08:00
d740ca4d2e up 2020-07-11 22:07:35 +08:00
1bb9613de1 Update memcached.sh 2020-07-11 22:04:57 +08:00
73cf09e75e Update lib.sh 2020-07-11 22:04:25 +08:00
fb5c483b22 Update nginx.conf 2020-07-11 10:22:28 +08:00
8d9126ea80 Update firewall_api.py 2020-07-11 02:37:38 +08:00
81ddf69370 Update firewall_api.py 2020-07-11 02:30:37 +08:00
0545fffd8c Update firewall_api.py 2020-07-11 02:21:29 +08:00
8fa6060729 Update index.py 2020-07-11 01:24:54 +08:00
63c3e513be Update redis.tpl 2020-07-11 00:37:56 +08:00
5249658207 Update index.py 2020-07-11 00:21:15 +08:00
10585f6406 Update __init__.py 2020-07-10 16:22:14 +08:00
72d5939ec3 Update update.sh 2020-07-10 15:59:04 +08:00
6c65e45d00 2020-07-10 解决public冲突。 2020-07-10 15:57:25 +08:00
89e3940771 Update requirements.txt 2020-07-10 13:47:47 +08:00
f802cc36d3 Update install_centos.sh 2020-07-09 20:05:14 +08:00
d938affe9b up 2020-07-09 19:26:34 +08:00
c1af2aaa63 Update requirements.txt 2020-07-09 19:07:08 +08:00
1fec620adb Update install_centos.sh 2020-07-09 18:54:16 +08:00
245ee059a1 Update update.sh 2020-07-04 12:41:27 +08:00
b39bf7e4d7 Create clear.sh 2020-07-04 12:19:03 +08:00
9533cc3960 up 2020-06-28 13:49:44 +08:00
8eebaebdf6 Update install.sh 2020-06-28 13:49:06 +08:00
6bde23e737 Update install.sh 2020-06-28 13:44:38 +08:00
1a61754255 Update install.sh 2020-06-28 13:16:02 +08:00
9496ee401b Update info.json 2020-06-28 13:10:34 +08:00
e35b0ecf76 优化openresty安装 2020-06-28 13:09:15 +08:00
f2505df3d7 Update redis.tpl 2020-06-28 12:58:45 +08:00
45e8c22825 Update crontab_api.py 2020-06-24 00:37:02 +08:00
f7115481dd Create v2ray.conf 2020-06-20 18:27:07 +08:00
b728766677 vmess 更新 2020-06-20 18:22:46 +08:00
6912798076 Update index.py 2020-06-20 17:19:15 +08:00
667210fc24 Update black_list.txt 2020-06-18 22:35:07 +08:00
b42710c0ed Update gogs.js 2020-06-18 15:54:10 +08:00
490df14a0a Update gogs.js 2020-06-18 15:49:25 +08:00
8e174f837d up 2020-06-16 22:18:44 +08:00
48c24c0126 默认开启443端口 2020-06-11 23:39:31 +08:00
bd352d946e Update install.sh 2020-06-08 23:18:45 +08:00
d956531421 v2ray 2020-06-08 08:45:48 +08:00
679c74b15a up 2020-06-08 08:42:18 +08:00
907e1ca275 Update index.py 2020-06-08 08:29:49 +08:00
caefc23670 Update index.py 2020-06-08 08:25:47 +08:00
53510581aa Update info.json 2020-06-08 08:13:09 +08:00
27b1d94a86 Update index.py 2020-06-08 08:11:33 +08:00
8e6edf8cd7 Update index.py 2020-06-08 08:10:52 +08:00
2651ed8ecb v2ray 2020-06-08 08:06:14 +08:00
bffe9547ff update redis 2020-06-07 16:29:49 +08:00
d6cae70249 shadowsocks 2020-06-06 23:21:37 +08:00
ff7e063f09 Update shadowsocks.json 2020-06-06 18:58:12 +08:00
3b53bcbcdb Update shadowsocks.tpl 2020-06-05 17:41:53 +08:00
497d6dd961 Update shadowsocks.tpl 2020-06-05 17:31:58 +08:00
41d33eef54 Update index.py 2020-06-02 23:05:53 +08:00
2ff18a9cf9 Update shadowsocks.js 2020-06-02 16:57:17 +08:00
0c43fcda07 shadowsocks 2020-06-02 16:55:41 +08:00
d0bb505b3f 更新PHP版本 2020-05-20 10:43:48 +08:00
a21cca51c3 simdht 2020-05-17 22:36:58 +08:00
30cb7516b1 Update requirements.txt 2020-05-12 01:21:41 +08:00
06e6deff87 Update requirements.txt 2020-04-20 14:41:01 +08:00
a4ce338088 up 2019-12-13 02:54:48 +08:00
45c7430af3 Update requirements.txt 2019-12-12 00:18:49 +08:00
b0b34a6ea1 Update requirements.txt 2019-12-12 00:14:26 +08:00
0fcada900b flask cache 2019-12-08 21:10:22 +08:00
ca5729e26d Update requirements.txt 2019-12-07 01:19:38 +08:00
22eed3f67b Update requirements.txt 2019-12-07 01:19:14 +08:00
cd0799cc15 Update index.py 2019-12-07 01:15:11 +08:00
a0724c4fa9 Update index.py 2019-12-07 01:08:18 +08:00
0145d8db47 Update index.py 2019-12-07 01:06:22 +08:00
7ba4d2332d Update index.py 2019-12-07 01:05:44 +08:00
fb5e522a81 up 2019-12-07 01:04:34 +08:00
71dae04946 up 2019-12-07 01:02:25 +08:00
8418c3c3a0 Update index.py 2019-12-07 00:57:56 +08:00
94ac06b35c up 2019-12-07 00:48:18 +08:00
9fd6160571 系统优化插件 2019-12-07 00:43:57 +08:00
4b9ffbe71f Update jenkins.js 2019-12-06 19:20:38 +08:00
8018682049 Update index.py 2019-12-06 19:16:17 +08:00
f44ff2fb0d Update jenkins.js 2019-12-06 19:09:55 +08:00
7a79388978 up 2019-12-06 19:09:32 +08:00
0d5af34b19 Update index.py 2019-12-06 18:07:02 +08:00
d05f5ebff8 jenkins plugin init 2019-12-06 18:01:46 +08:00
4c64feef62 Update index.py 2019-12-06 16:00:33 +08:00
0491503774 walle ok 2019-12-06 15:18:30 +08:00
fa67ee7e71 Update walle.js 2019-12-06 04:01:45 +08:00
1ae0682d77 Update install.sh 2019-12-06 03:48:55 +08:00
357749f22d Update install.sh 2019-12-06 03:28:40 +08:00
9a078193bd Update install.sh 2019-12-06 03:27:15 +08:00
fd9746b7ef update 2019-12-06 03:27:05 +08:00
a2de2b6ff1 Update requirements.txt 2019-12-06 03:06:43 +08:00
970706028a up 2019-12-06 03:02:43 +08:00
ced6c480d1 Update walle.conf 2019-12-06 02:31:30 +08:00
d795097290 Update install.sh 2019-12-06 00:12:14 +08:00
084a21a071 Update install.sh 2019-12-06 00:04:13 +08:00
590a13256d up 2019-12-05 23:52:04 +08:00
49c2250900 Update config_api.py 2019-11-30 21:41:03 +08:00
a6d70cd8a6 up 2019-11-30 18:28:34 +08:00
ed6d8e0d34 up 2019-11-30 18:02:21 +08:00
c0f37ceb08 up 2019-11-30 17:38:50 +08:00
d2160f388d up 2019-11-30 16:55:45 +08:00
1617bd521a up 2019-11-30 01:24:28 +08:00
15e475d667 up 2019-11-29 23:59:50 +08:00
ed779fd026 up 2019-11-29 23:00:04 +08:00
214634606f Update yar.sh 2019-11-29 22:08:38 +08:00
afaecef2d7 up 2019-11-29 21:51:49 +08:00
c76920f531 up 2019-11-29 20:22:45 +08:00
1657823988 Update swoole.sh 2019-11-29 19:30:46 +08:00
df9c7928ae up 2019-11-29 19:27:08 +08:00
f44710c0f1 update 2019-11-29 19:22:16 +08:00
adbfe2fdef up 2019-11-29 18:29:23 +08:00
910198ffc3 swoole 4.4.12 2019-11-29 18:14:45 +08:00
19a172347f Update yaf.sh 2019-11-29 17:51:41 +08:00
ccf00d17f6 up 2019-11-29 17:41:55 +08:00
1ac01637ef up 2019-11-29 17:21:38 +08:00
3861de61aa up 2019-11-29 16:58:45 +08:00
549686b9ef up 2019-11-29 16:36:09 +08:00
c484fd5136 updated 2019-11-29 16:25:44 +08:00
1f3cb33bd2 up 2019-11-29 15:52:49 +08:00
438628c773 Update install.sh 2019-11-23 17:53:39 +08:00
aeac132b09 up 2019-11-22 13:37:34 +08:00
8664186f7c Update install.sh 2019-11-22 13:30:13 +08:00
07e716c95f up 2019-11-22 13:25:24 +08:00
092b9ed4e8 up 2019-11-22 13:24:14 +08:00
2ae578a010 Update install.sh 2019-11-22 13:13:19 +08:00
df14029aa9 Update lib.sh 2019-11-22 13:05:39 +08:00
4b3c44cc18 Update install_centos.sh 2019-10-03 01:58:24 +08:00
859df3cb04 说明 2019-09-26 21:08:53 +08:00
51485fcabb Update index.py 2019-09-25 19:43:59 +08:00
43d2dcb81c up 2019-09-14 00:26:03 +08:00
9d020beff0 Update index.html 2019-09-14 00:06:48 +08:00
02af143025 up 2019-09-14 00:03:22 +08:00
826bf7f540 Update update_centos.sh 2019-09-13 18:49:32 +08:00
8f4b72d551 Update index.py 2019-09-13 01:43:05 +08:00
67dbfc8569 Update index.py 2019-09-13 01:42:30 +08:00
71c7a38297 Update rsyncd.tpl 2019-09-13 01:30:24 +08:00
7c3ba76494 Update index.py 2019-09-13 00:02:55 +08:00
a223f1e722 Update rsyncd.tpl 2019-09-12 23:55:25 +08:00
a71d0b5a55 Update rsyncd.tpl 2019-09-12 23:46:15 +08:00
37cb8c3898 Update rsyncd.tpl 2019-09-12 23:31:29 +08:00
c3b4fffd17 Update README.md 2019-09-12 23:21:39 +08:00
b3c917f456 Update solr.tpl 2019-09-12 23:12:41 +08:00
7f58398a43 Update rsyncd.tpl 2019-09-12 22:57:27 +08:00
777eb0c4a2 Update rsyncd.tpl 2019-09-12 22:56:32 +08:00
9c69443e2f Update index.py 2019-09-12 22:51:51 +08:00
440f68529c Update index.py 2019-09-12 22:49:35 +08:00
50706f9286 up 2019-09-12 22:38:34 +08:00
44e3434b6d Update index.py 2019-09-12 18:48:57 +08:00
a096631ab0 update 2019-09-06 21:06:12 +08:00
25ee8ab83b Update memcached.sh 2019-09-06 21:03:35 +08:00
28a9fdcdc8 update 2019-08-26 22:14:22 +08:00
ee12d11709 up 2019-08-26 19:16:38 +08:00
6db083584e Update install.sh 2019-08-26 18:50:05 +08:00
d833c9b441 up 2019-08-25 14:27:34 +08:00
7c2e77dbc5 Update web.xml 2019-08-23 12:15:06 +08:00
2e0dcb9b00 Update web.xml 2019-08-23 11:54:06 +08:00
6063ce9fcb 配置更新 2019-08-23 11:53:56 +08:00
2d6c2e8f9c Update solr.js 2019-08-22 21:11:28 +08:00
e6b9427b3a Update solr.js 2019-08-22 21:02:44 +08:00
6a0a53ce7e up 2019-08-20 19:11:01 +08:00
5cec4d5c82 Update solrconfig.xml 2019-08-20 18:51:07 +08:00
0d403c9c8f up 2019-08-20 18:46:32 +08:00
c1e66ba5a7 Update .gitignore 2019-08-20 18:33:18 +08:00
94c3d7d2e2 更新 2019-08-20 18:32:30 +08:00
202cfdb628 Create solrconfig.xml 2019-08-20 16:23:12 +08:00
d9176781ab Update install.sh 2019-08-20 15:55:09 +08:00
0979dc67e8 Update install.sh 2019-08-20 14:03:52 +08:00
2e02f6d274 Update install.sh 2019-08-20 14:01:02 +08:00
3893f057e1 Update info.json 2019-08-20 12:44:11 +08:00
7a25982022 Update index.py 2019-08-18 20:09:35 +08:00
824abad8e5 Update go-fastdfs.tpl 2019-08-07 17:09:05 +08:00
94239e2e44 go-fastdfs-web 2019-08-07 16:36:53 +08:00
72f1d1c43a Update index.py 2019-08-07 16:09:27 +08:00
a026da484f Update full.py 2019-08-06 23:35:39 +08:00
2e5c5efde7 Update full.py 2019-08-06 22:49:49 +08:00
72edb784db Update full.py 2019-08-06 22:49:37 +08:00
53c66ed216 Update full.py 2019-08-06 22:24:15 +08:00
f510735231 Update full.py 2019-08-06 22:22:45 +08:00
e6ea2737c0 up 2019-08-06 21:21:41 +08:00
65e84830a2 Update full.py 2019-08-06 20:08:52 +08:00
687decec5f solr全量同步脚本 2019-08-06 19:09:23 +08:00
967ca42c6b Create full.py 2019-08-06 19:05:27 +08:00
457f861ee0 Update solr.js 2019-08-06 14:13:27 +08:00
572a8d82b0 Update solr.js 2019-08-06 14:09:28 +08:00
0cbf7bb65a Update index.py 2019-08-06 00:35:25 +08:00
647c997a21 Update index.py 2019-08-06 00:31:45 +08:00
1575e2976b Update install.sh 2019-08-06 00:19:49 +08:00
9198799caa Update index.py 2019-08-06 00:14:29 +08:00
e766058c57 Update index.py 2019-08-05 23:54:05 +08:00
d7c758ccd5 Update index.py 2019-08-05 22:54:47 +08:00
ed3f29b824 Update index.py 2019-08-05 22:49:08 +08:00
789bd8fd70 Update install.sh 2019-08-05 22:32:53 +08:00
c4f11af537 Update index.py 2019-08-05 22:30:07 +08:00
fe939bc073 Update install.sh 2019-08-05 22:29:21 +08:00
ae18a12894 Update install.sh 2019-08-05 22:21:20 +08:00
0f51e27a14 Update install.sh 2019-08-05 22:10:31 +08:00
3409849c4a init 2019-08-05 15:20:01 +08:00
72900d7df6 修复错误 2019-08-05 13:21:33 +08:00
2dae8ff902 fastdfs ok 2019-08-03 13:23:34 +08:00
b1dbaf1d6d Update index.py 2019-08-03 11:03:45 +08:00
7bd49e6de1 up 2019-08-03 11:00:59 +08:00
a63bf8c39a up 2019-08-03 01:58:28 +08:00
8e14e0c82f Update go-fastdfs.tpl 2019-08-02 23:42:01 +08:00
e631259caa up 2019-08-02 22:35:24 +08:00
ff7b6a52e6 Update install.sh 2019-08-02 21:00:50 +08:00
f336d977ef Update install.sh 2019-08-02 20:26:32 +08:00
3b9d2c8c37 Update fastdfs.js 2019-08-02 19:03:45 +08:00
22699b9d6b up 2019-08-02 19:01:53 +08:00
2468e8ca6b Update install.sh 2019-08-02 18:58:45 +08:00
dfad245187 Update install.sh 2019-08-02 17:56:18 +08:00
3d2bc25355 update 2019-08-02 17:47:07 +08:00
1f4095fa65 update 2019-08-02 17:46:05 +08:00
6898193218 Update solr.js 2019-08-02 17:30:11 +08:00
fccf4fcd5b solr基本ok 2019-08-02 17:28:44 +08:00
183b142203 web管理 2019-08-02 13:46:51 +08:00
70e87ff5d6 优化 2019-08-02 13:46:42 +08:00
77174243ed 安装即下载mysql-connector-java
mysql-connector-java-5.1.48.jar
mysql-connector-java-8.0.17.jar
2019-08-02 13:03:50 +08:00
db4136ef62 Update __init__.py 2019-08-02 08:30:14 +08:00
220ca5a0a2 Update info.json 2019-08-01 23:52:17 +08:00
9bdf449d38 Update info.json 2019-08-01 23:14:21 +08:00
e2be44ad78 Update info.json 2019-08-01 23:09:13 +08:00
3913a77265 Update info.json 2019-08-01 23:08:27 +08:00
f395469a09 Update info.json 2019-08-01 23:07:46 +08:00
0101516935 Update info.json 2019-08-01 23:06:45 +08:00
d726fca5d0 solr 配置文件 2019-08-01 22:56:22 +08:00
39902363ab Update solr.js 2019-08-01 22:09:07 +08:00
4b93a7e3a1 Update info.json 2019-08-01 21:11:38 +08:00
9152fca0c9 solr delete ok 2019-08-01 19:05:30 +08:00
e5393b2127 solr add ok 2019-08-01 17:09:23 +08:00
034939a0c5 solr add 2019-08-01 16:46:34 +08:00
d35c6bb02f Update index.py 2019-08-01 15:32:17 +08:00
56746d9c01 Update phpmyadmin.conf 2019-08-01 11:07:12 +08:00
b2fe702d51 Update index.py 2019-07-31 23:54:44 +08:00
c6282d5660 Update index.py 2019-07-31 23:46:24 +08:00
a2851b2787 Update index.py 2019-07-31 23:45:28 +08:00
26f41228db Update setting.py 2019-07-31 21:42:52 +08:00
f5cb06ea53 Update setting.py 2019-07-31 21:42:29 +08:00
a16441e87d Update requirements.txt 2019-07-31 20:25:35 +08:00
3b4601e083 php安装脚本加入
--no-check-certificate
2019-07-31 17:56:39 +08:00
556f8175e8 Update install.sh 2019-07-31 17:53:04 +08:00
13d6128e39 Update requirements.txt 2019-07-31 17:49:45 +08:00
3bd56d161a Update install_centos.sh 2019-07-31 17:36:48 +08:00
eed88c721e Update install_centos.sh 2019-07-31 17:34:32 +08:00
0fbb507b07 Update README.md 2019-07-25 11:41:03 +08:00
57516929c1 u 2019-07-22 16:44:01 +08:00
a8d6a7eaf2 l2tp 2019-07-22 16:43:40 +08:00
49022b2f57 更新PHP版本 2019-05-22 13:07:25 +08:00
a7cd64a54c Update index.py 2019-05-18 15:28:09 +08:00
db4a7af2b5 Update install_centos.sh 2019-05-18 14:35:40 +08:00
c746876026 Update install_centos.sh 2019-05-18 14:34:56 +08:00
7578aa32ae Update install_centos.sh 2019-05-18 14:34:38 +08:00
9cae0dc4ab 修改提示地址 2019-05-06 14:53:37 +08:00
cc97c6299d update 2019-05-06 14:35:15 +08:00
e6e0f7dea7 up 2019-05-06 14:04:38 +08:00
bdfcf9179d up 2019-05-06 13:40:48 +08:00
cdb50b681f Update init.lua 2019-05-06 13:27:01 +08:00
8ca50abb0c Update init.lua 2019-05-06 13:21:46 +08:00
0196a7a622 优化 2019-05-06 13:11:00 +08:00
835a575535 update 2019-05-06 12:23:58 +08:00
d54d123850 update 2019-05-06 12:22:43 +08:00
83f033427d Update op_waf.js 2019-05-06 10:46:48 +08:00
de8242e5e5 update 2019-05-06 10:41:51 +08:00
8f416db0ad up 2019-05-05 22:01:40 +08:00
2323cbdf77 update 2019-05-05 21:35:29 +08:00
925bb15d7b Update task.py 2019-05-05 20:46:23 +08:00
50e18bb3d9 up 2019-05-05 19:00:39 +08:00
c15b97f2ba update 2019-05-05 17:17:38 +08:00
f367f10d02 update 2019-05-05 14:12:30 +08:00
9ee3e2a88e Update op_waf.js 2019-05-05 13:02:37 +08:00
5e0f877d20 Update index.py 2019-05-04 20:54:42 +08:00
6e3d9e6983 up 2019-05-04 20:41:10 +08:00
b1d04333bf up 2019-05-04 19:33:50 +08:00
1af55a1dd3 up 2019-05-04 11:44:27 +08:00
5f9cee95e6 Update op_waf.js 2019-05-03 23:50:28 +08:00
f139587464 up 2019-05-03 23:21:33 +08:00
0f2ee7ae54 Update op_waf.js 2019-05-02 15:41:57 +08:00
eff62918ba up 2019-05-02 10:59:08 +08:00
345808c200 update 2019-05-01 17:23:37 +08:00
15eabc51cb Update op_waf.js 2019-05-01 14:23:52 +08:00
a7c6a89583 update 2019-05-01 12:34:18 +08:00
5acba5ad76 update 2019-04-30 23:53:13 +08:00
40f782c602 Update index.py 2019-04-30 20:29:06 +08:00
1c0ac62b4f op 2019-04-30 18:11:58 +08:00
3d13ab9096 Update .gitignore 2019-04-30 00:14:25 +08:00
29bdbf0d5e up 2019-04-30 00:14:07 +08:00
555fdb4ff0 Update op_waf.js 2019-04-29 22:19:32 +08:00
541d74fc71 update 2019-04-29 19:20:31 +08:00
aee77b2ec6 优化 2019-04-29 15:17:54 +08:00
fdbc8ad689 update 2019-04-29 10:29:52 +08:00
3200412e0b 响应内容优化 2019-04-28 16:48:47 +08:00
39af5b6702 Update op_waf.js 2019-04-28 00:13:20 +08:00
c18f3c11f6 Update op_waf.js 2019-04-27 23:53:12 +08:00
f5e55d4f58 update 2019-04-27 22:02:31 +08:00
2438d2ab61 update 2019-04-27 20:21:26 +08:00
7bd906d374 Update init.lua 2019-04-27 17:59:20 +08:00
6a326649f9 update 2019-04-27 17:56:25 +08:00
72636d598f update 2019-04-27 17:54:09 +08:00
bd6635ee09 u 2019-04-27 16:44:52 +08:00
ef9bb2c4a6 uu 2019-04-27 16:44:46 +08:00
f8f892e323 Update config.json 2019-04-27 16:44:26 +08:00
7eeec1625b uu 2019-04-27 13:02:21 +08:00
26a33573fd u 2019-04-27 09:37:33 +08:00
72c7044465 up 2019-04-27 09:30:52 +08:00
5191c711c3 update 2019-04-26 23:59:22 +08:00
6a536c14fd uu 2019-04-26 23:47:48 +08:00
63a965f978 ii 2019-04-26 19:27:45 +08:00
e2b4c330fc 优化 2019-04-26 18:03:12 +08:00
02431fdd9e update 2019-04-26 15:58:58 +08:00
7a8bd83ab8 update 2019-04-26 15:12:57 +08:00
3475dd5036 uu 2019-04-26 13:58:07 +08:00
8771059682 Update op_waf.js 2019-04-25 23:45:12 +08:00
48990384df Create total.json 2019-04-25 23:17:28 +08:00
0c84f0da80 oo 2019-04-25 18:03:00 +08:00
a1d701cd9f 防火墙插件优化 2019-04-25 17:47:19 +08:00
b23315f19b 删除防火墙栏目 2019-04-25 17:47:05 +08:00
0ee844ee5b Update index.html 2019-04-25 00:02:06 +08:00
0d4d20553d delete 2019-04-24 23:44:03 +08:00
457a86b742 Update site_api.py
防跨站攻击(open_basedir) 手动设置生效,不自动生效
2019-04-24 23:40:55 +08:00
3482d5cb3e 优化 2019-04-24 22:07:54 +08:00
4ce30ff46e waf dev 2019-04-24 19:24:20 +08:00
bceec90de4 up 2019-04-24 14:11:37 +08:00
3e396f9e60 waf 2019-04-24 00:15:01 +08:00
9370884eb5 uu 2019-04-22 22:31:51 +08:00
8627925274 waf init 2019-04-22 21:21:49 +08:00
2bfb240c7f update 2019-04-22 13:46:13 +08:00
acbf965f94 uu 2019-04-22 11:33:29 +08:00
74800f70bc sphinx模板配置优化 2019-04-21 23:59:41 +08:00
003c8f856c yar-update 2019-04-21 23:36:07 +08:00
29c3557c66 Update soft.js 2019-04-21 18:54:18 +08:00
f7f8a5042a Update install.sh 2019-04-21 18:38:06 +08:00
19911de04f Update install.sh 2019-04-21 18:27:47 +08:00
954df1b522 up 2019-04-21 18:22:31 +08:00
e1d6a16672 Update soft.js 2019-04-21 18:02:18 +08:00
536138b9ce 设置默认地址-DONE 2019-04-19 23:18:35 +08:00
33e311f98e 优化重启和任务功能 2019-04-19 10:37:02 +08:00
66c542dbc8 默认文档修改 2019-04-18 17:19:53 +08:00
bd333d9854 php 添加yar扩展 2019-04-18 15:26:58 +08:00
ecad6fe891 Update app.ini 2019-04-17 13:38:53 +08:00
f709bef197 Update install.sh 2019-04-09 23:18:51 +08:00
980392b811 php7+,支持pdo_mysql 2019-04-03 17:50:21 +08:00
497217446b php7+,支持mysqli 2019-04-03 16:23:06 +08:00
f82c66a6bd Update qbittorrent.conf 2019-04-03 00:46:40 +08:00
e1c10caf81 Update qbittorrent.conf 2019-04-03 00:44:27 +08:00
bdea272028 增sphinx事例 2019-04-03 00:42:42 +08:00
e6e6dab8f6 update 2019-04-02 17:36:03 +08:00
03655f16eb Update install_centos.sh 2019-04-02 16:46:46 +08:00
b11f8793e3 提前处理了 2019-04-02 16:42:44 +08:00
595219da19 Update index.py 2019-04-02 15:53:47 +08:00
735aa7224b Update requirements.txt 2019-04-02 15:17:58 +08:00
8a522c43e5 优化rsyncd启动配置 2019-04-02 15:13:41 +08:00
c5b6df846b Update requirements.txt 2019-04-02 14:09:31 +08:00
4326e2c7ca Update update_centos.sh 2019-04-02 14:09:04 +08:00
d899e332e0 Update update_centos.sh 2019-04-02 14:08:12 +08:00
0eeedf22ea Update mw.tpl 2019-04-02 14:07:28 +08:00
c56e487e8d Update requirements.txt 2019-04-02 14:04:11 +08:00
0d753f0c9d Update requirements.txt 2019-04-02 14:03:51 +08:00
9a3855f2df Update bbr.sh 2019-04-02 13:56:23 +08:00
7d4a0bb1d4 PHP-00 配置文件支持3 2019-04-02 13:48:12 +08:00
49be7f3779 PHP-00 配置文件支持2 2019-04-02 13:42:10 +08:00
01288d2fa9 PHP-00 配置文件支持 2019-04-02 13:30:27 +08:00
527a1a70c8 Update index.py 2019-04-02 13:29:35 +08:00
cfe1b29518 Update requirements.txt 2019-04-02 13:07:14 +08:00
c0335f0936 Update requirements.txt 2019-04-02 12:54:59 +08:00
f1156b221d Update requirements.txt 2019-04-02 12:49:51 +08:00
43c260522c Update install_centos.sh 2019-04-02 12:46:01 +08:00
2272242493 Update index.py 2019-03-30 12:01:19 +08:00
4bc68d1f17 Update index.py 2019-03-30 12:00:59 +08:00
3f0957e3df Update index.py 2019-03-30 11:58:34 +08:00
77c5ead2b6 Update index.py 2019-03-30 11:46:15 +08:00
19674add02 Update index.py 2019-03-30 11:43:31 +08:00
064bd1a810 Update index.py 2019-03-30 11:34:16 +08:00
1f11d6b622 Update index.py 2019-03-30 11:33:09 +08:00
e5374afee3 Update install.sh 2019-03-30 11:30:17 +08:00
c874c3e6b2 update 2019-03-30 11:28:08 +08:00
bdc5c7b85c Update bbr.js 2019-03-30 11:23:54 +08:00
9b55c92dc2 Update bbr.js 2019-03-30 11:20:50 +08:00
b838831970 Update bbr.js 2019-03-30 11:20:00 +08:00
21fcf429b6 Update index.html 2019-03-30 11:19:01 +08:00
8d19106412 Update info.json 2019-03-30 11:12:29 +08:00
4b6460bd5b Update bbr.js 2019-03-30 11:11:20 +08:00
5c5cddd1bf 优化 2019-03-30 01:50:34 +08:00
5b6db26617 修复展示路径 2019-03-29 17:36:51 +08:00
a40fc46f47 修复展示路径 2019-03-29 17:36:21 +08:00
490daa14de Update rsyncd.conf 2019-03-29 16:44:31 +08:00
a022ea419f Update index.py 2019-03-29 16:43:54 +08:00
54c6ab3f08 Update files_api.py 2019-03-29 14:59:03 +08:00
83a9accf0f 优化说明 2019-03-29 14:36:46 +08:00
956e3b3ca2 update 2019-03-29 13:56:30 +08:00
83cf0c2604 0.7.3 2019-03-29 01:14:01 +08:00
7999108b91 减小图片大小 2019-03-29 01:10:00 +08:00
b80de25598 减小图片大小 2019-03-29 01:05:11 +08:00
7c25ae0ec2 BBR[DEV] 2019-03-29 01:02:58 +08:00
84e9c4a484 Update README.md 2019-03-28 17:21:44 +08:00
5178e11e44 截图 2019-03-28 17:20:00 +08:00
0e7c2769c8 修复bug
retJson
2019-03-27 00:30:43 +08:00
6651a706b7 Update files_api.py 2019-03-27 00:14:53 +08:00
a81f922592 Update .gitignore 2019-03-27 00:11:45 +08:00
2b87887054 批量复制|剪切|权限|压缩优化 2019-03-26 16:46:52 +08:00
7859bfb451 修复更新检查判断 2019-03-26 00:14:53 +08:00
35369f8f41 部分优化 2019-03-25 23:31:51 +08:00
a47166d547 Update files_api.py 2019-03-25 21:46:57 +08:00
457a69b34a Update config_api.py 2019-03-25 21:45:09 +08:00
881f571902 Update files.js 2019-03-25 21:44:53 +08:00
d889c3305f Update files.js 2019-03-25 21:43:31 +08:00
cb793d5f3f 0.7.0
fix
2019-03-25 21:42:49 +08:00
b4882aa0fc 优化配置 2019-03-25 10:52:09 +08:00
ef3b5b2a6c Create video.conf 2019-03-20 16:49:35 +08:00
d4501b736b 优化sphinx 2019-03-20 16:49:17 +08:00
261e24390f 优先显示 2019-03-19 17:26:14 +08:00
10abbd7efd 调整时间 2019-03-19 16:38:25 +08:00
e2196735d9 Update task.py 2019-03-19 16:28:59 +08:00
dbbc243359 Update task.py 2019-03-19 16:23:37 +08:00
94bb8e31cf Update task.py 2019-03-19 16:07:20 +08:00
282bcccf39 优化 2019-03-19 16:06:20 +08:00
886f6c2369 优化PHP插件
启动时,就配置php-fpm配置文件
2019-03-19 15:49:59 +08:00
ab822f0572 Update task.py 2019-03-19 15:27:02 +08:00
4ec2355182 添加PHP守护插件 2019-03-19 15:14:50 +08:00
a4237ca213 Update task.py 2019-03-18 22:49:21 +08:00
4615b70c60 Update firewall_api.py
关闭防火墙-删除自启动
开启防火墙-添加自启动
2019-03-18 21:30:31 +08:00
97b9d12769 gogs修改
post-receive很少修改。
commit 修改比较多
2019-03-18 15:17:41 +08:00
35a7c2d96f 权限设置修复 2019-03-18 14:42:04 +08:00
11ea1e2e1f 删除PHPmysqlAdmin未解决方案 2019-03-18 14:20:07 +08:00
1860dda320 登陆提示优化 2019-03-18 11:20:56 +08:00
5610b1b1da Update setting.py 2019-03-15 18:02:09 +08:00
422dea0e3f Update info.json 2019-03-15 17:48:31 +08:00
d52a355cc9 Update config_api.py 2019-03-15 17:45:55 +08:00
389d87c2b5 Update index.py 2019-03-15 17:44:33 +08:00
7ef8322731 Update index.py 2019-03-15 17:42:27 +08:00
d1a0b32bf6 Update gogs.tpl 2019-03-15 17:24:56 +08:00
295cb399e3 Update gogs.tpl 2019-03-15 17:15:06 +08:00
db9477c22e Update install_centos.sh 2019-03-15 17:05:50 +08:00
b2ae6b67d6 Update install_centos.sh 2019-03-15 16:58:10 +08:00
bf5f0cecff Update config_api.py 2019-03-15 16:54:55 +08:00
251503952d sphinx 自启动 done 2019-03-15 16:54:00 +08:00
60445a565d pureftp 自启动 done 2019-03-15 16:50:20 +08:00
6a8db02aa7 redis 自启动 done 2019-03-15 16:47:55 +08:00
ac50b335c3 memcached 自启动 done 2019-03-15 16:45:15 +08:00
c9826d5daf mysql 自启动done 2019-03-15 16:02:59 +08:00
ada8225e05 update 2019-03-15 15:23:54 +08:00
613ca4bce0 Update index.py 2019-03-15 14:53:08 +08:00
1bdfb0625a openresty 自启动 2019-03-15 14:52:18 +08:00
ad2e33fcd2 Update common.py 2019-03-15 14:43:00 +08:00
6e846a4a51 Update common.py 2019-03-15 14:42:38 +08:00
dc76f0ca33 chkconfig自启动需要 2019-03-15 14:33:33 +08:00
c619f00c54 Update README.md 2019-03-14 17:14:28 +08:00
015b132b85 update 2019-03-14 15:29:09 +08:00
4e4b4ad308 Update info.json 2019-03-14 14:29:41 +08:00
1226caaa39 Update update_centos.sh 2019-03-14 14:21:14 +08:00
5a92027f20 Update update_centos.sh 2019-03-14 14:21:01 +08:00
ea6ed08461 Update update_centos.sh 2019-03-14 14:20:43 +08:00
009231bbcf 0.4.2 2019-03-14 14:17:27 +08:00
d6fa8ca2a5 update 2019-03-14 14:15:44 +08:00
e3bfca777d Update info.json 2019-03-14 14:09:06 +08:00
292fb9362a Update plugins_api.py 2019-03-14 14:02:25 +08:00
f68a8c88d7 安装提示更新 2019-03-14 13:57:12 +08:00
4175a71547 优化 2019-03-14 13:26:08 +08:00
0a5680de12 update 2019-03-14 13:15:56 +08:00
b3df13210d ssh连接优化 2019-03-14 12:58:28 +08:00
55c9cb8856 Update __init__.py 2019-03-14 12:56:03 +08:00
740ad102ea up 2019-03-14 12:53:21 +08:00
1af0097673 Update __init__.py 2019-03-14 12:51:20 +08:00
b86a2f4243 Update __init__.py 2019-03-14 11:47:31 +08:00
9500e4a39d Update __init__.py 2019-03-14 11:45:31 +08:00
73b5d91ddc Update __init__.py 2019-03-14 11:44:01 +08:00
645cf21898 Update __init__.py 2019-03-14 11:42:26 +08:00
04e4e5a9dd Update __init__.py 2019-03-14 11:40:44 +08:00
3d215ba96d Update __init__.py 2019-03-14 11:36:52 +08:00
9b7722f847 Update __init__.py 2019-03-14 11:33:51 +08:00
040a6c0ed1 Update __init__.py 2019-03-14 11:31:00 +08:00
ef2a04e886 update 2019-03-14 11:14:53 +08:00
e656c64fee Update install.sh 2019-03-14 10:53:43 +08:00
0ee24a763a 优化修改
1.mysql修改备注
2.修改版本号
3.mysql迁移功能
4.选择文件优化
2019-03-14 02:07:39 +08:00
26120018c6 Update files_api.py 2019-03-13 20:29:44 +08:00
ae78b0aa8c Update mw.tpl 2019-03-13 20:21:07 +08:00
3cca69ae9f Update update_centos.sh 2019-03-13 20:20:00 +08:00
422460c422 Update update_centos.sh 2019-03-13 20:17:00 +08:00
47a60b3465 Update update_centos.sh 2019-03-13 20:14:37 +08:00
701ff6f817 Update update_centos.sh 2019-03-13 20:07:57 +08:00
385fa4bb5d Update update_centos.sh 2019-03-13 19:55:56 +08:00
f410727d42 Update update_centos.sh 2019-03-13 19:55:45 +08:00
f9baee0a4a Update update_centos.sh 2019-03-13 19:54:45 +08:00
c97e1ad3a7 Update update_centos.sh 2019-03-13 19:54:32 +08:00
deaa193478 Update update_centos.sh 2019-03-13 19:52:58 +08:00
e290af5403 Update update_centos.sh 2019-03-13 19:52:10 +08:00
f6f160883c Update update_centos.sh 2019-03-13 19:51:56 +08:00
0a2f8c9765 Update update_centos.sh 2019-03-13 19:49:06 +08:00
788a672e74 Update update_centos.sh 2019-03-13 19:48:36 +08:00
2a078d3290 Update update_centos.sh 2019-03-13 19:45:55 +08:00
03d3761805 Update lib.sh 2019-03-13 19:37:21 +08:00
6d16ae5767 Update lib.sh 2019-03-13 19:31:36 +08:00
66c9828b68 Update lib.sh 2019-03-13 19:24:39 +08:00
cf2ea6e16c Update update_centos.sh 2019-03-13 19:22:46 +08:00
b2533943ed 安装提示优化 2019-03-13 19:04:18 +08:00
5c9ccd9bd2 Update phplib.conf 2019-03-13 18:53:53 +08:00
fa48db5f1b update 2019-03-13 18:52:43 +08:00
79a45082c1 Update task.py 2019-03-13 17:59:14 +08:00
7998afb78a Update mongo.sh 2019-03-13 17:59:11 +08:00
492f875205 op 2019-03-13 17:59:07 +08:00
5e767fde08 Update phplib.conf 2019-03-13 17:58:39 +08:00
15acc8c67c 添加seaslog扩展 2019-03-13 17:58:36 +08:00
6234188ceb op 2019-03-13 17:19:33 +08:00
36842c8b2c 田间solr扩展 2019-03-13 14:41:02 +08:00
089de80c59 update 2019-03-13 14:38:02 +08:00
c60e9aabcd update 2019-03-13 13:09:37 +08:00
3195f915f5 Update install_centos.sh 2019-03-13 12:57:29 +08:00
24191e082a update 2019-03-13 12:53:54 +08:00
c2745a5f16 update 2019-03-13 12:38:03 +08:00
7d03e6ddf3 Update install.sh 2019-03-13 11:14:46 +08:00
77cfc12013 Update install_macos.sh 2019-03-13 11:14:39 +08:00
0bf9c06ef2 Update mongo.sh 2019-03-12 20:01:25 +08:00
d2b40b3399 Update install_macos.sh 2019-03-12 19:32:57 +08:00
482f4072c7 Update install_macos.sh 2019-03-12 19:05:02 +08:00
4879fee9a8 Update phplib.conf 2019-03-12 18:01:27 +08:00
51307c31f8 update 2019-03-12 17:59:44 +08:00
db451b630c update 2019-03-12 16:28:48 +08:00
400ea68cc9 update 2019-03-12 14:52:02 +08:00
078c755684 Update opcache.sh 2019-03-12 14:44:17 +08:00
f17c89605f php imagick 2019-03-12 14:37:13 +08:00
5f961febac update 2019-03-12 14:31:04 +08:00
1fb2c3ed5d Update gogs.js 2019-03-12 13:15:20 +08:00
acc6cd0c73 update 2019-03-12 13:11:00 +08:00
4e27082225 update 2019-03-11 19:22:18 +08:00
6563bb0044 update 2019-03-11 17:51:16 +08:00
d4b2a1214e Update gogs.tpl 2019-03-11 17:49:14 +08:00
097fb3b4cb Update index.py 2019-03-11 17:37:09 +08:00
f3f69767a1 Update index.py 2019-03-11 17:32:27 +08:00
dc149ac022 update 2019-03-11 17:30:22 +08:00
37cde7a7af update 2019-03-11 16:40:29 +08:00
e320104fb8 update 2019-03-11 15:46:41 +08:00
af4ad33031 qbittorrent 删除,不在主要软件管理中.. 2019-03-11 14:38:35 +08:00
2038111a11 修复问题 2019-03-11 14:24:36 +08:00
3481e660a3 Update install.sh 2019-03-11 13:56:18 +08:00
4651bf782c update 2019-03-11 13:43:04 +08:00
608a78ac67 update 2019-03-11 11:45:28 +08:00
4a12128315 Update install.sh 2019-03-11 10:55:27 +08:00
746b3295cb Update install_centos.sh 2019-03-10 20:06:42 +08:00
3d42cf67d7 Update requirements.txt 2019-03-10 19:42:50 +08:00
b7f5b7b5e5 Update requirements.txt 2019-03-09 23:17:13 +08:00
5e548f7899 update 2019-03-09 23:15:15 +08:00
fb68ad7705 update 2019-03-08 18:52:37 +08:00
e959ae2494 uu 2019-03-08 17:11:20 +08:00
3a6e84119f php安装版本 2019-03-08 13:11:37 +08:00
4f3f7a70a9 优化 2019-03-08 11:39:22 +08:00
e1bf1e306d 优化 2019-03-08 11:10:36 +08:00
c9333a3023 Update phplib.conf 2019-03-07 20:49:52 +08:00
840fd5243a update 2019-03-07 20:25:56 +08:00
dde8fb3202 update 2019-03-07 19:38:06 +08:00
0f5ef505d0 update 2019-03-07 19:05:12 +08:00
1673a23455 删除不通用的 2019-03-07 18:59:41 +08:00
b4b16ada27 安装文件优化 2019-03-07 18:59:26 +08:00
a4d75bfc04 php卸载优化 2019-03-07 18:59:15 +08:00
61bd4f799b 卸载软件功能优化 2019-03-07 18:54:17 +08:00
002a3ea79e Install_Libmemcached 2019-03-07 17:48:30 +08:00
5dce56357b Update plugins_api.py 2019-03-07 16:21:04 +08:00
89ab800565 修复php53安装问题 2019-03-07 16:03:16 +08:00
349741b31b Update index.py 2019-03-06 20:40:11 +08:00
725b398da9 Update index.py 2019-03-06 20:37:32 +08:00
ce9f53dddb Update index.py 2019-03-06 20:35:55 +08:00
fc37413d91 update 2019-03-06 20:31:29 +08:00
ba39c39622 Update index.py 2019-03-06 19:22:53 +08:00
6c5ee78b18 u 2019-03-06 18:54:19 +08:00
eafa575e8e rsyncd基本功能 2019-03-06 18:47:43 +08:00
a3dd458cb2 Update site.js 2019-03-06 18:47:26 +08:00
c5cb8b65f3 rsyncd 2019-03-06 15:07:04 +08:00
994b93852e 删除samba扩展 2019-03-06 14:39:57 +08:00
912eda2cb8 Update index.py 2019-03-06 14:33:32 +08:00
0461fabab0 Update index.py 2019-03-06 14:32:41 +08:00
0324872499 Update index.html 2019-03-06 14:30:53 +08:00
5877644570 update 2019-03-06 14:29:47 +08:00
f292fdd354 Update install.sh 2019-03-05 19:21:06 +08:00
85ce4dc462 rsyncd 2019-03-05 19:20:04 +08:00
a9d3aa4962 up 2019-03-05 18:35:28 +08:00
9a562934e5 Update config_api.py 2019-03-05 17:13:17 +08:00
784304f639 Update public.js 2019-03-05 17:02:30 +08:00
582792c2bf Update public.js 2019-03-05 17:01:45 +08:00
946523a73d Update index.html 2019-03-05 16:30:41 +08:00
39021dca1e 优化说明 2019-03-05 16:27:46 +08:00
e240ef713b 更改gogs- hook脚本 2019-03-05 16:00:31 +08:00
2b1f88ae0f Update site_api.py 2019-03-05 14:58:53 +08:00
8259823451 网站删除优化 2019-03-05 14:50:52 +08:00
05109a500d Update site.js 2019-03-05 14:29:15 +08:00
78b156aeed Update site_api.py 2019-03-05 14:27:53 +08:00
39789bcc33 Update site.js 2019-03-05 14:25:42 +08:00
310c8a57e7 Update site_api.py 2019-03-05 14:21:19 +08:00
3b947d6446 Update index.py 2019-03-05 13:56:21 +08:00
d163c84916 Update index.py 2019-03-05 13:50:02 +08:00
ef43ceab48 Update index.py 2019-03-05 13:47:05 +08:00
665952869a Update index.py 2019-03-05 13:46:27 +08:00
942a1fbf1a samba debug 2019-03-05 13:42:46 +08:00
0c05f87acd 优化
1.ssl跳转优化
2.acme安装
2019-03-05 12:59:37 +08:00
ef856a1420 Update README.md 2019-03-05 11:18:31 +08:00
0ea666bb7c 增加灵活性
1.php显示phpinfo优化
2.插件接口新增方法
2019-03-05 10:42:47 +08:00
5fc3a8607f 脚本修复 2019-03-05 10:04:05 +08:00
163ca52b7f Update plugins_api.py 2019-03-04 23:39:05 +08:00
dbcf62edb1 修复phpinfo显示 2019-03-04 23:22:29 +08:00
6e1ef774df 找到问题,待解决 2019-03-04 19:45:06 +08:00
84e646dbe4 优化数据显示 2019-03-04 18:02:30 +08:00
705ea56813 Update site_api.py 2019-03-04 17:56:08 +08:00
91ae7244b0 Update site_api.py 2019-03-04 17:12:27 +08:00
1539504258 samba init 2019-03-04 15:41:56 +08:00
1ef899d11e 源码中删除simdht 2019-03-04 15:20:15 +08:00
e36df4fff5 Update install_centos.sh 2019-03-04 14:39:56 +08:00
76a1fed75d 添加命令更新脚本 2019-03-04 14:24:49 +08:00
338ccef6d6 增加网站分类功能 2019-03-04 14:09:43 +08:00
1fa7fbda45 samba init 2019-03-04 11:04:10 +08:00
4459d296eb uu 2019-03-03 23:44:03 +08:00
a9f7a47022 Update __init__.py 2019-03-03 10:57:39 +08:00
e1e69a4677 Update __init__.py 2019-03-03 09:40:37 +08:00
6827de3f67 Update config_api.py 2019-03-03 08:41:29 +08:00
bffd4c1150 ssl功能90% 2019-03-02 23:32:11 +08:00
ad44c255cb ssl功能80% 2019-03-02 22:33:29 +08:00
c884197f2e 删除l2tp插件 2019-03-01 19:36:07 +08:00
1bc335d715 l2tp ok 2019-03-01 18:01:22 +08:00
a10f5a3337 Update index.py 2019-03-01 17:51:49 +08:00
c2c413a9ef Update index.py 2019-03-01 17:51:22 +08:00
c9eea53ff5 Update index.py 2019-03-01 17:50:10 +08:00
e176ac2e8d test 2019-03-01 17:46:53 +08:00
522f9f22e4 Update index.py 2019-03-01 17:41:39 +08:00
8fded1c678 update 2019-03-01 17:37:18 +08:00
2b0782f125 u 2019-03-01 17:15:42 +08:00
f7c2e38a5e y 2019-03-01 17:14:33 +08:00
93d3fc3cef Update l2tp.js 2019-03-01 16:36:08 +08:00
0e200e8c12 Update index.py 2019-03-01 16:34:31 +08:00
28ddb57c8e Update l2tp.js 2019-03-01 16:32:47 +08:00
348ecd938e Update index.py 2019-03-01 16:31:45 +08:00
6de200a294 Update l2tp.js 2019-03-01 16:29:45 +08:00
8b0dc43f74 Update index.py 2019-03-01 16:20:44 +08:00
e14d8109f2 Update l2tp.js 2019-03-01 16:17:34 +08:00
ea8b829c6e Update index.py 2019-03-01 16:15:50 +08:00
faf637aae1 u 2019-03-01 16:09:54 +08:00
bb69c92a9c update 2019-03-01 15:53:29 +08:00
3886888843 优化 2019-02-28 20:01:07 +08:00
1bd0a38f6b 优化gogs插件 2019-02-28 19:54:53 +08:00
ac7fe66734 u 2019-02-28 16:41:17 +08:00
3365ab9a49 update 2019-02-28 16:22:15 +08:00
3cfaa5361f l2tp测试 2019-02-28 16:17:50 +08:00
43800b6578 Update site.js 2019-02-28 15:43:02 +08:00
0891e206d5 Update index.py 2019-02-28 15:08:23 +08:00
8f6aae7e4c Update index.py 2019-02-28 14:47:08 +08:00
d860405b16 Update index.py 2019-02-28 14:43:44 +08:00
df4f1aa28b update 2019-02-28 14:24:43 +08:00
b464c848a9 0.0.8 2019-02-28 14:05:43 +08:00
04780d8094 Update info.json 2019-02-28 13:56:18 +08:00
e41604499a 优化 2019-02-28 13:52:06 +08:00
ef90ba7aab 重要插件不可修改 2019-02-28 13:27:46 +08:00
b5954be201 Update plugin_compress.sh 2019-02-28 13:15:16 +08:00
5d7b37cb18 删除不必要插件 2019-02-28 13:14:58 +08:00
71026d74e9 pm2 ok 2019-02-28 11:54:42 +08:00
d656d07487 Update pm2.js 2019-02-28 10:27:24 +08:00
3bf395c86f Update index.py 2019-02-28 02:10:52 +08:00
f841a89940 基本功能OK 2019-02-28 01:59:56 +08:00
287de96277 update 2019-02-27 19:58:32 +08:00
860bcd0c9d Update files.html 2019-02-27 19:15:36 +08:00
73f6354332 L2TP vpn 插件 2019-02-27 15:52:16 +08:00
9770821628 网站分类基本功能完成~ 2019-02-27 15:09:25 +08:00
dff57a4b13 Update site_api.py 2019-02-27 14:26:03 +08:00
cfed5e813d Update site.js 2019-02-27 14:25:59 +08:00
2518e53abc Update site.html 2019-02-27 14:25:56 +08:00
bf970dbd02 Update site.css 2019-02-27 14:25:09 +08:00
aa583e4586 Update public.js 2019-02-27 14:25:07 +08:00
07a33f1a5f Update control.js 2019-02-27 14:25:03 +08:00
bd1eff9fc8 Update default.sql 2019-02-27 14:24:58 +08:00
ded6dad023 Update config_api.py 2019-02-27 14:24:46 +08:00
52f7bdd65d pm2 init 2019-02-27 14:24:41 +08:00
6874bfc059 优化启动脚本 2019-02-27 10:40:47 +08:00
bef439ce55 Update site.html 2019-02-26 19:13:59 +08:00
726c684a94 Update php72.ini 2019-02-26 17:02:23 +08:00
e6b9fd8a66 Update info.json 2019-02-26 16:09:07 +08:00
350a1e8b61 修复重复js方法 2019-02-26 16:08:23 +08:00
b904ef4e8a Update system_api.py 2019-02-26 16:01:39 +08:00
d64040abb7 Update info.json 2019-02-26 15:57:36 +08:00
6451d1caa1 u 2019-02-26 15:47:51 +08:00
ca8d2ac405 Update public.py 2019-02-26 15:30:21 +08:00
9f9922abdd Update system_api.py 2019-02-26 15:30:19 +08:00
9ec0987cfa Update index.js 2019-02-26 15:30:12 +08:00
c21ad861af Update index.html 2019-02-26 15:30:08 +08:00
eac65528c7 Update layout.html 2019-02-26 15:30:05 +08:00
291071a3a3 插件安装 2019-02-26 11:26:29 +08:00
c454f7ddbe u 2019-02-26 11:26:17 +08:00
9e6a95460b Update site_api.py 2019-02-26 10:13:31 +08:00
5a4b06f12e u 2019-02-25 22:29:24 +08:00
9def3d0854 Update plugin_compress.sh 2019-02-25 19:37:51 +08:00
2183c74aa2 加入压缩脚本 2019-02-25 18:07:31 +08:00
3ffe6102e8 Update index.py 2019-02-25 17:15:53 +08:00
cb21fc08e4 u 2019-02-25 17:10:32 +08:00
ccd819d18a u 2019-02-25 15:41:01 +08:00
532f458993 站点启停 2019-02-25 15:18:26 +08:00
abc74b3e3b Update index.py 2019-02-25 15:18:08 +08:00
1d6664f01a u 2019-02-25 14:22:49 +08:00
c5f11d6819 网站备份 2019-02-25 14:07:56 +08:00
495a46deec u 2019-02-25 11:52:55 +08:00
7863a7b50d u 2019-02-24 23:54:06 +08:00
cb4a4d0568 u 2019-02-24 23:17:28 +08:00
639ee1c0ba update 2019-02-24 19:40:36 +08:00
1a380c2745 子目录绑定功能 2019-02-24 18:04:51 +08:00
4b4164f146 i 2019-02-23 14:42:47 +08:00
728add52d1 u 2019-02-23 11:25:39 +08:00
2b694bee35 Update system_api.py 2019-02-22 21:18:25 +08:00
9f4e4b8541 Update default.sql 2019-02-22 20:59:05 +08:00
736ceeb730 Update config_api.py 2019-02-22 20:56:34 +08:00
b95804587c 面板收藏功能完成2 2019-02-22 18:04:42 +08:00
77af5fcf7f 面板收藏功能完成 2019-02-22 18:00:39 +08:00
2c2aed7d18 Delete ssl.pl 2019-02-22 14:28:06 +08:00
ff543284cc 面板设置功能ok
1.关闭面板
2.ipv6监听
3.面板ssl
2019-02-22 14:22:13 +08:00
835fea0ad6 uu 2019-02-22 11:47:56 +08:00
8bbdcdb095 update 2019-02-21 23:05:09 +08:00
1e8c6ea498 Update .gitignore 2019-02-21 22:22:29 +08:00
da17e7782e update 2019-02-21 19:19:55 +08:00
11c9a9d736 u 2019-02-21 19:13:39 +08:00
b77c5ce39a Update simdht_worker.py 2019-02-21 17:39:40 +08:00
795322d77a simdht优化 2019-02-21 17:30:01 +08:00
78168a1df0 Update firewall.html 2019-02-21 15:43:24 +08:00
12b99b7c87 u 2019-02-21 15:40:27 +08:00
7976c16965 r 2019-02-21 15:31:36 +08:00
31de75f3ff u 2019-02-21 15:29:42 +08:00
45d14c4ad4 Update config_api.py 2019-02-21 15:27:54 +08:00
fc6ce6c614 update 2019-02-21 15:26:14 +08:00
b2b0716a48 Update firewall_api.py 2019-02-21 15:15:47 +08:00
0ce33bb170 update 2019-02-21 15:04:58 +08:00
e8fb2a231a Update firewall.js 2019-02-21 15:01:23 +08:00
9bafcaef7c Update firewall.html 2019-02-21 15:00:19 +08:00
6cf91549be u 2019-02-21 14:57:57 +08:00
80c9cafae1 u 2019-02-21 14:35:37 +08:00
6487cbae09 Update firewall_api.py 2019-02-21 14:32:30 +08:00
2f1b080870 u 2019-02-21 14:28:51 +08:00
cef24d3084 update 2019-02-21 13:53:46 +08:00
ca03199583 Update firewall_api.py 2019-02-21 13:50:04 +08:00
4170b790bf Update firewall_api.py 2019-02-21 13:46:14 +08:00
97f9391c41 Update firewall_api.py 2019-02-21 13:44:05 +08:00
5f704ec742 u 2019-02-21 13:37:51 +08:00
1ea7632b38 Update firewall.js 2019-02-21 13:34:13 +08:00
61853ee530 u 2019-02-21 13:24:12 +08:00
3d82092e1a u 2019-02-21 12:40:18 +08:00
0ba8620966 Update firewall.js 2019-02-21 11:30:01 +08:00
d657d7a322 Update system_api.py 2019-02-21 11:26:18 +08:00
95a9bc8d5f 功能OK
面板操作日志已清空!
2019-02-21 11:23:01 +08:00
1bfc2e9c1c 内存使用率功能优化 2019-02-21 10:49:36 +08:00
a81b16a27a Update backup.py 2019-02-20 18:31:08 +08:00
3d67694786 u 2019-02-20 18:18:21 +08:00
22b65e3bba Update crontab_api.py 2019-02-20 18:02:51 +08:00
3874cbee86 Delete libList.conf 2019-02-20 18:02:09 +08:00
990f52dd81 update 2019-02-20 18:01:51 +08:00
9f0be85a9f 文件上传OK 2019-02-20 13:27:13 +08:00
4ae442ae4c update 2019-02-19 18:59:27 +08:00
d0514fdca1 update 2019-02-19 17:29:07 +08:00
093ceae9d4 Update files.js 2019-02-19 14:59:18 +08:00
cfb6fb07ac update 2019-02-19 14:51:27 +08:00
ea3ece1639 update 2019-02-19 14:28:16 +08:00
ef4d35cee7 Update setting.py 2019-02-19 14:13:33 +08:00
d6e79d057a Update setting.py 2019-02-19 14:10:06 +08:00
17022f2fcb Update __init__.py 2019-02-19 14:05:03 +08:00
b4a371f1a1 Update setting.py 2019-02-19 14:04:40 +08:00
831bb240d1 Update __init__.py 2019-02-19 14:03:14 +08:00
b3ea4a8307 Update __init__.py 2019-02-19 14:02:26 +08:00
5f607ded95 Update webssh.js 2019-02-19 13:57:53 +08:00
cc01156b8c Update webssh.js 2019-02-19 13:55:10 +08:00
b208a5d751 Update webssh.js 2019-02-19 13:54:02 +08:00
72c31b8aaf Update webssh.js 2019-02-19 13:51:10 +08:00
5bd6f43b2a Update webssh.js 2019-02-19 13:48:59 +08:00
e8f0cc5003 Update webssh.js 2019-02-19 13:47:56 +08:00
34d17289cc Update webssh.js 2019-02-19 13:45:20 +08:00
30bc6f27ec update 2019-02-19 13:31:09 +08:00
77a36e6cfd Update __init__.py 2019-02-19 13:25:31 +08:00
2ff70a2c32 Update webssh.js 2019-02-19 13:24:51 +08:00
782389972b update 2019-02-19 13:21:19 +08:00
60fd8d306b u 2019-02-19 13:17:26 +08:00
e341272547 Update __init__.py 2019-02-19 13:12:17 +08:00
a28e9e2dbf Update __init__.py 2019-02-19 13:12:01 +08:00
1041f64c93 gevent模式 2019-02-19 11:37:24 +08:00
7c6d13473f u 2019-02-19 00:01:30 +08:00
cd38c261b7 update 2019-02-18 20:05:30 +08:00
091f5f3fbb Update __init__.py 2019-02-18 18:20:57 +08:00
212798426b update 2019-02-18 16:38:40 +08:00
29fa997ad2 update 2019-02-18 16:21:31 +08:00
c36cf7d83e update 2019-02-17 23:53:33 +08:00
8b6bdd25d9 u 2019-02-17 22:10:14 +08:00
f7b3fbc249 uu 2019-02-17 19:09:55 +08:00
baf091d8c3 u 2019-02-17 17:35:50 +08:00
6831c00c2a i 2019-02-17 16:33:19 +08:00
4050d9697b u 2019-02-17 15:06:54 +08:00
9872bf5e61 update 2019-02-17 14:42:51 +08:00
24f8a551d8 Update files.js 2019-02-16 20:51:47 +08:00
7dcc584c87 update 2019-02-16 20:40:58 +08:00
7a94dd9ad9 Update files.js 2019-02-16 19:32:20 +08:00
643f4f177c y 2019-02-16 18:49:23 +08:00
b2a1530b01 Update qbittorrent_worker.py 2019-02-16 16:12:06 +08:00
7753e7a7c1 Update qbittorrent_worker.py 2019-02-16 15:52:38 +08:00
19a9bf6554 Update qbittorrent_worker.py 2019-02-16 12:43:58 +08:00
477c48080b Update qbittorrent_worker.py 2019-02-16 03:35:24 +08:00
332324d218 Update qbittorrent_worker.py 2019-02-16 02:34:32 +08:00
f6928c1784 Update qbittorrent_worker.py 2019-02-16 02:29:55 +08:00
dd7b2c30a2 Update qbittorrent_worker.py 2019-02-16 02:13:59 +08:00
763744b4a5 通用的手动编辑 2019-02-16 01:20:56 +08:00
8e3202b354 Update commit.tpl 2019-02-16 01:11:41 +08:00
2a148c9309 gogs base ok 2019-02-15 20:19:41 +08:00
159c4d57b3 Update yaf.sh 2019-02-15 12:59:06 +08:00
aee172170e u 2019-02-15 00:21:56 +08:00
845fc8104a update 2019-02-14 17:50:32 +08:00
ef91abab77 update 2019-02-14 16:25:07 +08:00
ea295d1e0a update 2019-02-14 15:19:36 +08:00
ed83c1da60 Update app.ini 2019-02-14 14:31:19 +08:00
752b400c6c update 2019-02-14 14:28:11 +08:00
6fb2e94e05 update 2019-02-14 12:02:16 +08:00
8cf1cfad59 up 2019-02-14 02:11:48 +08:00
8eb7e20654 Update index.py 2019-02-13 19:58:42 +08:00
a62fe19491 Update index.py 2019-02-13 19:56:38 +08:00
77ebd5bc36 Update install.sh 2019-02-13 19:52:39 +08:00
49873a5249 update 2019-02-13 19:49:02 +08:00
6c90f2a7c3 Update site_api.py 2019-02-13 17:17:49 +08:00
13061a3808 update 2019-02-13 16:41:29 +08:00
e3aab8c8da update 2019-02-13 16:02:16 +08:00
dab3920618 update 2019-02-13 14:23:11 +08:00
5ff24872b9 Update public.py 2019-02-13 11:28:47 +08:00
e7e0295446 update 2019-02-13 11:21:38 +08:00
97752b690e update 2019-02-13 11:20:51 +08:00
8894280ad7 u 2019-02-12 23:30:28 +08:00
4a3ac08498 Update site_api.py 2019-02-12 19:44:17 +08:00
497981b4fc Update site_api.py 2019-02-12 19:41:39 +08:00
ac6d714c01 update 2019-02-12 18:43:28 +08:00
858540a440 update 2019-02-11 23:25:43 +08:00
a9300b0e43 update 2019-02-11 19:22:53 +08:00
abc04b7995 Update site_api.py 2019-02-11 18:03:27 +08:00
208d892675 update 2019-02-11 17:57:29 +08:00
3b83c0538f Update index.py 2019-02-11 16:24:29 +08:00
35bd7d4cc1 Update sphinx.js 2019-02-11 16:23:51 +08:00
6effc0ed8f Update sphinx.js 2019-02-11 16:19:21 +08:00
d50011d1e2 update 2019-02-11 16:00:29 +08:00
3e9cbf89da Update nginx.conf 2019-02-11 14:40:47 +08:00
f7df26a118 Update index.py 2019-02-10 12:43:24 +08:00
f5fe6ad747 update 2019-02-10 12:27:17 +08:00
c45b2d8d5f Update qbittorrent_worker.py 2019-02-10 00:52:00 +08:00
48729c39df Update simdht_worker.py 2019-02-09 21:43:50 +08:00
8946d8a12f Update qbittorrent_worker.py 2019-02-09 19:39:23 +08:00
3783ab407b Update simdht.tpl 2019-02-09 18:17:25 +08:00
14f59c7ae7 Update simdht_worker.py 2019-02-09 18:15:40 +08:00
a080a4f5f6 update 2019-02-09 14:00:52 +08:00
e43b66618c update 2019-02-09 12:43:46 +08:00
f2362bd7a2 Update qbittorrent_worker.py 2019-02-08 01:01:25 +08:00
e7513c7ed7 Update qb.sql 2019-02-08 01:00:15 +08:00
0cdc743b4f Update qbittorrent_worker.py 2019-02-07 19:25:55 +08:00
16e964ccbe Update qbittorrent_worker.py 2019-02-07 19:23:50 +08:00
d3d6feae0a Update index.py 2019-02-07 18:58:36 +08:00
31fa78c31c Update qbittorrent_worker.py 2019-02-07 17:25:55 +08:00
9cce88755e Update qbittorrent_worker.py 2019-02-07 15:36:23 +08:00
973e2fa1ac Update qb.sql 2019-02-05 19:37:33 +08:00
5645431d90 Update site.css 2019-02-05 15:42:02 +08:00
4c660e307a Update crontab.js 2019-02-03 20:29:40 +08:00
c76ed0ae97 update 2019-02-03 02:05:17 +08:00
8144de6ced Update install_centos.sh 2019-02-02 23:02:28 +08:00
328c84e78a Update install.sh 2019-02-02 22:58:54 +08:00
679a10104f Update install_centos.sh 2019-02-02 22:19:37 +08:00
c9e307382d Update install_centos.sh 2019-02-02 22:14:57 +08:00
bc4d25871d Update install.sh 2019-02-02 22:13:51 +08:00
d11a10e607 Update install_centos.sh 2019-02-02 19:38:16 +08:00
01cfa5a8d0 u 2019-02-02 18:53:07 +08:00
c880e935d7 Update install_centos.sh 2019-02-02 18:04:42 +08:00
4b67f348f6 Update install_centos.sh 2019-02-02 18:02:59 +08:00
2a9bfe15c0 Update install_centos.sh 2019-02-02 18:01:34 +08:00
bb8a6a3a2c Update install_centos.sh 2019-02-02 18:00:09 +08:00
d6b5a019cf update 2019-02-02 17:58:32 +08:00
d623cab022 Update install_centos.sh 2019-02-02 17:53:19 +08:00
26748bbeaa up 2019-02-02 16:22:37 +08:00
e211cc075f update 2019-01-30 14:14:14 +08:00
f52d8c0fbb Update qb.sql 2019-01-29 00:49:46 +08:00
22f6f04c8a Update qb.sql 2019-01-29 00:39:06 +08:00
bd4972e55d update 2019-01-29 00:23:34 +08:00
3318218764 update 2019-01-28 21:16:32 +08:00
fe468421f2 Update firewall.js 2019-01-27 16:32:37 +08:00
fee05f6af3 Update firewall.js 2019-01-27 16:17:24 +08:00
04c09ed101 Update firewall.js 2019-01-27 16:15:43 +08:00
142437ea7e Update firewall_api.py 2019-01-26 23:34:36 +08:00
bf3ddbf4a5 Update firewall_api.py 2019-01-26 23:24:25 +08:00
602ef37d88 Update firewall.js 2019-01-26 23:15:36 +08:00
9c860a5941 u 2019-01-26 22:47:00 +08:00
242ffd4517 Update qbittorrent_worker.py 2019-01-26 20:05:06 +08:00
6821f7a895 Update qbittorrent_worker.py 2019-01-26 19:47:31 +08:00
2bb03a71c6 Update qbittorrent_worker.py 2019-01-26 19:46:24 +08:00
433cf508e5 Update qbittorrent_worker.py 2019-01-26 19:34:43 +08:00
bdb852c8cf Update qbittorrent_worker.py 2019-01-26 19:31:31 +08:00
cf008c7ccd Update qbittorrent_worker.py 2019-01-26 19:25:29 +08:00
1f1870c5e2 Update qbittorrent_worker.py 2019-01-26 18:19:35 +08:00
aecabf7dd2 update 2019-01-26 18:05:01 +08:00
342652abe8 Update crontab_api.py 2019-01-26 18:00:49 +08:00
0bbe4f6ffc Update qbittorrent_worker.py 2019-01-26 17:37:55 +08:00
4411b4e70f Update qbittorrent_worker.py 2019-01-26 17:30:43 +08:00
b4757dfadd Update qbittorrent_worker.py 2019-01-26 13:47:17 +08:00
ed465ad8cf update 2019-01-26 13:10:07 +08:00
2896e2d9fb update 2019-01-25 19:08:22 +08:00
f6ff5c8e26 update 2019-01-25 18:10:33 +08:00
d6dfccb5bc update 2019-01-25 13:41:53 +08:00
d6007b273c Update qbittorrent_worker.py 2019-01-25 10:42:41 +08:00
b7da5f7db3 Update qbittorrent_worker.py 2019-01-25 10:36:40 +08:00
58258afe6e Update qbittorrent_worker.py 2019-01-25 10:34:56 +08:00
139b1cf03b Update qbittorrent_worker.py 2019-01-25 02:39:25 +08:00
8e3e170c6e Update qbittorrent_worker.py 2019-01-25 02:17:51 +08:00
51c50c8fc6 Update qbittorrent_worker.py 2019-01-25 01:56:06 +08:00
3513230de1 Update qbittorrent_worker.py 2019-01-24 23:33:33 +08:00
4b72cd448d Update qbittorrent_worker.py 2019-01-24 23:14:04 +08:00
7096a65591 Update qbittorrent_worker.py 2019-01-24 23:03:44 +08:00
7b36b808bd Update qbittorrent_worker.py 2019-01-24 17:57:59 +08:00
3a4467619e Update qbittorrent_worker.py 2019-01-24 17:57:05 +08:00
f928ef95f6 Update qbittorrent_worker.py 2019-01-24 17:46:55 +08:00
9cf984ed65 Update qbittorrent_worker.py 2019-01-24 17:45:22 +08:00
1f14e271c4 Update index.py 2019-01-24 17:43:14 +08:00
dddf0edb26 Update qbittorrent_worker.py 2019-01-24 17:42:14 +08:00
8ac906f11e Update qbittorrent_worker.py 2019-01-24 17:39:59 +08:00
243c1d2291 Update qbittorrent_worker.py 2019-01-24 17:37:18 +08:00
072bd93ac0 Update qbittorrent_worker.py 2019-01-24 17:25:33 +08:00
a3d2183eef Update qbittorrent_worker.py 2019-01-24 17:15:48 +08:00
71ffa35702 Update qb.conf 2019-01-24 17:14:15 +08:00
c28e48557d Update qbittorrent_worker.py 2019-01-24 17:13:58 +08:00
c6c88c0841 Update qb.conf 2019-01-24 17:11:35 +08:00
9dbc4baa25 update 2019-01-24 17:11:09 +08:00
0f7a493777 Update qbittorrent_worker.py 2019-01-24 17:04:53 +08:00
cd4c21697d Update qbittorrent_worker.py 2019-01-24 16:58:46 +08:00
e45832ea22 Update qbittorrent_worker.py 2019-01-24 16:56:58 +08:00
603323f576 Update qbittorrent.tpl 2019-01-24 16:55:04 +08:00
421e1d5623 Update qbittorrent.tpl 2019-01-24 16:52:36 +08:00
2492d38a1d Update index.py 2019-01-24 16:51:48 +08:00
22a023b877 Update qbittorrent_worker.py 2019-01-24 16:48:39 +08:00
b1f95fb5f2 Update qbittorrent_worker.py 2019-01-24 16:48:08 +08:00
7641d03f34 Update qbittorrent_worker.py 2019-01-24 16:37:26 +08:00
d2b9fbed4a update 2019-01-24 16:28:52 +08:00
67abcc17c5 update 2019-01-24 16:02:59 +08:00
dfdeef8f4c update 2019-01-24 13:46:43 +08:00
92e23cb018 Update qb.conf 2019-01-24 13:21:37 +08:00
8e9aa1489e Update qbittorrent_worker.py 2019-01-24 11:37:33 +08:00
47fc9576dc Update qbittorrent_worker.py 2019-01-24 11:37:22 +08:00
ab1ad909ad update 2019-01-24 11:11:34 +08:00
1da2a454ad Update index.html 2019-01-24 10:43:33 +08:00
33a418017a Update qbittorrent.tpl 2019-01-24 10:16:10 +08:00
c0161572f7 Update qbittorrent_worker.py 2019-01-24 10:06:00 +08:00
ba2a061eb1 Update qbittorrent_worker.py 2019-01-24 09:59:58 +08:00
7535598be6 Update index.py 2019-01-24 00:00:22 +08:00
f98e69ede7 Update qbittorrent_worker.py 2019-01-23 23:51:17 +08:00
9d88675756 Update qbittorrent_worker.py 2019-01-23 23:48:21 +08:00
8c07db3b57 Update qbittorrent_worker.py 2019-01-23 23:44:20 +08:00
a226c3c019 Update qbittorrent_worker.py 2019-01-23 20:59:50 +08:00
8533d667cd Update qbittorrent_worker.py 2019-01-23 20:52:34 +08:00
4b1f483565 Update qbittorrent.tpl 2019-01-23 20:51:56 +08:00
ede5bab112 update 2019-01-23 20:50:04 +08:00
be5fc96998 Update install.sh 2019-01-23 20:36:03 +08:00
ffbe43b589 Update install.sh 2019-01-23 20:35:45 +08:00
e2ae038fa2 Update qbittorrent_worker.py 2019-01-23 20:28:59 +08:00
f9482c43c7 Update qbittorrent_worker.py 2019-01-23 20:24:54 +08:00
b4898e32a5 Update qbittorrent_worker.py 2019-01-23 20:23:30 +08:00
0094d4e573 Update qbittorrent_worker.py 2019-01-23 19:55:21 +08:00
ffd1258d26 Update qbittorrent_worker.py 2019-01-23 19:50:46 +08:00
f46139e1f9 Update qbittorrent.tpl 2019-01-23 19:48:02 +08:00
4eb68cbdbb Update qbittorrent_worker.py 2019-01-23 19:47:13 +08:00
5b164ee478 update 2019-01-23 19:44:37 +08:00
619bbca29d Update qb.conf 2019-01-23 19:38:50 +08:00
32dfc0a1ab Update qbittorrent_worker.py 2019-01-23 19:35:35 +08:00
7124f314ac Update qbittorrent_worker.py 2019-01-23 15:14:06 +08:00
526ba2cd65 Update qbittorrent_worker.py 2019-01-23 13:44:12 +08:00
9fce92c7d5 Update qb.conf 2019-01-23 13:43:09 +08:00
7102f809c2 update 2019-01-23 13:41:28 +08:00
cb8d396b98 update 2019-01-23 09:57:24 +08:00
7c22685f49 Update qb.conf 2019-01-22 23:19:17 +08:00
0ae83fe2b2 Update index.py 2019-01-22 23:17:39 +08:00
6ec4c72219 Update install.sh 2019-01-22 22:56:31 +08:00
d6321dbbb7 update 2019-01-22 19:57:27 +08:00
3706c64b8f update 2019-01-22 19:28:26 +08:00
28e5787dc9 update 2019-01-22 18:26:05 +08:00
a8afc4fe88 Update simdht.js 2019-01-22 16:58:23 +08:00
86326de64f Update simdht_delta.conf 2019-01-22 16:51:20 +08:00
96d441fe5f update 2019-01-22 16:50:03 +08:00
b610e8f997 Update simdht_delta.conf 2019-01-22 15:56:52 +08:00
824d58e07f update 2019-01-22 15:00:30 +08:00
7d0a5713ba update 2019-01-22 14:40:04 +08:00
e59cd0d15d update 2019-01-22 11:04:35 +08:00
5975d712f8 Update index.py 2019-01-21 23:16:16 +08:00
42b25fb503 update 2019-01-21 18:57:37 +08:00
a50cf91428 Update install.sh 2019-01-21 17:37:27 +08:00
db55a16503 Update install.sh 2019-01-21 16:26:33 +08:00
100ac12bba Update install.sh 2019-01-21 16:24:38 +08:00
682c155ada Update install.sh 2019-01-21 16:04:45 +08:00
3cbb91409d Update install.sh 2019-01-21 15:57:07 +08:00
a1508357ee Update install.sh 2019-01-21 15:13:35 +08:00
d4742f061b Update install.sh 2019-01-21 15:07:17 +08:00
669259634a update 2019-01-21 15:05:56 +08:00
0050d85b8e Update simdht.sql 2019-01-21 14:46:35 +08:00
17b810436e Update install.sh 2019-01-21 14:12:39 +08:00
7249ec56c0 Update install.sh 2019-01-21 14:11:10 +08:00
537346dace qbittorrent 2019-01-21 14:10:25 +08:00
d83a4fe27f update 2019-01-21 11:27:21 +08:00
56168b76fb Update my.cnf 2019-01-21 10:27:25 +08:00
6bcf3c5d35 Update index.py 2019-01-20 23:07:50 +08:00
Mr Chen
edf44d09e1 Update public.py 2019-01-19 17:47:27 +08:00
Mr Chen
31e48ffc53 Update index.py 2019-01-19 16:49:50 +08:00
Mr Chen
030aa7b46c Update index.py 2019-01-19 16:45:14 +08:00
Mr Chen
ea6be0b69a Update public.js 2019-01-19 16:43:20 +08:00
Mr Chen
e172aa3a6e Update public.py 2019-01-19 16:41:11 +08:00
Mr Chen
6d8048af2f Update public.py 2019-01-19 16:39:57 +08:00
Mr Chen
ec3f8c0249 update 2019-01-19 16:37:08 +08:00
Mr Chen
ddd8a32abf Update index.py 2019-01-19 16:35:39 +08:00
Mr Chen
3b842620a0 Update index.py 2019-01-19 16:33:35 +08:00
Mr Chen
553b2b10d9 Update public.py 2019-01-19 16:26:52 +08:00
Mr Chen
177369585c Update public.py 2019-01-19 16:25:45 +08:00
Mr Chen
1977fa025a Update index.py 2019-01-19 16:24:31 +08:00
Mr Chen
13fd61f0cf Update index.py 2019-01-19 16:20:20 +08:00
Mr Chen
7ef6cdd76c Update index.py 2019-01-19 15:59:27 +08:00
Mr Chen
b1b1878637 Update index.py 2019-01-19 15:57:43 +08:00
Mr Chen
17f8b47625 Update public.py 2019-01-19 15:51:26 +08:00
Mr Chen
d7e7f5ea2d Update simdht.js 2019-01-19 15:33:17 +08:00
Mr Chen
6efa3e6a35 up 2019-01-19 15:31:17 +08:00
Mr Chen
e3e1545c9b Update common.py 2019-01-19 15:20:51 +08:00
Mr Chen
b26737eb3c Update common.py 2019-01-19 15:12:44 +08:00
4eb430a88b update 2019-01-19 03:05:55 +08:00
bfa0add999 update 2019-01-18 17:22:06 +08:00
7f20090e8c update 2019-01-18 17:11:29 +08:00
e151f0dee1 Update info.json 2019-01-18 16:20:25 +08:00
a5184e933e update 2019-01-18 16:05:21 +08:00
819e74333e 优化 2019-01-18 15:46:59 +08:00
4a09c3fd95 Update install.sh 2019-01-18 13:17:20 +08:00
c214c19a89 Update install.sh 2019-01-18 12:59:20 +08:00
889de6769a Update soft.js 2019-01-18 11:30:53 +08:00
7dfe6eb681 Update install.sh 2019-01-18 11:29:32 +08:00
ef21d5f47f Update install.sh 2019-01-18 11:22:23 +08:00
2d8e62417f update 2019-01-17 23:30:25 +08:00
d2750f41aa update 2019-01-17 23:16:45 +08:00
0ab7af4748 Update index.html 2019-01-17 16:04:38 +08:00
56cc3b75c3 update 2019-01-17 15:31:57 +08:00
127caf661c u 2019-01-17 14:19:48 +08:00
9bc857b000 update 2019-01-17 14:19:06 +08:00
233fa4cf60 Update index.html 2019-01-17 11:35:33 +08:00
d5b8f7f800 Update index.html 2019-01-17 11:33:27 +08:00
b595557f2c Update install.sh 2019-01-17 10:23:37 +08:00
d90509e479 Update plugins_api.py 2019-01-16 22:50:17 +08:00
e1e84741f5 update 2019-01-16 15:35:22 +08:00
9169ce58de update 2019-01-16 14:56:26 +08:00
0b55595ce6 update 2019-01-16 13:54:03 +08:00
b5aeaacc69 Update sphinx.tpl 2019-01-16 13:43:01 +08:00
1ed469b5f6 update 2019-01-16 13:27:51 +08:00
d900298a7b update 2019-01-16 13:02:05 +08:00
5ac1642927 sphinx init 2019-01-15 23:13:21 +08:00
d1f26a59ce Update install_macos.sh 2019-01-15 20:27:47 +08:00
7be7de2bce Update install_macos.sh 2019-01-15 20:23:10 +08:00
91c9250f74 Update install_centos.sh 2019-01-15 18:20:36 +08:00
91bd3abb74 Update install.sh 2019-01-15 18:19:32 +08:00
04d6166deb Update install_macos.sh 2019-01-15 18:15:28 +08:00
c66fd7abe0 update 2019-01-15 17:57:33 +08:00
ac71de01bd 两边一致 2019-01-15 16:21:22 +08:00
d0430e7b3c Update pick_filter.txt 2019-01-15 15:41:08 +08:00
0264e2edda Revert "update"
This reverts commit 631776c0ce.
2019-01-15 15:39:15 +08:00
631776c0ce update 2019-01-15 15:38:00 +08:00
008ff29e13 Update mw.tpl 2019-01-15 15:34:40 +08:00
c66105ae96 Create tools.py 2019-01-15 15:06:17 +08:00
6c2fe6c9de Update memcache.sh 2019-01-15 14:37:02 +08:00
970cc56ea1 update 2019-01-15 14:31:14 +08:00
4a582d75df php56 memcache 2019-01-15 14:31:08 +08:00
9438388877 php56
zendguardloader.sh
2019-01-15 14:01:57 +08:00
cc39d7cb25 mysql 工具功能ok 2019-01-15 12:59:56 +08:00
b7394e2f79 update 2019-01-14 23:29:07 +08:00
ab52563f3f update 2019-01-14 18:03:45 +08:00
c5c49f2ec0 Update php.js 2019-01-14 16:50:57 +08:00
a76c6af147 Update yaf.sh 2019-01-14 16:49:50 +08:00
e71b00669e ipdate 2019-01-14 15:28:27 +08:00
02df20fc57 update 2019-01-14 13:13:24 +08:00
cc0e4d1064 update 2019-01-13 23:51:09 +08:00
bff6b17839 Update simdht.js 2019-01-13 00:49:04 +08:00
9c397fff8a update 2019-01-13 00:45:45 +08:00
255f4b95a0 update 2019-01-12 23:49:41 +08:00
a9ed883407 update 2019-01-12 21:29:07 +08:00
2b446087fc update 2019-01-11 19:00:16 +08:00
6e9dc8e9e6 update 2019-01-11 18:12:08 +08:00
a08e48c139 Update index.py 2019-01-11 15:38:30 +08:00
557aabfaf8 Update simdht_worker.py 2019-01-11 14:56:03 +08:00
97c02f00a0 Update simdht_worker.py 2019-01-11 14:54:08 +08:00
2280d41ddd Update simdht_worker.py 2019-01-11 14:39:36 +08:00
72fb2d1ecc Update simdht_worker.py 2019-01-11 14:38:15 +08:00
85c88dcde0 Update simdht_worker.py 2019-01-11 14:37:22 +08:00
bd9f7510d3 update 2019-01-11 14:25:26 +08:00
e39b06cf83 Update simdht_worker.py 2019-01-11 14:18:33 +08:00
ed992ff1a3 update 2019-01-11 13:53:25 +08:00
f470ae037f update 2019-01-11 10:40:30 +08:00
b9f9b7c49d Update index.py 2019-01-11 10:38:10 +08:00
29b525cbee update 2019-01-11 10:35:07 +08:00
5fd8873068 Update index.html 2019-01-11 02:21:23 +08:00
7627ba6f4b Update metadata.py 2019-01-11 02:17:54 +08:00
e0b5956ad5 update 2019-01-11 02:13:40 +08:00
d7b09afd02 Update public.js 2019-01-11 01:48:50 +08:00
a5e146e918 update 2019-01-11 01:45:04 +08:00
666738eb56 Update simdht.js 2019-01-11 01:26:30 +08:00
75c3701e21 Update simdht_worker.py 2019-01-11 01:13:02 +08:00
733de4a0ff update 2019-01-11 01:09:23 +08:00
aedb8bba05 update 2019-01-11 00:56:02 +08:00
003e11eda3 Update simdht.sql 2019-01-11 00:45:52 +08:00
f44de8ec5c Update layout.html 2019-01-11 00:26:33 +08:00
dea8263e98 Update index.py 2019-01-11 00:23:24 +08:00
40456846a8 update 2019-01-11 00:09:06 +08:00
99ac5f34f0 update 2019-01-10 21:08:07 +08:00
bef1c16cb5 Update simdht_worker.py 2019-01-10 18:05:11 +08:00
d1282b667d Update db.cfg 2019-01-10 18:03:33 +08:00
222b878c79 Update simdht_worker.py 2019-01-10 17:55:29 +08:00
9bd6ec598d update 2019-01-10 17:50:53 +08:00
8bff295837 Update index.py 2019-01-10 14:52:22 +08:00
f28b0c3878 Update public.js 2019-01-10 14:48:44 +08:00
58fa31352e update 2019-01-10 13:13:18 +08:00
afa2e2e773 update 2019-01-10 01:07:53 +08:00
0b7548d10f update 2019-01-10 00:52:03 +08:00
f53b4f4139 Update mysql.js 2019-01-09 19:52:05 +08:00
f338814f97 Update mysql.js 2019-01-09 19:38:00 +08:00
28f2b28a53 update 2019-01-09 19:28:21 +08:00
e0861a2a9e up 2019-01-09 16:37:57 +08:00
72e23f11a4 Update index.py 2019-01-09 16:10:31 +08:00
256be27d3a update 2019-01-09 16:10:01 +08:00
482759a0e9 update 2019-01-09 13:51:14 +08:00
0faf8036da Update mysql.js 2019-01-08 23:38:36 +08:00
c8289a732c update 2019-01-08 20:23:18 +08:00
a579e5b1d6 update 2019-01-08 17:44:30 +08:00
5aa714876f update 2019-01-08 17:23:05 +08:00
b75c1c1049 update 2019-01-08 14:51:45 +08:00
9c03f9d8b7 update 2019-01-08 11:35:36 +08:00
f255eb1fda up 2019-01-07 23:31:13 +08:00
f7d17302a5 Update index.html 2019-01-07 19:58:38 +08:00
161d9656a8 update 2019-01-07 19:56:53 +08:00
d76f0b22f8 update 2019-01-07 18:05:45 +08:00
96f3e36183 Update index.py 2019-01-07 14:05:24 +08:00
f13b4c73b2 Update gogs.tpl 2019-01-07 14:03:11 +08:00
aa0f53f2fb update 2019-01-07 13:49:03 +08:00
fcd3088bee Update index.py 2019-01-07 13:48:54 +08:00
889757d42e up 2019-01-06 23:00:32 +08:00
4204310442 Update index.py 2019-01-06 21:50:01 +08:00
3209837e99 phpmyadmin init 2019-01-06 21:20:17 +08:00
7ad3aa3b21 update 2019-01-06 20:03:27 +08:00
e9ddd3bfa2 Update index.py 2019-01-06 17:14:55 +08:00
7a0042ff65 Update my.cnf 2019-01-06 16:33:09 +08:00
e5662b4ae7 Update install.sh 2019-01-06 16:21:48 +08:00
1ac3b3ae9d Update index.py 2019-01-06 16:19:06 +08:00
29e81cfdfe Update index.py 2019-01-06 16:12:02 +08:00
a1cf9fc980 up 2019-01-06 16:04:06 +08:00
2072955c37 Update mysql.js 2019-01-06 16:01:30 +08:00
8cc15d0c00 Update index.py 2019-01-06 15:25:37 +08:00
aaca84e1bc update 2019-01-06 15:17:20 +08:00
906cf1a8dc 数据库调整 2019-01-06 13:12:53 +08:00
b4c22268b1 Update index.py 2019-01-06 11:33:41 +08:00
157280c508 update 2019-01-05 22:06:15 +08:00
266ec5fde3 Update index.py 2019-01-05 19:46:18 +08:00
17a873b775 update 2019-01-05 19:10:58 +08:00
27294b5c35 Update index.py 2019-01-05 15:14:57 +08:00
28fcdd303f u 2019-01-05 15:07:40 +08:00
329adc2f6f update 2019-01-05 14:26:19 +08:00
5e076aee60 Update index.py 2019-01-05 11:42:29 +08:00
c95ea69f16 Update index.py 2019-01-05 11:41:08 +08:00
5a52354541 update 2019-01-04 19:16:47 +08:00
4ebf6af532 Update index.py 2019-01-04 18:07:50 +08:00
5a8e903695 Update pure-ftpd.conf 2019-01-04 18:02:03 +08:00
667956a6b9 update 2019-01-04 17:56:41 +08:00
3834eda363 Update index.py 2019-01-04 16:32:19 +08:00
58bd54ee67 Update index.py 2019-01-04 16:23:39 +08:00
e7c228cd35 Update db.py 2019-01-04 16:11:33 +08:00
8d948ca74b ftp基本ok 2019-01-04 15:31:19 +08:00
16c9103549 update 2019-01-04 14:20:30 +08:00
a461c143ee u 2019-01-04 11:53:31 +08:00
a3ca576667 Update ftp.js 2019-01-03 19:08:34 +08:00
f2bdce2ec1 搜索 2019-01-03 18:49:38 +08:00
ba560eb468 update 2019-01-03 17:34:23 +08:00
dc2c87999a update 2019-01-03 11:03:46 +08:00
174cf75755 up 2019-01-03 00:39:19 +08:00
0f4a16ace6 update 2019-01-02 18:27:00 +08:00
32a2acf61b update 2019-01-02 17:48:55 +08:00
328b67bd88 u 2019-01-02 17:02:24 +08:00
0d6f9b5c5f update 2019-01-02 16:54:52 +08:00
b359a594cd Update soft.js 2019-01-02 16:43:07 +08:00
8e31452c19 update 2019-01-02 16:27:18 +08:00
54ded3ae58 updata 2019-01-02 16:13:21 +08:00
7a8ab1acf1 update 2019-01-02 13:58:53 +08:00
e4179b4ae5 update 2019-01-02 13:29:29 +08:00
80fb58cefe Update index.html 2018-12-29 16:29:14 +08:00
87c8b585f8 Delete announce_server.py 2018-12-29 13:09:51 +08:00
90bc1750c7 update 2018-12-29 12:42:29 +08:00
5b2839515b update 2018-12-28 18:11:01 +08:00
392ab0e8cd simdht 2018-12-28 17:50:22 +08:00
e1f9aeb065 update 2018-12-28 17:33:20 +08:00
7bb412a0bd update 2018-12-28 17:02:38 +08:00
f67d9e088e update 2018-12-28 16:33:37 +08:00
ee7c42481f Update crontab.js 2018-12-28 14:18:15 +08:00
f7a764d6a4 update 2018-12-28 14:08:49 +08:00
d8ab3c2511 update 2018-12-28 13:15:03 +08:00
a36c619f23 Update __init__.py 2018-12-28 13:07:21 +08:00
1280c993fd Update login.html 2018-12-28 13:06:07 +08:00
b433042a87 update 2018-12-28 11:40:21 +08:00
62cb495ee0 update 2018-12-28 11:31:08 +08:00
feb91ce0b9 Update system_api.py 2018-12-28 11:12:50 +08:00
48b123ae17 update 2018-12-28 10:49:15 +08:00
45374c8e65 u 2018-12-27 23:16:12 +08:00
3e9c884d83 update 2018-12-27 19:38:15 +08:00
501c35f1f6 Update index.py 2018-12-27 19:17:18 +08:00
895bf541e2 Update install.sh 2018-12-27 19:14:54 +08:00
58b7cd5193 update 2018-12-27 19:14:18 +08:00
05184e5608 Update index.py 2018-12-27 19:11:08 +08:00
da05ef9b15 Update index.py 2018-12-27 19:00:15 +08:00
5ef627e490 update 2018-12-27 18:15:31 +08:00
d0e5ff7461 update 2018-12-27 17:22:11 +08:00
8b8533e820 Update www.conf 2018-12-27 16:06:39 +08:00
c6d591100f Update commit.tpl 2018-12-27 15:22:51 +08:00
cfe5463d87 Update commit.tpl 2018-12-27 15:14:19 +08:00
8825d01455 Update commit.tpl 2018-12-27 15:03:21 +08:00
57f2174764 Update install.sh 2018-12-27 14:42:04 +08:00
cc430c30ef up 2018-12-27 14:32:00 +08:00
3d150074fb update 2018-12-26 21:02:29 +08:00
5263efbbac Update install.sh 2018-12-26 20:33:25 +08:00
d26c529a3a Update commit.tpl 2018-12-26 20:28:22 +08:00
897f3ddfe6 Update csvn.js 2018-12-26 20:06:06 +08:00
606fc44641 Update gae.js 2018-12-26 20:04:41 +08:00
c49bed0474 Update index.py 2018-12-26 19:57:51 +08:00
c92f110893 Update index.py 2018-12-26 19:47:14 +08:00
be526ccd4e Update gae.js 2018-12-26 18:14:28 +08:00
31d4fef0ee Update index.py 2018-12-26 18:10:20 +08:00
f28784db54 update 2018-12-26 18:04:57 +08:00
6ca67961fb update 2018-12-26 15:57:26 +08:00
b367c45dd6 update 2018-12-26 15:10:29 +08:00
10661e4f14 update 2018-12-26 14:20:27 +08:00
684f80bec9 Update csvn.js 2018-12-26 14:20:10 +08:00
5523488b4c Update gae.js 2018-12-26 13:57:00 +08:00
c793e73d5d update 2018-12-26 12:38:13 +08:00
6f8bc6d012 Update ico.png 2018-12-26 10:22:53 +08:00
db9fcd952c Update crontab_api.py 2018-12-26 10:08:22 +08:00
fdfd90a7e5 Update requirements.txt 2018-12-26 10:08:18 +08:00
2c2a50f301 Update __init__.py 2018-12-25 23:48:29 +08:00
a96d0b7401 update 2018-12-25 17:43:28 +08:00
d8362d1341 update 2018-12-25 17:37:08 +08:00
b97a14638f Update system_api.py 2018-12-25 16:58:25 +08:00
3e705b02cf update 2018-12-25 16:56:57 +08:00
4df0859734 update 2018-12-25 15:41:46 +08:00
4c8022d47b update 2018-12-25 15:12:59 +08:00
21d7ab3406 update 2018-12-25 14:30:51 +08:00
9dd1c46521 Update __init__.py 2018-12-25 11:26:46 +08:00
438cfb6256 Update __init__.py 2018-12-25 11:21:20 +08:00
a2bda07cc6 update 2018-12-25 10:52:39 +08:00
9615fb2203 Update config.py 2018-12-25 10:09:33 +08:00
49c181c577 Update cli.sh 2018-12-25 10:07:16 +08:00
0fa5e4fb48 update 2018-12-24 22:33:49 +08:00
8e7130c382 Update app.py 2018-12-24 15:38:55 +08:00
33c1ac82c8 Update index.html 2018-12-24 11:48:07 +08:00
df5aec2e8f Update install.sh 2018-12-24 11:37:53 +08:00
6c864177ee Update install.sh 2018-12-24 11:37:35 +08:00
9ee09b0e7d update 2018-12-24 11:14:51 +08:00
b7da91f92b update 2018-12-21 11:44:38 +08:00
17e6703c07 Update site.js 2018-12-21 10:52:21 +08:00
a5f77a37f2 Update mw.tpl 2018-12-21 10:07:24 +08:00
78fc9fd90f u 2018-12-20 23:41:26 +08:00
700f042033 防盗链 ok 2018-12-20 22:30:00 +08:00
e44768e608 update 2018-12-20 21:45:09 +08:00
2acef86207 Update config.py 2018-12-20 21:35:49 +08:00
6256bb02da Update cli.sh 2018-12-20 21:34:52 +08:00
04f5a27492 Update system_api.py 2018-12-20 21:34:47 +08:00
7cd476696a Update site.js 2018-12-20 19:28:47 +08:00
2ecaf0e2a3 update 2018-12-20 19:22:33 +08:00
c5d3494a94 update 2018-12-20 14:15:13 +08:00
af0658fd41 update 2018-12-20 14:05:57 +08:00
cccbd88145 站点添加优化 2018-12-20 13:39:43 +08:00
48aad5b248 Update index.py 2018-12-20 13:29:05 +08:00
d843213c39 流量控制功能ok 2018-12-20 13:27:50 +08:00
7ad33c5c59 update 2018-12-20 11:12:39 +08:00
ee56cfe5ab Update README.md 2018-12-20 11:07:36 +08:00
c6b38aa996 update 2018-12-20 10:45:43 +08:00
c5205c2d55 文件保存 2018-12-20 00:48:41 +08:00
1be07f96ff Update install.sh 2018-12-20 00:26:07 +08:00
9f4af88c1e update 2018-12-19 23:37:31 +08:00
ebc0559dff up 2018-12-19 20:43:33 +08:00
fe320ecd3b phpinfo ok 2018-12-19 17:17:07 +08:00
02c06e7ff1 update 2018-12-19 16:50:15 +08:00
6d90d6fde5 update 2018-12-19 15:50:07 +08:00
bfc0b9efa3 update 2018-12-19 15:41:00 +08:00
6e4e7bcf68 update 2018-12-19 15:21:31 +08:00
5da505084d update 2018-12-19 13:54:19 +08:00
f19df17ef5 update 2018-12-19 10:42:37 +08:00
d99e89744d Update index.py 2018-12-19 10:34:18 +08:00
9695fe4b9b Update index.py 2018-12-18 23:22:08 +08:00
5907dc36c5 Update index.py 2018-12-18 19:50:57 +08:00
d694af9358 update 2018-12-18 19:43:41 +08:00
4dc2828c59 update 2018-12-18 19:37:46 +08:00
37519b4c92 超时限制,上传限制 2018-12-18 18:09:54 +08:00
90999c7ae1 u 2018-12-18 15:37:02 +08:00
f16d9ea269 update 2018-12-18 15:23:48 +08:00
86098541e0 PHP update 2018-12-18 15:13:33 +08:00
9ef04a4d9e Create php.ini 2018-12-18 15:13:22 +08:00
752f8fae5a Update csvn.js 2018-12-18 15:13:19 +08:00
c5fdecf459 up 2018-12-18 13:43:24 +08:00
19284cd5ef update 2018-12-18 13:17:37 +08:00
da92ab1c89 update 2018-12-18 10:38:46 +08:00
18ca47e8b3 up 2018-12-17 23:26:00 +08:00
8b624297ba Update site_api.py 2018-12-17 21:40:08 +08:00
f0d9ff2ae9 Update cli.sh 2018-12-17 21:38:15 +08:00
21b2c17220 Update site_api.py 2018-12-17 21:38:11 +08:00
0df898a7d9 Update install.sh 2018-12-17 21:38:08 +08:00
cf1f4c8538 Update default.sql 2018-12-17 21:35:13 +08:00
89ecdcd29a update 2018-12-17 19:17:51 +08:00
0c8fa5e616 Update site.py 2018-12-17 18:21:06 +08:00
f9252da1b0 update 2018-12-17 18:16:59 +08:00
e31cbad7dd update 2018-12-17 17:21:33 +08:00
5bed9f0802 update 2018-12-17 16:47:40 +08:00
1ae4b54779 update 2018-12-17 15:20:30 +08:00
2b2a75adf0 Update openresty.js 2018-12-17 11:23:05 +08:00
55184341d7 Update install.sh 2018-12-17 11:17:58 +08:00
6504decc30 update 2018-12-17 11:11:33 +08:00
843d798b91 update 2018-12-17 11:06:58 +08:00
087a6b4809 update 2018-12-16 23:29:35 +08:00
44438bd9aa Update install.sh 2018-12-15 11:18:33 +08:00
c33cba0e85 update 2018-12-15 01:22:00 +08:00
cdc3c95367 update 2018-12-14 23:29:47 +08:00
222cebe1b3 update 2018-12-14 21:53:33 +08:00
2fc2eff97e Update install.sh 2018-12-14 21:35:59 +08:00
79f8baeeb3 update 2018-12-14 21:35:55 +08:00
0399219df6 Update pick_filter.txt 2018-12-14 21:34:13 +08:00
cd0d5ede16 Update pick_filter.txt 2018-12-14 21:31:58 +08:00
1e6d1c6127 Update info.json 2018-12-14 19:21:23 +08:00
ff87dbe258 Update index.py 2018-12-14 18:38:27 +08:00
7d6ddb40db update 2018-12-14 18:29:53 +08:00
1cb57d3f65 update 2018-12-14 18:04:50 +08:00
9ed434d274 update 2018-12-14 17:39:47 +08:00
f532a376a7 update 2018-12-14 16:06:59 +08:00
4405f7720b Update info.json 2018-12-14 15:20:16 +08:00
fbde4aab88 Update commit.tpl 2018-12-14 15:20:11 +08:00
864691d357 同步数据处理 2018-12-14 14:52:33 +08:00
95bf0cb1e8 修正权限格式 2018-12-14 13:56:16 +08:00
126f2d553d Update index.py 2018-12-13 23:17:49 +08:00
2fb88be080 update 2018-12-13 23:15:33 +08:00
fa307cdb49 Update commit.tpl 2018-12-13 23:05:55 +08:00
0850b6ed44 Update index.py 2018-12-13 22:52:20 +08:00
ec1e99f9ca Update index.py 2018-12-13 22:47:45 +08:00
546dc4d7eb Update index.py 2018-12-13 22:45:16 +08:00
9b0b4ac305 Update index.py 2018-12-13 22:40:37 +08:00
23a1f3936d update 2018-12-13 22:37:27 +08:00
4cb22a1e35 update 2018-12-13 20:01:29 +08:00
3e3cdbe18c update 2018-12-13 18:20:27 +08:00
bdc46d9401 Update pick_filter.txt 2018-12-13 18:08:55 +08:00
64986dd125 gogs ready 2018-12-13 18:07:44 +08:00
7ee00ab0b5 Update csvn.js 2018-12-13 17:13:48 +08:00
488d92ba19 update 2018-12-13 17:09:23 +08:00
9cebfb64cb 查找更新 2018-12-13 15:36:19 +08:00
7800429f8d update 2018-12-13 15:20:47 +08:00
7954714bb7 update 2018-12-13 14:57:30 +08:00
1d396b73f0 Update index.html 2018-12-13 14:37:49 +08:00
5f95a1d56a update 2018-12-13 14:37:38 +08:00
51951a2685 update 2018-12-13 14:37:31 +08:00
737453600d Update csvn.js 2018-12-13 13:51:14 +08:00
17ef460f4c update 2018-12-13 13:34:06 +08:00
38be955738 add debug 2018-12-13 12:56:06 +08:00
daf5c7c2b0 Update pick_filter.txt 2018-12-13 12:51:22 +08:00
acdb35f395 Update install.sh 2018-12-13 11:14:54 +08:00
5e8a15c230 update 2018-12-13 01:28:54 +08:00
34bcdd915c Update setting.py 2018-12-13 01:14:25 +08:00
aa718adfea Update setting.py 2018-12-13 01:10:07 +08:00
936592661b update 2018-12-13 01:09:38 +08:00
c740b4affb Update config.py 2018-12-13 00:54:13 +08:00
042b07efa2 Update csvn.js 2018-12-13 00:49:11 +08:00
6a6d22fd2d Update index.py 2018-12-12 23:37:11 +08:00
f99502d2c8 Update config.py 2018-12-12 21:57:24 +08:00
1cf41348b7 Update config.py 2018-12-12 21:40:24 +08:00
acdb226df9 update 2018-12-12 21:35:04 +08:00
6259f21196 update 2018-12-12 19:30:42 +08:00
6ad1292003 Update task.py 2018-12-12 19:26:28 +08:00
a682ba3e43 Update mw.tpl 2018-12-12 19:21:44 +08:00
7509b259e7 Update setting.py 2018-12-12 18:47:42 +08:00
8d170d87e4 update 2018-12-12 18:45:33 +08:00
bc4e5f6a87 update 2018-12-12 18:06:02 +08:00
954f66c8dc update 2018-12-12 15:11:55 +08:00
a7f860de2b Update index.py 2018-12-12 14:06:10 +08:00
6e7e291da3 update 2018-12-12 13:57:43 +08:00
2bca78c32d update 2018-12-12 10:31:01 +08:00
fb4311cdbf update 2018-12-12 00:07:01 +08:00
d889bf2cf3 Update index.py 2018-12-11 19:51:01 +08:00
511a7ac12b Update index.py 2018-12-11 19:30:02 +08:00
03e126cb48 Update index.py 2018-12-11 17:56:05 +08:00
2acbe56e21 update 2018-12-11 17:53:37 +08:00
8425aa4942 update 2018-12-11 14:49:26 +08:00
17ad9abe6b update 2018-12-11 14:25:12 +08:00
11166bbab1 Update files.py 2018-12-11 13:54:50 +08:00
f5f3f7ded5 update 2018-12-11 13:46:27 +08:00
26bae283be update 2018-12-11 13:29:27 +08:00
bfb12692a6 Update csvn.js 2018-12-11 11:01:28 +08:00
6bc6f17783 Update csvn.js 2018-12-11 10:37:45 +08:00
cd6f86ebfa Update csvn.js 2018-12-11 10:34:20 +08:00
5abb2613a1 update 2018-12-11 10:31:53 +08:00
a08dee242a Update csvn.js 2018-12-11 01:17:09 +08:00
2700b6b67b Update csvn.js 2018-12-11 01:15:09 +08:00
e41148d72d Update index.py 2018-12-11 00:46:36 +08:00
9b5c80bc72 Update csvn.js 2018-12-11 00:44:29 +08:00
958755d18d update 2018-12-11 00:28:09 +08:00
9af7e0f95b up 2018-12-10 19:37:38 +08:00
90e86cda0d update 2018-12-10 19:17:40 +08:00
ea2ed9d003 Update crontab.html 2018-12-10 17:35:46 +08:00
67eb3590c7 update 2018-12-10 17:27:09 +08:00
e66afbbb2d Update index.py 2018-12-10 16:41:01 +08:00
f959391b85 Create mw.sh 2018-12-10 16:29:04 +08:00
663e95288a update 2018-12-10 16:18:35 +08:00
0af3c7622d update 2018-12-10 15:53:06 +08:00
40e2186a5b update 2018-12-10 15:32:31 +08:00
121c972951 优化显示 2018-12-10 15:10:07 +08:00
229cb977a1 update 2018-12-10 14:22:22 +08:00
ae845a702c u 2018-12-10 13:12:33 +08:00
35b0b1d153 Update public.js 2018-12-10 11:43:20 +08:00
4801850373 openresty error_logs 2018-12-10 11:42:13 +08:00
8b3d0cbba4 update 2018-12-10 10:45:30 +08:00
4f580d0427 update 2018-12-10 10:44:54 +08:00
2f794c5b73 update 2018-12-10 10:33:03 +08:00
21cd34d272 Update index.html 2018-12-09 23:30:57 +08:00
c58e1f7278 Update index.py 2018-12-09 23:30:54 +08:00
5b49f24a8d Update php56.tpl 2018-12-09 23:30:52 +08:00
ce89a2a275 Update php.js 2018-12-09 23:30:50 +08:00
35f905e94c Update public.js 2018-12-09 23:30:46 +08:00
1c431286e4 Update index.py 2018-12-09 21:23:56 +08:00
705cef730b Update public.js 2018-12-09 20:33:16 +08:00
2a5da5593b Update soft.js 2018-12-09 20:33:14 +08:00
22692d8ed4 Update index.py 2018-12-09 20:31:39 +08:00
5cdae707e9 Create php56.tpl 2018-12-09 20:31:31 +08:00
5be9f1ae66 Update public.js 2018-12-09 20:31:28 +08:00
ba931a0c2a Update index.py 2018-12-09 19:10:14 +08:00
5b87572bff up 2018-12-09 18:58:41 +08:00
d51de312ac Update index.py 2018-12-09 14:07:13 +08:00
bcd2e7298b update 2018-12-09 13:37:52 +08:00
a985511b3b Update index.py 2018-12-09 13:28:36 +08:00
abb9fb72f0 Update index.py 2018-12-09 13:23:37 +08:00
b36ad3a595 Update index.py 2018-12-09 13:20:05 +08:00
a118f33f57 Update index.py 2018-12-09 13:17:15 +08:00
58b888edcd Update index.py 2018-12-09 13:06:15 +08:00
43d906139e Update index.py 2018-12-09 13:00:18 +08:00
b91bc040d4 Update index.py 2018-12-09 12:59:36 +08:00
c6eba5bbf1 Update index.py 2018-12-09 12:52:41 +08:00
1adbf733d8 Update index.py 2018-12-09 12:50:30 +08:00
913d483e63 Update index.py 2018-12-09 12:40:43 +08:00
9951f7151e Update index.py 2018-12-09 12:37:49 +08:00
167a386a0d update 2018-12-09 11:59:00 +08:00
5473ee74cb Update install.sh 2018-12-09 11:43:57 +08:00
dbeefc06c8 update 2018-12-09 11:42:11 +08:00
444730e553 Update install.sh 2018-12-09 11:36:18 +08:00
8a2e17198e Update index.py 2018-12-09 11:16:32 +08:00
bc41788d49 u 2018-12-08 23:26:34 +08:00
ebd8e93b16 update 2018-12-08 23:02:58 +08:00
a45994c3c7 update 2018-12-08 22:33:32 +08:00
f41f616daf update 2018-12-08 17:30:58 +08:00
da5b9351e2 Update install.sh 2018-12-08 17:19:17 +08:00
3c080e0264 Update index.py 2018-12-08 17:09:36 +08:00
dc62aabfd4 Update index.html 2018-12-08 17:09:33 +08:00
c6da2e56ee Create csvn.js 2018-12-08 17:09:30 +08:00
461f3dcb0a Update index.html 2018-12-08 17:09:25 +08:00
ee5b9f35ad Update soft.js 2018-12-08 17:07:51 +08:00
3ad8496daf Update public.js 2018-12-08 16:49:37 +08:00
77023263a6 Update index.py 2018-12-08 16:25:45 +08:00
6497627931 update 2018-12-08 16:24:36 +08:00
2ae3426c82 Update index.py 2018-12-08 15:47:40 +08:00
dbeb919f05 update 2018-12-08 14:43:32 +08:00
2106746f6c Delete phpfpm_status.conf 2018-12-08 14:43:21 +08:00
31d5b90670 公共js 2018-12-08 14:43:17 +08:00
ceaf9c42db update 2018-12-08 12:42:02 +08:00
9067778bf3 u 2018-12-07 19:12:18 +08:00
99053b67ce 调整 2018-12-07 18:47:33 +08:00
07b8d91f31 redis调整ok 2018-12-07 17:44:32 +08:00
e9d4e09049 Update index.py 2018-12-07 16:44:08 +08:00
629416760f Update install.sh 2018-12-07 15:55:12 +08:00
d1ade4355e Update index.py 2018-12-07 15:52:40 +08:00
4508e30ea7 加入自启动选项功能
1.memcached 调整ok
2018-12-07 15:49:59 +08:00
b1c5c90bef update 2018-12-07 14:18:30 +08:00
e9a7db2c1d update 2018-12-06 23:29:41 +08:00
63e5f26491 u 2018-12-06 19:49:54 +08:00
ed93ccc0ee Update plugin_api.py 2018-12-06 15:41:57 +08:00
929a50c137 up 2018-12-06 00:09:25 +08:00
fe87092750 Update soft.js 2018-12-05 20:26:38 +08:00
c144cead18 u 2018-12-05 20:15:00 +08:00
afdc9720fc u 2018-12-05 18:46:45 +08:00
194c7b9d45 Delete control.conf 2018-12-05 18:45:57 +08:00
162557230a u 2018-12-05 17:35:24 +08:00
f4dfe502cb u 2018-12-05 17:34:32 +08:00
7a3d49a9cf u 2018-12-05 17:04:20 +08:00
49f1407c42 u 2018-12-05 16:24:39 +08:00
319f72865d Update install.sh 2018-12-05 15:13:28 +08:00
0eaa6f38e0 update 2018-12-05 14:56:50 +08:00
eeef8d488c Update info.json 2018-12-05 14:20:34 +08:00
4e69f9540a u 2018-12-05 14:12:10 +08:00
a0e8d75af7 u 2018-12-05 14:00:31 +08:00
f54f7d4ce3 Update soft.js 2018-12-05 11:22:38 +08:00
5f4893c115 u 2018-12-05 11:18:31 +08:00
a48b869fe9 abkill 2018-12-05 11:15:06 +08:00
266a8cf806 up 2018-12-05 11:09:48 +08:00
13e4dcf8ad u 2018-12-05 11:01:25 +08:00
1ca469518d csvn update 2018-12-05 10:36:41 +08:00
4284a3daf4 Update site.html 2018-12-04 23:35:33 +08:00
84995650ee Update task.py 2018-12-04 23:16:47 +08:00
fa662d75d6 update 2018-12-04 23:15:00 +08:00
842c0daf70 up 2018-12-04 19:38:27 +08:00
798608287e Update info.json 2018-12-04 19:22:10 +08:00
437225374e u 2018-12-04 19:20:54 +08:00
3a442570db Update system_api.py 2018-12-04 19:19:26 +08:00
366c3677c2 u 2018-12-04 18:55:42 +08:00
6dcf1db856 u 2018-12-04 18:55:27 +08:00
b3ca295e51 Update info.json 2018-12-04 13:59:48 +08:00
03f06ee384 Update .gitignore 2018-12-04 13:56:47 +08:00
2dc96cd04e u 2018-12-04 13:38:08 +08:00
a875293116 u 2018-12-04 13:26:58 +08:00
8735fb9238 u 2018-12-04 13:22:22 +08:00
58fcf0e8f9 Update install.sh 2018-12-04 13:13:36 +08:00
fccc30ebb1 Update system_api.py 2018-12-04 13:05:15 +08:00
6b9da57ff2 u 2018-12-03 19:37:46 +08:00
cd6b2ad65e 代码打包 2018-12-03 18:22:04 +08:00
60b2834adf Update system_api.py 2018-12-03 18:03:28 +08:00
c74e0428fd Update info.json 2018-12-03 17:57:08 +08:00
20d486629e u 2018-12-03 17:52:11 +08:00
f984e4ecc7 u 2018-12-03 17:50:43 +08:00
0bdea14560 Update .gitignore 2018-12-03 17:24:57 +08:00
0c3599facb u 2018-12-03 17:24:49 +08:00
05eb434bf8 Update system_api.py 2018-12-03 16:44:35 +08:00
12dccc1df0 u 2018-12-03 16:44:29 +08:00
11e7316911 Update info.json 2018-12-03 14:24:40 +08:00
26a6a80504 u 2018-12-03 13:52:12 +08:00
498799578a u 2018-12-03 13:44:20 +08:00
6a5b009766 u 2018-12-03 13:39:06 +08:00
8e23411be8 u 2018-12-03 13:11:43 +08:00
b597255d68 u 2018-12-03 12:49:03 +08:00
8979011ec3 u 2018-12-03 10:58:41 +08:00
11a21f9a8b Update crontab.html 2018-12-02 23:27:47 +08:00
1a12f625cd up 2018-12-02 22:58:14 +08:00
11e44d5b0e 监控完成 2018-12-02 21:59:33 +08:00
47c1394de6 u 2018-12-02 12:58:59 +08:00
5e7fa28feb Update task.py 2018-12-01 18:04:59 +08:00
d04f891ee7 up 2018-12-01 18:02:30 +08:00
3d28e0a3cb u 2018-12-01 17:20:10 +08:00
37112546b9 Delete system.db 2018-11-30 19:13:20 +08:00
cb719c9973 Update .gitignore 2018-11-30 19:13:01 +08:00
7ec5fe84b2 update 2018-11-30 19:12:16 +08:00
c68cce0198 up 2018-11-30 17:39:38 +08:00
0d7fd11de5 up 2018-11-30 16:58:50 +08:00
643a2e8cf8 u 2018-11-30 14:54:06 +08:00
35ee7d3d10 优化 2018-11-30 02:03:05 +08:00
2ce3871ee2 Update .gitignore 2018-11-29 21:04:39 +08:00
812ce86187 u 2018-11-29 21:04:13 +08:00
3d44b3014f u 2018-11-29 19:16:12 +08:00
092494a216 Update soft.js 2018-11-29 19:09:27 +08:00
a21ad254b7 Update soft.js 2018-11-29 19:07:28 +08:00
ebd6b9f389 u 2018-11-29 18:19:18 +08:00
33b90a976b 版本显示优化 2018-11-28 23:56:10 +08:00
2518d32019 wd 2018-11-28 21:35:26 +08:00
4ded4679f3 up 2018-11-28 19:11:55 +08:00
28d3996d17 openresty 2018-11-27 23:29:28 +08:00
b76950ed3b php 72 2018-11-27 23:05:01 +08:00
d49aa168eb u 2018-11-27 19:20:46 +08:00
5304d0b228 u 2018-11-27 14:37:24 +08:00
56e4ef1a4e u 2018-11-27 13:17:06 +08:00
91fc83e0ba a 2018-11-26 19:18:50 +08:00
fc0fdd5772 u 2018-11-26 16:08:19 +08:00
0d0007d9a1 u 2018-11-26 15:57:49 +08:00
a74ace856a u 2018-11-26 15:54:42 +08:00
f46af799a9 代码调整 2018-11-26 14:35:52 +08:00
3e4facbf57 u 2018-11-26 13:57:06 +08:00
ff9466d0a4 wd 2018-11-26 11:51:27 +08:00
9cbcff5dbc 优化 2018-11-26 10:55:53 +08:00
90834415bf update 2018-11-25 23:30:19 +08:00
c2862ab5d4 Update index.js 2018-11-25 18:11:30 +08:00
664a7864bc 首页界面更新 2018-11-25 18:05:39 +08:00
9cf6a40493 update 2018-11-25 17:48:48 +08:00
028422337e mem 2018-11-25 16:46:23 +08:00
5f10d9433c redis 设置 2018-11-25 16:13:59 +08:00
ed49f0b0bd Update redis.js 2018-11-23 19:14:18 +08:00
090fc0f243 redis文件修改 2018-11-23 15:02:02 +08:00
f2df81694f Update install.sh 2018-11-23 11:45:53 +08:00
6cf2e2d6b6 wd 2018-11-23 11:39:15 +08:00
defdc3d3b8 Update README.md 2018-11-23 10:09:19 +08:00
6d1d1b882e Update install.sh 2018-11-22 18:58:46 +08:00
54f90c9300 Update install.sh 2018-11-22 18:56:28 +08:00
a1aa7d465d Update README.md 2018-11-22 18:49:41 +08:00
62214c2a88 Update plugins.py 2018-11-22 18:44:19 +08:00
d5a4958566 wd 2018-11-22 17:47:19 +08:00
0bca4a3589 wd 2018-11-22 17:08:26 +08:00
30bc8b1ec1 u 2018-11-21 19:27:26 +08:00
0472102a3a u 2018-11-21 19:15:37 +08:00
2da863d98a u 2018-11-21 18:18:17 +08:00
88bab4b15b wq 2018-11-21 10:15:35 +08:00
d1b4a1cde1 up 2018-11-20 19:11:09 +08:00
d88f6903da Update task.py 2018-11-20 18:54:29 +08:00
3a53b360b7 o 2018-11-20 17:43:29 +08:00
3e5b951a41 wd 2018-11-20 14:01:17 +08:00
272b6fdeea up 2018-11-19 13:32:17 +08:00
49ac781e87 wq 2018-11-13 14:18:06 +08:00
b4f9fa0976 Update route/dashboard.py 2018-11-12 17:24:59 +08:00
96baa99bdc wq 2018-11-12 17:22:47 +08:00
5db4f39c76 o 2018-11-12 14:43:14 +08:00
23dadd7f6f wq 2018-11-12 14:38:35 +08:00
7d8d48f3d5 wq 2018-11-12 12:55:17 +08:00
74fd4bbe08 o 2018-11-12 11:41:00 +08:00
30240443e6 update 2018-11-11 23:51:11 +08:00
e069c3a24e w 2018-11-09 16:41:11 +08:00
73e75abb5f w 2018-11-09 16:23:17 +08:00
b35d516a8e o 2018-11-09 15:46:28 +08:00
aa1875612b Update templates/default/layout.html 2018-11-09 11:10:33 +08:00
b189d5b485 Update templates/default/layout.html 2018-11-09 11:10:11 +08:00
33b43b253c Update templates/default/layout.html 2018-11-09 11:09:47 +08:00
86cfb1b9cf q 2018-11-08 22:56:12 +08:00
f93afb772c Update templates/default/login.html 2018-11-08 17:59:31 +08:00
bd49bd3004 Update scripts/install.sh 2018-11-08 17:54:27 +08:00
db26b09eba q 2018-11-08 17:38:15 +08:00
85da65ad1e Update templates/default/login.html 2018-11-08 17:24:44 +08:00
d9a409ffcc Update app.py 2018-11-08 17:22:03 +08:00
ea923a45a6 q 2018-11-08 17:19:13 +08:00
7480cfb5d8 Update static/css/install.css 2018-11-08 17:18:59 +08:00
be513af18e q 2018-11-08 17:09:25 +08:00
1c5e61a3de q 2018-11-08 17:09:06 +08:00
d26474f222 a 2018-11-08 17:08:41 +08:00
03c796775a Update static/js/jquery.qrcode.min.js 2018-11-08 17:06:06 +08:00
182d434f84 d 2018-11-08 17:04:57 +08:00
7c1d409e61 o 2018-11-08 16:53:01 +08:00
dab12535f2 Update templates/default/login.html 2018-11-08 00:02:08 +08:00
deffb3d61b Update route/dashboard.py 2018-11-08 00:02:05 +08:00
a4a45f2005 Update route/files.py 2018-11-07 18:45:34 +08:00
32d6a89bd4 Update route/dashboard.py 2018-11-07 18:28:48 +08:00
f41c2454ee u 2018-11-07 18:13:05 +08:00
76dba077c0 o 2018-11-06 23:45:28 +08:00
1c34488abb Update templates/default/login.html 2018-11-06 19:10:33 +08:00
6742d971eb u 2018-11-06 13:42:24 +08:00
3de01da4ba Update models/index.html 2018-11-06 13:23:16 +08:00
4ba526ca2b up 2018-11-06 00:28:02 +08:00
a4e8b6a137 u 2018-11-05 23:47:37 +08:00
50ad3ed7e7 ww 2018-11-05 23:42:01 +08:00
64d29659f7 u 2018-11-05 19:25:07 +08:00
2794f49df4 u 2018-11-05 19:05:33 +08:00
3e27f85719 u 2018-11-05 17:19:02 +08:00
a4d70f2294 up 2018-11-05 16:49:37 +08:00
f3cd1f597e up 2018-11-04 23:37:33 +08:00
489c363daf u 2018-11-04 23:20:06 +08:00
77f44481b3 up 2018-11-04 23:02:45 +08:00
fcd4ba024a u 2018-11-03 18:19:47 +08:00
ce6b15939d dd 2018-11-02 14:43:41 +08:00
baaccb7960 u 2018-11-02 13:38:20 +08:00
fb559e9f11 u 2018-11-02 10:18:58 +08:00
283a2c052b u 2018-10-29 20:19:59 +08:00
a7bd9e3290 csvn dev 2018-10-29 14:10:41 +08:00
b64dbb9aa4 Update data/system.db 2018-10-26 16:56:15 +08:00
d9f63c3a9a u 2018-10-26 16:53:20 +08:00
3c02af41bc u 2018-10-26 15:54:23 +08:00
ac87a6c8b1 Update app.py 2018-10-26 15:02:57 +08:00
f19dd2a2b9 u 2018-10-26 15:01:33 +08:00
cef7215fdc u 2018-10-26 13:53:39 +08:00
edb4fc96e1 u 2018-10-26 13:17:19 +08:00
af9f8b73ba 修改模板 2018-10-25 23:23:37 +08:00
c85152e85a update 2018-10-25 19:32:21 +08:00
2ee2440c68 u 2018-10-25 17:33:34 +08:00
ecfafc9723 u 2018-10-25 16:40:45 +08:00
dbb4414e65 Update .idea/vcs.xml 2018-10-24 17:27:45 +08:00
a028e93881 u 2018-10-17 22:57:37 +08:00
475cb5176d u 2018-10-17 00:29:33 +08:00
8b07bd80e6 u 2018-10-17 00:17:59 +08:00
50d26d932f Update templates/default/config.html 2018-10-17 00:08:44 +08:00
22b5ab1179 Update del_pyc.sh 2018-10-14 20:55:05 +08:00
f7c76fb261 画 2018-10-14 20:49:20 +08:00
6531f686ad Update templates/default/database.html 2018-10-14 18:20:27 +08:00
b716f05fb4 u 2018-10-14 17:37:43 +08:00
9a98f1c859 u 2018-10-14 12:47:54 +08:00
e92fc4cfd1 u 2018-10-14 11:49:24 +08:00
da1a76cbef u 2018-10-13 22:54:11 +08:00
fa6b7c21ac u 2018-10-12 19:09:54 +08:00
11748fd33b Update plugins/deployment/icon.png 2018-10-12 18:46:22 +08:00
267bbe3865 u 2018-10-12 10:35:29 +08:00
dd27e4b076 Update class/page.py 2018-10-12 10:28:52 +08:00
459229ba15 Update plugins/nginx/install.sh 2018-10-11 19:30:01 +08:00
94c5161fde u 2018-10-11 19:26:06 +08:00
5646d1404c u 2018-10-11 09:55:27 +08:00
ef8a10b68d Update views/plugins.py 2018-10-09 19:53:03 +08:00
c772696f3e Update views/plugins.py 2018-10-09 19:51:23 +08:00
45faf4e9dd Update views/plugins.py 2018-10-08 20:10:44 +08:00
1197 changed files with 99204 additions and 26827 deletions

21
.gitignore vendored
View File

@@ -8,13 +8,11 @@ __pycache__/
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
@@ -106,3 +104,22 @@ venv.bak/
.DS_Store
.idea/*.xml
.idea/*.iml
tmp/*.pl
tmp/*.log
*.swp
*.zip
scripts/init.d/mw
logs/*
data/*.db
data/control.conf
data/iplist.txt
data/json/index.json
data/json/config.json
data/site.pl
data/admin_path.pl
data/close.pl
ssl/input.pl
data/datadir.pl
data/502Task.pl
data/default.pl
data/backup.pl

6
.idea/vcs.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@@ -1,14 +1,46 @@
# mdweb
简单的Linux面板
### mdserver-web 0.8.6
简单的Linux面板,感谢BT.CN写出如此好的web管理软件。我一看到,就知道这是我一直想要的页面化管理方式。
复制了后台管理界面,按照自己想要的方式写了一版。
* ssh工具优化
* 面板收藏功能完成
* 网站子目录绑定
* 网站备份功能
* 自动更新优化
* 插件方式管理
基本上可以使用,后续会继续优化!欢迎提供意见!
### 主要插件介绍
* OpenResty - 轻量级,占有内存少,并发能力强。
* PHP[52-80] - PHP是世界上最好的编程语言。
* MySQL - MySQL是一种关系数据库管理系统。
* phpMyAdmin - 著名Web端MySQL管理工具。
* Memcached - 一个高性能的分布式内存对象缓存系统。
* Redis - 一个高性能的key-value数据库。
* CSVN - 最流行的SVN代码共享管理软件。
* PureFtpd - 一款专注于程序健壮和软件安全的免费FTP服务器软件。
* Gogs - 一款极易搭建的自助Git服务。
* Rsyncd - 通用同步服务。
### 版本更新 0.8.6
* mysql主从配置。
* swap插件[虚拟内存]。
### 自动安装
```
curl -fsSL https://raw.githubusercontent.com/midoks/mdweb/master/install/install.sh | sh
curl -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/master/scripts/install.sh | sh
```
### 手动操作
- pip install pip==9.0.3
- pip install flask
- pip install gunicorn
- pip install psutil
- pip install -r requirements.txt
### 更新
```
curl -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/master/scripts/update.sh | sh
```
### 无图不真相
[![截图](/route/static/mdw.jpg)](/route/static/mdw.jpg)
### wiki
[了解更多...](https://github.com/midoks/mdserver-web/wiki)

42
app.py
View File

@@ -1,36 +1,14 @@
from flask import Flask
import views
# coding:utf-8
import sys
import io
import os
from route import app, socketio
sys.path.append("class/")
app = Flask(__name__)
app.debug = True
DEFAULT_MODULES = (
(views.dashboard, "/"),
(views.site, "/site"),
(views.files, "/files"),
(views.soft, "/soft"),
(views.config, "/config"),
(views.plugins, "/plugins"),
(views.task, "/task"),
)
import time
# print "time.time(): %f " % time.time()
app.config.version = "0.0.1" + str(time.time())
def setting_modules(app, modules):
for module, url_prefix in modules:
app.register_blueprint(module, url_prefix=url_prefix)
setting_modules(app, DEFAULT_MODULES)
if __name__ == "__main__":
app.run()
try:
if __name__ == "__main__":
PORT = 7200
HOST = '0.0.0.0'
socketio.run(app, host=HOST, port=PORT)
except Exception as ex:
print ex

85
class/core/common.py Executable file
View File

@@ -0,0 +1,85 @@
# coding: utf-8
import os
import sys
import time
import string
import json
import hashlib
import shlex
import datetime
import subprocess
import re
import hashlib
from random import Random
import mw
import db
from flask import redirect
def init():
initDB()
initInitD()
initUserInfo()
def local():
result = checkClose()
if result:
return result
# 检查面板是否关闭
def checkClose():
if os.path.exists('data/close.pl'):
return redirect('/close')
def initDB():
try:
sql = db.Sql().dbfile('default')
csql = mw.readFile('data/sql/default.sql')
csql_list = csql.split(';')
for index in range(len(csql_list)):
sql.execute(csql_list[index], ())
except Exception, ex:
print str(ex)
def initInitD():
script = mw.getRunDir() + '/scripts/init.d/mw.tpl'
script_bin = mw.getRunDir() + '/scripts/init.d/mw'
# if os.path.exists(script_bin):
# return
content = mw.readFile(script)
content = content.replace("{$SERVER_PATH}", mw.getRunDir())
mw.writeFile(script_bin, content)
mw.execShell('chmod +x ' + script_bin)
mw.setHostAddr(mw.getLocalIp())
if not mw.isAppleSystem():
initd_bin = '/etc/init.d/mw'
if not os.path.exists(initd_bin):
import shutil
shutil.copyfile(script_bin, initd_bin)
mw.execShell('chmod +x ' + initd_bin)
# 加入自启动
mw.execShell('chkconfig --add mw')
def initUserInfo():
data = mw.M('users').where('id=?', (1,)).getField('password')
if data == '21232f297a57a5a743894a0e4a801fc3':
pwd = mw.getRandomString(8).lower()
file_pw = mw.getRunDir() + '/data/default.pl'
mw.writeFile(file_pw, pwd)
mw.M('users').where('id=?', (1,)).setField(
'password', mw.md5(pwd))

323
class/core/config_api.py Executable file
View File

@@ -0,0 +1,323 @@
# coding: utf-8
import psutil
import time
import os
import sys
import mw
import re
import json
import pwd
from flask import session
from flask import request
class config_api:
# 本版解决自启动问题
# 文件管理重命名
# 优化计划任务管理
__version = '0.8.6'
def __init__(self):
pass
##### ----- start ----- ###
# 取面板列表
def getPanelListApi(self):
data = mw.M('panel').field(
'id,title,url,username,password,click,addtime').order('click desc').select()
return mw.getJson(data)
def addPanelInfoApi(self):
title = request.form.get('title', '')
url = request.form.get('url', '')
username = request.form.get('username', '')
password = request.form.get('password', '')
# 校验是还是重复
isAdd = mw.M('panel').where(
'title=? OR url=?', (title, url)).count()
if isAdd:
return mw.returnJson(False, '备注或面板地址重复!')
isRe = mw.M('panel').add('title,url,username,password,click,addtime',
(title, url, username, password, 0, int(time.time())))
if isRe:
return mw.returnJson(True, '添加成功!')
return mw.returnJson(False, '添加失败!')
# 删除面板资料
def delPanelInfoApi(self):
mid = request.form.get('id', '')
isExists = mw.M('panel').where('id=?', (mid,)).count()
if not isExists:
return mw.returnJson(False, '指定面板资料不存在!')
mw.M('panel').where('id=?', (mid,)).delete()
return mw.returnJson(True, '删除成功!')
# 修改面板资料
def setPanelInfoApi(self):
title = request.form.get('title', '')
url = request.form.get('url', '')
username = request.form.get('username', '')
password = request.form.get('password', '')
mid = request.form.get('id', '')
# 校验是还是重复
isSave = mw.M('panel').where(
'(title=? OR url=?) AND id!=?', (title, url, mid)).count()
if isSave:
return mw.returnJson(False, '备注或面板地址重复!')
# 更新到数据库
isRe = mw.M('panel').where('id=?', (mid,)).save(
'title,url,username,password', (title, url, username, password))
if isRe:
return mw.returnJson(True, '修改成功!')
return mw.returnJson(False, '修改失败!')
def syncDateApi(self):
if mw.isAppleSystem():
return mw.returnJson(True, '开发系统不必同步时间!')
data = mw.execShell('ntpdate -s time.nist.gov')
if data[0] == '':
return mw.returnJson(True, '同步成功!')
return mw.returnJson(False, '同步失败:' + data[0])
def setPasswordApi(self):
password1 = request.form.get('password1', '')
password2 = request.form.get('password2', '')
if password1 != password2:
return mw.returnJson(False, '两次输入的密码不一致,请重新输入!')
if len(password1) < 5:
return mw.returnJson(False, '用户密码不能小于5位!')
mw.M('users').where("username=?", (session['username'],)).setField(
'password', mw.md5(password1.strip()))
return mw.returnJson(True, '密码修改成功!')
def setNameApi(self):
name1 = request.form.get('name1', '')
name2 = request.form.get('name2', '')
if name1 != name2:
return mw.returnJson(False, '两次输入的用户名不一致,请重新输入!')
if len(name1) < 3:
return mw.returnJson(False, '用户名长度不能少于3位')
mw.M('users').where("username=?", (session['username'],)).setField(
'username', name1.strip())
session['username'] = name1
return mw.returnJson(True, '用户修改成功!')
def setApi(self):
webname = request.form.get('webname', '')
port = request.form.get('port', '')
host_ip = request.form.get('host_ip', '')
domain = request.form.get('domain', '')
sites_path = request.form.get('sites_path', '')
backup_path = request.form.get('backup_path', '')
if domain != '':
reg = "^([\w\-\*]{1,100}\.){1,4}(\w{1,10}|\w{1,10}\.\w{1,10})$"
if not re.match(reg, domain):
return mw.returnJson(False, '主域名格式不正确')
if int(port) >= 65535 or int(port) < 100:
return mw.returnJson(False, '端口范围不正确!')
if webname != mw.getConfig('title'):
mw.setConfig('title', webname)
if sites_path != mw.getWwwDir():
mw.setWwwDir(sites_path)
if backup_path != mw.getWwwDir():
mw.setBackupDir(backup_path)
if port != mw.getHostPort():
import system_api
mw.setHostPort(port)
system_api.system_api().restartMw()
if host_ip != mw.getHostAddr():
mw.setHostAddr(host_ip)
mhost = mw.getHostAddr()
info = {
'uri': '/config',
'host': mhost + ':' + port
}
return mw.returnJson(True, '保存成功!', info)
def setAdminPathApi(self):
admin_path = request.form.get('admin_path', '').strip()
admin_path_checks = ['/', '/close', '/login', '/do_login', '/site',
'/sites', '/download_file', '/control', '/crontab',
'/firewall', '/files', 'config', '/soft', '/system',
'/code', '/ssl', '/plugins']
if admin_path == '':
admin_path = '/'
if admin_path != '/':
if len(admin_path) < 6:
return mw.returnJson(False, '安全入口地址长度不能小于6位!')
if admin_path in admin_path_checks:
return mw.returnJson(False, '该入口已被面板占用,请使用其它入口!')
if not re.match("^/[\w\./-_]+$", admin_path):
return mw.returnJson(False, '入口地址格式不正确,示例: /my_panel')
else:
domain = mw.readFile('data/domain.conf')
if not domain:
domain = ''
limitip = mw.readFile('data/limitip.conf')
if not limitip:
limitip = ''
if not domain.strip() and not limitip.strip():
return mw.returnJson(False, '警告,关闭安全入口等于直接暴露你的后台地址在外网,十分危险,至少开启以下一种安全方式才能关闭:<a style="color:red;"><br>1、绑定访问域名<br>2、绑定授权IP</a>')
admin_path_file = 'data/admin_path.pl'
admin_path_old = '/'
if os.path.exists(admin_path_file):
admin_path_old = mw.readFile(admin_path_file).strip()
if admin_path_old != admin_path:
mw.writeFile(admin_path_file, admin_path)
mw.restartMw()
return mw.returnJson(True, '修改成功!')
def closePanelApi(self):
filename = 'data/close.pl'
if os.path.exists(filename):
os.remove(filename)
return mw.returnJson(True, '开启成功')
mw.writeFile(filename, 'True')
mw.execShell("chmod 600 " + filename)
mw.execShell("chown root.root " + filename)
return mw.returnJson(True, '面板已关闭!')
def setIpv6StatusApi(self):
ipv6_file = 'data/ipv6.pl'
if os.path.exists('data/ipv6.pl'):
os.remove(ipv6_file)
mw.writeLog('面板设置', '关闭面板IPv6兼容!')
else:
mw.writeFile(ipv6_file, 'True')
mw.writeLog('面板设置', '开启面板IPv6兼容!')
mw.restartMw()
return mw.returnJson(True, '设置成功!')
# 获取面板证书
def getPanelSslApi(self):
cert = {}
cert['privateKey'] = mw.readFile('ssl/privateKey.pem')
cert['certPem'] = mw.readFile('ssl/certificate.pem')
cert['rep'] = os.path.exists('ssl/input.pl')
return mw.getJson(cert)
# 保存面板证书
def savePanelSslApi(self):
keyPath = 'ssl/privateKey.pem'
certPath = 'ssl/certificate.pem'
checkCert = '/tmp/cert.pl'
certPem = request.form.get('certPem', '').strip()
privateKey = request.form.get('privateKey', '').strip()
mw.writeFile(checkCert, certPem)
if privateKey:
mw.writeFile(keyPath, privateKey)
if certPem:
mw.writeFile(certPath, certPem)
if not mw.checkCert(checkCert):
return mw.returnJson(False, '证书错误,请检查!')
mw.writeFile('ssl/input.pl', 'True')
return mw.returnJson(True, '证书已保存!')
# 设置面板SSL
def setPanelSslApi(self):
sslConf = mw.getRunDir() + '/data/ssl.pl'
if os.path.exists(sslConf):
os.system('rm -f ' + sslConf)
return mw.returnJson(True, 'SSL已关闭,请使用http协议访问面板!')
else:
os.system('pip install cffi==1.10')
os.system('pip install cryptography==2.1')
os.system('pip install pyOpenSSL==16.2')
try:
if not self.createSSL():
return mw.returnJson(False, '开启失败,无法自动安装pyOpenSSL组件!<p>请尝试手动安装: pip install pyOpenSSL</p>')
mw.writeFile(sslConf, 'True')
except Exception as ex:
return mw.returnJson(False, '开启失败,无法自动安装pyOpenSSL组件!<p>请尝试手动安装: pip install pyOpenSSL</p>')
return mw.returnJson(True, '开启成功,请使用https协议访问面板!')
def getApi(self):
data = {}
return mw.getJson(data)
##### ----- end ----- ###
# 自签证书
def createSSL(self):
if os.path.exists('ssl/input.pl'):
return True
import OpenSSL
key = OpenSSL.crypto.PKey()
key.generate_key(OpenSSL.crypto.TYPE_RSA, 2048)
cert = OpenSSL.crypto.X509()
cert.set_serial_number(0)
cert.get_subject().CN = mw.getLocalIp()
cert.set_issuer(cert.get_subject())
cert.gmtime_adj_notBefore(0)
cert.gmtime_adj_notAfter(86400 * 3650)
cert.set_pubkey(key)
cert.sign(key, 'md5')
cert_ca = OpenSSL.crypto.dump_certificate(
OpenSSL.crypto.FILETYPE_PEM, cert)
private_key = OpenSSL.crypto.dump_privatekey(
OpenSSL.crypto.FILETYPE_PEM, key)
if len(cert_ca) > 100 and len(private_key) > 100:
mw.writeFile('ssl/certificate.pem', cert_ca)
mw.writeFile('ssl/privateKey.pem', private_key)
print cert_ca, private_key
return True
return False
def getVersion(self):
return self.__version
def get(self):
data = {}
data['title'] = mw.getConfig('title')
data['site_path'] = mw.getWwwDir()
data['backup_path'] = mw.getBackupDir()
sformat = 'date +"%Y-%m-%d %H:%M:%S %Z %z"'
data['systemdate'] = mw.execShell(sformat)[0].strip()
data['port'] = mw.getHostPort()
data['ip'] = mw.getHostAddr()
admin_path_file = 'data/admin_path.pl'
if not os.path.exists(admin_path_file):
data['admin_path'] = '/'
else:
data['admin_path'] = mw.readFile(admin_path_file)
ipv6_file = 'data/ipv6.pl'
if os.path.exists('data/ipv6.pl'):
data['ipv6'] = 'checked'
else:
data['ipv6'] = ''
ssl_file = 'data/ssl.pl'
if os.path.exists('data/ssl.pl'):
data['ssl'] = 'checked'
else:
data['ssl'] = ''
data['site_count'] = mw.M('sites').count()
data['username'] = mw.M('users').where(
"id=?", (1,)).getField('username')
return data

524
class/core/crontab_api.py Executable file
View File

@@ -0,0 +1,524 @@
# coding: utf-8
import psutil
import time
import os
import sys
import mw
import re
import json
import pwd
from flask import request
class crontab_api:
field = 'id,name,type,where1,where_hour,where_minute,echo,addtime,status,save,backup_to,stype,sname,sbody,urladdress'
def __init__(self):
pass
##### ----- start ----- ###
def listApi(self):
p = request.args.get('p', 1)
psize = 10
startPage = (int(p) - 1) * psize
pageInfo = str(startPage) + ',' + str(psize)
_list = mw.M('crontab').where('', ()).field(
self.field).limit(pageInfo).order('id desc').select()
data = []
for i in range(len(_list)):
tmp = _list[i]
if _list[i]['type'] == "day":
tmp['type'] = '每天'
tmp['cycle'] = mw.getInfo('每天, {1}点{2}分 执行', (str(
_list[i]['where_hour']), str(_list[i]['where_minute'])))
elif _list[i]['type'] == "day-n":
tmp['type'] = mw.getInfo(
'每{1}天', (str(_list[i]['where1']),))
tmp['cycle'] = mw.getInfo('每隔{1}天, {2}点{3}分 执行', (str(
_list[i]['where1']), str(_list[i]['where_hour']), str(_list[i]['where_minute'])))
elif _list[i]['type'] == "hour":
tmp['type'] = '每小时'
tmp['cycle'] = mw.getInfo(
'每小时, 第{1}分钟 执行', (str(_list[i]['where_minute']),))
elif _list[i]['type'] == "hour-n":
tmp['type'] = mw.getInfo(
'每{1}小时', (str(_list[i]['where1']),))
tmp['cycle'] = mw.getInfo('每{1}小时, 第{2}分钟 执行', (str(
_list[i]['where1']), str(_list[i]['where_minute'])))
elif _list[i]['type'] == "minute-n":
tmp['type'] = mw.getInfo(
'每{1}分钟', (str(_list[i]['where1']),))
tmp['cycle'] = mw.getInfo(
'每隔{1}分钟执行', (str(_list[i]['where1']),))
elif _list[i]['type'] == "week":
tmp['type'] = '每周'
if not _list[i]['where1']:
_list[i]['where1'] = '0'
tmp['cycle'] = mw.getInfo('每周{1}, {2}点{3}分执行', (self.toWeek(int(
_list[i]['where1'])), str(_list[i]['where_hour']), str(_list[i]['where_minute'])))
elif _list[i]['type'] == "month":
tmp['type'] = '每月'
tmp['cycle'] = mw.getInfo('每月, {1}日 {2}点{3}分执行', (str(_list[i]['where1']), str(
_list[i]['where_hour']), str(_list[i]['where_minute'])))
data.append(tmp)
_ret = {}
_ret['data'] = data
count = mw.M('crontab').where('', ()).count()
_page = {}
_page['count'] = count
_page['p'] = p
_page['row'] = psize
_page['tojs'] = "getCronData"
_ret['list'] = mw.getPage(_page)
_ret['p'] = p
return mw.getJson(_ret)
# 设置计划任务状态
def setCronStatusApi(self):
mid = request.form.get('id', '')
cronInfo = mw.M('crontab').where(
'id=?', (mid,)).field(self.field).find()
status = 1
if cronInfo['status'] == status:
status = 0
self.removeForCrond(cronInfo['echo'])
else:
cronInfo['status'] = 1
self.syncToCrond(cronInfo)
mw.M('crontab').where('id=?', (mid,)).setField('status', status)
mw.writeLog(
'计划任务', '修改计划任务[' + cronInfo['name'] + ']状态为[' + str(status) + ']')
return mw.returnJson(True, '设置成功')
# 获取指定任务数据
def getCrondFindApi(self):
sid = request.form.get('id', '')
data = mw.M('crontab').where(
'id=?', (sid,)).field(self.field).find()
return mw.getJson(data)
def modifyCrondApi(self):
sid = request.form.get('id', '')
iname = request.form.get('name', '')
field_type = request.form.get('type', '')
week = request.form.get('week', '')
where1 = request.form.get('where1', '')
hour = request.form.get('hour', '')
minute = request.form.get('minute', '')
save = request.form.get('save', '')
backup_to = request.form.get('backup_to', '')
stype = request.form.get('stype', '')
sname = request.form.get('sname', '')
sbody = request.form.get('sbody', '')
urladdress = request.form.get('urladdress', '')
if len(iname) < 1:
return mw.returnJson(False, '任务名称不能为空!')
params = {
'name': iname,
'type': field_type,
'week': week,
'where1': where1,
'hour': hour,
'minute': minute,
'save': save,
'backup_to': backup_to,
'stype': stype,
'sname': sname,
'sbody': sbody,
'urladdress': urladdress,
}
cuonConfig, get, name = self.getCrondCycle(params)
cronInfo = mw.M('crontab').where(
'id=?', (sid,)).field(self.field).find()
del(cronInfo['id'])
del(cronInfo['addtime'])
cronInfo['name'] = get['name']
cronInfo['type'] = get['type']
cronInfo['where1'] = get['where1']
cronInfo['where_hour'] = get['hour']
cronInfo['where_minute'] = get['minute']
cronInfo['save'] = get['save']
cronInfo['backup_to'] = get['backup_to']
cronInfo['sbody'] = get['sbody']
cronInfo['urladdress'] = get['urladdress']
addData = mw.M('crontab').where('id=?', (sid,)).save('name,type,where1,where_hour,where_minute,save,backup_to,sbody,urladdress', (get[
'name'], field_type, get['where1'], get['hour'], get['minute'], get['save'], get['backup_to'], get['sbody'], get['urladdress']))
self.removeForCrond(cronInfo['echo'])
self.syncToCrond(cronInfo)
mw.writeLog('计划任务', '修改计划任务[' + cronInfo['name'] + ']成功')
return mw.returnJson(True, '修改成功')
def logsApi(self):
sid = request.form.get('id', '')
echo = mw.M('crontab').where("id=?", (sid,)).field('echo').find()
logFile = mw.getServerDir() + '/cron/' + echo['echo'] + '.log'
if not os.path.exists(logFile):
return mw.returnJson(False, '当前日志为空!')
log = mw.getNumLines(logFile, 500)
return mw.returnJson(True, log)
def addApi(self):
iname = request.form.get('name', '')
field_type = request.form.get('type', '')
week = request.form.get('week', '')
where1 = request.form.get('where1', '')
hour = request.form.get('hour', '')
minute = request.form.get('minute', '')
save = request.form.get('save', '')
backup_to = request.form.get('backupTo', '')
stype = request.form.get('sType', '')
sname = request.form.get('sName', '')
sbody = request.form.get('sBody', '')
urladdress = request.form.get('urladdress', '')
if len(iname) < 1:
return mw.returnJson(False, '任务名称不能为空!')
params = {
'name': iname,
'type': field_type,
'week': week,
'where1': where1,
'hour': hour,
'minute': minute,
'save': save,
'backup_to': backup_to,
'stype': stype,
'sname': sname,
'sbody': sbody,
'urladdress': urladdress,
}
# print params
cronConfig, get, name = self.getCrondCycle(params)
cronPath = mw.getServerDir() + '/cron'
cronName = self.getShell(params)
# print cronConfig, _params, name
# print 'vv', cronPath, cronName
# print 'stype', stype
if type(cronName) == dict:
return cronName
cronConfig += ' ' + cronPath + '/' + cronName + \
' >> ' + cronPath + '/' + cronName + '.log 2>&1'
if not mw.isAppleSystem():
wRes = self.writeShell(cronConfig)
if type(wRes) != bool:
return wRes
self.crondReload()
addData = mw.M('crontab').add('name,type,where1,where_hour,where_minute,echo,addtime,status,save,backup_to,stype,sname,sbody,urladdress', (iname, field_type, where1, hour, minute, cronName, time.strftime(
'%Y-%m-%d %X', time.localtime()), 1, save, backup_to, stype, sname, sbody, urladdress))
if addData > 0:
return mw.returnJson(True, '添加成功')
return mw.returnJson(False, '添加失败')
def startTaskApi(self):
sid = request.form.get('id', '')
echo = mw.M('crontab').where('id=?', (sid,)).getField('echo')
execstr = mw.getServerDir() + '/cron/' + echo
os.system('chmod +x ' + execstr)
os.system('nohup ' + execstr + ' >> ' + execstr + '.log 2>&1 &')
return mw.returnJson(True, '任务已执行!')
def delApi(self):
sid = request.form.get('id', '')
try:
find = mw.M('crontab').where(
"id=?", (sid,)).field('name,echo').find()
if not self.removeForCrond(find['echo']):
return mw.returnJson(False, '无法写入文件,请检查是否开启了系统加固功能!')
cronPath = mw.getServerDir() + '/cron'
sfile = cronPath + '/' + find['echo']
if os.path.exists(sfile):
os.remove(sfile)
sfile = cronPath + '/' + find['echo'] + '.log'
if os.path.exists(sfile):
os.remove(sfile)
mw.M('crontab').where("id=?", (sid,)).delete()
mw.writeLog('计划任务', mw.getInfo(
'删除计划任务[{1}]成功!', (find['name'],)))
return mw.returnJson(True, '删除成功')
except Exception as e:
return mw.returnJson(False, '删除失败:' + str(e))
def delLogsApi(self):
sid = request.form.get('id', '')
try:
echo = mw.M('crontab').where("id=?", (sid,)).getField('echo')
logFile = mw.getServerDir() + '/cron/' + echo + '.log'
os.remove(logFile)
return mw.returnJson(True, '任务日志已清空!')
except:
return mw.returnJson(False, '任务日志清空失败!')
# 取数据列表
def getDataListApi(self):
stype = request.form.get('type', '').encode('utf-8')
if stype == 'databases':
db_list = {}
db_list['orderOpt'] = []
path = mw.getServerDir() + '/mysql'
if not os.path.exists(path + '/mysql.db'):
db_list['data'] = []
else:
db_list['data'] = mw.M('databases').dbPos(
path, 'mysql').field('name,ps').select()
return mw.getJson(db_list)
data = {}
data['data'] = mw.M(stype).field('name,ps').select()
data['orderOpt'] = []
# try:
# tmp = mw.readFile('data/libList.conf')
# libs = json.loads(tmp)
# import imp
# for lib in libs:
# imp.find_module(lib['module'])
# tmp = {}
# tmp['name'] = lib['name']
# tmp['value'] = lib['opt']
# data['orderOpt'].append(tmp)
# except Exception as e:
# print e
return mw.getJson(data)
##### ----- start ----- ###
# 转换大写星期
def toWeek(self, num):
wheres = {
0: '日',
1: '一',
2: '二',
3: '三',
4: '四',
5: '五',
6: '六'
}
try:
return wheres[num]
except:
return ''
def getCrondCycle(self, params):
cuonConfig = ''
name = ''
if params['type'] == "day":
cuonConfig = self.getDay(params)
name = '每天'
elif params['type'] == "day-n":
cuonConfig = self.getDay_N(params)
name = mw.getInfo('每{1}天', (params['where1'],))
elif params['type'] == "hour":
cuonConfig = self.getHour(params)
name = '每小时'
elif params['type'] == "hour-n":
cuonConfig = self.getHour_N(params)
name = '每小时'
elif params['type'] == "minute-n":
cuonConfig = self.minute_N(params)
elif params['type'] == "week":
params['where1'] = params['week']
cuonConfig = self.week(params)
elif params['type'] == "month":
cuonConfig = self.month(params)
return cuonConfig, params, name
# 取任务构造Day
def getDay(self, param):
cuonConfig = "{0} {1} * * * ".format(param['minute'], param['hour'])
return cuonConfig
# 取任务构造Day_n
def getDay_N(self, param):
cuonConfig = "{0} {1} */{2} * * ".format(
param['minute'], param['hour'], param['where1'])
return cuonConfig
# 取任务构造Hour
def getHour(self, param):
cuonConfig = "{0} * * * * ".format(param['minute'])
return cuonConfig
# 取任务构造Hour-N
def getHour_N(self, param):
cuonConfig = "{0} */{1} * * * ".format(
param['minute'], param['where1'])
return cuonConfig
# 取任务构造Minute-N
def minute_N(self, param):
cuonConfig = "*/{0} * * * * ".format(param['where1'])
return cuonConfig
# 取任务构造week
def week(self, param):
cuonConfig = "{0} {1} * * {2}".format(
param['minute'], param['hour'], param['week'])
return cuonConfig
# 取任务构造Month
def month(self, param):
cuonConfig = "{0} {1} {2} * * ".format(
param['minute'], param['hour'], param['where1'])
return cuonConfig
# 取执行脚本
def getShell(self, param):
# try:
stype = param['stype']
if stype == 'toFile':
shell = param.sFile
else:
head = "#!/bin/bash\nPATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin\nexport PATH\n"
log = '.log'
wheres = {
'path': head + "python " + mw.getServerDir() + "/mdserver-web/scripts/backup.py path " + param['sname'] + " " + str(param['save']),
'site': head + "python " + mw.getServerDir() + "/mdserver-web/scripts/backup.py site " + param['sname'] + " " + str(param['save']),
'database': head + "python " + mw.getServerDir() + "/mdserver-web/scripts/backup.py database " + param['sname'] + " " + str(param['save']),
'logs': head + "python " + mw.getServerDir() + "/mdserver-web/scripts/logs_backup.py " + param['sname'] + log + " " + str(param['save']),
'rememory': head + "/bin/bash " + mw.getServerDir() + '/mdserver-web/scripts/rememory.sh'
}
if param['backup_to'] != 'localhost':
cfile = mw.getServerDir() + "/mdserver-web/plugin/" + param[
'backup_to'] + "/" + param['backup_to'] + "_main.py"
if not os.path.exists(cfile):
cfile = mw.getServerDir() + "/mdserver-web/script/backup_" + \
param['backup_to'] + ".py"
wheres = {
'path': head + "python " + cfile + " path " + param['sname'] + " " + str(param['save']),
'site': head + "python " + cfile + " site " + param['sname'] + " " + str(param['save']),
'database': head + "python " + cfile + " database " + param['sname'] + " " + str(param['save']),
'logs': head + "python " + mw.getServerDir() + "/mdserver-web/scripts/logs_backup.py " + param['sname'] + log + " " + str(param['save']),
'rememory': head + "/bin/bash " + mw.getServerDir() + '/mdserver-web/scripts/rememory.sh'
}
try:
shell = wheres[stype]
except:
if stype == 'toUrl':
shell = head + "curl -sS --connect-timeout 10 -m 60 '" + \
param['urladdress'] + "'"
else:
shell = head + param['sbody'].replace("\r\n", "\n")
shell += '''
echo "----------------------------------------------------------------------------"
endDate=`date +"%Y-%m-%d %H:%M:%S"`
echo "★[$endDate] Successful"
echo "----------------------------------------------------------------------------"
'''
cronPath = mw.getServerDir() + '/cron'
if not os.path.exists(cronPath):
mw.execShell('mkdir -p ' + cronPath)
if not 'echo' in param:
cronName = mw.md5(mw.md5(str(time.time()) + '_mw'))
else:
cronName = param['echo']
file = cronPath + '/' + cronName
mw.writeFile(file, self.checkScript(shell))
mw.execShell('chmod 750 ' + file)
return cronName
# 检查脚本
def checkScript(self, shell):
keys = ['shutdown', 'init 0', 'mkfs', 'passwd',
'chpasswd', '--stdin', 'mkfs.ext', 'mke2fs']
for key in keys:
shell = shell.replace(key, '[***]')
return shell
# 将Shell脚本写到文件
def writeShell(self, config):
u_file = '/var/spool/cron/crontabs/root'
if not os.path.exists(u_file):
file = '/var/spool/cron/root'
if mw.isAppleSystem():
file = '/etc/crontab'
else:
file = u_file
if not os.path.exists(file):
mw.writeFile(file, '')
conf = mw.readFile(file)
conf += str(config) + "\n"
if mw.writeFile(file, conf):
if not os.path.exists(u_file):
mw.execShell("chmod 600 '" + file +
"' && chown root.root " + file)
else:
mw.execShell("chmod 600 '" + file +
"' && chown root.crontab " + file)
return True
return mw.returnJson(False, '文件写入失败,请检查是否开启系统加固功能!')
# 重载配置
def crondReload(self):
if mw.isAppleSystem():
if os.path.exists('/etc/crontab'):
pass
# mw.execShell('/usr/sbin/cron restart')
else:
if os.path.exists('/etc/init.d/crond'):
mw.execShell('/etc/init.d/crond reload')
elif os.path.exists('/etc/init.d/cron'):
mw.execShell('service cron restart')
else:
mw.execShell("systemctl reload crond")
# 从crond删除
def removeForCrond(self, echo):
u_file = '/var/spool/cron/crontabs/root'
if not os.path.exists(u_file):
file = '/var/spool/cron/root'
if mw.isAppleSystem():
file = '/etc/crontab'
else:
file = u_file
conf = mw.readFile(file)
rep = ".+" + str(echo) + ".+\n"
conf = re.sub(rep, "", conf)
if not mw.writeFile(file, conf):
return False
self.crondReload()
return True
def syncToCrond(self, cronInfo):
if 'status' in cronInfo:
if cronInfo['status'] == 0:
return False
if 'where_hour' in cronInfo:
cronInfo['hour'] = cronInfo['where_hour']
cronInfo['minute'] = cronInfo['where_minute']
cronInfo['week'] = cronInfo['where1']
cuonConfig, cronInfo, name = self.getCrondCycle(cronInfo)
cronPath = mw.getServerDir() + '/cron'
cronName = self.getShell(cronInfo)
if type(cronName) == dict:
return cronName
cuonConfig += ' ' + cronPath + '/' + cronName + \
' >> ' + cronPath + '/' + cronName + '.log 2>&1'
wRes = self.writeShell(cuonConfig)
if type(wRes) != bool:
return False
self.crondReload()

281
class/core/db.py Executable file
View File

@@ -0,0 +1,281 @@
# coding: utf-8
import sqlite3
import os
class Sql():
#------------------------------
# 数据库操作类 For sqlite3
#------------------------------
__DB_FILE = None # 数据库文件
__DB_CONN = None # 数据库连接对象
__DB_TABLE = "" # 被操作的表名称
__OPT_WHERE = "" # where条件
__OPT_LIMIT = "" # limit条件
__OPT_ORDER = "" # order条件
__OPT_FIELD = "*" # field条件
__OPT_PARAM = () # where值
def __init__(self):
self.__DB_FILE = 'data/default.db'
def __GetConn(self):
# 取数据库对象
try:
if self.__DB_CONN == None:
self.__DB_CONN = sqlite3.connect(self.__DB_FILE)
except Exception, ex:
return "error: " + str(ex)
def dbfile(self, name):
self.__DB_FILE = 'data/' + name + '.db'
return self
def dbPos(self, path, name):
self.__DB_FILE = path + '/' + name + '.db'
return self
def table(self, table):
# 设置表名
self.__DB_TABLE = table
return self
def where(self, where, param):
# WHERE条件
if where:
self.__OPT_WHERE = " WHERE " + where
self.__OPT_PARAM = param
return self
def order(self, order):
# ORDER条件
if len(order):
self.__OPT_ORDER = " ORDER BY " + order
return self
def limit(self, limit):
# LIMIT条件
if len(limit):
self.__OPT_LIMIT = " LIMIT " + limit
return self
def field(self, field):
# FIELD条件
if len(field):
self.__OPT_FIELD = field
return self
def select(self):
# 查询数据集
self.__GetConn()
try:
sql = "SELECT " + self.__OPT_FIELD + " FROM " + self.__DB_TABLE + \
self.__OPT_WHERE + self.__OPT_ORDER + self.__OPT_LIMIT
result = self.__DB_CONN.execute(sql, self.__OPT_PARAM)
data = result.fetchall()
# 构造字曲系列
if self.__OPT_FIELD != "*":
field = self.__OPT_FIELD.split(',')
tmp = []
for row in data:
i = 0
tmp1 = {}
for key in field:
tmp1[key] = row[i]
i += 1
tmp.append(tmp1)
del(tmp1)
data = tmp
del(tmp)
else:
# 将元组转换成列表
tmp = map(list, data)
data = tmp
del(tmp)
self.__close()
return data
except Exception, ex:
return "error: " + str(ex)
def getField(self, keyName):
# 取回指定字段
result = self.field(keyName).select()
if len(result) == 1:
return result[0][keyName]
return result
def setField(self, keyName, keyValue):
# 更新指定字段
return self.save(keyName, (keyValue,))
def find(self):
# 取一行数据
result = self.limit("1").select()
if len(result) == 1:
return result[0]
return result
def count(self):
# 取行数
key = "COUNT(*)"
data = self.field(key).select()
try:
return int(data[0][key])
except:
return 0
def add(self, keys, param):
# 插入数据
self.__GetConn()
self.__DB_CONN.text_factory = str
try:
values = ""
for key in keys.split(','):
values += "?,"
values = self.checkInput(values[0:len(values) - 1])
sql = "INSERT INTO " + self.__DB_TABLE + \
"(" + keys + ") " + "VALUES(" + values + ")"
result = self.__DB_CONN.execute(sql, param)
id = result.lastrowid
self.__close()
self.__DB_CONN.commit()
return id
except Exception, ex:
return "error: " + str(ex)
def checkInput(self, data):
if not data:
return data
if type(data) != str:
return data
checkList = [
{'d': '<', 'r': '<'},
{'d': '>', 'r': '>'},
{'d': '\'', 'r': '‘'},
{'d': '"', 'r': '“'},
{'d': '&', 'r': '&'},
{'d': '#', 'r': '#'},
{'d': '<', 'r': '<'}
]
for v in checkList:
data = data.replace(v['d'], v['r'])
return data
def addAll(self, keys, param):
# 插入数据
self.__GetConn()
self.__DB_CONN.text_factory = str
try:
values = ""
for key in keys.split(','):
values += "?,"
values = values[0:len(values) - 1]
sql = "INSERT INTO " + self.__DB_TABLE + \
"(" + keys + ") " + "VALUES(" + values + ")"
result = self.__DB_CONN.execute(sql, param)
return True
except Exception, ex:
return "error: " + str(ex)
def commit(self):
self.__close()
self.__DB_CONN.commit()
def save(self, keys, param):
# 更新数据
self.__GetConn()
self.__DB_CONN.text_factory = str
try:
opt = ""
for key in keys.split(','):
opt += key + "=?,"
opt = opt[0:len(opt) - 1]
sql = "UPDATE " + self.__DB_TABLE + " SET " + opt + self.__OPT_WHERE
import mw
mw.writeFile('/tmp/test.pl', sql)
# 处理拼接WHERE与UPDATE参数
tmp = list(param)
for arg in self.__OPT_PARAM:
tmp.append(arg)
self.__OPT_PARAM = tuple(tmp)
result = self.__DB_CONN.execute(sql, self.__OPT_PARAM)
self.__close()
self.__DB_CONN.commit()
return result.rowcount
except Exception, ex:
return "error: " + str(ex)
def delete(self, id=None):
# 删除数据
self.__GetConn()
try:
if id:
self.__OPT_WHERE = " WHERE id=?"
self.__OPT_PARAM = (id,)
sql = "DELETE FROM " + self.__DB_TABLE + self.__OPT_WHERE
result = self.__DB_CONN.execute(sql, self.__OPT_PARAM)
self.__close()
self.__DB_CONN.commit()
return result.rowcount
except Exception, ex:
return "error: " + str(ex)
def execute(self, sql, param):
# 执行SQL语句返回受影响行
self.__GetConn()
# print sql, param
try:
result = self.__DB_CONN.execute(sql, param)
self.__DB_CONN.commit()
return result.rowcount
except Exception, ex:
return "error: " + str(ex)
def query(self, sql, param):
# 执行SQL语句返回数据集
self.__GetConn()
try:
result = self.__DB_CONN.execute(sql, param)
# 将元组转换成列表
data = map(list, result)
return data
except Exception, ex:
return "error: " + str(ex)
def create(self, name):
# 创建数据表
self.__GetConn()
import mw
script = mw.readFile('data/' + name + '.sql')
result = self.__DB_CONN.executescript(script)
self.__DB_CONN.commit()
return result.rowcount
def fofile(self, filename):
# 执行脚本
self.__GetConn()
import mw
script = mw.readFile(filename)
result = self.__DB_CONN.executescript(script)
self.__DB_CONN.commit()
return result.rowcount
def __close(self):
# 清理条件属性
self.__OPT_WHERE = ""
self.__OPT_FIELD = "*"
self.__OPT_ORDER = ""
self.__OPT_LIMIT = ""
self.__OPT_PARAM = ()
def close(self):
# 释放资源
try:
self.__DB_CONN.close()
self.__DB_CONN = None
except:
pass

843
class/core/files_api.py Executable file
View File

@@ -0,0 +1,843 @@
# coding: utf-8
import psutil
import time
import os
import sys
import mw
import re
import json
import pwd
import shutil
from flask import request
from flask import send_file, send_from_directory
from flask import make_response
from flask import session
class files_api:
rPath = None
def __init__(self):
self.rPath = mw.getRootDir() + '/recycle_bin/'
##### ----- start ----- ###
def getBodyApi(self):
path = request.form.get('path', '').encode('utf-8')
return self.getBody(path)
def getLastBodyApi(self):
path = request.form.get('path', '').encode('utf-8')
line = request.form.get('line', '100')
if not os.path.exists(path):
return mw.returnJson(False, '文件不存在', (path,))
try:
data = mw.getNumLines(path, int(line))
return mw.returnJson(True, 'OK', data)
except Exception as ex:
return mw.returnJson(False, u'无法正确读取文件!' + str(ex))
def saveBodyApi(self):
path = request.form.get('path', '').encode('utf-8')
data = request.form.get('data', '').encode('utf-8')
encoding = request.form.get('encoding', '').encode('utf-8')
return self.saveBody(path, data, encoding)
def downloadApi(self):
filename = request.args.get('filename', '').encode('utf-8')
if not os.path.exists(filename):
return ''
response = make_response(send_from_directory(
os.path.dirname(filename).encode('utf-8'), os.path.basename(filename).encode('utf-8'), as_attachment=True))
return response
def zipApi(self):
sfile = request.form.get('sfile', '').encode('utf-8')
dfile = request.form.get('dfile', '').encode('utf-8')
stype = request.form.get('type', '').encode('utf-8')
path = request.form.get('path', '').encode('utf-8')
return self.zip(sfile, dfile, stype, path)
# 移动文件或目录
def mvFileApi(self):
sfile = request.form.get('sfile', '').encode('utf-8')
dfile = request.form.get('dfile', '').encode('utf-8')
if not self.checkFileName(dfile):
return mw.returnJson(False, '文件名中不能包含特殊字符!')
if not os.path.exists(sfile):
return mw.returnJson(False, '指定文件不存在!')
if not self.checkDir(sfile):
return mw.returnJson(False, 'FILE_DANGER')
import shutil
try:
shutil.move(sfile, dfile)
msg = mw.getInfo('移动文件或目录[{1}]到[{2}]成功!', (sfile, dfile,))
mw.writeLog('文件管理', msg)
return mw.returnJson(True, '移动文件或目录成功!')
except:
return mw.returnJson(False, '移动文件或目录失败!')
def deleteApi(self):
path = request.form.get('path', '').encode('utf-8')
return self.delete(path)
def fileAccessApi(self):
filename = request.form.get('filename', '').encode('utf-8')
data = self.getAccess(filename)
return mw.getJson(data)
def setFileAccessApi(self):
if mw.isAppleSystem():
return mw.returnJson(True, '开发机不设置!')
filename = request.form.get('filename', '').encode('utf-8')
user = request.form.get('user', '').encode('utf-8')
access = request.form.get('access', '755')
sall = '-R'
try:
if not self.checkDir(filename):
return mw.returnJson(False, '请不要花样作死')
if not os.path.exists(filename):
return mw.returnJson(False, '指定文件不存在!')
os.system('chmod ' + sall + ' ' + access + " '" + filename + "'")
os.system('chown ' + sall + ' ' + user +
':' + user + " '" + filename + "'")
msg = mw.getInfo(
'设置[{1}]权限为[{2}]所有者为[{3}]', (filename, access, user,))
mw.writeLog('文件管理', msg)
return mw.returnJson(True, '设置成功!')
except:
return mw.returnJson(False, '设置失败!')
def getDirSizeApi(self):
path = request.form.get('path', '').encode('utf-8')
tmp = self.getDirSize(path)
return mw.returnJson(True, tmp[0].split()[0])
def getDirApi(self):
path = request.form.get('path', '').encode('utf-8')
if not os.path.exists(path):
path = mw.getRootDir() + "/wwwroot"
search = request.args.get('search', '').strip().lower()
page = request.args.get('p', '1').strip().lower()
row = request.args.get('showRow', '10')
disk = request.form.get('disk', '')
if disk == 'True':
row = 1000
return self.getDir(path, int(page), int(row), search)
def createFileApi(self):
file = request.form.get('path', '').encode('utf-8')
try:
if not self.checkFileName(file):
return mw.returnJson(False, '文件名中不能包含特殊字符!')
if os.path.exists(file):
return mw.returnJson(False, '指定文件已存在!')
_path = os.path.dirname(file)
if not os.path.exists(_path):
os.makedirs(_path)
open(file, 'w+').close()
self.setFileAccept(file)
msg = mw.getInfo('创建文件[{1}]成功!', (file,))
mw.writeLog('文件管理', msg)
return mw.returnJson(True, '文件创建成功!')
except Exception as e:
# print str(e)
return mw.returnJson(True, '文件创建失败!')
def createDirApi(self):
path = request.form.get('path', '').encode('utf-8')
try:
if not self.checkFileName(path):
return mw.returnJson(False, '目录名中不能包含特殊字符!')
if os.path.exists(path):
return mw.returnJson(False, '指定目录已存在!')
os.makedirs(path)
self.setFileAccept(path)
msg = mw.getInfo('创建目录[{1}]成功!', (path,))
mw.writeLog('文件管理', msg)
return mw.returnJson(True, '目录创建成功!')
except Exception as e:
return mw.returnJson(False, '目录创建失败!')
def downloadFileApi(self):
import db
import time
url = request.form.get('url', '').encode('utf-8')
path = request.form.get('path', '').encode('utf-8')
filename = request.form.get('filename', '').encode('utf-8')
isTask = mw.getRootDir() + '/tmp/panelTask.pl'
execstr = url + '|mw|' + path + '/' + filename
mw.M('tasks').add('name,type,status,addtime,execstr',
('下载文件[' + filename + ']', 'download', '0', time.strftime('%Y-%m-%d %H:%M:%S'), execstr))
mw.writeFile(isTask, 'True')
# self.setFileAccept(path + '/' + filename)
return mw.returnJson(True, '已将下载任务添加到队列!')
def removeTaskApi(self):
mid = request.form.get('id', '').encode('utf-8')
try:
name = mw.M('tasks').where('id=?', (mid,)).getField('name')
status = mw.M('tasks').where('id=?', (mid,)).getField('status')
mw.M('tasks').delete(mid)
if status == '-1':
os.system(
"kill `ps -ef |grep 'python panelSafe.pyc'|grep -v grep|grep -v panelExec|awk '{print $2}'`")
os.system(
"kill `ps aux | grep 'python task.pyc$'|awk '{print $2}'`")
os.system('''
pids=`ps aux | grep 'sh'|grep -v grep|grep install|awk '{print $2}'`
arr=($pids)
for p in ${arr[@]}
do
kill -9 $p
done
''')
os.system(
'rm -f ' + name.replace('扫描目录[', '').replace(']', '') + '/scan.pl')
isTask = mw.getRootDir() + '/tmp/panelTask.pl'
mw.writeFile(isTask, 'True')
os.system('/etc/init.d/mw start')
except:
os.system('/etc/init.d/mw start')
return mw.returnJson(True, '任务已删除!')
# 上传文件
def uploadFileApi(self):
from werkzeug.utils import secure_filename
from flask import request
path = request.args.get('path', '').encode('utf-8')
if not os.path.exists(path):
os.makedirs(path)
f = request.files['zunfile']
filename = os.path.join(path, f.filename)
if sys.version_info[0] == 2:
filename = filename.encode('utf-8')
s_path = path
if os.path.exists(filename):
s_path = filename
p_stat = os.stat(s_path)
f.save(filename)
os.chown(filename, p_stat.st_uid, p_stat.st_gid)
os.chmod(filename, p_stat.st_mode)
msg = mw.getInfo('上传文件[{1}] 到 [{2}]成功!', (filename, path))
mw.writeLog('文件管理', msg)
return mw.returnMsg(True, '上传成功!')
def getRecycleBinApi(self):
rPath = self.rPath
if not os.path.exists(rPath):
os.system('mkdir -p ' + rPath)
data = {}
data['dirs'] = []
data['files'] = []
data['status'] = os.path.exists('data/recycle_bin.pl')
data['status_db'] = os.path.exists('data/recycle_bin_db.pl')
for file in os.listdir(rPath):
try:
tmp = {}
fname = rPath + file
tmp1 = file.split('_mw_')
tmp2 = tmp1[len(tmp1) - 1].split('_t_')
tmp['rname'] = file
tmp['dname'] = file.replace('_mw_', '/').split('_t_')[0]
tmp['name'] = tmp2[0]
tmp['time'] = int(float(tmp2[1]))
if os.path.islink(fname):
filePath = os.readlink(fname)
link = ' -> ' + filePath
if os.path.exists(filePath):
tmp['size'] = os.path.getsize(filePath)
else:
tmp['size'] = 0
else:
tmp['size'] = os.path.getsize(fname)
if os.path.isdir(fname):
data['dirs'].append(tmp)
else:
data['files'].append(tmp)
except:
continue
return mw.returnJson(True, 'OK', data)
# 回收站开关
def recycleBinApi(self):
c = 'data/recycle_bin.pl'
db = request.form.get('db', '').encode('utf-8')
if db != '':
c = 'data/recycle_bin_db.pl'
if os.path.exists(c):
os.remove(c)
mw.writeLog('文件管理', '已关闭回收站功能!')
return mw.returnJson(True, '已关闭回收站功能!')
else:
mw.writeFile(c, 'True')
mw.writeLog('文件管理', '已开启回收站功能!')
return mw.returnJson(True, '已开启回收站功能!')
def reRecycleBinApi(self):
rPath = self.rPath
path = request.form.get('path', '').encode('utf-8')
dFile = path.replace('_mw_', '/').split('_t_')[0]
try:
import shutil
shutil.move(rPath + path, dFile)
msg = mw.getInfo('移动文件[{1}]到回收站成功!', (dFile,))
mw.writeLog('文件管理', msg)
return mw.returnJson(True, '恢复成功!')
except Exception as e:
msg = mw.getInfo('从回收站恢复[{1}]失败!', (dFile,))
mw.writeLog('文件管理', msg)
return mw.returnJson(False, '恢复失败!')
def delRecycleBinApi(self):
rPath = self.rPath
path = request.form.get('path', '').encode('utf-8')
empty = request.form.get('empty', '').encode('utf-8')
dFile = path.split('_t_')[0]
if not self.checkDir(path):
return mw.returnJson(False, '敏感目录,请不要花样作死!')
os.system('which chattr && chattr -R -i ' + rPath + path)
if os.path.isdir(rPath + path):
import shutil
shutil.rmtree(rPath + path)
else:
os.remove(rPath + path)
tfile = path.replace('_mw_', '/').split('_t_')[0]
msg = mw.getInfo('已彻底从回收站删除{1}!', (tfile,))
mw.writeLog('文件管理', msg)
return mw.returnJson(True, msg)
# 获取进度
def getSpeedApi(self):
data = mw.getSpeed()
return mw.returnJson(True, '已清空回收站!', data)
def closeRecycleBinApi(self):
rPath = self.rPath
os.system('which chattr && chattr -R -i ' + rPath)
rlist = os.listdir(rPath)
i = 0
l = len(rlist)
for name in rlist:
i += 1
path = rPath + name
mw.writeSpeed(name, i, l)
if os.path.isdir(path):
shutil.rmtree(path)
else:
os.remove(path)
mw.writeSpeed(None, 0, 0)
mw.writeLog('文件管理', '已清空回收站!')
return mw.returnJson(True, '已清空回收站!')
def deleteDirApi(self):
path = request.form.get('path', '').encode('utf-8')
if not os.path.exists(path):
return mw.returnJson(False, '指定文件不存在!')
# 检查是否为.user.ini
if path.find('.user.ini'):
os.system("chattr -i '" + path + "'")
try:
if os.path.exists('data/recycle_bin.pl'):
if self.mvRecycleBin(path):
return mw.returnJson(True, '已将文件移动到回收站!')
mw.execShell('rm -rf ' + path)
mw.writeLog('文件管理', '删除文件成功!', (path,))
return mw.returnJson(True, '删除文件成功!')
except:
return mw.returnJson(False, '删除文件失败!')
def closeLogsApi(self):
logPath = mw.getLogsDir()
os.system('rm -f ' + logPath + '/*')
os.system('kill -USR1 `cat ' + mw.getServerDir() +
'openresty/nginx/logs/nginx.pid`')
mw.writeLog('文件管理', '网站日志已被清空!')
tmp = self.getDirSize(logPath)
return mw.returnJson(True, tmp[0].split()[0])
def setBatchDataApi(self):
path = request.form.get('path', '').encode('utf-8')
stype = request.form.get('type', '').encode('utf-8')
access = request.form.get('access', '').encode('utf-8')
user = request.form.get('user', '').encode('utf-8')
data = request.form.get('data')
if stype == '1' or stype == '2':
session['selected'] = {
'path': path,
'type': stype,
'access': access,
'user': user,
'data': data
}
return mw.returnJson(True, '标记成功,请在目标目录点击粘贴所有按钮!')
elif stype == '3':
for key in json.loads(data):
try:
key = key.encode('utf-8')
filename = path + '/' + key
if not self.checkDir(filename):
return mw.returnJson(False, 'FILE_DANGER')
os.system('chmod -R ' + access + " '" + filename + "'")
os.system('chown -R ' + user + ':' +
user + " '" + filename + "'")
except:
continue
mw.writeLog('文件管理', '批量设置权限成功!')
return mw.returnJson(True, '批量设置权限成功!')
else:
import shutil
isRecyle = os.path.exists('data/recycle_bin.pl')
data = json.loads(data)
l = len(data)
i = 0
for key in data:
try:
filename = path + '/' + key.encode('utf-8')
topath = filename
if not os.path.exists(filename):
continue
i += 1
mw.writeSpeed(key, i, l)
if os.path.isdir(filename):
if not self.checkDir(filename):
return mw.returnJson(False, '请不要花样作死!')
if isRecyle:
self.mvRecycleBin(topath)
else:
shutil.rmtree(filename)
else:
if key == '.user.ini':
os.system('which chattr && chattr -i ' + filename)
if isRecyle:
self.mvRecycleBin(topath)
else:
os.remove(filename)
except:
continue
mw.writeSpeed(None, 0, 0)
mw.writeLog('文件管理', '批量删除成功!')
return mw.returnJson(True, '批量删除成功!')
def checkExistsFilesApi(self):
dfile = request.form.get('dfile', '').encode('utf-8')
filename = request.form.get('filename', '').encode('utf-8')
data = []
filesx = []
if filename == '':
filesx = json.loads(session['selected']['data'])
else:
filesx.append(filename)
print filesx
for fn in filesx:
if fn == '.':
continue
filename = dfile + '/' + fn
if os.path.exists(filename):
tmp = {}
stat = os.stat(filename)
tmp['filename'] = fn
tmp['size'] = os.path.getsize(filename)
tmp['mtime'] = str(int(stat.st_mtime))
data.append(tmp)
return mw.returnJson(True, 'ok', data)
def batchPasteApi(self):
path = request.form.get('path', '').encode('utf-8')
stype = request.form.get('type', '').encode('utf-8')
# filename = request.form.get('filename', '').encode('utf-8')
import shutil
if not self.checkDir(path):
return mw.returnJson(False, '请不要花样作死!')
i = 0
myfiles = json.loads(session['selected']['data'])
l = len(myfiles)
if stype == '1':
for key in myfiles:
i += 1
mw.writeSpeed(key, i, l)
try:
sfile = session['selected'][
'path'] + '/' + key.encode('utf-8')
dfile = path + '/' + key.encode('utf-8')
if os.path.isdir(sfile):
shutil.copytree(sfile, dfile)
else:
shutil.copyfile(sfile, dfile)
stat = os.stat(sfile)
os.chown(dfile, stat.st_uid, stat.st_gid)
except:
continue
msg = mw.getInfo('从[{1}]批量复制到[{2}]成功',
(session['selected']['path'], path,))
mw.writeLog('文件管理', msg)
else:
for key in myfiles:
try:
i += 1
mw.writeSpeed(key, i, l)
sfile = session['selected'][
'path'] + '/' + key.encode('utf-8')
dfile = path + '/' + key.encode('utf-8')
shutil.move(sfile, dfile)
except:
continue
msg = mw.getInfo('从[{1}]批量移动到[{2}]成功',
(session['selected']['path'], path,))
mw.writeLog('文件管理', msg)
mw.writeSpeed(None, 0, 0)
errorCount = len(myfiles) - i
del(session['selected'])
msg = mw.getInfo('批量操作成功[{1}],失败[{2}]', (str(i), str(errorCount)))
return mw.returnJson(True, msg)
def copyFileApi(self):
sfile = request.form.get('sfile', '').encode('utf-8')
dfile = request.form.get('dfile', '').encode('utf-8')
if not os.path.exists(sfile):
return mw.returnJson(False, '指定文件不存在!')
if os.path.isdir(sfile):
return self.copyDir(sfile, dfile)
import shutil
try:
shutil.copyfile(sfile, dfile)
msg = mw.getInfo('复制文件[{1}]到[{2}]成功!', (sfile, dfile,))
mw.writeLog('文件管理', msg)
stat = os.stat(sfile)
os.chown(dfile, stat.st_uid, stat.st_gid)
return mw.returnJson(True, '文件复制成功!')
except:
return mw.returnJson(False, '文件复制失败!')
##### ----- end ----- ###
def copyDir(self, sfile, dfile):
if not os.path.exists(sfile):
return mw.returnJson(False, '指定目录不存在!')
if os.path.exists(dfile):
return mw.returnJson(False, '指定目录已存在!')
import shutil
try:
shutil.copytree(sfile, dfile)
stat = os.stat(sfile)
os.chown(dfile, stat.st_uid, stat.st_gid)
msg = mw.getInfo('复制目录[{1}]到[{2}]成功!', (sfile, dfile))
mw.writeLog('文件管理', msg)
return mw.returnJson(True, '目录复制成功!')
except:
return mw.returnJson(False, '目录复制失败!')
# 检查敏感目录
def checkDir(self, path):
path = path.replace('//', '/')
if path[-1:] == '/':
path = path[:-1]
nDirs = ('',
'/',
'/*',
'/www',
'/root',
'/boot',
'/bin',
'/etc',
'/home',
'/dev',
'/sbin',
'/var',
'/usr',
'/tmp',
'/sys',
'/proc',
'/media',
'/mnt',
'/opt',
'/lib',
'/srv',
'/selinux',
'/www/server',
'/www/server/data',
mw.getRootDir())
return not path in nDirs
def getDirSize(self, path):
if mw.getOs() == 'darwin':
tmp = mw.execShell('du -sh ' + path)
else:
tmp = mw.execShell('du -sbh ' + path)
return tmp
def checkFileName(self, filename):
# 检测文件名
nots = ['\\', '&', '*', '|', ';']
if filename.find('/') != -1:
filename = filename.split('/')[-1]
for n in nots:
if n in filename:
return False
return True
def setFileAccept(self, filename):
auth = 'www:www'
if mw.getOs() == 'darwin':
user = mw.execShell(
"who | sed -n '2, 1p' |awk '{print $1}'")[0].strip()
auth = user + ':staff'
os.system('chown -R ' + auth + ' ' + filename)
os.system('chmod -R 755 ' + filename)
# 移动到回收站
def mvRecycleBin(self, path):
rPath = self.rPath
if not os.path.exists(rPath):
os.system('mkdir -p ' + rPath)
rFile = rPath + path.replace('/', '_mw_') + '_t_' + str(time.time())
try:
import shutil
shutil.move(path, rFile)
mw.writeLog('文件管理', mw.getInfo(
'移动文件[{1}]到回收站成功!', (path)))
return True
except:
mw.writeLog('文件管理', mw.getInfo(
'移动文件[{1}]到回收站失败!', (path)))
return False
def getBody(self, path):
if not os.path.exists(path):
return mw.returnJson(False, '文件不存在', (path,))
if os.path.getsize(path) > 2097152:
return mw.returnJson(False, u'不能在线编辑大于2MB的文件!')
fp = open(path, 'rb')
data = {}
data['status'] = True
try:
if fp:
from chardet.universaldetector import UniversalDetector
detector = UniversalDetector()
srcBody = b""
for line in fp.readlines():
detector.feed(line)
srcBody += line
detector.close()
char = detector.result
data['encoding'] = char['encoding']
if char['encoding'] == 'GB2312' or not char['encoding'] or char[
'encoding'] == 'TIS-620' or char['encoding'] == 'ISO-8859-9':
data['encoding'] = 'GBK'
if char['encoding'] == 'ascii' or char[
'encoding'] == 'ISO-8859-1':
data['encoding'] = 'utf-8'
if char['encoding'] == 'Big5':
data['encoding'] = 'BIG5'
if not char['encoding'] in ['GBK', 'utf-8',
'BIG5']:
data['encoding'] = 'utf-8'
try:
if sys.version_info[0] == 2:
data['data'] = srcBody.decode(
data['encoding']).encode('utf-8', errors='ignore')
else:
data['data'] = srcBody.decode(data['encoding'])
except:
data['encoding'] = char['encoding']
if sys.version_info[0] == 2:
data['data'] = srcBody.decode(
data['encoding']).encode('utf-8', errors='ignore')
else:
data['data'] = srcBody.decode(data['encoding'])
else:
if sys.version_info[0] == 2:
data['data'] = srcBody.decode('utf-8').encode('utf-8')
else:
data['data'] = srcBody.decode('utf-8')
data['encoding'] = u'utf-8'
return mw.returnJson(True, 'OK', data)
except Exception as ex:
return mw.returnJson(False, u'文件编码不被兼容,无法正确读取文件!' + str(ex))
def saveBody(self, path, data, encoding='utf-8'):
if not os.path.exists(path):
return mw.returnJson(False, '文件不存在')
try:
if encoding == 'ascii':
encoding = 'utf-8'
if sys.version_info[0] == 2:
data = data.encode(encoding, errors='ignore')
fp = open(path, 'w+')
else:
data = data.encode(
encoding, errors='ignore').decode(encoding)
fp = open(path, 'w+', encoding=encoding)
fp.write(data)
fp.close()
mw.writeLog('文件管理', '文件保存成功', (path,))
return mw.returnJson(True, '文件保存成功')
except Exception as ex:
return mw.returnJson(False, 'FILE_SAVE_ERR:' + str(ex))
def zip(self, sfile, dfile, stype, path):
if sfile.find(',') == -1:
if not os.path.exists(path + '/' + sfile):
return mw.returnMsg(False, '指定文件不存在!')
try:
tmps = mw.getRunDir() + '/tmp/panelExec.log'
if stype == 'zip':
os.system("cd '" + path + "' && zip '" + dfile +
"' -r '" + sfile + "' > " + tmps + " 2>&1")
else:
sfiles = ''
for sfile in sfile.split(','):
if not sfile:
continue
sfiles += " '" + sfile + "'"
os.system("cd '" + path + "' && tar -zcvf '" +
dfile + "' " + sfiles + " > " + tmps + " 2>&1")
self.setFileAccept(dfile)
mw.writeLog("文件管理", '文件压缩成功!', (sfile, dfile))
return mw.returnJson(True, '文件压缩成功!')
except:
return mw.returnJson(False, '文件压缩失败!')
def delete(self, path):
if not os.path.exists(path):
return mw.returnJson(False, '指定文件不存在!')
# 检查是否为.user.ini
if path.find('.user.ini') >= 0:
os.system("chattr -i '" + path + "'")
try:
if os.path.exists('data/recycle_bin.pl'):
if self.mvRecycleBin(path):
return mw.returnJson(True, '已将文件移动到回收站!')
os.remove(path)
mw.writeLog('文件管理', mw.getInfo(
'删除文件[{1}]成功!', (path)))
return mw.returnJson(True, '删除文件成功!')
except:
return mw.returnJson(False, '删除文件失败!')
def getAccess(self, filename):
data = {}
try:
stat = os.stat(filename)
data['chmod'] = str(oct(stat.st_mode)[-3:])
data['chown'] = pwd.getpwuid(stat.st_uid).pw_name
except:
data['chmod'] = 755
data['chown'] = 'www'
return data
# 计算文件数量
def getCount(self, path, search):
i = 0
for name in os.listdir(path):
if search:
if name.lower().find(search) == -1:
continue
# if name[0:1] == '.':
# continue
i += 1
return i
def getDir(self, path, page=1, page_size=10, search=None):
data = {}
dirnames = []
filenames = []
info = {}
info['count'] = self.getCount(path, search)
info['row'] = page_size
info['p'] = page
info['tojs'] = 'getFiles'
pageObj = mw.getPageObject(info, '1,2,3,4,5,6,7,8')
data['PAGE'] = pageObj[0]
i = 0
n = 0
for filename in os.listdir(path):
if search:
if filename.lower().find(search) == -1:
continue
i += 1
if n >= pageObj[1].ROW:
break
if i < pageObj[1].SHIFT:
continue
try:
filePath = (path + '/' + filename).encode('utf8')
link = ''
if os.path.islink(filePath):
filePath = os.readlink(filePath)
link = ' -> ' + filePath
if not os.path.exists(filePath):
filePath = path + '/' + filePath
if not os.path.exists(filePath):
continue
stat = os.stat(filePath)
accept = str(oct(stat.st_mode)[-3:])
mtime = str(int(stat.st_mtime))
user = ''
try:
user = pwd.getpwuid(stat.st_uid).pw_name
except:
user = str(stat.st_uid)
size = str(stat.st_size)
if os.path.isdir(filePath):
dirnames.append(filename + ';' + size + ';' +
mtime + ';' + accept + ';' + user + ';' + link)
else:
filenames.append(filename + ';' + size + ';' +
mtime + ';' + accept + ';' + user + ';' + link)
n += 1
except:
continue
data['DIR'] = sorted(dirnames)
data['FILES'] = sorted(filenames)
data['PATH'] = path.replace('//', '/')
return mw.getJson(data)

413
class/core/firewall_api.py Executable file
View File

@@ -0,0 +1,413 @@
# coding: utf-8
import psutil
import time
import os
import sys
import mw
import re
import json
import pwd
from flask import request
class firewall_api:
__isFirewalld = False
__isUfw = False
__isMac = False
def __init__(self):
if os.path.exists('/usr/sbin/firewalld'):
self.__isFirewalld = True
if os.path.exists('/usr/sbin/ufw'):
self.__isUfw = True
if mw.isAppleSystem():
self.__isMac = True
##### ----- start ----- ###
# 添加屏蔽IP
def addDropAddressApi(self):
import re
port = request.form.get('port', '').strip()
ps = request.form.get('ps', '').strip()
rep = "^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(\/\d{1,2})?$"
if not re.search(rep, port):
return mw.returnJson(False, '您输入的IP地址不合法!')
address = port
if mw.M('firewall').where("port=?", (address,)).count() > 0:
return mw.returnJson(False, '您要放屏蔽的IP已存在屏蔽列表,无需重复处理!')
if self.__isUfw:
mw.execShell('ufw deny from ' + address + ' to any')
else:
if self.__isFirewalld:
cmd = 'firewall-cmd --permanent --add-rich-rule=\'rule family=ipv4 source address="' + \
address + '" drop\''
mw.execShell(cmd)
else:
cmd = 'iptables -I INPUT -s ' + address + ' -j DROP'
mw.execShell(cmd)
msg = mw.getInfo('屏蔽IP[{1}]成功!', (address,))
mw.writeLog("防火墙管理", msg)
addtime = time.strftime('%Y-%m-%d %X', time.localtime())
mw.M('firewall').add('port,ps,addtime', (address, ps, addtime))
self.firewallReload()
return mw.returnJson(True, '添加成功!')
# 添加放行端口
def addAcceptPortApi(self):
if not self.getFwStatus():
return mw.returnJson(False, '防火墙启动时,才能添加规则!')
import re
import time
port = request.form.get('port', '').strip()
ps = request.form.get('ps', '').strip()
stype = request.form.get('type', '').strip()
rep = "^\d{1,5}(:\d{1,5})?$"
if not re.search(rep, port):
return mw.returnJson(False, '端口范围不正确!')
if mw.M('firewall').where("port=?", (port,)).count() > 0:
return mw.returnJson(False, '您要放行的端口已存在,无需重复放行!')
msg = mw.getInfo('放行端口[{1}]成功', (port,))
mw.writeLog("防火墙管理", msg)
addtime = time.strftime('%Y-%m-%d %X', time.localtime())
mw.M('firewall').add('port,ps,addtime', (port, ps, addtime))
self.addAcceptPort(port)
self.firewallReload()
return mw.returnJson(True, '添加放行(' + port + ')端口成功!')
# 删除IP屏蔽
def delDropAddressApi(self):
if not self.getFwStatus():
return mw.returnJson(False, '防火墙启动时,才能删除规则!')
port = request.form.get('port', '').strip()
ps = request.form.get('ps', '').strip()
sid = request.form.get('id', '').strip()
address = port
if self.__isUfw:
mw.execShell('ufw delete deny from ' + address + ' to any')
else:
if self.__isFirewalld:
mw.execShell(
'firewall-cmd --permanent --remove-rich-rule=\'rule family=ipv4 source address="' + address + '" drop\'')
elif self.__isMac:
pass
else:
cmd = 'iptables -D INPUT -s ' + address + ' -j DROP'
mw.execShell(cmd)
msg = mw.getInfo('解除IP[{1}]的屏蔽!', (address,))
mw.writeLog("防火墙管理", msg)
mw.M('firewall').where("id=?", (sid,)).delete()
self.firewallReload()
return mw.returnJson(True, '删除成功!')
# 删除放行端口
def delAcceptPortApi(self):
port = request.form.get('port', '').strip()
sid = request.form.get('id', '').strip()
mw_port = mw.readFile('data/port.pl')
try:
if(port == mw_port):
return mw.returnJson(False, '失败,不能删除当前面板端口!')
if self.__isUfw:
mw.execShell('ufw delete allow ' + port + '/tcp')
else:
if self.__isFirewalld:
mw.execShell(
'firewall-cmd --permanent --zone=public --remove-port=' + port + '/tcp')
mw.execShell(
'firewall-cmd --permanent --zone=public --remove-port=' + port + '/udp')
else:
mw.execShell(
'iptables -D INPUT -p tcp -m state --state NEW -m tcp --dport ' + port + ' -j ACCEPT')
msg = mw.getInfo('删除防火墙放行端口[{1}]成功!', (port,))
mw.writeLog("防火墙管理", msg)
mw.M('firewall').where("id=?", (sid,)).delete()
self.firewallReload()
return mw.returnJson(True, '删除成功!')
except Exception as e:
return mw.returnJson(False, '删除失败!:' + str(e))
def getWwwPathApi(self):
path = mw.getLogsDir()
return mw.getJson({'path': path})
def getListApi(self):
p = request.form.get('p', '1').strip()
limit = request.form.get('limit', '10').strip()
return self.getList(int(p), int(limit))
def getLogListApi(self):
p = request.form.get('p', '1').strip()
limit = request.form.get('limit', '10').strip()
search = request.form.get('search', '').strip()
return self.getLogList(int(p), int(limit), search)
def getSshInfoApi(self):
file = '/etc/ssh/sshd_config'
conf = mw.readFile(file)
rep = "#*Port\s+([0-9]+)\s*\n"
port = re.search(rep, conf).groups(0)[0]
isPing = True
try:
if mw.isAppleSystem():
isPing = True
else:
file = '/etc/sysctl.conf'
conf = mw.readFile(file)
rep = "#*net\.ipv4\.icmp_echo_ignore_all\s*=\s*([0-9]+)"
tmp = re.search(rep, conf).groups(0)[0]
if tmp == '1':
isPing = False
except:
isPing = True
import system_api
panelsys = system_api.system_api()
version = panelsys.getSystemVersion()
if os.path.exists('/usr/bin/apt-get'):
if os.path.exists('/etc/init.d/sshd'):
cmd = "service sshd status | grep -P '(dead|stop)'|grep -v grep"
status = mw.execShell(cmd)
else:
cmd = "service ssh status | grep -P '(dead|stop)'|grep -v grep"
status = mw.execShell(cmd)
else:
if version.find(' 7.') != -1:
cmd = "systemctl status sshd.service | grep 'dead'|grep -v grep"
status = mw.execShell(cmd)
else:
cmd = "/etc/init.d/sshd status | grep -e 'stopped' -e '已停'|grep -v grep"
status = mw.execShell(cmd)
if len(status[0]) > 3:
status = False
else:
status = True
data = {}
data['port'] = port
data['status'] = status
data['ping'] = isPing
if mw.isAppleSystem():
data['firewall_status'] = False
else:
data['firewall_status'] = self.getFwStatus()
return mw.getJson(data)
def setSshPortApi(self):
port = request.form.get('port', '1').strip()
if int(port) < 22 or int(port) > 65535:
return mw.returnJson(False, '端口范围必需在22-65535之间!')
ports = ['21', '25', '80', '443', '7200', '8080', '888', '8888']
if port in ports:
return mw.returnJson(False, '(' + port + ')' + '特殊端口不可设置!')
file = '/etc/ssh/sshd_config'
conf = mw.readFile(file)
rep = "#*Port\s+([0-9]+)\s*\n"
conf = re.sub(rep, "Port " + port + "\n", conf)
mw.writeFile(file, conf)
if self.__isFirewalld:
mw.execShell('setenforce 0')
mw.execShell(
'sed -i "s#SELINUX=enforcing#SELINUX=disabled#" /etc/selinux/config')
mw.execShell("systemctl restart sshd.service")
elif self.__isUfw:
mw.execShell('ufw allow ' + port + '/tcp')
mw.execShell("service ssh restart")
else:
mw.execShell(
'iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport ' + port + ' -j ACCEPT')
mw.execShell("/etc/init.d/sshd restart")
self.firewallReload()
# mw.M('firewall').where(
# "ps=?", ('SSH远程管理服务',)).setField('port', port)
msg = mw.getInfo('改SSH端口为[{1}]成功!', port)
mw.writeLog("防火墙管理", msg)
return mw.returnJson(True, '修改成功!')
def setSshStatusApi(self):
if mw.isAppleSystem():
return mw.returnJson(True, '开发机不能操作!')
status = request.form.get('status', '1').strip()
version = mw.readFile('/etc/redhat-release')
if int(status) == 1:
msg = 'SSH服务已停用'
act = 'stop'
else:
msg = 'SSH服务已启用'
act = 'start'
if not os.path.exists('/etc/redhat-release'):
mw.execShell('service ssh ' + act)
elif version.find(' 7.') != -1:
mw.execShell("systemctl " + act + " sshd.service")
else:
mw.execShell("/etc/init.d/sshd " + act)
mw.writeLog("防火墙管理", msg)
return mw.returnJson(True, '操作成功!')
def setPingApi(self):
if mw.isAppleSystem():
return mw.returnJson(True, '开发机不能操作!')
status = request.form.get('status')
filename = '/etc/sysctl.conf'
conf = mw.readFile(filename)
if conf.find('net.ipv4.icmp_echo') != -1:
rep = u"net\.ipv4\.icmp_echo.*"
conf = re.sub(rep, 'net.ipv4.icmp_echo_ignore_all=' + status, conf)
else:
conf += "\nnet.ipv4.icmp_echo_ignore_all=" + status
mw.writeFile(filename, conf)
mw.execShell('sysctl -p')
return mw.returnJson(True, '设置成功!')
def setFwApi(self):
if mw.isAppleSystem():
return mw.returnJson(True, '开发机不能设置!')
status = request.form.get('status', '1')
if status == '1':
if self.__isUfw:
mw.execShell('/usr/sbin/ufw stop')
return
if self.__isFirewalld:
mw.execShell('systemctl stop firewalld.service')
mw.execShell('systemctl disable firewalld.service')
elif self.__isMac:
pass
else:
mw.execShell('/etc/init.d/iptables save')
mw.execShell('/etc/init.d/iptables stop')
else:
if self.__isUfw:
mw.execShell('/usr/sbin/ufw start')
return
if self.__isFirewalld:
mw.execShell('systemctl start firewalld.service')
mw.execShell('systemctl enable firewalld.service')
elif self.__isMac:
pass
else:
mw.execShell('/etc/init.d/iptables save')
mw.execShell('/etc/init.d/iptables restart')
return mw.returnJson(True, '设置成功!')
def delPanelLogsApi(self):
mw.M('logs').where('id>?', (0,)).delete()
mw.writeLog('面板设置', '面板操作日志已清空!')
return mw.returnJson(True, '面板操作日志已清空!')
##### ----- start ----- ###
def getList(self, page, limit):
start = (page - 1) * limit
_list = mw.M('firewall').field('id,port,ps,addtime').limit(
str(start) + ',' + str(limit)).order('id desc').select()
data = {}
data['data'] = _list
count = mw.M('firewall').count()
_page = {}
_page['count'] = count
_page['tojs'] = 'showAccept'
_page['p'] = page
data['page'] = mw.getPage(_page)
return mw.getJson(data)
def getLogList(self, page, limit, search=''):
find_search = ''
if search != '':
find_search = "type like '%" + search + "%' or log like '%" + \
search + "%' or addtime like '%" + search + "%'"
start = (page - 1) * limit
_list = mw.M('logs').where(find_search, ()).field(
'id,type,log,addtime').limit(str(start) + ',' + str(limit)).order('id desc').select()
data = {}
data['data'] = _list
count = mw.M('logs').where(find_search, ()).count()
_page = {}
_page['count'] = count
_page['tojs'] = 'getLogs'
_page['p'] = page
data['page'] = mw.getPage(_page)
return mw.getJson(data)
def addAcceptPort(self, port):
if self.__isUfw:
mw.execShell('ufw allow ' + port + '/tcp')
else:
if self.__isFirewalld:
port = port.replace(':', '-')
cmd = 'firewall-cmd --permanent --zone=public --add-port=' + port + '/tcp'
mw.execShell(cmd)
elif self.__isMac:
pass
else:
cmd = 'iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport ' + port + ' -j ACCEPT'
mw.execShell(cmd)
def firewallReload(self):
if self.__isUfw:
mw.execShell('/usr/sbin/ufw reload')
return
if self.__isFirewalld:
mw.execShell('firewall-cmd --reload')
elif self.__isMac:
pass
else:
mw.execShell('/etc/init.d/iptables save')
mw.execShell('/etc/init.d/iptables restart')
def getFwStatus(self):
if self.__isUfw:
cmd = "ps -ef|grep ufw |grep -v grep | awk '{print $2}'"
data = mw.execShell(cmd)
if data[0] == '':
return False
return True
if self.__isFirewalld:
cmd = "ps -ef|grep firewalld |grep -v grep | awk '{print $2}'"
data = mw.execShell(cmd)
if data[0] == '':
return False
return True
elif self.__isMac:
return False
else:
cmd = "ps -ef|grep iptables |grep -v grep | awk '{print $2}'"
data = mw.execShell(cmd)
if data[0] == '':
return False
return True

910
class/core/mw.py Executable file
View File

@@ -0,0 +1,910 @@
# coding: utf-8
import os
import sys
import time
import string
import json
import hashlib
import shlex
import datetime
import subprocess
import re
import hashlib
import db
from random import Random
def execShell(cmdstring, cwd=None, timeout=None, shell=True):
if shell:
cmdstring_list = cmdstring
else:
cmdstring_list = shlex.split(cmdstring)
if timeout:
end_time = datetime.datetime.now() + datetime.timedelta(seconds=timeout)
sub = subprocess.Popen(cmdstring_list, cwd=cwd, stdin=subprocess.PIPE,
shell=shell, bufsize=4096, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
while sub.poll() is None:
time.sleep(0.1)
if timeout:
if end_time <= datetime.datetime.now():
raise Exception("Timeout:%s" % cmdstring)
return sub.communicate()
def getRunDir():
return os.getcwd()
def getRootDir():
return os.path.dirname(os.path.dirname(getRunDir()))
def getPluginDir():
return getRunDir() + '/plugins'
def getServerDir():
return getRootDir() + '/server'
def getWwwDir():
file = getRunDir() + '/data/site.pl'
if os.path.exists(file):
return readFile(file).strip()
return getRootDir() + '/wwwroot'
def setWwwDir(wdir):
file = getRunDir() + '/data/site.pl'
return writeFile(file, wdir)
def getLogsDir():
return getRootDir() + '/wwwlogs'
def getBackupDir():
return getRootDir() + '/backup'
def setBackupDir(bdir):
file = getRunDir() + '/data/backup.pl'
return writeFile(file, bdir)
def getOs():
return sys.platform
def isAppleSystem():
if getOs() == 'darwin':
return True
return False
def deleteFile(file):
if os.path.exists(file):
os.remove(file)
def isInstalledWeb():
path = getServerDir() + '/openresty/nginx/sbin/nginx'
if os.path.exists(path):
return True
return False
def restartWeb():
if isInstalledWeb():
initd = getServerDir() + '/openresty/init.d/openresty'
execShell(initd + ' ' + 'reload')
def restartMw():
import system_api
system_api.system_api().restartMw()
def checkWebConfig():
op_dir = getServerDir() + '/openresty'
cmd = "ulimit -n 10240 && " + op_dir + \
"/nginx/sbin/nginx -t -c " + op_dir + "/nginx/conf/nginx.conf"
result = execShell(cmd)
searchStr = 'successful'
if result[1].find(searchStr) == -1:
msg = getInfo('配置文件错误: {1}', (result[1],))
writeLog("软件管理", msg)
return result[1]
return True
def M(table):
sql = db.Sql()
return sql.table(table)
def getPage(args, result='1,2,3,4,5,8'):
data = getPageObject(args, result)
return data[0]
def getPageObject(args, result='1,2,3,4,5,8'):
# 取分页
import page
# 实例化分页类
page = page.Page()
info = {}
info['count'] = 0
if args.has_key('count'):
info['count'] = int(args['count'])
info['row'] = 10
if args.has_key('row'):
info['row'] = int(args['row'])
info['p'] = 1
if args.has_key('p'):
info['p'] = int(args['p'])
info['uri'] = {}
info['return_js'] = ''
if args.has_key('tojs'):
info['return_js'] = args['tojs']
return (page.GetPage(info, result), page)
def md5(str):
# 生成MD5
try:
m = hashlib.md5()
m.update(str)
return m.hexdigest()
except:
return False
def getFileMd5(filename):
# 文件的MD5值
if not os.path.isfile(filename):
return False
myhash = hashlib.md5()
f = file(filename, 'rb')
while True:
b = f.read(8096)
if not b:
break
myhash.update(b)
f.close()
return myhash.hexdigest()
def getRandomString(length):
# 取随机字符串
str = ''
chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
chrlen = len(chars) - 1
random = Random()
for i in range(length):
str += chars[random.randint(0, chrlen)]
return str
def getJson(data):
import json
return json.dumps(data)
def returnData(status, msg, data=None):
return {'status': status, 'msg': msg, 'data': data}
def returnJson(status, msg, data=None):
# if data == None:
# return {'status': status, 'msg': msg}
# return {'status': status, 'msg': msg, 'data': data}
if data == None:
return getJson({'status': status, 'msg': msg})
return getJson({'status': status, 'msg': msg, 'data': data})
def returnMsg(status, msg, args=()):
# 取通用字曲返回
pjson = 'static/language/' + getLanguage() + '/public.json'
logMessage = json.loads(readFile(pjson))
keys = logMessage.keys()
if msg in keys:
msg = logMessage[msg]
for i in range(len(args)):
rep = '{' + str(i + 1) + '}'
msg = msg.replace(rep, args[i])
return {'status': status, 'msg': msg, 'data': args}
def getInfo(msg, args=()):
# 取提示消息
for i in range(len(args)):
rep = '{' + str(i + 1) + '}'
msg = msg.replace(rep, args[i])
return msg
def getMsg(key, args=()):
# 取提示消息
try:
logMessage = json.loads(
readFile('static/language/' + getLanguage() + '/public.json'))
keys = logMessage.keys()
msg = None
if key in keys:
msg = logMessage[key]
for i in range(len(args)):
rep = '{' + str(i + 1) + '}'
msg = msg.replace(rep, args[i])
return msg
except:
return key
def getLan(key):
# 取提示消息
logMessage = json.loads(
readFile('static/language/' + getLanguage() + '/template.json'))
keys = logMessage.keys()
msg = None
if key in keys:
msg = logMessage[key]
return msg
def readFile(filename):
# 读文件内容
try:
fp = open(filename, 'r')
fBody = fp.read()
fp.close()
return fBody
except:
return False
def getDate():
# 取格式时间
import time
return time.strftime('%Y-%m-%d %X', time.localtime())
def getLanguage():
path = 'data/language.pl'
if not os.path.exists(path):
return 'Simplified_Chinese'
return readFile(path).strip()
def writeLog(type, logMsg, args=()):
# 写日志
try:
import time
import db
import json
sql = db.Sql()
mDate = time.strftime('%Y-%m-%d %X', time.localtime())
data = (type, logMsg, mDate)
result = sql.table('logs').add('type,log,addtime', data)
except Exception as e:
print e
def writeFile(filename, str):
# 写文件内容
try:
fp = open(filename, 'w+')
fp.write(str)
fp.close()
return True
except:
return False
def HttpGet(url, timeout=10):
"""
发送GET请求
@url 被请求的URL地址(必需)
@timeout 超时时间默认60秒
return string
"""
if sys.version_info[0] == 2:
try:
import urllib2
import ssl
if sys.version_info[0] == 2:
reload(urllib2)
reload(ssl)
try:
ssl._create_default_https_context = ssl._create_unverified_context
except:
pass
response = urllib2.urlopen(url, timeout=timeout)
return response.read()
except Exception as ex:
return str(ex)
else:
try:
import urllib.request
import ssl
try:
ssl._create_default_https_context = ssl._create_unverified_context
except:
pass
response = urllib.request.urlopen(url, timeout=timeout)
result = response.read()
if type(result) == bytes:
result = result.decode('utf-8')
return result
except Exception as ex:
return str(ex)
def HttpGet2(url, timeout):
import urllib2
try:
req = urllib2.Request(url)
res = urllib2.urlopen(req, timeout=timeout)
result = res.read()
return result
except Exception as e:
return str(e)
def httpGet(url, timeout=10):
return HttpGet2(url, timeout)
def HttpPost(url, data, timeout=10):
"""
发送POST请求
@url 被请求的URL地址(必需)
@data POST参数,可以是字符串或字典(必需)
@timeout 超时时间默认60秒
return string
"""
if sys.version_info[0] == 2:
try:
import urllib
import urllib2
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
data = urllib.urlencode(data)
req = urllib2.Request(url, data)
response = urllib2.urlopen(req, timeout=timeout)
return response.read()
except Exception as ex:
return str(ex)
else:
try:
import urllib.request
import ssl
try:
ssl._create_default_https_context = ssl._create_unverified_context
except:
pass
data = urllib.parse.urlencode(data).encode('utf-8')
req = urllib.request.Request(url, data)
response = urllib.request.urlopen(req, timeout=timeout)
result = response.read()
if type(result) == bytes:
result = result.decode('utf-8')
return result
except Exception as ex:
return str(ex)
def httpPost(url, data, timeout=10):
return HttpPost(url, data, timeout)
def writeSpeed(title, used, total, speed=0):
# 写进度
if not title:
data = {'title': None, 'progress': 0,
'total': 0, 'used': 0, 'speed': 0}
else:
progress = int((100.0 * used / total))
data = {'title': title, 'progress': progress,
'total': total, 'used': used, 'speed': speed}
writeFile('/tmp/panelSpeed.pl', json.dumps(data))
return True
def getSpeed():
# 取进度
path = getRootDir()
data = readFile(path + '/tmp/panelSpeed.pl')
if not data:
data = json.dumps({'title': None, 'progress': 0,
'total': 0, 'used': 0, 'speed': 0})
writeFile(path + '/tmp/panelSpeed.pl', data)
return json.loads(data)
def getLastLine(inputfile, lineNum):
# 读文件指定倒数行数
try:
fp = open(inputfile, 'r')
lastLine = ""
lines = fp.readlines()
count = len(lines)
if count > lineNum:
num = lineNum
else:
num = count
i = 1
lastre = []
for i in range(1, (num + 1)):
if lines:
n = -i
lastLine = lines[n].strip()
fp.close()
lastre.append(lastLine)
result = ''
num -= 1
while num >= 0:
result += lastre[num] + "\n"
num -= 1
return result
except:
return getMsg('TASK_SLEEP')
def getNumLines(path, num, p=1):
pyVersion = sys.version_info[0]
try:
import cgi
if not os.path.exists(path):
return ""
start_line = (p - 1) * num
count = start_line + num
fp = open(path, 'rb')
buf = ""
fp.seek(-1, 2)
if fp.read(1) == "\n":
fp.seek(-1, 2)
data = []
b = True
n = 0
for i in range(count):
while True:
newline_pos = str.rfind(str(buf), "\n")
pos = fp.tell()
if newline_pos != -1:
if n >= start_line:
line = buf[newline_pos + 1:]
try:
data.insert(0, cgi.escape(line))
except:
pass
buf = buf[:newline_pos]
n += 1
break
else:
if pos == 0:
b = False
break
to_read = min(4096, pos)
fp.seek(-to_read, 1)
t_buf = fp.read(to_read)
if pyVersion == 3:
if type(t_buf) == bytes:
t_buf = t_buf.decode('utf-8')
buf = t_buf + buf
fp.seek(-to_read, 1)
if pos - to_read == 0:
buf = "\n" + buf
if not b:
break
fp.close()
except Exception as e:
return ''
return "\n".join(data)
def downloadFile(url, filename):
import urllib
urllib.urlretrieve(url, filename=filename, reporthook=downloadHook)
def downloadHook(count, blockSize, totalSize):
speed = {'total': totalSize, 'block': blockSize, 'count': count}
print speed
print '%02d%%' % (100.0 * count * blockSize / totalSize)
def getLocalIp():
# 取本地外网IP
try:
import re
filename = 'data/iplist.txt'
ipaddress = readFile(filename)
if not ipaddress:
import urllib2
url = 'http://pv.sohu.com/cityjson?ie=utf-8'
opener = urllib2.urlopen(url)
str = opener.read()
ipaddress = re.search('\d+.\d+.\d+.\d+', str).group(0)
writeFile(filename, ipaddress)
ipaddress = re.search('\d+.\d+.\d+.\d+', ipaddress).group(0)
return ipaddress
except:
return '127.0.0.1'
def inArray(arrays, searchStr):
# 搜索数据中是否存在
for key in arrays:
if key == searchStr:
return True
return False
def checkIp(ip):
# 检查是否为IPv4地址
import re
p = re.compile(
'^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$')
if p.match(ip):
return True
else:
return False
def checkPort(port):
# 检查端口是否合法
ports = ['21', '25', '443', '7200', '8080', '888', '8888', '8443']
if port in ports:
return False
intport = int(port)
if intport < 1 or intport > 65535:
return False
return True
def getStrBetween(startStr, endStr, srcStr):
# 字符串取中间
start = srcStr.find(startStr)
if start == -1:
return None
end = srcStr.find(endStr)
if end == -1:
return None
return srcStr[start + 1:end]
def getCpuType():
# 取CPU类型
cpuinfo = open('/proc/cpuinfo', 'r').read()
rep = "model\s+name\s+:\s+(.+)"
tmp = re.search(rep, cpuinfo)
cpuType = None
if tmp:
cpuType = tmp.groups()[0]
return cpuType
def isRestart():
# 检查是否允许重启
num = M('tasks').where('status!=?', ('1',)).count()
if num > 0:
return False
return True
def isUpdateLocalSoft():
num = M('tasks').where('status!=?', ('1',)).count()
if os.path.exists('mdserver-web.zip'):
return True
if num > 0:
data = M('tasks').where('status!=?', ('1',)).field(
'id,type,execstr').limit('1').select()
argv = data[0]['execstr'].split('|dl|')
if data[0]['type'] == 'download' and argv[1] == 'mdserver-web.zip':
return True
return False
def hasPwd(password):
# 加密密码字符
import crypt
return crypt.crypt(password, password)
def getTimeout(url):
start = time.time()
result = httpGet(url)
if result != 'True':
return False
return int((time.time() - start) * 1000)
def makeConf():
file = getRunDir() + '/data/json/config.json'
if not os.path.exists(file):
c = {}
c['title'] = 'Linux面板'
c['home'] = 'http://github/midoks/mdserver-web'
c['recycle_bin'] = True
c['template'] = 'default'
writeFile(file, json.dumps(c))
return c
c = readFile(file)
return json.loads(c)
def getConfig(k):
c = makeConf()
return c[k]
def setConfig(k, v):
c = makeConf()
c[k] = v
file = getRunDir() + '/data/json/config.json'
return writeFile(file, json.dumps(c))
def getHostAddr():
if os.path.exists('data/iplist.txt'):
return readFile('data/iplist.txt').strip()
return '127.0.0.1'
def setHostAddr(addr):
file = getRunDir() + '/data/iplist.txt'
return writeFile(file, addr)
def getHostPort():
if os.path.exists('data/port.pl'):
return readFile('data/port.pl').strip()
return '7200'
def setHostPort(port):
file = getRunDir() + '/data/port.pl'
return writeFile(file, port)
def auth_decode(data):
# 解密数据
token = GetToken()
# 是否有生成Token
if not token:
return returnMsg(False, 'REQUEST_ERR')
# 校验access_key是否正确
if token['access_key'] != data['btauth_key']:
return returnMsg(False, 'REQUEST_ERR')
# 解码数据
import binascii
import hashlib
import urllib
import hmac
import json
tdata = binascii.unhexlify(data['data'])
# 校验signature是否正确
signature = binascii.hexlify(
hmac.new(token['secret_key'], tdata, digestmod=hashlib.sha256).digest())
if signature != data['signature']:
return returnMsg(False, 'REQUEST_ERR')
# 返回
return json.loads(urllib.unquote(tdata))
# 数据加密
def auth_encode(data):
token = GetToken()
pdata = {}
# 是否有生成Token
if not token:
return returnMsg(False, 'REQUEST_ERR')
# 生成signature
import binascii
import hashlib
import urllib
import hmac
import json
tdata = urllib.quote(json.dumps(data))
# 公式 hex(hmac_sha256(data))
pdata['signature'] = binascii.hexlify(
hmac.new(token['secret_key'], tdata, digestmod=hashlib.sha256).digest())
# 加密数据
pdata['btauth_key'] = token['access_key']
pdata['data'] = binascii.hexlify(tdata)
pdata['timestamp'] = time.time()
# 返回
return pdata
def checkToken(get):
# 检查Token
tempFile = 'data/tempToken.json'
if not os.path.exists(tempFile):
return False
import json
import time
tempToken = json.loads(readFile(tempFile))
if time.time() > tempToken['timeout']:
return False
if get.token != tempToken['token']:
return False
return True
def checkInput(data):
# 过滤输入
if not data:
return data
if type(data) != str:
return data
checkList = [
{'d': '<', 'r': '<'},
{'d': '>', 'r': '>'},
{'d': '\'', 'r': '‘'},
{'d': '"', 'r': '“'},
{'d': '&', 'r': '&'},
{'d': '#', 'r': '#'},
{'d': '<', 'r': '<'}
]
for v in checkList:
data = data.replace(v['d'], v['r'])
return data
def checkCert(certPath='ssl/certificate.pem'):
# 验证证书
openssl = '/usr/local/openssl/bin/openssl'
if not os.path.exists(openssl):
openssl = 'openssl'
certPem = readFile(certPath)
s = "\n-----BEGIN CERTIFICATE-----"
tmp = certPem.strip().split(s)
for tmp1 in tmp:
if tmp1.find('-----BEGIN CERTIFICATE-----') == -1:
tmp1 = s + tmp1
writeFile(certPath, tmp1)
result = execShell(openssl + " x509 -in " +
certPath + " -noout -subject")
if result[1].find('-bash:') != -1:
return True
if len(result[1]) > 2:
return False
if result[0].find('error:') != -1:
return False
return True
def getPathSize(path):
# 取文件或目录大小
if not os.path.exists(path):
return 0
if not os.path.isdir(path):
return os.path.getsize(path)
size_total = 0
for nf in os.walk(path):
for f in nf[2]:
filename = nf[0] + '/' + f
size_total += os.path.getsize(filename)
return size_total
def toSize(size):
# 字节单位转换
d = ('b', 'KB', 'MB', 'GB', 'TB')
s = d[0]
for b in d:
if size < 1024:
return str(round(size, 2)) + ' ' + b
size = float(size) / 1024.0
s = b
return str(round(size, 2)) + ' ' + b
def getMacAddress():
# 获取mac
import uuid
mac = uuid.UUID(int=uuid.getnode()).hex[-12:]
return ":".join([mac[e:e + 2] for e in range(0, 11, 2)])
def get_string(t):
if t != -1:
max = 126
m_types = [{'m': 122, 'n': 97}, {'m': 90, 'n': 65}, {'m': 57, 'n': 48}, {
'm': 47, 'n': 32}, {'m': 64, 'n': 58}, {'m': 96, 'n': 91}, {'m': 125, 'n': 123}]
else:
max = 256
t = 0
m_types = [{'m': 255, 'n': 0}]
arr = []
for i in range(max):
if i < m_types[t]['n'] or i > m_types[t]['m']:
continue
arr.append(chr(i))
return arr
def get_string_find(t):
if type(t) != list:
t = [t]
return_str = ''
for s1 in t:
return_str += get_string(int(s1[0]))[int(s1[1:])]
return return_str
def get_string_arr(t):
s_arr = {}
t_arr = []
for s1 in t:
for i in range(6):
if not i in s_arr:
s_arr[i] = get_string(i)
for j in range(len(s_arr[i])):
if s1 == s_arr[i][j]:
t_arr.append(str(i) + str(j))
return t_arr
def getSSHPort():
try:
file = '/etc/ssh/sshd_config'
conf = readFile(file)
rep = "#*Port\s+([0-9]+)\s*\n"
port = re.search(rep, conf).groups(0)[0]
return int(port)
except:
return 22
def getSSHStatus():
if os.path.exists('/usr/bin/apt-get'):
status = execShell("service ssh status | grep -P '(dead|stop)'")
else:
import system_api
version = system_api.system_api().getSystemVersion()
if version.find(' Mac ') != -1:
return True
if version.find(' 7.') != -1:
status = execShell("systemctl status sshd.service | grep 'dead'")
else:
status = execShell(
"/etc/init.d/sshd status | grep -e 'stopped' -e '已停'")
if len(status[0]) > 3:
status = False
else:
status = True
return status

222
class/core/page.py Executable file
View File

@@ -0,0 +1,222 @@
# coding: utf-8
import math
import string
import mw
class Page():
#--------------------------
# 分页类 - JS回调版
#--------------------------
__PREV = '上一页'
__NEXT = '下一页'
__START = '首页'
__END = '尾页'
__COUNT_START = '共'
__COUNT_END = '条数据'
__FO = '从'
__LINE = '条'
__LIST_NUM = 4
SHIFT = None # 偏移量
ROW = None # 每页行数
__C_PAGE = None # 当前页
__COUNT_PAGE = None # 总页数
__COUNT_ROW = None # 总行数
__URI = None # URI
__RTURN_JS = False # 是否返回JS回调
__START_NUM = None # 起始行
__END_NUM = None # 结束行
def __init__(self):
# tmp = mw.getMsg('PAGE')
if False:
self.__PREV = tmp['PREV']
self.__NEXT = tmp['NEXT']
self.__START = tmp['START']
self.__END = tmp['END']
self.__COUNT_START = tmp['COUNT_START']
self.__COUNT_END = tmp['COUNT_END']
self.__FO = tmp['FO']
self.__LINE = tmp['LINE']
def GetPage(self, pageInfo, limit='1,2,3,4,5,6,7,8'):
# 取分页信息
# @param pageInfo 传入分页参数字典
# @param limit 返回系列
self.__RTURN_JS = pageInfo['return_js']
self.__COUNT_ROW = pageInfo['count']
self.ROW = pageInfo['row']
self.__C_PAGE = self.__GetCpage(pageInfo['p'])
self.__START_NUM = self.__StartRow()
self.__END_NUM = self.__EndRow()
self.__COUNT_PAGE = self.__GetCountPage()
self.__URI = self.__SetUri(pageInfo['uri'])
self.SHIFT = self.__START_NUM - 1
keys = limit.split(',')
pages = {}
# 起始页
pages['1'] = self.__GetStart()
# 上一页
pages['2'] = self.__GetPrev()
# 分页
pages['3'] = self.__GetPages()
# 下一页
pages['4'] = self.__GetNext()
# 尾页
pages['5'] = self.__GetEnd()
# 当前显示页与总页数
pages['6'] = "<span class='Pnumber'>" + \
bytes(self.__C_PAGE) + "/" + bytes(self.__COUNT_PAGE) + "</span>"
# 本页显示开始与结束行
pages['7'] = "<span class='Pline'>" + self.__FO + \
bytes(self.__START_NUM) + "-" + \
bytes(self.__END_NUM) + self.__LINE + "</span>"
# 行数
pages['8'] = "<span class='Pcount'>" + self.__COUNT_START + \
bytes(self.__COUNT_ROW) + self.__COUNT_END + "</span>"
# 构造返回数据
retuls = '<div>'
for value in keys:
retuls += pages[value]
retuls += '</div>'
# 返回分页数据
return retuls
def __GetEnd(self):
# 构造尾页
endStr = ""
if self.__C_PAGE >= self.__COUNT_PAGE:
endStr = ''
else:
if self.__RTURN_JS == "":
endStr = "<a class='Pend' href='" + self.__URI + "p=" + \
bytes(self.__COUNT_PAGE) + "'>" + self.__END + "</a>"
else:
endStr = "<a class='Pend' onclick='" + self.__RTURN_JS + \
"(" + bytes(self.__COUNT_PAGE) + ")'>" + self.__END + "</a>"
return endStr
def __GetNext(self):
# 构造下一页
nextStr = ""
if self.__C_PAGE >= self.__COUNT_PAGE:
nextStr = ''
else:
if self.__RTURN_JS == "":
nextStr = "<a class='Pnext' href='" + self.__URI + "p=" + \
bytes(self.__C_PAGE + 1) + "'>" + self.__NEXT + "</a>"
else:
nextStr = "<a class='Pnext' onclick='" + self.__RTURN_JS + \
"(" + bytes(self.__C_PAGE + 1) + ")'>" + self.__NEXT + "</a>"
return nextStr
def __GetPages(self):
# 构造分页
pages = ''
num = 0
# 当前页之前
if (self.__COUNT_PAGE - self.__C_PAGE) < self.__LIST_NUM:
num = self.__LIST_NUM + \
(self.__LIST_NUM - (self.__COUNT_PAGE - self.__C_PAGE))
else:
num = self.__LIST_NUM
n = 0
for i in range(num):
n = num - i
page = self.__C_PAGE - n
if page > 0:
if self.__RTURN_JS == "":
pages += "<a class='Pnum' href='" + self.__URI + \
"p=" + bytes(page) + "'>" + bytes(page) + "</a>"
else:
pages += "<a class='Pnum' onclick='" + self.__RTURN_JS + \
"(" + bytes(page) + ")'>" + bytes(page) + "</a>"
# 当前页
if self.__C_PAGE > 0:
pages += "<span class='Pcurrent'>" + \
bytes(self.__C_PAGE) + "</span>"
# 当前页之后
if self.__C_PAGE <= self.__LIST_NUM:
num = self.__LIST_NUM + (self.__LIST_NUM - self.__C_PAGE) + 1
else:
num = self.__LIST_NUM
for i in range(num):
if i == 0:
continue
page = self.__C_PAGE + i
if page > self.__COUNT_PAGE:
break
if self.__RTURN_JS == "":
pages += "<a class='Pnum' href='" + self.__URI + \
"p=" + bytes(page) + "'>" + bytes(page) + "</a>"
else:
pages += "<a class='Pnum' onclick='" + self.__RTURN_JS + \
"(" + bytes(page) + ")'>" + bytes(page) + "</a>"
return pages
def __GetPrev(self):
# 构造上一页
startStr = ''
if self.__C_PAGE == 1:
startStr = ''
else:
if self.__RTURN_JS == "":
startStr = "<a class='Ppren' href='" + self.__URI + "p=" + \
bytes(self.__C_PAGE - 1) + "'>" + self.__PREV + "</a>"
else:
startStr = "<a class='Ppren' onclick='" + self.__RTURN_JS + \
"(" + bytes(self.__C_PAGE - 1) + ")'>" + self.__PREV + "</a>"
return startStr
def __GetStart(self):
# 构造起始分页
startStr = ''
if self.__C_PAGE == 1:
startStr = ''
else:
if self.__RTURN_JS == "":
startStr = "<a class='Pstart' href='" + \
self.__URI + "p=1'>" + self.__START + "</a>"
else:
startStr = "<a class='Pstart' onclick='" + \
self.__RTURN_JS + "(1)'>" + self.__START + "</a>"
return startStr
def __GetCpage(self, p):
# 取当前页
if p:
return p
return 1
def __StartRow(self):
# 从多少行开始
return (self.__C_PAGE - 1) * self.ROW + 1
def __EndRow(self):
# 从多少行结束
if self.ROW > self.__COUNT_ROW:
return self.__COUNT_ROW
return self.__C_PAGE * self.ROW
def __GetCountPage(self):
# 取总页数
return int(math.ceil(self.__COUNT_ROW / float(self.ROW)))
def __SetUri(self, input):
# 构造URI
uri = '?'
for key in input:
if key == 'p':
continue
uri += key + '=' + input[key] + '&'
return str(uri)

810
class/core/plugins_api.py Executable file
View File

@@ -0,0 +1,810 @@
# coding: utf-8
import psutil
import time
import os
import mw
import re
import json
import sys
reload(sys)
sys.setdefaultencoding('utf8')
import threading
import multiprocessing
from flask import request
class pa_thread(threading.Thread):
def __init__(self, func, args, name=''):
threading.Thread.__init__(self)
self.name = name
self.func = func
self.args = args
self.result = self.func(*self.args)
def getResult(self):
try:
return self.result
except Exception:
return None
class plugins_api:
__tasks = None
__plugin_dir = 'plugins'
__type = 'data/json/type.json'
__index = 'data/json/index.json'
setupPath = None
def __init__(self):
self.setupPath = 'server'
##### ----- start ----- ###
def listApi(self):
sType = request.args.get('type', '0')
sPage = request.args.get('p', '1')
# print sPage
data = self.getPluginList(sType, int(sPage))
return mw.getJson(data)
def fileApi(self):
name = request.args.get('name', '')
if name.strip() == '':
return ''
f = request.args.get('f', '')
if f.strip() == '':
return ''
file = self.__plugin_dir + '/' + name + '/' + f
if not os.path.exists(file):
return ''
c = mw.readFile(file)
return c
def indexListApi(self):
data = self.getIndexList()
return mw.getJson(data)
def indexSortApi(self):
sort = request.form.get('ssort', '')
if sort.strip() == '':
return mw.returnJson(False, '排序数据不能为空!')
data = self.setIndexSort(sort)
if data:
return mw.returnJson(True, '成功!')
return mw.returnJson(False, '失败!')
def installApi(self):
rundir = mw.getRunDir()
name = request.form.get('name', '')
version = request.form.get('version', '')
mmsg = '安装'
if hasattr(request.form, 'upgrade'):
mtype = 'update'
mmsg = 'upgrade'
if name.strip() == '':
return mw.returnJson(False, '缺少插件名称!', ())
if version.strip() == '':
return mw.returnJson(False, '缺少版本信息!', ())
infoJsonPos = self.__plugin_dir + '/' + name + '/' + 'info.json'
# print infoJsonPos
if not os.path.exists(infoJsonPos):
return mw.returnJson(False, '配置文件不存在!', ())
pluginInfo = json.loads(mw.readFile(infoJsonPos))
execstr = "cd " + os.getcwd() + "/plugins/" + \
name + " && /bin/bash " + pluginInfo["shell"] \
+ " install " + version
taskAdd = (None, mmsg + '[' + name + '-' + version + ']',
'execshell', '0', time.strftime('%Y-%m-%d %H:%M:%S'), execstr)
mw.M('tasks').add('id,name,type,status,addtime, execstr', taskAdd)
return mw.returnJson(True, '已将安装任务添加到队列!')
def uninstallOldApi(self):
rundir = mw.getRunDir()
name = request.form.get('name', '')
version = request.form.get('version', '')
if name.strip() == '':
return mw.returnJson(False, "缺少插件名称!", ())
if version.strip() == '':
return mw.returnJson(False, "缺少版本信息!", ())
infoJsonPos = self.__plugin_dir + '/' + name + '/' + 'info.json'
if not os.path.exists(infoJsonPos):
return mw.returnJson(False, "配置文件不存在!", ())
pluginInfo = json.loads(mw.readFile(infoJsonPos))
execstr = "cd " + os.getcwd() + "/plugins/" + \
name + " && /bin/bash " + pluginInfo["shell"] \
+ " uninstall " + version
taskAdd = (None, '卸载[' + name + '-' + version + ']',
'execshell', '0', time.strftime('%Y-%m-%d %H:%M:%S'), execstr)
mw.M('tasks').add('id,name,type,status,addtime, execstr', taskAdd)
return mw.returnJson(True, '已将卸载任务添加到队列!')
# 卸载时间短,不加入任务中...
def uninstallApi(self):
rundir = mw.getRunDir()
name = request.form.get('name', '')
version = request.form.get('version', '')
if name.strip() == '':
return mw.returnJson(False, "缺少插件名称!", ())
if version.strip() == '':
return mw.returnJson(False, "缺少版本信息!", ())
infoJsonPos = self.__plugin_dir + '/' + name + '/' + 'info.json'
if not os.path.exists(infoJsonPos):
return mw.returnJson(False, "配置文件不存在!", ())
pluginInfo = json.loads(mw.readFile(infoJsonPos))
execstr = "cd " + os.getcwd() + "/plugins/" + \
name + " && /bin/bash " + pluginInfo["shell"] \
+ " uninstall " + version
data = mw.execShell(execstr)
if mw.isAppleSystem():
print execstr
print data[0], data[1]
return mw.returnJson(True, '卸载执行成功!')
# if data[1] == '':
# return mw.returnJson(True, '已将卸载成功!')
# else:
# return mw.returnJson(False, '卸载出现错误信息!' + data[1])
def checkApi(self):
name = request.form.get('name', '')
if name.strip() == '':
return mw.returnJson(False, "缺少插件名称!", ())
infoJsonPos = self.__plugin_dir + '/' + name + '/' + 'info.json'
if not os.path.exists(infoJsonPos):
return mw.returnJson(False, "配置文件不存在!", ())
return mw.returnJson(True, "插件存在!", ())
def setIndexApi(self):
name = request.form.get('name', '')
status = request.form.get('status', '0')
version = request.form.get('version', '')
if status == '1':
return self.addIndex(name, version)
return self.removeIndex(name, version)
def settingApi(self):
name = request.args.get('name', '')
html = self.__plugin_dir + '/' + name + '/index.html'
return mw.readFile(html)
def runApi(self):
name = request.form.get('name', '')
func = request.form.get('func', '')
version = request.form.get('version', '')
args = request.form.get('args', '')
script = request.form.get('script', 'index')
data = self.run(name, func, version, args, script)
if data[1] == '':
return mw.returnJson(True, "OK", data[0].strip())
return mw.returnJson(False, data[1].strip())
def callbackApi(self):
name = request.form.get('name', '')
func = request.form.get('func', '')
args = request.form.get('args', '')
script = request.form.get('script', 'index')
data = self.callback(name, func, args, script)
if data[0]:
return mw.returnJson(True, "OK", data[1])
return mw.returnJson(False, data[1])
def updateZipApi(self):
tmp_path = mw.getRootDir() + '/temp'
if not os.path.exists(tmp_path):
os.makedirs(tmp_path)
mw.execShell("rm -rf " + tmp_path + '/*')
tmp_file = tmp_path + '/plugin_tmp.zip'
from werkzeug.utils import secure_filename
from flask import request
f = request.files['plugin_zip']
if f.filename[-4:] != '.zip':
return mw.returnJson(False, '仅支持zip文件!')
f.save(tmp_file)
mw.execShell('cd ' + tmp_path + ' && unzip ' + tmp_file)
os.remove(tmp_file)
p_info = tmp_path + '/info.json'
if not os.path.exists(p_info):
d_path = None
for df in os.walk(tmp_path):
if len(df[2]) < 3:
continue
if not 'info.json' in df[2]:
continue
if not 'install.sh' in df[2]:
continue
if not os.path.exists(df[0] + '/info.json'):
continue
d_path = df[0]
if d_path:
tmp_path = d_path
p_info = tmp_path + '/info.json'
try:
data = json.loads(mw.readFile(p_info))
data['size'] = mw.getPathSize(tmp_path)
if not 'author' in data:
data['author'] = '未知'
if not 'home' in data:
data['home'] = 'https://www.bt.cn/bbs/forum-40-1.html'
plugin_path = mw.getPluginDir() + data['name'] + '/info.json'
data['old_version'] = '0'
data['tmp_path'] = tmp_path
if os.path.exists(plugin_path):
try:
old_info = json.loads(mw.ReadFile(plugin_path))
data['old_version'] = old_info['versions']
except:
pass
except:
mw.execShell("rm -rf " + tmp_path)
return mw.returnJson(False, '在压缩包中没有找到插件信息,请检查插件包!')
protectPlist = ('openresty', 'mysql', 'php', 'csvn', 'gogs', 'pureftp')
if data['name'] in protectPlist:
return mw.returnJson(False, '[' + data['name'] + '],重要插件不可修改!')
return mw.getJson(data)
def inputZipApi(self):
plugin_name = request.form.get('plugin_name', '')
tmp_path = request.form.get('tmp_path', '')
if not os.path.exists(tmp_path):
return mw.returnJson(False, '临时文件不存在,请重新上传!')
plugin_path = mw.getPluginDir() + '/' + plugin_name
if not os.path.exists(plugin_path):
print mw.execShell('mkdir -p ' + plugin_path)
mw.execShell("\cp -rf " + tmp_path + '/* ' + plugin_path + '/')
mw.execShell('chmod -R 755 ' + plugin_path)
p_info = mw.readFile(plugin_path + '/info.json')
if p_info:
mw.writeLog('软件管理', '安装第三方插件[%s]' %
json.loads(p_info)['title'])
return mw.returnJson(True, '安装成功!')
mw.execShell("rm -rf " + plugin_path)
return mw.returnJson(False, '安装失败!')
##### ----- end ----- ###
# 进程是否存在
def processExists(self, pname, exe=None):
try:
if not self.pids:
self.pids = psutil.pids()
for pid in self.pids:
try:
p = psutil.Process(pid)
if p.name() == pname:
if not exe:
return True
else:
if p.exe() == exe:
return True
except:
pass
return False
except:
return True
# 检查是否正在安装
def checkSetupTask(self, sName, sVer, sCoexist):
if not self.__tasks:
self.__tasks = mw.M('tasks').where(
"status!=?", ('1',)).field('status,name').select()
isTask = '1'
for task in self.__tasks:
tmpt = mw.getStrBetween('[', ']', task['name'])
if not tmpt:
continue
tmp1 = tmpt.split('-')
name1 = tmp1[0].lower()
if sCoexist:
if name1 == sName and tmp1[1] == sVer:
isTask = task['status']
else:
if name1 == sName:
isTask = task['status']
return isTask
def checkStatus(self, info):
if not info['setup']:
return False
data = self.run(info['name'], 'status', info['setup_version'])
if data[0] == 'start':
return True
return False
def checkStatusProcess(self, info, i, return_dict):
if not info['setup']:
return_dict[i] = False
return
data = self.run(info['name'], 'status', info['setup_version'])
if data[0] == 'start':
return_dict[i] = True
else:
return_dict[i] = False
def checkStatusThreads(self, info, i):
if not info['setup']:
return False
data = self.run(info['name'], 'status', info['setup_version'])
if data[0] == 'start':
return True
else:
return False
def checkStatusMThreads(self, plugins_info):
try:
threads = []
ntmp_list = range(len(plugins_info))
for i in ntmp_list:
t = pa_thread(self.checkStatusThreads, (plugins_info[i], i))
threads.append(t)
for i in ntmp_list:
threads[i].start()
for i in ntmp_list:
threads[i].join()
for i in ntmp_list:
t = threads[i].getResult()
plugins_info[i]['status'] = t
except Exception as e:
print 'checkStatusMThreads:', str(e)
return plugins_info
def checkStatusMProcess(self, plugins_info):
manager = multiprocessing.Manager()
return_dict = manager.dict()
jobs = []
for i in range(len(plugins_info)):
p = multiprocessing.Process(
target=self.checkStatusProcess, args=(plugins_info[i], i, return_dict))
jobs.append(p)
p.start()
for proc in jobs:
proc.join()
returnData = return_dict.values()
for i in ntmp_list:
plugins_info[i]['status'] = returnData[i]
return plugins_info
def checkDisplayIndex(self, name, version):
if not os.path.exists(self.__index):
mw.writeFile(self.__index, '[]')
indexList = json.loads(mw.readFile(self.__index))
if type(version) == list:
for index in range(len(version)):
vname = name + '-' + version[index]
if vname in indexList:
return True
else:
vname = name + '-' + version
if vname in indexList:
return True
return False
def getVersion(self, path):
version_f = path + '/version.pl'
if os.path.exists(version_f):
return mw.readFile(version_f).strip()
return ''
# 构造本地插件信息
def getPluginInfo(self, info):
checks = ''
path = ''
coexist = False
if info["checks"][0:1] == '/':
checks = info["checks"]
else:
checks = mw.getRootDir() + '/' + info['checks']
if info.has_key('path'):
path = info['path']
if path[0:1] != '/':
path = mw.getRootDir() + '/' + path
if info.has_key('coexist') and info['coexist']:
coexist = True
pInfo = {
"id": 10000,
"pid": info['pid'],
"type": 1000,
"name": info['name'],
"title": info['title'],
"ps": info['ps'],
"dependnet": "",
"mutex": "",
"path": path,
"install_checks": checks,
"uninsatll_checks": checks,
"coexist": coexist,
"versions": info['versions'],
# "updates": info['updates'],
"display": False,
"setup": False,
"setup_version": "",
"status": False,
}
if checks.find('VERSION') > -1:
pInfo['install_checks'] = checks.replace(
'VERSION', info['versions'])
if path.find('VERSION') > -1:
pInfo['path'] = path.replace(
'VERSION', info['versions'])
pInfo['task'] = self.checkSetupTask(
pInfo['name'], info['versions'], coexist)
pInfo['display'] = self.checkDisplayIndex(
info['name'], pInfo['versions'])
pInfo['setup'] = os.path.exists(pInfo['install_checks'])
if coexist and pInfo['setup']:
pInfo['setup_version'] = info['versions']
else:
pInfo['setup_version'] = self.getVersion(pInfo['install_checks'])
# pluginInfo['status'] = self.checkStatus(pluginInfo)
pInfo['status'] = False
return pInfo
def makeCoexist(self, data):
plugins_info = []
for index in range(len(data['versions'])):
tmp = data.copy()
tmp['title'] = tmp['title'] + \
'-' + data['versions'][index]
tmp['versions'] = data['versions'][index]
pg = self.getPluginInfo(tmp)
plugins_info.append(pg)
return plugins_info
def makeList(self, data, sType='0'):
plugins_info = []
if (data['pid'] == sType):
if type(data['versions']) == list and data.has_key('coexist') and data['coexist']:
tmp_data = self.makeCoexist(data)
for index in range(len(tmp_data)):
plugins_info.append(tmp_data[index])
else:
pg = self.getPluginInfo(data)
plugins_info.append(pg)
return plugins_info
if sType == '0':
if type(data['versions']) == list and data.has_key('coexist') and data['coexist']:
tmp_data = self.makeCoexist(data)
for index in range(len(tmp_data)):
plugins_info.append(tmp_data[index])
else:
pg = self.getPluginInfo(data)
plugins_info.append(pg)
# print plugins_info, data
return plugins_info
def getAllList(self, sType='0'):
plugins_info = []
for dirinfo in os.listdir(self.__plugin_dir):
if dirinfo[0:1] == '.':
continue
path = self.__plugin_dir + '/' + dirinfo
if os.path.isdir(path):
json_file = path + '/info.json'
if os.path.exists(json_file):
try:
data = json.loads(mw.readFile(json_file))
tmp_data = self.makeList(data, sType)
for index in range(len(tmp_data)):
plugins_info.append(tmp_data[index])
except Exception, e:
print e
return plugins_info
def getAllListPage(self, sType='0', page=1, pageSize=10):
plugins_info = []
for dirinfo in os.listdir(self.__plugin_dir):
if dirinfo[0:1] == '.':
continue
path = self.__plugin_dir + '/' + dirinfo
if os.path.isdir(path):
json_file = path + '/info.json'
if os.path.exists(json_file):
try:
data = json.loads(mw.readFile(json_file))
tmp_data = self.makeList(data, sType)
for index in range(len(tmp_data)):
plugins_info.append(tmp_data[index])
except Exception, e:
print e
start = (page - 1) * pageSize
end = start + pageSize
_plugins_info = plugins_info[start:end]
_plugins_info = self.checkStatusMThreads(_plugins_info)
return (_plugins_info, len(plugins_info))
def makeListThread(self, data, sType='0'):
plugins_info = []
if (data['pid'] == sType):
if type(data['versions']) == list and data.has_key('coexist') and data['coexist']:
tmp_data = self.makeCoexist(data)
for index in range(len(tmp_data)):
plugins_info.append(tmp_data[index])
else:
pg = self.getPluginInfo(data)
plugins_info.append(pg)
return plugins_info
if sType == '0':
if type(data['versions']) == list and data.has_key('coexist') and data['coexist']:
tmp_data = self.makeCoexist(data)
for index in range(len(tmp_data)):
plugins_info.append(tmp_data[index])
else:
pg = self.getPluginInfo(data)
plugins_info.append(pg)
# print plugins_info, data
return plugins_info
def getAllListThread(self, sType='0'):
plugins_info = []
tmp_list = []
threads = []
for dirinfo in os.listdir(self.__plugin_dir):
if dirinfo[0:1] == '.':
continue
path = self.__plugin_dir + '/' + dirinfo
if os.path.isdir(path):
json_file = path + '/info.json'
if os.path.exists(json_file):
data = json.loads(mw.readFile(json_file))
if sType == '0':
tmp_list.append(data)
if (data['pid'] == sType):
tmp_list.append(data)
ntmp_list = range(len(tmp_list))
for i in ntmp_list:
t = pa_thread(self.makeListThread, (tmp_list[i], sType))
threads.append(t)
for i in ntmp_list:
threads[i].start()
for i in ntmp_list:
threads[i].join()
for i in ntmp_list:
t = threads[i].getResult()
for index in range(len(t)):
plugins_info.append(t[index])
return plugins_info
def makeListProcess(self, data, sType, i, return_dict):
plugins_info = []
if (data['pid'] == sType):
if type(data['versions']) == list and data.has_key('coexist') and data['coexist']:
tmp_data = self.makeCoexist(data)
for index in range(len(tmp_data)):
plugins_info.append(tmp_data[index])
else:
pg = self.getPluginInfo(data)
plugins_info.append(pg)
# return plugins_info
if sType == '0':
if type(data['versions']) == list and data.has_key('coexist') and data['coexist']:
tmp_data = self.makeCoexist(data)
for index in range(len(tmp_data)):
plugins_info.append(tmp_data[index])
else:
pg = self.getPluginInfo(data)
plugins_info.append(pg)
return_dict[i] = plugins_info
# return plugins_info
def getAllListProcess(self, sType='0'):
plugins_info = []
tmp_list = []
manager = multiprocessing.Manager()
return_dict = manager.dict()
jobs = []
for dirinfo in os.listdir(self.__plugin_dir):
if dirinfo[0:1] == '.':
continue
path = self.__plugin_dir + '/' + dirinfo
if os.path.isdir(path):
json_file = path + '/info.json'
if os.path.exists(json_file):
data = json.loads(mw.readFile(json_file))
if sType == '0':
tmp_list.append(data)
if (data['pid'] == sType):
tmp_list.append(data)
ntmp_list = range(len(tmp_list))
for i in ntmp_list:
p = multiprocessing.Process(
target=self.makeListProcess, args=(tmp_list[i], sType, i, return_dict))
jobs.append(p)
p.start()
for proc in jobs:
proc.join()
returnData = return_dict.values()
for i in ntmp_list:
for index in range(len(returnData[i])):
plugins_info.append(returnData[i][index])
return plugins_info
def getPluginList(self, sType, sPage=1, sPageSize=10):
# print sType, sPage, sPageSize
ret = {}
ret['type'] = json.loads(mw.readFile(self.__type))
# plugins_info = self.getAllListThread(sType)
# plugins_info = self.getAllListProcess(sType)
data = self.getAllListPage(sType, sPage, sPageSize)
ret['data'] = data[0]
args = {}
args['count'] = data[1]
args['p'] = sPage
args['tojs'] = 'getSList'
args['row'] = sPageSize
ret['list'] = mw.getPage(args)
return ret
def getIndexList(self):
if not os.path.exists(self.__index):
mw.writeFile(self.__index, '[]')
indexList = json.loads(mw.readFile(self.__index))
plist = []
app = []
for i in indexList:
info = i.split('-')
if not info[0] in app:
app.append(info[0])
path = self.__plugin_dir + '/' + info[0]
if os.path.isdir(path):
json_file = path + '/info.json'
if os.path.exists(json_file):
try:
data = json.loads(mw.readFile(json_file))
tmp_data = self.makeList(data)
for index in range(len(tmp_data)):
if tmp_data[index]['versions'] == info[1] or info[1] in tmp_data[index]['versions']:
tmp_data[index]['display'] = True
plist.append(tmp_data[index])
continue
except Exception, e:
print 'getIndexList:', e
# 使用gevent模式时,无法使用多进程
# plist = self.checkStatusMProcess(plist)
plist = self.checkStatusMThreads(plist)
return plist
def setIndexSort(self, sort):
data = sort.split('|')
mw.writeFile(self.__index, json.dumps(data))
return True
def addIndex(self, name, version):
if not os.path.exists(self.__index):
mw.writeFile(self.__index, '[]')
indexList = json.loads(mw.readFile(self.__index))
vname = name + '-' + version
if vname in indexList:
return mw.returnJson(False, '请不要重复添加!')
if len(indexList) >= 12:
return mw.returnJson(False, '首页最多只能显示12个软件!')
indexList.append(vname)
mw.writeFile(self.__index, json.dumps(indexList))
return mw.returnJson(True, '添加成功!')
def removeIndex(self, name, version):
if not os.path.exists(self.__index):
mw.writeFile(self.__index, '[]')
indexList = json.loads(mw.readFile(self.__index))
vname = name + '-' + version
if not vname in indexList:
return mw.returnJson(True, '删除成功!')
indexList.remove(vname)
mw.writeFile(self.__index, json.dumps(indexList))
return mw.returnJson(True, '删除成功!')
# shell 调用
def run(self, name, func, version, args='', script='index'):
path = mw.getRunDir() + '/' + self.__plugin_dir + \
'/' + name + '/' + script + '.py'
py = 'python ' + path
if args == '':
py_cmd = py + ' ' + func + ' ' + version
else:
py_cmd = py + ' ' + func + ' ' + version + ' ' + args
if not os.path.exists(path):
return ('', '')
data = mw.execShell(py_cmd)
# data = os.popen(py_cmd).read()
if mw.isAppleSystem():
print 'run', py_cmd
# print os.path.exists(py_cmd)
return (data[0].strip(), data[1].strip())
# 映射包调用
def callback(self, name, func, args='', script='index'):
package = mw.getRunDir() + '/plugins/' + name
if not os.path.exists(package):
return (False, "插件不存在!")
sys.path.append(package)
eval_str = "__import__('" + script + "')." + func + '(' + args + ')'
newRet = eval(eval_str)
if mw.isAppleSystem():
print 'callback', eval_str
return (True, newRet)

1868
class/core/site_api.py Executable file

File diff suppressed because it is too large Load Diff

695
class/core/system_api.py Executable file
View File

@@ -0,0 +1,695 @@
# coding: utf-8
import psutil
import time
import os
import re
import math
import json
from flask import Flask, session
from flask import request
import db
import mw
import requests
import config_api
from threading import Thread
from time import sleep
def async(f):
def wrapper(*args, **kwargs):
thr = Thread(target=f, args=args, kwargs=kwargs)
thr.start()
return wrapper
class system_api:
setupPath = None
pids = None
def __init__(self):
self.setupPath = mw.getServerDir()
##### ----- start ----- ###
def networkApi(self):
data = self.getNetWork()
return mw.getJson(data)
def updateServerApi(self):
stype = request.args.get('type', 'check')
version = request.args.get('version', '')
return self.updateServer(stype, version)
def systemTotalApi(self):
data = self.getSystemTotal()
return mw.getJson(data)
def diskInfoApi(self):
diskInfo = self.getDiskInfo()
return mw.getJson(diskInfo)
def setControlApi(self):
stype = request.form.get('type', '')
day = request.form.get('day', '')
data = self.setControl(stype, day)
return data
def getLoadAverageApi(self):
start = request.args.get('start', '')
end = request.args.get('end', '')
data = self.getLoadAverageData(start, end)
return mw.getJson(data)
def getCpuIoApi(self):
start = request.args.get('start', '')
end = request.args.get('end', '')
data = self.getCpuIoData(start, end)
return mw.getJson(data)
def getDiskIoApi(self):
start = request.args.get('start', '')
end = request.args.get('end', '')
data = self.getDiskIoData(start, end)
return mw.getJson(data)
def getNetworkIoApi(self):
start = request.args.get('start', '')
end = request.args.get('end', '')
data = self.getNetWorkIoData(start, end)
return mw.getJson(data)
def rememoryApi(self):
os.system('sync')
scriptFile = mw.getRunDir() + '/script/rememory.sh'
mw.execShell("/bin/bash " + scriptFile)
data = self.getMemInfo()
return mw.getJson(data)
# 重启面板
def restartApi(self):
self.restartMw()
return mw.returnJson(True, '面板已重启!')
def restartServerApi(self):
if mw.isAppleSystem():
return mw.returnJson(False, "开发环境不可重起")
self.restartServer()
return mw.returnJson(True, '正在重启服务器!')
##### ----- end ----- ###
@async
def restartMw(self):
sleep(0.3)
# cmd = mw.getRunDir() + '/scripts/init.d/mw restart'
# print cmd
mw.execShell('service mw restart')
@async
def restartServer(self):
if not mw.isRestart():
return mw.returnJson(False, '请等待所有安装任务完成再执行!')
mw.execShell("sync && init 6 &")
return mw.returnJson(True, '命令发送成功!')
# 名取PID
def getPid(self, pname):
try:
if not self.pids:
self.pids = psutil.pids()
for pid in self.pids:
if psutil.Process(pid).name() == pname:
return True
return False
except:
return False
# 检查端口是否占用
def isOpen(self, port):
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect(('127.0.0.1', int(port)))
s.shutdown(2)
return True
except:
return False
# 检测指定进程是否存活
def checkProcess(self, pid):
try:
if not self.pids:
self.pids = psutil.pids()
if int(pid) in self.pids:
return True
return False
except:
return False
def getPanelInfo(self, get=None):
# 取面板配置
address = mw.GetLocalIp()
try:
try:
port = web.ctx.host.split(':')[1]
except:
port = mw.readFile('data/port.pl')
except:
port = '8888'
domain = ''
if os.path.exists('data/domain.conf'):
domain = mw.readFile('data/domain.conf')
autoUpdate = ''
if os.path.exists('data/autoUpdate.pl'):
autoUpdate = 'checked'
limitip = ''
if os.path.exists('data/limitip.conf'):
limitip = mw.readFile('data/limitip.conf')
templates = []
for template in os.listdir('templates/'):
if os.path.isdir('templates/' + template):
templates.append(template)
template = mw.readFile('data/templates.pl')
check502 = ''
if os.path.exists('data/502Task.pl'):
check502 = 'checked'
return {'port': port, 'address': address, 'domain': domain, 'auto': autoUpdate, '502': check502, 'limitip': limitip, 'templates': templates, 'template': template}
def getSystemTotal(self, interval=1):
# 取系统统计信息
data = self.getMemInfo()
cpu = self.getCpuInfo(interval)
data['cpuNum'] = cpu[1]
data['cpuRealUsed'] = cpu[0]
data['time'] = self.getBootTime()
data['system'] = self.getSystemVersion()
data['isuser'] = mw.M('users').where(
'username=?', ('admin',)).count()
data['version'] = '0.0.1'
return data
def getLoadAverage(self):
c = os.getloadavg()
data = {}
data['one'] = float(c[0])
data['five'] = float(c[1])
data['fifteen'] = float(c[2])
data['max'] = psutil.cpu_count() * 2
data['limit'] = data['max']
data['safe'] = data['max'] * 0.75
return data
def getAllInfo(self, get):
data = {}
data['load_average'] = self.GetLoadAverage(get)
data['title'] = self.GetTitle()
data['network'] = self.GetNetWorkApi(get)
data['panel_status'] = not os.path.exists(
'/www/server/mdserver-web/data/close.pl')
import firewalls
ssh_info = firewalls.firewalls().GetSshInfo(None)
data['enable_ssh_status'] = ssh_info['status']
data['disable_ping_status'] = not ssh_info['ping']
data['time'] = self.GetBootTime()
# data['system'] = self.GetSystemVersion();
# data['mem'] = self.GetMemInfo();
data['version'] = web.ctx.session.version
return data
def getTitle(self):
titlePl = 'data/title.pl'
title = 'Linux面板'
if os.path.exists(titlePl):
title = mw.readFile(titlePl).strip()
return title
def getSystemVersion(self):
# 取操作系统版本
if mw.getOs() == 'darwin':
data = mw.execShell('sw_vers')[0]
data_list = data.strip().split("\n")
mac_version = ''
for x in data_list:
mac_version += x.split("\t")[1] + ' '
return mac_version
version = mw.readFile('/etc/redhat-release')
if not version:
version = mw.readFile(
'/etc/issue').strip().split("\n")[0].replace('\\n', '').replace('\l', '').strip()
else:
version = version.replace('release ', '').strip()
return version
def getBootTime(self):
# 取系统启动时间
start_time = psutil.boot_time()
run_time = time.time() - start_time
# conf = mw.readFile('/proc/uptime').split()
tStr = float(run_time)
min = tStr / 60
hours = min / 60
days = math.floor(hours / 24)
hours = math.floor(hours - (days * 24))
min = math.floor(min - (days * 60 * 24) - (hours * 60))
return mw.getInfo('已不间断运行: {1}天{2}小时{3}分钟', (str(int(days)), str(int(hours)), str(int(min))))
def getCpuInfo(self, interval=1):
# 取CPU信息
cpuCount = psutil.cpu_count()
used = psutil.cpu_percent(interval=interval)
return used, cpuCount
def getMemInfo(self):
# 取内存信息
mem = psutil.virtual_memory()
if mw.getOs() == 'darwin':
memInfo = {
'memTotal': mem.total / 1024 / 1024
}
memInfo['memRealUsed'] = memInfo['memTotal'] * (mem.percent / 100)
else:
memInfo = {
'memTotal': mem.total / 1024 / 1024,
'memFree': mem.free / 1024 / 1024,
'memBuffers': mem.buffers / 1024 / 1024,
'memCached': mem.cached / 1024 / 1024
}
memInfo['memRealUsed'] = memInfo['memTotal'] - \
memInfo['memFree'] - memInfo['memBuffers'] - \
memInfo['memCached']
return memInfo
def getMemUsed(self):
# 取内存使用率
try:
import psutil
mem = psutil.virtual_memory()
if mw.getOs() == 'darwin':
return mem.percent
memInfo = {'memTotal': mem.total / 1024 / 1024, 'memFree': mem.free / 1024 / 1024,
'memBuffers': mem.buffers / 1024 / 1024, 'memCached': mem.cached / 1024 / 1024}
tmp = memInfo['memTotal'] - memInfo['memFree'] - \
memInfo['memBuffers'] - memInfo['memCached']
tmp1 = memInfo['memTotal'] / 100
return (tmp / tmp1)
except Exception, ex:
return 1
def getDiskInfo(self, get=None):
return self.getDiskInfo2()
# 取磁盘分区信息
diskIo = psutil.disk_partitions()
diskInfo = []
for disk in diskIo:
if disk[1] == '/mnt/cdrom':
continue
if disk[1] == '/boot':
continue
tmp = {}
tmp['path'] = disk[1]
tmp['size'] = psutil.disk_usage(disk[1])
diskInfo.append(tmp)
return diskInfo
def getDiskInfo2(self):
# 取磁盘分区信息
temp = mw.execShell(
"df -h -P|grep '/'|grep -v tmpfs | grep -v devfs")[0]
tempInodes = mw.execShell(
"df -i -P|grep '/'|grep -v tmpfs | grep -v devfs")[0]
temp1 = temp.split('\n')
tempInodes1 = tempInodes.split('\n')
diskInfo = []
n = 0
cuts = ['/mnt/cdrom', '/boot', '/boot/efi', '/dev',
'/dev/shm', '/run/lock', '/run', '/run/shm', '/run/user']
for tmp in temp1:
n += 1
inodes = tempInodes1[n - 1].split()
disk = tmp.split()
if len(disk) < 5:
continue
if disk[1].find('M') != -1:
continue
if disk[1].find('K') != -1:
continue
if len(disk[5].split('/')) > 4:
continue
if disk[5] in cuts:
continue
arr = {}
arr['path'] = disk[5]
tmp1 = [disk[1], disk[2], disk[3], disk[4]]
arr['size'] = tmp1
arr['inodes'] = [inodes[1], inodes[2], inodes[3], inodes[4]]
if disk[5] == '/':
bootLog = os.getcwd() + '/tmp/panelBoot.pl'
if disk[2].find('M') != -1:
if os.path.exists(bootLog):
os.system('rm -f ' + bootLog)
else:
if not os.path.exists(bootLog):
pass
if inodes[2] != '0':
diskInfo.append(arr)
return diskInfo
# 清理系统垃圾
def clearSystem(self, get):
count = total = 0
tmp_total, tmp_count = self.ClearMail()
count += tmp_count
total += tmp_total
tmp_total, tmp_count = self.ClearOther()
count += tmp_count
total += tmp_total
return count, total
# 清理邮件日志
def clearMail(self):
rpath = '/var/spool'
total = count = 0
import shutil
con = ['cron', 'anacron', 'mail']
for d in os.listdir(rpath):
if d in con:
continue
dpath = rpath + '/' + d
time.sleep(0.2)
num = size = 0
for n in os.listdir(dpath):
filename = dpath + '/' + n
fsize = os.path.getsize(filename)
size += fsize
if os.path.isdir(filename):
shutil.rmtree(filename)
else:
os.remove(filename)
print '\t\033[1;32m[OK]\033[0m'
num += 1
total += size
count += num
return total, count
# 清理其它
def clearOther(self):
clearPath = [
{'path': '/www/server/mdserver-web', 'find': 'testDisk_'},
{'path': '/www/wwwlogs', 'find': 'log'},
{'path': '/tmp', 'find': 'panelBoot.pl'},
{'path': '/www/server/mdserver-web/install', 'find': '.rpm'}
]
total = count = 0
for c in clearPath:
for d in os.listdir(c['path']):
if d.find(c['find']) == -1:
continue
filename = c['path'] + '/' + d
fsize = os.path.getsize(filename)
total += fsize
if os.path.isdir(filename):
shutil.rmtree(filename)
else:
os.remove(filename)
count += 1
mw.serviceReload()
os.system('echo > /tmp/panelBoot.pl')
return total, count
def getNetWork(self):
# return self.GetNetWorkApi(get);
# 取网络流量信息
try:
# 取网络流量信息
networkIo = psutil.net_io_counters()[:4]
if not "otime" in session:
session['up'] = networkIo[0]
session['down'] = networkIo[1]
session['otime'] = time.time()
ntime = time.time()
networkInfo = {}
networkInfo['upTotal'] = networkIo[0]
networkInfo['downTotal'] = networkIo[1]
networkInfo['up'] = round(float(
networkIo[0] - session['up']) / 1024 / (ntime - session['otime']), 2)
networkInfo['down'] = round(
float(networkIo[1] - session['down']) / 1024 / (ntime - session['otime']), 2)
networkInfo['downPackets'] = networkIo[3]
networkInfo['upPackets'] = networkIo[2]
# print networkIo[1], session['down'], ntime, session['otime']
session['up'] = networkIo[0]
session['down'] = networkIo[1]
session['otime'] = time.time()
networkInfo['cpu'] = self.getCpuInfo()
networkInfo['load'] = self.getLoadAverage()
networkInfo['mem'] = self.getMemInfo()
return networkInfo
except Exception, e:
print e
return None
def getNetWorkApi(self):
# 取网络流量信息
try:
tmpfile = 'data/network.temp'
networkIo = psutil.net_io_counters()[:4]
if not os.path.exists(tmpfile):
mw.writeFile(tmpfile, str(
networkIo[0]) + '|' + str(networkIo[1]) + '|' + str(int(time.time())))
lastValue = mw.readFile(tmpfile).split('|')
ntime = time.time()
networkInfo = {}
networkInfo['upTotal'] = networkIo[0]
networkInfo['downTotal'] = networkIo[1]
networkInfo['up'] = round(
float(networkIo[0] - int(lastValue[0])) / 1024 / (ntime - int(lastValue[2])), 2)
networkInfo['down'] = round(
float(networkIo[1] - int(lastValue[1])) / 1024 / (ntime - int(lastValue[2])), 2)
networkInfo['downPackets'] = networkIo[3]
networkInfo['upPackets'] = networkIo[2]
mw.writeFile(tmpfile, str(
networkIo[0]) + '|' + str(networkIo[1]) + '|' + str(int(time.time())))
# networkInfo['cpu'] = self.GetCpuInfo(0.1)
return networkInfo
except:
return None
def getNetWorkIoData(self, start, end):
# 取指定时间段的网络Io
data = mw.M('network').dbfile('system').where("addtime>=? AND addtime<=?", (start, end)).field(
'id,up,down,total_up,total_down,down_packets,up_packets,addtime').order('id asc').select()
return self.toAddtime(data)
def getDiskIoData(self, start, end):
# 取指定时间段的磁盘Io
data = mw.M('diskio').dbfile('system').where("addtime>=? AND addtime<=?", (start, end)).field(
'id,read_count,write_count,read_bytes,write_bytes,read_time,write_time,addtime').order('id asc').select()
return self.toAddtime(data)
def getCpuIoData(self, start, end):
# 取指定时间段的CpuIo
data = mw.M('cpuio').dbfile('system').where("addtime>=? AND addtime<=?",
(start, end)).field('id,pro,mem,addtime').order('id asc').select()
return self.toAddtime(data, True)
def getLoadAverageData(self, start, end):
data = mw.M('load_average').dbfile('system').where("addtime>=? AND addtime<=?", (
start, end)).field('id,pro,one,five,fifteen,addtime').order('id asc').select()
return self.toAddtime(data)
# 格式化addtime列
def toAddtime(self, data, tomem=False):
import time
if tomem:
import psutil
mPre = (psutil.virtual_memory().total / 1024 / 1024) / 100
length = len(data)
he = 1
if length > 100:
he = 1
if length > 1000:
he = 3
if length > 10000:
he = 15
if he == 1:
for i in range(length):
data[i]['addtime'] = time.strftime(
'%m/%d %H:%M', time.localtime(float(data[i]['addtime'])))
if tomem and data[i]['mem'] > 100:
data[i]['mem'] = data[i]['mem'] / mPre
return data
else:
count = 0
tmp = []
for value in data:
if count < he:
count += 1
continue
value['addtime'] = time.strftime(
'%m/%d %H:%M', time.localtime(float(value['addtime'])))
if tomem and value['mem'] > 100:
value['mem'] = value['mem'] / mPre
tmp.append(value)
count = 0
return tmp
def setControl(self, stype, day):
filename = 'data/control.conf'
if stype == '0':
mw.execShell("rm -f " + filename)
elif stype == '1':
_day = int(day)
if _day < 1:
return mw.returnJson(False, "设置失败!")
mw.writeFile(filename, day)
elif stype == 'del':
if not mw.isRestart():
return mw.returnJson(False, '请等待所有安装任务完成再执行')
os.remove("data/system.db")
sql = db.Sql().dbfile('system')
csql = mw.readFile('data/sql/system.sql')
csql_list = csql.split(';')
for index in range(len(csql_list)):
sql.execute(csql_list[index], ())
return mw.returnJson(True, "监控服务已关闭")
else:
data = {}
if os.path.exists(filename):
try:
data['day'] = int(mw.readFile(filename))
except:
data['day'] = 30
data['status'] = True
else:
data['day'] = 30
data['status'] = False
return mw.getJson(data)
return mw.returnJson(True, "设置成功!")
def versionDiff(self, old, new):
'''
test 测试
new 有新版本
none 没有新版本
'''
new_list = new.split('.')
if len(new_list) > 3:
return 'test'
old_list = old.split('.')
ret = 'none'
isHasNew = True
if int(new_list[0]) == int(old_list[0]) and int(new_list[1]) == int(old_list[1]) and int(new_list[2]) == int(old_list[2]):
isHasNew = False
if isHasNew:
return 'new'
return ret
def getServerInfo(self):
upAddr = 'https://raw.githubusercontent.com/midoks/mdserver-web/master/version/info.json'
try:
requests.adapters.DEFAULT_RETRIES = 2
r = requests.get(upAddr, verify=False)
version = json.loads(r.content)
return version[0]
except Exception as e:
print 'getServerInfo', e
return {}
def updateServer(self, stype, version=''):
# 更新服务
try:
if not mw.isRestart():
return mw.returnJson(False, '请等待所有安装任务完成再执行!')
if stype == 'check':
version_now = config_api.config_api().getVersion()
version_new_info = self.getServerInfo()
if not 'version' in version_new_info:
return mw.returnJson(False, '服务器数据或网络有问题!')
diff = self.versionDiff(
version_now, version_new_info['version'])
if diff == 'new':
return mw.returnJson(True, '有新版本!', version_new_info['version'])
elif diff == 'test':
return mw.returnJson(True, '有测试版本!', version_new_info['version'])
else:
return mw.returnJson(False, '已经是最新,无需更新!')
if stype == 'info':
version_new_info = self.getServerInfo()
version_now = config_api.config_api().getVersion()
if not 'version' in version_new_info:
return mw.returnJson(False, '服务器数据有问题!')
diff = self.versionDiff(
version_now, version_new_info['version'])
return mw.returnJson(True, '更新信息!', version_new_info)
if stype == 'update':
if version == '':
return mw.returnJson(False, '缺少版本信息!')
v_new_info = self.getServerInfo()
if v_new_info['version'] != version:
return mw.returnJson(False, '更新失败,请重试!')
if not 'path' in v_new_info or v_new_info['path'] == '':
return mw.returnJson(False, '下载地址不存在!')
newUrl = v_new_info['path']
toPath = mw.getRootDir() + '/temp'
if not os.path.exists(toPath):
mw.execShell('mkdir -p ' + toPath)
mw.execShell('wget -O ' + toPath + '/mw.zip ' + newUrl)
mw.execShell('unzip -o ' + toPath + '/mw.zip' + ' -d ./')
mw.execShell('unzip -o mw.zip -d ./')
mw.execShell('rm -f mw.zip')
return mw.returnJson(True, '安装更新成功,需自己重启!')
return mw.returnJson(False, '已经是最新,无需更新!')
except Exception as ex:
print 'updateServer', ex
return mw.returnJson(False, "连接服务器失败!")
# 修复面板
def repPanel(self, get):
vp = ''
if mw.readFile('/www/server/mdserver-web/class/common.py').find('checkSafe') != -1:
vp = '_pro'
mw.ExecShell("wget -O update.sh " + mw.get_url() +
"/install/update" + vp + ".sh && bash update.sh")
if hasattr(web.ctx.session, 'getCloudPlugin'):
del(web.ctx.session['getCloudPlugin'])
return True

86
class/core/task_api.py Executable file
View File

@@ -0,0 +1,86 @@
# coding: utf-8
import psutil
import time
import os
import sys
import mw
import re
import json
import pwd
from flask import request
class task_api:
def __init__(self):
pass
def countApi(self):
c = mw.M('tasks').where("status!=?", ('1',)).count()
return str(c)
def listApi(self):
p = request.form.get('p', '1').encode('utf-8')
limit = request.form.get('limit', '10').strip()
search = request.form.get('search', '').strip()
start = (int(p) - 1) * int(limit)
limit_str = str(start) + ',' + str(limit)
_list = mw.M('tasks').where('', ()).field(
'id,name,type,status,addtime,start,end').limit(limit_str).order('id desc').select()
_ret = {}
_ret['data'] = _list
count = mw.M('tasks').where('', ()).count()
_page = {}
_page['count'] = count
_page['tojs'] = 'remind'
_page['p'] = p
_ret['page'] = mw.getPage(_page)
return mw.getJson(_ret)
def getExecLogApi(self):
file = os.getcwd() + "/tmp/panelExec.log"
v = mw.getLastLine(file, 100)
return v
def getTaskSpeedApi(self):
tempFile = os.getcwd() + '/tmp/panelExec.log'
freshFile = os.getcwd() + '/tmp/panelFresh'
find = mw.M('tasks').where('status=? OR status=?',
('-1', '0')).field('id,type,name,execstr').find()
if not len(find):
return mw.returnJson(False, '当前没有任务队列在执行-2!')
isTask = os.getcwd() + '/tmp/panelTask.pl'
mw.writeFile(isTask, 'True')
echoMsg = {}
echoMsg['name'] = find['name']
echoMsg['execstr'] = find['execstr']
if find['type'] == 'download':
import json
try:
tmp = mw.readFile(tempFile)
if len(tmp) < 10:
return mw.returnJson(False, '当前没有任务队列在执行-3!')
echoMsg['msg'] = json.loads(tmp)
echoMsg['isDownload'] = True
except:
mw.M('tasks').where(
"id=?", (find['id'],)).save('status', ('0',))
return mw.returnJson(False, '当前没有任务队列在执行-4!')
else:
echoMsg['msg'] = mw.getLastLine(tempFile, 10)
echoMsg['isDownload'] = False
echoMsg['task'] = mw.M('tasks').where("status!=?", ('1',)).field(
'id,status,name,type').order("id asc").select()
return mw.getJson(echoMsg)

132
class/core/vilidate.py Executable file
View File

@@ -0,0 +1,132 @@
#!/usr/bin/env python
# coding: utf-8
import random
import math
from PIL import Image, ImageDraw, ImageFont, ImageFilter
class vieCode:
__fontSize = 20 # 字体大小
__width = 120 # 画布宽度
__heigth = 45 # 画布高度
__length = 4 # 验证码长度
__draw = None # 画布
__img = None # 图片资源
__code = None # 验证码字符
__str = None # 自定义验证码字符集
__inCurve = True # 是否画干扰线
__inNoise = True # 是否画干扰点
__type = 2 # 验证码类型 1、纯字母 2、数字字母混合
__fontPatn = 'class/fonts/2.ttf' # 字体
def GetCodeImage(self, size=80, length=4):
'''获取验证码图片
@param int size 验证码大小
@param int length 验证码长度
'''
# 准备基础数据
self.__length = length
self.__fontSize = size
self.__width = self.__fontSize * self.__length
self.__heigth = int(self.__fontSize * 1.5)
# 生成验证码图片
self.__createCode()
self.__createImage()
self.__createNoise()
self.__printString()
self.__cerateFilter()
return self.__img, self.__code
def __cerateFilter(self):
'''模糊处理'''
self.__img = self.__img.filter(ImageFilter.BLUR)
filter = ImageFilter.ModeFilter(8)
self.__img = self.__img.filter(filter)
def __createCode(self):
'''创建验证码字符'''
# 是否自定义字符集合
if not self.__str:
# 源文本
number = "3456789"
srcLetter = "qwertyuipasdfghjkzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM"
srcUpper = srcLetter.upper()
if self.__type == 1:
self.__str = number
else:
self.__str = srcLetter + srcUpper + number
# 构造验证码
self.__code = random.sample(self.__str, self.__length)
def __createImage(self):
'''创建画布'''
bgColor = (random.randint(200, 255), random.randint(
200, 255), random.randint(200, 255))
self.__img = Image.new('RGB', (self.__width, self.__heigth), bgColor)
self.__draw = ImageDraw.Draw(self.__img)
def __createNoise(self):
'''画干扰点'''
if not self.__inNoise:
return
font = ImageFont.truetype(self.__fontPatn, int(self.__fontSize / 1.5))
for i in xrange(5):
# 杂点颜色
noiseColor = (random.randint(150, 200), random.randint(
150, 200), random.randint(150, 200))
putStr = random.sample(self.__str, 2)
for j in range(2):
# 绘杂点
size = (random.randint(-10, self.__width),
random.randint(-10, self.__heigth))
self.__draw.text(size, putStr[j], font=font, fill=noiseColor)
pass
def __createCurve(self):
'''画干扰线'''
if not self.__inCurve:
return
x = y = 0
# 计算曲线系数
a = random.uniform(1, self.__heigth / 2)
b = random.uniform(-self.__width / 4, self.__heigth / 4)
f = random.uniform(-self.__heigth / 4, self.__heigth / 4)
t = random.uniform(self.__heigth, self.__width * 2)
xend = random.randint(self.__width / 2, self.__width * 2)
w = (2 * math.pi) / t
# 画曲线
color = (random.randint(30, 150), random.randint(
30, 150), random.randint(30, 150))
for x in xrange(xend):
if w != 0:
for k in xrange(int(self.__heigth / 10)):
y = a * math.sin(w * x + f) + b + self.__heigth / 2
i = int(self.__fontSize / 5)
while i > 0:
px = x + i
py = y + i + k
self.__draw.point((px, py), color)
i -= i
def __printString(self):
'''打印验证码字符串'''
font = ImageFont.truetype(self.__fontPatn, self.__fontSize)
x = 0
# 打印字符到画板
for i in xrange(self.__length):
# 设置字体随机颜色
color = (random.randint(30, 150), random.randint(
30, 150), random.randint(30, 150))
# 计算座标
x = random.uniform(self.__fontSize * i * 0.95,
self.__fontSize * i * 1.1)
y = self.__fontSize * random.uniform(0.3, 0.5)
# 打印字符
self.__draw.text((x, y), self.__code[i], font=font, fill=color)

BIN
class/fonts/2.ttf Executable file

Binary file not shown.

0
static/css/index.html → class/os/README.md Executable file → Normal file
View File

0
static/img/index.html → class/os/win32/README.md Executable file → Normal file
View File

0
static/js/index.html → class/plugin/README.md Executable file → Normal file
View File

View File

@@ -1,841 +0,0 @@
# coding: utf-8
import os
import sys
import time
import string
def M(table):
import db
sql = db.Sql()
return sql.table(table)
def md5(str):
# 生成MD5
try:
import hashlib
m = hashlib.md5()
m.update(str)
return m.hexdigest()
except:
return False
# 文件的MD5值
def GetFileMd5(filename):
if not os.path.isfile(filename):
return False
import hashlib
myhash = hashlib.md5()
f = file(filename, 'rb')
while True:
b = f.read(8096)
if not b:
break
myhash.update(b)
f.close()
return myhash.hexdigest()
# 取随机字符串
def GetRandomString(length):
from random import Random
str = ''
chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
chrlen = len(chars) - 1
random = Random()
for i in range(length):
str += chars[random.randint(0, chrlen)]
return str
def checkCode(code, outime=120):
# 校验验证码
import time
import web
try:
if md5(code.lower()) != web.ctx.session.codeStr:
web.ctx.session.login_error = getMsg('CODE_ERR')
return False
if time.time() - web.ctx.session.codeTime > outime:
web.ctx.session.login_error = getMsg('CODE_TIMEOUT')
return False
return True
except:
web.ctx.session.login_error = getMsg('CODE_NOT_EXISTS')
return False
def returnJson(status, msg, args=()):
# 取通用Json返回
return getJson(returnMsg(status, msg, args))
def returnMsg(status, msg, args=()):
import json
# 取通用字曲返回
logMessage = json.loads(
readFile('static/language/' + get_language() + '/public.json'))
keys = logMessage.keys()
if msg in keys:
msg = logMessage[msg]
for i in range(len(args)):
rep = '{' + str(i + 1) + '}'
msg = msg.replace(rep, args[i])
return {'status': status, 'msg': msg}
# 取提示消息
def getMsg(key, args=()):
try:
import json
logMessage = json.loads(
readFile('static/language/' + get_language() + '/public.json'))
keys = logMessage.keys()
msg = None
if key in keys:
msg = logMessage[key]
for i in range(len(args)):
rep = '{' + str(i + 1) + '}'
msg = msg.replace(rep, args[i])
return msg
except:
return key
# 取提示消息
def getLan(key):
import json
logMessage = json.loads(
readFile('static/language/' + get_language() + '/template.json'))
keys = logMessage.keys()
msg = None
if key in keys:
msg = logMessage[key]
return msg
def getJson(data):
import json
import web
web.header('Content-Type', 'application/json; charset=utf-8')
return json.dumps(data)
def readFile(filename):
# 读文件内容
try:
fp = open(filename, 'r')
fBody = fp.read()
fp.close()
return fBody
except:
return False
def getDate():
# 取格式时间
import time
return time.strftime('%Y-%m-%d %X', time.localtime())
def get_language():
path = 'data/language.pl'
if not os.path.exists(path):
return 'Simplified_Chinese'
return readFile(path).strip()
def WriteLog(type, logMsg, args=()):
# 写日志
try:
import time
import db
import json
logMessage = json.loads(
readFile('static/language/' + get_language() + '/log.json'))
keys = logMessage.keys()
if logMsg in keys:
logMsg = logMessage[logMsg]
for i in range(len(args)):
rep = '{' + str(i + 1) + '}'
logMsg = logMsg.replace(rep, args[i])
if type in keys:
type = logMessage[type]
sql = db.Sql()
mDate = time.strftime('%Y-%m-%d %X', time.localtime())
data = (type, logMsg, mDate)
result = sql.table('logs').add('type,log,addtime', data)
except:
pass
def writeFile(filename, str):
# 写文件内容
try:
fp = open(filename, 'w+')
fp.write(str)
fp.close()
return True
except:
return False
def httpGet(url, timeout=30):
# 发送GET请求
try:
import urllib2
import ssl
try:
ssl._create_default_https_context = ssl._create_unverified_context
except:
pass
response = urllib2.urlopen(url, timeout=timeout)
return response.read()
except Exception, ex:
#WriteLog('网络诊断',str(ex) + '['+url+']');
return str(ex)
def httpPost(url, data, timeout=30):
# 发送POST请求
try:
import urllib
import urllib2
import ssl
try:
ssl._create_default_https_context = ssl._create_unverified_context
except:
pass
data = urllib.urlencode(data)
req = urllib2.Request(url, data)
response = urllib2.urlopen(req, timeout=timeout)
return response.read()
except Exception, ex:
#WriteLog('网络诊断',str(ex) + '['+url+']');
return str(ex)
# 写进度
def writeSpeed(title, used, total, speed=0):
import json
if not title:
data = {'title': None, 'progress': 0,
'total': 0, 'used': 0, 'speed': 0}
else:
progress = int((100.0 * used / total))
data = {'title': title, 'progress': progress,
'total': total, 'used': used, 'speed': speed}
writeFile('/tmp/panelSpeed.pl', json.dumps(data))
return True
# 取进度
def getSpeed():
import json
data = readFile('/tmp/panelSpeed.pl')
if not data:
data = json.dumps({'title': None, 'progress': 0,
'total': 0, 'used': 0, 'speed': 0})
writeFile('/tmp/panelSpeed.pl', data)
return json.loads(data)
def ExecShell(cmdstring, cwd=None, timeout=None, shell=True):
import shlex
import datetime
import subprocess
import time
if shell:
cmdstring_list = cmdstring
else:
cmdstring_list = shlex.split(cmdstring)
if timeout:
end_time = datetime.datetime.now() + datetime.timedelta(seconds=timeout)
sub = subprocess.Popen(cmdstring_list, cwd=cwd, stdin=subprocess.PIPE,
shell=shell, bufsize=4096, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
while sub.poll() is None:
time.sleep(0.1)
if timeout:
if end_time <= datetime.datetime.now():
raise Exception("Timeout:%s" % cmdstring)
return sub.communicate()
def serviceReload():
# 重载Web服务配置
if os.path.exists('/www/server/nginx/sbin/nginx'):
result = ExecShell('/etc/init.d/nginx reload')
if result[1].find('nginx.pid') != -1:
ExecShell('pkill -9 nginx && sleep 1')
ExecShell('/etc/init.d/nginx start')
else:
result = ExecShell('/etc/init.d/httpd reload')
return result
def phpReload(version):
# 重载PHP配置
import os
if os.path.exists('/www/server/php/' + version + '/libphp5.so'):
ExecShell('/etc/init.d/httpd reload')
else:
ExecShell('/etc/init.d/php-fpm-' + version + ' reload')
def downloadFile(url, filename):
import urllib
urllib.urlretrieve(url, filename=filename, reporthook=downloadHook)
def downloadHook(count, blockSize, totalSize):
speed = {'total': totalSize, 'block': blockSize, 'count': count}
print speed
print '%02d%%' % (100.0 * count * blockSize / totalSize)
def GetLocalIp():
# 取本地外网IP
try:
import re
filename = 'data/iplist.txt'
ipaddress = readFile(filename)
if not ipaddress:
import urllib2
url = 'http://pv.sohu.com/cityjson?ie=utf-8'
opener = urllib2.urlopen(url)
str = opener.read()
ipaddress = re.search('\d+.\d+.\d+.\d+', str).group(0)
writeFile(filename, ipaddress)
ipaddress = re.search('\d+.\d+.\d+.\d+', ipaddress).group(0)
return ipaddress
except:
try:
url = web.ctx.session.home + '/Api/getIpAddress'
opener = urllib2.urlopen(url)
return opener.read()
except:
import web
return web.ctx.host.split(':')[0]
# 搜索数据中是否存在
def inArray(arrays, searchStr):
for key in arrays:
if key == searchStr:
return True
return False
# 检查Web服务器配置文件是否有错误
def checkWebConfig():
import web
if get_webserver() == 'nginx':
result = ExecShell(
"ulimit -n 10240 && /www/server/nginx/sbin/nginx -t -c /www/server/nginx/conf/nginx.conf")
searchStr = 'successful'
else:
result = ExecShell(
"ulimit -n 10240 && /www/server/apache/bin/apachectl -t")
searchStr = 'Syntax OK'
if result[1].find(searchStr) == -1:
WriteLog("TYPE_SOFT", 'CONF_CHECK_ERR', (result[1],))
return result[1]
return True
# 检查是否为IPv4地址
def checkIp(ip):
import re
p = re.compile(
'^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$')
if p.match(ip):
return True
else:
return False
# 检查端口是否合法
def checkPort(port):
ports = ['21', '25', '443', '8080', '888', '8888', '8443']
if port in ports:
return False
intport = int(port)
if intport < 1 or intport > 65535:
return False
return True
# 字符串取中间
def getStrBetween(startStr, endStr, srcStr):
start = srcStr.find(startStr)
if start == -1:
return None
end = srcStr.find(endStr)
if end == -1:
return None
return srcStr[start + 1:end]
# 取CPU类型
def getCpuType():
import re
cpuinfo = open('/proc/cpuinfo', 'r').read()
rep = "model\s+name\s+:\s+(.+)"
tmp = re.search(rep, cpuinfo)
cpuType = None
if tmp:
cpuType = tmp.groups()[0]
return cpuType
# 检查是否允许重启
def IsRestart():
num = M('tasks').where('status!=?', ('1',)).count()
if num > 0:
return False
return True
# 加密密码字符
def hasPwd(password):
import crypt
return crypt.crypt(password, password)
# 处理MySQL配置文件
def CheckMyCnf():
import os
confFile = '/etc/my.cnf'
if os.path.exists(confFile):
conf = readFile(confFile)
if len(conf) > 100:
return True
versionFile = '/www/server/mysql/version.pl'
if not os.path.exists(versionFile):
return False
versions = ['5.1', '5.5', '5.6', '5.7', 'AliSQL']
version = readFile(versionFile)
for key in versions:
if key in version:
version = key
break
shellStr = '''
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
CN='125.88.182.172'
HK='download.bt.cn'
HK2='103.224.251.67'
US='174.139.221.74'
sleep 0.5;
CN_PING=`ping -c 1 -w 1 $CN|grep time=|awk '{print $7}'|sed "s/time=//"`
HK_PING=`ping -c 1 -w 1 $HK|grep time=|awk '{print $7}'|sed "s/time=//"`
HK2_PING=`ping -c 1 -w 1 $HK2|grep time=|awk '{print $7}'|sed "s/time=//"`
US_PING=`ping -c 1 -w 1 $US|grep time=|awk '{print $7}'|sed "s/time=//"`
echo "$HK_PING $HK" > ping.pl
echo "$HK2_PING $HK2" >> ping.pl
echo "$US_PING $US" >> ping.pl
echo "$CN_PING $CN" >> ping.pl
nodeAddr=`sort -V ping.pl|sed -n '1p'|awk '{print $2}'`
if [ "$nodeAddr" == "" ];then
nodeAddr=$HK
fi
Download_Url=http://$nodeAddr:5880
MySQL_Opt()
{
MemTotal=`free -m | grep Mem | awk '{print $2}'`
if [[ ${MemTotal} -gt 1024 && ${MemTotal} -lt 2048 ]]; then
sed -i "s#^key_buffer_size.*#key_buffer_size = 32M#" /etc/my.cnf
sed -i "s#^table_open_cache.*#table_open_cache = 128#" /etc/my.cnf
sed -i "s#^sort_buffer_size.*#sort_buffer_size = 768K#" /etc/my.cnf
sed -i "s#^read_buffer_size.*#read_buffer_size = 768K#" /etc/my.cnf
sed -i "s#^myisam_sort_buffer_size.*#myisam_sort_buffer_size = 8M#" /etc/my.cnf
sed -i "s#^thread_cache_size.*#thread_cache_size = 16#" /etc/my.cnf
sed -i "s#^query_cache_size.*#query_cache_size = 16M#" /etc/my.cnf
sed -i "s#^tmp_table_size.*#tmp_table_size = 32M#" /etc/my.cnf
sed -i "s#^innodb_buffer_pool_size.*#innodb_buffer_pool_size = 128M#" /etc/my.cnf
sed -i "s#^innodb_log_file_size.*#innodb_log_file_size = 32M#" /etc/my.cnf
elif [[ ${MemTotal} -ge 2048 && ${MemTotal} -lt 4096 ]]; then
sed -i "s#^key_buffer_size.*#key_buffer_size = 64M#" /etc/my.cnf
sed -i "s#^table_open_cache.*#table_open_cache = 256#" /etc/my.cnf
sed -i "s#^sort_buffer_size.*#sort_buffer_size = 1M#" /etc/my.cnf
sed -i "s#^read_buffer_size.*#read_buffer_size = 1M#" /etc/my.cnf
sed -i "s#^myisam_sort_buffer_size.*#myisam_sort_buffer_size = 16M#" /etc/my.cnf
sed -i "s#^thread_cache_size.*#thread_cache_size = 32#" /etc/my.cnf
sed -i "s#^query_cache_size.*#query_cache_size = 32M#" /etc/my.cnf
sed -i "s#^tmp_table_size.*#tmp_table_size = 64M#" /etc/my.cnf
sed -i "s#^innodb_buffer_pool_size.*#innodb_buffer_pool_size = 256M#" /etc/my.cnf
sed -i "s#^innodb_log_file_size.*#innodb_log_file_size = 64M#" /etc/my.cnf
elif [[ ${MemTotal} -ge 4096 && ${MemTotal} -lt 8192 ]]; then
sed -i "s#^key_buffer_size.*#key_buffer_size = 128M#" /etc/my.cnf
sed -i "s#^table_open_cache.*#table_open_cache = 512#" /etc/my.cnf
sed -i "s#^sort_buffer_size.*#sort_buffer_size = 2M#" /etc/my.cnf
sed -i "s#^read_buffer_size.*#read_buffer_size = 2M#" /etc/my.cnf
sed -i "s#^myisam_sort_buffer_size.*#myisam_sort_buffer_size = 32M#" /etc/my.cnf
sed -i "s#^thread_cache_size.*#thread_cache_size = 64#" /etc/my.cnf
sed -i "s#^query_cache_size.*#query_cache_size = 64M#" /etc/my.cnf
sed -i "s#^tmp_table_size.*#tmp_table_size = 64M#" /etc/my.cnf
sed -i "s#^innodb_buffer_pool_size.*#innodb_buffer_pool_size = 512M#" /etc/my.cnf
sed -i "s#^innodb_log_file_size.*#innodb_log_file_size = 128M#" /etc/my.cnf
elif [[ ${MemTotal} -ge 8192 && ${MemTotal} -lt 16384 ]]; then
sed -i "s#^key_buffer_size.*#key_buffer_size = 256M#" /etc/my.cnf
sed -i "s#^table_open_cache.*#table_open_cache = 1024#" /etc/my.cnf
sed -i "s#^sort_buffer_size.*#sort_buffer_size = 4M#" /etc/my.cnf
sed -i "s#^read_buffer_size.*#read_buffer_size = 4M#" /etc/my.cnf
sed -i "s#^myisam_sort_buffer_size.*#myisam_sort_buffer_size = 64M#" /etc/my.cnf
sed -i "s#^thread_cache_size.*#thread_cache_size = 128#" /etc/my.cnf
sed -i "s#^query_cache_size.*#query_cache_size = 128M#" /etc/my.cnf
sed -i "s#^tmp_table_size.*#tmp_table_size = 128M#" /etc/my.cnf
sed -i "s#^innodb_buffer_pool_size.*#innodb_buffer_pool_size = 1024M#" /etc/my.cnf
sed -i "s#^innodb_log_file_size.*#innodb_log_file_size = 256M#" /etc/my.cnf
elif [[ ${MemTotal} -ge 16384 && ${MemTotal} -lt 32768 ]]; then
sed -i "s#^key_buffer_size.*#key_buffer_size = 512M#" /etc/my.cnf
sed -i "s#^table_open_cache.*#table_open_cache = 2048#" /etc/my.cnf
sed -i "s#^sort_buffer_size.*#sort_buffer_size = 8M#" /etc/my.cnf
sed -i "s#^read_buffer_size.*#read_buffer_size = 8M#" /etc/my.cnf
sed -i "s#^myisam_sort_buffer_size.*#myisam_sort_buffer_size = 128M#" /etc/my.cnf
sed -i "s#^thread_cache_size.*#thread_cache_size = 256#" /etc/my.cnf
sed -i "s#^query_cache_size.*#query_cache_size = 256M#" /etc/my.cnf
sed -i "s#^tmp_table_size.*#tmp_table_size = 256M#" /etc/my.cnf
sed -i "s#^innodb_buffer_pool_size.*#innodb_buffer_pool_size = 2048M#" /etc/my.cnf
sed -i "s#^innodb_log_file_size.*#innodb_log_file_size = 512M#" /etc/my.cnf
elif [[ ${MemTotal} -ge 32768 ]]; then
sed -i "s#^key_buffer_size.*#key_buffer_size = 1024M#" /etc/my.cnf
sed -i "s#^table_open_cache.*#table_open_cache = 4096#" /etc/my.cnf
sed -i "s#^sort_buffer_size.*#sort_buffer_size = 16M#" /etc/my.cnf
sed -i "s#^read_buffer_size.*#read_buffer_size = 16M#" /etc/my.cnf
sed -i "s#^myisam_sort_buffer_size.*#myisam_sort_buffer_size = 256M#" /etc/my.cnf
sed -i "s#^thread_cache_size.*#thread_cache_size = 512#" /etc/my.cnf
sed -i "s#^query_cache_size.*#query_cache_size = 512M#" /etc/my.cnf
sed -i "s#^tmp_table_size.*#tmp_table_size = 512M#" /etc/my.cnf
sed -i "s#^innodb_buffer_pool_size.*#innodb_buffer_pool_size = 4096M#" /etc/my.cnf
sed -i "s#^innodb_log_file_size.*#innodb_log_file_size = 1024M#" /etc/my.cnf
fi
}
wget -O /etc/my.cnf $Download_Url/install/conf/mysql-%s.conf -T 5
MySQL_Opt
''' % (version,)
# 判断是否迁移目录
if os.path.exists('data/datadir.pl'):
newPath = public.readFile('data/datadir.pl')
mycnf = public.readFile('/etc/my.cnf')
mycnf = mycnf.replace('/www/server/data', newPath)
public.writeFile('/etc/my.cnf', mycnf)
os.system(shellStr)
WriteLog('TYPE_SOFE', 'MYSQL_CHECK_ERR')
return True
def get_url(timeout=0.5):
import json
try:
nodeFile = '/www/server/panel/data/node.json'
node_list = json.loads(readFile(nodeFile))
mnode = None
for node in node_list:
node['ping'] = get_timeout(
node['protocol'] + node['address'] + ':' + node['port'] + '/check.txt')
if not node['ping']:
continue
if not mnode:
mnode = node
if node['ping'] < mnode['ping']:
mnode = node
return mnode['protocol'] + mnode['address'] + ':' + mnode['port']
except:
return 'http://download.bt.cn'
def get_timeout(url):
start = time.time()
result = httpGet(url)
if result != 'True':
return False
return int((time.time() - start) * 1000)
# 获取Token
def GetToken():
try:
from json import loads
tokenFile = 'data/token.json'
if not os.path.exists(tokenFile):
return False
token = loads(public.readFile(tokenFile))
return token
except:
return False
# 解密数据
def auth_decode(data):
token = GetToken()
# 是否有生成Token
if not token:
return returnMsg(False, 'REQUEST_ERR')
# 校验access_key是否正确
if token['access_key'] != data['btauth_key']:
return returnMsg(False, 'REQUEST_ERR')
# 解码数据
import binascii
import hashlib
import urllib
import hmac
import json
tdata = binascii.unhexlify(data['data'])
# 校验signature是否正确
signature = binascii.hexlify(
hmac.new(token['secret_key'], tdata, digestmod=hashlib.sha256).digest())
if signature != data['signature']:
return returnMsg(False, 'REQUEST_ERR')
# 返回
return json.loads(urllib.unquote(tdata))
# 数据加密
def auth_encode(data):
token = GetToken()
pdata = {}
# 是否有生成Token
if not token:
return returnMsg(False, 'REQUEST_ERR')
# 生成signature
import binascii
import hashlib
import urllib
import hmac
import json
tdata = urllib.quote(json.dumps(data))
# 公式 hex(hmac_sha256(data))
pdata['signature'] = binascii.hexlify(
hmac.new(token['secret_key'], tdata, digestmod=hashlib.sha256).digest())
# 加密数据
pdata['btauth_key'] = token['access_key']
pdata['data'] = binascii.hexlify(tdata)
pdata['timestamp'] = time.time()
# 返回
return pdata
# 检查Token
def checkToken(get):
tempFile = 'data/tempToken.json'
if not os.path.exists(tempFile):
return False
import json
import time
tempToken = json.loads(readFile(tempFile))
if time.time() > tempToken['timeout']:
return False
if get.token != tempToken['token']:
return False
return True
# 获取Web服务器
def get_webserver():
webserver = 'nginx'
if not os.path.exists('/www/server/nginx/sbin/nginx'):
webserver = 'apache'
return webserver
# 过滤输入
def checkInput(data):
if not data:
return data
if type(data) != str:
return data
checkList = [
{'d': '<', 'r': '<'},
{'d': '>', 'r': '>'},
{'d': '\'', 'r': '‘'},
{'d': '"', 'r': '“'},
{'d': '&', 'r': '&'},
{'d': '#', 'r': '#'},
{'d': '<', 'r': '<'}
]
for v in checkList:
data = data.replace(v['d'], v['r'])
return data
# 取文件指定尾行数
def GetNumLines(path, num, p=1):
try:
import cgi
if not os.path.exists(path):
return ""
start_line = (p - 1) * num
count = start_line + num
fp = open(path)
buf = ""
fp.seek(-1, 2)
if fp.read(1) == "\n":
fp.seek(-1, 2)
data = []
b = True
n = 0
for i in range(count):
while True:
newline_pos = string.rfind(buf, "\n")
pos = fp.tell()
if newline_pos != -1:
if n >= start_line:
line = buf[newline_pos + 1:]
try:
data.insert(0, cgi.escape(line))
except:
pass
buf = buf[:newline_pos]
n += 1
break
else:
if pos == 0:
b = False
break
to_read = min(4096, pos)
fp.seek(-to_read, 1)
buf = fp.read(to_read) + buf
fp.seek(-to_read, 1)
if pos - to_read == 0:
buf = "\n" + buf
if not b:
break
fp.close()
except:
data = []
return "\n".join(data)
# 验证证书
def CheckCert(certPath='ssl/certificate.pem'):
openssl = '/usr/local/openssl/bin/openssl'
if not os.path.exists(openssl):
openssl = 'openssl'
certPem = readFile(certPath)
s = "\n-----BEGIN CERTIFICATE-----"
tmp = certPem.strip().split(s)
for tmp1 in tmp:
if tmp1.find('-----BEGIN CERTIFICATE-----') == -1:
tmp1 = s + tmp1
writeFile(certPath, tmp1)
result = ExecShell(openssl + " x509 -in " +
certPath + " -noout -subject")
if result[1].find('-bash:') != -1:
return True
if len(result[1]) > 2:
return False
if result[0].find('error:') != -1:
return False
return True
# 获取面板地址
def getPanelAddr():
import web
protocol = 'https://' if os.path.exists("data/ssl.pl") else 'http://'
h = web.ctx.host.split(':')
try:
result = protocol + h[0] + ':' + h[1]
except:
result = protocol + h[0] + ':' + readFile('data/port.pl').strip()
return result
# 字节单位转换
def to_size(size):
d = ('b', 'KB', 'MB', 'GB', 'TB')
s = d[0]
for b in d:
if size < 1024:
return str(size) + ' ' + b
size = size / 1024
s = b
return str(size) + ' ' + b
def get_string(t):
if t != -1:
max = 126
m_types = [{'m': 122, 'n': 97}, {'m': 90, 'n': 65}, {'m': 57, 'n': 48}, {
'm': 47, 'n': 32}, {'m': 64, 'n': 58}, {'m': 96, 'n': 91}, {'m': 125, 'n': 123}]
else:
max = 256
t = 0
m_types = [{'m': 255, 'n': 0}]
arr = []
for i in range(max):
if i < m_types[t]['n'] or i > m_types[t]['m']:
continue
arr.append(chr(i))
return arr
def get_string_find(t):
if type(t) != list:
t = [t]
return_str = ''
for s1 in t:
return_str += get_string(int(s1[0]))[int(s1[1:])]
return return_str
def get_string_arr(t):
s_arr = {}
t_arr = []
for s1 in t:
for i in range(6):
if not i in s_arr:
s_arr[i] = get_string(i)
for j in range(len(s_arr[i])):
if s1 == s_arr[i][j]:
t_arr.append(str(i) + str(j))
return t_arr

7
clear.sh Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/usr/local/lib/python2.7/bin
find . -name .DS_Store | xargs rm -rf
find . -type d -name "*.pyc" | xargs rm -rf

41
cli.sh Executable file
View File

@@ -0,0 +1,41 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/usr/local/lib/python2.7/bin
mw_start(){
gunicorn -c setting.py app:app
python task.py &
}
mw_start_debug(){
python task.py &
gunicorn -b :7200 -k gevent -w 1 app:app
# gunicorn -b :7200 -k eventlet -w 1 app:app
# gunicorn -c setting.py app:app
}
mw_stop()
{
PLIST=`ps -ef|grep app:app |grep -v grep|awk '{print $2}'`
for i in $PLIST
do
kill -9 $i
done
ps -ef|grep task.py |grep -v grep|awk '{print $2}'|xargs kill -9
}
case "$1" in
'start') mw_start;;
'stop') mw_stop;;
'restart')
mw_stop
mw_start
;;
'debug')
mw_stop
mw_start_debug
;;
esac

1
data/defaultSite.pl Normal file
View File

@@ -0,0 +1 @@
t.vvv

32
data/json/type.json Executable file
View File

@@ -0,0 +1,32 @@
[
{
"title":"全部",
"type":0,
"ps":""
},
{
"title":"运行环境",
"type":1,
"ps":""
},
{
"title":"数据软件",
"type":2,
"ps":""
},
{
"title":"代码管理",
"type":3,
"ps":""
},
{
"title":"系统工具",
"type":4,
"ps":""
},
{
"title":"其他插件",
"type":5,
"ps":""
}
]

1
data/port.pl Executable file
View File

@@ -0,0 +1 @@
7200

1
data/recycle_bin.pl Executable file
View File

@@ -0,0 +1 @@
True

121
data/sql/default.sql Executable file
View File

@@ -0,0 +1,121 @@
CREATE TABLE IF NOT EXISTS `backup` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`type` INTEGER,
`name` TEXT,
`pid` INTEGER,
`filename` TEXT,
`size` INTEGER,
`addtime` TEXT
);
CREATE TABLE IF NOT EXISTS `binding` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`pid` INTEGER,
`domain` TEXT,
`path` TEXT,
`port` INTEGER,
`addtime` TEXT
);
CREATE TABLE IF NOT EXISTS `crontab` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`name` TEXT,
`type` TEXT,
`where1` TEXT,
`where_hour` INTEGER,
`where_minute` INTEGER,
`echo` TEXT,
`addtime` TEXT,
`status` INTEGER DEFAULT '1',
`save` INTEGER DEFAULT '3',
`backup_to` TEXT DEFAULT 'off',
`sname` TEXT,
`sbody` TEXT,
'stype' TEXT,
`urladdress` TEXT
);
CREATE TABLE IF NOT EXISTS `firewall` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`port` TEXT,
`ps` TEXT,
`addtime` TEXT
);
INSERT INTO `firewall` (`id`, `port`, `ps`, `addtime`) VALUES
(1, '80', '网站默认端口', '0000-00-00 00:00:00'),
(2, '7200', 'WEB面板', '0000-00-00 00:00:00'),
(3, '22', 'SSH远程管理服务', '0000-00-00 00:00:00'),
(4, '888', 'phpMyAdmin默认端口', '0000-00-00 00:00:00'),
(5, '3306', 'MySQL端口', '0000-00-00 00:00:00');
CREATE TABLE IF NOT EXISTS `logs` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`type` TEXT,
`log` TEXT,
`addtime` TEXT
);
CREATE TABLE IF NOT EXISTS `sites` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`name` TEXT,
`path` TEXT,
`status` TEXT,
`index` TEXT,
`type_id` INTEGER,
`ps` TEXT,
`edate` TEXT,
`addtime` TEXT
);
CREATE TABLE IF NOT EXISTS `site_types` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`name` TEXT
);
CREATE TABLE IF NOT EXISTS `domain` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`pid` INTEGER,
`name` TEXT,
`port` INTEGER,
`addtime` TEXT
);
CREATE TABLE IF NOT EXISTS `users` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`username` TEXT,
`password` TEXT,
`login_ip` TEXT,
`login_time` TEXT,
`phone` TEXT,
`email` TEXT
);
INSERT INTO `users` (`id`, `username`, `password`, `login_ip`, `login_time`, `phone`, `email`) VALUES
(1, 'admin', '21232f297a57a5a743894a0e4a801fc3', '192.168.0.10', '2016-12-10 15:12:56', 0, '287962566@qq.com');
CREATE TABLE IF NOT EXISTS `tasks` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`name` TEXT,
`type` TEXT,
`status` TEXT,
`addtime` TEXT,
`start` INTEGER,
`end` INTEGER,
`execstr` TEXT
);
CREATE TABLE IF NOT EXISTS `panel` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`title` TEXT,
`url` TEXT,
`username` TEXT,
`password` TEXT,
`click` INTEGER,
`addtime` INTEGER
);

37
data/sql/system.sql Executable file
View File

@@ -0,0 +1,37 @@
CREATE TABLE IF NOT EXISTS `network` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`up` INTEGER,
`down` INTEGER,
`total_up` INTEGER,
`total_down` INTEGER,
`down_packets` INTEGER,
`up_packets` INTEGER,
`addtime` INTEGER
);
CREATE TABLE IF NOT EXISTS `cpuio` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`pro` INTEGER,
`mem` INTEGER,
`addtime` INTEGER
);
CREATE TABLE IF NOT EXISTS `diskio` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`read_count` INTEGER,
`write_count` INTEGER,
`read_bytes` INTEGER,
`write_bytes` INTEGER,
`read_time` INTEGER,
`write_time` INTEGER,
`addtime` INTEGER
);
CREATE TABLE IF NOT EXISTS `load_average` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`pro` REAL,
`one` REAL,
`five` REAL,
`fifteen` REAL,
`addtime` INTEGER
);

52
data/tpl/nginx.conf Executable file
View File

@@ -0,0 +1,52 @@
server
{
listen {$PORT};
server_name {$SERVER_NAME};
index index.php index.html index.htm default.php default.htm default.html;
root {$ROOT_DIR};
#SSL-START
#error_page 404/404.html;
#SSL-END
#ERROR-PAGE-START
error_page 404 /404.html;
error_page 502 /502.html;
#ERROR-PAGE-END
#PHP-INFO-START
include enable-php-{$PHPVER}.conf;
#PHP-INFO-END
#REWRITE-START
include {$OR_REWRITE}/{$SERVER_NAME}.conf;
#REWRITE-END
#禁止访问的文件或目录
location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md)
{
return 404;
}
#一键申请SSL证书验证目录相关设置
location ~ \.well-known{
allow all;
}
location ~ .*\\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
error_log off;
access_log /dev/null;
}
location ~ .*\\.(js|css)?$
{
expires 12h;
error_log off;
access_log /dev/null;
}
access_log {$LOGPATH}/{$SERVER_NAME}.log main;
error_log {$LOGPATH}/{$SERVER_NAME}.error.log;
}

55
data/tpl/nginx_dirbind.conf Executable file
View File

@@ -0,0 +1,55 @@
#BINDING-{$DIRBIND}-START
server
{
listen {$PORT};
server_name {$DIRBIND};
index index.php index.html index.htm default.php default.htm default.html;
root {$ROOT_DIR};
#SSL-START
#error_page 404/404.html;
#SSL-END
#ERROR-PAGE-START
error_page 404 /404.html;
error_page 502 /502.html;
#ERROR-PAGE-END
#PHP-INFO-START
include enable-php-{$PHPVER}.conf;
#PHP-INFO-END
#REWRITE-START
include {$OR_REWRITE}/{$SERVER_MAIN}.conf;
#REWRITE-END
#禁止访问的文件或目录
location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md)
{
return 404;
}
#一键申请SSL证书验证目录相关设置
location ~ \.well-known{
allow all;
}
location ~ .*\\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
error_log off;
access_log /dev/null;
}
location ~ .*\\.(js|css)?$
{
expires 12h;
error_log off;
access_log /dev/null;
}
access_log {$LOGPATH}/{$SERVER_MAIN}_{$DIRBIND}.log;
error_log {$LOGPATH}/{$SERVER_MAIN}_{$DIRBIND}.error.log;
}
#BINDING-{$DIRBIND}-END

View File

@@ -1,22 +0,0 @@
[
{
"title":"全部",
"type":0,
"ps":""
},
{
"title":"运行环境",
"type":1,
"ps":""
},
{
"title":"系统工具",
"type":2,
"ps":""
},
{
"title":"其他插件",
"type":3,
"ps":""
}
]

View File

@@ -1,13 +0,0 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
LANG=en_US.UTF-8
is64bit=`getconf LONG_BIT`
startTime=`date +%s`
echo "hello"
endTime=`date +%s`
((outTime=($endTime-$startTime)/60))
echo -e "Time consumed:\033[32m $outTime \033[0mMinute!"

102
plugins/aria2/conf/aria2.conf Executable file
View File

@@ -0,0 +1,102 @@
## 文件保存相关 ##
# 文件的保存路径(可使用绝对路径或相对路径), 默认: 当前启动位置
dir=/tmp/aria2
# 设置日志等级
log-level=error
# 日志保存路径
log={$SERVER_PATH}/aria2.log
# 启用磁盘缓存, 0为禁用缓存, 需1.16以上版本, 默认:16M
disk-cache=32M
# 文件预分配方式, 能有效降低磁盘碎片, 默认:prealloc
# 预分配所需时间: none < falloc ? trunc < prealloc
# falloc和trunc则需要文件系统和内核支持
# NTFS建议使用falloc, EXT3/4建议trunc, MAC 下需要注释此项
#file-allocation=none
# 断点续传
continue=true
## 下载连接相关 ##
# 最大同时下载任务数, 运行时可修改, 默认:5
max-concurrent-downloads=5
# 同一服务器连接数, 添加时可指定, 默认:1
max-connection-per-server=10
# 最小文件分片大小, 添加时可指定, 取值范围1M -1024M, 默认:20M
# 假定size=10M, 文件为20MiB 则使用两个来源下载; 文件为15MiB 则使用一个来源下载
min-split-size=10M
# 单个任务最大线程数, 添加时可指定, 默认:5
split=128
# 整体下载速度限制, 运行时可修改, 默认:0
#max-overall-download-limit=0
# 单个任务下载速度限制, 默认:0
#max-download-limit=0
# 整体上传速度限制, 运行时可修改, 默认:0
#max-overall-upload-limit=0
# 单个任务上传速度限制, 默认:0
#max-upload-limit=0
# 禁用IPv6, 默认:false
disable-ipv6=true
## 进度保存相关 ##
# 从会话文件中读取下载任务
input-file={$SERVER_PATH}/aria2.session
# 在Aria2退出时保存`错误/未完成`的下载任务到会话文件
save-session={$SERVER_PATH}/aria2.session
# 定时保存会话, 0为退出时才保存, 需1.16.1以上版本, 默认:0
#save-session-interval=60
## RPC相关设置 ##
# 启用RPC, 默认:false
enable-rpc=true
# 允许所有来源, 默认:false
rpc-allow-origin-all=true
# 允许非外部访问, 默认:false
rpc-listen-all=true
# 事件轮询方式, 取值:[epoll, kqueue, port, poll, select], 不同系统默认值不同
#event-poll=select
# RPC监听端口, 端口被占用时可以修改, 默认:6800
rpc-listen-port=6800
# 设置的RPC授权令牌, v1.18.4新增功能, 取代 --rpc-user 和 --rpc-passwd 选项
#rpc-secret=sark
# 设置的RPC访问用户名, 此选项新版已废弃, 建议改用 --rpc-secret 选项
#rpc-user=<USER>
# 设置的RPC访问密码, 此选项新版已废弃, 建议改用 --rpc-secret 选项
#rpc-passwd=<PASSWD>
## BT/PT下载相关 ##
# 当下载的是一个种子(以.torrent结尾)时, 自动开始BT任务, 默认:true
#follow-torrent=true
# BT监听端口, 当端口被屏蔽时使用, 默认:6881-6999
listen-port=51413
# 单个种子最大连接数, 默认:55
#bt-max-peers=55
# 打开DHT功能, PT需要禁用, 默认:true
enable-dht=false
# 打开IPv6 DHT功能, PT需要禁用
#enable-dht6=false
# DHT网络监听端口, 默认:6881-6999
#dht-listen-port=6881-6999
# 本地节点查找, PT需要禁用, 默认:false
#bt-enable-lpd=false
# 种子交换, PT需要禁用, 默认:true
enable-peer-exchange=false
# 每个种子限速, 对少种的PT很有用, 默认:50K
#bt-request-peer-speed-limit=50K
# 客户端伪装, PT需要
peer-id-prefix=-TR2770-
user-agent=Transmission/2.77
# 当种子的分享率达到这个数时, 自动停止做种, 0为一直做种, 默认:1.0
seed-ratio=0
# 强制保存会话, 即使任务已经完成, 默认:false
# 较新的版本开启后会在任务完成后依然保留.aria2文件
#force-save=false
# BT校验相关, 默认:true
#bt-hash-check-seed=true
# 继续之前的BT任务时, 无需再次校验, 默认:false
bt-seed-unverified=true
# 保存磁力链接元数据为种子文件(.torrent文件), 默认:false
bt-save-metadata=true

BIN
plugins/aria2/ico.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

19
plugins/aria2/index.html Executable file
View File

@@ -0,0 +1,19 @@
<div class="bt-form">
<div class="bt-w-main">
<div class="bt-w-menu">
<p class="bgw" onclick="pluginService('aria2');">服务</p>
<p onclick="pluginInitD('aria2');">自启动</p>
<p onclick="pluginConfig('aria2');">配置修改</p>
<p onclick="pluginLogs('aria2','','run_log');">运行日志</p>
<p onclick="readme();">说明</p>
</div>
<div class="bt-w-con pd15">
<div class="soft-man-con"></div>
</div>
</div>
</div>
<script type="text/javascript">
$.getScript( "/plugins/file?name=aria2&f=js/aria2.js", function(){
pluginService('aria2');
});
</script>

211
plugins/aria2/index.py Executable file
View File

@@ -0,0 +1,211 @@
# coding:utf-8
import sys
import io
import os
import time
import shutil
sys.path.append(os.getcwd() + "/class/core")
import mw
app_debug = False
if mw.isAppleSystem():
app_debug = True
def getPluginName():
return 'aria2'
def getPluginDir():
return mw.getPluginDir() + '/' + getPluginName()
def getServerDir():
return mw.getServerDir() + '/' + getPluginName()
def getInitDTpl():
path = getPluginDir() + "/init.d/aria2.tpl"
return path
def getArgs():
args = sys.argv[2:]
tmp = {}
args_len = len(args)
if args_len == 1:
t = args[0].strip('{').strip('}')
t = t.split(':')
tmp[t[0]] = t[1]
elif args_len > 1:
for i in range(len(args)):
t = args[i].split(':')
tmp[t[0]] = t[1]
return tmp
def initDreplace():
file_tpl = getInitDTpl()
service_path = os.path.dirname(os.getcwd())
initD_path = getServerDir() + '/init.d'
file_bin = initD_path + '/' + getPluginName()
if not os.path.exists(initD_path):
os.mkdir(initD_path)
# initd replace
content = mw.readFile(file_tpl)
content = content.replace('{$SERVER_PATH}', service_path)
mw.writeFile(file_bin, content)
mw.execShell('chmod +x ' + file_bin)
aria2_path = getServerDir() + '/aria2'
mw.execShell('mkdir -p /tmp/download')
if not os.path.exists(aria2_path):
mw.execShell('mkdir -p ' + aria2_path)
mw.execShell('touch ' + aria2_path + '/aria2.session')
path = getPluginDir() + "/conf/aria2.conf"
content = mw.readFile(path)
content = content.replace('{$SERVER_PATH}', aria2_path)
mw.writeFile(aria2_path + '/aria2.conf', content)
return file_bin
def checkArgs(data, ck=[]):
for i in range(len(ck)):
if not ck[i] in data:
return (False, mw.returnJson(False, '参数:(' + ck[i] + ')没有!'))
return (True, mw.returnJson(True, 'ok'))
def status():
cmd = "ps -ef|grep aria2 |grep -v grep | grep -v 'mdserver-web'| awk '{print $2}'"
data = mw.execShell(cmd)
if data[0] == '':
return 'stop'
return 'start'
def start():
file = initDreplace()
data = mw.execShell(file + ' start')
if data[1] == '':
return 'ok'
return data[1]
def stop():
file = initDreplace()
data = mw.execShell(file + ' stop')
# print data
if data[1] == '':
return 'ok'
return data[1]
def restart():
file = initDreplace()
data = mw.execShell(file + ' reload')
if data[1] == '':
return 'ok'
return data[1]
def reload():
file = initDreplace()
data = mw.execShell(file + ' reload')
if data[1] == '':
return 'ok'
return data[1]
def getPathFile():
if mw.isAppleSystem():
user = mw.execShell(
"who | sed -n '2, 1p' |awk '{print $1}'")[0].strip()
return '/Users/' + user + '/.aria2/aria2.conf'
return getServerDir() + '/aria2/aria2.conf'
def getInitDFile():
if app_debug:
return '/tmp/' + getPluginName()
return '/etc/init.d/' + getPluginName()
def initdStatus():
if not app_debug:
if mw.isAppleSystem():
return "Apple Computer does not support"
initd_bin = getInitDFile()
if os.path.exists(initd_bin):
return 'ok'
return 'fail'
def initdInstall():
source_bin = initDreplace()
initd_bin = getInitDFile()
shutil.copyfile(source_bin, initd_bin)
mw.execShell('chmod +x ' + initd_bin)
if not app_debug:
mw.execShell('chkconfig --add ' + getPluginName())
return 'ok'
def initdUinstall():
if not app_debug:
mw.execShell('chkconfig --del ' + getPluginName())
initd_bin = getInitDFile()
if os.path.exists(initd_bin):
os.remove(initd_bin)
return 'ok'
def getLog():
if mw.isAppleSystem():
user = mw.execShell(
"who | sed -n '2, 1p' |awk '{print $1}'")[0].strip()
return '/Users/' + user + '/.aria2/aria2.log'
return getServerDir() + '/aria2/aria2.log'
if __name__ == "__main__":
func = sys.argv[1]
if func == 'status':
print status()
elif func == 'start':
print start()
elif func == 'stop':
print stop()
elif func == 'restart':
print restart()
elif func == 'reload':
print reload()
elif func == 'conf':
print getPathFile()
elif func == 'initd_status':
print initdStatus()
elif func == 'initd_install':
print initdInstall()
elif func == 'initd_uninstall':
print initdUinstall()
elif func == 'run_log':
print getLog()
else:
print 'error'

15
plugins/aria2/info.json Executable file
View File

@@ -0,0 +1,15 @@
{
"title":"aria2",
"tip":"soft",
"name":"aria2",
"type":"其他插件",
"ps":"一款下载神器",
"versions":"1.0",
"shell":"install.sh",
"checks":"server/aria2",
"path": "server/aria2",
"author":"midoks",
"home":"https://github.com/aria2/aria2",
"date":"2020-06-08",
"pid": "5"
}

49
plugins/aria2/init.d/aria2.tpl Executable file
View File

@@ -0,0 +1,49 @@
#!/bin/sh
# chkconfig: 2345 55 25
# description: aria2 Service
### BEGIN INIT INFO
# Provides: aria2
# Required-Start: $all
# Required-Stop: $all
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: starts aria2
# Description: starts the MDW-Web
### END INIT INFO
app_start(){
# aria2c -D
aria2c --daemon --enable-rpc --rpc-listen-all -c -D --conf-path={$SERVER_PATH}/aria2/aria2/aria2.conf
echo "aria2 started"
}
app_stop(){
echo "Stopping ..."
arr=`ps -ef | grep "aria2" | grep -v 'grep' | grep -v '/bin/sh'|grep -v 'index.py' | awk '{print $2}'`
echo $arr
for p in ${arr[@]}
do
kill -9 $p &>/dev/null
done
echo "aria2 stopped"
}
case "$1" in
start)
app_start
;;
stop)
app_stop
;;
restart|reload)
app_stop
sleep 0.3
app_start
;;
*)
echo "Please use start or stop as first argument"
;;
esac

49
plugins/aria2/install.sh Executable file
View File

@@ -0,0 +1,49 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
SYSOS=`uname`
Install_aria2()
{
isStart=""
echo '正在安装脚本文件...' > $install_tmp
mkdir -p $serverPath/aria2
echo '1.0' > $serverPath/aria2/version.pl
if [ "Darwin" == "$SYSOS" ];then
echo 'macosx unavailable' > $install_tmp
find_sh=`which aria2c`
if [ "$?" != "0" ];then
brew install aria2
fi
else
find_sh=`which aria2c`
if [ "$?" != "0" ];then
yum install aria2 -y
fi
fi
echo 'Install complete' > $install_tmp
}
Uninstall_aria2()
{
rm -rf $serverPath/aria2
echo "Uninstall completed" > $install_tmp
}
action=$1
if [ "${1}" == 'install' ];then
Install_aria2
else
Uninstall_aria2
fi

92
plugins/aria2/js/aria2.js Executable file
View File

@@ -0,0 +1,92 @@
function str2Obj(str){
var data = {};
kv = str.split('&');
for(i in kv){
v = kv[i].split('=');
data[v[0]] = v[1];
}
return data;
}
function lpPost(method,args,callback, title){
var _args = null;
if (typeof(args) == 'string'){
_args = JSON.stringify(str2Obj(args));
} else {
_args = JSON.stringify(args);
}
var _title = '正在获取...';
if (typeof(title) != 'undefined'){
_title = title;
}
var loadT = layer.msg(_title, { icon: 16, time: 0, shade: 0.3 });
$.post('/plugins/run', {name:'aria2', func:method, args:_args}, function(data) {
layer.close(loadT);
if (!data.status){
layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
if(typeof(callback) == 'function'){
callback(data);
}
},'json');
}
function lpAsyncPost(method,args){
var _args = null;
if (typeof(args) == 'string'){
_args = JSON.stringify(str2Obj(args));
} else {
_args = JSON.stringify(args);
}
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
return syncPost('/plugins/run', {name:'l2tp', func:method, args:_args});
}
function userList(){
lpPost('user_list', '' ,function(data){
var rdata = $.parseJSON(data['data']);
if (!rdata['status']){
layer.msg(rdata.msg,{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
var list = rdata['data'];
var con = '';
con += '<div class="divtable" style="margin-top:5px;"><table class="table table-hover" width="100%" cellspacing="0" cellpadding="0" border="0">';
con += '<thead><tr>';
con += '<th>用户</th>';
con += '<th>密码</th>';
con += '<th>操作(<a class="btlink" onclick="addUser()">添加</a>)</th>';
con += '</tr></thead>';
con += '<tbody>';
for (var i = 0; i < list.length; i++) {
con += '<tr>'+
'<td>' + list[i]['user']+'</td>' +
'<td>' + list[i]['pwd']+'</td>' +
'<td><a class="btlink" onclick="modUser(\''+list[i]['user']+'\')">改密</a>|<a class="btlink" onclick="delUser(\''+list[i]['user']+'\')">删除</a></td></tr>';
}
con += '</tbody>';
con += '</table></div>';
$(".soft-man-con").html(con);
});
}
function readme(){
var readme = '<ul class="help-info-text c7">';
readme += '<li>使用时,查看对应的端口</li>';
readme += '</ul>';
$('.soft-man-con').html(readme);
}

BIN
plugins/bbr/ico.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 498 B

17
plugins/bbr/index.html Executable file
View File

@@ -0,0 +1,17 @@
<div class="bt-form">
<div class="bt-w-main">
<div class="bt-w-menu">
<p class="bgw" onclick="pluginService('bbr');">服务</p>
<p onclick="readme();">说明</p>
</div>
<div class="bt-w-con pd15">
<div class="soft-man-con"></div>
</div>
</div>
</div>
<script type="text/javascript">
$.getScript( "/plugins/file?name=bbr&f=js/bbr.js", function() {
pluginService('bbr');
});
</script>

109
plugins/bbr/index.py Executable file
View File

@@ -0,0 +1,109 @@
# coding: utf-8
import time
import random
import os
import json
import re
import sys
sys.path.append(os.getcwd() + "/class/core")
import mw
app_debug = False
if mw.isAppleSystem():
app_debug = True
def getPluginName():
return 'bbr'
def getPluginDir():
return mw.getPluginDir() + '/' + getPluginName()
def getServerDir():
return mw.getServerDir() + '/' + getPluginName()
def getInitDFile():
if app_debug:
return '/tmp/' + getPluginName()
return '/etc/init.d/' + getPluginName()
def getArgs():
args = sys.argv[2:]
tmp = {}
args_len = len(args)
if args_len == 1:
t = args[0].strip('{').strip('}')
t = t.split(':')
tmp[t[0]] = t[1]
elif args_len > 1:
for i in range(len(args)):
t = args[i].split(':')
tmp[t[0]] = t[1]
return tmp
def status():
if not app_debug:
if mw.isAppleSystem():
return "stop"
data = mw.execShell('sudo sysctl -n net.ipv4.tcp_congestion_control')
r = data[0].strip()
if r == 'bbr':
return 'start'
return 'stop'
def start():
if not app_debug:
if mw.isAppleSystem():
return "Apple Computer does not support"
mw.execShell('echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf')
cmd = 'echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf'
mw.execShell(cmd)
mw.execShell('sysctl -p')
return '执行成功!重启系统生效'
def stop():
if not app_debug:
if mw.isAppleSystem():
return "Apple Computer does not support"
cmd1 = "sed -i '/net\.core\.default_qdisc/d' /etc/sysctl.conf"
mw.execShell(cmd1)
cmd2 = "sed -i '/net\.ipv4\.tcp_congestion_control/d' /etc/sysctl.conf"
mw.execShell(cmd2)
mw.execShell("sysctl -p")
return '执行成功!重启系统生效'
def restart():
return '无效'
def reload():
return '无效'
if __name__ == "__main__":
func = sys.argv[1]
if func == 'status':
print status()
elif func == 'start':
print start()
elif func == 'stop':
print stop()
elif func == 'restart':
print restart()
elif func == 'reload':
print reload()

16
plugins/bbr/info.json Executable file
View File

@@ -0,0 +1,16 @@
{
"id":4,
"title":"BBR",
"tip":"soft",
"name":"bbr",
"type":"软件",
"ps":"[DEV][谨慎]BBR是Google提出的一种新型拥塞控制算法",
"versions":"1.0",
"shell":"install.sh",
"checks":"server/bbr",
"path":"server/bbr",
"author":"Google",
"home":"https://github.com/google/bbr",
"date":"2019-03-29",
"pid":"5"
}

36
plugins/bbr/install.sh Executable file
View File

@@ -0,0 +1,36 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
Install_bbr()
{
echo '正在安装脚本文件...' > $install_tmp
chmod +x $curPath/scripts/bbr.sh
sh $curPath/scripts/bbr.sh
mkdir -p $serverPath/bbr
echo '1.0' > $serverPath/bbr/version.pl
echo '安装完成' > $install_tmp
}
Uninstall_bbr()
{
rm -rf $serverPath/bbr
echo "卸载完成" > $install_tmp
}
action=$1
if [ "${1}" == 'install' ];then
Install_bbr
else
Uninstall_bbr
fi

13
plugins/bbr/js/bbr.js Executable file
View File

@@ -0,0 +1,13 @@
function readme(){
var con = '<ul class="help-info-text c7">';
con += '<li>一旦安装无法退回!谨慎使用</li>';
con += '<li>只有KVM架构的VPS才能使用</li>';
con += '<li>安装 Google BBR 需升级系统内核,而安装锐速则需降级系统内核,<br/>故两者不能同时安装。</li>';
con += '<li>安装 Google BBR 需升级系统内核,有可能造成系统不稳定,<br/>故不建议将其应用在重要的生产环境中</li>';
con += '<hr/>';
con += '<li>安装升级后,可删除无用的旧内核[谨慎操作]</li>';
con += '<li>yum remove $(rpm -qa | grep kernel | grep -v $(uname -r))</li>';
con += '</ul>';
$(".soft-man-con").html(con);
}

389
plugins/bbr/scripts/bbr.sh Normal file
View File

@@ -0,0 +1,389 @@
#!/usr/bin/env bash
#
# Auto install latest kernel for TCP BBR
#
# System Required: CentOS 6+, Debian7+, Ubuntu12+
#
# Copyright (C) 2016-2018 Teddysun <i@teddysun.com>
#
# URL: https://teddysun.com/489.html
#
red='\033[0;31m'
green='\033[0;32m'
yellow='\033[0;33m'
plain='\033[0m'
cur_dir=$(pwd)
[[ $EUID -ne 0 ]] && echo -e "${red}Error:${plain} This script must be run as root!" && exit 1
[[ -d "/proc/vz" ]] && echo -e "${red}Error:${plain} Your VPS is based on OpenVZ, which is not supported." && exit 1
if [ -f /etc/redhat-release ]; then
release="centos"
elif cat /etc/issue | grep -Eqi "debian"; then
release="debian"
elif cat /etc/issue | grep -Eqi "ubuntu"; then
release="ubuntu"
elif cat /etc/issue | grep -Eqi "centos|red hat|redhat"; then
release="centos"
elif cat /proc/version | grep -Eqi "debian"; then
release="debian"
elif cat /proc/version | grep -Eqi "ubuntu"; then
release="ubuntu"
elif cat /proc/version | grep -Eqi "centos|red hat|redhat"; then
release="centos"
else
release=""
fi
is_digit(){
local input=${1}
if [[ "$input" =~ ^[0-9]+$ ]]; then
return 0
else
return 1
fi
}
is_64bit(){
if [ $(getconf WORD_BIT) = '32' ] && [ $(getconf LONG_BIT) = '64' ]; then
return 0
else
return 1
fi
}
get_valid_valname(){
local val=${1}
local new_val=$(eval echo $val | sed 's/[-.]/_/g')
echo ${new_val}
}
get_hint(){
local val=${1}
local new_val=$(get_valid_valname $val)
eval echo "\$hint_${new_val}"
}
#Display Memu
display_menu(){
local soft=${1}
local default=${2}
eval local arr=(\${${soft}_arr[@]})
local default_prompt
if [[ "$default" != "" ]]; then
if [[ "$default" == "last" ]]; then
default=${#arr[@]}
fi
default_prompt="(default ${arr[$default-1]})"
fi
local pick
local hint
local vname
local prompt="which ${soft} you'd select ${default_prompt}: "
while :
do
echo -e "\n------------ ${soft} setting ------------\n"
for ((i=1;i<=${#arr[@]};i++ )); do
vname="$(get_valid_valname ${arr[$i-1]})"
hint="$(get_hint $vname)"
[[ "$hint" == "" ]] && hint="${arr[$i-1]}"
echo -e "${green}${i}${plain}) $hint"
done
echo
read -p "${prompt}" pick
if [[ "$pick" == "" && "$default" != "" ]]; then
pick=${default}
break
fi
if ! is_digit "$pick"; then
prompt="Input error, please input a number"
continue
fi
if [[ "$pick" -lt 1 || "$pick" -gt ${#arr[@]} ]]; then
prompt="Input error, please input a number between 1 and ${#arr[@]}: "
continue
fi
break
done
eval ${soft}=${arr[$pick-1]}
vname="$(get_valid_valname ${arr[$pick-1]})"
hint="$(get_hint $vname)"
[[ "$hint" == "" ]] && hint="${arr[$pick-1]}"
echo -e "\nyour selection: $hint\n"
}
version_ge(){
test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" == "$1"
}
get_latest_version() {
latest_version=($(wget -qO- https://kernel.ubuntu.com/~kernel-ppa/mainline/ | awk -F'\"v' '/v[4-9]./{print $2}' | cut -d/ -f1 | grep -v - | sort -V))
[ ${#latest_version[@]} -eq 0 ] && echo -e "${red}Error:${plain} Get latest kernel version failed." && exit 1
kernel_arr=()
for i in ${latest_version[@]}; do
if version_ge $i 4.14; then
kernel_arr+=($i);
fi
done
display_menu kernel last
if [[ `getconf WORD_BIT` == "32" && `getconf LONG_BIT` == "64" ]]; then
deb_name=$(wget -qO- https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/ | grep "linux-image" | grep "generic" | awk -F'\">' '/amd64.deb/{print $2}' | cut -d'<' -f1 | head -1)
deb_kernel_url="https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/${deb_name}"
deb_kernel_name="linux-image-${kernel}-amd64.deb"
modules_deb_name=$(wget -qO- https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/ | grep "linux-modules" | grep "generic" | awk -F'\">' '/amd64.deb/{print $2}' | cut -d'<' -f1 | head -1)
deb_kernel_modules_url="https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/${modules_deb_name}"
deb_kernel_modules_name="linux-modules-${kernel}-amd64.deb"
else
deb_name=$(wget -qO- https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/ | grep "linux-image" | grep "generic" | awk -F'\">' '/i386.deb/{print $2}' | cut -d'<' -f1 | head -1)
deb_kernel_url="https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/${deb_name}"
deb_kernel_name="linux-image-${kernel}-i386.deb"
modules_deb_name=$(wget -qO- https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/ | grep "linux-modules" | grep "generic" | awk -F'\">' '/i386.deb/{print $2}' | cut -d'<' -f1 | head -1)
deb_kernel_modules_url="https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/${modules_deb_name}"
deb_kernel_modules_name="linux-modules-${kernel}-i386.deb"
fi
[ -z ${deb_name} ] && echo -e "${red}Error:${plain} Getting Linux kernel binary package name failed, maybe kernel build failed. Please choose other one and try again." && exit 1
}
get_opsy() {
[ -f /etc/redhat-release ] && awk '{print ($1,$3~/^[0-9]/?$3:$4)}' /etc/redhat-release && return
[ -f /etc/os-release ] && awk -F'[= "]' '/PRETTY_NAME/{print $3,$4,$5}' /etc/os-release && return
[ -f /etc/lsb-release ] && awk -F'[="]+' '/DESCRIPTION/{print $2}' /etc/lsb-release && return
}
opsy=$( get_opsy )
arch=$( uname -m )
lbit=$( getconf LONG_BIT )
kern=$( uname -r )
get_char() {
SAVEDSTTY=`stty -g`
stty -echo
stty cbreak
dd if=/dev/tty bs=1 count=1 2> /dev/null
stty -raw
stty echo
stty $SAVEDSTTY
}
getversion() {
if [[ -s /etc/redhat-release ]]; then
grep -oE "[0-9.]+" /etc/redhat-release
else
grep -oE "[0-9.]+" /etc/issue
fi
}
centosversion() {
if [ x"${release}" == x"centos" ]; then
local code=$1
local version="$(getversion)"
local main_ver=${version%%.*}
if [ "$main_ver" == "$code" ]; then
return 0
else
return 1
fi
else
return 1
fi
}
check_bbr_status() {
local param=$(sysctl net.ipv4.tcp_congestion_control | awk '{print $3}')
if [[ x"${param}" == x"bbr" ]]; then
return 0
else
return 1
fi
}
check_kernel_version() {
local kernel_version=$(uname -r | cut -d- -f1)
if version_ge ${kernel_version} 4.9; then
return 0
else
return 1
fi
}
install_elrepo() {
if centosversion 5; then
echo -e "${red}Error:${plain} not supported CentOS 5."
exit 1
fi
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
if centosversion 6; then
rpm -Uvh https://www.elrepo.org/elrepo-release-6-8.el6.elrepo.noarch.rpm
elif centosversion 7; then
rpm -Uvh https://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
fi
if [ ! -f /etc/yum.repos.d/elrepo.repo ]; then
echo -e "${red}Error:${plain} Install elrepo failed, please check it."
exit 1
fi
}
sysctl_config() {
sed -i '/net.core.default_qdisc/d' /etc/sysctl.conf
sed -i '/net.ipv4.tcp_congestion_control/d' /etc/sysctl.conf
echo "net.core.default_qdisc = fq" >> /etc/sysctl.conf
echo "net.ipv4.tcp_congestion_control = bbr" >> /etc/sysctl.conf
sysctl -p >/dev/null 2>&1
}
install_config() {
if [[ x"${release}" == x"centos" ]]; then
if centosversion 6; then
if [ ! -f "/boot/grub/grub.conf" ]; then
echo -e "${red}Error:${plain} /boot/grub/grub.conf not found, please check it."
exit 1
fi
sed -i 's/^default=.*/default=0/g' /boot/grub/grub.conf
elif centosversion 7; then
if [ ! -f "/boot/grub2/grub.cfg" ]; then
echo -e "${red}Error:${plain} /boot/grub2/grub.cfg not found, please check it."
exit 1
fi
grub2-set-default 0
fi
elif [[ x"${release}" == x"debian" || x"${release}" == x"ubuntu" ]]; then
/usr/sbin/update-grub
fi
}
reboot_os() {
echo
echo -e "${green}Info:${plain} The system needs to reboot."
# read -p "Do you want to restart system? [y/n]" is_reboot
# if [[ ${is_reboot} == "y" || ${is_reboot} == "Y" ]]; then
# reboot
# else
# echo -e "${green}Info:${plain} Reboot has been canceled..."
# exit 0
# fi
}
install_bbr() {
check_bbr_status
if [ $? -eq 0 ]; then
echo
echo -e "${green}Info:${plain} TCP BBR has already been installed. nothing to do..."
exit 0
fi
check_kernel_version
if [ $? -eq 0 ]; then
echo
echo -e "${green}Info:${plain} Your kernel version is greater than 4.9, directly setting TCP BBR..."
sysctl_config
echo -e "${green}Info:${plain} Setting TCP BBR completed..."
exit 0
fi
if [[ x"${release}" == x"centos" ]]; then
install_elrepo
[ ! "$(command -v yum-config-manager)" ] && yum install -y yum-utils > /dev/null 2>&1
[ x"$(yum-config-manager elrepo-kernel | grep -w enabled | awk '{print $3}')" != x"True" ] && yum-config-manager --enable elrepo-kernel > /dev/null 2>&1
if centosversion 6; then
if is_64bit; then
rpm_kernel_name="kernel-ml-4.18.20-1.el6.elrepo.x86_64.rpm"
rpm_kernel_devel_name="kernel-ml-devel-4.18.20-1.el6.elrepo.x86_64.rpm"
rpm_kernel_url_1="http://repos.lax.quadranet.com/elrepo/archive/kernel/el6/x86_64/RPMS/"
else
rpm_kernel_name="kernel-ml-4.18.20-1.el6.elrepo.i686.rpm"
rpm_kernel_devel_name="kernel-ml-devel-4.18.20-1.el6.elrepo.i686.rpm"
rpm_kernel_url_1="http://repos.lax.quadranet.com/elrepo/archive/kernel/el6/i386/RPMS/"
fi
rpm_kernel_url_2="https://dl.lamp.sh/files/"
wget -c -t3 -T60 -O ${rpm_kernel_name} ${rpm_kernel_url_1}${rpm_kernel_name}
if [ $? -ne 0 ]; then
rm -rf ${rpm_kernel_name}
wget -c -t3 -T60 -O ${rpm_kernel_name} ${rpm_kernel_url_2}${rpm_kernel_name}
fi
wget -c -t3 -T60 -O ${rpm_kernel_devel_name} ${rpm_kernel_url_1}${rpm_kernel_devel_name}
if [ $? -ne 0 ]; then
rm -rf ${rpm_kernel_devel_name}
wget -c -t3 -T60 -O ${rpm_kernel_devel_name} ${rpm_kernel_url_2}${rpm_kernel_devel_name}
fi
if [ -f "${rpm_kernel_name}" ]; then
rpm -ivh ${rpm_kernel_name}
else
echo -e "${red}Error:${plain} Download ${rpm_kernel_name} failed, please check it."
exit 1
fi
if [ -f "${rpm_kernel_devel_name}" ]; then
rpm -ivh ${rpm_kernel_devel_name}
else
echo -e "${red}Error:${plain} Download ${rpm_kernel_devel_name} failed, please check it."
exit 1
fi
rm -f ${rpm_kernel_name} ${rpm_kernel_devel_name}
elif centosversion 7; then
yum -y install kernel-ml kernel-ml-devel
if [ $? -ne 0 ]; then
echo -e "${red}Error:${plain} Install latest kernel failed, please check it."
exit 1
fi
fi
elif [[ x"${release}" == x"debian" || x"${release}" == x"ubuntu" ]]; then
[[ ! -e "/usr/bin/wget" ]] && apt-get -y update && apt-get -y install wget
echo -e "${green}Info:${plain} Getting latest kernel version..."
get_latest_version
if [ -n ${modules_deb_name} ]; then
wget -c -t3 -T60 -O ${deb_kernel_modules_name} ${deb_kernel_modules_url}
if [ $? -ne 0 ]; then
echo -e "${red}Error:${plain} Download ${deb_kernel_modules_name} failed, please check it."
exit 1
fi
fi
wget -c -t3 -T60 -O ${deb_kernel_name} ${deb_kernel_url}
if [ $? -ne 0 ]; then
echo -e "${red}Error:${plain} Download ${deb_kernel_name} failed, please check it."
exit 1
fi
[ -f ${deb_kernel_modules_name} ] && dpkg -i ${deb_kernel_modules_name}
dpkg -i ${deb_kernel_name}
rm -f ${deb_kernel_name} ${deb_kernel_modules_name}
else
echo -e "${red}Error:${plain} OS is not be supported, please change to CentOS/Debian/Ubuntu and try again."
exit 1
fi
install_config
sysctl_config
reboot_os
}
clear
echo "---------- System Information ----------"
echo " OS : $opsy"
echo " Arch : $arch ($lbit Bit)"
echo " Kernel : $kern"
echo "----------------------------------------"
echo " Auto install latest kernel for TCP BBR"
echo
echo " URL: https://teddysun.com/489.html"
echo "----------------------------------------"
echo
# echo "Press any key to start...or Press Ctrl+C to cancel"
# char=`get_char`
#install_bbr 2>&1 | tee ${cur_dir}/install_bbr.log
install_bbr

34
plugins/csvn/hook/commit.tpl Executable file
View File

@@ -0,0 +1,34 @@
#!/bin/bash
export LC_ALL=en_US.UTF-8
export LC_CTYPE=zh_CN.UTF-8
REPOS="$1"
REV="$2"
TXN_NAME="$3"
if [ ! -d {$PROJECT_DIR}/csvn ]; then
sudo mkdir -p {$PROJECT_DIR}/csvn
sudo chown -R csvn:csvn {$PROJECT_DIR}/csvn
fi
SAVE_PATH={$PROJECT_DIR}/csvn/$REPOS
SVN_PATH=http://127.0.0.1:{$PORT}/svn/$REPOS
if [ ! -d $SAVE_PATH ]; then
svn co $SVN_PATH $SAVE_PATH \
--username={$CSVN_USER} \
--password={$CSVN_PWD} \
--no-auth-cache \
--non-interactive
fi
cd $SAVE_PATH && svn update --username={$CSVN_USER} --password={$CSVN_PWD} --no-auth-cache --non-interactive
WEB_PATH={$PROJECT_DIR}/wwwroot/$REPOS
sudo mkdir -p $WEB_PATH
sudo rsync -vauP --delete --exclude=".*" $SAVE_PATH/ $WEB_PATH
sudo chown -R www:www $WEB_PATH

View File

@@ -0,0 +1,11 @@
#!/bin/bash
REPOS="$1"
REV="$2"
TXN_NAME="$3"
REPOS_NAME=${REPOS##*/}
sh -x $REPOS/hooks/commit $REPOS_NAME $REV $TXN_NAME 2>$REPOS/sh.log

BIN
plugins/csvn/ico.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

41
plugins/csvn/index.html Executable file
View File

@@ -0,0 +1,41 @@
<style type="text/css">
.outline_no {
outline:none;
}
</style>
<div class="bt-form">
<div class="bt-w-main">
<div class="bt-w-menu">
<p class="bgw" onclick="pluginService('csvn');">服务</p>
<p onclick="pluginInitD('csvn');">自启动</p>
<p onclick="csvnEdit();">手动编辑</p>
<p onclick="csvnUserList(1);">用户管理</p>
<p onclick="csvnProjectList(1);">项目管理</p>
<p onclick="csvnReadme();">使用说明</p>
</div>
<div class="bt-w-con pd15">
<div class="soft-man-con"></div>
</div>
</div>
</div>
<script type="text/javascript">
resetPluginWinWidth(700);
$.getScript( "/plugins/file?name=csvn&f=js/csvn.js");
function csvnReadme(){
var readme = '<ul class="help-info-text c7">';
readme += '<li>注意:在启动时会比较慢,需要耐心等待一会</li>';
readme += '<li>注意:csvn需要java环境,在安装会自动检查并安装</li>';
readme += '<li>注意:默认后台密码admin:admin,最好马上修改</li>';
readme += '<li>注意:牢记admin的密码,在后csvn的管理后台和这里不同步</li>';
readme += '<li>注意:在这里添加用户和csvn后台并不同步</li>';
readme += '<li>注意:项目管理的地址一般是正确的,但在特殊环境下,地址可能不一致</li>';
readme += '<li>注意:脚本内使用sudo名,需要注释(vi /etc/sudoers)[#Default requiretty]</li>';
readme += '</ul>';
$('.bt-w-main .soft-man-con').html(readme);
}
</script>

709
plugins/csvn/index.py Executable file
View File

@@ -0,0 +1,709 @@
# coding: utf-8
import time
import random
import os
import urllib
import binascii
import json
import re
import sys
import subprocess
sys.path.append(os.getcwd() + "/class/core")
import mw
app_debug = False
if mw.isAppleSystem():
app_debug = True
def getPluginName():
return 'csvn'
def getPluginDir():
return mw.getPluginDir() + '/' + getPluginName()
def getServerDir():
return mw.getServerDir() + '/' + getPluginName()
def getInitDFile():
if app_debug:
return '/tmp/' + getPluginName()
return '/etc/init.d/' + getPluginName()
def getArgs():
args = sys.argv[2:]
tmp = {}
args_len = len(args)
if args_len == 1:
t = args[0].strip('{').strip('}')
t = t.split(':')
tmp[t[0]] = t[1]
elif args_len > 1:
for i in range(len(args)):
t = args[i].split(':')
tmp[t[0]] = t[1]
return tmp
def initDreplace():
initd_file = getInitDFile()
if not os.path.exists(initd_file):
return getServerDir()
return initd_file
def status():
data = mw.execShell(
"ps -ef|grep " + getPluginName() + " |grep -v grep | grep -v python | awk '{print $2}'")
if data[0] == '':
return 'stop'
return 'start'
def csvnOp(method):
if app_debug:
os_name = mw.getOs()
if os_name == 'darwin':
return "Apple Computer does not support"
_initd_csvn = '/etc/init.d/csvn'
_initd_csvn_httpd = '/etc/init.d/csvn-httpd'
#_csvn = getServerDir() + '/bin/csvn'
#_csvn_httpd = getServerDir() + '/bin/csvn-httpd'
ret_csvn_httpd = mw.execShell(_initd_csvn_httpd + ' ' + method)
# ret_csvn = mw.execShell(_initd_csvn + ' ' + method)
subprocess.Popen(_initd_csvn + ' ' + method,
stdout=subprocess.PIPE, shell=True)
if ret_csvn_httpd[1] == '':
return 'ok'
return 'fail'
def start():
return csvnOp('start')
def stop():
return csvnOp('stop')
def restart():
return csvnOp('restart')
def reload():
return csvnOp('reload')
def initdStatus():
if not app_debug:
if mw.isAppleSystem():
return "Apple Computer does not support"
_initd_csvn = '/etc/init.d/csvn'
_initd_csvn_httpd = '/etc/init.d/csvn-httpd'
if os.path.exists(_initd_csvn) and os.path.exists(_initd_csvn_httpd):
return 'ok'
return 'fail'
def initdInstall():
import shutil
if not app_debug:
if mw.isAppleSystem():
return "Apple Computer does not support"
_csvn = getServerDir() + '/bin/csvn'
_csvn_httpd = getServerDir() + '/bin/csvn-httpd'
ret_csvn = mw.execShell(_csvn + ' install')
ret_csvn_httpd = mw.execShell(_csvn_httpd + ' install')
if ret_csvn[1] == '' and ret_csvn_httpd[1] == '':
return 'ok'
return 'fail'
def initdUinstall():
if not app_debug:
if mw.isAppleSystem():
return "Apple Computer does not support"
_csvn = getServerDir() + '/bin/csvn'
_csvn_httpd = getServerDir() + '/bin/csvn-httpd'
ret_csvn = mw.execShell(_csvn + ' remove')
ret_csvn_httpd = mw.execShell(_csvn_httpd + ' remove')
return 'ok'
def csvnEdit():
data = {}
data['svn_access_file'] = getServerDir() + '/data/conf/svn_access_file'
data['commit_tpl'] = getPluginDir() + '/hook/commit.tpl'
data['post_commit_tpl'] = getPluginDir() + '/hook/post-commit.tpl'
return mw.getJson(data)
def userAdd():
args = getArgs()
if not 'username' in args:
return 'name missing'
if not 'password' in args:
return 'password missing'
htpasswd = getServerDir() + "/bin/htpasswd"
svn_auth_file = getServerDir() + "/data/conf/svn_auth_file"
cmd = htpasswd + ' -b ' + svn_auth_file + ' ' + \
args['username'] + ' ' + args['password']
data = mw.execShell(cmd)
# print data
if data[0] == '':
return 'ok'
return 'fail'
def userDel():
args = getArgs()
if not 'username' in args:
return 'name missing'
htpasswd = getServerDir() + "/bin/htpasswd"
svn_auth_file = getServerDir() + "/data/conf/svn_auth_file"
cmd = htpasswd + ' -D ' + svn_auth_file + ' ' + args['username']
data = mw.execShell(cmd)
if data[0] == '':
return 'ok'
return 'fail'
def getAllUser(search=''):
svn_auth_file = getServerDir() + '/data/conf/svn_auth_file'
if not os.path.exists(svn_auth_file):
return mw.getJson([])
auth = mw.readFile(svn_auth_file)
auth = auth.strip()
auth_list = auth.split("\n")
ulist = []
for x in range(len(auth_list)):
tmp = auth_list[x].split(':')
if search != '':
if tmp[0].find(search) != -1:
ulist.append(tmp[0])
else:
ulist.append(tmp[0])
return ulist
def userList():
import math
args = getArgs()
page = 1
page_size = 10
search = ''
if 'page' in args:
page = int(args['page'])
if 'page_size' in args:
page_size = int(args['page_size'])
if 'search' in args:
search = args['search']
ulist = getAllUser(search)
ulist_sum = len(ulist)
page_info = {'count': ulist_sum, 'p': page,
'row': 10, 'tojs': 'csvnUserList'}
data = {}
data['list'] = mw.getPage(page_info)
data['page'] = page
data['page_size'] = page_size
data['page_count'] = int(math.ceil(ulist_sum / page_size))
start = (page - 1) * page_size
data['data'] = ulist[start:start + page_size]
return mw.getJson(data)
def projectAdd():
args = getArgs()
if not 'name' in args:
return 'project name missing'
path = getServerDir() + '/bin/svnadmin'
dest = getServerDir() + '/data/repositories/' + args['name']
cmd = path + ' create ' + dest
data = mw.execShell(cmd)
if data[1] == '':
mw.execShell('chown -R csvn:csvn ' + dest)
return 'ok'
return 'fail'
def projectDel():
args = getArgs()
if not 'name' in args:
return 'project name missing'
dest = getServerDir() + '/data/repositories/' + args['name']
cmd = 'rm -rf ' + dest
data = mw.execShell(cmd)
if data[0] == '':
return 'ok'
return 'fail'
def getHttpPort():
http_main_conf = getServerDir() + '/data/conf/csvn_main_httpd.conf'
try:
if os.path.exists(http_main_conf):
content = mw.readFile(http_main_conf)
return re.search('Listen\s(\d+)', content).groups()[0]
except Exception as e:
pass # print e
return '80'
def getCsvnPort():
http_main_conf = getServerDir() + '/data/conf/csvn-wrapper.conf'
try:
if os.path.exists(http_main_conf):
content = mw.readFile(http_main_conf)
return re.search('wrapper.java.additional.3=-Djetty.port=(\d+)', content).groups()[0]
except Exception as e:
pass # print e
return '3343'
def getALlProjectList(search=''):
path = getServerDir() + '/data/repositories'
dlist = []
if os.path.exists(path):
for filename in os.listdir(path):
tmp = {}
filePath = path + '/' + filename
if os.path.isdir(filePath):
if search == '':
tmp['name'] = filename
dlist.append(tmp)
else:
if filename.find(search) != -1:
tmp['name'] = filename
dlist.append(tmp)
return dlist
def checkProjectListIsHasScript(data):
dlen = len(data)
for x in range(dlen):
path = getServerDir() + '/data/repositories/' + \
data[x]['name'] + '/hooks/post-commit'
if os.path.exists(path):
data[x]['has_hook'] = True
else:
data[x]['has_hook'] = False
return data
def projectList():
import math
args = getArgs()
page = 1
page_size = 10
search = ''
if 'page' in args:
page = int(args['page'])
if 'page_size' in args:
page_size = int(args['page_size'])
if 'search' in args:
search = args['search']
dlist = getALlProjectList(search)
dlist_sum = len(dlist)
start = (page - 1) * page_size
ret_data = dlist[start:start + page_size]
ret_data = checkProjectListIsHasScript(ret_data)
data = {}
data['data'] = ret_data
data['list'] = mw.getPage(
{'count': dlist_sum, 'p': page, 'row': 10, 'tojs': 'csvnProjectList'})
data['ip'] = mw.getLocalIp()
data['port'] = getHttpPort()
data['csvn_port'] = getCsvnPort()
return mw.getJson(data)
def getAllAclList():
svn_access_file = getServerDir() + '/data/conf/svn_access_file'
aData = mw.readFile(svn_access_file)
aData = re.sub('#.*', '', aData)
aData = aData.strip().split('[')[1:]
allAcl = {}
for i in range(len(aData)):
oData = aData[i].strip().split(']')
name = oData[0].strip('/').strip(':')
if oData[1] == '':
allAcl[name] = []
else:
user = oData[1].strip().split('\n')
userAll = []
for iu in range(len(user)):
ulist = user[iu].split('=')
utmp = {}
utmp['user'] = ulist[0].strip()
utmp['acl'] = ulist[1].strip()
userAll.append(utmp)
allAcl[name] = userAll
return allAcl
def makeAclFile(content):
# print content
svn_access_file = getServerDir() + '/data/conf/svn_access_file'
tmp = "\n"
for k, v in content.items():
if k == '':
tmp += "[/]\n"
else:
tmp += "[" + k + ":/]\n"
for iv in range(len(v)):
tmp += v[iv]['user'] + ' = ' + v[iv]['acl'] + "\n"
tmp += "\n"
# svn_tmp_path = getServerDir() + '/data/conf/svn_access_file.log'
return mw.writeFile(svn_access_file, tmp)
def projectAclList():
args = getArgs()
if not 'name' in args:
return 'name missing!'
name = args['name']
acl = getAllAclList()
if name in acl:
return mw.getJson(acl[name])
else:
return 'fail'
def projectAclAdd():
args = getArgs()
if not 'uname' in args:
return 'username missing'
if not 'pname' in args:
return 'project name missing'
uname = args['uname']
pname = args['pname']
ulist = getAllUser()
if not uname in ulist:
return uname + " user not exists!"
acl = getAllAclList()
tmp_acl = {'user': uname, 'acl': 'rw'}
if not pname in acl:
acl[pname] = [tmp_acl]
makeAclFile(acl)
return 'ok'
tmp = acl[pname]
tmp_len = len(tmp)
if tmp_len == 0:
acl[pname] = [tmp_acl]
else:
is_have = False
for x in range(tmp_len):
if tmp[x]['user'] == uname:
is_have = True
return uname + ' users already exist!'
if not is_have:
tmp.append(tmp_acl)
acl[pname] = tmp
makeAclFile(acl)
return 'ok'
def projectAclDel():
args = getArgs()
if not 'uname' in args:
return 'username missing'
if not 'pname' in args:
return 'project name missing'
uname = args['uname']
pname = args['pname']
ulist = getAllUser()
if not uname in ulist:
return uname + " user not exists!"
acl = getAllAclList()
if not pname in acl:
return 'project not exists!'
tmp = acl[pname]
tmp_len = len(tmp)
if tmp_len == 0:
return 'project no have user:' + uname
else:
is_have = False
rtmp = []
for x in range(tmp_len):
if tmp[x]['user'] != uname:
rtmp.append(tmp[x])
acl[pname] = rtmp
makeAclFile(acl)
return 'ok'
def projectAclSet():
args = getArgs()
if not 'uname' in args:
return 'username missing'
if not 'pname' in args:
return 'project name missing'
if not 'acl' in args:
return 'acl missing'
uname = args['uname']
pname = args['pname']
up_acl = args['acl']
ulist = getAllUser()
if not uname in ulist:
return uname + " user not exists!"
acl = getAllAclList()
if not pname in acl:
return 'project not exists!'
tmp = acl[pname]
tmp_len = len(tmp)
if tmp_len == 0:
return 'project no have user:' + uname
else:
is_have = False
for x in range(tmp_len):
if tmp[x]['user'] == uname:
tmp[x]['acl'] = up_acl
acl[pname] = tmp
makeAclFile(acl)
return 'ok'
def getCsvnUser():
user = 'admin_sync'
acl = getAllAclList()
if '' in acl:
tmp = acl['']
is_has = False
for data in tmp:
if data['user'] == user:
is_has = True
if not is_has:
tmp.append({'user': user, 'acl': 'r'})
acl[''] = tmp
makeAclFile(acl)
return user
def getCsvnPwd(user):
if app_debug:
return user + '123'
pwd_file = 'data/csvn_sync.pl'
if os.path.exists(pwd_file):
return mw.readFile(pwd_file).strip()
import time
cur_time = time.time()
rand_pwd = mw.md5(str(cur_time))
pwd = user + rand_pwd[:5]
htpasswd = getServerDir() + "/bin/htpasswd"
svn_auth_file = getServerDir() + "/data/conf/svn_auth_file"
cmd = htpasswd + ' -b ' + svn_auth_file + ' ' + user + ' ' + pwd
data = mw.execShell(cmd)
mw.writeFile(pwd_file, pwd)
return pwd
def projectScriptLoad():
args = getArgs()
if not 'pname' in args:
return 'project name missing'
post_commit_tpl = getPluginDir() + '/hook/post-commit.tpl'
hook_path = getServerDir() + '/data/repositories/' + \
args['pname'] + '/hooks'
post_commit_file = hook_path + '/post-commit'
pct_content = mw.readFile(post_commit_tpl)
mw.writeFile(post_commit_file, pct_content)
mw.execShell('chmod 777 ' + post_commit_file)
commit_tpl = getPluginDir() + '/hook/commit.tpl'
commit_file = hook_path + '/commit'
ct_content = mw.readFile(commit_tpl)
ct_content = ct_content.replace('{$PROJECT_DIR}', mw.getRootDir())
ct_content = ct_content.replace('{$PORT}', getHttpPort())
ct_content = ct_content.replace('{$CSVN_USER}', getCsvnUser())
ct_content = ct_content.replace('{$CSVN_PWD}', getCsvnPwd(getCsvnUser()))
mw.writeFile(commit_file, ct_content)
mw.execShell('chmod 777 ' + commit_file)
return 'ok'
def projectScriptUnload():
args = getArgs()
if not 'pname' in args:
return 'project name missing'
post_commit_file = getServerDir() + '/data/repositories/' + '/' + \
args['pname'] + '/hooks/post-commit'
mw.execShell('rm -f ' + post_commit_file)
commit_file = getServerDir() + '/data/repositories/' + '/' + \
args['pname'] + '/hooks/commit'
mw.execShell('rm -f ' + commit_file)
return 'ok'
def projectScriptEdit():
args = getArgs()
if not 'pname' in args:
return 'project name missing'
data = {}
commit_file = getServerDir() + '/data/repositories/' + \
args['pname'] + '/hooks/commit'
if os.path.exists(commit_file):
data['status'] = True
data['path'] = commit_file
else:
data['status'] = False
data['msg'] = 'file does not exist'
return mw.getJson(data)
def projectScriptDebug():
args = getArgs()
if not 'pname' in args:
return 'project name missing'
data = {}
commit_log = getServerDir() + '/data/repositories/' + \
args['pname'] + '/sh.log'
if os.path.exists(commit_log):
data['status'] = True
data['path'] = commit_log
else:
data['status'] = False
data['msg'] = 'file does not exist'
return mw.getJson(data)
def getTotalStatistics():
st = status()
data = {}
if st == 'start':
svn_path = getServerDir() + '/data/repositories'
data['status'] = True
data['count'] = len(os.listdir(svn_path))
data['ver'] = mw.readFile(getServerDir() + '/version.pl').strip()
return mw.returnJson(True, 'ok', data)
else:
data['status'] = False
data['count'] = 0
return mw.returnJson(False, 'fail', data)
if __name__ == "__main__":
func = sys.argv[1]
if func == 'status':
print status()
elif func == 'start':
print start()
elif func == 'stop':
print stop()
elif func == 'restart':
print restart()
elif func == 'reload':
print reload()
elif func == 'initd_status':
print initdStatus()
elif func == 'initd_install':
print initdInstall()
elif func == 'initd_uninstall':
print initdUinstall()
elif func == 'csvn_edit':
print csvnEdit()
elif func == 'user_list':
print userList()
elif func == 'user_add':
print userAdd()
elif func == 'user_del':
print userDel()
elif func == 'project_list':
print projectList()
elif func == 'project_del':
print projectDel()
elif func == 'project_add':
print projectAdd()
elif func == 'project_acl_list':
print projectAclList()
elif func == 'project_acl_add':
print projectAclAdd()
elif func == 'project_acl_del':
print projectAclDel()
elif func == 'project_acl_set':
print projectAclSet()
elif func == 'project_script_load':
print projectScriptLoad()
elif func == 'project_script_unload':
print projectScriptUnload()
elif func == 'project_script_edit':
print projectScriptEdit()
elif func == 'project_script_debug':
print projectScriptDebug()
elif func == 'get_total_statistics':
print getTotalStatistics()
else:
print 'fail'

17
plugins/csvn/info.json Executable file
View File

@@ -0,0 +1,17 @@
{
"sort": 7,
"ps": "最流行的SVN代码共享管理软件",
"shell": "install.sh",
"name": "csvn",
"title": "CSVN",
"versions": "5.1",
"updates":"5.1.4",
"tip": "soft",
"checks": "server/csvn",
"path":"server/csvn",
"author": "midoks",
"date": "2017-04-01",
"home": "https://www.collab.net",
"type": "SVN代码共享管理软件",
"pid": "3"
}

72
plugins/csvn/install.sh Executable file
View File

@@ -0,0 +1,72 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
CSVN_SOURCE='https://github.com/midoks/mdserver-web/releases/download/init/CollabNetSubversionEdge-5.1.4_linux-x86_64.tar.xz'
CheckJAVA()
{
which "java" > /dev/null
if [ $? -eq 0 ]
then
echo 'java is exist'
else
echo 'java install...'
yum install -y java
fi
}
Install_csvn()
{
CheckJAVA
mkdir -p $serverPath/source
echo '正在安装脚本文件...' > $install_tmp
if [ ! -f $serverPath/source/csvn.tar.xz ];then
wget -O $serverPath/source/csvn.tar.xz ${CSVN_SOURCE}
fi
cd $serverPath/source && tar -Jxf $serverPath/source/csvn.tar.xz
mv $serverPath/source/csvn $serverPath/csvn
echo '5.1' > $serverPath/csvn/version.pl
if id -u csvn > /dev/null 2>&1; then
echo "csvn user exists"
else
useradd csvn
cp /etc/sudoers{,.`date +"%Y-%m-%d_%H-%M-%S"`}
echo "csvn ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
fi
chown -R csvn:csvn $serverPath/csvn
# $serverPath/csvn/bin/csvn install
# $serverPath/csvn/bin/csvn-httpd install
echo '安装完成' > $install_tmp
}
Uninstall_csvn()
{
rm -rf $serverPath/csvn
}
action=$1
host=$2
if [ "${1}" == 'install' ];then
Install_csvn
else
Uninstall_csvn
fi

500
plugins/csvn/js/csvn.js Executable file
View File

@@ -0,0 +1,500 @@
pluginService('csvn');
function csvnPost(method,args,callback){
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
$.post('/plugins/run', {name:'csvn', func:method, args:JSON.stringify(args)}, function(data) {
layer.close(loadT);
if (!data.status){
layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
if(typeof(callback) == 'function'){
callback(data);
}
},'json');
}
function csvnEdit(){
csvnPost('csvn_edit',{} , function(data){
// console.log(data);
var rdata = $.parseJSON(data.data);
var edit = '<p class="status">通用的手动编辑:</p>';
edit +='<div class="sfm-opt">\
<button class="btn btn-default btn-sm" onclick="onlineEditFile(0,\''+rdata['svn_access_file']+'\');">权限编辑</button>\
<button class="btn btn-default btn-sm" onclick="onlineEditFile(0,\''+rdata['post_commit_tpl']+'\');">post_commit_tpl</button>\
<button class="btn btn-default btn-sm" onclick="onlineEditFile(0,\''+rdata['commit_tpl']+'\');">commit_tpl</button>\
</div>';
$(".soft-man-con").html(edit);
});
}
function csvnUserFind(){
var search = $('#csvn_find_user').val();
if (search==''){
layer.msg('搜索字符不能为空!',{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
csvnUserList(1, search);
}
function csvnUserList(page, search) {
var _data = {};
if (typeof(page) =='undefined'){
var page = 1;
}
_data['page'] = page;
_data['page_size'] = 10;
if(typeof(search) != 'undefined'){
_data['search'] = search;
}
csvnPost('user_list', _data, function(data){
var rdata = $.parseJSON(data.data);
// console.log(rdata);
content = '<div class="finduser"><input class="bt-input-text mr5 outline_no" type="text" placeholder="查找用户名" id="csvn_find_user" style="height: 28px; border-radius: 3px;width: 505px;">';
content += '<button class="btn btn-success btn-sm" onclick="csvnUserFind();">查找</button></div>';
content += '<div class="divtable" style="margin-top:5px;"><table class="table table-hover" width="100%" cellspacing="0" cellpadding="0" border="0">';
content += '<thead><tr>';
content += '<th>用户名</th>';
content += '<th>操作(<a class="btlink" onclick="csvnAddUser();">添加</a>)</th>';
content += '</tr></thead>';
content += '<tbody>';
ulist = rdata.data;
for (i in ulist){
content += '<tr><td>'+ulist[i]+'</td><td>'+
'<a class="btlink" onclick="csvnDelUser(\''+ulist[i]+'\')">删除</a> | ' +
'<a class="btlink" onclick="csvnModPwdUser(\''+ulist[i]+'\')">改密</a></td></tr>';
}
content += '</tbody>';
content += '</table></div>';
page = '<div class="dataTables_paginate paging_bootstrap pagination" style="margin-top:0px;"><ul id="softPage" class="page"><div>';
page += rdata.list;
page += '</div></ul></div>';
content += page;
$(".soft-man-con").html(content);
});
}
function csvnDelUser(name){
var loadOpen = layer.open({
type: 1,
title: '删除用户',
area: '350px',
content:"<div class='bt-form pd20 pb70 c6'>\
<div class='version line'>你要确认要删除"+ name + "账户?</div>\
<div class='bt-form-submit-btn'>\
<button type='button' id='csvn_del_close' class='btn btn-danger btn-sm btn-title'>关闭</button>\
<button type='button' id='csvn_del_ok' class='btn btn-success btn-sm btn-title bi-btn'>确认</button>\
</div>\
</div>"
});
$('#csvn_del_close').click(function(){
layer.close(loadOpen);
});
$('#csvn_del_ok').click(function(){
_data = {};
_data['username'] = name;
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
$.post('/plugins/run', {name:'csvn', func:'user_del', args:JSON.stringify(_data)}, function(data) {
layer.close(loadT);
if (!data.status){
layer.msg(data.data,{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
if (data.data !='ok'){
layer.msg(data.data,{icon:2,time:2000,shade: [0.3, '#000']});
}
layer.close(loadOpen);
layer.msg("删除成功!",{icon:1,time:3000,shade: [0.3, '#000']});
},'json');
});
}
function csvnAddUser(username){
user_input = ''
if (typeof(username) == 'undefined'){
user_input = "<div><input class='bt-input-text mr5 outline_no' type='text' id='csvn_username' name='username' style='height: 28px; border-radius: 3px;width: 200px;' placeholder='输入用户名'></div>";
} else {
user_input = "<div><input value='"+ username +"' class='bt-input-text mr5 outline_no' type='text' id='csvn_username' name='username' style='height: 28px; border-radius: 3px;width: 200px;' disabled='true'></div>";
}
var loadOpen = layer.open({
type: 1,
title: '添加用户',
area: '240px',
content:"<div class='bt-form pd20 pb70 c6'>\
<div class='version line'>\
"+user_input+"\
<div style='padding-top:3px;'><input class='bt-input-text mr5 outline_no' type='text' id='csvn_password' name='password' style='height: 28px; border-radius: 3px;width: 200px;' placeholder='输入密码'></div>\
</div>\
<div class='bt-form-submit-btn'>\
<button type='button' id='csvn_add_close' class='btn btn-danger btn-sm btn-title'>关闭</button>\
<button type='button' id='csvn_add_ok' class='btn btn-success btn-sm btn-title bi-btn'>确认</button>\
</div>\
</div>"
});
$('#csvn_add_close').click(function(){
layer.close(loadOpen);
});
$('#csvn_add_ok').click(function(){
_data = {};
_data['username'] = $('#csvn_username').val();
_data['password'] = $('#csvn_password').val();
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
$.post('/plugins/run', {name:'csvn', func:'user_add', args:JSON.stringify(_data)}, function(data) {
layer.close(loadT);
if (!data.status){
layer.msg(data.data,{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
if (data.data !='ok'){
layer.msg(data.data,{icon:2,time:2000,shade: [0.3, '#000']});
}
csvnUserList();
layer.close(loadOpen);
layer.msg("操作成功!",{icon:1,time:3000,shade: [0.3, '#000']});
},'json');
});
}
function csvnModPwdUser(name){
csvnAddUser(name);
}
function csvnProjectFind(){
var search = $('#csvn_project_find').val();
if (search == ''){
layer.msg('查找字符不能为空!',{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
csvnProjectList(1, search);
}
function csvnProjectList(page, search){
var _data = {};
_data['page_size'] = 10;
if (typeof(search) != 'undefined'){
_data['search'] = search;
}
if (typeof(page) != 'undefined'){
_data['page'] = page;
setCookie('csvnProjectListPage',page);
} else {
_data['page'] = 1;
cookie_page = getCookie('csvnProjectListPage')
if (cookie_page >0){
_data['page'] = cookie_page;
}
}
csvnPost('project_list', _data, function(data){
var rdata = $.parseJSON($.trim(data.data));
var csvn_mg = project_url = 'http://' +rdata['ip'] +(rdata['csvn_port'] == '80' ? '': ':'+rdata['csvn_port']);
content = '<div><input class="bt-input-text mr5" type="text" placeholder="查找项目" id="csvn_project_find" style="height: 28px; border-radius: 3px;width: 505px;">';
content += '<button class="btn btn-success btn-sm" onclick="csvnProjectFind();">查找</button></div>';
content += '<div class="divtable" style="margin-top:5px;"><table class="table table-hover" width="100%" cellspacing="0" cellpadding="0" border="0">';
content += '<thead><tr>';
content += '<th>项目名</th>';
content += '<th>地址</th>';
content += '<th>操作(<a class="btlink" onclick="csvnAddProject();">添加</a>) | <a class="btlink" target="_blank" href="'+csvn_mg+'">后台管理</a> </th>';
content += '</tr></thead>';
content += '<tbody>';
// console.log(rdata);
ulist = rdata.data;
for (i in ulist){
var project_url = 'http://' +rdata['ip'] +(rdata['port'] == '80' ? '': ':'+rdata['port'])+ '/svn/'+ulist[i]['name'];
var code_url = 'http://' +rdata['ip'] +(rdata['port'] == '80' ? '': ':'+rdata['port'])+ '/viewvc/'+ulist[i]['name'];
content += '<tr><td>'+ulist[i]['name']+'</td>'+
'<td>'+project_url+'</td><td>'+
'<a class="btlink" onclick="csvnDelProject(\''+ulist[i]['name']+'\')">删除</a> | ' +
'<a class="btlink" onclick="csvnAclProject(\''+ulist[i]['name']+'\')">权限</a> | ' +
'<a class="btlink" target="_blank" href="' + code_url +'">源码</a> | ' +
'<a class="btlink" onclick="csvnProjectScript(\''+ulist[i]['name']+'\','+ ulist[i]['has_hook']+')">脚本</a>' +
'</td></tr>';
}
content += '</tbody>';
content += '</table></div>';
page = '<div class="dataTables_paginate paging_bootstrap pagination" style="margin-top:0px;"><ul id="softPage" class="page"><div>';
page += rdata.list;
page += '</div></ul></div>';
content += page;
$(".soft-man-con").html(content);
});
}
function csvnDelProject(name){
var loadOpen = layer.open({
type: 1,
title: '删除用户',
area: '350px',
content:"<div class='bt-form pd20 pb70 c6'>\
<div class='version line'>你要确认要删除"+ name + "账户?</div>\
<div class='bt-form-submit-btn'>\
<button type='button' id='csvn_del_close' class='btn btn-danger btn-sm btn-title'>关闭</button>\
<button type='button' id='csvn_del_ok' class='btn btn-success btn-sm btn-title bi-btn'>确认</button>\
</div>\
</div>"
});
$('#csvn_del_close').click(function(){
layer.close(loadOpen);
});
$('#csvn_del_ok').click(function(){
var _data = {};
_data['name'] = name;
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
$.post('/plugins/run', {name:'csvn', func:'project_del', args:JSON.stringify(_data)}, function(data) {
layer.close(loadT);
if (!data.status){
layer.msg(data.data,{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
if (data.data !='ok'){
layer.msg(data.data,{icon:2,time:2000,shade: [0.3, '#000']});
return;
}
csvnProjectList();
layer.close(loadOpen);
layer.msg("删除成功!",{icon:1,time:3000,shade: [0.3, '#000']});
},'json');
});
}
function csvnAddProject(){
var loadOpen = layer.open({
type: 1,
title: '添加项目',
area: '240px',
content:"<div class='bt-form pd20 pb70 c6'>\
<div class='version line'>\
<div><input class='bt-input-text mr5 outline_no' type='text' id='csvn_name' name='username' style='height: 28px; border-radius: 3px;width: 200px;' placeholder='输入项目名'></div>\
</div>\
<div class='bt-form-submit-btn'>\
<button type='button' id='csvn_project_close' class='btn btn-danger btn-sm btn-title'>关闭</button>\
<button type='button' id='csvn_project_ok' class='btn btn-success btn-sm btn-title bi-btn'>确认</button>\
</div>\
</div>"
});
$('#csvn_project_close').click(function(){
layer.close(loadOpen);
});
$('#csvn_project_ok').click(function(){
var _data = {};
_data['name'] = $('#csvn_name').val();
csvnPost('project_add', _data, function(data){
if (data.data !='ok'){
layer.msg(data.data,{icon:2,time:2000,shade: [0.3, '#000']});
return;
}
csvnProjectList();
layer.close(loadOpen);
layer.msg("操作成功!",{icon:1,time:3000,shade: [0.3, '#000']});
});
});
}
function csvnProjectScript(pname, has_hook){
var html = '';
if (has_hook){
html += '<button onclick="csvnProjectScriptEdit(\''+pname+'\')" class="btn btn-default btn-sm">手动编辑</button>';
html += '<button onclick="csvnProjectScriptDebug(\''+pname+'\')" class="btn btn-default btn-sm">调试日志</button>';
html += '<button onclick="csvnProjectScriptLoad(\''+pname+'\')" class="btn btn-default btn-sm">重新加载</button>';
html += '<button onclick="csvnProjectScriptUnload(\''+pname+'\')" class="btn btn-default btn-sm">卸载脚本</button>';
} else {
html += '<button onclick="csvnProjectScriptLoad(\''+pname+'\')" class="btn btn-default btn-sm">加载脚本</button>';
}
var loadOpen = layer.open({
type: 1,
title: '脚本设置',
area: '240px',
content:'<div class="change-default pd20">'+html+'</div>'
});
}
function csvnProjectScriptLoad(pname){
csvnPost('project_script_load', {'pname':pname}, function(data){
if (data.data != 'ok'){
layer.msg(data.data,{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
layer.msg('加载成功!',{icon:1,time:2000,shade: [0.3, '#000']});
setTimeout(function(){
csvnProjectList();
},2000);
});
}
function csvnProjectScriptUnload(pname){
csvnPost('project_script_unload', {'pname':pname}, function(data){
if (data.data != 'ok'){
layer.msg(data.data,{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
layer.msg('卸载成功!',{icon:1,time:2000,shade: [0.3, '#000']});
setTimeout(function(){
csvnProjectList();
},2000);
});
}
function csvnProjectScriptEdit(pname){
csvnPost('project_script_edit', {'pname':pname}, function(data){
var rdata = $.parseJSON(data.data);
if (rdata['status']){
onlineEditFile(0, rdata['path']);
csvnProjectList();
} else {
layer.msg(rdata.msg,{icon:1,time:2000,shade: [0.3, '#000']});
}
});
}
function csvnProjectScriptDebug(pname){
csvnPost('project_script_debug', {'pname':pname}, function(data){
var rdata = $.parseJSON(data.data);
if (rdata['status']){
onlineEditFile(0, rdata['path']);
csvnProjectList();
} else {
layer.msg(rdata.msg,{icon:1,time:2000,shade: [0.3, '#000']});
}
});
}
function csvnAclAdd(pname){
var uname = $('#csvn_username').val();
if (uname == ''){
layer.msg('添加用户名不能为空!',{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
csvnPost('project_acl_add', {'pname':pname,'uname':uname}, function(data){
if (data.data != 'ok'){
layer.msg(data.data,{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
$('.layui-layer-close1').click();
csvnAclProject(pname);
});
}
function csvnAclDel(pname, uname){
csvnPost('project_acl_del', {'pname':pname,'uname':uname}, function(data){
if (data.data != 'ok'){
layer.msg(data.data,{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
$('.layui-layer-close1').click();
csvnAclProject(pname);
});
}
function csvnAclSet(obj, pname, uname, acl, selected){
if (selected){
$(obj).prop('checked',true);
layer.msg('权限没有变化!',{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
csvnPost('project_acl_set', {'pname':pname,'uname':uname, 'acl':acl}, function(data){
if (data.data != 'ok'){
layer.msg(data.data,{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
$('.layui-layer-close1').click();
csvnAclProject(pname);
});
}
function csvnAclProject(pname){
csvnPost('project_acl_list', {'name':pname}, function(data){
var rdata = [];
try {
rdata = $.parseJSON(data.data);
} catch(e){}
var list = '';
for (i in rdata) {
var user = rdata[i]['user'];
var acl = '';
if (rdata[i]['acl'] == 'r'){
acl += '<input type="checkbox" onclick="csvnAclSet(this,\''+pname+'\',\''+user+'\',\'r\',true)" checked="true"> 只读 | <input type="checkbox" onclick="csvnAclSet(this,\''+pname+'\',\''+user+'\',\'rw\', false)"> 读写';
} else {
acl += '<input type="checkbox" onclick="csvnAclSet(this,\''+pname+'\',\''+user+'\',\'r\',false)"> 只读 | <input type="checkbox" onclick="csvnAclSet(this,\''+pname+'\',\''+user+'\',\'rw\',true)" checked="true"> 读写';
}
list += '<tr><td>'+user+'</td><td>' + acl +'</td>'+
'<td><a class="btlink" onclick="csvnAclDel(\''+pname+'\',\''+user+'\')">删除</a></td>'+'</tr>';
}
var loadOpen = layer.open({
type: 1,
title: '项目('+pname+')权限设置',
area: '300px',
content:"<div class='bt-form pd20 c6'>\
<div>\
<div><input class='bt-input-text mr5 outline_no' type='text' id='csvn_username' name='username' style='height: 28px; border-radius: 3px;width: 205px;' placeholder='用户名'>\
<button class='btn btn-success btn-sm' onclick='csvnAclAdd(\""+pname+"\");'>添加</button></div>\
<div class='divtable' style='margin-top:5px;'><table class='table table-hover'><thead><tr><th>用户</th><th>权限</th><th>操作</th></tr></thead>\
<tbody>"+list+"</tbody>\
</table></div>\
</div>\
</div>"
});
});
}

View File

@@ -1,350 +0,0 @@
#coding: utf-8
# +-------------------------------------------------------------------
# | 宝塔Linux面板 x3
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2017 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <2879625666@qq.com>
# +-------------------------------------------------------------------
#+--------------------------------------------------------------------
#| 自动部署网站
#+--------------------------------------------------------------------
import public,json,os,time;
class obj: id=0;
class deployment_main:
__setupPath = '/www/server/panel/plugin/deployment';
__panelPath = '/www/server/panel';
logPath = '/www/server/panel/plugin/deployment/speed.json'
timeoutCount = 0;
oldTime = 0;
#获取列表
def GetList(self,get):
self.GetCloudList(get);
jsonFile = self.__setupPath + '/list.json';
if not os.path.exists(jsonFile): return public.returnMsg(False,'配置文件不存在!');
data = {}
data = json.loads(public.readFile(jsonFile));
if not hasattr(get,'type'):
get.type = 0;
else:
get.type = int(get.type)
if not hasattr(get,'search'):
search = None
m = 0
else:
search = get.search.encode('utf-8').lower();
m = 1
tmp = [];
for d in data:
i=0;
if get.type > 0:
if get.type == d['type']: i+=1
else:
i+=1
if search:
if d['name'].lower().find(search) != -1: i+=1;
if d['title'].lower().find(search) != -1: i+=1;
if get.type > 0 and get.type != d['type']: i -= 1;
if i>m:tmp.append(d);
data = tmp;
result = {}
result['data'] = data;
jsonFile = self.__setupPath + '/type.json';
if not os.path.exists(jsonFile): self.GetCloudList(get);
result['type'] = json.loads(public.readFile(jsonFile));
return result;
#获取插件列表
def GetDepList(self,get):
jsonFile = self.__setupPath + '/list.json';
if not os.path.exists(jsonFile): return public.returnMsg(False,'配置文件不存在!');
data = {}
data = json.loads(public.readFile(jsonFile));
return data;
#从云端获取列表
def GetCloudList(self,get):
try:
import web
if not hasattr(web.ctx.session,'package'):
downloadUrl = public.get_url() + '/install/lib/plugin/deployment/package.json';
tmp = json.loads(public.httpGet(downloadUrl));
if not tmp: return public.returnMsg(False,'从云端获取失败!');
jsonFile = self.__setupPath + '/list.json';
public.writeFile(jsonFile,json.dumps(tmp));
downloadUrl = public.get_url() + '/install/lib/plugin/deployment/type.json';
tmp = json.loads(public.httpGet(downloadUrl));
if not tmp: return public.returnMsg(False,'从云端获取失败!');
jsonFile = self.__setupPath + '/type.json';
public.writeFile(jsonFile,json.dumps(tmp));
web.ctx.session.package = True
return public.returnMsg(True,'更新成功!');
return public.returnMsg(True,'无需更新!');
except:
return public.returnMsg(False,'从云端获取失败!');
#添加程序包
def AddPackage(self,get):
jsonFile = self.__setupPath + '/list.json';
if not os.path.exists(jsonFile): return public.returnMsg(False,'配置文件不存在!');
data = {}
data = json.loads(public.readFile(jsonFile));
for d in data:
if d['name'] == get.dname: return public.returnMsg(False,'您要添加的程序标识已存在!');
if d['title'] == get.title: return public.returnMsg(False,'您要添加的程序名称已存在!');
if hasattr(get,'rewrite'): get.rewrite = True;
pinfo = {}
pinfo['name'] = get.dname;
pinfo['title'] = get.title;
pinfo['version'] = get.version;
pinfo['md5'] = get.md5;
pinfo['rewrite'] = get.rewrite;
pinfo['php'] = get.php;
pinfo['ps'] = get.ps;
pinfo['shell'] = get.shell;
pinfo['download'] = get.download;
data.append(pinfo);
public.writeFile(jsonFile,json.dumps(data));
return public.returnMsg(True,'添加成功!');
#删除程序包
def DelPackage(self,get):
jsonFile = self.__setupPath + '/list.json';
if not os.path.exists(jsonFile): return public.returnMsg(False,'配置文件不存在!');
data = {}
data = json.loads(public.readFile(jsonFile));
tmp = [];
for d in data:
if d['name'].find(get.dname) != -1: continue;
tmp.append(d);
data = tmp;
public.writeFile(jsonFile,json.dumps(data));
return public.returnMsg(True,'删除成功!');
#下载文件
def DownloadFile(self,url,filename):
try:
import urllib,socket
socket.setdefaulttimeout(10)
self.pre = 0;
self.oldTime = time.time();
urllib.urlretrieve(url,filename=filename,reporthook= self.DownloadHook)
self.WriteLogs(json.dumps({'name':'下载文件','total':0,'used':0,'pre':0,'speed':0}));
except:
if self.timeoutCount > 5: return;
self.timeoutCount += 1
time.sleep(5)
self.DownloadFile(url,filename)
#下载文件进度回调
def DownloadHook(self,count, blockSize, totalSize):
used = count * blockSize
pre1 = int((100.0 * used / totalSize))
if self.pre != pre1:
dspeed = used / (time.time() - self.oldTime);
speed = {'name':'下载文件','total':totalSize,'used':used,'pre':self.pre,'speed':dspeed}
self.WriteLogs(json.dumps(speed))
self.pre = pre1
#写输出日志
def WriteLogs(self,logMsg):
fp = open(self.logPath,'w+');
fp.write(logMsg)
fp.close()
#一键安装网站程序
#param string name 程序名称
#param string site_name 网站名称
#param string php_version PHP版本
def SetupPackage(self,get):
name = get.dname
site_name = get.site_name;
php_version = get.php_version;
#取基础信息
find = public.M('sites').where('name=?',(site_name,)).field('id,path').find();
path = find['path'];
#获取包信息
pinfo = self.GetPackageInfo(name);
if not pinfo: return public.returnMsg(False,'指定软件包不存在!');
#检查本地包
self.WriteLogs(json.dumps({'name':'检查软件包','total':0,'used':0,'pre':0,'speed':0}));
packageZip = self.__setupPath + '/package/' + name + '.zip';
isDownload = False;
if os.path.exists(packageZip):
md5str = self.GetFileMd5(packageZip);
if md5str != pinfo['md5']: isDownload = True;
else:
isDownload = True;
#下载文件
if isDownload:
self.WriteLogs(json.dumps({'name':'下载文件','total':0,'used':0,'pre':0,'speed':0}));
self.DownloadFile(pinfo['download'], packageZip);
if not os.path.exists(packageZip): return public.returnMsg(False,'文件下载失败!');
os.system('unzip -o '+packageZip+' -d ' + path + '/');
#设置权限
self.WriteLogs(json.dumps({'name':'设置权限','total':0,'used':0,'pre':0,'speed':0}));
os.system('chmod -R 755 ' + path);
os.system('chown -R www.www ' + path);
if pinfo['chmod'] != "":
access = pinfo['chmod'].split(',')
for chm in access:
tmp = chm.split('|');
if len(tmp) != 2: continue;
os.system('chmod -R ' + tmp[0] + ' ' + path + '/' + tmp[1]);
#安装PHP扩展
self.WriteLogs(json.dumps({'name':'安装必要的PHP扩展','total':0,'used':0,'pre':0,'speed':0}));
if pinfo['ext'] != '':
exts = pinfo['ext'].split(',');
import files
mfile = files.files();
for ext in exts:
if ext == 'pathinfo':
import config
con = config.config();
get.version = php_version;
get.type = 'on';
con.setPathInfo(get);
else:
get.name = ext
get.version = php_version
get.type = '1';
mfile.InstallSoft(get);
#执行额外shell进行依赖安装
self.WriteLogs(json.dumps({'name':'执行额外SHELL','total':0,'used':0,'pre':0,'speed':0}));
if os.path.exists(path+'/install.sh'):
os.system('cd '+path+' && bash ' + 'install.sh');
os.system('rm -f ' + path+'/install.sh')
#是否执行Composer
if os.path.exists(path + '/composer.json'):
self.WriteLogs(json.dumps({'name':'执行Composer','total':0,'used':0,'pre':0,'speed':0}));
if not os.path.exists(path + '/composer.lock'):
execPHP = '/www/server/php/' + php_version +'/bin/php';
if execPHP:
if public.get_url().find('125.88'):
os.system('cd ' +path+' && '+execPHP+' /usr/bin/composer config repo.packagist composer https://packagist.phpcomposer.com');
import panelSite;
phpini = '/www/server/php/' + php_version + '/etc/php.ini'
phpiniConf = public.readFile(phpini);
phpiniConf = phpiniConf.replace('proc_open,proc_get_status,','');
public.writeFile(phpini,phpiniConf);
os.system('nohup cd '+path+' && '+execPHP+' /usr/bin/composer install -vvv > /tmp/composer.log 2>&1 &');
#写伪静态
self.WriteLogs(json.dumps({'name':'设置伪静态','total':0,'used':0,'pre':0,'speed':0}));
swfile = path + '/nginx.rewrite';
if os.path.exists(swfile):
rewriteConf = public.readFile(swfile);
dwfile = self.__panelPath + '/vhost/rewrite/' + site_name + '.conf';
public.writeFile(dwfile,rewriteConf);
#设置运行目录
self.WriteLogs(json.dumps({'name':'设置运行目录','total':0,'used':0,'pre':0,'speed':0}));
if pinfo['run'] != '/':
import panelSite;
siteObj = panelSite.panelSite();
mobj = obj();
mobj.id = find['id'];
mobj.runPath = pinfo['run'];
siteObj.SetSiteRunPath(mobj);
#导入数据
self.WriteLogs(json.dumps({'name':'导入数据库','total':0,'used':0,'pre':0,'speed':0}));
if os.path.exists(path+'/import.sql'):
databaseInfo = public.M('databases').where('pid=?',(find['id'],)).field('username,password').find();
if databaseInfo:
os.system('/www/server/mysql/bin/mysql -u' + databaseInfo['username'] + ' -p' + databaseInfo['password'] + ' ' + databaseInfo['username'] + ' < ' + path + '/import.sql');
os.system('rm -f ' + path + '/import.sql');
siteConfigFile = path + '/' + pinfo['config'];
if os.path.exists(siteConfigFile):
siteConfig = public.readFile(siteConfigFile)
siteConfig = siteConfig.replace('BT_DB_USERNAME',databaseInfo['username'])
siteConfig = siteConfig.replace('BT_DB_PASSWORD',databaseInfo['password'])
siteConfig = siteConfig.replace('BT_DB_NAME',databaseInfo['username'])
public.writeFile(siteConfigFile,siteConfig)
public.serviceReload();
self.depTotal(name);
self.WriteLogs(json.dumps({'name':'准备部署','total':0,'used':0,'pre':0,'speed':0}));
return public.returnMsg(True,pinfo);
#提交安装统计
def depTotal(self,name):
try:
import urllib2
urllib2.urlopen("https://www.bt.cn/Api/depTotal?name=" + name, timeout = 3)
return True
except:
return False;
#获取进度
def GetSpeed(self,get):
try:
if not os.path.exists(self.logPath): public.returnMsg(False,'当前没有部署任务!');
return json.loads(public.readFile(self.logPath));
except:
return {'name':'准备部署','total':0,'used':0,'pre':0,'speed':0}
#获取包信息
def GetPackageInfo(self,name):
data = self.GetDepList(None);
if not data: return False;
downUrl = public.get_url() + '/install/package';
for info in data:
if info['name'] == name:
info['download'] = info['download'].replace('{Download}',downUrl);
return info;
return False;
#检查指定包是否存在
def CheckPackageExists(self,name):
data = self.GetDepList(None);
if not data: return False;
for info in data:
if info['name'] == name: return True;
return False;
#文件的MD5值
def GetFileMd5(self,filename):
if not os.path.isfile(filename): return False;
import hashlib;
myhash = hashlib.md5()
f = file(filename,'rb')
while True:
b = f.read(8096)
if not b :
break
myhash.update(b)
f.close()
return myhash.hexdigest();
#获取站点标识
def GetSiteId(self,get):
return public.M('sites').where('name=?',(get.webname,)).getField('id');

Binary file not shown.

Before

Width:  |  Height:  |  Size: 553 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 553 B

View File

@@ -1,415 +0,0 @@
<style>
.disable {
background-color: #ededed;
}
.onekeyCode .table > tbody > tr > td{
line-height:1.7;
}
.oneKeysearchBar{
position: absolute;
top: 10px;
right:15px;
z-index: 20;
}
.success-msg .suc-con {
float: right;
width: 280px;
}
.bt-progress {
background-color: #e2e2e2;
border-radius: 8px;
height: 16px;
line-height: 16px;
position: relative;
margin:5px 0;
}
.bt-progress-bar {
background-color: #5ab76c;
border-radius: 8px;
height: 16px;
max-width: 100%;
position: absolute;
text-align: right;
transition: all 0.3s ease 0s;
width: 0;
}
.bt-progress-text {
font-size: 12px;
color: #fff;
padding: 0 10px;
position: static;
}
.onekey-menu-sub{
background-color: #fff;
border-bottom: 1px solid #ccc;
height: 50px;
line-height: 50px;
}
.onekey-menu-sub span{
height: 50px;
padding: 0 15px;
cursor: pointer;
display: inline-block;
font-size: 14px;
}
.onekey-menu-sub .on {
border-bottom: 2px solid #20a53a;
color: #20a53a;
font-weight: bold;
}
</style>
<div class="oneKeysearchBar">
<input class="searchInput bt-input-text" type="text" placeholder="请输入检索条件" value="" style="width:140px" />
<button class="btn btn-default btn-sm va0" onclick="GetSrcList();">查找</button>
</div>
<div class="onekey-menu-sub mlr15 onekey-type"></div>
<div class="divtable pd15 onekeyCode" style="max-height:500px; overflow:auto">
<table class="table table-hover" width="100%">
<thead>
<tr>
<th>名称</th>
<th>版本</th>
<th>简介</th>
<th>支持PHP版本</th>
<th style="text-align: right;" width="80">操作</th>
</tr>
</thead>
<tbody id="zipBody"></tbody>
</table>
</div>
<script type="javascript/text">
$('.layui-layer-page').css({'width':'760px'});
var openId = add = null;
function AddDeployment(maction){
if(maction == 1){
var pdata = 'title=' + $("input[name='title']").val()
+'&dname=' + $("input[name='name']").val()
+'&ps=' + $("input[name='ps']").val()
+'&version=' + $("input[name='version']").val()
+'&rewrite=' + ($("input[name='rewrite']").attr('checked')?1:0)
+'&shell=' + ($("input[name='shell']").attr('checked')?1:0)
+'&php=' + $("input[name='php']").val()
+'&md5=' + $("input[name='md5']").val()
+'&download=' + $("input[name='download']").val()
var loadT = layer.msg('正在提交 <img src="/static/img/ing.gif">',{icon:16,time:0,shade: [0.3, '#000']});
$.post('/plugin?action=a&name=deployment&s=AddPackage',pdata,function(rdata){
layer.close(loadT);
layer.msg(rdata.msg,{icon:rdata.status?1:5});
if(rdata.status) {
GetSrcList();
layer.close(openId);
}
});
return;
}
openId = layer.open({
type: 1,
skin: 'demo-class',
area: '480px',
title: '添加源码包',
closeBtn: 2,
shift: 5,
shadeClose: false,
content:'标题:<input type="text" name="title"><br>\
标识:<input type="text" name="name"><br>\
描述:<input type="text" name="ps"><br>\
版本:<input type="text" name="version"><br>\
是否写伪静态:<input type="checkbox" name="rewrite"><br>\
是否执行安装脚本:<input type="checkbox" name="shell"><br>\
支持的PHP版本:<input type="text" name="php"><br>\
md5:<input type="text" name="md5">\
下载地址:<input type="text" name="download"><br>\
<button class="btn btn-default btn-sm" onclick="AddDeployment(1);">提交</button>'
});
}
$(".searchInput").keyup(function(e){
if(e.keyCode == 13){
GetSrcList();
}
});
function AddSite(codename){
var array;
var str="";
var domainlist='';
var domain = array = $("#mainDomain").val().split("\n");
var Webport=[];
var checkDomain = domain[0].split('.');
if(checkDomain.length < 1){
layer.msg('域名格式不正确,请重新输入!',{icon:2});
return;
}
for(var i=1; i<domain.length; i++){
domainlist += '"'+domain[i]+'",';
}
Webport = domain[0].split(":")[1];//主域名端口
if(Webport==undefined){
Webport="80";
}
domainlist = domainlist.substring(0,domainlist.length-1);//子域名json
mainDomain = domain[0].split(':')[0];
domain ='{"domain":"'+domain[0]+'","domainlist":['+domainlist+'],"count":'+domain.length+'}';//拼接joson
var php_version = $("select[name='version']").val();
var loadT = layer.msg('正在创建站点 <img src="/static/img/ing.gif">',{icon:16,time:0,shade: [0.3, "#000"]})
var data = $("#addweb").serialize()+"&port="+Webport+"&webname="+domain+'&ftp=false&sql=true&address=localhost&codeing=utf8&version='+php_version;
$.post('/site?action=AddSite', data, function(ret) {
layer.close(loadT)
if(!ret.siteStatus){
layer.msg(ret.msg,{icon:5});
return;
}
layer.close(add)
var sqlData = '';
if (ret.databaseStatus) {
sqlData = "<p class='p1'>数据库账号资料</p>\
<p><span>数据库名:</span><strong>" + ret.databaseUser + "</strong></p>\
<p><span>用户:</span><strong>" + ret.databaseUser + "</strong></p>\
<p><span>密码:</span><strong>" + ret.databasePass + "</strong></p>\
"
}
var pdata = 'dname=' + codename + '&site_name=' + mainDomain + '&php_version='+php_version;
var loadT = layer.msg('<div class="depSpeed">正在提交 <img src="/static/img/ing.gif"></div>',{icon:16,time:0,shade: [0.3, "#000"]});
setTimeout(function(){
GetSpeed();
},2000);
$.post('/plugin?action=a&name=deployment&s=SetupPackage',pdata,function(rdata){
layer.close(loadT)
if(!rdata.status){
layer.msg('源码下载失败!',{icon:5});
return;
}
if(rdata.msg.username != ''){
sqlData = "<p class='p1'>已成功部署,无需安装,请登录修改默认账号密码</p>\
<p><span>用户:</span><strong>" + rdata.msg.username + "</strong></p>\
<p><span>密码:</span><strong>" + rdata.msg.password + "</strong></p>\
"
}
sqlData += "<p><span>访问站点:</span><a class='btlink' href='http://" + mainDomain + rdata.msg.install + "' target='_blank'>http://" + mainDomain + rdata.msg.install + "</a></p>";
layer.open({
type: 1,
area: '600px',
title: '已成功部署'+codename,
closeBtn:2,
shadeClose: false,
content: "<div class='success-msg'>\
<div class='pic'><img src='/static/img/success-pic.png'></div>\
<div class='suc-con'>\
" + sqlData + "\
</div>\
</div>",
});
if ($(".success-msg").height() < 150) {
$(".success-msg").find("img").css({
"width": "150px",
"margin-top": "30px"
});
}
});
});
}
function GetSpeed(){
if(!$('.depSpeed')) return;
$.get('/plugin?action=a&name=deployment&s=GetSpeed',function(speed){
if(speed.status === false) return;
if(speed.name == '下载文件'){
speed = '<p>正在'+speed.name+' <img src="/static/img/ing.gif"></p>\
<div class="bt-progress"><div class="bt-progress-bar" style="width:'+speed.pre+'%"><span class="bt-progress-text">'+speed.pre+'%</span></div></div>\
<p class="f12 c9"><span class="pull-left">'+ToSize(speed.used)+'/'+ToSize(speed.total)+'</span><span class="pull-right">'+ToSize(speed.speed)+'/s</span></p>';
$('.depSpeed').prev().hide();
$('.depSpeed').css({"margin-left":"-37px","width":"380px"});
$('.depSpeed').parents(".layui-layer").css({"margin-left":"-100px"});
}else{
speed = '<p>'+speed.name+'</p>';
$('.depSpeed').prev().show();
$('.depSpeed').removeAttr("style");
$('.depSpeed').parents(".layui-layer").css({"margin-left":"0"});
}
$('.depSpeed').html(speed);
setTimeout(function(){
GetSpeed();
},1000);
});
}
function onekeyCodeSite(codename,versions){
$.post('/site?action=GetPHPVersion',function(rdata){
var php_version = "";
var n = 0;
for(var i=rdata.length-1;i>=0;i--){
if(versions.indexOf(rdata[i].version) != -1){
php_version += "<option value='"+rdata[i].version+"'>"+rdata[i].name+"</option>";
n++;
}
}
if(n == 0){
layer.msg('缺少被支持的PHP版本,请安装!',{icon:5});
return;
}
var con='<form class="bt-form pd20 pb70" id="addweb">\
<div class="line"><span class="tname">域名</span>\
<div class="info-r c4"><textarea id="mainDomain" class="bt-input-text" name="webname" style="width:398px;height:100px;line-height:22px"></textarea>\
<div class="placeholder c9" style="top:10px;left:10px">每行填写一个域名,默认为80端口<br>泛解析添加方法 *.domain.com<br>如另加端口格式为 www.domain.com:88</div>\
</div>\
</div>\
<div class="line"><span class="tname">备注</span>\
<div class="info-r c4"><input id="Wbeizhu" class="bt-input-text" name="ps" placeholder="网站备注" style="width:398px" type="text"> </div>\
</div>\
<div class="line"><span class="tname">根目录</span>\
<div class="info-r c4"><input id="inputPath" class="bt-input-text mr5" name="path" value="/www/wwwroot/" placeholder="网站根目录" style="width:398px" type="text"><span class="glyphicon glyphicon-folder-open cursor" onclick="ChangePath(\'inputPath\')"></span> </div>\
</div>\
<div class="line"><span class="tname">数据库</span>\
<div class="info-r c4">\
<input id="datauser" class="bt-input-text" name="datauser" placeholder="用户名/数据库名" style="width:190px;margin-right:13px" type="text">\
<input id="datapassword" class="bt-input-text" name="datapassword" placeholder="密码" style="width:190px" type="text">\
</div>\
</div>\
<div class="line"><span class="tname">源码</span>\
<input class="bt-input-text mr5 disable" name="code" style="width:100px" value="'+codename+'" disabled>\
<span class="c9">准备为你部署的源码程序</span>\
</div>\
<div class="line"><span class="tname">PHP版本</span>\
<select class="bt-input-text mr5" name="version" id="c_k3" style="width:100px">\
'+php_version+'\
</select>\
<span class="c9">请选择源码程序支持的php版本</span>\
</div>\
<div class="bt-form-submit-btn">\
<button type="button" class="btn btn-danger btn-sm onekeycodeclose">取消</button>\
<button type="button" class="btn btn-success btn-sm" onclick="AddSite(\''+codename+'\')">提交</button>\
</div>\
</from>';
add = layer.open({
type: 1,
title: "宝塔一键部署"+codename,
area: '560px',
closeBtn: 2,
shadeClose: false,
content:con
});
var placeholder = "<div class='placeholder c9' style='top:10px;left:10px'>每行填写一个域名,默认为80端口<br>泛解析添加方法 *.domain.com<br>如另加端口格式为 www.domain.com:88</div>";
$(".onekeycodeclose").click(function(){
layer.close(add);
});
$('#mainDomain').after(placeholder);
$(".placeholder").click(function(){
$(this).hide();
$('#mainDomain').focus();
})
$('#mainDomain').focus(function() {
$(".placeholder").hide();
});
$('#mainDomain').blur(function() {
if($(this).val().length==0){
$(".placeholder").show();
}
});
//FTP账号数据绑定域名
$('#mainDomain').on('input', function() {
var defaultPath = '/www/wwwroot';
var array;
var res,ress;
var str = $(this).val();
var len = str.replace(/[^\x00-\xff]/g, "**").length;
array = str.split("\n");
ress =array[0].split(":")[0];
res = ress.replace(new RegExp(/([-.])/g), '_');
if(res.length > 15) res = res.substr(0,15);
if($("#inputPath").val().substr(0,defaultPath.length) == defaultPath) $("#inputPath").val(defaultPath+'/'+ress);
if(!isNaN(res.substr(0,1))) res = "sql"+res;
if(res.length > 15) res = res.substr(0,15);
$("#Wbeizhu").val(ress);
$("#datauser").val(res);
})
$('#Wbeizhu').on('input', function() {
var str = $(this).val();
var len = str.replace(/[^\x00-\xff]/g, "**").length;
if (len > 20) {
str = str.substring(0, 20);
$(this).val(str);
layer.msg('不要超出20个字符', {
icon: 0
});
}
})
//获取当前时间时间戳,截取后6位
var timestamp = new Date().getTime().toString();
var dtpw = timestamp.substring(7);
$("#datauser").val("sql" + dtpw);
$("#datapassword").val(_getRandomString(10));
});
}
//生成n位随机密码
function _getRandomString(len) {
len = len || 32;
var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'; // 默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1
var maxPos = $chars.length;
var pwd = '';
for (i = 0; i < len; i++) {
pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
}
return pwd;
}
function GetSrcList(){
var loadT = layer.msg('正在获取列表 <img src="/static/img/ing.gif">',{icon:16,time:0,shade: [0.3, '#000']});
var search = $(".searchInput").val();
if(search != ''){
search = '&search=' + search+'&';
}
var type = '';
var istype = getCookie('depType');
if(istype == 'undefined' || istype == 'null' || !istype) {
istype = '0';
}
type = '&type='+istype;
$.get('/plugin?action=a&name=deployment&s=GetList' + search + type,function(mlist){
layer.close(loadT);
tbody = '';
for(var i=0;i<mlist.type.length;i++){
var c = '';
if(istype == mlist.type[i].type){
c = 'class="on"';
}
tbody += '<span typeid="'+mlist.type[i].type+'" '+c+'>'+mlist.type[i].title+'</span>';
}
$(".onekey-type").html(tbody);
var zbody = '';
for(var i=mlist.data.length-1;i>=0;i--){
zbody += '<tr>'
+'<td>'+mlist.data[i].title+'</td>'
+'<td>'+mlist.data[i].version+'</td>'
+'<td>'+mlist.data[i].ps+'</td>'
+'<td>'+mlist.data[i].php+'</td>'
+'<td class="text-right"><a href="javascript:onekeyCodeSite(\''+mlist.data[i].name+'\',\''+mlist.data[i].php+'\');" class="btlink">一键部署</a></td>'
+'</tr>'
}
$("#zipBody").html(zbody);
$(".searchInput").val('');
$(".onekey-menu-sub span").click(function(){
setCookie('depType',$(this).attr('typeid'));
$(this).addClass("on").siblings().removeClass("on");
GetSrcList();
});
});
}
GetSrcList();
</script>

View File

@@ -1,16 +0,0 @@
{
"title":"宝塔一键部署源码",
"tip":"lib",
"name":"deployment",
"type":"扩展",
"ps":"快速部署常用程序!",
"versions":"1.1",
"shell":"deployment.sh",
"checks":"/www/server/panel/plugin/deployment",
"author":"宝塔",
"home":"http://www.bt.cn/bbs",
"date":"2017-07-26",
"default":false,
"display":1,
"pid":"2"
}

View File

@@ -1,52 +0,0 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
install_tmp='/tmp/bt_install.pl'
CN='125.88.182.172'
HK='download.bt.cn'
HK2='103.224.251.67'
US='174.139.221.74'
sleep 0.5;
CN_PING=`ping -c 1 -w 1 $CN|grep time=|awk '{print $7}'|sed "s/time=//"`
HK_PING=`ping -c 1 -w 1 $HK|grep time=|awk '{print $7}'|sed "s/time=//"`
HK2_PING=`ping -c 1 -w 1 $HK2|grep time=|awk '{print $7}'|sed "s/time=//"`
US_PING=`ping -c 1 -w 1 $US|grep time=|awk '{print $7}'|sed "s/time=//"`
echo "$HK_PING $HK" > ping.pl
echo "$HK2_PING $HK2" >> ping.pl
echo "$US_PING $US" >> ping.pl
echo "$CN_PING $CN" >> ping.pl
nodeAddr=`sort -V ping.pl|sed -n '1p'|awk '{print $2}'`
if [ "$nodeAddr" == "" ];then
nodeAddr=$HK2
fi
download_Url=http://$nodeAddr:5880
Install_deployment()
{
mkdir -p /www/server/panel/plugin/deployment
mkdir -p /www/server/panel/plugin/deployment/package
echo '正在安装脚本文件...' > $install_tmp
wget -O /www/server/panel/plugin/deployment/deployment_main.py $download_Url/install/lib/plugin/deployment/deployment_main.py -T 5
wget -O /www/server/panel/plugin/deployment/index.html $download_Url/install/lib/plugin/deployment/index.html -T 5
wget -O /www/server/panel/plugin/deployment/info.json $download_Url/install/lib/plugin/deployment/info.json -T 5
wget -O /www/server/panel/plugin/deployment/list.json $download_Url/install/lib/plugin/deployment/list.json -T 5
wget -O /www/server/panel/plugin/deployment/type.json $download_Url/install/lib/plugin/deployment/type.json -T 5
wget -O /www/server/panel/plugin/deployment/icon.png $download_Url/install/lib/plugin/deployment/icon.png -T 5
wget -O /www/server/panel/static/img/soft_ico/ico-deployment.png $download_Url/install/lib/plugin/deployment/icon.png -T 5
echo '安装完成' > $install_tmp
}
Uninstall_deployment()
{
rm -rf /www/server/panel/plugin/deployment
}
action=$1
if [ "${1}" == 'install' ];then
Install_deployment
else
Uninstall_deployment
fi

View File

@@ -1,495 +0,0 @@
[
{
"name":"niucms",
"title":"NIUCMS",
"type":1,
"version":"3.6",
"md5":"f5ea5a231a7d25d66ee324d60dcdd4f1",
"ext":"pathinfo",
"chmod":"",
"install":"/install/index.php",
"php":"53,54,55,56",
"ps":"智慧城市生活系统(商业软件)",
"config":"",
"username":"",
"password":"",
"run":"/",
"download":"{Download}/niucms.zip"
},
{
"name":"tpt-blog",
"title":"Tpt-Blog",
"type":4,
"version":"1.1",
"md5":"aa195fece581582182e17143f53b2dfc",
"ext":"pathinfo",
"chmod":"",
"install":"/admin.php",
"php":"53,54,55,56,70,71,72",
"ps":"免费开源的博客程序",
"config":"/Application/Common/Conf/db.php",
"username":"admin",
"password":"admin<br>口令:123456",
"run":"/",
"download":"{Download}/tpt-blog_auto.zip"
},
{
"name":"phpcms",
"title":"PHPCMS",
"type":1,
"version":"9.6.3",
"md5":"4de608ae7b74175dd4513911ef7ebf78",
"ext":"pathinfo",
"chmod":"",
"install":"/install",
"php":"52,53,54,55,56,70",
"ps":"PHPCMS内容管理系统",
"config":"",
"username":"",
"password":"",
"run":"/",
"download":"{Download}/phpcms.zip"
},
{
"name":"ecshop_2.7",
"title":"EcShop-2.7",
"type":2,
"version":"2.7.3",
"md5":"9115294f5a458249a5f2c793eab3639c",
"ext":"",
"chmod":"",
"install":"/install",
"php":"52,53",
"ps":"B2C独立网店系统",
"config":"",
"username":"",
"password":"",
"run":"/",
"download":"{Download}/ecshop_2.7.zip"
},
{
"name":"ecshop_3.6",
"title":"EcShop-3.6",
"type":2,
"version":"3.6.0",
"md5":"38fdc7fe8faf67edd91ebfbb8291cbc7",
"ext":"",
"chmod":"",
"install":"/install",
"php":"53,54,55,56",
"ps":"B2C独立网店系统",
"config":"",
"username":"",
"password":"",
"run":"/ecshop",
"download":"{Download}/ecshop_3.6.zip"
},
{
"name":"emlog",
"title":"Emlog",
"type":4,
"version":"5.3.1",
"md5":"cecaa55d8d9644e8d8b7098c836af1ad",
"ext":"",
"chmod":"",
"install":"",
"php":"53,54,55,56",
"ps":"博客程序",
"config":"",
"username":"",
"password":"",
"run":"/",
"download":"{Download}/emlog.zip"
},
{
"name":"empirecms",
"title":"帝国CMS",
"type":1,
"version":"7.2",
"md5":"07bb4ffe56c939170ff080744fc13dd8",
"ext":"",
"chmod":"",
"install":"/e/install",
"php":"52,53,54,55,56",
"ps":"帝国内容管理系统",
"config":"",
"username":"",
"password":"",
"run":"/",
"download":"{Download}/empirecms.zip"
},
{
"name":"jieqiarticle170",
"title":"杰奇1.7",
"type":1,
"version":"1.7",
"md5":"e5168ea7b27f5c6de2a01dbf40f772b7",
"ext":"",
"chmod":"",
"install":"/install",
"php":"52",
"ps":"小说连载程序",
"config":"",
"username":"",
"password":"",
"run":"/",
"download":"{Download}/jieqiarticle170.zip"
},
{
"name":"codeigniter",
"title":"CI框架",
"type":6,
"version":"3.1.5",
"md5":"47a615ef55910a908aff367dc5f59a70",
"ext":"pathinfo",
"chmod":"",
"install":"",
"php":"53,54,55,56,70,71,72",
"ps":"知名PHP框架",
"config":"",
"username":"",
"password":"",
"run":"/public",
"download":"{Download}/codeIgniter.zip"
},
{
"name":"laravel",
"title":"Laravel",
"type":6,
"version":"5.4",
"md5":"988566e8982e835ffa6f7d9ad14b5330",
"ext":"pathinfo",
"chmod":"",
"install":"",
"php":"56,70,71,72",
"ps":"优雅的PHP开发框架",
"config":"",
"username":"",
"password":"",
"run":"/public",
"download":"{Download}/laravel.zip"
},
{
"name":"thinkphp_3.2",
"title":"ThinkPHP-3.2",
"type":6,
"version":"3.2.3",
"md5":"6cd0e16bf478e7df2fc62b6819eebcce",
"ext":"pathinfo",
"chmod":"",
"install":"",
"php":"53,54,55,56",
"ps":"国内知名PHP框架",
"config":"",
"username":"",
"password":"",
"run":"/",
"download":"{Download}/thinkphp-3.2.zip"
},
{
"name":"thinkphp_5.0",
"title":"ThinkPHP-5.0",
"type":6,
"version":"5.0.15",
"md5":"830fd878a802237a968ba36fceb1ae92",
"ext":"pathinfo",
"chmod":"",
"install":"",
"php":"54,55,56,70,71,72",
"ps":"国内知名PHP框架",
"config":"",
"username":"",
"password":"",
"run":"/public",
"download":"{Download}/thinkphp-5.0.zip"
},
{
"name":"dedecms",
"title":"织梦CMS",
"type":1,
"version":"v5.7SP2",
"md5":"6f64be35597dbd2c51b1954f74cfb3ad",
"ext":"",
"chmod":"",
"install":"/install",
"php":"52,53,54,55,56,70,71,72",
"ps":"国内知名内容管理系统",
"config":"",
"username":"",
"password":"",
"run":"/",
"download":"{Download}/dedecms.zip"
},
{
"name":"discuz_x3.4",
"title":"Discuz 3.4",
"type":3,
"version":"x3.4",
"md5":"44c4250ebdf5fa796712f336fbd2ef42",
"ext":"pathinfo",
"chmod":"",
"install":"/install",
"php":"52,53,54,55,56,70,71,72",
"ps":"国内知名论坛程序",
"config":"",
"username":"",
"password":"",
"run":"/",
"download":"{Download}/discuz_x3.4.zip"
},
{
"name":"discuz",
"title":"Discuz",
"type":3,
"version":"x3.3",
"md5":"b31e43927daa00c7c3d92818298943fa",
"ext":"pathinfo",
"chmod":"",
"install":"/install",
"php":"52,53,54,55,56,70,71,72",
"ps":"国内知名论坛程序",
"config":"",
"username":"",
"password":"",
"run":"/",
"download":"{Download}/discuz.zip"
},
{
"name":"typecho",
"title":"Typecho",
"type":4,
"version":"1.1",
"md5":"8b638551974e98994401cda253a3f836",
"ext":"pathinfo",
"chmod":"",
"install":"",
"php":"54,55,56,70,71,72",
"ps":"轻量级博客程序",
"config":"",
"username":"",
"password":"",
"run":"/",
"download":"{Download}/typecho.zip"
},
{
"name":"wordpress",
"title":"Wordpress",
"type":4,
"version":"4.9.2",
"md5":"6d7285257c7df3791255d8c4975804b5",
"ext":"pathinfo",
"chmod":"",
"install":"",
"php":"52,53,54,55,56,70,71,72",
"ps":"最多人用的博客程序",
"config":"",
"username":"",
"password":"",
"run":"/",
"download":"{Download}/wordpress.zip"
},
{
"name":"metInfo",
"title":"<a href='https://www.bt.cn/redirect?name=metInfo' class='btlink' target='_blank'>MetInfo</a>",
"type":1,
"version":"6.0.0",
"md5":"fff363bc0cbb13a5c2dc8c2a652da825",
"ext":"",
"chmod":"",
"install":"",
"php":"52,53,54,55,56,70",
"ps":"企业建站系统<font style='color: #fff;padding: 1px 4px;position: relative;margin-left: 6px;border-radius: 3px;background-color: #fc6d26;'>推荐</font>",
"config":"",
"username":"",
"password":"",
"run":"/",
"download":"{Download}/metInfo.zip"
},
{
"name":"chanzhi",
"title":"<a href='https://www.bt.cn/redirect?name=chanzhi' class='btlink' target='_blank'>蝉知CMS</a>",
"type":1,
"version":"6.5",
"md5":"793af27f2984127c34490229124644b8",
"ext":"pathinfo",
"chmod":"",
"install":"/admin.php",
"php":"53,54,55,56,70,71",
"ps":"开源免费的企业门户系统,CMS系统<font style='color: #fff;padding: 1px 4px;position: relative;margin-left: 6px;border-radius: 3px;background-color: #fc6d26;'>推荐</font>",
"config":"/system/config/my.php",
"username":"admin",
"password":"admin",
"run":"/www",
"download":"{Download}/chanzhi_auto.zip"
},
{
"name":"cscms",
"title":"<a href='https://www.bt.cn/redirect?name=cscms' class='btlink' target='_blank'>CSCMS</a>",
"type":1,
"version":"4.1",
"md5":"12b66ea05ad3b829be916fe541c1dedc",
"ext":"",
"chmod":"",
"install":"/install.php",
"php":"53,54,55,56",
"ps":"多元化内容管理系统<font style='color: #fff;padding: 1px 4px;position: relative;margin-left: 6px;border-radius: 3px;background-color: #fc6d26;'>推荐</font>",
"config":"",
"username":"",
"password":"",
"run":"/",
"download":"{Download}/cscms.zip"
},
{
"name":"kodexplorer",
"title":"<a href='https://www.bt.cn/redirect?name=kodexplorer' class='btlink' target='_blank'>可道云KodExplorer</a>",
"type":1,
"version":"4.06",
"md5":"2907559eac6714394eb9f5a44e005eea",
"ext":"",
"chmod":"",
"install":"/index.php",
"php":"52,53,54,55,56,70,71,72",
"ps":"强大易用的私有云/在线文档管理<font style='color: #fff;padding: 1px 4px;position: relative;margin-left: 6px;border-radius: 3px;background-color: #fc6d26;'>推荐</font>",
"config":"",
"username":"",
"password":"",
"run":"/",
"download":"{Download}/kodexplorer.zip"
},
{
"name":"tipask",
"title":"<a href='https://www.bt.cn/redirect?name=tipask' class='btlink' target='_blank'>Tipask</a>",
"type":1,
"version":"3.2",
"md5":"ae99702f944bf1c60b14065d00a3d676",
"ext":"fileinfo,opcache,pathinfo",
"chmod":"775|storage/app/,775|storage/framework/,775|storage/logs/,775|bootstrap/cache/,664|.env",
"install":"",
"php":"55,56,70,71,72",
"ps":"国内知名问答程序<font style='color: #fff;padding: 1px 4px;position: relative;margin-left: 6px;border-radius: 3px;background-color: #fc6d26;'>推荐</font>",
"config":".env",
"username":"admin@tipask.com",
"password":"tipask",
"run":"/public",
"download":"{Download}/tipask_auto.zip"
},
{
"name":"maccms",
"title":"<a href='https://www.bt.cn/redirect?name=maccms' class='btlink' target='_blank'>苹果CMS</a>",
"type":1,
"version":"8.0",
"md5":"a9801d94d1c592b5bb6d2474e5c0c37e",
"ext":"",
"chmod":"",
"install":"",
"php":"52,53,54,55,56,70,71,72",
"ps":"PHP开源建站系统<font style='color: #fff;padding: 1px 4px;position: relative;margin-left: 6px;border-radius: 3px;background-color: #fc6d26;'>推荐</font>",
"config":"",
"username":"",
"password":"",
"run":"/",
"download":"{Download}/maccms.zip"
},
{
"name":"seacms",
"title":"<a href='https://www.bt.cn/redirect?name=seacms' class='btlink' target='_blank'>海洋CMS</a>",
"type":1,
"version":"6.54",
"md5":"ca43469682b8e5e7cdceba020bf39375",
"ext":"",
"chmod":"",
"install":"/admin",
"php":"52,53,54,55,56.70",
"ps":"完全开源免费的PHP视频管理系统<font style='color: #fff;padding: 1px 4px;position: relative;margin-left: 6px;border-radius: 3px;background-color: #fc6d26;'>推荐</font>",
"config":"data/common.inc.php",
"username":"admin",
"password":"admin",
"run":"/",
"download":"{Download}/seacms_auto.zip"
},
{
"name":"cxxcms",
"title":"<a href='https://www.bt.cn/redirect?name=cxxcms' class='btlink' target='_blank'>程序侠CMS</a>",
"type":1,
"version":"1.1.2",
"md5":"8ad9c0671e41eeed34f046bf2abc3f22",
"ext":"pathinfo",
"chmod":"777|runtime,777|data,777|application/extra,777|application/database.php",
"install":"/admin",
"php":"54,55,56,70,71,72",
"ps":"专业、安全的淘宝客CMS系统<font style='color: #fff;padding: 1px 4px;position: relative;margin-left: 6px;border-radius: 3px;background-color: #fc6d26;'>推荐</font>",
"config":"application/database.php",
"username":"admin",
"password":"chengxuxia.com",
"run":"/",
"download":"{Download}/cxxcms_auto.zip"
},
{
"name":"z-blog",
"title":"<a href='https://www.bt.cn/redirect?name=z-blog' class='btlink' target='_blank'>Z-Blog</a>",
"type":4,
"version":"1.5.2",
"md5":"07faf7fbeecfe9cad10872fe03ab3127",
"ext":"pathinfo",
"chmod":"",
"install":"",
"php":"52,53,54,55,56,70,71,72",
"ps":"国内知名博客程序<font style='color: #fff;padding: 1px 4px;position: relative;margin-left: 6px;border-radius: 3px;background-color: #fc6d26;'>推荐</font>",
"config":"zb_users/c_option.php",
"username":"admin",
"password":"zblogger",
"run":"/",
"download":"{Download}/z-blog_auto.zip"
},
{
"name":"dbshop",
"title":"<a href='https://www.bt.cn/redirect?name=dbshop' class='btlink' target='_blank'>DBShop</a>",
"type":2,
"version":"v1.2",
"md5":"f3c5559fa8eb04bdc9938382658f3a03",
"ext":"pathinfo",
"chmod":"",
"install":"/admin",
"php":"53,54,55,56,70,71,72",
"ps":"专业且良心的商城系统<font style='color: #fff;padding: 1px 4px;position: relative;margin-left: 6px;border-radius: 3px;background-color: #fc6d26;'>推荐</font>",
"config":"data/Database.ini.php",
"username":"admin",
"password":"1234567",
"run":"/",
"download":"{Download}/dbshop_auto.zip"
},
{
"name":"niushop",
"title":"<a href='https://www.bt.cn/redirect?name=niushop' class='btlink' target='_blank'>NiuShop</a>",
"type":2,
"version":"1.1.9",
"md5":"637c6ad54fa4732df35857304e5eeb82",
"ext":"pathinfo",
"chmod":"",
"install":"",
"php":"54,55,56,70",
"ps":"优秀的TP5.0开源商城系统<font style='color: #fff;padding: 1px 4px;position: relative;margin-left: 6px;border-radius: 3px;background-color: #fc6d26;'>推荐</font>",
"config":"application/database.php",
"username":"admin",
"password":"123456",
"run":"/",
"download":"{Download}/niushop_auto.zip"
},
{
"name":"weengine",
"title":"<a href='https://www.bt.cn/redirect?name=weengine' class='btlink' target='_blank'>微擎</a>",
"type":5,
"version":"1.0",
"md5":"8424881fe0e60042df5064ca4638f56c",
"ext":"fileinfo,pathinfo,ioncube",
"chmod":"755|addons,755|api,755|app,755|data,755|attachment,755|framework,755|payment,755|web",
"install":"/index.php",
"php":"53,54,55,56,70,71,72",
"ps":"微信第三方管理引擎<font style='color: #fff;padding: 1px 4px;position: relative;margin-left: 6px;border-radius: 3px;background-color: #fc6d26;'>推荐</font>",
"config":"data/config.php",
"username":"admin",
"password":"we7.cc",
"run":"/",
"download":"{Download}/weengine_auto.zip"
}
]

View File

@@ -1,495 +0,0 @@
[
{
"name":"niucms",
"title":"NIUCMS",
"type":1,
"version":"3.6",
"md5":"f5ea5a231a7d25d66ee324d60dcdd4f1",
"ext":"pathinfo",
"chmod":"",
"install":"/install/index.php",
"php":"53,54,55,56",
"ps":"智慧城市生活系统(商业软件)",
"config":"",
"username":"",
"password":"",
"run":"/",
"download":"{Download}/niucms.zip"
},
{
"name":"tpt-blog",
"title":"Tpt-Blog",
"type":4,
"version":"1.1",
"md5":"aa195fece581582182e17143f53b2dfc",
"ext":"pathinfo",
"chmod":"",
"install":"/admin.php",
"php":"53,54,55,56,70,71,72",
"ps":"免费开源的博客程序",
"config":"/Application/Common/Conf/db.php",
"username":"admin",
"password":"admin<br>口令:123456",
"run":"/",
"download":"{Download}/tpt-blog_auto.zip"
},
{
"name":"phpcms",
"title":"PHPCMS",
"type":1,
"version":"9.6.3",
"md5":"4de608ae7b74175dd4513911ef7ebf78",
"ext":"pathinfo",
"chmod":"",
"install":"/install",
"php":"52,53,54,55,56,70",
"ps":"PHPCMS内容管理系统",
"config":"",
"username":"",
"password":"",
"run":"/",
"download":"{Download}/phpcms.zip"
},
{
"name":"ecshop_2.7",
"title":"EcShop-2.7",
"type":2,
"version":"2.7.3",
"md5":"9115294f5a458249a5f2c793eab3639c",
"ext":"",
"chmod":"",
"install":"/install",
"php":"52,53",
"ps":"B2C独立网店系统",
"config":"",
"username":"",
"password":"",
"run":"/",
"download":"{Download}/ecshop_2.7.zip"
},
{
"name":"ecshop_3.6",
"title":"EcShop-3.6",
"type":2,
"version":"3.6.0",
"md5":"38fdc7fe8faf67edd91ebfbb8291cbc7",
"ext":"",
"chmod":"",
"install":"/install",
"php":"53,54,55,56",
"ps":"B2C独立网店系统",
"config":"",
"username":"",
"password":"",
"run":"/ecshop",
"download":"{Download}/ecshop_3.6.zip"
},
{
"name":"emlog",
"title":"Emlog",
"type":4,
"version":"5.3.1",
"md5":"cecaa55d8d9644e8d8b7098c836af1ad",
"ext":"",
"chmod":"",
"install":"",
"php":"53,54,55,56",
"ps":"博客程序",
"config":"",
"username":"",
"password":"",
"run":"/",
"download":"{Download}/emlog.zip"
},
{
"name":"empirecms",
"title":"帝国CMS",
"type":1,
"version":"7.2",
"md5":"07bb4ffe56c939170ff080744fc13dd8",
"ext":"",
"chmod":"",
"install":"/e/install",
"php":"52,53,54,55,56",
"ps":"帝国内容管理系统",
"config":"",
"username":"",
"password":"",
"run":"/",
"download":"{Download}/empirecms.zip"
},
{
"name":"jieqiarticle170",
"title":"杰奇1.7",
"type":1,
"version":"1.7",
"md5":"e5168ea7b27f5c6de2a01dbf40f772b7",
"ext":"",
"chmod":"",
"install":"/install",
"php":"52",
"ps":"小说连载程序",
"config":"",
"username":"",
"password":"",
"run":"/",
"download":"{Download}/jieqiarticle170.zip"
},
{
"name":"codeigniter",
"title":"CI框架",
"type":6,
"version":"3.1.5",
"md5":"47a615ef55910a908aff367dc5f59a70",
"ext":"pathinfo",
"chmod":"",
"install":"",
"php":"53,54,55,56,70,71,72",
"ps":"知名PHP框架",
"config":"",
"username":"",
"password":"",
"run":"/public",
"download":"{Download}/codeIgniter.zip"
},
{
"name":"laravel",
"title":"Laravel",
"type":6,
"version":"5.4",
"md5":"988566e8982e835ffa6f7d9ad14b5330",
"ext":"pathinfo",
"chmod":"",
"install":"",
"php":"56,70,71,72",
"ps":"优雅的PHP开发框架",
"config":"",
"username":"",
"password":"",
"run":"/public",
"download":"{Download}/laravel.zip"
},
{
"name":"thinkphp_3.2",
"title":"ThinkPHP-3.2",
"type":6,
"version":"3.2.3",
"md5":"6cd0e16bf478e7df2fc62b6819eebcce",
"ext":"pathinfo",
"chmod":"",
"install":"",
"php":"53,54,55,56",
"ps":"国内知名PHP框架",
"config":"",
"username":"",
"password":"",
"run":"/",
"download":"{Download}/thinkphp-3.2.zip"
},
{
"name":"thinkphp_5.0",
"title":"ThinkPHP-5.0",
"type":6,
"version":"5.0.15",
"md5":"830fd878a802237a968ba36fceb1ae92",
"ext":"pathinfo",
"chmod":"",
"install":"",
"php":"54,55,56,70,71,72",
"ps":"国内知名PHP框架",
"config":"",
"username":"",
"password":"",
"run":"/public",
"download":"{Download}/thinkphp-5.0.zip"
},
{
"name":"dedecms",
"title":"织梦CMS",
"type":1,
"version":"v5.7SP2",
"md5":"6f64be35597dbd2c51b1954f74cfb3ad",
"ext":"",
"chmod":"",
"install":"/install",
"php":"52,53,54,55,56,70,71,72",
"ps":"国内知名内容管理系统",
"config":"",
"username":"",
"password":"",
"run":"/",
"download":"{Download}/dedecms.zip"
},
{
"name":"discuz_x3.4",
"title":"Discuz 3.4",
"type":3,
"version":"x3.4",
"md5":"44c4250ebdf5fa796712f336fbd2ef42",
"ext":"pathinfo",
"chmod":"",
"install":"/install",
"php":"52,53,54,55,56,70,71,72",
"ps":"国内知名论坛程序",
"config":"",
"username":"",
"password":"",
"run":"/",
"download":"{Download}/discuz_x3.4.zip"
},
{
"name":"discuz",
"title":"Discuz",
"type":3,
"version":"x3.3",
"md5":"b31e43927daa00c7c3d92818298943fa",
"ext":"pathinfo",
"chmod":"",
"install":"/install",
"php":"52,53,54,55,56,70,71,72",
"ps":"国内知名论坛程序",
"config":"",
"username":"",
"password":"",
"run":"/",
"download":"{Download}/discuz.zip"
},
{
"name":"typecho",
"title":"Typecho",
"type":4,
"version":"1.1",
"md5":"8b638551974e98994401cda253a3f836",
"ext":"pathinfo",
"chmod":"",
"install":"",
"php":"54,55,56,70,71,72",
"ps":"轻量级博客程序",
"config":"",
"username":"",
"password":"",
"run":"/",
"download":"{Download}/typecho.zip"
},
{
"name":"wordpress",
"title":"Wordpress",
"type":4,
"version":"4.9.2",
"md5":"6d7285257c7df3791255d8c4975804b5",
"ext":"pathinfo",
"chmod":"",
"install":"",
"php":"52,53,54,55,56,70,71,72",
"ps":"最多人用的博客程序",
"config":"",
"username":"",
"password":"",
"run":"/",
"download":"{Download}/wordpress.zip"
},
{
"name":"metInfo",
"title":"<a href='https://www.bt.cn/redirect?name=metInfo' class='btlink' target='_blank'>MetInfo</a>",
"type":1,
"version":"6.0.0",
"md5":"fff363bc0cbb13a5c2dc8c2a652da825",
"ext":"",
"chmod":"",
"install":"",
"php":"52,53,54,55,56,70",
"ps":"企业建站系统<font style='color: #fff;padding: 1px 4px;position: relative;margin-left: 6px;border-radius: 3px;background-color: #fc6d26;'>推荐</font>",
"config":"",
"username":"",
"password":"",
"run":"/",
"download":"{Download}/metInfo.zip"
},
{
"name":"chanzhi",
"title":"<a href='https://www.bt.cn/redirect?name=chanzhi' class='btlink' target='_blank'>蝉知CMS</a>",
"type":1,
"version":"6.5",
"md5":"793af27f2984127c34490229124644b8",
"ext":"pathinfo",
"chmod":"",
"install":"/admin.php",
"php":"53,54,55,56,70,71",
"ps":"开源免费的企业门户系统,CMS系统<font style='color: #fff;padding: 1px 4px;position: relative;margin-left: 6px;border-radius: 3px;background-color: #fc6d26;'>推荐</font>",
"config":"/system/config/my.php",
"username":"admin",
"password":"admin",
"run":"/www",
"download":"{Download}/chanzhi_auto.zip"
},
{
"name":"cscms",
"title":"<a href='https://www.bt.cn/redirect?name=cscms' class='btlink' target='_blank'>CSCMS</a>",
"type":1,
"version":"4.1",
"md5":"12b66ea05ad3b829be916fe541c1dedc",
"ext":"",
"chmod":"",
"install":"/install.php",
"php":"53,54,55,56",
"ps":"多元化内容管理系统<font style='color: #fff;padding: 1px 4px;position: relative;margin-left: 6px;border-radius: 3px;background-color: #fc6d26;'>推荐</font>",
"config":"",
"username":"",
"password":"",
"run":"/",
"download":"{Download}/cscms.zip"
},
{
"name":"kodexplorer",
"title":"<a href='https://www.bt.cn/redirect?name=kodexplorer' class='btlink' target='_blank'>可道云KodExplorer</a>",
"type":1,
"version":"4.06",
"md5":"2907559eac6714394eb9f5a44e005eea",
"ext":"",
"chmod":"",
"install":"/index.php",
"php":"52,53,54,55,56,70,71,72",
"ps":"强大易用的私有云/在线文档管理<font style='color: #fff;padding: 1px 4px;position: relative;margin-left: 6px;border-radius: 3px;background-color: #fc6d26;'>推荐</font>",
"config":"",
"username":"",
"password":"",
"run":"/",
"download":"{Download}/kodexplorer.zip"
},
{
"name":"tipask",
"title":"<a href='https://www.bt.cn/redirect?name=tipask' class='btlink' target='_blank'>Tipask</a>",
"type":1,
"version":"3.2",
"md5":"ae99702f944bf1c60b14065d00a3d676",
"ext":"fileinfo,opcache,pathinfo",
"chmod":"775|storage/app/,775|storage/framework/,775|storage/logs/,775|bootstrap/cache/,664|.env",
"install":"",
"php":"55,56,70,71,72",
"ps":"国内知名问答程序<font style='color: #fff;padding: 1px 4px;position: relative;margin-left: 6px;border-radius: 3px;background-color: #fc6d26;'>推荐</font>",
"config":".env",
"username":"admin@tipask.com",
"password":"tipask",
"run":"/public",
"download":"{Download}/tipask_auto.zip"
},
{
"name":"maccms",
"title":"<a href='https://www.bt.cn/redirect?name=maccms' class='btlink' target='_blank'>苹果CMS</a>",
"type":1,
"version":"8.0",
"md5":"a9801d94d1c592b5bb6d2474e5c0c37e",
"ext":"",
"chmod":"",
"install":"",
"php":"52,53,54,55,56,70,71,72",
"ps":"PHP开源建站系统<font style='color: #fff;padding: 1px 4px;position: relative;margin-left: 6px;border-radius: 3px;background-color: #fc6d26;'>推荐</font>",
"config":"",
"username":"",
"password":"",
"run":"/",
"download":"{Download}/maccms.zip"
},
{
"name":"seacms",
"title":"<a href='https://www.bt.cn/redirect?name=seacms' class='btlink' target='_blank'>海洋CMS</a>",
"type":1,
"version":"6.54",
"md5":"ca43469682b8e5e7cdceba020bf39375",
"ext":"",
"chmod":"",
"install":"/admin",
"php":"52,53,54,55,56.70",
"ps":"完全开源免费的PHP视频管理系统<font style='color: #fff;padding: 1px 4px;position: relative;margin-left: 6px;border-radius: 3px;background-color: #fc6d26;'>推荐</font>",
"config":"data/common.inc.php",
"username":"admin",
"password":"admin",
"run":"/",
"download":"{Download}/seacms_auto.zip"
},
{
"name":"cxxcms",
"title":"<a href='https://www.bt.cn/redirect?name=cxxcms' class='btlink' target='_blank'>程序侠CMS</a>",
"type":1,
"version":"1.1.2",
"md5":"8ad9c0671e41eeed34f046bf2abc3f22",
"ext":"pathinfo",
"chmod":"777|runtime,777|data,777|application/extra,777|application/database.php",
"install":"/admin",
"php":"54,55,56,70,71,72",
"ps":"专业、安全的淘宝客CMS系统<font style='color: #fff;padding: 1px 4px;position: relative;margin-left: 6px;border-radius: 3px;background-color: #fc6d26;'>推荐</font>",
"config":"application/database.php",
"username":"admin",
"password":"chengxuxia.com",
"run":"/",
"download":"{Download}/cxxcms_auto.zip"
},
{
"name":"z-blog",
"title":"<a href='https://www.bt.cn/redirect?name=z-blog' class='btlink' target='_blank'>Z-Blog</a>",
"type":4,
"version":"1.5.2",
"md5":"07faf7fbeecfe9cad10872fe03ab3127",
"ext":"pathinfo",
"chmod":"",
"install":"",
"php":"52,53,54,55,56,70,71,72",
"ps":"国内知名博客程序<font style='color: #fff;padding: 1px 4px;position: relative;margin-left: 6px;border-radius: 3px;background-color: #fc6d26;'>推荐</font>",
"config":"zb_users/c_option.php",
"username":"admin",
"password":"zblogger",
"run":"/",
"download":"{Download}/z-blog_auto.zip"
},
{
"name":"dbshop",
"title":"<a href='https://www.bt.cn/redirect?name=dbshop' class='btlink' target='_blank'>DBShop</a>",
"type":2,
"version":"v1.2",
"md5":"f3c5559fa8eb04bdc9938382658f3a03",
"ext":"pathinfo",
"chmod":"",
"install":"/admin",
"php":"53,54,55,56,70,71,72",
"ps":"专业且良心的商城系统<font style='color: #fff;padding: 1px 4px;position: relative;margin-left: 6px;border-radius: 3px;background-color: #fc6d26;'>推荐</font>",
"config":"data/Database.ini.php",
"username":"admin",
"password":"1234567",
"run":"/",
"download":"{Download}/dbshop_auto.zip"
},
{
"name":"niushop",
"title":"<a href='https://www.bt.cn/redirect?name=niushop' class='btlink' target='_blank'>NiuShop</a>",
"type":2,
"version":"1.1.9",
"md5":"637c6ad54fa4732df35857304e5eeb82",
"ext":"pathinfo",
"chmod":"",
"install":"",
"php":"54,55,56,70",
"ps":"优秀的TP5.0开源商城系统<font style='color: #fff;padding: 1px 4px;position: relative;margin-left: 6px;border-radius: 3px;background-color: #fc6d26;'>推荐</font>",
"config":"application/database.php",
"username":"admin",
"password":"123456",
"run":"/",
"download":"{Download}/niushop_auto.zip"
},
{
"name":"weengine",
"title":"<a href='https://www.bt.cn/redirect?name=weengine' class='btlink' target='_blank'>微擎</a>",
"type":5,
"version":"1.0",
"md5":"8424881fe0e60042df5064ca4638f56c",
"ext":"fileinfo,pathinfo,ioncube",
"chmod":"755|addons,755|api,755|app,755|data,755|attachment,755|framework,755|payment,755|web",
"install":"/index.php",
"php":"53,54,55,56,70,71,72",
"ps":"微信第三方管理引擎<font style='color: #fff;padding: 1px 4px;position: relative;margin-left: 6px;border-radius: 3px;background-color: #fc6d26;'>推荐</font>",
"config":"data/config.php",
"username":"admin",
"password":"we7.cc",
"run":"/",
"download":"{Download}/weengine_auto.zip"
}
]

View File

@@ -1,37 +0,0 @@
[
{
"title":"推荐",
"type":0,
"ps":""
},
{
"title":"建站",
"type":1,
"ps":""
},
{
"title":"商城",
"type":2,
"ps":""
},
{
"title":"论坛",
"type":3,
"ps":""
},
{
"title":"博客",
"type":4,
"ps":""
},
{
"title":"微信",
"type":5,
"ps":""
},
{
"title":"框架",
"type":6,
"ps":""
}
]

7
plugins/gae/app/app.yaml Normal file
View File

@@ -0,0 +1,7 @@
runtime: php55
api_version: 1
threadsafe: true
handlers:
- url: /.*
script: helloworld.php

View File

@@ -0,0 +1,3 @@
<?php
echo 'Hello, GAE!';

BIN
plugins/gae/ico.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

27
plugins/gae/index.html Executable file
View File

@@ -0,0 +1,27 @@
<div class="bt-form">
<div class="bt-w-main">
<div class="bt-w-menu">
<p class="bgw" onclick="readme();">插件说明</p>
<p onclick="projectList();">项目列表</p>
</div>
<div class="bt-w-con pd15">
<div class="soft-man-con">
</div>
</div>
</div>
</div>
<script type="text/javascript">
$.getScript( "/plugins/file?name=gae&f=js/gae.js");
resetPluginWinWidth(720);
readme();
function readme(){
var html = '<p>开发文档:https://cloud.google.com/sdk/docs/</p>';
html += '<p>* 注意:本插件通过Google <a class="btlink" target="_blank" href="https://cloud.google.com/sdk/docs/scripting-gcloud">JSON 格式</a>赋权免交互式</p>';
html += '<p>* 注意:添加:gcloud auth activate-service-account --key-file [KEY_FILE]</p>';
html += '<p>* 注意:设置后,一般同步项目命令:gcloud app deploy << y</p>';
html += '<p>* 注意:可以查看命令,把命令加入到脚本中...自动更新。</p>';
$('.bt-w-main .soft-man-con').html(html);
}
</script>

240
plugins/gae/index.py Executable file
View File

@@ -0,0 +1,240 @@
# coding: utf-8
import time
import random
import os
import json
import re
import sys
sys.path.append(os.getcwd() + "/class/core")
import mw
def getPluginName():
return 'gae'
def getPluginDir():
return mw.getPluginDir() + '/' + getPluginName()
def getServerDir():
return mw.getServerDir() + '/' + getPluginName()
def getInitDFile():
if app_debug:
return '/tmp/' + getPluginName()
return '/etc/init.d/' + getPluginName()
def getArgs():
args = sys.argv[2:]
tmp = {}
args_len = len(args)
if args_len == 1:
t = args[0].strip('{').strip('}')
t = t.split(':')
tmp[t[0]] = t[1]
elif args_len > 1:
for i in range(len(args)):
t = args[i].split(':')
tmp[t[0]] = t[1]
return tmp
def status():
return 'start'
def getAllProjectList(search):
path = mw.getWwwDir()
dlist = []
if os.path.exists(path):
for filename in os.listdir(path):
tmp = {}
filePath = path + '/' + filename
if os.path.isdir(filePath):
if search == '':
tmp['name'] = filename
tmp['dir'] = filePath
dlist.append(tmp)
else:
if filename.find(search) != -1:
tmp['name'] = filename
tmp['dir'] = filePath
dlist.append(tmp)
return dlist
def checkProjectListIsSet(data):
dlen = len(data)
for x in range(dlen):
path = getServerDir() + '/' + data[x]['name'] + '.json'
if os.path.exists(path):
if os.path.getsize(path) == 0:
data[x]['isset'] = False
else:
data[x]['isset'] = True
else:
data[x]['isset'] = False
return data
def projectListEdit():
args = getArgs()
if not 'name' in args:
return 'missing name!'
file = getServerDir() + '/' + args['name'] + '.json'
if not os.path.exists(file):
mw.execShell('touch ' + file)
return file
def projectListDel():
args = getArgs()
if not 'name' in args:
return 'missing name!'
file = getServerDir() + '/' + args['name'] + '.json'
if os.path.exists(file):
content = mw.readFile(file)
contentObj = json.loads(content)
asyncUser = contentObj['client_email']
cmd = getServerDir() + '/google-cloud-sdk/bin/'
mw.execShell(cmd + 'gcloud auth revoke ' + asyncUser)
mw.execShell('rm -rf ' + file)
return 'ok'
def checkUserExist(cmd, user):
data = mw.execShell(cmd + 'gcloud auth list | grep ' + user)
if data[0] == '':
return False
return True
def projectListAsync():
import subprocess
args = getArgs()
if not 'name' in args:
return 'missing name!'
file = getServerDir() + '/' + args['name'] + '.json'
if not os.path.exists(file):
return 'not configured file!'
content = mw.readFile(file)
contentObj = json.loads(content)
asyncUser = contentObj['client_email']
cmd = getServerDir() + '/google-cloud-sdk/bin/'
projectDir = mw.getWwwDir() + '/' + args['name']
if not checkUserExist(cmd, asyncUser):
mw.execShell(
cmd + 'gcloud auth activate-service-account --key-file ' + file)
pName = contentObj['project_id']
setUserCmd = cmd + 'gcloud config set account ' + asyncUser
setUserCmd += ' && ' + cmd + 'gcloud config set project ' + pName
asyncCmd = setUserCmd + ' && cd ' + projectDir + \
' && ' + cmd + 'gcloud app deploy << y'
taskAdd = (None, 'gae[async]',
'execshell', '0', time.strftime('%Y-%m-%d %H:%M:%S'), asyncCmd)
mw.M('tasks').add('id,name,type,status,addtime, execstr', taskAdd)
return 'ok'
def projectListCmd():
args = getArgs()
if not 'name' in args:
return 'missing name!'
file = getServerDir() + '/' + args['name'] + '.json'
if not os.path.exists(file):
return 'not configured file!'
content = mw.readFile(file)
contentObj = json.loads(content)
asyncUser = contentObj['client_email']
cmd = getServerDir() + '/google-cloud-sdk/bin/'
pName = contentObj['project_id']
projectDir = mw.getWwwDir() + '/' + args['name']
setUserCmd = 'sudo ' + cmd + 'gcloud config set account ' + asyncUser
setUserCmd += ' && sudo ' + cmd + 'gcloud config set project ' + pName
asyncCmd = setUserCmd + ' && sudo cd ' + projectDir + \
' && sudo ' + cmd + 'gcloud app deploy <<y'
return asyncCmd
def projectListUrl():
args = getArgs()
if not 'name' in args:
return 'missing name!'
file = getServerDir() + '/' + args['name'] + '.json'
if not os.path.exists(file):
return 'not configured file!'
content = mw.readFile(file)
contentObj = json.loads(content)
asyncUser = contentObj['client_email']
plist = asyncUser.split('@')
url = 'https://' + plist[0] + '.appspot.com'
return url
def projectList():
args = getArgs()
page = 1
page_size = 10
search = ''
if 'page' in args:
page = int(args['page'])
if 'page_size' in args:
page_size = int(args['page_size'])
if 'search' in args:
search = args['search']
dlist = getAllProjectList(search)
dlist_sum = len(dlist)
start = (page - 1) * page_size
ret_data = dlist[start:start + page_size]
ret_data = checkProjectListIsSet(ret_data)
data = {}
data['data'] = ret_data
data['list'] = mw.getPage(
{'count': dlist_sum, 'p': page, 'row': 10, 'tojs': 'projectList'})
return mw.getJson(data)
if __name__ == "__main__":
func = sys.argv[1]
if func == 'status':
print status()
elif func == 'project_list':
print projectList()
elif func == 'project_list_edit':
print projectListEdit()
elif func == 'project_list_del':
print projectListDel()
elif func == 'project_list_async':
print projectListAsync()
elif func == 'project_list_cmd':
print projectListCmd()
elif func == 'project_list_url':
print projectListUrl()
else:
print 'error'

14
plugins/gae/info.json Executable file
View File

@@ -0,0 +1,14 @@
{
"title":"GAE",
"tip":"soft",
"name":"gae",
"ps":"GAE是Google用于WEB应用程序的开发和托管的平台",
"versions": "0.1",
"shell":"install.sh",
"checks":"server/gae",
"path":"server/gae",
"author":"mdserver-web",
"home":"https://github.com/midoks/mdserver-web",
"date":"2018-11-30",
"pid":"5"
}

51
plugins/gae/install.sh Executable file
View File

@@ -0,0 +1,51 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
Install_gae()
{
mkdir -p ${serverPath}/gae
mkdir -p ${serverPath}/source/gae
os=`uname`
if [ "Darwin" == "$os" ];then
file=google-cloud-sdk-218.0.0-darwin-x86_64.tar.gz
else
file=google-cloud-sdk-218.0.0-linux-x86_64.tar.gz
fi
if [ ! -f $serverPath/source/gae/$file ];then
wget -O $serverPath/source/gae/$file https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/$file
fi
if [ ! -d $serverPath/source/gae/google-cloud-sdk ];then
cd $serverPath/source/gae && tar zxvf $file
fi
cp -r $serverPath/source/gae/google-cloud-sdk ${serverPath}/gae
echo "${1}" > ${serverPath}/gae/version.pl
echo '安装完成' > $install_tmp
}
Uninstall_gae()
{
rm -rf ${serverPath}/gae
echo '卸载完成' > $install_tmp
}
action=$1
if [ "${1}" == 'install' ];then
Install_gae $2
else
Uninstall_gae $2
fi

164
plugins/gae/js/gae.js Executable file
View File

@@ -0,0 +1,164 @@
function gaePost(method,args,callback){
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
$.post('/plugins/run', {name:'gae', func:method, args:JSON.stringify(args)}, function(data) {
layer.close(loadT);
if (!data.status){
layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
if(typeof(callback) == 'function'){
callback(data);
}
},'json');
}
function projectList(page, search){
var _data = {};
_data['page_size'] = 10;
if (typeof(search) != 'undefined'){
_data['search'] = search;
}
if (typeof(page) != 'undefined'){
_data['page'] = page;
setCookie('gaeProjectListPage',page);
} else {
_data['page'] = 1;
cookie_page = getCookie('gaeProjectListPage')
if (cookie_page >0){
_data['page'] = cookie_page;
}
}
gaePost('project_list', _data, function(data){
var rdata = $.parseJSON($.trim(data.data));
// console.log(rdata);
content = '<div><input class="bt-input-text mr5" type="text" placeholder="查找项目" id="project_find" style="height: 28px; border-radius: 3px;width: 435px;">';
content += '<button class="btn btn-success btn-sm" onclick="projectListFind();">查找</button></div>';
content += '<div class="divtable" style="margin-top:5px;"><table class="table table-hover" width="100%" cellspacing="0" cellpadding="0" border="0">';
content += '<thead><tr>';
content += '<th>项目名</th>';
content += '<th>地址</th>';
content += '<th>操作(<a class="btlink" target="_blank" href="https://console.cloud.google.com/">官方地址</a>)</th>';
content += '</tr></thead>';
content += '<tbody>';
ulist = rdata.data;
for (i in ulist){
setName = ulist[i]['isset'] ? '已设置' : '设置';
content += '<tr><td>'+ulist[i]['name']+'</td>'+
'<td>'+ulist[i]['dir']+'</td><td>'+
'<a class="btlink" onclick="gaeSetProject(\''+ulist[i]['name']+'\','+ulist[i]['isset']+')">'+setName+'</a> | ' +
'<a class="btlink" onclick="gaeAsyncProject(\''+ulist[i]['name']+'\')">同步</a> | ' +
'<a class="btlink" target="_blank" onclick="gaeProjectCmd(\''+ulist[i]['name']+'\')">命令</a> | ' +
'<a class="btlink" target="_blank" onclick="gaeProjectUrl(\''+ulist[i]['name']+'\')">访问</a>' +
'</td></tr>';
}
content += '</tbody>';
content += '</table></div>';
page = '<div class="dataTables_paginate paging_bootstrap pagination" style="margin-top:0px;"><ul id="softPage" class="page"><div>';
page += rdata.list;
page += '</div></ul></div>';
content += page;
$(".soft-man-con").html(content);
});
}
function projectListFind(){
var search = $('#project_find').val();
if (search == ''){
layer.msg('查找字符不能为空!',{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
projectList(1, search);
}
function gaeSetProject(pname,isset){
var html = '';
if (isset){
html += '<button onclick="gaeProjectDel(\''+pname+'\')" class="btn btn-default btn-sm">删除</button>';
}
html += '<button onclick="gaeProjectEdit(\''+pname+'\')" class="btn btn-default btn-sm">编辑</button>';
var loadOpen = layer.open({
type: 1,
title: '['+ pname +']密钥设置',
area: '240px',
content:'<div class="change-default pd20">'+html+'</div>'
});
}
function gaeProjectEdit(pname){
gaePost('project_list_edit', {'name':pname}, function(data){
onlineEditFile(0,data.data);
});
}
function gaeProjectDel(pname){
gaePost('project_list_del', {'name':pname}, function(data){
showMsg('删除成功!',function(){
$('.layui-layer-close1').click();
projectList();
},{icon:0,time:2000,shade: [0.3, '#000']});
});
}
function gaeAsyncProject(pname){
gaePost('project_list_async', {'name':pname}, function(data){
if (data.data !='ok'){
layer.msg(data.data,{icon:0,time:2000,shade: [0.3, '#000']});
} else {
layer.msg('加入任务,请自行观察!',{icon:1,time:2000,shade: [0.3, '#000']});
}
$('.layui-layer-close1').click();
});
}
function stringToEntity(str,radix){
let arr=[]
//返回的字符实体默认10进制,也可以选择16进制
radix=radix||0
for(let i=0;i<str.length;i++){
arr.push((!radix?'&#'+str.charCodeAt(i):'&#x'+str.charCodeAt(i).toString(16))+';')
}
let tmp=arr.join('')
// console.log(`'${str}' 转实体为 '${tmp}'`)
return tmp
}
function gaeProjectCmd(pname){
gaePost('project_list_cmd', {'name':pname}, function(data){
var data_str = data.data;
if (data_str.indexOf('gcloud') !== -1){
layer.msg(stringToEntity(data.data),{icon:1,time:5000,shade: [0.3, '#000']});
} else {
layer.msg(data.data,{icon:0,time:5000,shade: [0.3, '#000']});
}
});
}
function gaeProjectUrl(pname){
gaePost('project_list_url', {'name':pname}, function(data){
var data_str = data.data;
if (data_str.indexOf('appspot.com') !== -1){
window.open(data.data);
} else {
layer.msg(data.data,{icon:0,time:5000,shade: [0.3, '#000']});
}
});
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@@ -0,0 +1,21 @@
<div class="bt-form">
<div class="bt-w-main">
<div class="bt-w-menu">
<p class="bgw" onclick="pluginService('go-fastdfs-web');">服务</p>
<p onclick="pluginInitD('go-fastdfs-web');">自启动</p>
<p onclick="pluginConfig('go-fastdfs-web');">配置</p>
<p onclick="pluginLogs('go-fastdfs-web','','run_log');">运行日志</p>
<p onclick="pRead()">说明</p>
</div>
<div class="bt-w-con pd15">
<div class="soft-man-con"></div>
</div>
</div>
</div>
<script type="text/javascript">
resetPluginWinWidth(700);
$.getScript( "/plugins/file?name=go-fastdfs-web&f=js/fastdfs.js", function() {
pluginService('go-fastdfs');
});
</script>

196
plugins/go-fastdfs-web/index.py Executable file
View File

@@ -0,0 +1,196 @@
# coding: utf-8
import time
import random
import os
import json
import re
import sys
import subprocess
import threading
sys.path.append(os.getcwd() + "/class/core")
import mw
app_debug = False
if mw.isAppleSystem():
app_debug = True
def getPluginName():
return 'go-fastdfs-web'
def getPluginDir():
return mw.getPluginDir() + '/' + getPluginName()
def getServerDir():
return mw.getServerDir() + '/' + getPluginName()
def getInitDFile():
if app_debug:
return '/tmp/' + getPluginName()
return '/etc/init.d/' + getPluginName()
def getInitDTpl():
return getPluginDir() + "/init.d/" + getPluginName() + ".tpl"
def getLog():
return getServerDir() + "/log/fileserver.log"
def gfBreakpointLog():
return getServerDir() + "/log/tusd.log"
def getArgs():
args = sys.argv[2:]
tmp = {}
args_len = len(args)
if args_len == 1:
t = args[0].strip('{').strip('}')
t = t.split(':')
tmp[t[0]] = t[1]
elif args_len > 1:
for i in range(len(args)):
t = args[i].split(':')
tmp[t[0]] = t[1]
return tmp
def checkArgs(data, ck=[]):
for i in range(len(ck)):
if not ck[i] in data:
return (False, mw.returnJson(False, '参数:(' + ck[i] + ')没有!'))
return (True, mw.returnJson(True, 'ok'))
def status():
pn = getPluginName()
data = mw.execShell(
"ps -ef|grep " + pn + " | grep -v grep | grep -v python | awk '{print $2}'")
if data[0] == '':
return 'stop'
return 'start'
def initDreplace():
file_tpl = getInitDTpl()
service_path = os.path.dirname(os.getcwd())
initD_path = getServerDir() + '/init.d'
if not os.path.exists(initD_path):
os.mkdir(initD_path)
file_bin = initD_path + '/' + getPluginName()
if not os.path.exists(file_bin):
content = mw.readFile(file_tpl)
content = content.replace('{$SERVER_PATH}', service_path)
mw.writeFile(file_bin, content)
mw.execShell('chmod +x ' + file_bin)
return file_bin
def start():
file = initDreplace()
data = mw.execShell(file + ' start')
if data[1] == '':
return 'ok'
return 'fail'
def stop():
file = initDreplace()
data = mw.execShell(file + ' stop')
if data[1] == '':
return 'ok'
return 'fail'
def restart():
file = initDreplace()
data = mw.execShell(file + ' restart')
if data[1] == '':
return 'ok'
return 'fail'
def reload():
file = initDreplace()
data = mw.execShell(file + ' reload')
if data[1] == '':
return 'ok'
return 'fail'
def initdStatus():
initd_bin = getInitDFile()
if os.path.exists(initd_bin):
return 'ok'
return 'fail'
def initdInstall():
import shutil
source_bin = initDreplace()
initd_bin = getInitDFile()
shutil.copyfile(source_bin, initd_bin)
mw.execShell('chmod +x ' + initd_bin)
if not app_debug:
mw.execShell('chkconfig --add ' + getPluginName())
return 'ok'
def initdUinstall():
if not app_debug:
mw.execShell('chkconfig --del ' + getPluginName())
initd_bin = getInitDFile()
if os.path.exists(initd_bin):
os.remove(initd_bin)
return 'ok'
def gfConf():
return getServerDir() + "/config/application-prod.properties"
def getLog():
return getServerDir() + "/logs/go-fastdfs-web.log"
if __name__ == "__main__":
func = sys.argv[1]
if func == 'status':
print status()
elif func == 'start':
print start()
elif func == 'stop':
print stop()
elif func == 'restart':
print restart()
elif func == 'reload':
print reload()
elif func == 'initd_status':
print initdStatus()
elif func == 'initd_install':
print initdInstall()
elif func == 'initd_uninstall':
print initdUinstall()
elif func == 'run_log':
print getLog()
elif func == 'conf':
print gfConf()
else:
print 'error'

View File

@@ -0,0 +1,16 @@
{
"id":10,
"title":"go-fastdfs-web",
"tip":"soft",
"name":"go-fastdfs-web",
"type":"软件",
"ps":"Go-Fastdfs web管理平台",
"versions":"1.1.2",
"shell":"install.sh",
"checks":"server/go-fastdfs-web",
"path": "server/go-fastdfs-web",
"author":"midoks",
"home":"https://github.com/perfree/go-fastdfs-web",
"date":"2019-08-07",
"pid":"2"
}

View File

@@ -0,0 +1,91 @@
#!/bin/bash
# chkconfig: 2345 55 25
# description: go-fastdfs-web Cloud Service
### BEGIN INIT INFO
# Provides: bt
# Required-Start: $all
# Required-Stop: $all
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: starts go-fastdfs-web
# Description: starts the go-fastdfs-web
### END INIT INFO
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
SpringBoot=go-fastdfs-web.jar
gf_path={$SERVER_PATH}/go-fastdfs-web/$SpringBoot
if [ "$1" = "" ];
then
echo -e "\033[0;31m 未输入操作名 \033[0m \033[0;34m {start|stop|restart|status} \033[0m"
exit 1
fi
if [ "$SpringBoot" = "" ];
then
echo -e "\033[0;31m 未输入应用名 \033[0m"
exit 1
fi
function start()
{
count=`ps -ef |grep java|grep $SpringBoot|grep -v grep|wc -l`
if [ $count != 0 ];then
echo "$SpringBoot is running..."
else
echo "Start $SpringBoot success..."
cd $gf_path
nohup java -jar $SpringBoot > /dev/null 2>&1 &
fi
}
function stop()
{
echo "Stop $SpringBoot"
boot_id=`ps -ef |grep java|grep $SpringBoot|grep -v grep|awk '{print $2}'`
count=`ps -ef |grep java|grep $SpringBoot|grep -v grep|wc -l`
if [ $count != 0 ];then
kill $boot_id
count=`ps -ef |grep java|grep $SpringBoot|grep -v grep|wc -l`
boot_id=`ps -ef |grep java|grep $SpringBoot|grep -v grep|awk '{print $2}'`
kill -9 $boot_id
fi
}
function restart()
{
stop
sleep 2
start
}
function status()
{
count=`ps -ef |grep java|grep $SpringBoot|grep -v grep|wc -l`
if [ $count != 0 ];then
echo "$SpringBoot is running..."
else
echo "$SpringBoot is not running..."
fi
}
case $1 in
start)
start;;
stop)
stop;;
restart)
restart;;
status)
status;;
*)
echo -e "\033[0;31m Usage: \033[0m \033[0;34m sh $0 {start|stop|restart|status} {SpringBootJarName} \033[0m
\033[0;31m Example: \033[0m
\033[0;33m sh $0 start esmart-test.jar \033[0m"
esac

View File

@@ -0,0 +1,54 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
sysName=`uname`
install_tmp=${rootPath}/tmp/mw_install.pl
action=$1
version=$2
Install_gf()
{
echo '正在安装脚本文件...' > $install_tmp
mkdir -p $serverPath/go-fastdfs-web
FF_DIR=${serverPath}/go-fastdfs-web
cd $FF_DIR
if [ $sysName == 'Darwin' ]; then
FF_SS_DIR=${serverPath}/source/go-fastdfs-web
mkdir -p $FF_SS_DIR
if [ ! -f $FF_SS_DIR/go-fastdfs-web-1.1.2.tar.gz ]; then
wget -O $FF_SS_DIR/go-fastdfs-web-1.1.2.tar.gz https://github.com/perfree/go-fastdfs-web/releases/download/1.1.2/go-fastdfs-web-1.1.2.tar.gz
fi
cd $FF_SS_DIR
if [ ! -d $FF_SS_DIR/go-fastdfs-web ]; then
tar -zxvf $FF_SS_DIR/go-fastdfs-web-1.1.2.tar.gz
fi
if [ ! -d $FF_DIR/config ];then
cp -rf $FF_SS_DIR/go-fastdfs-web/* $FF_DIR/
fi
fi
echo "$version" > $FF_DIR/version.pl
echo '安装完成' > $install_tmp
}
Uninstall_gf()
{
rm -rf $serverPath/go-fastdfs-web
echo "卸载完成" > $install_tmp
}
if [ "${1}" == 'install' ];then
Install_gf $version
else
Uninstall_gf $version
fi

View File

@@ -0,0 +1,47 @@
function str2Obj(str){
var data = {};
kv = str.split('&');
for(i in kv){
v = kv[i].split('=');
data[v[0]] = v[1];
}
return data;
}
function pPost(method,args,callback, title){
var _args = null;
if (typeof(args) == 'string'){
_args = JSON.stringify(str2Obj(args));
} else {
_args = JSON.stringify(args);
}
var _title = '正在获取...';
if (typeof(title) != 'undefined'){
_title = title;
}
var loadT = layer.msg(_title, { icon: 16, time: 0, shade: 0.3 });
$.post('/plugins/run', {name:'go-fastdfs-web', func:method, args:_args}, function(data) {
layer.close(loadT);
if (!data.status){
layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
if(typeof(callback) == 'function'){
callback(data);
}
},'json');
}
function pRead(){
var readme = '<ul class="help-info-text c7">';
readme += '<li>根据配置查看,开启相应防火墙端口</li>';
readme += '</ul>';
$('.soft-man-con').html(readme);
}

BIN
plugins/go-fastdfs/ico.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

23
plugins/go-fastdfs/index.html Executable file
View File

@@ -0,0 +1,23 @@
<div class="bt-form">
<div class="bt-w-main">
<div class="bt-w-menu">
<p class="bgw" onclick="pluginService('go-fastdfs');">服务</p>
<p onclick="pluginInitD('go-fastdfs');">自启动</p>
<p onclick="pluginConfig('go-fastdfs');">配置文件</p>
<p onclick="gfConfigSet()">重要配置查看</p>
<p onclick="pluginLogs('go-fastdfs','','run_log');">运行日志</p>
<p onclick="pluginLogs('go-fastdfs','','breakpoint_log');">断点日志</p>
<p onclick="pRead()">说明</p>
</div>
<div class="bt-w-con pd15">
<div class="soft-man-con"></div>
</div>
</div>
</div>
<script type="text/javascript">
resetPluginWinWidth(700);
$.getScript( "/plugins/file?name=go-fastdfs&f=js/fastdfs.js", function() {
pluginService('go-fastdfs');
});
</script>

224
plugins/go-fastdfs/index.py Executable file
View File

@@ -0,0 +1,224 @@
# coding: utf-8
import time
import random
import os
import json
import re
import sys
import subprocess
import threading
sys.path.append(os.getcwd() + "/class/core")
import mw
app_debug = False
if mw.isAppleSystem():
app_debug = True
def getPluginName():
return 'go-fastdfs'
def getPluginDir():
return mw.getPluginDir() + '/' + getPluginName()
def getServerDir():
return mw.getServerDir() + '/' + getPluginName()
def getInitDFile():
if app_debug:
return '/tmp/' + getPluginName()
return '/etc/init.d/' + getPluginName()
def getInitDTpl():
return getPluginDir() + "/init.d/" + getPluginName() + ".tpl"
def getLog():
return getServerDir() + "/log/fileserver.log"
def gfBreakpointLog():
return getServerDir() + "/log/tusd.log"
def getArgs():
args = sys.argv[2:]
tmp = {}
args_len = len(args)
if args_len == 1:
t = args[0].strip('{').strip('}')
t = t.split(':')
tmp[t[0]] = t[1]
elif args_len > 1:
for i in range(len(args)):
t = args[i].split(':')
tmp[t[0]] = t[1]
return tmp
def checkArgs(data, ck=[]):
for i in range(len(ck)):
if not ck[i] in data:
return (False, mw.returnJson(False, '参数:(' + ck[i] + ')没有!'))
return (True, mw.returnJson(True, 'ok'))
def status():
pn = getPluginName()
data = mw.execShell(
"ps -ef|grep " + pn + " |grep -v grep |grep -v .jar | grep -v python | awk '{print $2}'")
if data[0] == '':
return 'stop'
return 'start'
def initDreplace():
file_tpl = getInitDTpl()
service_path = os.path.dirname(os.getcwd())
initD_path = getServerDir() + '/init.d'
if not os.path.exists(initD_path):
os.mkdir(initD_path)
file_bin = initD_path + '/' + getPluginName()
if not os.path.exists(file_bin):
content = mw.readFile(file_tpl)
content = content.replace('{$SERVER_PATH}', service_path)
mw.writeFile(file_bin, content)
mw.execShell('chmod +x ' + file_bin)
return file_bin
def start():
file = initDreplace()
data = mw.execShell(file + ' start')
if data[1] == '':
return 'ok'
return 'fail'
def stop():
file = initDreplace()
data = mw.execShell(file + ' stop')
if data[1] == '':
return 'ok'
return 'fail'
def restart():
file = initDreplace()
data = mw.execShell(file + ' restart')
if data[1] == '':
return 'ok'
return 'fail'
def reload():
file = initDreplace()
data = mw.execShell(file + ' reload')
if data[1] == '':
return 'ok'
return 'fail'
def initdStatus():
initd_bin = getInitDFile()
if os.path.exists(initd_bin):
return 'ok'
return 'fail'
def initdInstall():
import shutil
source_bin = initDreplace()
initd_bin = getInitDFile()
shutil.copyfile(source_bin, initd_bin)
mw.execShell('chmod +x ' + initd_bin)
if not app_debug:
mw.execShell('chkconfig --add ' + getPluginName())
return 'ok'
def initdUinstall():
if not app_debug:
mw.execShell('chkconfig --del ' + getPluginName())
initd_bin = getInitDFile()
if os.path.exists(initd_bin):
os.remove(initd_bin)
return 'ok'
def gfConf():
return getServerDir() + "/conf/cfg.json"
def gfConfSet():
gets = [
{'name': 'addr', 'type': -1, 'ps': '绑定端口'},
{'name': 'peer_id', 'type': -1, 'ps': '集群内唯一,请使用0-9的单字符'},
{'name': 'host', 'type': -1, 'ps': '本主机地址'},
{'name': 'group', 'type': -1, 'ps': '组号'},
{'name': 'support_group_manage', 'type': 0, 'ps': '是否支持按组(集群)管理'},
{'name': 'enable_merge_small_file', 'type': 0, 'ps': '是否合并小文件'},
{'name': 'refresh_interval', 'type': 1, 'ps': '重试同步失败文件的时间'},
{'name': 'rename_file', 'type': 0, 'ps': '是否自动重命名'},
{'name': 'enable_web_upload', 'type': 0, 'ps': '是否支持web上传,方便调试'},
{'name': 'enable_custom_path', 'type': 0, 'ps': '是否支持非日期路径'},
{'name': 'enable_migrate', 'type': 0, 'ps': '是否启用迁移'},
{'name': 'enable_cross_origin', 'type': 0, 'ps': '是否开启跨站访问'},
{'name': 'enable_tus', 'type': 0, 'ps': '是否开启断点续传'}
]
file = mw.readFile(gfConf())
data = json.loads(file)
result = []
for g in gets:
if g['name'] in data:
g['value'] = data[g['name']]
result.append(g)
return mw.getJson(result)
if __name__ == "__main__":
func = sys.argv[1]
if func == 'status':
print status()
elif func == 'start':
print start()
elif func == 'stop':
print stop()
elif func == 'restart':
print restart()
elif func == 'reload':
print reload()
elif func == 'initd_status':
print initdStatus()
elif func == 'initd_install':
print initdInstall()
elif func == 'initd_uninstall':
print initdUinstall()
elif func == 'run_log':
print getLog()
elif func == 'breakpoint_log':
print gfBreakpointLog()
elif func == 'conf':
print gfConf()
elif func == 'gf_conf_set':
print gfConfSet()
else:
print 'error'

16
plugins/go-fastdfs/info.json Executable file
View File

@@ -0,0 +1,16 @@
{
"id":10,
"title":"go-fastdfs",
"tip":"soft",
"name":"go-fastdfs",
"type":"软件",
"ps":"一个基于http协议的分布式文件系统",
"versions":"1.3.1",
"shell":"install.sh",
"checks":"server/go-fastdfs",
"path": "server/go-fastdfs",
"author":"midoks",
"home":"https://github.com/sjqzhang/go-fastdfs",
"date":"2019-08-02",
"pid":"2"
}

View File

@@ -0,0 +1,72 @@
#!/bin/bash
# chkconfig: 2345 55 25
# description: go-fastdfs Cloud Service
### BEGIN INIT INFO
# Provides: bt
# Required-Start: $all
# Required-Stop: $all
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: starts go-fastdfs
# Description: starts the go-fastdfs
### END INIT INFO
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
gf_path={$SERVER_PATH}/go-fastdfs
gf_start(){
isStart=`ps -ef| grep -v python|grep -v bash |grep go-fastdfs |grep -v .jar | grep -v grep|awk '{print $2}'`
if [ "$isStart" == '' ];then
echo -e "Starting go-fastdfs... \c"
cd $gf_path
nohup ./go-fastdfs > /dev/null 2>&1 &
echo -e "\033[32mdone\033[0m"
else
echo -e "Starting go-fastdfs(pid $(echo $isStart)) already running"
fi
}
gf_stop()
{
echo -e "Stopping go-fastdfs... \c"
pids=$(ps -ef| grep -v python |grep -v bash |grep go-fastdfs |grep -v .jar | grep -v grep | awk '{print $2}')
arr=($pids)
for p in ${arr[@]}
do
kill -9 $p
done
echo -e "\033[32mdone\033[0m"
}
gf_status()
{
isStart=$(ps -ef | grep -v python | grep -v bash | grep go-fastdfs |grep -v .jar | grep -v grep | awk '{print $2}')
if [ "$isStart" != '' ];then
echo -e "\033[32mgo-fastdfs (pid $(echo $isStart)) already running\033[0m"
else
echo -e "\033[31mgo-fastdfs not running\033[0m"
fi
}
gf_reload()
{
gf_stop
gf_start
}
case "$1" in
'start') gf_start;;
'stop') gf_stop;;
'reload') gf_reload;;
'status') gf_status;;
'restart')
gf_stop
gf_start;;
esac

75
plugins/go-fastdfs/install.sh Executable file
View File

@@ -0,0 +1,75 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
sysName=`uname`
install_tmp=${rootPath}/tmp/mw_install.pl
action=$1
version=$2
Install_gf()
{
echo '正在安装脚本文件...' > $install_tmp
mkdir -p $serverPath/go-fastdfs
FF_DIR=${serverPath}/go-fastdfs
cd $FF_DIR
if [ $sysName == 'Darwin' ]; then
FF_SS_DIR=${serverPath}/source/go-fastdfs
mkdir -p $FF_SS_DIR
if [ ! -f $FF_SS_DIR/v1.3.1.tar.gz ]; then
wget -O $FF_SS_DIR/v1.3.1.tar.gz https://github.com/sjqzhang/go-fastdfs/archive/v1.3.1.tar.gz
fi
if [ ! -d $FF_SS_DIR/go-fastdfs-1.3.1 ]; then
cd $FF_SS_DIR && tar -zxvf $FF_SS_DIR/v1.3.1.tar.gz
fi
cd $FF_SS_DIR/go-fastdfs-1.3.1
if [ -d $FF_SS_DIR/go-fastdfs-1.3.1/vendor ];then
mv vendor src
fi
if [ ! -f $FF_SS_DIR/go-fastdfs-1.3.1/fileserver ]; then
pwd=`pwd`
echo "$pwd go build -o fileserver fileserver.go"
GOPATH=$pwd go build -o fileserver fileserver.go
fi
if [ ! -f $FF_DIR/go-fastdfs ];then
cp -f fileserver $FF_DIR/go-fastdfs
cd $FF_DIR
fi
else
cd $FF_DIR
if [ ! -f ${FF_DIR}/fileserver ];then
wget --no-check-certificate https://github.com/sjqzhang/go-fastdfs/releases/download/v1.3.1/fileserver -O fileserver
chmod +x fileserver
fi
fi
echo "$version" > $FF_DIR/version.pl
echo '安装完成' > $install_tmp
}
Uninstall_gf()
{
rm -rf $serverPath/go-fastdfs
echo "卸载完成" > $install_tmp
}
if [ "${1}" == 'install' ];then
Install_gf $version
else
Uninstall_gf $version
fi

View File

@@ -0,0 +1,93 @@
function str2Obj(str){
var data = {};
kv = str.split('&');
for(i in kv){
v = kv[i].split('=');
data[v[0]] = v[1];
}
return data;
}
function pPost(method,args,callback, title){
var _args = null;
if (typeof(args) == 'string'){
_args = JSON.stringify(str2Obj(args));
} else {
_args = JSON.stringify(args);
}
var _title = '正在获取...';
if (typeof(title) != 'undefined'){
_title = title;
}
var loadT = layer.msg(_title, { icon: 16, time: 0, shade: 0.3 });
$.post('/plugins/run', {name:'go-fastdfs', func:method, args:_args}, function(data) {
layer.close(loadT);
if (!data.status){
layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
if(typeof(callback) == 'function'){
callback(data);
}
},'json');
}
function gfConfigSet(){
pPost('gf_conf_set', '', function(data){
var rdata = $.parseJSON(data.data);
var mlist = '';
for (var i = 0; i < rdata.length; i++) {
var w = '140';
if (rdata[i].name == 'error_reporting') w = '250';
var ibody = '<input style="width: ' + w + 'px;" class="bt-input-text mr5" name="' + rdata[i].name + '" value="' + rdata[i].value + '" type="text" >';
switch (rdata[i].type) {
case 0:
var selected_1 = (rdata[i].value == 1) ? 'selected' : '';
var selected_0 = (rdata[i].value == 0) ? 'selected' : '';
ibody = '<select class="bt-input-text mr5" name="' + rdata[i].name + '" style="width: ' + w + 'px;">\
<option value="1" ' + selected_1 + '>开启</option>\
<option value="0" ' + selected_0 + '>关闭</option>\
</select>';
break;
case 1:
var selected_1 = (rdata[i].value == 'On') ? 'selected' : '';
var selected_0 = (rdata[i].value == 'Off') ? 'selected' : '';
ibody = '<select class="bt-input-text mr5" name="' + rdata[i].name + '" style="width: ' + w + 'px;">\
<option value="On" ' + selected_1 + '>开启</option>\
<option value="Off" ' + selected_0 + '>关闭</option></select>'
break;
case 2:
var selected_1 = (rdata[i].value == 'true') ? 'selected' : '';
var selected_0 = (rdata[i].value == 'false') ? 'selected' : '';
ibody = '<select class="bt-input-text mr5" name="' + rdata[i].name + '" style="width: ' + w + 'px;">\
<option value="true" ' + selected_1 + '>开启</option>\
<option value="false" ' + selected_0 + '>关闭</option></select>'
break;
}
mlist += '<p><span>' + rdata[i].name + '</span>' + ibody + ', <font>' + rdata[i].ps + '</font></p>'
}
var html = '<style>.conf_p p{margin-bottom: 2px}</style><div class="conf_p" style="margin-bottom:0">\
' + mlist + '\
<div style="margin-top:10px; padding-right:15px" class="text-right">\
</div>';
$(".soft-man-con").html(html);
});
}
function pRead(){
var readme = '<ul class="help-info-text c7">';
readme += '<li>官方地址<a target="_blank" href="https://github.com/sjqzhang/go-fastdfs">查看</a></li>';
readme += '<li>如果开启防火墙,需要放行端口,例如(8080)</li>';
readme += '<li>要自行配置openresty</li>';
readme += '</ul>';
$('.soft-man-con').html(readme);
}

91
plugins/gogs/class/mysqlDb.py Executable file
View File

@@ -0,0 +1,91 @@
# coding: utf-8
import re
import os
import sys
sys.path.append("/usr/local/lib/python2.7/site-packages")
class mysqlDb:
__DB_PASS = None
__DB_USER = 'root'
__DB_PORT = 3306
__DB_HOST = 'localhost'
__DB_NAME = 'test'
__DB_CONN = None
__DB_CUR = None
__DB_ERR = None
__DB_CNF = '/etc/my.cnf'
def __Conn(self):
'''连接MYSQL数据库'''
try:
socket = '/tmp/mysql.sock'
try:
import MySQLdb
except Exception, ex:
self.__DB_ERR = ex
return False
try:
self.__DB_CONN = MySQLdb.connect(host=self.__DB_HOST, user=self.__DB_USER, passwd=self.__DB_PASS,
port=self.__DB_PORT, db=self.__DB_NAME, charset="utf8", connect_timeout=10, unix_socket=socket)
except MySQLdb.Error, e:
self.__DB_HOST = '127.0.0.1'
self.__DB_CONN = MySQLdb.connect(host=self.__DB_HOST, user=self.__DB_USER, passwd=self.__DB_PASS,
port=self.__DB_PORT, db=self.__DB_NAME, charset="utf8", connect_timeout=10, unix_socket=socket)
self.__DB_CUR = self.__DB_CONN.cursor()
return True
except MySQLdb.Error, e:
self.__DB_ERR = e
return False
def setHost(self, host):
self.__DB_HOST = host
def setPwd(self, pwd):
self.__DB_PASS = pwd
def setUser(self, user):
self.__DB_USER = user
def setPort(self, port):
self.__DB_PORT = port
def setDb(self, name):
self.__DB_NAME = name
def getPwd(self):
return self.__DB_PASS
def execute(self, sql):
# 执行SQL语句返回受影响行
if not self.__Conn():
return self.__DB_ERR
try:
result = self.__DB_CUR.execute(sql)
self.__DB_CONN.commit()
self.__Close()
return result
except Exception, ex:
return ex
def query(self, sql):
# 执行SQL语句返回数据集
if not self.__Conn():
return self.__DB_ERR
try:
self.__DB_CUR.execute(sql)
result = self.__DB_CUR.fetchall()
# 将元组转换成列表
data = map(list, result)
self.__Close()
return data
except Exception, ex:
return ex
# 关闭连接
def __Close(self):
self.__DB_CUR.close()
self.__DB_CONN.close()

63
plugins/gogs/conf/app.ini Normal file
View File

@@ -0,0 +1,63 @@
APP_NAME = Gogs
RUN_USER = {$RUN_USER}
RUN_MODE = prod
[database]
DB_TYPE = mysql
HOST = 127.0.0.1:3306
NAME = gogs
USER = gogs
PASSWD = gogs
SSL_MODE = disable
PATH = data/gogs.db
[repository]
ROOT = {$ROOT_PATH}/gogs-repositories
FORCE_PRIVATE = true
[server]
DOMAIN = 127.0.0.1
HTTP_PORT = 3000
ROOT_URL = http://127.0.0.1:3000/
DISABLE_SSH = false
SSH_PORT = 2000
START_SSH_SERVER = false
OFFLINE_MODE = false
LANDING_PAGE = home
[mailer]
ENABLED = false
HOST = smtp.163.com:465
USER = midoks@163.com
PASSWD = ***
USE_PLAIN_TEXT = true
[service]
REGISTER_EMAIL_CONFIRM = false
ENABLE_NOTIFY_MAIL = false
DISABLE_REGISTRATION = true
ENABLE_CAPTCHA = true
REQUIRE_SIGNIN_VIEW = true
[picture]
DISABLE_GRAVATAR = false
ENABLE_FEDERATED_AVATAR = false
[session]
PROVIDER = file
[log]
MODE = console, file
LEVEL = Info
ROOT_PATH = {$SERVER_PATH}/gogs/log
[security]
INSTALL_LOCK = true
SECRET_KEY = jmGSJXDBH5Ng4wt
[other]
SHOW_FOOTER_BRANDING = false
SHOW_FOOTER_VERSION = false
SHOW_FOOTER_TEMPLATE_LOAD_TIME = false

36
plugins/gogs/hook/commit.tpl Executable file
View File

@@ -0,0 +1,36 @@
#!/bin/bash
echo `date`
GITADDR="{$GITROOTURL}/{$USERNAME}/{$PROJECT}"
GIT_SDIR="{$CODE_DIR}"
GIT_USER_DIR="${GIT_SDIR}/{$USERNAME}"
GIT_PROJECT_DIR="${GIT_USER_DIR}/{$PROJECT}"
# echo $GIT_PROJECT_DIR
if [ ! -d $GIT_PROJECT_DIR ];then
mkdir -p $GIT_USER_DIR && cd $GIT_USER_DIR
git clone $GITADDR
fi
unset GIT_DIR
cd $GIT_PROJECT_DIR && git pull
# func 2
# cd $GIT_PROJECT_DIR && env -i git pull origin master
WEB_PATH={$WEB_ROOT}/{$USERNAME}/{$PROJECT}
mkdir -p $WEB_PATH
rsync -vauP --delete --exclude=".*" $GIT_PROJECT_DIR/ $WEB_PATH
sysName=`uname`
if [ $sysName == 'Darwin' ]; then
USER=$(who | sed -n "2,1p" |awk '{print $1}')
chown -R $USER:staff $WEB_PATH
else
chown -R www:www $WEB_PATH
fi

View File

@@ -0,0 +1,3 @@
#!/bin/bash
sh -x {$PATH}/commit 2>{$PATH}/sh.log

BIN
plugins/gogs/ico.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

23
plugins/gogs/index.html Executable file
View File

@@ -0,0 +1,23 @@
<div class="bt-form">
<div class="bt-w-main">
<div class="bt-w-menu">
<p class="bgw" onclick="pluginService('gogs');">服务</p>
<p onclick="pluginInitD('gogs');">自启动</p>
<p onclick="pluginConfig('gogs',null, 'init_conf');">启动配置</p>
<p onclick="gogsEdit();">手动编辑</p>
<p onclick="pluginConfig('gogs',null, 'conf');">配置文件</p>
<p onclick="gogsSetConfig();">配置修改</p>
<p onclick="gogsUserList();">用户列表</p>
<p onclick="pluginLogs('gogs',null,'run_log');">运行日志</p>
<p onclick="pluginLogs('gogs',null,'post_receive_log');" title="提交post-receive日志">提交日志</p>
<p onclick="gogsRead();">使用说明</p>
</div>
<div class="bt-w-con pd15">
<div class="soft-man-con"></div>
</div>
</div>
</div>
<script type="text/javascript">
$.getScript( "/plugins/file?name=gogs&f=js/gogs.js");
pluginService('gogs');
</script>

686
plugins/gogs/index.py Executable file
View File

@@ -0,0 +1,686 @@
# coding: utf-8
import time
import os
import sys
import re
sys.path.append("/usr/local/lib/python2.7/site-packages")
import psutil
sys.path.append(os.getcwd() + "/class/core")
import mw
app_debug = False
if mw.isAppleSystem():
app_debug = True
def getPluginName():
return 'gogs'
def getPluginDir():
return mw.getPluginDir() + '/' + getPluginName()
sys.path.append(getPluginDir() + "/class")
import mysqlDb
def getServerDir():
return mw.getServerDir() + '/' + getPluginName()
def getInitDFile():
if app_debug:
return '/tmp/' + getPluginName()
return '/etc/init.d/' + getPluginName()
def getArgs():
args = sys.argv[2:]
tmp = {}
args_len = len(args)
if args_len == 1:
t = args[0].strip('{').strip('}')
t = t.split(':', 1)
tmp[t[0]] = t[1]
elif args_len > 1:
for i in range(len(args)):
t = args[i].split(':', 1)
tmp[t[0]] = t[1]
return tmp
def getInitdConfTpl():
path = getPluginDir() + "/init.d/gogs.tpl"
return path
def getInitdConf():
path = getServerDir() + "/init.d/gogs"
return path
def getConf():
path = getServerDir() + "/custom/conf/app.ini"
return path
def getConfTpl():
path = getPluginDir() + "/conf/app.ini"
return path
def status():
data = mw.execShell(
"ps -ef|grep " + getPluginName() + " |grep -v grep | grep -v python | awk '{print $2}'")
if data[0] == '':
return 'stop'
return 'start'
def getHomeDir():
if mw.isAppleSystem():
user = mw.execShell(
"who | sed -n '2, 1p' |awk '{print $1}'")[0].strip()
return '/Users/' + user
else:
return '/root'
def getRunUser():
if mw.isAppleSystem():
user = mw.execShell(
"who | sed -n '2, 1p' |awk '{print $1}'")[0].strip()
return user
else:
return 'root'
__SR = '''#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
export USER=%s
export HOME=%s && ''' % ( getRunUser(), getHomeDir())
def contentReplace(content):
service_path = mw.getServerDir()
content = content.replace('{$ROOT_PATH}', mw.getRootDir())
content = content.replace('{$SERVER_PATH}', service_path)
content = content.replace('{$RUN_USER}', getRunUser())
content = content.replace('{$HOME_DIR}', getHomeDir())
return content
def initDreplace():
file_tpl = getInitdConfTpl()
service_path = mw.getServerDir()
initD_path = getServerDir() + '/init.d'
if not os.path.exists(initD_path):
os.mkdir(initD_path)
file_bin = initD_path + '/' + getPluginName()
if not os.path.exists(file_bin):
content = mw.readFile(file_tpl)
content = contentReplace(content)
mw.writeFile(file_bin, content)
mw.execShell('chmod +x ' + file_bin)
conf_bin = getConf()
if not os.path.exists(conf_bin):
mw.execShell('mkdir -p ' + getServerDir() + '/custom/conf')
conf_tpl = getConfTpl()
content = mw.readFile(conf_tpl)
content = contentReplace(content)
mw.writeFile(conf_bin, content)
log_path = getServerDir() + '/log'
if not os.path.exists(log_path):
os.mkdir(log_path)
return file_bin
def getRootUrl():
content = mw.readFile(getConf())
rep = 'ROOT_URL\s*=\s*(.*)'
tmp = re.search(rep, content)
if not tmp:
return ''
return tmp.groups()[0]
def getSshPort():
content = mw.readFile(getConf())
rep = 'SSH_PORT\s*=\s*(.*)'
tmp = re.search(rep, content)
if not tmp:
return ''
return tmp.groups()[0]
def getRootPath():
content = mw.readFile(getConf())
rep = 'ROOT\s*=\s*(.*)'
tmp = re.search(rep, content)
if not tmp:
return ''
return tmp.groups()[0]
def getDbConfValue():
content = mw.readFile(getConf())
rep_scope = "\[database\](.*?)\["
tmp = re.findall(rep_scope, content, re.S)
rep = '(\w*)\s*=\s*(.*)'
tmp = re.findall(rep, tmp[0])
r = {}
for x in range(len(tmp)):
k = tmp[x][0]
v = tmp[x][1]
r[k] = v
return r
def pMysqlDb():
conf = getDbConfValue()
host = conf['HOST'].split(':')
conn = mysqlDb.mysqlDb()
conn.setHost(host[0])
conn.setUser(conf['USER'])
conn.setPwd(conf['PASSWD'])
conn.setPort(int(host[1]))
conn.setDb(conf['NAME'])
return conn
def isSqlError(mysqlMsg):
# 检测数据库执行错误
_mysqlMsg = str(mysqlMsg)
# print _mysqlMsg
if "MySQLdb" in _mysqlMsg:
return mw.returnData(False, 'MySQLdb组件缺失! <br>进入SSH命令行输入: pip install mysql-python')
if "2002," in _mysqlMsg:
return mw.returnData(False, '数据库连接失败,请检查数据库服务是否启动!')
if "using password:" in _mysqlMsg:
return mw.returnData(False, '数据库管理密码错误!')
if "Connection refused" in _mysqlMsg:
return mw.returnData(False, '数据库连接失败,请检查数据库服务是否启动!')
if "1133," in _mysqlMsg:
return mw.returnData(False, '数据库用户不存在!')
if "1007," in _mysqlMsg:
return mw.returnData(False, '数据库已经存在!')
if "1044," in _mysqlMsg:
return mw.returnData(False, mysqlMsg[1])
if "2003," in _mysqlMsg:
return mw.returnData(False, mysqlMsg[1])
return mw.returnData(True, 'OK')
def start():
is_frist = True
conf_bin = getConf()
if os.path.exists(conf_bin):
is_frist = False
file = initDreplace()
if is_frist:
return "第一次启动Gogs,默认使用MySQL连接!<br>可以在配置文件中重新设置,再启动!"
conn = pMysqlDb()
list_table = conn.query('show tables')
data = isSqlError(list_table)
if not data['status']:
return data['msg']
data = mw.execShell(__SR + file + ' start')
if data[1] == '':
return 'ok'
return data[0]
def stop():
file = initDreplace()
data = mw.execShell(__SR + file + ' stop')
if data[1] == '':
return 'ok'
return data[1]
def restart():
file = initDreplace()
data = mw.execShell(__SR + file + ' restart')
if data[1] == '':
return 'ok'
return data[1]
def reload():
file = initDreplace()
data = mw.execShell(__SR + file + ' reload')
if data[1] == '':
return 'ok'
return data[1]
def initdStatus():
if not app_debug:
os_name = mw.getOs()
if os_name == 'darwin':
return "Apple Computer does not support"
initd_bin = getInitDFile()
if os.path.exists(initd_bin):
return 'ok'
return 'fail'
def initdInstall():
import shutil
if not app_debug:
os_name = mw.getOs()
if os_name == 'darwin':
return "Apple Computer does not support"
mem_bin = initDreplace()
initd_bin = getInitDFile()
shutil.copyfile(mem_bin, initd_bin)
mw.execShell('chmod +x ' + initd_bin)
mw.execShell('chkconfig --add ' + getPluginName())
return 'ok'
def initdUinstall():
if not app_debug:
os_name = mw.getOs()
if os_name == 'darwin':
return "Apple Computer does not support"
initd_bin = getInitDFile()
os.remove(initd_bin)
mw.execShell('chkconfig --del ' + getPluginName())
return 'ok'
def runLog():
log_path = getServerDir() + '/log/gogs.log'
return log_path
def postReceiveLog():
log_path = getServerDir() + '/log/hooks/post-receive.log'
return log_path
def getGogsConf():
gets = [
{'name': 'DOMAIN', 'type': -1, 'ps': '服务器域名'},
{'name': 'ROOT_URL', 'type': -1, 'ps': '公开的完整URL路径'},
{'name': 'HTTP_ADDR', 'type': -1, 'ps': '应用HTTP监听地址'},
{'name': 'HTTP_PORT', 'type': -1, 'ps': '应用 HTTP 监听端口号'},
{'name': 'START_SSH_SERVER', 'type': 2, 'ps': '启动内置SSH服务器'},
{'name': 'SSH_PORT', 'type': -1, 'ps': 'SSH 端口号'},
{'name': 'REQUIRE_SIGNIN_VIEW', 'type': 2, 'ps': '强制登录浏览'},
{'name': 'ENABLE_CAPTCHA', 'type': 2, 'ps': '启用验证码服务'},
{'name': 'DISABLE_REGISTRATION', 'type': 2, 'ps': '禁止注册,只能由管理员创建帐号'},
{'name': 'ENABLE_NOTIFY_MAIL', 'type': 2, 'ps': '是否开启邮件通知'},
{'name': 'FORCE_PRIVATE', 'type': 2, 'ps': '强制要求所有新建的仓库都是私有'},
{'name': 'SHOW_FOOTER_BRANDING', 'type': 2, 'ps': 'Gogs推广信息'},
{'name': 'SHOW_FOOTER_VERSION', 'type': 2, 'ps': 'Gogs版本信息'},
{'name': 'SHOW_FOOTER_TEMPLATE_LOAD_TIME', 'type': 2, 'ps': 'Gogs模板加载时间'},
]
conf = mw.readFile(getConf())
result = []
for g in gets:
rep = g['name'] + '\s*=\s*(.*)'
tmp = re.search(rep, conf)
if not tmp:
continue
g['value'] = tmp.groups()[0]
result.append(g)
return mw.getJson(result)
def submitGogsConf():
gets = ['DOMAIN',
'ROOT_URL',
'HTTP_ADDR',
'HTTP_PORT',
'START_SSH_SERVER',
'SSH_PORT',
'REQUIRE_SIGNIN_VIEW',
'FORCE_PRIVATE',
'ENABLE_CAPTCHA',
'DISABLE_REGISTRATION',
'ENABLE_NOTIFY_MAIL',
'SHOW_FOOTER_BRANDING',
'SHOW_FOOTER_VERSION',
'SHOW_FOOTER_TEMPLATE_LOAD_TIME']
args = getArgs()
filename = getConf()
conf = mw.readFile(filename)
for g in gets:
if g in args:
rep = g + '\s*=\s*(.*)'
val = g + ' = ' + args[g]
conf = re.sub(rep, val, conf)
mw.writeFile(filename, conf)
reload()
return mw.returnJson(True, '设置成功')
def userList():
import math
args = getArgs()
page = 1
page_size = 10
search = ''
if 'page' in args:
page = int(args['page'])
if 'page_size' in args:
page_size = int(args['page_size'])
if 'search' in args:
search = args['search']
data = {}
data['root_url'] = getRootUrl()
pm = pMysqlDb()
start = (page - 1) * page_size
list_count = pm.query('select count(id) as num from user')
count = list_count[0][0]
list_data = pm.query(
'select id,name,email from user order by id desc limit ' + str(start) + ',' + str(page_size))
page_info = {'count': count, 'p': page,
'row': page_size, 'tojs': 'gogsUserList'}
data['list'] = mw.getPage(page_info)
data['page'] = page
data['page_size'] = page_size
data['page_count'] = int(math.ceil(count / page_size))
data['data'] = list_data
return mw.returnJson(True, 'OK', data)
def getAllUserProject(user, search=''):
path = getRootPath() + '/' + user
dlist = []
if os.path.exists(path):
for filename in os.listdir(path):
tmp = {}
filePath = path + '/' + filename
if os.path.isdir(filePath):
if search == '':
tmp['name'] = filename.replace('.git', '')
dlist.append(tmp)
else:
if filename.find(search) != -1:
tmp['name'] = filename.replace('.git', '')
dlist.append(tmp)
return dlist
def checkProjectListIsHasScript(user, data):
path = getRootPath() + '/' + user
for x in range(len(data)):
name = data[x]['name'] + '.git'
path_tmp = path + '/' + name + '/custom_hooks/post-receive'
if os.path.exists(path_tmp):
data[x]['has_hook'] = True
else:
data[x]['has_hook'] = False
return data
def userProjectList():
import math
args = getArgs()
# print args
page = 1
page_size = 5
search = ''
if not 'name' in args:
return mw.returnJson(False, '缺少参数name')
if 'page' in args:
page = int(args['page'])
if 'page_size' in args:
page_size = int(args['page_size'])
if 'search' in args:
search = args['search']
data = {}
ulist = getAllUserProject(args['name'])
dlist_sum = len(ulist)
start = (page - 1) * page_size
ret_data = ulist[start:start + page_size]
ret_data = checkProjectListIsHasScript(args['name'], ret_data)
data['root_url'] = getRootUrl()
data['data'] = ret_data
data['args'] = args
data['list'] = mw.getPage(
{'count': dlist_sum, 'p': page, 'row': page_size, 'tojs': 'userProjectList'})
return mw.returnJson(True, 'OK', data)
def projectScriptEdit():
args = getArgs()
if not 'user' in args:
return mw.returnJson(True, 'username missing')
if not 'name' in args:
return mw.returnJson(True, 'project name missing')
user = args['user']
name = args['name'] + '.git'
post_receive = getRootPath() + '/' + user + '/' + name + \
'/custom_hooks/commit'
if os.path.exists(post_receive):
return mw.returnJson(True, 'OK', {'path': post_receive})
else:
return mw.returnJson(False, 'file does not exist')
def projectScriptLoad():
args = getArgs()
if not 'user' in args:
return mw.returnJson(True, 'username missing')
if not 'name' in args:
return mw.returnJson(True, 'project name missing')
user = args['user']
name = args['name'] + '.git'
path = getRootPath() + '/' + user + '/' + name
post_receive_tpl = getPluginDir() + '/hook/post-receive.tpl'
post_receive = path + '/custom_hooks/post-receive'
if not os.path.exists(path + '/custom_hooks'):
mw.execShell('mkdir -p ' + path + '/custom_hooks')
pct_content = mw.readFile(post_receive_tpl)
pct_content = pct_content.replace('{$PATH}', path + '/custom_hooks')
mw.writeFile(post_receive, pct_content)
mw.execShell('chmod 777 ' + post_receive)
commit_tpl = getPluginDir() + '/hook/commit.tpl'
commit = path + '/custom_hooks/commit'
codeDir = mw.getRootDir() + '/git'
cc_content = mw.readFile(commit_tpl)
sshUrl = 'ssh://127.0.0.1:' + getSshPort()
cc_content = cc_content.replace('{$GITROOTURL}', sshUrl)
cc_content = cc_content.replace('{$CODE_DIR}', codeDir)
cc_content = cc_content.replace('{$USERNAME}', user)
cc_content = cc_content.replace('{$PROJECT}', args['name'])
cc_content = cc_content.replace('{$WEB_ROOT}', mw.getWwwDir())
mw.writeFile(commit, cc_content)
mw.execShell('chmod 777 ' + commit)
return 'ok'
def projectScriptUnload():
args = getArgs()
if not 'user' in args:
return mw.returnJson(True, 'username missing')
if not 'name' in args:
return mw.returnJson(True, 'project name missing')
user = args['user']
name = args['name'] + '.git'
post_receive = getRootPath() + '/' + user + '/' + name + \
'/custom_hooks/post-receive'
mw.execShell('rm -f ' + post_receive)
commit = getRootPath() + '/' + user + '/' + name + \
'/custom_hooks/commit'
mw.execShell('rm -f ' + commit)
return 'ok'
def projectScriptDebug():
args = getArgs()
if not 'user' in args:
return mw.returnJson(True, 'username missing')
if not 'name' in args:
return mw.returnJson(True, 'project name missing')
user = args['user']
name = args['name'] + '.git'
commit_log = getRootPath() + '/' + user + '/' + name + \
'/custom_hooks/sh.log'
data = {}
if os.path.exists(commit_log):
data['status'] = True
data['path'] = commit_log
else:
data['status'] = False
data['msg'] = '没有日志文件'
return mw.getJson(data)
def gogsEdit():
data = {}
data['post_receive'] = getPluginDir() + '/hook/post-receive.tpl'
data['commit'] = getPluginDir() + '/hook/commit.tpl'
return mw.getJson(data)
def getRsaPublic():
path = getHomeDir()
path += '/.ssh/id_rsa.pub'
content = mw.readFile(path)
data = {}
data['mw'] = content
return mw.getJson(data)
def getTotalStatistics():
st = status()
data = {}
if st == 'start':
pm = pMysqlDb()
list_count = pm.query('select count(id) as num from repository')
count = list_count[0][0]
data['status'] = True
data['count'] = count
data['ver'] = mw.readFile(getServerDir() + '/version.pl').strip()
return mw.returnJson(True, 'ok', data)
else:
data['status'] = False
data['count'] = 0
return mw.returnJson(False, 'fail', data)
if __name__ == "__main__":
func = sys.argv[1]
if func == 'status':
print status()
elif func == 'start':
print start()
elif func == 'stop':
print stop()
elif func == 'restart':
print restart()
elif func == 'reload':
print reload()
elif func == 'initd_status':
print initdStatus()
elif func == 'initd_install':
print initdInstall()
elif func == 'initd_uninstall':
print initdUinstall()
elif func == 'run_log':
print runLog()
elif func == 'post_receive_log':
print postReceiveLog()
elif func == 'conf':
print getConf()
elif func == 'init_conf':
print getInitdConf()
elif func == 'get_gogs_conf':
print getGogsConf()
elif func == 'submit_gogs_conf':
print submitGogsConf()
elif func == 'user_list':
print userList()
elif func == 'user_project_list':
print userProjectList()
elif func == 'project_script_edit':
print projectScriptEdit()
elif func == 'project_script_load':
print projectScriptLoad()
elif func == 'project_script_unload':
print projectScriptUnload()
elif func == 'project_script_debug':
print projectScriptDebug()
elif func == 'gogs_edit':
print gogsEdit()
elif func == 'get_rsa_public':
print getRsaPublic()
elif func == 'get_total_statistics':
print getTotalStatistics()
else:
print 'fail'

16
plugins/gogs/info.json Executable file
View File

@@ -0,0 +1,16 @@
{
"ps": "Gogs是一款极易搭建的自助Git服务",
"name": "gogs",
"title": "Gogs",
"versions": ["0.11.86"],
"tip": "soft",
"checks": "server/gogs",
"path":"server/gogs",
"author": "midoks",
"date": "201-04-01",
"home": "https://gogs.io",
"type": "git服务器",
"shell": "install.sh",
"pid": "3",
"sort": 7
}

View File

@@ -0,0 +1,110 @@
#!/bin/sh
#
# /etc/rc.d/init.d/gogs
#
# Runs the Gogs
#
#
# chkconfig: - 85 15
#
### BEGIN INIT INFO
# Provides: gogs
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Should-Start: mysql postgresql
# Should-Stop: mysql postgresql
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start gogs at boot time.
# Description: Control gogs.
### END INIT INFO
# Source function library.
if [ -f /etc/init.d/functions ];then
. /etc/init.d/functions
fi
if [ -f /etc/rc.d/init.d/functions ];then
. /etc/rc.d/init.d/functions
fi
# Default values
export HOME={$HOME_DIR}
export USER={$RUN_USER}
NAME=gogs
GOGS_HOME={$SERVER_PATH}/gogs
GOGS_PATH=${GOGS_HOME}/$NAME
GOGS_USER={$RUN_USER}
SERVICENAME="Gogs"
LOCKFILE=/tmp/gogs.lock
LOGPATH=${GOGS_HOME}/log
LOGFILE=${LOGPATH}/gogs.log
RETVAL=0
[ -r /etc/sysconfig/$NAME ] && . /etc/sysconfig/$NAME
DAEMON_OPTS="--check $NAME"
[ ! -z "$GOGS_USER" ] && DAEMON_OPTS="$DAEMON_OPTS --user=${GOGS_USER}"
status(){
isStart=`ps -ef|grep 'gogs web' |grep -v grep|awk '{print $2}'`
if [ "$isStart" == '' ];then
echo -e "${SERVICENAME} not running"
else
echo -e "${SERVICENAME}(pid $(echo $isStart)) already running"
fi
}
start() {
isStart=`ps -ef|grep 'gogs web' |grep -v grep|awk '{print $2}'`
if [ "$isStart" != '' ];then
echo "${SERVICENAME}(pid $(echo $isStart)) already running"
return $RETVAL
fi
cd ${GOGS_HOME}
echo -e "Starting ${SERVICENAME}: \c"
${GOGS_PATH} web > ${LOGFILE} 2>&1 &
RETVAL=$?
[ $RETVAL = 0 ] && touch ${LOCKFILE} && echo -e "\033[32mdone\033[0m"
return $RETVAL
}
stop() {
pids=`ps -ef|grep 'gogs web' |grep -v grep|awk '{print $2}'`
arr=($pids)
echo -e "Stopping gogs... \c"
for p in ${arr[@]}
do
kill -9 $p
done
echo -e "\033[32mdone\033[0m"
}
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status
;;
restart)
stop
start
;;
reload)
stop
start
;;
*)
echo "Usage: ${NAME} {start|stop|status|restart}"
exit 1
;;
esac
exit $RETVAL

76
plugins/gogs/install.sh Executable file
View File

@@ -0,0 +1,76 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
GOGS_DOWNLOAD='https://dl.gogs.io'
getOs(){
os=`uname`
if [ "Darwin" == "$os" ];then
echo 'darwin'
else
echo 'linux'
fi
return 0
}
getBit(){
echo `getconf LONG_BIT`
}
Install_gogs()
{
mkdir -p $serverPath/source/gogs
echo '正在安装脚本文件...' > $install_tmp
version=$1
os=`getOs`
if [ "darwin" == "$os" ];then
file=gogs_${version}_darwin_amd64.zip
else
file=gogs_${version}_linux_amd64.zip
fi
if [ ! -f $serverPath/source/gogs/$file ];then
wget -O $serverPath/source/gogs/$file ${GOGS_DOWNLOAD}/${version}/${file}
fi
cd $serverPath/source/gogs && unzip -o $file -d gogs_${version}
mv $serverPath/source/gogs/gogs_${version}/gogs/ $serverPath/gogs
echo $version > $serverPath/gogs/version.pl
# if id -u gogs > /dev/null 2>&1; then
# echo "gogs user exists"
# else
# useradd gogs
# cp /etc/sudoers{,.`date +"%Y-%m-%d_%H-%M-%S"`}
# echo "gogs ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
# fi
echo 'install success' > $install_tmp
}
Uninstall_gogs()
{
rm -rf $serverPath/gogs
echo 'uninstall success' > $install_tmp
}
action=$1
version=$2
if [ "${1}" == 'install' ];then
Install_gogs $version
else
Uninstall_gogs $version
fi

346
plugins/gogs/js/gogs.js Executable file
View File

@@ -0,0 +1,346 @@
function str2Obj(str){
var data = {};
kv = str.split('&');
for(i in kv){
v = kv[i].split('=');
data[v[0]] = v[1];
}
return data;
}
function gogsPost(method,args,callback, title){
var _args = null;
if (typeof(args) == 'string'){
_args = JSON.stringify(str2Obj(args));
} else {
_args = JSON.stringify(args);
}
var _title = '正在获取...';
if (typeof(title) != 'undefined'){
_title = title;
}
var loadT = layer.msg(_title, { icon: 16, time: 0, shade: 0.3 });
$.post('/plugins/run', {name:'gogs', func:method, args:_args}, function(data) {
layer.close(loadT);
if (!data.status){
layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
if(typeof(callback) == 'function'){
callback(data);
}
},'json');
}
function gogsSetConfig(){
gogsPost('get_gogs_conf', '', function(data){
// console.log(data);
var rdata = $.parseJSON(data.data);
// console.log(rdata);
var mlist = '';
for (var i = 0; i < rdata.length; i++) {
var w = '140';
if (rdata[i].name == 'error_reporting') w = '250';
var ibody = '<input style="width: ' + w + 'px;" class="bt-input-text mr5" name="' + rdata[i].name + '" value="' + rdata[i].value + '" type="text" >';
switch (rdata[i].type) {
case 0:
var selected_1 = (rdata[i].value == 1) ? 'selected' : '';
var selected_0 = (rdata[i].value == 0) ? 'selected' : '';
ibody = '<select class="bt-input-text mr5" name="' + rdata[i].name + '" style="width: ' + w + 'px;">\
<option value="1" ' + selected_1 + '>开启</option>\
<option value="0" ' + selected_0 + '>关闭</option>\
</select>';
break;
case 1:
var selected_1 = (rdata[i].value == 'On') ? 'selected' : '';
var selected_0 = (rdata[i].value == 'Off') ? 'selected' : '';
ibody = '<select class="bt-input-text mr5" name="' + rdata[i].name + '" style="width: ' + w + 'px;">\
<option value="On" ' + selected_1 + '>开启</option>\
<option value="Off" ' + selected_0 + '>关闭</option></select>'
break;
case 2:
var selected_1 = (rdata[i].value == 'true') ? 'selected' : '';
var selected_0 = (rdata[i].value == 'false') ? 'selected' : '';
ibody = '<select class="bt-input-text mr5" name="' + rdata[i].name + '" style="width: ' + w + 'px;">\
<option value="true" ' + selected_1 + '>开启</option>\
<option value="false" ' + selected_0 + '>关闭</option></select>'
break;
}
mlist += '<p><span>' + rdata[i].name + '</span>' + ibody + ', <font>' + rdata[i].ps + '</font></p>'
}
var html = '<style>.conf_p p{margin-bottom: 2px}</style><div class="conf_p" style="margin-bottom:0">\
' + mlist + '\
<div style="margin-top:10px; padding-right:15px" class="text-right">\
<button class="btn btn-success btn-sm mr5" onclick="gogsSetConfig()">刷新</button>\
<button class="btn btn-success btn-sm" onclick="submitGogsConf()">保存</button></div>\
</div>';
$(".soft-man-con").html(html);
});
}
//提交PHP配置
function submitGogsConf() {
var data = {
DOMAIN: $("input[name='DOMAIN']").val(),
ROOT_URL: $("input[name='ROOT_URL']").val(),
HTTP_ADDR: $("select[name='HTTP_ADDR']").val(),
HTTP_PORT: $("input[name='HTTP_PORT']").val(),
START_SSH_SERVER: $("select[name='START_SSH_SERVER']").val() || 'false',
SSH_PORT: $("input[name='SSH_PORT']").val(),
REQUIRE_SIGNIN_VIEW: $("select[name='REQUIRE_SIGNIN_VIEW']").val() || 'false',
ENABLE_CAPTCHA: $("select[name='ENABLE_CAPTCHA']").val() || 'true',
DISABLE_REGISTRATION: $("select[name='DISABLE_REGISTRATION']").val() || 'false',
ENABLE_NOTIFY_MAIL: $("select[name='ENABLE_NOTIFY_MAIL']").val() || 'false',
FORCE_PRIVATE: $("select[name='FORCE_PRIVATE']").val() || 'false',
SHOW_FOOTER_BRANDING: $("select[name='SHOW_FOOTER_BRANDING']").val() || 'false',
SHOW_FOOTER_VERSION: $("select[name='SHOW_FOOTER_VERSION']").val() || 'false',
SHOW_FOOTER_TEMPLATE_LOAD_TIME: $("select[name='SHOW_FOOTER_TEMPLATE_LOAD_TIME']").val() || 'false',
};
gogsPost('submit_gogs_conf', data, function(ret_data){
var rdata = $.parseJSON(ret_data.data);
layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
gogsSetConfig();
});
}
function gogsEdit(){
gogsPost('gogs_edit',{} , function(data){
// console.log(data);
var rdata = $.parseJSON(data.data);
var edit = '<p class="status">通用的手动编辑:</p>';
edit +='<div class="sfm-opt">\
<button class="btn btn-default btn-sm" onclick="onlineEditFile(0,\''+rdata['post_receive']+'\');">post-receive.tpl</button>\
<button class="btn btn-default btn-sm" onclick="onlineEditFile(0,\''+rdata['commit']+'\');">commit.tpl</button>\
</div>';
$(".soft-man-con").html(edit);
});
}
function gogsUserList(page, search) {
var _data = {};
if (typeof(page) =='undefined'){
var page = 1;
}
_data['page'] = page;
_data['page_size'] = 10;
if(typeof(search) != 'undefined'){
_data['search'] = search;
}
gogsPost('user_list', _data, function(data){
var rdata = $.parseJSON(data.data);
// console.log(rdata);
content = '<div class="finduser"><input class="bt-input-text mr5 outline_no" type="text" placeholder="查找用户名" id="find_user" style="height: 28px; border-radius: 3px;width: 435px;">';
content += '<button class="btn btn-success btn-sm" onclick="userFind();">查找</button></div>';
content += '<div class="divtable" style="margin-top:5px;"><table class="table table-hover" width="100%" cellspacing="0" cellpadding="0" border="0">';
content += '<thead><tr>';
content += '<th>序号</th>';
content += '<th>用户或组织</th>';
content += '<th>邮件地址</th>';
content += '<th>操作(<a href="'+rdata['data']['root_url']+'" class="btlink" target="_blank">WEB管理</a>)</th>';
content += '</tr></thead>';
content += '<tbody>';
ulist = rdata['data']['data'];
for (i in ulist){
email = ulist[i][2] == '' ? '无' : ulist[i][2];
content += '<tr><td>'+ulist[i][0]+'</td>'+
'<td>'+ulist[i][1]+'</td>'+
'<td>'+email+'</td>'+
'<td><a class="btlink" onclick="userProjectList(\''+ulist[i][1]+'\')">项目管理</a></td>'+
'</tr>';
}
content += '</tbody>';
content += '</table></div>';
var page = '<div class="dataTables_paginate paging_bootstrap pagination" style="margin-top:0px;"><ul id="softPage" class="page"><div>';
page += rdata['data']['list'];
page += '</div></ul></div>';
content += page;
$(".soft-man-con").html(content);
});
}
function userProjectList(user, search){
var req = {};
if (!isNaN(user)){
req['page'] = user;
req['name'] = user = getCookie('gogsUserSelected');
} else {
req['page'] = 1;
req['name'] = user;
setCookie('gogsUserSelected', user);
}
req['page_size'] = 5;
req['search'] = '';
if(typeof(search) != 'undefined'){
req['search'] = search;
}
$('.layui-layer-close1').click();
gogsPost('user_project_list', req, function(data){
var rdata = [];
try {
rdata = $.parseJSON(data.data);
} catch(e){}
if (!rdata['status']){
layer.msg(rdata['msg'], { icon: 2 });
return;
}
var list = '';
// console.log(rdata);
var project_list = rdata['data']['data'];
for (i in project_list) {
var name = project_list[i]['name'];
list += '<tr><td>'+name+'</td>\
<td>\
<a class="btlink" target="_blank" href="'+rdata['data']['root_url']+user+'/'+name+'">源码</a> | \
<a class="btlink" onclick="projectScript(\''+user+'\',\''+name+'\','+project_list[i]['has_hook']+');">脚本</a>\
</td>\
</tr>';
}
var page = '<div class="dataTables_paginate paging_bootstrap pagination" style="margin-top:0px;"><ul id="softPage" class="page"><div>';
page += rdata['data']['list'];
page += '</div></ul></div>';
var loadOpen = layer.open({
type: 1,
title: '用户('+user+')项目列表',
area: '500px',
content:"<div class='bt-form pd20 c6'>\
<div>\
<div class='divtable' style='margin-top:5px;'>\
<table class='table table-hover'>\
<thead><tr><th>项目</th><th>操作</th></tr></thead>\
<tbody>" + list + "</tbody>\
</table>" +
page +
"</div></div></div>"
});
});
}
function projectScript(user, name,has_hook){
// console.log(user,name,has_hook);
var html = '';
if (has_hook){
html += '<button onclick="projectScriptEdit(\''+user+'\',\''+name+'\')" class="btn btn-default btn-sm">手动编辑</button>';
html += '<button onclick="projectScriptDebug(\''+user+'\',\''+name+'\')" class="btn btn-default btn-sm">调试日志</button>';
html += '<button onclick="projectScriptLoad(\''+user+'\',\''+name+'\')" class="btn btn-default btn-sm">重新加载</button>';
html += '<button onclick="projectScriptUnload(\''+user+'\',\''+name+'\')" class="btn btn-default btn-sm">卸载脚本</button>';
} else {
html += '<button onclick="projectScriptLoad(\''+user+'\',\''+name+'\')" class="btn btn-default btn-sm">加载脚本</button>';
}
var loadOpen = layer.open({
type: 1,
title: '['+user+']['+name+']脚本设置',
area: '240px',
content:'<div class="change-default pd20">'+html+'</div>'
});
}
function projectScriptEdit(user,name){
gogsPost('project_script_edit', {'user':user,'name':name}, function(data){
var rdata = $.parseJSON(data.data);
if (rdata['status']){
onlineEditFile(0, rdata['data']['path']);
} else {
layer.msg(rdata.msg,{icon:1,time:2000,shade: [0.3, '#000']});
}
});
}
function projectScriptLoad(user,name){
gogsPost('project_script_load', {'user':user,'name':name}, function(data){
if (data.data != 'ok'){
layer.msg(data.data,{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
layer.msg('加载成功!',{icon:1,time:2000,shade: [0.3, '#000']});
setTimeout(function(){
userProjectList(1);
}, 2000);
});
}
function projectScriptUnload(user,name){
gogsPost('project_script_unload', {'user':user,'name':name}, function(data){
if (data.data != 'ok'){
layer.msg(data.data,{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
layer.msg('卸载成功!',{icon:1,time:2000,shade: [0.3, '#000']});
setTimeout(function(){
userProjectList(1);
}, 2000);
});
}
function projectScriptDebug(user,name){
gogsPost('project_script_debug', {'user':user,'name':name}, function(data){
var rdata = $.parseJSON(data.data);
if (rdata['status']){
onlineEditFile(0, rdata['path']);
} else {
layer.msg(rdata.msg,{icon:1,time:2000,shade: [0.3, '#000']});
}
});
}
function getRsaPublic(){
gogsPost('get_rsa_public', {}, function(data){
var rdata = $.parseJSON(data.data);
var con = '<div class="tab-con">\
<div class="myKeyCon ptb15">\
<textarea style="margin:0px;width:580px;height:110px;outline:none;" spellcheck="false">'+rdata.public+'</textarea>\
</div>\
<ul class="help-info-text c7 pull-left"></ul>\
</div>'
layer.open({
type: 1,
area: "600px",
title: '本机公钥',
closeBtn: 2,
shift: 5,
shadeClose: false,
content:con
});
});
}
function gogsRead(){
var readme = '<ul class="help-info-text c7">';
readme += '<li>默认使用MySQL,第一个启动加载各种配置,并修改成正确的数据库配置</li>';
readme += '<li>邮件端口使用456,gogs仅支持使用STARTTLS的SMTP协议</li>';
readme += '<li>如果使用项目中脚本本地同步,<a target="_blank" href="https://github.com/midoks/mdserver-web/wiki/%E6%8F%92%E4%BB%B6%E7%AE%A1%E7%90%86%5Bgogs%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E%5D#%E5%90%AF%E5%8A%A8gogs%E5%90%8E%E5%A6%82%E6%9E%9C%E8%A6%81%E4%BD%BF%E7%94%A8hook%E8%84%9A%E6%9C%AC%E5%90%8C%E6%AD%A5%E4%BB%A3%E7%A0%81%E9%9C%80%E8%A6%81%E5%BC%80%E5%90%AFssh%E7%AB%AF%E5%8F%A3">点击查看</></li>';
readme += '<li><a href="#" onclick="getRsaPublic();">点击查看本机公钥</></li>';
readme += '</ul>';
$('.soft-man-con').html(readme);
}

BIN
plugins/jenkins/ico.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Some files were not shown because too many files have changed in this diff Show More