diff --git a/base/mdb/hash.go b/base/mdb/hash.go index 06ef123c..2abe8c6a 100644 --- a/base/mdb/hash.go +++ b/base/mdb/hash.go @@ -282,6 +282,7 @@ func HashSelect(m *ice.Message, arg ...string) *ice.Message { m.Table(func(value ice.Maps) { m.SetAppend().OptionFields(ice.FIELDS_DETAIL) kit.For(kit.Split(HashField(m)), func(key string) { + key = strings.TrimSuffix(key, "*") if key == HASH { m.Push(key, arg[0]) } else { diff --git a/base/nfs/cat.go b/base/nfs/cat.go index d84b9b32..dbb74f36 100644 --- a/base/nfs/cat.go +++ b/base/nfs/cat.go @@ -72,6 +72,7 @@ const ( BINARY = "binary" SCRIPT = "script" + CLONE = "clone" REPOS = "repos" REMOTE = "remote" ORIGIN = "origin" diff --git a/base/web/dream.go b/base/web/dream.go index 61045351..ed0099b0 100644 --- a/base/web/dream.go +++ b/base/web/dream.go @@ -31,16 +31,16 @@ func _dream_list(m *ice.Message) *ice.Message { if space, ok := list[value[mdb.NAME]]; ok { msg := gdb.Event(m.Spawn(value, space), DREAM_TABLES).Copy(m.Spawn().PushButton(cli.STOP)) m.Push(mdb.TYPE, space[mdb.TYPE]).Push(cli.STATUS, cli.START) - m.Push(nfs.VERSION, space[nfs.VERSION]).Push(mdb.TEXT, msg.Append(mdb.TEXT)) + m.Push(nfs.MODULE, space[nfs.MODULE]).Push(nfs.VERSION, space[nfs.VERSION]).Push(mdb.TEXT, msg.Append(mdb.TEXT)) m.PushButton(strings.Join(msg.Appendv(ctx.ACTION), "")) } else { if m.Push(mdb.TYPE, WORKER); nfs.Exists(m, path.Join(ice.USR_LOCAL_WORK, value[mdb.NAME])) { m.Push(cli.STATUS, cli.STOP) - m.Push(nfs.VERSION, "").Push(mdb.TEXT, "") + m.Push(nfs.MODULE, "").Push(nfs.VERSION, "").Push(mdb.TEXT, "") m.PushButton(cli.START, nfs.TRASH) } else { m.Push(cli.STATUS, cli.BEGIN) - m.Push(nfs.VERSION, "").Push(mdb.TEXT, "") + m.Push(nfs.MODULE, "").Push(nfs.VERSION, "").Push(mdb.TEXT, "") m.PushButton(cli.START, mdb.REMOVE) } } @@ -364,7 +364,7 @@ func init() { } }}, }, StatsAction(), DreamAction(), mdb.ImportantHashAction( - mdb.SHORT, mdb.NAME, mdb.FIELD, "time,name,icon,repos,binary,template,restart", ctx.TOOLS, kit.Simple(CODE_GIT_SEARCH, ROUTE, SPIDE), + mdb.SHORT, mdb.NAME, mdb.FIELD, "time,name,icon,repos,binary,template,restart", ctx.TOOLS, kit.Simple(STORE, SPIDE, ROUTE), html.BUTTON, kit.JoinWord(PORTAL, ADMIN, DESKTOP, WIKI_WORD, STATUS, VIMER, XTERM, COMPILE), )), Hand: func(m *ice.Message, arg ...string) { if len(arg) == 0 { @@ -384,34 +384,30 @@ func init() { }) ctx.DisplayTableCard(m) kit.If(cli.SystemFind(m, "go"), func() { - m.Action(mdb.CREATE, STARTALL, STOPALL, cli.BUILD, PUBLISH) + m.Action("filter", mdb.CREATE, STARTALL, STOPALL, cli.BUILD, PUBLISH) }, func() { m.Action(mdb.CREATE, STARTALL, STOPALL) }) msg := m.Cmds(SPACE) msg.Table(func(value ice.Maps) { + value[mdb.ICON] = nfs.USR_ICONS_VOLCANOS + value[mdb.STATUS] = cli.START + value[nfs.REPOS] = "https://" + value[nfs.MODULE] switch value[mdb.TYPE] { case SERVER: - m.Push(mdb.TYPE, value[mdb.TYPE]) - m.Push(mdb.NAME, value[mdb.NAME]) - m.Push(mdb.ICON, nfs.USR_ICONS_ICEBERGS) - m.Push(mdb.TEXT, value[mdb.TEXT]) + value[mdb.ICON] = nfs.USR_ICONS_ICEBERGS msg := gdb.Event(m.Spawn(value), DREAM_TABLES) - m.PushButton(strings.Join(msg.Appendv(ctx.ACTION), "")) + defer m.PushButton(strings.Join(msg.Appendv(ctx.ACTION), "")) case MASTER: - m.Push(mdb.TYPE, value[mdb.TYPE]) - m.Push(mdb.NAME, value[mdb.NAME]) - m.Push(mdb.ICON, nfs.USR_ICONS_VOLCANOS) - m.Push(mdb.TEXT, value[mdb.TEXT]) msg := gdb.Event(m.Spawn(value), DREAM_TABLES) - m.PushButton(strings.Join(msg.Appendv(ctx.ACTION), "")) + defer m.PushButton(strings.Join(msg.Appendv(ctx.ACTION), "")) case aaa.LOGIN: - m.Push(mdb.TYPE, value[mdb.TYPE]) - m.Push(mdb.NAME, value[mdb.NAME]) - m.Push(mdb.ICON, nfs.USR_ICONS_VOLCANOS) - m.Push(mdb.TEXT, kit.JoinWord(value["agent"], value[cli.SYSTEM], value[aaa.IP])) - m.PushButton("grant") + value[mdb.TEXT] = kit.JoinWord(value["agent"], value[cli.SYSTEM], value[aaa.IP]) + defer m.PushButton("grant") + default: + return } + m.Push("", value, kit.Split(mdb.Config(m, mdb.FIELD)+",type,status,module,version,text")) }) stat := map[string]int{} m.Table(func(value ice.Maps) { stat[value[mdb.TYPE]]++; stat[value[mdb.STATUS]]++ }) diff --git a/base/web/space.go b/base/web/space.go index 747ffea7..e5ba5768 100644 --- a/base/web/space.go +++ b/base/web/space.go @@ -32,8 +32,8 @@ func _space_qrcode(m *ice.Message, dev string) { func _space_dial(m *ice.Message, dev, name string, arg ...string) { origin := m.Cmdv(SPIDE, dev, CLIENT_ORIGIN) u := kit.ParseURL(kit.MergeURL2(strings.Replace(origin, HTTP, "ws", 1), PP(SPACE), mdb.TYPE, ice.Info.NodeType, mdb.NAME, name, - nfs.MODULE, ice.Info.Make.Module, nfs.VERSION, ice.Info.Make.Versions(), "goos", runtime.GOOS, "goarch", runtime.GOARCH, arg)) - args := kit.SimpleKV("type,name,host,port", u.Scheme, dev, u.Hostname(), kit.Select(kit.Select("443", "80", u.Scheme == "ws"), u.Port())) + 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{} redial := kit.Dict(mdb.Configv(m, REDIAL)) @@ -52,10 +52,10 @@ func _space_dial(m *ice.Message, dev, name string, arg ...string) { }, kit.Join(kit.Simple(SPACE, name), lex.SP)) } func _space_agent(m *ice.Message, args ...string) []string { - kit.If(m.Option("goos"), func(p string) { args = append(args, "system", p) }) + kit.If(m.Option(cli.GOOS), func(p string) { args = append(args, cli.SYSTEM, p) }) for _, p := range []string{"Android", "iPhone", "Mac", "Windows"} { if strings.Contains(m.Option(ice.MSG_USERUA), p) { - args = append(args, "system", p) + args = append(args, cli.SYSTEM, p) break } } @@ -182,11 +182,8 @@ func _space_exec(m *ice.Message, name string, source, target []string, c *websoc switch kit.Select(cli.PWD, m.Detailv(), 0) { case cli.PWD: mdb.HashModify(m, mdb.HASH, name, - aaa.USERNICK, m.Option(ice.MSG_USERNICK), - aaa.USERNAME, m.Option(ice.MSG_USERNAME), - aaa.USERROLE, m.Option(ice.MSG_USERROLE), - aaa.IP, m.Option(ice.MSG_USERIP), - m.OptionSimple(nfs.MODULE, nfs.VERSION, AGENT, cli.SYSTEM), + aaa.USERNICK, m.Option(ice.MSG_USERNICK), aaa.USERNAME, m.Option(ice.MSG_USERNAME), aaa.USERROLE, m.Option(ice.MSG_USERROLE), + aaa.IP, m.Option(ice.MSG_USERIP), aaa.UA, m.Option(ice.MSG_USERUA), m.OptionSimple(nfs.MODULE, nfs.VERSION, AGENT, cli.SYSTEM), ) m.Push(mdb.LINK, m.MergePod(kit.Select("", source, -1))) default: diff --git a/base/web/spide.go b/base/web/spide.go index c943b953..01f43dea 100644 --- a/base/web/spide.go +++ b/base/web/spide.go @@ -24,12 +24,13 @@ import ( kit "shylinux.com/x/toolkits" ) -func _spide_create(m *ice.Message, name, link string) { +func _spide_create(m *ice.Message, name, link, types string) { if u, e := url.Parse(link); !m.Warn(e != nil || link == "", ice.ErrNotValid, link) { dir, file := path.Split(u.EscapedPath()) m.Logs(mdb.INSERT, SPIDE, name, LINK, link) mdb.HashSelectUpdate(m, mdb.HashCreate(m, CLIENT_NAME, name), func(value ice.Map) { - value[SPIDE_CLIENT] = kit.Dict(mdb.NAME, name, SPIDE_METHOD, http.MethodGet, URL, link, ORIGIN, u.Scheme+"://"+u.Host, + value[SPIDE_CLIENT] = kit.Dict( + mdb.NAME, name, mdb.TYPE, types, SPIDE_METHOD, http.MethodGet, URL, link, ORIGIN, u.Scheme+"://"+u.Host, tcp.PROTOCOL, u.Scheme, tcp.HOSTNAME, u.Hostname(), tcp.HOST, u.Host, nfs.PATH, dir, nfs.FILE, file, cli.TIMEOUT, "300s", ) }) @@ -243,6 +244,7 @@ const ( CLIENT_URL = "client.url" CLIENT_NAME = "client.name" + CLIENT_TYPE = "client.type" CLIENT_METHOD = "client.method" CLIENT_ORIGIN = "client.origin" CLIENT_TIMEOUT = "client.timeout" @@ -293,16 +295,17 @@ func init() { Index.MergeCommands(ice.Commands{ // SPIDE: {Name: "spide client.name action=raw,msg,save,cache method=GET,PUT,POST,DELETE url format=form,part,json,data,file arg run create", Help: "蜘蛛侠", Actions: ice.MergeActions(ice.Actions{ SPIDE: {Help: "蜘蛛侠", Meta: kit.Dict(ice.CTX_TRANS, kit.Dict(html.INPUT, kit.Dict( + CLIENT_TYPE, "类型", CLIENT_NAME, "名称", CLIENT_URL, "地址", CLIENT_METHOD, "方法", CLIENT_ORIGIN, "服务", CLIENT_TIMEOUT, "超时", CLIENT_PROTOCOL, "协议", CLIENT_HOST, "主机", CLIENT_HOSTNAME, "机器", ))), Actions: ice.MergeActions(ice.Actions{ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { conf := mdb.Confm(m, cli.RUNTIME, cli.CONF) - m.Cmd("", mdb.CREATE, ice.SHY, kit.Select("https://shylinux.com", conf[cli.CTX_SHY])) - m.Cmd("", mdb.CREATE, ice.DEV, kit.Select("https://2021.shylinux.com", ice.Info.Make.Domain, conf[cli.CTX_DEV])) - m.Cmd("", mdb.CREATE, "dev_ip", kit.Select("https://2021.shylinux.com", os.Getenv("ctx_dev_ip"))) - m.Cmd("", mdb.CREATE, ice.OPS, kit.Select("http://localhost:9020", conf[cli.CTX_OPS])) + m.Cmd("", mdb.CREATE, ice.SHY, kit.Select("https://shylinux.com", conf[cli.CTX_SHY]), nfs.REPOS) + m.Cmd("", mdb.CREATE, ice.DEV, kit.Select("https://2021.shylinux.com", ice.Info.Make.Domain, conf[cli.CTX_DEV]), nfs.REPOS) + m.Cmd("", mdb.CREATE, "dev_ip", kit.Select("https://2021.shylinux.com", os.Getenv("ctx_dev_ip")), nfs.REPOS) + m.Cmd("", mdb.CREATE, ice.OPS, kit.Select("http://localhost:9020", conf[cli.CTX_OPS]), nfs.REPOS) m.Cmd("", mdb.CREATE, ice.DEMO, kit.Select("http://localhost:20000", conf[cli.CTX_DEMO])) m.Cmd("", mdb.CREATE, ice.MAIL, kit.Select("https://mail.shylinux.com", conf[cli.CTX_MAIL])) m.Cmd("", mdb.CREATE, nfs.REPOS, kit.Select("https://repos.shylinux.com", conf[cli.CTX_HUB])) @@ -329,11 +332,19 @@ func init() { case mdb.KEY: m.Push(arg[0], html.Authorization) } + case CLIENT_NAME: + mdb.HashSelectValue(m.Spawn(), func(value ice.Map) { + m.Push(arg[0], kit.Value(value, CLIENT_NAME)) + m.Push(mdb.TYPE, kit.Value(value, CLIENT_TYPE)) + }) + m.Sort(arg[0]) default: mdb.HashSelectValue(m.Spawn(), func(value ice.Map) { m.Push(kit.Select(ORIGIN, arg, 0), kit.Value(value, CLIENT_ORIGIN)) }) } }}, - mdb.CREATE: {Name: "create name link", Hand: func(m *ice.Message, arg ...string) { _spide_create(m, m.Option(mdb.NAME), m.Option(LINK)) }}, + mdb.CREATE: {Name: "create name origin type", Hand: func(m *ice.Message, arg ...string) { + _spide_create(m, m.Option(mdb.NAME), m.Option(ORIGIN), m.Option(mdb.TYPE)) + }}, 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)) }}, @@ -354,10 +365,10 @@ func init() { DEV_CREATE_TOKEN: {Hand: func(m *ice.Message, arg ...string) { m.Cmd(SPACE, tcp.DIAL, ice.DEV, m.Option(CLIENT_NAME), m.OptionSimple(TOKEN)) }}, - }, DevTokenAction(CLIENT_NAME, CLIENT_URL), mdb.HashAction(mdb.SHORT, CLIENT_NAME, mdb.FIELD, "time,client.name,client.url,token")), Hand: func(m *ice.Message, arg ...string) { + }, DevTokenAction(CLIENT_NAME, CLIENT_URL), mdb.HashAction(mdb.SHORT, CLIENT_NAME, mdb.FIELD, "time,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_NAME) + mdb.HashSelect(m, kit.Slice(arg, 0, 1)...).Sort("client.type,client.name", []string{nfs.REPOS, ""}) m.Table(func(value ice.Maps) { if _, ok := list[value[CLIENT_NAME]]; ok { m.Push(mdb.STATUS, ONLINE) diff --git a/base/web/web.go b/base/web/web.go index d11f2105..28796145 100644 --- a/base/web/web.go +++ b/base/web/web.go @@ -81,6 +81,7 @@ func init() { ice.Index.Register(Index, &Frame{}, BROAD, SERVE, DREAM, ROUTE, SPACE, TOKEN, SHARE, CACHE, SPIDE, COUNT, + STORE, ADMIN, STATS, ) } diff --git a/core/chat/macos/desktop.go b/core/chat/macos/desktop.go index 87babf42..82c2e80a 100644 --- a/core/chat/macos/desktop.go +++ b/core/chat/macos/desktop.go @@ -33,6 +33,7 @@ func init() { DockAppend(m, "git.png", web.CODE_GIT_STATUS) DockAppend(m, "vimer.png", web.CODE_VIMER) } + AppInstall(m, "App Store.png", web.STORE) m.Travel(func(p *ice.Context, c *ice.Context, key string, cmd *ice.Command) { kit.If(cmd.Icon, func() { if !kit.HasPrefix(cmd.Icon, nfs.PS, web.HTTP) { diff --git a/core/chat/pod.go b/core/chat/pod.go index dea4d631..71aa7ad3 100644 --- a/core/chat/pod.go +++ b/core/chat/pod.go @@ -25,6 +25,7 @@ func init() { 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) }) }) + m.Cut("name,size,time") m.RenderResult() } else if strings.HasPrefix(m.Option(ice.MSG_USERUA), "git/") { m.RenderRedirect(kit.MergeURL2(m.Cmdv(web.SPACE, arg[0], web.CODE_GIT_REPOS, nfs.REMOTE, nfs.REMOTE), "/info/refs", m.OptionSimple("service"))) diff --git a/core/chat/script.js b/core/chat/script.js index 19d3f268..3754f4b7 100644 --- a/core/chat/script.js +++ b/core/chat/script.js @@ -21,10 +21,14 @@ Volcanos(chat.ONACTION, { function action(skip) { sub.Update(sub.request({}, {_handle: ice.TRUE}), [ctx.ACTION, msg.Option(cli.PLAY)], function(msg) { sub.onimport._process(sub, msg) || msg.Length() == 0 && msg.Result() == "" || can.onappend._output(sub, msg), next && next() }) } - can.onmotion.delay(can, function() { if (done || sub._auto) { return } done = true, action() }, 300) - sub.onexport.output = function() { if (done) { return } done = true, action(true) - can.page.style(can, sub._output, html.HEIGHT, "", html.MAX_HEIGHT, "") - }, can.onmotion.delay(can, function() { can.onmotion.scrollIntoView(can, sub._target) }, 300) + if (msg.Option(ctx.STYLE) == "async") { + done = true, sub.Update(sub.request({}, {_handle: ice.TRUE}), [ctx.ACTION, msg.Option(cli.PLAY)]), next && next() + } else { + can.onmotion.delay(can, function() { if (done || sub._auto) { return } done = true, action() }, 300) + } + sub.onexport.output = function() { can.page.style(can, sub._output, html.HEIGHT, "", html.MAX_HEIGHT, "") + if (done) { return } done = true, action(true) + }, msg.Option(ctx.STYLE) == html.HIDE || can.onmotion.delay(can, function() { can.onmotion.scrollIntoView(can, sub._target) }, 300) }) }, }) diff --git a/meta.go b/meta.go index ab1c90f7..c977082c 100644 --- a/meta.go +++ b/meta.go @@ -68,6 +68,7 @@ func (m *Message) Push(key string, value Any, arg ...Any) *Message { kit.If(len(head) == 0, func() { head = kit.SortedKey(kit.KeyValue(nil, "", value)) }) kit.If(len(arg) > 1, func() { val, _ = arg[1].(Map) }) kit.For(head, func(k string) { + k = strings.TrimSuffix(k, "*") var v Any switch k { case "_target": @@ -107,15 +108,16 @@ func (m *Message) Push(key string, value Any, arg ...Any) *Message { }) case Maps: kit.If(len(head) == 0, func() { head = kit.SortedKey(value) }) - kit.For(head, func(k string) { m.Push(k, value[k]) }) + kit.For(head, func(k string) { + k = strings.TrimSuffix(k, "*") + m.Push(k, value[k]) + }) default: kit.For(kit.Simple(value, arg), func(v string) { + key = strings.TrimSuffix(key, "*") if m.FieldsIsDetail() { m.Add(MSG_APPEND, KEY, key).Add(MSG_APPEND, VALUE, kit.Format(value)) } else { - if m.ActionKey() == INPUTS && kit.IndexOf(m.value(key), v) > -1 { - // return - } m.Add(MSG_APPEND, key, v) } }) @@ -317,6 +319,8 @@ func (m *Message) Sort(key string, arg ...Any) *Message { for s, k := range keys { if a, b := list[i][k], list[j][k]; a != b { if v, ok := order[k]; ok { + kit.If(v[a] == 0, func() { v[a] = len(v) + 1 }) + kit.If(v[b] == 0, func() { v[b] = len(v) + 1 }) if v[a] > v[b] { return true } else if v[a] < v[b] { diff --git a/misc/git/search.go b/misc/git/search.go index d7f7c227..b7b3220a 100644 --- a/misc/git/search.go +++ b/misc/git/search.go @@ -11,7 +11,6 @@ import ( "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/base/web" - "shylinux.com/x/icebergs/core/chat/macos" kit "shylinux.com/x/toolkits" ) @@ -30,11 +29,10 @@ func init() { const SEARCH = "search" Index.MergeCommands(ice.Commands{ SEARCH: {Name: "search keyword auto", Help: "源码库", Role: aaa.VOID, Actions: ice.MergeActions(ice.Actions{ - ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { macos.AppInstall(m, "App Store.png", m.PrefixKey()) }}, - cli.START: {Name: "start name*", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(web.DREAM, mdb.CREATE); m.Cmdy(web.DREAM, cli.START) }}, - CLONE: {Name: "clone name*", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(REPOS, CLONE, m.Option(REPOS)) }}, - HTML_URL: {Help: "源码", Hand: func(m *ice.Message, arg ...string) { m.ProcessOpen(m.Option(HTML_URL)) }}, - WEBSITE: {Help: "官网", Hand: func(m *ice.Message, arg ...string) { m.ProcessOpen(m.Option(WEBSITE)) }}, + cli.START: {Name: "start name*", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(web.DREAM, mdb.CREATE); m.Cmdy(web.DREAM, cli.START) }}, + CLONE: {Name: "clone name*", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(REPOS, CLONE, m.Option(REPOS)) }}, + HTML_URL: {Help: "源码", Hand: func(m *ice.Message, arg ...string) { m.ProcessOpen(m.Option(HTML_URL)) }}, + WEBSITE: {Help: "官网", Hand: func(m *ice.Message, arg ...string) { m.ProcessOpen(m.Option(WEBSITE)) }}, ORIGIN: {Help: "平台", Icon: "bi bi-box-arrow-up-right", Hand: func(m *ice.Message, arg ...string) { m.ProcessOpen(web.SpideOrigin(m, REPOS) + EXPLORE_REPOS) }},