1
0
mirror of https://shylinux.com/x/icebergs synced 2025-04-25 17:18:05 +08:00

Compare commits

..

136 Commits

Author SHA1 Message Date
shy
7e5cff6b81 add some 2025-03-22 12:54:06 +08:00
shy
6c0e3a0a58 add some 2025-03-15 20:27:05 +08:00
shy
08f2f1626d add some 2025-03-10 18:38:39 +08:00
shy
5260027c9f add some 2025-03-08 08:38:13 +08:00
shy
26e62a1b22 add some 2025-03-05 23:33:47 +08:00
shy
e008f4d417 add some 2025-03-05 08:55:30 +08:00
shy
5fc5ccd0ea add some 2025-03-04 14:52:57 +08:00
shy
35c1407d29 add some 2025-03-03 22:13:05 +08:00
shy
55a0c3d120 add some 2025-03-03 18:39:51 +08:00
shy
968d9389c9 opt some 2025-03-02 22:10:17 +08:00
shy
7fea8e88a4 add some 2025-03-01 11:36:50 +08:00
shy
8fa2f6e8b3 add some 2025-02-28 14:17:28 +08:00
shy
fe1a6d30aa opt some 2025-02-27 17:56:24 +08:00
shy
02962f9d20 add some 2025-02-27 16:39:54 +08:00
shy
612ecdf4a6 add some 2025-02-27 16:29:06 +08:00
shy
c3f37f626b add some 2025-02-27 16:27:42 +08:00
shy
b4627b2975 add some 2025-02-26 21:51:32 +08:00
shy
f3bc5eb1e1 opt some 2025-02-25 21:57:33 +08:00
shy
03990b839e add some 2025-02-25 21:54:41 +08:00
shy
473826664a add some 2025-02-25 12:14:41 +08:00
root
be66627287 add some 2025-02-25 10:52:06 +08:00
shy
030c018877 add some 2025-02-25 09:59:30 +08:00
root
0071ba89d9 add some 2025-02-25 07:32:49 +08:00
shy
c067576dd6 add some 2025-02-23 09:58:37 +08:00
shy
96d812612b add some 2025-02-23 08:03:37 +08:00
root
a33bc88dcc add some 2025-02-19 21:00:50 +08:00
shy
2f715c5233 opt some 2025-02-18 11:26:19 +08:00
root
8a27ce7d66 add some 2025-02-18 11:18:22 +08:00
root
da81284b37 add some 2025-02-17 19:54:36 +08:00
root
bbb0ae9de9 add some 2025-02-16 08:44:53 +08:00
shy
7bb197ed94 add some 2025-02-16 08:27:23 +08:00
shy
bc94d8e1e4 add some 2025-02-15 18:35:15 +08:00
shy
942606d750 add some 2025-02-15 12:32:06 +08:00
shy
c418c8c070 add some 2025-02-13 22:35:33 +08:00
shy
87c96c880d opt some 2025-02-10 23:03:10 +08:00
shy
cdaa2d7984 opt some 2025-02-10 10:11:34 +08:00
root
38b7942c1b add some 2025-02-10 08:30:04 +08:00
root
240a0c88bf add some 2025-02-08 15:00:09 +08:00
root
297c299694 add some 2025-02-08 12:02:50 +08:00
root
324cd9dc57 add some 2025-02-06 16:21:11 +08:00
shy
1829822e43 add some 2025-02-05 17:37:25 +08:00
shy
a8b365dc31 add some 2025-02-05 09:49:32 +08:00
root
b64a3b5725 add some 2025-02-05 09:44:27 +08:00
root
0ef29edbad add some 2025-02-04 14:10:16 +08:00
shy
6fc5cbde02 add publish 2025-02-04 12:01:02 +08:00
shy
85e1f1dcb6 add some 2025-02-04 10:26:51 +08:00
root
cd5882b2ee add some 2025-02-04 08:52:06 +08:00
shy
259aa7639a add some 2025-02-03 20:42:02 +08:00
shy
91f4578d63 add some 2025-02-02 23:54:43 +08:00
root
54211e220d add some 2025-02-02 23:53:03 +08:00
shy
00d0a3f449 add some 2025-01-31 10:26:51 +08:00
root
8782b192e3 add some 2025-01-30 10:49:34 +08:00
root
92a2fcac3c add some 2025-01-29 12:00:59 +08:00
shy
c045033e55 add some 2025-01-25 15:15:48 +08:00
shy
c022852de3 add some 2025-01-23 21:36:46 +08:00
shy
fa73c5c940 add some 2025-01-23 18:59:31 +08:00
shy
0be5c0f6f3 add some 2025-01-22 16:23:02 +08:00
shy
524bbf6430 add some 2025-01-22 16:12:23 +08:00
root
50ba5c3a3f add some 2025-01-22 15:32:30 +08:00
shy
d9fcacd679 opt some 2025-01-17 21:18:36 +08:00
root
c661ed4f12 add some 2025-01-14 08:42:01 +08:00
root
193a2ab917 add some 2025-01-13 18:02:50 +08:00
shy
aa756c2bc3 add some 2025-01-12 21:53:42 +08:00
shy
7551a8dfab add some 2025-01-10 15:04:47 +08:00
shy
be8c60d97c add some 2025-01-06 21:38:46 +08:00
root
61b81cf089 add some 2025-01-05 20:36:15 +08:00
shy
813ec2b17a add some 2025-01-05 12:45:21 +08:00
shy
d4c73ce195 add some 2025-01-05 12:01:27 +08:00
shy
472f72889a add some 2025-01-03 12:36:17 +08:00
shy
a3e4861989 add some 2025-01-02 20:48:29 +08:00
root
18d65c81e5 add some 2025-01-02 20:42:58 +08:00
root
f59b7cc461 add some 2025-01-02 18:29:31 +08:00
shy
ec961b40fb add some 2025-01-01 09:49:06 +08:00
shy
a075aa7975 add some 2025-01-01 09:23:30 +08:00
root
287083f9ca add some 2024-12-31 19:22:00 +08:00
shy
2e0131a331 add some 2024-12-31 12:33:48 +08:00
root
7dcf68b0d8 add some 2024-12-16 16:02:46 +08:00
shy
66033654c5 add some 2024-12-08 22:27:31 +08:00
shy
6540f3f3f1 add some 2024-12-03 22:45:07 +08:00
shy
37fe3b44b0 add some 2024-11-28 12:32:02 +08:00
shy
bcdce97856 add some 2024-11-26 23:12:53 +08:00
shy
ff0590852d add some 2024-11-25 10:02:13 +08:00
shy
a352374bb4 add some 2024-11-24 07:46:53 +08:00
shy
d30b4e2034 add some 2024-11-23 16:51:24 +08:00
shy
131858f4b1 opt some 2024-11-23 10:11:56 +08:00
shy
e042dc832c add some 2024-11-20 22:49:56 +08:00
shy
8f10a46fb5 add some 2024-11-19 09:32:17 +08:00
root
313b7d4c95 add some 2024-11-18 09:11:37 +08:00
shy
f8af90a71e add some 2024-11-15 20:09:08 +08:00
root
52b47dee2a add some 2024-11-15 09:56:30 +08:00
root
5776c42f7b add some 2024-11-10 13:07:07 +08:00
root
73c32ccc9b add some 2024-11-09 11:35:33 +08:00
root
f9932b5dba add some 2024-11-04 10:27:19 +08:00
root
5afc3781a6 add some 2024-10-25 17:49:24 +08:00
root
dc242dfa54 add some 2024-10-22 07:35:48 +08:00
root
e02517a57e add some 2024-10-20 22:55:19 +08:00
root
f6a009c7fa add some 2024-10-20 08:16:21 +08:00
root
be0a295b52 add some 2024-10-18 14:45:24 +08:00
root
39a5ce360e add some 2024-10-18 14:08:56 +08:00
root
928666d2c9 add some 2024-10-17 23:45:20 +08:00
root
51ae44aeb3 add some 2024-10-17 12:13:39 +08:00
root
d3ba62cc61 add some 2024-10-17 09:38:54 +08:00
root
07111495dd add some 2024-10-16 11:18:41 +08:00
shy
e34752141a opt some 2024-10-16 10:27:26 +08:00
root
95b45c2f15 add some 2024-10-15 18:25:37 +08:00
root
b2b4616ec1 add some 2024-10-13 18:25:36 +08:00
root
1060a60a5e add some 2024-10-12 11:06:29 +08:00
shy
4d892e03d3 add some 2024-10-10 22:23:51 +08:00
shy
ca734d3baf add some 2024-10-09 14:41:19 +08:00
shy
2deff32468 add some 2024-10-06 22:19:03 +08:00
shy
ed39ff23e7 add some 2024-10-04 12:23:39 +08:00
shy
d4f4754be8 add some 2024-10-02 22:24:09 +08:00
shy
80807ed1d2 add some 2024-10-01 00:12:59 +08:00
shy
c4b9641a5e add some 2024-09-27 23:58:19 +08:00
shy
0bff96f485 add some 2024-09-25 17:16:22 +08:00
shy
7ab38ec81f add some 2024-09-24 13:10:56 +08:00
shy
56b87e9e78 add some 2024-09-20 20:53:41 +08:00
shy
f174577bde opt some 2024-09-19 21:09:34 +08:00
shy
ed65d194e6 add some 2024-09-18 20:40:55 +08:00
shy
15a79273ac add some 2024-09-18 13:32:50 +08:00
shy
0eac777f6f add some 2024-09-14 00:36:42 +08:00
shy
0f8a77af25 add some 2024-09-10 08:06:53 +08:00
shy
9a192b012f add some 2024-09-07 17:11:52 +08:00
shy
4b27054210 add some 2024-09-05 20:02:56 +08:00
shy
8d1374149c add some 2024-09-04 07:54:59 +08:00
shy
768bca93b1 add some 2024-09-03 22:42:25 +08:00
shy
f45d784af7 add some 2024-09-03 18:29:15 +08:00
shy
329f963a38 add some 2024-09-03 07:35:53 +08:00
shy
53c5a80da6 add some 2024-09-02 17:34:07 +08:00
shy
b1d5d09a80 add some 2024-08-30 21:56:33 +08:00
shy
4a5256c19f add some 2024-08-29 11:09:33 +08:00
shy
e3fb897137 add some 2024-08-26 22:15:14 +08:00
shy
b1bd23cc26 add some 2024-08-24 20:22:51 +08:00
shy
67b1e41db9 add some 2024-08-18 02:26:42 +08:00
shy
ce0735856e add some 2024-08-16 07:53:33 +08:00
jingganjiaoyu
a0ef75490c opt some 2024-08-15 11:48:38 +08:00
98 changed files with 1442 additions and 689 deletions

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2020 shylinux
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,3 +1,3 @@
# icebergs
icebergs 是一个应用框架,通过模块化、集群化、自动化方式,在各种设备上,即可一键启动完整的云计算服务与云研发环境。
icebergs 是一个后端框架,通过集群化、模块化、自动化方式,在各种设备上,即可一键启动完整的云计算服务与云研发环境。

View File

@ -32,7 +32,7 @@ func init() {
)
Index.MergeCommands(ice.Commands{
EMAIL: {Help: "邮件", Actions: ice.MergeActions(ice.Actions{
mdb.CREATE: {Name: "create name*=admin service*='mail.shylinux.com:25' username*='shy@shylinux.com' password*"},
mdb.CREATE: {Name: "create name*=admin service*='smtp.163.com:25' username* password*"},
SEND: {Name: "send from=admin to*='shy@shylinux.com' cc subject*=hi content*:textarea=hello", Help: "发送", Icon: "bi bi-send-plus", Hand: func(m *ice.Message, arg ...string) {
msg := mdb.HashSelects(m.Spawn(), m.OptionDefault(FROM, ADMIN))
if m.WarnNotFound(msg.Append(SERVICE) == "", m.Option(FROM)) {

View File

@ -78,9 +78,11 @@ func (s apply) Login(m *ice.Message, arg ...string) {
}
m.Options(ice.MSG_USERNAME, m.Option(aaa.EMAIL))
space := kit.Keys(kit.Slice(kit.Split(m.Option(ice.MSG_DAEMON), nfs.PT), 0, -1))
share := m.Cmd(web.SHARE, mdb.CREATE, mdb.TYPE, web.FIELD, mdb.NAME, web.CHAT_GRANT, mdb.TEXT, space).Append(mdb.LINK)
share := m.Cmd(web.SHARE, mdb.CREATE, mdb.TYPE, web.FIELD, mdb.NAME, web.CHAT_GRANT, mdb.TEXT, space, web.SPACE, ice.OPS).Append(mdb.LINK)
m.Options(web.LINK, share).SendEmail("", "", "")
m.ProcessHold(m.Trans("please auth login in mailbox", "请注意查收邮件"))
// m.ProcessHold(m.Trans("please auth login in mailbox", "请注意查收邮件"))
m.Echo(m.Trans("please auth login in mailbox", "请注意查收邮件"))
m.ProcessInner()
}
}
func (s apply) List(m *ice.Message, arg ...string) *ice.Message {

View File

@ -87,6 +87,7 @@ func init() {
roleHandle(m, role, list...)
})
})
m.Cmd(ROLE, WHITE, VOID, ROLE, "action", RIGHT)
}},
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {
if arg[0] == mdb.KEY {

View File

@ -62,7 +62,7 @@ func init() {
m.Option(ice.TABLE_CHECKBOX, ice.TRUE)
}
}},
mdb.CREATE: {Name: "create userrole=void,tech username* usernick language userzone email", Hand: func(m *ice.Message, arg ...string) {
mdb.CREATE: {Name: "create userrole=void,tech username* usernick language userzone email avatar", Hand: func(m *ice.Message, arg ...string) {
_user_create(m, m.Option(USERNAME), m.OptionSimple(USERROLE, USERNICK, LANGUAGE, AVATAR, BACKGROUND, USERZONE, EMAIL)...)
}},
mdb.REMOVE: {Hand: func(m *ice.Message, arg ...string) { _user_remove(m, m.Option(USERNAME)) }},
@ -105,7 +105,7 @@ func UserRoot(m *ice.Message, arg ...string) *ice.Message {
userzone := kit.Select(ice.OPS, arg, 4)
email := kit.Select(UserEmail(m, username), arg, 5)
if len(arg) > 0 {
ice.Info.Username = username
kit.If(username != ROOT, func() { ice.Info.Username = username })
m.Cmd(USER, mdb.CREATE, userrole, username, usernick, language, userzone, email)
}
return SessAuth(m, kit.Dict(USERROLE, userrole, USERNAME, username, USERNICK, usernick))

View File

@ -74,7 +74,7 @@ func init() {
// m.OptionDefault(SIZE, kit.Select("360", "280", m.IsMobileUA()))
m.Option(FG, kit.Select(m.Option(ice.MSG_FG), arg, 1))
m.Option(BG, kit.Select(m.Option(ice.MSG_BG), arg, 2))
m.Option(SIZE, kit.Select(m.OptionDefault(SIZE, "360"), arg, 3))
m.Option(SIZE, kit.Select(m.OptionDefault(SIZE, "320"), arg, 3))
switch m.Option(ice.MSG_THEME) {
case LIGHT, WHITE:
m.OptionDefault(FG, BLACK, BG, WHITE)

View File

@ -43,9 +43,10 @@ func _runtime_init(m *ice.Message) {
kit.HashSeed = append(kit.HashSeed, ice.Info.Username)
kit.HashSeed = append(kit.HashSeed, ice.Info.Hostname)
kit.HashSeed = append(kit.HashSeed, ice.Info.Pathname)
aaa.UserRoot(ice.Pulse, aaa.ROOT, aaa.ROOT)
aaa.UserRoot(ice.Pulse, aaa.TECH, ice.Info.Make.Author, "", "", ice.DEV, ice.Info.Make.Email)
aaa.UserRoot(ice.Pulse, aaa.TECH, ice.Info.Make.Username, "", "", ice.DEV, ice.Info.Make.Email)
aaa.UserRoot(ice.Pulse, aaa.TECH, ice.Info.Username)
aaa.UserRoot(ice.Pulse, aaa.ROOT, ice.Info.Username)
aaa.UserRoot(ice.Pulse, aaa.ROOT, aaa.ROOT)
ice.Info.Time = m.Time()
m.Conf(RUNTIME, kit.Keys(BOOT, mdb.TIME), ice.Info.Time)
if runtime.GOARCH != MIPSLE {
@ -134,6 +135,8 @@ const (
KERNEL = "kernel"
ARCH = "arch"
CPU = "cpu"
OS = "os"
)
const (
PATH = "PATH"
@ -154,6 +157,7 @@ const (
CTX_DEMO = "ctx_demo"
CTX_MAIL = "ctx_mail"
CTX_ROOT = "ctx_root"
CTX_DOMAIN = "ctx_domain"
CTX_PID = "ctx_pid"
CTX_LOG = "ctx_log"
@ -182,8 +186,8 @@ const RUNTIME = "runtime"
func init() {
Index.MergeCommands(ice.Commands{
RUNTIME: {Name: "runtime info=bootinfo,ifconfig,diskinfo,hostinfo,userinfo,bootinfo,role,api,cli,cmd,mod,env,path,chain auto upgrade reboot lock", Icon: "Infomation.png", Help: "运行环境", Actions: ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { _runtime_init(m); }},
RUNTIME: {Name: "runtime info=bootinfo,ifconfig,diskinfo,hostinfo,userinfo,bootinfo,role,api,cli,cmd,mod,env,path,chain auto upgrade reboot lock", Icon: "Infomation.png", Help: "环境", Actions: ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { _runtime_init(m) }},
IFCONFIG: {Hand: func(m *ice.Message, arg ...string) { m.Cmdy(tcp.HOST) }},
DISKINFO: {Hand: func(m *ice.Message, arg ...string) { _runtime_diskinfo(m) }},
HOSTINFO: {Hand: func(m *ice.Message, arg ...string) { _runtime_hostinfo(m) }},

View File

@ -65,6 +65,7 @@ func _system_cmd(m *ice.Message, arg ...string) *exec.Cmd {
}
kit.For(env, func(k, v string) { cmd.Env = append(cmd.Env, kit.Format("%s=%s", k, v)) })
kit.If(len(cmd.Env) > 0 && m.IsDebug(), func() { m.Logs(EXEC, CMD_ENV, kit.Format(cmd.Env)) })
kit.If(len(cmd.Env) > 0, func() { m.Logs(EXEC, CMD_ENV, kit.Format(cmd.Env)) })
_system_cmds(m, cmd, arg...)
return cmd
}
@ -159,6 +160,7 @@ const (
const (
SH = "sh"
LN = "ln"
CP = "cp"
MV = "mv"
RM = "rm"
CD = "cd"

View File

@ -18,6 +18,7 @@ func _command_list(m *ice.Message, name string) *ice.Message {
return m.Push(mdb.INDEX, name).Push(mdb.NAME, name).Push(mdb.HELP, "").Push(mdb.META, "").Push(mdb.LIST, "")
}
m.Option(ice.MSG_NODENAME, ice.Info.Titles)
m.Option(ice.MSG_NODEICON, m.Resource(ice.Info.NodeIcon))
m.Spawn(m.Source()).Search(name, func(p *ice.Context, s *ice.Context, key string, cmd *ice.Command) {
icon := kit.Format(kit.Value(cmd.Meta, kit.Keys(ice.CTX_ICONS, key)))
m.Push(mdb.INDEX, kit.Keys(s.Prefix(), key))

View File

@ -51,6 +51,9 @@ func DisplayStoryForm(m *ice.Message, arg ...ice.Any) *ice.Message {
func DisplayInputKey(m *ice.Message, arg ...ice.Any) *ice.Message {
return DisplayInput(m, "key", arg...)
}
func DisplayStoryWeight(m *ice.Message, arg ...ice.Any) *ice.Message {
return DisplayStory(m, "weight", arg...)
}
func DisplayStoryPie(m *ice.Message, arg ...ice.Any) *ice.Message {
return DisplayStory(m, "pie", arg...)
}
@ -81,6 +84,10 @@ func DisplayBase(m *ice.Message, file string, arg ...ice.Any) *ice.Message {
m.Option(ice.MSG_DISPLAY, kit.MergeURL(kit.Select(kit.ExtChange(file, nfs.JS), file, strings.Contains(file, mdb.QS)), arg...))
return Toolkit(m, "")
}
func DisplayBaseCSS(m *ice.Message, file string, arg ...ice.Any) *ice.Message {
m.Option(ice.MSG_DISPLAY_CSS, kit.MergeURL(kit.Select(kit.ExtChange(file, nfs.CSS), file, strings.Contains(file, mdb.QS)), arg...))
return m
}
func Toolkit(m *ice.Message, arg ...string) *ice.Message {
m.OptionDefault(ice.MSG_ONLINE, mdb.Config(m, "online"))
return m.Options(ice.MSG_TOOLKIT, kit.Select(mdb.Config(m, mdb.TOOLS), kit.Fields(arg)))

View File

@ -1,6 +1,7 @@
package log
import (
"regexp"
"strings"
"time"
"unicode"
@ -23,7 +24,7 @@ func init() {
LEVEL = "level"
)
Index.MergeCommands(ice.Commands{
DEBUG: {Name: "debug level=error,bench,debug,error,watch offset limit auto reset app doc", Help: "后台日志", Actions: ice.Actions{
DEBUG: {Name: "debug level=error,bench,debug,error,watch offset limit auto reset app doc", Help: "日志", Actions: ice.Actions{
"doc": {Help: "文档", Hand: func(m *ice.Message, arg ...string) { m.ProcessOpen("https://pkg.go.dev/std") }},
"reset": {Help: "重置", Hand: func(m *ice.Message, arg ...string) {
m.Cmd(nfs.CAT, _debug_file(arg[0]), func(line string, index int) { m.ProcessRewrite(mdb.OFFSET, index+2, mdb.LIMIT, 1000) })
@ -32,6 +33,7 @@ func init() {
cli.OpenCmds(m, kit.Format("cd %s", kit.Path("")), "tail -f var/log/bench.log")
}},
}, Hand: func(m *ice.Message, arg ...string) {
r := regexp.MustCompile("{.*}")
offset, limit := kit.Int(kit.Select("0", arg, 1)), kit.Int(kit.Select("100", arg, 2))
switch arg[0] {
case BENCH, ERROR, DEBUG:
@ -66,6 +68,10 @@ func init() {
ls[6], ls[7] = ls[6]+lex.SP+_ls[0], _ls[1]
}
}
switch ls[6] {
case "recv", "done", "send", "echo":
ls[7] += "\n" + kit.Formats(kit.UnMarshal(r.FindString(ls[7])))
}
m.Push(ctx.SHIP, ls[5]).Push(LEVEL, ls[6]).Push(nfs.CONTENT, ls[7])
})
case WATCH:

View File

@ -22,10 +22,6 @@ type Log struct {
type Frame struct{ p chan *Log }
func (f *Frame) Begin(m *ice.Message, arg ...string) {
f.p = make(chan *Log, ice.MOD_BUFS)
ice.Info.Log = func(m *ice.Message, p, l, s string) {
f.p <- &Log{c: m.Option(ice.LOG_DEBUG) == ice.TRUE, p: p, l: l, s: s}
}
}
func (f *Frame) Start(m *ice.Message, arg ...string) {
if !ice.HasVar() {
@ -40,6 +36,10 @@ func (f *Frame) Start(m *ice.Message, arg ...string) {
v[FILE] = bufio.NewWriter(f)
}
})
f.p = make(chan *Log, ice.MOD_BUFS)
ice.Info.Log = func(m *ice.Message, p, l, s string) {
f.p <- &Log{c: m.Option(ice.LOG_DEBUG) == ice.TRUE, p: p, l: l, s: s}
}
for {
select {
case l, ok := <-f.p:

View File

@ -115,7 +115,7 @@ func _hash_export(m *ice.Message, prefix, chain, file string) {
m.Logs(EXPORT, KEY, path.Join(prefix, chain), FILE, p)
en := json.NewEncoder(f)
if en.SetIndent("", " "); !m.WarnNotValid(en.Encode(m.Confv(prefix, kit.Keys(chain, HASH))), EXPORT, prefix) {
m.Conf(prefix, kit.Keys(chain, HASH), "")
// m.Conf(prefix, kit.Keys(chain, HASH), "")
}
}
func _hash_import(m *ice.Message, prefix, chain, file string) {

View File

@ -18,8 +18,12 @@ func getLock(m *ice.Message, arg ...string) *task.Lock {
kit.If(!ok, func() { l = &task.Lock{}; _locks[key] = l })
return l
}
func Lock(m *ice.Message, arg ...string) func() { return getLock(m, arg...).Lock() }
func RLock(m *ice.Message, arg ...string) func() { return getLock(m, arg...).RLock() }
func Lock(m *ice.Message, arg ...string) func() {
return getLock(m, arg...).Lock()
}
func RLock(m *ice.Message, arg ...string) func() {
return getLock(m, arg...).RLock()
}
func ConfigSimple(m *ice.Message, key ...string) (res []string) {
for _, key := range key {

View File

@ -133,16 +133,17 @@ const (
WEIGHT = "weight"
SUBKEY = "mdb.sub"
ACTION = "action"
UPLOAD = "upload"
RECENT = "recent"
REPEAT = "repeat"
REVERT = "revert"
RENAME = "rename"
VENDOR = "vendor"
PRUNE = "prune"
TABLE = "table"
CLASS = "class"
ACTION = "action"
UPLOAD = "upload"
RECENT = "recent"
REPEAT = "repeat"
REVERT = "revert"
RENAME = "rename"
VENDOR = "vendor"
PRUNE = "prune"
TABLE = "table"
CLASS = "class"
DATABASE = "database"
PAGE = "page"
NEXT = "next"
@ -226,29 +227,21 @@ var Index = &ice.Context{Name: MDB, Help: "数据模块", Commands: ice.Commands
EXPORT: {Name: "export index auto", Help: "导出数据", Actions: ice.MergeActions(ice.Actions{
IMPORT: {Hand: func(m *ice.Message, arg ...string) {
HashSelect(m).Table(func(value ice.Maps) {
if value[STATUS] != DISABLE {
if value[ENABLE] != ice.FALSE {
m.Cmd(IMPORT, value[INDEX], "", value[TYPE])
}
})
}},
EXPORT: {Hand: func(m *ice.Message, arg ...string) {
HashSelect(m).Table(func(value ice.Maps) {
if value[STATUS] != DISABLE {
if value[ENABLE] != ice.FALSE {
m.Cmd(EXPORT, value[INDEX], "", value[TYPE])
}
})
}},
ENABLE: {Hand: func(m *ice.Message, arg ...string) { HashModify(m, STATUS, ENABLE) }},
DISABLE: {Hand: func(m *ice.Message, arg ...string) { HashModify(m, STATUS, DISABLE) }},
}, ExportHashAction(SHORT, INDEX, FIELD, "time,index,type,status")), Hand: func(m *ice.Message, arg ...string) {
}, ExportHashAction(SHORT, INDEX, FIELD, "time,index,type,enable")), Hand: func(m *ice.Message, arg ...string) {
if len(arg) < 2 {
HashSelect(m, arg...).RewriteAppend(func(value, key string, index int) string {
kit.If(key == STATUS, func() { value = kit.Select(ENABLE, value) })
return value
}).PushAction()
if len(arg) == 1 {
m.Cmdy("nfs.cat", "usr/local/export/"+arg[0]+"/hash.json")
}
HashSelect(m, arg...).PushAction(REMOVE)
return
}
m.OptionDefault(CACHE_LIMIT, "-1")
@ -303,6 +296,8 @@ func AutoConfig(arg ...Any) *ice.Action {
})
return
}
kit.If(cmd.Meta[CREATE] == nil, func() { m.Design(CREATE, "", add(kit.Split(HashField(m)))...) })
return
if cmd.Actions[INSERT] != nil {
kit.If(cmd.Meta[INSERT] == nil, func() { m.Design(INSERT, "", add(kit.Simple(Config(m, SHORT), kit.Split(ListField(m))))...) })
kit.If(cmd.Meta[CREATE] == nil, func() { m.Design(CREATE, "", add(kit.Split(Config(m, SHORT)))...) })

View File

@ -116,7 +116,7 @@ func _dir_list(m *ice.Message, root string, dir string, level int, deep bool, di
if m.IsCliUA() || m.Option(ice.MSG_USERROLE) == aaa.VOID {
break
}
m.PushButton(mdb.SHOW, TRASH)
m.PushButton(mdb.SHOW, "rename", TRASH)
default:
m.Push(field, "")
}
@ -147,11 +147,15 @@ const (
SCAN = "scan"
GOWORK = "gowork"
PORTAL_GO = "portal.go"
PORTAL_JSON = "portal.json"
ETC_LOCAL_SH = "etc/local.sh"
ETC_CERT_KEY = "etc/cert/cert.key"
ETC_CERT_PEM = "etc/cert/cert.pem"
SRC_DOCUMENT = "src/document/"
SRC_PRIVATE = "src/private/"
SRC_MAIN_PNG = "src/main.png"
SRC_OPTION_GO = "src/option.go"
SRC_TEMPLATE = ice.SRC_TEMPLATE
USR_TOOLKITS = ice.USR_TOOLKITS
USR_ICEBERGS = ice.USR_ICEBERGS
@ -159,6 +163,8 @@ const (
USR_PUBLISH = ice.USR_PUBLISH
USR_LOCAL = ice.USR_LOCAL
USR_LOCAL_WORK = ice.USR_LOCAL_WORK
USR_IMAGE = "usr/image/"
USR_MATERIAL = "usr/material/"
USR_LOCAL_IMAGE = "usr/local/image/"
USR_LEARNING_PORTAL = "usr/learning/portal/"
USR_MODULES = "usr/node_modules/"
@ -188,6 +194,7 @@ const (
SHARE_LOCAL = "/share/local/"
PATHNAME = "pathname"
FILENAME = "filename"
CONTEXTS = "contexts"
TYPE_ALL = "all"
TYPE_BIN = "bin"
@ -196,8 +203,8 @@ const (
TYPE_BOTH = "both"
DIR_ROOT = "dir_root"
DIR_TYPE = "dir_type"
DIR_DEEP = "dir_deep"
DIR_TYPE = "dir_type"
DIR_REG = "dir_reg"
DIR_DEF_FIELDS = "time,path,size,action"
@ -236,7 +243,12 @@ func init() {
SIZE: {Hand: func(m *ice.Message, arg ...string) {
m.Echo(kit.Select("", kit.Split(m.System("du", "-sh").Result()), 0))
}},
TRASH: {Hand: func(m *ice.Message, arg ...string) { m.Cmd(TRASH, mdb.CREATE, m.Option(PATH)) }},
"rename": {Name: "rename to", Hand: func(m *ice.Message, arg ...string) {
m.Cmd(MOVE, path.Join(path.Dir(m.Option(PATH)), m.Option(TO)), m.Option(PATH))
}},
TRASH: {Hand: func(m *ice.Message, arg ...string) {
m.Cmd(TRASH, mdb.CREATE, m.Option(PATH))
}},
}, Hand: func(m *ice.Message, arg ...string) {
root, dir := kit.Select(PWD, m.Option(DIR_ROOT)), kit.Select(PWD, arg, 0)
kit.If(strings.HasPrefix(dir, PS), func() { root = "" })

View File

@ -24,6 +24,9 @@ func _host_domain(m *ice.Message) string {
}
return ""
},
func() string {
return LOCALHOST
},
)
}
func _host_list(m *ice.Message, name string) *ice.Message {

View File

@ -38,7 +38,7 @@ func init() {
m.ProcessHold()
}
}},
}, mdb.HashAction(mdb.SHORT, SSID, mdb.FIELD, "time,ssid,password")), Hand: func(m *ice.Message, arg ...string) {
}, mdb.ExportHashAction(mdb.SHORT, SSID, mdb.FIELD, "time,ssid,password")), Hand: func(m *ice.Message, arg ...string) {
if mdb.HashSelect(m, arg...).PushAction(CONNECT, mdb.REMOVE); len(arg) > 0 {
m.EchoQRCode(kit.Format("WIFI:T:WPA;S:%s;P:%s;H:false;;", m.Append(SSID), m.Append(aaa.PASSWORD)))
}

View File

@ -7,6 +7,7 @@ import (
"path"
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/aaa"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
"shylinux.com/x/icebergs/base/tcp"
@ -70,6 +71,7 @@ func _cache_upload(m *ice.Message, r *http.Request) (mime, name, file, size stri
return "", "", "", "0"
}
func _cache_download(m *ice.Message, r *http.Response, file string, cb ice.Any) string {
m.Option(ice.MSG_USERROLE, aaa.TECH)
if f, p, e := miss.CreateFile(file); !m.WarnNotValid(e, DOWNLOAD) {
defer func() {
if s, e := os.Stat(file); e == nil && s.Size() == 0 {
@ -174,11 +176,14 @@ func init() {
action.Hand = ice.MergeHand(func(m *ice.Message, arg ...string) {
up := Upload(m)
m.Assert(len(up) > 1)
if m.Cmd(CACHE, m.Option(ice.MSG_UPLOAD)).Table(func(value ice.Maps) { m.Options(value) }).Length() == 0 {
msg := m.Cmd(CACHE, m.Option(ice.MSG_UPLOAD))
// if m.Cmd(CACHE, m.Option(ice.MSG_UPLOAD)).Table(func(value ice.Maps) { m.Options(value) }).Length() == 0 {
if msg.Length() == 0 {
SpideCache(m.Spawn(), m.MergeLink(SHARE_CACHE+up[0]))
}
if m.Options(mdb.HASH, up[0], mdb.NAME, up[1]); watch {
m.Cmdy(CACHE, WATCH, m.Option(mdb.HASH), path.Join(m.Option(nfs.PATH), up[1]))
// if m.Options(mdb.HASH, up[0], mdb.NAME, up[1]); watch {
if watch {
m.Cmdy(CACHE, WATCH, up[0], path.Join(msg.Append(nfs.PATH), up[1]))
}
}, action.Hand)
}
@ -186,8 +191,14 @@ func init() {
}
func Upload(m *ice.Message) []string {
if up := kit.Simple(m.Optionv(ice.MSG_UPLOAD)); len(up) == 1 {
if m.Cmdy(CACHE, UPLOAD).Optionv(ice.MSG_UPLOAD, kit.Simple(m.Append(mdb.HASH), m.Append(mdb.NAME), m.Append(nfs.SIZE))); m.Option(ice.MSG_USERPOD) != "" {
m.Cmd(SPACE, m.Option(ice.MSG_USERPOD), SPIDE, ice.DEV, SPIDE_CACHE, http.MethodGet, tcp.PublishLocalhost(m, m.MergeLink(PP(SHARE, CACHE, m.Append(mdb.HASH)))))
msg := m.Cmd(CACHE, UPLOAD)
if m.Optionv(ice.MSG_UPLOAD, kit.Simple(msg.Append(mdb.HASH), msg.Append(mdb.NAME), msg.Append(nfs.SIZE))); m.Option(ice.MSG_USERPOD) != "" {
if nfs.Exists(m, nfs.USR_LOCAL_WORK+m.Option(ice.MSG_USERPOD)) {
m.Cmd(nfs.LINK, path.Join(nfs.USR_LOCAL_WORK+m.Option(ice.MSG_USERPOD), msg.Append(nfs.FILE)), msg.Append(nfs.FILE))
m.Cmd(SPACE, m.Option(ice.MSG_USERPOD), CACHE, mdb.CREATE, msg.AppendSimple(mdb.NAME, mdb.TEXT, nfs.FILE, nfs.SIZE))
} else {
m.Cmd(SPACE, m.Option(ice.MSG_USERPOD), SPIDE, ice.DEV, SPIDE_CACHE, http.MethodGet, tcp.PublishLocalhost(m, m.MergeLink(PP(SHARE, CACHE, msg.Append(mdb.HASH)))))
}
}
return kit.Simple(m.Optionv(ice.MSG_UPLOAD))
} else {

View File

@ -1,7 +1,6 @@
package web
import (
"net/http"
"os"
"path"
"regexp"
@ -22,95 +21,91 @@ import (
kit "shylinux.com/x/toolkits"
)
func _dream_list(m *ice.Message, simple bool) *ice.Message {
func _dream_list(m *ice.Message) *ice.Message {
list := m.CmdMap(SPACE, mdb.NAME)
mdb.HashSelects(m.Spawn()).Table(func(value ice.Maps, index int, head []string) {
if value[aaa.ACCESS] == aaa.PRIVATE && (m.Option(ice.FROM_SPACE) != "" || !aaa.IsTechOrRoot(m)) {
return
}
if space, ok := list[value[mdb.NAME]]; ok {
value[ice.MAIN] = space[ice.MAIN]
value[mdb.ICONS] = space[mdb.ICONS]
m.Push("", value, kit.Slice(head, 0, -1))
if m.IsCliUA() || simple {
m.Push(mdb.TYPE, space[mdb.TYPE]).Push(cli.STATUS, cli.START)
m.Push(nfs.MODULE, space[nfs.MODULE]).Push(nfs.VERSION, space[nfs.VERSION]).Push(mdb.TEXT, DreamStat(m, value[mdb.NAME]))
kit.If(aaa.IsTechOrRoot(m), func() { m.PushButton(cli.STOP) }, func() { m.PushButton() })
} else {
msg := gdb.Event(m.Spawn(value, space), DREAM_TABLES)
kit.If(aaa.IsTechOrRoot(m), func() { msg.Copy(m.Spawn().PushButton(cli.STOP)) })
m.Push(mdb.TYPE, space[mdb.TYPE]).Push(cli.STATUS, cli.START)
m.Push(nfs.MODULE, space[nfs.MODULE]).Push(nfs.VERSION, space[nfs.VERSION])
m.Push(mdb.TEXT, space[nfs.MODULE]+"\n"+msg.Append(mdb.TEXT))
m.PushButton(strings.Join(msg.Appendv(ctx.ACTION), ""))
}
m.Push(mdb.TYPE, space[mdb.TYPE]).Push(cli.STATUS, cli.START)
m.Push(nfs.MODULE, space[nfs.MODULE]).Push(nfs.VERSION, space[nfs.VERSION])
button := []ice.Any{PORTAL, DESKTOP, ADMIN, WORD}
text := space[nfs.MODULE]
kit.If(m.Option(ice.DREAM_SIMPLE) != ice.TRUE && aaa.IsTechOrRoot(m), func() {
kit.If(m.IsDebug(), func() {
button = append(button, VIMER, STATUS, COMPILE, cli.RUNTIME, XTERM)
text += "\n" + DreamStat(m, value[mdb.NAME])
})
button = append(button, "settings", cli.STOP)
})
m.Push(mdb.TEXT, text)
m.PushButton(append(button, OPEN)...)
} else if aaa.IsTechOrRoot(m) {
m.Push("", value, kit.Slice(head, 0, -1))
m.Push(nfs.MODULE, "").Push(nfs.VERSION, "").Push(mdb.TEXT, "")
if m.Push(mdb.TYPE, WORKER); nfs.Exists(m, path.Join(ice.USR_LOCAL_WORK, value[mdb.NAME])) {
m.Push(cli.STATUS, cli.STOP).Push(nfs.MODULE, "").Push(nfs.VERSION, "").Push(mdb.TEXT, "")
kit.If(aaa.IsTechOrRoot(m), func() { m.PushButton(cli.START, nfs.TRASH) }, func() { m.PushButton() })
m.Push(cli.STATUS, cli.STOP).PushButton(cli.START, nfs.TRASH)
} else {
m.Push(cli.STATUS, cli.BEGIN).Push(nfs.MODULE, "").Push(nfs.VERSION, "").Push(mdb.TEXT, "")
kit.If(aaa.IsTechOrRoot(m), func() { m.PushButton(cli.START, mdb.REMOVE) }, func() { m.PushButton() })
m.Push(cli.STATUS, cli.BEGIN).PushButton(cli.START, mdb.REMOVE)
}
}
})
m.RewriteAppend(func(value, key string, index int) string {
if key == mdb.TIME {
if space, ok := list[m.Appendv(mdb.NAME)[index]]; ok {
value = space[mdb.TIME]
return space[mdb.TIME]
}
}
return value
})
return m
}
func _dream_list_icon(m *ice.Message) {
m.RewriteAppend(func(value, key string, index int) string {
if key == mdb.ICONS {
} else if key == mdb.ICONS {
if kit.HasPrefix(value, HTTP, nfs.PS) {
return value
} else if nfs.ExistsFile(m, path.Join(ice.USR_LOCAL_WORK, m.Appendv(mdb.NAME)[index], value)) {
return m.Spawn(kit.Dict(ice.MSG_USERPOD, m.Appendv(mdb.NAME)[index])).FileURI(value)
} else if nfs.ExistsFile(m, value) {
return m.FileURI(value)
} else {
return m.FileURI(nfs.USR_ICONS_ICEBERGS)
}
}
return value
})
return m
}
func _dream_list_more(m *ice.Message, simple bool) *ice.Message {
func _dream_list_more(m *ice.Message) *ice.Message {
field := kit.Split(mdb.Config(m, mdb.FIELD) + ",type,status,module,version,text")
m.Cmds(SPACE).Table(func(value ice.Maps) {
value[nfs.REPOS] = "https://" + value[nfs.MODULE]
value[aaa.ACCESS] = kit.Select("", value[aaa.USERROLE], value[aaa.USERROLE] != aaa.VOID)
value[mdb.STATUS] = cli.START
button := []ice.Any{PORTAL, DESKTOP, ADMIN, WORD}
kit.If(m.IsDebug(), func() { button = append(button, VIMER, STATUS, COMPILE, cli.RUNTIME, XTERM) })
switch value[mdb.TYPE] {
case SERVER:
value[mdb.TEXT] = kit.JoinLine(value[nfs.MODULE], value[mdb.TEXT])
if simple {
defer m.PushButton("")
} else {
msg := gdb.Event(m.Spawn(value), DREAM_TABLES)
defer m.PushButton(strings.Join(msg.Appendv(ctx.ACTION), ""))
}
case ORIGIN:
value[mdb.TEXT] = kit.JoinLine(value[nfs.MODULE], value[mdb.TEXT])
if simple {
defer m.PushButton("")
} else if value[aaa.ACCESS] == "" {
defer m.PushButton(PORTAL)
} else {
msg := gdb.Event(m.Spawn(value), DREAM_TABLES)
defer m.PushButton(strings.Join(msg.Appendv(ctx.ACTION), ""))
if m.IsCliUA() {
return
}
value[mdb.TEXT] = kit.JoinLine(value[nfs.MODULE], value[mdb.TEXT])
button = append(button, GETTOKEN, OPEN)
kit.If(value[aaa.ACCESS] == "", func() { button = []ice.Any{PORTAL, OPEN} })
case SERVER:
if !m.IsCliUA() {
value[mdb.TEXT] = kit.JoinLine(value[nfs.MODULE], value[mdb.TEXT])
} else if !strings.HasPrefix(value[mdb.TEXT], ice.HTTP) {
return
}
button = append(button, SETTOKEN, OPEN)
case aaa.LOGIN:
if m.IsCliUA() {
return
}
value[mdb.TEXT] = kit.JoinWord(value[AGENT], value[cli.SYSTEM], value[aaa.IP], kit.Format(PublicIP(m, value[aaa.IP])))
defer m.PushButton(GRANT)
button = []ice.Any{GRANT}
default:
return
}
m.Push("", value, kit.Split(mdb.Config(m, mdb.FIELD)+",type,status,module,version,text"))
m.Push("", value, field)
m.PushButton(button...)
})
return m
}
@ -119,9 +114,7 @@ func _dream_start(m *ice.Message, name string) {
return
}
if !m.IsCliUA() {
// defer m.ProcessOpenAndRefresh(m.MergePod(name))
defer m.ProcessRefresh()
defer ToastProcess(m, mdb.CREATE, name)()
}
defer mdb.Lock(m, m.PrefixKey(), cli.START, name)()
p := _dream_check(m, name)
@ -140,7 +133,7 @@ func _dream_start(m *ice.Message, name string) {
kit.If(m.Option(nfs.BINARY), func(p string) { _dream_binary(m, p) })
kit.If(m.Option(nfs.TEMPLATE), func(p string) { _dream_template(m, p) })
bin := kit.Select(kit.Path(os.Args[0]), cli.SystemFind(m, ice.ICE_BIN, nfs.PWD+path.Join(p, ice.BIN), nfs.PWD+ice.BIN))
if cli.IsSuccess(m.Cmd(cli.DAEMON, bin, SPACE, tcp.DIAL, ice.DEV, ice.OPS, mdb.TYPE, WORKER, m.OptionSimple(mdb.NAME), cli.DAEMON, ice.OPS)) {
if cli.IsSuccess(m.Cmd(cli.DAEMON, bin, SPACE, tcp.DIAL, ice.DEV, ice.OPS, cli.DAEMON, ice.OPS)) {
gdb.WaitEvent(m, DREAM_OPEN, func(m *ice.Message, arg ...string) bool { return m.Option(mdb.NAME) == name })
m.Sleep300ms()
}
@ -149,7 +142,7 @@ func _dream_check(m *ice.Message, name string) string {
p := path.Join(ice.USR_LOCAL_WORK, name)
msg := m.Spawn(kit.Dict(ice.MSG_USERROLE, aaa.ROOT))
if pp := path.Join(p, ice.VAR_LOG_ICE_PID); nfs.Exists(m, pp) {
for i := 0; i < 10; i++ {
for i := 0; i < 5; i++ {
pid := msg.Cmdx(nfs.CAT, pp)
if pid == "" {
return p
@ -163,7 +156,7 @@ func _dream_check(m *ice.Message, name string) string {
return p
}
if nfs.Exists(m, "/proc/"+pid) && runtime.GOOS == cli.LINUX {
if !kit.HasPrefix(msg.Cmdx(nfs.CAT, "/proc/"+pid+"/cmdline"), kit.Path("bin/ice.bin"), kit.Path(p, "bin/ice.bin")) {
if !kit.HasPrefix(msg.Cmdx(nfs.CAT, "/proc/"+pid+"/cmdline"), kit.Path(ice.BIN_ICE_BIN), kit.Path(p, ice.BIN_ICE_BIN)) {
return p
} else {
return ""
@ -181,7 +174,8 @@ func _dream_binary(m *ice.Message, p string) {
if bin := path.Join(m.Option(cli.CMD_DIR), ice.BIN_ICE_BIN); nfs.Exists(m, bin) {
return
} else if kit.IsUrl(p) || strings.HasPrefix(p, S()) {
m.Cmd(DREAM, DOWNLOAD, bin, p)
// m.Cmd(DREAM, DOWNLOAD, bin, kit.MergeURL2(p, kit.Format("/publish/ice.%s.%s", runtime.GOOS, runtime.GOARCH), ice.POD, m.Option(mdb.NAME)))
m.Cmd(DREAM, DOWNLOAD, bin, kit.MergeURL(p, cli.GOOS, runtime.GOOS, cli.GOARCH, runtime.GOARCH))
} else {
m.Cmd(nfs.LINK, bin, kit.Path(p))
}
@ -210,6 +204,8 @@ const (
STOPALL = "stopall"
FOR_EACH = "forEach"
FOR_FLOW = "forFlow"
GETTOKEN = "gettoken"
SETTOKEN = "settoken"
DREAM_INPUTS = "dream.inputs"
DREAM_CREATE = "dream.create"
@ -219,7 +215,6 @@ const (
DREAM_STOP = "dream.stop"
DREAM_OPEN = "dream.open"
DREAM_CLOSE = "dream.close"
DREAM_TABLES = "dream.tables"
DREAM_ACTION = "dream.action"
@ -233,75 +228,50 @@ func init() {
DREAM: {Name: "dream refresh", Help: "梦想家", Icon: "Launchpad.png", Role: aaa.VOID, Meta: kit.Dict(
ice.CTX_TRANS, kit.Dict(html.INPUT, kit.Dict(WORKER, "空间", SERVER, "门户", ORIGIN, "主机")),
), Actions: ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
ice.AFTER_INIT: {Hand: func(m *ice.Message, arg ...string) {
AddPortalProduct(m, "云空间", `
比虚拟机和容器更加轻量每个空间都是一个完整的系统拥有各种软件与独立的环境
空间内所有的软件配置数据以源码库形式保存每个空间都可以随时启动停止上传下载分享
每个空间都自带软件开发工具也可以随时编程添加新的功能
`, 200.0)
}},
html.BUTTON: {Hand: func(m *ice.Message, arg ...string) {
mdb.Config(m, html.BUTTON, kit.Join(arg))
}},
mdb.SEARCH: {Hand: func(m *ice.Message, arg ...string) {
if mdb.IsSearchPreview(m, arg) {
mdb.HashSelects(m.Spawn()).Table(func(value ice.Maps) { m.PushSearch(mdb.TYPE, WORKER, mdb.TEXT, m.MergePod(value[mdb.NAME]), value) })
}
}},
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {
switch m.Option(ctx.ACTION) {
case mdb.CREATE:
switch arg[0] {
case mdb.NAME:
_dream_list(m, true).Cut("name,status,time")
case mdb.ICONS:
mdb.HashInputs(m, arg)
case nfs.BINARY:
m.Cmdy(nfs.DIR, ice.BIN, "path,size,time", kit.Dict(nfs.DIR_TYPE, nfs.TYPE_BIN))
m.Cmd(nfs.DIR, ice.USR_LOCAL_WORK, kit.Dict(nfs.DIR_TYPE, nfs.TYPE_BOTH), func(value ice.Maps) {
m.Cmdy(nfs.DIR, path.Join(value[nfs.PATH], ice.BIN), "path,size,time", kit.Dict(nfs.DIR_TYPE, nfs.TYPE_BIN))
})
m.RenameAppend(nfs.PATH, arg[0])
DreamListSpide(m, []string{ice.DEV}, ORIGIN, func(dev, origin string) {
m.Spawn().SplitIndex(m.Cmdx(SPIDE, dev, SPIDE_RAW, http.MethodGet, S(), cli.GOOS, runtime.GOOS, cli.GOARCH, runtime.GOARCH)).Table(func(value ice.Maps) {
m.Push(arg[0], origin+S(value[mdb.NAME])).Push(nfs.SIZE, value[nfs.SIZE]).Push(mdb.TIME, value[mdb.TIME])
})
})
}
case STARTALL:
DreamEach(m, "", cli.STOP, func(name string) { m.Push(arg[0], name) })
case tcp.SEND:
m.Cmd(SPACE, func(value ice.Maps) {
kit.If(kit.IsIn(value[mdb.TYPE], SERVER), func() { m.Push(arg[0], value[mdb.NAME]) })
})
default:
switch arg[0] {
case mdb.NAME:
DreamEach(m, "", cli.START, func(name string) { m.Push(arg[0], name) })
case ctx.CMDS:
m.Cmdy(ctx.COMMAND)
case nfs.FILE:
m.Options(nfs.DIR_TYPE, nfs.TYPE_CAT, ice.MSG_FIELDS, nfs.PATH)
m.Cmdy(nfs.DIR, nfs.SRC).Cmdy(nfs.DIR, nfs.ETC).Cmdy(nfs.DIR, "")
case tcp.NODENAME:
m.Cmdy(SPACE, m.Option(mdb.NAME), SPACE, ice.INFO).CutTo(mdb.NAME, tcp.NODENAME)
case aaa.USERNAME:
switch arg[0] {
case mdb.NAME:
DreamEach(m, "", kit.Select(cli.START, cli.STOP, m.Option(ctx.ACTION) == STARTALL), func(name string) { m.Push(arg[0], name) })
case tcp.NODENAME:
m.Cmdy(SPACE, m.Option(mdb.NAME), SPACE, ice.INFO).CutTo(mdb.NAME, arg[0])
case aaa.USERNAME:
if aaa.IsTechOrRoot(m) && m.Option(ctx.ACTION) == GRANT {
m.Cmdy(aaa.USER).Cut(aaa.USERNAME, aaa.USERNICK).Option(ice.TABLE_CHECKBOX, ice.FALSE)
} else {
m.Push(arg[0], m.Option(tcp.NODENAME))
m.Push(arg[0], m.Option(ice.MSG_USERNAME))
default:
gdb.Event(m, DREAM_INPUTS, arg)
}
case nfs.REPOS:
case nfs.BINARY:
default:
gdb.Event(m, DREAM_INPUTS, arg)
}
}},
nfs.SCAN: {Hand: func(m *ice.Message, arg ...string) {
list := m.CmdMap(CODE_GIT_REPOS, nfs.REPOS)
GoToastTable(m.Cmd(nfs.DIR, nfs.USR_LOCAL_WORK, mdb.NAME), mdb.NAME, func(value ice.Maps) {
if repos, ok := list[value[mdb.NAME]]; ok {
m.Cmd("", mdb.CREATE, value[mdb.NAME], repos[ORIGIN])
}
})
}},
mdb.CREATE: {Name: "create name*=hi repos binary", Hand: func(m *ice.Message, arg ...string) {
kit.If(!strings.Contains(m.Option(mdb.NAME), "-") || !strings.HasPrefix(m.Option(mdb.NAME), "20"), func() { m.Option(mdb.NAME, m.Time("20060102-")+m.Option(mdb.NAME)) })
kit.If(mdb.Config(m, nfs.BINARY), func(p string) { m.OptionDefault(nfs.BINARY, p+m.Option(mdb.NAME)) })
kit.If(mdb.Config(m, nfs.REPOS), func(p string) { m.OptionDefault(nfs.REPOS, p+m.Option(mdb.NAME)) })
m.Option(nfs.REPOS, kit.Select("", kit.Split(m.Option(nfs.REPOS)), -1))
// m.OptionDefault(mdb.ICONS, nfs.USR_ICONS_CONTEXTS)
if mdb.HashCreate(m); ice.Info.Important == true {
_dream_start(m, m.Option(mdb.NAME))
StreamPushRefreshConfirm(m, m.Trans("refresh for new space ", "刷新列表查看新空间 ")+m.Option(mdb.NAME))
SpaceEvent(m, OPS_DREAM_CREATE, m.Option(mdb.NAME), m.OptionSimple(mdb.NAME, nfs.REPOS, nfs.BINARY)...)
}
}},
@ -329,24 +299,35 @@ func init() {
m.Cmd(SPACE, path.Base(p), cli.RUNTIME, UPGRADE)
return true
}
})
kit.If(m.Option(mdb.NAME) == "", func() { m.Sleep("5s").Cmdy(ROUTE, cli.BUILD).ProcessInner() })
}).Sleep3s()
m.ProcessHold()
}},
PUBLISH: {Name: "publish name", Hand: func(m *ice.Message, arg ...string) {
m.Option(ice.MSG_TITLE, kit.Keys(m.Option(ice.MSG_USERPOD0), m.Option(ice.MSG_USERPOD), m.CommandKey(), m.ActionKey()))
list := []string{cli.LINUX, cli.DARWIN, cli.WINDOWS}
msg := m.Spawn(ice.Maps{ice.MSG_DAEMON: ""})
func() {
if m.Option(mdb.NAME) != "" {
return
}
defer ToastProcess(m, PUBLISH, ice.Info.Pathname)()
m.Cmd(AUTOGEN, BINPACK)
kit.For(list, func(goos string) {
PushNoticeRich(m, mdb.NAME, ice.Info.NodeName, msg.Cmd(COMPILE, goos, cli.AMD64).AppendSimple())
list := []string{cli.AMD64}
kit.If(goos == cli.DARWIN, func() { list = append(list, cli.ARM64) })
kit.For(list, func(arch string) {
PushNoticeRich(m, mdb.NAME, ice.Info.NodeName, msg.Cmd(COMPILE, goos, arch).AppendSimple())
})
})
}()
DreamEach(m, m.Option(mdb.NAME), "", func(name string) {
m.Cmd(SPACE, name, AUTOGEN, BINPACK)
kit.For(list, func(goos string) {
PushNoticeRich(m.Options(ice.MSG_COUNT, "0", ice.LOG_DISABLE, ice.TRUE), mdb.NAME, name, msg.Cmd(SPACE, name, COMPILE, goos, cli.AMD64, kit.Dict(ice.MSG_USERPOD, name)).AppendSimple())
list := []string{cli.AMD64}
kit.If(goos == cli.DARWIN, func() { list = append(list, cli.ARM64) })
kit.For(list, func(arch string) {
PushNoticeRich(m.Options(ice.MSG_COUNT, "0", ice.LOG_DISABLE, ice.TRUE), mdb.NAME, name, msg.Cmd(SPACE, name, COMPILE, goos, arch, kit.Dict(ice.MSG_USERPOD, name)).AppendSimple())
})
})
})
m.ProcessHold()
@ -362,69 +343,61 @@ func init() {
if cb, ok := m.OptionCB("").(func(string) bool); ok && cb(p) {
return
}
defer PushNoticeGrow(msg, "\r\n\r\n\r\n")
PushNoticeGrow(msg, kit.Format("[%s]%s$ %s\r\n", time.Now().Format(ice.MOD_TIME_ONLY), name, m.Option(ice.CMD)))
defer PushNoticeGrow(msg, "\r\n\r\n")
PushNoticeGrow(msg, kit.Format("\033[33m[%s]%s$\033[0m %s\r\n", time.Now().Format(ice.MOD_TIME_ONLY), name, m.Option(ice.CMD)))
m.Cmd(cli.SYSTEM, kit.Split(m.Option(ice.CMD)), kit.Dict(cli.CMD_DIR, p)).Sleep300ms()
})
}},
ctx.CMDS: {Name: "cmds name cmds*", Help: "命令", Icon: "bi bi-terminal", Hand: func(m *ice.Message, arg ...string) {
DreamEach(m, m.Option(mdb.NAME), "", func(name string) {
m.Push(mdb.NAME, name).Push(mdb.TEXT, m.Cmdx(SPACE, name, kit.Split(m.Option(ctx.CMDS))))
}).StatusTimeCount(m.OptionSimple(ctx.CMDS)).ProcessInner()
}},
nfs.FILE: {Name: "file name file*", Help: "文件", Icon: "bi bi-file-earmark-code", Hand: func(m *ice.Message, arg ...string) {
DreamEach(m, m.Option(mdb.NAME), "", func(name string) {
m.Push(mdb.NAME, name).Push(mdb.TEXT, m.Cmdx(SPACE, name, nfs.CAT, m.Option(nfs.FILE)))
}).StatusTimeCount(m.OptionSimple(nfs.FILE)).ProcessInner()
}},
cli.START: {Hand: func(m *ice.Message, arg ...string) {
_dream_start(m, m.Option(mdb.NAME))
gdb.Event(m, DREAM_START, arg)
}},
cli.STOP: {Hand: func(m *ice.Message, arg ...string) {
defer ToastProcess(m)()
gdb.Event(m, DREAM_STOP, arg)
m.Cmd(SPACE, mdb.MODIFY, m.OptionSimple(mdb.NAME), mdb.STATUS, cli.STOP)
m.Cmd(SPACE, m.Option(mdb.NAME), ice.EXIT).Sleep3s()
}},
cli.RUNTIME: {Hand: func(m *ice.Message, arg ...string) {
ProcessPodCmd(m, m.Option(mdb.NAME), "", nil, arg...)
}},
"settings": {Name: "settings restart=manual,always access=public,private", Help: "设置", Icon: "bi bi-gear", Hand: func(m *ice.Message, arg ...string) {
kit.If(m.Option(cli.RESTART) == "manual", func() { m.Option(cli.RESTART, "") })
kit.If(m.Option(aaa.ACCESS) == aaa.PUBLIC, func() { m.Option(aaa.ACCESS, "") })
mdb.HashModify(m, m.OptionSimple(mdb.NAME, cli.RESTART, aaa.ACCESS))
}},
tcp.SEND: {Name: "send to*", Hand: func(m *ice.Message, arg ...string) {
m.Cmd(SPACE, m.Option(nfs.TO), DREAM, mdb.CREATE, m.OptionSimple(mdb.NAME, mdb.ICONS, nfs.REPOS, nfs.BINARY))
m.Cmd(SPACE, m.Option(nfs.TO), DREAM, cli.START, m.OptionSimple(mdb.NAME))
ProcessIframe(m, "", m.MergePod(kit.Keys(m.Option(nfs.TO), m.Option(mdb.NAME))))
}},
nfs.COPY: {Name: "copy to*", Help: "复制", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy("", mdb.CREATE, mdb.NAME, m.Option(nfs.TO), nfs.BINARY, path.Join(ice.USR_LOCAL_WORK, m.Option(mdb.NAME), ice.BIN_ICE_BIN))
}},
nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) {
gdb.Event(m, DREAM_TRASH, arg)
nfs.Trash(m, path.Join(ice.USR_LOCAL_WORK, m.Option(mdb.NAME)))
}},
GRANT: {Hand: func(m *ice.Message, arg ...string) {
m.Cmd(CHAT_GRANT, aaa.CONFIRM, kit.Dict(SPACE, m.Option(mdb.NAME)))
cli.RUNTIME: {Hand: func(m *ice.Message, arg ...string) {
ProcessPodCmd(m, m.Option(mdb.NAME), "", nil, arg...)
}},
TOKEN: {Hand: func(m *ice.Message, arg ...string) {
"settings": {Name: "settings restart=manual,always access=public,private", Help: "设置", Style: html.DANGER, Hand: func(m *ice.Message, arg ...string) {
kit.If(m.Option(cli.RESTART) == "manual", func() { m.Option(cli.RESTART, "") })
kit.If(m.Option(aaa.ACCESS) == aaa.PUBLIC, func() { m.Option(aaa.ACCESS, "") })
mdb.HashModify(m, m.OptionSimple(mdb.NAME, cli.RESTART, aaa.ACCESS))
}},
SETTOKEN: {Name: "settoken nodename* username*", Help: "令牌", Style: html.DANGER, Hand: func(m *ice.Message, arg ...string) {
token := m.Cmdx(TOKEN, mdb.CREATE, mdb.TYPE, SERVER, mdb.NAME, m.Option(aaa.USERNAME), mdb.TEXT, m.Option(tcp.NODENAME))
m.Cmd(SPACE, m.Option(mdb.NAME), SPIDE, DEV_CREATE_TOKEN, ice.Maps{TOKEN: token})
}},
GETTOKEN: {Help: "令牌", Style: html.DANGER, Hand: func(m *ice.Message, arg ...string) {
m.Options(m.Cmd(SPIDE, m.Option(mdb.NAME)).AppendSimple()).Cmdy(SPIDE, mdb.DEV_REQUEST)
}},
"settoken": {Name: "settoken nodename* username*", Help: "令牌", Icon: "bi bi-person-fill-down", Hand: func(m *ice.Message, arg ...string) {
token := m.Cmdx(TOKEN, mdb.CREATE, mdb.TYPE, SERVER, mdb.NAME, m.Option(aaa.USERNAME), mdb.TEXT, m.Option(tcp.NODENAME))
m.Cmd(SPACE, m.Option(mdb.NAME), SPIDE, DEV_CREATE_TOKEN, ice.Maps{CLIENT_NAME: ice.DEV, TOKEN: token})
GRANT: {Name: "grant username", Role: aaa.VOID, Hand: func(m *ice.Message, arg ...string) {
if aaa.IsTechOrRoot(m) && m.Option(aaa.USERNAME) != "" {
m.Option(ice.MSG_USERNAME, m.Option(aaa.USERNAME))
}
m.Cmd(CHAT_GRANT, aaa.CONFIRM, kit.Dict(SPACE, m.Option(mdb.NAME)))
}},
OPEN: {Role: aaa.VOID, Hand: func(m *ice.Message, arg ...string) {
if m.Option(mdb.TYPE) == ORIGIN {
OPEN: {Style: html.NOTICE, Role: aaa.VOID, Hand: func(m *ice.Message, arg ...string) {
if strings.HasSuffix(m.Option(ice.MAIN), ".portal") || kit.HasPrefixList(arg, ctx.RUN) {
if !kit.HasPrefixList(arg, ctx.RUN) {
defer m.Push(TITLE, m.Option(mdb.NAME))
defer m.Push("_icon", m.Option(mdb.ICON))
defer m.Push("_style", "portal")
defer m.Push("_height", "844")
defer m.Push("_width", "390")
}
ctx.ProcessFloat(m, CHAT_IFRAME, S(m.Option(mdb.NAME)), arg...)
} else if m.Option(mdb.TYPE) == ORIGIN {
m.ProcessOpen(SpideOrigin(m, m.Option(mdb.NAME)))
} else if p := ProxyDomain(m, m.Option(mdb.NAME)); p != "" {
m.ProcessOpen(p)
} else {
m.ProcessOpen(S(m.Option(mdb.NAME)))
m.ProcessOpen(S(kit.Keys(m.Option(ice.MSG_USERPOD), m.Option(mdb.NAME))))
}
}},
DREAM_OPEN: {Hand: func(m *ice.Message, arg ...string) {}},
@ -436,31 +409,18 @@ func init() {
})
}},
DREAM_TABLES: {Hand: func(m *ice.Message, arg ...string) {
if !aaa.IsTechOrRoot(m) {
m.PushButton(OPEN)
return
}
list := []ice.Any{}
// kit.If(m.IsDebug(), func() { list = append(list, cli.RUNTIME) })
switch m.Option(mdb.TYPE) {
case WORKER:
list = append(list, "settings", nfs.COPY, tcp.SEND)
case SERVER:
list = append(list, "settoken", DREAM)
default:
list = append(list, TOKEN, DREAM)
}
list = append(list, OPEN)
m.PushButton(list...)
}},
STATS_TABLES: {Hand: func(m *ice.Message, arg ...string) {
if msg := _dream_list(m.Spawn(), true); msg.Length() > 0 {
stat := map[string]int{}
msg.Table(func(value ice.Maps) { stat[value[mdb.TYPE]]++; stat[value[mdb.STATUS]]++ })
PushStats(m, kit.Keys(m.CommandKey(), cli.START), stat[cli.START], "", "已启动空间")
PushStats(m, kit.Keys(m.CommandKey(), SERVER), stat[SERVER], "", "已连接机器")
PushStats(m, kit.Keys(m.CommandKey(), ORIGIN), stat[ORIGIN], "", "已连接主机")
button := []ice.Any{}
if aaa.IsTechOrRoot(m) {
switch m.Option(mdb.TYPE) {
case ORIGIN:
button = append(button, DREAM, GETTOKEN)
case SERVER:
button = append(button, DREAM, SETTOKEN)
case WORKER:
button = append(button, "settings")
}
}
m.PushButton(append(button, OPEN)...)
}},
SERVE_START: {Hand: func(m *ice.Message, arg ...string) {
for _, cmd := range kit.Reverse(kit.Split(mdb.Config(m, html.BUTTON))) {
@ -468,23 +428,41 @@ func init() {
m.Cmd(gdb.EVENT, gdb.LISTEN, gdb.EVENT, DREAM_ACTION, ice.CMD, cmd)
aaa.White(m, kit.Keys(m.ShortKey(), ctx.ACTION, cmd))
}
mdb.HashSelects(m.Spawn()).Table(func(value ice.Maps) {
mdb.HashSelects(m.Spawn()).SortStrR(mdb.NAME).Table(func(value ice.Maps) {
if value[cli.RESTART] == ALWAYS && nfs.Exists(m, path.Join(ice.USR_LOCAL_WORK+value[mdb.NAME])) {
m.Cmd(DREAM, cli.START, kit.Dict(mdb.NAME, value[mdb.NAME]))
}
})
}},
STATS_TABLES: {Hand: func(m *ice.Message, arg ...string) {
if msg := _dream_list(m.Spawn()); msg.Length() > 0 {
stat := map[string]int{}
msg.Table(func(value ice.Maps) { stat[value[mdb.TYPE]]++; stat[value[mdb.STATUS]]++ })
PushStats(m, kit.Keys(m.CommandKey(), cli.START), stat[cli.START], "", "已启动空间")
PushStats(m, kit.Keys(m.CommandKey(), SERVER), stat[SERVER], "", "已连接机器")
PushStats(m, kit.Keys(m.CommandKey(), ORIGIN), stat[ORIGIN], "", "已连接主机")
}
}},
ORIGIN: {Hand: func(m *ice.Message, arg ...string) {
m.Cmd(SPACE).Table(func(value ice.Maps, index int, head []string) {
kit.If(value[mdb.TYPE] == m.ActionKey(), func() { m.PushRecord(value, head...) })
})
m.Sort(mdb.TIME, ice.STR_R)
m.SortStrR(mdb.NAME)
kit.If(len(arg) > 0, func() { m.Cut(arg...) })
}},
SERVER: {Hand: func(m *ice.Message, arg ...string) {
m.Cmd(SPACE).Table(func(value ice.Maps, index int, head []string) {
kit.If(value[mdb.TYPE] == m.ActionKey(), func() { m.PushRecord(value, head...) })
})
m.Sort(mdb.TIME, ice.STR_R)
m.SortStrR(mdb.NAME)
kit.If(len(arg) > 0, func() { m.Cut(arg...) })
}},
WORKER: {Hand: func(m *ice.Message, arg ...string) {
m.Cmd(SPACE).Table(func(value ice.Maps, index int, head []string) {
kit.If(value[mdb.TYPE] == m.ActionKey(), func() { m.PushRecord(value, head...) })
})
m.SortStrR(mdb.NAME)
kit.If(len(arg) > 0, func() { m.Cut(arg...) })
}},
DOWNLOAD: {Name: "download path link", Hand: func(m *ice.Message, arg ...string) {
GoToast(m, func(toast func(string, int, int)) []string {
@ -502,60 +480,35 @@ func init() {
m.Cmd(cli.SYSTEM, cli.GO, "work", "init")
kit.For([]string{".", nfs.USR_RELEASE, nfs.USR_ICEBERGS, nfs.USR_TOOLKITS}, func(p string) { m.Cmd(cli.SYSTEM, cli.GO, "work", "use", p) })
DreamEach(m, m.Option(mdb.NAME), "", func(name string) { m.Cmd(cli.SYSTEM, cli.GO, "work", "use", path.Join(ice.USR_LOCAL_WORK, name)) })
}},
nfs.SCAN: {Hand: func(m *ice.Message, arg ...string) {
list := m.CmdMap(CODE_GIT_REPOS, nfs.REPOS)
GoToastTable(m.Cmd(nfs.DIR, nfs.USR_LOCAL_WORK, mdb.NAME), mdb.NAME, func(value ice.Maps) {
if repos, ok := list[value[mdb.NAME]]; ok {
m.Cmd("", mdb.CREATE, value[mdb.NAME], repos[ORIGIN])
}
})
m.Cmdy(nfs.CAT, "go.work")
}},
}, StatsAction(), DreamAction(), DreamTablesAction(), mdb.ImportantHashAction(
mdb.SHORT, mdb.NAME, mdb.FIELD, "time,name,icons,repos,binary,template,restart,access",
html.BUTTON, kit.JoinWord(PORTAL, DESKTOP, ADMIN, WORD, STATUS, VIMER, COMPILE, XTERM, DREAM),
ONLINE, ice.TRUE,
mdb.SHORT, mdb.NAME, mdb.FIELD, "time,name,main,icons,repos,binary,template,restart,access",
html.BUTTON, kit.JoinWord(PORTAL, DESKTOP, ADMIN, WORD, VIMER, STATUS, COMPILE, XTERM, DREAM),
)), Hand: func(m *ice.Message, arg ...string) {
if len(arg) == 0 {
simple := m.Option(ice.DREAM_SIMPLE) == ice.TRUE
if ice.Info.NodeType != WORKER {
_dream_list(m, simple)
_dream_list_icon(m)
if m.Length() == 0 {
m.EchoInfoButton(m.Trans("please scan or create new dream", "请扫描或创建新空间"), mdb.CREATE, nfs.SCAN)
return
}
if ice.Info.NodeType == WORKER {
return
}
if !m.IsCliUA() && aaa.IsTechOrRoot(m) {
_dream_list_more(m, simple)
} else {
msg := m.Spawn(kit.Dict(ice.MSG_USERROLE, aaa.TECH))
m.Cmds(SPACE).Table(func(value ice.Maps) {
if value[mdb.TYPE] == SERVER {
if p := ProxyDomain(msg, value[mdb.NAME]); p != "" {
value[mdb.TEXT] = p
m.PushRecord(value, mdb.TIME, mdb.TYPE, mdb.NAME, mdb.ICONS, nfs.MODULE, nfs.VERSION, mdb.TEXT)
m.PushButton(PORTAL, DESKTOP)
}
}
})
}
if ice.Info.NodeType == WORKER || !aaa.IsTechOrRoot(m) || m.IsCliUA() {
_dream_list(m)
if _dream_list_more(m); !aaa.IsTechOrRoot(m) || m.IsCliUA() {
m.Action()
} else if m.IsDebug() && cli.SystemFindGo(m) {
m.Action(mdb.CREATE, STARTALL, STOPALL, cli.BUILD, PUBLISH)
} else {
m.Action(mdb.CREATE, STARTALL, STOPALL)
}
if m.Length() == 0 {
m.EchoInfoButton(m.Trans("please scan or create new dream", "请扫描或创建新空间"), mdb.CREATE, nfs.SCAN)
return
}
ctx.DisplayTableCard(m)
m.Options(ice.MSG_TOOLKIT, "web.code.compose.insight")
m.Sort("type,status,name", []string{aaa.LOGIN, WORKER, SERVER, ORIGIN}, []string{cli.START, cli.STOP, cli.BEGIN}, ice.STR_R)
m.StatusTimeCountStats(mdb.TYPE, mdb.STATUS)
ctx.DisplayTableCard(m)
kit.If(!aaa.IsTechOrRoot(m), func() { m.Options(ice.MSG_TOOLKIT, "", ice.MSG_ONLINE, ice.FALSE) })
kit.If(!m.IsDebug(), func() { m.Options(ice.MSG_TOOLKIT, "") })
} else if arg[0] == ctx.ACTION {
gdb.Event(m, DREAM_ACTION, arg)
} else {
mdb.HashSelects(m, arg[0]).PushAction(PORTAL, DESKTOP, ADMIN, OPEN, mdb.REMOVE)
m.Cmdy(arg[1], DREAM_ACTION, arg)
// gdb.Event(m, DREAM_ACTION, arg)
}
}},
})
@ -585,7 +538,8 @@ func DreamProcessIframe(m *ice.Message, arg ...string) {
return
}
if len(arg) == 2 {
defer m.Push(TITLE, kit.Keys(m.Option(mdb.NAME), m.ShortKey()))
defer m.Push(TITLE, kit.Keys(m.Option(mdb.NAME), m.ShortKey())+kit.Format("(%s)", m.Command().Help))
defer m.Push("_icon", m.Option(mdb.ICON))
}
DreamProcess(m, CHAT_IFRAME, func() string {
p := S(kit.Keys(m.Option(ice.MSG_USERPOD), m.Option(mdb.NAME)))

View File

@ -119,7 +119,7 @@ func init() {
}},
}, ctx.ConfAction(
mdb.FIELD, "time,domain,status,type,name,text,icons,repos,binary,module,version,access",
ctx.TOOLS, kit.Simple(SPIDE, VERSION, STATUS), ONLINE, ice.TRUE, cli.TIMEOUT, "10s",
ctx.TOOLS, kit.Simple("web.code.compose.insight", VERSION), ONLINE, ice.TRUE, cli.TIMEOUT, "10s",
)), Hand: func(m *ice.Message, arg ...string) {
if kit.HasPrefixList(arg, ctx.ACTION) {
_matrix_action(m, arg[1], arg[2:]...)

View File

@ -52,7 +52,9 @@ Volcanos(chat.ONIMPORT, {
if (value.module == item.module) { worker = value }
})
}
return !worker? html.NOTICE: (worker.status != cli.STOP && item.status != cli.STOP && (item.version != worker.version || item.time < worker.time))? html.DANGER: ""
return !worker? html.NOTICE: (worker.status != cli.STOP && item.status != cli.STOP && (item.version != worker.version ||
(item["server.type"] == "origin"? item.time > worker.time: item.time < worker.time)
))? html.DANGER: ""
},
}, [""])
Volcanos(chat.ONACTION, {

View File

@ -15,7 +15,7 @@ import (
)
func UserWeb(m *ice.Message) *url.URL {
return kit.ParseURL(m.Option(ice.MSG_USERWEB))
return kit.ParseURL(m.OptionDefault(ice.MSG_USERWEB, "http://localhost:9020"))
}
func UserHost(m *ice.Message) string {
if p := m.Option(ice.MSG_USERHOST); p != "" {

View File

@ -38,7 +38,7 @@ func ProcessHashPodCmd(m *ice.Message, arg ...string) (msg *ice.Message) {
return ctx.ProcessFloat(m.Options(ice.POD, msg.Append(SPACE)), msg.Append(ctx.INDEX), kit.Split(msg.Append(ctx.ARGS)), arg...)
}
func processSpace(m *ice.Message, pod string, arg ...string) {
m.ProcessField(ctx.ACTION, m.ActionKey(), ctx.RUN, arg)
m.ProcessField(kit.TransArgs(kit.Simple(ctx.ACTION, m.ActionKey(), ctx.RUN, arg))...)
m.RewriteAppend(func(value, key string, index int) string { return kit.Select("", value, key != SPACE) })
m.Push(ice.MSG_SPACE, strings.TrimPrefix(pod, "ops."))
}

View File

@ -13,15 +13,12 @@ const PRODUCT = "product"
func init() {
Index.MergeCommands(ice.Commands{
PRODUCT: {Name: "product refresh", Help: "产品展示", Actions: mdb.HashAction(mdb.SHORT, "index", mdb.FIELD, "time,name,text,order,enable,index,args"), Hand: func(m *ice.Message, arg ...string) {
PRODUCT: {Name: "product refresh", Help: "产品展示", Actions: mdb.HashAction(mdb.SHORT, "index", mdb.FIELD, "time,name,text,order,disable,index,args"), Hand: func(m *ice.Message, arg ...string) {
mdb.HashSelect(m, arg...).SortInt(mdb.ORDER)
}},
})
}
func AddPortalProduct(m *ice.Message, name, text string, order float64, arg ...string) {
msg := m.Spawn()
m.GoSleep("300ms", func() {
msg.Cmd("web.product", mdb.CREATE, mdb.NAME, name, mdb.TEXT, strings.TrimSpace(text), mdb.ORDER, order, ctx.INDEX, msg.PrefixKey(), ctx.ARGS, kit.Format(arg))
})
m.Cmd("web.product", mdb.CREATE, mdb.NAME, name, mdb.TEXT, strings.TrimSpace(text), mdb.ORDER, order, ctx.INDEX, m.PrefixKey(), ctx.ARGS, kit.Format(arg))
}

View File

@ -75,14 +75,17 @@ func Render(m *ice.Message, cmd string, args ...ice.Any) bool {
res := m.Cmdx(nfs.CAT, arg[0])
fieldset := "fieldset." + m.Option(ctx.INDEX)
m.W.Write([]byte(kit.ReplaceAll(res,
"$content", fieldset+">div.output>div.layout>div.layout>div.content",
"$profile", fieldset+">div.output>div.layout>div.layout>div.profile",
"$display", fieldset+">div.output>div.layout>div.display",
"$project", fieldset+">div.output>div.project",
"$option", fieldset+">form.option",
"$action", fieldset+">div.action",
"$output", fieldset+">div.output",
"$project", fieldset+">div.output>div.project",
"$display", fieldset+">div.output>div.layout>div.display",
"$profile", fieldset+">div.output>div.layout>div.layout>div.profile",
"$content", fieldset+">div.output>div.layout>div.layout>div.content",
"$fieldset", fieldset, "$index", m.Option(ctx.INDEX),
"$status", fieldset+">div.status",
"$fieldset", fieldset,
"$body", "body.cmd."+m.Option(ctx.INDEX),
"$index", m.Option(ctx.INDEX),
"$input", "body>div.input.float."+m.Option(ctx.INDEX),
)))
break
@ -153,7 +156,9 @@ func RenderMain(m *ice.Message) *ice.Message {
}
m.Options(nfs.SCRIPT, ice.SRC_MAIN_JS, nfs.VERSION, RenderVersion(m))
m.OptionDefault(mdb.ICONS, strings.Split(m.Resource(ice.Info.NodeIcon), "?")[0]+m.Option(nfs.VERSION))
m.OptionDefault(TITLE, kit.Select("localhost:9020", UserWeb(m).Host, m.Option(ice.MSG_USERPOD), kit.Select("", ice.Info.Titles, ice.Info.Titles != "ContextOS")))
m.OptionDefault(TITLE, kit.Select("", ice.Info.Titles, ice.Info.Titles != "ContextOS"))
kit.If(ice.Info.NodeType == WORKER, func() { m.OptionDefault(TITLE, m.Option(ice.MSG_USERPOD)) })
m.OptionDefault(TITLE, kit.Select("ContextOS", UserWeb(m).Host))
return m.RenderResult(kit.Renders(m.Cmdx(nfs.CAT, ice.SRC_MAIN_HTML), m))
}
func RenderCmds(m *ice.Message, cmds ...ice.Any) {
@ -163,23 +168,24 @@ func RenderPodCmd(m *ice.Message, pod, cmd string, arg ...ice.Any) {
if msg := m.Cmd(Space(m, pod), ctx.COMMAND, kit.Select(m.ShortKey(), cmd)); msg.Length() == 0 {
RenderResult(m, kit.Format("not found command %s", cmd))
} else {
m.OptionDefault(mdb.ICONS, m.Resource(kit.Select(ice.Info.NodeIcon, msg.Append(mdb.ICONS))))
if !kit.IsIn(cmd, PORTAL, DESKTOP, ADMIN) {
pod = kit.Select(pod, msg.Option(ice.MSG_NODENAME))
m.OptionDefault(TITLE, kit.Select(cmd, msg.Append(mdb.HELP)+kit.Select("", " "+pod, pod != ""), !m.IsEnglish()))
if kit.IsIn(msg.Append(ctx.INDEX), "word", "vimer", "web.wiki.word", "web.code.vimer") {
m.Option(mdb.ICONS, msg.Option(ice.MSG_NODEICON))
}
m.OptionDefault(mdb.ICONS, m.Resource(kit.Select(ice.Info.NodeIcon, msg.Option(ice.MSG_NODEICON), msg.Append(mdb.ICONS))))
serve := strings.Split(UserHost(m), "://")[1]
pod = kit.Select(pod, msg.Option(ice.MSG_NODENAME), m.Option(ice.MSG_USERPOD) != "")
m.OptionDefault(TITLE, kit.Select(cmd, msg.Append(mdb.HELP), !m.IsEnglish())+" "+kit.Select(serve, pod))
RenderCmds(m, kit.Dict(msg.AppendSimple(), ctx.ARGS, kit.Simple(arg), ctx.DISPLAY, m.Option(ice.MSG_DISPLAY)))
}
}
func RenderCmd(m *ice.Message, cmd string, arg ...ice.Any) { RenderPodCmd(m, "", cmd, arg...) }
func RenderVersion(m *ice.Message) string {
if ice.Info.Make.Hash == "" {
return ""
}
ls := []string{ice.Info.Make.Version, ice.Info.Make.Forword, ice.Info.Make.Hash[:6]}
if m.Option(log.DEBUG) == ice.TRUE || m.R != nil && strings.Contains(m.R.URL.RawQuery, "debug=true") {
ls = append(ls, kit.Format("%d", time.Now().Unix()-kit.Time(ice.Info.Make.When)/int64(time.Second)))
ls := []string{ice.Info.Make.Versions()}
if strings.Contains(ice.Info.Make.Domain, "debug=true") {
if m.Option(log.DEBUG) == ice.TRUE || m.R != nil && strings.Contains(m.R.URL.RawQuery, "debug=true") {
ls = append(ls, kit.Format("%d", time.Now().Unix()-kit.Time(ice.Info.Make.When)/int64(time.Second)))
}
}
return "?" + kit.JoinQuery(kit.Simple(kit.Dict("_v", strings.Join(ls, "-"), ice.POD, m.Option(ice.MSG_USERPOD)))...)
}
@ -205,36 +211,41 @@ const (
UPGRADE = "upgrade"
INSTALL = "install"
CODE_GIT_SERVICE = "web.code.git.service"
CODE_GIT_SEARCH = "web.code.git.search"
CODE_GIT_STATUS = "web.code.git.status"
CODE_GIT_REPOS = "web.code.git.repos"
CODE_AUTOGEN = "web.code.autogen"
CODE_COMPILE = "web.code.compile"
CODE_PUBLISH = "web.code.publish"
CODE_UPGRADE = "web.code.upgrade"
CODE_VIMER = "web.code.vimer"
CODE_INNER = "web.code.inner"
CODE_XTERM = "web.code.xterm"
CODE_MOD = "web.code.mod"
WIKI_FEEL = "web.wiki.feel"
WIKI_DRAW = "web.wiki.draw"
WIKI_WORD = "web.wiki.word"
WIKI_PORTAL = "web.wiki.portal"
CHAT_OAUTH_CLIENT = "web.chat.oauth.client"
CHAT_WX_ACCESS = "web.chat.wx.access"
CHAT_WX_AGENT = "web.chat.wx.agent"
CHAT_WX_TEMPLATE = "web.chat.wx.template"
CHAT_WX_OCR = "web.chat.wx.ocr"
CHAT_MESSAGE = "web.chat.message"
CHAT_HEADER = "web.chat.header"
CHAT_IFRAME = "web.chat.iframe"
CHAT_FAVOR = "web.chat.favor"
CHAT_FLOWS = "web.chat.flows"
CHAT_GRANT = "web.chat.grant"
CHAT_POD = "web.chat.pod"
CHAT_CMD = "web.chat.cmd"
TEAM_PLAN = "web.team.plan"
CODE_MYSQL_CLIENT = "web.code.mysql.client"
CODE_MYSQL_QUERY = "web.code.mysql.query"
CODE_GIT_SERVICE = "web.code.git.service"
CODE_GIT_SEARCH = "web.code.git.search"
CODE_GIT_STATUS = "web.code.git.status"
CODE_GIT_REPOS = "web.code.git.repos"
CODE_AUTOGEN = "web.code.autogen"
CODE_COMPILE = "web.code.compile"
CODE_PUBLISH = "web.code.publish"
CODE_UPGRADE = "web.code.upgrade"
CODE_VIMER = "web.code.vimer"
CODE_INNER = "web.code.inner"
CODE_XTERM = "web.code.xterm"
CODE_MOD = "web.code.mod"
WIKI_FEEL = "web.wiki.feel"
WIKI_DRAW = "web.wiki.draw"
WIKI_WORD = "web.wiki.word"
WIKI_PORTAL = "web.wiki.portal"
CHAT_OAUTH_CLIENT = "web.chat.oauth.client"
CHAT_WX_ACCESS = "web.chat.wx.access"
CHAT_WX_AGENT = "web.chat.wx.agent"
CHAT_WX_TEMPLATE = "web.chat.wx.template"
CHAT_WX_OCR = "web.chat.wx.ocr"
CHAT_MESSAGE = "web.chat.message"
CHAT_HEADER = "web.chat.header"
CHAT_IFRAME = "web.chat.iframe"
CHAT_FAVOR = "web.chat.favor"
CHAT_FLOWS = "web.chat.flows"
CHAT_GRANT = "web.chat.grant"
CHAT_POD = "web.chat.pod"
CHAT_CMD = "web.chat.cmd"
TEAM_PLAN = "web.team.plan"
TEAM_GONGANXITONG_USER = "web.team.gonganxitong.user"
TEAM_GONGANXITONG_CITY = "web.team.gonganxitong.city"
TEAM_GONGANXITONG_DOMAIN = "web.team.gonganxitong.domain"
)
func MessageInsertJSON(m *ice.Message, zone, name, text string, arg ...string) {

View File

@ -1,6 +1,7 @@
package web
import (
"io/ioutil"
"net/http"
"net/url"
"os"
@ -34,23 +35,24 @@ func _serve_start(m *ice.Message) {
}).Sleep(cli.TIME_1s)
cli.NodeInfo(m, kit.Select(kit.Split(ice.Info.Hostname, nfs.PT)[0], m.Option(tcp.NODENAME)), SERVER, mdb.Config(m, mdb.ICONS))
kit.If(ice.HasVar(), func() { m.Cmd(nfs.SAVE, ice.VAR_LOG_ICE_PORT, m.Option(tcp.PORT)) })
kit.For(kit.Split(m.Option(ice.DEV)), func(dev string) {
if strings.HasPrefix(dev, HTTP) {
m.Cmd(SPIDE, mdb.CREATE, dev, ice.DEV, "", nfs.REPOS)
m.Cmd(SPIDE, mdb.CREATE, dev, "dev_ip", "", "dev_ip")
dev = ice.DEV
}
if msg := m.Cmd(SPIDE, dev); msg.Append(TOKEN) == "" {
if m.Option(TOKEN) != "" {
m.Cmd(SPACE, tcp.DIAL, ice.DEV, dev, TOKEN, m.Option(TOKEN))
} else {
m.Cmd(SPACE, tcp.DIAL, ice.DEV, dev)
}
}
})
m.Spawn(ice.Maps{TOKEN: ""}).Start("", m.OptionSimple(tcp.HOST, tcp.PORT)...)
if m.Cmd(tcp.HOST).Length() == 0 {
return
}
kit.For(kit.Split(m.Option(ice.DEV)), func(dev string) {
if strings.HasPrefix(dev, HTTP) {
m.Cmd(SPIDE, mdb.CREATE, dev, ice.DEV, "", nfs.REPOS)
dev = ice.DEV
}
if msg := m.Cmds(SPIDE, dev); msg.Append(TOKEN) == "" {
if m.Option(TOKEN) != "" {
m.Sleep30ms(SPACE, tcp.DIAL, ice.DEV, dev, TOKEN, m.Option(TOKEN))
} else {
m.Sleep30ms(SPACE, tcp.DIAL, ice.DEV, dev)
}
}
})
}
func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool {
const (
@ -63,6 +65,10 @@ func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool {
} else {
return true
}
func() {
defer InfoLock.Lock()()
Info.ServeMainCount++
}()
if ip := r.Header.Get(X_REAL_IP); ip != "" {
if r.Header.Set(ice.MSG_USERIP, ip); r.Header.Get(X_REAL_PORT) != "" {
r.Header.Set(ice.MSG_USERADDR, ip+nfs.DF+r.Header.Get(X_REAL_PORT))
@ -107,15 +113,23 @@ func _serve_static(msg *ice.Message, w http.ResponseWriter, r *http.Request) boo
if kit.Contains(r.URL.String(), "render=replace") {
return false
}
p := strings.TrimPrefix(r.URL.Path, nfs.P)
if pp := path.Join(nfs.USR_LOCAL_WORK, msg.Option(ice.POD)); ispod && nfs.Exists(msg, pp) {
p := path.Join(strings.TrimPrefix(r.URL.Path, nfs.P))
if pp := path.Join(nfs.USR_LOCAL_WORK, msg.Option(ice.POD)); ispod && nfs.Exists(msg, pp) && !strings.HasPrefix(p, "require/") {
if kit.HasPrefix(p, "var/", "usr/local/") {
return false
}
if pp = path.Join(pp, p); nfs.Exists(msg, pp) {
return Render(msg, ice.RENDER_DOWNLOAD, pp)
} else {
} else if nfs.Exists(msg, p) {
return Render(msg, ice.RENDER_DOWNLOAD, p)
}
}
return (!ispod && kit.HasPrefix(p, nfs.SRC) || kit.HasPrefix(p, ice.USR_ICEBERGS, ice.USR_ICONS)) && nfs.Exists(msg, p) && Render(msg, ice.RENDER_DOWNLOAD, p)
if kit.HasPrefix(p, ice.USR_ICEBERGS, ice.USR_ICONS) && nfs.Exists(msg, p) {
return Render(msg, ice.RENDER_DOWNLOAD, p)
}
if !ispod {
return (kit.HasPrefix(p, nfs.SRC) && nfs.Exists(msg, p)) && Render(msg, ice.RENDER_DOWNLOAD, p)
}
} else if kit.HasPrefix(r.URL.Path, nfs.M) {
p := nfs.USR_MODULES + strings.TrimPrefix(r.URL.Path, nfs.M)
return nfs.Exists(msg, p) && Render(msg, ice.RENDER_DOWNLOAD, p)
@ -166,7 +180,9 @@ func _serve_handle(key string, cmd *ice.Command, m *ice.Message, w http.Response
}
switch kit.Select("", kit.Split(r.Header.Get(html.ContentType)), 0) {
case html.ApplicationJSON:
kit.For(kit.UnMarshal(r.Body), func(k string, v ice.Any) { m.Optionv(k, v) })
buf, _ := ioutil.ReadAll(r.Body)
m.Option("request.data", string(buf))
kit.For(kit.UnMarshal(string(buf)), func(k string, v ice.Any) { m.Optionv(k, v) })
default:
r.ParseMultipartForm(kit.Int64(kit.Select("4096", r.Header.Get(html.ContentLength))))
kit.For(r.PostForm, func(k string, v []string) { _log(FORM, k, kit.Join(v, lex.SP)).Optionv(k, v) })
@ -181,6 +197,10 @@ func _serve_handle(key string, cmd *ice.Command, m *ice.Message, w http.Response
kit.If(strings.TrimPrefix(r.URL.Path, key), func(p string) { m.Optionv(ice.MSG_CMDS, strings.Split(p, nfs.PS)) })
})
UserHost(m)
for k, v := range m.R.Header {
// m.Info("what %v %v", k, v)
kit.If(strings.HasPrefix(k, "Wechatpay"), func() { m.Option(k, v) })
}
m.W.Header().Add(strings.ReplaceAll(ice.LOG_TRACEID, ".", "-"), m.Option(ice.LOG_TRACEID))
defer func() { Render(m, m.Option(ice.MSG_OUTPUT), kit.List(m.Optionv(ice.MSG_ARGS))...) }()
if cmds, ok := _serve_auth(m, key, kit.Simple(m.Optionv(ice.MSG_CMDS)), w, r); ok {
@ -198,6 +218,20 @@ func _serve_handle(key string, cmd *ice.Command, m *ice.Message, w http.Response
} else {
m.CmdHand(cmd, key, cmds...)
}
func() {
defer InfoLock.Lock()()
Info.Commands[kit.Select(kit.Select("", cmds, 0), m.Option(ice.MSG_INDEX))]++
switch r.Method {
case http.MethodGet:
Info.ServeGetCount++
case http.MethodPut:
Info.ServePutCount++
case http.MethodPost:
Info.ServePostCount++
case http.MethodDelete:
Info.ServeDeleteCount++
}
}()
}
}
func _serve_domain(m *ice.Message) string {
@ -258,11 +292,13 @@ const SERVE = "serve"
func init() {
Index.MergeCommands(ice.Commands{P(ice.EXIT): {Hand: func(m *ice.Message, arg ...string) { m.Cmd(ice.EXIT) }},
SERVE: {Name: "serve port auto main host system", Help: "服务器", Actions: ice.MergeActions(ice.Actions{
ice.MAIN: {Name: "main index", Help: "首页", Hand: func(m *ice.Message, arg ...string) {
ice.MAIN: {Name: "main index space", Help: "首页", Hand: func(m *ice.Message, arg ...string) {
if m.Option(ctx.INDEX) == "" {
mdb.Config(m, ice.MAIN, "")
} else {
} else if m.Option(SPACE) == "" {
mdb.Config(m, ice.MAIN, C(m.Option(ctx.INDEX)))
} else {
mdb.Config(m, ice.MAIN, S(m.Option(SPACE))+C(m.Option(ctx.INDEX)))
}
}},
mdb.ICONS: {Hand: func(m *ice.Message, arg ...string) { mdb.Config(m, mdb.ICONS, arg[0]) }},
@ -281,7 +317,7 @@ func init() {
SERVE_START: {Hand: func(m *ice.Message, arg ...string) {
kit.If(m.Option(ice.DEMO) == ice.TRUE, func() { m.Cmd(CHAT_HEADER, ice.DEMO) })
kit.If(os.Getenv(cli.TERM), func() { m.Go(func() { ssh.PrintQRCode(m, tcp.PublishLocalhost(m, _serve_address(m))) }) })
m.Cmd(SPIDE, mdb.CREATE, HostPort(m, tcp.LOCALHOST, m.Option(tcp.PORT)), ice.OPS, nfs.USR_ICONS_CONTEXTS, nfs.REPOS, "")
m.Cmd(SPIDE, mdb.CREATE, HostPort(m, tcp.LOCALHOST, m.Option(tcp.PORT)), ice.OPS, ice.SRC_MAIN_ICO, nfs.REPOS, "")
m.Cmds(SPIDE).Table(func(value ice.Maps) {
kit.If(value[CLIENT_NAME] != ice.OPS && value[TOKEN] != "", func() {
m.Cmd(SPACE, tcp.DIAL, ice.DEV, value[CLIENT_NAME], TOKEN, value[TOKEN], mdb.TYPE, SERVER)
@ -294,10 +330,14 @@ func init() {
ice.Info.Important = ice.HasVar()
}},
PROXY_CONF: {Name: "proxyConf name* port host path", Hand: func(m *ice.Message, arg ...string) {
if dir := m.OptionDefault(nfs.PATH, PROXY_PATH, tcp.HOST, "127.0.0.1", tcp.PORT, tcp.PORT_9020); true || nfs.Exists(m, dir) {
for _, p := range []string{"server.conf", "location.conf", "upstream.conf"} {
if dir := m.OptionDefault(nfs.PATH, PROXY_PATH, tcp.HOST, "127.0.0.1", tcp.PORT, tcp.PORT_9020); nfs.Exists(m, dir) {
for _, p := range []string{"upstream.conf"} {
m.Cmd(nfs.SAVE, kit.Format("%s/conf/portal/%s/%s", dir, m.Option(mdb.NAME), p), m.Template(p)+lex.NL)
}
for _, p := range []string{"server.conf", "location.conf"} {
m.Cmd(nfs.DEFS, kit.Format("%s/conf/portal/%s/%s", dir, m.Option(mdb.NAME), p), m.Template(p)+lex.NL)
}
m.Cmd(cli.SYSTEM, cli.SUDO, kit.Path(dir, "sbin/nginx"), "-p", kit.Path(dir), "-s", "reload")
}
}},
}, gdb.EventsAction(SERVE_START), mdb.HashAction(

View File

@ -91,7 +91,8 @@ func init() {
ctx.RUN: {Hand: func(m *ice.Message, arg ...string) {
if msg := mdb.HashSelects(m.Spawn(), m.Option(SHARE)); !IsNotValidFieldShare(m, msg) {
aaa.SessAuth(m, kit.Dict(msg.AppendSimple(aaa.USERNICK, aaa.USERNAME, aaa.USERROLE)))
m.Cmdy(Space(m, msg.Append(SPACE)), msg.Append(mdb.NAME), kit.UnMarshal(msg.Append(mdb.TEXT)), arg[1:], kit.Dict(ice.MSG_USERPOD, msg.Append(SPACE)))
// m.Cmdy(Space(m, msg.Append(SPACE)), msg.Append(mdb.NAME), kit.UnMarshal(msg.Append(mdb.TEXT)), arg[1:], kit.Dict(ice.MSG_USERPOD, msg.Append(SPACE)))
m.Cmdy(Space(m, msg.Append(SPACE)), msg.Append(mdb.NAME), arg[1:], kit.Dict(ice.MSG_USERPOD, msg.Append(SPACE)))
}
}},
nfs.PS: {Hand: func(m *ice.Message, arg ...string) {
@ -118,7 +119,11 @@ func init() {
RenderCookie(m, aaa.SessCreate(m, msg.Append(aaa.USERNAME)))
m.RenderRedirect(m.MergeLink(kit.Select(nfs.PS, msg.Append(mdb.TEXT)), msg.AppendSimple(RIVER, STORM)))
case FIELD:
RenderPodCmd(m, msg.Append(SPACE), msg.Append(mdb.NAME), kit.UnMarshal(msg.Append(mdb.TEXT)))
if msg.Append(mdb.NAME) == "web.chat.grant" {
RenderPodCmd(m, "", msg.Append(mdb.NAME), kit.UnMarshal(msg.Append(mdb.TEXT)))
} else {
RenderPodCmd(m, msg.Append(SPACE), msg.Append(mdb.NAME), kit.UnMarshal(msg.Append(mdb.TEXT)))
}
case DOWNLOAD:
m.RenderDownload(msg.Append(mdb.TEXT))
default:
@ -169,15 +174,28 @@ func ShareLocalFile(m *ice.Message, arg ...string) {
} else if m.Option(ice.POD) == "" && !aaa.Right(m, ls) {
return
} else {
if m.Option(ice.POD) != "" && !strings.Contains(p, "/src/") && !strings.HasPrefix(p, "src/") {
if strings.HasPrefix(p, "usr/local/storage/") {
if m.Cmd(SPACE, "20240903-operation", "web.team.storage.file", aaa.RIGHT, ls[3:]).IsErr() {
return
}
} else if m.WarnNotRight(m.Cmdx(SPACE, m.Option(ice.POD), aaa.ROLE, aaa.RIGHT, aaa.VOID, p) != ice.OK) {
return
}
}
}
}
if m.Option(ice.POD) != "" && nfs.Exists(m, path.Join(ice.USR_LOCAL_WORK, m.Option(ice.POD))) {
if pp := kit.Path(ice.USR_LOCAL_WORK, m.Option(ice.POD), p); nfs.Exists(m, pp) {
m.RenderDownload(pp)
return
} else if nfs.Exists(m, p) {
m.RenderDownload(p)
return
}
} else if m.Option(ice.POD) == "" || (kit.HasPrefix(p, ice.USR_ICONS, ice.USR_VOLCANOS, ice.USR_ICEBERGS, ice.USR_INTSHELL) && nfs.Exists(m, p)) {
}
if m.Option(ice.POD) == "" || (kit.HasPrefix(p, ice.USR_ICONS, ice.USR_VOLCANOS, ice.USR_ICEBERGS, ice.USR_INTSHELL) && nfs.Exists(m, p)) {
m.RenderDownload(p)
} else if pp := kit.Path(ice.USR_LOCAL_WORK, m.Option(ice.POD), p); nfs.Exists(m, pp) {
m.RenderDownload(pp)
@ -205,7 +223,7 @@ func ProxyUpload(m *ice.Message, pod string, p string) string {
size, cache = s.Size(), s.ModTime()
}
if m.Cmdv(SPACE, pod, mdb.TYPE) == ORIGIN {
m.Cmd(SPIDE, pod, SPIDE_SAVE, pp, p)
m.Cmd(SPIDE, pod, SPIDE_SAVE, pp, "/p/"+p)
} else {
kit.If(p == ice.BIN_ICE_BIN, func() { m.Option(ice.MSG_USERROLE, aaa.TECH) })
share := m.Cmdx(SHARE, mdb.CREATE, mdb.TYPE, PROXY, mdb.NAME, p, mdb.TEXT, pod)

View File

@ -23,8 +23,26 @@ import (
"shylinux.com/x/icebergs/base/web/html"
"shylinux.com/x/icebergs/misc/websocket"
kit "shylinux.com/x/toolkits"
"shylinux.com/x/toolkits/task"
)
var Info = struct {
ServeMainCount int
ServeGetCount int
ServePutCount int
ServePostCount int
ServeDeleteCount int
SpaceCmdCount int
SpaceReadCount int
SpaceReadByte int
SpaceWriteCount int
SpaceWriteByte int
Commands map[string]int
}{
Commands: map[string]int{},
}
var InfoLock = &task.Lock{}
func _space_qrcode(m *ice.Message, dev string) {
ssh.PrintQRCode(m, m.Cmdv(SPACE, dev, cli.PWD, mdb.LINK))
}
@ -32,7 +50,7 @@ func _space_dial(m *ice.Message, dev, name string, arg ...string) {
msg := m.Cmd(SPIDE, dev)
origin := msg.Append(CLIENT_ORIGIN)
u := kit.ParseURL(kit.MergeURL2(strings.Replace(origin, HTTP, "ws", 1), PP(SPACE), mdb.TYPE, ice.Info.NodeType, mdb.NAME, name, TOKEN, msg.Append(TOKEN), mdb.ICONS, ice.Info.NodeIcon,
mdb.TIME, ice.Info.Make.Time, nfs.MODULE, ice.Info.Make.Module, nfs.VERSION, ice.Info.Make.Versions(), cli.GOOS, runtime.GOOS, cli.GOARCH, runtime.GOARCH, arg))
ice.MAIN, ice.Info.NodeMain, mdb.TIME, ice.Info.Make.Time, nfs.MODULE, ice.Info.Make.Module, nfs.VERSION, ice.Info.Make.Versions(), cli.GOOS, runtime.GOOS, cli.GOARCH, runtime.GOARCH, arg))
args := kit.SimpleKV("type,name,host,port", u.Scheme, dev, u.Hostname(), kit.Select(kit.Select(tcp.PORT_443, tcp.PORT_80, u.Scheme == "ws"), u.Port()))
gdb.Go(m, func() {
once := sync.Once{}
@ -80,11 +98,12 @@ func _space_fork(m *ice.Message) {
if msg := m.Cmd(TOKEN, m.Option(TOKEN)); msg.Append(mdb.TIME) > m.Time() && kit.IsIn(msg.Append(mdb.TYPE), SERVER, SPIDE) {
aaa.SessAuth(m, kit.Dict(m.Cmd(aaa.USER, m.Option(ice.MSG_USERNAME, msg.Append(mdb.NAME))).AppendSimple()))
name = SpaceName(kit.Select(name, msg.Append(mdb.TEXT)))
// kit.If(ProxyDomain(m.Spawn(kit.Dict(ice.MSG_USERROLE, aaa.TECH)), name), func(p string) { text = p })
kit.If(ProxyDomain(m, name), func(p string) { text = p })
safe = aaa.IsTechOrRoot(m)
}
}
args := kit.Simple(mdb.TYPE, m.Option(mdb.TYPE), mdb.NAME, name, mdb.TEXT, text, m.OptionSimple(mdb.ICONS, mdb.TIME, nfs.MODULE, nfs.VERSION, cli.DAEMON))
args := kit.Simple(mdb.TYPE, m.Option(mdb.TYPE), mdb.NAME, name, mdb.TEXT, text, m.OptionSimple(mdb.ICONS, mdb.TIME, nfs.MODULE, nfs.VERSION, cli.DAEMON, "main"))
args = append(args, aaa.USERNICK, m.Option(ice.MSG_USERNICK), aaa.USERNAME, m.Option(ice.MSG_USERNAME), aaa.USERROLE, m.Option(ice.MSG_USERROLE))
args = append(args, cli.SYSTEM, m.Option(cli.GOOS))
args = append(args, ParseUA(m)...)
@ -106,7 +125,7 @@ func _space_fork(m *ice.Message) {
safe = true
m.Go(func() {
SpacePwd(m, name, kit.Path(""))
SpaceEvent(m, OPS_SERVER_OPEN, name, args...)
// SpaceEvent(m, OPS_DREAM_OPEN, name, args...)
})
case SERVER:
defer gdb.EventDeferEvent(m, SPACE_OPEN, args)(SPACE_CLOSE, args)
@ -115,7 +134,7 @@ func _space_fork(m *ice.Message) {
SpaceEvent(m.Spawn(ice.MSG_USERROLE, aaa.TECH), OPS_SERVER_OPEN, name, args...)
})
}
_space_handle(m, safe, name, c)
_space_handle(m.Spawn(), safe, name, c)
}, kit.JoinWord(SPACE, name))
}
}
@ -127,6 +146,11 @@ func _space_handle(m *ice.Message, safe bool, name string, c *websocket.Conn) {
if e != nil {
break
}
func() {
defer InfoLock.Lock()()
Info.SpaceReadCount++
Info.SpaceReadByte += len(b)
}()
msg := m.Spawn(b)
if safe && msg.Option(ice.MSG_UNSAFE) != ice.TRUE { // 下行权限
if !aaa.IsTechOrRoot(msg) && msg.Option(ice.MSG_HANDLE) != ice.TRUE {
@ -138,7 +162,7 @@ func _space_handle(m *ice.Message, safe bool, name string, c *websocket.Conn) {
kit.If(msg.Option(ice.MSG_USERROLE), func() { msg.Option(ice.MSG_USERROLE, aaa.VOID) })
}
source, target := kit.Simple(msg.Optionv(ice.MSG_SOURCE), name), kit.Simple(msg.Optionv(ice.MSG_TARGET))
msg.Log(kit.Select(tcp.RECV, tcp.ECHO, msg.Option(ice.MSG_HANDLE) == ice.TRUE), "%v->%v %v %v", source, target, msg.Detailv(), msg.FormatMeta())
msg.Log(kit.Select(tcp.RECV, tcp.ECHO, msg.Option(ice.MSG_HANDLE) == ice.TRUE), "%d %v->%v %v %v", len(b), source, target, msg.Detailv(), msg.FormatMeta())
if next := msg.Option(ice.MSG_TARGET); next == "" || len(target) == 0 {
msg.Go(func() {
if k := kit.Keys(msg.Option(ice.MSG_USERPOD), "_token"); msg.Option(k) != "" {
@ -163,8 +187,6 @@ func _space_handle(m *ice.Message, safe bool, name string, c *websocket.Conn) {
}), SPACE, next) {
break
}
m.Info("what %v", msg.FormatStack(1, 100))
m.Info("what %v", msg.FormatChain())
if kit.HasPrefixList(msg.Detailv(), "toast") {
break
}
@ -205,11 +227,16 @@ func _space_exec(m *ice.Message, name string, source, target []string, c *websoc
args := m.OptionSimple(mdb.ICONS, mdb.TIME, nfs.MODULE, nfs.VERSION, AGENT, cli.SYSTEM)
kit.If(name == ice.OPS, func() { args = append(args, m.OptionSimple(mdb.TEXT)...) })
mdb.HashModify(m, mdb.HASH, name, ParseUA(m), args)
SpaceEvent(m, OPS_ORIGIN_OPEN, name, kit.Simple(mdb.NAME, name, args)...)
// SpaceEvent(m, OPS_ORIGIN_OPEN, name, kit.Simple(mdb.NAME, name, args)...)
default:
if m.IsErr() {
return
}
func() {
defer InfoLock.Lock()()
Info.SpaceCmdCount++
Info.Commands[kit.Select(kit.Select("", m.Detailv(), 0), m.Option(ice.MSG_INDEX))]++
}()
m.Options(ice.MSG_ARGS, "", ice.MSG_COUNT, "0")
kit.If(m.Option(ice.MSG_DAEMON), func(p string) {
m.Option(ice.MSG_DAEMON0, m.Option(ice.MSG_DAEMON))
@ -228,9 +255,17 @@ func _space_exec(m *ice.Message, name string, source, target []string, c *websoc
}
func _space_echo(m *ice.Message, source, target []string, c *websocket.Conn) {
defer func() { m.WarnNotValid(recover()) }()
if m.Options(ice.MSG_SOURCE, source, ice.MSG_TARGET, target[1:]); !m.WarnNotValid(c.WriteMessage(1, []byte(m.FormatMeta()))) {
m.Options(ice.MSG_SOURCE, source, ice.MSG_TARGET, target[1:])
data := m.FormatMeta()
if !m.WarnNotValid(c.WriteMessage(1, []byte(data))) {
func() {
defer InfoLock.Lock()()
Info.SpaceWriteCount++
Info.SpaceWriteByte += len(data)
}()
if source != nil {
m.Log(kit.Select(tcp.SEND, tcp.DONE, m.Option(ice.MSG_HANDLE) == ice.TRUE), "%v->%v %v %v", source, target, kit.ReplaceAll(kit.Format("%v", m.Detailv()), "\r\n", "\\r\\n", "\t", "\\t", "\n", "\\n"), m.FormatMeta())
m.Log(kit.Select(tcp.SEND, tcp.DONE, m.Option(ice.MSG_HANDLE) == ice.TRUE), "%d %v->%v %v %v", len(data), source, target,
kit.ReplaceAll(kit.Format("%v", m.Detailv()), "\r\n", "\\r\\n", "\t", "\\t", "\n", "\\n"), data)
}
}
}
@ -289,6 +324,7 @@ const (
OPS_ORIGIN_OPEN = "ops.origin.open"
OPS_SERVER_OPEN = "ops.server.open"
OPS_DREAM_SPAWN = "ops.dream.spawn"
OPS_DREAM_OPEN = "ops.dream.open"
SPACE_LOGIN = "space.login"
SPACE_LOGIN_CLOSE = "space.login.close"
@ -303,6 +339,10 @@ const SPACE = "space"
func init() {
Index.MergeCommands(ice.Commands{
"p": {Help: "资源", Actions: ApiWhiteAction(), Hand: func(m *ice.Message, arg ...string) {
if arg[0] == "require" {
m.Cmdy("/require/", arg[1:])
return
}
if kit.IsIn(arg[0], ice.SRC, ice.USR) {
ShareLocalFile(m, arg...)
} else {
@ -329,8 +369,8 @@ func init() {
aaa.White(m, SPACE, ice.MAIN)
if kit.IsIn(ice.Info.NodeIcon, "src/main.ico", "") {
nfs.Exists(m, "src/main.ico", func(p string) { ice.Info.NodeIcon = p })
nfs.Exists(m, "src/main.png", func(p string) { ice.Info.NodeIcon = p })
nfs.Exists(m, "src/main.jpg", func(p string) { ice.Info.NodeIcon = p })
nfs.Exists(m, "src/main.png", func(p string) { ice.Info.NodeIcon = p })
}
}},
mdb.ICONS: {Hand: func(m *ice.Message, arg ...string) {
@ -405,7 +445,7 @@ func init() {
}},
nfs.PS: {Hand: func(m *ice.Message, arg ...string) { _space_fork(m) }},
}, gdb.EventsAction(SPACE_LOGIN), mdb.HashAction(mdb.LIMIT, 1000, mdb.LEAST, 500,
mdb.SHORT, mdb.NAME, mdb.FIELD, "time,type,name,text,icons,module,version,agent,system,ip,usernick,username,userrole",
mdb.SHORT, mdb.NAME, mdb.FIELD, "time,type,name,text,main,icons,module,version,agent,system,ip,usernick,username,userrole",
ctx.ACTION, OPEN, REDIAL, kit.Dict("a", 1000, "b", 100, "c", 1000),
), mdb.ClearOnExitHashAction()), Hand: func(m *ice.Message, arg ...string) {
if len(arg) < 2 {
@ -452,10 +492,17 @@ func init() {
})
m.Sort("", kit.Simple(aaa.LOGIN, WEIXIN, PORTAL, WORKER, SERVER, ORIGIN))
} else {
if kit.IsIn(arg[0], "", ice.CONTEXTS) {
if ice.Info.NodeType != WORKER && arg[0] == ice.OPS {
m.Cmdy(arg[1:])
return
}
if kit.IsIn(arg[0], "", ice.Info.NodeName) {
m.Cmdy(arg[1:])
return
}
if ice.Info.NodeType == WORKER && !strings.HasPrefix(arg[0], ice.OPS) {
arg[0] = kit.Keys(ice.OPS, arg[0])
}
for i := 0; i < 5; i++ {
if _space_send(m, arg[0], kit.Simple(kit.Split(arg[1]), arg[2:])...); !m.IsErrNotFoundSpace() {
break
@ -488,10 +535,13 @@ func init() {
m.SetAppend().Push(arg[0], SpideOrigin(m, ice.DEV))
m.Copy(m.Cmd(SPIDE, kit.Dict(ice.MSG_FIELDS, CLIENT_ORIGIN)).CutTo(CLIENT_ORIGIN, arg[0]).Sort(arg[0]))
case mdb.ICONS:
m.Options(nfs.DIR_REG, kit.ExtReg(nfs.PNG, nfs.JPG, nfs.JPEG), nfs.DIR_DEEP, ice.TRUE)
m.Options(nfs.DIR_DEEP, ice.TRUE, nfs.DIR_REG, kit.ExtReg(nfs.PNG, nfs.JPG, nfs.JPEG))
m.Cmdy(nfs.DIR, nfs.SRC, nfs.PATH)
m.Cmdy(nfs.DIR, ice.USR_LOCAL_IMAGE, nfs.PATH)
m.Cmdy(nfs.DIR, ice.USR_ICONS, nfs.PATH)
if aaa.IsTechOrRoot(m) {
m.Cmdy(nfs.DIR, nfs.USR_LOCAL_IMAGE, nfs.PATH)
}
m.Cmdy(nfs.DIR, nfs.USR_IMAGE, nfs.PATH)
m.Cmdy(nfs.DIR, nfs.USR_ICONS, nfs.PATH)
m.CutTo(nfs.PATH, arg[0])
case ctx.INDEX, ice.CMD:
m.OptionFields(ctx.INDEX)
@ -529,7 +579,7 @@ func init() {
Upload(m)
if pod := m.Option(ice.POD); pod != "" {
if ls := kit.Simple(m.Optionv(ice.MSG_UPLOAD)); len(ls) > 1 {
m.Cmd(SPACE, pod, SPIDE, ice.DEV, CACHE, SHARE_CACHE+ls[0])
// m.Cmd(SPACE, pod, SPIDE, ice.DEV, CACHE, SHARE_CACHE+ls[0])
}
m.Options(ice.POD, []string{}, ice.MSG_USERPOD, strings.TrimPrefix(pod, "ops.")).Cmdy(append(kit.List(ice.SPACE, pod), arg...)...)
return true

View File

@ -15,7 +15,6 @@ import (
"time"
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/aaa"
"shylinux.com/x/icebergs/base/cli"
"shylinux.com/x/icebergs/base/ctx"
"shylinux.com/x/icebergs/base/log"
@ -41,7 +40,7 @@ func _spide_create(m *ice.Message, link, types, name, icons, token string) {
}
func _spide_show(m *ice.Message, name string, arg ...string) {
file := ""
action, arg := _spide_args(m, arg, SPIDE_RAW, SPIDE_DETAIL, SPIDE_MSG, SPIDE_SAVE, SPIDE_CACHE)
action, arg := _spide_args(m, arg, SPIDE_RAW, SPIDE_DETAIL, SPIDE_MSG, SPIDE_SAVE, SPIDE_CACHE, SPIDE_STREAM)
kit.If(action == SPIDE_SAVE, func() { file, arg = arg[0], arg[1:] })
msg := mdb.HashSelects(m.Spawn(), name)
method, arg := _spide_args(m, arg, http.MethodGet, http.MethodPut, http.MethodPost, http.MethodDelete)
@ -92,7 +91,7 @@ func _spide_show(m *ice.Message, name string, arg ...string) {
}
})
})
if m.WarnNotValid(res.StatusCode != http.StatusOK && res.StatusCode != http.StatusCreated, uri, cli.STATUS, res.Status) {
if m.WarnNotValid(res.StatusCode != http.StatusOK && res.StatusCode != http.StatusCreated && res.StatusCode != http.StatusNoContent, uri, cli.STATUS, res.Status) {
switch res.StatusCode {
case http.StatusNotFound, http.StatusUnauthorized:
return
@ -114,8 +113,9 @@ func _spide_body(m *ice.Message, method string, arg ...string) (io.Reader, ice.M
head := ice.Maps{}
switch kit.If(len(arg) == 1, func() { arg = []string{SPIDE_DATA, arg[0]} }); arg[0] {
case SPIDE_FORM:
arg = kit.Simple(arg, func(v string) string { return url.QueryEscape(v) })
// arg = kit.Simple(arg, func(v string) string { return url.QueryEscape(v) })
head[html.ContentType], body = html.ApplicationForm, bytes.NewBufferString(kit.JoinQuery(arg[1:]...))
m.Info("debug what %v", kit.JoinQuery(arg[1:]...))
case SPIDE_PART:
head[html.ContentType], body = _spide_part(m, arg...)
case SPIDE_FILE:
@ -214,6 +214,19 @@ func _spide_save(m *ice.Message, action, file, uri string, res *http.Response) {
case SPIDE_CACHE:
m.Cmdy(CACHE, DOWNLOAD, res.Header.Get(html.ContentType), uri, kit.Dict(RESPONSE, res), m.OptionCB(SPIDE))
m.Echo(m.Append(mdb.HASH))
case SPIDE_STREAM:
cb, ok := m.Optionv(SPIDE_STREAM).(func(string))
if !ok {
cb = func(text string) { PushNoticeGrow(m, m.Option("which"), text) }
}
b := make([]byte, 1024)
for {
if n, e := res.Body.Read(b); e != nil {
break
} else {
cb(string(b[:n]))
}
}
default:
var data ice.Any
if b, e := ioutil.ReadAll(res.Body); !m.WarnNotFound(e) {
@ -232,6 +245,7 @@ const (
SPIDE_MSG = "msg"
SPIDE_SAVE = "save"
SPIDE_CACHE = "cache"
SPIDE_STREAM = "stream"
SPIDE_BODY = "body"
SPIDE_FORM = "form"
@ -292,16 +306,16 @@ func init() {
))), Actions: ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
conf := mdb.Confm(m, cli.RUNTIME, cli.CONF)
dev := kit.Select("https://2021.shylinux.com", ice.Info.Make.Domain, conf[cli.CTX_DEV])
m.Cmd("", mdb.CREATE, kit.Select("https://shylinux.com", conf[cli.CTX_SHY]), ice.SHY, "", nfs.REPOS)
dev := kit.Select("https://dev.shylinux.com", ice.Info.Make.Domain, conf[cli.CTX_DEV])
m.Cmd("", mdb.CREATE, dev, ice.DEV, ice.SRC_MAIN_ICO, nfs.REPOS)
m.Cmd("", mdb.CREATE, kit.Select(dev, os.Getenv("ctx_dev_ip")), ice.DEV_IP)
m.Cmd("", mdb.CREATE, kit.Select("http://localhost:9020", conf[cli.CTX_OPS]), ice.OPS, nfs.USR_ICONS_CONTEXTS, nfs.REPOS)
m.Cmd("", mdb.CREATE, kit.Select("http://localhost:20000", conf[cli.CTX_DEMO]), ice.DEMO, nfs.USR_ICONS_VOLCANOS)
m.Cmd("", mdb.CREATE, kit.Select("https://mail.shylinux.com", conf[cli.CTX_MAIL]), ice.MAIL, "usr/icons/Mail.png")
m.Cmd("", mdb.CREATE, kit.Select("https://user.shylinux.com"), aaa.USER, "usr/icons/Mail.png")
m.Cmd("", mdb.CREATE, "https://2023-contexts.shylinux.com", "2023-contexts", ice.SRC_MAIN_ICO, nfs.REPOS)
m.Cmd("", mdb.CREATE, "https://2024-contexts.shylinux.com", "2024-contexts", ice.SRC_MAIN_ICO, nfs.REPOS)
m.Cmd("", mdb.CREATE, kit.Select(dev, os.Getenv("ctx_dev_ip")), ice.DEV_IP, ice.SRC_MAIN_ICO, "dev_ip")
m.Cmd("", mdb.CREATE, kit.Select("http://localhost:9020", conf[cli.CTX_OPS]), ice.OPS, ice.SRC_MAIN_ICO, nfs.REPOS)
m.Cmd("", mdb.CREATE, kit.Select("https://shylinux.com", conf[cli.CTX_SHY]), ice.SHY, ice.SRC_MAIN_ICO, nfs.REPOS)
m.Cmd("", mdb.CREATE, kit.Select("https://mail.shylinux.com", conf[cli.CTX_MAIL]), ice.MAIL, "usr/icons/Mail.png", "mail")
m.Cmd("", mdb.CREATE, kit.Select("https://demo.shylinux.com", conf[cli.CTX_DEMO]), ice.DEMO, ice.SRC_MAIN_ICO, "demo")
m.Cmd("", mdb.CREATE, "https://2023.shylinux.com", "2023-ContextOS", ice.SRC_MAIN_ICO, nfs.REPOS)
m.Cmd("", mdb.CREATE, "https://2024.shylinux.com", "2024-ContextOS", ice.SRC_MAIN_ICO, nfs.REPOS)
m.Cmd("", mdb.CREATE, "https://2025.shylinux.com", "2025-ContextOS", ice.SRC_MAIN_ICO, nfs.REPOS)
}},
mdb.SEARCH: {Hand: func(m *ice.Message, arg ...string) {
if mdb.IsSearchPreview(m, arg) {
@ -331,30 +345,31 @@ func init() {
default:
switch arg[0] {
case mdb.NAME, mdb.ICONS:
m.SplitIndex(m.Cmdx(SPIDE, ice.DEV, kit.MergeURL2(m.Option(ORIGIN), C(SPACE, "info")))).Cut(arg[0])
m.SplitIndex(m.Cmdx(SPIDE, ice.DEV, kit.MergeURL2(m.Option(ORIGIN), C(SPACE, ice.INFO)))).Cut(arg[0])
mdb.HashInputs(m, arg)
default:
mdb.HashSelectValue(m.Spawn(), func(value ice.Map) {
m.Push(kit.Select(ORIGIN, arg, 0), kit.Value(value, kit.Keys("client", arg[0])))
})
kit.If(arg[0] == mdb.TYPE, func() { m.Push(arg[0], nfs.REPOS) })
m.Sort(arg[0])
}
}
}},
mdb.CREATE: {Name: "create origin* name icons type token", Hand: func(m *ice.Message, arg ...string) {
if m.Option(mdb.NAME) == "" && m.Option(mdb.ICONS) == "" {
msg := m.Spawn().SplitIndex(m.Cmdx(SPIDE, ice.DEV, kit.MergeURL2(m.Option(ORIGIN), C(SPACE, "info"))))
m.Option(mdb.ICONS, m.Resource(msg.Append(mdb.ICONS), msg.Append(ORIGIN)))
m.Option(mdb.NAME, msg.Append(mdb.NAME))
m.OptionDefault(mdb.TYPE, nfs.REPOS)
if m.Option(mdb.TYPE) == nfs.REPOS && (m.Option(mdb.NAME) == "" || m.Option(mdb.ICONS) == "") {
msg := m.Spawn().SplitIndex(m.Cmdx(SPIDE, ice.DEV, kit.MergeURL2(m.Option(ORIGIN), C(SPACE, ice.INFO))))
if m.OptionDefault(mdb.NAME, msg.Append(mdb.NAME)); msg.Append(mdb.ICONS) != "" {
m.OptionDefault(mdb.ICONS, m.Resource(msg.Append(mdb.ICONS), msg.Append(ORIGIN)))
}
}
if u, e := url.Parse(m.Option(ORIGIN)); m.Warn(e != nil || u.Host == "", ice.ErrNotValid, m.Option(ORIGIN)) {
if u, e := url.Parse(m.Option(ORIGIN)); m.WarnNotValid(e != nil || u.Host == "", m.Option(ORIGIN)) {
return
} else {
m.OptionDefault(mdb.NAME, kit.Split(u.Host, ".:")[0])
kit.If(u.Query().Get(TOKEN), func(p string) { m.OptionDefault(TOKEN, p) })
_spide_create(m, m.Option(ORIGIN), m.Option(mdb.TYPE), m.Option(mdb.NAME), m.Option(mdb.ICONS), m.Option(TOKEN))
}
_spide_create(m, m.Option(ORIGIN), m.Option(mdb.TYPE), m.Option(mdb.NAME), m.OptionDefault(mdb.ICONS, nfs.USR_ICONS_VOLCANOS), m.Option(TOKEN))
}},
COOKIE: {Name: "cookie key* value", Help: "状态量", Hand: func(m *ice.Message, arg ...string) {
mdb.HashModify(m, m.OptionSimple(CLIENT_NAME), kit.Keys(COOKIE, m.Option(mdb.KEY)), m.Option(mdb.VALUE))
@ -368,27 +383,23 @@ func init() {
PROXY: {Name: "proxy url size cache upload", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(SPIDE, ice.DEV, SPIDE_RAW, http.MethodPost, m.Option(URL), SPIDE_PART, arg[2:])
}},
"disconn": {Help: "断连", Icon: "bi bi-person-x", Hand: func(m *ice.Message, arg ...string) {
"disconn": {Help: "断连", Icon: "bi bi-person-x", Style: "danger", Hand: func(m *ice.Message, arg ...string) {
m.Cmd(SPACE, cli.CLOSE, kit.Dict(mdb.NAME, m.Option(CLIENT_NAME)))
mdb.HashModify(m, mdb.NAME, m.Option(CLIENT_NAME), TOKEN, "")
}},
DEV_REQUEST_TEXT: {Hand: func(m *ice.Message, arg ...string) { m.Echo(SpaceName(ice.Info.NodeName)) }},
DEV_CREATE_TOKEN: {Hand: func(m *ice.Message, arg ...string) {
m.OptionDefault(CLIENT_NAME, m.Option(ice.FROM_SPACE))
mdb.HashModify(m, m.OptionSimple(CLIENT_NAME, TOKEN))
m.Cmd(SPACE, tcp.DIAL, ice.DEV, m.Option(CLIENT_NAME), m.OptionSimple(TOKEN)).Sleep300ms()
m.Cmd(SPACE, tcp.DIAL, m.Option(CLIENT_NAME)).Sleep300ms()
}},
DEV_REQUEST_TEXT: {Hand: func(m *ice.Message, arg ...string) { m.Echo(SpaceName(ice.Info.NodeName)) }},
}, DevTokenAction(CLIENT_NAME, CLIENT_URL), mdb.ImportantHashAction(mdb.SHORT, CLIENT_NAME, mdb.FIELD, "time,icons,client.name,client.url,client.type,token")), Hand: func(m *ice.Message, arg ...string) {
if len(arg) < 2 || arg[0] == "" || (len(arg) > 3 && arg[3] == "") {
list := m.CmdMap(SPACE, mdb.NAME)
mdb.HashSelect(m, kit.Slice(arg, 0, 1)...).Sort("client.type,client.name", []string{nfs.REPOS, ""})
m.RewriteAppend(func(value, key string, index int) string {
kit.If(key == CLIENT_URL, func() { value = kit.MergeURL(value, m.OptionSimple(ice.MSG_DEBUG)) })
return value
})
m.Table(func(value ice.Maps) {
mdb.HashSelect(m, kit.Slice(arg, 0, 1)...).Table(func(value ice.Maps) {
if value[CLIENT_TYPE] == nfs.REPOS {
if _, ok := list[value[CLIENT_NAME]]; ok {
m.Push(mdb.STATUS, ONLINE).PushButton("disconn", mdb.DEV_REQUEST, mdb.REMOVE)
m.Push(mdb.STATUS, ONLINE).PushButton(mdb.DEV_REQUEST, "disconn", mdb.REMOVE)
} else {
m.Push(mdb.STATUS, "").PushButton(mdb.DEV_REQUEST, mdb.REMOVE)
}
@ -397,31 +408,40 @@ func init() {
}
})
kit.If(len(arg) > 0 && arg[0] != "", func() { m.Action(COOKIE, HEADER) })
m.Sort("client.type,client.name", []string{nfs.REPOS, "dev_ip", "demo", "mail"})
} else {
_spide_show(m, arg[0], arg[1:]...)
}
}},
http.MethodGet: {Name: "GET url key value run", Help: "蜘蛛侠", Hand: func(m *ice.Message, arg ...string) {
http.MethodGet: {Name: "GET url key value run", Hand: func(m *ice.Message, arg ...string) {
m.Echo(kit.Formats(kit.UnMarshal(m.Cmdx(SPIDE, ice.DEV, SPIDE_RAW, http.MethodGet, arg[0], arg[1:]))))
}},
http.MethodPut: {Name: "PUT url key value run", Help: "蜘蛛侠", Hand: func(m *ice.Message, arg ...string) {
http.MethodPut: {Name: "PUT url key value run", Hand: func(m *ice.Message, arg ...string) {
m.Echo(kit.Formats(kit.UnMarshal(m.Cmdx(SPIDE, ice.DEV, SPIDE_RAW, http.MethodPut, arg[0], arg[1:]))))
}},
http.MethodPost: {Name: "POST url key value run", Help: "蜘蛛侠", Hand: func(m *ice.Message, arg ...string) {
http.MethodPost: {Name: "POST url key value run", Hand: func(m *ice.Message, arg ...string) {
m.Echo(kit.Formats(kit.UnMarshal(m.Cmdx(SPIDE, ice.DEV, SPIDE_RAW, http.MethodPost, arg[0], arg[1:]))))
}},
http.MethodDelete: {Name: "DELETE url key value run", Help: "蜘蛛侠", Hand: func(m *ice.Message, arg ...string) {
http.MethodDelete: {Name: "DELETE url key value run", Hand: func(m *ice.Message, arg ...string) {
m.Echo(kit.Formats(kit.UnMarshal(m.Cmdx(SPIDE, ice.DEV, SPIDE_RAW, http.MethodDelete, arg[0], arg[1:]))))
}},
})
nfs.TemplateText = func(m *ice.Message, p string) string {
// if p := kit.Select(nfs.TemplatePath(m, path.Base(p)), m.Option("_template")); kit.HasPrefix(p, nfs.P, nfs.REQUIRE, ice.HTTP) {
if p := kit.Select(nfs.TemplatePath(m, p), m.Option("_template")); kit.HasPrefix(p, nfs.P, nfs.REQUIRE, ice.HTTP) {
return m.Cmdx(SPIDE, ice.OPS, SPIDE_RAW, http.MethodGet, p)
return kit.Format(mdb.Cache(ice.Pulse, p, func() ice.Any { return m.Cmdx(SPIDE, ice.OPS, SPIDE_RAW, http.MethodGet, p) }))
} else if p == "" {
return ""
} else {
} else if nfs.Exists(m, p) {
return m.Cmdx(nfs.CAT, p)
} else if strings.Contains(p, "/pkg/mod/") {
ls := strings.Split(p, "/pkg/mod/")
return kit.Format(mdb.Cache(ice.Pulse, p, func() ice.Any { return m.Cmdx(SPIDE, ice.OPS, SPIDE_RAW, http.MethodGet, nfs.REQUIRE+ls[1]) }))
} else if strings.Contains(p, "/usr/local/work/") {
ls := strings.Split(strings.Split(p, "/usr/local/work/")[1], "/src/")
pp := kit.MergeURL2(ice.Info.Make.Domain, "/p/src/"+ls[1]+"?pod="+ls[0])
return kit.Format(mdb.Cache(ice.Pulse, p, func() ice.Any { return m.Cmdx(SPIDE, ice.OPS, SPIDE_RAW, http.MethodGet, pp) }))
} else {
return ""
}
}
nfs.TemplatePath = func(m *ice.Message, arg ...string) string {
@ -454,32 +474,6 @@ func init() {
}
}
func HostPort(m *ice.Message, host, port string, arg ...string) string {
p := ""
if len(arg) > 0 {
kit.If(kit.Select("", arg, 0), func(pod string) { p += S(pod) })
kit.If(kit.Select("", arg, 1), func(cmd string) { p += C(cmd) })
}
kit.If(m.Option(ice.LOG_DEBUG) == ice.TRUE, func() { p += "?debug=true" })
kit.If(host == "", func() { host = kit.ParseURL(UserHost(m)).Hostname() })
if port == tcp.PORT_443 {
return kit.Format("https://%s", host) + p
} else if port == tcp.PORT_80 {
return kit.Format("http://%s", host) + p
} else if port == "" {
return kit.Format("%s://%s", UserWeb(m).Scheme, host) + p
} else {
return kit.Format("http://%s:%s", host, port) + p
}
}
func PublicIP(m *ice.Message, arg ...string) ice.Any {
if len(arg) == 0 {
return SpideGet(m, "http://ip-api.com/json")
}
return mdb.Cache(m, "web.spide.location."+arg[0], func() ice.Any {
return kit.Format(kit.Value(SpideGet(m, "http://opendata.baidu.com/api.php?co=&resource_id=6006&oe=utf8", "query", arg[0]), "data.0.location"))
})
}
func SpideGet(m *ice.Message, arg ...ice.Any) ice.Any {
return kit.UnMarshal(m.Cmdx(http.MethodGet, arg))
}
@ -492,6 +486,9 @@ func SpidePost(m *ice.Message, arg ...ice.Any) ice.Any {
func SpideDelete(m *ice.Message, arg ...ice.Any) ice.Any {
return kit.UnMarshal(m.Cmdx(http.MethodDelete, arg))
}
func SpideCache(m *ice.Message, link string) *ice.Message {
return m.Cmd(Prefix(SPIDE), ice.DEV_IP, SPIDE_CACHE, http.MethodGet, link)
}
func SpideSave(m *ice.Message, file, link string, cb func(count, total, value int)) *ice.Message {
for _, p := range []string{ice.DEV_IP, ice.DEV} {
msg := m.Cmd(Prefix(SPIDE), p, SPIDE_SAVE, file, http.MethodGet, link, cb)
@ -501,9 +498,6 @@ func SpideSave(m *ice.Message, file, link string, cb func(count, total, value in
}
return m
}
func SpideCache(m *ice.Message, link string) *ice.Message {
return m.Cmd(Prefix(SPIDE), ice.DEV_IP, SPIDE_CACHE, http.MethodGet, link)
}
func SpideOrigin(m *ice.Message, name string) string { return m.Cmdv(SPIDE, name, CLIENT_ORIGIN) }
func SpideURL(m *ice.Message, name string) string { return m.Cmdv(SPIDE, name, CLIENT_URL) }
func SpideList(m *ice.Message) *ice.Message { return m.Copy(AdminCmd(m, SPIDE)) }
@ -517,3 +511,34 @@ func SpideReposList(m *ice.Message) *ice.Message {
ctx.DisplayInputKey(m, "style", "_nameicon")
return m
}
func PublicIP(m *ice.Message, arg ...string) ice.Any {
if len(arg) == 0 {
return SpideGet(m, "http://ip-api.com/json")
}
return mdb.Cache(m, "web.spide.location."+arg[0], func() ice.Any {
return kit.Format(kit.Value(SpideGet(m, "http://opendata.baidu.com/api.php?co=&resource_id=6006&oe=utf8", "query", arg[0]), "data.0.location"))
})
}
func HostPort(m *ice.Message, host, port string, arg ...string) string {
p := ""
if len(arg) > 0 {
kit.If(kit.Select("", arg, 0), func(pod string) { p += S(pod) })
kit.If(kit.Select("", arg, 1), func(cmd string) { p += C(cmd) })
}
kit.If(m.Option(ice.LOG_DEBUG) == ice.TRUE, func() { p += "?debug=true" })
kit.If(host == "", func() {
if u := kit.ParseURL(UserHost(m)); u != nil {
host = u.Hostname()
}
})
host = kit.Select("localhost", host)
if port == tcp.PORT_443 {
return kit.Format("https://%s", host) + p
} else if port == tcp.PORT_80 {
return kit.Format("http://%s", host) + p
} else if port == "" {
return kit.Format("%s://%s", UserWeb(m).Scheme, host) + p
} else {
return kit.Format("http://%s:%s", host, port) + p
}
}

View File

@ -16,19 +16,31 @@ const STORE = "store"
func init() {
Index.MergeCommands(ice.Commands{
STORE: {Name: "store refresh", Help: "商店", Icon: "App Store.png", Role: aaa.VOID, Actions: ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
ice.AFTER_INIT: {Hand: func(m *ice.Message, arg ...string) {
AddPortalProduct(m, "云商店", `
每个用户都可以将自己的空间列表以系统商店的方式分享给其它用户
同样的每个用户也可以添加任意多个商店直接将空间下载到本机使用
`, 300.0)
}},
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) { m.Cmdy(SPIDE, mdb.INPUTS, arg) }},
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {
switch arg[0] {
case ORIGIN:
m.Cmd(BROAD).Table(func(value ice.Maps) {
m.Push(arg[0], HostPort(m, value[tcp.HOST], value[tcp.PORT]))
})
}
m.Cmdy(SPIDE, mdb.INPUTS, arg)
}},
mdb.CREATE: {Name: "create origin* name icons", Hand: func(m *ice.Message, arg ...string) {
m.Cmd(SPIDE, mdb.CREATE, m.OptionSimple("origin,name,icons"), mdb.TYPE, nfs.REPOS)
}},
mdb.REMOVE: {Hand: func(m *ice.Message, arg ...string) {
m.Cmd(SPIDE, mdb.REMOVE, CLIENT_NAME, m.Option(mdb.NAME))
}},
tcp.DIAL: {Hand: func(m *ice.Message, arg ...string) {
m.Options(m.Cmd(SPIDE, m.Option(mdb.NAME)).AppendSimple())
m.Cmdy(SPIDE, mdb.DEV_REQUEST)
}},
INSTALL: {Name: "install name*", Hand: func(m *ice.Message, arg ...string) {
if !kit.HasPrefixList(arg, ctx.RUN) {
m.Cmdy(DREAM, mdb.CREATE, m.OptionSimple(mdb.NAME, nfs.REPOS, nfs.BINARY))
@ -39,12 +51,6 @@ func init() {
PORTAL: {Role: aaa.VOID, Hand: func(m *ice.Message, arg ...string) {
ProcessIframe(m, m.Option(mdb.NAME), m.Option(ORIGIN)+S(m.Option(mdb.NAME))+C(m.ActionKey()), arg...)
}},
DESKTOP: {Role: aaa.VOID, Hand: func(m *ice.Message, arg ...string) {
ProcessIframe(m, kit.Keys(m.Option(mdb.NAME), m.ActionKey()), S(m.Option(mdb.NAME))+C(m.ActionKey()), arg...)
}},
ADMIN: {Role: aaa.VOID, Hand: func(m *ice.Message, arg ...string) {
ProcessIframe(m, kit.Keys(m.Option(mdb.NAME), m.ActionKey()), S(m.Option(mdb.NAME))+C(m.ActionKey()), arg...)
}},
OPEN: {Hand: func(m *ice.Message, arg ...string) {
if m.Option(mdb.TYPE) == ORIGIN {
m.ProcessOpen(m.Option(ORIGIN))
@ -52,10 +58,6 @@ func init() {
m.ProcessOpen(S(m.Option(mdb.NAME)))
}
}},
"connect": {Help: "连接", Hand: func(m *ice.Message, arg ...string) {
m.Options(m.Cmd(SPIDE, m.Option(mdb.NAME)).AppendSimple())
m.Cmdy(SPIDE, mdb.DEV_REQUEST)
}},
}, ctx.ConfAction(CLIENT_TIMEOUT, cli.TIME_3s), DREAM), Hand: func(m *ice.Message, arg ...string) {
if kit.HasPrefixList(arg, ctx.ACTION) {
m.Cmdy(DREAM, arg)
@ -64,19 +66,18 @@ func init() {
m.Cmd(SPIDE, arg, kit.Dict(ice.MSG_FIELDS, "time,icons,client.type,client.name,client.origin")).Table(func(value ice.Maps) {
kit.If(value[CLIENT_TYPE] == nfs.REPOS && value[CLIENT_NAME] != ice.SHY, func() {
kit.If(value[CLIENT_NAME] == ice.OPS, func() { value[CLIENT_ORIGIN] = UserHost(m) })
m.Push(mdb.TYPE, ORIGIN)
m.Push(mdb.NAME, value[CLIENT_NAME]).Push(mdb.ICONS, value[mdb.ICONS]).Push(ORIGIN, value[CLIENT_ORIGIN])
m.Push(mdb.TYPE, ORIGIN).Push(mdb.NAME, value[CLIENT_NAME]).Push(mdb.ICONS, value[mdb.ICONS]).Push(ORIGIN, value[CLIENT_ORIGIN])
if _, ok := list[value[CLIENT_NAME]]; ok || kit.IsIn(value[CLIENT_NAME], ice.OPS, ice.DEV) {
m.Push("exists", ice.TRUE)
m.Push(mdb.STATUS, ice.TRUE)
} else {
m.Push("exists", ice.FALSE)
m.Push(mdb.STATUS, ice.FALSE)
}
})
})
if ice.Info.NodeType == WORKER || !aaa.IsTechOrRoot(m) {
if m.SortStrR(mdb.NAME); ice.Info.NodeType == WORKER || !aaa.IsTechOrRoot(m) {
m.Action()
} else {
m.PushAction(OPEN, "connect", mdb.REMOVE).Action(mdb.CREATE)
m.PushAction(OPEN, tcp.DIAL, mdb.REMOVE).Action(mdb.CREATE)
}
} else {
defer ToastProcess(m, ice.LIST, arg[0])()
@ -87,36 +88,41 @@ func init() {
dream := C(DREAM)
origin := SpideOrigin(m, arg[0])
kit.If(origin == "", func() { arg[0], origin, dream = ice.DEV, arg[0], arg[0]+dream })
if kit.IsIn(kit.ParseURL(origin).Hostname(), append(m.Cmds(tcp.HOST).Appendv(aaa.IP), tcp.LOCALHOST)...) {
origin = m.Option(ice.MSG_USERHOST)
} else {
origin = tcp.PublishLocalhost(m, origin)
}
// if kit.IsIn(kit.ParseURL(origin).Hostname(), append(m.Cmds(tcp.HOST).Appendv(aaa.IP), tcp.LOCALHOST)...) {
// if kit.IsIn(kit.ParseURL(origin).Hostname(), tcp.LOCALHOST) {
// origin = m.Option(ice.MSG_USERHOST)
// } else {
// origin = tcp.PublishLocalhost(m, origin)
// }
// origin = tcp.PublishLocalhost(m, origin)
stat := map[string]int{}
list := m.Spawn(ice.Maps{ice.MSG_FIELDS: ""}).CmdMap(SPACE, mdb.NAME)
m.SetAppend().Spawn().SplitIndex(m.Cmdx(SPIDE, arg[0], dream, kit.Dict(mdb.ConfigSimple(m, CLIENT_TIMEOUT)))).Table(func(value ice.Maps) {
if value[mdb.TYPE] == ORIGIN {
return
}
stat[value[mdb.TYPE]]++
if value[nfs.BINARY] == "" {
value[nfs.BINARY] = origin + S(value[mdb.NAME])
}
m.Push("", value, kit.Split("time,type,name,icons,repos,binary,module,version"))
if _, ok := list[value[mdb.NAME]]; ok {
m.Push("exists", ice.TRUE)
m.Push(mdb.STATUS, ice.TRUE)
} else {
m.Push("exists", ice.FALSE)
m.Push(mdb.STATUS, ice.FALSE)
}
if value[mdb.TYPE] == SERVER {
m.Push(mdb.TEXT, value[mdb.TEXT]).Push(ORIGIN, value[mdb.TEXT]).PushButton()
return
}
m.Push(mdb.TEXT, value[nfs.REPOS]).Push(ORIGIN, origin)
if _, ok := list[value[mdb.NAME]]; ok || arg[0] == ice.OPS {
m.PushButton(PORTAL, INSTALL)
} else if ice.Info.NodeType == WORKER || !aaa.IsTechOrRoot(m) {
m.PushButton(PORTAL)
} else {
m.PushButton(PORTAL, INSTALL)
button := []ice.Any{PORTAL}
if _, ok := list[value[mdb.NAME]]; ok {
button = append(button, OPEN)
} else if aaa.IsTechOrRoot(m) {
button = append(button, INSTALL)
}
m.PushButton(button...)
})
m.StatusTimeCount(ORIGIN, origin, stat)
}

View File

@ -6,7 +6,7 @@ Volcanos(chat.ONIMPORT, {
},
_project: function(can, msg, dev, target) {
msg.Table(function(value) { if (value.type == web.WORKER) { return }
value.nick = [{text: value.name}, value.exists == "true" && {text: ["●", "", "exists"]}]
value.nick = [{text: value.name}, value.status == "true" && {text: ["●", "", "exists"]}]
value._hash = dev.concat([value.name]).join(":"), value._select = can.base.beginWith(can.db.hash.join(":"), value._hash)
value.icons = can.misc.Resource(can, value.icons||"usr/icons/icebergs.png", "", value.origin)
can.onimport.itemlist(can, [value], function(event, item, show, target) {

View File

@ -25,7 +25,7 @@ func init() {
}
})
}},
}, mdb.ExportHashAction(mdb.SHORT, mdb.UNIQ, mdb.EXPIRE, mdb.MONTH, html.CHECKBOX, ice.TRUE)), Hand: func(m *ice.Message, arg ...string) {
}, mdb.HashAction(mdb.SHORT, mdb.UNIQ, mdb.EXPIRE, mdb.MONTH, html.CHECKBOX, ice.TRUE)), Hand: func(m *ice.Message, arg ...string) {
if mdb.HashSelect(m, arg...); len(arg) > 0 {
m.EchoScript(kit.MergeURL2(m.Option(ice.MSG_USERWEB), nfs.PS, TOKEN, arg[0]))
} else {

View File

@ -62,7 +62,7 @@ func (f *Frame) Start(m *ice.Message, arg ...string) {
default:
m.Cmd(tcp.SERVER, tcp.LISTEN, mdb.TYPE, HTTP, mdb.NAME, logs.FileLine(1), m.OptionSimple(tcp.HOST, tcp.PORT), func(l net.Listener) {
defer mdb.HashCreateDeferRemove(m, m.OptionSimple(mdb.NAME, tcp.PROTO), arg, cli.STATUS, tcp.START)()
m.Go(func() { gdb.Event(m.Spawn(), SERVE_START, arg) })
m.GoSleep("300ms", func() { gdb.Event(m.Spawn(), SERVE_START, arg) })
if m.Option(tcp.PORT) == tcp.PORT_443 {
m.WarnNotValid(f.Server.ServeTLS(l, nfs.ETC_CERT_PEM, nfs.ETC_CERT_KEY))
} else {

23
conf.go
View File

@ -28,6 +28,7 @@ const (
MAIL = "mail"
HELP = "help"
INFO = "info"
SHOW = "show"
MAIN = "main"
AUTO = "auto"
LIST = "list"
@ -60,7 +61,8 @@ const (
INT = "int"
)
const ( // REPOS
CONTEXTS = "contexts"
CONTEXTOS = "ContextOS"
// CONTEXTS = "contexts"
INTSHELL = "intshell"
LEARNING = "learning"
VOLCANOS = "volcanos"
@ -256,11 +258,13 @@ const ( // MSG
LOG_DISABLE = "log.disable"
LOG_TRACEID = "log.id"
MSG_NODETYPE = "node.type"
MSG_NODEICON = "node.icon"
MSG_NODENAME = "node.name"
MSG_NODETYPE = "node.type"
MSG_FILES = "file.system"
FROM_SPACE = "from.space"
FROM_DAEMON = "from.daemon"
FIELD_OPTION = "field.option"
TABLE_CHECKBOX = "table.checkbox"
TOAST_DURATION = "toast.duration"
DREAM_SIMPLE = "dream.simple"
@ -320,13 +324,14 @@ const ( // CTX
CTX_SERVE = "serve"
CTX_CLOSE = "close"
CTX_INIT = "_init"
CTX_EXIT = "_exit"
CTX_OPEN = "_open"
CTX_TITLE = "_title"
CTX_TRANS = "_trans"
CTX_ICONS = "_icons"
CTX_STYLE = "_style"
CTX_INIT = "_init"
CTX_EXIT = "_exit"
CTX_OPEN = "_open"
CTX_TITLE = "_title"
CTX_TRANS = "_trans"
CTX_ICONS = "_icons"
CTX_STYLE = "_style"
AFTER_INIT = "afterInit"
)
const ( // LOG
LOG_CMDS = "cmds"

View File

@ -0,0 +1,34 @@
package center
import (
"shylinux.com/x/ice"
"shylinux.com/x/icebergs/base/ctx"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
"shylinux.com/x/icebergs/base/web"
kit "shylinux.com/x/toolkits"
)
type center struct {
list string `name:"list list" help:"云游"`
}
func (s center) List(m *ice.Message, arg ...string) {
if len(arg) == 0 {
m.Cmd(web.SPACE).Table(func(value ice.Maps) {
if value[mdb.TYPE] == web.SERVER {
m.PushRecord(value, mdb.NAME, mdb.ICONS, nfs.MODULE, nfs.VERSION)
}
})
m.Display("/plugin/story/spides.js?split=.").Option(nfs.DIR_ROOT, ice.Info.NodeName)
} else {
m.Cmdy(web.SPACE, arg[0], m.PrefixKey()).Table(func(value ice.Maps) {
m.Push(nfs.FILE, kit.Keys(arg[0], value[mdb.NAME]))
})
if m.Length() == 0 {
m.Push(web.SPACE, arg[0]).Push(ctx.INDEX, web.DESKTOP)
}
}
}
func init() { ice.Cmd("web.chat.center.center", center{}) }

View File

@ -0,0 +1,37 @@
package center
import (
"shylinux.com/x/ice"
"shylinux.com/x/icebergs/base/aaa"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/web"
)
type password struct {
change string `name:"change" help:"修改登录"`
login string `name:"login username* password*" help:"登录" role:"void"`
list string `name:"list refresh" help:"密码登录" role:"void"`
}
func (s password) Init(m *ice.Message, arg ...string) {
m.Cmd(web.HEADER, mdb.CREATE, mdb.TYPE, "qrcode", mdb.NAME, "qrcode", mdb.HELP, "扫码登录", mdb.ORDER, "10")
m.Cmd(web.HEADER, mdb.CREATE, mdb.TYPE, "plugin", mdb.NAME, m.CommandKey(), mdb.HELP, "密码登录", mdb.ORDER, "11", mdb.INDEX, m.PrefixKey())
}
func (s password) Change(m *ice.Message, arg ...string) {
m.Cmd(aaa.USER, mdb.MODIFY, aaa.USERNAME, m.Option(ice.MSG_USERNAME), aaa.PASSWORD, arg[1])
}
func (s password) Login(m *ice.Message, arg ...string) {
if m.WarnNotValid(m.Option(aaa.PASSWORD) != m.Cmd(aaa.USER, m.Option(aaa.USERNAME)).Append(aaa.PASSWORD), aaa.PASSWORD) {
return
}
web.RenderCookie(m.Message, aaa.SessCreate(m.Message, m.Option(aaa.USERNAME)))
}
func (s password) List(m *ice.Message, arg ...string) {
if m.Option(ice.MSG_USERNAME) == "" {
m.DisplayForm("username*", "password*", s.Login)
} else {
m.DisplayForm("password*", s.Change)
}
}
func init() { ice.Cmd("web.chat.password", password{}) }

View File

@ -117,7 +117,9 @@ func init() {
link := tcp.PublishLocalhost(m, m.OptionDefault(mdb.LINK, m.Option(ice.MSG_USERWEB)))
m.Push(mdb.NAME, link).PushQRCode(mdb.TEXT, kit.MergeURL(link, ice.FROM_DAEMON, m.Option(ice.MSG_DAEMON)))
}},
mdb.CREATE: {Name: "create type*=plugin,qrcode,oauth name* help icons link order space index args", Hand: func(m *ice.Message, arg ...string) { mdb.HashCreate(m, m.OptionSimple()) }},
mdb.CREATE: {Name: "create type*=plugin,qrcode,oauth name* help icons link order space index args"},
// Hand: func(m *ice.Message, arg ...string) { mdb.HashCreate(m, m.OptionSimple())},
mdb.REMOVE: {Hand: func(m *ice.Message, arg ...string) { mdb.HashRemove(m, m.OptionSimple(mdb.NAME)) }},
mdb.MODIFY: {Hand: func(m *ice.Message, arg ...string) { mdb.HashModify(m, m.OptionSimple(mdb.NAME), arg) }},
ice.DEMO: {Help: "体验", Icon: "bi bi-shield-fill-check", Hand: func(m *ice.Message, arg ...string) {
@ -140,12 +142,21 @@ func init() {
}
}},
}, web.ApiAction(), mdb.ImportantHashAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,type,name,help,icons,order,link,space,index,args")), Hand: func(m *ice.Message, arg ...string) {
kit.If(m.Option(ice.MSG_USERPOD), func(p string) {
m.Cmdy(web.SPACE, p, m.PrefixKey(), ice.Maps{ice.MSG_USERPOD: ""})
if kit.Contains(m.Option(ice.MSG_USERUA), "MicroMessenger") {
if m.Option(ice.MSG_USERNAME) == "" && m.Option("code") == "" && mdb.Config(m, "oauth") != "" {
m.ProcessOpen(mdb.Config(m, "oauth"))
// return
}
}
kit.If(kit.Select(m.Option(ice.POD), m.Option(ice.MSG_USERPOD)), func(p string) {
m.Cmdy(web.SPACE, p, m.PrefixKey(), ice.Maps{ice.MSG_USERPOD: "", ice.POD: ""})
}, func() {
m.Option(ice.MSG_NODETYPE, ice.Info.NodeType)
m.Option(ice.MSG_NODENAME, ice.Info.NodeName)
m.Option("favicon", ice.Info.NodeIcon)
if ice.Info.NodeType == web.WORKER && ice.Info.Titles == "ContextOS" {
return
}
m.Option("titles", ice.Info.Titles)
})
if ice.Info.NodeType == web.WORKER {
@ -153,12 +164,17 @@ func init() {
}
m.Option(aaa.LANGUAGE, strings.ReplaceAll(strings.ToLower(kit.Select("", kit.Split(kit.GetValid(
func() string { return kit.Select("", "zh-cn", strings.Contains(m.Option(ice.MSG_USERUA), "zh_CN")) },
func() string { return kit.Select("", kit.Split(m.R.Header.Get(html.AcceptLanguage), ",;"), 0) },
func() string {
if m.R != nil {
return kit.Select("", kit.Split(m.R.Header.Get(html.AcceptLanguage), ",;"), 0)
}
return ""
},
func() string { return ice.Info.Lang },
), " ."), 0)), "_", "-"))
m.Option("language.list", m.Cmd(nfs.DIR, nfs.TemplatePath(m, aaa.LANGUAGE)+nfs.PS, nfs.FILE).Appendv(nfs.FILE))
m.Option("theme.list", m.Cmd(nfs.DIR, nfs.TemplatePath(m, aaa.THEME)+nfs.PS, nfs.FILE).Appendv(nfs.FILE))
if m.Option(ice.MSG_USERNAME) == "" || m.Option(ice.MSG_INDEX) == m.PrefixKey() {
if m.Option(ice.MSG_USERNAME) == "" || kit.IsIn(m.Option(ice.MSG_INDEX), m.PrefixKey(), m.CommandKey()) {
mdb.HashSelect(m, arg...).Sort(mdb.ORDER, ice.INT)
m.Table(func(value ice.Maps) { m.Push(mdb.STATUS, kit.Select(mdb.ENABLE, mdb.DISABLE, value[mdb.ORDER] == "")) })
defer m.StatusTimeCount(kit.Dict(mdb.ConfigSimple(m, ice.DEMO)))
@ -168,7 +184,7 @@ func init() {
m.Push(mdb.TIME, m.Time()).Push(mdb.NAME, cli.QRCODE).Push(mdb.HELP, "扫码登录").Push(mdb.ICONS, nfs.USR_ICONS_VOLCANOS).Push(mdb.TYPE, cli.QRCODE).Push(web.LINK, "").Push(mdb.ORDER, "10")
})
kit.If(GetSSO(m), func(p string) {
m.Push(mdb.TIME, m.Time()).Push(mdb.NAME, web.SERVE).Push(mdb.ICONS, nfs.USR_ICONS_ICEBERGS).Push(mdb.TYPE, "oauth").Push(web.LINK, p)
m.Push(mdb.TIME, m.Time()).Push(mdb.NAME, web.SERVE).Push(mdb.ICONS, nfs.USR_ICONS_ICEBERGS).Push(mdb.TYPE, "oauth").Push(web.LINK, p).Push(mdb.ORDER, "100")
})
} else {
kit.If(kit.IsIn(m.Option(ice.MSG_USERROLE), aaa.TECH, aaa.ROOT), func() { m.Action(mdb.CREATE, ice.DEMO) })
@ -183,5 +199,7 @@ func init() {
})
}
func AddHeaderLogin(m *ice.Message, types, name, help, order string, arg ...string) {
m.Cmd(web.CHAT_HEADER, mdb.CREATE, mdb.TYPE, types, mdb.NAME, name, mdb.HELP, help, mdb.ORDER, order, arg)
m.Cmd(web.SPACE, ice.OPS, web.CHAT_HEADER, mdb.CREATE, mdb.TYPE, types, mdb.NAME, name, mdb.HELP, help, mdb.ORDER, order,
web.SPACE, m.Option(ice.MSG_USERPOD), ctx.INDEX, m.PrefixKey(), arg,
)
}

View File

@ -65,7 +65,10 @@ func init() {
kit.If(m.Option(mdb.TYPE) == web.LINK, func() { ctx.ProcessField(m, m.ShortKey(), m.Option(mdb.TEXT)) })
}},
}, FavorAction(), mdb.HashAction(mdb.SHORT, web.LINK, mdb.FIELD, "time,hash,type,name,link")), Hand: func(m *ice.Message, arg ...string) {
list := []string{m.MergePodCmd("", web.PORTAL), m.MergePodCmd("", web.ADMIN)}
list := []string{m.MergePodCmd("", web.PORTAL), m.MergePodCmd("", web.ADMIN), m.MergePodCmd("", web.DESKTOP)}
m.Cmd(web.SPACE).Table(func(value ice.Maps) {
kit.If(kit.IsIn(value[mdb.TYPE], web.WORKER, web.SERVER), func() { list = append(list, m.MergePod(value[mdb.NAME])) })
})
if mdb.HashSelect(m, arg...); len(arg) == 0 {
for _, link := range list {
if u := kit.ParseURL(link); u != nil {

View File

@ -67,12 +67,19 @@ fieldset.desktop>div.output>div.desktop>fieldset.web.chat.macos.finder>div.statu
fieldset.desktop>div.output>div.desktop>fieldset.web.chat.macos.finder>div.output div.item.disable { display:none; }
fieldset.desktop>div.output>fieldset.web.chat.macos.dock>div.output div.item.disable { display:none; }
fieldset.desktop>div.output>div.desktop>div.item.disable { display:none; }
fieldset.macos.menu>div.output>div.item { padding:0 var(--input-padding); height:var(--desktop-menu-height); float:right; }
fieldset.macos.menu>div.output>div.item { padding:0 var(--button-padding); height:var(--desktop-menu-height); float:right; }
body.mobile fieldset.macos.menu>div.output>div.item { padding:0 var(--input-padding); }
body.mobile fieldset.macos.menu>div.output>div.tabs { display:none; }
body.mobile fieldset.macos.menu>div.output>div.icon.create { display:none; }
body.mobile fieldset.macos.menu>div.output>div.item.search { display:none; }
body.mobile fieldset.macos.menu>div.output>div.item.notify { display:none; }
fieldset.macos.menu>div.output>div.item.avatar>img { padding:0; height:var(--desktop-menu-height); }
fieldset.macos.menu>div.output>div.menu { padding:0 var(--input-padding); float:left; }
fieldset.macos.menu>div.output>div.menu { padding:0 var(--button-padding); float:left; }
body.mobile fieldset.macos.menu>div.output>div.menu { padding:0 var(--input-padding); }
fieldset.macos.menu>div.output>div.tabs { font-style:italic; padding:0 var(--input-padding); float:left; }
fieldset.macos.menu.cmd>div.output>div.tabs { padding:0 var(--button-padding); }
fieldset.macos.menu>div.output>div.tabs.select { background-color:var(--panel-hover-bg-color); color:var(--panel-hover-fg-color); }
fieldset.macos.dock { transition:left 1s; }
fieldset.macos.dock>div.output { height:var(--desktop-icon-size); display:flex; overflow:auto; }
fieldset.macos.dock>div.output>div.space { background-color:#ececec36; margin:var(--button-margin); height:calc(100% - 20px); width:2px; }
fieldset.macos.dock>div.output>div.item { text-align:center; align-self:baseline; transition:margin-top 0.3s; }

View File

@ -42,7 +42,7 @@ func init() {
Notify(m, "usr/icons/Infomation.png", cli.RUNTIME, "系统启动成功", ctx.INDEX, cli.RUNTIME)
}},
DESKTOP: {Help: "桌面", Role: aaa.VOID, Actions: ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
ice.AFTER_INIT: {Hand: func(m *ice.Message, arg ...string) {
web.AddPortalProduct(m, "云桌面", `
一款网页版的电脑桌面打开网页即可随时随地的使用各种软件
无论这些软件是运行在本机还是远程还是任何虚拟的空间无论是内存还是磁盘

View File

@ -1,12 +1,12 @@
(function() {
Volcanos(chat.ONIMPORT, {
_init: function(can, msg) { can.isCmdMode() && can.onappend.style(can, html.OUTPUT)
can.onlayout.background(can, can.user.info.background||"/p/usr/icons/background.jpg", can._fields)
can.onlayout.background(can, can.misc.ResourceIcons(can, can.user.info.background||"usr/icons/background.png"), can._fields)
can.onimport._menu(can), can.onimport._notifications(can), can.onimport._searchs(can), can.onimport._dock(can)
can.sup.onexport.link = function() { return can.misc.MergeURL(can, {pod: can.ConfSpace()||can.misc.Search(can, ice.POD), cmd: web.DESKTOP}) }
can.onexport.title(can, can.ConfHelp(), can.user.titles)
},
_menu: function(can) { can.onappend.plugin(can, {index: "web.chat.macos.menu", style: html.OUTPUT}, function(sub) { can.ui.menu = sub
sub._desktop = can
_menu: function(can) { can.onappend.plugin(can, {index: "web.chat.macos.menu", style: html.OUTPUT, title: can.Conf("title")}, function(sub) { can.ui.menu = sub, sub._desktop = can
var tabs = can.misc.sessionStorage(can, [can.ConfIndex(), html.TABS])
sub.onexport.output = function() { can.onimport._desktop(can, can._msg)
var sess = can.misc.SearchHash(can)[0]||can.Conf("session")
@ -18,12 +18,10 @@ Volcanos(chat.ONIMPORT, {
switch (value) {
case "notifications": can.ui.notifications._output.innerHTML && can.onmotion.toggle(can, can.ui.notifications._target); break
case "searchs": can.onaction._search(can); break
case "reload": can.Update(); break
case cli.QRCODE: can.sup.onaction["生成链接"]({}, can.sup); break
case mdb.CREATE: can.onaction.create(event, can); break
case html.DESKTOP:
var carte = can.user.carte(event, can, {}, can.core.Item(can.onfigure), function(event, button, meta, carte) {
can.onfigure[button](event, can, carte); return true
}); break
case html.DESKTOP: var carte = can.user.carte(event, can, {}, can.core.Item(can.onfigure), function(event, button, meta, carte) { can.onfigure[button](event, can, carte); return true }); break
default: can.onimport._window(can, value)
}
}
@ -51,7 +49,13 @@ Volcanos(chat.ONIMPORT, {
} }
}) },
_dock: function(can) { can.onappend.plugin(can, {index: "web.chat.macos.dock", style: html.OUTPUT}, function(sub) { can.ui.dock = sub
sub.onexport.output = function(sub, msg) { can.onimport.layout(can) }
can.onimport.layout(can)
sub.onexport.output = function(sub, msg) {
can.onimport.layout(can)
can.onmotion.delay(can, function() {
can.onimport.layout(can)
})
}
sub.onexport.record = function(sub, value, key, item) { can.onimport._window(can, item) }
}) },
_desktop: function(can, msg, name) { var target = can.page.Append(can, can._output, [html.DESKTOP])._target; can.ui.desktop = target
@ -75,8 +79,7 @@ Volcanos(chat.ONIMPORT, {
item.height = can.base.Max(html.DESKTOP_HEIGHT, can.ConfHeight()-125), item.width = can.base.Max(html.DESKTOP_WIDTH, can.ConfWidth())
item.left = (can.ConfWidth()-item.width)/2, item.top = (can.ConfHeight()-item.height-125)/4+25
item.type = html.PLUGIN, item.style = {left: item.left, top: item.top, height: item.height, width: item.width}
can.onappend.plugin(can, item, function(sub) { can.onappend.style(can, html.FLOAT, sub._target), can.ondetail.select(can, sub._target)
can.page.style(can, sub._target, html.HEIGHT, item.height, html.WIDTH, item.width)
can.onappend.plugin(can, item, function(sub) {
var index = 0; can.core.Item({
close: {color: "#f95f57", inner: "x", onclick: function(event) { sub.onaction._close(event, sub) }},
small: {color: "#fcbc2f", inner: "-", onclick: function(event) { var dock = can.page.Append(can, can.ui.dock._output, [{view: html.ITEM, list: [{view: html.ICON, list: [{img: can.misc.PathJoin(item.icon)}]}], onclick: function() {
@ -86,25 +89,28 @@ Volcanos(chat.ONIMPORT, {
}, function(name, item) {
can.page.insertBefore(can, [{view: [[html.ITEM, html.BUTTON, "window", name], ""], title: name, list: [{text: item.inner}], style: {"background-color": item.color, right: 10+25*index++}, onclick: item.onclick}], sub._output)
})
sub.onimport._open = function(sub, msg, arg) { can.onimport._window(can, {title: msg.Option(html.TITLE), index: web.CHAT_IFRAME, args: [arg]}) }
sub.onimport._field = function(sub, msg) { msg.Table(function(item) { can.onimport._window(can, item) }) }
sub.onaction._close = function() { can.page.Remove(can, sub._target), can.onexport.tabs(can) }
sub.onappend.dock = function(item) { can.ui.dock.runAction(can.request(event, item), mdb.CREATE, [], function() { can.ui.dock.Update() }) }
sub.onappend.desktop = function(item) { can.onimport._item(can, item) }
sub.onexport.record = function(sub, value, key, item) { can.onimport._window(can, item) }
sub.onexport.marginTop = function() { return 25 }, sub.onexport.marginBottom = function() { return 100 }
sub.onexport.actionHeight = function(sub) { return can.page.ClassList.has(can, sub._target, html.OUTPUT)? 0: html.ACTION_HEIGHT+20 }
sub.onexport.output = function() { sub.onimport.size(sub, item.height, can.base.Min(sub._target.offsetWidth, item.width), false)
sub._target._meta.args = can.base.trim(can.page.SelectArgs(can, sub._option, "", function(target) { return target.value })), can.onexport.tabs(can)
}, sub.onimport.size(sub, item.height, can.base.Min(sub._target.offsetWidth, item.width), false)
sub.onexport.record = function(sub, value, key, item) { can.onimport._window(can, item) }
sub.onimport._open = function(sub, msg, arg) { can.onimport._window(can, {title: msg.Option(html.TITLE), index: web.CHAT_IFRAME, args: [arg]}) }
sub.onimport._field = function(sub, msg) { msg.Table(function(item) { can.onimport._window(can, item) }) }
sub.onappend.dock = function(item) { can.ui.dock.runAction(can.request(event, item), mdb.CREATE, [], function() { can.ui.dock.Update() }) }
sub.onaction._close = function() { can.page.Remove(can, sub._target), can.onexport.tabs(can) }
sub.onappend.desktop = function(item) { can.onimport._item(can, item) }
}
can.onappend.style(can, html.FLOAT, sub._target), can.ondetail.select(can, sub._target, sub)
sub.onimport.size(sub, item.height, can.base.Min(sub._target.offsetWidth, item.width), false)
can.page.style(can, sub._target, html.HEIGHT, item.height, html.WIDTH, item.width)
can.onmotion.move(can, sub._target, {top: item.top, left: item.left})
sub.Conf("style.left", ""), sub.Conf("style.top", "")
sub.onmotion.resize(can, sub._target, function(height, width) {
can.page.style(sub, sub._target, html.HEIGHT, height, html.WIDTH, width)
sub.onimport.size(sub, item.height = height, item.width = width, false)
can.page.style(sub, sub._target, html.HEIGHT, height, html.WIDTH, width)
sub._target._meta.height = height, sub._target._meta.width = width, can.onexport.tabs(can)
}, 25, 0, can.ui.desktop)
sub._target.onclick = function(event) { can.ondetail.select(can, sub._target) }
sub._target.onclick = function(event) { can.ondetail.select(can, sub._target, sub) }
sub._target._meta = {index: sub.ConfIndex(), args: sub.Conf(ctx.ARGS)}, can.onexport.tabs(can)
cb && cb(sub)
}, can.ui.desktop)
@ -119,10 +125,11 @@ Volcanos(chat.ONIMPORT, {
}, function() { next() })
}, function() { _select && _select.click() })
},
layout: function(can) { can.page.style(can, can._output, html.HEIGHT, can.ConfHeight(), html.WIDTH, can.ConfWidth())
can.ui.dock && can.page.style(can, can.ui.dock._output, "position", "")
can.ui.dock && can.page.style(can, can.ui.dock._target, html.LEFT, can.base.Min((can.ConfWidth()-(can.ui.dock._target.offsetWidth||502))/2, 0))
layout: function(can) {
can.page.style(can, can._output, html.HEIGHT, can.ConfHeight(), html.WIDTH, can.ConfWidth())
can.ui.menu && can.ui.menu.onimport.size(can.ui.menu, html.DESKTOP_MENU_HEIHGT, can.ConfWidth(), false)
can.ui.dock && can.page.style(can, can.ui.dock._target, html.LEFT, can.base.Min((can.ConfWidth()-can.ui.dock._target.offsetWidth)/2, 0))
can.ui.dock && can.page.style(can, can.ui.dock._output, "position", "")
},
}, [""])
Volcanos(chat.ONACTION, {
@ -134,16 +141,11 @@ Volcanos(chat.ONACTION, {
} },
create: function(event, can) { can.onimport._desktop(can) },
})
Volcanos(chat.ONKEYMAP, {
escape: function(event, can) { can.onmotion.hidden(can, can.ui.searchs._target) },
space: function(event, can) { can.onaction._search(can), can.onkeymap.prevent(event) },
enter: function(event, can) { can.page.Select(can, can.ui.desktop, "fieldset.select", function(target) { target._can.Update(event) }) },
ctrln: function(event, can) { can.onkeymap.selectCtrlN(event, can, can.ui.menu._output, html.DIV_TABS) },
tabx: function(event, can) { can.page.Select(can, can.ui.menu._output, html.DIV_TABS_SELECT, function(target) { target._close() }) },
tabs: function(event, can) { can.onaction.create(event, can) },
})
Volcanos(chat.ONDETAIL, {
select: function(can, target) { can.onmotion.select(can, can.ui.desktop, html.FIELDSET, target) },
select: function(can, target, sub) {
can.onmotion.select(can, can.ui.desktop, html.FIELDSET, target)
can.onexport.title(can, sub.ConfHelp())
},
})
Volcanos(chat.ONEXPORT, {
tabs: function(can) {
@ -154,6 +156,14 @@ Volcanos(chat.ONEXPORT, {
} }); can.misc.sessionStorage(can, [can.ConfIndex(), html.TABS], JSON.stringify(list))
},
})
Volcanos(chat.ONKEYMAP, {
escape: function(event, can) { can.onmotion.hidden(can, can.ui.searchs._target) },
space: function(event, can) { can.onaction._search(can), can.onkeymap.prevent(event) },
enter: function(event, can) { can.page.Select(can, can.ui.desktop, "fieldset.select", function(target) { target._can.Update(event) }) },
ctrln: function(event, can) { can.onkeymap.selectCtrlN(event, can, can.ui.menu._output, html.DIV_TABS) },
tabx: function(event, can) { can.page.Select(can, can.ui.menu._output, html.DIV_TABS_SELECT, function(target) { target._close() }) },
tabs: function(event, can) { can.onaction.create(event, can) },
})
Volcanos(chat.ONFIGURE, {
"session\t>": function(event, can, carte) { can.runActionCommand(event, "session", [], function(msg) {
var hash = can.misc.SearchHash(can)

View File

@ -1,10 +1,13 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg) { can.page.style(can, can._output, html.MAX_WIDTH, can.page.width())
can.onimport.icon(can, msg = msg||can._msg, can._output, function(target, item) { can.page.Modify(can, target, {
onclick: function(event) { can.sup.onexport.record(can, item.name, mdb.NAME, item) },
oncontextmenu: function(event) { var carte = can.user.carte(event, can, {
remove: function() { item.name != "Finder" && can.runAction(event, mdb.REMOVE, [item.hash]) },
}); can.page.style(can, carte._target, html.LEFT, event.x) },
}) }), can.page.Append(can, can._output, [{view: "space"}])
can.onimport.icon(can, msg = msg||can._msg, can._output, function(target, item) {
can.page.Modify(can, target, {
style: {"max-width": (can.page.width()-15)/msg.Length()},
onclick: function(event) { can.sup.onexport.record(can, item.name, mdb.NAME, item) },
oncontextmenu: function(event) { var carte = can.user.carte(event, can, {
remove: function() { item.name != "Finder" && can.runAction(event, mdb.REMOVE, [item.hash]) },
}); can.page.style(can, carte._target, html.LEFT, event.x) },
})
}), can.page.Append(can, can._output, [{view: "space"}])
},
})

View File

@ -1,15 +1,21 @@
Volcanos(chat.ONIMPORT, {_init: function(can, msg) { can.page.style(can, can._output, html.MAX_WIDTH, "")
can.page.Append(can, can._output, can.user.header(can.sup._desktop)), can.page.Append(can, can._output, [
{view: [html.ITEM], list: [{icon: icon.notifications}], onclick: function(event) { can.sup.onexport.record(can, "notifications") }},
{view: [html.ITEM], list: [{icon: icon.search}], onclick: function(event) { can.sup.onexport.record(can, "searchs") }},
{view: [[html.ITEM, "state", "notify"]], list: [{icon: icon.notifications}], onclick: function(event) { can.sup.onexport.record(can, "notifications") }},
{view: [[html.ITEM, "state", "search"]], list: [{icon: icon.search}], onclick: function(event) { can.sup.onexport.record(can, "searchs") }},
].concat(msg.Table(function(item) {
return {view: [html.ITEM], list: [{img: can.page.drawText(can, item.name||item.index, 25, 0, 20)}], onclick: function(event) { can.sup.onexport.record(can, item) }}
return {view: [[html.ITEM, item.name]], list: [{img: can.page.drawText(can, item.name||item.index, 25, 0, 20)}], onclick: function(event) { can.sup.onexport.record(can, item) }}
}), [
{view: [[html.MENU, html.TITLE]], list: [
{img: can.misc.ResourceFavicon(can, msg.Option(html.FAVICON), can.ConfSpace())},
{text: decodeURIComponent(can.ConfSpace()||can.misc.Search(can, ice.POD)||location.host)},
{text: decodeURIComponent(
can.Conf("title")||
(window == top? can.user.info.titles: "")||can.ConfSpace()||can.misc.Search(can, ice.POD)||location.host
)},
], onclick: function(event) { can.sup.onexport.record(can, html.DESKTOP) }},
{view: [[html.MENU, mdb.ICON, web.REFRESH], "", can.page.unicode.refresh], onclick: function(event) { can.user.reload(true) }},
{view: [[html.MENU, mdb.ICON, web.REFRESH], "", can.page.unicode.refresh], onclick: function(event) {
can.sup.onexport.record(can, "reload")
// can.user.reload(true)
}},
{view: [[html.MENU, mdb.ICON, mdb.CREATE], "", can.page.unicode.create], onclick: function(event) { can.sup.onexport.record(can, mdb.CREATE) }},
]))
}})

3
core/chat/password.go Normal file
View File

@ -0,0 +1,3 @@
package chat
func init() {}

View File

@ -21,11 +21,15 @@ func init() {
if m.IsCliUA() {
if len(arg) == 0 || arg[0] == "" {
m.Option(ice.MSG_USERROLE, aaa.TECH)
list := m.CmdMap(web.DREAM, mdb.NAME)
m.Cmd(web.SPACE, func(value ice.Maps) {
msg := m.Cmd(nfs.DIR, path.Join(ice.USR_LOCAL_WORK, value[mdb.NAME], ice.USR_PUBLISH, kit.Keys(ice.ICE, m.OptionDefault(cli.GOOS, cli.LINUX), m.OptionDefault(cli.GOARCH, cli.AMD64))))
kit.If(msg.Length() > 0, func() { m.Push(mdb.NAME, value[mdb.NAME]).Copy(msg) })
kit.If(msg.Length() > 0, func() {
m.Push(mdb.ICONS, list[value[mdb.NAME]][mdb.ICONS])
m.Push(mdb.NAME, value[mdb.NAME]).Copy(msg)
})
})
m.Cut("name,size,time")
m.Cut("icons,name,size,time")
m.RenderResult()
} else if len(arg) > 1 {
m.Option(ice.MSG_USERPOD, arg[0])
@ -47,7 +51,7 @@ func init() {
if m.Option(ice.MSG_USERPOD, arg[0]); len(arg) == 1 {
m.Cmdy(web.SPACE, arg[0], web.SPACE, ice.MAIN)
} else if kit.IsIn(arg[1], CMD, "c") {
if kit.IsIn(arg[2], web.ADMIN) {
if m.R.Method == "POST" || kit.IsIn(arg[2], web.ADMIN) {
m.Cmdy(web.SPACE, arg[0], arg[2], arg[3:])
} else {
m.Options(msg.AppendSimple()).Options(mdb.ICONS, "")

View File

@ -2,6 +2,7 @@ package code
import (
"bytes"
"os"
"path"
"strings"
@ -42,12 +43,15 @@ func _autogen_module(m *ice.Message, file string) {
func _autogen_defs(m *ice.Message, arg ...string) {
kit.For(arg, func(p string) { m.Cmd(nfs.DEFS, p, m.Cmdx(nfs.CAT, p)); ReposAddFile(m, "", p) })
}
func _autogen_import(m *ice.Message, main string, ctx string, mod string) {
func _autogen_import(m *ice.Message, main string, ctx string, mod string) string {
m.Cmd(nfs.DEFS, ice.ETC_MISS_SH, m.Template("miss.sh"))
_autogen_defs(m, ice.README_MD, ice.MAKEFILE, ice.LICENSE)
// _autogen_defs(m, ice.README_MD, ice.MAKEFILE, ice.LICENSE)
_autogen_defs(m, ice.SRC_MAIN_GO, ice.ETC_MISS_SH, ice.README_MD, ice.MAKEFILE, ice.LICENSE)
begin, done, list := false, false, []string{}
imports := kit.Format(`_ "%s/src/%s"`, mod, ctx)
if mod == "shylinux.com/x/ice" {
imports = kit.Format(`_ "%s/%s"`, mod, ctx)
}
m.Cmd(nfs.CAT, main, func(line string, index int) {
if strings.HasSuffix(line, imports) {
done = true
@ -66,6 +70,7 @@ func _autogen_import(m *ice.Message, main string, ctx string, mod string) {
m.Cmd(nfs.SAVE, main, kit.Join(list, lex.NL))
GoImports(m, main)
ReposAddFile(m, "", main)
return path.Join(mod, "src", ctx)
}
func _autogen_version(m *ice.Message) string {
if mod := _autogen_mod(m, ice.GO_MOD); !nfs.Exists(m, ".git") {
@ -93,9 +98,17 @@ func _autogen_gits(m *ice.Message, arg ...string) string {
}
func _autogen_git(m *ice.Message, arg ...string) ice.Map {
msg := m.Cmd(REPOS, REMOTE)
m.Cmd(MOD, mdb.RENDER, MOD, "go.mod", "./").Table(func(value ice.Maps) {
if value["require"] == "shylinux.com/x/ice" {
msg.Append("release", value["version"])
}
if value["require"] == "shylinux.com/x/icebergs" {
msg.Append("icebergs", value["version"])
}
})
return kit.Dict(arg, aaa.USERNAME, m.Option(ice.MSG_USERNAME), tcp.HOSTNAME, ice.Info.Hostname, nfs.PATH, kit.Path("")+nfs.PS, mdb.TIME, m.Time(),
GIT, GitVersion(m), GO, GoVersion(m), nfs.MODULE, _autogen_mod(m, ice.GO_MOD),
msg.AppendSimple("remote,branch,version,forword,author,email,hash,when,message"),
msg.AppendSimple("remote,branch,version,forword,author,email,hash,when,message,release,icebergs"),
web.DOMAIN, m.Spawn(kit.Dict(ice.MSG_USERWEB, web.UserHost(m), ice.MSG_USERPOD, m.Option(ice.MSG_USERPOD))).MergePod(""),
cli.SYSTEM, ice.Info.System,
)
@ -158,6 +171,11 @@ func init() {
m.Cmd(nfs.DEFS, ice.ETC_MISS_SH, m.Cmdx(nfs.CAT, ice.ETC_MISS_SH))
m.Cmdy(nfs.DIR, ice.ETC_MISS_SH).Cmdy(nfs.CAT, ice.ETC_MISS_SH)
}},
nfs.REPOS: {Help: "仓库", Hand: func(m *ice.Message, arg ...string) {
_autogen_defs(m, ice.SRC_MAIN_GO, ice.SRC_MAIN_SHY, ice.ETC_MISS_SH, ice.README_MD, ice.MAKEFILE, ice.LICENSE)
_autogen_mod(m, ice.GO_MOD)
ReposAddFile(m, "", ice.GO_MOD)
}},
nfs.MODULE: {Name: "module name*=hi help type*=Hash,Zone,Data,Lang,Code main*=main.go@key zone top", Help: "模块", Hand: func(m *ice.Message, arg ...string) {
if m.WarnNotFound(!nfs.Exists(m, kit.Path(".git")), "未初始化代码库") {
return
@ -179,19 +197,25 @@ func init() {
}
}},
DEVPACK: {Help: "开发", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(WEBPACK, mdb.REMOVE)
if ice.Info.NodeType == web.SERVER {
m.Cmd(web.DREAM, nfs.GOWORK)
if m.Cmdy(WEBPACK, mdb.REMOVE); ice.Info.NodeType == web.SERVER {
m.Cmdy(web.DREAM, nfs.GOWORK)
}
}},
WEBPACK: {Help: "打包", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(WEBPACK, mdb.CREATE)
if ice.Info.NodeType == web.SERVER {
if m.Cmdy(WEBPACK, mdb.CREATE); ice.Info.NodeType == web.SERVER {
nfs.Trash(m, ice.GO_WORK_SUM)
nfs.Trash(m, ice.GO_WORK)
}
}},
IMPORT: {Hand: func(m *ice.Message, arg ...string) {
m.Echo(_autogen_import(m, kit.Select(ice.SRC_MAIN_GO, arg, 2), arg[0], kit.Select(_autogen_mod(m, ice.GO_MOD), arg, 1)))
}},
BINPACK: {Help: "打包", Hand: func(m *ice.Message, arg ...string) {
kit.For([]string{"intshell", "volcanos", "node_modules", "learning", "icons"}, func(p string) {
if _, e := os.Stat("usr/" + p); os.IsNotExist(e) {
m.Cmd("web.code.git.repos", "clone", "https://shylinux.com/x/"+p, p, "usr/"+p+"/")
}
})
const (
USR_RELEASE_CONF_GO = "usr/release/conf.go"
USR_RELEASE_BINPACK_GO = "usr/release/binpack.go"
@ -212,11 +236,11 @@ func init() {
})
}
func isReleaseContexts(m *ice.Message) bool {
return nfs.Exists(m, ice.USR_RELEASE) && nfs.Exists(m, ice.USR_VOLCANOS) && nfs.Exists(m, ice.USR_INTSHELL) && ice.Info.Make.Module == "shylinux.com/x/contexts"
return ice.Info.Make.Module == "shylinux.com/x/ContextOS" && nfs.Exists(m, ice.USR_RELEASE) && nfs.Exists(m, ice.USR_VOLCANOS) && nfs.Exists(m, ice.USR_INTSHELL)
}
func AutogenMod(m *ice.Message) string {
return _autogen_mod(m, ice.GO_MOD)
}
func AutogenImport(m *ice.Message, zone string) {
_autogen_import(m, ice.SRC_MAIN_GO, zone, _autogen_mod(m, ice.GO_MOD))
func AutogenImport(m *ice.Message, zone string) string {
return _autogen_import(m, ice.SRC_MAIN_GO, zone, _autogen_mod(m, ice.GO_MOD))
}

View File

@ -24,7 +24,7 @@ func _binpack_file(m *ice.Message, files map[string]bool, w io.Writer, arg ...st
return
} else if kit.Contains(arg[0], "/bin/", "/log/") {
return
} else if kit.HasPrefix(arg[0], "usr/volcanos/publish/", "etc/conf/cert/") && !strings.HasSuffix(arg[0], "/proto.js") {
} else if kit.HasPrefix(arg[0], "usr/volcanos/publish/", "etc/conf/cert/", "src/private/") && !strings.HasSuffix(arg[0], "/proto.js") {
return
}
switch arg[0] {

View File

@ -1,7 +1,6 @@
package code
import (
"os"
"path"
"runtime"
"strings"
@ -88,7 +87,7 @@ const COMPILE = "compile"
func init() {
Index.MergeCommands(ice.Commands{
COMPILE: {Name: "compile arch=amd64,386,arm,arm64,mipsle os=linux,darwin,windows file=src/main.go@key run binpack webpack devpack install", Help: "构建", Icon: "go.png", Actions: ice.MergeActions(ice.Actions{
COMPILE: {Name: "compile arch=amd64,386,arm,arm64,aarch64,mipsle os=linux,darwin,windows file=src/main.go@key run binpack webpack devpack install", Help: "构建", Icon: "go.png", Actions: ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { cli.IsAlpine(m, GO, "go git") }},
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {
switch arg[0] {
@ -107,29 +106,28 @@ func init() {
m.Cmdy(INSTALL, web.DOWNLOAD, kit.Format("%s/go%s.%s-%s.%s", m.Option(SERVICE), m.Option(VERSION), runtime.GOOS, runtime.GOARCH, kit.Select("tar.gz", "zip", runtime.GOOS == cli.WINDOWS)), ice.USR_LOCAL)
}},
web.DREAM_TABLES: {Hand: func(m *ice.Message, arg ...string) {
kit.If(m.IsDebug() && aaa.IsTechOrRoot(m) && m.Option(mdb.TYPE) == web.WORKER && nfs.Exists(m, path.Join(ice.USR_LOCAL_WORK, m.Option(mdb.NAME), ice.SRC_MAIN_GO)), func() {
// kit.If(m.IsDebug() && aaa.IsTechOrRoot(m) && m.Option(mdb.TYPE) == web.WORKER && nfs.Exists(m, path.Join(ice.USR_LOCAL_WORK, m.Option(mdb.NAME), ice.SRC_MAIN_GO)), func() {
kit.If(m.IsDebug() && aaa.IsTechOrRoot(m), func() {
kit.If(cli.SystemFindGo(m), func() { m.PushButton(kit.Dict(m.CommandKey(), m.Commands("").Help)) })
})
}},
}, web.DreamTablesAction(), ctx.ConfAction(cli.ENV, kit.Dict(GOPRIVATE, "shylinux.com,github.com", GOPROXY, "https://goproxy.cn,direct", CGO_ENABLED, "0"))), Hand: func(m *ice.Message, arg ...string) {
main, file, goos, arch := _compile_target(m, arg...)
defer web.ToastProcess(m, file)()
env := kit.Simple(cli.PATH, cli.BinPath(), cli.HOME, kit.Select(kit.Path(""), kit.Env(cli.HOME)), mdb.Configv(m, cli.ENV), m.Optionv(cli.ENV), cli.GOOS, goos, cli.GOARCH, arch)
kit.If(runtime.GOOS == cli.WINDOWS, func() { env = append(env, GOPATH, kit.HomePath(GO), GOCACHE, kit.HomePath("go/go-build")) })
m.Options(cli.CMD_ENV, env).Cmd(AUTOGEN, VERSION)
_compile_get(m, main)
defer m.StatusTime(VERSION, strings.TrimPrefix(GoVersion(m), "go version"))
args := []string{main, ice.SRC_VERSION_GO, ice.SRC_BINPACK_GO, ice.SRC_BINPACK_USR_GO}
if _, e := os.Stat("src/option.go"); e == nil {
args = append(args, "src/option.go")
}
args := []string{main, ice.SRC_VERSION_GO}
nfs.Exists(m, "src/option.go", func(p string) { args = append(args, p) })
kit.If(file != ice.BIN_ICE_BIN, func() { args = append(args, ice.SRC_BINPACK_GO, ice.SRC_BINPACK_USR_GO) })
if msg := GoBuild(m.Spawn(), file, args...); !cli.IsSuccess(msg) {
m.Copy(msg)
} else {
m.Logs(nfs.SAVE, nfs.TARGET, file, nfs.SOURCE, main)
m.Cmdy(nfs.DIR, file, "time,path,size,hash,link")
web.MessageInsertJSON(m, cli.SYSTEM, "", m.Spawn().Copy(m).FormatMeta(), ctx.ARGS, m.Append(mdb.HASH))
kit.If(!m.IsCliUA() && strings.Contains(file, ice.ICE), func() { m.Cmdy(PUBLISH, ice.CONTEXTS, ice.APP) })
kit.If(!m.IsCliUA() && strings.Contains(file, ice.ICE), func() { m.Cmdy(PUBLISH, nfs.CONTEXTS, ice.APP) })
web.Count(m, "", file)
}
}},

View File

@ -0,0 +1,105 @@
package compose
import (
"os"
"path"
"shylinux.com/x/ice"
"shylinux.com/x/icebergs/base/cli"
"shylinux.com/x/icebergs/base/ctx"
"shylinux.com/x/icebergs/base/lex"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
"shylinux.com/x/icebergs/base/tcp"
"shylinux.com/x/icebergs/base/web"
kit "shylinux.com/x/toolkits"
)
type insight struct {
serveStart string `name:"serveStart path* port* repos binary" help:"启动服务" icon:"bi bi-plus-square-dotted"`
loadConfig string `name:"load path*=etc/compose/compose.shy type" help:"加载配置" icon:"bi bi-folder-plus"`
saveConfig string `name:"save path*=etc/compose/compose.shy type" help:"保存配置" icon:"bi bi-floppy"`
list string `name:"list list" help:"云游"`
}
func (s insight) Inputs(m *ice.Message, arg ...string) {
switch arg[0] {
case nfs.PATH:
m.Cmdy(nfs.DIR, "etc/compose/", arg[0])
case mdb.TYPE:
m.Push(arg[0], "local", "cluster", "docker", "kubectl")
}
}
func (s insight) ServeStart(m *ice.Message, arg ...string) {
pwd, _ := os.Getwd()
dir := path.Join(path.Dir(pwd), m.Option(nfs.PATH))
bin := path.Join(dir, ice.BIN_ICE_BIN)
if m.Echo(bin); bin == os.Args[0] {
return
}
if !nfs.Exists(m.Message, dir) {
m.Cmd(cli.SYSTEM, cli.GIT, "clone", m.OptionDefault(nfs.REPOS, ice.Info.Make.Remote), dir)
}
if !nfs.Exists(m.Message, bin) {
nfs.MkdirAll(m.Message, path.Dir(bin))
m.Cmd(cli.SYSTEM, cli.CP, os.Args[0], bin)
}
m.Info("serve start %v", bin)
m.Cmd(cli.DAEMON, bin, cli.FOREVER, cli.START, ice.DEV, m.Option(ice.MSG_USERHOST), tcp.NODENAME, path.Base(dir), m.OptionSimple(tcp.PORT), arg[4:], kit.Dict(cli.CMD_DIR, dir))
m.WaitEvent(web.OPS_SERVER_OPEN, func(msg *ice.Message, arg ...string) bool { return msg.Option(mdb.NAME) == path.Base(dir) })
}
func (s insight) LoadConfig(m *ice.Message, arg ...string) {
bin := ""
defer m.ToastProcess()()
cache := map[string][]string{}
m.Cmd(lex.SPLIT, m.Option(nfs.PATH), func(deep int, ls []string) {
switch deep {
case 1:
m.ToastProcess(ls[0] + " 服务启动中...")
bin = m.Cmdx("", s.ServeStart, nfs.PATH, ls[0], tcp.PORT, ls[1], cache["serve"], ls[2:])
cache["serve"] = append(cache["serve"], ls[2:]...)
case 2:
m.Info("dream start %v", bin)
m.Cmd(cli.SYSTEM, bin, web.ADMIN, web.DREAM, mdb.CREATE, "--", mdb.NAME, ls[0], cache[ls[0]], ls[1:], kit.Dict(cli.CMD_DIR, path.Dir(path.Dir(bin))))
// cache[ls[0]] = ls[1:]
cache[ls[0]] = append(cache[ls[0]], ls[1:]...)
}
})
}
func (s insight) SaveConfig(m *ice.Message, arg ...string) {
m.Cmd(nfs.SAVE, m.Option(nfs.PATH), kit.Format("%s %s username %q usernick %q language %q avatar %q\n", path.Base(kit.Pwd()), m.Option(tcp.PORT),
m.Option(ice.MSG_USERNAME), m.Option(ice.MSG_USERNICK), m.Option(ice.MSG_LANGUAGE), m.Option(ice.MSG_AVATAR)))
m.Cmd(web.DREAM).Table(func(value ice.Maps) {
if value[mdb.TYPE] == web.WORKER {
m.Cmd(nfs.PUSH, m.Option(nfs.PATH), kit.Format(" %s repos %q binary %q\n", value[mdb.NAME], value[nfs.REPOS], value[nfs.BINARY]))
}
if value[mdb.TYPE] == web.SERVER {
msg := m.Cmd(web.SPACE, value[mdb.NAME], web.SERVE)
m.Cmd(nfs.PUSH, m.Option(nfs.PATH), kit.Format("%s %s repos %q binary %q\n", value[mdb.NAME], msg.Append(tcp.PORT), value[nfs.REPOS], value[nfs.BINARY]))
m.Cmd(web.SPACE, value[mdb.NAME], web.DREAM).Table(func(value ice.Maps) {
if value[mdb.TYPE] == web.WORKER {
m.Cmd(nfs.PUSH, m.Option(nfs.PATH), kit.Format(" %s repos %q binary %q\n", value[mdb.NAME], value[nfs.REPOS], value[nfs.BINARY]))
}
})
}
})
}
func (s insight) List(m *ice.Message, arg ...string) {
if len(arg) == 0 {
m.Cmd(web.SPACE).Table(func(value ice.Maps) {
if value[mdb.TYPE] == web.SERVER {
m.PushRecord(value, mdb.NAME, mdb.ICONS, nfs.MODULE, nfs.VERSION)
}
})
m.Action(s.ServeStart, s.LoadConfig, s.SaveConfig)
m.Display("/plugin/story/spides.js?split=.").Option(nfs.DIR_ROOT, ice.Info.NodeName)
kit.If(m.Length() == 0, func() { m.EchoInfoButton("请加载配置创建集群", s.LoadConfig) })
} else {
m.Cmdy(web.SPACE, arg[0], m.PrefixKey()).Table(func(value ice.Maps) {
m.Push(nfs.FILE, kit.Keys(arg[0], value[mdb.NAME]))
})
kit.If(m.Length() == 0, func() { m.Push(web.SPACE, arg[0]).Push(ctx.INDEX, web.DESKTOP) })
}
}
func init() { ice.Cmd("web.code.compose.insight", insight{}) }

View File

@ -22,6 +22,11 @@ func _css_show(m *ice.Message, arg ...string) {
m.EchoIFrame(m.MergePodCmd("", web.ADMIN))
return
}
cmd := kit.Select(ice.CAN_PLUGIN, ctx.GetFileCmd(kit.ExtChange(path.Join(arg[2], arg[1]), GO)))
ctx.DisplayBaseCSS(m, require(arg[2], arg[1]), "render", "replace", ctx.INDEX, cmd, ice.POD, m.Option(ice.MSG_USERPOD))
ctx.DisplayBase(m, require(arg[2], arg[1]))
ctx.ProcessField(m, cmd, kit.Simple())
return
zone, stats_key, stats_value := "", map[string]int{}, map[string]int{}
m.Cmd(nfs.CAT, path.Join(arg[2], arg[1]), func(line string) {
if line = strings.TrimSpace(line); line == "" || strings.HasPrefix(line, "//") || strings.HasPrefix(line, "/*") {
@ -74,9 +79,7 @@ func init() {
CSS: {Actions: ice.MergeActions(ice.Actions{
mdb.RENDER: {Hand: func(m *ice.Message, arg ...string) { _css_show(m, arg...) }},
mdb.ENGINE: {Hand: func(m *ice.Message, arg ...string) { _css_exec(m, arg...) }},
TEMPLATE: {Hand: func(m *ice.Message, arg ...string) {
m.Echo(kit.Format(nfs.Template(m, DEMO_CSS), kit.Select(mdb.PLUGIN, ctx.GetFileCmd(kit.ExtChange(path.Join(arg[2], arg[1]), GO)))))
}},
TEMPLATE: {Hand: func(m *ice.Message, arg ...string) { m.Echo(nfs.Template(m, DEMO_CSS)) }},
}, PlugAction())},
})
}

View File

@ -68,7 +68,32 @@ func _go_show(m *ice.Message, arg ...string) {
ctx.ProcessField(m, cli.RUNTIME, kit.Simple())
} else if arg[1] == "binpack.go" {
ctx.ProcessField(m, nfs.PACK, kit.Simple())
} else if path.Base(arg[1]) == "model.go" {
ctx.ProcessField(m, "web.code.mysql.query", kit.Simple("mysql", kit.Split(arg[1], "/", "/")[0]))
} else if path.Base(arg[1]) == "common.go" {
// ctx.ProcessField(m, "web.code.xterm", kit.Simple())
ctx.ProcessField(m, "log.debug", kit.Simple("bench"))
} else if cmd := ctx.GetFileCmd(path.Join(arg[2], arg[1])); cmd != "" {
if p := path.Join(arg[2], strings.Split(arg[1], "/")[0], "portal.go"); path.Base(arg[1]) != "portal.go" &&
!kit.IsIn(arg[1],
"gonganxitong/user.go",
"gonganxitong/sess.go",
"gonganxitong/grant.go",
"gonganxitong/domain.go",
"gonganxitong/command.go",
"gonganxitong/quotalist.go",
"operation/studio.go",
) && nfs.Exists(m, p) {
if cmd := ctx.GetFileCmd(p); cmd != "" {
if m.ActionKey() == mdb.RENDER {
ctx.ProcessField(m, cmd, kit.Simple())
} else {
ls := kit.Split(strings.TrimSuffix(arg[1], ".go"), "/")
ctx.ProcessField(m, "web.code.mysql.query", kit.Simple("mysql", ls[0], TableName(kit.Select("", ls, -1))))
}
return
}
}
ctx.ProcessField(m, cmd, kit.Simple())
} else if msg := m.Cmd(yac.STACK, path.Join(arg[2], arg[1])); msg.Option("__index") != "" {
ctx.ProcessField(m, msg.Option("__index"), kit.Simple())
@ -198,3 +223,20 @@ func GoVersion(m *ice.Message) string { return m.Cmdx(cli.SYSTEM, GO, VERSION
func GoBuild(m *ice.Message, target string, arg ...string) *ice.Message {
return m.Cmdy(cli.SYSTEM, GO, cli.BUILD, "-ldflags", "-w -s", "-o", target, arg)
}
func TableName(model string) string {
if strings.Contains("0123456789", model[len(model)-1:]) {
return model
}
if kit.IsIn(model, "sms", "equipment") {
} else if kit.HasSuffix(model, "y") && !kit.HasSuffix(model, "way") {
model = model[:len(model)-1] + "ies"
} else if kit.HasSuffix(model, "s") {
if !kit.HasSuffix(model, "os") {
model = model + "es"
}
} else {
model = model + "s"
}
return model
}

View File

@ -75,7 +75,7 @@ const INNER = "inner"
func init() {
Index.MergeCommands(ice.Commands{
INNER: {Name: "inner path=src/ file=main.go line=1 auto", Help: "源代码", Role: aaa.VOID, Actions: ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
ice.AFTER_INIT: {Hand: func(m *ice.Message, arg ...string) {
web.AddPortalProduct(m, "编辑器", `
一款网页版的编辑器打开网页即可随时随地的编程
无论这些代码是保存在本机还是远程还是任何虚拟的空间无论是内存还是磁盘

View File

@ -22,6 +22,14 @@ func _js_show(m *ice.Message, arg ...string) {
ctx.ProcessField(m, kit.Select(ice.CAN_PLUGIN, "web."+strings.Replace(strings.TrimSuffix(strings.TrimPrefix(arg[1], "plugin/local/"), nfs.PT+JS), nfs.PS, nfs.PT, -1)), nil)
}
} else {
if p := path.Join(arg[2], strings.Split(arg[1], "/")[0], "portal.go"); !kit.IsIn(arg[1],
"operation/studio.js",
) && nfs.Exists(m, p) {
if cmd := ctx.GetFileCmd(p); cmd != "" {
ctx.ProcessField(m, cmd, kit.Simple())
return
}
}
ctx.DisplayBase(m, require(arg[2], arg[1]))
ctx.ProcessField(m, kit.Select(ice.CAN_PLUGIN, ctx.GetFileCmd(kit.ExtChange(path.Join(arg[2], arg[1]), GO))), kit.Simple())
}

View File

@ -1,7 +1,10 @@
package code
import (
"path"
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/ctx"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
kit "shylinux.com/x/toolkits"
@ -16,8 +19,22 @@ const JSON = "json"
func init() {
Index.MergeCommands(ice.Commands{
JSON: {Actions: ice.MergeActions(ice.Actions{
mdb.RENDER: {Hand: func(m *ice.Message, arg ...string) {}},
mdb.ENGINE: {Hand: func(m *ice.Message, arg ...string) {}},
mdb.RENDER: {Hand: func(m *ice.Message, arg ...string) {
if path.Base(arg[1]) == "portal.json" {
if cmd := ctx.GetFileCmd(path.Join(arg[2], arg[1])); cmd != "" {
ctx.ProcessField(m, cmd, kit.Simple("table"))
return
}
}
m.FieldsSetDetail()
kit.For(kit.KeyValue(nil, "", kit.UnMarshal(m.Cmdx(nfs.CAT, path.Join(arg[2], arg[1])))), func(key, value string) {
m.Push(key, value)
})
}},
mdb.ENGINE: {Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(nfs.CAT, path.Join(arg[2], arg[1]))
ctx.DisplayStoryJSON(m)
}},
TEMPLATE: {Hand: func(m *ice.Message, arg ...string) {
m.Echo(kit.Format(nfs.Template(m, DEMO_JSON)))
}},

View File

@ -63,15 +63,16 @@ func _publish_contexts(m *ice.Message, arg ...string) {
// fallthrough
case nfs.BINARY, ice.APP:
if host := msg.Append(tcp.HOSTPORT); !strings.HasPrefix(host, m.Option(web.DOMAIN)) {
env = append(env, cli.CTX_DEV_IP, strings.Split(host, "?")[0])
// env = append(env, cli.CTX_DEV_IP, strings.Split(host, "?")[0])
}
if m.Option(ice.MSG_USERPOD) != "" {
env = append(env, cli.CTX_POD, m.Option(ice.MSG_USERPOD))
} else if name := msg.Append(nfs.PATHNAME); !kit.IsIn(name, path.Base(m.Option(nfs.SOURCE)), ice.CONTEXTS) {
} else if name := msg.Append(nfs.PATHNAME); !kit.IsIn(name, path.Base(m.Option(nfs.SOURCE))) {
env = append(env, cli.CTX_NAME, name)
}
case cli.CURL, cli.WGET:
}
env = append(env, kit.Simple(m.Optionv(cli.CTX_ENV))...)
kit.If(len(env) > 0, func() { m.Options(cli.CTX_ENV, lex.SP+kit.JoinKV(mdb.EQ, lex.SP, env...)) })
if template := strings.TrimSpace(nfs.Template(m, kit.Keys(k, SH))); m.Option(nfs.FORMAT) == "raw" {
m.Echo(template)
@ -93,9 +94,9 @@ func init() {
Index.MergeCommands(ice.Commands{
PUBLISH: {Name: "publish path auto create volcanos icebergs intshell", Help: "发布", Icon: "QuickTime Player.png", Role: aaa.VOID, Actions: ice.MergeActions(ice.Actions{
ice.VOLCANOS: {Help: "火山架", Hand: func(m *ice.Message, arg ...string) { _publish_list(m, kit.ExtReg(HTML, CSS, JS)) }},
ice.ICEBERGS: {Help: "冰山架", Hand: func(m *ice.Message, arg ...string) { _publish_bin_list(m).Cmdy("", ice.CONTEXTS) }},
ice.ICEBERGS: {Help: "冰山架", Hand: func(m *ice.Message, arg ...string) { _publish_bin_list(m).Cmdy("", nfs.CONTEXTS) }},
ice.INTSHELL: {Help: "神农架", Hand: func(m *ice.Message, arg ...string) { _publish_list(m, kit.ExtReg(SH, VIM, CONF)) }},
ice.CONTEXTS: {Hand: func(m *ice.Message, arg ...string) { _publish_contexts(m, arg...) }},
nfs.CONTEXTS: {Hand: func(m *ice.Message, arg ...string) { _publish_contexts(m, arg...) }},
nfs.SOURCE: {Hand: func(m *ice.Message, arg ...string) { _publish_contexts(m, nfs.SOURCE) }},
nfs.BINARY: {Hand: func(m *ice.Message, arg ...string) { _publish_contexts(m, nfs.BINARY) }},
cli.CURL: {Hand: func(m *ice.Message, arg ...string) { _publish_contexts(m, cli.CURL) }},
@ -110,13 +111,18 @@ func init() {
)
}},
nfs.VERSION: {Hand: func(m *ice.Message, arg ...string) {
defer m.Echo("<table>").Echo("</table>")
kit.For([]string{cli.AMD64, cli.X86, cli.ARM}, func(cpu string) {
defer m.Echo("<tr>").Echo("</tr>")
echo := func(p string) func() { m.Echo("<" + p + ">"); return func() { m.Echo("</" + p + ">") } }
defer echo("table")()
kit.For([]string{cli.AMD64, cli.X86, cli.ARM, cli.ARM64}, func(cpu string) {
defer echo("tr")()
kit.For([]string{cli.LINUX, cli.WINDOWS, cli.DARWIN}, func(sys string) {
defer m.Echo("<td>").Echo("</td>")
defer echo("td")()
if file := fmt.Sprintf("ice.%s.%s", sys, cpu); nfs.Exists(m, ice.USR_PUBLISH+file) {
m.EchoAnchor(file, "/publish/"+file)
if sys == cli.WINDOWS {
m.EchoAnchor(file, "/publish/"+file+"?filename=ice.exe")
} else {
m.EchoAnchor(file, "/publish/"+file)
}
}
})
})
@ -126,7 +132,7 @@ func init() {
nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) { nfs.Trash(m, path.Join(ice.USR_PUBLISH, m.Option(nfs.PATH))) }},
}, ctx.ConfAction(mdb.FIELD, nfs.PATH)), Hand: func(m *ice.Message, arg ...string) {
if m.Option(nfs.DIR_ROOT, ice.USR_PUBLISH); len(arg) == 0 {
_publish_list(m).Cmdy("", ice.CONTEXTS, ice.APP)
_publish_list(m).Cmdy("", nfs.CONTEXTS, ice.APP)
} else {
m.Cmdy(nfs.DIR, arg[0], "time,path,size,hash,link,action", ice.OptionFields(mdb.DETAIL))
web.PushImages(m, web.P(PUBLISH, arg[0]))

View File

@ -0,0 +1,43 @@
package publish
import (
"path"
"shylinux.com/x/ice"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
"shylinux.com/x/icebergs/base/tcp"
"shylinux.com/x/icebergs/base/web"
)
type client struct {
create string `name:"create origin* name icons"`
list string `name:"list list" help:"软件包"`
}
func (s client) Create(m *ice.Message, arg ...string) {
m.Cmd(web.SPIDE, mdb.CREATE, m.OptionSimple("origin,name,icons"), mdb.TYPE, nfs.REPOS)
}
func (s client) List(m *ice.Message, arg ...string) {
if len(arg) == 0 {
m.Cmd(web.SPIDE).Table(func(value ice.Maps) {
if value[web.CLIENT_TYPE] == nfs.REPOS {
m.PushRecord(value, mdb.ICONS, web.CLIENT_NAME)
}
})
m.Action(s.Create).SortStrR(web.CLIENT_NAME).Display("")
} else {
m.SplitIndex(m.Cmdx(web.SPIDE, arg[0], web.C(m.Prefix(tcp.SERVER)))).PushAction(s.Download)
}
}
func (s client) Download(m *ice.Message, arg ...string) {
web.GoToast(m.Message, func(toast func(string, int, int)) (res []string) {
name := path.Base(m.Option(nfs.PATH))
m.Cmd(web.SPIDE, m.Option(web.CLIENT_NAME), web.SPIDE_SAVE, nfs.USR_PUBLISH+name, "/publish/"+name, func(count, total, value int) {
toast(name, count, total)
})
return nil
})
}
func init() { ice.Cmd("web.code.publish.client", client{}) }

View File

@ -0,0 +1,19 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg) { can.ui = can.onappend.layout(can)
msg.Table(function(value) {
can.onimport.item(can, {name: value[web.CLIENT_NAME], icons: value.icons}, function(event, item, show, target) { can.db.client_name = item.name
can.onimport.tabsCache(can, item, target, function(event) {
can.run(event, [item.name], function(msg) {
can.onappend.table(can, msg, null, can.ui.content), can.onappend._status(can, msg)
})
})
})
})
},
})
Volcanos(chat.ONACTION, {
download: function(event, can) {
var msg = can.request(event); msg.Option(web.CLIENT_NAME, can.db.client_name)
can.runAction(event, web.DOWNLOAD)
},
})

View File

@ -0,0 +1,51 @@
package publish
import (
"shylinux.com/x/ice"
"shylinux.com/x/icebergs/base/cli"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
"shylinux.com/x/icebergs/core/code"
)
type server struct {
ice.Hash
short string `data:"name"`
field string `data:"time,name*,text,path,version*,compile,runtime,os,cpu"`
list string `name:"list name auto" help:"软件源" role:"void"`
}
func (s server) Inputs(m *ice.Message, arg ...string) {
switch arg[0] {
case nfs.PATH:
m.Cmdy(nfs.DIR, nfs.USR_PUBLISH, nfs.PATH)
case code.COMPILE:
m.Push(arg[0], "go")
m.Push(arg[0], "javac")
case cli.RUNTIME:
m.Push(arg[0], "python")
m.Push(arg[0], "java")
m.Push(arg[0], "php")
case cli.OS:
m.Push(arg[0], "Linux")
m.Push(arg[0], "macOS")
m.Push(arg[0], "Windows")
case cli.CPU:
m.Push(arg[0], "amd64")
m.Push(arg[0], "x86")
m.Push(arg[0], "arm")
m.Push(arg[0], "arm64")
default:
s.Hash.Inputs(m, arg...)
}
}
func (s server) Upload(m *ice.Message, arg ...string) {
s.Modify(m, mdb.NAME, m.Option(mdb.NAME), nfs.PATH, m.UploadSave(nfs.USR_PUBLISH))
}
func (s server) List(m *ice.Message, arg ...string) {
if s.Hash.List(m, arg...); m.IsTech() {
m.PushAction(s.Detail, s.Upload, s.Remove)
}
}
func init() { ice.Cmd("web.code.publish.server", server{}) }

View File

@ -0,0 +1,10 @@
{
"icons": {},
"input": {
"compile": "编译器",
"runtime": "运行时",
"os": "操作系统",
"cpu": "芯片架构"
},
"value": {}
}

View File

@ -33,6 +33,7 @@ func init() {
uri := "/publish/" + kit.Format(value[nfs.FILE])
kit.If(m.Spawn().Options(ice.MSG_USERPOD, "").ParseLink(ice.Info.Make.Domain).Option(ice.MSG_USERPOD), func(p string) {
uri = kit.MergeURL(uri, ice.POD, p)
uri = kit.MergeURL2(ice.Info.Make.Domain, uri)
})
dir := path.Join(kit.Format(value[nfs.PATH]), kit.Format(value[nfs.FILE]))
web.GoToast(m, func(toast func(name string, count, total int)) []string {

View File

@ -55,6 +55,13 @@ const VIMER = "vimer"
func init() {
Index.MergeCommands(ice.Commands{
VIMER: {Name: "vimer path=src/ file=main.go line=1 list", Help: "编辑器", Icon: "vimer.png", Role: aaa.VOID, Actions: ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
if ice.Info.CodeMain != "" {
ls := nfs.SplitPath(m, ice.Info.CodeMain)
kit.Value(m.Command().List, "0.value", ls[0])
kit.Value(m.Command().List, "1.value", ls[1])
}
}},
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {
switch m.Option(ctx.ACTION) {
case nfs.MODULE:
@ -114,13 +121,13 @@ func init() {
}
}
}},
nfs.MODULE: {Name: "module name*=hi help type*=Hash,Zone,Code main*=main.go zone top", Help: "创建模块", Hand: func(m *ice.Message, arg ...string) {
nfs.MODULE: {Name: "module name*=hi help type*=Hash,Zone,Code main*=main.go zone*=hi top", Help: "创建模块", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(AUTOGEN, nfs.MODULE, arg)
}},
nfs.SCRIPT: {Name: "script file*", Help: "脚本", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(nfs.DEFS, path.Join(m.Option(nfs.PATH), m.Option(nfs.FILE)), m.Cmdx("", TEMPLATE))
}},
mdb.CREATE: {Name: "create file*", Help: "文件", Icon: "bi bi-file-earmark-text", Hand: func(m *ice.Message, arg ...string) {
mdb.CREATE: {Name: "create file*", Help: "添加文件", Icon: "bi bi-file-earmark-text", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(nfs.DEFS, path.Join(m.Option(nfs.PATH), m.Option(nfs.FILE)), m.Cmdx("", TEMPLATE))
}},
mdb.RENAME: {Name: "rename to*", Hand: func(m *ice.Message, arg ...string) {
@ -164,7 +171,7 @@ func init() {
m.PushButton(kit.Dict(m.CommandKey(), "编程"))
})
}},
}, web.DreamTablesAction("编程"), ctx.ConfAction(ctx.TOOLS, "xterm,compile,runtime", web.ONLINE, ice.TRUE)), Hand: func(m *ice.Message, arg ...string) {
}, web.DreamTablesAction("编程"), ctx.ConfAction(ctx.TOOLS, "xterm,runtime,compile", web.ONLINE, ice.TRUE)), Hand: func(m *ice.Message, arg ...string) {
if m.Cmdy(INNER, arg); arg[0] == ctx.ACTION {
return
} else if len(arg) == 1 {

View File

@ -69,7 +69,7 @@ const XTERM = "xterm"
func init() {
Index.MergeCommands(ice.Commands{
XTERM: {Name: "xterm refresh", Help: "终端", Icon: "Terminal.png", Actions: ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
ice.AFTER_INIT: {Hand: func(m *ice.Message, arg ...string) {
web.AddPortalProduct(m, "命令行", `
一款网页版的命令行打开网页即可随时随地的敲命令
无论这些命令是运行在本机还是远程还是任何虚拟的空间无论是内存还是磁盘

View File

@ -2,7 +2,6 @@ package core
import (
_ "shylinux.com/x/icebergs/core/chat"
_ "shylinux.com/x/icebergs/core/chat/location"
_ "shylinux.com/x/icebergs/core/chat/macos"
_ "shylinux.com/x/icebergs/core/code"
_ "shylinux.com/x/icebergs/core/mall"

View File

@ -4,17 +4,25 @@ import (
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/web"
kit "shylinux.com/x/toolkits"
)
func init() {
const corporation = "corporation"
Index.MergeCommands(ice.Commands{
corporation: {Name: "corporation username auto", Help: "法人", Actions: ice.MergeActions(ice.Actions{}, mdb.ExportHashAction(
mdb.SHORT, "username", mdb.FIELD, "time,username,mobile,idnumber,usci,account,bank,email,portal",
corporation: {Name: "corporation username auto", Help: "法人", Meta: kit.Dict(
"_trans.input", kit.Dict(
"idnumber", "身份证号",
"usci", "统一社会信用代码",
"account", "对公账户",
"bank", "开户银行",
"record", "备案号",
),
), Actions: ice.MergeActions(ice.Actions{}, mdb.ExportHashAction(
mdb.SHORT, "username", mdb.FIELD, "time,username,mobile,idnumber,usci,company,address,bank,account,email,portal,record",
)), Hand: func(m *ice.Message, arg ...string) {
mdb.HashSelect(m, arg...)
mdb.HashSelect(m, arg...).Action(mdb.CREATE)
web.PushPodCmd(m, "", arg...)
m.Action(mdb.CREATE)
}},
})
}

View File

@ -21,6 +21,7 @@ const (
USR_IMAGE = "usr/image/"
USR_COVER = "usr/cover/"
USR_AVATAR = "usr/avatar/"
USR_MATERIAL = "usr/material/"
USR_ICONS = "usr/icons/"
USR_ICONS_AVATAR = "usr/icons/avatar.jpg"
USR_ICONS_BACKGROUND = "usr/icons/background.jpg"
@ -45,7 +46,7 @@ func init() {
}},
web.UPLOAD: {Hand: func(m *ice.Message, arg ...string) {
up := kit.Simple(m.Optionv(ice.MSG_UPLOAD))
m.Cmdy(web.CACHE, web.WATCH, m.Option(mdb.HASH), path.Join(m.Option(nfs.PATH), up[1]))
m.Cmdy(web.CACHE, web.WATCH, up[0], path.Join(m.Option(nfs.PATH), up[1]))
}},
mdb.RENAME: {Name: "rename name*", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(nfs.MOVE, path.Join(path.Dir(m.Option(nfs.PATH)), m.Option(mdb.NAME)), m.Option(nfs.PATH))
@ -85,14 +86,15 @@ func init() {
m.ProcessInner()
}
}},
}, chat.FavorAction(), WikiAction("", "ico|png|PNG|jpg|JPG|jpeg|mp4|m4v|mov|MOV|webm|mp3"), mdb.HashAction(mdb.SHORT, nfs.PATH, mdb.FIELD, "time,path,name,cover")), Hand: func(m *ice.Message, arg ...string) {
}, chat.FavorAction(), WikiAction("", "ico|png|PNG|gif|jpg|JPG|jpeg|mp4|m4v|mov|MOV|webm|mp3"), mdb.HashAction(mdb.SHORT, nfs.PATH, mdb.FIELD, "time,path,name,cover")), Hand: func(m *ice.Message, arg ...string) {
if len(kit.Slice(arg, 0, 1)) == 0 {
if mdb.HashSelect(m); aaa.IsTechOrRoot(m) {
m.Push(nfs.PATH, USR_AVATAR).Push(mdb.NAME, "头像库").Push(COVER, USR_ICONS_AVATAR)
// m.Push(nfs.PATH, USR_AVATAR).Push(mdb.NAME, "头像库").Push(COVER, USR_ICONS_AVATAR)
m.Push(nfs.PATH, USR_LOCAL_IMAGE).Push(mdb.NAME, "私有库").Push(COVER, USR_ICONS_BACKGROUND)
}
m.Push(nfs.PATH, USR_IMAGE).Push(mdb.NAME, "图片库").Push(COVER, USR_ICONS_BACKGROUND)
m.Push(nfs.PATH, USR_COVER).Push(mdb.NAME, "封面库").Push(COVER, USR_ICONS_BACKGROUND)
m.Push(nfs.PATH, USR_MATERIAL).Push(mdb.NAME, "素材库").Push(COVER, SRC_MAIN)
m.Push(nfs.PATH, USR_ICONS).Push(mdb.NAME, "图标库").Push(COVER, SRC_MAIN)
} else {
if _wiki_list(m, kit.Slice(arg, 0, 1)...); arg[0] == USR_ICONS {

View File

@ -21,7 +21,7 @@ func init() {
Index.MergeCommands(ice.Commands{
GEOAREA: {Name: "geoarea path auto", Help: "地区", Actions: ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
m.Cmd(web.SPIDE, mdb.CREATE, "https://geo.datav.aliyun.com/areas_v3/bound/", GEOAREA)
// m.Cmd(web.SPIDE, mdb.CREATE, "https://geo.datav.aliyun.com/areas_v3/bound/", GEOAREA)
}},
nfs.PS: {Hand: func(m *ice.Message, arg ...string) {
p := path.Join(ice.USR_GEOAREA, path.Join(arg...))

View File

@ -2,6 +2,7 @@ package wiki
import (
"path"
"strings"
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/nfs"
@ -19,7 +20,13 @@ const IMAGE = "image"
func init() {
Index.MergeCommands(ice.Commands{
IMAGE: {Name: "image path", Help: "图片", Hand: func(m *ice.Message, arg ...string) {
IMAGE: {Name: "image path", Help: "图片", Actions: ice.Actions{
"material": {Hand: func(m *ice.Message, arg ...string) {
if nfs.Exists(m, nfs.USR_MATERIAL) {
m.Cmdy(IMAGE, path.Join(nfs.USR_MATERIAL, strings.TrimPrefix(path.Dir(m.Option("_script")), nfs.USR), arg[0]))
}
}},
}, Hand: func(m *ice.Message, arg ...string) {
arg = _name(m, arg)
_image_show(m, arg[0], arg[1], arg[2:]...)
}},

View File

@ -2,56 +2,60 @@ fieldset.web.wiki.portal { --portal-max-width:1200px; --portal-header-height:64p
fieldset.web.wiki.portal.home { --portal-max-width:1500px; }
fieldset.web.wiki.portal>div.header { display:none; }
fieldset.web.wiki.portal>div.output { padding:0; }
fieldset.web.wiki.portal>div.output>div.header { background-color:rgb(22 31 49); height:var(--portal-header-height); --hover-bg-color:var(--plugin-bg-color); }
fieldset.web.wiki.portal>div.output>div.header { background-color:var(--panel-bg-color); height:var(--portal-header-height); --hover-bg-color:var(--plugin-bg-color); }
fieldset.web.wiki.portal>div.output>div.header div.list { display:flex; }
fieldset.web.wiki.portal>div.output>div.header div.story[data-name=navmenu] { --hover-fg-color:white; }
fieldset.web.wiki.portal>div.output>div.header div.story div.item span { white-space:pre; overflow:hidden; }
fieldset.web.wiki.portal>div.output>div.header div.story[data-name=navmenu] { display:flex; justify-content:center; }
fieldset.web.wiki.portal>div.output>div.header div.story[data-name=navmenu] div.item { text-align:center; padding:var(--legend-padding); height:var(--portal-header-height); }
fieldset.web.wiki.portal>div.output>div.header div.story[data-name=navmenu] div.item { display:flex; align-items:center; }
fieldset.web.wiki.portal>div.output>div.header div.story[data-name=navmenu] div.item:first-child { padding:var(--input-padding); }
fieldset.web.wiki.portal>div.output>div.header div.story[data-name=navmenu] div.item:first-child { line-height:calc(var(--portal-header-height) - 2 * var(--legend-padding)); font-size:24px; font-weight:bold; font-style:italic; }
body.mobile fieldset.web.wiki.portal>div.output>div.header div.story[data-name=navmenu] div.item:first-child span { display:none; font-size:18px; max-width:160px; }
fieldset.web.wiki.portal>div.output>div.header div.story[data-name=navmenu] div.item:first-child { line-height:calc(var(--portal-header-height) - 2 * var(--legend-padding)); font-size:24px; font-weight:bold; }
fieldset.web.wiki.portal>div.output>div.header div.story[data-name=navmenu] div.item:first-child img { margin-right:var(--button-margin); }
fieldset.web.wiki.portal>div.output>div.header div.story[data-name=navmenu] div.item.select { background-color:var(--output-bg-color); }
fieldset.web.wiki.portal>div.output>div.header div.story[data-name=navmenu] div.item:hover { background-color:var(--output-bg-color); }
fieldset.web.wiki.portal>div.output>div.header div.story[data-name=navmenu] div.item.space { padding:0px; margin:0 var(--portal-main-padding); }
fieldset.web.wiki.portal>div.output>div.layout { display:flex; justify-content:center; }
fieldset.web.wiki.portal>div.output>div.layout table.story.content { background-color:var(--output-bg-color); }
fieldset.web.wiki.portal>div.output>div.layout table.story.content th { text-align:left; padding:var(--table-padding); }
fieldset.web.wiki.portal>div.output>div.layout>div.nav { border-right:var(--box-border); padding:var(--portal-main-padding); padding-right:var(--button-padding); min-width:var(--project-width); overflow:auto; }
fieldset.web.wiki.portal>div.output>div.layout>div.nav div.story[data-name=navmenu] div.item { padding:var(--input-padding); }
fieldset.web.wiki.portal>div.output>div.layout>div.nav div.story[data-name=navmenu] div.item.select { border-right:var(--box-notice); }
fieldset.web.wiki.portal>div.output>div.layout>div.nav div.story[data-name=navmenu]>div.item { border-bottom:var(--box-border); margin-top:var(--button-margin); }
fieldset.web.wiki.portal>div.output>div.layout>div.nav div.story[data-name=navmenu] div.list { padding-left:var(--legend-padding); }
fieldset.web.wiki.portal>div.output>div.layout>div.aside { padding:var(--portal-main-padding); padding-left:var(--button-padding); min-width:var(--project-width); overflow:auto; }
fieldset.web.wiki.portal>div.output>div.layout>div.aside div.item { padding:var(--input-padding); }
fieldset.web.wiki.portal>div.output>div.layout>div.aside div.item.select { border-left:var(--box-notice); }
fieldset.web.wiki.portal>div.output>div.layout>div.aside div.item.section { padding-left:var(--legend-padding); }
fieldset.web.wiki.portal>div.output>div.layout>div.main { padding:var(--portal-main-padding); height:600px; min-width:390px; max-width:var(--portal-max-width); overflow:auto; overflow-x:hidden; }
fieldset.web.wiki.portal>div.output>div.layout>div.main div.story.column { display:flex; flex-direction:column; justify-content:center; }
fieldset.web.wiki.portal>div.output>div.layout>div.main div.story.column fieldset.inner>div.output>div.layout>div.layout div.content div.tips { top:5px; right:10px; }
fieldset.web.wiki.portal>div.output>div.layout>div.main div.story.column h1 { font-size:48px; font-style:italic; margin-top:0; }
fieldset.web.wiki.portal>div.output>div.layout>div.main div.story.column h1 { font-size:24px; font-style:italic; margin-top:0; }
body.mobile fieldset.web.wiki.portal>div.output>div.layout>div.main div.story.column h2 { font-size:18px; }
body:not(.mobile) fieldset.web.wiki.portal>div.output>div.layout>div.main div.story.column h1 { font-size:32px; }
fieldset.web.wiki.portal>div.output>div.layout>div.main div.story.column h2 { margin:0 !important; }
fieldset.web.wiki.portal>div.output>div.layout>div.main img[data-name="qrcode"] { margin-top:20px; width:240px !important; }
fieldset.web.wiki.portal>div.output>div.layout>div.main div.story.column li { margin:10px 0; }
fieldset.web.wiki.portal>div.output>div.layout>div.main div.story.column ul { margin:10px; }
fieldset.web.wiki.portal>div.output>div.layout>div.main div.story.column b { font-size:22px; }
fieldset.web.wiki.portal>div.output>div.layout>div.main div.story.column input[type=button] { box-shadow:var(--th-box-shadow); border:0; background-color:var(--notice-bg-color); color:var(--notice-fg-color); }
fieldset.web.wiki.portal>div.output>div.layout>div.main div.story.column input[type=button]:hover { box-shadow:var(--notice-box-shadow); }
fieldset.web.wiki.portal>div.output>div.layout>div.main fieldset.desktop>legend { display:none; }
fieldset.web.wiki.portal>div.output>div.layout>div.main fieldset.inner.output div.content { background-color:var(--code-bg-color); color:var(--code-fg-color); padding:var(--input-padding) 0;
--code-keyword:orange; --code-comment:silver;
--code-function:cyan; --code-constant:silver; --code-string:silver;
--code-package:silver; --code-datatype:silver; --code-object:silver;
}
fieldset.web.wiki.portal>div.output>div.layout>div.main div.story[data-type=spark][data-name=shell] { box-shadow:var(--th-box-shadow); border:0; border-left:var(--box-notice3); }
fieldset.web.wiki.portal>div.output>div.layout>div.main fieldset.inner.output div.content { padding:var(--input-padding) 0; }
fieldset.web.wiki.portal>div.output>div.layout>div.main div.story[data-type=spark][data-name=shell] { border:var(--box-border); border-left:var(--box-notice3); }
fieldset.web.wiki.portal>div.output>div.layout>div.main div.story[data-type=spark][data-name=shell]:hover { box-shadow:var(--notice-box-shadow); }
fieldset.web.wiki.portal>div.output>div.layout>div.main div.story[data-type=spark][data-name=shell] { background-color:var(--code-bg-color); color:var(--code-fg-color); padding:var(--button-padding); margin-top:var(--button-margin); }
fieldset.web.wiki.portal>div.output>div.layout>div.main div.story[data-type=spark][data-name=shell] { padding:var(--button-padding); margin-top:var(--button-margin); }
fieldset.web.wiki.portal>div.output>div.layout>div.main table.content div.story[data-type=spark][data-name=shell] { margin-top:unset; }
fieldset.web.wiki.portal.home>div.output>div.layout>div.main p { white-space:pre-wrap; text-align:center; }
fieldset.web.wiki.portal.home>div.output>div.layout>div.main p { white-space:pre-wrap; }
div.story[data-type=qrcode] { text-align:center; }
fieldset.web.wiki.portal.home>div.output>div.layout>div.main p:hover { background-color:var(--hover-bg-color); color:var(--hover-fg-color); }
body.dark fieldset.web.wiki.portal>div.output>div.header div.story[data-name=navmenu] div.item:hover { background-color:var(--plugin-bg-color); }
body.dark fieldset.web.wiki.portal>div.output>div.header div.story[data-name=navmenu] div.item.select { background-color:var(--plugin-bg-color); }
body.dark fieldset.web.wiki.portal>div.output>div.header div.story[data-name=navmenu] div.item:hover { background-color:var(--output-bg-color); }
body.dark fieldset.web.wiki.portal>div.output>div.header div.story[data-name=navmenu] div.item.select { background-color:var(--output-bg-color); }
body.dark fieldset.web.wiki.portal>div.output>div.layout { background-color:var(--plugin-bg-color); --code-bg-color:var(--output-bg-color); }
body.dark fieldset.web.wiki.portal>div.output>div.layout>div.main fieldset:not(.macos) { border:var(--plugin-border); }
body.dark fieldset.web.wiki.portal>div.output>div.layout>div.main fieldset.output>div.output { border-radius:var(--plugin-radius); }
body.dark fieldset.web.wiki.portal>div.output>div.layout>div.main fieldset { border-radius:0; }
body.dark fieldset.web.wiki.portal>div.output>div.layout>div.main div.story[data-type=spark][data-name=shell] { border-left:var(--box-notice3); }
// body.dark fieldset.web.wiki.portal>div.output>div.layout>div.main div.story[data-type=spark][data-name=shell] { border:var(--box-border); }
body.white fieldset.web.wiki.portal>div.output>div.header { color:silver; }
body.light fieldset.web.wiki.portal>div.output>div.header { color:white; }
body.light fieldset.web.wiki.portal>div.output>div.header div.story[data-name=navmenu] { --hover-fg-color:black; }
@ -68,4 +72,3 @@ body.mobile fieldset.web.wiki.portal.home>div.output>div.layout>div.main h2 { ma
body.mobile fieldset.web.wiki.portal>div.output>div.layout>div.main p { padding:var(--input-padding); margin:0; }
body.width2 fieldset.web.wiki.portal>div.output>div.layout>div.main>div.flex { flex-direction:column; }
body.web.wiki.portal fieldset.Action.home>div.toast { display:none; }
body.web.wiki.portal.cmd { background-color:rgb(22 31 49); }

View File

@ -6,6 +6,7 @@ import (
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/aaa"
"shylinux.com/x/icebergs/base/ctx"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
"shylinux.com/x/icebergs/base/web"
)
@ -33,6 +34,7 @@ func init() {
}},
web.DREAM_ACTION: {Hand: func(m *ice.Message, arg ...string) { web.DreamProcessIframe(m, arg...) }},
}, web.ServeCmdAction(), web.DreamTablesAction()), Hand: func(m *ice.Message, arg ...string) {
m.Option(mdb.ICONS, ice.Info.NodeIcon)
if m.Push(HEADER, m.Cmdx(WORD, _portal_path(m, INDEX_SHY))); len(arg) > 0 {
m.Push(NAV, m.Cmdx(WORD, _portal_path(m, path.Join(arg...), INDEX_SHY)))
}

View File

@ -1,22 +1,14 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg, cb) { can.require(["/plugin/local/wiki/word.js"])
var p = "/cmd/"+web.PORTAL; can.db.prefix = location.pathname.indexOf(p) > -1? location.pathname.split(p)[0]+p: nfs.WIKI_PORTAL
var p = "/c/"+web.PORTAL; can.db.prefix = location.pathname.indexOf(p) > -1? location.pathname.split(p)[0]+p: nfs.WIKI_PORTAL
var p = "/c/portal"; can.db.prefix = location.pathname.indexOf(p) > -1? location.pathname.split(p)[0]+p: p
can.db.current = can.isCmdMode()? can.base.trimPrefix(location.pathname, can.db.prefix+nfs.PS, can.db.prefix): can.Option(nfs.PATH)
if (can.base.isIn(can.db.current, "", nfs.PS)) {
can.page.ClassList.add(can, can._fields, ice.HOME)
can.page.ClassList.add(can, can._root.Action._target, ice.HOME)
can.page.ClassList.add(can, can._fields, ice.HOME), can.page.ClassList.add(can, can._root.Action._target, ice.HOME)
} else {
can.page.ClassList.del(can, can._fields, ice.HOME)
can.page.ClassList.del(can, can._root.Action._target, ice.HOME)
can.page.ClassList.del(can, can._fields, ice.HOME), can.page.ClassList.del(can, can._root.Action._target, ice.HOME)
}
can.ui = can.onappend.layout(can, [html.HEADER, [html.NAV, html.MAIN, html.ASIDE]], html.FLOW), can.onimport._scroll(can)
can.ui.header.innerHTML = msg.Append(html.HEADER), can.ui.nav.innerHTML = msg.Append(html.NAV)
can.onmotion.delay(can, function() {
can.page.Select(can, can.ui.header, "div.item:first-child>span", function(target, index) {
index == 0 && can.page.insertBefore(can, [{img: can.misc.ResourceFavicon(can, can.user.info.favicon), style: {height: 42}}], target)
})
}, 300)
if (msg.Append(html.NAV) == "") {
can.onmotion.hidden(can, can.ui.nav), can.onmotion.hidden(can, can.ui.aside)
} else {
@ -25,29 +17,39 @@ Volcanos(chat.ONIMPORT, {
}
can.onmotion.delay(can, function() { cb && cb(msg), can.Conf(html.PADDING, can.page.styleValueInt(can, "--portal-main-padding", can._output)||(can.user.isMobile? 5: 40))
can.user.isMobile && can.Conf(html.PADDING, can.isCmdMode()? 5: 15)
var file = can.isCmdMode()? can.db.hash[0]: can.Option(nfs.FILE); can.base.beginWith(file, nfs.SRC, nfs.USR) || (file = can.db.current+file)
var file = can.isCmdMode()? can.db.hash[0]: can.Option(nfs.FILE); can.base.beginWith(file, nfs.SRC, nfs.USR) || (file = can.db.current+(file||""))
can.db.nav = {}, can.page.Select(can, can._output, wiki.STORY_ITEM, function(target) { var meta = target.dataset||{}
can.core.CallFunc([can.onimport, can.onimport[meta.name]? meta.name: meta.type||target.tagName.toLowerCase()], [can, meta, target])
meta.style && can.page.style(can, target, can.base.Obj(meta.style))
}); var nav = can.db.nav[file]; nav? nav.click(): can.onimport.content(can, "content.shy")
}, 300)
})
var nav = can.db.nav[file]; nav? nav.click(): can.ui.nav.innerHTML == "" && can.onimport.content(can, "content.shy")
can.page.Select(can, can.ui.header, "div.item:first-child>span", function(target, index) {
can.page.insertBefore(can, [{img: can.misc.ResourceFavicon(can, msg.Option(mdb.ICONS)||can.user.info.favicon), style: {height: 42}}], target)
})
can.isCmdMode() && can.misc.isDebug(can) && can.page.Append(can, can.ui.header.firstChild, [{view: html.ITEM, list: [{text: "后台"}], onclick: function() {
can.user.open(can.misc.MergePodCmd(can, {cmd: web.ADMIN}))
}}])
}, 100)
},
_scroll: function(can) { can.ui.main.onscroll = function(event) { var top = can.ui.main.scrollTop, select
can.page.SelectChild(can, can.ui.main, "h1,h2,h3", function(target) { if (!select && target.offsetTop > top) {
select = target, can.onmotion.select(can, can.ui.aside, html.DIV_ITEM, target._menu)
} })
} },
navmenu: function(can, meta, target) { var link
navmenu: function(can, meta, target) { var link, _target
can.onimport.list(can, can.base.Obj(meta.data), function(event, item) {
can.page.Select(can, target, html.DIV_ITEM, function(target) { target != event.target && can.page.ClassList.del(can, target, html.SELECT) })
item.list && item.list.length > 0 || can.onaction.route(event, can, item.meta.link)
can.page.Select(can, target, html.DIV_ITEM, function(target) { target != event.currentTarget && can.page.ClassList.del(can, target, html.SELECT) })
item.list && item.list.length > 0 || can.onaction.route(event, can, item.meta.link), can.onimport.layout(can)
}, can.page.ClassList.has(can, target.parentNode, html.HEADER)? function(target, item) {
item.meta.link == nfs.USR_LEARNING_PORTAL+can.db.current && can.onappend.style(can, html.SELECT, target)
item.meta.link == nfs.SRC_DOCUMENT+can.db.current && can.onmotion.delay(can, function() { can.onappend.style(can, html.SELECT, target) })
}: function(target, item) { can.db.nav[can.base.trimPrefix(item.meta.link, nfs.USR_LEARNING_PORTAL, nfs.SRC_DOCUMENT)] = target
location.hash || item.list && item.list.length > 0 || link || (link = can.onaction.route({}, can, item.meta.link, true))
}, target)
location.hash || item.list && item.list.length > 0 || link || (_target = _target||target)
item.meta.link == nfs.USR_LEARNING_PORTAL+can.db.current+can.db.hash[0] && (_target = target)
}, target), _target && can.onmotion.delay(can, function() {
can.onappend.style(can, html.SELECT, _target), _target.click()
}, 0)
},
content: function(can, file) {
content: function(can, file) { can.request(event, {_method: "GET"})
can.runActionCommand(event, web.WIKI_WORD, [(can.base.beginWith(file, nfs.USR, nfs.SRC)? "": nfs.USR_LEARNING_PORTAL+can.db.current)+file], function(msg) { can.ui.main.innerHTML = msg.Result(), can.onmotion.clear(can, can.ui.aside)
can.onimport._content(can, can.ui.main, function(target, meta) {
meta.type == wiki.TITLE && can.onappend.style(can, meta.name, target._menu = can.onimport.item(can, {name: meta.text}, function(event) { target.scrollIntoView() }, function() {}, can.ui.aside))
@ -63,7 +65,9 @@ Volcanos(chat.ONIMPORT, {
can.page.style(can, can.ui.nav, html.HEIGHT, "", html.WIDTH, can.page.width())
can.page.style(can, can.ui.main, html.HEIGHT, "", html.WIDTH, can.page.width())
}
can.core.List(can._plugins, function(sub) { sub.onimport.size(sub, can.base.Min(html.FLOAT_HEIGHT, can.ConfHeight()/2, can.ConfHeight()), (can.ConfWidth()-2*padding), true) })
can.core.List(can._plugins, function(sub) {
sub.onimport.size(sub, can.base.Min(html.FLOAT_HEIGHT, can.ConfHeight()/2, can.ConfHeight()), (can.ConfWidth()-2*padding), true)
})
},
}, [""])
Volcanos(chat.ONACTION, {
@ -78,7 +82,7 @@ Volcanos(chat.ONACTION, {
}
var file = can.base.trimPrefix(link, can.db.current); can.isCmdMode() && can.user.jumps("#"+file)
if (can.onmotion.cache(can, function(save, load) { save({plugins: can._plugins})
return load(file, function(bak) { can._plugins = bak.file })
return load(file, function(bak) { can._plugins = bak.plugins })
}, can.ui.main, can.ui.aside)) { return file } can.onimport.content(can, file)
return link
},

View File

@ -81,8 +81,8 @@ func init() {
if aaa.Right(m.Spawn(), arg[0]) {
m.Cmdy(FIELD, "", arg[0], arg[1:])
} else {
p := kit.Format("http://localhost:9020/chat/cmd/%s", arg[0])
m.Cmdy(SPARK, p, arg[1:]).Cmdy(IFRAME, p, arg[1:])
p := kit.Format("https://demo.shylinux.com/c/%s", arg[0])
m.Cmdy(SPARK, p, arg[1:]).Cmdy("web.wiki.iframe", p, arg[1:])
}
}},
INNER: {Hand: func(m *ice.Message, arg ...string) {
@ -115,19 +115,23 @@ func init() {
})
}
func _spark_project(m *ice.Message, arg ...string) {
defer m.Cmdy(STYLE, FLEX).Cmdy(STYLE, END)
m.Cmdy(STYLE, COLUMN)
m.Cmdy(TITLE, ice.Info.Title())
m.Cmdy(SPARK, TITLE, arg[0]).Cmdy(ORDER, arg[1])
m.Cmdy(STYLE, FLEX)
m.Cmdy(SPARK, html.BUTTON, "体 验", ROUTE, web.SpideOrigin(m, ice.DEMO))
m.Cmdy(SPARK, html.BUTTON, "下 载", ROUTE, "download/")
m.Cmdy(SPARK, html.BUTTON, "文 档", ROUTE, "started/")
m.Cmdy(STYLE, END)
m.Cmdy(STYLE, END)
m.Cmdy(STYLE, COLUMN, FLEX, "0 0 500px", "padding", "10px")
m.Cmdy(SPARK, INNER, ice.SRC_MAIN_GO, html.WIDTH, "480px")
m.Cmdy(SPARK, SHELL, kit.Renders(`
func() {
defer m.Cmdy(STYLE, FLEX).Cmdy(STYLE, END)
func() {
defer m.Cmdy(STYLE, COLUMN).Cmdy(STYLE, END)
m.Cmdy(TITLE, ice.Info.Title())
m.Cmdy(SPARK, TITLE, arg[0]).Cmdy(ORDER, arg[1])
func() {
defer m.Cmdy(STYLE, FLEX).Cmdy(STYLE, END)
m.Cmdy(SPARK, html.BUTTON, "体 验", ROUTE, web.SpideOrigin(m, ice.DEMO))
m.Cmdy(SPARK, html.BUTTON, "下 载", ROUTE, "download/")
m.Cmdy(SPARK, html.BUTTON, "文 档", ROUTE, "started/")
}()
}()
func() {
defer m.Cmdy(STYLE, COLUMN, FLEX, "0 0 500px", "padding", "10px").Cmdy(STYLE, END)
m.Cmdy(SPARK, INNER, ice.SRC_MAIN_GO, html.WIDTH, "480px")
m.Cmdy(SPARK, SHELL, kit.Renders(`
git clone {{ .Make.Remote }}
cd {{ .Make.Remote | Base }} && source etc/miss.sh
@ -135,12 +139,18 @@ cd {{ .Make.Remote | Base }} && source etc/miss.sh
open http://localhost:9020
`, ice.Info), "style.width", "480px")
m.Cmdy(STYLE, END)
}()
}()
if nfs.Exists(m, "src/qrcode.jpg") {
defer m.Echo(`<div class="story" data-type="qrcode">`).Echo("</div>")
m.Cmdy(IMAGE, "qrcode", "src/qrcode.jpg")
m.Cmdy(SPARK, "请使用微信扫码,打开公众号体验服务")
}
}
func _spark_product(m *ice.Message, arg ...string) {
if len(arg) == 0 {
m.Cmd("web.product").Table(func(value ice.Maps) {
if value[mdb.ENABLE] == ice.TRUE {
if value[mdb.DISABLE] == ice.TRUE {
_spark_product(m, value[ctx.INDEX], value[mdb.NAME], value[mdb.TEXT])
}
})

View File

@ -1,14 +1,24 @@
package wiki
import (
"path"
"strings"
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/nfs"
)
const VIDEO = "video"
func init() {
Index.MergeCommands(ice.Commands{
VIDEO: {Name: "video path", Help: "视频", Hand: func(m *ice.Message, arg ...string) {
VIDEO: {Name: "video path", Help: "视频", Actions: ice.Actions{
"material": {Hand: func(m *ice.Message, arg ...string) {
if nfs.Exists(m, nfs.USR_MATERIAL) {
m.Cmdy(VIDEO, path.Join(nfs.USR_MATERIAL, strings.TrimPrefix(path.Dir(m.Option("_script")), nfs.USR), arg[0]))
}
}},
}, Hand: func(m *ice.Message, arg ...string) {
arg = _name(m, arg)
_image_show(m, arg[0], arg[1], arg[2:]...)
}},

View File

@ -69,6 +69,7 @@ func init() {
FEEL, DRAW, DATA, WORD, PORTAL, STYLE,
TITLE, BRIEF, REFER, SPARK, FIELD,
ORDER, TABLE, CHART, IMAGE, VIDEO, AUDIO,
// IFRAME,
)
}
func Prefix(arg ...string) string { return web.Prefix(WIKI, kit.Keys(arg)) }

View File

@ -42,6 +42,11 @@ func init() {
WordAlias(m, LABEL, CHART, LABEL)
WordAlias(m, CHAIN, CHART, CHAIN)
WordAlias(m, SEQUENCE, CHART, SEQUENCE)
if ls := kit.SplitLine(m.Cmdx(nfs.CAT, ice.SRC_MAIN_SHY)); len(ls) > 0 {
if list := kit.SplitWord(ls[0]); len(list) > 0 && list[0] == TITLE {
ice.Info.Titles = list[1]
}
}
}},
mdb.SEARCH: {Hand: func(m *ice.Message, arg ...string) {
if mdb.IsSearchPreview(m, arg) {

2
go.mod
View File

@ -5,6 +5,6 @@ go 1.13
require (
shylinux.com/x/go-git/v5 v5.6.7
shylinux.com/x/go-qrcode v0.0.3
shylinux.com/x/toolkits v1.0.14
shylinux.com/x/toolkits v1.0.19
shylinux.com/x/websocket v0.0.4
)

4
go.sum
View File

@ -4,7 +4,7 @@ shylinux.com/x/go-qrcode v0.0.3 h1:RMo+Vidbgq3HatLBj7DDXcTbTLFUwzis5K7TqBkD38U=
shylinux.com/x/go-qrcode v0.0.3/go.mod h1:KAbtU+KwiiABMZ/CJ0zh9PI2AX82Uf9rRYcQ4ODm4po=
shylinux.com/x/toolkits v0.7.10 h1:65d5rkQXQ71MD8FzYnZ9DFxb1XcOYSYfmRc4j8qQsUw=
shylinux.com/x/toolkits v0.7.10/go.mod h1:CHDJarGlDkg60kVsvMLYL/a5hAnRLEOShiEsMOuEp0Q=
shylinux.com/x/toolkits v1.0.14 h1:ysp9Yl0YjVqtGn/KXQnKfjn3/3RYgVdll2WOYUscd9c=
shylinux.com/x/toolkits v1.0.14/go.mod h1:CHDJarGlDkg60kVsvMLYL/a5hAnRLEOShiEsMOuEp0Q=
shylinux.com/x/toolkits v1.0.19 h1:Nrx0xYRc5ph1WS66EZ1hJUCe+2FdSWQ4QP6tBlguikQ=
shylinux.com/x/toolkits v1.0.19/go.mod h1:CHDJarGlDkg60kVsvMLYL/a5hAnRLEOShiEsMOuEp0Q=
shylinux.com/x/websocket v0.0.4 h1:AJpwblePoOpiE6C8NrvgNYpKTotXMLrDDX2chTvx44Q=
shylinux.com/x/websocket v0.0.4/go.mod h1:3UGWkjTu3ie5NAZen7J+uLPBrO7DFeKloj6Jxo13Oiw=

24
info.go
View File

@ -21,15 +21,17 @@ type MakeInfo struct {
Git string
Go string
Remote string
Branch string
Version string
Forword string
Message string
Author string
Email string
Hash string
When string
Icebergs string
Release string
Remote string
Branch string
Version string
Forword string
Message string
Author string
Email string
Hash string
When string
}
func (s MakeInfo) Versions() string {
@ -51,6 +53,9 @@ func (s info) Title() string {
return p
return kit.Capital(p)
}
func (s info) IconTitle() string {
return kit.Format("<img src='%s'/><span>%s</span>", Pulse.Resource(s.NodeIcon), s.Title())
}
type info struct {
Make MakeInfo
@ -65,6 +70,7 @@ type info struct {
NodeType string
NodeIcon string
NodeMain string
CodeMain string
Pwd string
Lang string

View File

@ -65,6 +65,11 @@ var Index = &Context{Name: ICE, Help: "冰山模块", Commands: Commands{
m.Cmd(SOURCE, ETC_INIT_SHY)
loadImportant(m)
m.Cmd(CTX_OPEN)
m.Travel(func(p *Context, c *Context, key string, cmd *Command) {
if h, ok := cmd.Actions["afterInit"]; ok {
h.Hand(m.Spawn(c, key, cmd), arg...)
}
})
}},
QUIT: {Hand: func(m *Message, arg ...string) {
m.GoSleep300ms(func() { os.Exit(kit.Int(kit.Select("0", arg, 0))) })
@ -73,10 +78,10 @@ var Index = &Context{Name: ICE, Help: "冰山模块", Commands: Commands{
m.GoSleep300ms(func() {
m.root.Option(EXIT, kit.Select("0", arg, 0))
m.Cmd(SOURCE, ETC_EXIT_SHY)
m.Cmd(CTX_EXIT)
if HasUsr() {
m.Cmd(EXPORT, EXPORT)
}
m.Cmd(CTX_EXIT)
removeImportant(m)
})
}},

View File

@ -130,6 +130,10 @@ func (m *Message) Push(key string, value Any, arg ...Any) *Message {
k = strings.TrimSuffix(k, "*")
m.Push(k, kit.Select(kit.Format(val[k]), value[k]))
})
case map[string]int:
kit.For(value, func(key string, value int) {
m.Push(key, value)
})
default:
keys := strings.Split(key, ",")
kit.For(kit.Simple(value, arg), func(v string, i int) {

View File

@ -52,4 +52,4 @@ func (s server) List(m *ice.Message, arg ...string) {
})
}
}
func init() { ice.CodeCtxCmd(server{}) }
func init() { ice.Cmd("web.code.coder.server", server{}) }

View File

@ -398,6 +398,7 @@ func init() {
web.PP(ice.REQUIRE): {Name: "/require/shylinux.com/x/volcanos@v0.0.1/proto.js", Actions: ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
kit.If(cli.SystemFind(m, code.GO), func() { cache = code.GoCache(m) })
aaa.White(m, "require")
}},
}), Hand: func(m *ice.Message, arg ...string) {
if len(arg) < 4 {
@ -438,12 +439,17 @@ func init() {
m.Cmd(nfs.DIR, nfs.USR_LOCAL_WORK, func(value ice.Maps) { _repos_insert(m, value[nfs.PATH]) })
m.ProcessRefresh().ToastSuccess()
}},
mdb.CREATE: {Hand: func(m *ice.Message, arg ...string) {
_repos_insert(m, arg[0])
}},
INIT: {Name: "init remote*", Help: "初始化", Hand: func(m *ice.Message, arg ...string) {
m.OptionDefault(nfs.PATH, kit.Path(""))
m.Cmd(nfs.DEFS, path.Join(m.Option(nfs.PATH), ".git/config"), kit.Format(nfs.Template(m, CONFIG), m.Option(REMOTE)))
m.Cmd(nfs.DEFS, path.Join(m.Option(nfs.PATH), _GITIGNORE), nfs.Template(m, IGNORE))
git.PlainInit(m.Option(nfs.PATH), false)
_repos_insert(m, m.Option(nfs.PATH))
m.Cmd(code.AUTOGEN, nfs.REPOS)
m.Cmd(STATUS, web.DEV_CREATE_TOKEN, kit.Dict(web.ORIGIN, web.UserHost(m), web.TOKEN, m.Cmdx(web.SPACE, ice.OPS, web.TOKEN, mdb.CREATE, mdb.TYPE, STATUS, mdb.NAME, m.Option(ice.MSG_USERNAME), mdb.TEXT, web.UserHost(m))))
m.ProcessRefresh()
}},
INSTEADOF: {Name: "insteadof remote", Help: "代理", Icon: "bi bi-clouds", Hand: func(m *ice.Message, arg ...string) {
@ -504,13 +510,19 @@ func init() {
switch mdb.HashInputs(m, arg); m.Option(ctx.ACTION) {
case INIT:
m.Push(arg[0], ice.Info.Make.Remote)
m.Cmd(web.SPIDE, ice.OptionFields(web.CLIENT_ORIGIN), func(value ice.Maps) { m.Push(arg[0], value[web.CLIENT_ORIGIN]+web.X(path.Base(kit.Path("")))) })
m.Push(arg[0], kit.MergeURL2(web.UserHost(m), web.X(path.Base(kit.Path("")))))
m.Sort(arg[0])
m.Cmd(web.SPIDE, ice.OptionFields(web.CLIENT_ORIGIN, web.CLIENT_TYPE)).Sort(web.CLIENT_ORIGIN).Table(func(value ice.Maps) {
if value[web.CLIENT_TYPE] == nfs.REPOS {
m.Push(arg[0], value[web.CLIENT_ORIGIN]+web.X(path.Base(kit.Path(""))))
}
})
case INSTEADOF:
m.Cmd(web.SPIDE, ice.OptionFields(web.CLIENT_ORIGIN), func(value ice.Maps) { m.Push(arg[0], value[web.CLIENT_ORIGIN]+web.X()) })
m.Push(arg[0], kit.MergeURL2(web.UserHost(m), web.X()))
m.Sort(arg[0])
m.Cmd(web.SPIDE, ice.OptionFields(web.CLIENT_ORIGIN, web.CLIENT_TYPE)).Sort(web.CLIENT_ORIGIN).Table(func(value ice.Maps) {
if value[web.CLIENT_TYPE] == nfs.REPOS {
m.Push(arg[0], value[web.CLIENT_ORIGIN]+web.X())
}
})
default:
switch arg[0] {
case MESSAGE:

View File

@ -202,7 +202,7 @@ func init() {
m.Push(nfs.SIZE, kit.Split(m.Cmdx(cli.SYSTEM, "du", "-sh", path.Join(ice.USR_LOCAL_REPOS, value[REPOS])))[0])
m.PushScript(kit.Format("git clone %s", _service_link(m, value[REPOS])))
}).Sort(REPOS)
kit.If(!m.IsCliUA(), func() { m.Cmdy(web.CODE_PUBLISH, ice.CONTEXTS, ice.DEV) })
kit.If(!m.IsCliUA(), func() { m.Cmdy(web.CODE_PUBLISH, nfs.CONTEXTS, ice.DEV) })
kit.If(mdb.Config(m, aaa.AUTH) == aaa.PRIVATE, func() { m.StatusTimeCount(aaa.AUTH, aaa.PRIVATE) })
m.PushAction("settoken", mdb.REMOVE).Action(mdb.CREATE, aaa.AUTH)
} else if repos := _repos_open(m, arg[0]); len(arg) == 1 {

View File

@ -2,6 +2,7 @@ package git
import (
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/aaa"
"shylinux.com/x/icebergs/base/ctx"
"shylinux.com/x/icebergs/base/nfs"
)
@ -10,7 +11,7 @@ const SPIDES = "spides"
func init() {
Index.MergeCommands(ice.Commands{
SPIDES: {Name: "spides repos auto", Help: "构架图", Hand: func(m *ice.Message, arg ...string) {
SPIDES: {Name: "spides repos auto", Help: "构架图", Role: aaa.VOID, Hand: func(m *ice.Message, arg ...string) {
if len(arg) == 0 {
m.Cmdy(REPOS)
} else if p := _repos_path(m, arg[0]); len(arg) == 1 {

View File

@ -78,7 +78,7 @@ func init() {
m.Cmd(CONFIGS, mdb.CREATE, "credential.helper", "store")
m.ProcessClose()
}},
}, ctx.ConfAction(ctx.TOOLS, "xterm,compile"), web.DreamTablesAction(), web.DevTokenAction(web.ORIGIN, web.ORIGIN), Prefix(REPOS)), Hand: func(m *ice.Message, arg ...string) {
}, web.DreamTablesAction(), web.DevTokenAction(web.ORIGIN, web.ORIGIN), Prefix(REPOS)), Hand: func(m *ice.Message, arg ...string) {
if len(arg) > 0 && arg[0] == ctx.ACTION {
m.Cmdy(REPOS, arg)
} else if config, err := config.LoadConfig(config.GlobalScope); err == nil && config.User.Email == "" && mdb.Config(m, aaa.EMAIL) == "" {
@ -93,7 +93,7 @@ func init() {
} else {
m.Action(PULL, PUSH, INSTEADOF, mdb.DEV_REQUEST, ctx.CONFIG, STASH)
}
kit.If(!m.IsCliUA(), func() { m.Cmdy(code.PUBLISH, ice.CONTEXTS, ice.DEV) })
kit.If(!m.IsCliUA(), func() { m.Cmdy(code.PUBLISH, nfs.CONTEXTS, ice.DEV) })
ctx.Toolkit(m)
} else {
_repos_cmd(m, arg[0], DIFF)

View File

@ -118,9 +118,9 @@ func init() {
}
func TableGo(m *ice.Message, cb ice.Any) *ice.Message {
wg, lock := sync.WaitGroup{}, &task.Lock{}
wg.Add(m.Length())
defer wg.Wait()
m.Table(func(value ice.Maps) {
wg.Add(1)
task.Put(m.FormatTaskMeta(), logs.FileLine(cb), func(*task.Task) {
defer wg.Done()
switch cb := cb.(type) {

34
misc/md/md.go Normal file
View File

@ -0,0 +1,34 @@
package md
import (
"path"
"github.com/gomarkdown/markdown"
"shylinux.com/x/ice"
"shylinux.com/x/icebergs/base/nfs"
)
type md struct {
ice.Code
ice.Lang
list string `name:"list name auto" help:"示例"`
}
func (s md) Init(m *ice.Message, arg ...string) {
s.Lang.Init(m, nfs.SCRIPT, m.Resource(""))
}
func (s md) List(m *ice.Message, arg ...string) {
s.Code.Source(m, "", arg...)
}
func (s md) Render(m *ice.Message, arg ...string) {
md := []byte(m.Cmdx(nfs.CAT, path.Join(arg[2], arg[1])))
html := markdown.ToHTML(md, nil, nil)
m.Echo(string(html))
}
func (s md) Engine(m *ice.Message, arg ...string) {
md := []byte(m.Cmdx(nfs.CAT, path.Join(arg[2], arg[1])))
html := markdown.ToHTML(md, nil, nil)
m.Echo(string(html))
}
func init() { ice.Cmd("web.wiki.md", md{}) }

13
misc/md/md.js Normal file
View File

@ -0,0 +1,13 @@
Volcanos(chat.ONSYNTAX, {
md: {
prefix: {"//": code.COMMENT},
regexp: {"[A-Z_0-9]+": code.CONSTANT},
keyword: {
"package": code.KEYWORD,
"import": code.KEYWORD,
"public": code.KEYWORD,
"private": code.KEYWORD,
"static": code.KEYWORD,
},
},
})

View File

@ -1,8 +1,5 @@
package misc
import (
// _ "shylinux.com/x/icebergs/misc/bash"
_ "shylinux.com/x/icebergs/misc/git"
// _ "shylinux.com/x/icebergs/misc/tmux"
// _ "shylinux.com/x/icebergs/misc/vim"
)

View File

@ -48,7 +48,8 @@ func _ssh_open(m *ice.Message, arg ...string) {
}, arg...)
}
func _ssh_dial(m *ice.Message, cb func(net.Conn), arg ...string) {
p := kit.HomePath(".ssh", fmt.Sprintf("%s@%s:%s", m.Option(aaa.USERNAME), m.Option(tcp.HOST), m.Option(tcp.PORT)))
os.Mkdir(kit.HomePath(".ssh/sess"), 0755)
p := kit.HomePath(".ssh/sess", fmt.Sprintf("%s@%s:%s", m.Option(aaa.USERNAME), m.Option(tcp.HOST), m.Option(tcp.PORT)))
if nfs.Exists(m, p) {
if c, e := net.Dial(tcp.UNIX, p); e == nil {
cb(c)
@ -322,5 +323,5 @@ func PushShell(m *ice.Message, cmds []string, cb func(string)) {
func RunConnect(arg ...string) string {
defer func() { recover() }()
kit.If(len(arg) == 0, func() { arg = append(arg, os.Args...) })
return ice.Run(kit.Simple("ssh.connect", "open", AUTHFILE, kit.HomePath(".ssh/", path.Base(arg[0])+".json"), arg[1:])...)
return ice.Run(kit.Simple("ssh.connect", "open", AUTHFILE, kit.HomePath(".ssh/host/", path.Base(arg[0])+".json"), arg[1:])...)
}

View File

@ -79,7 +79,7 @@ type relay struct {
pushbin string `name:"pushbin dream portal nodename dev" icon:"bi bi-box-arrow-in-up"`
adminCmd string `name:"adminCmd cmd" icon:"bi bi-terminal-plus"`
pushkey string `name:"pushkey server" icon:"bi bi-person-fill-up"`
setIcon string `name:"setIcon icons*"`
setIcon string `name:"setIcon icons*" help:"图标"`
}
func (s relay) Init(m *ice.Message, arg ...string) {
@ -228,18 +228,21 @@ func (s relay) List(m *ice.Message, arg ...string) *ice.Message {
stats[DISK_TOTAL] += kit.Int(ls[1])
}
if value[web.PORTAL] == "" {
m.Push(web.LINK, "").PushButton(s.Xterm, s.Pushbin, s.Install, s.Remove)
m.Push(web.LINK, "").PushButton(s.Xterm,
// s.Pushbin, s.Install,
s.Remove)
} else {
m.Push(web.LINK, m.HostPort(value[tcp.HOST], value[web.PORTAL]))
m.PushButton(s.Portal, s.Desktop, s.Admin, s.Open,
s.Status, s.Vimer, s.Login,
// s.Status, s.Vimer,
s.Login,
s.Spide,
s.AdminCmd,
s.Upgrade,
s.Pushbin,
s.Pushkey,
// s.AdminCmd,
// s.Upgrade,
// s.Pushbin,
// s.Pushkey,
s.Xterm,
s.SetIcon,
// s.SetIcon,
s.Remove)
kit.If(len(arg) > 0, func() { m.PushQRCode(cli.QRCODE, m.Append(web.LINK)) })
}
@ -348,7 +351,7 @@ func (s relay) Login(m *ice.Message, arg ...string) {
)), func(res string) { m.Echo(res) })
m.ProcessOpen(m.Option(mdb.LINK))
} else if m.Option(ice.MSG_METHOD) == http.MethodGet {
m.EchoInfoButton("")
m.EchoInfoButton("请授权登录 " + m.Option(MACHINE))
} else {
defer m.ToastProcess()()
ssh.CombinedOutput(m.Message, s.admins(m, kit.JoinCmds(web.SHARE, mdb.CREATE, mdb.TYPE, aaa.LOGIN, "--", mdb.TEXT, m.Option(ice.BACK))), func(res string) {

View File

@ -110,6 +110,7 @@ func init() {
m.OptionSimple("user_cmd", "sess_cmd"),
)
m.Cmd(AGENT, OAUTH, m.Cmdx("web.chat.oauth.client", web.LINK, oauth))
m.Cmd(web.SPACE, ice.OPS, ctx.CONFIG, "web.chat.header", OAUTH, m.Cmdx("web.chat.oauth.client", web.LINK, oauth))
}},
web.SSO: {Name: "sso name*=weixin help*=微信扫码 order=11 env=release,trial,develop wifi", Hand: func(m *ice.Message, arg ...string) {
m.Cmd(web.CHAT_HEADER, mdb.CREATE, mdb.TYPE, mdb.PLUGIN, m.OptionSimple(mdb.NAME, mdb.HELP, mdb.ORDER),
@ -138,24 +139,26 @@ func init() {
}, gdb.EventsAction(web.SPACE_GRANT, web.SPACE_LOGIN_CLOSE), mdb.ExportHashAction(
mdb.SHORT, ACCESS, mdb.FIELD, "time,type,access,icons,usernick,appid,secret,token", tcp.SERVER, CGI_BIN,
)), Hand: func(m *ice.Message, arg ...string) {
mdb.HashSelect(m, arg...).PushAction(OAUTH, web.SSO, TICKET, TOKENS, STABLE_TOKEN, "user", "api", mdb.REMOVE).StatusTimeCount(mdb.ConfigSimple(m, ACCESS, APPID), web.SERVE, m.MergeLink("/chat/wx/login/"))
mdb.HashSelect(m, arg...).PushAction(OAUTH, web.SSO, mdb.REMOVE).StatusTimeCount(mdb.ConfigSimple(m, ACCESS, APPID), web.SERVE, m.MergeLink("/chat/wx/login/"))
m.RewriteAppend(func(value, key string, index int) string {
kit.If(key == cli.QRCODE, func() { value = ice.Render(m, ice.RENDER_QRCODE, value) })
return value
})
if m.Length() == 0 {
m.EchoInfoButton("请添加公众号或小程序", mdb.CREATE)
}
}},
})
}
func spideToken(m *ice.Message, api string, token, expire string, arg ...string) {
msg := mdb.HashSelect(m.Spawn(), m.OptionDefault(ACCESS, mdb.Config(m, ACCESS)))
m.Info("what token %v %v", msg.Append(expire), msg.Append(token))
if msg.Append(token) == "" || m.Time() > msg.Append(expire) {
kit.If(api != TICKET_GETTICKET, func() { arg = append(arg, msg.AppendSimple(APPID, SECRET)...) })
res := m.Cmd(web.SPIDE, WX, kit.Select(http.MethodGet, http.MethodPost, api == STABLE_TOKEN), api, arg)
if m.Warn(!kit.IsIn(res.Append("errcode"), "0", ""), res.Append("errmsg")) {
return
}
m.Info("what res: %v", res.FormatMeta())
m.Info("res: %v", res.FormatMeta())
mdb.HashModify(m, m.OptionSimple(ACCESS), expire, m.Time(kit.Format("%vs", res.Append(oauth.EXPIRES_IN))), token, res.Append(kit.Select(oauth.ACCESS_TOKEN, TICKET, api == TICKET_GETTICKET)))
msg = mdb.HashSelect(m.Spawn(), m.Option(ACCESS))
}

View File

@ -12,7 +12,6 @@ import (
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
"shylinux.com/x/icebergs/base/web"
// "shylinux.com/x/icebergs/base/web/html"
"shylinux.com/x/icebergs/core/chat"
"shylinux.com/x/icebergs/core/chat/location"
kit "shylinux.com/x/toolkits"
@ -21,7 +20,6 @@ import (
func _wx_sign(m *ice.Message, nonce, stamp string) string {
return kit.Format(sha1.Sum([]byte(kit.Join(kit.Sort(kit.Simple(
kit.Format("jsapi_ticket=%s", m.Cmdx(ACCESS, TICKET)),
// kit.Format("url=%s", m.R.Header.Get(html.Referer)),
kit.Format("url=%s", m.Option(ice.MSG_REFERER)),
kit.Format("timestamp=%s", stamp),
kit.Format("noncestr=%s", nonce),
@ -40,18 +38,22 @@ func init() {
Index.MergeCommands(ice.Commands{
AGENT: {Name: "agent auto", Help: "代理", Role: aaa.VOID, Actions: ice.MergeActions(ice.Actions{
chat.HEADER_AGENT: {Hand: func(m *ice.Message, arg ...string) {
if m.Option(ice.MSG_USERNAME) == "" && mdb.Config(m, "oauth") != "" {
m.ProcessOpen(mdb.Config(m, "oauth"))
}
kit.If(strings.Index(m.Option(ice.MSG_USERUA), "MicroMessenger") > -1, func() {
m.Optionv(mdb.PLUGIN, m.PrefixKey(), mdb.Config(m, web.SPACE))
})
}},
"getLocation": {Hand: func(m *ice.Message, arg ...string) { m.Cmdy(location.LOCATION, mdb.CREATE, arg) }},
"scanQRCode1": {Hand: func(m *ice.Message, arg ...string) { m.Cmdy(chat.FAVOR, mdb.CREATE, arg) }},
"oauth": {Hand: func(m *ice.Message, arg ...string) { mdb.Config(m, "oauth", arg[0]) }},
"scanQRCode1": {Hand: func(m *ice.Message, arg ...string) { m.Cmdy(chat.FAVOR, mdb.CREATE, arg) }},
"getLocation": {Hand: func(m *ice.Message, arg ...string) { m.Cmdy(location.LOCATION, mdb.CREATE, arg) }},
}, gdb.EventsAction(chat.HEADER_AGENT), ctx.ConfAction(
"space", "", "oauth", "", nfs.SCRIPT, "https://res.wx.qq.com/open/js/jweixin-1.6.0.js",
"oauth", "", web.SPACE, "", nfs.SCRIPT, "https://res.wx.qq.com/open/js/jweixin-1.6.0.js",
)), Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(ACCESS, AGENT).Options(SIGNATURE, _wx_sign(m, m.Option(NONCESTR, ice.Info.Pathname), m.Option(TIMESTAMP, kit.Format(time.Now().Unix())))).Display("")
ctx.OptionFromConfig(m, nfs.SCRIPT, "oauth")
ctx.OptionFromConfig(m, "oauth", nfs.SCRIPT)
m.Option("oauth", strings.ReplaceAll(m.Option("oauth"), "https%3A%2F%2Fyunxuanlinghang.com", strings.ReplaceAll(m.Option(ice.MSG_USERHOST), "://", "%3A%2F%2F")))
}},
})
}

View File

@ -20,12 +20,13 @@ func init() {
CLICK = "click"
)
Index.MergeCommands(ice.Commands{
EVENTS: {Help: "事件", Actions: ice.Actions{
EVENTS: {Help: "事件", Actions: ice.MergeActions(ice.Actions{
SUBSCRIBE: {Hand: func(m *ice.Message, arg ...string) {
m.Option(mdb.NAME, ice.Info.Titles)
m.Option(mdb.TEXT, "欢迎光临")
// m.Option(mdb.TEXT, "无边界的扩张业务\n无极限的扩大规模")
m.Option(mdb.TEXT, "ContextOS-SaaS-AI\n软件平台免费提供各种各样的软件系统。")
m.Option(mdb.ICONS, m.MergeLink(m.Resource(ice.Info.NodeIcon)))
m.Cmdy(TEXT, web.LINK, m.MergeLink(nfs.PS))
m.Cmdy(TEXT, web.LINK, m.MergeLink(mdb.Config(m, SUBSCRIBE)))
}},
UNSUBSCRIBE: {Hand: func(m *ice.Message, arg ...string) {
}},
@ -57,6 +58,6 @@ func init() {
m.Cmdy(TEXT, web.LINK, m.MergePodCmd("", msg.Append(ctx.INDEX), kit.Split(msg.Append(ctx.ARGS))))
}
}},
}},
}, mdb.HashAction(SUBSCRIBE, "/s/20240724-enterprise/c/web.team.guanlixitong.portal"))},
})
}

View File

@ -48,8 +48,12 @@ func init() {
m.ProcessHold()
}},
}, mdb.ExportHashAction(mdb.SHORT, "scene,river,storm", mdb.FIELD, "time,hash,scene,river,storm,type,name,text,icons,space,index,args")), Hand: func(m *ice.Message, arg ...string) {
m.Option("cache.limit", "-1")
if len(arg) == 0 {
m.Cmdy(ACCESS).PushAction("").Option(ice.MSG_ACTION, "")
if m.Length() == 0 {
m.SetResult()
}
} else if mdb.HashSelect(m, arg[1:]...).Sort(mdb.Config(m, mdb.SHORT), ice.STR, ice.INT, ice.INT); len(arg) == 1 {
m.Action(mdb.CREATE, mdb.UPDATE)
}

View File

@ -218,7 +218,7 @@ func (m *Message) PushDownload(key string, arg ...string) *Message {
func (m *Message) EchoInfoButton(info string, arg ...Any) *Message {
kit.If(info == "", func() { info = Info.Template(m, m.ActionKey()+".html") })
kit.If(len(arg) == 0, func() { arg = append(arg, m.ActionKey()) })
kit.If(len(arg) == 0, func() { arg = append(arg, kit.Select(CREATE, m.ActionKey())) })
m.Display("/plugin/table.js", "style", "form")
return m.Echo(html.Format("div", info, "class", "info", "style", kit.JoinCSS())).EchoButton(arg...).Echo(NL).Action(arg...)
}

View File

@ -242,6 +242,7 @@ func (m *Message) Time(arg ...string) string {
func (m *Message) Message() *Message { return m.message }
func (m *Message) Source() *Context { return m.source }
func (m *Message) Target() *Context { return m.target }
func (m *Message) Command() *Command { return m._cmd }
func (m *Message) _fileline() string {
switch m.target.Name {
case MDB, AAA, GDB: