1
0
mirror of https://shylinux.com/x/ContextOS synced 2025-04-25 16:58:06 +08:00

Compare commits

...

1015 Commits

Author SHA1 Message Date
shy
2a5a64530e opt some 2025-03-10 18:44:27 +08:00
shy
0bddd31b25 add some 2025-03-04 14:53:04 +08:00
shy
d347df63ea opt some 2025-03-03 22:14:23 +08:00
shy
ac4cf99a20 opt some 2025-03-03 18:46:39 +08:00
shy
3de53ca1d8 opt some 2025-03-02 22:37:02 +08:00
shy
473a68c9ac add some 2025-03-01 17:44:31 +08:00
shy
88944e138e opt some 2025-02-28 20:40:42 +08:00
shy
21669f0f0f opt some 2025-02-28 19:16:04 +08:00
shy
81078a3b7a opt some 2025-02-28 14:21:42 +08:00
shy
dce09aabf5 opt some 2025-02-27 17:58:59 +08:00
shy
51d6cfd067 opt some 2025-02-27 17:49:20 +08:00
shy
8e6c3d7275 opt some 2025-02-26 21:54:53 +08:00
shy
7a1687604b opt some 2025-02-25 22:00:56 +08:00
shy
c982d09daa opt some 2025-02-25 10:56:44 +08:00
root
9f323ebfd6 add some 2025-02-19 21:00:46 +08:00
shy
eecb6fe6df opt some 2025-02-18 15:34:44 +08:00
shy
b7c276a7b5 opt some 2025-02-18 11:28:58 +08:00
shy
14032e7259 opt some 2025-02-16 22:09:34 +08:00
shy
334c3c3371 opt some 2025-02-16 08:55:42 +08:00
shy
311f283c5f opt some 2025-02-16 08:44:12 +08:00
shy
18e2325b0d add some 2025-02-16 08:29:46 +08:00
shy
2dc75bec5c opt some 2025-02-16 08:24:04 +08:00
shy
956b5affb2 opt some 2025-02-16 08:23:55 +08:00
shy
d7071dbe26 opt some 2025-02-15 11:00:44 +08:00
shy
6b966c400b opt some 2025-02-15 11:00:01 +08:00
shy
7a77cc87f3 opt some 2025-02-15 10:58:21 +08:00
shy
4f94e2287e opt some 2025-02-14 13:31:33 +08:00
shy
d279dd7503 opt some 2025-02-14 13:04:41 +08:00
shy
45eca37d12 opt some 2025-02-14 12:56:37 +08:00
shy
409c53f26c opt some 2025-02-14 12:54:19 +08:00
shy
3faeb85998 opt some 2025-02-14 12:27:40 +08:00
shy
a7a3154c6e opt some 2025-02-14 00:48:11 +08:00
shy
ea818b457c opt some 2025-02-14 00:36:56 +08:00
shy
915330d435 opt some 2025-02-13 23:20:23 +08:00
shy
e8f2b8b757 opt some 2025-02-13 23:11:22 +08:00
shy
a5420e958a opt some 2025-02-13 22:53:10 +08:00
shy
d87b9c889f opt some 2025-02-13 22:49:09 +08:00
shy
094f23d1b8 opt some 2025-02-13 22:46:04 +08:00
shy
192e73004d opt some 2025-02-13 22:43:00 +08:00
shy
a73c715f0e opt some 2025-02-13 11:28:36 +08:00
root
2e1d2a7256 add some 2025-02-11 16:14:13 +08:00
shy
b5be3ac686 add some 2025-02-10 23:01:36 +08:00
root
65a337e727 add some 2025-02-10 08:30:11 +08:00
shy
fc75893210 opt some 2025-02-09 11:33:06 +08:00
shy
1785e85fbb add some 2025-02-09 11:32:11 +08:00
shy
715aab8ea8 add some 2025-02-09 11:32:06 +08:00
root
512812625a add some 2025-02-09 11:11:57 +08:00
shy
b34617c804 opt some 2025-02-05 17:50:01 +08:00
shy
3e756e3630 add some 2025-02-05 17:37:59 +08:00
root
95b0bc0853 add some 2025-02-05 09:44:30 +08:00
shy
6b7b0ea0ab add some 2025-02-05 09:25:39 +08:00
shy
121cad9ef5 opt some 2025-02-04 14:16:03 +08:00
root
ceee2e0268 add some 2025-02-04 11:59:27 +08:00
shy
ba55589135 opt some 2025-02-04 09:31:23 +08:00
root
ce5e4afbd1 add some 2025-02-02 18:00:18 +08:00
root
ce5aa5f240 add some 2025-01-29 12:01:02 +08:00
shy
3c1c151d38 opt some 2025-01-22 16:25:42 +08:00
root
51a013c0d5 add some 2025-01-22 15:32:50 +08:00
shy
58ef541862 opt some 2025-01-18 16:57:43 +08:00
root
b04a6edf08 add some 2025-01-14 08:46:17 +08:00
shy
30bc62f325 opt some 2025-01-13 13:39:22 +08:00
shy
721faf9fd5 add some 2025-01-12 21:53:39 +08:00
shy
48268f36a5 add some 2025-01-06 21:38:56 +08:00
root
195cb141da add some 2025-01-05 20:36:22 +08:00
root
fb82981102 add some 2025-01-05 20:36:09 +08:00
shy
2070343cad opt some 2025-01-05 12:09:06 +08:00
root
5b3c8766d9 add some 2025-01-02 18:29:48 +08:00
shy
fe47f800a2 add some 2025-01-01 09:23:44 +08:00
shy
b60e54c4a3 add some 2024-12-31 12:33:50 +08:00
shy
104987e47b opt some 2024-11-27 13:58:43 +08:00
shy
7471f9ae74 opt some 2024-11-23 10:20:37 +08:00
root
4fe2000455 add some 2024-11-23 10:18:34 +08:00
shy
d6fe45bb1b opt some 2024-10-20 18:43:32 +08:00
root
fed602aab2 add some 2024-10-20 08:16:27 +08:00
shy
a80a336ec7 opt some 2024-10-18 07:38:58 +08:00
root
6d523cd878 add some 2024-10-17 23:45:41 +08:00
root
2889f21b2f add some 2024-10-16 14:00:32 +08:00
shy
f7bc108272 opt some 2024-10-12 11:19:44 +08:00
root
bb8e9c1971 add some 2024-10-12 11:06:35 +08:00
shy
9db26bdf6b opt some 2024-10-09 15:08:50 +08:00
shy
387f81f0b0 add some 2024-10-01 08:47:52 +08:00
shy
17dc6b49d5 opt some 2024-09-19 21:25:38 +08:00
shy
112e506878 add some 2024-09-12 00:38:30 +08:00
shy
6659e7a88b opt some 2024-09-02 18:11:24 +08:00
shy
c7ccf380e8 opt some 2024-08-12 21:14:28 +08:00
shy
025988915a add some 2024-08-12 07:31:07 +08:00
shy
fc731726aa opt some 2024-08-11 02:18:05 +08:00
shy
0443ba02c1 add some 2024-08-11 02:06:42 +08:00
shy
edcfe5afa3 opt some 2024-08-05 23:22:36 +08:00
shy
dc4a6ba65b add some 2024-07-30 07:18:17 +08:00
shy
a1ab79bc1b add some 2024-07-24 20:32:55 +08:00
shy
2955192d1c add some 2024-07-22 22:45:27 +08:00
shy
8e6251d9d1 opt some 2024-07-21 16:17:43 +08:00
shy
dd929ee81d opt some 2024-07-21 16:11:11 +08:00
shy
64f2e03dc8 add some 2024-07-16 10:54:37 +08:00
shy
73a7bb032f add some 2024-07-16 08:03:36 +08:00
shy
a0b0699b58 add some 2024-07-15 23:03:03 +08:00
shy
e9966c034e add some 2024-07-15 18:59:22 +08:00
shy
981562c7ed opt some 2024-07-14 19:19:35 +08:00
shy
009ed2c1ae add some 2024-07-09 10:38:48 +08:00
shy
48657980cf add some 2024-07-06 02:04:24 +08:00
shy
474950255b add some 2024-07-04 19:35:02 +08:00
shy
bc4bc4b2d6 add some 2024-07-03 14:30:25 +08:00
shy
00d8255293 opt some 2024-07-01 11:03:34 +08:00
shy
2b1c8074c8 add some 2024-07-01 08:26:13 +08:00
shy
777b0b0f85 add some 2024-06-30 19:52:48 +08:00
shy
6d980ab742 add some 2024-06-29 23:57:24 +08:00
shy
07440cc6c4 add some 2024-06-20 10:50:51 +08:00
shy
a50fd5db39 add some 2024-06-19 09:11:55 +08:00
shy
b1dafd6eca add some 2024-06-17 21:29:26 +08:00
shy
b650d9baad add some 2024-06-17 18:27:55 +08:00
shy
a241d541c4 add some 2024-06-11 11:04:28 +08:00
shy
a3bcf1e645 opt some 2024-06-09 23:05:04 +08:00
shy
1edd43c97f add some 2024-06-08 23:06:42 +08:00
shy
5ed5c3df3c add some 2024-05-28 07:31:26 +08:00
shy
7c7686c5ac add some 2024-05-27 19:32:14 +08:00
shy
0ae0986696 add some 2024-05-26 11:57:46 +08:00
shy
fea4f85a3c add some 2024-05-26 11:28:27 +08:00
shy
d2cf10195c add some 2024-05-26 08:31:22 +08:00
shy
231dffffed opt some 2024-05-25 20:54:39 +08:00
shy
aeecf73d65 add some 2024-05-25 19:57:35 +08:00
shy
a759bf70a9 opt some 2024-05-22 23:14:56 +08:00
shy
992fa66c67 add some 2024-05-21 19:22:52 +08:00
shy
ac86be36c0 add some 2024-05-18 21:02:36 +08:00
shy
f42f1d5dc2 add some 2024-05-17 19:39:45 +08:00
shy
67a8d967b8 opt some 2024-05-17 00:47:17 +08:00
shy
08fb70cf75 add some 2024-05-15 15:59:02 +08:00
shy
4d7dde6302 add some 2024-05-14 23:27:46 +08:00
shy
edd47db9fa add tutor 2024-05-13 20:33:35 +08:00
shy
314618bfba add some 2024-05-12 15:24:16 +08:00
shy
25d64150f3 add some 2024-05-11 18:21:08 +08:00
shy
9a31c67145 add some 2024-05-09 22:48:09 +08:00
shy
ffda3c9b2b add some 2024-05-09 07:56:51 +08:00
shy
d71db49ca6 add some 2024-05-05 17:32:39 +08:00
shy
9c10238b5f add some 2024-05-04 19:20:45 +08:00
shy
4acede3b92 add some 2024-05-01 18:32:58 +08:00
shy
3ae4be388e add some 2024-05-01 18:26:24 +08:00
shy
d8ad3fa3c0 opt some 2024-04-27 19:06:20 +08:00
shy
3e237e6a4c add some 2024-04-27 18:35:19 +08:00
shy
9287c57088 add some 2024-04-27 09:21:03 +08:00
shy
2853afd2ed add some 2024-04-25 21:11:41 +08:00
shy
70a78e7770 add some 2024-04-24 16:31:37 +08:00
shy
9888a8aed1 add some 2024-04-24 10:23:31 +08:00
shy
e7502f03bd add some 2024-04-22 20:14:12 +08:00
shy
cf156fa573 add some 2024-04-22 10:34:21 +08:00
shy
860fe60b36 add some 2024-04-20 22:46:22 +08:00
shy
0fc5303e37 opt some 2024-04-20 22:28:41 +08:00
shy
de802deb89 opt some 2024-04-20 19:42:05 +08:00
shy
e0c6526286 add some 2024-04-20 19:26:30 +08:00
shy
b4a951cecc add some 2024-04-20 15:56:29 +08:00
shy
d586ddd5f0 add some 2024-04-19 19:35:36 +08:00
shy
8411e1d62b add some 2024-04-18 23:54:32 +08:00
shy
51e11b27a8 opt border 2024-04-18 22:15:34 +08:00
shy
035e55e86a add some 2024-04-18 14:04:15 +08:00
shy
2a86610366 add some 2024-04-18 13:40:52 +08:00
shy
f97b666bf5 add some 2024-04-18 10:48:47 +08:00
shy
921c4d2aa4 add some 2024-04-17 04:15:42 +08:00
shy
e6c7c0dc18 add some 2024-04-15 12:26:09 +08:00
shy
c586616827 add some 2024-04-14 19:26:37 +08:00
shy
8c1f31ff34 add some 2024-04-14 01:09:46 +08:00
shy
6e6786781d add some 2024-04-11 23:59:44 +08:00
root
c348459b8e add some 2024-04-11 22:20:58 +08:00
root
2456245f37 add some 2024-04-11 21:58:25 +08:00
shy
9b5c5336ee add some 2024-04-10 00:33:07 +08:00
shy
7c375a80e2 add some 2024-04-09 13:20:13 +08:00
shy
b951ad6cbc add some 2024-04-08 23:23:07 +08:00
shy
98043b3213 add some 2024-04-08 23:00:31 +08:00
shy
550e287f07 opt some 2024-04-07 23:25:50 +08:00
shy
b772486fee opt some 2024-04-07 23:23:27 +08:00
shy
756dc925d4 opt some 2024-04-07 23:23:07 +08:00
shy
7a95d0d64b add some 2024-04-07 23:14:29 +08:00
shy
3ea378c638 add some 2024-04-07 15:33:35 +08:00
shy
f28bac79a0 add some 2024-04-07 13:28:31 +08:00
shy
893a87dc18 add some 2024-04-07 02:23:06 +08:00
shy
51904057f8 add some 2024-04-06 15:05:32 +08:00
shy
04b862104b add some 2024-04-06 00:23:54 +08:00
shy
c582b902ba add some 2024-04-05 21:16:58 +08:00
shy
bcf0198006 add some 2024-04-04 15:34:21 +08:00
shy
ab4195d13e add some 2024-04-04 13:49:16 +08:00
shy
c77f8b0ee4 opt some 2024-04-03 03:32:26 +08:00
shy
130fb83421 add some 2024-04-03 03:27:51 +08:00
shy
945611c633 opt some 2024-04-03 03:05:03 +08:00
shy
f432d6cc8b opt some 2024-04-03 03:01:05 +08:00
shy
5c9edfa0c7 opt some 2024-04-03 02:56:05 +08:00
shy
11305ca63c add some 2024-04-03 01:19:07 +08:00
shy
9573211bd8 add some 2024-04-02 20:15:38 +08:00
shy
708f7840d2 add some 2024-04-01 20:08:33 +08:00
shy
ac45e590af add some 2024-03-30 22:26:07 +08:00
shy
d2207d4ecf add some 2024-03-30 22:09:29 +08:00
shy
2c2ee34c13 add package 2024-03-28 23:45:12 +08:00
shy
1a65ce5f5a add some 2024-03-28 08:57:35 +08:00
shy
c9190b797b add some 2024-03-27 13:25:54 +08:00
shy
0fab1107e9 add some 2024-03-27 00:03:25 +08:00
shy
3ad0c3f0ab add some 2024-03-26 15:32:36 +08:00
shy
83168f0a6c add some 2024-03-25 23:53:36 +08:00
shy
ba4d6d8427 add some 2024-03-25 12:29:49 +08:00
shy
5e3065882c add some 2024-03-23 21:42:21 +08:00
shy
3ae9595fe9 add some 2024-03-23 21:15:25 +08:00
shy
58d566ff23 add some 2024-03-23 13:23:58 +08:00
shy
c68d4a9089 add some 2024-03-23 00:22:28 +08:00
shy
df5c135b54 add some 2024-03-21 14:44:28 +08:00
shy
919eb3531e add some 2024-03-19 22:20:57 +08:00
shy
3a90eac79d opt some 2024-03-18 21:43:02 +08:00
shy
18dd20fac7 add some 2024-03-18 21:25:12 +08:00
shy
68a1f8f7c3 add some 2024-03-18 14:29:24 +08:00
shy
7326d3da6e add some 2024-03-18 13:28:14 +08:00
shy
c1c837e57c add some 2024-03-18 01:08:33 +08:00
shy
12daa6e4f8 add some 2024-03-18 00:54:14 +08:00
shy
76674ba510 opt some 2024-03-17 23:25:05 +08:00
shy
5f06ed7cf3 add some 2024-03-17 12:28:06 +08:00
shy
dc599872d6 add some 2024-03-16 15:33:58 +08:00
shy
cedfdf0507 add some 2024-03-16 12:38:48 +08:00
shy
7274fe8187 add some 2024-03-15 14:41:01 +08:00
shy
387d2999ef add some 2024-03-15 00:32:45 +08:00
shy
261e080d35 add some 2024-03-14 00:52:31 +08:00
shy
bd22ceedfc add some 2024-03-13 16:15:41 +08:00
shy
d596913ce6 opt some 2024-03-13 13:33:15 +08:00
shy
a564902f24 add some 2024-03-12 22:25:30 +08:00
shy
4d6efc3f4c add some 2024-03-12 21:45:34 +08:00
shy
f69f274fff add some 2024-03-12 21:02:45 +08:00
shy
4fb31dbc97 add some 2024-03-12 18:32:43 +08:00
shy
265f22b758 add some 2024-03-12 16:27:54 +08:00
shy
a486ea22b6 add some 2024-03-12 16:23:33 +08:00
shy
ddae463207 add some 2024-03-12 13:32:13 +08:00
shy
8006fcc0a5 add some 2024-03-12 10:20:18 +08:00
shy
90768437c8 opt some 2024-03-12 09:54:30 +08:00
shy
3ff9cb91dd add some 2024-03-12 09:51:57 +08:00
shy
519340e2fb opt some 2024-03-11 23:39:39 +08:00
shy
543f27be9c add some 2024-03-11 17:34:56 +08:00
shy
88f7df5440 add some 2024-03-10 10:52:33 +08:00
shy
322bff0c66 add some 2024-03-09 09:43:40 +08:00
shy
7262d6e2f8 add some 2024-03-08 19:04:28 +08:00
shy
9732ebf1b7 add some 2024-03-08 11:37:58 +08:00
shy
bc97e058b8 add ssh.cloud.tencent 2024-03-07 20:32:18 +08:00
shy
a1efe60fb9 add some 2024-03-07 10:39:46 +08:00
shy
ec45142f50 add some 2024-03-06 01:37:02 +08:00
shy
d3b9cf874d add some 2024-03-05 21:25:34 +08:00
shy
33e7c49d9c add some 2024-03-05 21:24:41 +08:00
shy
9f6e4514bd add some 2024-03-05 19:13:59 +08:00
shy
4855bb4e9e add some 2024-03-05 16:49:57 +08:00
shy
88eccd8c36 opt portal 2024-03-05 13:56:04 +08:00
shy
cd06eabdf4 opt some 2024-03-04 23:29:04 +08:00
shy
90e97adf1c add some 2024-03-04 16:51:57 +08:00
shy
9b77296bea add some 2024-03-04 12:45:47 +08:00
shy
4716e39ea5 add some 2024-03-03 20:15:30 +08:00
shy
26677df67d add some 2024-03-03 17:17:28 +08:00
shy
2ce28fd712 add some 2024-03-03 14:30:08 +08:00
shy
ca19320a58 opt some 2024-03-02 21:48:15 +08:00
shy
512fa64417 add some 2024-03-02 19:06:33 +08:00
shy
6b94e1d07c add some 2024-03-02 19:03:35 +08:00
shy
536f512293 add some 2024-03-02 17:26:02 +08:00
shy
4ac554251e add some 2024-03-01 21:22:06 +08:00
shy
fb72cbfbae add some 2024-03-01 20:35:57 +08:00
shy
7cb15fb817 add some 2024-03-01 15:58:09 +08:00
shy
ea8aedd0b9 add some 2024-03-01 15:28:41 +08:00
shy
e273d35260 add some 2024-02-29 20:14:40 +08:00
shy
7151f8392f add web.stream 2024-02-29 14:04:32 +08:00
shy
035d1cc92a opt some 2024-02-28 23:30:35 +08:00
shy
aa9cbe981f opt some 2024-02-27 22:03:26 +08:00
shy
638dbd7f15 add some 2024-02-25 13:22:46 +08:00
shy
f05ea3338b add some 2024-02-24 23:28:44 +08:00
shy
a974ed24a9 add some 2024-02-24 23:28:15 +08:00
shy
b1c196eb98 opt some 2024-02-24 15:31:15 +08:00
shy
31e454755d add some 2024-02-24 13:40:07 +08:00
shy
ff6796bb53 add some 2024-02-24 12:32:56 +08:00
shy
feb5363eab add some 2024-02-24 00:33:43 +08:00
shy
cb90f9ca7f add some 2024-02-22 14:37:16 +08:00
shy
cd55ef9df8 add some 2024-02-22 13:28:00 +08:00
shy
004652d42d add some 2024-02-22 08:27:28 +08:00
shy
8a028c89b4 add some 2024-02-22 08:16:17 +08:00
shy
d6f301bbe1 add some 2024-02-21 00:42:36 +08:00
shy
a9a8c78c59 add some 2024-02-18 14:23:25 +08:00
shy
420f3a7e11 add some 2024-02-18 12:31:04 +08:00
shy
facd4b5f42 add some 2024-02-17 08:19:40 +08:00
shy
768487c059 add some 2024-02-16 00:28:56 +08:00
shy
601acc9b4b add some 2024-02-15 16:21:51 +08:00
shy
5f76efd1f6 add toast hash 2024-02-15 15:58:14 +08:00
shy
ad22a48cd0 add some 2024-02-15 00:59:18 +08:00
shy
72a5ecd10d add some 2024-02-14 23:29:10 +08:00
shy
99bfd420bd del honor 2024-02-14 18:11:00 +08:00
shy
49e374d4ff opt matrix 2024-02-14 18:00:14 +08:00
shy
bdd0fb86b9 add matrix 2024-02-13 15:49:41 +08:00
shy
3fe7203aaf add island.matrix 2024-02-13 03:56:02 +08:00
shy
f5e9a974ef add some 2024-02-12 11:13:17 +08:00
shy
e44ad9011a add some 2024-02-11 22:56:35 +08:00
shy
c03babb086 add some 2024-02-06 23:26:31 +08:00
shy
5217168dce opt aaa 2024-02-06 17:56:54 +08:00
shy
5ab5b4c8b9 opt aaa.apply 2024-02-06 15:08:31 +08:00
shy
f73b577392 add some 2024-02-05 23:04:48 +08:00
shy
cf0222efbc opt theme 2024-02-03 17:56:51 +08:00
shy
e6700107cb add some 2024-02-02 17:49:36 +08:00
shy
f0cc2db8a0 add some 2024-02-02 00:23:24 +08:00
shy
17ffcef6ef add island.group 2024-02-02 00:05:42 +08:00
shy
4c7fa77442 add some 2024-01-31 23:37:22 +08:00
shy
6156c8f9be opt some 2024-01-30 22:06:30 +08:00
shy
a684b8e0ad add some 2024-01-30 21:54:26 +08:00
shy
9a8912321f add some 2024-01-30 21:54:21 +08:00
shy
e3785898e0 add some 2024-01-30 18:32:58 +08:00
shy
48d3d2f633 opt count 2024-01-30 12:54:17 +08:00
shy
f6fae66c8f add some 2024-01-29 21:24:02 +08:00
shy
3ee7968942 add some 2024-01-29 20:22:00 +08:00
shy
3d42851aee add some 2024-01-29 18:10:15 +08:00
shy
08c0dd82f5 opt some 2024-01-29 15:07:05 +08:00
shy
f8cae20ed0 add some 2024-01-29 10:57:04 +08:00
shy
638046ddef add some 2024-01-28 20:02:20 +08:00
shy
aa07ebe22f add some 2024-01-28 14:28:37 +08:00
shy
a9c64533cb add some 2024-01-28 14:00:59 +08:00
shy
bd918c3d77 add some 2024-01-27 22:38:07 +08:00
shy
e41f8efc5d add some 2024-01-27 17:35:40 +08:00
shy
7f4b8850a8 add some 2024-01-26 20:55:48 +08:00
shy
da67a11445 add some 2024-01-26 16:08:08 +08:00
shy
5a047779ac add some 2024-01-26 13:13:04 +08:00
shy
bb6caa7b08 opt const 2024-01-26 11:04:27 +08:00
shy
895e7a3f6b add some 2024-01-25 23:59:10 +08:00
shy
3be41009f2 add some 2024-01-25 15:03:17 +08:00
shy
f481fd8e43 add some 2024-01-24 21:43:25 +08:00
shy
f68e9bd38d add chat.message 2024-01-24 19:16:10 +08:00
shy
6dac3ee159 add chat.message 2024-01-24 19:15:46 +08:00
shy
8969252215 add some 2024-01-24 09:29:31 +08:00
shy
2d904f06c6 add web.store 2024-01-23 14:56:16 +08:00
shy
68e71550f9 add script 2024-01-22 22:24:34 +08:00
shy
b0f3f1fef3 add some 2024-01-21 23:08:04 +08:00
shy
e515b4e9bc add chat.script 2024-01-21 21:19:16 +08:00
shy
b58526ecb0 add chat.script 2024-01-21 16:01:28 +08:00
shy
0576907874 add some 2024-01-20 21:31:27 +08:00
shy
3ca5acc5e3 add some 2024-01-20 19:21:15 +08:00
shy
dbb0139c4b add some 2024-01-19 22:56:28 +08:00
shy
2a7fdb8431 add some 2024-01-19 21:10:05 +08:00
shy
9c7ec53b5f add some 2024-01-19 18:34:55 +08:00
shy
6b7a76b711 add some 2024-01-18 10:21:30 +08:00
shy
2370dc574c add some 2024-01-18 00:11:58 +08:00
shy
0cdb526588 add some 2024-01-17 19:32:56 +08:00
shy
71bf661e5f add some 2024-01-17 14:35:49 +08:00
shy
3077d9bac2 add some 2024-01-17 14:35:44 +08:00
shy
a265822d4e add some 2024-01-17 11:25:32 +08:00
shy
aebdbf7c6f add some 2024-01-16 15:28:51 +08:00
shy
a6bc20485e add some 2024-01-16 13:15:17 +08:00
shy
5a7cd859ad opt document 2024-01-15 12:19:15 +08:00
shy
7df9779939 add some 2024-01-15 09:07:44 +08:00
shy
ebb31cff54 add some 2024-01-14 20:21:43 +08:00
shy
3eadab1e75 opt some 2024-01-14 16:46:52 +08:00
shy
ac59ff235d add some 2024-01-14 13:11:12 +08:00
shy
a440e20876 opt island 2024-01-13 15:32:36 +08:00
shy
dbc605d23e add some 2024-01-13 08:47:29 +08:00
shy
b902fe472b opt layout 2024-01-11 12:33:28 +08:00
shy
9d628c1285 add some 2024-01-10 21:07:00 +08:00
shy
c7b3163266 add some 2024-01-10 13:31:42 +08:00
shy
dd6180c694 add some 2024-01-09 23:06:24 +08:00
shy
b1a55248e3 add some 2024-01-09 22:30:05 +08:00
shy
56b53afe44 opt some 2024-01-09 10:41:14 +08:00
shy
6e2ecf2d83 add some 2024-01-09 10:40:20 +08:00
shy
7d24b2ff44 add some 2024-01-08 21:47:40 +08:00
shy
e7a5a5f5f3 add some 2024-01-08 21:47:37 +08:00
shy
5998563dc7 opt aaa.offer 2024-01-08 20:57:55 +08:00
shy
823bb6a5bc opt aaa.offer 2024-01-08 18:59:48 +08:00
shy
bf67e54d58 add aaa.SendEmail 2024-01-08 13:18:38 +08:00
shy
c9d8f21a0c add some 2024-01-08 11:14:05 +08:00
shy
1162b66cee opt relay 2024-01-06 09:12:41 +08:00
shy
6a197a16e8 opt ice.MSG_DAEMON 2024-01-05 12:26:18 +08:00
shy
2eef7d92a6 add MergeLink 2024-01-04 17:34:07 +08:00
shy
cf578ac318 add some 2024-01-04 10:17:22 +08:00
shy
31c61f34ee add some 2024-01-03 22:02:54 +08:00
shy
26aeff1eb4 opt some 2024-01-03 20:25:16 +08:00
shy
a318e309a2 add some 2024-01-03 19:43:58 +08:00
shy
e67ab8163d add some 2024-01-03 19:42:21 +08:00
shy
cea512992b add some 2024-01-03 17:34:55 +08:00
shy
381af478f1 opt aaa.sesss 2024-01-02 17:37:27 +08:00
shy
b754a75445 opt aaa.sess 2024-01-02 16:16:21 +08:00
shylinux@163.com
115f7052a4 opt aaa.apply 2024-01-02 12:21:10 +08:00
shy
25d2cf981a add aaa.apply 2024-01-01 20:35:37 +08:00
shy
fda2a2db99 opt git 2023-12-30 20:19:17 +08:00
shy
9acbedd8cf opt dream 2023-12-30 11:24:17 +08:00
shy
e73f97948e opt url 2023-12-29 17:59:14 +08:00
shy
f7c9b36f69 add status.source 2023-12-28 23:19:14 +08:00
shy
cf5731b2bb opt portal 2023-12-28 10:04:58 +08:00
shy
0857c04f7d opt icon 2023-12-26 18:36:04 +08:00
shy
8bf9cfc137 opt debug 2023-12-22 23:00:10 +08:00
shy
efb3564e7c opt debug 2023-12-22 17:49:40 +08:00
shy
c35b20d75b opt some 2023-12-21 19:28:13 +08:00
shy
4a5d3cff30 add some 2023-12-21 15:54:49 +08:00
shy
e0b6d31a42 add some 2023-12-21 13:22:38 +08:00
shy
e86df95f97 opt space 2023-12-21 12:29:56 +08:00
shy
9542e862a7 opt some 2023-12-21 00:31:42 +08:00
shy
623da7e70c opt repos 2023-12-21 00:01:51 +08:00
shy
612933f445 add some 2023-12-20 15:05:09 +08:00
shy
386b568a9a add some 2023-12-13 12:40:31 +08:00
shy
1e5902bd6e opt some 2023-12-13 12:24:01 +08:00
shy
44935edd2d add some 2023-12-13 12:22:50 +08:00
shy
f4cfc5a812 add some 2023-12-13 09:49:38 +08:00
shy
88cf7e50fd add some 2023-12-12 21:47:17 +08:00
shy
3923672449 add some 2023-12-12 21:42:43 +08:00
shy
18c809858b add some 2023-12-12 15:28:50 +08:00
shy
66a479b63f add some 2023-12-12 14:57:10 +08:00
shy
caee12d3c8 add some 2023-12-11 16:40:52 +08:00
shy
2072eb8cfb add checkbox 2023-12-11 15:38:55 +08:00
shy
42fd2f8490 opt mp 2023-12-10 09:51:09 +08:00
shy
00cbffcec2 add wx 2023-12-10 00:17:15 +08:00
shy
96cf11c59e add wx.ide autogen 2023-12-09 18:04:15 +08:00
shy
03c8b5ad66 opt web.stats 2023-12-08 19:39:30 +08:00
shy
ddf7a9dd38 opt some 2023-12-08 12:01:22 +08:00
shy
03663b6ad6 add usr/program/ 2023-12-07 22:48:22 +08:00
shy
289f2e6b5a opt some 2023-12-07 13:19:23 +08:00
shy
81d2e285c7 opt some 2023-12-07 11:11:16 +08:00
shy
1024a6969a fix share 2023-12-07 08:57:52 +08:00
shy
ea8eaa0ecf add relay.go 2023-12-06 13:56:01 +08:00
shy
6f43d500f8 add relay.go 2023-12-06 12:51:40 +08:00
shy
5339860895 add some 2023-12-05 23:18:08 +08:00
shy
18e8fbba5e opt some 2023-12-05 18:01:24 +08:00
shy
5de731d835 add some 2023-12-05 04:05:45 +08:00
shy
adf7a9cc95 add some 2023-12-03 10:52:21 +08:00
shy
a004412492 add relay 2023-12-02 15:38:49 +08:00
shy
05742b34f0 add boot 2023-12-02 11:14:08 +08:00
shy
83f68756e5 add some 2023-12-02 09:59:38 +08:00
shy
bfe181ec1e add rc_local.sh 2023-12-01 23:33:41 +08:00
shy
d6582f37e4 add some 2023-12-01 12:26:00 +08:00
shy
b54910b817 add web.chat.wx.ide 2023-11-30 13:49:22 +08:00
shy
6a77b95906 add some 2023-11-30 13:14:57 +08:00
shy
c0dcf39538 opt wx.ide 2023-11-29 16:11:21 +08:00
shy
8aa0cbad84 opt some 2023-11-27 19:02:42 +08:00
shy
9c0cb9bbc2 add some 2023-11-27 15:01:07 +08:00
shy
41ea46126f add some 2023-11-27 14:00:42 +08:00
shy
5287572e06 add some 2023-11-27 13:24:35 +08:00
shy
23933c678a add some 2023-11-27 13:18:56 +08:00
shy
ebf57cebf2 add some 2023-11-27 10:57:23 +08:00
shy
05ae6c4e30 opt etc/conf 2023-11-27 09:38:43 +08:00
shy
d0ad38096f add some 2023-11-27 00:06:56 +08:00
shy
91a01c234e add main.css 2023-11-26 21:08:39 +08:00
shy
0d807e22f3 opt desktop 2023-11-26 13:43:18 +08:00
shy
fa042bf109 opt favor 2023-11-26 00:04:21 +08:00
shy
e8ddc340e0 opt theme 2023-11-23 23:02:27 +08:00
shy
d6a124e879 add some 2023-11-22 22:43:33 +08:00
shy
d23c37c9bc add some 2023-11-22 10:48:56 +08:00
shy
37d56acd92 add some 2023-11-22 10:17:25 +08:00
shy
ce157b7cf5 add mp 2023-11-21 15:53:30 +08:00
shy
109c00dc0c add wx.ide 2023-11-20 22:33:53 +08:00
shy
961b15f01d add wx.ide 2023-11-20 22:33:38 +08:00
shy
dae08e84d5 add mp 2023-11-18 16:20:10 +08:00
shy
96bb645e8e add mp 2023-11-18 13:06:45 +08:00
shy
8745682d94 add mp 2023-11-18 00:05:02 +08:00
shy
a45584dcd0 add some 2023-11-16 21:35:55 +08:00
shy
7d7d7f36a6 add some 2023-11-16 18:00:47 +08:00
shy
d164db52cd opt some 2023-11-16 17:01:07 +08:00
shy
2d32476d4d add stats 2023-11-16 16:49:07 +08:00
shy
572f91074e add some 2023-11-16 13:53:24 +08:00
shy
163ebcf921 add stats 2023-11-16 13:11:17 +08:00
shy
badb3a5ef1 add asset 2023-11-16 00:27:19 +08:00
shy
805658ea63 add some 2023-11-15 11:11:37 +08:00
shy
d3c548fbb4 add some 2023-11-14 08:46:54 +08:00
shy
753fd59c72 opt header 2023-11-12 10:54:13 +08:00
shy
e2ccbb900d add header 2023-11-12 08:29:41 +08:00
shy
6247460c0c add some 2023-11-11 19:53:56 +08:00
shy
243623d883 opt some 2023-11-11 14:21:12 +08:00
shy
b2f7a67715 add some 2023-11-11 14:06:51 +08:00
shy
e62c68ff12 add some 2023-11-11 14:06:28 +08:00
shy
3a08da5fa0 add some 2023-11-11 00:07:11 +08:00
shy
96d73e66cf add wx.shy 2023-11-10 17:34:15 +08:00
shy
71394f99ac add wx.shy 2023-11-10 02:17:10 +08:00
shy
3f04db079f add wx.shy 2023-11-10 02:13:02 +08:00
shy
80ce15d2c2 opt some 2023-11-09 09:09:43 +08:00
shy
3dd920a5a7 add some 2023-11-08 18:22:54 +08:00
shy
4c3f37fbcc add some 2023-11-08 17:57:49 +08:00
shy
dae976b72c add some 2023-11-08 00:59:33 +08:00
shy
dd0977e812 add some 2023-11-07 09:30:26 +08:00
shy
01fde97a9d add some 2023-11-06 17:09:14 +08:00
shy
76adc9d810 add some 2023-11-06 16:02:37 +08:00
shy
a844092744 opt some 2023-11-06 15:40:28 +08:00
shy
56bcf2c536 add geo 2023-11-05 13:31:22 +08:00
shy
8c4af1abca add some 2023-11-05 08:33:32 +08:00
shy
13faf105c0 opt some 2023-11-03 13:28:24 +08:00
shy
5e5d2e65e7 add some 2023-11-03 12:22:04 +08:00
shy
ffc97b35bb add some 2023-11-03 00:02:51 +08:00
shy
28f37662f3 add some 2023-11-02 23:25:43 +08:00
shy
cf7d878b6e add some 2023-11-02 17:10:06 +08:00
shy
bd0ea44624 add some 2023-11-02 15:15:58 +08:00
shy
423e028ffd add some 2023-11-02 11:51:07 +08:00
shy
8d968457c9 add some 2023-11-01 20:09:00 +08:00
shy
dcdd135714 add some 2023-11-01 19:36:23 +08:00
shy
02f7cd2b50 add some 2023-10-31 10:00:17 +08:00
shy
0dbd08df81 add some 2023-10-31 07:36:34 +08:00
shy
a964f13582 add some 2023-10-29 22:32:43 +08:00
shy
d9b0db22b4 add some 2023-10-29 10:09:33 +08:00
shy
ae8fa41793 add some 2023-10-27 13:39:22 +08:00
shy
110c499129 opt some 2023-10-26 18:02:29 +08:00
shy
0e25bac70f add some 2023-10-23 22:30:39 +08:00
shy
8fac3f63ab opt some 2023-10-23 18:55:02 +08:00
shy
0b88317486 opt some 2023-10-20 00:35:24 +08:00
shy
12652b8e46 opt some 2023-10-19 21:09:04 +08:00
shy
b4625698fa add some 2023-10-17 16:19:25 +08:00
shy
83c00fcd0e add some 2023-10-16 18:28:14 +08:00
shy
008505262b add some 2023-10-13 22:28:33 +08:00
shy
e68059a9a4 add some 2023-10-13 21:05:34 +08:00
shy
962965f996 add some 2023-10-13 10:12:51 +08:00
shy
b68d75d9eb add some 2023-10-12 20:14:37 +08:00
shy
716b791759 add some 2023-10-12 11:54:31 +08:00
shy
6281fb9b1b opt some 2023-10-09 20:22:12 +08:00
shy
2fd2496f83 opt wiki 2023-10-09 13:07:52 +08:00
shy
3dce05fbcf add some 2023-10-08 16:59:25 +08:00
shy
725b12b9b3 add some 2023-10-07 07:49:48 +08:00
shy
5140d5930c add some 2023-10-05 21:14:57 +08:00
shy
b764a459f5 opt code 2023-10-05 11:55:41 +08:00
shy
e257fa9a6a add some 2023-10-03 20:03:26 +08:00
shy
a5c3bc635c add some 2023-10-03 19:07:08 +08:00
shy
22cb595a55 add some 2023-10-03 17:49:53 +08:00
shy
75a41013ad add some 2023-09-29 12:27:32 +08:00
shy
d3462778f4 add some 2023-09-26 10:06:49 +08:00
shy
4c0f0c35f7 add some 2023-09-25 19:47:15 +08:00
shy
0b96712c68 add some 2023-09-22 07:17:39 +08:00
shy
3a12d3e725 add some 2023-09-21 01:33:43 +08:00
shy
3027067db0 add some 2023-09-18 22:08:17 +08:00
shy
26a1053e16 add icon 2023-09-18 22:07:56 +08:00
shy
3b8f806e6d add some 2023-09-18 15:21:25 +08:00
shy
cc353d8e17 add some 2023-09-17 15:40:32 +08:00
shy
3de45b88ca add some 2023-09-16 17:39:48 +08:00
shy
c01f2adb8c add some 2023-09-16 12:04:27 +08:00
shy
b30cae31dc add some 2023-09-12 08:09:42 +08:00
shy
c208af0857 add some 2023-09-11 09:26:30 +08:00
shy
5f51763af6 add some 2023-09-10 17:14:51 +08:00
shy
fce04a14de add clock 2023-09-08 18:20:48 +08:00
shy
37dbc62647 add clock 2023-09-08 18:20:35 +08:00
shy
fe22bf0727 opt some 2023-09-06 16:12:40 +08:00
shy
4bbd6667bc add some 2023-09-05 12:27:20 +08:00
shy
42b1634e6d add some 2023-09-04 11:39:49 +08:00
shy
1ca4df670c add git.search 2023-09-03 23:34:59 +08:00
shy
3183f1ccc7 add some 2023-09-01 15:57:18 +08:00
shy
72591a2230 add some 2023-08-30 22:09:43 +08:00
shy
a91917e540 opt index.css 2023-08-28 19:42:44 +08:00
shy
d568180aa9 opt theme 2023-08-28 13:47:29 +08:00
shy
dccf40a6e5 opt studio 2023-08-27 21:06:35 +08:00
shy
6bb170c74c opt icon 2023-08-26 22:46:08 +08:00
shy
72ff32739d add some 2023-08-26 21:09:24 +08:00
shy
e157954f9d add some 2023-08-23 11:15:35 +08:00
shy
861d8bbfc7 add some 2023-08-21 19:05:55 +08:00
shy
a05536eeb0 add some 2023-08-21 19:05:48 +08:00
shy
6b4fa06ca6 add mail 2023-08-21 01:34:18 +08:00
shy
973cab3c2f add email 2023-08-19 22:07:14 +08:00
shy
40ee45f00b add some 2023-08-18 18:06:58 +08:00
shy
8c72c9e113 add some 2023-08-18 17:46:25 +08:00
shy
6e0370da49 add some 2023-08-18 17:05:43 +08:00
shy
c5b83801b4 add some 2023-08-18 13:04:24 +08:00
shy
2653787c32 add some 2023-08-17 00:15:30 +08:00
shylinux
ac9d146b21 add some 2023-08-16 23:39:10 +08:00
shylinux
36ae89dbea add some 2023-08-16 01:27:48 +08:00
shy
378e62e0a5 add some 2023-08-13 22:14:25 +08:00
shy
efc3f1a3e8 add some 2023-08-13 09:59:48 +08:00
0677a84dff opt some 2023-08-10 21:28:00 +08:00
7d415f29d0 add some 2023-08-08 03:45:21 +08:00
1449b7c61e add some 2023-08-04 18:19:22 +08:00
ed2601ece7 add some 2023-08-03 12:17:13 +08:00
b65a01d390 add some 2023-08-01 10:05:00 +08:00
af1832ea62 add some 2023-07-31 18:45:06 +08:00
293e34b19b add some 2023-07-31 16:49:19 +08:00
7ffda2824c add some 2023-07-31 00:17:41 +08:00
9c3b2f0d5c add some 2023-07-31 00:17:34 +08:00
873ed68008 add some 2023-07-30 23:43:21 +08:00
dff4b6e553 opt some 2023-07-30 23:35:46 +08:00
eeb738ba65 add web.flows 2023-07-30 09:48:36 +08:00
0263c88eb4 opt some 2023-07-28 22:49:40 +08:00
3409f40031 add web.route 2023-07-28 00:49:12 +08:00
f7fef37359 add some 2023-07-26 17:59:24 +08:00
4bfe2ee915 add web.count 2023-07-26 14:23:40 +08:00
d3c142ff49 add some 2023-07-25 17:46:35 +08:00
3ed018b934 opt some 2023-07-22 16:56:00 +08:00
01f685cfb6 opt some 2023-07-22 10:57:17 +08:00
b3f6e23f94 opt some 2023-07-22 09:04:42 +08:00
65dc3e1135 opt some 2023-07-21 15:49:01 +08:00
e83499a4e3 opt some 2023-07-16 22:19:02 +08:00
25f9eeffee opt some 2023-07-16 19:27:22 +08:00
7cc4966a52 opt some 2023-07-16 17:23:02 +08:00
47af7b74c5 opt some 2023-07-16 14:04:57 +08:00
edbde954ce opt some 2023-07-15 10:14:40 +08:00
826dd83e69 opt git.service 2023-07-15 10:08:51 +08:00
3eecdc893c opt some 2023-07-15 00:38:28 +08:00
3ab5fb3f80 opt some 2023-07-15 00:13:34 +08:00
122056465e opt some 2023-07-14 12:59:42 +08:00
ad3040e680 opt some 2023-07-13 19:03:54 +08:00
7c99b97d87 opt some 2023-07-13 15:02:19 +08:00
229e4f1e4f opt some 2023-07-12 23:14:06 +08:00
50ca215bff opt some 2023-07-12 22:47:37 +08:00
92096a4933 opt some 2023-07-12 12:50:53 +08:00
0ef2a48e74 opt some 2023-07-12 12:50:03 +08:00
c993d60caf opt some 2023-07-11 17:59:05 +08:00
c72f8bc3ad opt some 2023-07-11 11:05:11 +08:00
cf0cf30b3f opt some 2023-07-10 12:48:35 +08:00
37df5ff34c opt some 2023-07-08 12:42:47 +08:00
b6efe088e4 opt some 2023-07-08 09:00:54 +08:00
d60d496026 opt some 2023-07-08 08:56:04 +08:00
shy
943f58396a opt some 2023-07-08 08:40:48 +08:00
shy
e049c89b93 opt some 2023-07-07 19:55:44 +08:00
885cacfd22 opt some 2023-07-07 18:40:08 +08:00
3577b4b867 opt some 2023-07-07 16:34:36 +08:00
a26f0f7f2a opt some 2023-07-06 18:49:54 +08:00
5f57b9ec1d opt feel 2023-07-06 18:47:55 +08:00
a21fe41952 opt some 2023-07-05 15:59:23 +08:00
d501df7629 opt portal 2023-07-05 00:45:09 +08:00
ac8c80a85c opt some 2023-07-04 11:04:46 +08:00
f7eff930b8 opt portal 2023-07-01 22:35:46 +08:00
1fe76aa8ef opt document 2023-07-01 13:44:02 +08:00
8833f00015 opt portal 2023-06-29 21:23:35 +08:00
240c75c781 add portal 2023-06-28 21:54:44 +08:00
26cfb0eabd opt theme 2023-06-24 11:55:29 +08:00
861e6185a9 opt some 2023-06-23 18:31:10 +08:00
54394d9e5e opt some 2023-06-23 11:39:53 +08:00
ea59996834 opt some 2023-06-15 16:18:01 +08:00
35bd43186c opt vue 2023-06-04 21:28:29 +08:00
d9175929ad add node 2023-06-03 09:06:50 +08:00
f0e0de9fb9 add some 2023-06-01 09:56:31 +08:00
dc5cda7f8b opt some 2023-05-31 01:17:47 +08:00
145b823171 add some 2023-05-29 15:34:09 +08:00
e11bc448a4 add some 2023-05-28 20:07:09 +08:00
80f68b136a opt some 2023-05-27 12:19:37 +08:00
476bda6390 opt some 2023-05-26 15:49:55 +08:00
9bdc4efbd9 add some 2023-05-25 16:00:59 +08:00
280d00918b opt some 2023-05-24 17:01:42 +08:00
a898599832 opt some 2023-05-24 01:44:42 +08:00
c4adefbee7 opt some 2023-05-23 01:35:54 +08:00
9bc86f08be opt some 2023-05-22 23:41:48 +08:00
8678022db6 opt some 2023-05-22 23:14:55 +08:00
ee2bccda48 opt some 2023-05-22 22:43:38 +08:00
ec838a3224 opt some 2023-05-22 22:40:28 +08:00
9a8906da35 add some 2023-05-22 22:20:07 +08:00
507b3d41b7 add some 2023-05-22 15:48:42 +08:00
cb8a1809b2 add some 2023-05-20 14:37:56 +08:00
f5efc8e8fe opt some 2023-05-16 09:23:19 +08:00
a9ed601d8f opt some 2023-05-14 16:07:19 +08:00
301bed99d1 add some 2023-05-14 16:02:25 +08:00
94fdbb79df opt some 2023-05-13 20:46:28 +08:00
6943a096ac opt some 2023-05-12 00:03:22 +08:00
238a44b8f2 opt some 2023-05-11 13:11:26 +08:00
abae040f98 opt some 2023-05-10 10:38:24 +08:00
bf4080d796 opt some 2023-05-07 22:23:41 +08:00
00c88312b1 opt some 2023-05-07 22:23:22 +08:00
85ba6a51f4 add some 2023-05-05 08:34:36 +08:00
d8151b9fc7 opt some 2023-05-05 00:21:11 +08:00
53fc01266e opt some 2023-05-04 14:46:19 +08:00
d03033f18d opt some 2023-05-04 14:17:47 +08:00
525cf8bf08 opt macos 2023-05-03 23:23:42 +08:00
d542864c2b add searchs 2023-05-03 16:46:48 +08:00
8e3f3f8f15 opt some 2023-05-02 21:51:44 +08:00
ad31f2cbcc opt desktop 2023-05-02 17:30:05 +08:00
947d34a8d2 opt some 2023-05-02 07:42:13 +08:00
28820ac34d opt some 2023-04-30 13:03:18 +08:00
1b1c9eb0ce opt macos 2023-04-30 10:49:48 +08:00
5259773d90 add applications 2023-04-29 23:16:49 +08:00
d97767507c opt theme 2023-04-29 20:19:21 +08:00
bd01155d8b add macosx 2023-04-28 22:35:04 +08:00
97362018d9 opt some 2023-04-27 14:25:48 +08:00
08d5fd0bd0 opt service 2023-04-26 23:37:18 +08:00
51d8a084d9 opt some 2023-04-26 00:33:00 +08:00
1f8ad1ca77 add space 2023-04-25 22:42:09 +08:00
9eda869ff6 opt some 2023-04-24 21:46:16 +08:00
a0b3d42fd8 opt some 2023-04-24 16:02:12 +08:00
b372525231 opt const 2023-04-23 12:08:03 +08:00
ea16ebfda7 opt some 2023-04-22 21:24:17 +08:00
b86b4195b4 opt some 2023-04-21 08:00:25 +08:00
1525852228 opt vimer.js 2023-04-20 21:01:02 +08:00
7cb0419b7e add some 2023-04-17 21:21:50 +08:00
d4f524891f opt some 2023-04-17 00:12:54 +08:00
562771d162 opt some 2023-04-16 22:37:21 +08:00
316c0dcda9 add some 2023-04-16 22:37:05 +08:00
e2b0755576 opt git 2023-04-16 16:01:57 +08:00
293bd8e11e add repos 2023-04-16 12:57:01 +08:00
38aa82e8c9 add git 2023-04-15 00:26:39 +08:00
cf7b6ff6a9 opt some 2023-04-14 16:17:08 +08:00
a31aa41a3b opt some 2023-04-14 10:20:55 +08:00
844fa4b01c opt story 2023-04-13 23:43:58 +08:00
6f289c2f14 opt wiki 2023-04-13 02:53:03 +08:00
e802328fcc opt some 2023-04-12 10:42:34 +08:00
93adcab4bf opt wiki 2023-04-12 10:35:17 +08:00
73d4adf07a opt kit 2023-04-10 00:27:21 +08:00
e557472834 opt stack 2023-04-07 21:41:55 +08:00
043586efcb opt type 2023-04-07 00:25:33 +08:00
8f1a284feb add yac.type 2023-04-06 15:35:23 +08:00
c3df162d11 opt some 2023-04-03 01:05:22 +08:00
a07152a643 opt some 2023-04-02 21:37:28 +08:00
3e4a62506b opt some 2023-04-02 15:40:02 +08:00
71c6127c6c add exp 2023-04-02 08:22:30 +08:00
acc990ac7f opt yac 2023-03-31 13:01:37 +08:00
13579d56d7 opt some 2023-03-30 08:34:51 +08:00
2513a37b7e opt yac 2023-03-30 07:38:37 +08:00
b28acce3bc opt yac 2023-03-29 15:15:14 +08:00
5cb37f6f46 opt yac 2023-03-29 12:55:03 +08:00
7aec5a9227 opt yac 2023-03-29 10:23:30 +08:00
77452654a8 opt yac 2023-03-28 22:38:14 +08:00
f07e8be264 opt base 2023-03-28 14:21:22 +08:00
888367f477 opt serve 2023-03-25 11:44:19 +08:00
79f5e2b493 opt some 2023-03-24 20:47:55 +08:00
803446a728 Merge branch 'master' of https://shylinux.com/x/contexts 2023-03-24 15:19:26 +08:00
a9b91341f4 opt some 2023-03-23 21:35:35 +08:00
96de3c751b opt some 2023-03-23 02:45:17 +08:00
f3cd010a2d opt some 2023-03-22 18:12:56 +08:00
4883012516 opt lock 2023-03-22 17:31:27 +08:00
93ed1e381f opt some 2023-03-20 01:26:29 +08:00
4a8d0ab69d opt some 2023-03-19 22:34:44 +08:00
de7bc7906d opt code 2023-03-19 15:18:49 +08:00
827478826c opt code 2023-03-17 08:09:07 +08:00
5d3f408634 opt code 2023-03-16 23:05:43 +08:00
bd43f59363 opt vimer.js 2023-03-15 20:37:34 +08:00
0b4b4f6735 opt xterm.go 2023-03-14 12:09:30 +08:00
5a4eda9bb3 opt some 2023-03-12 10:11:14 +08:00
9650b411d1 opt some 2023-03-11 17:20:51 +08:00
e32371da16 opt some 2023-03-11 11:44:57 +08:00
8c42753347 opt some 2023-03-11 11:21:13 +08:00
c873a3aa23 opt some 2023-03-11 11:07:39 +08:00
763f0d43d9 opt some 2023-03-10 22:14:45 +08:00
3bfac6e81e opt some 2023-03-10 17:21:21 +08:00
e0b085b32c opt some 2023-03-10 10:03:39 +08:00
6938d972a9 opt some 2023-03-10 07:10:13 +08:00
92bc2186ce opt code 2023-03-09 11:40:25 +08:00
07bfa7a98d opt code 2023-03-07 23:42:41 +08:00
439bd78535 opt some 2023-03-07 03:44:57 +08:00
fa5065b0f3 opt code 2023-03-07 03:44:34 +08:00
bc8eba229d opt module 2023-03-06 18:59:24 +08:00
746beb6247 opt some 2023-03-05 10:48:20 +08:00
e2bfbd56aa opt some 2023-03-04 21:00:57 +08:00
bddff57985 opt favor 2023-03-04 16:45:21 +08:00
17e1ce0f32 opt some 2023-03-03 08:50:44 +08:00
0ec2f3fd3a opt some 2023-03-02 20:38:32 +08:00
4313fdc8f9 opt some 2023-03-02 13:29:19 +08:00
f37610e90f opt some 2023-03-02 10:01:39 +08:00
fcdf60a409 opt some 2023-03-02 08:20:08 +08:00
1591e33d11 opt some 2023-03-02 00:40:28 +08:00
0bfad00322 opt some 2023-03-01 20:23:35 +08:00
682d362adb opt some 2023-03-01 19:17:32 +08:00
81b53fdada opt some 2023-03-01 18:48:11 +08:00
5fb0b39a01 opt some 2023-03-01 18:03:09 +08:00
58cb4cd35d opt some 2023-03-01 13:45:36 +08:00
e352d79c58 opt some 2023-03-01 13:02:35 +08:00
3b60ca35c4 opt some 2023-03-01 12:42:33 +08:00
ec7b4020d9 opt some 2023-02-28 21:46:01 +08:00
f48bd6a99a opt some 2023-02-28 17:17:22 +08:00
e2eccb3a84 opt some 2023-02-28 14:08:17 +08:00
harveyshao
4230bbd158 opt some 2023-02-24 00:01:15 +08:00
harveyshao
aebf0e0ef5 opt some 2023-02-21 21:12:41 +08:00
harveyshao
d0b1674189 opt some 2023-02-21 16:23:38 +08:00
shylinux
53d210aed0 opt some 2023-02-21 16:15:25 +08:00
harveyshao
1582e627dc opt some 2023-02-21 15:52:48 +08:00
shylinux
fe347b3f72 opt some 2023-02-21 15:17:17 +08:00
5f9a8a1599 opt some 2023-02-21 14:24:31 +08:00
harveyshao
b0a63dd112 opt intshell 2023-02-21 13:26:46 +08:00
shaoying
7a2f2f2b28 opt intshell 2023-02-21 08:22:48 +08:00
harveyshao
7ff38a4575 opt some 2023-02-20 20:38:11 +08:00
harveyshao
b19fc4fc58 opt some 2023-02-20 19:18:00 +08:00
harveyshao
689dd69894 opt some 2023-02-20 09:12:15 +08:00
harveyshao
672b1a91d0 opt module 2023-02-20 01:11:48 +08:00
harveyshao
0c08e5eb9d opt module 2023-02-20 01:07:43 +08:00
shaoying
3a1aa7a593 opt some 2023-02-19 20:44:58 +08:00
harveyshao
f06c47b6fa opt some 2023-02-19 20:26:33 +08:00
harveyshao
853afab87c opt some 2023-02-19 20:21:02 +08:00
harveyshao
e345dc317f opt some 2023-02-19 20:10:22 +08:00
harveyshao
b4354fa7f8 opt code 2023-02-19 19:14:30 +08:00
harveyshao
45c5cdf79b opt some 2023-02-18 13:06:03 +08:00
shaoying
b8dbea6213 opt some 2023-02-18 09:07:27 +08:00
shylinux
8df7dcafab opt some 2023-02-18 00:09:59 +08:00
shylinux
9dc30e4f0c opt some 2023-02-17 22:14:41 +08:00
shylinux
e280e63886 opt some 2023-02-17 15:08:56 +08:00
harveyshao
4c1295125b opt windows 2023-02-14 19:48:29 +08:00
shaoying
a1f55baf14 opt some 2023-02-08 23:09:28 +08:00
harveyshao
8477a5f831 opt inner.js 2023-01-25 23:13:45 +08:00
harveyshao
a324da2ab1 opt vimer.js 2023-01-25 00:36:00 +08:00
harveyshao
bb1c760a91 opt some 2023-01-23 14:20:52 +08:00
harveyshao
bf6bd59b16 opt some 2023-01-22 15:56:49 +08:00
harveyshao
0b6dc7695f opt some 2023-01-22 13:21:59 +08:00
harveyshao
1d9191d830 opt can.debug 2023-01-21 19:02:41 +08:00
harveyshao
d3db87c598 opt log 2023-01-20 14:51:33 +08:00
harveyshao
b11806d62b opt some 2023-01-19 13:56:06 +08:00
harveyshao
1e93dc2fbd opt onappend 2023-01-17 23:28:36 +08:00
harveyshao
bdf628eaf1 opt frame.js 2023-01-16 22:21:05 +08:00
harveyshao
8225085203 opt index.css 2023-01-15 18:00:38 +08:00
harveyshao
260dc069a5 opt some 2023-01-14 08:44:47 +08:00
harveyshao
92c7ad316c opt index.css 2023-01-13 16:11:41 +08:00
harveyshao
4a2a137112 opt some 2023-01-13 04:09:35 +08:00
harveyshao
7a51f891c0 opt inner.css 2023-01-12 20:21:59 +08:00
harveyshao
6156a52c13 add dark 2023-01-10 21:43:16 +08:00
harveyshao
cfb3446c1b opt some 2023-01-08 09:55:20 +08:00
ef046d48bb opt some 2023-01-03 15:11:48 +08:00
harveyshao
505b4102c2 opt some 2023-01-02 18:54:36 +08:00
harveyshao
b781f240bd opt some 2023-01-01 22:45:20 +08:00
harveyshao
d0ab031ee9 opt some 2022-12-31 21:28:13 +08:00
shaoying
4be627b252 opt some 2022-12-27 11:52:05 +08:00
harveyshao
2059a45ca6 opt some 2022-12-26 23:18:48 +08:00
harveyshao
1b7591f4cc opt some 2022-12-26 15:25:39 +08:00
harveyshao
b618338913 opt some 2022-12-26 10:46:32 +08:00
shaoying
1ea965be17 opt some 2022-12-26 09:49:30 +08:00
shaoying
ef633de5d3 opt some 2022-12-26 08:56:26 +08:00
harveyshao
4829592139 opt some 2022-12-25 21:54:38 +08:00
harveyshao
3e3f1b8dc3 opt some 2022-12-25 21:27:28 +08:00
harveyshao
83d78db8b3 opt some 2022-12-25 21:12:54 +08:00
harveyshao
f7a9439acb opt some 2022-12-24 23:44:22 +08:00
harveyshao
a348e92770 opt some 2022-12-24 23:44:18 +08:00
harveyshao
f01ef4dca9 opt some 2022-12-24 15:13:41 +08:00
3a67c65dba opt some 2022-12-24 10:14:34 +08:00
harveyshao
83fc676926 opt some 2022-12-22 20:43:49 +08:00
6e70543e44 opt some 2022-12-19 19:47:25 +08:00
harveyshao
8755fa7347 opt some 2022-12-19 18:02:46 +08:00
shaoying
18f8a84f7d opt html 2022-12-17 09:11:46 +08:00
harveyshao
de3adc66e2 opt some 2022-12-16 23:53:20 +08:00
a3d22d86b0 opt some 2022-12-15 14:51:49 +08:00
shaoying
e85fdc93dd opt some 2022-12-15 09:14:54 +08:00
harveyshao
1fde418d51 opt chrome 2022-12-14 13:42:10 +08:00
harveyshao
e5df07e7b4 opt some 2022-12-13 21:50:48 +08:00
harveyshao
b7c5eefafd opt vim 2022-12-13 21:27:30 +08:00
harveyshao
b709d1c10b opt vim 2022-12-12 19:42:17 +08:00
harveyshao
13ab66df3f opt bash 2022-12-11 20:18:44 +08:00
shaoying
4052e9ff31 opt some 2022-12-09 11:39:23 +08:00
harveyshao
5c4eadbb8e opt some 2022-12-08 22:42:40 +08:00
harveyshao
74a006273a opt some 2022-12-08 22:06:00 +08:00
harveyshao
36f9745a33 opt git 2022-12-08 21:16:16 +08:00
harveyshao
376960ea16 opt git 2022-12-07 03:13:04 +08:00
bebe388ef4 opt some 2022-12-05 16:54:04 +08:00
harveyshao
d1fbdee3b6 opt some 2022-12-05 16:50:33 +08:00
harveyshao
99690531ed opt git 2022-12-05 16:47:13 +08:00
005ba29cc2 opt some 2022-12-05 09:46:55 +08:00
harveyshao
151400a525 opt some 2022-12-04 20:28:59 +08:00
shaoying
e97619a0aa opt some 2022-12-04 19:12:37 +08:00
harveyshao
eb34b9afcc opt code 2022-12-04 13:05:29 +08:00
shaoying
39bb6f5702 opt code 2022-12-04 09:17:15 +08:00
shaoying
c143bf646d opt some 2022-12-03 18:05:51 +08:00
shaoying
0c2cd488ce opt web 2022-12-03 09:38:35 +08:00
harveyshao
1461f67275 opt some 2022-11-29 15:59:53 +08:00
harveyshao
4fd60c6856 opt web 2022-11-28 00:36:15 +08:00
harveyshao
8fefa66945 opt dream 2022-11-18 21:59:39 +08:00
harveyshao
fe58d3b390 opt chat 2022-11-18 14:40:52 +08:00
harveyshao
a273e294ad opt some 2022-11-15 21:29:02 +08:00
harveyshao
7ecf5fc586 opt some 2022-11-14 23:19:19 +08:00
harveyshao
ed355ea42a opt main.js 2022-11-14 15:26:22 +08:00
harveyshao
7a2b2a50dc opt chat 2022-11-12 22:15:36 +08:00
harveyshao
8b54528604 opt chat 2022-11-12 00:34:07 +08:00
harveyshao
6b9caa76c1 opt some 2022-11-10 23:22:31 +08:00
harveyshao
957dd921f4 opt some 2022-11-05 14:46:38 +08:00
shaoying
ed157d2110 opt some 2022-11-05 09:13:07 +08:00
harveyshao
e7dd84c6d2 opt some 2022-11-04 23:15:10 +08:00
shaoying
0d01f0e54e opt chart.go 2022-11-04 18:31:52 +08:00
harveyshao
36a1ae14b9 opt chart.go 2022-11-04 16:26:05 +08:00
harveyshao
5cf1729d25 opt wiki 2022-11-04 02:41:51 +08:00
harveyshao
bb471c2089 opt some 2022-10-27 22:28:42 +08:00
harveyshao
52e5771416 opt some 2022-10-22 11:24:54 +08:00
harveyshao
a510c7d5df opt some 2022-10-20 20:27:41 +08:00
shaoying
1c2d515ce4 opt some 2022-10-18 15:49:26 +08:00
harveyshao
df919a40e8 opt some 2022-10-18 12:23:55 +08:00
harveyshao
402272d920 opt some 2022-10-17 14:06:35 +08:00
harveyshao
39ee04aadd opt some 2022-10-16 13:55:46 +08:00
harveyshao
32f4d8fa8e opt plan 2022-10-15 23:18:17 +08:00
harveyshao
1f6b4942dd opt some 2022-10-15 11:46:12 +08:00
harveyshao
23967d62f3 opt code 2022-10-15 01:50:19 +08:00
harveyshao
339e035443 opt some 2022-10-08 09:23:07 +08:00
harveyshao
c86951c16e opt some 2022-10-07 22:40:11 +08:00
harveyshao
f6a6f8ceff opt some 2022-10-07 13:48:48 +08:00
shaoying
d1cf9a68a7 opt some 2022-10-06 09:03:16 +08:00
shaoying
716e112d13 opt some 2022-10-04 23:00:09 +08:00
harveyshao
bb069ac546 opt some 2022-10-04 15:23:12 +08:00
shaoying
13dbde80ee opt some 2022-10-03 19:56:42 +08:00
shylinux@163.com
f434ea1231 opt some 2022-10-02 18:55:39 +08:00
shylinux@163.com
29b77a2962 opt some 2022-09-30 19:53:43 +08:00
86f8c70fd9 opt some 2022-09-30 09:07:52 +08:00
b029dce7d3 opt some 2022-09-29 18:41:57 +08:00
64d3531510 opt some 2022-09-29 17:18:20 +08:00
5b650d353e opt some 2022-09-29 10:37:03 +08:00
7019ce5af4 opt chat 2022-09-29 10:34:55 +08:00
shylinux@163.com
6052f6fa9e opt some 2022-09-25 22:50:50 +08:00
283087d2ce opt some 2022-09-24 19:48:03 +08:00
shylinux@163.com
9a5ba7376e opt some 2022-09-24 10:16:44 +08:00
d44fd53f9f opt some 2022-09-23 23:56:50 +08:00
shylinux@163.com
cb8610a272 opt some 2022-09-23 23:43:11 +08:00
shaoying
3f02859263 opt some 2022-09-20 12:42:47 +08:00
2bc5476726 opt some 2022-09-19 23:09:53 +08:00
shylinux@163.com
7c0f8752b3 opt some 2022-09-19 23:07:58 +08:00
shylinux@163.com
dfce4f8561 opt some 2022-09-16 12:44:26 +08:00
shylinux@163.com
37afa6146d opt some 2022-09-16 08:02:19 +08:00
shaoying
19bf77250f opt some 2022-09-13 13:08:43 +08:00
shylinux@163.com
806a528eef opt some 2022-09-13 11:49:54 +08:00
shylinux@163.com
24c33f8d32 opt some 2022-09-13 11:44:01 +08:00
shylinux@163.com
cf0c15bc3a opt some 2022-09-11 19:18:35 +08:00
shylinux@163.com
651188fdf3 opt some 2022-09-09 07:41:35 +08:00
2b7ea60b2b opt some 2022-09-08 13:36:39 +08:00
3f6313759e opt some 2022-09-08 13:35:30 +08:00
dd9ae90de2 opt some 2022-09-03 16:44:32 +08:00
shylinux@163.com
3b5a6b3fcf opt some 2022-08-30 07:20:38 +08:00
shylinux
5a29ed7149 opt some 2022-08-29 08:36:05 +08:00
harveyshao
472e9e6e02 opt some 2022-08-28 20:35:47 +08:00
393d4f788b opt some 2022-08-28 18:15:23 +08:00
harveyshao
66c208357b opt some 2022-08-28 18:13:13 +08:00
cf3d0d7a05 opt some 2022-08-28 11:51:15 +08:00
ca5f1aa921 opt some 2022-08-28 09:20:53 +08:00
shylinux@163.com
315fd71355 opt some 2022-08-27 22:05:56 +08:00
shylinux@163.com
f066451adb opt some 2022-08-27 21:55:07 +08:00
shylinux@163.com
67b8ddd458 opt some 2022-08-27 21:54:45 +08:00
shylinux@163.com
fdf3c736d7 opt some 2022-08-27 18:52:21 +08:00
6253c2ece0 opt some 2022-08-26 12:51:07 +08:00
shylinux@163.com
ad6e86789f opt some 2022-08-26 10:39:46 +08:00
shylinux@163.com
6e797947eb opt some 2022-08-24 20:57:36 +08:00
12cdddba83 opt some 2022-08-24 16:35:24 +08:00
37485beb93 opt some 2022-08-24 14:26:29 +08:00
df706ba2bf opt some 2022-08-24 08:00:41 +08:00
0ea622c212 opt some 2022-08-21 19:22:25 +08:00
f7e644de62 opt some 2022-08-21 19:05:00 +08:00
458f32bb4e opt some 2022-08-21 18:29:47 +08:00
b99f9a2e6d opt some 2022-08-21 18:22:12 +08:00
f310949291 opt some 2022-08-21 15:56:52 +08:00
ea221a7a22 opt some 2022-08-19 19:20:18 +08:00
2fb89fdd00 opt some 2022-08-19 11:12:36 +08:00
76e547c3df opt some 2022-08-17 21:02:05 +08:00
0107ac4988 opt some 2022-08-17 20:34:07 +08:00
8579c97e4e opt some 2022-08-17 20:23:59 +08:00
harveyshao
d058972636 opt some 2022-08-16 19:40:24 +08:00
harveyshao
c2d6e194fe opt ssh 2022-08-16 14:38:40 +08:00
a574a2c2ca opt misc 2022-08-16 10:41:37 +08:00
72cfae0429 opt some 2022-08-15 12:26:47 +08:00
shy
c8ec447c28 opt some 2022-08-14 22:37:49 +08:00
shy
518605c440 opt some 2022-08-11 15:33:20 +08:00
shy
30a36ffe36 opt some 2022-08-09 16:50:52 +08:00
harveyshao
8d41628462 opt some 2022-08-09 16:21:56 +08:00
harveyshao
15179c7909 opt some 2022-08-09 14:34:41 +08:00
shy
7a10841374 opt some 2022-08-09 11:36:55 +08:00
harveyshao
0687a4b882 opt some 2022-08-09 08:24:17 +08:00
shy
66769889af opt some 2022-08-07 11:09:56 +08:00
harveyshao
674c4f5146 opt some 2022-08-06 02:09:05 +08:00
shy
39e104aa7c opt some 2022-08-05 19:01:44 +08:00
harveyshao
ffb8e4c212 opt chat 2022-08-05 17:29:32 +08:00
harveyshao
07567fc4c5 opt some 2022-07-25 22:00:06 +08:00
harveyshao
d2374610fd opt some 2022-07-25 20:20:26 +08:00
harveyshao
8875b9efa9 opt some 2022-07-25 18:12:42 +08:00
harveyshao
13891cf56f opt some 2022-07-25 15:17:30 +08:00
harveyshao
d03f678b65 opt some 2022-07-24 19:58:24 +08:00
shy
6d750ca2e1 opt some 2022-07-24 08:05:16 +08:00
harveyshao
16182fae9a opt xterm 2022-07-23 05:23:45 +08:00
harveyshao
2377a81621 opt some 2022-07-18 15:05:09 +08:00
shy
5777d6b926 opt some 2022-07-17 22:31:54 +08:00
shy
c438706c0c opt some 2022-07-17 17:47:36 +08:00
harveyshao
a56dd470e1 opt vimer.js 2022-07-14 18:39:04 +08:00
harveyshao
1ab770be44 opt vimer.js 2022-07-13 17:48:06 +08:00
harveyshao
239cab91ef opt some 2022-07-13 08:20:26 +08:00
harveyshao
22826f8d1e opt some 2022-07-11 08:41:12 +08:00
harveyshao
1596f99f56 opt inner.js 2022-07-10 22:34:28 +08:00
shy
d8c6c25b6b opt some 2022-07-01 21:32:29 +08:00
shy
a660dc95bc opt some 2022-07-01 14:52:01 +08:00
shy
03a94cd880 opt mips 2022-06-25 17:37:49 +08:00
harveyshao
96537f11c5 opt some 2022-06-19 20:02:38 +08:00
harveyshao
b7d3bf88e7 opt some 2022-06-19 16:00:51 +08:00
harveyshao
e55c710ee7 opt some 2022-06-14 17:17:28 +08:00
harveyshao
d8dc0a69b5 opt some 2022-06-12 23:06:01 +08:00
harveyshao
5c583defc9 opt some 2022-06-12 11:38:49 +08:00
harveyshao
e46f816ccf opt some 2022-06-05 17:30:18 +08:00
shy
1ad090703a opt some 2022-06-05 17:18:46 +08:00
harveyshao
0215458cd3 opt some 2022-06-04 16:21:59 +08:00
harveyshao
4c4cf813c1 opt some 2022-06-04 10:45:56 +08:00
harveyshao
6fe8e40865 opt some 2022-05-26 14:29:11 +08:00
harveyshao
a6704159a4 opt some 2022-05-17 10:57:34 +08:00
harveyshao
88bf8abd6e opt some 2022-05-16 12:07:17 +08:00
harveyshao
13b65201b4 opt index 2022-05-16 11:27:11 +08:00
harveyshao
93d0f88987 opt vimer 2022-05-15 23:29:44 +08:00
harveyshao
1f435e66f0 opt some 2022-05-14 15:26:16 +08:00
harveyshao
de3d585165 opt some 2022-05-09 21:35:32 +08:00
harveyshao
bb65cf5fa8 opt zml 2022-05-09 10:27:26 +08:00
harveyshao
a4a269f140 opt some 2022-05-08 18:29:33 +08:00
harveyshao
f428f2388e opt some 2022-05-07 17:40:36 +08:00
shaoying
67ac335d7c opt some 2022-05-05 20:08:33 +08:00
shy
5f33ecaa33 opt some 2022-05-05 10:49:37 +08:00
harveyshao
ee524fb350 add parse 2022-05-04 23:24:46 +08:00
harveyshao
3f348b90c2 opt some 2022-04-30 02:06:12 +08:00
harveyshao
c36c6f8950 opt some 2022-04-23 11:49:12 +08:00
shy
9dd6a2736b opt some 2022-04-18 22:24:21 +08:00
harveyshao
af38ab2797 opt some 2022-04-10 23:05:12 +08:00
harveyshao
138d69314a opt some 2022-04-10 13:14:55 +08:00
harveyshao
cbb61087fb opt some 2022-04-10 11:43:11 +08:00
harveyshao
a9c8fbc39e opt some 2022-04-09 23:28:21 +08:00
harveyshao
027e6d3f95 opt webview 2022-04-09 17:58:13 +08:00
shy
2227a60b77 opt nginx 2022-04-09 10:27:50 +08:00
harveyshao
1f016f1b3e opt some 2022-04-09 07:36:50 +08:00
shy
db80878e86 opt some 2022-04-06 12:27:07 +08:00
harveyshao
85ccc515a5 opt some 2022-04-01 10:17:33 +08:00
harveyshao
117f360f55 opt some 2022-04-01 09:48:17 +08:00
shy
55e02fbcf9 opt css 2022-03-26 23:14:11 +08:00
harveyshao
36bd013daa opt css 2022-03-21 12:37:50 +08:00
harveyshao
a21f42d7c5 opt some 2022-03-20 12:21:59 +08:00
shy
6b38afaa80 opt some 2022-03-17 21:11:06 +08:00
harveyshao
b9b3b5a7be opt some 2022-03-16 14:28:24 +08:00
harveyshao
9dd7fdb1bc opt some 2022-03-16 14:02:24 +08:00
shy
52ec9ec6dd opt some 2022-03-15 20:49:53 +08:00
shy
26ec4cb073 opt some 2022-03-15 11:45:43 +08:00
harveyshao
c24ff7dcfe opt some 2022-03-15 03:32:16 +08:00
harveyshao
5bb310c205 opt some 2022-03-15 02:41:49 +08:00
harveyshao
3d85d57fe3 add iml 2022-03-15 02:32:29 +08:00
harveyshao
b8cd7960cd opt some 2022-03-12 19:24:19 +08:00
harveyshao
afc1d821e8 opt some 2022-03-10 10:31:46 +08:00
harveyshao
4489edf0c1 opt some 2022-03-03 14:43:17 +08:00
harveyshao
4be6f7acae opt website 2022-03-03 10:43:43 +08:00
shy
f5f192a243 opt some 2022-03-01 17:25:19 +08:00
harveyshao
34e39099b9 opt some 2022-03-01 17:12:48 +08:00
harveyshao
f22656116f opt some 2022-02-25 19:56:44 +08:00
shy
dada079f2a opt some 2022-02-25 19:46:18 +08:00
harveyshao
3acbb5acac opt lang 2022-02-24 17:35:01 +08:00
harveyshao
0eb31e877c opt login 2022-02-23 12:33:32 +08:00
harveyshao
e87b76cc81 opt login 2022-02-23 12:30:02 +08:00
shy
f6625dd2bc opt login 2022-02-23 12:16:24 +08:00
harveyshao
92d66337ff opt some 2022-02-22 13:38:22 +08:00
harveyshao
eb4a112985 opt code 2022-02-20 23:04:03 +08:00
harveyshao
b9759648cc opt some 2022-02-20 23:03:14 +08:00
harveyshao
256c60b57c opt code 2022-02-19 19:52:31 +08:00
harveyshao
1a577a7826 opt webpack 2022-02-18 11:20:37 +08:00
harveyshao
e7d108d8ba opt some 2022-02-14 16:07:14 +08:00
shy
224261cd39 opt some 2022-02-14 12:21:41 +08:00
harveyshao
d80258c828 opt some 2022-02-14 01:52:18 +08:00
harveyshao
edde076709 opt some 2022-02-14 01:50:25 +08:00
harveyshao
5f2b2b20c1 opt some 2022-02-13 18:14:19 +08:00
harveyshao
311f9a676b opt some 2022-02-13 18:13:51 +08:00
harveyshao
dfed648d2c add forever 2022-02-12 15:43:48 +08:00
harveyshao
dee01a9098 opt some 2022-02-09 17:27:44 +08:00
shy
48ca29930e opt some 2022-01-26 02:51:30 +08:00
harveyshao
c357f2a85e opt some 2022-01-26 01:40:44 +08:00
harveyshao
779ea0d28c opt some 2022-01-24 17:29:56 +08:00
harveyshao
9fff05eae2 opt honor 2022-01-24 10:37:00 +08:00
harveyshao
99741e44d4 opt some 2022-01-23 16:53:31 +08:00
harveyshao
4bd4084fd7 opt some 2022-01-23 16:53:20 +08:00
harveyshao
6ef832a4fc opt some 2022-01-23 14:17:19 +08:00
34c390f575 opt some 2022-01-13 00:25:54 +08:00
378 changed files with 2017 additions and 21373 deletions

8
.gitignore vendored
View File

@ -1,12 +1,12 @@
src/binpack_usr.go
src/binpack.go
src/version.go
etc/local.shy
etc/local.sh
etc/path
*.swp
*.swo
bin/
var/
usr/
usr/local/export/
go.work.sum
go.work
.*

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2021 码神
Copyright (c) 2017-2025 shylinux
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -1,22 +1,12 @@
export GOPROXY=https://goproxy.cn,direct
export GOPRIVATE=shylinux.com,github.com
export CGO_ENABLED=0
binarys = bin/ice.bin
option = src/option.go
version = src/version.go
flags = -ldflags "-w -s" -v
all:
@echo && date
[ -f src/version.go ] || echo "package main" > src/version.go
go build -v -o bin/ice.bin src/main.go src/version.go && chmod u+x bin/ice.bin && ./bin/ice.sh restart
ice:
cat src/binpack.go|sed 's/package main/package ice/g' > usr/release/binpack.go
app:
CGO_ENABLED=1 go build -o usr/publish/contexts.app/Contents/MacOS/contexts src/app.go src/binpack.go && open usr/publish/contexts.app
hdiutil create usr/publish/tmp.dmg -ov -volname "ContextsInstall" -fs HFS+ -srcfolder "usr/publish/contexts.app"
rm -f usr/publish/ContextsInstall.dmg
hdiutil convert usr/publish/tmp.dmg -format UDZO -o usr/publish/ContextsInstall.dmg
%: src/%.go
@echo && date
go build -v -o usr/publish/$@ src/$@.go && chmod u+x usr/publish/$@
all: def
@date +"%Y-%m-%d %H:%M:%S"
go build ${flags} -o ${binarys} src/main.go ${option} ${version} && ./${binarys} forever restart &>/dev/null
def:
@[ -f ${option} ] || echo "package main">${option}
@[ -f ${version} ] || echo "package main">${version}

View File

@ -1,18 +1,17 @@
# contexts
# ContextOS
ContextOS 通过集群化、模块化、自动化的方式,只用一个 20M 大小的程序文件,就可以在各种设备上,一键启动完整的云计算服务与云研发环境。
contexts通过集群化、模块化、自动化的方式可以在各种设备上一键搭起云计算服务。
## install
### install by binary
## 安装系统
### 下载编译
```sh
export ctx_temp=$(mktemp); curl -fsSL https://shylinux.com -o $ctx_temp; source $ctx_temp binary
git clone https://shylinux.com/x/ContextOS
cd ContextOS; source etc/miss.sh
```
### install by source
### 启动服务
```sh
export ctx_temp=$(mktemp); curl -fsSL https://shylinux.com -o $ctx_temp; source $ctx_temp source
ish_miss_serve
```
## page
then open http://localhost:9020
### 管理后台
打开管理后台 [http://localhost:9020](http://localhost:9020)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +0,0 @@
package cli
var version = struct {
init []string
time string
host string
self int
}{
[]string{"2017-11-01 01:02:03", "2019-07-13 18:02:21"},
`2019-11-29 12:39:40`, `mac`, 658,
}

View File

@ -1,240 +0,0 @@
package ctx
import (
"text/template"
"bytes"
"io"
"path"
"strings"
"toolkit"
)
func index(name string, arg ...interface{}) interface{} {
if len(arg) == 0 {
return ""
}
switch m := arg[0].(type) {
case *Message:
if len(arg) == 1 {
return m.Meta[name]
}
switch value := arg[1].(type) {
case int:
if 0 <= value && value < len(m.Meta[name]) {
return m.Meta[name][value]
}
case string:
if len(arg) == 2 {
if name == "option" {
return m.Optionv(value)
} else {
return m.Append(value)
}
}
switch val := arg[2].(type) {
case int:
switch list := m.Optionv(value).(type) {
case []string:
if 0 <= val && val < len(list) {
return list[val]
}
case []interface{}:
if 0 <= val && val < len(list) {
return list[val]
}
}
}
}
case map[string][]string:
if len(arg) == 1 {
return m[name]
}
switch value := arg[1].(type) {
case int:
return m[name][value]
case string:
if len(arg) == 2 {
return m[value]
}
switch val := arg[2].(type) {
case int:
return m[value][val]
}
}
case []string:
if len(arg) == 1 {
return m
}
switch value := arg[1].(type) {
case int:
return m[value]
}
default:
return m
}
return ""
}
var CGI = template.FuncMap{
"options": func(arg ...interface{}) string {
switch value := index("option", arg...).(type) {
case string:
return value
case []string:
return strings.Join(value, "")
}
return ""
},
"option": func(arg ...interface{}) interface{} {
return index("option", arg...)
},
"conf": func(arg ...interface{}) interface{} {
switch m := arg[0].(type) {
case *Message:
switch c := arg[1].(type) {
case string:
if len(arg) == 2 {
return m.Confv(c)
}
if len(arg) == 3 {
return m.Confv(c, arg[2])
}
}
}
return nil
},
"cmd": func(arg ...interface{}) interface{} {
switch m := arg[0].(type) {
case *Message:
switch c := arg[1].(type) {
case string:
return m.Cmd(c, arg[2:])
}
}
return nil
},
"appends": func(arg ...interface{}) interface{} {
switch value := index("append", arg...).(type) {
case string:
return value
case []string:
return strings.Join(value, "")
}
return ""
},
"append": func(arg ...interface{}) interface{} {
switch m := arg[0].(type) {
case *Message:
if len(arg) == 1 {
return m.Meta["append"]
}
if len(arg) > 1 {
switch c := arg[1].(type) {
case string:
if len(arg) > 2 {
switch i := arg[2].(type) {
case int:
return kit.Select("", m.Meta[c], i)
}
}
return m.Meta[c]
}
}
}
return nil
},
"trans": func(arg ...interface{}) interface{} {
switch m := arg[0].(type) {
case *Message:
list := [][]string{m.Meta["append"]}
m.Table(func(index int, value map[string]string) {
line := []string{}
for _, k := range m.Meta["append"] {
line = append(line, value[k])
}
list = append(list, line)
})
return list
}
return nil
},
"result": func(arg ...interface{}) interface{} {
switch m := arg[0].(type) {
case *Message:
return m.Meta["result"]
}
return nil
},
"results": func(arg ...interface{}) interface{} {
switch m := arg[0].(type) {
case *Message:
return strings.Join(m.Meta["result"], "")
}
return nil
},
}
func LocalCGI(m *Message, c *Context) *template.FuncMap {
cgi := template.FuncMap{
"format": func(arg ...interface{}) interface{} {
switch msg := arg[0].(type) {
case *Message:
buffer := bytes.NewBuffer([]byte{})
tmpl := m.Optionv("tmpl").(*template.Template)
m.Assert(tmpl.ExecuteTemplate(buffer, kit.Select("table", arg, 1), msg))
return string(buffer.Bytes())
}
return nil
},
}
for k, v := range c.Commands {
if strings.HasPrefix(k, "/") || strings.HasPrefix(k, "_") {
continue
}
func(k string, v *Command) {
cgi[k] = func(arg ...interface{}) (res interface{}) {
m.TryCatch(m.Spawn(), true, func(msg *Message) {
v.Hand(msg, c, k, msg.Form(v, kit.Trans(arg))...)
buffer := bytes.NewBuffer([]byte{})
m.Assert(m.Optionv("tmpl").(*template.Template).ExecuteTemplate(buffer,
kit.Select(kit.Select("code", "table", len(msg.Meta["append"]) > 0), msg.Option("render")), msg))
res = string(buffer.Bytes())
})
return
}
}(k, v)
}
for k, v := range CGI {
cgi[k] = v
}
return &cgi
}
func ExecuteFile(m *Message, w io.Writer, p string) error {
tmpl := template.New("render").Funcs(CGI)
tmpl.ParseGlob(p)
return tmpl.ExecuteTemplate(w, path.Base(p), m)
}
func ExecuteStr(m *Message, w io.Writer, p string) error {
tmpl := template.New("render").Funcs(CGI)
tmpl, _ = tmpl.Parse(p)
return tmpl.Execute(w, m)
}
func Execute(m *Message, p string) string {
m.Log("fuck", "waht %v", path.Join(m.Conf("route", "template_dir"), "/*.tmpl"))
t := template.Must(template.New("render").Funcs(CGI).ParseGlob(path.Join(m.Conf("route", "template_dir"), "/*.tmpl")))
for _, v := range t.Templates() {
m.Log("fuck", "waht %v", v.Name())
}
buf := bytes.NewBuffer(make([]byte, 0, 1024))
t.ExecuteTemplate(buf, p, m)
m.Log("fuck", "waht %v", p)
m.Log("fuck", "waht %v", buf)
return buf.String()
}

View File

@ -1,574 +0,0 @@
package ctx
import (
"errors"
"fmt"
"io"
"strings"
"time"
"toolkit"
)
func (c *Context) Register(s *Context, x Server, args ...interface{}) *Context {
name, force := s.Name, false
if len(args) > 0 {
switch arg := args[0].(type) {
case bool:
force = arg
case string:
force = true
name, s.Name = arg, arg
}
}
if c.contexts == nil {
c.contexts = make(map[string]*Context)
}
if x, ok := c.contexts[name]; ok && !force {
panic(errors.New(c.Name + "上下文中已存在模块:" + x.Name))
}
c.contexts[name] = s
s.context = c
s.Server = x
s.root = c.root
return s
}
func (c *Context) Plugin(s *Context, args []string) string {
c.Register(s, nil)
m := Pulse.Spawn(s)
// m := &Message{code: 0, time: time.Now(), source: s, target: s, Meta: map[string][]string{}}
// kit.DisableLog = true
m.Option("log.disable", false)
m.Option("bio.modal", "action")
if len(args) == 0 {
m.Echo("%s: %s\n\n", s.Name, s.Help)
m.Echo("命令列表:\n")
for k, v := range s.Commands {
if !strings.HasPrefix(k, "_") {
m.Echo("--%s: %s\n %v\n\n", k, v.Name, v.Help)
}
}
m.Echo("配置列表:\n")
for k, v := range s.Configs {
if !strings.HasPrefix(k, "_") {
m.Echo("--%s(%v): %s\n", k, kit.Formats(v.Value), v.Help)
}
}
} else {
if Index.Begin(Pulse, args...); Index.Start(Pulse, args...) {
}
m.Cmd(args)
}
for _, v := range m.Meta["result"] {
fmt.Printf(v)
}
return ""
}
func (c *Context) Spawn(m *Message, name string, help string) *Context {
s := &Context{Name: name, Help: help, root: c.root, context: c, message: m,
Caches: map[string]*Cache{},
Configs: map[string]*Config{},
Commands: map[string]*Command{},
}
if m.target = s; c.Server != nil {
c.Register(s, c.Server.Spawn(m, s, m.Meta["detail"]...))
} else {
c.Register(s, nil)
}
return s
}
func (c *Context) Begin(m *Message, arg ...string) *Context {
if len(arg) > 0 {
m.Set("detail", arg)
}
module := c.Name
if c.context != nil && c.context.Caches != nil && c.context.Caches["module"] != nil {
module = c.context.Caches["module"].Value + "." + c.Name
}
c.Caches["module"] = &Cache{Name: "module", Value: module, Help: "模块域名"}
c.Caches["status"] = &Cache{Name: "status(begin/start/close)", Value: "begin", Help: "模块状态, begin: 初始完成, start: 正在运行, close: 运行结束"}
c.Caches["stream"] = &Cache{Name: "stream", Value: "", Help: "模块数据"}
c.message = m
c.requests = append(c.requests, m)
m.source.sessions = append(m.source.sessions, m)
c.exit = make(chan bool, 3)
if c.Server != nil {
c.Server.Begin(m, m.Meta["detail"]...)
}
m.root.Capi("ncontext", 1)
return c
}
func (c *Context) Start(m *Message, arg ...string) bool {
sync := false
if len(arg) > 0 && arg[0] == "sync" {
sync, arg = true, arg[1:]
}
if len(arg) > 0 {
m.Set("detail", arg)
}
c.requests = append(c.requests, m)
m.source.sessions = append(m.source.sessions, m)
if m.Hand = true; m.Cap("status") == "start" {
return true
}
m.Gos(m, func(m *Message) {
m.Log(m.Cap("status", "start"), "%d server %v %v", m.Capi("nserver", 1), m.Meta["detail"], m.Meta["option"])
c.message = m
if c.exit <- false; c.Server == nil || c.Server.Start(m, m.Meta["detail"]...) {
c.Close(m, m.Meta["detail"]...)
c.exit <- true
}
}, func(m *Message) {
c.Close(m, m.Meta["detail"]...)
c.exit <- true
})
if sync {
for !<-c.exit {
}
return true
}
return <-c.exit
}
func (c *Context) Close(m *Message, arg ...string) bool {
if len(c.requests) == 0 {
return true
}
if m.target == c {
for i := len(c.requests) - 1; i >= 0; i-- {
if msg := c.requests[i]; msg.code == m.code {
if c.Server == nil || c.Server.Close(m, arg...) {
msg.Free()
for j := i; j < len(c.requests)-1; j++ {
c.requests[j] = c.requests[j+1]
}
c.requests = c.requests[:len(c.requests)-1]
}
}
}
}
if len(c.requests) > 0 {
return false
}
if m.Cap("status") == "start" {
m.Log(m.Cap("status", "close"), "%d server %v", m.root.Capi("nserver", -1), arg)
for _, msg := range c.sessions {
if msg.Cap("status") != "close" {
msg.target.Close(msg, arg...)
}
}
}
if c.context != nil {
m.Log("close", "%d context %v", m.root.Capi("ncontext", -1), arg)
delete(c.context.contexts, c.Name)
c.exit <- true
}
return true
}
func (m *Message) TryCatch(msg *Message, safe bool, hand ...func(msg *Message)) *Message {
defer func() {
switch e := recover(); e {
case io.EOF:
case nil:
default:
m.Log("bench", "chain: %s", msg.Format("chain"))
m.Log("bench", "catch: %s", e)
m.Log("bench", "stack: %s", msg.Format("stack"))
if m.Log("error", "catch: %s", e); len(hand) > 1 {
m.TryCatch(msg, safe, hand[1:]...)
} else if !safe {
m.Assert(e)
}
}
}()
if len(hand) > 0 {
hand[0](msg)
}
return m
}
func (m *Message) Assert(e interface{}, msg ...string) bool {
switch v := e.(type) {
case nil:
return true
case *Message:
if v.Result(0) != "error: " {
return true
}
e = errors.New(strings.Join(v.Meta["result"], ""))
default:
if kit.Right(v) {
return true
}
}
switch e.(type) {
case error:
default:
e = errors.New(kit.Format(msg))
}
kit.Log("error", "%v", e)
panic(e)
}
func (m *Message) GoLoop(msg *Message, hand ...func(msg *Message)) *Message {
m.Gos(msg, func(msg *Message) {
for {
hand[0](msg)
}
})
return m
}
func (m *Message) Gos(msg *Message, hand ...func(msg *Message)) *Message {
go func() {
msg.Option("ctx.routine", m.Capi("ngo", 1))
m.TryCatch(msg, true, hand...)
}()
return m
}
func (m *Message) Spawn(arg ...interface{}) *Message {
temp := false
c := m.target
for i := 0; i < len(arg); i++ {
switch v := arg[i].(type) {
case *Context:
c = v
case *Message:
c = v.target
case string:
temp = kit.Right(v)
case bool:
temp = v
}
}
msg := &Message{
time: time.Now(),
code: -1,
source: m.target,
target: c,
message: m,
root: m.root,
}
if temp {
return msg
}
msg.code = m.Capi("nmessage", 1)
m.messages = append(m.messages, msg)
return msg
}
func (m *Message) Sess(key string, arg ...interface{}) *Message {
if key == "" {
return m.Spawn()
}
spawn := true
if len(arg) > 0 {
switch v := arg[0].(type) {
case bool:
spawn, arg = v, arg[1:]
}
}
if len(arg) > 0 {
if m.Sessions == nil {
m.Sessions = make(map[string]*Message)
}
switch value := arg[0].(type) {
case *Message:
m.Sessions[key] = value
return m.Sessions[key]
case *Context:
m.Sessions[key] = m.Spawn(value)
return m.Sessions[key]
case string:
root := len(arg) < 3 || kit.Right(arg[2])
method := "find"
if len(arg) > 1 {
method = kit.Format(arg[1])
}
switch method {
case "find":
m.Sessions[key] = m.Find(value, root)
case "search":
m.Sessions[key] = m.Search(value, root)[0]
}
return m.Sessions[key]
case nil:
delete(m.Sessions, key)
return nil
}
}
temp := false
if len(arg) > 0 {
switch v := arg[0].(type) {
case bool:
temp, arg = v, arg[1:]
}
}
for msg := m; msg != nil; msg = msg.message {
if x, ok := msg.Sessions[key]; ok {
if spawn {
x = m.Spawn(x.target, temp)
x.callback = func(sub *Message) *Message { return sub }
}
return x
}
}
return nil
}
func (m *Message) Form(x *Command, arg []string) []string {
form, ok := m.Optionv("ctx.form").(map[string]int)
if !ok {
return arg
}
for _, form := range []map[string]int{form, x.Form} {
if args := []string{}; form != nil {
for i := 0; i < len(arg); i++ {
if n, ok := form[arg[i]]; ok {
if n < 0 {
n += len(arg) - i
}
for j := i + 1; j <= i+n && j < len(arg); j++ {
if _, ok := form[arg[j]]; ok {
n = j - i - 1
}
}
if i+1+n > len(arg) {
m.Add("option", arg[i], arg[i+1:])
} else {
m.Add("option", arg[i], arg[i+1:i+1+n])
}
i += n
} else {
args = append(args, arg[i])
}
}
arg = args
}
}
return arg
}
func (m *Message) Call(cb func(msg *Message) (sub *Message), arg ...interface{}) *Message {
if m == nil {
return m
}
if m.callback = cb; len(arg) > 0 && kit.Format(arg[0]) == "skip" {
return m
}
if len(arg) > 0 || len(m.Meta["detail"]) > 0 {
m.Log("call", m.Format("detail", "option"))
m.Cmd(arg...)
}
return m
}
func (m *Message) Back(ms ...*Message) *Message {
if m.callback == nil {
return m
}
if len(ms) == 0 {
ms = append(ms, m.Spawn(m.source).Copy(m, "append").Copy(m, "result"))
}
ns := []*Message{}
for _, msg := range ms {
if msg.Hand {
m.Log("back", msg.Format("ship", "result", "append"))
} else {
m.Log("back", msg.Format("ship", "detail", "option"))
}
if sub := m.callback(msg); sub != nil && m.message != nil && m.message != m {
ns = append(ns, sub)
}
}
if len(ns) > 0 {
m.message.Back(ns...)
}
return m
}
func (m *Message) CallBack(sync bool, cb func(msg *Message) (sub *Message), arg ...interface{}) *Message {
if !sync {
return m.Call(cb, arg...)
}
wait := make(chan *Message, 10)
m.Call(func(sub *Message) *Message {
msg := cb(sub)
wait <- m
return msg
}, arg...)
select {
case <-time.After(kit.Duration(m.Confx("call_timeout"))):
m.Log("sync", m.Format("timeout", "detail", "option"))
m.Echo("time out %v", m.Confx("call_timeout"))
case <-wait:
}
return m
}
func (m *Message) Free(cbs ...func(msg *Message) (done bool)) *Message {
if len(cbs) == 0 {
for i := len(m.freeback) - 1; i >= 0; i-- {
m.Log("free", "%d/%d", i, len(m.freeback)-1)
if !m.freeback[i](m) {
break
}
m.freeback = m.freeback[:i]
}
return m
}
m.freeback = append(m.freeback, cbs...)
return m
}
func (m *Message) Match(key string, spawn bool, hand func(m *Message, s *Context, c *Context, key string) bool) *Message {
if m == nil {
return m
}
context := []*Context{m.target}
for _, v := range kit.Trans(m.Optionv("ctx.chain")) {
if msg := m.Sess(v, false); msg != nil && msg.target != nil {
if msg.target != m.target && msg.target != m.source {
context = append(context, msg.target)
}
}
}
context = append(context, m.source)
for _, s := range context {
for c := s; c != nil; c = c.context {
if hand(m, s, c, key) {
return m
}
}
}
return m
}
func (m *Message) Magic(begin string, chain interface{}, args ...interface{}) interface{} {
auth := []string{"bench", "session", "user", "role", "componet", "command"}
key := []string{"bench", "sessid", "username", "role", "componet", "command"}
aaa := m.Sess("aaa", false)
for i, v := range auth {
if v == begin {
h := m.Option(key[i])
if v == "user" {
h, _ = kit.Hash("username", m.Option("username"))
}
data := aaa.Confv("auth", []string{h, "data"})
if kit.Format(chain) == "" {
return data
}
if len(args) > 0 {
value := kit.Chain(data, chain, args[0])
aaa.Conf("auth", []string{m.Option(key[i]), "data"}, value)
return value
}
value := kit.Chain(data, chain)
if value != nil {
return value
}
if i < len(auth)-1 {
begin = auth[i+1]
}
}
}
return nil
}
func (m *Message) Parse(arg interface{}) string {
switch str := arg.(type) {
case string:
if len(str) > 1 && str[0] == '$' {
return m.Cap(str[1:])
}
if len(str) > 1 && str[0] == '@' {
if v := m.Option(str[1:]); v != "" {
return v
}
if v := kit.Format(m.Magic("bench", str[1:])); v != "" {
return v
}
v := m.Conf(str[1:])
return v
}
return str
}
return ""
}
func (m *Message) Goshy(input []string, index int, stack *kit.Stack, cb func(*Message)) bool {
m.Optionv("bio.msg", m)
if stack == nil {
stack = &kit.Stack{}
stack.Push("source", true, 0)
}
m.Optionv("bio.stack", stack)
m.Optionv("bio.input", input)
for i := index; i < len(input); i++ {
line := input[i]
m.Optioni("stack.pos", i)
// 执行语句
msg := m.Sess("yac").Cmd("parse", line+"\n")
if cb != nil {
cb(msg)
}
// 切换模块
if v := msg.Optionv("bio.ctx"); v != nil {
m.Optionv("bio.ctx", v)
}
// 跳转语句
if msg.Appends("bio.pos0") {
i = int(msg.Appendi("bio.pos0")) - 1
msg.Append("bio.pos0", "")
}
// 结束脚本
if msg.Appends("bio.end") {
m.Copy(msg, "append").Copy(msg, "result")
msg.Appends("bio.end", "")
return true
}
}
return false
}

File diff suppressed because it is too large Load Diff

View File

@ -1,686 +0,0 @@
package ctx
import (
"encoding/csv"
"fmt"
"os"
"regexp"
"runtime"
"sort"
"strings"
"time"
"toolkit"
)
func (m *Message) Log(action string, str string, arg ...interface{}) *Message {
if action == "error" {
kit.Log("error", fmt.Sprintf("chain: %s", m.Format("chain")))
kit.Log("error", fmt.Sprintf("%s %s %s", m.Format(), action, fmt.Sprintf(str, arg...)))
kit.Log("error", fmt.Sprintf("stack: %s", m.Format("stack")))
}
// if m.Options("log.disable") {
// return m
// }
if l := m.Sess("log", false); l != nil {
if log, ok := l.target.Server.(LOGGER); ok {
if action == "error" {
log.Log(m, "error", "chain: %s", m.Format("chain"))
}
if log.Log(m, action, str, arg...); action == "error" {
log.Log(m, "error", "stack: %s", m.Format("stack"))
}
return m
}
} else {
fmt.Fprintf(os.Stderr, str, arg...)
}
return m
}
func (m *Message) Gdb(arg ...interface{}) interface{} {
// if !m.Options("log.enable") {
// return ""
// }
if g := m.Sess("gdb", false); g != nil {
if gdb, ok := g.target.Server.(DEBUG); ok {
return gdb.Wait(m, arg...)
}
}
return ""
}
func (m *Message) Show(str string, args ...interface{}) *Message {
res := fmt.Sprintf(str, args...)
if m.Option("bio.modal") == "action" {
fmt.Fprintf(os.Stderr, res)
} else if kit.STDIO != nil {
kit.STDIO.Show(res)
} else {
m.Log("info", "show: %v", res)
}
return m
}
func (m *Message) Format(arg ...interface{}) string {
if len(arg) == 0 {
arg = append(arg, "time", "ship")
}
meta := []string{}
for _, v := range arg {
switch kit.Format(v) {
case "cost":
meta = append(meta, kit.FmtTime(time.Now().Sub(m.time).Nanoseconds()))
case "summary":
msg := arg[1].(*Message)
ms := make([]*Message, 0, 1024)
ms = append(ms, msg.message, msg)
for i := 0; i < len(ms); i++ {
msg := ms[i]
if m.Add("append", "index", i); msg == nil {
m.Add("append", "message", "")
m.Add("append", "time", "")
m.Add("append", "code", "")
m.Add("append", "source", "")
m.Add("append", "target", "")
m.Add("append", "details", "")
m.Add("append", "options", "")
continue
}
if msg.message != nil {
m.Add("append", "message", msg.message.code)
} else {
m.Add("append", "message", "")
}
m.Add("append", "time", msg.time.Format("15:04:05"))
m.Add("append", "code", msg.code)
m.Add("append", "source", msg.source.Name)
m.Add("append", "target", msg.target.Name)
m.Add("append", "details", fmt.Sprintf("%v", msg.Meta["detail"]))
m.Add("append", "options", fmt.Sprintf("%v", msg.Meta["option"]))
if i == 0 {
continue
}
if len(ms) < 30 && len(arg) > 2 && arg[2] == "deep" {
ms = append(ms, ms[i].messages...)
}
}
m.Table()
case "time":
meta = append(meta, m.Time())
case "mill":
meta = append(meta, fmt.Sprintf("%d", int64(m.time.UnixNano())/1000%1000000))
case "code":
meta = append(meta, kit.Format(m.code))
case "ship":
meta = append(meta, fmt.Sprintf("%s:%d(%s->%s)", m.Option("ctx.routine"), m.code, m.source.Name, m.target.Name))
case "source":
target := m.target
m.target = m.source
meta = append(meta, m.Cap("module"))
m.target = target
case "target":
meta = append(meta, m.Cap("module"))
case "detail":
meta = append(meta, fmt.Sprintf("%v", m.Meta["detail"]))
case "option":
meta = append(meta, fmt.Sprintf("%v", m.Meta["option"]))
case "append":
meta = append(meta, fmt.Sprintf("%v", m.Meta["append"]))
case "result":
meta = append(meta, fmt.Sprintf("%v", m.Meta["result"]))
case "full":
case "chain":
ms := []*Message{}
if v == "full" {
ms = append(ms, m)
} else {
for msg := m; msg != nil; msg = msg.message {
ms = append(ms, msg)
}
}
meta = append(meta, "\n")
for i := len(ms) - 1; i >= 0; i-- {
msg := ms[i]
meta = append(meta, fmt.Sprintf("%s", msg.Format("time", "ship")))
if len(msg.Meta["detail"]) > 0 {
meta = append(meta, fmt.Sprintf("detail:%d %v", len(msg.Meta["detail"]), msg.Meta["detail"]))
}
if len(msg.Meta["option"]) > 0 {
meta = append(meta, fmt.Sprintf("option:%d %v\n", len(msg.Meta["option"]), msg.Meta["option"]))
for _, k := range msg.Meta["option"] {
if v, ok := msg.Meta[k]; ok {
meta = append(meta, fmt.Sprintf(" %s: %d %v\n", k, len(v), v))
}
}
} else {
meta = append(meta, "\n")
}
if len(msg.Meta["append"]) > 0 {
meta = append(meta, fmt.Sprintf(" append:%d %v\n", len(msg.Meta["append"]), msg.Meta["append"]))
for _, k := range msg.Meta["append"] {
if v, ok := msg.Meta[k]; ok {
meta = append(meta, fmt.Sprintf(" %s: %d %v\n", k, len(v), v))
}
}
}
if len(msg.Meta["result"]) > 0 {
meta = append(meta, fmt.Sprintf(" result:%d %v\n", len(msg.Meta["result"]), msg.Meta["result"]))
}
}
case "stack":
pc := make([]uintptr, 100)
pc = pc[:runtime.Callers(5, pc)]
frames := runtime.CallersFrames(pc)
for {
frame, more := frames.Next()
file := strings.Split(frame.File, "/")
name := strings.Split(frame.Function, "/")
meta = append(meta, fmt.Sprintf("\n%s:%d\t%s", file[len(file)-1], frame.Line, name[len(name)-1]))
if !more {
break
}
}
default:
meta = append(meta, kit.Format(v))
}
}
return strings.Join(meta, " ")
}
func (m *Message) Short(arg ...string) {
for _, k := range arg {
if v := m.Option(k); v != "" && len(v) != 32 {
m.Option(k, m.Cmdx("aaa.short", v))
}
}
}
func (m *Message) Err(str string, arg ...interface{}) {
m.Echo("").Echo("error: ").Echo(str, arg...)
}
func (m *Message) Start(name string, help string, arg ...string) bool {
return m.Set("detail", arg).target.Spawn(m, name, help).Begin(m).Start(m)
}
func (m *Message) Wait() bool {
if m.target.exit != nil {
return <-m.target.exit
}
return true
}
func (m *Message) Find(name string, root ...bool) *Message {
if name == "" {
return m.Spawn()
}
target := m.target.root
if len(root) > 0 && !root[0] {
target = m.target
}
cs := target.contexts
for _, v := range strings.Split(name, ".") {
if x, ok := cs[v]; ok {
target, cs = x, x.contexts
} else if target.Name == v {
continue
} else {
return nil
}
}
if len(root) > 1 && root[1] {
m.target = target
return m
}
return m.Spawn(target)
}
func (m *Message) Search(key string, root ...bool) []*Message {
reg, e := regexp.Compile(key)
m.Assert(e)
target := m.target
if target == nil {
return []*Message{nil}
}
if len(root) > 0 && root[0] {
target = m.target.root
}
cs := make([]*Context, 0, 3)
target.Travel(m, func(m *Message, i int) bool {
if reg.MatchString(m.target.Name) || reg.FindString(m.target.Help) != "" {
cs = append(cs, m.target)
}
return false
})
ms := make([]*Message, len(cs))
for i := 0; i < len(cs); i++ {
ms[i] = m.Spawn(cs[i])
}
if len(ms) == 0 {
ms = append(ms, nil)
}
return ms
}
func (c *Context) Travel(m *Message, hand func(m *Message, n int) (stop bool)) *Context {
if c == nil {
return nil
}
target := m.target
cs := []*Context{c}
for i := 0; i < len(cs); i++ {
if m.target = cs[i]; hand(m, i) {
return cs[i]
}
keys := []string{}
for k, _ := range cs[i].contexts {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
cs = append(cs, cs[i].contexts[k])
}
}
m.target = target
return target
}
func (c *Context) BackTrace(m *Message, hand func(m *Message) (stop bool)) *Context {
target := m.target
for s := m.target; s != nil; s = s.context {
if m.target = s; hand(m) {
return s
}
}
m.target = target
return target
}
func (m *Message) Add(meta string, key string, value ...interface{}) *Message {
if m.Meta == nil {
m.Meta = make(map[string][]string)
}
if _, ok := m.Meta[meta]; !ok {
m.Meta[meta] = make([]string, 0, 3)
}
switch meta {
case "detail", "result":
m.Meta[meta] = append(m.Meta[meta], key)
m.Meta[meta] = append(m.Meta[meta], kit.Trans(value...)...)
case "option", "append":
if _, ok := m.Meta[key]; !ok {
m.Meta[key] = make([]string, 0, 3)
}
m.Meta[key] = append(m.Meta[key], kit.Trans(value...)...)
for _, v := range m.Meta[meta] {
if v == key {
return m
}
}
m.Meta[meta] = append(m.Meta[meta], key)
default:
m.Log("error", "add meta error %s %s %v", meta, key, value)
}
return m
}
func (m *Message) Set(meta string, arg ...interface{}) *Message {
switch meta {
case "detail", "result":
if m != nil && m.Meta != nil {
delete(m.Meta, meta)
}
case "option", "append":
if len(arg) > 0 {
for _, k := range arg {
delete(m.Data, kit.Format(k))
delete(m.Meta, kit.Format(k))
}
} else {
for _, k := range m.Meta[meta] {
delete(m.Data, k)
delete(m.Meta, k)
}
delete(m.Meta, meta)
}
default:
m.Log("error", "set meta error %s %s %v", meta, arg)
}
if args := kit.Trans(arg...); len(args) > 0 {
m.Add(meta, args[0], args[1:])
}
return m
}
func (m *Message) Put(meta string, key string, value interface{}) *Message {
switch meta {
case "option", "append":
if m.Set(meta, key); m.Data == nil {
m.Data = make(map[string]interface{})
}
m.Data[key] = value
default:
m.Log("error", "put data error %s %s %v", meta, key, value)
}
return m
}
func (m *Message) Get(key string, arg ...interface{}) string {
if meta, ok := m.Meta[key]; ok && len(meta) > 0 {
index := 0
if len(arg) > 0 {
index = kit.Int(arg[0])
}
index = (index+2)%(len(meta)+2) - 2
if index >= 0 && index < len(meta) {
return meta[index]
}
}
return ""
}
func (m *Message) Has(key ...string) bool {
switch len(key) {
case 1:
if _, ok := m.Data[key[0]]; ok {
return true
}
if _, ok := m.Meta[key[0]]; ok {
return true
}
}
return false
}
func (m *Message) CopyTo(msg *Message, arg ...string) *Message {
msg.Copy(m, "append").Copy(m, "result")
return m
}
func (m *Message) CopyFuck(msg *Message, arg ...string) *Message {
if m == msg {
return m
}
for i := 0; i < len(arg); i++ {
meta := arg[i]
switch meta {
case "target":
m.target = msg.target
case "callback":
m.callback = msg.callback
case "detail", "result":
if len(msg.Meta[meta]) > 0 {
m.Add(meta, msg.Meta[meta][0], msg.Meta[meta][1:])
}
case "option", "append":
if msg.Meta == nil {
msg.Meta = map[string][]string{}
}
if msg.Meta[meta] == nil {
break
}
if i == len(arg)-1 {
arg = append(arg, msg.Meta[meta]...)
}
for i++; i < len(arg); i++ {
if v, ok := msg.Data[arg[i]]; ok {
m.Put(meta, arg[i], v)
} else if v, ok := msg.Meta[arg[i]]; ok {
m.Add(meta, arg[i], v) // TODO fuck Add
}
}
default:
if msg.Hand {
meta = "append"
} else {
meta = "option"
}
if v, ok := msg.Data[arg[i]]; ok {
m.Put(meta, arg[i], v)
}
if v, ok := msg.Meta[arg[i]]; ok {
m.Add(meta, arg[i], v)
}
}
}
return m
}
func (m *Message) ToHTML(style string) string {
cmd := strings.Join(m.Meta["detail"], " ")
result := []string{}
if len(m.Meta["append"]) > 0 {
result = append(result, fmt.Sprintf("<table class='%s'>", style))
result = append(result, "<caption>", cmd, "</caption>")
m.Table(func(line int, maps map[string]string) {
if line == 0 {
result = append(result, "<tr>")
for _, v := range m.Meta["append"] {
result = append(result, "<th>", v, "</th>")
}
result = append(result, "</tr>")
return
}
result = append(result, "<tr>")
for _, k := range m.Meta["append"] {
result = append(result, "<td>", maps[k], "</td>")
}
result = append(result, "</tr>")
})
result = append(result, "</table>")
} else {
result = append(result, "<pre><code>")
result = append(result, fmt.Sprintf("%s", m.Find("shy", false).Conf("prompt")), cmd, "\n")
result = append(result, m.Meta["result"]...)
result = append(result, "</code></pre>")
}
return strings.Join(result, "")
}
func (m *Message) Grow(key string, args interface{}, data interface{}) interface{} {
cache := m.Confm(key, args)
if args == nil {
cache = m.Confm(key)
}
if cache == nil {
cache = map[string]interface{}{}
}
meta, ok := cache["meta"].(map[string]interface{})
if !ok {
meta = map[string]interface{}{}
}
list, _ := cache["list"].([]interface{})
list = append(list, data)
if len(list) > kit.Int(kit.Select(m.Conf("cache", "limit"), meta["limit"])) {
offset := kit.Int(meta["offset"])
least := kit.Int(kit.Select(m.Conf("cache", "least"), meta["least"]))
name := kit.Select(m.Option("cache.store"), meta["store"])
f, e := os.OpenFile(name, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666)
if e != nil {
f, _, e = kit.Create(name)
}
defer f.Close()
s, e := f.Stat()
m.Assert(e)
keys := []string{}
w := csv.NewWriter(f)
if s.Size() == 0 {
for k := range list[0].(map[string]interface{}) {
keys = append(keys, k)
}
sort.Strings(keys)
w.Write(keys)
w.Flush()
s, e = f.Stat()
} else {
r := csv.NewReader(f)
keys, e = r.Read()
}
count := len(list) - least
record, _ := meta["record"].([]interface{})
meta["record"] = append(record, map[string]interface{}{
"time": m.Time(),
"offset": offset,
"position": s.Size(),
"count": count,
"file": name,
})
for i, v := range list {
if i >= count {
break
}
val := v.(map[string]interface{})
values := []string{}
for _, k := range keys {
values = append(values, kit.Format(val[k]))
}
w.Write(values)
if i < least {
list[i] = list[count+i]
}
}
m.Log("info", "save %s offset %v+%v", name, offset, count)
meta["offset"] = offset + count
list = list[:least]
w.Flush()
}
cache["meta"] = meta
cache["list"] = list
if args == nil {
m.Conf(key, cache)
} else {
m.Conf(key, args, cache)
}
return list
}
func (m *Message) Grows(key string, args interface{}, cb interface{}) map[string]interface{} {
cache := m.Confm(key, args)
if args == nil {
cache = m.Confm(key)
}
if cache == nil {
return nil
}
meta, ok := cache["meta"].(map[string]interface{})
if !ok {
return nil
}
list, ok := cache["list"].([]interface{})
if !ok {
return nil
}
offend := kit.Int(kit.Select("0", m.Option("cache.offend")))
limit := kit.Int(kit.Select("10", m.Option("cache.limit")))
match := kit.Select("", m.Option("cache.match"))
value := kit.Select("", m.Option("cache.value"))
current := kit.Int(meta["offset"])
end := current + len(list) - offend
begin := end - limit
data := make([]interface{}, 0, limit)
m.Log("info", "read %v-%v from %v-%v", begin, end, current, current+len(list))
if begin < current {
store, _ := meta["record"].([]interface{})
for s := len(store) - 1; s > -1; s-- {
item, _ := store[s].(map[string]interface{})
line := kit.Int(item["offset"])
m.Log("info", "check history %v %v %v", s, line, item)
if begin < line && s > 0 {
continue
}
for ; s < len(store); s++ {
if begin >= end {
break
}
item, _ := store[s].(map[string]interface{})
if line+kit.Int(item["count"]) < begin {
continue
}
name := kit.Format(item["file"])
pos := kit.Int(item["position"])
line := kit.Int(item["offset"])
m.Log("info", "load history %v %v %v", s, line, item)
if f, e := os.Open(name); m.Assert(e) {
defer f.Close()
r := csv.NewReader(f)
heads, _ := r.Read()
m.Log("info", "load head %v", heads)
f.Seek(int64(pos), os.SEEK_SET)
r = csv.NewReader(f)
for i := line; i < end; i++ {
lines, e := r.Read()
if e != nil {
break
}
if i >= begin {
item := map[string]interface{}{}
for i := range heads {
item[heads[i]] = lines[i]
}
m.Log("info", "load line %v %v %v", i, len(data), item)
if match == "" || strings.Contains(kit.Format(item[match]), value) {
data = append(data, item)
}
begin = i + 1
} else {
m.Log("info", "skip line %v", i)
}
}
}
}
break
}
}
if begin < current {
begin = current
}
m.Log("info", "cache %v-%v", begin-current, end-current)
for i := begin - current; i < end-current; i++ {
if match == "" || strings.Contains(kit.Format(kit.Chain(list[i], match)), value) {
data = append(data, list[i])
}
}
return kit.Map(map[string]interface{}{"meta": meta, "list": data}, "", cb)
}

View File

@ -1,879 +0,0 @@
package ctx
import (
"fmt"
_ "github.com/shylinux/icebergs"
"strconv"
"strings"
"time"
"toolkit"
)
type Cache struct {
Value string
Name string
Help string
Hand func(m *Message, x *Cache, arg ...string) string
}
type Config struct {
Value interface{}
Name string
Help string
Hand func(m *Message, x *Config, arg ...string) string
}
type Command struct {
Form map[string]int
Name string
Help interface{}
Auto func(m *Message, c *Context, key string, arg ...string) (ok bool)
Hand func(m *Message, c *Context, key string, arg ...string) (e error)
}
type Context struct {
Name string
Help string
Caches map[string]*Cache
Configs map[string]*Config
Commands map[string]*Command
message *Message
requests []*Message
sessions []*Message
contexts map[string]*Context
context *Context
root *Context
exit chan bool
Server
}
type Server interface {
Spawn(m *Message, c *Context, arg ...string) Server
Begin(m *Message, arg ...string) Server
Start(m *Message, arg ...string) bool
Close(m *Message, arg ...string) bool
}
func (c *Context) Context() *Context {
return c.context
}
func (c *Context) Message() *Message {
return c.message
}
type Message struct {
time time.Time
code int
source *Context
target *Context
Hand bool
Meta map[string][]string
Data map[string]interface{}
Sync chan bool
callback func(msg *Message) (sub *Message)
freeback []func(msg *Message) (done bool)
Sessions map[string]*Message
messages []*Message
message *Message
root *Message
}
type LOGGER interface {
Log(*Message, string, string, ...interface{})
}
type DEBUG interface {
Wait(*Message, ...interface{}) interface{}
Goon(interface{}, ...interface{})
}
func (m *Message) Time(arg ...interface{}) string {
t := m.time
if len(arg) > 0 {
if d, e := time.ParseDuration(arg[0].(string)); e == nil {
arg, t = arg[1:], t.Add(d)
}
}
str := m.Conf("time", "format")
if len(arg) > 1 {
str = fmt.Sprintf(arg[0].(string), arg[1:]...)
} else if len(arg) > 0 {
str = fmt.Sprintf("%v", arg[0])
}
if str == "stamp" {
return kit.Format(t.Unix())
}
return t.Format(str)
}
func (m *Message) Code() int {
return m.code
}
func (m *Message) Source() *Context {
return m.source
}
func (m *Message) Target() *Context {
return m.target
}
func (m *Message) Insert(meta string, index int, arg ...interface{}) string {
if m == nil {
return ""
}
if m.Meta == nil {
m.Meta = make(map[string][]string)
}
m.Meta[meta] = kit.Array(m.Meta[meta], index, arg)
if -1 < index && index < len(m.Meta[meta]) {
return m.Meta[meta][index]
}
return ""
}
func (m *Message) Detail(arg ...interface{}) string {
noset, index := true, 0
if len(arg) > 0 {
switch v := arg[0].(type) {
case int:
noset, index, arg = false, v, arg[1:]
}
}
if noset && len(arg) > 0 {
index = -2
}
return m.Insert("detail", index, arg...)
}
func (m *Message) Option(key string, arg ...interface{}) string {
if m == nil {
return ""
}
if len(arg) > 0 {
m.Insert(key, 0, arg...)
if _, ok := m.Meta[key]; ok {
m.Add("option", key)
}
}
for msg := m; msg != nil; msg = msg.message {
if !msg.Has(key) {
continue
}
for _, k := range msg.Meta["option"] {
if k == key {
return msg.Get(key)
}
}
}
return ""
}
func (m *Message) Optioni(key string, arg ...interface{}) int {
return kit.Int(m.Option(key, arg...))
}
func (m *Message) Options(key string, arg ...interface{}) bool {
return kit.Right(m.Option(key, arg...))
}
func (m *Message) Optionv(key string, arg ...interface{}) interface{} {
if len(arg) > 0 {
switch arg[0].(type) {
case nil:
default:
m.Put("option", key, arg[0])
}
}
for msg := m; msg != nil; msg = msg.message {
if msg.Meta == nil || !msg.Has(key) {
continue
}
for _, k := range msg.Meta["option"] {
if k == key {
if v, ok := msg.Data[key]; ok {
return v
}
return msg.Meta[key]
}
}
}
return nil
}
func (m *Message) Append(key string, arg ...interface{}) string {
if len(arg) > 0 {
m.Insert(key, 0, arg...)
if _, ok := m.Meta[key]; ok {
m.Add("append", key)
}
}
ms := []*Message{m}
for i := 0; i < len(ms); i++ {
ms = append(ms, ms[i].messages...)
if !ms[i].Has(key) {
continue
}
for _, k := range ms[i].Meta["append"] {
if k == key {
return ms[i].Get(key)
}
}
}
return ""
}
func (m *Message) Appendi(key string, arg ...interface{}) int64 {
i, _ := strconv.ParseInt(m.Append(key, arg...), 10, 64)
return i
}
func (m *Message) Appends(key string, arg ...interface{}) bool {
return kit.Right(m.Append(key, arg...))
}
func (m *Message) Result(arg ...interface{}) string {
noset, index := true, 0
if len(arg) > 0 {
switch v := arg[0].(type) {
case int:
noset, index, arg = false, v, arg[1:]
}
}
if noset && len(arg) > 0 {
index = -2
}
return m.Insert("result", index, arg...)
}
func (m *Message) Push(key interface{}, arg ...interface{}) *Message {
keys := []string{}
switch key := key.(type) {
case string:
keys = strings.Split(key, " ")
case []string:
keys = key
}
for _, key := range keys {
switch m.Option("table.format") {
case "table":
m.Add("append", "key", key)
key = "value"
}
switch value := arg[0].(type) {
case map[string]interface{}:
m.Add("append", key, kit.Select(" ", kit.Format(kit.Chain(value, key))))
default:
m.Add("append", key, arg...)
}
}
return m
}
func (m *Message) Sort(key string, arg ...string) *Message {
cmp := "str"
if len(arg) > 0 && arg[0] != "" {
cmp = arg[0]
} else {
cmp = "int"
for _, v := range m.Meta[key] {
if _, e := strconv.Atoi(v); e != nil {
cmp = "str"
}
}
}
number := map[int]int{}
table := []map[string]string{}
m.Table(func(index int, line map[string]string) {
table = append(table, line)
switch cmp {
case "int":
number[index] = kit.Int(line[key])
case "int_r":
number[index] = -kit.Int(line[key])
case "time":
number[index] = kit.Time(line[key])
case "time_r":
number[index] = -kit.Time(line[key])
}
})
for i := 0; i < len(table)-1; i++ {
for j := i + 1; j < len(table); j++ {
result := false
switch cmp {
case "", "str":
if table[i][key] > table[j][key] {
result = true
}
case "str_r":
if table[i][key] < table[j][key] {
result = true
}
default:
if number[i] > number[j] {
result = true
}
}
if result {
table[i], table[j] = table[j], table[i]
number[i], number[j] = number[j], number[i]
}
}
}
for _, k := range m.Meta["append"] {
delete(m.Meta, k)
}
for _, v := range table {
for _, k := range m.Meta["append"] {
m.Add("append", k, v[k])
}
}
return m
}
func (m *Message) Split(str string, arg ...string) *Message {
c := rune(kit.Select(" ", arg, 0)[0])
lines := strings.Split(str, "\n")
pos := []int{}
heads := []string{}
if h := kit.Select("", arg, 2); h != "" {
heads = strings.Split(h, " ")
} else {
h, lines = lines[0], lines[1:]
v := kit.Trans(m.Optionv("cmd_headers"))
for i := 0; i < len(v)-1; i += 2 {
h = strings.Replace(h, v[i], v[i+1], 1)
}
heads = kit.Split(h, c, kit.Int(kit.Select("-1", arg, 1)))
for _, v := range heads {
pos = append(pos, strings.Index(h, v))
}
}
for _, l := range lines {
if len(l) == 0 {
continue
}
if len(pos) > 0 {
for i, v := range pos {
if v < len(l) && i == len(pos)-1 {
m.Add("append", heads[i], strings.TrimSpace(l[v:]))
} else if v < len(l) && i+1 < len(pos) && pos[i+1] < len(l) {
m.Add("append", heads[i], strings.TrimSpace(l[v:pos[i+1]]))
} else {
m.Add("append", heads[i], "")
}
}
continue
}
ls := kit.Split(l, c, len(heads))
for i, v := range heads {
m.Add("append", v, kit.Select("", ls, i))
}
}
m.Table()
return m
}
func (m *Message) Limit(offset, limit int) *Message {
l := len(m.Meta[m.Meta["append"][0]])
if offset < 0 {
offset = 0
}
if offset > l {
offset = l
}
if offset+limit > l {
limit = l - offset
}
for _, k := range m.Meta["append"] {
m.Meta[k] = m.Meta[k][offset : offset+limit]
}
return m
}
func (m *Message) Filter(value string) *Message {
return m
}
func (m *Message) Group(method string, args ...string) *Message {
nrow := len(m.Meta[m.Meta["append"][0]])
keys := map[string]bool{}
for _, v := range args {
keys[v] = true
}
counts := []int{}
mis := map[int]bool{}
for i := 0; i < nrow; i++ {
counts = append(counts, 1)
if mis[i] {
continue
}
next:
for j := i + 1; j < nrow; j++ {
if mis[j] {
continue
}
for key := range keys {
if m.Meta[key][i] != m.Meta[key][j] {
continue next
}
}
for _, k := range m.Meta["append"] {
if !keys[k] {
switch method {
case "sum", "avg":
v1, e1 := strconv.Atoi(m.Meta[k][i])
v2, e2 := strconv.Atoi(m.Meta[k][j])
if e1 == nil && e2 == nil {
m.Meta[k][i] = fmt.Sprintf("%d", v1+v2)
}
}
}
}
mis[j] = true
counts[i]++
}
}
for i := 0; i < nrow; i++ {
for _, k := range m.Meta["append"] {
if !keys[k] {
switch method {
case "avg":
if v1, e1 := strconv.Atoi(m.Meta[k][i]); e1 == nil {
m.Meta[k][i] = strconv.Itoa(v1 / counts[i])
}
}
}
}
}
for i := 0; i < nrow; i++ {
m.Push("_counts", counts[i])
}
for i := 0; i < nrow; i++ {
if mis[i] {
for j := i + 1; j < nrow; j++ {
if !mis[j] {
for _, k := range m.Meta["append"] {
m.Meta[k][i] = m.Meta[k][j]
}
mis[i], mis[j] = false, true
break
}
}
}
if mis[i] {
for _, k := range m.Meta["append"] {
m.Meta[k] = m.Meta[k][0:i]
}
break
}
}
return m
}
func (m *Message) Table(cbs ...interface{}) *Message {
if len(m.Meta["append"]) == 0 {
return m
}
// 遍历函数
if len(cbs) > 0 {
nrow := len(m.Meta[m.Meta["append"][0]])
for i := 0; i < nrow; i++ {
line := map[string]string{}
for _, k := range m.Meta["append"] {
line[k] = kit.Select("", m.Meta[k], i)
}
switch cb := cbs[0].(type) {
case func(map[string]string):
cb(line)
case func(map[string]string) bool:
if !cb(line) {
return m
}
case func(int, map[string]string):
cb(i, line)
}
}
return m
}
//计算列宽
space := kit.Select(m.Conf("table", "space"), m.Option("table.space"))
depth, width := 0, map[string]int{}
for _, k := range m.Meta["append"] {
if len(m.Meta[k]) > depth {
depth = len(m.Meta[k])
}
width[k] = kit.Width(k, len(space))
for _, v := range m.Meta[k] {
if kit.Width(v, len(space)) > width[k] {
width[k] = kit.Width(v, len(space))
}
}
}
// 回调函数
rows := kit.Select(m.Conf("table", "row_sep"), m.Option("table.row_sep"))
cols := kit.Select(m.Conf("table", "col_sep"), m.Option("table.col_sep"))
compact := kit.Right(kit.Select(m.Conf("table", "compact"), m.Option("table.compact")))
cb := func(maps map[string]string, lists []string, line int) bool {
for i, v := range lists {
if k := m.Meta["append"][i]; compact {
v = maps[k]
}
if m.Echo(v); i < len(lists)-1 {
m.Echo(cols)
}
}
m.Echo(rows)
return true
}
// 输出表头
row := map[string]string{}
wor := []string{}
for _, k := range m.Meta["append"] {
row[k], wor = k, append(wor, k+strings.Repeat(space, width[k]-kit.Width(k, len(space))))
}
if !cb(row, wor, -1) {
return m
}
// 输出数据
for i := 0; i < depth; i++ {
row := map[string]string{}
wor := []string{}
for _, k := range m.Meta["append"] {
data := ""
if i < len(m.Meta[k]) {
data = m.Meta[k][i]
}
row[k], wor = data, append(wor, data+strings.Repeat(space, width[k]-kit.Width(data, len(space))))
}
if !cb(row, wor, i) {
break
}
}
return m
}
func (m *Message) Copy(msg *Message, arg ...string) *Message {
if msg == nil || m == msg {
return m
}
for i := 0; i < len(arg); i++ {
meta := arg[i]
switch meta {
case "target":
m.target = msg.target
case "callback":
m.callback = msg.callback
case "detail", "result":
if len(msg.Meta[meta]) > 0 {
m.Add(meta, msg.Meta[meta][0], msg.Meta[meta][1:])
}
case "option", "append":
if msg.Meta == nil {
msg.Meta = map[string][]string{}
}
if msg.Meta[meta] == nil {
break
}
if i == len(arg)-1 {
arg = append(arg, msg.Meta[meta]...)
}
for i++; i < len(arg); i++ {
if v, ok := msg.Data[arg[i]]; ok {
m.Put(meta, arg[i], v)
} else if v, ok := msg.Meta[arg[i]]; ok {
m.Set(meta, arg[i], v) // TODO fuck Add
}
}
default:
if msg.Hand {
meta = "append"
} else {
meta = "option"
}
if v, ok := msg.Data[arg[i]]; ok {
m.Put(meta, arg[i], v)
}
if v, ok := msg.Meta[arg[i]]; ok {
m.Add(meta, arg[i], v)
}
}
}
return m
}
func (m *Message) Echo(str string, arg ...interface{}) *Message {
if len(arg) > 0 {
return m.Add("result", fmt.Sprintf(str, arg...))
}
return m.Add("result", str)
}
func (m *Message) Cmdp(t time.Duration, head []string, prefix []string, suffix [][]string) *Message {
if head != nil && len(head) > 0 {
m.Show(fmt.Sprintf("[%s]...\n", strings.Join(head, " ")))
}
for i, v := range suffix {
m.Show(fmt.Sprintf("%v/%v %v...\n", i+1, len(suffix), v))
m.CopyFuck(m.Cmd(prefix, v), "append")
time.Sleep(t)
}
m.Show("\n")
m.Table()
return m
}
func (m *Message) Cmdy(args ...interface{}) *Message {
m.Cmd(args...).CopyTo(m)
return m
}
func (m *Message) Cmdx(args ...interface{}) string {
msg := m.Cmd(args...)
if msg.Result(0) == "error: " {
return msg.Result(1)
}
return msg.Result(0)
}
func (m *Message) Cmds(args ...interface{}) bool {
return kit.Right(m.Cmdx(args...))
}
func (m *Message) Cmd(args ...interface{}) *Message {
if m == nil {
return m
}
if len(args) > 0 {
m.Set("detail", kit.Trans(args...))
}
key, arg := m.Meta["detail"][0], m.Meta["detail"][1:]
if key == "_" {
return m
}
msg := m
if strings.Contains(key, ":") {
ps := strings.Split(key, ":")
if ps[0] == "_" {
ps[0], arg = arg[0], arg[1:]
}
msg, key, arg = m.Sess("ssh"), "_route", append([]string{"sync", ps[0], ps[1]}, arg...)
defer func() { m.Copy(msg, "append").Copy(msg, "result") }()
m.Hand = true
} else if strings.Contains(key, ".") {
arg := strings.Split(key, ".")
if msg, key = m.Sess(arg[0]), arg[1]; len(arg) == 2 && msg != nil {
msg.Option("remote_code", "")
} else if msg, key = m.Find(strings.Join(arg[0:len(arg)-1], "."), true), arg[len(arg)-1]; msg != nil {
msg.Option("remote_code", "")
}
}
if msg == nil {
return msg
}
msg = msg.Match(key, true, func(msg *Message, s *Context, c *Context, key string) bool {
msg.Hand = false
if x, ok := c.Commands[key]; ok && x.Hand != nil {
msg.TryCatch(msg, true, func(msg *Message) {
msg.Log("cmd", "%s %s %v %v", c.Name, key, arg, msg.Meta["option"])
msg.Hand = true
x.Hand(msg, c, key, msg.Form(x, arg)...)
})
}
return msg.Hand
})
return msg
}
func (m *Message) Confm(key string, args ...interface{}) map[string]interface{} {
random := ""
var chain interface{}
if len(args) > 0 {
switch arg := args[0].(type) {
case []interface{}:
chain, args = arg, args[1:]
case []string:
chain, args = arg, args[1:]
case string:
switch arg {
case "%", "*":
random, args = arg, args[1:]
default:
chain, args = arg, args[1:]
}
}
}
var v interface{}
if chain == nil {
v = m.Confv(key)
} else {
v = m.Confv(key, chain)
}
return kit.Map(v, random, args...)
}
func (m *Message) Confx(key string, args ...interface{}) string {
value := kit.Select(m.Conf(key), m.Option(key))
if len(args) == 0 {
return value
}
switch arg := args[0].(type) {
case []string:
if len(args) > 1 {
value = kit.Select(value, arg, args[1])
} else {
value = kit.Select(value, arg)
}
args = args[1:]
case map[string]interface{}:
value = kit.Select(value, kit.Format(arg[key]))
case string:
value = kit.Select(value, arg)
case nil:
default:
value = kit.Select(value, args[0])
}
format := "%s"
if args = args[1:]; len(args) > 0 {
format, args = kit.Format(args[0]), args[1:]
}
arg := []interface{}{format, value}
for _, v := range args {
arg = append(arg, v)
}
return kit.Format(arg...)
}
func (m *Message) Confv(key string, args ...interface{}) interface{} {
if strings.Contains(key, ".") {
target := m.target
defer func() { m.target = target }()
ps := strings.Split(key, ".")
if msg := m.Sess(ps[0], false); msg != nil {
m.target, key = msg.target, ps[1]
}
}
var config *Config
m.Match(key, false, func(m *Message, s *Context, c *Context, key string) bool {
if x, ok := c.Configs[key]; ok {
config = x
return true
}
return false
})
if len(args) == 0 {
if config == nil {
return nil
}
return config.Value
}
if config == nil {
config = &Config{}
m.target.Configs[key] = config
}
switch config.Value.(type) {
case string:
config.Value = kit.Format(args...)
case bool:
config.Value = kit.Right(args...)
case int:
config.Value = kit.Int(args...)
case nil:
config.Value = args[0]
default:
for i := 0; i < len(args); i += 2 {
if i < len(args)-1 {
config.Value = kit.Chain(config.Value, args[i], args[i+1])
} else {
return kit.Chain(config.Value, args[i])
}
}
}
return config.Value
}
func (m *Message) Confs(key string, arg ...interface{}) bool {
return kit.Right(m.Confv(key, arg...))
}
func (m *Message) Confi(key string, arg ...interface{}) int {
return kit.Int(m.Confv(key, arg...))
}
func (m *Message) Conf(key string, args ...interface{}) string {
return kit.Format(m.Confv(key, args...))
}
func (m *Message) Caps(key string, arg ...interface{}) bool {
if len(arg) > 0 {
return kit.Right(m.Cap(key, arg...))
}
return kit.Right(m.Cap(key))
}
func (m *Message) Capi(key string, arg ...interface{}) int {
n := kit.Int(m.Cap(key))
if len(arg) > 0 {
return kit.Int(m.Cap(key, n+kit.Int(arg...)))
}
return n
}
func (m *Message) Cap(key string, arg ...interface{}) string {
var cache *Cache
m.Match(key, false, func(m *Message, s *Context, c *Context, key string) bool {
if x, ok := c.Caches[key]; ok {
cache = x
return true
}
return false
})
if len(arg) == 0 {
if cache == nil {
return ""
}
if cache.Hand != nil {
return cache.Hand(m, cache)
}
return cache.Value
}
if cache == nil {
cache = &Cache{}
m.target.Caches[key] = cache
}
if cache.Hand != nil {
cache.Value = cache.Hand(m, cache, kit.Format(arg...))
} else {
cache.Value = kit.Format(arg...)
}
return cache.Value
}

View File

@ -1,218 +0,0 @@
package gdb
import (
"contexts/ctx"
"toolkit"
"os"
"os/signal"
"syscall"
"time"
)
type GDB struct {
feed map[string]chan interface{}
wait chan interface{}
goon chan os.Signal
*ctx.Context
}
func (gdb *GDB) Value(m *ctx.Message, arg ...interface{}) bool {
if value, ok := kit.Chain(gdb.Configs["debug"].Value, kit.Trans(arg, "value")).(map[string]interface{}); ok {
if !kit.Right(value["enable"]) {
return false
}
if kit.Right(value["source"]) && kit.Format(value["source"]) != m.Source().Name {
return false
}
if kit.Right(value["target"]) && kit.Format(value["target"]) != m.Target().Name {
return false
}
m.Log("error", "value %v %v", arg, kit.Formats(value))
return true
}
return false
}
func (gdb *GDB) Wait(msg *ctx.Message, arg ...interface{}) interface{} {
m := gdb.Message()
if m.Cap("status") != "start" {
return nil
}
for i := len(arg); i > 0; i-- {
if gdb.Value(m, arg[:i]...) {
if result := kit.Chain(kit.Chain(gdb.Configs["debug"].Value, arg[:i]), []string{"value", "result"}); result != nil {
m.Log("error", "done %d %v", len(arg[:i]), arg)
return result
}
feed := kit.Select("web", kit.Format(kit.Chain(kit.Chain(gdb.Configs["debug"].Value, arg[:i]), []string{"value", "feed"})))
c, ok := gdb.feed[feed]
if !ok {
c = make(chan interface{})
gdb.feed[feed] = c
}
m.Log("error", "wait %d %v", len(arg[:i]), arg)
result := <-c
m.Log("error", "done %d %v %v", len(arg[:i]), arg, result)
return result
}
}
return nil
}
func (gdb *GDB) Goon(result interface{}, arg ...interface{}) {
m := gdb.Message()
if m.Cap("status") != "start" {
return
}
if m.Log("error", "goon %v %v", arg, result); len(arg) > 0 {
if c, ok := gdb.feed[kit.Format(arg[0])]; ok {
c <- result
return
}
}
gdb.wait <- result
}
func (gdb *GDB) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server {
return &GDB{Context: c}
}
func (gdb *GDB) Begin(m *ctx.Message, arg ...string) ctx.Server {
return gdb
}
func (gdb *GDB) Start(m *ctx.Message, arg ...string) bool {
m.Cmd("nfs.save", m.Conf("logpid"), os.Getpid())
gdb.wait = make(chan interface{}, 10)
gdb.goon = make(chan os.Signal, 10)
gdb.feed = map[string]chan interface{}{}
m.Confm("signal", func(sig string, action string) {
m.Log("signal", "add %s: %s", action, sig)
signal.Notify(gdb.goon, syscall.Signal(kit.Int(sig)))
})
for {
select {
case sig := <-gdb.goon:
action := m.Conf("signal", sig)
m.Log("signal", "%v: %v", action, sig)
switch action {
case "QUIT", "INT":
m.Cmd("cli.quit", 0)
case "restart":
m.Cmd("cli.quit", 1)
case "TERM":
m.Cmd("cli.quit", 2)
case "upgrade":
m.Cmd("cli.upgrade", "bench")
m.Cmd("cli.upgrade", "system")
case "WINCH":
m.Cmd("nfs.term", "init")
case "CONT":
gdb.wait <- time.Now().Format("2006-01-02 15:04:05")
default:
// gdb.Goon(nil, "cache", "read", "value")
}
}
}
return true
}
func (gdb *GDB) Close(m *ctx.Message, arg ...string) bool {
return false
}
var Index = &ctx.Context{Name: "gdb", Help: "调试中心",
Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{
"logpid": &ctx.Config{Name: "logpid", Value: "var/run/bench.pid", Help: ""},
"signal": &ctx.Config{Name: "signal", Value: map[string]interface{}{
"2": "INT",
"3": "QUIT",
"15": "TERM",
"28": "WINCH",
"30": "restart",
"31": "upgrade",
"5": "TRAP",
"1": "HUP",
// "9": "KILL",
// "10": "BUS",
// "11": "SEGV",
// "17": "STOP",
// "23": "IO",
// "29": "INFO",
"18": "TSTP",
"19": "CONT",
"6": "ABRT",
"14": "ALRM",
"20": "CHLD",
"21": "TTIN",
"22": "TTOUT",
"13": "PIPE",
"16": "URG",
"4": "ILL",
"7": "EMT",
"8": "FPE",
"12": "SYS",
"24": "XCPU",
"25": "XFSZ",
"26": "VTALRM",
"27": "PROF",
}, Help: "信号"},
"debug": &ctx.Config{Name: "debug", Value: map[string]interface{}{"value": map[string]interface{}{"enable": false},
"trace": map[string]interface{}{"value": map[string]interface{}{"enable": true}},
"context": map[string]interface{}{"value": map[string]interface{}{"enable": false},
"begin": map[string]interface{}{"value": map[string]interface{}{"enable": false}},
"start": map[string]interface{}{"value": map[string]interface{}{"enable": false}},
},
"command": map[string]interface{}{"value": map[string]interface{}{"enable": false},
"shit": map[string]interface{}{"value": map[string]interface{}{"enable": true}},
},
"config": map[string]interface{}{"value": map[string]interface{}{"enable": true}},
"cache": map[string]interface{}{"value": map[string]interface{}{"enable": false},
"read": map[string]interface{}{"value": map[string]interface{}{"enable": false},
"ncontext": map[string]interface{}{"value": map[string]interface{}{"enable": false}},
},
},
"web": map[string]interface{}{"value": map[string]interface{}{"enable": true, "feed": "web"}},
}},
},
Commands: map[string]*ctx.Command{
"_init": &ctx.Command{Name: "_init", Help: "等待调试", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Target().Start(m)
return
}},
"wait": &ctx.Command{Name: "wait arg...", Help: "等待调试", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if gdb, ok := m.Target().Server.(*GDB); m.Assert(ok) {
go func() {
m.Log("info", "wait %v", arg)
m.Log("info", "done %v", gdb.Wait(m, arg))
}()
}
return
}},
"goon": &ctx.Command{Name: "goon arg...", Help: "继续运行", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if gdb, ok := m.Target().Server.(*GDB); m.Assert(ok) {
gdb.Goon(arg[0], arg[1])
}
return
}},
},
}
func init() {
ctx.Index.Register(Index, &GDB{Context: Index})
}

View File

@ -1,512 +0,0 @@
package lex
import (
"contexts/ctx"
"toolkit"
"fmt"
"strconv"
"strings"
)
type Seed struct {
page int
hash int
word string
}
type Point struct {
s int
c byte
}
type State struct {
star bool
next int
hash int
}
type LEX struct {
seed []*Seed
hash map[string]int
word map[int]string
hand map[int]string
page map[string]int
char map[byte][]byte
state map[State]*State
mat []map[byte]*State
*ctx.Context
}
func (lex *LEX) charset(c byte) []byte {
if cs, ok := lex.char[c]; ok {
return cs
}
return []byte{c}
}
func (lex *LEX) index(m *ctx.Message, hash string, h string) int {
which, names := lex.hash, lex.word
if hash == "npage" {
which, names = lex.page, lex.hand
}
if x, e := strconv.Atoi(h); e == nil {
if hash == "npage" {
m.Assert(x <= m.Capi("npage"), "语法集合未创建")
} else {
lex.hash[h] = x
}
return x
}
if x, ok := which[h]; ok {
return x
}
which[h] = m.Capi(hash, 1)
names[which[h]] = h
m.Assert(hash != "npage" || m.Capi("npage") < m.Confi("meta", "nlang"), "语法集合超过上限")
return which[h]
}
func (lex *LEX) train(m *ctx.Message, page int, hash int, seed []byte) int {
m.Log("debug", "%s %s page: %v hash: %v seed: %v", "train", "lex", page, hash, string(seed))
ss := []int{page}
cn := make([]bool, m.Confi("meta", "ncell"))
cc := make([]byte, 0, m.Confi("meta", "ncell"))
sn := make([]bool, m.Capi("nline"))
points := []*Point{}
for p := 0; p < len(seed); p++ {
switch seed[p] {
case '[':
set := true
if p++; seed[p] == '^' {
set, p = false, p+1
}
for ; seed[p] != ']'; p++ {
if seed[p] == '\\' {
p++
for _, c := range lex.charset(seed[p]) {
cn[c] = true
}
continue
}
if seed[p+1] == '-' {
begin, end := seed[p], seed[p+2]
if begin > end {
begin, end = end, begin
}
for c := begin; c <= end; c++ {
cn[c] = true
}
p += 2
continue
}
cn[seed[p]] = true
}
for c := 0; c < len(cn); c++ {
if (set && cn[c]) || (!set && !cn[c]) {
cc = append(cc, byte(c))
}
cn[c] = false
}
case '.':
for c := 0; c < len(cn); c++ {
cc = append(cc, byte(c))
}
case '\\':
p++
for _, c := range lex.charset(seed[p]) {
cc = append(cc, c)
}
default:
cc = append(cc, seed[p])
}
m.Log("debug", "page: \033[31m%d %v\033[0m", len(ss), ss)
m.Log("debug", "cell: \033[32m%d %v\033[0m", len(cc), cc)
flag := '\000'
if p+1 < len(seed) {
flag = rune(seed[p+1])
switch flag {
case '+', '*', '?':
p++
}
}
for _, s := range ss {
line := 0
for _, c := range cc {
state := &State{}
if lex.mat[s][c] != nil {
*state = *lex.mat[s][c]
} else {
m.Capi("nnode", 1)
}
m.Log("debug", "GET(%d,%d): %v", s, c, state)
switch flag {
case '+':
state.star = true
case '*':
state.star = true
sn[s] = true
case '?':
sn[s] = true
}
if state.next == 0 {
if line == 0 || !m.Confs("meta", "compact") {
lex.mat = append(lex.mat, make(map[byte]*State))
line = m.Capi("nline", 1) - 1
sn = append(sn, false)
}
state.next = line
}
sn[state.next] = true
lex.mat[s][c] = state
points = append(points, &Point{s, c})
m.Log("debug", "SET(%d,%d): %v(%s,%s)", s, c, state, m.Cap("nnode"), m.Cap("nreal"))
}
}
cc, ss = cc[:0], ss[:0]
for s, b := range sn {
if sn[s] = false; b {
ss = append(ss, s)
}
}
}
for _, s := range ss {
if s < m.Confi("meta", "nlang") || s >= len(lex.mat) {
continue
}
if len(lex.mat[s]) == 0 {
last := m.Capi("nline") - 1
m.Cap("nline", "0")
m.Log("debug", "DEL: %d-%d", last, m.Capi("nline", s))
lex.mat = lex.mat[:s]
}
}
for _, s := range ss {
for _, p := range points {
state := &State{}
*state = *lex.mat[p.s][p.c]
if state.next == s {
m.Log("debug", "GET(%d, %d): %v", p.s, p.c, state)
if state.hash = hash; state.next >= len(lex.mat) {
state.next = 0
}
lex.mat[p.s][p.c] = state
m.Log("debug", "SET(%d, %d): %v", p.s, p.c, state)
}
if x, ok := lex.state[*state]; !ok {
lex.state[*state] = lex.mat[p.s][p.c]
m.Capi("nreal", 1)
} else {
lex.mat[p.s][p.c] = x
}
}
}
m.Log("debug", "%s %s npage: %v nhash: %v nseed: %v", "train", "lex", m.Capi("npage"), m.Capi("nhash"), m.Capi("nseed"))
return hash
}
func (lex *LEX) parse(m *ctx.Message, page int, line []byte) (hash int, rest []byte, word []byte) {
m.Log("debug", "%s %s page: %v line: %v", "parse", "lex", page, line)
pos := 0
for star, s := 0, page; s != 0 && pos < len(line); pos++ {
c := line[pos]
if c == '\\' && pos < len(line)-1 { //跳过转义
pos++
c = lex.charset(line[pos])[0]
}
if c > 127 { //跳过中文
word = append(word, c)
continue
}
state := lex.mat[s][c]
if state == nil {
s, star, pos = star, 0, pos-1
continue
}
m.Log("debug", "GET (%d,%d): %v", s, c, state)
word = append(word, c)
if state.star {
star = s
} else if x, ok := lex.mat[star][c]; !ok || !x.star {
star = 0
}
if s, hash = state.next, state.hash; s == 0 {
s, star = star, 0
}
}
if pos == len(line) {
// hash, pos, word = -1, 0, word[:0]
} else if hash == 0 {
pos, word = 0, word[:0]
}
rest = line[pos:]
m.Log("debug", "%s %s hash: %v word: %v rest: %v", "parse", "lex", hash, word, rest)
return
}
func (lex *LEX) Parse(m *ctx.Message, line []byte, page string) (hash int, rest []byte, word []byte) {
hash, rest, word = lex.parse(m, lex.index(m, "npage", page), line)
return hash, rest, word
}
func (lex *LEX) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server {
return &LEX{Context: c}
}
func (lex *LEX) Begin(m *ctx.Message, arg ...string) ctx.Server {
lex.Caches["nseed"] = &ctx.Cache{Name: "种子数量", Value: "0", Help: "词法模板的数量"}
lex.Caches["npage"] = &ctx.Cache{Name: "集合数量", Value: "0", Help: "词法集合的数量"}
lex.Caches["nhash"] = &ctx.Cache{Name: "类型数量", Value: "0", Help: "词法类型的数量"}
lex.Caches["nline"] = &ctx.Cache{Name: "状态数量", Value: m.Conf("meta", "nlang"), Help: "状态机状态的数量"}
lex.Caches["nnode"] = &ctx.Cache{Name: "节点数量", Value: "0", Help: "状态机连接的逻辑数量"}
lex.Caches["nreal"] = &ctx.Cache{Name: "实点数量", Value: "0", Help: "状态机连接的存储数量"}
lex.page = map[string]int{"nil": 0}
lex.hash = map[string]int{"nil": 0}
lex.word = map[int]string{0: "nil"}
lex.hand = map[int]string{0: "nil"}
lex.char = map[byte][]byte{
't': []byte{'\t'},
'n': []byte{'\n'},
'b': []byte{'\t', ' '},
's': []byte{'\t', ' ', '\n'},
'd': []byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'},
'x': []byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F'},
}
lex.state = make(map[State]*State)
lex.mat = make([]map[byte]*State, m.Capi("nline"))
return lex
}
func (lex *LEX) Start(m *ctx.Message, arg ...string) bool {
return false
}
func (lex *LEX) Close(m *ctx.Message, arg ...string) bool {
return true
}
var Index = &ctx.Context{Name: "lex", Help: "词法中心",
Caches: map[string]*ctx.Cache{
"nmat": &ctx.Cache{Name: "nmat", Value: "0", Help: "矩阵数量"},
},
Configs: map[string]*ctx.Config{
"npage": &ctx.Config{Name: "npage", Value: "1", Help: "默认页"},
"nhash": &ctx.Config{Name: "nhash", Value: "1", Help: "默认值"},
"meta": &ctx.Config{Name: "meta", Value: map[string]interface{}{
"ncell": 128, "nlang": 64, "compact": true,
"name": "mat%d", "help": "matrix",
}, Help: "初始参数"},
},
Commands: map[string]*ctx.Command{
"_init": &ctx.Command{Name: "_init", Help: "默认矩阵", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if _, ok := m.Target().Server.(*LEX); m.Assert(ok) {
m.Spawn().Cmd("train", "-?[a-zA-Z_0-9:/.]+", "key", "cmd")
m.Spawn().Cmd("train", "\"[^\"]*\"", "str", "cmd")
m.Spawn().Cmd("train", "'[^']*'", "str", "cmd")
m.Spawn().Cmd("train", "#[^\n]*", "com", "cmd")
m.Spawn().Cmd("train", "[~!@$%()]", "ops", "cmd")
}
return
}},
"spawn": &ctx.Command{Name: "spawn [help [name]]", Help: "创建矩阵", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if _, ok := m.Target().Server.(*LEX); m.Assert(ok) {
m.Start(fmt.Sprintf(kit.Select(m.Conf("lex.meta", "name"), arg, 1), m.Capi("nmat", 1)),
kit.Select(m.Conf("lex.meta", "help"), arg, 0))
}
return
}},
"train": &ctx.Command{Name: "train seed [hash [page]", Help: "词法训练", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if lex, ok := m.Target().Server.(*LEX); m.Assert(ok) {
hash := lex.index(m, "nhash", m.Confx("nhash", arg, 1))
page := lex.index(m, "npage", m.Confx("npage", arg, 2))
if lex.mat[page] == nil {
lex.mat[page] = map[byte]*State{}
}
m.Result(0, lex.train(m, page, hash, []byte(arg[0])))
lex.seed = append(lex.seed, &Seed{page, hash, arg[0]})
m.Cap("stream", fmt.Sprintf("%s,%s,%s", m.Cap("nseed", len(lex.seed)),
m.Cap("npage"), m.Cap("nhash", len(lex.hash)-1)))
}
return
}},
"parse": &ctx.Command{Name: "parse line [page]", Help: "词法解析", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if lex, ok := m.Target().Server.(*LEX); m.Assert(ok) {
hash, rest, word := lex.parse(m, lex.index(m, "npage", m.Confx("npage", arg, 1)), []byte(arg[0]))
m.Result(0, hash, string(rest), string(word))
}
return
}},
"split": &ctx.Command{Name: "split line [page]", Help: "词法分隔", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if lex, ok := m.Target().Server.(*LEX); m.Assert(ok) {
for input := []byte(arg[0]); len(input) > 0; {
hash, rest, word := lex.parse(m, lex.index(m, "npage", m.Confx("npage", arg, 1)), input)
m.Log("fuck", "what %v %v %v", hash, rest, word)
if hash == 0 || len(word) == 0 || len(rest) == len(input) {
if len(input) > 0 {
input = input[1:]
}
continue
}
m.Push("word", string(word))
m.Push("hash", lex.word[hash])
m.Push("rest", string(rest))
input = rest
}
m.Table()
}
return
}},
"show": &ctx.Command{Name: "show seed|page|hash|mat|node", Help: "查看信息", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if lex, ok := m.Target().Server.(*LEX); m.Assert(ok) {
if len(arg) == 0 {
m.Push("seed", len(lex.seed))
m.Push("page", len(lex.page))
m.Push("hash", len(lex.hash))
m.Push("nmat", len(lex.mat))
m.Push("node", len(lex.state))
m.Table()
return
}
switch arg[0] {
case "seed":
for _, v := range lex.seed {
m.Push("page", lex.hand[v.page])
m.Push("word", strings.Replace(strings.Replace(v.word, "\n", "\\n", -1), "\t", "\\t", -1))
m.Push("hash", lex.word[v.hash])
}
m.Sort("page", "int").Table()
case "page":
for k, v := range lex.page {
m.Push("page", k)
m.Push("code", v)
}
m.Sort("code", "int").Table()
case "hash":
for k, v := range lex.hash {
m.Push("hash", k)
m.Push("code", v)
}
m.Sort("code", "int").Table()
case "node":
for _, v := range lex.state {
m.Push("star", v.star)
m.Push("next", v.next)
m.Push("hash", v.hash)
}
m.Table()
case "mat":
for i, v := range lex.mat {
if i <= m.Capi("npage") {
m.Push("index", lex.hand[i])
} else if i < m.Confi("meta", "nlang") {
continue
} else {
m.Push("index", i)
}
for j := byte(0); j < byte(m.Confi("meta", "ncell")); j++ {
c := fmt.Sprintf("%c", j)
switch c {
case "\n":
c = "\\n"
case "\t":
c = "\\t"
case " ":
default:
if j < 0x20 {
c = fmt.Sprintf("\\%x", j)
}
}
if s := v[j]; s == nil {
m.Push(c, "")
} else {
star := 0
if s.star {
star = 1
}
m.Push(c, fmt.Sprintf("%d,%d,%d", star, s.next, s.hash))
}
}
}
ncol := len(m.Meta["append"])
nrow := len(m.Meta[m.Meta["append"][0]])
for i := 0; i < ncol-1; i++ {
for j := i + 1; j < ncol; j++ {
same := true
void := true
for n := 0; n < nrow; n++ {
if m.Meta[m.Meta["append"][i]][n] != "" {
void = false
}
if m.Meta[m.Meta["append"][i]][n] != m.Meta[m.Meta["append"][j]][n] {
same = false
break
}
}
if same {
if !void {
key = m.Meta["append"][i] + m.Meta["append"][j]
m.Meta[key] = m.Meta[m.Meta["append"][i]]
m.Meta["append"][i] = key
}
for k := j; k < ncol-1; k++ {
m.Meta["append"][k] = m.Meta["append"][k+1]
}
ncol--
j--
}
}
}
m.Meta["append"] = m.Meta["append"][:ncol]
m.Table()
}
}
return
}},
},
}
func init() {
ctx.Index.Register(Index, &LEX{Context: Index})
}

View File

@ -1,201 +0,0 @@
package log
import (
"contexts/ctx"
"toolkit"
"fmt"
"os"
"path"
)
type LOG struct {
queue chan map[string]interface{}
file map[string]*os.File
*ctx.Context
}
func (log *LOG) Log(msg *ctx.Message, action string, str string, arg ...interface{}) {
if log.queue != nil {
log.queue <- map[string]interface{}{"action": action, "str": str, "arg": arg, "msg": msg}
}
}
func (log *LOG) Value(msg *ctx.Message, arg ...interface{}) []string {
args := append(kit.Trans(arg...))
if value, ok := kit.Chain(log.Configs["output"].Value, args).(map[string]interface{}); ok {
if kit.Right(value["source"]) && kit.Format(value["source"]) != msg.Source().Name {
return nil
}
if kit.Right(value["target"]) && kit.Format(value["target"]) != msg.Target().Name {
return nil
}
return kit.Trans(value["value"])
}
return nil
}
func (log *LOG) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server {
return &LOG{Context: c}
}
func (log *LOG) Begin(m *ctx.Message, arg ...string) ctx.Server {
return log
}
func (log *LOG) Start(m *ctx.Message, arg ...string) bool {
// 创建文件
log.file = map[string]*os.File{}
m.Assert(os.MkdirAll(m.Conf("logdir"), 0770))
m.Confm("output", "file", func(key string, value string) {
switch value {
case "":
case "stderr":
log.file[key] = os.Stderr
case "stdout":
log.file[key] = os.Stdout
default:
if f, e := os.Create(path.Join(m.Conf("logdir"), value)); m.Assert(e) {
log.file[key] = f
}
}
})
// 创建队列
log.queue = make(chan map[string]interface{}, m.Confi("logbuf"))
m.Cap("stream", m.Conf("output", []string{"bench", "value", "file"}))
for {
select {
case l := <-log.queue:
m.Capi("nlog", 1)
msg := l["msg"].(*ctx.Message)
args := kit.Trans(l["arg"].([]interface{})...)
loop:
for _, v := range []string{kit.Format(l["action"]), "bench"} {
for i := len(args); i >= 0; i-- {
value := log.Value(msg, append([]string{v}, args[:i]...))
if !kit.Right(value) {
continue
}
if value[0] == "debug" && !m.Options("log.debug") {
break loop
}
// 日志文件
file := os.Stderr
if f, ok := log.file[value[0]]; ok {
file = f
} else {
break loop
}
// 日志格式
font := m.Conf("output", []string{"font", kit.Select("", value, 1)})
meta := msg.Format(m.Confv("output", []string{"meta", kit.Select("short", value, 2)}).([]interface{})...)
str := fmt.Sprintf("%d %s %s%s %s%s", m.Capi("nout", 1), meta, font,
kit.Format(l["action"]), fmt.Sprintf(kit.Format(l["str"]), l["arg"].([]interface{})...),
kit.Select("", "\033[0m", font != ""))
// 输出日志
if fmt.Fprintln(file, str); m.Confs("output", []string{"stdio", value[0]}) {
fmt.Println(str)
}
break loop
}
}
}
}
return true
}
func (log *LOG) Close(m *ctx.Message, arg ...string) bool {
return false
}
var Index = &ctx.Context{Name: "log", Help: "日志中心",
Caches: map[string]*ctx.Cache{
"nlog": &ctx.Cache{Name: "nlog", Value: "0", Help: "日志调用数量"},
"nout": &ctx.Cache{Name: "nout", Value: "0", Help: "日志输出数量"},
},
Configs: map[string]*ctx.Config{
"logbuf": &ctx.Config{Name: "logbuf", Value: "1024", Help: "日志队列长度"},
"logdir": &ctx.Config{Name: "logdir", Value: "var/log", Help: "日志目录"},
"output": &ctx.Config{Name: "output", Value: map[string]interface{}{
"stdio": map[string]interface{}{
"bench": false,
},
"file": map[string]interface{}{
"debug": "debug.log",
"bench": "bench.log",
"right": "right.log",
"error": "error.log",
},
"font": map[string]interface{}{
"red": "\033[31m",
"green": "\033[32m",
"yellow": "\033[33m",
},
"meta": map[string]interface{}{
"short": []interface{}{"time", "ship"},
"long": []interface{}{"time", "ship"},
"cost": []interface{}{"time", "ship", "mill"},
},
"debug": map[string]interface{}{"value": []interface{}{"debug"}},
"search": map[string]interface{}{"value": []interface{}{"debug"}},
"call": map[string]interface{}{"value": []interface{}{"debug"}},
"back": map[string]interface{}{"value": []interface{}{"debug"}},
"send": map[string]interface{}{"value": []interface{}{"debug"}},
"recv": map[string]interface{}{"value": []interface{}{"debug"}},
"bench": map[string]interface{}{"value": []interface{}{"bench"}},
"begin": map[string]interface{}{"value": []interface{}{"bench", "red"}},
"start": map[string]interface{}{"value": []interface{}{"bench", "red"}},
"close": map[string]interface{}{"value": []interface{}{"bench", "red"}},
"stack": map[string]interface{}{"value": []interface{}{"bench", "yellow"}},
"warn": map[string]interface{}{"value": []interface{}{"bench", "yellow"}},
"time": map[string]interface{}{"value": []interface{}{"bench", "red"}},
"right": map[string]interface{}{"value": []interface{}{"right"}},
"error": map[string]interface{}{"value": []interface{}{"error", "red"}},
"trace": map[string]interface{}{"value": []interface{}{"error", "red"}},
"cmd": map[string]interface{}{"value": []interface{}{"bench", "green"},
"lex": map[string]interface{}{"value": []interface{}{"debug", "green"}},
"yac": map[string]interface{}{"value": []interface{}{"debug", "green"}},
"cli": map[string]interface{}{
"cmd": map[string]interface{}{"value": []interface{}{"debug", "red"}},
},
"mdb": map[string]interface{}{
"note": map[string]interface{}{"value": []interface{}{"debug", "red"}},
},
"aaa": map[string]interface{}{
"auth": map[string]interface{}{"value": []interface{}{"debug", "red"}},
"hash": map[string]interface{}{"value": []interface{}{"debug", "red"}},
"rsa": map[string]interface{}{"value": []interface{}{"debug", "red"}},
},
},
}, Help: "日志输出配置"},
},
Commands: map[string]*ctx.Command{
"_init": &ctx.Command{Name: "_init", Help: "初始化", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Target().Start(m)
return
}},
"log": &ctx.Command{Name: "log level string...", Help: "输出日志, level: 日志类型, string: 日志内容", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if log, ok := m.Target().Server.(*LOG); m.Assert(ok) {
log.Log(m, arg[0], arg[1], arg[2:])
}
return
}},
},
}
func init() {
ctx.Index.Register(Index, &LOG{Context: Index})
}

View File

@ -1,803 +0,0 @@
package mdb
import (
_ "github.com/go-sql-driver/mysql"
"github.com/gomodule/redigo/redis"
"contexts/ctx"
"toolkit"
"database/sql"
"encoding/json"
"fmt"
"strings"
"time"
)
type MDB struct {
conn redis.Conn
*sql.DB
*ctx.Context
}
func (mdb *MDB) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server {
c.Caches = map[string]*ctx.Cache{
"database": &ctx.Cache{Name: "database", Value: m.Confx("database", arg, 0), Help: "数据库"},
"username": &ctx.Cache{Name: "username", Value: m.Confx("username", arg, 1), Help: "用户名"},
"password": &ctx.Cache{Name: "password", Value: m.Confx("password", arg, 2), Help: "密码"},
"address": &ctx.Cache{Name: "address", Value: m.Confx("address", arg, 3), Help: "地址"},
"protocol": &ctx.Cache{Name: "protocol(tcp)", Value: m.Confx("protocol", arg, 4), Help: "协议"},
"driver": &ctx.Cache{Name: "driver(mysql)", Value: m.Confx("driver", arg, 5), Help: "驱动"},
"redis": &ctx.Cache{Name: "redis", Value: "", Help: "数据缓存"},
}
c.Configs = map[string]*ctx.Config{
"dbs": &ctx.Config{Name: "dbs", Value: []string{}, Help: "数据库"},
"tabs": &ctx.Config{Name: "tabs", Value: []string{}, Help: "关系表"},
"limit": &ctx.Config{Name: "limit", Value: "10", Help: "分页"},
"offset": &ctx.Config{Name: "offset", Value: "0", Help: "偏移"},
}
return &MDB{Context: c}
}
func (mdb *MDB) Begin(m *ctx.Message, arg ...string) ctx.Server {
return mdb
}
func (mdb *MDB) Start(m *ctx.Message, arg ...string) bool {
if db, e := sql.Open(m.Cap("driver"), fmt.Sprintf("%s:%s@%s(%s)/%s", m.Cap("username"), m.Cap("password"),
m.Cap("protocol"), m.Cap("address"), m.Cap("database"))); m.Assert(e) {
m.Log("info", "mdb open %s", m.Cap("stream", m.Cap("database")))
mdb.DB = db
}
return false
}
func (mdb *MDB) Close(m *ctx.Message, arg ...string) bool {
return false
}
var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
Caches: map[string]*ctx.Cache{
"nsource": &ctx.Cache{Name: "nsource", Value: "0", Help: "已打开数据库的数量"},
},
Configs: map[string]*ctx.Config{
"database": &ctx.Config{Name: "database", Value: "demo", Help: "默认数据库"},
"username": &ctx.Config{Name: "username", Value: "demo", Help: "默认账户"},
"password": &ctx.Config{Name: "password", Value: "demo", Help: "默认密码"},
"address": &ctx.Config{Name: "address", Value: ":6379", Help: "默认地址"},
"protocol": &ctx.Config{Name: "protocol(tcp)", Value: "tcp", Help: "默认协议"},
"driver": &ctx.Config{Name: "driver(mysql)", Value: "mysql", Help: "默认驱动"},
"ktv": &ctx.Config{Name: "ktv", Value: map[string]interface{}{
"conf": map[string]interface{}{"expire": "24h"}, "data": map[string]interface{}{},
}, Help: "缓存数据"},
"temp": &ctx.Config{Name: "temp", Value: map[string]interface{}{}, Help: "缓存数据"},
"temp_view": &ctx.Config{Name: "temp_view", Value: map[string]interface{}{}, Help: "缓存数据"},
"temp_expire": &ctx.Config{Name: "temp_expire(s)", Value: "3000", Help: "缓存数据"},
"note": &ctx.Config{Name: "note", Value: map[string]interface{}{
"faa01a8fc2fc92dae3fbc02ac1b4ec75": map[string]interface{}{
"create_time": "1990-07-30 07:08:09", "access_time": "2017-11-01 02:03:04",
"type": "index", "name": "shy", "data": "", "ship": map[string]interface{}{
"prev": map[string]interface{}{"type": "index", "data": ""},
},
},
"81c5709d091eb04bd31ee751c3f81023": map[string]interface{}{
"create_time": "1990-07-30 07:08:09", "access_time": "2017-11-01 02:03:04",
"meta": []interface{}{"text", "text", "place", "place", "label", "label", "friend", "friend", "username", "username"},
"view": map[string]interface{}{
"list": map[string]interface{}{"name": "left", "create_date": "right"},
"edit": map[string]interface{}{"model": "hidden", "username": "hidden"},
},
"bind": map[string]interface{}{},
"type": "model", "name": "shy", "data": "", "ship": map[string]interface{}{
"prev": map[string]interface{}{"type": "model", "data": ""},
},
},
}, Help: "数据结构"},
"note_view": &ctx.Config{Name: "note_view", Value: map[string]interface{}{
"default": []interface{}{"key", "create_time", "type", "name", "model", "value"},
"base": []interface{}{"key", "create_time", "type", "name", "model", "value"},
"full": []interface{}{"key", "create_time", "access_time", "type", "name", "model", "value", "view", "data", "ship"},
}, Help: "数据视图"},
},
Commands: map[string]*ctx.Command{
"open": &ctx.Command{Name: "open [database [username [password [address [protocol [driver]]]]]]",
Help: "打开数据库, database: 数据库名, username: 用户名, password: 密码, address: 服务地址, protocol: 服务协议, driver: 数据库类型",
Form: map[string]int{"dbname": 1, "dbhelp": 1}, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Start(kit.Select(fmt.Sprintf("db%d", m.Capi("nsource", 1)), m.Option("dbname")),
kit.Select("数据源", m.Option("dbhelp")), arg...)
return
}},
"exec": &ctx.Command{Name: "exec sql [arg]", Help: "操作数据库, sql: SQL语句, arg: 操作参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if mdb, ok := m.Target().Server.(*MDB); m.Assert(ok) && mdb.DB != nil {
which := make([]interface{}, 0, len(arg))
for _, v := range arg[1:] {
which = append(which, v)
}
if ret, e := mdb.Exec(arg[0], which...); m.Assert(e) {
id, _ := ret.LastInsertId()
n, _ := ret.RowsAffected()
m.Log("info", "last(%s) nrow(%s)", m.Append("last", id), m.Append("nrow", n))
m.Echo("%d", n)
}
}
return
}},
"query": &ctx.Command{Name: "query sql [arg]", Help: "查询数据库, sql: SQL语句, arg: 查询参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if mdb, ok := m.Target().Server.(*MDB); m.Assert(ok) && mdb.DB != nil {
which := make([]interface{}, 0, len(arg))
for _, v := range arg[1:] {
which = append(which, v)
}
if rows, e := mdb.Query(arg[0], which...); m.Assert(e) {
defer rows.Close()
if cols, e := rows.Columns(); m.Assert(e) {
num := len(cols)
for rows.Next() {
vals := make([]interface{}, num)
ptrs := make([]interface{}, num)
for i := range vals {
ptrs[i] = &vals[i]
}
rows.Scan(ptrs...)
for i, k := range cols {
m.Push(k, vals[i])
}
}
if len(m.Meta["append"]) > 0 {
m.Log("info", "rows(%d) cols(%d)", len(m.Meta[m.Meta["append"][0]]), len(m.Meta["append"]))
} else {
m.Log("info", "rows(0) cols(0)")
}
m.Table()
}
}
}
return
}},
"redis": &ctx.Command{Name: "redis [open address]|[cmd...]", Help: "缓存数据库", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if mdb, ok := m.Target().Server.(*MDB); m.Assert(ok) {
switch arg[0] {
case "open":
if mdb.conn, e = redis.Dial("tcp", m.Cap("redis", arg[1]), redis.DialKeepAlive(time.Second*10)); m.Assert(e) {
m.Log("info", "redis: %v", arg[1])
}
default:
if mdb.conn == nil || mdb.conn.Err() != nil {
if m.Caps("redis") {
m.Cmd("mdb.redis", "open", m.Cap("redis"))
} else {
m.Echo("not open")
break
}
}
args := []interface{}{}
for _, v := range arg[1:] {
args = append(args, v)
}
if res, err := mdb.conn.Do(arg[0], args...); m.Assert(err) {
switch val := res.(type) {
case redis.Error:
m.Echo("%v", val)
case []interface{}:
for i, v := range val {
m.Add("append", "index", i)
m.Add("append", "value", v)
}
m.Table()
default:
var data interface{}
if str := kit.Format(res); json.Unmarshal([]byte(str), &data) == nil {
m.Echo(kit.Formats(data))
} else {
m.Echo(str)
}
}
}
}
}
return
}},
"db": &ctx.Command{Name: "db [which]", Help: "查看或选择数据库", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) == 0 {
m.Cmdy(".query", "show databases").Table()
return
}
m.Assert(m.Cmdy("exec", fmt.Sprintf("use %s", arg[0])))
m.Echo(m.Cap("database", arg[0]))
return
}},
"tab": &ctx.Command{Name: "tab [which [field]]", Help: "查看关系表which: 表名, field: 字段名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
switch len(arg) {
case 0:
m.Cmdy(".query", "show tables").Table()
case 1:
m.Cmdy(".query", fmt.Sprintf("desc %s", arg[0])).Table()
case 2:
m.Cmdy(".query", fmt.Sprintf("desc %s", arg[0])).Cmd("select", "Field", arg[1]).CopyTo(m)
}
return
}},
"show": &ctx.Command{Name: "show table fields...", Help: "查询数据, table: 表名, fields: 字段, where: 查询条件, group: 聚合字段, order: 排序字段",
Form: map[string]int{"where": 1, "eq": 2, "ne": 2, "in": 2, "like": 2, "begin": 2, "group": 1, "order": 1, "desc": 0, "limit": 1, "offset": 1, "other": -1},
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) == 0 {
m.Cmdy(".query", "show tables")
return
}
stmt := []string{
fmt.Sprintf("select %s", kit.Select("*", strings.Join(arg[1:], ","))),
fmt.Sprintf("from %s", arg[0]),
}
where := []string{}
if m.Has("where") {
where = append(where, m.Option("where"))
}
for i := 0; i < len(m.Meta["eq"]); i += 2 {
where = append(where, fmt.Sprintf("%s='%s'", m.Meta["eq"][i], m.Meta["eq"][i+1]))
}
for i := 0; i < len(m.Meta["ne"]); i += 2 {
where = append(where, fmt.Sprintf("%s!='%s'", m.Meta["ne"][i], m.Meta["ne"][i+1]))
}
for i := 0; i < len(m.Meta["in"]); i += 2 {
where = append(where, fmt.Sprintf("%s in (%s)", m.Meta["in"][i], m.Meta["in"][i+1]))
}
for i := 0; i < len(m.Meta["like"]); i += 2 {
where = append(where, fmt.Sprintf("%s like '%s'", m.Meta["like"][i], m.Meta["like"][i+1]))
}
for i := 0; i < len(m.Meta["begin"]); i += 2 {
where = append(where, fmt.Sprintf("%s like '%s%%'", m.Meta["begin"][i], m.Meta["begin"][i+1]))
}
if len(where) > 0 {
stmt = append(stmt, "where", strings.Join(where, " and "))
}
if m.Has("group") {
stmt = append(stmt, fmt.Sprintf("group by %s", m.Option("group")))
}
if m.Has("order") {
stmt = append(stmt, fmt.Sprintf("order by %s", m.Option("order")))
}
if m.Has("desc") {
stmt = append(stmt, "desc")
}
stmt = append(stmt, fmt.Sprintf("limit %s", m.Confx("limit")))
stmt = append(stmt, fmt.Sprintf("offset %s", m.Confx("offset")))
for _, v := range m.Meta["other"] {
stmt = append(stmt, m.Parse(v))
}
m.Cmdy(".query", strings.Join(stmt, " "))
return
}},
"update": &ctx.Command{Name: "update [table [condition [field [value]]...]]",
Help: "修改数据, table: 关系表, condition: 条件语句, field: 字段名, value: 字段值",
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
switch len(arg) {
case 0:
m.Cmdy(".show")
case 1:
m.Cmdy(".show", arg[0])
case 2:
m.Cmdy(".show", arg[0], "where", arg[1])
case 3:
m.Cmdy(".show", arg[0], arg[2], "where", arg[1])
default:
fields := []string{}
values := []string{}
for i := 2; i < len(arg)-1; i += 2 {
fields = append(fields, arg[i])
values = append(values, fmt.Sprintf("%s='%s'", arg[i], arg[i+1]))
}
stmt := []string{"update", arg[0]}
stmt = append(stmt, "set", strings.Join(values, ","))
stmt = append(stmt, "where", arg[1])
m.Cmd(".exec", strings.Join(stmt, " "))
m.Cmdy(".show", arg[0], fields, "where", arg[1])
}
return
}},
"ktv": &ctx.Command{Name: "ktv", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) == 0 {
now := kit.Int(m.Time("stamp"))
m.Confm("ktv", "data", func(key string, value map[string]interface{}) {
m.Push("key", key)
m.Push("expire", kit.Int(value["expire"])-now)
m.Push("value", value["value"])
})
m.Table()
return
}
if len(arg) == 1 {
if m.Confi("ktv", []string{"data", arg[0], "expire"}) < kit.Int(m.Time("stamp")) {
m.Conf("ktv", []string{"data", arg[0]}, "")
}
m.Echo(m.Conf("ktv", []string{"data", arg[0], "value"}))
return
}
m.Confv("ktv", []string{"data", arg[0]}, map[string]interface{}{
"expire": m.Time(kit.Select(m.Conf("ktv", "conf.expire"), arg, 2), "stamp"),
"value": arg[1],
})
m.Echo(arg[1])
return
}},
"temp": &ctx.Command{Name: "temp [type [meta [data]]] [tid [node|ship|data] [chain... [select ...]]]",
Form: map[string]int{"select": -1, "limit": 1}, Help: "缓存数据", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) > 0 && arg[0] == "check" {
h := ""
for i := 1; i < len(arg)-1; i += 2 {
switch arg[i] {
case "url", "trans":
h = ""
}
if h = m.Cmdx("aaa.hash", arg[i], arg[i+1], h); !m.Confs("temp", h) {
return
}
expire := kit.Time(m.Conf("temp", []string{h, "create_time"})) + kit.Int(m.Confx("temp_expire")) - kit.Time(m.Time())
m.Log("info", "expire: %ds", expire)
if expire < 0 {
return
}
}
m.Echo(h)
return
}
if len(arg) > 2 { // 添加数据
if temp := m.Confm("temp", arg[0]); temp == nil {
h := m.Cmdx("aaa.hash", arg[0], arg[1])
m.Confv("temp", h, map[string]interface{}{
"create_time": m.Time(), "expire_time": m.Time("60s"),
"type": arg[0], "meta": arg[1], "data": m.Optionv(arg[2]),
})
arg[2], arg = h, arg[2:]
}
}
if len(arg) > 1 {
if temp, msg := m.Confm("temp", arg[0]), m; temp != nil {
hash, arg := arg[0], arg[1:]
switch arg[0] {
case "node": // 查看节点
m.Put("option", "temp", temp).Cmdy("ctx.trans", "temp")
return
case "ship": //查看链接
for k, v := range temp {
val := v.(map[string]interface{})
m.Add("append", "key", k)
m.Add("append", "create_time", val["create_time"])
m.Add("append", "type", val["type"])
m.Add("append", "meta", val["meta"])
}
m.Sort("create_time", "time_r").Table()
return
case "data": // 查看数据
arg = arg[1:]
}
trans := strings.Join(append([]string{hash, "data"}, arg...), ".")
h := m.Cmdx("aaa.hash", "trans", trans)
if len(arg) == 0 || temp["type"].(string) == "trans" {
h = hash
} else { // 转换数据
if view := m.Confm("temp", h); view != nil && false { // 加载缓存
msg = m.Spawn()
switch data := view["data"].(type) {
case map[string][]string:
msg.Meta = data
case map[string]interface{}:
for k, v := range data {
switch val := v.(type) {
case []interface{}:
msg.Add("append", k, val)
}
}
m.Confv("temp", []string{h, "data"}, msg.Meta)
}
temp = view
} else if arg[0] == "hash" { // 添加缓存
m.Echo(hash)
} else if arg[0] == "" { // 添加缓存
b, _ := json.MarshalIndent(temp["data"], "", " ")
m.Echo(string(b))
} else {
msg = m.Put("option", "temp", temp["data"]).Cmd("ctx.trans", "temp", arg)
m.Confv("temp", h, map[string]interface{}{
"create_time": m.Time(), "expire_time": m.Time("60s"),
"type": "trans", "meta": trans, "data": msg.Meta,
"ship": map[string]interface{}{
hash: map[string]interface{}{"create_time": m.Time(), "ship": "0", "type": temp["type"], "meta": temp["meta"]},
},
})
m.Confv("temp", []string{hash, "ship", h}, map[string]interface{}{
"create_time": m.Time(), "ship": "1", "type": "trans", "meta": trans,
})
temp = m.Confm("temp", h)
}
}
if m.Options("select") { // 过滤数据
chain := strings.Join(m.Optionv("select").([]string), " ")
hh := m.Cmdx("aaa.hash", "select", chain, h)
if view := m.Confm("temp", hh); view != nil && false { // 加载缓存
msg = msg.Spawn()
switch data := view["data"].(type) {
case map[string][]string:
msg.Meta = data
case map[string]interface{}:
for k, v := range data {
switch val := v.(type) {
case []interface{}:
msg.Add("append", k, val)
}
}
m.Confv("temp", []string{h, "data"}, msg.Meta)
}
} else { // 添加缓存
msg = msg.Spawn().Copy(msg, "append").Cmd("select", m.Optionv("select"))
m.Confv("temp", hh, map[string]interface{}{
"create_time": m.Time(), "expire_time": m.Time("60s"),
"type": "select", "meta": chain, "data": msg.Meta,
"ship": map[string]interface{}{
h: map[string]interface{}{"create_time": m.Time(), "ship": "0", "type": temp["type"], "meta": temp["meta"]},
},
})
m.Confv("temp", []string{h, "ship", hh}, map[string]interface{}{
"create_time": m.Time(), "ship": "1", "type": "select", "meta": chain,
})
}
}
msg.CopyTo(m)
return
}
}
h, arg := arg[0], arg[1:]
if h != "" {
if temp := m.Confm("temp", h); temp != nil {
m.Echo(h)
return
}
}
// 缓存列表
m.Confm("temp", func(key string, temp map[string]interface{}) {
if len(arg) == 0 || strings.HasPrefix(key, arg[0]) || strings.HasSuffix(key, arg[0]) || (temp["type"].(string) == arg[0] && (len(arg) == 1 || strings.Contains(temp["meta"].(string), arg[1]))) {
m.Add("append", "key", key)
m.Add("append", "create_time", temp["create_time"])
m.Add("append", "type", temp["type"])
m.Add("append", "meta", temp["meta"])
}
})
m.Sort("create_time", "time_r").Table().Cmd("select", m.Optionv("select"))
return
}},
"note": &ctx.Command{Name: "note [model [name [type name]...]]|[index [name data...]]|[value name data...]|[name model data...]",
Form: map[string]int{"eq": 2, "begin": 2, "offset": 1, "limit": 1}, Help: "记事", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
offset := kit.Int(kit.Select(m.Conf("table", "offset"), m.Option("table.offset")))
limit := kit.Int(kit.Select(m.Conf("table", "limit"), m.Option("table.limit")))
// 节点列表
if len(arg) == 0 {
m.CopyFuck(m.Cmd("mdb.config", "note", "format", "table", "fields", "create_time", "access_time", "type", "name", "data", "ship"), "append").Set("result").Table()
return
}
// 节点详情
if note := m.Confm("note", arg[0]); note != nil {
m.CopyFuck(m.Cmd("mdb.config", "note", arg[0]), "append").Set("result").Table()
return
}
// 节点列表
hm, _ := kit.Hash("type", arg[0], "name", "shy")
if len(arg) == 2 && arg[0] == "value" {
hm, _ = kit.Hash("type", "index", "name", arg[1])
hm = m.Conf("note", []string{hm, "ship", "value", "data"})
arg = arg[1:]
} else if len(arg) == 2 && arg[0] == "note" {
hm, _ = kit.Hash("type", "model", "name", arg[1])
hm = m.Conf("note", []string{hm, "ship", "note", "data"})
arg = arg[1:]
}
if len(arg) == 1 && arg[0] != "show" {
for i := offset; hm != "" && i < limit+offset; hm, i = m.Conf("note", []string{hm, "ship", "prev", "data"}), i+1 {
model := m.Confm("note", hm)
m.Add("append", "key", hm)
m.Add("append", "create_time", model["create_time"])
m.Add("append", "access_time", model["access_time"])
m.Add("append", "type", model["type"])
m.Add("append", "name", model["name"])
m.Add("append", "view", kit.Format(model["view"]))
m.Add("append", "data", kit.Format(model["data"]))
m.Add("append", "ship", kit.Format(model["ship"]))
}
m.Table()
return
}
switch arg[0] {
case "show":
if len(arg) == 1 { // 查看索引
m.Cmdy("mdb.note", "index")
break
}
if len(arg) == 2 {
if arg[1] == "model" { // 查看模型
m.Cmdy("mdb.note", "model")
} else { // 查看数值
m.Cmdy("mdb.note", "value", arg[1])
}
break
}
fields := kit.View(arg[3:], m.Confm("note_view"))
hv, _ := kit.Hash("type", "value", "name", arg[1], "data", kit.Select(arg[2], m.Option(arg[2])))
hn := m.Conf("note", []string{hv, "ship", "note", "data"})
if arg[1] == "model" {
hm, _ := kit.Hash("type", "model", "name", arg[2])
hv, hn = "prev", m.Conf("note", []string{hm, "ship", "note", "data"})
}
fuck := 0
for i := 0; hn != "" && i < limit+offset; hn, i = m.Conf("note", []string{hn, "ship", hv, "data"}), i+1 {
m.Log("fuck", "what %d %d %d %s", offset, limit, i, hn)
// m.Log("fuck", "what hn: %v %v", hn, kit.Formats(m.Confv("note", hn)))
// 翻页
if fuck++; fuck > 1000 {
break
}
if i < offset {
continue
}
// 关系表
note := m.Confm("note", hn)
hvs := kit.Trans(note["data"])
hm := kit.Format(kit.Chain(note, "ship.model.data"))
// 值转换
value := []interface{}{}
values := map[string]interface{}{}
m.Confm("note", []string{hm, "data"}, func(i int, model map[string]interface{}) {
v := m.Conf("note", []string{hvs[i], "data"})
value = append(value, map[string]interface{}{"type": model["type"], "name": model["name"], "value": v})
values[kit.Format(model["name"])] = v
})
// 行筛选
miss := false
if !miss && m.Has("eq") {
for j := 0; j < len(m.Meta["eq"]); j += 2 {
if kit.Select(kit.Format(note[m.Meta["eq"][j]]), kit.Format(values[m.Meta["eq"][j]])) != m.Meta["eq"][j+1] {
miss = true
break
}
}
}
if !miss && m.Has("begin") {
for j := 0; j < len(m.Meta["begin"]); j += 2 {
if !strings.HasPrefix(kit.Select(kit.Format(note[m.Meta["begin"][j]]),
kit.Format(values[m.Meta["begin"][j]])), m.Meta["begin"][j+1]) {
miss = true
break
}
}
}
if miss {
i--
continue
}
// 列筛选
for j := 0; j < len(fields); j++ {
switch fields[j] {
case "key":
m.Add("append", "key", hn)
case "create_time", "access_time", "type", "name":
m.Add("append", fields[j], note[fields[j]])
case "model":
m.Add("append", "model", m.Conf("note", []string{hm, "name"}))
case "view":
m.Add("append", "view", kit.Format(m.Conf("note", []string{hm, "view"})))
case "value":
m.Add("append", "value", kit.Format(value))
case "data", "ship":
m.Add("append", fields[j], kit.Format(note[fields[j]]))
default:
m.Add("append", fields[j], kit.Format(values[fields[j]]))
}
}
}
m.Table()
case "model":
// 模板详情
hm, _ := kit.Hash("type", arg[0], "name", arg[1])
if len(arg) == 2 {
m.CopyFuck(m.Cmd("mdb.config", "note", hm), "append").Set("result").Table()
break
}
// 模板视图
if arg[2] == "view" {
for i := 4; i < len(arg)-1; i += 2 {
m.Conf("note", []string{hm, "view", arg[3], arg[i]}, arg[i+1])
}
break
}
// 操作模板
data := []interface{}{}
if model := m.Confm("note", hm); model == nil { // 添加模板
view := map[string]interface{}{}
m.Confm("note", "81c5709d091eb04bd31ee751c3f81023.view", func(key string, fields map[string]interface{}) {
vs := map[string]interface{}{}
for k, v := range fields {
vs[k] = v
}
view[key] = vs
})
prev := m.Conf("note", []string{"81c5709d091eb04bd31ee751c3f81023", "ship", "prev", "data"})
m.Confv("note", hm, map[string]interface{}{
"type": "model", "name": arg[1], "data": data, "view": view,
"create_time": m.Time(), "access_time": m.Time(),
"ship": map[string]interface{}{
"prev": map[string]interface{}{"type": "model", "data": prev},
"note": map[string]interface{}{"type": "note", "data": ""},
},
})
m.Conf("note", []string{"81c5709d091eb04bd31ee751c3f81023", "ship", "prev", "data"}, hm)
} else { // 修改模板
data = m.Confv("note", []string{hm, "data"}).([]interface{})
m.Confv("note", []string{hm, "access_time"}, m.Time())
}
// 操作元素
if len(data) == 0 {
arg = append(arg, kit.Trans(m.Confv("note", "81c5709d091eb04bd31ee751c3f81023.meta"))...)
for i := 2; i < len(arg)-1; i += 2 {
data = append(data, map[string]interface{}{"name": arg[i], "type": arg[i+1]})
hi, _ := kit.Hash("type", "index", "name", arg[i+1])
if index := m.Confm("note", hi); index == nil {
m.Cmd("mdb.note", "index", arg[i+1])
}
}
}
m.Confv("note", []string{hm, "data"}, data)
m.Echo(hm)
case "index":
// 操作索引
data := arg[2:]
hi, _ := kit.Hash("type", arg[0], "name", arg[1])
if index := m.Confm("note", hi); index == nil { // 添加索引
prev := m.Conf("note", []string{"faa01a8fc2fc92dae3fbc02ac1b4ec75", "ship", "prev", "data"})
m.Confv("note", hi, map[string]interface{}{
"create_time": m.Time(), "access_time": m.Time(),
"type": "index", "name": arg[1], "data": data, "ship": map[string]interface{}{
"prev": map[string]interface{}{"type": "index", "data": prev},
"value": map[string]interface{}{"type": "value", "data": ""},
},
})
m.Confv("note", []string{"faa01a8fc2fc92dae3fbc02ac1b4ec75", "ship", "prev", "data"}, hi)
} else { // 修改索引
m.Confv("note", []string{hi, "access_time"}, m.Time())
data, _ = m.Confv("note", []string{hi, "data"}).([]string)
}
// 操作元素
m.Confv("note", []string{hi, "data"}, data)
m.Echo(hi)
case "value":
hi := m.Cmdx("mdb.note", "index", arg[1])
hv, _ := kit.Hash("type", arg[0], "name", arg[1], "data", arg[2])
if value := m.Confm("note", hv); value == nil {
prev := m.Conf("note", []string{hi, "ship", "value", "data"})
m.Confv("note", hv, map[string]interface{}{
"create_time": m.Time(), "access_time": m.Time(),
"type": arg[0], "name": arg[1], "data": arg[2], "ship": map[string]interface{}{
"prev": map[string]interface{}{"type": "value", "data": prev},
"index": map[string]interface{}{"type": "index", "data": hi},
"note": map[string]interface{}{"type": "note", "data": ""},
},
})
m.Conf("note", []string{hi, "ship", "value", "data"}, hv)
} else {
m.Confv("note", []string{hv, "access_time"}, m.Time())
}
m.Echo(hv)
default:
if len(arg) == 2 {
}
hm, _ := kit.Hash("type", "model", "name", arg[1])
hn, _ := kit.Hash("type", "note", "name", arg[0], "uniq")
hp := m.Conf("note", []string{hm, "ship", "note", "data"})
if hp == hn {
hp = ""
}
ship := map[string]interface{}{
"prev": map[string]interface{}{"type": "note", "data": hp},
"model": map[string]interface{}{"type": "model", "data": hm},
}
data := []interface{}{}
m.Confm("note", []string{hm, "data"}, func(i int, index map[string]interface{}) {
hv := m.Cmdx("mdb.note", "value", index["type"], kit.Select(m.Option(kit.Format(index["name"])), arg, i+2))
data = append(data, hv)
ship[hv] = map[string]interface{}{"type": "note", "data": m.Conf("note", []string{hv, "ship", "note", "data"})}
m.Conf("note", []string{hv, "ship", "note", "data"}, hn)
})
m.Confv("note", hn, map[string]interface{}{
"create_time": m.Time(), "access_time": m.Time(),
"type": "note", "name": arg[0], "data": data, "ship": ship,
})
m.Conf("note", []string{hm, "ship", "note", "data"}, hn)
m.Echo(hn)
}
return
sync := len(arg) > 0 && arg[0] == "sync"
if sync {
m.Cmdy("ssh.sh", "sub", "context", "mdb", "note", arg)
m.Set("result").Table()
arg = arg[1:]
}
h, _ := kit.Hash("uniq")
data := map[string]interface{}{
"create_time": m.Time(),
"type": arg[0],
"title": arg[1],
"content": arg[2],
}
for i := 3; i < len(arg)-1; i += 2 {
kit.Chain(data, data[arg[i]], arg[i+1])
}
m.Conf("note", h, data)
m.Echo(h)
return
}},
},
}
func init() {
ctx.Index.Register(Index, &MDB{Context: Index})
}

File diff suppressed because it is too large Load Diff

View File

@ -1,647 +0,0 @@
package nfs
import (
"github.com/nsf/termbox-go"
"contexts/ctx"
"toolkit"
"fmt"
"strings"
"time"
)
func (nfs *NFS) Read(p []byte) (n int, err error) {
m := nfs.Context.Message()
if !m.Caps("termbox") {
return nfs.in.Read(p)
}
m.TryCatch(m, true, func(m *ctx.Message) {
scroll_count := 0
scroll_lines := m.Confi("term", "scroll_lines")
which := m.Capi("ninput")
what := make([]rune, 0, 1024)
rest := make([]rune, 0, 1024)
back := make([]rune, 0, 1024)
m.Option("bio.cmd", "")
m.Options("bio.shadow", m.Confs("show_shadow"))
defer func() { m.Option("bio.cmd", "") }()
frame, table, index, pick := map[string]interface{}{}, []map[string]string{}, 0, 0
if change, f, t, i := nfs.Auto(what, ":", 0); change {
frame, table, index, pick = f, t, i, 0
}
for {
switch ev := termbox.PollEvent(); ev.Type {
case termbox.EventInterrupt:
case termbox.EventResize:
nfs.Term(m, "resize")
case termbox.EventMouse:
switch ev.Key {
case termbox.MouseLeft:
if m.Confs("term", "mouse.resize") {
nfs.Term(m, "window", ev.MouseX, ev.MouseY)
nfs.prompt(what).shadow(rest)
}
case termbox.MouseMiddle:
case termbox.MouseRight:
if m.Confs("term", "mouse.resize") {
nfs.Term(m, "resize", ev.MouseX, ev.MouseY)
}
case termbox.MouseRelease:
case termbox.MouseWheelUp:
if scroll_count++; scroll_count > m.Confi("term", "scroll_count") {
nfs.Term(m, "scroll", -1).Term(m, "flush")
scroll_count = 0
}
case termbox.MouseWheelDown:
if scroll_count++; scroll_count > m.Confi("term", "scroll_count") {
nfs.Term(m, "scroll", 1).Term(m, "flush")
scroll_count = 0
}
}
case termbox.EventError:
case termbox.EventNone:
case termbox.EventRaw:
case termbox.EventKey:
switch ev.Key {
case termbox.KeyCtrlP:
if which--; which < 0 {
which = m.Capi("ninput") - 1
}
if v := m.Conf("input", []interface{}{which, "line"}); v != "" {
what, rest = append(what[:0], []rune(v)...), rest[:0]
nfs.prompt(what).shadow(rest)
}
case termbox.KeyCtrlN:
if which++; which >= m.Capi("ninput") {
which = 0
}
if v := m.Conf("input", []interface{}{which, "line"}); v != "" {
what, rest = append(what[:0], []rune(v)...), rest[:0]
nfs.prompt(what).shadow(rest)
}
case termbox.KeyCtrlA:
if len(what) > 0 {
what, rest = append(what, rest...), rest[:0]
rest, what = append(rest, what...), what[:0]
nfs.prompt(what).shadow(rest)
}
case termbox.KeyCtrlF:
if len(rest) > 0 {
pos := len(what) + 1
what, rest = append(what, rest...), rest[:0]
rest, what = append(rest, what[pos:]...), what[:pos]
nfs.prompt(what).shadow(rest)
}
case termbox.KeyCtrlB:
if len(what) > 0 {
pos := len(what) - 1
what, rest = append(what, rest...), rest[:0]
rest, what = append(rest, what[pos:]...), what[:pos]
nfs.prompt(what).shadow(rest)
}
case termbox.KeyCtrlE:
if len(rest) > 0 {
what, rest = append(what, rest...), rest[:0]
nfs.prompt(what).shadow(rest)
}
case termbox.KeyCtrlU:
back = back[:0]
back, what = append(back, what...), what[:0]
nfs.prompt(what).shadow(rest)
case termbox.KeyCtrlD: // termbox.KeyBackspace
if len(rest) > 0 {
pos := len(what)
what, rest = append(what, rest[1:]...), rest[:0]
rest, what = append(rest, what[pos:]...), what[:pos]
nfs.prompt(what).shadow(rest)
}
case termbox.KeyCtrlH: // termbox.KeyBackspace
if len(what) > 0 {
what = what[:len(what)-1]
nfs.prompt(what).shadow(rest)
}
case termbox.KeyCtrlK:
back = back[:0]
back, rest = append(back, rest...), rest[:0]
nfs.prompt(what).shadow(rest)
case termbox.KeyCtrlW:
if len(what) > 0 {
pos := len(what) - 1
for space := what[pos] == ' '; pos >= 0; pos-- {
if (space && what[pos] != ' ') || (!space && what[pos] == ' ') {
break
}
}
back = back[:0]
back, what = append(back, what[pos+1:]...), what[:pos+1]
nfs.prompt(what).shadow(rest)
}
case termbox.KeyCtrlY:
what = append(what, back...)
nfs.prompt(what).shadow(rest)
case termbox.KeyCtrlR:
nfs.Term(m, "refresh").Term(m, "flush")
nfs.prompt(what).shadow(rest)
case termbox.KeyCtrlL:
m.Confi("term", "begin_row", m.Capi("noutput"))
m.Confi("term", "begin_col", 0)
nfs.Term(m, "clear", "all").Term(m, "flush")
nfs.prompt(what).shadow(rest)
case termbox.KeyCtrlT:
m.Option("scroll", true)
nfs.Term(m, "scroll", scroll_lines).Term(m, "flush")
m.Option("scroll", false)
case termbox.KeyCtrlO:
m.Option("scroll", true)
nfs.Term(m, "scroll", -scroll_lines).Term(m, "flush")
m.Option("scroll", false)
case termbox.KeyCtrlJ, termbox.KeyEnter:
what = append(what, '\n')
n = copy(p, []byte(string(what)))
return
case termbox.KeyCtrlQ, termbox.KeyCtrlC:
nfs.Term(m, "exit")
n = copy(p, []byte("return\n"))
return
case termbox.KeyCtrlV:
for i := -1; i < 8; i++ {
nfs.Term(m, "color", i, m.Confi("term", "rest_fg"), fmt.Sprintf("\nhello bg %d", i))
}
for i := -1; i < 8; i++ {
nfs.Term(m, "color", m.Confi("term", "rest_bg"), i, fmt.Sprintf("\nhello fg %d", i))
}
nfs.Term(m, "flush")
case termbox.KeyCtrlG:
case termbox.KeyCtrlX:
m.Options("bio.shadow", !m.Options("bio.shadow"))
case termbox.KeyCtrlS:
case termbox.KeyCtrlZ:
case termbox.KeyTab:
m.Options("bio.shadow", true)
// if index > len(what) {
// nfs.shadow("", table, frame)
// } else {
// if lines := kit.Int(frame["lines"]); lines > 0 {
// pick = (pick + 1) % lines
// }
// nfs.shadow(what[index:], table, frame, pick)
// rest = append(rest[:0], []rune(kit.Format(frame["pick"]))[len(what)-index:]...)
// nfs.prompt(what).shadow(rest)
// nfs.shadow(what[index:], table, frame, pick)
// }
//
case termbox.KeySpace:
what = append(what, ' ')
nfs.prompt(what).shadow(rest)
if !m.Options("bio.shadow") {
break
}
if index > len(what) {
nfs.shadow("", table, frame)
} else {
m.Option("auto_key", strings.TrimSpace(string(what[index:])))
if change, f, t, i := nfs.Auto(what, " ", len(what)); change {
frame, table, index, pick = f, t, i, 0
}
if nfs.shadow(what[index:], table, frame); len(table) > 0 {
rest = append(rest[:0], []rune(table[0][kit.Format(frame["field"])])...)
nfs.prompt(what).shadow(rest)
nfs.shadow(what[index:], table, frame)
}
}
default:
what = append(what, ev.Ch)
nfs.prompt(what).shadow(rest)
if !m.Options("bio.shadow") {
break
}
if change, f, t, i := nfs.Auto(what, kit.Format(ev.Ch), len(what)); change {
frame, table, index, pick = f, t, i, 0
}
if index > len(what) {
nfs.shadow("", table, frame)
} else {
nfs.shadow(what[index:], table, frame, pick)
if pos, word := len(what)-index, kit.Format(frame["pick"]); len(table) > 0 && pos < len(word) {
rest = append(rest[:0], []rune(word)[pos:]...)
} else {
}
nfs.prompt(what).shadow(rest)
nfs.shadow(what[index:], table, frame, pick)
}
}
}
}
})
return
}
func (nfs *NFS) Auto(what []rune, trigger string, index int) (change bool, frame map[string]interface{}, table []map[string]string, nindex int) {
return
m := nfs.Context.Message()
auto_target := m.Optionv("bio.ctx").(*ctx.Context)
auto_cmd := ""
auto_arg := []string{}
switch trigger {
case " ":
switch m.Conf("term", "help_state") {
case "context":
// auto_target = auto_target.Sub(m.Option("auto_key"))
m.Optionv("bio.ctx", auto_target)
trigger = ":"
case "command":
m.Option("arg_index", index)
auto_cmd = m.Option("bio.cmd", m.Option("auto_key"))
trigger = "="
case "argument":
auto_cmd = m.Option("bio.cmd")
auto_arg = strings.Split(strings.TrimSpace(string(what[m.Optioni("arg_index"):])), " ")
trigger = "="
}
}
auto := m.Confm("auto", trigger)
if auto == nil {
return false, nil, nil, 0
}
cmd := []interface{}{kit.Select(kit.Format(auto["cmd"]), auto_cmd)}
if len(auto_arg) == 0 {
auto_arg = kit.Trans(auto["arg"])
}
for _, v := range auto_arg {
cmd = append(cmd, m.Parse(v))
}
table = []map[string]string{}
m.Spawn(auto_target).Cmd(cmd...).Table(func(line int, maps map[string]string) {
fields := []interface{}{}
for _, v := range auto["fields"].([]interface{}) {
fields = append(fields, maps[kit.Format(v)])
}
maps["format"] = fmt.Sprintf(kit.Format(auto["format"]), fields...)
table = append(table, maps)
})
m.Conf("term", []interface{}{"help_table", auto["table"]}, table)
frame = map[string]interface{}{
"color": auto["color"],
"table": auto["table"],
"field": auto["field"],
}
if m.Conf("term", []interface{}{"help_index"}, index); index == 0 {
m.Conf("term", "help_stack", []interface{}{frame})
} else {
m.Conf("term", []interface{}{"help_stack", -2}, frame)
}
m.Conf("term", "help_next_auto", auto["next_auto"])
m.Conf("term", "help_state", auto["state"])
return true, frame, table, index
}
func (nfs *NFS) Term(msg *ctx.Message, action string, args ...interface{}) *NFS {
m := nfs.Context.Message()
// m.Log("debug", "%s %v", action, args)
switch action {
case "exit":
if m.Caps("termbox") {
termbox.Close()
}
m.Caps("termbox", false)
return nfs
case "init":
defer func() {
if e := recover(); e != nil {
m.Log("warn", "term init %s", e)
}
}()
termbox.Init()
termbox.SetInputMode(termbox.InputEsc)
termbox.SetInputMode(termbox.InputMouse)
m.Cap("termbox", "true")
}
width, height := termbox.Size()
msg.Conf("term", "width", width)
msg.Conf("term", "height", height)
left := msg.Confi("term", "left")
top := msg.Confi("term", "top")
right := msg.Confi("term", "right")
bottom := msg.Confi("term", "bottom")
x := m.Confi("term", "cursor_x")
y := m.Confi("term", "cursor_y")
bg := termbox.Attribute(msg.Confi("term", "bgcolor"))
fg := termbox.Attribute(msg.Confi("term", "fgcolor"))
begin_row := m.Confi("term", "begin_row")
begin_col := m.Confi("term", "begin_col")
switch action {
case "init":
m.Conf("term", "left", 0)
m.Conf("term", "top", 0)
m.Conf("term", "right", width)
m.Conf("term", "bottom", height)
case "exit":
m.Cap("termbox", "false")
termbox.Close()
case "window":
if len(args) > 1 {
msg.Conf("term", "left", args[0])
msg.Conf("term", "top", args[1])
}
if len(args) > 3 {
msg.Conf("term", "right", args[2])
msg.Conf("term", "bottom", args[3])
} else {
msg.Conf("term", "right", width)
msg.Conf("term", "bottom", height)
}
case "resize":
if len(args) > 1 {
msg.Conf("term", "right", args[0])
msg.Conf("term", "bottom", args[1])
right = msg.Confi("term", "right")
bottom = msg.Confi("term", "bottom")
} else {
msg.Conf("term", "right", right)
msg.Conf("term", "bottom", bottom)
}
fallthrough
case "clear":
if len(args) == 0 {
top = m.Confi("term", "prompt_y")
} else if kit.Format(args[0]) == "all" {
// nothing
}
for x := left; x < right; x++ {
for y := top; y < bottom; y++ {
termbox.SetCell(x, y, ' ', fg, bg)
}
}
m.Conf("term", "cursor_x", left)
m.Conf("term", "cursor_y", top)
termbox.SetCursor(left, top)
case "cursor":
m.Conf("term", "cursor_x", kit.Format(args[0]))
m.Conf("term", "cursor_y", kit.Format(args[1]))
termbox.SetCursor(m.Confi("term", "cursor_x"), m.Confi("term", "cursor_y"))
case "flush":
termbox.Flush()
case "scroll":
n := 1
if len(args) > 0 {
n = kit.Int(args[0])
}
m.Options("on_scroll", true)
// 向下滚动
for i := begin_row; n > 0 && i < m.Capi("noutput"); i++ {
line := []rune(m.Conf("output", []interface{}{i, "line"}))
for j, l := begin_col, left; n > 0; j, l = j+1, l+1 {
if j >= len(line)-1 {
begin_row, begin_col = i+1, 0
n--
break
} else if line[j] == '\n' {
begin_row, begin_col = i, j+1
n--
} else if l >= right-1 && m.Confs("term", "wrap") {
begin_row, begin_col = i, j
n--
}
}
}
// 向上滚动
for i := begin_row; n < 0 && i >= 0; i-- {
line := []rune(m.Conf("output", []interface{}{i, "line"}))
if begin_col == 0 {
i--
line = []rune(m.Conf("output", []interface{}{i, "line"}))
begin_col = len(line)
}
for j, l := begin_col-1, right-1; n < 0; j, l = j-1, l-1 {
if j <= 0 {
begin_row, begin_col = i, 0
n++
break
} else if line[j-1] == '\n' {
begin_row, begin_col = i, j
n++
} else if l < left && m.Confs("term", "wrap") {
begin_row, begin_col = i, j
n++
}
}
}
m.Conf("term", "begin_row", begin_row)
m.Conf("term", "begin_col", begin_col)
fallthrough
case "refresh":
nfs.Term(m, "clear", "all")
for i := begin_row; i < m.Capi("noutput"); i++ {
if line := m.Conf("output", []interface{}{i, "line"}); begin_col < len(line) {
nfs.Term(m, "print", line[begin_col:])
}
begin_col = 0
}
// nfs.Term(m, "print", "\n")
// nfs.Term(m, "print", m.Conf("prompt"))
m.Options("on_scroll", false)
case "print":
list := kit.Format(args...)
n := strings.Count(list, "\n") + y - bottom
for _, v := range list {
if x < right {
if termbox.SetCell(x, y, v, fg, bg); v > 255 {
x++
}
}
if x++; v == '\n' || (x >= right && m.Confs("term", "wrap")) {
x, y = left, y+1
if y >= bottom {
if m.Options("on_scroll") {
break
}
if n%bottom > 0 {
nfs.Term(m, "scroll", n%bottom+1)
n -= n % bottom
x = m.Confi("term", "cursor_x")
y = m.Confi("term", "cursor_y")
} else if n > 0 {
nfs.Term(m, "scroll", bottom)
n -= bottom
x = m.Confi("term", "cursor_x")
y = m.Confi("term", "cursor_y")
}
}
}
if x < right {
m.Conf("term", "cursor_x", x)
m.Conf("term", "cursor_y", y)
termbox.SetCursor(x, y)
}
}
if m.Options("on_scroll") {
x = 0
y = y + 1
m.Conf("term", "cursor_x", x)
m.Conf("term", "cursor_y", y)
termbox.SetCursor(x, y)
}
case "color":
msg.Conf("term", "bgcolor", kit.Int(args[0])+1)
msg.Conf("term", "fgcolor", kit.Int(args[1])+1)
nfs.Term(m, "print", args[2:]...)
msg.Conf("term", "fgcolor", fg)
msg.Conf("term", "bgcolor", bg)
case "shadow":
x := m.Confi("term", "cursor_x")
y := m.Confi("term", "cursor_y")
nfs.Term(m, "color", args...)
nfs.Term(m, "cursor", x, y).Term(m, "flush")
}
return nfs
}
func (nfs *NFS) prompt(arg ...interface{}) *NFS {
m := nfs.Context.Message()
target, _ := m.Optionv("bio.ctx").(*ctx.Context)
if target == nil {
target = nfs.Context
}
line := fmt.Sprintf("%d[%s]%s> ", m.Capi("ninput"), time.Now().Format("15:04:05"), target.Name)
m.Conf("prompt", line)
line += kit.Format(arg...)
if m.Caps("termbox") {
m.Conf("term", "prompt_y", m.Conf("term", "cursor_y"))
nfs.Term(m, "clear").Term(m, "print", line).Term(m, "flush")
} else if nfs.out != nil {
nfs.out.WriteString(line)
}
return nfs
}
func (nfs *NFS) shadow(args ...interface{}) *NFS {
if len(args) == 0 {
return nfs
}
m := nfs.Context.Message()
x := m.Confi("term", "cursor_x")
y := m.Confi("term", "cursor_y")
defer func() { nfs.Term(m, "cursor", x, y).Term(m, "flush") }()
switch arg := args[0].(type) {
case []rune:
if len(args) == 1 {
nfs.Term(m, "color", m.Confi("term", "rest_bg"), m.Confi("term", "rest_fg"), string(arg))
} else {
cmd := strings.Split(string(arg), " ")
switch table := args[1].(type) {
case []map[string]string:
frame := args[2].(map[string]interface{})
field := kit.Format(frame["field"])
fg := kit.Int(frame["color"])
pick := kit.Int(kit.Select("0", args, 3))
i := 0
for _, line := range table {
if strings.Contains(kit.Format(line[field]), cmd[0]) {
if i == pick {
frame["pick"] = line[field]
nfs.Term(m, "color", m.Confi("term", "pick_bg"), m.Confi("term", "pick_fg"), "\n", kit.Format(line["format"]))
} else {
nfs.Term(m, "color", 0, fg, "\n", kit.Format(line["format"]))
}
i++
if i > 10 {
break
}
}
}
frame["lines"] = i
}
}
}
return nfs
}
func (nfs *NFS) print(arg ...string) *NFS {
m := nfs.Context.Message()
line := strings.TrimRight(strings.Join(arg, ""), "\n")
m.Log("debug", "noutput %s", m.Cap("noutput", m.Capi("noutput")+1))
m.Confv("output", -2, map[string]interface{}{"time": time.Now().Unix(), "line": line})
if m.Caps("termbox") {
nfs.Term(m, "clear").Term(m, "print", line).Term(m, "flush")
m.Conf("term", "prompt_y", m.Confi("term", "cursor_y")+1)
m.Conf("term", "cursor_y", m.Confi("term", "cursor_y")+1)
} else {
nfs.out.WriteString(line)
nfs.out.WriteString("\n")
}
return nfs
}
func (nfs *NFS) Show(arg ...interface{}) bool {
nfs.prompt(arg...)
return true
}

File diff suppressed because it is too large Load Diff

View File

@ -1,309 +0,0 @@
package tcp
import (
"contexts/ctx"
"toolkit"
"crypto/tls"
"fmt"
"io"
"net"
"strconv"
"strings"
"sync/atomic"
"time"
)
type TCP struct {
net.Conn
net.Listener
*ctx.Context
}
func (tcp *TCP) parse(m *ctx.Message, arg ...string) ([]string, []string, bool) {
defer func() {
if e := recover(); e != nil {
m.Log("warn", "%v", e)
}
}()
address := []string{}
if arg[1] == "dev" {
m.Cmd("web.get", arg[1], arg[2], "temp", "ports", "format", "object", "temp_expire", "10").Table(func(line map[string]string) {
address = append(address, line["value"])
})
if len(address) == 0 {
return nil, nil, false
}
for i := 2; i < len(arg)-1; i++ {
arg[i] = arg[i+1]
}
if len(arg) > 2 {
arg = arg[:len(arg)-1]
}
} else {
address = append(address, m.Cap("address", m.Confx("address", arg, 1)))
}
return address, arg, true
}
func (tcp *TCP) retry(m *ctx.Message, address []string, action func(address string) (net.Conn, error)) net.Conn {
var count int32
cs := make(chan net.Conn)
for i := 0; i < m.Confi("retry", "counts"); i++ {
for _, p := range address {
m.Gos(m.Spawn().Add("option", "address", p), func(msg *ctx.Message) {
m.Log("info", "dial: %v", msg.Option("address"))
if count >= 1 {
msg.Log("info", "skip: %v", msg.Option("address"))
} else if c, e := action(msg.Option("address")); e != nil {
msg.Log("info", "%s", e)
} else if atomic.AddInt32(&count, 1) > 1 {
msg.Log("info", "close: %s", c.LocalAddr())
c.Close()
} else {
cs <- c
}
})
}
select {
case c := <-cs:
return c
case <-time.After(kit.Duration(m.Conf("retry", "interval"))):
m.Log("info", "dial %s:%v timeout", m.Cap("protocol"), address)
}
}
return nil
}
func (tcp *TCP) Read(b []byte) (n int, e error) {
if m := tcp.Context.Message(); m.Assert(tcp.Conn != nil) {
if n, e = tcp.Conn.Read(b); e == io.EOF || m.Assert(e) {
m.Capi("nrecv", n)
}
}
return
}
func (tcp *TCP) Write(b []byte) (n int, e error) {
if m := tcp.Context.Message(); m.Assert(tcp.Conn != nil) {
if n, e = tcp.Conn.Write(b); e == io.EOF || m.Assert(e) {
m.Capi("nsend", n)
}
}
return
}
func (tcp *TCP) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server {
c.Caches = map[string]*ctx.Cache{
"protocol": &ctx.Cache{Name: "protocol(tcp/tcp4/tcp6)", Value: "", Help: "网络协议"},
"security": &ctx.Cache{Name: "security(true/false)", Value: "", Help: "加密通信"},
"address": &ctx.Cache{Name: "address", Value: "", Help: "网络地址"},
"nrecv": &ctx.Cache{Name: "nrecv", Value: "0", Help: "接收字节数"},
"nsend": &ctx.Cache{Name: "nsend", Value: "0", Help: "发送字节数"},
}
return &TCP{Context: c}
}
func (tcp *TCP) Begin(m *ctx.Message, arg ...string) ctx.Server {
return tcp
}
func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool {
address, arg, ok := tcp.parse(m, arg...)
if len(address) == 0 || !ok {
return true
}
m.Cap("security", m.Confx("security", arg, 2))
m.Cap("protocol", m.Confx("protocol", arg, 3))
switch arg[0] {
case "dial":
if m.Caps("security") {
cert, e := tls.LoadX509KeyPair(m.Cap("certfile"), m.Cap("keyfile"))
m.Assert(e)
conf := &tls.Config{Certificates: []tls.Certificate{cert}, InsecureSkipVerify: true}
tcp.Conn = tcp.retry(m, address, func(p string) (net.Conn, error) {
return tls.Dial(m.Cap("protocol"), p, conf)
})
} else {
tcp.Conn = tcp.retry(m, address, func(p string) (net.Conn, error) {
return net.DialTimeout(m.Cap("protocol"), p, kit.Duration(m.Conf("retry", "timeout")))
})
}
m.Log("info", "%s connect %s", m.Cap("nclient"),
m.Cap("stream", fmt.Sprintf("%s->%s", tcp.LocalAddr(), m.Cap("address", tcp.RemoteAddr().String()))))
m.Sess("tcp", m)
m.Option("ms_source", tcp.Context.Name)
m.Put("option", "io", tcp).Back()
return false
case "accept":
c, e := m.Optionv("io").(net.Conn)
m.Assert(e)
tcp.Conn = c
m.Log("info", "%s accept %s", m.Cap("nclient"),
m.Cap("stream", fmt.Sprintf("%s<-%s", tcp.LocalAddr(), tcp.RemoteAddr())))
m.Sess("tcp", m)
m.Option("ms_source", tcp.Context.Name)
m.Put("option", "io", tcp).Back()
return false
case "listen":
if m.Caps("security") {
m.Sess("aaa", m.Sess("aaa").Cmd("login", "cert", m.Cap("certfile"), "key", m.Cap("keyfile"), "tcp"))
cert, e := tls.LoadX509KeyPair(m.Cap("certfile"), m.Cap("keyfile"))
m.Assert(e)
conf := &tls.Config{Certificates: []tls.Certificate{cert}}
l, e := tls.Listen(m.Cap("protocol"), m.Cap("address"), conf)
m.Assert(e)
tcp.Listener = l
} else {
l, e := net.Listen(m.Cap("protocol"), m.Cap("address"))
m.Assert(e)
tcp.Listener = l
}
m.Log("info", "%d listen %v", m.Capi("nlisten"), m.Cap("stream", fmt.Sprintf("%s", tcp.Addr())))
addr := strings.Split(tcp.Addr().String(), ":")
ports := []interface{}{}
if m.Cmd("tcp.ifconfig").Table(func(line map[string]string) {
ports = append(ports, fmt.Sprintf("%s:%s", line["ip"], addr[len(addr)-1]))
}); len(ports) == 0 {
ports = append(ports, fmt.Sprintf("%s:%s", "127.0.0.1", addr[len(addr)-1]))
}
m.Back(m.Spawn(m.Source()).Put("option", "node.port", ports))
default:
return true
}
for {
if c, e := tcp.Accept(); m.Assert(e) {
m.Spawn(Index).Put("option", "io", c).Call(func(sub *ctx.Message) *ctx.Message {
return sub.Spawn(m.Source())
}, "accept", c.RemoteAddr().String(), m.Cap("security"), m.Cap("protocol"))
}
}
return true
}
func (tcp *TCP) Close(m *ctx.Message, arg ...string) bool {
switch tcp.Context {
case m.Target():
if tcp.Listener != nil {
m.Log("info", " close %v", m.Cap("stream"))
tcp.Listener.Close()
tcp.Listener = nil
}
if tcp.Conn != nil {
m.Log("info", " close %v", m.Cap("stream"))
tcp.Conn.Close()
tcp.Conn = nil
}
case m.Source():
}
return true
}
var Index = &ctx.Context{Name: "tcp", Help: "网络中心",
Caches: map[string]*ctx.Cache{
"nlisten": &ctx.Cache{Name: "nlisten", Value: "0", Help: "监听数量"},
"nclient": &ctx.Cache{Name: "nclient", Value: "0", Help: "连接数量"},
},
Configs: map[string]*ctx.Config{
"address": &ctx.Config{Name: "address", Value: ":9090", Help: "网络地址"},
"security": &ctx.Config{Name: "security(true/false)", Value: "false", Help: "加密通信"},
"protocol": &ctx.Config{Name: "protocol(tcp/tcp4/tcp6)", Value: "tcp4", Help: "网络协议"},
"retry": &ctx.Config{Name: "retry", Value: map[string]interface{}{
"interval": "3s", "counts": 3, "timeout": "10s",
}, Help: "网络重试"},
},
Commands: map[string]*ctx.Command{
"listen": &ctx.Command{Name: "listen address [security [protocol]]", Help: "网络监听", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Start(fmt.Sprintf("pub%d", m.Capi("nlisten", 1)), "网络监听", m.Meta["detail"]...)
return
}},
"accept": &ctx.Command{Name: "accept address [security [protocol]]", Help: "网络连接", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Start(fmt.Sprintf("sub%d", m.Capi("nclient", 1)), "网络连接", m.Meta["detail"]...)
return
}},
"dial": &ctx.Command{Name: "dial address [security [protocol]]", Help: "网络连接", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Start(fmt.Sprintf("com%d", m.Capi("nclient", 1)), "网络连接", m.Meta["detail"]...)
return
}},
"send": &ctx.Command{Name: "send message", Help: "发送消息", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if tcp, ok := m.Target().Server.(*TCP); m.Assert(ok) {
fmt.Fprint(tcp, arg[0])
}
return
}},
"recv": &ctx.Command{Name: "recv size", Help: "接收消息", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if tcp, ok := m.Target().Server.(*TCP); m.Assert(ok) {
if n, e := strconv.Atoi(arg[0]); m.Assert(e) {
buf := make([]byte, n)
n, _ = tcp.Read(buf)
m.Echo(string(buf[:n]))
}
}
return
}},
"ifconfig": &ctx.Command{Name: "ifconfig [name]", Help: "网络配置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if ifs, e := net.Interfaces(); m.Assert(e) {
for _, v := range ifs {
if len(arg) > 0 && !strings.Contains(v.Name, arg[0]) {
continue
}
if ips, e := v.Addrs(); m.Assert(e) {
for _, x := range ips {
ip := strings.Split(x.String(), "/")
if strings.Contains(ip[0], ":") || len(ip) == 0 {
continue
}
if len(v.HardwareAddr.String()) == 0 {
continue
}
m.Push("index", v.Index)
m.Push("name", v.Name)
m.Push("ip", ip[0])
m.Push("mask", ip[1])
m.Push("hard", v.HardwareAddr.String())
}
}
}
m.Table()
}
return
}},
"probe": &ctx.Command{Name: "probe [port]", Help: "端口检测", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) == 0 {
for i := 0; i < 1024; i++ {
m.Show("port: %v", i)
if t, e := net.DialTimeout("tcp", fmt.Sprintf(":%d", i), 3*time.Second); e == nil {
m.Push("port", i)
t.Close()
}
}
m.Table()
return
}
if t, e := net.DialTimeout("tcp", arg[0], 10*time.Second); e == nil {
m.Echo("active")
t.Close()
}
return
}},
},
}
func init() {
ctx.Index.Register(Index, &TCP{Context: Index})
}

View File

@ -1,56 +0,0 @@
package web
import (
// "github.com/PuerkitoBio/goquery"
)
func parseHTML() {
/*
page, e := goquery.NewDocumentFromReader(res.Body)
m.Assert(e)
page.Find(kit.Select("html", m.Option("parse_chain"))).Each(func(n int, s *goquery.Selection) {
if m.Options("parse_select") {
for i := 0; i < len(m.Meta["parse_select"])-2; i += 3 {
item := s.Find(m.Meta["parse_select"][i+1])
if m.Meta["parse_select"][i+1] == "" {
item = s
}
if v, ok := item.Attr(m.Meta["parse_select"][i+2]); ok {
m.Add("append", m.Meta["parse_select"][i], v)
m.Log("info", "item attr %v", v)
} else {
m.Add("append", m.Meta["parse_select"][i], strings.Replace(item.Text(), "\n", "", -1))
m.Log("info", "item text %v", item.Text())
}
}
return
}
s.Find("a").Each(func(n int, s *goquery.Selection) {
if attr, ok := s.Attr("href"); ok {
s.SetAttr("href", proxy(m, attr))
}
})
s.Find("img").Each(func(n int, s *goquery.Selection) {
if attr, ok := s.Attr("src"); ok {
s.SetAttr("src", proxy(m, attr))
}
if attr, ok := s.Attr("r-lazyload"); ok {
s.SetAttr("src", proxy(m, attr))
}
})
s.Find("script").Each(func(n int, s *goquery.Selection) {
if attr, ok := s.Attr("src"); ok {
s.SetAttr("src", proxy(m, attr))
}
})
if html, e := s.Html(); e == nil {
m.Add("append", "html", html)
}
})
m.Table()
*/
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,617 +0,0 @@
package chat
import (
"contexts/ctx"
"contexts/web"
mis "github.com/shylinux/toolkits"
"fmt"
"net/http"
"os"
"path"
"strings"
"toolkit"
)
func check(m *ctx.Message, arg []string) ([]string, string, bool) {
if !m.Options("sessid") || !m.Options("username") {
return nil, "", false
}
rid := m.Option("river")
if len(arg[0]) != 32 {
arg[0] = m.Cmdx("aaa.short", arg[0])
}
if m.Confs("flow", arg[0]) {
rid, arg = arg[0], arg[1:]
}
if rid != "" && len(rid) != 32 {
rid = m.Cmdx("aaa.short", rid)
}
return arg, rid, true
}
var Index = &ctx.Context{Name: "chat", Help: "会议中心",
Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{
"login": &ctx.Config{Name: "login", Value: map[string]interface{}{"check": false, "local": true, "expire": "720h"}, Help: "用户登录"},
"componet": &ctx.Config{Name: "componet", Value: map[string]interface{}{
"index": []interface{}{
map[string]interface{}{"name": "head",
"tmpl": "head", "metas": []interface{}{map[string]interface{}{
"name": "viewport", "content": "width=device-width, initial-scale=0.7, user-scalable=no",
}}, "favicon": "favicon.ico", "styles": []interface{}{
// "example.css", "chat.css",
"can_style.css",
}},
map[string]interface{}{"name": "toast",
"tmpl": "fieldset", "view": "Toast dialog", "init": "initToast",
},
map[string]interface{}{"name": "carte",
"tmpl": "fieldset", "view": "Carte dialog", "init": "initCarte",
},
map[string]interface{}{"name": "debug",
"tmpl": "fieldset", "view": "Debug dialog", "init": "initDebug",
},
map[string]interface{}{"name": "favor",
"tmpl": "fieldset", "view": "Favor dialog", "init": "initFavor",
"ctx": "web.chat", "cmd": "favor",
},
map[string]interface{}{"name": "tutor",
"tmpl": "fieldset", "view": "Tutor dialog", "init": "initTutor",
"ctx": "web.chat", "cmd": "tutor",
},
map[string]interface{}{"name": "login",
"tmpl": "fieldset", "view": "Login dialog", "init": "initLogin",
"ctx": "web.chat", "cmd": "login",
},
map[string]interface{}{"name": "header",
"tmpl": "fieldset", "view": "Header", "init": "initHeader",
"ctx": "web.chat", "cmd": "login",
},
map[string]interface{}{"name": "ocean",
"tmpl": "fieldset", "view": "Ocean dialog", "init": "initOcean",
"ctx": "web.chat", "cmd": "ocean",
},
map[string]interface{}{"name": "steam",
"tmpl": "fieldset", "view": "Steam dialog", "init": "initSteam",
"ctx": "web.chat", "cmd": "steam",
},
map[string]interface{}{"name": "river",
"tmpl": "fieldset", "view": "River", "init": "initRiver",
"ctx": "web.chat", "cmd": "river",
},
map[string]interface{}{"name": "storm",
"tmpl": "fieldset", "view": "Storm", "init": "initStorm",
"ctx": "web.chat", "cmd": "storm",
},
map[string]interface{}{"name": "target",
"tmpl": "fieldset", "view": "Target", "init": "initTarget",
"ctx": "web.chat", "cmd": "river",
},
map[string]interface{}{"name": "source",
"tmpl": "fieldset", "view": "Source", "init": "initSource",
"ctx": "web.chat", "cmd": "storm",
},
map[string]interface{}{"name": "action",
"tmpl": "fieldset", "view": "Action", "init": "initAction",
"ctx": "web.chat", "cmd": "storm",
},
map[string]interface{}{"name": "footer",
"tmpl": "fieldset", "view": "Footer", "init": "initFooter",
"ctx": "web.chat", "cmd": "login",
},
map[string]interface{}{"name": "tail",
"tmpl": "tail", "scripts": []interface{}{
// "toolkit.js", "context.js", "example.js", "chat.js",
"can_proto.js", "can_order.js", "can_frame.js",
},
},
},
}, Help: "组件列表"},
"share": &ctx.Config{Name: "share", Value: map[string]interface{}{
"meta": map[string]interface{}{
"fields": "id time share type code remote_ip",
"store": "var/tmp/share.csv",
"limit": 30, "least": 10,
},
"hash": map[string]interface{}{},
"list": []interface{}{},
}, Help: "共享链接"},
},
Commands: map[string]*ctx.Command{
"login": &ctx.Command{Name: "login [username password]", Help: "登录", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) > 0 {
switch arg[0] {
case "weixin":
if msg := m.Find("cli.weixin", true); msg != nil {
msg.Cmd("js_token")
m.Copy(msg, "append")
m.Append("remote_ip", m.Option("remote_ip"))
m.Append("nickname", kit.Select(m.Option("username"), m.Option("nickname")))
m.Table()
}
return
}
}
// 非登录态
if !m.Options("sessid") || !m.Options("username") {
if len(arg) > 0 {
// 用户登录
if m.Cmds("ssh.work", "share", arg[0]) {
if m.Cmds("aaa.auth", "username", arg[0], "password", arg[1]) {
m.Option("username", arg[0])
m.Option("sessid", m.Cmdx("aaa.user", "session", "select"))
if !m.Cmds("aaa.auth", "username", arg[0], "data", "chat.default") && m.Option("username") != m.Conf("runtime", "work.name") {
m.Cmd("aaa.auth", "username", arg[0], "data", "chat.default",
m.Cmdx(".ocean", "spawn", "", m.Option("username")+"@"+m.Conf("runtime", "work.name"), m.Option("username")))
}
r := m.Optionv("request").(*http.Request)
w := m.Optionv("response").(http.ResponseWriter)
web.Cookie(m, w, r)
m.Echo(m.Option("sessid"))
}
}
}
return
}
if len(arg) > 0 {
switch arg[0] {
case "share":
m.Append("qrcode", arg[1])
return
case "relay":
relay := m.Cmdx("aaa.relay", "share", arg[1:])
m.Log("info", "relay: %s", relay)
m.Echo(m.Cmdx("aaa.short", relay))
return
case "rename":
m.Cmd("aaa.auth", "username", m.Option("username"), "data", "nickname", arg[1])
}
}
// if m.Log("info", "nickname: %s", m.Option("nickname", m.Cmdx("aaa.auth", "username", m.Option("username"), "data", "nickname"))); !m.Options("nickname") {
// m.Option("nickname", m.Option("username"))
// }
m.Append("remote_ip", m.Option("remote_ip"))
m.Append("nickname", kit.Select(m.Option("username"), m.Option("nickname")))
m.Echo(m.Option("username"))
return
}},
"ocean": &ctx.Command{Name: "ocean [search [name]]|[spawn hash name user...]", Help: "海洋, search [name]: 搜索员工, spawn hash name user...: 创建群聊", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
// 登录失败
if !m.Options("sessid") || !m.Options("username") {
return
}
if len(arg) == 0 {
arg = append(arg, "search")
}
switch arg[0] {
// 搜索员工
case "search":
m.Cmdy("ssh.work", "search")
// 创建群聊
case "spawn":
// 用户列表
user := map[string]interface{}{}
if len(arg) > 3 {
arg = append(arg, m.Option("username"))
arg = append(arg, m.Conf("runtime", "work.name"))
for _, v := range arg[3:] {
if p := m.Cmdx("ssh._route", m.Conf("runtime", "work.route"), "_check", "work", v); p != "" {
user[v] = map[string]interface{}{"user": p}
}
}
}
// 添加群聊
h := kit.Select(kit.Hashs("uniq"), arg, 1)
m.Conf("flow", h, map[string]interface{}{
"conf": map[string]interface{}{
"create_user": m.Option("username"),
"create_time": m.Time(),
"update_time": m.Time(),
"nick": kit.Select("what", arg, 2),
"route": kit.Select(m.Conf("runtime", "node.route"), m.Option("node.route"), arg[1] != ""),
},
"user": user,
"tool": map[string]interface{}{},
"text": map[string]interface{}{},
})
if m.Echo(h); arg[1] != "" {
return
}
m.Cmdx(".steam", h, "spawn", "index")
// 分发群聊
m.Confm("flow", []string{h, "user"}, func(key string, value map[string]interface{}) {
if kit.Right(value["user"]) && kit.Format(value["user"]) != m.Conf("runtime", "node.route") {
m.Cmd("ssh._route", value["user"], "context", "chat", "ocean", "spawn", h, arg[2])
}
})
}
return
}},
"river": &ctx.Command{Name: "river hash [brow begin]|[flow type text [index]]|[wave route group index args...]", Help: "河流", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
// 登录失败
if !m.Options("sessid") || !m.Options("username") {
return
}
// 自动入群
if m.Options("river") {
if m.Short("river"); m.Confs("flow", m.Option("river")) && !m.Confs("flow", []string{m.Option("river"), "user", m.Option("username")}) {
u := m.Cmdx("ssh._route", m.Conf("runtime", "work.route"), "_check", "work", m.Option("username"))
m.Conf("flow", []string{m.Option("river"), "user", m.Option("username"), "user"}, u)
}
}
// 群聊列表
if len(arg) == 0 {
m.Confm("flow", func(key string, value map[string]interface{}) {
if kit.Chain(value, []string{"user", m.Option("username")}) == nil {
return
}
m.Push("key", m.Cmdx("aaa.short", key))
m.Push("nick", kit.Chains(value, "conf.nick"))
m.Push("create_user", kit.Chains(value, "conf.create_user"))
m.Push("create_time", kit.Chains(value, "conf.create_time"))
m.Push("update_time", kit.Chains(value, "conf.update_time"))
if list, ok := kit.Chain(value, "text.list").([]interface{}); ok {
m.Push("count", len(list))
} else {
m.Push("count", 0)
}
})
if !m.Appends("key") {
m.Cmd(".ocean", "spawn", "", "hello", m.Option("username"))
m.Cmdy(".river")
return
}
m.Sort("name").Sort("update_time", "time_r").Table()
return
}
// 登录失败
arg, rid, ok := check(m, arg)
if !ok {
return
}
switch arg[0] {
// 消息列表
case "brow":
begin := kit.Int(kit.Select("0", arg, 1))
m.Confm("flow", []string{rid, "text.list"}, func(index int, value map[string]interface{}) {
if index < begin {
return
}
m.Push("index", index)
m.Push("type", value["type"])
m.Push("text", value["text"])
m.Push("create_time", value["create_time"])
m.Push("create_user", value["create_user"])
m.Push("create_nick", value["create_nick"])
})
m.Table()
return
// 推送消息
case "flow":
up := m.Conf("flow", []string{rid, "conf.route"})
// 上传消息
if len(arg) == 3 && up != m.Conf("runtime", "node.route") {
m.Cmdy("ssh._route", up, "context", "chat", "river", rid, "flow", arg[1], arg[2])
return
}
// 保存消息
m.Conf("flow", []string{rid, "text.list.-2"}, map[string]interface{}{
"create_nick": m.Option("nickname"),
"create_user": m.Option("username"),
"create_time": m.Time(),
"type": arg[1],
"text": arg[2],
})
m.Conf("flow", []string{rid, "conf.update_time"}, m.Time())
count := m.Confi("flow", []string{rid, "text.count"}) + 1
m.Confi("flow", []string{rid, "text.count"}, count)
m.Append("create_user", m.Option("username"))
m.Echo("%d", count)
// 分发消息
if up == m.Conf("runtime", "node.route") {
m.Confm("flow", []string{rid, "user"}, func(key string, value map[string]interface{}) {
if kit.Right(value["user"]) && kit.Format(value["user"]) != m.Conf("runtime", "node.route") {
m.Cmd("ssh._route", value["user"], "context", "chat", "river", rid, "flow", arg[1], arg[2], count, "sync")
}
})
}
// 推送命令
case "wave":
m.Cmdy("ssh._route", arg[1], "tool", "run", arg[2], arg[3], rid, arg[4:])
}
return
}},
"storm": &ctx.Command{Name: "storm rid [[delete] group [index [arg...]]]", Help: "风雨", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
// 登录失败
if len(arg[0]) != 32 {
arg[0] = m.Cmdx("aaa.short", arg[0])
}
rid, arg := arg[0], arg[1:]
m.Option("river", rid)
// 命令列表
if len(arg) == 0 {
m.Confm("flow", []string{rid, "tool"}, func(key string, value map[string]interface{}) {
m.Push("key", key)
m.Push("count", len(value["list"].([]interface{})))
m.Push("status", kit.Format(value["status"]))
})
m.Sort("key").Table()
return
}
switch arg[0] {
// 删除命令
case "delete":
str := m.Conf("flow", []string{rid, "tool", arg[1]})
m.Log("info", "delete %v %v %v", rid, arg[1], str)
m.Conf("flow", []string{rid, "tool", arg[1]}, "")
m.Echo(str)
case "clone":
args := []string{}
m.Confm("flow", []string{rid, "tool", arg[2], "list"}, func(index int, value map[string]interface{}) {
args = append(args, kit.Format(value["node"]), kit.Format(value["group"]), kit.Format(value["index"]), kit.Format(value["name"]))
})
m.Cmdy(".steam", rid, "spawn", arg[1], args)
arg[2] = m.Conf("flow", []string{rid, "tool", arg[2], "status"})
fallthrough
case "save":
if arg[2] != "" {
m.Cmdy("ssh._route", arg[2], "web.chat.storm", rid, arg[:2], "", arg[3:])
break
}
if m.Confv("flow", []string{rid, "tool", arg[1], "status"}, arg[3]); kit.Select("", arg, 4) != "" {
m.Confv("flow", []string{rid, "tool", arg[1], "list"}, kit.UnMarshal(arg[4]))
}
case "load":
if len(arg) > 2 {
m.Cmdy("ssh._route", arg[2], "web.chat.storm", rid, arg[:2])
break
}
m.Confm("flow", []string{rid, "tool", arg[1]}, func(value map[string]interface{}) {
m.Append("status", kit.Format(value["status"]))
m.Append("list", kit.Format(value["list"]))
})
default:
// 命令列表
m.Set("option", "name")
m.Set("option", "init")
m.Set("option", "view")
if len(arg) == 1 {
list := m.Confv("flow", []string{rid, "tool", arg[0], "list"})
if m.Option("you") != "" {
if msg := m.Cmd("ssh._route", m.Option("you"), "web.chat.storm", rid, "load", arg[0]); msg.Appends("list") {
list = kit.UnMarshal(msg.Append("list"))
}
}
short := m.Cmdx("aaa.short", rid)
kit.Map(list, "", func(index int, tool map[string]interface{}) {
m.Push("river", short)
m.Push("storm", arg[0])
m.Push("action", index)
m.Push("node", tool["node"])
m.Push("group", tool["group"])
m.Push("index", tool["index"])
msg := m.Cmd("ssh._route", tool["node"], "tool", tool["group"], tool["index"])
m.Push("name", msg.Append("name"))
m.Push("help", msg.Append("help"))
m.Push("view", msg.Append("view"))
m.Push("init", msg.Append("init"))
m.Push("inputs", msg.Append("inputs"))
m.Push("exports", msg.Append("exports"))
m.Push("display", msg.Append("display"))
m.Push("feature", msg.Append("feature"))
})
m.Table()
break
}
// 推送命令
if tool := m.Confm("flow", []string{rid, "tool", arg[0], "list", arg[1]}); tool != nil {
m.Cmdy("ssh._route", tool["node"], "tool", "run", tool["group"], tool["index"], rid, arg[2:])
}
}
return
}},
"steam": &ctx.Command{Name: "steam rid [user node]|[spawn name [route group index name]...]", Help: "天空", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
// 登录失败
arg, rid, ok := check(m, arg)
if !ok {
return
}
// 上传请求
if up := m.Conf("flow", []string{rid, "conf.route"}); up != m.Conf("runtime", "node.route") {
m.Cmdy("ssh._remote", up, "context", "chat", "steam", rid, arg)
return
}
// 设备列表
if len(arg) == 0 {
m.Confm("flow", []string{rid, "user"}, func(key string, value map[string]interface{}) {
m.Push("user", key)
m.Push("node", value["user"])
})
m.Confm("ssh.node", func(key string, value map[string]interface{}) {
m.Push("user", value["type"])
m.Push("node", value["name"])
})
m.Table()
return
}
switch arg[0] {
// 创建命令
case "spawn":
if len(arg) == 2 {
self := m.Conf("runtime", "node.route")
m.Confm("ssh.componet", arg[1], func(index int, value map[string]interface{}) {
arg = append(arg, self, arg[1], kit.Format(index), kit.Format(value["name"]))
})
}
list := []interface{}{}
for i := 2; i < len(arg)-3; i += 4 {
list = append(list, map[string]interface{}{
"node": arg[i], "group": arg[i+1], "index": arg[i+2], "name": arg[i+3],
})
}
m.Conf("flow", []string{rid, "tool", arg[1]}, map[string]interface{}{
"create_user": m.Option("username"),
"create_time": m.Time(),
"list": list,
})
// 命令列表
default:
m.Cmdy("ssh._route", arg[1], "tool")
}
return
}},
"favor": &ctx.Command{Name: "favor", Help: "命令", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Cmdy(arg)
return
}},
"tutor": &ctx.Command{Name: "tutor", Help: "向导", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Cmdy(arg)
return
}},
"/share/": &ctx.Command{Name: "/share/", Help: "共享链接", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
h := strings.TrimPrefix(key, "/share/")
m.Confm("share", []string{"hash", h}, func(value map[string]interface{}) {
switch kit.Format(value["type"]) {
case "file":
// 下载文件
m.Cmdy("/download/" + h)
case "wiki":
// 查看文档
p := path.Join(path.Join("var/share", h))
if !m.Options("force") {
if _, e := os.Stat(p); e == nil {
// 读取缓存
m.Log("info", "read cache %v", p)
r := m.Optionv("request").(*http.Request)
w := m.Optionv("response").(http.ResponseWriter)
http.ServeFile(w, r, p)
break
}
}
m.Option("title", fmt.Sprintf("%v:%v", value["dream"], value["code"]))
m.Option("favicon", "favicon.ico")
// 生成模板
m.Echo(ctx.Execute(m, "share.tmpl"))
// 生成文档
m.Cmdy("ssh._route", value["dream"], "web.wiki.note", value["code"])
if f, _, e := kit.Create(p); e == nil {
defer f.Close()
for _, v := range m.Meta["result"] {
f.WriteString(v)
}
}
}
// 访问记录
m.Grow("share", nil, map[string]interface{}{
"time": m.Time(),
"share": h,
"type": value["type"],
"code": value["code"],
"sid": m.Option("sid"),
"agent": m.Option("agent"),
"sessid": m.Option("sessid"),
"username": m.Option("username"),
"remote_ip": m.Option("remote_ip"),
})
})
return
}},
"share": &ctx.Command{Name: "share type code", Help: "共享链接", Hand: func(m *ctx.Message, c *ctx.Context, cmd string, arg ...string) (e error) {
if len(arg) > 2 {
switch arg[1] {
case "delete":
// 删除共享
switch arg[2] {
case "key":
m.Log("info", "delete share %v %v", arg[3], mis.Formats(m.Conf("share", "hash."+arg[3])))
m.Conf("share", "hash."+arg[3], "")
}
return
}
}
if len(arg) < 2 {
// 共享列表
m.Confm("share", "hash", func(key string, value map[string]interface{}) {
m.Push("key", key)
m.Push("time", value["time"])
m.Push("type", value["type"])
m.Push("code", value["code"])
m.Push("dream", value["dream"])
m.Push("link", fmt.Sprintf("%s/chat/share/%s", m.Cmdx(".spide", "self", "client", "url"), key))
})
m.Sort("time", "time_r")
return
}
// 共享链接
h := kit.ShortKey(m.Confm(cmd, "hash"), 6)
m.Confv(cmd, []string{"hash", h}, map[string]interface{}{
"from": m.Option("username"),
"time": m.Time(),
"type": arg[0],
"code": arg[1],
"dream": m.Option("you"),
})
m.Echo("%s/chat/share/%s", m.Cmdx(".spide", "self", "client", "url"), h)
return
}},
},
}
func init() {
web.Index.Register(Index, &web.WEB{Context: Index})
}

View File

@ -1,358 +0,0 @@
package chat
import (
"contexts/ctx"
"contexts/web"
"examples/chat"
"toolkit"
"encoding/json"
"net/http"
"strings"
"time"
)
func get(m *ctx.Message, arg ...string) *ctx.Message {
m.Option("temp_expire", -1)
m.Option("format", "object")
m.Cmdy("web.get", "feishu", arg, "temp", "data")
return m
}
func post(m *ctx.Message, arg ...string) *ctx.Message {
m.Option("temp_expire", -1)
m.Option("format", "object")
m.Cmdy("web.get", "method", "POST", "feishu", arg,
"content_type", "application/json",
"temp", "data",
)
return m
}
func parse(m *ctx.Message) {
data := m.Optionv("content_data")
if data == nil {
json.NewDecoder(m.Optionv("request").(*http.Request).Body).Decode(&data)
m.Optionv("content_data", data)
switch d := data.(type) {
case map[string]interface{}:
for k, v := range d {
switch d := v.(type) {
case map[string]interface{}:
for k, v := range d {
m.Add("option", k, v)
}
default:
for _, v := range kit.Trans(v) {
m.Add("option", "msg."+k, v)
}
}
}
}
}
if kit.Map(kit.Chain(data, "action.value"), "", func(key string, value string) {
m.Add("option", key, value)
}) != nil {
m.Option("msg.type", "event_click")
}
m.Log("info", "msg: %v", kit.Formats(data))
}
var Index = &ctx.Context{Name: "feishu", Help: "飞书",
Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{
"app": &ctx.Config{Name: "app", Value: map[string]interface{}{}, Help: "服务配置"},
"user": &ctx.Config{Name: "user", Value: map[string]interface{}{}, Help: "服务配置"},
},
Commands: map[string]*ctx.Command{
"app": &ctx.Command{Name: "app login|token bot", Help: "应用", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) == 0 {
m.Confm("app", func(key string, value map[string]interface{}) {
m.Push("key", key)
m.Push("id", value["id"])
})
m.Table()
return
}
switch arg[0] {
case "login":
m.Confv("app", arg[1], map[string]interface{}{"id": arg[2], "mm": arg[3]})
case "token":
if now := time.Now().Unix(); !m.Confs("app", []string{arg[1], "token"}) || int64(m.Confi("app", []string{arg[1], "expire"})) < now {
post(m, "auth/v3/tenant_access_token/internal/", "app_id", m.Conf("app", []string{arg[1], "id"}),
"app_secret", m.Conf("app", []string{arg[1], "mm"}))
m.Conf("app", []string{arg[1], "token"}, m.Append("tenant_access_token"))
m.Conf("app", []string{arg[1], "expire"}, int64(m.Appendi("expire"))+now)
m.Set("result")
}
m.Echo(m.Conf("app", []string{arg[1], "token"}))
}
return
}},
"ship": &ctx.Command{Name: "ship", Help: "组织", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
data := kit.UnMarshal(m.Cmdx("web.get", "feishu", "contact/v1/scope/get/",
"headers", "Authorization", "Bearer "+m.Cmdx(".app", "token", "bot"),
))
kit.Map(kit.Chain(data, "data.authed_departments"), "", func(index int, value string) {
m.Push("type", "ship")
m.Push("value", value)
})
kit.Map(kit.Chain(data, "data.authed_open_ids"), "", func(index int, value string) {
m.Push("type", "user")
m.Push("value", value)
})
m.Table()
return
}},
"group": &ctx.Command{Name: "group", Help: "群组", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) == 0 {
kit.Map(kit.Chain(kit.UnMarshal(m.Cmdx("web.get", "feishu", "chat/v4/list", "headers", "Authorization", "Bearer "+m.Cmdx(".app", "token", "bot"))),
"data.groups"), "", func(index int, value map[string]interface{}) {
m.Push("key", value["chat_id"])
m.Push("name", value["name"])
m.Push("avatar", value["avatar"])
})
m.Table()
}
kit.Map(kit.Chain(kit.UnMarshal(m.Cmdx("web.get", "feishu", "chat/v4/info", "headers", "Authorization", "Bearer "+m.Cmdx(".app", "token", "bot"))),
"data.members"), "", func(index int, value map[string]interface{}) {
m.Push("key", value["open_id"])
})
m.Table()
return
}},
"user": &ctx.Command{Name: "user code|email|mobile", Help: "用户", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
switch arg[0] {
case "code":
post(m, "/connect/qrconnect/oauth2/access_token/",
"app_secret", m.Conf("app", []string{"bot", "mm"}), "app_id", m.Conf("app", []string{"bot", "id"}),
"grant_type", "authorization_code", "code", arg[1],
)
msg := get(m.Spawn(), "/connect/qrconnect/oauth2/user_info/",
"headers", "Authorization", "Bearer "+m.Append("access_token"),
)
m.Confv("user", m.Append("open_id"), map[string]interface{}{
"name": m.Append("name"),
"en_name": m.Append("en_name"),
"avatar_url": m.Append("avatar_url"),
"access_token": m.Append("access_token"),
"token_type": m.Append("token_type"),
"expire": int64(m.Appendi("expire")) + time.Now().Unix(),
"refresh_token": m.Append("refresh_token"),
"tenant_key": m.Append("tenant_key"),
"email": msg.Append("Email"),
"mobile": msg.Append("Mobile"),
"status": msg.Append("status"),
"employee": msg.Append("EmployeeID"),
})
default:
us := []string{}
ps := []string{}
for i := 0; i < len(arg); i++ {
us = append(us, kit.Select("mobiles", "emails", strings.Contains(arg[i], "@")), arg[i])
ps = append(ps, kit.Select("mobile", "email", strings.Contains(arg[i], "@"))+"_users")
}
data := kit.UnMarshal(m.Cmdx("web.get", "feishu", "user/v1/batch_get_id", us,
"headers", "Authorization", "Bearer "+m.Cmdx(".app", "token", "bot")))
for i, v := range ps {
m.Append(arg[i], kit.Chain(data, []string{"data", v, arg[i], "0", "open_id"}))
}
m.Table()
}
return
}},
"send": &ctx.Command{Name: "send [chat_id|open_id|user_id|email] who [menu] [title] text", Help: "消息", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
var form = map[string]interface{}{"content": map[string]interface{}{}}
switch arg[0] {
case "chat_id", "open_id", "user_id", "email":
form[arg[0]], arg = arg[1], arg[2:]
default:
form["chat_id"], arg = arg[0], arg[1:]
}
switch arg[0] {
case "menu":
elements := []interface{}{}
elements = append(elements, map[string]interface{}{
"tag": "div",
"text": map[string]interface{}{
"tag": "plain_text",
"content": arg[2],
},
})
actions := []interface{}{}
for i := 3; i < len(arg); i++ {
button := map[string]interface{}{
"tag": "button", "text": map[string]interface{}{
"tag": "plain_text", "content": arg[i],
},
"type": "default",
}
switch arg[i+1] {
case "confirm":
button[arg[i+1]], i = map[string]interface{}{
"title": map[string]interface{}{"tag": "lark_md", "content": arg[i+2]},
"text": map[string]interface{}{"tag": "lark_md", "content": arg[i+3]},
}, i+3
case "value":
button[arg[i+1]], i = map[string]interface{}{
arg[i+2]: arg[i+3],
}, i+3
case "url":
button[arg[i+1]], i = arg[i+2], i+2
default:
button["value"], i = map[string]interface{}{
arg[i+1]: arg[i+2],
}, i+2
}
actions = append(actions, button)
}
elements = append(elements, map[string]interface{}{
"tag": "action", "actions": actions,
})
kit.Chain(form, "msg_type", "interactive")
kit.Chain(form, "card", map[string]interface{}{
"config": map[string]interface{}{
"wide_screen_mode": true,
// "title": map[string]interface{}{
// "tag": "lark_md", "content": arg[1],
// },
},
"header": map[string]interface{}{
"title": map[string]interface{}{
"tag": "lark_md", "content": arg[1],
},
},
"elements": elements,
})
default:
switch len(arg) {
case 0:
case 1:
kit.Chain(form, "msg_type", "text")
kit.Chain(form, "content.text", arg[0])
default:
content := []interface{}{}
line := []interface{}{}
for _, v := range arg[1:] {
if v == "\n" {
content, line = append(content, line), []interface{}{}
continue
}
line = append(line, map[string]interface{}{
"tag": "text", "text": v,
})
}
content = append(content, line)
kit.Chain(form, "msg_type", "post")
kit.Chain(form, "content.post", map[string]interface{}{
"zh_cn": map[string]interface{}{
"title": arg[0],
"content": content,
},
})
}
}
m.Cmdy("web.get", "method", "POST", "feishu", "message/v4/send/",
"headers", "Authorization", "Bearer "+m.Cmdx(".app", "token", "bot"),
"content_data", kit.Formats(form), "content_type", "application/json",
"temp", "data", "data.message_id",
)
return
}},
"/msg": &ctx.Command{Name: "/msg", Help: "消息", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
parse(m)
switch m.Option("msg.type") {
case "url_verification":
m.Echo(kit.Format(map[string]interface{}{"challenge": m.Option("challenge")}))
case "event_callback":
switch m.Option("type") {
case "chat_disband":
case "p2p_chat_create":
if m.Options("open_chat_id") {
m.Cmdy(".send", m.Option("open_chat_id"), "我们做朋友吧~")
}
case "add_bot":
if m.Options("open_chat_id") {
m.Cmdy(".send", m.Option("open_chat_id"), "我来也~")
}
default:
if m.Options("open_chat_id") {
m.Option("username", m.Option("open_id"))
m.Option("sessid", m.Cmdx("aaa.user", "session", "select"))
m.Cmd("ssh._check", "work", "create", m.Option("username"))
m.Goshy([]string{m.Option("text_without_at_bot")}, 0, nil, func(msg *ctx.Message) {
m.Cmdy(".send", m.Option("open_chat_id"), kit.Select("你好", strings.Join(msg.Meta["result"], "")))
})
}
}
case "event_click":
m.Echo(kit.Format(map[string]interface{}{
"header": map[string]interface{}{
"title": map[string]interface{}{
"tag": "lark_md", "content": "haha",
},
},
"elements": []interface{}{
map[string]interface{}{
"tag": "action",
"actions": []interface{}{
map[string]interface{}{
"tag": "button",
"type": "default",
"text": map[string]interface{}{
"tag": "plain_text",
"content": m.Time(),
},
"value": map[string]interface{}{
"hi": "hello",
},
},
},
},
},
}))
}
return
}},
"/sso": &ctx.Command{Name: "/sso", Help: "消息", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if m.Options("code") {
m.Option("username", m.Cmd(".user", "code", m.Option("code")).Append("open_id"))
m.Option("sessid", m.Cmdx("aaa.user", "session", "select"))
m.Cmd("ssh._check", "work", "create", m.Option("username"))
w := m.Optionv("response").(http.ResponseWriter)
r := m.Optionv("request").(*http.Request)
web.Cookie(m, w, r)
m.Append("redirect", m.Cmdx("web.spide", "serve", "merge", m.Option("index_path")), "code", "")
return
}
if !m.Options("sessid") || !m.Options("username") {
m.Append("redirect", m.Cmdx("web.spide", "feishu", "merge", "/connect/qrconnect/page/sso/",
"redirect_uri", m.Cmdx("web.spide", "serve", "merge", m.Option("index_path")),
"app_id", m.Conf("app", "bot.id"), "state", "ok"))
return
}
m.Cmd("/render")
return
}},
},
}
func init() {
chat.Index.Register(Index, &web.WEB{Context: Index})
}

File diff suppressed because it is too large Load Diff

View File

@ -1,51 +0,0 @@
package mall
import (
"contexts/ctx"
"contexts/web"
"toolkit"
)
var Index = &ctx.Context{Name: "mall", Help: "交易中心",
Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{},
Commands: map[string]*ctx.Command{
"salary": {Name: "salary table month total base tax", Help: "工资", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) < 3 || arg[2] == "" {
m.Cmdy("ssh.data", "show", arg[0], "fields", "id", "month",
"total", "base", "zhu", "old", "bad", "mis", "tax", "rest")
return
}
total := kit.Int(arg[2])
base := kit.Int(kit.Select(arg[2], arg, 3))
tax := kit.Int(kit.Select("0", arg, 4))
zhu := base * 120 / 1000
if len(arg) > 5 {
zhu = kit.Int(arg[5])
}
old := base * 80 / 1000
if len(arg) > 6 {
old = kit.Int(arg[6])
}
bad := base * 20 / 1000
if len(arg) > 7 {
bad = kit.Int(arg[7])
}
mis := base * 5 / 1000
if len(arg) > 8 {
mis = kit.Int(arg[8])
}
rest := total - zhu - old - bad - mis - tax
m.Cmdy("ssh.data", "insert", arg[0], "month", arg[1], "total", total, "base", base, "tax",
tax, "zhu", zhu, "old", old, "bad", bad, "mis", mis, "rest", rest)
return
}},
},
}
func init() {
web.Index.Register(Index, &web.WEB{Context: Index})
}

View File

@ -1,79 +0,0 @@
package team
import (
"contexts/ctx"
"contexts/web"
"fmt"
"toolkit"
)
var Index = &ctx.Context{Name: "team", Help: "团队中心",
Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{},
Commands: map[string]*ctx.Command{
"task": {Name: "task create table level class status begin_time close_time target detail arg...", Help: "任务", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
switch arg[0] {
case "progress":
if len(arg) > 3 && arg[1] != "" {
switch arg[3] {
case "prepare", "action", "cancel", "finish":
time := "close_time"
switch arg[3] {
case "prepare", "action":
time = "begin_time"
case "cancel", "finish":
time = "close_time"
default:
time = "update_time"
}
// 更新任务
m.Cmd("ssh.data", "update", arg[1], arg[2], "status", arg[3], time, m.Time())
arg = []string{arg[0], m.Option("table")}
}
}
// 任务进度
m.Option("cache.limit", kit.Select("30", arg, 2))
m.Option("cache.offend", kit.Select("0", arg, 3))
m.Meta["append"] = []string{"prepare", "action", "cancel", "finish"}
m.Cmd("ssh.data", "show", arg[1]).Table(func(index int, value map[string]string) {
m.Push(value["status"],
fmt.Sprintf("<span data-id='%s' title='%s'>%s</span>", value["id"], value["detail"], value["target"]))
})
m.Table()
case "create":
// 创建任务
if len(arg) > 7 {
if len(arg) < 9 {
arg = append(arg, "")
}
m.Cmdy("ssh.data", "insert", arg[1], "level", arg[2], "class", arg[3],
"status", arg[4], "begin_time", arg[5], "close_time", arg[6],
"target", arg[7], "detail", arg[8], arg[9:])
break
}
arg = []string{arg[1]}
fallthrough
default:
// 更新任务
if len(arg) > 1 && arg[1] == "modify" {
m.Cmdy("ssh.data", "update", m.Option("table"), arg[0], arg[2], arg[3])
break
}
// 查看任务
if len(arg) > 0 && arg[0] == "" {
arg = arg[:0]
}
m.Cmdy("ssh.data", "show", arg, "fields", "id", "level", "class", "status", "target", "begin_time", "close_time")
}
return
}},
},
}
func init() {
web.Index.Register(Index, &web.WEB{Context: Index})
}

View File

@ -1,277 +0,0 @@
package wiki
import (
"contexts/ctx"
mis "github.com/shylinux/toolkits"
"strings"
"toolkit"
)
// 图形接口
type Chart interface {
Init(*ctx.Message, ...string) Chart
Draw(*ctx.Message, int, int) Chart
GetWidth(...string) int
GetHeight(...string) int
}
// 图形基类
type Block struct {
Text string
FontColor string
FontFamily string
BackGround string
FontSize int
LineSize int
Padding int
Margin int
Width, Height int
TextData string
RectData string
}
func (b *Block) Init(m *ctx.Message, arg ...string) Chart {
b.Text = kit.Select(b.Text, arg, 0)
b.FontColor = kit.Select("white", kit.Select(b.FontColor, arg, 1))
b.BackGround = kit.Select("red", kit.Select(b.BackGround, arg, 2))
b.FontSize = kit.Int(kit.Select("24", kit.Select(kit.Format(b.FontSize), arg, 3)))
b.LineSize = kit.Int(kit.Select("12", kit.Select(kit.Format(b.LineSize), arg, 4)))
return b
}
func (b *Block) Draw(m *ctx.Message, x, y int) Chart {
m.Echo(`<rect x="%d" y="%d" width="%d" height="%d" fill="%s" %v/>`,
x+b.Margin/2, y+b.Margin/2, b.GetWidth(), b.GetHeight(), b.BackGround, b.RectData)
m.Echo("\n")
m.Echo(`<text x="%d" y="%d" font-size="%d" style="dominant-baseline:middle;text-anchor:middle;" fill="%s" %v>%v</text>`,
x+b.GetWidths()/2, y+b.GetHeights()/2, b.FontSize, b.FontColor, b.TextData, b.Text)
m.Echo("\n")
return b
}
func (b *Block) Data(root interface{}) {
mis.Table(mis.Value(root, "data"), 0, 100, func(key string, value string) {
b.TextData += key + "='" + value + "' "
})
mis.Table(mis.Value(root, "rect"), 0, 100, func(key string, value string) {
b.RectData += key + "='" + value + "' "
})
b.FontColor = kit.Select(b.FontColor, mis.Value(root, "fg"))
b.BackGround = kit.Select(b.BackGround, mis.Value(root, "bg"))
}
func (b *Block) GetWidth(str ...string) int {
if b.Width != 0 {
return b.Width
}
return len(kit.Select(b.Text, str, 0))*b.FontSize*6/10 + b.Padding
}
func (b *Block) GetHeight(str ...string) int {
if b.Height != 0 {
return b.Height
}
return b.FontSize*b.LineSize/10 + b.Padding
}
func (b *Block) GetWidths(str ...string) int {
return b.GetWidth(str...) + b.Margin
}
func (b *Block) GetHeights(str ...string) int {
return b.GetHeight() + b.Margin
}
// 树
type Chain struct {
data map[string]interface{}
max map[int]int
Block
}
func (b *Chain) Init(m *ctx.Message, arg ...string) Chart {
// 解数据
b.data = mis.Parse(nil, "", b.show(m, arg[0])...).(map[string]interface{})
b.FontColor = kit.Select("white", arg, 1)
b.BackGround = kit.Select("red", arg, 2)
b.FontSize = kit.Int(kit.Select("24", arg, 3))
b.LineSize = kit.Int(kit.Select("12", arg, 4))
b.Padding = kit.Int(kit.Select("8", arg, 5))
b.Margin = kit.Int(kit.Select("8", arg, 6))
m.Log("info", "data %v", kit.Formats(b.data))
// 计算尺寸
b.max = map[int]int{}
b.Height = b.size(m, b.data, 0, b.max) * b.GetHeights()
width := 0
for _, v := range b.max {
width += b.GetWidths(strings.Repeat(" ", v))
}
b.Width = width
m.Log("info", "data %v", kit.Formats(b.data))
return b
}
func (b *Chain) Draw(m *ctx.Message, x, y int) Chart {
return b.draw(m, b.data, 0, b.max, x, y, &Block{})
}
func (b *Chain) show(m *ctx.Message, str string) (res []string) {
miss := []int{}
list := mis.Split(str, "\n")
for _, line := range list {
// 计算缩进
dep := 0
loop:
for _, v := range []rune(line) {
switch v {
case ' ':
dep++
case '\t':
dep += 4
default:
break loop
}
}
// 计算层次
if len(miss) > 0 {
if miss[len(miss)-1] > dep {
for i := len(miss) - 1; i >= 0; i-- {
if miss[i] < dep {
break
}
res = append(res, "]", "}")
miss = miss[:i]
}
miss = append(miss, dep)
} else if miss[len(miss)-1] < dep {
miss = append(miss, dep)
} else {
res = append(res, "]", "}")
}
} else {
miss = append(miss, dep)
}
// 输出节点
word := mis.Split(line)
res = append(res, "{", "meta", "{", "text")
res = append(res, word...)
res = append(res, "}", "list", "[")
}
return
}
func (b *Chain) size(m *ctx.Message, root map[string]interface{}, depth int, width map[int]int) int {
meta := root["meta"].(map[string]interface{})
// 最大宽度
text := kit.Format(meta["text"])
if len(text) > width[depth] {
width[depth] = len(text)
}
// 计算高度
height := 0
if list, ok := root["list"].([]interface{}); ok && len(list) > 0 {
kit.Map(root["list"], "", func(index int, value map[string]interface{}) {
height += b.size(m, value, depth+1, width)
})
} else {
height = 1
}
meta["height"] = height
return height
}
func (b *Chain) draw(m *ctx.Message, root map[string]interface{}, depth int, width map[int]int, x, y int, p *Block) Chart {
meta := root["meta"].(map[string]interface{})
b.Width, b.Height = 0, 0
// 当前节点
block := &Block{
BackGround: kit.Select(b.BackGround, kit.Select(p.BackGround, meta["bg"])),
FontColor: kit.Select(b.FontColor, kit.Select(p.FontColor, meta["fg"])),
FontSize: b.FontSize,
LineSize: b.LineSize,
Padding: b.Padding,
Margin: b.Margin,
Width: b.GetWidth(strings.Repeat(" ", width[depth])),
}
block.Data(root["meta"])
block.Init(m, kit.Format(meta["text"])).Draw(m, x, y+(kit.Int(meta["height"])-1)*b.GetHeights()/2)
// 递归节点
kit.Map(root["list"], "", func(index int, value map[string]interface{}) {
b.draw(m, value, depth+1, width, x+b.GetWidths(strings.Repeat(" ", width[depth])), y, block)
y += kit.Int(kit.Chain(value, "meta.height")) * b.GetHeights()
})
return b
}
// 表
type Table struct {
data [][]string
max map[int]int
Block
}
func (b *Table) Init(m *ctx.Message, arg ...string) Chart {
// 解析数据
b.max = map[int]int{}
for _, v := range mis.Split(arg[0], "\n") {
l := mis.Split(v)
for i, v := range l {
switch data := mis.Parse(nil, "", mis.Split(v)...).(type) {
case map[string]interface{}:
v = kit.Select("", data["text"])
}
if len(v) > b.max[i] {
b.max[i] = len(v)
}
}
b.data = append(b.data, l)
}
b.FontColor = kit.Select("white", arg, 1)
b.BackGround = kit.Select("red", arg, 2)
b.FontSize = kit.Int(kit.Select("24", arg, 3))
b.LineSize = kit.Int(kit.Select("12", arg, 4))
b.Padding = kit.Int(kit.Select("8", arg, 5))
b.Margin = kit.Int(kit.Select("8", arg, 6))
// 计算尺寸
width := 0
for _, v := range b.max {
width += b.GetWidths(strings.Repeat(" ", v))
}
b.Width = width
b.Height = len(b.data) * b.GetHeights()
m.Log("info", "data %v", kit.Formats(b.data))
return b
}
func (b *Table) Draw(m *ctx.Message, x, y int) Chart {
b.Width, b.Height = 0, 0
for n, line := range b.data {
for i, text := range line {
l := 0
for j := 0; j < i; j++ {
l += b.GetWidths(strings.Repeat(" ", b.max[i]))
}
block := &Block{
BackGround: kit.Select(b.BackGround),
FontColor: kit.Select(b.FontColor),
FontSize: b.FontSize,
LineSize: b.LineSize,
Padding: b.Padding,
Margin: b.Margin,
Width: b.GetWidth(strings.Repeat(" ", b.max[i])),
}
switch data := mis.Parse(nil, "", mis.Split(text)...).(type) {
case map[string]interface{}:
text = kit.Select(text, data["text"])
block.Data(data)
}
block.Init(m, text).Draw(m, x+l, y+n*b.GetHeights())
}
}
return b
}

View File

@ -1,547 +0,0 @@
package wiki
import (
"github.com/gomarkdown/markdown"
mis "github.com/shylinux/toolkits"
"contexts/ctx"
"contexts/web"
"toolkit"
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"path"
"strconv"
"strings"
"text/template"
)
type opt struct {
font_size int
font_color string
background string
padding int
margin int
}
func show(m *ctx.Message, str string) (res []string) {
miss := []int{}
list := mis.Split(str, "\n")
for _, line := range list {
dep := 0
loop:
for _, v := range []rune(line) {
switch v {
case ' ':
dep++
case '\t':
dep += 4
default:
break loop
}
}
if len(miss) > 0 {
if miss[len(miss)-1] > dep {
for i := len(miss) - 1; i >= 0; i-- {
if miss[i] < dep {
break
}
m.Log("show", "pop %d %v %v", dep, mis.Format(miss), line)
res = append(res, "]", "}")
miss = miss[:i]
}
m.Log("show", "push %d %v %v", dep, mis.Format(miss), line)
miss = append(miss, dep)
} else if miss[len(miss)-1] < dep {
m.Log("show", "push %d %v %v", dep, mis.Format(miss), line)
miss = append(miss, dep)
} else {
res = append(res, "]", "}")
}
} else {
m.Log("show", "push %d %v", dep, mis.Format(miss))
miss = append(miss, dep)
}
word := mis.Split(line)
res = append(res, "{", "meta", "{", "text")
res = append(res, word...)
res = append(res, "}", "list", "[")
}
m.Log("haha", "%v %v", str, res)
return
}
func size(m *ctx.Message, root map[string]interface{}, depth int, width map[int]int) int {
text := kit.Format(kit.Chain(root, "meta.text"))
if len(text) > width[depth] {
width[depth] = len(text)
}
if list, ok := root["list"].([]interface{}); !ok || len(list) == 0 {
kit.Chain(root, "meta.height", 1)
m.Log("fuck", "size %v %d", kit.Chain(root, "meta.text"), 1)
return 1
}
height := 0
kit.Map(root["list"], "", func(index int, value map[string]interface{}) {
height += size(m, value, depth+1, width)
})
kit.Chain(root, "meta.height", height)
m.Log("fuck", "size %v %d", kit.Chain(root, "meta.text"), height)
return height
}
func draw(m *ctx.Message, root map[string]interface{}, depth int, width map[int]int, x int, y int, opt *opt) {
meta := root["meta"].(map[string]interface{})
m.Log("fuck", "draw %v %d", meta["text"], y)
height := kit.Int(meta["height"])
p := (height - 1) * (opt.font_size + opt.margin + opt.padding)
m.Echo(`<rect x="%d" y="%d" width="%d" height="%d" fill="%s"/>`,
x, y+p/2, width[depth]*opt.font_size/2+opt.padding, opt.font_size+opt.padding, kit.Select(opt.background, meta["bg"]))
m.Echo(`<text x="%d" y="%d" font-size="%d" text-anchor="middle" fill="%s">%v</text>`,
x+width[depth]*opt.font_size/2/2+opt.padding/2, y+p/2+opt.font_size-opt.padding/2, opt.font_size, kit.Select(opt.font_color, meta["fg"]), meta["text"])
kit.Map(root["list"], "", func(index int, value map[string]interface{}) {
draw(m, value, depth+1, width, x+width[depth]*opt.font_size/2+opt.margin+opt.padding, y, opt)
y += kit.Int(kit.Chain(value, "meta.height")) * (opt.font_size + opt.margin + opt.padding)
})
}
var Index = &ctx.Context{Name: "wiki", Help: "文档中心",
Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{
"login": {Name: "login", Value: map[string]interface{}{"check": "false", "meta": map[string]interface{}{
"script": "usr/script",
}}, Help: "用户登录"},
"componet": {Name: "componet", Value: map[string]interface{}{
"index": []interface{}{
map[string]interface{}{"name": "wiki",
"tmpl": "head", "metas": []interface{}{map[string]interface{}{
"name": "viewport", "content": "width=device-width, initial-scale=0.7, user-scalable=no",
}}, "favicon": "favicon.ico", "styles": []interface{}{
"example.css", "wiki.css",
}},
map[string]interface{}{"name": "header",
"tmpl": "fieldset", "view": "Header", "init": "initHeader",
},
map[string]interface{}{"name": "tree",
"tmpl": "fieldset", "view": "Tree", "init": "initTree",
"ctx": "web.wiki", "cmd": "tree",
},
map[string]interface{}{"name": "text",
"tmpl": "fieldset", "view": "Text", "init": "initText",
"ctx": "web.wiki", "cmd": "text",
},
map[string]interface{}{"name": "footer",
"tmpl": "fieldset", "view": "Footer", "init": "initFooter",
},
map[string]interface{}{"name": "tail",
"tmpl": "tail", "scripts": []interface{}{
"toolkit.js", "context.js", "example.js", "wiki.js",
},
},
},
}, Help: "组件列表"},
"level": {Name: "level", Value: "usr/local/wiki", Help: "文档路径"},
"class": {Name: "class", Value: "", Help: "文档目录"},
"favor": {Name: "favor", Value: "index.md", Help: "默认文档"},
"story": {Name: "story", Value: map[string]interface{}{
"data": map[string]interface{}{},
"node": map[string]interface{}{},
"head": map[string]interface{}{},
}, Help: "故事会"},
"template": {Name: "template", Value: map[string]interface{}{
"list": []interface{}{
`{{define "raw"}}{{.|results}}{{end}}`,
`{{define "title"}}{{.|results}}{{end}}`,
`{{define "chapter"}}{{.|results}}{{end}}`,
`{{define "section"}}{{.|results}}{{end}}`,
`{{define "block"}}<div>{{.|results}}<div>{{end}}`,
},
}, Help: "故事会"},
},
Commands: map[string]*ctx.Command{
"tree": {Name: "tree", Help: "目录", Form: map[string]int{"level": 1, "class": 1}, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Cmdy("nfs.dir", path.Join(m.Confx("level"), m.Confx("class", arg, 0)),
"time", "size", "line", "file", "dir_sort", "time", "time_r").Set("result")
return
}},
"text": {Name: "text", Help: "文章", Form: map[string]int{"level": 1, "class": 1, "favor": 1}, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
which := m.Cmdx("nfs.path", path.Join(m.Confx("level"), m.Confx("class", arg, 1), m.Confx("favor", arg, 0)))
tmpl := template.New("render").Funcs(*ctx.LocalCGI(m, c))
m.Confm("template", "list", func(index int, value string) { tmpl = template.Must(tmpl.Parse(value)) })
tmpl = template.Must(tmpl.ParseGlob(path.Join(m.Cmdx("nfs.path", m.Conf("route", "template_dir")), "/*.tmpl")))
tmpl = template.Must(tmpl.ParseGlob(path.Join(m.Cmdx("nfs.path", m.Conf("route", "template_dir")), m.Cap("route"), "/*.tmpl")))
tmpl = template.Must(tmpl.ParseFiles(which))
for i, v := range tmpl.Templates() {
m.Log("info", "%v, %v", i, v.Name())
}
m.Optionv("title", map[string]int{})
m.Optionv("tmpl", tmpl)
m.Option("render", "")
buffer := bytes.NewBuffer([]byte{})
m.Assert(tmpl.ExecuteTemplate(buffer, m.Option("filename", path.Base(which)), m))
if f, p, e := kit.Create(path.Join("var/tmp/file", which)); e == nil {
defer f.Close()
f.Write(buffer.Bytes())
m.Log("info", "save %v", p)
}
data := markdown.ToHTML(buffer.Bytes(), nil, nil)
m.Echo(string(data))
return
}},
"note": {Name: "note file|favor|commit", Help: "笔记", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) == 0 {
m.Cmd("tree")
return
}
switch arg[0] {
case "favor", "commit":
m.Cmd("story", arg[0], arg[1:])
default:
m.Cmd(kit.Select("tree", "text", strings.HasSuffix(arg[0], ".md")), arg[0])
}
return
}},
"story": {Name: "story favor|commit|branch|remote story scene enjoy happy", Help: "故事会", Hand: func(m *ctx.Message, c *ctx.Context, cmd string, arg ...string) (e error) {
switch arg[0] {
case "favor":
if len(arg) < 4 {
m.Cmdy("ssh.data", "show", arg[1:])
break
}
head := kit.Hashs(arg[2], arg[4])
prev := m.Conf(cmd, []string{"head", head, "node"})
m.Cmdy("ssh.data", "insert", arg[1], "story", arg[2], "scene", arg[3], "enjoy", arg[4], "node", prev)
case "commit":
head := kit.Hashs(arg[1], arg[3])
prev := m.Conf(cmd, []string{"head", head, "node"})
m.Log("info", "head: %v %#v", head, prev)
if len(arg) > 4 {
data := kit.Hashs(arg[4])
m.Log("info", "data: %v %v", data, arg[4])
if m.Conf(cmd, []string{"node", prev, "data"}) != data {
m.Conf(cmd, []string{"data", data}, arg[4])
meta := map[string]interface{}{
"time": m.Time(),
"story": arg[1],
"scene": arg[2],
"enjoy": arg[3],
"data": data,
"prev": prev,
}
node := kit.Hashs(kit.Format(meta))
m.Log("info", "node: %v %v", node, meta)
m.Conf(cmd, []string{"node", node}, meta)
m.Log("info", "head: %v %v", head, node)
m.Conf(cmd, []string{"head", head, "node"}, node)
m.Echo("%v", kit.Formats(meta))
break
}
}
for prev != "" {
node := m.Confm(cmd, []string{"node", prev})
m.Push("node", kit.Short(prev, 6))
m.Push("time", node["time"])
m.Push("data", m.Conf(cmd, []string{"data", kit.Format(node["data"])}))
prev = kit.Format(node["prev"])
}
m.Table()
return
case "branch":
m.Confm(cmd, "head", func(key string, value map[string]interface{}) {
node := kit.Format(value["node"])
m.Push("key", kit.Short(key, 6))
m.Push("story", m.Conf(cmd, []string{"node", node, "story"}))
m.Push("scene", m.Conf(cmd, []string{"node", node, "scene"}))
m.Push("enjoy", m.Conf(cmd, []string{"node", node, "enjoy"}))
m.Push("node", kit.Short(value["node"], 6))
})
m.Table()
case "remote":
}
return
}},
"index": {Name: "index name|hash", Help: "索引", Hand: func(m *ctx.Message, c *ctx.Context, cmd string, arg ...string) (e error) {
scene := ""
if hash := m.Conf("story", []string{"head", kit.Hashs(m.Option("filename"), arg[0]), "node"}); hash != "" {
arg[0] = hash
} else if hash := m.Conf("story", []string{"head", arg[0], "node"}); hash != "" {
arg[0] = hash
}
if hash := m.Conf("story", []string{"node", arg[0], "data"}); hash != "" {
scene = m.Conf("story", []string{"node", arg[0], "scene"})
arg[0] = hash
}
if data := m.Conf("story", []string{"data", arg[0]}); data != "" {
arg[0] = data
}
if scene != "" {
m.Cmdy(scene, "", arg[0])
} else {
m.Echo(arg[0])
}
return
}},
"table": {Name: "table name data", Help: "表格", Hand: func(m *ctx.Message, c *ctx.Context, cmd string, arg ...string) (e error) {
if len(arg) < 2 {
return
}
m.Option("scene", cmd)
m.Option("enjoy", arg[0])
m.Option("happy", arg[1])
m.Option("render", cmd)
head := []string{}
for i, l := range strings.Split(strings.TrimSpace(arg[1]), "\n") {
if i == 0 {
head = kit.Split(l, ' ', 100)
continue
}
for j, v := range kit.Split(l, ' ', 100) {
m.Push(head[j], v)
}
}
return
}},
"order": {Name: "order", Help: "列表", Hand: func(m *ctx.Message, c *ctx.Context, cmd string, arg ...string) (e error) {
if len(arg) < 2 {
return
}
m.Option("scene", cmd)
m.Option("enjoy", arg[0])
m.Option("happy", arg[1])
m.Option("render", cmd)
for _, l := range strings.Split(strings.TrimSpace(arg[1]), "\n") {
m.Push("list", l)
}
return
}},
"refer": {Name: "refer", Help: "链接地址", Hand: func(m *ctx.Message, c *ctx.Context, cmd string, arg ...string) (e error) {
if len(arg) == 1 {
cmd, arg = arg[0], arg[1:]
for _, l := range strings.Split(strings.TrimSpace(cmd), "\n") {
if l = strings.TrimSpace(l); len(l) > 0 {
arg = append(arg, kit.Split(l, ' ', 2)...)
}
}
}
m.Set("option", "render", "order")
for i := 0; i < len(arg)-1; i += 2 {
m.Push("list", fmt.Sprintf(`%s: <a href="%s" target="_blank">%s</a>`, arg[i], arg[i+1], arg[i+1]))
}
return
}},
"favor": {Name: "favor type tab", Help: "链接地址", Hand: func(m *ctx.Message, c *ctx.Context, cmd string, arg ...string) (e error) {
msg := m.Cmd("ssh.data", "show", "tip", "", "1000", "0", "tab", arg[1])
switch arg[0] {
case "script":
m.Set("option", "render", "code")
if b, e := ioutil.ReadFile(path.Join(m.Conf("login", "meta.script"), arg[1])); e == nil {
m.Echo(string(b))
}
case "li":
m.Set("option", "render", "order")
msg.Table(func(index int, value map[string]string) {
m.Push("list", fmt.Sprintf(`%s: <a href="%s" target="_blank">%s</a>`, value["note"], value["word"], value["word"]))
})
case "sh":
m.Set("option", "render", "code")
m.Echo("#! /bin/sh\n")
m.Echo("# %v\n", arg[1])
m.Echo("\n")
msg.Table(func(index int, value map[string]string) {
m.Echo("# %d %v\n%v\n\n", index, value["note"], value["word"])
})
}
return
}},
"shell": {Name: "shell dir cmd", Help: "命令行", Form: map[string]int{"style": 1}, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Option("render", "code")
m.Echo("$ %v\n", strings.Join(arg[1:], " "))
m.Cmdy("cli.system", "cmd_dir", arg[0], "bash", "-c", strings.Join(arg[1:], " "))
return
}},
"chart": {Name: "chart type text", Help: "绘图", Form: map[string]int{"style": 1}, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Option("render", "raw")
var chart Chart
switch arg[0] {
case "block":
chart = &Block{}
case "chain":
chart = &Chain{}
case "table":
chart = &Table{}
}
arg[1] = strings.TrimSpace(arg[1])
chart.Init(m, arg[1:]...)
m.Echo(`<svg vertion="1.1" xmlns="http://www.w3.org/2000/svg" width="%d", height="%d" style="%s">`,
chart.GetWidth(), chart.GetHeight(), m.Option("style"))
m.Echo("\n")
chart.Draw(m, 0, 0)
m.Echo(`</svg>`)
m.Echo("\n")
return
}},
"title": {Name: "title text", Help: "一级标题", Hand: func(m *ctx.Message, c *ctx.Context, cmd string, arg ...string) (e error) {
ns := strings.Split(m.Conf("runtime", "node.name"), "-")
m.Set("option", "render", cmd).Echo(kit.Select(ns[len(ns)-1], arg, 0))
return
}},
"chapter": {Name: "chaper text", Help: "二级标题", Hand: func(m *ctx.Message, c *ctx.Context, cmd string, arg ...string) (e error) {
prefix := ""
if title, ok := m.Optionv("title").(map[string]int); ok {
title["chapter"]++
title["section"] = 0
prefix = strconv.Itoa(title["chapter"]) + " "
}
m.Set("option", "render", cmd).Echo(prefix + kit.Select("", arg, 0))
return
}},
"section": {Name: "section text", Help: "三级标题", Hand: func(m *ctx.Message, c *ctx.Context, cmd string, arg ...string) (e error) {
prefix := ""
if title, ok := m.Optionv("title").(map[string]int); ok {
title["section"]++
prefix = strconv.Itoa(title["chapter"]) + "." + strconv.Itoa(title["section"]) + " "
}
m.Set("option", "render", cmd).Echo(prefix + kit.Select("", arg, 0))
return
}},
"run": {Name: "run", Help: "便签", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Option("render", "raw")
m.Cmdy(arg)
return
}},
"time": {Name: "time", Help: "便签", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Cmdy("cli.time", "show").Set("append")
return
}},
"svg": {Name: "svg", Help: "绘图", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
data := map[string]interface{}{"meta": map[string]interface{}{"text": "chat"}, "list": []interface{}{
map[string]interface{}{"meta": map[string]interface{}{"text": "ocean"}},
map[string]interface{}{"meta": map[string]interface{}{"text": "river"}},
map[string]interface{}{"meta": map[string]interface{}{"text": "dream"}, "list": []interface{}{
map[string]interface{}{"meta": map[string]interface{}{"text": "zsh"}, "list": []interface{}{
map[string]interface{}{"meta": map[string]interface{}{"text": "auto.sh"}},
}},
map[string]interface{}{"meta": map[string]interface{}{"text": "tmux"}},
map[string]interface{}{"meta": map[string]interface{}{"text": "docker"}},
map[string]interface{}{"meta": map[string]interface{}{"text": "git"}},
map[string]interface{}{"meta": map[string]interface{}{"text": "vim"}, "list": []interface{}{
map[string]interface{}{"meta": map[string]interface{}{"text": "auto.vim"}},
}},
}},
map[string]interface{}{"meta": map[string]interface{}{"text": "storm"}},
map[string]interface{}{"meta": map[string]interface{}{"text": "steam"}},
}}
opt := &opt{
font_size: kit.Int(kit.Select("60", arg, 0)),
font_color: kit.Select("red", arg, 1),
background: kit.Select("green", arg, 2),
padding: 10,
margin: 20,
}
if len(arg) > 3 {
data = mis.Parse(nil, "", show(m, arg[3])...).(map[string]interface{})
}
max := map[int]int{}
num := size(m, data, 0, max)
width := 0
for _, v := range max {
width += v*opt.font_size/2 + opt.margin
}
m.Echo(`<svg vertion="1.1" xmlns="http://www.w3.org/2000/svg" width="%d", height="%d">`,
width, num*(opt.font_size+opt.padding+opt.margin)-opt.margin)
draw(m, data, 0, max, 0, 0, opt)
m.Echo(`</svg>`)
// m.Echo(`<rect width="100%" height="100%" fill="red"/>`)
// m.Echo(`<circle cx="150" cy="100" r="80" fill="green"/>`)
// m.Echo(`<text x="150" y="100" font-size="60" text-anchor="middle" fill="black">SVG</text>`)
return
}},
"xls": {Name: "xls", Help: "表格", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
switch len(arg) {
case 0:
m.Cmdy("ssh.data", "show", "xls")
m.Meta["append"] = []string{"id", "title"}
case 1:
var data map[int]map[int]string
what := m.Cmd("ssh.data", "show", "xls", arg[0], "format", "object").Append("content")
json.Unmarshal([]byte(what), &data)
max, n := 0, 0
for i, v := range data {
if i > n {
n = i
}
for i := range v {
if i > max {
max = i
}
}
}
m.Log("info", "m: %d n: %d", max, n)
for k := 0; k < n+2; k++ {
for i := 0; i < max+2; i++ {
m.Push(kit.Format(k), kit.Format(data[k][i]))
}
}
case 2:
m.Cmdy("ssh.data", "insert", "xls", "title", arg[0], "content", arg[1])
default:
data := map[int]map[int]string{}
what := m.Cmd("ssh.data", "show", "xls", arg[0], "format", "object").Append("content")
json.Unmarshal([]byte(what), &data)
for i := 1; i < len(arg)-2; i += 3 {
if _, ok := data[kit.Int(arg[i])]; !ok {
data[kit.Int(arg[i])] = make(map[int]string)
}
data[kit.Int(arg[i])][kit.Int(arg[i+1])] = arg[i+2]
}
m.Cmdy("ssh.data", "update", "xls", arg[0], "content", kit.Format(data))
}
return
}},
},
}
func init() {
web.Index.Register(Index, &web.WEB{Context: Index})
}

View File

@ -1,83 +0,0 @@
package main
import (
"bufio"
"fmt"
"io"
"os"
"regexp"
"toolkit"
)
var files = ".*\\.(xml|html|css|js)$"
var words = "[[:^ascii:]]+"
func main() {
if len(os.Args) == 1 {
fmt.Println("usage", os.Args[0], "dirs [files [words]]")
fmt.Println("在目录dirs中查找匹配files的文件并查找匹配words的单词")
os.Exit(1)
}
if len(os.Args) > 2 {
files = os.Args[2]
}
if len(os.Args) > 3 {
words = os.Args[3]
}
word, e := regexp.Compile(words)
kit.Check(e)
// out, e := os.Create(os.Args[2])
// kit.Check(e)
out := os.Stdout
total := 0
count := 0
chars := 0
kit.DirWalk(os.Args[1], func(file string) {
s, _ := os.Stat(file)
if s.IsDir() {
return
}
if m, e := regexp.MatchString(files, file); !kit.Check(e) || !m {
return
}
f, e := os.Open(file)
kit.Check(e)
bio := bufio.NewReader(f)
fmt.Fprintln(out, kit.FmtSize(s.Size()), file)
line := 0
cs := 0
for i := 1; true; i++ {
l, e := bio.ReadString('\n')
if e == io.EOF {
break
}
kit.Check(e)
if i == 1 {
continue
}
a := word.FindAllString(l, 20)
for _, v := range a {
n := len([]rune(v))
fmt.Fprintf(out, "l:%d c:%d %s\n", i, n, v)
total++
line++
chars += n
cs += n
}
}
fmt.Fprintln(out, "lines:", line, "chars:", cs, file)
fmt.Fprintln(out)
if line > 0 {
count++
}
})
fmt.Fprintln(out, "files:", count, "lines:", total, "chars:", chars, os.Args[1])
return
}

View File

@ -1,33 +0,0 @@
package main
import (
// 数据层
_ "contexts/mdb" //数据中心
_ "contexts/nfs" //存储中心
_ "contexts/ssh" //集群中心
_ "contexts/tcp" //网络中心
// 控制层
_ "contexts/gdb" //调试中心
_ "contexts/lex" //词法中心
_ "contexts/log" //日志中心
_ "contexts/yac" //语法中心
// 服务层
_ "contexts/aaa" //认证中心
_ "contexts/cli" //管理中心
c "contexts/ctx" //模块中心
_ "contexts/web" //应用中心
// 应用层
_ "examples/chat" //会议中心
_ "examples/code" //代码中心
_ "examples/mall" //交易中心
_ "examples/team" //团队中心
_ "examples/wiki" //文档中心
// 应用层
_ "examples/chat/feishu" //飞书
)
func main() {
c.Start()
}

View File

@ -1,36 +0,0 @@
package main
import (
"contexts/cli"
"contexts/ctx"
"toolkit"
"fmt"
"os"
)
var Index = &ctx.Context{Name: "test", Help: "测试工具",
Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{
"_index": &ctx.Config{Name: "index", Value: []interface{}{
map[string]interface{}{"name": "demo", "help": "demo",
"tmpl": "componet", "view": "componet", "init": "",
"type": "public", "ctx": "demo", "cmd": "demo",
"args": []interface{}{}, "inputs": []interface{}{
map[string]interface{}{"type": "text", "name": "pod", "value": "hello world"},
map[string]interface{}{"type": "button", "value": "执行"},
},
},
}},
},
Commands: map[string]*ctx.Command{
"demo": {Name: "demo", Help: "demo", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Echo(kit.Select("hello world", arg, 0))
return
}},
},
}
func main() {
fmt.Print(cli.Index.Plugin(Index, os.Args[1:]))
}

View File

@ -1,4 +0,0 @@
Script["context/index.js"] = function(field, option, output) {
return {}
}

View File

@ -1,72 +0,0 @@
kit project "项目" private \
select "" values "plugin review submit trends trend stats stat init" action auto \
text "" name see imports plugin_see action auto \
feature detail "加载" "复制" "下载" \
exports see name see \
button "执行" action auto \
button "返回" cb Last
kit compile "编译" private \
select "" values "plugin restart windows darwin linux self all" action auto \
text "" name see imports plugin_see \
button "编译"
kit publish "发布" private \
text "" name see imports plugin_see \
button "发布"
kit upgrade "升级" private "_:cli.upgrade" \
text "" name pod imports plugin_pod \
select "" values "script plugin restart package system portal bench" action auto \
text "" name see imports plugin_see \
button "升级"
kit missyou "任务" private "_:cli.missyou" \
text "" name pod imports plugin_pod \
text "" name you view long \
text "" name see imports plugin_see \
button "行动" action auto \
exports you you "" "" status you_status
kit pod "设备" private "_:ssh.remote" \
text "" name pod imports plugin_pod \
button "查看" action auto \
button "返回" cb Last \
exports pod node pod
kit ctx "模块" private "_:context" _ _ list \
text "" name pod imports plugin_pod action auto \
text "cli" name ctx imports plugin_ctx action auto \
button "查看" \
exports ctx names
kit cmd "命令" private "_:context" _ _ command \
text "" name pod imports plugin_pod \
text "cli" name ctx imports plugin_ctx \
text "date" name cmd imports plugin_cmd \
button "执行" \
button "返回" cb Last \
exports cmd cmd
kit dir "目录" private "_:nfs.dir" _ _ time size line path \
text "" name pod imports plugin_pod action auto \
text "usr/local" name path action auto view long \
button "浏览" action auto \
button "返回" cb Last \
exports dir "" dir
fun wss "推送" private \
text "" name wss imports plugin_wss \
text "" name cmd view long \
button "推送" \
button "返回" cb Last \
exports wss key
if $2 == ""
copy web.wss
else
copy web.wss _ sync
end
end

View File

@ -1 +0,0 @@

View File

@ -1,3 +0,0 @@
fieldset.item.docker div.output {
}

View File

@ -1,36 +0,0 @@
package main
import (
"contexts/cli"
"contexts/ctx"
"toolkit"
"fmt"
"os"
)
var Index = &ctx.Context{Name: `docker`, Help: `plugin`,
Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{
"_index": &ctx.Config{Name: "index", Value: []interface{}{
map[string]interface{}{"name": "demo", "help": "demo",
"tmpl": "componet", "view": "", "init": "",
"type": "public", "ctx": "demo", "cmd": "demo",
"args": []interface{}{}, "inputs": []interface{}{
map[string]interface{}{"type": "text", "name": "pod", "value": "hello world"},
map[string]interface{}{"type": "button", "value": "执行"},
},
},
}},
},
Commands: map[string]*ctx.Command{
"demo": {Name: "demo", Help: "demo", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Echo(kit.Select("hello world", arg, 0))
return
}},
},
}
func main() {
fmt.Print(cli.Index.Plugin(Index, os.Args[1:]))
}

View File

@ -1,3 +0,0 @@
Script["docker/index.js"] = function(field, option, output) {return {
}}

View File

@ -1,74 +0,0 @@
kit dir "目录" private "_:web.code.zsh" "@pod" \
text "" name dir imports plugin_path action auto \
select "" name cmd values "list find tail grep init" action auto \
text "" name txt \
exports path path \
feature display editor \
button "搜索" action auto \
button "返回" cb Last
kit clip "粘贴板" private "web.code.tmux" "" "buffer" \
text "" name buffer action auto \
text "" name txt \
exports buffer buffer \
button "查看" action auto \
button "返回" cb Last
kit tmux "终端" private "web.code.tmux" \
text "" name session imports plugin_session action auto \
text "" name window imports plugin_window action auto \
text "" name pane imports plugin_pane view char action auto \
exports session session "" window window "" pane pane "" \
button "查看" action auto \
button "返回" cb Last
kit tmuxs "终端" private "web.code.tmux" \
text "" name session imports plugin_session \
select "" name cmd values "favor pane cmd"\
text "" name arg \
button "执行"
kit image "镜像" private "web.code.docker" "image" \
text "" name pos \
text "" name tag \
exports IMAGE_ID IMAGE_ID "" REPOSITORY REPOSITORY "" TAG TAG "" \
feature detail "运行" "清理" "删除" "创建" \
button "查看"
kit volume "存储" private "web.code.docker" "volume" \
text "" name arg imports plugin_VOLUME_NAME \
exports VOLUME_NAME VOLUME_NAME \
button "查看"
kit network "网络" private "web.code.docker" "network" \
text "" name arg imports plugin_NETWORK_ID action auto \
exports NETWORK_ID NETWORK_ID \
button "查看"
kit container "容器" private "web.code.docker" "container" \
text "" name arg imports plugin_CONTAINER_ID \
feature detail "进入" "停止" "启动" "重启" "清理" "修改" "删除" \
exports CONTAINER_ID CONTAINER_ID "" CONTAINER_NAME NAMES "" \
button "查看" action auto
kit command "命令" private "web.code.docker" "command" \
text "" name tag imports plugin_CONTAINER_ID \
select "" name pkg values "apk apt yum" \
select "" name cmd values "base" \
text "" name arg view long \
button "执行"
kit git "记录" private "_:web.code.zsh" "@you"\
text "usr/local" name dir imports plugin_git_path action auto \
select "git" name cmd values git \
select "status" name cmd values "diff status commit branch remote pull push sum init" action auto \
text "" name txt \
exports branch branch "" git_path path "" \
button "查看" action auto \
button "返回" cb Last
kit vim "编辑器" private "web.code.vim" \
select "bufs" name cmd values editor values prune values opens values cmds values txts values bufs values regs values marks values tags values fixs \
button "查看" action auto

View File

@ -1,3 +0,0 @@
fieldset.item.dream div.output {
}

View File

@ -1,36 +0,0 @@
package main
import (
"contexts/cli"
"contexts/ctx"
"toolkit"
"fmt"
"os"
)
var Index = &ctx.Context{Name: `dream`, Help: `plugin`,
Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{
"_index": &ctx.Config{Name: "index", Value: []interface{}{
map[string]interface{}{"name": "demo", "help": "demo",
"tmpl": "componet", "view": "", "init": "",
"type": "public", "ctx": "demo", "cmd": "demo",
"args": []interface{}{}, "inputs": []interface{}{
map[string]interface{}{"type": "text", "name": "pod", "value": "hello world"},
map[string]interface{}{"type": "button", "value": "执行"},
},
},
}},
},
Commands: map[string]*ctx.Command{
"demo": {Name: "demo", Help: "demo", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Echo(kit.Select("hello world", arg, 0))
return
}},
},
}
func main() {
fmt.Print(cli.Index.Plugin(Index, os.Args[1:]))
}

View File

@ -1,3 +0,0 @@
Script["dream/index.js"] = function(field, option, output) {return {
}}

View File

@ -1,3 +0,0 @@
kit share "梦想主题" private "web.code.dream" list \
button "查看"

View File

@ -1,36 +0,0 @@
package main
import (
"contexts/cli"
"contexts/ctx"
"toolkit"
"fmt"
"os"
)
var Index = &ctx.Context{Name: "test", Help: "测试工具",
Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{
"_index": &ctx.Config{Name: "index", Value: []interface{}{
map[string]interface{}{"name": "demo", "help": "demo",
"tmpl": "componet", "view": "componet", "init": "",
"type": "public", "ctx": "demo", "cmd": "demo",
"args": []interface{}{}, "inputs": []interface{}{
map[string]interface{}{"type": "text", "name": "pod", "value": "hello world"},
map[string]interface{}{"type": "button", "value": "执行"},
},
},
}},
},
Commands: map[string]*ctx.Command{
"demo": {Name: "demo", Help: "demo", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Echo(kit.Select("hello world", arg, 0))
return
}},
},
}
func main() {
fmt.Print(cli.Index.Plugin(Index, os.Args[1:]))
}

View File

@ -1,8 +0,0 @@
Plugin["favor/index.js"] = function(field, option, output) {return {
share: function(event) {var plugin = field.Plugin
plugin.Run(event, ["share", option.txt.value], function(msg) {
kit.AppendChilds(output, [{img: [msg.result.join("")]}])
typeof cb == "function" && cb({})
})
},
}}

View File

@ -1,61 +0,0 @@
fun qrcode "二维码" "index.js" public \
text "" name txt view long \
button "生成" cb share
append qrcode ($1 || $referer)
end
kit macro "脚本宏" "macro.js" public \
text "" name mac imports plugin_mac action auto \
button "查看" \
button "全部" cb "all" \
button "录制" cb "Record" \
button "运行" cb "Replay" \
exports mac name
kit sys "命令行" public "ssh._route" _ "nfs.source" \
text "" name pod imports plugin_pod \
button "运行" \
textarea "" view long \
exports mac name
fun salary "工资单" public \
text "9000" label total \
text "9000" label base \
button "计算"
let total = $1 || $2
let base = $2 || $1
let house = $base * 120 / 1000
let old = $base * 80 / 1000
let tread = $base * 20 / 1000
let job = $base * 2 / 1000
let get = $total - $house - $old - $tread - $job
let tax = 0
let rest = $get
let list = [85000 45 60000 35 40000 30 30000 25 17000 20 8000 10 5000 3]
for i amount percent in list
if $rest > $amount
let tax = $tax + ($rest - $amount) * $percent / 100
let rest = $amount
end
end
let rest = $get - $tax
append "公积金" $house
append "养老保险" $old
append "医疗保险" $tread
append "失业保险" $job
append "个税" $tax
append "结余" $rest
end
kit svg "绘图" public "web.wiki.svg" \
text "download/usr/script/teacherInfo.svg" name svg view long \
feature display svg \
button "查看"

View File

@ -1 +0,0 @@

View File

@ -1,33 +0,0 @@
Plugin["favor/macro.js"] = function(field, option, output) {return {
Record: function() {
if (confirm("run script "+option.mac.value)) {
page.script("record", option.mac.value)
}
},
Replay: function() {
if (confirm("run script "+option.mac.value)) {
page.script("replay", option.mac.value)
}
},
all: function() {var plugin = field.Plugin
option.mac.value = "", plugin.Runs(window.event, function() {
page.Sync("plugin_"+plugin.exports[0]).set(plugin.onexport[plugin.exports[2]||""]("", "name", {name: ""}))
})
},
Run: function(event, args, cb) {var plugin = field.Plugin
var script = page.script()
if (args[0] && !script[args[0]]) {
return confirm("create script "+args[0]) && page.script("create", args[0])
}
plugin.msg = args[0]? ({append: ["index", "script"],
index: kit.List(script[args[0]], function(item, index) {return index+""}),
script: kit.List(script[args[0]], function(item) {return item.join(" ")}),
}): ({append: ["name", "count"],
name: kit.Item(script),
count: kit.Item(script, function(key, list) {return list.length+""}),
}), plugin.display("table", cb)
},
}}

View File

@ -1,3 +0,0 @@
fieldset.item.feature div.output {
}

View File

@ -1,36 +0,0 @@
package main
import (
"contexts/cli"
"contexts/ctx"
"toolkit"
"fmt"
"os"
)
var Index = &ctx.Context{Name: `feature`, Help: `plugin`,
Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{
"_index": &ctx.Config{Name: "index", Value: []interface{}{
map[string]interface{}{"name": "demo", "help": "demo",
"tmpl": "componet", "view": "", "init": "",
"type": "public", "ctx": "demo", "cmd": "demo",
"args": []interface{}{}, "inputs": []interface{}{
map[string]interface{}{"type": "text", "name": "pod", "value": "hello world"},
map[string]interface{}{"type": "button", "value": "执行"},
},
},
}},
},
Commands: map[string]*ctx.Command{
"demo": {Name: "demo", Help: "demo", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Echo(kit.Select("hello world", arg, 0))
return
}},
},
}
func main() {
fmt.Print(cli.Index.Plugin(Index, os.Args[1:]))
}

View File

@ -1,2 +0,0 @@
Plugin["feature/index.js"] = function(field, option, output) {return {
}}

View File

@ -1,42 +0,0 @@
fun date "每一天" "index.js" "index.css" protected \
text "love" name "table" imports plugin_table view tiny \
text "2019-10-16" name "起始时间" \
text "" name "截止时间" init date \
button "日历" action auto \
button "记录" cb data \
button "展示" cb show \
exports index ""
if $2 == "" || $3 == ""
copy skip ssh.data show _ fields id when where what
else
copy skip cli.date $2 nature $3 space true format '<span class="%s">%s</span>' "s20060102"
end
end
kit progress "任务进度" public "_:web.team.task" "@you" progress \
text "task" name table \
text "30" name limit \
text "0" name offset \
feature detail action finish cancel prepare \
button "查看" action auto
kit create "创建任务" public "_:web.team.task" "@you" create \
text "task" name table \
select "3" name level values 1 values 2 values 3 values 4 values 5 \
select "" name class values add values opt values fix \
select "" name status values prepare values action values finish values cancel \
text "" name begin_time init date width "108px" before br \
text "" name close_time init date width "108px" \
text "" name target view long before br \
textarea "" name detail half "4" \
button "添加" before br
kit select "查看任务" public "_:web.team.task" "@you" \
text "task" name table imports pluing_table \
text "" name index imports plugin_task_id action auto \
button "查看" action auto \
button "返回" cb Last \
feature detail "修改" "复制" "下载" \
exports task_id id

View File

@ -1,37 +0,0 @@
fieldset.item.love.date table td.today {
border:solid 2px red;
}
fieldset.item.love.date table td {
text-align:center;
min-width:40px;
}
fieldset.item.love.days div.day {
margin:8px;
border:solid 2px cyan;
padding:8px;
opacity:0;
float:left;
}
fieldset.item.love.days span.what {
font-size:24px;
}
fieldset.item.love.days span.day0 {
font-size:32px;
color:red;
}
fieldset.item.love.days span.day1 {
font-size:32px;
color:green;
}
fieldset.item.love.media table td {
text-align:center;
min-width:60px;
}
fieldset.item.love.pics img {
border:solid 2px red;
margin:10px;
}

View File

@ -1,36 +0,0 @@
package main
import (
"contexts/cli"
"contexts/ctx"
"toolkit"
"fmt"
"os"
)
var Index = &ctx.Context{Name: "test", Help: "测试工具",
Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{
"_index": &ctx.Config{Name: "index", Value: []interface{}{
map[string]interface{}{"name": "demo", "help": "demo",
"tmpl": "componet", "view": "", "init": "",
"type": "public", "ctx": "demo", "cmd": "demo",
"args": []interface{}{}, "inputs": []interface{}{
map[string]interface{}{"type": "text", "name": "pod", "value": "hello world"},
map[string]interface{}{"type": "button", "value": "执行"},
},
},
}},
},
Commands: map[string]*ctx.Command{
"demo": {Name: "demo", Help: "demo", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Echo(kit.Select("hello world", arg, 0))
return
}},
},
}
func main() {
fmt.Print(cli.Index.Plugin(Index, os.Args[1:]))
}

View File

@ -1,78 +0,0 @@
Plugin["love/index.js"] = function(field, option, output) {return {
data: function(event) {var plugin = field.Plugin
plugin.Run(event, [option.table.value], function(msg) {
plugin.ondaemon(msg)
})
},
show: function(event) {var plugin = field.Plugin
plugin.Check(event, undefined, function(msg) {
plugin.Run(event, [option.table.value], function(msg) {
kit.List(msg.Table(), function(line) {
kit.Selector(output, ".s"+line.when.split(" ")[0].split("-").join(""), function(item) {
kit.classList.add(item.parentNode, "select")
item.parentNode.title = line.what
plugin.ontoast(line.what, line.where)
})
}, 200)
}, true)
})
},
show_after: function(msg) {
kit.Selector(output, ".s"+ kit.time().split(" ")[0].split("-").join(""), function(item) {
kit.classList.add(item.parentNode, "today")
})
},
onexport: {"": function(value, name, line) {var plugin = field.Plugin
switch (field.Meta.name) {
case "days": plugin.flash(line, function(list) {
return kit.AppendChilds(output, list)
}); break
case "date":
plugin.Check(event, undefined, function(msg) {
kit.Selector(output, ".s"+line.when.split(" ")[0].split("-").join(""), function(item) {
kit.classList.add(item.parentNode, "select")
item.parentNode.title = line.what
})
})
break
case "detail":
kit.Change(event.target, function(value) {
plugin.Run(event, ["update", option.table.value, option.index.value, line.key, value], function(msg) {
kit.Log("ok")
})
})
break
}
return line.id
}},
flash: function(line, cb, index, array) {var plugin = field.Plugin
var now = new Date()
var day = new Date(line.when)
var mis = parseInt((day.getTime() - now.getTime()) / 1000 / 3600 / 24)
if (array && index == array.length-1) {
mis = 999999
}
var list = kit.Span()
list.span(["距", "day"], line.when.split(" ")[0])
list.span(["在", "day"], line.where)
list.span([line.what, "what"])
list.span(mis>0? "还有": "过去", [mis, mis>0? "day1": "day0"], "天")
kit.Opacity(cb([{text: [list.join(""), "div", "day"]}]).last)
},
Order: function(t, cb, cbs) {var plugin = field.Plugin
kit.List(plugin.msg.Table().concat([{when: "9999-01-08", what: "最后一次爱你", where: "北京市"}]), function(line, index, array) {
plugin.flash(line, cb, index, array)
}, t, cbs)
},
Flash: function(event) {var plugin = field.Plugin
plugin.Order(1000, function(list) {
return kit.AppendChilds(output, list)
}, function() {
output.innerHTML = "", plugin.Order(400, function(list) {
return kit.AppendChild(output, list)
})
})
},
}}

View File

@ -1,103 +0,0 @@
fun date "每一天" "index.js" "index.css" protected \
text "love" name "table" imports plugin_table view tiny \
text "2019-07-08" name "起始时间" \
text "" name "截止时间" init date \
button "日历" action auto \
button "记录" cb data \
button "展示" cb show \
exports index ""
if $2 == "" || $3 == ""
copy skip ssh.data show _ fields id when where what
else
copy skip cli.date $2 nature $3 space true format '<span class="%s">%s</span>' "s20060102"
end
end
fun maps "每一面" "maps.js" "index.css" protected \
text "love" name table imports plugin_table \
text "" name when init date \
text "" name what view long \
button "本地" cb Current \
text "北京市" name city view tiny \
text "弘源首著" name where \
button "搜索" cb Search \
button "记录" cb Record \
button "展示" cb Flashs \
exports index ""
if $2 == "" || $3 == ""
copy skip ssh.data show _
else
copy ssh.data insert _ when _ what _ city _ where _
end
end
fun days "每一次" "index.js" "index.css" protected \
text "love" name table imports plugin_table \
text "" name when init date \
text "" name what view long \
button "记录" \
button "展示" cb Flash \
exports index ""
if $2 == "" || $3 == ""
copy skip ssh.data show _ fields id when where what
else
copy ssh.data insert _ when _ what __
end
end
fun detail "详情" "index.js" protected \
text "love" name table imports plugin_table \
text "1" name index imports plugin_index action auto view tiny \
button "查看"
if $1 == "update"
copy ssh.data
else
copy ssh.data show
end
end
kit append "扩展" "index.js" protected "ssh.data" update _ _ extra \
text "love" name table imports plugin_table \
text "1" name index imports plugin_index action auto view tiny \
text "" name field \
text "" name value \
button "添加"
kit pics "图片" "pics.js" "index.css" private "ssh.data" show \
text "image" name table imports plugin_table \
upfile "" name upload \
button "上传" cb upload \
button "记录" \
button "展示" cb show
fun delay "以后告诉你" protected \
text "delay" name table imports plugin_table \
text "" name when init date\
text "" name what view long \
button "记下了"
if $2 == "" || $3 == ""
copy skip ssh.data show _
else
copy ssh.data insert _ when _ what __
end
end
fun media "娱乐" private \
text "media" name table imports plugin_table \
select "电影" values "电影" values "音乐" values "电视剧" \
text "" name title \
text "" name link view long \
button "记下了"
if $2 == "" || $3 == "" || $4 == ""
copy skip ssh.data show $1 fields id type name link
else
copy ssh.data insert _ type _ name _ link __
end
end

View File

@ -1,63 +0,0 @@
Plugin["love/maps.js"] = function(field, option, output) {
var id
return {
initMap: function() {var plugin = field.Plugin
!id && (id = plugin.id+"map"+plugin.ID())
var width = field.parentNode.clientWidth-40
kit.AppendChilds(output, [{type: "div", data: {id: id}, style: {width: width+"px", height: width*(kit.device.isMobile? 7: 3)/5}}])
map = new BMap.Map(id)
map.addControl(new BMap.NavigationControl())
map.addControl(new BMap.ScaleControl())
map.addControl(new BMap.OverviewMapControl())
map.addControl(new BMap.MapTypeControl())
return map
},
Current: function() {
var geo = new BMap.Geolocation()
geo.getCurrentPosition(function(p) {
option.city.value = p.address.city
option.where.value = kit.Value(kit.Value(p.address.street, "")+kit.Value(p.address.street_number, ""), p.address.city)
map.centerAndZoom(p.point, map.getZoom())
})
},
Search: function() {var plugin = field.Plugin
plugin.initMap()
var g = new BMap.Geocoder()
g.getPoint(option.where.value, function(p) {
kit.Log("where", p)
if (!p) {alert("not found"); return}
map.centerAndZoom(p, 18)
}, option.city.value)
},
Record: function() {var plugin = field.Plugin
function trunc(value, len) {
len = kit.Value(len, 1000000)
return parseInt(value*len)/parseFloat(len)
}
var l = map.getCenter()
plugin.Run(event, [option.table.value, option.when.value, option.what.value, option.city.value, option.where.value,
"longitude", trunc(l.lng), "latitude", trunc(l.lat), "scale", map.getZoom()])
},
Flashs: function() {var plugin = field.Plugin
plugin.initMap(), plugin.Run(event, [option.table.value], function(msg) {
kit.List(msg.Table(), plugin.place, 1000)
}, true)
},
place: function(line) {
var p = new BMap.Point(line.longitude, line.latitude)
map.centerAndZoom(p, line.scale)
var info = new BMap.InfoWindow(line.when+"<br/>"+line.where, {width: 200, height: 100, title: line.what})
map.openInfoWindow(info, map.getCenter())
output.style.opacity = 0
kit.Opacity(output)
},
onexport: {"": function(value, name, line) {var plugin = field.Plugin
plugin.initMap(), plugin.place(line)
return line.id
}},
}}

View File

@ -1,29 +0,0 @@
Plugin["love/pics.js"] = function(field, option, output) {return {
onexport: {"": function(value, name, line) {var plugin = field.Plugin
kit.AppendChilds(output, [{img: ["/download/"+line.hash], data: {width: output.clientWidth, onclick: function() {
plugin.display("table")
}}}])
}},
show: function() {var plugin = field.Plugin
var msg = plugin.msg
var width = output.clientWidth
output.innerHTML = "", kit.List(msg.Table(), function(line) {
kit.Opacity(kit.AppendChilds(output, [{img: ["/download/"+line.hash], data: {width: width, onclick: function(event) {
}}}]).last)
}, 1000, function() {
output.innerHTML = "", kit.List(msg.Table(), function(line) {
kit.Opacity(kit.AppendChild(output, [{img: ["/download/"+line.hash], data: {width: 200, onclick: function(event) {
plugin.ontoast({width: width, height: width*3/5+40,
text: {img: ["/download/"+line.hash], data: {width: width-20, onclick: function(event) {
plugin.ontoast()
}}}, button: ["确定"], cb: function() {
plugin.ontoast()
}
})
}}}]).last)
}, 500)
})
},
}}

View File

@ -1,5 +0,0 @@
fieldset.item.mind.xls div.output table td {
text-align:center;
min-width:16px;
height:16px;
}

View File

@ -1,76 +0,0 @@
package main
import (
"contexts/cli"
"contexts/ctx"
"toolkit"
"encoding/json"
"fmt"
"os"
)
var Index = &ctx.Context{Name: "mind", Help: "思维导图",
Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{},
Commands: map[string]*ctx.Command{
"doc": {Name: "doc", Help: "文档", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
return
}},
"xls": {Name: "xls", Help: "表格", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
switch len(arg) {
case 0:
m.Cmdy("ssh.data", "show", "xls")
m.Meta["append"] = []string{"id", "title"}
case 1:
var data map[int]map[int]string
what := m.Cmd("ssh.data", "show", "xls", arg[0], "format", "object").Append("content")
json.Unmarshal([]byte(what), &data)
max, n := 0, 0
for i, v := range data {
if i > n {
n = i
}
for i := range v {
if i > max {
max = i
}
}
}
m.Log("info", "m: %d n: %d", m, n)
for k := 0; k < n + 2; k++ {
for i := 0; i < max + 2; i++ {
m.Push(kit.Format(k), kit.Format(data[k][i]))
}
}
case 2:
m.Cmdy("ssh.data", "insert", "xls", "title", arg[0], "content", arg[1])
default:
data := map[int]map[int]string{}
what := m.Cmd("ssh.data", "show", "xls", arg[0], "format", "object").Append("content")
json.Unmarshal([]byte(what), &data)
for i := 1; i < len(arg) - 2; i += 3 {
if _, ok := data[kit.Int(arg[i])]; !ok {
data[kit.Int(arg[i])] = make(map[int]string)
}
data[kit.Int(arg[i])][kit.Int(arg[i+1])] = arg[i+2]
}
m.Cmdy("ssh.data", "update", "xls", arg[0], "content", kit.Format(data))
}
return
}},
"ppt": {Name: "ppt", Help: "文稿", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
return
}},
},
}
func main() {
fmt.Print(cli.Index.Plugin(Index, os.Args[1:]))
}

View File

@ -1,55 +0,0 @@
Plugin["mind/index.js"] = function(field, option, output) {return {
onfigure: shy(function(type, msg, cb) {if (msg.event && msg.event.type == "blur") {return}
var plugin = field.Plugin
output.innerHTML = "", msg.append && kit.OrderTable(kit.AppendTable(kit.AppendChild(output, "table"), msg.Table(), msg.append), "", function(event, value, name, line, index) {
if (name == "id") {
plugin.onexport(event, value, name, line)
} else {
var td = event.target
function submit(event) {
(td.innerText = event.target.value) != value && plugin.Run(event, [option.title.value, name, index-1, event.target.value], plugin.Check)
}
kit.AppendChilds(td, [{type: "input", value: value, data: {onblur: submit, onkeyup: function(event) {
switch (event.key) {
case "Enter":
case "Tab":
break
default:
return
}
event.stopPropagation()
event.preventDefault()
}, onkeydown: function(event) {
switch (event.key) {
case "Enter":
var s = td.parentNode[event.shiftKey?"previousSibling":"nextSibling"]
s && s.querySelector("td").click()
break
case "Tab":
if (event.shiftKey) {
if (td.previousSibling) {
td.previousSibling.click()
} else {
td.parentNode.previousSibling.querySelector("td").click()
}
} else {
if (td.nextSibling) {
td.nextSibling.click()
} else {
td.parentNode.nextSibling.querySelector("td").click()
}
}
break
default:
return
}
event.stopPropagation()
event.preventDefault()
}}}]).first.focus()
}
}), typeof cb == "function" && cb(msg)
}),
}}

View File

@ -1,65 +0,0 @@
kit xls "表格" "index.js" "index.css" private context find "web.wiki" xls \
text "" name title imports plugin_xls_id action auto \
text "" name content \
button "执行" \
button "返回" cb Last \
feature style "mind" \
exports xls_id id
kit dir "目录" private "ssh._route" _ "nfs.dir" _ time size line path \
text "" name pod imports plugin_pod action auto \
text "usr/local/redis-5.0.5/src" name dir imports plugin_dir action auto view long \
button "浏览" action auto \
button "返回" cb Last \
feature display editor \
exports dir "" dir
kit grep "搜索" public "cli.system" grep _ _ "-rn" "--color" cmd_parse cut 3 ":" "file line word" \
text "" name txt imports plugin_editor_word \
text "usr/local/redis-5.0.5" name dir view long \
button "搜索" \
exports dir file "" editor_file file "" editor_index line ""
fun mark "标签" public \
text "mark" name table \
text "" name file imports plugin_editor_file view long \
text "" name index imports plugin_editor_index view tiny \
text "" name word imports plugin_editor_word \
text "" name mark view long \
button "操作" \
exports dir file "" editor_index index "" editor_word word
if $5 == ""
copy skip ssh.data show _
else
copy ssh.data insert _ file _ index _ word _ mark _
end
end
fun blog "博客" public \
text "" name tag \
text "" name url view long \
button "保存" action auto
if $2 == ""
copy skip ssh.data show blog
else
copy ssh.data insert blog tag _ url _
end
end
fun note "记事本" public \
text "" name you imports plugin_you action auto \
text "" name tip imports plugin_tip view long action auto \
button "查看" action auto \
button "返回" cb Last \
exports tip file tip \
feature display inner
if $2 == "" || $2 ~ ".*/$"
copy ssh._route _ context wiki tree __ level local/wiki
else
copy ssh._route _ context wiki text __ level local/wiki
end
end

View File

@ -1 +0,0 @@

View File

@ -1,3 +0,0 @@
fieldset.item.redis div.output {
}

View File

@ -1,36 +0,0 @@
package main
import (
"contexts/cli"
"contexts/ctx"
"toolkit"
"fmt"
"os"
)
var Index = &ctx.Context{Name: `redis`, Help: `plugin`,
Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{
"_index": &ctx.Config{Name: "index", Value: []interface{}{
map[string]interface{}{"name": "demo", "help": "demo",
"tmpl": "componet", "view": "", "init": "",
"type": "public", "ctx": "demo", "cmd": "demo",
"args": []interface{}{}, "inputs": []interface{}{
map[string]interface{}{"type": "text", "name": "pod", "value": "hello world"},
map[string]interface{}{"type": "button", "value": "执行"},
},
},
}},
},
Commands: map[string]*ctx.Command{
"demo": {Name: "demo", Help: "demo", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Echo(kit.Select("hello world", arg, 0))
return
}},
},
}
func main() {
fmt.Print(cli.Index.Plugin(Index, os.Args[1:]))
}

View File

@ -1,3 +0,0 @@
Script["redis/index.js"] = function(field, option, output) {return {
}}

View File

@ -1,54 +0,0 @@
fun download "下载" public \
text "redis-5.0.5.tar.gz" name src view long \
button "下载"
let local = "usr/local/"
let path = $local + $1 - ".tar.gz"
if $(path $path)
return $path
end
let src = "http://download.redis.io/releases/" + $1
let usr = $local + $1
web.get method GET "" $src save $usr
tar xvf $usr -C $local
make -C $path
return $path
end
kit dir "目录" public "nfs.dir" _ time size line path \
text "usr/local/redis-5.0.5" name dir imports plugin_dir action auto view long \
button "浏览" action auto \
button "返回" cb Last \
feature display editor \
exports dir "" dir
kit grep "搜索" public "nfs.grep" search _ _ "-rn" "--color" cmd_parse cut 3 ":" "file line word" \
text "" name txt imports plugin_editor_word \
text "usr/local/redis-5.0.5" name dir view long \
button "搜索" \
exports dir file "" editor_file file "" editor_index line ""
fun mark "标签" public \
text "mark" name table \
text "" name file imports plugin_editor_file view long \
text "" name index imports plugin_editor_index view tiny \
text "" name word imports plugin_editor_word \
text "" name mark view long \
button "操作" \
exports dir file "" editor_index index "" editor_word word
if $5 == ""
copy skip ssh.data show _
else
copy ssh.data insert _ file _ index _ word _ mark _
end
end
fun hello world "" "" public \
text "" \
button "执行"
copy pwd
end

View File

@ -1,198 +0,0 @@
package main
import (
"contexts/cli"
"contexts/ctx"
_ "contexts/nfs"
"toolkit"
"fmt"
"math"
"math/rand"
"os"
"strings"
)
func Merge(left []int, right []int) []int {
result := make([]int, 0, len(left)+len(right))
for len(left) > 0 || len(right) > 0 {
if len(right) == 0 || (len(left) > 0 && (left[0] < right[0])) {
result, left = append(result, left[0]), left[1:]
} else {
result, right = append(result, right[0]), right[1:]
}
}
return result
}
func MergeSort(m *ctx.Message, level int, data []int) []int {
if len(data) < 2 {
m.Add("append", kit.Format(level), fmt.Sprintf("[][]"))
return data
}
middle := len(data) / 2
m.Add("append", kit.Format(level), fmt.Sprintf("%v%v", data[:middle], data[middle:]))
return Merge(MergeSort(m, level+1, data[:middle]), MergeSort(m, level+1, data[middle:]))
}
func QuickSort(m *ctx.Message, level int, data []int, left int, right int) {
if left >= right {
return
}
p, l, r := left, left+1, right
for l < r {
for ; p < r && data[p] < data[r]; r-- {
}
if p < r {
p, data[p], data[r] = r, data[r], data[p]
}
for ; l < p && data[l] < data[p]; l++ {
}
if l < p {
p, data[l], data[p] = l, data[p], data[l]
}
}
m.Add("append", kit.Format(level), fmt.Sprintf("%v%v", data[left:p+1], data[p+1:right+1]))
QuickSort(m, level+1, data, left, p)
QuickSort(m, level+1, data, p+1, right)
}
var Index = &ctx.Context{Name: "sort", Help: "sort code",
Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{
"data": &ctx.Config{Name: "data", Value: map[string]interface{}{
"seed": []int{47, 59, 81, 40, 56, 0, 94, 11, 18, 25},
}},
"_index": &ctx.Config{Name: "index", Value: []interface{}{
map[string]interface{}{"componet_name": "select", "componet_help": "选择排序",
"componet_tmpl": "componet", "componet_view": "componet", "componet_init": "",
"componet_type": "public", "componet_ctx": "sort", "componet_cmd": "select",
"componet_args": []interface{}{}, "inputs": []interface{}{
map[string]interface{}{"type": "text", "name": "pod", "imports": "plugin_pod"},
map[string]interface{}{"type": "button", "value": "执行"},
},
},
}},
},
Commands: map[string]*ctx.Command{
"_init": &ctx.Command{Name: "_init", Help: "_init", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) > 0 {
keys := []string{}
for key, _ := range c.Commands {
if !strings.HasPrefix(key, "_") && !strings.HasPrefix(key, "/") {
keys = append(keys, key)
}
}
list := []interface{}{}
for _, key := range keys {
cmd := c.Commands[key]
list = append(list, map[string]interface{}{"componet_name": cmd.Name, "componet_help": cmd.Help,
"componet_tmpl": "componet", "componet_view": "", "componet_init": "",
"componet_ctx": "cli." + arg[0], "componet_cmd": key,
"componet_args": []interface{}{"@text", "@total"}, "inputs": []interface{}{
map[string]interface{}{"type": "input"},
map[string]interface{}{"type": "button", "value": "show"},
},
})
}
m.Confv("ssh.componet", arg[0], list)
}
return
}},
"data": &ctx.Command{Name: "data", Help: "data", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
data := []int{}
for i := 0; i < kit.Int(kit.Select("10", arg, 0)); i++ {
data = append(data, rand.Intn(kit.Int(kit.Select("100", arg, 1))))
}
m.Confv("data", "seed", data)
m.Echo("data: %v", data)
return
}},
"select": &ctx.Command{Name: "select", Help: "select", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
data := append([]int{}, m.Confv("data", "seed").([]int)...)
m.Echo("data: %v\n", data)
for i := 0; i < len(data)-1; i++ {
for j := i + 1; j < len(data); j++ {
if data[j] < data[i] {
data[i], data[j] = data[j], data[i]
}
}
m.Echo("data: %d %v %v\n", i, data[:i+1], data[i+1:])
}
m.Echo("data: %v\n", data)
return
}},
"insert": &ctx.Command{Name: "insert", Help: "insert", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
data := append([]int{}, m.Confv("data", "seed").([]int)...)
m.Echo("data: %v\n", data)
for i, j := 1, 0; i < len(data); i++ {
tmp := data[i]
for j = i - 1; j >= 0; j-- {
if data[j] < tmp {
break
}
data[j+1] = data[j]
}
data[j+1] = tmp
m.Echo("data: %d %v %v\n", i, data[:i+1], data[i+1:])
}
m.Echo("data: %v\n", data)
return
}},
"bubble": &ctx.Command{Name: "bubble", Help: "bubble", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
data := append([]int{}, m.Confv("data", "seed").([]int)...)
m.Echo("data: %v\n", data)
for i := 1; i < len(data); i++ {
finish := true
for j := 0; j < len(data)-i; j++ {
if data[j] > data[j+1] {
finish, data[j], data[j+1] = false, data[j+1], data[j]
}
}
if finish {
break
}
m.Echo("data: %d %v %v\n", i, data[:len(data)-i], data[len(data)-i:])
}
m.Echo("data: %v\n", data)
return
}},
"quick": &ctx.Command{Name: "quick", Help: "quick", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
data := append([]int{}, m.Confv("data", "seed").([]int)...)
m.Echo("data: %v\n", data)
QuickSort(m, 0, data, 0, len(data)-1)
for i := 0; i < len(data); i++ {
meta, ok := m.Meta[kit.Format(i)]
if !ok {
break
}
m.Echo("data: %v %v\n", i, meta)
}
m.Echo("data: %v\n", data)
return
}},
"merge": &ctx.Command{Name: "merge", Help: "merge", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
data := append([]int{}, m.Confv("data", "seed").([]int)...)
m.Echo("data: %v\n", data)
data = MergeSort(m, 0, data)
for i := 0; int(math.Exp2(float64(i))) < len(data); i++ {
meta, ok := m.Meta[kit.Format(i)]
if !ok {
break
}
m.Echo("data: %v %v\n", i, meta)
}
m.Echo("data: %v\n", data)
return
}},
},
}
func main() {
fmt.Print(cli.Index.Plugin(Index, os.Args[1:]))
}

View File

@ -1,36 +0,0 @@
package main
import (
"contexts/cli"
"contexts/ctx"
"toolkit"
"fmt"
"os"
)
var Index = &ctx.Context{Name: "test", Help: "测试工具",
Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{
"_index": &ctx.Config{Name: "index", Value: []interface{}{
map[string]interface{}{"name": "demo", "help": "demo",
"tmpl": "componet", "view": "componet", "init": "",
"type": "public", "ctx": "demo", "cmd": "demo",
"args": []interface{}{}, "inputs": []interface{}{
map[string]interface{}{"type": "text", "name": "pod", "value": "hello world"},
map[string]interface{}{"type": "button", "value": "执行"},
},
},
}},
},
Commands: map[string]*ctx.Command{
"demo": {Name: "demo", Help: "demo", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Echo(kit.Select("hello world", arg, 0))
return
}},
},
}
func main() {
fmt.Print(cli.Index.Plugin(Index, os.Args[1:]))
}

View File

@ -1,2 +0,0 @@
Plugin["storage/index.js"] = function(field, option, output) {return {
}}

View File

@ -1,41 +0,0 @@
fun clip "剪切板" public \
text "" name you imports plugin_you action auto \
text "" name tag \
text "" name txt view long \
button "保存" action auto
if $3 == ""
copy skip ssh._route _ data show clip
else
copy ssh._route _ data insert clip tag _ txt _
end
end
kit data "数据库" public "ssh.data" show \
text "" name table imports plugin_table action auto view long \
text "" name index imports plugin_index action auto \
button "查看" action auto \
button "返回" cb Last \
exports table table "" index id ""
kit save "导出" private "ssh.data" export \
text "love" name table imports plugin_table \
button "导出"
kit load "导入" private "ssh.data" import \
text "love" name table imports plugin_table \
text "etc/list.csv" name file \
button "导入"
kit push "上传" private "web./download/" \
upfile "" name upload \
button "上传" cb upload \
button "查看"
kit git "版本" private "ssh._route" _ "nfs.git" __ \
text "" name pod imports plugin_pod action auto \
select "" values status values diff commit values values log values init action auto \
text "" name txt action auto \
button "查看"

View File

@ -1 +0,0 @@

View File

@ -1,3 +0,0 @@
fieldset.item.story div.output {
}

View File

@ -1,36 +0,0 @@
package main
import (
"contexts/cli"
"contexts/ctx"
"toolkit"
"fmt"
"os"
)
var Index = &ctx.Context{Name: `story`, Help: `plugin`,
Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{
"_index": &ctx.Config{Name: "index", Value: []interface{}{
map[string]interface{}{"name": "demo", "help": "demo",
"tmpl": "componet", "view": "", "init": "",
"type": "public", "ctx": "demo", "cmd": "demo",
"args": []interface{}{}, "inputs": []interface{}{
map[string]interface{}{"type": "text", "name": "pod", "value": "hello world"},
map[string]interface{}{"type": "button", "value": "执行"},
},
},
}},
},
Commands: map[string]*ctx.Command{
"demo": {Name: "demo", Help: "demo", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Echo(kit.Select("hello world", arg, 0))
return
}},
},
}
func main() {
fmt.Print(cli.Index.Plugin(Index, os.Args[1:]))
}

View File

@ -1,3 +0,0 @@
Plugin["story/index.js"] = function(field, option, output) {return {
}}

View File

@ -1,51 +0,0 @@
kit share "共享" public "web.chat.share" \
select "" name kind values "wiki file" \
text "miss.md" name story imports plugin_story view long \
button "共享"
kit note "记事本" public "_:web.wiki.note" "@you" \
text "miss.md" name story imports path view long action auto \
button "查看" action auto \
button "返回" cb Last \
exports story file \
feature display inner
kit favor "收藏夹" public "_:web.wiki.story" "@you" favor \
text "see" name table imports plugin_story_table action auto \
text "" name index imports plugin_story_id view tiny action auto \
feature detail "修改" "复制" "下载" \
exports story_table table "" story_id id "" \
button "记录" action auto \
button "返回" cb Last
kit commit "记录" public "_:web.wiki.story" "@you" commit \
text "miss.md" name story imports plugin_story \
text "table" name sence \
text "hello" name enjoy \
textarea "" name happy half 4 \
button "提交"
kit branch "分支" public "ssh._route" _ "web.wiki.story" branch \
text "" name dream imports plugin_you \
button "查看"
kit remote "仓库" public "ssh._route" _ "web.wiki.story" remote \
text "" name dream imports plugin_you \
button "查看"
kit xls "表格" "index.js" "index.css" private "web.wiki.xls" \
text "" name scene imports plugin_xls_id action auto \
text "" name content \
button "执行" \
button "返回" cb Last \
feature style "mind" \
exports xls_id id
kit chart "图表" public "web.wiki.chart" \
select "" name kind values "chain block" action auto \
textarea "" name happy half 4 height "200px" \
select "" name kind values "white red yellow green blue black" action auto \
select "" name kind values "black blue green yellow red white" action auto \
feature display inner \
button "查看"

View File

@ -1,3 +0,0 @@
fieldset.item.task div.output {
}

View File

@ -1,36 +0,0 @@
package main
import (
"contexts/cli"
"contexts/ctx"
"toolkit"
"fmt"
"os"
)
var Index = &ctx.Context{Name: `task`, Help: `plugin`,
Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{
"_index": &ctx.Config{Name: "index", Value: []interface{}{
map[string]interface{}{"name": "demo", "help": "demo",
"tmpl": "componet", "view": "", "init": "",
"type": "public", "ctx": "demo", "cmd": "demo",
"args": []interface{}{}, "inputs": []interface{}{
map[string]interface{}{"type": "text", "name": "pod", "value": "hello world"},
map[string]interface{}{"type": "button", "value": "执行"},
},
},
}},
},
Commands: map[string]*ctx.Command{
"demo": {Name: "demo", Help: "demo", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Echo(kit.Select("hello world", arg, 0))
return
}},
},
}
func main() {
fmt.Print(cli.Index.Plugin(Index, os.Args[1:]))
}

View File

@ -1,3 +0,0 @@
Script["task/index.js"] = function(field, option, output) {return {
}}

View File

@ -1,14 +0,0 @@
kit task "任务" public "web.team.task" \
text "task" name table \
text "" name title \
text "" name content \
button "执行"
kit salary "工资" public "web.mall.salary" \
text "salary" name table \
text "2019-10" name month init month \
text "" name total \
text "" name base \
text "" name tax \
button "执行"

View File

@ -1,293 +0,0 @@
package main
import (
"contexts/cli"
"contexts/ctx"
"toolkit"
"bufio"
"bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"path"
"runtime"
"strings"
"sync"
"sync/atomic"
"time"
)
func Input(m *ctx.Message, file string, input chan []string) {
f, e := os.Open(file)
m.Assert(e)
defer f.Close()
nline := 0
for bio := bufio.NewScanner(f); nline < kit.Int(m.Confx("limit")) && bio.Scan(); {
word := strings.Split(bio.Text(), " ")
if len(word) != 2 {
continue
}
uri := word[0][len(m.Conf("prefix0")) : len(word[0])-1]
arg := word[1][len(m.Conf("prefix1")) : len(word[1])-1]
if len(arg) > m.Confi("nskip") {
continue
}
input <- []string{fmt.Sprintf("%d", nline), uri, arg}
if nline++; nline%kit.Int(m.Confx("nsleep")) == 0 {
fmt.Printf("nline:%d sleep 1s...\n", nline)
time.Sleep(time.Second)
}
}
close(input)
}
func Output(m *ctx.Message, output <-chan []string) {
os.MkdirAll(m.Conf("outdir"), 0777)
files := map[string]*os.File{}
for {
data, ok := <-output
if !ok {
break
}
uri := data[1]
if files[uri] == nil {
f, _ := os.Create(path.Join(m.Conf("outdir"), strings.Replace(uri, "/", "_", -1)+".txt"))
defer f.Close()
files[uri] = f
}
for _, v := range data {
fmt.Fprintf(files[uri], v)
}
}
}
func Process(m *ctx.Message, file string, cb func(*ctx.Message, *http.Client, []string, chan []string)) (int32, time.Duration) {
nline, begin := int32(0), time.Now()
input := make(chan []string, kit.Int(m.Confx("nread")))
output := make(chan []string, kit.Int(m.Confx("nwrite")))
go Input(m, file, input)
go Output(m, output)
wg := sync.WaitGroup{}
for i := 0; i < m.Confi("nwork"); i++ {
go func(msg *ctx.Message) {
wg.Add(1)
defer wg.Done()
for {
word, ok := <-input
if !ok {
break
}
atomic.AddInt32(&nline, 1)
cb(msg, &http.Client{Timeout: kit.Duration(m.Conf("timeout"))}, word, output)
}
}(m.Spawn())
}
runtime.Gosched()
wg.Wait()
close(output)
return nline, time.Since(begin)
}
func Compare(b1 []byte, b2 []byte) bool {
if len(b1) != len(b2) {
return false
}
if bytes.Compare(b1, b2) == 0 {
return true
}
var d1, d2 interface{}
json.Unmarshal(b1, &d1)
json.Unmarshal(b2, &d2)
s1, _ := json.Marshal(d1)
s2, _ := json.Marshal(d2)
if bytes.Compare(s1, s2) == 0 {
return true
}
return false
}
var Index = &ctx.Context{Name: "test", Help: "测试工具",
Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{
"nread": {Name: "nread", Help: "读取Channel长度", Value: 1},
"nwork": {Name: "nwork", Help: "协程数量", Value: 20},
"limit": {Name: "limit", Help: "请求数量", Value: 100},
"nskip": {Name: "nskip", Help: "请求限长", Value: 100},
"nsleep": {Name: "nsleep", Help: "阻塞时长", Value: "10000"},
"nwrite": {Name: "nwrite", Help: "输出Channel长度", Value: 1},
"outdir": {Name: "outdir", Help: "输出目录", Value: "tmp"},
"timeout": {Name: "timeout", Help: "请求超时", Value: "10s"},
"prefix0": {Name: "prefix0", Help: "请求前缀", Value: "uri["},
"prefix1": {Name: "prefix1", Help: "参数前缀", Value: "request_param["},
"_index": &ctx.Config{Name: "index", Value: []interface{}{
map[string]interface{}{"componet_name": "status", "componet_help": "状态",
"componet_tmpl": "componet", "componet_view": "Company", "componet_init": "",
"componet_type": "private", "componet_ctx": "test", "componet_cmd": "diff",
"componet_args": []interface{}{}, "inputs": []interface{}{
map[string]interface{}{"type": "text", "name": "pod", "imports": "plugin_pod"},
map[string]interface{}{"type": "select", "name": "sub", "values": []interface{}{"status", ""}},
map[string]interface{}{"type": "button", "value": "执行"},
},
},
}},
},
Commands: map[string]*ctx.Command{
"diff": {Name: "diff file server1 server2", Form: map[string]int{"nsleep": 1}, Help: "接口对比工具", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) < 3 {
m.Echo("usage: %v", "diff file server1 server2")
return
}
var diff, same, error int32 = 0, 0, 0
api := map[string]int{}
mu := sync.Mutex{}
nline, cost := Process(m, arg[0], func(msg *ctx.Message, client *http.Client, word []string, output chan []string) {
key, uri, args := word[0], word[1], word[2]
mu.Lock()
api[uri]++
mu.Unlock()
begin := time.Now()
res1, e1 := client.Post(arg[1]+uri, "application/json", bytes.NewReader([]byte(args)))
t1 := time.Since(begin)
begin = time.Now()
res2, e2 := client.Post(arg[2]+uri, "application/json", bytes.NewReader([]byte(args)))
t2 := time.Since(begin)
size1, size2 := 0, 0
result := "error"
var t3, t4 time.Duration
if e1 != nil || e2 != nil {
atomic.AddInt32(&error, 1)
fmt.Printf("%v %d cost: %v/%v error: %v %v\n", key, error, t1, t2, e1, e2)
} else if res1.StatusCode != http.StatusOK || res2.StatusCode != http.StatusOK {
atomic.AddInt32(&error, 1)
fmt.Printf("%v %d %s %s cost: %v/%v error: %v %v\n", key, error, "error", uri, t1, t2, res1.StatusCode, res2.StatusCode)
} else {
begin = time.Now()
b1, _ := ioutil.ReadAll(res1.Body)
b2, _ := ioutil.ReadAll(res2.Body)
t3 = time.Since(begin)
begin = time.Now()
var num int32
if Compare(b1, b2) {
atomic.AddInt32(&same, 1)
num = same
result = "same"
} else {
atomic.AddInt32(&diff, 1)
num = diff
result = "diff"
result1 := []string{
fmt.Sprintf("index:%v uri:", key),
fmt.Sprintf(uri),
fmt.Sprintf(" arguments:"),
fmt.Sprintf(args),
}
result1 = append(result1, "\n")
result1 = append(result1, "\n")
result1 = append(result1, "result0:")
result1 = append(result1, string(b1))
result1 = append(result1, "\n")
result1 = append(result1, "\n")
result1 = append(result1, "result1:")
result1 = append(result1, string(b2))
result1 = append(result1, "\n")
result1 = append(result1, "\n")
output <- result1
}
size1 = len(b1)
size2 = len(b2)
t4 = time.Since(begin)
fmt.Printf("%v %d %s %s size: %v/%v cost: %v/%v diff: %v/%v\n", key, num, result, uri, len(b1), len(b2), t1, t2, t3, t4)
}
mu.Lock()
m.Add("append", "uri", uri)
m.Add("append", "time1", t1/1000000)
m.Add("append", "time2", t2/1000000)
m.Add("append", "time3", t3/1000000)
m.Add("append", "time4", t4/1000000)
m.Add("append", "size1", size1)
m.Add("append", "size2", size2)
m.Add("append", "action", result)
mu.Unlock()
})
fmt.Printf("\n\nnuri: %v nreq: %v same: %v diff: %v error: %v cost: %v\n\n", len(api), nline, same, diff, error, cost)
m.Sort("time1", "int").Table()
return
}},
"cost": {Name: "cost file server nroute", Help: "接口耗时测试", Form: map[string]int{"nwork": 1, "limit": 1, "nsleep": 1}, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
var success int32 = 0
var times time.Duration
mu := sync.Mutex{}
limit := kit.Int(m.Confx("limit"))
nline := 0
_, cost := Process(m, arg[0], func(msg *ctx.Message, client *http.Client, word []string, output chan []string) {
key, uri, args := word[0], word[1], word[2]
for _, host := range arg[1:] {
fmt.Printf("%v/%v post: %v\t%v\n", key, limit, host+uri, args)
begin := time.Now()
res, err := client.Post(host+uri, "application/json", bytes.NewReader([]byte(args)))
if res.StatusCode == http.StatusOK {
io.Copy(ioutil.Discard, res.Body)
atomic.AddInt32(&success, 1)
} else {
fmt.Printf("%v/%v error: %v\n", key, limit, err)
}
t := time.Since(begin)
times += t
mu.Lock()
nline++
m.Add("append", "host", host)
m.Add("append", "uri", uri)
m.Add("append", "cost", t/1000000)
mu.Unlock()
}
})
m.Sort("cost", "int_r")
m.Echo("\n\nnclient: %v nreq: %v success: %v time: %v average: %vms",
m.Confx("nwork"), nline, success, cost, int(times)/int(nline)/1000000)
return
}},
"cmd": {Name: "cmd file", Help: "生成测试命令", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
str := kit.Select("./hey -n 10000 -c 100 -m POST -T \"application/json\" -d '%s' http://127.0.0.1:6363%s\n", arg, 1)
Process(m, arg[0], func(msg *ctx.Message, client *http.Client, word []string, output chan []string) {
m.Echo(str, word[2], word[1])
})
return
}},
},
}
func main() {
fmt.Print(cli.Index.Plugin(Index, os.Args[1:]))
}

View File

@ -1,253 +0,0 @@
package main
import (
"contexts/cli"
"contexts/ctx"
"toolkit"
"fmt"
"os"
"strings"
"time"
)
var Index = &ctx.Context{Name: "tmux", Help: "终端管理",
Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{
"mux": &ctx.Config{Name: "mux", Value: map[string]interface{}{
"cmd_timeout": "100ms",
"view": map[string]interface{}{
"session": []interface{}{
"session_id",
"session_name",
"session_windows",
"session_height",
"session_width",
"session_created_string",
},
"window": []interface{}{
"window_id",
"window_name",
"window_panes",
"window_height",
"window_width",
},
"pane": []interface{}{
"pane_id",
"pane_index",
"pane_tty",
"pane_height",
"pane_width",
},
},
"bind": map[string]interface{}{
"0": map[string]interface{}{},
"1": map[string]interface{}{
"x": []interface{}{"kill-session"},
},
"2": map[string]interface{}{
"x": []interface{}{"kill-window"},
"s": []interface{}{"swap-window", "-s"},
"e": []interface{}{"rename-window"},
},
"3": map[string]interface{}{
"x": []interface{}{"kill-pane"},
"b": []interface{}{"break-pane"},
"h": []interface{}{"split-window", "-h"},
"v": []interface{}{"split-window", "-v"},
"r": []interface{}{"send-keys"},
"p": []interface{}{"pipe-pane"},
"g": []interface{}{"capture-pane", "-p"},
"s": []interface{}{"swap-pane", "-d", "-s"},
"mh": []interface{}{"move-pane", "-h", "-s"},
"mv": []interface{}{"move-pane", "-v", "-s"},
"H": []interface{}{"resize-pane", "-L"},
"L": []interface{}{"resize-pane", "-R"},
"J": []interface{}{"resize-pane", "-D"},
"K": []interface{}{"resize-pane", "-U"},
"Z": []interface{}{"resize-pane", "-Z"},
},
},
}, Help: "文档管理"},
},
Commands: map[string]*ctx.Command{
"mux": &ctx.Command{Name: "mux [session [window [pane]]] args...", Help: "终端管理", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
// 会话列表
if len(arg) == 0 {
view := kit.View([]string{"session"}, m.Confm("mux", "view"))
for _, row := range strings.Split(strings.TrimSpace(m.Cmdx("cli.system", "tmux", "list-sessions", "-F", fmt.Sprintf("#{%s}", strings.Join(view, "},#{")))), "\n") {
for j, col := range strings.Split(row, ",") {
m.Add("append", view[j], col)
}
}
for i, k := range m.Meta["append"] {
if strings.HasPrefix(k, "session_") {
x := strings.TrimPrefix(k, "session_")
m.Meta["append"][i] = x
m.Meta[x] = m.Meta[k]
}
}
m.Table()
return
}
if v := m.Confv("mux", []string{"bind", "0", arg[0]}); v != nil {
m.Cmdy("cli.system", "tmux", v, arg[1:])
return
}
//窗口列表
if len(arg) == 1 {
view := kit.View([]string{"window"}, m.Confm("mux", "view"))
for _, row := range strings.Split(strings.TrimSpace(m.Cmdx("cli.system", "tmux", "list-windows", "-t", arg[0], "-F", fmt.Sprintf("#{%s}", strings.Join(view, "},#{")))), "\n") {
for j, col := range strings.Split(row, ",") {
m.Add("append", view[j], col)
}
}
for i, k := range m.Meta["append"] {
if strings.HasPrefix(k, "window_") {
x := strings.TrimPrefix(k, "window_")
m.Meta["append"][i] = x
m.Meta[x] = m.Meta[k]
}
}
m.Table()
return
}
switch arg[1] {
// 创建会话
case "create":
m.Cmdy("cli.system", "tmux", "new-session", "-s", arg[0], arg[2:], "-d", "cmd_env", "TMUX", "")
return
// 检查会话
case "exist":
m.Cmdy("cli.system", "tmux", "has-session", "-t", arg[0])
return
// 会话操作
default:
if v := m.Confv("mux", []string{"bind", "1", arg[1]}); v != nil {
m.Cmdy("cli.system", "tmux", v, "-t", arg[0], arg[2:])
return
}
}
target := fmt.Sprintf("%s:%s", arg[0], arg[1])
// 面板列表
if len(arg) == 2 {
view := kit.View([]string{"pane"}, m.Confm("mux", "view"))
for _, row := range strings.Split(strings.TrimSpace(m.Cmdx("cli.system", "tmux", "list-panes", "-t", target, "-F", fmt.Sprintf("#{%s}", strings.Join(view, "},#{")))), "\n") {
for j, col := range strings.Split(row, ",") {
m.Add("append", view[j], col)
}
}
for i, k := range m.Meta["append"] {
if strings.HasPrefix(k, "pane_") {
x := strings.TrimPrefix(k, "pane_")
m.Meta["append"][i] = x
m.Meta[x] = m.Meta[k]
}
}
m.Table()
return
}
switch arg[2] {
// 创建窗口
case "create":
m.Cmdy("cli.system", "tmux", "new-window", "-t", arg[0], "-n", arg[1], arg[3:])
return
// 窗口操作
default:
if v := m.Confv("mux", []string{"bind", "2", arg[2]}); v != nil {
m.Cmdy("cli.system", "tmux", v, arg[3:], "-t", target)
return
}
}
// 面板内容
if target = fmt.Sprintf("%s:%s.%s", arg[0], arg[1], arg[2]); len(arg) == 3 {
m.Cmdy("cli.system", "tmux", "capture-pane", "-t", target, "-p")
return
}
switch arg[3] {
case "split":
ls := strings.Split(m.Cmdx("cli.system", "tmux", "capture-pane", "-t", target, "-p"), "\n")
for i := 1; i < len(ls)-1; i++ {
for j, v := range strings.Split(ls[i], " ") {
m.Push(kit.Format(j), v)
}
}
m.Table()
case "run":
m.Cmd("cli.system", "tmux", "send-keys", "-t", target, "clear", "Enter")
time.Sleep(kit.Duration(m.Conf("mux", "cmd_timeout")))
prompt := strings.TrimSpace(m.Cmdx("cli.system", "tmux", "capture-pane", "-t", target, "-p"))
m.Log("info", "wait for prompt %v", prompt)
m.Cmd("cli.system", "tmux", "send-keys", "-t", target, strings.Join(arg[4:], " "), "Enter")
for i := 0; i < 1000; i++ {
time.Sleep(kit.Duration(m.Conf("mux", "cmd_timeout")))
list := strings.Split(m.Cmdx("cli.system", "tmux", "capture-pane", "-t", target, "-p"), "\n")
m.Log("info", "current %v", list)
for j := len(list) - 1; j >= 0; j-- {
if list[j] != "" {
if list[j] == prompt {
i = 1000
}
break
}
}
}
return
}
if v := m.Confv("mux", []string{"bind", "3", arg[3]}); v != nil {
switch arg[3] {
case "r":
m.Cmd("cli.system", "tmux", "send-keys", "-t", target, "clear", "Enter")
m.Cmd("cli.system", "tmux", "clear-history", "-t", target)
time.Sleep(kit.Duration("10ms"))
m.Cmd("cli.system", "tmux", "send-keys", "-t", target, strings.Join(arg[4:], " "), "Enter")
time.Sleep(kit.Duration(m.Conf("mux", "cmd_timeout")))
m.Cmdy("cli.system", "tmux", "capture-pane", "-t", target, "-p", "-S", "-1000")
case "p":
m.Cmdy("cli.system", "tmux", "pipe-pane", "-t", target, arg[4:])
default:
m.Cmdy("cli.system", "tmux", v, arg[4:], "-t", target)
}
return
}
m.Cmdy("cli.system", "tmux", "send-keys", "-t", target, arg[3:])
return
}},
"buf": &ctx.Command{Name: "buf", Help: "缓存管理", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
if len(arg) > 0 {
msg := m.Cmd(".buf")
arg[0] = msg.Meta[msg.Meta["append"][0]][0]
}
switch len(arg) {
case 0:
m.Cmdy("cli.system", "tmux", "list-buffer", "cmd_parse", "cut", 3, ":", "cur bytes text")
case 2:
m.Cmdy("cli.system", "tmux", "set-buffer", "-b", arg[0], arg[1])
fallthrough
case 1:
m.Cmdy("cli.system", "tmux", "show-buffer", "-b", arg[0])
}
return
}},
},
}
func main() {
fmt.Print(cli.Index.Plugin(Index, os.Args[1:]))
}

View File

@ -1,3 +0,0 @@
Plugin["tmux/index.js"] = function(field, option, output) {return {
}}

View File

@ -1,60 +0,0 @@
kit buffer "粘贴板" private buf \
text "0" name index imports plugin_tmux_bindex action auto \
text "" name txt action auto \
button "查看" action auto \
button "返回" cb Last \
exports tmux_bindex cur
fun list "列表" "" "" private \
text "docker" name table imports plugin_table \
text "" name txt \
text "" name cmd view long \
button "记录" \
exports tmux_cmd cmd
if $2 == "" || $3 == ""
copy skip ssh.data show _ fields id txt cmd
else
copy ssh.data insert _ txt _ cmd __
end
end
kit session "会话" private mux \
button "查看" action auto \
exports tmux_sess name
kit windows "窗口" private mux \
text "context" imports plugin_tmux_sess action auto \
button "查看" \
exports tmux_wins name
kit pane "面板" private mux \
text "context" imports plugin_tmux_sess \
text "docker" imports plugin_tmux_wins action auto \
button "查看" \
exports tmux_pane index
kit view "内容" private mux \
text "context" imports plugin_tmux_sess \
text "docker" imports plugin_tmux_wins \
text "4" imports plugin_tmux_pane action auto view tiny \
button "查看"
kit cmd "命令" private mux _ _ _ r \
text "context" imports plugin_tmux_sess \
text "docker" imports plugin_tmux_wins \
text "4" imports plugin_tmux_pane view tiny \
text "pwd" view full imports plugin_tmux_cmd \
button "执行"
kit list "内容" private mux _ _ _ split \
text "context" imports plugin_tmux_sess \
text "docker" imports plugin_tmux_wins \
text "4" imports plugin_tmux_pane action auto view tiny \
button "查看"
kit json "解析" private "nfs.json" \
text "" view full \
button "执行"

View File

@ -1 +0,0 @@

View File

@ -1,3 +0,0 @@
fieldset.item.vim div.output {
}

View File

@ -1,36 +0,0 @@
package main
import (
"contexts/cli"
"contexts/ctx"
"toolkit"
"fmt"
"os"
)
var Index = &ctx.Context{Name: `vim`, Help: `plugin`,
Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{
"_index": &ctx.Config{Name: "index", Value: []interface{}{
map[string]interface{}{"name": "demo", "help": "demo",
"tmpl": "componet", "view": "", "init": "",
"type": "public", "ctx": "demo", "cmd": "demo",
"args": []interface{}{}, "inputs": []interface{}{
map[string]interface{}{"type": "text", "name": "pod", "value": "hello world"},
map[string]interface{}{"type": "button", "value": "执行"},
},
},
}},
},
Commands: map[string]*ctx.Command{
"demo": {Name: "demo", Help: "demo", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Echo(kit.Select("hello world", arg, 0))
return
}},
},
}
func main() {
fmt.Print(cli.Index.Plugin(Index, os.Args[1:]))
}

View File

@ -1,3 +0,0 @@
Script["vim/index.js"] = function(field, option, output) {return {
}}

View File

@ -1,89 +0,0 @@
kit tips "便签" private "_:web.code.favor" "@you" list \
text "tip" name table view tiny \
text "" name index imports plugin_vim_favor view tiny action auto \
text "" name limit view tiny \
text "" name offend view tiny \
feature detail "修改" "复制" "下载" \
exports vim_favor id \
button "查看" action auto \
button "返回" cb Last
kit favor "收藏" private "_:web.code.favor" "@you" post \
text "tip" name table view tiny \
text "" name tab \
text "" name note \
text "" name word imports plugin_vim_word \
text "" name file imports plugin_vim_file \
text "" name line imports plugin_vim_line view tiny \
text "" name col imports plugin_vim_col view tiny \
button "添加"
kit editor "编辑器" private "web.code.login" list vim \
text "" name vim_sid action auto \
text "" name dream imports plugin_you \
text "" name topic imports plugin_see \
feature detail "prune" "复制" "下载" \
exports vim_sid sid \
button "查看" action auto \
button "返回" cb Last
kit opens "文件记录" private "web.code.trend" list "vim.opens" \
text "" name index imports plugin_vim_opens view tiny action auto \
text "" name limit view tiny \
text "" name offend view tiny \
exports vim_opens id "" vim_file file \
button "查看" action auto \
button "返回" cb Last
kit cmds "命令记录" private "web.code.trend" list "vim.cmds" \
text "" name index imports plugin_vim_cmds view tiny action auto \
text "" name limit view tiny \
text "" name offend view tiny \
exports vim_cmds id "" vim_file file \
button "查看" action auto \
button "返回" cb Last
kit txts "插入记录" private "web.code.trend" list "vim.txts" \
text "" name index imports plugin_vim_txts view tiny action auto \
text "" name limit view tiny \
text "" name offend view tiny \
exports vim_txts id "" vim_word word "" vim_file file "" vim_line line "" vim_col col "" \
button "查看" action auto \
button "返回" cb Last
kit bufs "文件缓存" private "web.code.state" list vim bufs \
text "" name vim_sid action auto \
text "tag" name match view tiny \
text "" name value view tiny \
exports vim_file file "" vim_line line \
button "查看" action auto
kit regs "粘贴缓存" private "web.code.state" list vim regs \
text "" name vim_sid action auto \
text "reg" name match view tiny \
text "" name value view tiny \
exports vim_word word \
button "查看" action auto
kit marks "文件标记" private "web.code.state" list vim marks \
text "" name vim_sid action auto \
text "mark" name match view tiny \
text "" name value view tiny \
exports vim_file file "" vim_line line "" vim_col col "" \
button "查看" action auto
kit tags "语法标记" private "web.code.state" list vim tags \
text "" name vim_sid action auto \
text "tag" name match view tiny \
text "" name value view tiny \
exports vim_file file "" vim_line line "" vim_word tag "" \
button "查看" action auto
kit fixs "项目索引" private "web.code.state" list vim fixs \
text "" name vim_sid action auto \
text "files" name value view tiny \
text "" name value view tiny \
exports vim_file file "" vim_line line "" vim_word word "" \
button "查看" action auto

View File

@ -1,2 +0,0 @@
fieldset.item.demo div.output {
}

View File

@ -1,238 +0,0 @@
package main
import (
"contexts/cli"
"contexts/ctx"
"contexts/web"
"toolkit"
"crypto/sha1"
"encoding/hex"
"encoding/json"
"encoding/xml"
"net/http"
"net/url"
"sort"
"fmt"
"os"
"strings"
"time"
)
func Marshal(m *ctx.Message, meta string) string {
b, e := xml.Marshal(struct {
CreateTime int64
FromUserName string
ToUserName string
MsgType string
Content string
XMLName xml.Name `xml:"xml"`
}{
time.Now().Unix(),
m.Option("selfname"), m.Option("username"),
meta, strings.Join(m.Meta["result"], ""), xml.Name{},
})
m.Assert(e)
m.Set("append").Set("result").Echo(string(b))
return string(b)
}
var Index = &ctx.Context{Name: "weixin", Help: "微信后台",
Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{
"chat": &ctx.Config{Name: "chat", Value: map[string]interface{}{
"appid": "", "appmm": "", "token": "", "site": "https://shylinux.com",
"auth": "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=STATE#wechat_redirect",
"access": map[string]interface{}{"token": "", "expire": 0, "url": "/cgi-bin/token?grant_type=client_credential"},
"ticket": map[string]interface{}{"value": "", "expire": 0, "url": "/cgi-bin/ticket/getticket?type=jsapi"},
}, Help: "聊天记录"},
"mp": &ctx.Config{Name: "chat", Value: map[string]interface{}{
"appid": "", "appmm": "", "token": "", "site": "https://shylinux.com",
"auth": "/sns/jscode2session?grant_type=authorization_code",
"tool_path": "/Applications/wechatwebdevtools.app/Contents/MacOS/cli",
"project_path": "/Users/shaoying/context/usr/client/mp",
}, Help: "聊天记录"},
},
Commands: map[string]*ctx.Command{
"access": &ctx.Command{Name: "access", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Option("format", "object")
m.Option("temp_expire", "1")
now := kit.Int(time.Now().Unix())
access := m.Confm("chat", "access")
if kit.Int(access["expire"]) < now {
msg := m.Cmd("web.get", "wexin", access["url"], "appid", m.Conf("chat", "appid"), "secret", m.Conf("chat", "appmm"), "temp", "data")
access["token"] = msg.Append("access_token")
access["expire"] = int(msg.Appendi("expires_in")) + now
}
m.Echo("%v", access["token"])
return
}},
"ticket": &ctx.Command{Name: "ticket", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Option("format", "object")
m.Option("temp_expire", "1")
now := kit.Int(time.Now().Unix())
ticket := m.Confm("chat", "ticket")
if kit.Int(ticket["expire"]) < now {
msg := m.Cmd("web.get", "wexin", ticket["url"], "access_token", m.Cmdx(".access"), "temp", "data")
ticket["value"] = msg.Append("ticket")
ticket["expire"] = int(msg.Appendi("expires_in")) + now
}
m.Echo("%v", ticket["value"])
return
}},
"js_token": &ctx.Command{Name: "js_token", Help: "zhihu", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
nonce := []string{
"jsapi_ticket=" + m.Cmdx(".ticket"),
"noncestr=" + m.Append("nonce", "what"),
"timestamp=" + m.Append("timestamp", kit.Int(time.Now())),
"url=" + m.Append("url", m.Conf("chat", "site")+m.Option("index_url")),
}
sort.Strings(nonce)
h := sha1.Sum([]byte(strings.Join(nonce, "&")))
m.Append("signature", hex.EncodeToString(h[:]))
m.Append("appid", m.Conf("chat", "appid"))
m.Append("remote_ip", m.Option("remote_ip"))
m.Append("auth2.0", fmt.Sprintf(m.Conf("chat", "auth"), m.Conf("chat", "appid"),
url.QueryEscape(fmt.Sprintf("%s%s", m.Conf("chat", "site"), m.Option("index_url"))), kit.Select("snsapi_base", m.Option("scope"))))
return
}},
"/chat": &ctx.Command{Name: "user", Help: "应用示例", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
// 信息验证
nonce := []string{m.Option("timestamp"), m.Option("nonce"), m.Conf("chat", "token")}
sort.Strings(nonce)
h := sha1.Sum([]byte(strings.Join(nonce, "")))
if hex.EncodeToString(h[:]) == m.Option("signature") {
// m.Echo(m.Option("echostr"))
} else {
return
}
// 解析数据
var data struct {
MsgId int64
CreateTime int64
ToUserName string
FromUserName string
MsgType string
Content string
}
r := m.Optionv("request").(*http.Request)
m.Assert(xml.NewDecoder(r.Body).Decode(&data))
m.Option("username", data.FromUserName)
m.Option("selfname", data.ToUserName)
// 创建会话
m.Option("sessid", m.Cmdx("aaa.user", "session", "select"))
m.Option("bench", m.Cmdx("aaa.sess", "bench", "select"))
m.Option("current_ctx", kit.Select("chat", m.Magic("bench", "current_ctx")))
switch data.MsgType {
case "text":
m.Echo(web.Merge(m, map[string]interface{}{"path": "chat"}, m.Conf("chat", "site"), "sessid", m.Option("sessid")))
if !m.Cmds("aaa.auth", "username", m.Option("usernmae"), "data", "chat.default") && m.Option("username") != m.Conf("runtime", "work.name") {
if m.Cmds("ssh.work", "share", m.Option("username")) {
m.Cmd("aaa.auth", "username", m.Option("username"), "data", "nickname", "someone")
m.Cmds("aaa.auth", "username", m.Option("username"), "data", "chat.default", m.Spawn().Cmdx(".ocean", "spawn", "", m.Option("username")+"@"+m.Conf("runtime", "work.name")))
}
}
Marshal(m, "text")
return
// 执行命令
cmd := strings.Split(data.Content, " ")
if !m.Cmds("aaa.work", m.Option("bench"), "right", data.FromUserName, "chat", cmd[0]) {
m.Echo("no right %s %s", "chat", cmd[0])
} else if m.Cmdy("cli.source", data.Content); m.Appends("redirect") {
}
Marshal(m, "text")
}
return
}},
"share": &ctx.Command{Name: "share", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Echo("%s?bench=%s&sessid=%s", m.Conf("chat", "site"), m.Option("bench"), m.Option("sessid"))
return
}},
"check": &ctx.Command{Name: "check", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
sort.Strings(arg)
h := sha1.Sum([]byte(strings.Join(arg, "")))
if hex.EncodeToString(h[:]) == m.Option("signature") {
m.Echo("true")
}
return
}},
"/mp": &ctx.Command{Name: "/mp", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
// 用户登录
if m.Options("code") {
m.Option("format", "object")
msg := m.Cmd("web.get", "wexin", m.Conf("mp", "auth"), "js_code", m.Option("code"), "appid", m.Conf("mp", "appid"), "secret", m.Conf("mp", "appmm"), "parse", "json", "temp", "data")
// 创建会话
if !m.Options("sessid") {
m.Cmd("aaa.sess", m.Option("sessid", m.Cmdx("aaa.sess", "mp", "ip", "what")), msg.Append("openid"), "ppid", "what")
defer func() {
m.Set("result").Echo(m.Option("sessid"))
}()
}
m.Magic("session", "user.openid", msg.Append("openid"))
m.Magic("session", "user.expires_in", kit.Int(msg.Append("expires_in"), time.Now()))
m.Magic("session", "user.session_key", msg.Append("session_key"))
}
// 用户信息
if m.Options("userInfo") && m.Options("rawData") {
h := sha1.Sum([]byte(strings.Join([]string{m.Option("rawData"), kit.Format(m.Magic("session", "user.session_key"))}, "")))
if hex.EncodeToString(h[:]) == m.Option("signature") {
var info interface{}
json.Unmarshal([]byte(m.Option("userInfo")), &info)
m.Log("info", "user %v %v", m.Option("sessid"), info)
m.Magic("session", "user.info", info)
m.Magic("session", "user.encryptedData", m.Option("encryptedData"))
m.Magic("session", "user.iv", m.Option("iv"))
}
}
if m.Option("username", m.Magic("session", "user.openid")) == "" || m.Option("cmd") == "" {
return
}
if m.Option("username") == "o978M0XIrcmco28CU1UbPgNxIL78" {
m.Option("username", "shy")
}
if m.Option("username") == "o978M0ff_Y76hFu1FPLif6hFfmsM" {
m.Option("username", "shy")
}
// 创建空间
if !m.Options("bench") && m.Option("bench", m.Cmd("aaa.sess", m.Option("sessid"), "bench").Append("key")) == "" {
m.Option("bench", m.Cmdx("aaa.work", m.Option("sessid"), "mp"))
}
m.Option("current_ctx", kit.Select("chat", m.Magic("bench", "current_ctx")))
// 执行命令
cmd := kit.Trans(m.Optionv("cmd"))
if !m.Cmds("aaa.work", m.Option("bench"), "right", m.Option("username"), "mp", cmd[0]) {
m.Echo("no right %s %s", "chat", cmd[0])
} else if m.Cmdy(cmd); m.Appends("redirect") {
}
return
}},
"mp": &ctx.Command{Name: "mp", Help: "talk", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Cmdy("cli.system", m.Conf("mp", "tool_path"), arg, m.Conf("mp", "project_path"), "cmd_active", "true")
return
}},
},
}
var Target = &web.WEB{Context: Index}
func main() {
fmt.Print(cli.Index.Plugin(Index, os.Args[1:]))
}

View File

@ -1,2 +0,0 @@
Plugin["weixin/index.js"] = function(field, option, output) {return {
}}

View File

@ -1,5 +0,0 @@
fun hello world "" "" public \
text "" \
button "执行"
copy pwd
end

View File

@ -1,3 +0,0 @@
fieldset.item.zsh div.output {
}

View File

@ -1,36 +0,0 @@
package main
import (
"contexts/cli"
"contexts/ctx"
"toolkit"
"fmt"
"os"
)
var Index = &ctx.Context{Name: `zsh`, Help: `plugin`,
Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{
"_index": &ctx.Config{Name: "index", Value: []interface{}{
map[string]interface{}{"name": "demo", "help": "demo",
"tmpl": "componet", "view": "", "init": "",
"type": "public", "ctx": "demo", "cmd": "demo",
"args": []interface{}{}, "inputs": []interface{}{
map[string]interface{}{"type": "text", "name": "pod", "value": "hello world"},
map[string]interface{}{"type": "button", "value": "执行"},
},
},
}},
},
Commands: map[string]*ctx.Command{
"demo": {Name: "demo", Help: "demo", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
m.Echo(kit.Select("hello world", arg, 0))
return
}},
},
}
func main() {
fmt.Print(cli.Index.Plugin(Index, os.Args[1:]))
}

View File

@ -1,3 +0,0 @@
Script["zsh/index.js"] = function(field, option, output) {return {
}}

View File

@ -1,70 +0,0 @@
kit file "文件" private "_:web.code.favor" "@you" file \
text "file" name table view tiny \
text "" name index imports plugin_zsh_block action auto view tiny \
text "" name limit view tiny \
text "" name offend view tiny \
exports zsh_block id \
button "查看" action auto \
button "返回" cb Last
kit tips "便签" private "_:web.code.favor" "@you" list \
text "tip" name table view tiny \
text "" name index imports plugin_zsh_favor view tiny action auto \
text "" name limit view tiny \
text "" name offend view tiny \
feature detail "修改" "复制" "下载" \
exports zsh_favor id \
button "查看" action auto \
button "返回" cb Last
kit favor "收藏" private "_:web.code.favor" "@you" post \
text "tip" name table view tiny \
text "" name tab \
text "" name note \
text "" name word imports plugin_zsh_cmd \
button "添加"
kit terminal "终端" private "web.code.login" list zsh \
text "" name zsh_sid action auto \
text "" name dream imports plugin_you \
text "" name topic imports plugin_see \
feature detail "prune" "修改" "复制" "下载" \
exports zsh_sid sid \
button "查看" action auto \
button "返回" cb Last
kit history "命令" private "web.code.trend" list "zsh.history" \
text "" name index imports plugin_zsh_history view tiny action auto \
text "" name limit view tiny \
text "" name offend view tiny \
exports zsh_history id "" zsh_cmd cmd "" \
button "查看" action auto \
button "返回" cb Last
kit free "内存" private "web.code.trend" list "zsh.free" \
text "" name index imports plugin_zsh_free view tiny action auto \
text "" name limit view tiny \
text "" name offend view tiny \
exports zsh_free id \
button "查看" action auto \
button "返回" cb Last
kit env "环境" private "web.code.state" list zsh env \
text "" name zsh_sid action auto \
text "name" name match view tiny \
text "" name value view tiny \
button "查看" action auto
kit ps "进程" private "web.code.state" list zsh ps \
text "" name zsh_sid action auto \
text "PPID" name match view tiny \
text "" name value view tiny \
button "查看" action auto
kit df "磁盘" private "web.code.state" list zsh df \
text "" name zsh_sid action auto \
text "fs" name match view tiny \
text "" name value view tiny \
button "查看" action auto

View File

@ -1,50 +0,0 @@
package wuhan
import (
"github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/core/team"
"github.com/shylinux/toolkits"
)
var Index = &ice.Context{Name: "wuhan", Help: "武汉加油",
Caches: map[string]*ice.Cache{},
Configs: map[string]*ice.Config{
"wuhan": {Name: "wuhan", Help: "武汉", Value: kit.Data(kit.MDB_SHORT, "name")},
},
Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
"wuhan": {Name: "wuhan", Help: "武汉", Meta: kit.Dict(
"display", "china",
), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
data := kit.UnMarshal(m.Cmdx(ice.WEB_SPIDE, "shy", "raw", "GET", "https://view.inews.qq.com/g2/getOnsInfo?name=wuwei_ww_area_counts"))
m.Option("title", kit.Format("疫情分布\n%s", m.Time()))
suspect := map[string]int{}
confirm := map[string]int{}
dead := map[string]int{}
deal := map[string]int{}
kit.Fetch(kit.UnMarshal(kit.Value(data, "data").(string)), func(index int, value map[string]interface{}) {
area := kit.Select(kit.Format(value["country"]), kit.Format(value["area"]))
suspect[area] += kit.Int(value["suspect"])
confirm[area] += kit.Int(value["confirm"])
dead[area] += kit.Int(value["dead"])
deal[area] += kit.Int(value["deal"])
})
for k, v := range suspect {
m.Push("name", k)
m.Push("suspect", v)
m.Push("confirm", confirm[k])
m.Push("dead", dead[k])
m.Push("deal", deal[k])
m.Push("value", confirm[k])
}
m.Sort("confirm", "int_r")
}},
},
}
func init() { team.Index.Register(Index, nil) }

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