From 0adc958bc2b4262f88bee78c71bc70e27856fc9b Mon Sep 17 00:00:00 2001 From: shylinux Date: Fri, 24 Mar 2023 15:14:29 +0800 Subject: [PATCH] opt icebergs --- README.md | 2 +- base/aaa/totp.go | 2 +- base/cli/daemon.go | 4 +- base/cli/runtime.go | 4 - base/ctx/command.go | 8 +- base/ctx/config.go | 2 +- base/ctx/process.go | 2 +- base/gdb/event.go | 2 +- base/gdb/signal.go | 2 +- base/gdb/timer.go | 2 +- base/log/tail.go | 2 +- base/mdb/hash.go | 2 +- base/mdb/mdb.go | 2 +- base/mdb/render.go | 2 +- base/mdb/search.go | 6 +- base/nfs/dir.go | 4 +- base/nfs/trash.go | 2 +- base/ssh/render.go | 2 +- base/web/cache.go | 7 +- base/web/dream.go | 2 +- base/web/option.go | 2 +- base/web/render.go | 10 +- base/web/serve.go | 11 +- base/web/share.go | 2 +- base/web/space.go | 8 +- base/web/web.go | 2 +- conf.go | 128 +++++++------ core/chat/action.go | 2 +- core/chat/favor.go | 4 +- core/chat/grant.go | 4 +- core/chat/sso.go | 2 +- core/chat/theme.go | 4 +- core/chat/website.go | 2 +- core/code/binpack.go | 4 +- core/code/favor.go | 2 +- core/code/install.go | 2 +- core/code/pprof.go | 2 +- core/code/publish.go | 4 +- core/code/upgrade.go | 2 +- core/code/vimer.go | 14 +- core/code/webpack.go | 10 +- core/mall/asset.go | 4 +- core/mall/salary.go | 2 +- core/team/epic.go | 2 +- core/team/task.go | 2 +- core/wiki/wiki.go | 2 +- core/wiki/word.go | 2 +- data.go | 14 +- exec.go | 168 +++++++++++++++-- info.go | 182 +++++++++++++++--- init.go | 9 +- logs.go | 137 ++++---------- meta.go | 312 +++++++++++-------------------- misc.go | 421 +++--------------------------------------- misc/alpha/alpha.go | 2 +- misc/bash/download.go | 2 +- misc/bash/favor.go | 2 +- misc/bash/grant.go | 2 +- misc/bash/run.go | 2 +- misc/chrome/daemon.go | 6 +- misc/chrome/field.go | 2 +- misc/chrome/spide.go | 2 +- misc/chrome/style.go | 2 +- misc/coder/server.go | 4 +- misc/git/server.go | 4 +- misc/git/status.go | 5 +- misc/git/total.go | 9 +- misc/lark/sso.go | 2 +- misc/lark/talk.go | 2 +- misc/ssh/channel.go | 2 +- misc/ssh/connect.go | 7 +- misc/ssh/rsa.go | 2 +- misc/ssh/service.go | 10 +- misc/ssh/session.go | 4 +- misc/tmux/session.go | 2 +- misc/vim/tags.go | 8 +- misc/wx/favor.go | 2 +- misc/wx/menu.go | 4 +- misc/wx/text.go | 2 +- option.go | 35 ++-- render.go | 20 +- type.go | 82 +++++--- 82 files changed, 747 insertions(+), 1020 deletions(-) diff --git a/README.md b/README.md index 2061e1e2..85b6769e 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ # icebergs -icebergs 是一个应用框架,通过模块化、集群化、自动化方式,在各种设备上,一键部署完整的个人云计算与云研发平台。 +icebergs 是一个应用框架,通过群化、模块化、集自动化方式,在各种设备上,一键部署完整的个人云计算与云研发平台。 diff --git a/base/aaa/totp.go b/base/aaa/totp.go index 1e6ecfcb..b04d0967 100644 --- a/base/aaa/totp.go +++ b/base/aaa/totp.go @@ -52,7 +52,7 @@ func init() { mdb.HashCreate(m, m.OptionSimple(mdb.NAME, NUMBER, PERIOD, SECRET)) }}, }, mdb.HashAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,name,number,period,secret", mdb.LINK, "otpauth://totp/%s?secret=%s")), Hand: func(m *ice.Message, arg ...string) { - mdb.HashSelect(m.Spawn(), arg...).Tables(func(value ice.Maps) { + mdb.HashSelect(m.Spawn(), arg...).Table(func(value ice.Maps) { kit.If(len(arg) > 0, func() { m.OptionFields(ice.FIELDS_DETAIL) }) m.Push(mdb.TIME, m.Time()).Push(mdb.NAME, value[mdb.NAME]) period := kit.Int64(value[PERIOD]) diff --git a/base/cli/daemon.go b/base/cli/daemon.go index c084f70f..543356b0 100644 --- a/base/cli/daemon.go +++ b/base/cli/daemon.go @@ -120,7 +120,7 @@ func init() { STOP: {Hand: func(m *ice.Message, arg ...string) { m.OptionFields(mdb.HashField(m)) h, pid := m.Option(mdb.HASH), m.Option(PID) - mdb.HashSelect(m, m.Option(mdb.HASH)).Tables(func(value ice.Maps) { + mdb.HashSelect(m, m.Option(mdb.HASH)).Table(func(value ice.Maps) { if h == "" && value[PID] != pid { return } @@ -130,7 +130,7 @@ func init() { }}, }, mdb.StatusHashAction(mdb.FIELD, "time,hash,status,pid,cmd,dir,env")), Hand: func(m *ice.Message, arg ...string) { if len(arg) == 0 || !strings.Contains(arg[0], ice.PS) { - if mdb.HashSelect(m, kit.Slice(arg, 0, 1)...).Tables(func(value ice.Maps) { + if mdb.HashSelect(m, kit.Slice(arg, 0, 1)...).Table(func(value ice.Maps) { switch value[STATUS] { case START: m.PushButton(RESTART, STOP) diff --git a/base/cli/runtime.go b/base/cli/runtime.go index 2f30f465..09688943 100644 --- a/base/cli/runtime.go +++ b/base/cli/runtime.go @@ -32,10 +32,6 @@ func _runtime_init(m *ice.Message) { switch m.Conf(RUNTIME, kit.Keys(CONF, k), kit.Env(k)); k { case CTX_PID: ice.Info.PidPath = kit.Env(k) - case CTX_SHARE: - ice.Info.CtxShare = kit.Env(k) - case CTX_RIVER: - ice.Info.CtxRiver = kit.Env(k) } } m.Conf(RUNTIME, kit.Keys(BOOT, HOSTNAME), kit.Env("HOSTNAME")) diff --git a/base/ctx/command.go b/base/ctx/command.go index b1bc5990..aec9ec9d 100644 --- a/base/ctx/command.go +++ b/base/ctx/command.go @@ -57,7 +57,7 @@ func _command_search(m *ice.Message, kind, name, text string) { } m.PushSearch(ice.CTX, kit.PathName(1), ice.CMD, kit.FileName(1), kit.SimpleKV("", s.Cap(ice.CTX_FOLLOW), cmd.Name, cmd.Help), CONTEXT, s.Cap(ice.CTX_FOLLOW), COMMAND, key, INDEX, kit.Keys(s.Cap(ice.CTX_FOLLOW), key), - mdb.HELP, cmd.Help, nfs.FILE, FileURI(cmd.GetFileLines()), + mdb.HELP, cmd.Help, nfs.FILE, FileURI(cmd.FileLine()), ) }) m.Sort(m.OptionFields()) @@ -91,7 +91,7 @@ func init() { mdb.EXPORT: {Hand: func(m *ice.Message, arg ...string) { TravelCmd(m, func(key, file, line string) { m.Push(mdb.NAME, key).Push(nfs.FILE, file).Push(nfs.LINE, line) - }).Sort(mdb.NAME).Tables(func(value ice.Maps) { + }).Sort(mdb.NAME).Table(func(value ice.Maps) { m.Echo(`%s %s %s;" f`+ice.NL, value[mdb.NAME], value[nfs.FILE], value[nfs.LINE]) }).Cmd(nfs.SAVE, "tags", m.Result()) }}, @@ -181,7 +181,7 @@ func GetFileCmd(dir string) string { } func GetCmdFile(m *ice.Message, cmds string) (file string) { m.Search(cmds, func(key string, cmd *ice.Command) { - if file = strings.TrimPrefix(FileURI(kit.Split(cmd.GetFileLines(), ice.DF)[0]), "/require/"); !nfs.ExistsFile(m, file) { + if file = strings.TrimPrefix(FileURI(kit.Split(cmd.FileLine(), ice.DF)[0]), "/require/"); !nfs.ExistsFile(m, file) { file = path.Join(ice.ISH_PLUGED, file) } }) @@ -192,7 +192,7 @@ func TravelCmd(m *ice.Message, cb func(key, file, line string)) *ice.Message { if IsOrderCmd(key) { return } - if ls := kit.Split(cmd.GetFileLines(), ice.DF); len(ls) > 0 && cmd.Name != "" { + if ls := kit.Split(cmd.FileLine(), ice.DF); len(ls) > 0 && cmd.Name != "" { cb(kit.Keys(s.Cap(ice.CTX_FOLLOW), key), strings.TrimPrefix(ls[0], kit.Path("")+ice.PS), kit.Select("1", ls, 1)) } }) diff --git a/base/ctx/config.go b/base/ctx/config.go index cca3b8b2..bae573bf 100644 --- a/base/ctx/config.go +++ b/base/ctx/config.go @@ -55,7 +55,7 @@ func _config_load(m *ice.Message, name string, arg ...string) { data, msg := ice.Map{}, m.Spawn(m.Source()) json.NewDecoder(f).Decode(&data) for k, v := range data { - msg.Search(k, func(p *ice.Context, s *ice.Context, key string) { + msg.Search(k, func(p *ice.Context, s *ice.Context, key string, conf *ice.Config) { if s.Configs[key] == nil { s.Configs[key] = &ice.Config{} } diff --git a/base/ctx/process.go b/base/ctx/process.go index b4cd98dd..6a1266cc 100644 --- a/base/ctx/process.go +++ b/base/ctx/process.go @@ -41,7 +41,7 @@ func Process(m *ice.Message, key string, args ice.Any, arg ...string) { } func ProcessField(m *ice.Message, cmd string, args ice.Any, arg ...string) *ice.Message { if cmd = kit.Select(m.ActionKey(), cmd); !kit.HasPrefixList(arg, ice.RUN) { - m.Cmdy(COMMAND, cmd).Push(ARGS, _process_args(m, args)).ProcessField(ACTION, m.ActionKey(), ice.RUN).Option("_index", m.PrefixKey()) + m.Cmdy(COMMAND, cmd).Push(ARGS, _process_args(m, args)).Options(ice.MSG_INDEX, m.PrefixKey()).ProcessField(ACTION, m.ActionKey(), ice.RUN) } else { kit.If(aaa.Right(m, cmd, arg[1:]), func() { m.Cmdy(cmd, arg[1:]) }) } diff --git a/base/gdb/event.go b/base/gdb/event.go index bec3f35f..b759f8ee 100644 --- a/base/gdb/event.go +++ b/base/gdb/event.go @@ -25,7 +25,7 @@ func init() { HAPPEN: {Name: "happen event*", Help: "触发", Hand: func(m *ice.Message, arg ...string) { defer m.Cost() m.OptionCB(mdb.SELECT, "") - mdb.ZoneSelect(m.Spawn(ice.OptionFields("")), arg[1]).Tables(func(value ice.Maps) { + mdb.ZoneSelect(m.Spawn(ice.OptionFields("")), arg[1]).Table(func(value ice.Maps) { m.Cmdy(kit.Split(value[ice.CMD]), arg[1], arg[2:], ice.OptionFields("")) }) }}, diff --git a/base/gdb/signal.go b/base/gdb/signal.go index 186379b0..fd6f254d 100644 --- a/base/gdb/signal.go +++ b/base/gdb/signal.go @@ -18,7 +18,7 @@ func _signal_listen(m *ice.Message, s int, arg ...string) { } } func _signal_action(m *ice.Message, arg ...string) { - mdb.HashSelect(m.Spawn(), arg...).Tables(func(value ice.Maps) { m.Cmdy(kit.Split(value[ice.CMD])) }) + mdb.HashSelect(m.Spawn(), arg...).Table(func(value ice.Maps) { m.Cmdy(kit.Split(value[ice.CMD])) }) } func _signal_process(m *ice.Message, p string, s os.Signal) { if p == "" { diff --git a/base/gdb/timer.go b/base/gdb/timer.go index 17b89ab0..8d651123 100644 --- a/base/gdb/timer.go +++ b/base/gdb/timer.go @@ -9,7 +9,7 @@ import ( ) func _timer_action(m *ice.Message, now time.Time, arg ...string) { - mdb.HashSelects(m).Tables(func(value ice.Maps) { + mdb.HashSelects(m).Table(func(value ice.Maps) { if value[mdb.COUNT] == "0" { return } diff --git a/base/log/tail.go b/base/log/tail.go index ba5b146e..e2eb190c 100644 --- a/base/log/tail.go +++ b/base/log/tail.go @@ -25,7 +25,7 @@ func init() { Index.MergeCommands(ice.Commands{ TAIL: {Name: "tail name id auto page create", Help: "日志流", Actions: ice.MergeActions(ice.Actions{ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { - mdb.HashSelect(m.Spawn(ice.OptionFields("name,file"))).Tables(func(value ice.Maps) { + mdb.HashSelect(m.Spawn(ice.OptionFields("name,file"))).Table(func(value ice.Maps) { m.Cmd("", mdb.CREATE, kit.SimpleKV("name,file", value)) }) }}, diff --git a/base/mdb/hash.go b/base/mdb/hash.go index a4024b74..4b4f7afa 100644 --- a/base/mdb/hash.go +++ b/base/mdb/hash.go @@ -63,7 +63,7 @@ func _hash_modify(m *ice.Message, prefix, chain string, field, value string, arg } func _hash_select(m *ice.Message, prefix, chain, field, value string) { kit.If(field == HASH && value == RANDOM, func() { value = RANDOMS }) - defer m.SortTimeR(TIME) + defer m.SortStrR(TIME) fields := _hash_fields(m) defer RLock(m, prefix, chain)() Richs(m, prefix, chain, value, func(key string, value Map) { _mdb_select(m, m.OptionCB(""), key, value, fields, nil) }) diff --git a/base/mdb/mdb.go b/base/mdb/mdb.go index f0774856..fde0eb92 100644 --- a/base/mdb/mdb.go +++ b/base/mdb/mdb.go @@ -174,7 +174,7 @@ var Index = &ice.Context{Name: MDB, Help: "数据模块", Commands: ice.Commands kit.Switch(arg[2], HASH, func() { _hash_prunes(m, arg[0], arg[1], arg[3:]...) - m.Tables(func(value Maps) { _hash_delete(m, arg[0], arg[1], HASH, value[HASH]) }) + m.Table(func(value Maps) { _hash_delete(m, arg[0], arg[1], HASH, value[HASH]) }) }, // ZONE, func() { _list_prunes(m, arg[0], _domain_chain(m, kit.Keys(arg[1], kit.KeyHash(arg[3]))), arg[4:]...) }, // LIST, func() { _list_prunes(m, arg[0], arg[1], arg[3:]...) }, diff --git a/base/mdb/render.go b/base/mdb/render.go index 4c18abcb..b0d77599 100644 --- a/base/mdb/render.go +++ b/base/mdb/render.go @@ -18,7 +18,7 @@ func RenderAction(arg ...ice.Any) ice.Actions { return } kit.For(kit.Split(arg[0]), func(k string) { - HashSelects(m.Spawn(), k).Tables(func(value ice.Maps) { + HashSelects(m.Spawn(), k).Table(func(value ice.Maps) { m.Cmdy(kit.Keys(value[TEXT], value[NAME]), m.CommandKey(), k, arg[1], kit.Select("", arg, 2), kit.Slice(arg, 3)) }) }) diff --git a/base/mdb/search.go b/base/mdb/search.go index 3f07717b..48a8a886 100644 --- a/base/mdb/search.go +++ b/base/mdb/search.go @@ -6,10 +6,10 @@ const SEARCH = "search" func init() { Index.MergeCommands(ice.Commands{SEARCH: {Help: "搜索", Actions: RenderAction()}}) - ice.AddMerges(func(c *ice.Context, key string, cmd *ice.Command, sub string, action *ice.Action) (ice.Handler, ice.Handler) { + ice.AddMerges(func(c *ice.Context, key string, cmd *ice.Command, sub string, action *ice.Action) ice.Handler { if sub == SEARCH { - return func(m *ice.Message, arg ...string) { m.Cmd(sub, CREATE, m.CommandKey(), m.PrefixKey()) }, nil + return func(m *ice.Message, arg ...string) { m.Cmd(sub, CREATE, m.CommandKey(), m.PrefixKey()) } } - return nil, nil + return nil }) } diff --git a/base/nfs/dir.go b/base/nfs/dir.go index 3677c368..950fba1f 100644 --- a/base/nfs/dir.go +++ b/base/nfs/dir.go @@ -183,7 +183,7 @@ func init() { if arg[0] == mdb.FOREACH && arg[1] == "" && m.Cmdx("host", "islocal", m.Option(ice.MSG_USERIP)) == ice.OK { for _, p := range []string{"Desktop", "Documents", "Downloads", "Pictures"} { p := kit.HomePath(p) - m.Cmd(DIR, PWD, mdb.NAME, mdb.TIME, kit.Dict(DIR_ROOT, p)).SortTimeR(mdb.TIME).TablesLimit(5, func(value ice.Maps) { + m.Cmd(DIR, PWD, mdb.NAME, mdb.TIME, kit.Dict(DIR_ROOT, p)).SortStrR(mdb.TIME).TablesLimit(5, func(value ice.Maps) { name := value[mdb.NAME] if len(kit.TrimExt(name)) > 30 { name = name[:10] + ".." + name[len(name)-10:] @@ -237,7 +237,7 @@ func Dir(m *ice.Message, sort string) *ice.Message { func DirDeepAll(m *ice.Message, root, dir string, cb func(ice.Maps), arg ...string) *ice.Message { m.Options(DIR_TYPE, CAT, DIR_ROOT, root, DIR_DEEP, ice.TRUE) defer m.Options(DIR_TYPE, "", DIR_ROOT, "", DIR_DEEP, "") - if msg := m.Cmd(DIR, dir, arg).Tables(cb); cb == nil { + if msg := m.Cmd(DIR, dir, arg).Table(cb); cb == nil { return m.Copy(msg) } else { return msg diff --git a/base/nfs/trash.go b/base/nfs/trash.go index 5d71b20f..8bba5192 100644 --- a/base/nfs/trash.go +++ b/base/nfs/trash.go @@ -47,7 +47,7 @@ func init() { mdb.HashRemove(m, m.OptionSimple(mdb.HASH)) }}, mdb.PRUNES: {Hand: func(m *ice.Message, arg ...string) { - mdb.HashPrunes(m, nil).Tables(func(value ice.Maps) { Remove(m, value[FILE]) }) + mdb.HashPrunes(m, nil).Table(func(value ice.Maps) { Remove(m, value[FILE]) }) }}, }, mdb.HashAction(mdb.SHORT, FROM, mdb.FIELD, "time,hash,from,file", mdb.ACTION, mdb.REVERT))}, }) diff --git a/base/ssh/render.go b/base/ssh/render.go index 439ccc57..4779f7aa 100644 --- a/base/ssh/render.go +++ b/base/ssh/render.go @@ -19,7 +19,7 @@ func Render(msg *ice.Message, cmd string, arg ...ice.Any) (res string) { return res default: if res = msg.Result(); res == "" { - res = msg.Table().Result() + res = msg.TableEcho().Result() } } if fmt.Fprint(msg.O, res); !strings.HasSuffix(res, ice.NL) { diff --git a/base/web/cache.go b/base/web/cache.go index 74c00bc9..257e0463 100644 --- a/base/web/cache.go +++ b/base/web/cache.go @@ -43,7 +43,7 @@ func _cache_save(m *ice.Message, mime, name, text string, arg ...string) { m.Push(mdb.TYPE, mime).Push(mdb.NAME, name).Push(mdb.TEXT, text).Push(nfs.FILE, file).Push(nfs.SIZE, size) } func _cache_watch(m *ice.Message, key, path string) { - mdb.HashSelect(m.Spawn(), key).Tables(func(value ice.Maps) { + mdb.HashSelect(m.Spawn(), key).Table(func(value ice.Maps) { if value[nfs.FILE] == "" { m.Cmdy(nfs.SAVE, path, value[mdb.TEXT]) } else { @@ -155,7 +155,7 @@ func init() { } }}, }) - ice.AddMerges(func(c *ice.Context, key string, cmd *ice.Command, sub string, action *ice.Action) (ice.Handler, ice.Handler) { + ice.AddMerges(func(c *ice.Context, key string, cmd *ice.Command, sub string, action *ice.Action) { switch sub { case UPLOAD: if c.Name == WEB && key == CACHE { @@ -165,13 +165,12 @@ func init() { action.Hand = ice.MergeHand(func(m *ice.Message, arg ...string) { up := Upload(m) m.Assert(len(up) > 1) - m.Cmd(CACHE, m.Option(ice.MSG_UPLOAD)).Tables(func(value ice.Maps) { m.Options(value) }) + m.Cmd(CACHE, m.Option(ice.MSG_UPLOAD)).Table(func(value ice.Maps) { m.Options(value) }) 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), m.Option(mdb.NAME))) } }, action.Hand) } - return nil, nil }) ctx.Upload = Upload } diff --git a/base/web/dream.go b/base/web/dream.go index 0064bd87..a8c71b09 100644 --- a/base/web/dream.go +++ b/base/web/dream.go @@ -18,7 +18,7 @@ import ( func _dream_list(m *ice.Message) *ice.Message { list := m.CmdMap(SPACE, mdb.NAME) - m.Cmdy(nfs.DIR, ice.USR_LOCAL_WORK, "time,size,name").Tables(func(value ice.Maps) { + m.Cmdy(nfs.DIR, ice.USR_LOCAL_WORK, "time,size,name").Table(func(value ice.Maps) { 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]) diff --git a/base/web/option.go b/base/web/option.go index cd7aff1d..f6346edd 100644 --- a/base/web/option.go +++ b/base/web/option.go @@ -93,7 +93,7 @@ func PushStream(m *ice.Message, cmds ...ice.Any) *ice.Message { } func PushPodCmd(m *ice.Message, cmd string, arg ...string) { if m.Length() > 0 && len(m.Appendv(ice.POD)) == 0 { - m.Tables(func(value ice.Maps) { m.Push(ice.POD, m.Option(ice.MSG_USERPOD)) }) + m.Table(func(value ice.Maps) { m.Push(ice.POD, m.Option(ice.MSG_USERPOD)) }) } m.Cmd(SPACE, ice.OptionFields(mdb.TYPE, mdb.NAME), func(value ice.Maps) { diff --git a/base/web/render.go b/base/web/render.go index 3468bb50..2c9d0c2f 100644 --- a/base/web/render.go +++ b/base/web/render.go @@ -55,7 +55,7 @@ func Render(m *ice.Message, cmd string, args ...ice.Any) bool { m.W.Write([]byte(kit.Format(arg[0], args[1:]...))) } else { if m.Result() == "" && m.Length() > 0 { - m.Table() + m.TableEcho() } m.W.Write([]byte(m.Result())) } @@ -67,7 +67,7 @@ func Render(m *ice.Message, cmd string, args ...ice.Any) bool { m.Echo(kit.Format(cmd, args...)) } RenderType(m.W, nfs.JSON, "") - m.DumpMeta(m.W) + m.FormatsMeta(m.W) } m.Render(ice.RENDER_VOID) return true @@ -116,12 +116,6 @@ func RenderTemplate(m *ice.Message, file string, arg ...ice.Any) *ice.Message { func RenderRefresh(m *ice.Message, arg ...string) { // url text delay RenderTemplate(m, "refresh.html", kit.Select("3", arg, 2), kit.Select(m.Option(ice.MSG_USERWEB), arg, 0), kit.Select("loading...", arg, 1)) } -func RenderIndex(m *ice.Message, file ...string) *ice.Message { - if m.IsCliUA() { - return m.RenderDownload(path.Join(ice.USR_INTSHELL, kit.Select(ice.INDEX_SH, path.Join(file...)))) - } - return m.RenderDownload(path.Join(ice.USR_VOLCANOS, kit.Select("page/"+ice.INDEX_HTML, path.Join(file...)))) -} func RenderMain(m *ice.Message) *ice.Message { if m.IsCliUA() { return m.RenderDownload(path.Join(ice.USR_INTSHELL, ice.INDEX_SH)) diff --git a/base/web/serve.go b/base/web/serve.go index ebf3b4fa..018ae025 100644 --- a/base/web/serve.go +++ b/base/web/serve.go @@ -205,12 +205,6 @@ func init() { m.Echo(ice.Info.Domain) }}, }, mdb.HashAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,status,name,proto,host,port", tcp.LOCALHOST, ice.TRUE), mdb.ClearOnExitHashAction())}, - PP(ice.INTSHELL): {Name: "/intshell/", Help: "命令行", Actions: aaa.WhiteAction(), Hand: func(m *ice.Message, arg ...string) { - RenderIndex(m, arg...) - }}, - PP(ice.VOLCANOS): {Name: "/volcanos/", Help: "浏览器", Actions: aaa.WhiteAction(), Hand: func(m *ice.Message, arg ...string) { - RenderIndex(m, arg...) - }}, PP(ice.PUBLISH): {Name: "/publish/", Help: "定制化", Actions: aaa.WhiteAction(), Hand: func(m *ice.Message, arg ...string) { _share_local(m, ice.USR_PUBLISH, path.Join(arg...)) }}, @@ -242,14 +236,14 @@ func init() { _share_local(m, ice.USR, path.Join(arg...)) }}, PP(REQUIRE_MODULES): {Name: "/require/modules/", Help: "依赖库", Hand: func(m *ice.Message, arg ...string) { - p := path.Join(ice.USR_NODE_MODULES, path.Join(arg...)) + p := path.Join(ice.USR_MODULES, path.Join(arg...)) if !nfs.ExistsFile(m, p) { m.Cmd(cli.SYSTEM, "npm", "install", arg[0], kit.Dict(cli.CMD_DIR, ice.USR)) } m.RenderDownload(p) }}, }) - ice.AddMerges(func(c *ice.Context, key string, cmd *ice.Command, sub string, action *ice.Action) (ice.Handler, ice.Handler) { + ice.AddMerges(func(c *ice.Context, key string, cmd *ice.Command, sub string, action *ice.Action) { if strings.HasPrefix(sub, ice.PS) { if sub = kit.Select(PP(key, sub), PP(key), sub == ice.PS); action.Hand == nil { action.Hand = func(m *ice.Message, arg ...string) { m.Cmdy(key, arg) } @@ -263,7 +257,6 @@ func init() { } c.Commands[sub] = &ice.Command{Name: sub, Help: cmd.Help, Actions: actions, Hand: action.Hand} } - return nil, nil }) } func ServeAction() ice.Actions { return gdb.EventsAction(SERVE_START, SERVE_LOGIN, SERVE_CHECK) } diff --git a/base/web/share.go b/base/web/share.go index 9d1814f6..f193affa 100644 --- a/base/web/share.go +++ b/base/web/share.go @@ -111,7 +111,7 @@ func init() { if m.Option(ice.MSG_USERNAME) == "" && m.Option(SHARE) != "" { switch msg := m.Cmd(SHARE, m.Option(SHARE)); msg.Append(mdb.TYPE) { case STORM, FIELD: - msg.Tables(func(value ice.Maps) { aaa.SessAuth(m, value) }) + msg.Table(func(value ice.Maps) { aaa.SessAuth(m, value) }) } } }}, diff --git a/base/web/space.go b/base/web/space.go index 77a5976c..efe3134f 100644 --- a/base/web/space.go +++ b/base/web/space.go @@ -21,7 +21,7 @@ import ( func _space_dial(m *ice.Message, dev, name string, arg ...string) { msg := m.Cmd(SPIDE, tcp.CLIENT, dev, PP(SPACE)) - uri := kit.ParseURL(strings.Replace(kit.MergeURL(msg.Append(DOMAIN), mdb.TYPE, ice.Info.NodeType, mdb.NAME, name, SHARE, ice.Info.CtxShare, RIVER, ice.Info.CtxRiver, arg), ice.HTTP, "ws", 1)) + uri := kit.ParseURL(strings.Replace(kit.MergeURL(msg.Append(DOMAIN), mdb.TYPE, ice.Info.NodeType, mdb.NAME, name, arg), ice.HTTP, "ws", 1)) args := kit.SimpleKV("type,name,host,port", msg.Append(tcp.PROTOCOL), dev, msg.Append(tcp.HOST), msg.Append(tcp.PORT)) prints := false m.Go(func() { @@ -74,7 +74,7 @@ func _space_handle(m *ice.Message, safe bool, name string, conn *websocket.Conn) } msg := m.Spawn(b) source, target := kit.Simple(msg.Optionv(ice.MSG_SOURCE), name), kit.Simple(msg.Optionv(ice.MSG_TARGET)) - msg.Log("recv", "%v->%v %v %v", source, target, msg.Detailv(), msg.DumpMeta(nil)) + msg.Log("recv", "%v->%v %v %v", source, target, msg.Detailv(), msg.FormatsMeta(nil)) if next := msg.Option(ice.MSG_TARGET); next == "" || len(target) == 0 { if msg.Optionv(ice.MSG_HANDLE, ice.TRUE); safe { // 下行命令 gdb.Event(msg, SPACE_LOGIN) @@ -122,7 +122,7 @@ func _space_echo(m *ice.Message, source, target []string, conn *websocket.Conn) if m.Options(ice.MSG_SOURCE, source, ice.MSG_TARGET, target[1:]); m.Warn(conn.WriteMessage(1, []byte(m.FormatMeta()))) { mdb.HashRemove(m, mdb.NAME, target[0]) } else { - m.Log("send", "%v->%v %v %v", source, target, m.Detailv(), m.DumpMeta(nil)) + m.Log("send", "%v->%v %v %v", source, target, m.Detailv(), m.FormatsMeta(nil)) } } func _space_send(m *ice.Message, space string, arg ...string) { @@ -225,7 +225,7 @@ func init() { ), mdb.ClearOnExitHashAction(), SpaceAction(), aaa.WhiteAction()), Hand: func(m *ice.Message, arg ...string) { if len(arg) < 2 { mdb.HashSelect(m, arg...).Sort("type,name,text") - m.Tables(func(values ice.Maps) { + m.Table(func(values ice.Maps) { switch values[mdb.TYPE] { case LOGIN: m.PushButton(LOGIN, mdb.REMOVE) diff --git a/base/web/web.go b/base/web/web.go index 4ba5571c..3d081305 100644 --- a/base/web/web.go +++ b/base/web/web.go @@ -51,7 +51,7 @@ func (f *Frame) Start(m *ice.Message, arg ...string) { f.HandleFunc(key, func(w http.ResponseWriter, r *http.Request) { m.TryCatch(m.Spawn(key, cmd, c, w, r), true, func(msg *ice.Message) { _serve_handle(key, cmd, msg, w, r) }) }) - ice.Info.Route[path.Join(list[c], key)] = ctx.FileURI(cmd.GetFileLines()) + ice.Info.Route[path.Join(list[c], key)] = ctx.FileURI(cmd.FileLine()) }(key, cmd) } }) diff --git a/conf.go b/conf.go index ea8651b7..c26a8f40 100644 --- a/conf.go +++ b/conf.go @@ -5,8 +5,8 @@ const ( SP = " " DF = ":" EQ = "=" - QS = "?" AT = "@" + QS = "?" PS = "/" PT = "." FS = "," @@ -15,9 +15,9 @@ const ( OK = "ok" TRUE = "true" FALSE = "false" - PROCESS = "process" - FAILURE = "failure" SUCCESS = "success" + FAILURE = "failure" + PROCESS = "process" HTTP = "http" AUTO = "auto" @@ -51,18 +51,17 @@ const ( // MOD MOD_TIME = "2006-01-02 15:04:05" ) const ( // REPOS - INTSHELL = "intshell" CONTEXTS = "contexts" + INTSHELL = "intshell" ICEBERGS = "icebergs" TOOLKITS = "toolkits" VOLCANOS = "volcanos" LEARNING = "learning" INSTALL = "install" + REQUIRE = "require" PUBLISH = "publish" RELEASE = "release" - REQUIRE = "require" - DISPLAY = "display" ) const ( // DIR SRC = "src" @@ -73,11 +72,11 @@ const ( // DIR JSON = "json" CSV = "csv" - SVG = "svg" - GO = "go" SH = "sh" + GO = "go" JS = "js" CSS = "css" + SVG = "svg" HTML = "html" LIB = "lib" @@ -86,48 +85,41 @@ const ( // DIR PLUGIN = "plugin" STORY = "story" - INDEX_HTML = "index.html" - INDEX_CSS = "index.css" - PROTO_JS = "proto.js" - FRAME_JS = "frame.js" - INDEX_JS = "index.js" - INDEX_SH = "index.sh" - ICE_BIN = "ice.bin" + INDEX_CSS = "index.css" + PROTO_JS = "proto.js" + FRAME_JS = "frame.js" + INDEX_SH = "index.sh" FAVICON_ICO = "/favicon.ico" PLUGIN_INPUT = "/plugin/input/" PLUGIN_LOCAL = "/plugin/local/" PLUGIN_STORY = "/plugin/story/" + ISH_PLUGED = ".ish/pluged/" - CAN_PLUGIN = "can._plugin" - MODULES = "modules" - - USR_NODE_MODULES = "usr/node_modules/" - - USR_LEARNING = "usr/learning/" - USR_VOLCANOS = "usr/volcanos/" - USR_INTSHELL = "usr/intshell/" - USR_TOOLKITS = "usr/toolkits/" - USR_ICEBERGS = "usr/icebergs/" - USR_RELEASE = "usr/release/" + USR_MODULES = "usr/node_modules/" USR_INSTALL = "usr/install/" USR_REQUIRE = "usr/require/" USR_PUBLISH = "usr/publish/" + USR_RELEASE = "usr/release/" + USR_INTSHELL = "usr/intshell/" + USR_ICEBERGS = "usr/icebergs/" + USR_TOOLKITS = "usr/toolkits/" + USR_VOLCANOS = "usr/volcanos/" + USR_LEARNING = "usr/learning/" - USR_LOCAL = "usr/local/" - USR_LOCAL_GO = "usr/local/go/" - USR_LOCAL_GO_BIN = "usr/local/go/bin/" - USR_LOCAL_BIN = "usr/local/bin/" - USR_LOCAL_LIB = "usr/local/lib/" - USR_LOCAL_WORK = "usr/local/work/" - USR_LOCAL_REPOS = "usr/local/repos/" - USR_LOCAL_IMAGE = "usr/local/image/" - USR_LOCAL_EXPORT = "usr/local/export/" - USR_LOCAL_DAEMON = "usr/local/daemon/" - VAR_LOG_BOOT_LOG = "var/log/boot.log" - VAR_LOG_ICE_PID = "var/log/ice.pid" - + USR_LOCAL = "usr/local/" + USR_LOCAL_GO = "usr/local/go/" + USR_LOCAL_GO_BIN = "usr/local/go/bin/" + USR_LOCAL_BIN = "usr/local/bin/" + USR_LOCAL_LIB = "usr/local/lib/" + USR_LOCAL_WORK = "usr/local/work/" + USR_LOCAL_REPOS = "usr/local/repos/" + USR_LOCAL_IMAGE = "usr/local/image/" + USR_LOCAL_EXPORT = "usr/local/export/" + USR_LOCAL_DAEMON = "usr/local/daemon/" VAR_DATA_IMPORTANT = "var/data/.important" + VAR_LOG_BOOT_LOG = "var/log/boot.log" + VAR_LOG_ICE_PID = "var/log/ice.pid" VAR_LOG = "var/log/" VAR_TMP = "var/tmp/" @@ -158,22 +150,24 @@ const ( // DIR LICENSE = "LICENSE" GO_MOD = "go.mod" GO_SUM = "go.sum" + ICE_BIN = "ice.bin" + CAN_PLUGIN = "can._plugin" ) const ( // MSG + MSG_CMDS = "cmds" + MSG_FIELDS = "fields" + MSG_SESSID = "sessid" + MSG_DETAIL = "detail" MSG_OPTION = "option" MSG_APPEND = "append" MSG_RESULT = "result" - MSG_CMDS = "cmds" - MSG_FIELDS = "fields" - MSG_SESSID = "sessid" - MSG_OPTS = "_option" + MSG_UPLOAD = "_upload" MSG_SOURCE = "_source" MSG_TARGET = "_target" MSG_HANDLE = "_handle" - MSG_UPLOAD = "_upload" MSG_ACTION = "_action" MSG_STATUS = "_status" @@ -191,14 +185,14 @@ const ( // MSG MSG_USERUA = "user.ua" MSG_USERWEB = "user.web" MSG_USERPOD = "user.pod" + MSG_USERHOST = "user.host" MSG_USERADDR = "user.addr" MSG_USERDATA = "user.data" - MSG_USERROLE = "user.role" - MSG_USERNAME = "user.name" MSG_USERNICK = "user.nick" + MSG_USERNAME = "user.name" + MSG_USERROLE = "user.role" MSG_USERZONE = "user.zone" MSG_LANGUAGE = "user.lang" - MSG_USERHOST = "user.host" MSG_MODE = "sess.mode" MSG_TITLE = "sess.title" @@ -210,8 +204,6 @@ const ( // MSG MSG_DAEMON = "sess.daemon" MSG_FILES = "file.system" LOG_DISABLE = "log.disable" - - FIELDS_DETAIL = "detail" ) const ( // RENDER RENDER_BUTTON = "_button" @@ -223,10 +215,10 @@ const ( // RENDER RENDER_IFRAME = "_iframe" RENDER_SCRIPT = "_script" - RENDER_TEMPLATE = "_template" RENDER_STATUS = "_status" RENDER_REDIRECT = "_redirect" RENDER_DOWNLOAD = "_download" + RENDER_TEMPLATE = "_template" RENDER_RESULT = "_result" RENDER_JSON = "_json" RENDER_VOID = "_void" @@ -240,24 +232,24 @@ const ( // PROCESS PROCESS_REFRESH = "_refresh" PROCESS_REWRITE = "_rewrite" PROCESS_DISPLAY = "_display" - PROCESS_FIELD = "_field" - PROCESS_FLOAT = "_float" - PROCESS_INNER = "_inner" - PROCESS_AGAIN = "_again" - PROCESS_HOLD = "_hold" - PROCESS_BACK = "_back" - PROCESS_RICH = "_rich" - PROCESS_GROW = "_grow" - PROCESS_OPEN = "_open" + PROCESS_FIELD = "_field" + PROCESS_FLOAT = "_float" + PROCESS_INNER = "_inner" + PROCESS_AGAIN = "_again" + PROCESS_HOLD = "_hold" + PROCESS_BACK = "_back" + PROCESS_RICH = "_rich" + PROCESS_GROW = "_grow" + PROCESS_OPEN = "_open" - PROCESS_ARG = "_arg" - FIELD_PREFIX = "_prefix" + PROCESS_ARG = "_arg" + FIELD_PREFIX = "_prefix" + FIELDS_DETAIL = "detail" ) const ( // CTX CTX_ARG = "ctx_arg" CTX_DAEMON = "ctx_daemon" - CTX_FOLLOW = "follow" CTX_BEGIN = "begin" @@ -282,8 +274,8 @@ const ( // Err ErrNotLogin = "not login: " ErrNotRight = "not right: " - ErrNotFound = "not found: " ErrNotValid = "not valid: " + ErrNotFound = "not found: " ErrNotStart = "not start: " ErrNotImplement = "not implement: " @@ -296,12 +288,13 @@ const ( // ctx ) const ( // mdb SEARCH = "search" + INPUTS = "inputs" SELECT = "select" KEY = "key" + FIELD = "field" VALUE = "value" EXTRA = "extra" - FIELD = "field" META = "meta" HASH = "hash" TIME = "time" @@ -314,11 +307,11 @@ const ( // web SERVE = "serve" SPACE = "space" - THEME = "theme" TITLE = "title" + THEME = "theme" ) const ( // gdb - DEBUG = "debug" + EVENT = "event" ) const ( // nfs SOURCE = "source" @@ -328,6 +321,9 @@ const ( // cli SYSTEM = "system" START = "start" ) +const ( // log + DEBUG = "debug" +) const ( // ice CTX = "ctx" MDB = "mdb" diff --git a/core/chat/action.go b/core/chat/action.go index fbc6cf9a..0c54cdbc 100644 --- a/core/chat/action.go +++ b/core/chat/action.go @@ -31,7 +31,7 @@ func _action_auth(m *ice.Message, share string) *ice.Message { msg.Append(mdb.TYPE, "") return msg } - m.Tables(func(value ice.Maps) { + m.Table(func(value ice.Maps) { aaa.SessAuth(m, kit.Dict(value), RIVER, m.Option(ice.MSG_RIVER, msg.Append(RIVER)), STORM, m.Option(ice.MSG_STORM, msg.Append(STORM))) }) if m.Warn(!_river_right(m, msg.Append(web.RIVER)), ice.ErrNotRight) { diff --git a/core/chat/favor.go b/core/chat/favor.go index d8e16b99..9bbf4e07 100644 --- a/core/chat/favor.go +++ b/core/chat/favor.go @@ -37,7 +37,7 @@ func init() { FAVOR: {Name: "favor hash auto create getClipboardData getLocation scanQRCode record1 record2 upload", Help: "收藏夹", Actions: ice.MergeActions(ice.Actions{ mdb.SEARCH: {Hand: func(m *ice.Message, arg ...string) { if arg[0] == mdb.FOREACH { - m.Cmd("", ice.OptionFields("")).Tables(func(value ice.Maps) { + m.Cmd("", ice.OptionFields("")).Table(func(value ice.Maps) { if arg[1] == "" || arg[1] == value[mdb.TYPE] || strings.Contains(value[mdb.TEXT], arg[1]) { m.PushSearch(value) } @@ -120,7 +120,7 @@ func init() { m.PushScript(nfs.SCRIPT, text) m.PushQRCode(cli.QRCODE, text) } - m.Tables(func(value ice.Maps) { + m.Table(func(value ice.Maps) { if msg := gdb.Event(m.Spawn(), FAVOR_TABLES, mdb.TYPE, value[mdb.TYPE]); msg.Append(ctx.ACTION) != "" { m.PushButton(msg.Append(ctx.ACTION)) return diff --git a/core/chat/grant.go b/core/chat/grant.go index a3b122e0..c145992b 100644 --- a/core/chat/grant.go +++ b/core/chat/grant.go @@ -17,9 +17,9 @@ func init() { Index.MergeCommands(ice.Commands{ GRANT: {Name: "grant space auto", Help: "授权", Actions: ice.MergeActions(ice.Actions{ web.SPACE_LOGIN: {Hand: func(m *ice.Message, arg ...string) { - m.Go(func(msg *ice.Message) { + m.Go(func() { link := tcp.PublishLocalhost(m, web.MergePodCmd(m, "", "", web.SPACE, m.Option(mdb.NAME))) - msg.Sleep300ms(web.SPACE, m.Option(mdb.NAME), cli.PWD, m.Option(mdb.NAME), link, msg.Cmdx(cli.QRCODE, link)) + m.Sleep300ms(web.SPACE, m.Option(mdb.NAME), cli.PWD, m.Option(mdb.NAME), link, m.Cmdx(cli.QRCODE, link)) }) }}, CONFIRM: {Help: "授权", Hand: func(m *ice.Message, arg ...string) { diff --git a/core/chat/sso.go b/core/chat/sso.go index 243c8667..0bc955db 100644 --- a/core/chat/sso.go +++ b/core/chat/sso.go @@ -17,7 +17,7 @@ func init() { Index.MergeCommands(ice.Commands{ web.P(SSO): {Name: "/sso", Help: "授权", Actions: aaa.WhiteAction(), Hand: func(m *ice.Message, arg ...string) { if m.Warn(m.Option(ice.MSG_USERNAME) == "", ice.ErrNotLogin) || m.Warn(m.Option(cli.BACK) == "", ice.ErrNotValid) { - web.RenderIndex(m) + web.RenderMain(m) return } m.RenderRedirect(kit.MergeURL(m.Option(cli.BACK), ice.MSG_SESSID, m.Cmdx(web.SPACE, m.Option(web.SPACE), aaa.SESS, mdb.CREATE, diff --git a/core/chat/theme.go b/core/chat/theme.go index 9a0c013a..d2818217 100644 --- a/core/chat/theme.go +++ b/core/chat/theme.go @@ -76,7 +76,7 @@ func init() { }}, }, mdb.ZoneAction(mdb.FIELD, "time,id,tags,type,name,value"), aaa.WhiteAction()), Hand: func(m *ice.Message, arg ...string) { if mdb.ZoneSelect(m, arg...); len(arg) == 0 { - m.Cmd(nfs.DIR, nfs.PWD, ice.OptionFields(), kit.Dict(nfs.DIR_ROOT, "src/website/theme/")).RenameAppend(nfs.PATH, mdb.ZONE, nfs.SIZE, mdb.COUNT).Tables(func(values ice.Maps) { + m.Cmd(nfs.DIR, nfs.PWD, ice.OptionFields(), kit.Dict(nfs.DIR_ROOT, "src/website/theme/")).RenameAppend(nfs.PATH, mdb.ZONE, nfs.SIZE, mdb.COUNT).Table(func(values ice.Maps) { m.Push("", values) }) m.PushAction("choose", "form", mdb.REMOVE) @@ -84,7 +84,7 @@ func init() { if p := "src/website/theme/" + arg[0]; nfs.ExistsFile(m, p) { m.Cmdy(nfs.CAT, p) } else { - m.Tables(func(value ice.Maps) { + m.Table(func(value ice.Maps) { m.Echo("body.%s %s { %s:%s }\n", arg[0], value["tag"], value[mdb.NAME], value[mdb.VALUE]) }) } diff --git a/core/chat/website.go b/core/chat/website.go index aa930cee..023e7b31 100644 --- a/core/chat/website.go +++ b/core/chat/website.go @@ -210,7 +210,7 @@ func init() { } }}, }, mdb.HashAction(mdb.SHORT, nfs.PATH, mdb.FIELD, "time,path,type,name,text"), ctx.CmdAction(), web.ApiAction(), aaa.WhiteAction()), Hand: func(m *ice.Message, arg ...string) { - mdb.HashSelect(m, arg...).Tables(func(value ice.Maps) { m.PushAnchor(web.MergePodWebSite(m, "", value[nfs.PATH])) }) + mdb.HashSelect(m, arg...).Table(func(value ice.Maps) { m.PushAnchor(web.MergePodWebSite(m, "", value[nfs.PATH])) }) }}, }) } diff --git a/core/code/binpack.go b/core/code/binpack.go index 6778d10e..09a83ae5 100644 --- a/core/code/binpack.go +++ b/core/code/binpack.go @@ -71,11 +71,11 @@ func _binpack_all(m *ice.Message) { } for _, k := range kit.SortedKey(list) { v := kit.Select(k, list[k]) - m.Cmd(nfs.DIR, nfs.PWD, nfs.PATH, kit.Dict(nfs.DIR_ROOT, v, nfs.DIR_REG, kit.ExtReg(SH, SHY, PY, JS, CSS, HTML))).Tables(func(value ice.Maps) { + m.Cmd(nfs.DIR, nfs.PWD, nfs.PATH, kit.Dict(nfs.DIR_ROOT, v, nfs.DIR_REG, kit.ExtReg(SH, SHY, PY, JS, CSS, HTML))).Table(func(value ice.Maps) { _binpack_file(m, w, kit.Path(v, value[nfs.PATH]), path.Join(k, value[nfs.PATH])) }) } - mdb.HashSelects(m).Sort(nfs.PATH).Tables(func(value ice.Maps) { + mdb.HashSelects(m).Sort(nfs.PATH).Table(func(value ice.Maps) { if strings.HasSuffix(value[nfs.PATH], ice.PS) { _binpack_dir(m, w, value[nfs.PATH]) } else { diff --git a/core/code/favor.go b/core/code/favor.go index d206d87c..3f237093 100644 --- a/core/code/favor.go +++ b/core/code/favor.go @@ -24,7 +24,7 @@ func init() { }}, }, mdb.PageZoneAction(mdb.FIELD, "time,id,type,name,text,path,file,line")), Hand: func(m *ice.Message, arg ...string) { if mdb.PageZoneSelect(m, arg...); len(arg) > 0 && arg[0] != "" { - m.Tables(func(value ice.Maps) { m.PushButton(kit.Select(INNER, XTERM, value[nfs.FILE] == "")) }).Option(ctx.STYLE, arg[0]) + m.Table(func(value ice.Maps) { m.PushButton(kit.Select(INNER, XTERM, value[nfs.FILE] == "")) }).Option(ctx.STYLE, arg[0]) } }}, }) diff --git a/core/code/install.go b/core/code/install.go index d3391862..938d6fa3 100644 --- a/core/code/install.go +++ b/core/code/install.go @@ -147,7 +147,7 @@ func _install_service(m *ice.Message, arg ...string) { } } }) - m.Set(tcp.PORT).Tables(func(value ice.Maps) { m.Push(tcp.PORT, path.Base(value[nfs.DIR])) }).StatusTimeCount() + m.Set(tcp.PORT).Table(func(value ice.Maps) { m.Push(tcp.PORT, path.Base(value[nfs.DIR])) }).StatusTimeCount() } const ( diff --git a/core/code/pprof.go b/core/code/pprof.go index 94ae3e17..a1d9186c 100644 --- a/core/code/pprof.go +++ b/core/code/pprof.go @@ -59,7 +59,7 @@ func init() { m.PushAction(cli.START, mdb.REMOVE).Action(mdb.CREATE) m.EchoAnchor(web.MergeLink(m, "/debug/pprof/")) } else { - m.Tables(func(value ice.Maps) { m.PushDownload(mdb.LINK, "pprof.pd.gz", value[nfs.FILE]).PushButton(web.SERVE) }) + m.Table(func(value ice.Maps) { m.PushDownload(mdb.LINK, "pprof.pd.gz", value[nfs.FILE]).PushButton(web.SERVE) }) } }}, }) diff --git a/core/code/publish.go b/core/code/publish.go index 4e154b6a..d9d9040b 100644 --- a/core/code/publish.go +++ b/core/code/publish.go @@ -17,7 +17,7 @@ import ( ) func _publish_bin_list(m *ice.Message) *ice.Message { - defer m.SortTimeR(mdb.TIME) + defer m.SortStrR(mdb.TIME) m.Option(cli.CMD_DIR, ice.USR_PUBLISH) for _, ls := range strings.Split(cli.SystemCmds(m, "ls |xargs file |grep executable"), ice.NL) { if file := strings.TrimSpace(strings.Split(ls, ice.DF)[0]); file != "" { @@ -30,7 +30,7 @@ func _publish_bin_list(m *ice.Message) *ice.Message { return m } func _publish_list(m *ice.Message, arg ...string) *ice.Message { - defer m.SortTimeR(mdb.TIME) + defer m.SortStrR(mdb.TIME) m.Option(nfs.DIR_REG, kit.Select("", arg, 0)) return nfs.DirDeepAll(m, ice.USR_PUBLISH, nfs.PWD, nil, nfs.DIR_WEB_FIELDS) } diff --git a/core/code/upgrade.go b/core/code/upgrade.go index 16720935..d7d3b1af 100644 --- a/core/code/upgrade.go +++ b/core/code/upgrade.go @@ -27,7 +27,7 @@ func init() { UPGRADE: {Name: "upgrade item=target,binary,source,compile run restart", Help: "升级", Actions: ice.MergeActions(ice.Actions{ cli.RESTART: {Hand: func(m *ice.Message, arg ...string) { m.Go(func() { m.Sleep300ms(ice.EXIT, 1) }) }}, }), Hand: func(m *ice.Message, arg ...string) { - mdb.ZoneSelect(m.Spawn(), kit.Select(nfs.TARGET, arg, 0)).Tables(func(value ice.Maps) { + mdb.ZoneSelect(m.Spawn(), kit.Select(nfs.TARGET, arg, 0)).Table(func(value ice.Maps) { if value[nfs.FILE] == ice.ICE_BIN { value[nfs.FILE] = kit.Keys(ice.ICE, runtime.GOOS, runtime.GOARCH) defer nfs.Rename(m, value[nfs.FILE], ice.BIN_ICE_BIN) diff --git a/core/code/vimer.go b/core/code/vimer.go index 9260068f..cb7de036 100644 --- a/core/code/vimer.go +++ b/core/code/vimer.go @@ -79,7 +79,7 @@ func init() { kit.IfNoKey(list, kit.Select(k, k+ice.DF, k != "")+p, func(p string) { m.Push(nfs.PATH, p) }) } mdb.HashSelect(m.Spawn()).TablesLimit(10, func(value ice.Maps) { push("", value[nfs.PATH]) }) - m.Cmd(mdb.SEARCH, mdb.FOREACH, "", ice.OptionFields("type,name,text")).Sort("type,name,text").Tables(func(value ice.Maps) { + m.Cmd(mdb.SEARCH, mdb.FOREACH, "", ice.OptionFields("type,name,text")).Sort("type,name,text").Table(func(value ice.Maps) { switch value[mdb.TYPE] { case nfs.FILE: push("", value[mdb.TEXT]) @@ -102,8 +102,8 @@ func init() { for _, p := range kit.Split(kit.Select(m.Option(nfs.PATH), m.Option("paths"))) { nfs.DirDeepAll(m.Spawn(), nfs.PWD, p, func(value ice.Maps) { push("", value[nfs.PATH]) }, nfs.PATH) } - m.Cmd(ctx.COMMAND, mdb.SEARCH, ctx.COMMAND, ice.OptionFields(ctx.INDEX)).Tables(func(value ice.Maps) { push(ctx.INDEX, value[ctx.INDEX]) }) - m.Cmd(mdb.SEARCH, cli.SYSTEM, cli.OPENS, ice.OptionFields("type,name,text")).Sort("type,name,text").Tables(func(value ice.Maps) { push(cli.OPENS, value[nfs.NAME]) }) + m.Cmd(ctx.COMMAND, mdb.SEARCH, ctx.COMMAND, ice.OptionFields(ctx.INDEX)).Table(func(value ice.Maps) { push(ctx.INDEX, value[ctx.INDEX]) }) + m.Cmd(mdb.SEARCH, cli.SYSTEM, cli.OPENS, ice.OptionFields("type,name,text")).Sort("type,name,text").Table(func(value ice.Maps) { push(cli.OPENS, value[nfs.NAME]) }) default: m.Cmdy(INNER, mdb.INPUTS, arg) } @@ -180,14 +180,12 @@ func init() { Index.MergeCommands(ice.Commands{TEMPLATE: {Name: "template type name text auto", Help: "模板", Actions: mdb.RenderAction()}}) Index.MergeCommands(ice.Commands{COMPLETE: {Name: "complete type name text auto", Help: "补全", Actions: mdb.RenderAction()}}) Index.MergeCommands(ice.Commands{NAVIGATE: {Name: "navigate type name text auto", Help: "跳转", Actions: mdb.RenderAction()}}) - ice.AddMerges(func(c *ice.Context, key string, cmd *ice.Command, sub string, action *ice.Action) (ice.Handler, ice.Handler) { + ice.AddMerges(func(c *ice.Context, key string, cmd *ice.Command, sub string, action *ice.Action) ice.Handler { switch sub { case TEMPLATE, COMPLETE, NAVIGATE: - return func(m *ice.Message, arg ...string) { - m.Cmd(sub, mdb.CREATE, key, m.PrefixKey()) - }, nil + return func(m *ice.Message, arg ...string) { m.Cmd(sub, mdb.CREATE, key, m.PrefixKey()) } } - return nil, nil + return nil }) } func Complete(m *ice.Message, text string, data ice.Map) { diff --git a/core/code/webpack.go b/core/code/webpack.go index cb62c12c..54839e7b 100644 --- a/core/code/webpack.go +++ b/core/code/webpack.go @@ -19,7 +19,7 @@ import ( func _volcanos(m *ice.Message, p ...string) string { return ice.USR_VOLCANOS + path.Join(p...) } func _publish(m *ice.Message, p ...string) string { return ice.USR_PUBLISH + path.Join(p...) } func _require(m *ice.Message, p string) string { - return path.Join(ice.PS, strings.TrimPrefix(strings.Replace(p, ice.USR_NODE_MODULES, web.REQUIRE_MODULES, 1), ice.USR_VOLCANOS)) + return path.Join(ice.PS, strings.TrimPrefix(strings.Replace(p, ice.USR_MODULES, web.REQUIRE_MODULES, 1), ice.USR_VOLCANOS)) } func _webpack_css(m *ice.Message, css, js io.Writer, p string) { fmt.Fprintln(css, kit.Format("/* %s */", _require(m, p))) @@ -67,13 +67,13 @@ func _webpack_cache(m *ice.Message, dir string, write bool) { for _, k := range []string{ice.FRAME_JS} { _webpack_js(m, js, _volcanos(m, k)) } - mdb.HashSelects(m).Sort(nfs.PATH).Tables(func(value ice.Maps) { + mdb.HashSelects(m).Sort(nfs.PATH).Table(func(value ice.Maps) { defer fmt.Fprintln(js, "") if p := value[nfs.PATH]; kit.Ext(p) == nfs.CSS { - _webpack_css(m, css, js, path.Join(ice.USR_NODE_MODULES, p)) + _webpack_css(m, css, js, path.Join(ice.USR_MODULES, p)) } else { p = kit.Select(path.Join(p, LIB, kit.Keys(p, JS)), p, kit.Ext(p) == nfs.JS) - _webpack_node(m, js, path.Join(ice.USR_NODE_MODULES, p)) + _webpack_node(m, js, path.Join(ice.USR_MODULES, p)) } }) } @@ -85,7 +85,7 @@ func _webpack_build(m *ice.Message, name string) { if f, p, e := nfs.CreateFile(m, kit.Keys(name, HTML)); m.Assert(e) { defer f.Close() defer m.Echo(p) - fmt.Fprintf(f, nfs.Template(m, ice.INDEX_HTML), m.Cmdx(nfs.CAT, USR_PUBLISH_CAN_CSS), m.Cmdx(nfs.CAT, USR_PUBLISH_CAN_JS), kit.JoinKV(ice.EQ, ice.NL, + fmt.Fprintf(f, nfs.Template(m, "index.html"), m.Cmdx(nfs.CAT, USR_PUBLISH_CAN_CSS), m.Cmdx(nfs.CAT, USR_PUBLISH_CAN_JS), kit.JoinKV(ice.EQ, ice.NL, `Volcanos.meta.args`, kit.Formats(kit.Dict(m.OptionSimple(kit.Split(m.Option(ctx.ARGS))...))), `Volcanos.meta.pack`, kit.Formats(kit.UnMarshal(kit.Select("{}", m.Option(nfs.CONTENT)))), `Volcanos.meta.webpack`, ice.TRUE, diff --git a/core/mall/asset.go b/core/mall/asset.go index dd54f102..1aa4fcb5 100644 --- a/core/mall/asset.go +++ b/core/mall/asset.go @@ -99,7 +99,7 @@ func init() { m.PushAction(CHECK) m.SortIntR(AMOUNT) - m.Tables(func(value ice.Maps) { + m.Table(func(value ice.Maps) { amount += kit.Int(value[AMOUNT]) count += kit.Int(value[COUNT]) }) @@ -107,7 +107,7 @@ func init() { } else { m.PushAction(mdb.PLUGIN) - m.Tables(func(value ice.Maps) { + m.Table(func(value ice.Maps) { amount += kit.Int(value[AMOUNT]) count++ }) diff --git a/core/mall/salary.go b/core/mall/salary.go index 970c2168..279affd6 100644 --- a/core/mall/salary.go +++ b/core/mall/salary.go @@ -20,7 +20,7 @@ func init() { }, mdb.HashAction(mdb.SHORT, MONTH, mdb.FIELD, "month,company,amount,income,tax")), Hand: func(m *ice.Message, arg ...string) { mdb.HashSelect(m, arg...) amount, income, tax := 0, 0, 0 - m.Tables(func(value ice.Maps) { + m.Table(func(value ice.Maps) { amount += kit.Int(value[AMOUNT]) income += kit.Int(value[INCOME]) tax += kit.Int(value[TAX]) diff --git a/core/team/epic.go b/core/team/epic.go index e8461015..b4ca14e2 100644 --- a/core/team/epic.go +++ b/core/team/epic.go @@ -17,7 +17,7 @@ func init() { EPIC: {Name: "epic hash list", Help: "史记", Actions: ice.MergeActions(ice.Actions{ mdb.CREATE: {Name: "create time zone name"}, mdb.MODIFY: {Name: "modify time zone name"}, }, mdb.HashAction(mdb.FIELD, "time,hash,zone,name")), Hand: func(m *ice.Message, arg ...string) { - if mdb.HashSelect(m, arg...).Tables(func(value ice.Maps) { + if mdb.HashSelect(m, arg...).Table(func(value ice.Maps) { if span := kit.Time(m.Time()) - kit.Time(value[mdb.TIME]); span > 0 { m.Push(mdb.TEXT, kit.Format(`已经 %v
距 %s
`, int(time.Duration(span)/time.Hour/24), kit.Split(value[mdb.TIME])[0], diff --git a/core/team/task.go b/core/team/task.go index 6ef0477d..408eeb3b 100644 --- a/core/team/task.go +++ b/core/team/task.go @@ -80,7 +80,7 @@ func init() { }, mdb.ZoneAction(mdb.FIELD, "begin_time,close_time,id,status,level,score,type,name,text")), Hand: func(m *ice.Message, arg ...string) { if mdb.ZoneSelect(m, arg...); len(arg) > 0 && arg[0] != "" { status := map[string]int{} - m.Tables(func(value ice.Maps) { + m.Table(func(value ice.Maps) { m.PushButton(_task_action(m, value[STATUS])) status[value[mdb.STATUS]]++ }) diff --git a/core/wiki/wiki.go b/core/wiki/wiki.go index 56610665..470fd778 100644 --- a/core/wiki/wiki.go +++ b/core/wiki/wiki.go @@ -48,7 +48,7 @@ func _wiki_list(m *ice.Message, arg ...string) bool { } m.Cmdy(nfs.DIR, kit.Slice(arg, 0, 1), kit.Dict(nfs.DIR_TYPE, nfs.CAT, nfs.DIR_REG, mdb.Config(m, lex.REGEXP))) m.StatusTimeCount() - m.SortTimeR(mdb.TIME) + m.SortStrR(mdb.TIME) return true } ctx.DisplayLocal(m, path.Join(kit.PathName(2), kit.Keys(kit.FileName(2), ice.JS))) diff --git a/core/wiki/word.go b/core/wiki/word.go index 506fbe8c..3a8f956b 100644 --- a/core/wiki/word.go +++ b/core/wiki/word.go @@ -33,7 +33,7 @@ func init() { WordAlias(m, SEQUENCE, CHART, SEQUENCE) }}, mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) { - m.Cmd(git.REPOS, ice.OptionFields(nfs.PATH)).Tables(func(value ice.Maps) { + m.Cmd(git.REPOS, ice.OptionFields(nfs.PATH)).Table(func(value ice.Maps) { if m.Option(nfs.DIR_DEEP, ice.TRUE); kit.Path(value[nfs.PATH]) == kit.Path("") { _wiki_list(m, "src/") } else { diff --git a/data.go b/data.go index a3f0b6ae..754a47ea 100644 --- a/data.go +++ b/data.go @@ -13,28 +13,22 @@ func (m *Message) ActionKey() string { return strings.TrimPrefix(strings.TrimSu func (m *Message) CommandKey() string { return strings.TrimPrefix(strings.TrimSuffix(m._key, PS), PS) } func (m *Message) PrefixKey() string { return m.Prefix(m.CommandKey()) } func (m *Message) PrefixPath(arg ...Any) string { - return strings.TrimPrefix(path.Join(strings.ReplaceAll(m.PrefixRawKey(arg...), PT, PS)), "web") + PS + return strings.TrimPrefix(path.Join(strings.ReplaceAll(m.Prefix(m._key, kit.Keys(arg...)), PT, PS)), WEB) + PS } -func (m *Message) PrefixRawKey(arg ...Any) string { return m.Prefix(m._key, kit.Keys(arg...)) } -func (m *Message) Prefix(arg ...string) string { return m.Target().Prefix(arg...) } +func (m *Message) Prefix(arg ...string) string { return m.Target().Prefix(arg...) } func SaveImportant(m *Message, arg ...string) { if Info.Important != true { return } - for i, v := range arg { - kit.If(v == "" || strings.Contains(v, SP), func() { arg[i] = "\"" + v + "\"" }) - } + kit.For(arg, func(i int, v string) { kit.If(v == "" || strings.Contains(v, SP), func() { arg[i] = "\"" + v + "\"" }) }) m.Cmd("nfs.push", VAR_DATA_IMPORTANT, kit.Join(arg, SP), NL) } func loadImportant(m *Message) { if f, e := os.Open(VAR_DATA_IMPORTANT); e == nil { defer f.Close() for bio := bufio.NewScanner(f); bio.Scan(); { - if bio.Text() == "" || strings.HasPrefix(bio.Text(), "# ") { - continue - } - m.Cmd(kit.Split(bio.Text())) + kit.If(bio.Text() != "" && !strings.HasPrefix(bio.Text(), "# "), func() { m.Cmd(kit.Split(bio.Text())) }) } } Info.Important = true diff --git a/exec.go b/exec.go index 9550c448..b58db7d8 100644 --- a/exec.go +++ b/exec.go @@ -3,6 +3,8 @@ package ice import ( "errors" "io" + "reflect" + "strings" "time" kit "shylinux.com/x/toolkits" @@ -10,10 +12,10 @@ import ( "shylinux.com/x/toolkits/task" ) -func (m *Message) TryCatch(msg *Message, catch bool, cb ...func(msg *Message)) *Message { +func (m *Message) TryCatch(msg *Message, catch bool, cb ...func(msg *Message)) { defer func() { switch e := recover(); e { - case nil, io.EOF: + case io.EOF, nil: default: fileline := m.FormatStack(2, 1) m.Log(LOG_WARN, "catch: %s %s", e, fileline).Log("chain", msg.FormatChain()) @@ -27,7 +29,6 @@ func (m *Message) TryCatch(msg *Message, catch bool, cb ...func(msg *Message)) * } }() kit.If(len(cb) > 0, func() { cb[0](msg) }) - return m } func (m *Message) Assert(expr Any) bool { switch e := expr.(type) { @@ -45,28 +46,155 @@ func (m *Message) Assert(expr Any) bool { panic(expr) } func (m *Message) Sleep(d Any, arg ...Any) *Message { - if time.Sleep(kit.Duration(d)); len(arg) > 0 { - m.Cmdy(arg...) - } + defer kit.If(len(arg) > 0, func() { m.Cmdy(arg...) }) + time.Sleep(kit.Duration(d)) return m } func (m *Message) Sleep300ms(arg ...Any) *Message { return m.Sleep("300ms", arg...) } func (m *Message) Sleep30ms(arg ...Any) *Message { return m.Sleep("30ms", arg...) } func (m *Message) Sleep3s(arg ...Any) *Message { return m.Sleep("3s", arg...) } -func (m *Message) Go(cb Any, arg ...Any) *Message { +func (m *Message) Go(cb func(), arg ...Any) { kit.If(len(arg) == 0, func() { arg = append(arg, logs.FileLine(cb)) }) - task.Put(arg[0], func(task *task.Task) error { - m.TryCatch(m, true, func(m *Message) { - switch cb := cb.(type) { - case func(*Message): - cb(m.Spawn()) - case func(): - cb() - default: - m.ErrorNotImplement(cb) - } - }) - return nil - }) + task.Put(arg[0], func(task *task.Task) { m.TryCatch(m, true, func(m *Message) { cb() }) }) +} + +func (m *Message) CmdHand(cmd *Command, key string, arg ...string) *Message { + if m._cmd, m._key = cmd, key; cmd == nil { + return m + } + if m._target = cmd.FileLines(); key == SELECT { + m.Log(LOG_CMDS, "%s.%s %d %v %v", m.Target().Name, key, len(arg), arg, m.Optionv(MSG_FIELDS), logs.FileLineMeta(m._fileline())) + } else { + m.Log(LOG_CMDS, "%s.%s %d %v", m.Target().Name, key, len(arg), arg, logs.FileLineMeta(m._fileline())) + } + if cmd.Hand != nil { + cmd.Hand(m, arg...) + } else if cmd.Actions != nil && cmd.Actions[SELECT] != nil { + cmd.Actions[SELECT].Hand(m, arg...) + } return m } +func (m *Message) ActionHand(cmd *Command, key, sub string, arg ...string) *Message { + if action, ok := cmd.Actions[sub]; !m.Warn(!ok, ErrNotFound, sub, cmd.FileLines()) { + return m.Target()._action(m, cmd, key, sub, action, arg...) + } + return m +} +func (m *Message) _command(arg ...Any) *Message { + args, opts, cbs, _source := []Any{}, Map{}, kit.Value(nil), logs.FileLine(3) + for _, v := range arg { + switch val := v.(type) { + case nil: + case string: + args = append(args, v) + case Maps: + kit.For(val, func(k, v string) { opts[k] = v }) + case Map: + kit.For(kit.KeyValue(nil, "", val), func(k string, v Any) { opts[k] = v }) + case Option: + opts[val.Name] = val.Value + case logs.Meta: + kit.If(val.Key == "fileline", func() { _source = val.Value }) + case func(int, Maps, []string): + defer func() { m.Table(val) }() + case func(Maps): + defer func() { m.Table(val) }() + default: + if reflect.TypeOf(val).Kind() == reflect.Func { + cbs = val + } else { + args = append(args, v) + } + } + } + list := kit.Simple(args...) + kit.If(len(list) == 0, func() { list = m.meta[MSG_DETAIL] }) + if len(list) == 0 { + return m + } + ok := false + run := func(msg *Message, ctx *Context, cmd *Command, key string, arg ...string) { + ok = true + msg._source = _source + key = kit.Slice(strings.Split(key, PT), -1)[0] + kit.If(cbs, func() { msg.OptionCB(key, cbs) }) + kit.For(opts, func(k string, v Any) { msg.Option(k, v) }) + m = ctx._command(msg, cmd, key, arg...) + } + if list[0] == "" { + run(m.Spawn(), m.target, m._cmd, m._key, list[1:]...) + } else if cmd, ok := m.target.Commands[strings.TrimPrefix(list[0], m.target.Prefix()+PT)]; ok { + run(m.Spawn(), m.target, cmd, list[0], list[1:]...) + } else if cmd, ok := m.source.Commands[strings.TrimPrefix(list[0], m.source.Prefix()+PT)]; ok { + run(m.Spawn(m.source), m.source, cmd, list[0], list[1:]...) + } else { + m.Search(list[0], func(p *Context, s *Context, key string, cmd *Command) { run(m.Spawn(s), s, cmd, key, list[1:]...) }) + } + m.Warn(!ok, ErrNotFound, kit.Format(list)) + return m +} +func (c *Context) _command(m *Message, cmd *Command, key string, arg ...string) *Message { + if m._cmd, m._key, m._sub = cmd, key, SELECT; cmd == nil { + return m + } + if m.meta[MSG_DETAIL] = kit.Simple(m.PrefixKey(), arg); cmd.Actions != nil { + if len(arg) > 1 && arg[0] == ACTION { + if h, ok := cmd.Actions[arg[1]]; ok { + return c._action(m, cmd, key, arg[1], h, arg[2:]...) + } + } else if len(arg) > 0 { + if h, ok := cmd.Actions[arg[0]]; ok { + return c._action(m, cmd, key, arg[0], h, arg[1:]...) + } + } + } + if len(arg) > 0 && arg[0] == ACTION && arg[1] == INPUTS { + return m + } + return m.CmdHand(cmd, key, arg...) +} +func (c *Context) _action(m *Message, cmd *Command, key string, sub string, h *Action, arg ...string) *Message { + if h.Hand == nil { + return m.Cmdy(kit.Split(kit.Select(sub, h.Name)), arg) + } + if m._cmd, m._key, m._sub = cmd, key, sub; len(h.List) > 0 && sub != SEARCH { + order := false + for i, v := range h.List { + name := kit.Format(kit.Value(v, NAME)) + if i == 0 { + if len(arg) > 0 && arg[0] == name { + kit.For(arg, func(k, v string) { m.Option(k, v) }) + } else { + order = true + } + } + kit.If(order && i < len(arg), func() { m.Option(name, arg[i]) }) + if m.Warn(m.OptionDefault(name, kit.Format(kit.Value(v, VALUE))) == "" && kit.Value(v, "need") == "must", ErrNotValid, name) { + return m + } + } + } + m._target = kit.Select(logs.FileLine(h.Hand), cmd.FileLines(), cmd.RawHand != nil) + m.Log(LOG_CMDS, "%s.%s %s %d %v", c.Name, key, sub, len(arg), arg, logs.FileLineMeta(m._fileline())) + h.Hand(m, arg...) + return m +} +func (c *Command) FileLines() string { + return kit.Join(kit.Slice(kit.Split(c.FileLine(), PS), -3), PS) +} +func (c *Command) FileLine() string { + if c == nil { + return "" + } else if c.RawHand != nil { + switch h := c.RawHand.(type) { + case string: + return h + default: + return logs.FileLines(c.RawHand) + } + } else if c.Hand != nil { + return logs.FileLines(c.Hand) + } else { + return "" + } +} diff --git a/info.go b/info.go index 299e4c6b..584a4701 100644 --- a/info.go +++ b/info.go @@ -1,11 +1,17 @@ package ice +import ( + "strings" + + kit "shylinux.com/x/toolkits" +) + type MakeInfo struct { + Hash string Time string Path string - Hash string - Domain string Module string + Domain string Remote string Branch string Version string @@ -20,52 +26,170 @@ var Info = struct { Hostname string Pathname string Username string - Password string - Intshell string - Volcanos string - - Domain string - NodeType string - NodeName string - CtxShare string - CtxRiver string PidPath string Colors bool - Help string + Domain string + NodeType string + NodeName string + Localhost bool + Important bool + File Maps Gomod Maps Route Maps Index Map - Important bool - Localhost bool - - merges []MergeHandler + merges []Any render map[string]func(*Message, ...Any) string - Save func(m *Message, key ...string) *Message Load func(m *Message, key ...string) *Message + Save func(m *Message, key ...string) *Message Log func(m *Message, p, l, s string) }{ - Help: ` -^_^ 欢迎使用冰山框架 ^_^ -^_^ Welcome to Icebergs World ^_^ - -report: shylinuxc@gmail.com -server: https://shylinux.com -source: https://shylinux.com/x/contexts -`, File: Maps{}, - Route: Maps{}, Gomod: Maps{}, + Route: Maps{}, Index: Map{}, render: map[string]func(*Message, ...Any) string{}, - Save: func(m *Message, key ...string) *Message { return m }, Load: func(m *Message, key ...string) *Message { return m }, + Save: func(m *Message, key ...string) *Message { return m }, Log: func(m *Message, p, l, s string) {}, } -type MergeHandler func(*Context, string, *Command, string, *Action) (Handler, Handler) +func AddMerges(h ...Any) { Info.merges = append(Info.merges, h...) } -func AddMerges(h ...MergeHandler) { Info.merges = append(Info.merges, h...) } +func MergeHand(hand ...Handler) Handler { + if len(hand) == 0 { + return nil + } + if len(hand) == 1 { + return hand[0] + } + return func(m *Message, arg ...string) { + for _, h := range hand { + if h != nil { + h(m, arg...) + } + } + } +} +func MergeActions(arg ...Any) Actions { + if len(arg) == 0 { + return nil + } + list := arg[0].(Actions) + for _, from := range arg[1:] { + switch from := from.(type) { + case Actions: + for k, v := range from { + if h, ok := list[k]; !ok { + list[k] = v + } else if k == CTX_INIT { + h.Hand = MergeHand(v.Hand, h.Hand) + } else if k == CTX_EXIT { + h.Hand = MergeHand(h.Hand, v.Hand) + } else if h.Name = kit.Select(v.Name, h.Name); h.Hand == nil { + h.Hand = v.Hand + } + } + case string: + h := list[CTX_INIT] + if h == nil { + list[CTX_INIT] = &Action{} + h = list[CTX_INIT] + } + h.Hand = MergeHand(h.Hand, func(m *Message, arg ...string) { + m.Search(from, func(p *Context, s *Context, key string, cmd *Command) { + for k, v := range cmd.Actions { + func(k string) { + if h, ok := list[k]; !ok { + list[k] = &Action{Name: v.Name, Help: v.Help, Hand: func(m *Message, arg ...string) { m.Cmdy(from, k, arg) }} + } else if h.Hand == nil { + h.Hand = func(m *Message, arg ...string) { m.Cmdy(from, k, arg) } + } + }(k) + } + }) + }) + default: + Pulse.ErrorNotImplement(from) + } + } + return list +} +func SplitCmd(name string, actions Actions) (list []Any) { + const ( + TEXT = "text" + TEXTAREA = "textarea" + PASSWORD = "password" + SELECT = "select" + BUTTON = "button" + ) + const ( + RUN = "run" + REFRESH = "refresh" + LIST = "list" + BACK = "back" + AUTO = "auto" + PAGE = "page" + ARGS = "args" + CONTENT = "content" + ) + item, button := kit.Dict(), false + push := func(arg ...string) { + button = kit.Select("", arg, 0) == BUTTON + item = kit.Dict(TYPE, kit.Select("", arg, 0), NAME, kit.Select("", arg, 1), ACTION, kit.Select("", arg, 2)) + list = append(list, item) + } + ls := kit.Split(name, SP, "*:=@") + for i := 1; i < len(ls); i++ { + switch ls[i] { + case RUN: + push(BUTTON, ls[i]) + case REFRESH: + push(BUTTON, ls[i], AUTO) + case LIST: + push(BUTTON, ls[i], AUTO) + case AUTO: + push(BUTTON, LIST, AUTO) + push(BUTTON, BACK) + case PAGE: + push(BUTTON, "prev") + push(BUTTON, "next") + push(TEXT, "offend") + push(TEXT, "limit") + case ARGS, CONTENT, TEXTAREA, TEXT: + push(TEXTAREA, ls[i]) + case PASSWORD: + push(PASSWORD, ls[i]) + case "*": + item["need"] = "must" + case DF: + if item[TYPE] = kit.Select("", ls, i+1); item[TYPE] == BUTTON { + button = true + } + i++ + case EQ: + if value := kit.Select("", ls, i+1); strings.Contains(value, FS) { + vs := kit.Split(value) + if strings.Count(value, vs[0]) > 1 { + item["values"] = vs[1:] + } else { + item["values"] = vs + } + item[VALUE] = vs[0] + item[TYPE] = SELECT + } else { + item[VALUE] = value + } + i++ + case AT: + item[ACTION] = kit.Select("", ls, i+1) + i++ + default: + push(kit.Select(TEXT, BUTTON, button || actions != nil && actions[ls[i]] != nil), ls[i]) + } + } + return list +} diff --git a/init.go b/init.go index d0a2158c..831fd8ad 100644 --- a/init.go +++ b/init.go @@ -24,10 +24,9 @@ func (s *Frame) Begin(m *Message, arg ...string) { }) } func (s *Frame) Start(m *Message, arg ...string) { - m.Cmd(kit.Keys(MDB, CTX_INIT)) m.Cmd(INIT, arg) + kit.For(kit.Split(kit.Select(kit.Join([]string{LOG, GDB, SSH}), os.Getenv(CTX_DAEMON))), func(k string) { m.Sleep("10ms").Start(k) }) m.Cmd(arg) - kit.For(kit.Split(kit.Select("log,gdb,ssh", os.Getenv(CTX_DAEMON))), func(k string) { m.Sleep("10ms").Start(k) }) } func (s *Frame) Close(m *Message, arg ...string) { list := map[*Context]*Message{m.target: m} @@ -55,6 +54,7 @@ var Index = &Context{Name: ICE, Help: "冰山模块", Commands: Commands{ loadImportant(m) }}, INIT: {Hand: func(m *Message, arg ...string) { + m.Cmd(kit.Keys(MDB, CTX_INIT)) m.Cmd(CTX_INIT) m.Cmd(SOURCE, ETC_INIT_SHY) }}, @@ -72,7 +72,7 @@ var Index = &Context{Name: ICE, Help: "冰山模块", Commands: Commands{ removeImportant(m) }}, }, server: &Frame{}} -var Pulse = &Message{time: time.Now(), code: 0, Hand: true, meta: map[string][]string{}, data: Map{}, source: Index, target: Index} +var Pulse = &Message{time: time.Now(), meta: map[string][]string{}, data: Map{}, source: Index, target: Index} func init() { Index.root, Pulse.root = Index, Pulse } @@ -101,10 +101,9 @@ func Run(arg ...string) string { conf.Wait() os.Exit(kit.Int(Pulse.Option(EXIT))) default: - logs.Disable(true) Pulse.Cmdy(INIT).Cmdy(arg) kit.If(Pulse.IsErrNotFound(), func() { Pulse.SetAppend().SetResult().Cmdy(SYSTEM, arg) }) - kit.If(strings.TrimSpace(Pulse.Result()) == "" && Pulse.Length() > 0, func() { Pulse.Table() }) + kit.If(strings.TrimSpace(Pulse.Result()) == "" && Pulse.Length() > 0, func() { Pulse.TableEcho() }) kit.If(Pulse.Result() != "" && !strings.HasSuffix(Pulse.Result(), NL), func() { Pulse.Echo(NL) }) } return Pulse.Result() diff --git a/logs.go b/logs.go index 34a9cab9..743c955b 100644 --- a/logs.go +++ b/logs.go @@ -6,6 +6,7 @@ import ( "encoding/json" "fmt" "io" + "net/http" "runtime" "strings" "time" @@ -24,7 +25,7 @@ func (m *Message) join(arg ...Any) (string, []Any) { i-- continue case []string: - list = append(list, kit.JoinKV(": ", " ", v...)) + list = append(list, kit.JoinKV(DF, SP, v...)) i-- continue } @@ -48,13 +49,11 @@ func (m *Message) join(arg ...Any) (string, []Any) { return kit.Join(list, SP), meta } func (m *Message) log(level string, str string, arg ...Any) *Message { - _source := logs.FileLineMeta(3) - if Info.Log != nil { - Info.Log(m, m.FormatPrefix(), level, logs.Format(str, append(arg, _source)...)) - } if m.Option(LOG_DISABLE) == TRUE { return m } + _source := logs.FileLineMeta(3) + kit.If(Info.Log != nil, func() { Info.Log(m, m.FormatPrefix(), level, logs.Format(str, append(arg, _source)...)) }) prefix, suffix := "", "" if Info.Colors { switch level { @@ -66,12 +65,7 @@ func (m *Message) log(level string, str string, arg ...Any) *Message { prefix, suffix = "\033[31m", "\033[0m" } } - switch level { - case LOG_INFO: - if len(str) > 4096 { - str = str[:4096] - } - } + kit.If(level == LOG_INFO && len(str) > 4096, func() { str = str[:4096] }) logs.Infof(str, append(arg, logs.PrefixMeta(kit.Format("%02d %4s->%-4s %s%s ", m.code, m.source.Name, m.target.Name, prefix, level)), logs.SuffixMeta(suffix), _source)...) return m } @@ -80,9 +74,7 @@ func (m *Message) Log(level string, str string, arg ...Any) *Message { } func (m *Message) Logs(level string, arg ...Any) *Message { str, meta := m.join(arg...) - if len(level) > 0 && unicode.IsUpper([]rune(level)[0]) { - meta = []Any{logs.FileLineMeta("")} - } + kit.If(len(level) > 0 && unicode.IsUpper([]rune(level)[0]), func() { meta = []Any{logs.FileLineMeta("")} }) return m.log(level, str, meta...) } @@ -92,19 +84,12 @@ func (m *Message) Auth(arg ...Any) *Message { } func (m *Message) Cost(arg ...Any) *Message { str, meta := m.join(arg...) - if str == "" || len(arg) == 0 { - str = kit.Join(m.meta[MSG_DETAIL], SP) - meta = []Any{logs.FileLineMeta(m._fileline())} - } - list := []string{m.FormatCost(), str} - return m.log(LOG_COST, kit.Join(list, SP), meta...) + kit.If(str == "" || len(arg) == 0, func() { str, meta = kit.Join(m.meta[MSG_DETAIL], SP), []Any{logs.FileLineMeta(m._fileline())} }) + return m.log(LOG_COST, kit.Join([]string{m.FormatCost(), str}, SP), meta...) } func (m *Message) Info(str string, arg ...Any) *Message { return m.log(LOG_INFO, str, arg...) } -func (m *Message) WarnTimeNotValid(time Any, arg ...Any) bool { - return m.Warn(kit.Format(time) < m.Time(), ErrNotValid, kit.Simple(arg), time, m.Time(), logs.FileLineMeta(2)) -} func (m *Message) Warn(err Any, arg ...Any) bool { switch err := err.(type) { case error: @@ -120,21 +105,20 @@ func (m *Message) Warn(err Any, arg ...Any) bool { return false } str, meta := m.join(arg...) - m.log(LOG_WARN, str, meta...) - if !m.IsErr() && len(arg) > 0 { - switch m.error(arg...); kit.Format(arg[0]) { - case ErrNotLogin: - m.RenderStatusUnauthorized(str) - case ErrNotRight: - m.RenderStatusForbidden(str) - case ErrNotFound: - m.RenderStatusNotFound(str) - case ErrNotValid: - m.RenderStatusBadRequest(str) - } + if m.log(LOG_WARN, str, meta...); !m.IsErr() && len(arg) > 0 { + m.error(arg...) + kit.If(map[string]int{ + ErrNotLogin: http.StatusUnauthorized, + ErrNotRight: http.StatusForbidden, + ErrNotFound: http.StatusNotFound, + ErrNotValid: http.StatusBadRequest, + }[kit.Format(arg[0])], func(s int) { m.Render(RENDER_STATUS, s, str) }) } return true } +func (m *Message) WarnTimeNotValid(time Any, arg ...Any) bool { + return m.Warn(kit.Format(time) < m.Time(), ErrNotValid, kit.Simple(arg), time, m.Time(), logs.FileLineMeta(2)) +} func (m *Message) ErrorNotImplement(arg ...Any) *Message { m.Error(true, append(kit.List(ErrNotImplement), arg...)...) return m @@ -142,10 +126,7 @@ func (m *Message) ErrorNotImplement(arg ...Any) *Message { func (m *Message) Error(err bool, arg ...Any) bool { if err { str, meta := m.join(arg...) - m.log(LOG_ERROR, m.FormatChain()) - m.log(LOG_ERROR, str, meta) - m.log(LOG_ERROR, m.FormatStack(2, 100)) - m.error(arg...) + m.log(LOG_ERROR, m.FormatChain()).log(LOG_ERROR, str, meta).log(LOG_ERROR, m.FormatStack(2, 100)).error(arg...) return true } return false @@ -160,34 +141,27 @@ func (m *Message) error(arg ...Any) { } func (m *Message) IsOk() bool { return m.Result() == OK } func (m *Message) IsErr(arg ...string) bool { - return len(arg) == 0 && m.Result(0) == ErrWarn || len(arg) > 0 && m.Result(1) == arg[0] + return len(arg) == 0 && kit.Select("", m.meta[MSG_RESULT], 0) == ErrWarn || len(arg) > 0 && kit.Select("", m.meta[MSG_RESULT], 1) == arg[0] } func (m *Message) IsErrNotFound() bool { return m.IsErr(ErrNotFound) } func (m *Message) Debug(str string, arg ...Any) { - if str == "" { - str = m.FormatMeta() - } + kit.Format(str == "", func() { str = m.FormatMeta() }) m.log(LOG_DEBUG, str, arg...) } func (m *Message) FormatPrefix() string { return kit.Format("%s %d %s->%s", logs.FmtTime(logs.Now()), m.code, m.source.Name, m.target.Name) } -func (m *Message) FormatShip() string { - return kit.Format("%s->%s", m.source.Name, m.target.Name) -} -func (m *Message) FormatCost() string { - return kit.FmtDuration(time.Since(m.time)) -} func (m *Message) FormatSize() string { return kit.Format("%dx%d %v", m.Length(), len(m.meta[MSG_APPEND]), kit.Simple(m.meta[MSG_APPEND])) } -func (m *Message) DumpMeta(w io.Writer, arg ...string) (res string) { - kit.If(len(arg) == 0 && m.Option(DEBUG) == TRUE, func() { arg = []string{SP, SP, NL} }) +func (m *Message) FormatCost() string { return kit.FmtDuration(time.Since(m.time)) } +func (m *Message) FormatMeta() string { return kit.Format(m.meta) } +func (m *Message) FormatsMeta(w io.Writer, arg ...string) (res string) { if w == nil { - buf := bytes.NewBuffer(make([]byte, 1024)) + buf := bytes.NewBuffer(make([]byte, MOD_BUFS)) defer func() { res = buf.String() }() w = buf } @@ -195,6 +169,7 @@ func (m *Message) DumpMeta(w io.Writer, arg ...string) (res string) { kit.If(len(m.meta[k]) == 0 || len(m.meta[k]) == 1 && m.meta[k][0] == "", func() { m.meta[MSG_OPTION][i] = "" }) }) m.meta[MSG_OPTION] = kit.Filters(m.meta[MSG_OPTION], MSG_CMDS, MSG_FIELDS, MSG_SESSID, MSG_OPTS, MSG_HANDLE, MSG_OUTPUT, MSG_INDEX, "", "aaa.checker") + kit.If(len(arg) == 0 && m.Option(DEBUG) == TRUE, func() { arg = []string{SP, SP, NL} }) bio, count, NL := bufio.NewWriter(w), 0, kit.Select("", arg, 2) defer bio.Flush() echo := func(arg ...Any) { fmt.Fprint(bio, arg...) } @@ -213,81 +188,41 @@ func (m *Message) DumpMeta(w io.Writer, arg ...string) (res string) { kit.For(kit.Simple(MSG_DETAIL, MSG_OPTION, m.meta[MSG_OPTION], m.meta[MSG_APPEND], MSG_APPEND, MSG_RESULT), push) return } -func (m *Message) FormatMeta() string { - return kit.Format(m.meta) -} -func (m *Message) FormatsMeta() string { - return kit.Formats(m.meta) -} func (m *Message) FormatChain() string { ms := []*Message{} for msg := m; msg != nil; msg = msg.message { ms = append(ms, msg) } - show := func(msg *Message, meta string) string { - if len(msg.meta[meta]) == 0 || len(msg.meta[meta]) == 1 && msg.meta[meta][0] == "" { + show := func(msg *Message, key string, arg ...string) string { + if len(msg.meta[key]) == 0 || len(msg.meta[key]) == 1 && msg.meta[key][0] == "" { return "" } - return kit.Format("%s:%d %v", meta, len(msg.meta[meta]), msg.meta[meta]) + return kit.Format("%s%s:%s%d %v", kit.Select("", arg, 0), key, kit.Select("", arg, 1), len(msg.meta[key]), msg.meta[key]) } meta := []string{} for i := len(ms) - 1; i >= 0; i-- { msg := ms[i] - meta = append(meta, kit.Join([]string{msg.FormatPrefix(), show(msg, MSG_DETAIL), show(msg, MSG_OPTION), show(msg, MSG_APPEND), show(msg, MSG_RESULT), msg._cmd.GetFileLine()}, SP)) - for _, k := range msg.meta[MSG_OPTION] { - if v, ok := msg.meta[k]; ok { - if len(v) == 0 || len(v) == 1 && v[0] == "" { - continue - } - meta = append(meta, kit.Format("\t%s: %d %v", k, len(v), v)) - } - } - for _, k := range msg.meta[MSG_APPEND] { - if v, ok := msg.meta[k]; ok { - meta = append(meta, kit.Format("\t%s: %d %v", k, len(v), v)) - } - } + meta = append(meta, kit.Join([]string{msg.FormatPrefix(), show(msg, MSG_DETAIL), show(msg, MSG_OPTION), show(msg, MSG_APPEND), show(msg, MSG_RESULT), msg._cmd.FileLines()}, SP)) + kit.For(msg.meta[MSG_OPTION], func(k string) { kit.If(show(msg, k, TB, SP), func(s string) { meta = append(meta, s) }) }) + kit.For(msg.meta[MSG_APPEND], func(k string) { kit.If(show(msg, k, TB, SP), func(s string) { meta = append(meta, s) }) }) } return kit.Join(meta, NL) } func (m *Message) FormatStack(s, n int) string { - pc := make([]uintptr, n+10) + list, pc := []string{}, make([]uintptr, n+10) frames := runtime.CallersFrames(pc[:runtime.Callers(s+1, pc)]) - list := []string{} for { frame, more := frames.Next() - file := kit.Slice(kit.Split(frame.File, PS, PS), -1)[0] name := kit.Slice(kit.Split(frame.Function, PS, PS), -1)[0] + file := kit.Join(kit.Slice(kit.Split(frame.File, PS, PS), -2), PS) switch ls := kit.Split(name, PT, PT); kit.Select("", ls, 0) { case "reflect", "runtime", "http": default: list = append(list, kit.Format("%s:%d\t%s", file, frame.Line, name)) } - if len(list) >= n { - break - } - if !more { + if len(list) >= n || !more { break } } return kit.Join(list, NL) } -func (c *Command) GetFileLine() string { - return kit.Join(kit.Slice(kit.Split(c.GetFileLines(), PS), -3), PS) -} -func (c *Command) GetFileLines() string { - if c == nil { - return "" - } else if c.RawHand != nil { - switch h := c.RawHand.(type) { - case string: - return h - default: - return logs.FileLines(c.RawHand) - } - } else if c.Hand != nil { - return logs.FileLines(c.Hand) - } else { - return "" - } -} diff --git a/meta.go b/meta.go index 0b66b66b..e200953e 100644 --- a/meta.go +++ b/meta.go @@ -12,7 +12,7 @@ func (m *Message) setDetail(key string, arg ...string) *Message { if m.meta[KEY][i] == key { if len(arg) > 0 { m.meta[VALUE][i] = arg[0] - break + return m } for ; i < len(m.meta[KEY])-1; i++ { m.meta[KEY][i] = m.meta[KEY][i+1] @@ -20,9 +20,13 @@ func (m *Message) setDetail(key string, arg ...string) *Message { } m.meta[KEY] = kit.Slice(m.meta[KEY], 0, -1) m.meta[VALUE] = kit.Slice(m.meta[VALUE], 0, -1) - break + return m } } + if len(arg) > 0 { + m.meta[KEY] = append(m.meta[KEY], key) + m.meta[VALUE] = append(m.meta[VALUE], arg[0]) + } return m } func (m *Message) Set(key string, arg ...string) *Message { @@ -43,9 +47,7 @@ func (m *Message) Set(key string, arg ...string) *Message { m.meta[arg[0]] = arg[1:] } } else { - for _, k := range m.meta[key] { - delete(m.meta, k) - } + kit.For(m.meta[key], func(k string) { delete(m.meta, k) }) delete(m.meta, key) } return m @@ -53,9 +55,7 @@ func (m *Message) Set(key string, arg ...string) *Message { if m.FieldsIsDetail() { return m.setDetail(key, arg...) } - for _, k := range kit.Split(key) { - delete(m.meta, k) - } + kit.For(kit.Split(key), func(k string) { delete(m.meta, k) }) } if len(arg) == 0 { return m @@ -90,29 +90,19 @@ func (m *Message) CutTo(key, to string) *Message { } func (m *Message) Push(key string, value Any, arg ...Any) *Message { head := kit.Simple() - if len(head) == 0 && len(arg) > 0 { - head = kit.Simple(arg[0]) - } - if len(head) == 0 { - head = kit.Simple(m.meta[MSG_APPEND]) - } - if len(head) == 0 && !m.FieldsIsDetail() { - head = kit.Split(m.OptionFields()) - } + kit.If(len(head) == 0 && len(arg) > 0, func() { head = kit.Simple(arg[0]) }) + kit.If(len(head) == 0, func() { head = kit.Simple(m.meta[MSG_APPEND]) }) + kit.If(len(head) == 0 && !m.FieldsIsDetail(), func() { head = kit.Split(m.OptionFields()) }) switch value := value.(type) { case Map: - if len(head) == 0 { - head = kit.SortedKey(kit.KeyValue(nil, "", value)) - } + kit.If(len(head) == 0, func() { head = kit.SortedKey(kit.KeyValue(nil, "", value)) }) var val Map - if len(arg) > 1 { - val, _ = arg[1].(Map) - } - for _, k := range head { + kit.If(len(arg) > 1, func() { val, _ = arg[1].(Map) }) + kit.For(head, func(k string) { var v Any switch k { case "_target": - continue + return case KEY, HASH: if key != "" && key != FIELDS_DETAIL { v = key @@ -141,33 +131,25 @@ func (m *Message) Push(key string, value Any, arg ...Any) *Message { } switch v := kit.Format(v); key { case FIELDS_DETAIL: - m.Add(MSG_APPEND, KEY, strings.TrimPrefix(k, EXTRA+PT)) - m.Add(MSG_APPEND, VALUE, v) + m.Add(MSG_APPEND, KEY, strings.TrimPrefix(k, EXTRA+PT)).Add(MSG_APPEND, VALUE, v) default: m.Add(MSG_APPEND, k, v) } - } + }) case Maps: - if len(head) == 0 { - head = kit.SortedKey(value) - } - for _, k := range head { - m.Push(k, value[k]) - } + kit.If(len(head) == 0, func() { head = kit.SortedKey(value) }) + kit.For(head, func(k string) { m.Push(k, value[k]) }) default: - for _, v := range kit.Simple(value, arg) { + kit.For(kit.Simple(value, arg), func(v string) { if m.FieldsIsDetail() { - m.Add(MSG_APPEND, KEY, key) - m.Add(MSG_APPEND, VALUE, kit.Format(value)) + m.Add(MSG_APPEND, KEY, key).Add(MSG_APPEND, VALUE, kit.Format(value)) } else { - if m.ActionKey() == "inputs" { - if kit.IndexOf(m.meta[key], v) > -1 { - continue - } + if m.ActionKey() == INPUTS && kit.IndexOf(m.meta[key], v) > -1 { + return } m.Add(MSG_APPEND, key, v) } - } + }) } return m } @@ -185,14 +167,12 @@ func (m *Message) Copy(msg *Message, arg ...string) *Message { return m } if len(arg) > 0 { - for _, k := range arg[1:] { - m.Add(arg[0], kit.Simple(k, msg.meta[k])...) - } + kit.For(arg[1:], func(k string) { m.Add(arg[0], kit.Simple(k, msg.meta[k])...) }) return m } for _, k := range msg.meta[MSG_OPTION] { switch k { - case MSG_CMDS, MSG_FIELDS, MSG_SESSID, "event": + case MSG_CMDS, MSG_FIELDS, MSG_SESSID, EVENT: continue } if strings.HasSuffix(k, ".cb") { @@ -208,70 +188,50 @@ func (m *Message) Copy(msg *Message, arg ...string) *Message { } m.Add(MSG_OPTION, kit.Simple(k, msg.meta[k])...) } - for _, k := range msg.meta[MSG_APPEND] { - m.Add(MSG_APPEND, kit.Simple(k, msg.meta[k])...) - } + kit.For(msg.meta[MSG_APPEND], func(k string) { m.Add(MSG_APPEND, kit.Simple(k, msg.meta[k])...) }) return m.Add(MSG_RESULT, msg.meta[MSG_RESULT]...) } func (m *Message) Length() (max int) { - for _, k := range m.meta[MSG_APPEND] { - if l := len(m.meta[k]); l > max { - max = l - } - } + kit.For(m.meta[MSG_APPEND], func(k string) { max = kit.Max(len(m.meta[k]), max) }) return max } -func (m *Message) TablesLimit(count int, cbs ...func(value Maps)) *Message { - return m.Table(func(index int, value Maps, head []string) { - if index < count { - for _, cb := range cbs { - if cb != nil { - cb(value) - } - } - } - }) +func (m *Message) TablesLimit(count int, cb func(value Maps)) *Message { + return m.Table(func(index int, value Maps) { kit.If(index < count, func() { cb(value) }) }) } -func (m *Message) Tables(cbs ...func(value Maps)) *Message { - return m.Table(func(index int, value Maps, head []string) { - for _, cb := range cbs { - if cb != nil { - cb(value) - } - } - }) -} -func (m *Message) Table(cbs ...func(index int, value Maps, head []string)) *Message { - if len(cbs) > 0 && cbs[0] != nil { - n := m.Length() - if n == 0 { - return m - } - if m.FieldsIsDetail() { - value := Maps{} - for i, k := range m.meta[KEY] { - value[k] = kit.Select("", m.meta[VALUE], i) - } - for _, cb := range cbs { - cb(0, value, m.meta[KEY]) - } - return m - } - for i := 0; i < n; i++ { - value := Maps{} - for _, k := range m.meta[MSG_APPEND] { - value[k] = kit.Select("", m.meta[k], i) - } - for _, cb := range cbs { - cb(i, value, m.meta[MSG_APPEND]) - } - } +func (m *Message) Table(cb Any) *Message { + n := m.Length() + if n == 0 { return m } + cbs := func(index int, value Maps, head []string) { + switch cb := cb.(type) { + case func(index int, value Maps, head []string): + cb(index, value, head) + case func(index int, value Maps): + cb(index, value) + case func(value Maps): + cb(value) + default: + m.ErrorNotImplement(cb) + } + } + if m.FieldsIsDetail() { + value := Maps{} + kit.For(m.meta[KEY], func(i int, k string) { value[k] = kit.Select("", m.meta[VALUE], i) }) + cbs(0, value, m.meta[KEY]) + return m + } + for i := 0; i < n; i++ { + value := Maps{} + kit.For(m.meta[MSG_APPEND], func(k string) { value[k] = kit.Select("", m.meta[k], i) }) + cbs(i, value, m.meta[MSG_APPEND]) + } + return m +} +func (m *Message) TableEcho() *Message { const ( TABLE_ROW_SEP = "table.row_sep" TABLE_COL_SEP = "table.col_sep" - TABLE_COMPACT = "table.compact" TABLE_SPACE = "table.space" TABLE_ALIGN = "table.align" ) @@ -285,35 +245,27 @@ func (m *Message) Table(cbs ...func(index int, value Maps, head []string)) *Mess } m.Echo(rows) } - compact := m.Option(TABLE_COMPACT) == TRUE space := kit.Select(SP, m.Option(TABLE_SPACE)) align := kit.Select("left", m.Option(TABLE_ALIGN)) _align := func(value string, width int) string { - if compact { - return value + space - } - n := width - kit.Width(value, len(space)) - switch align { + switch n := width - kit.Width(value, len(space)); align { case "left": return value + strings.Repeat(space, n) case "right": return strings.Repeat(space, n) + value case "center": return strings.Repeat(space, n/2) + value + strings.Repeat(space, n-n/2) + default: + return value + space } - return value + space } length, width := 0, map[string]int{} for _, k := range m.meta[MSG_APPEND] { - if len(m.meta[k]) > length { - length = len(m.meta[k]) - } + kit.If(len(m.meta[k]) > length, func() { length = len(m.meta[k]) }) width[k] = kit.Width(k, len(space)) - for _, v := range m.meta[k] { - if kit.Width(v, len(space)) > width[k] { - width[k] = kit.Width(v, len(space)) - } - } + kit.For(m.meta[k], func(v string) { + kit.If(kit.Width(v, len(space)) > width[k], func() { width[k] = kit.Width(v, len(space)) }) + }) } show(kit.Simple(m.meta[MSG_APPEND], func(k string) string { return _align(k, width[k]) })) for i := 0; i < length; i++ { @@ -323,13 +275,10 @@ func (m *Message) Table(cbs ...func(index int, value Maps, head []string)) *Mess } const ( - INT = "int" - STR = "str" - // TIME = "time" - - TIME_R = "time_r" - STR_R = "str_r" - INT_R = "int_r" + STR = "str" + STR_R = "str_r" + INT_R = "int_r" + INT = "int" ) func (m *Message) Sort(key string, arg ...string) *Message { @@ -350,34 +299,23 @@ func (m *Message) Sort(key string, arg ...string) *Message { cmps = append(cmps, cmp) } list := []Maps{} - m.Tables(func(value Maps) { list = append(list, value) }) + m.Table(func(value Maps) { list = append(list, value) }) gt := func(i, j int) bool { for s, k := range keys { - a, b := list[i][k], list[j][k] - if a == b { - continue - } - switch cmp := cmps[s]; cmp { - case INT, INT_R: - if kit.Int(a) > kit.Int(b) { - return cmp == INT - } - if kit.Int(a) < kit.Int(b) { - return cmp == INT_R - } - case STR, STR_R: - if a > b { - return cmp == STR - } - if a < b { - return cmp == STR_R - } - case TIME, TIME_R: - if kit.Time(a) > kit.Time(b) { - return cmp == TIME - } - if kit.Time(a) < kit.Time(b) { - return cmp == TIME_R + if a, b := list[i][k], list[j][k]; a != b { + switch cmp := cmps[s]; cmp { + case STR, STR_R: + if a > b { + return cmp == STR + } else if a < b { + return cmp == STR_R + } + case INT, INT_R: + if kit.Int(a) > kit.Int(b) { + return cmp == INT + } else if kit.Int(a) < kit.Int(b) { + return cmp == INT_R + } } } } @@ -386,67 +324,44 @@ func (m *Message) Sort(key string, arg ...string) *Message { for i := 0; i < len(list)-1; i++ { min := i for j := i + 1; j < len(list); j++ { - if gt(min, j) { - min = j - } + kit.If(gt(min, j), func() { min = j }) } for j := min; j > i; j-- { list[j], list[j-1] = list[j-1], list[j] } } - for _, k := range m.meta[MSG_APPEND] { - delete(m.meta, k) - } + kit.For(m.meta[MSG_APPEND], func(k string) { delete(m.meta, k) }) for _, v := range list { - for _, k := range m.meta[MSG_APPEND] { - m.Add(MSG_APPEND, k, v[k]) - } + kit.For(m.meta[MSG_APPEND], func(k string) { m.Add(MSG_APPEND, k, v[k]) }) } return m } -func (m *Message) SortInt(key string) *Message { return m.Sort(key, INT) } -func (m *Message) SortStr(key string) *Message { return m.Sort(key, STR) } -func (m *Message) SortTime(key string) *Message { return m.Sort(key, TIME) } -func (m *Message) SortTimeR(key string) *Message { return m.Sort(key, TIME_R) } -func (m *Message) SortStrR(key string) *Message { return m.Sort(key, STR_R) } -func (m *Message) SortIntR(key string) *Message { return m.Sort(key, INT_R) } +func (m *Message) SortStr(key string) *Message { return m.Sort(key, STR) } +func (m *Message) SortStrR(key string) *Message { return m.Sort(key, STR_R) } +func (m *Message) SortIntR(key string) *Message { return m.Sort(key, INT_R) } +func (m *Message) SortInt(key string) *Message { return m.Sort(key, INT) } func (m *Message) Detail(arg ...Any) string { return kit.Select("", m.meta[MSG_DETAIL], 0) } func (m *Message) Detailv(arg ...Any) []string { - if len(arg) > 0 { - m.meta[MSG_DETAIL] = kit.Simple(arg...) - } + kit.If(len(arg) > 0, func() { m.meta[MSG_DETAIL] = kit.Simple(arg...) }) return m.meta[MSG_DETAIL] } func (m *Message) Options(arg ...Any) *Message { for i := 0; i < len(arg); i += 2 { - switch val := arg[i].(type) { - case Maps: - for k, v := range val { - m.Optionv(k, v) - } + if key, ok := arg[i].(string); ok { + kit.If(i+1 < len(arg), func() { m.Optionv(key, arg[i+1]) }) + } else { + kit.For(arg[i], func(k, v string) { m.Optionv(k, v) }) i-- - continue - case []string: - for i := 0; i < len(val)-1; i += 2 { - m.Optionv(val[i], val[i+1]) - } - i-- - continue - } - if i+1 < len(arg) { - m.Optionv(kit.Format(arg[i]), arg[i+1]) } } return m } func (m *Message) Optionv(key string, arg ...Any) Any { if len(arg) > 0 { - if kit.IndexOf(m.meta[MSG_OPTION], key) == -1 { - m.meta[MSG_OPTION] = append(m.meta[MSG_OPTION], key) - } + kit.If(kit.IndexOf(m.meta[MSG_OPTION], key) == -1, func() { m.meta[MSG_OPTION] = append(m.meta[MSG_OPTION], key) }) switch delete(m.data, key); v := arg[0].(type) { case nil: delete(m.meta, key) @@ -481,28 +396,21 @@ func (m *Message) Appendv(key string, arg ...Any) []string { if m.FieldsIsDetail() { for i, k := range m.meta[KEY] { if k == key || k == kit.Keys(EXTRA, key) { - if len(arg) > 0 { - m.meta[VALUE][i] = kit.Format(arg[0]) - } + kit.If(len(arg) > 0, func() { m.meta[VALUE][i] = kit.Format(arg[0]) }) return []string{kit.Select("", m.meta[VALUE], i)} } } if len(arg) > 0 { - m.Add(MSG_APPEND, KEY, key) - m.Add(MSG_APPEND, VALUE, kit.Format(arg[0])) + m.Add(MSG_APPEND, KEY, key).Add(MSG_APPEND, VALUE, kit.Format(arg[0])) return []string{kit.Format(arg[0])} } return nil } if key == MSG_APPEND { - if len(arg) > 0 { - m.meta[MSG_APPEND] = kit.Simple(arg) - } + kit.If(len(arg) > 0, func() { m.meta[key] = kit.Simple(arg) }) return m.meta[key] } - if len(arg) > 0 { - m.meta[key] = kit.Simple(arg...) - } + kit.If(len(arg) > 0, func() { m.meta[key] = kit.Simple(arg...) }) if v, ok := m.meta[key]; ok { return v } @@ -512,20 +420,10 @@ func (m *Message) Appendv(key string, arg ...Any) []string { return nil } func (m *Message) Resultv(arg ...Any) []string { - if len(arg) > 0 { - m.meta[MSG_RESULT] = kit.Simple(arg...) - } + kit.If(len(arg) > 0, func() { m.meta[MSG_RESULT] = kit.Simple(arg...) }) return m.meta[MSG_RESULT] } -func (m *Message) Result(arg ...Any) string { - if len(arg) > 0 { - switch v := arg[0].(type) { - case int: - return kit.Select("", m.meta[MSG_RESULT], v) - } - } - return strings.Join(m.Resultv(arg...), "") -} +func (m *Message) Result(arg ...Any) string { return strings.Join(m.Resultv(arg...), "") } func (m *Message) Results(arg ...Any) string { - return kit.Select("", strings.TrimSpace(m.Result()), !m.IsErr()) + return kit.Select("", strings.TrimSpace(m.Result(arg...)), !m.IsErr()) } diff --git a/misc.go b/misc.go index 459e76ca..c0bcb44c 100644 --- a/misc.go +++ b/misc.go @@ -1,11 +1,9 @@ package ice import ( - "reflect" "strings" kit "shylinux.com/x/toolkits" - "shylinux.com/x/toolkits/logs" ) func (m *Message) Split(str string, arg ...string) *Message { @@ -65,6 +63,13 @@ func (m *Message) Split(str string, arg ...string) *Message { func (m *Message) SplitIndex(str string, arg ...string) *Message { return m.Split(str, kit.Simple(INDEX, arg)...) } +func (m *Message) SetAppend(arg ...string) *Message { + kit.If(len(arg) == 0, func() { m.OptionFields("") }) + return m.Set(MSG_APPEND, arg...) +} +func (m *Message) SetResult(arg ...string) *Message { + return m.Set(MSG_RESULT, arg...) +} func (m *Message) PushRecord(value Any, arg ...string) *Message { return m.Push("", value, kit.Split(kit.Join(arg))) } @@ -75,31 +80,25 @@ func (m *Message) PushDetail(value Any, arg ...string) *Message { } return m.Push(FIELDS_DETAIL, value, kit.Split(kit.Join(arg))) } - -func (m *Message) ToLowerAppend(arg ...string) *Message { - for _, k := range m.meta[MSG_APPEND] { - m.RenameAppend(k, strings.ToLower(k)) - } - return m -} func (m *Message) RenameOption(from, to string) *Message { - m.Option(to, m.Option(from)) - m.Option(from, "") - return m + return m.Options(to, m.Option(from), from, "") } func (m *Message) RenameAppend(arg ...string) *Message { - for i := 0; i < len(arg)-1; i += 2 { - if arg[i] == arg[i+1] { - continue + kit.For(arg, func(from, to string) { + if from == to { + return } - for j, v := range m.meta[MSG_APPEND] { - if v == arg[i] { - m.meta[MSG_APPEND][j] = arg[i+1] - m.meta[arg[i+1]] = m.meta[arg[i]] - delete(m.meta, arg[i]) + kit.For(m.meta[MSG_APPEND], func(i int, k string) { + if k == from { + m.meta[MSG_APPEND][i], m.meta[to] = to, m.meta[from] + delete(m.meta, from) } - } - } + }) + }) + return m +} +func (m *Message) ToLowerAppend(arg ...string) *Message { + kit.For(m.meta[MSG_APPEND], func(k string) { m.RenameAppend(k, strings.ToLower(k)) }) return m } func (m *Message) AppendSimple(key ...string) (res []string) { @@ -110,9 +109,7 @@ func (m *Message) AppendSimple(key ...string) (res []string) { key = append(key, m.Appendv(MSG_APPEND)...) } } - for _, k := range key { - res = append(res, k, m.Append(k)) - } + kit.For(key, func(k string) { res = append(res, k, m.Append(k)) }) return } func (m *Message) AppendTrans(cb func(value string, key string, index int) string) *Message { @@ -130,379 +127,13 @@ func (m *Message) AppendTrans(cb func(value string, key string, index int) strin } return m } -func (m *Message) SetAppend(arg ...string) *Message { - if len(arg) == 0 { - m.OptionFields("") - } - return m.Set(MSG_APPEND, arg...) -} -func (m *Message) SetResult(arg ...string) *Message { - return m.Set(MSG_RESULT, arg...) -} - -func (m *Message) Design(action Any, help string, input ...Any) { - list := kit.List() - for _, input := range input { - switch input := input.(type) { - case string: - list = append(list, SplitCmd("action "+input, nil)...) - case Map: - if kit.Format(input[TYPE]) != "" && kit.Format(input[NAME]) != "" { - list = append(list, input) - continue - } - kit.For(kit.KeyValue(nil, "", input), func(k string, v Any) { - list = append(list, kit.Dict(NAME, k, TYPE, TEXT, VALUE, v)) - }) - default: - m.ErrorNotImplement(input) - } - } - k := kit.Format(action) - if a, ok := m._cmd.Actions[k]; ok { - m._cmd.Meta[k], a.List = list, list - kit.Value(m._cmd.Meta, kit.Keys("_trans", k), help) - } -} -func (m *Message) _fileline() string { - switch m.target.Name { - case MDB, GDB, AAA: - return m._source - default: - return m._target - } -} -func (m *Message) ActionHand(cmd *Command, key, sub string, arg ...string) *Message { - if action, ok := cmd.Actions[sub]; !m.Warn(!ok, ErrNotFound, sub, cmd.GetFileLine()) { - return m.Target()._action(m, cmd, key, sub, action, arg...) - } - return m -} -func (m *Message) CmdHand(cmd *Command, key string, arg ...string) *Message { - if m._key, m._cmd = key, cmd; cmd == nil { - return m - } - m._target = kit.Join(kit.Slice(kit.Split(cmd.GetFileLines(), PS), -3), PS) - if fileline := m._fileline(); key == SELECT { - m.Log(LOG_CMDS, "%s.%s %d %v %v", m.Target().Name, key, len(arg), arg, m.Optionv(MSG_FIELDS), logs.FileLineMeta(fileline)) - } else { - m.Log(LOG_CMDS, "%s.%s %d %v", m.Target().Name, key, len(arg), arg, logs.FileLineMeta(fileline)) - } - if cmd.Hand != nil { - cmd.Hand(m, arg...) - } else if cmd.Actions != nil && cmd.Actions[SELECT] != nil { - cmd.Actions[SELECT].Hand(m, arg...) - } - return m -} -func (m *Message) _command(arg ...Any) *Message { - args, opts, cbs, _source := []Any{}, Map{}, kit.Value(nil), logs.FileLine(3) - for _, v := range arg { - switch val := v.(type) { - case string: - args = append(args, v) - case Maps: - for k, v := range val { - opts[k] = v - } - case Map: - for k, v := range kit.KeyValue(nil, "", val) { - opts[k] = v - } - case Option: - opts[val.Name] = val.Value - case *Option: - opts[val.Name] = val.Value - case logs.Meta: - if val.Key == "fileline" { - _source = val.Value - } - case func(int, Maps, []string): - defer func() { m.Table(val) }() - case func(Maps): - defer func() { m.Tables(val) }() - case nil: - default: - if reflect.TypeOf(val).Kind() == reflect.Func { - cbs = val - } else { - args = append(args, v) - } - } - } - list := kit.Simple(args...) - if len(list) == 0 && !m.Hand { - list = m.meta[MSG_DETAIL] - } - if len(list) == 0 { - return m - } - ok := false - run := func(msg *Message, ctx *Context, cmd *Command, key string, arg ...string) { - key = kit.Slice(strings.Split(key, PT), -1)[0] - if ok = true; cbs != nil { - msg.OptionCB(key, cbs) - } - for k, v := range opts { - msg.Option(k, v) - } - msg._source = _source - m.TryCatch(msg, true, func(msg *Message) { m = ctx._command(msg, cmd, key, arg...) }) - } - if list[0] == "" { - run(m.Spawn(), m.target, m._cmd, m._key, list[1:]...) - } else if cmd, ok := m.target.Commands[strings.TrimPrefix(list[0], m.target.Cap(CTX_FOLLOW)+PT)]; ok { - run(m.Spawn(), m.target, cmd, list[0], list[1:]...) - } else if cmd, ok := m.source.Commands[strings.TrimPrefix(list[0], m.source.Cap(CTX_FOLLOW)+PT)]; ok { - run(m.Spawn(m.source), m.source, cmd, list[0], list[1:]...) - } else { - m.Search(list[0], func(p *Context, s *Context, key string, cmd *Command) { - run(m.Spawn(s), s, cmd, key, list[1:]...) - }) - } - m.Warn(!ok, ErrNotFound, kit.Format(list)) - return m -} -func (c *Context) _command(m *Message, cmd *Command, key string, arg ...string) *Message { - if m._key, m._sub, m._cmd = key, SELECT, cmd; cmd == nil { - return m - } - if m.Hand, m.meta[MSG_DETAIL] = true, kit.Simple(m.PrefixKey(), arg); cmd.Actions != nil { - if len(arg) > 1 && arg[0] == ACTION { - if h, ok := cmd.Actions[arg[1]]; ok { - return c._action(m, cmd, key, arg[1], h, arg[2:]...) - } - } - if len(arg) > 0 { - if h, ok := cmd.Actions[arg[0]]; ok { - return c._action(m, cmd, key, arg[0], h, arg[1:]...) - } - } - } - if len(arg) > 0 && arg[0] == ACTION { - if arg[1] == "inputs" { - return m - } - } - return m.CmdHand(cmd, key, arg...) -} -func (c *Context) _action(m *Message, cmd *Command, key string, sub string, h *Action, arg ...string) *Message { - if h.Hand == nil { - return m.Cmdy(kit.Split(kit.Select(sub, h.Name)), arg) - } - if m._key, m._cmd, m._sub = key, cmd, sub; len(h.List) > 0 && sub != SEARCH { - order := false - for i, v := range h.List { - name := kit.Format(kit.Value(v, NAME)) - if i == 0 { - if len(arg) > 0 && arg[0] == name { - for i := 0; i < len(arg)-1; i += 2 { - if strings.HasPrefix(arg[i], PS) { - break - } - // if arg[i+1] != "" { - // m.Option(arg[i], arg[i+1]) - // } - m.Option(arg[i], arg[i+1]) - } - } else { - order = true - } - } - if order { - // if value := kit.Select("", arg, i); value != "" { - // m.Option(name, value) - // } - if i < len(arg) { - m.Option(name, arg[i]) - } - } - if m.Warn(m.OptionDefault(name, kit.Format(kit.Value(v, VALUE))) == "" && kit.Value(v, "need") == "must", ErrNotValid, name) { - return m - } - } - } - if m._target = logs.FileLine(h.Hand); cmd.RawHand != nil { - m._target = kit.Join(kit.Slice(kit.Split(kit.Format(cmd.RawHand), PS), -3), PS) - } - m.Log(LOG_CMDS, "%s.%s %s %d %v", c.Name, key, sub, len(arg), arg, logs.FileLineMeta(m._fileline())) - h.Hand(m, arg...) - return m -} -func MergeActions(arg ...Any) Actions { - if len(arg) == 0 { - return nil - } - list := arg[0].(Actions) - for _, from := range arg[1:] { - switch from := from.(type) { - case Actions: - for k, v := range from { - if h, ok := list[k]; !ok { - list[k] = v - } else if k == CTX_INIT { - last := h.Hand - hand := v.Hand - h.Hand = func(m *Message, arg ...string) { - hand(m, arg...) - last(m, arg...) - } - } else if k == CTX_EXIT { - last := h.Hand - hand := v.Hand - h.Hand = func(m *Message, arg ...string) { - last(m, arg...) - hand(m, arg...) - } - } else if h.Name = kit.Select(v.Name, h.Name); h.Hand == nil { - h.Hand = v.Hand - } - } - case string: - h := list[CTX_INIT] - list[CTX_INIT] = &Action{Hand: func(m *Message, arg ...string) { - m.Search(from, func(p *Context, s *Context, key string, cmd *Command) { - for k, v := range cmd.Actions { - func(k string) { - if h, ok := list[k]; !ok { - list[k] = &Action{Name: v.Name, Help: v.Help, Hand: func(m *Message, arg ...string) { m.Cmdy(from, k, arg) }} - } else if h.Hand == nil { - h.Hand = func(m *Message, arg ...string) { m.Cmdy(from, k, arg) } - } - }(k) - } - }) - if h != nil { - h.Hand(m, arg...) - } - }} - default: - Pulse.ErrorNotImplement(from) - } - } - return list -} -func SplitCmd(name string, actions Actions) (list []Any) { - const ( - TEXT = "text" - CONTENT = "content" - TEXTAREA = "textarea" - PASSWORD = "password" - SELECT = "select" - BUTTON = "button" - ) - const ( - RUN = "run" - REFRESH = "refresh" - LIST = "list" - BACK = "back" - AUTO = "auto" - PAGE = "page" - ARGS = "args" - ) - item, button := kit.Dict(), false - push := func(arg ...string) { - button = kit.Select("", arg, 0) == BUTTON - item = kit.Dict(TYPE, kit.Select("", arg, 0), NAME, kit.Select("", arg, 1), ACTION, kit.Select("", arg, 2)) - list = append(list, item) - } - ls := kit.Split(name, SP, "*:=@") - for i := 1; i < len(ls); i++ { - switch ls[i] { - case RUN: - push(BUTTON, ls[i]) - case REFRESH: - push(BUTTON, ls[i], AUTO) - case LIST: - push(BUTTON, ls[i], AUTO) - case AUTO: - push(BUTTON, LIST, AUTO) - push(BUTTON, BACK) - case PAGE: - push(TEXT, "limit") - push(TEXT, "offend") - push(BUTTON, "prev") - push(BUTTON, "next") - case ARGS, TEXT, TEXTAREA, CONTENT: - push(TEXTAREA, ls[i]) - case PASSWORD: - push(PASSWORD, ls[i]) - case "time": - push(TEXT, ls[i], "date") - case "*": - item["need"] = "must" - case DF: - if item[TYPE] = kit.Select("", ls, i+1); item[TYPE] == BUTTON { - button = true - } - i++ - case EQ: - if value := kit.Select("", ls, i+1); strings.Contains(value, FS) { - vs := kit.Split(value) - if strings.Count(value, vs[0]) > 1 { - item["values"] = vs[1:] - } else { - item["values"] = vs - } - item[VALUE] = vs[0] - item[TYPE] = SELECT - } else { - item[VALUE] = value - } - i++ - case AT: - item[ACTION] = kit.Select("", ls, i+1) - i++ - default: - push(kit.Select(TEXT, BUTTON, button || actions != nil && actions[ls[i]] != nil), ls[i]) - } - } - return list -} -func MergeHand(hand ...Handler) Handler { - if len(hand) == 0 { - return nil - } - if len(hand) == 1 { - return hand[0] - } - return func(m *Message, arg ...string) { - for _, h := range hand { - if h != nil { - h(m, arg...) - } - } - } -} -func (m *Message) CmdMap(arg ...string) map[string]map[string]string { - field, list := kit.Slice(arg, -1)[0], map[string]map[string]string{} - m._command(kit.Slice(arg, 0, -1)).Tables(func(value Maps) { list[value[field]] = value }) - return list -} func (m *Message) CmdAppend(arg ...Any) string { args := kit.Simple(arg...) field := kit.Slice(args, -1)[0] return m._command(kit.Slice(args, 0, -1), OptionFields(field)).Append(field) } -func (m *Message) IsCliUA() bool { - if m.Option(MSG_USERUA) == "" || !strings.HasPrefix(m.Option(MSG_USERUA), "Mozilla") { - return true - } - return false -} -func (m *Message) IsMobileUA() bool { - return strings.Contains(m.Option(MSG_USERUA), "Mobile") -} -func (m *Message) MergePodCmd(pod, cmd string, arg ...Any) string { - ls := []string{"chat"} - kit.If(kit.Keys(m.Option(MSG_USERPOD), pod), func(p string) { ls = append(ls, POD, p) }) - if cmd == "" { - if _, ok := Info.Index[m.CommandKey()]; ok { - cmd = m.CommandKey() - } else { - cmd = m.PrefixKey() - } - } - ls = append(ls, CMD, cmd) - return kit.MergeURL2(strings.Split(kit.Select(Info.Domain, m.Option(MSG_USERWEB)), QS)[0], PS+kit.Join(ls, PS), arg...) +func (m *Message) CmdMap(arg ...string) map[string]map[string]string { + field, list := kit.Slice(arg, -1)[0], map[string]map[string]string{} + m._command(kit.Slice(arg, 0, -1)).Table(func(value Maps) { list[value[field]] = value }) + return list } diff --git a/misc/alpha/alpha.go b/misc/alpha/alpha.go index ad4236f8..95009d6b 100644 --- a/misc/alpha/alpha.go +++ b/misc/alpha/alpha.go @@ -55,7 +55,7 @@ func (s alpha) List(m *ice.Message, arg ...string) { m.OptionFields(ice.FIELDS_DETAIL) arg[1] = "^" + arg[1] + ice.FS } - wiki.CSV(m.Message.Spawn(), m.Cmdx(cli.SYSTEM, "grep", "-rih", arg[1], mdb.Config(m, mdb.STORE)), kit.Split(mdb.Config(m, mdb.FIELD))...).Tables(func(value ice.Maps) { + wiki.CSV(m.Message.Spawn(), m.Cmdx(cli.SYSTEM, "grep", "-rih", arg[1], mdb.Config(m, mdb.STORE)), kit.Split(mdb.Config(m, mdb.FIELD))...).Table(func(value ice.Maps) { kit.If(m.FieldsIsDetail(), func() { m.PushDetail(value, mdb.Config(m, mdb.FIELD)) }, func() { m.PushRecord(value, mdb.Config(m, mdb.FIELD)) }) }).StatusTimeCount() } diff --git a/misc/bash/download.go b/misc/bash/download.go index ede7a279..3d52e3a7 100644 --- a/misc/bash/download.go +++ b/misc/bash/download.go @@ -19,7 +19,7 @@ func init() { Index.MergeCommands(ice.Commands{ web.P(web.DOWNLOAD): {Hand: func(m *ice.Message, arg ...string) { if len(arg) == 0 || arg[0] == "" { - m.Cmdy(FAVOR, _DOWNLOAD).Table() + m.Cmdy(FAVOR, _DOWNLOAD).TableEcho() } else { m.Cmdy(web.CACHE, m.Cmd(FAVOR, _DOWNLOAD, arg[0]).Append(mdb.TEXT)) m.Render(kit.Select(ice.RENDER_DOWNLOAD, ice.RENDER_RESULT, m.Append(nfs.FILE) == ""), m.Append(mdb.TEXT)) diff --git a/misc/bash/favor.go b/misc/bash/favor.go index 341ea4d3..fe2e43a9 100644 --- a/misc/bash/favor.go +++ b/misc/bash/favor.go @@ -42,6 +42,6 @@ func init() { } }) }}, - }, Hand: func(m *ice.Message, arg ...string) { m.Cmdy(FAVOR).Table() }}, + }, Hand: func(m *ice.Message, arg ...string) { m.Cmdy(FAVOR).TableEcho() }}, }) } diff --git a/misc/bash/grant.go b/misc/bash/grant.go index a88035ac..ffd9e217 100644 --- a/misc/bash/grant.go +++ b/misc/bash/grant.go @@ -20,7 +20,7 @@ func init() { if m.Cmdy(SESS, arg); len(arg) > 0 && m.Append(GRANT) == "" { m.Echo("请授权 %s@%s 访问 %s", m.Append(aaa.USERNAME), m.Append(tcp.HOSTNAME), web.UserHost(m)) } - m.Tables(func(value ice.Maps) { m.PushButton(kit.Select(mdb.REVERT, mdb.MODIFY, value[GRANT] == "")) }) + m.Table(func(value ice.Maps) { m.PushButton(kit.Select(mdb.REVERT, mdb.MODIFY, value[GRANT] == "")) }) }}, }) } diff --git a/misc/bash/run.go b/misc/bash/run.go index 0eae5012..c74a7d56 100644 --- a/misc/bash/run.go +++ b/misc/bash/run.go @@ -127,7 +127,7 @@ func Complete(m *ice.Message, detail bool, arg ...string) (res []string) { }) } else { m.Options(arg[3:]) - m.Cmdy(arg[0], mdb.INPUTS, kit.Select("", arg, -1)).Tables(func(value ice.Maps) { + m.Cmdy(arg[0], mdb.INPUTS, kit.Select("", arg, -1)).Table(func(value ice.Maps) { v := value[m.Appendv(ice.MSG_APPEND)[0]] kit.If(strings.Contains(v, ice.SP), func() { echo("\"" + v + "\"") }, func() { echo(v) }) }) diff --git a/misc/chrome/daemon.go b/misc/chrome/daemon.go index 88685bdc..21245929 100644 --- a/misc/chrome/daemon.go +++ b/misc/chrome/daemon.go @@ -23,15 +23,13 @@ func (s daemon) send(m *ice.Message, arg ...ice.Any) *ice.Message { func (s daemon) Inputs(m *ice.Message, arg ...string) { switch arg[0] { case web.DOMAIN: - s.send(m.Spawn()).Tables(func(value ice.Maps) { - s.send(m.Spawn(), value[WID]).Tables(func(value ice.Maps) { + s.send(m.Spawn()).Table(func(value ice.Maps) { + s.send(m.Spawn(), value[WID]).Table(func(value ice.Maps) { if value[URL] != "" { m.Push(arg[0], kit.ParseURL(value[URL]).Host) } }) - m.Debug("what %v", m.FormatsMeta()) }).Sort(arg[0]) - m.Debug("what %v", m.FormatsMeta()) case ctx.INDEX: ctx.CmdList(m.Message) } diff --git a/misc/chrome/field.go b/misc/chrome/field.go index 30e58f8b..2dba0b5a 100644 --- a/misc/chrome/field.go +++ b/misc/chrome/field.go @@ -32,7 +32,7 @@ func (s field) Command(m *ice.Message, arg ...string) { }) } func (s field) Run(m *ice.Message, arg ...string) { - s.Zone.List(m.Spawn(), m.Option(web.DOMAIN), arg[0]).Tables(func(value ice.Maps) { + s.Zone.List(m.Spawn(), m.Option(web.DOMAIN), arg[0]).Table(func(value ice.Maps) { m.Cmdy(value[mdb.INDEX], arg[1:]) }) } diff --git a/misc/chrome/spide.go b/misc/chrome/spide.go index c34bf85d..4328402d 100644 --- a/misc/chrome/spide.go +++ b/misc/chrome/spide.go @@ -19,7 +19,7 @@ func (s spide) List(m *ice.Message, arg ...string) { s.daemon.List(m, arg...) return } - s.send(m, arg[:2], "spide").Tables(func(value ice.Maps) { + s.send(m, arg[:2], "spide").Table(func(value ice.Maps) { switch value[mdb.TYPE] { case wiki.AUDIO: m.PushAudios(mdb.SHOW, value[mdb.LINK]) diff --git a/misc/chrome/style.go b/misc/chrome/style.go index 1807a137..59beea4c 100644 --- a/misc/chrome/style.go +++ b/misc/chrome/style.go @@ -23,7 +23,7 @@ func (s style) Inputs(m *ice.Message, arg ...string) { s.daemon.Inputs(m, arg...) } func (s style) Command(m *ice.Message, arg ...string) { - s.Zone.List(m, m.Option(web.DOMAIN)).Tables(func(value ice.Maps) { + s.Zone.List(m, m.Option(web.DOMAIN)).Table(func(value ice.Maps) { s.send(m, "1", m.Option(TID), m.CommandKey(), value[SELECTOR], value[PROPERTY]) }) } diff --git a/misc/coder/server.go b/misc/coder/server.go index e22298a9..d73e4d2d 100644 --- a/misc/coder/server.go +++ b/misc/coder/server.go @@ -25,7 +25,7 @@ type server struct { func (s server) Search(m *ice.Message, arg ...string) { if arg[0] == mdb.FOREACH && arg[1] == "" { s.Code.List(m.Spawn(kit.Dict(ice.MSG_FIELDS, "time,port,status,pid,cmd,dir")), "") - m.Tables(func(value ice.Maps) { + m.Table(func(value ice.Maps) { m.PushSearch(mdb.TYPE, value[cli.STATUS], mdb.NAME, value[nfs.PATH], mdb.TEXT, value[mdb.LINK]) }) } @@ -42,7 +42,7 @@ password: %s } func (s server) List(m *ice.Message, arg ...string) { if s.Code.List(m, "", arg...); len(arg) == 0 { - m.Tables(func(value ice.Maps) { + m.Table(func(value ice.Maps) { switch value[cli.STATUS] { case cli.START: m.PushButton(s.Open, s.Stop) diff --git a/misc/git/server.go b/misc/git/server.go index f9760755..09548578 100644 --- a/misc/git/server.go +++ b/misc/git/server.go @@ -153,7 +153,7 @@ func init() { _repos_init(m, path.Join(ice.USR_LOCAL_REPOS, m.Option(mdb.NAME))) }}, mdb.IMPORT: {Hand: func(m *ice.Message, arg ...string) { - ReposList(m).Tables(func(value ice.Maps) { + ReposList(m).Table(func(value ice.Maps) { m.Option(cli.CMD_DIR, value[nfs.PATH]) remote := _git_url(m, value[REPOS]) _git_cmd(m, PUSH, remote, MASTER) @@ -190,7 +190,7 @@ func init() { m.Option(ice.MSG_USERROLE, aaa.TECH) m.Cmdy(nfs.DIR, nfs.PWD, "time,name,size,action", kit.Dict(nfs.DIR_TYPE, nfs.TYPE_DIR), func(value ice.Maps) { m.PushScript("git clone " + _git_url(m, value[mdb.NAME])) - }).Cut("time,name,size,script,action").RenameAppend(mdb.NAME, nfs.REPOS).SortTimeR(mdb.TIME) + }).Cut("time,name,size,script,action").RenameAppend(mdb.NAME, nfs.REPOS).SortStrR(mdb.TIME) m.Echo(strings.ReplaceAll(m.Cmdx("web.code.publish", ice.CONTEXTS), "app username", "dev username")) m.Echo(m.Cmdx(TOKEN, m.Option(ice.MSG_USERNAME))) } else if dir := path.Join(m.Option(nfs.DIR_ROOT), arg[0]); len(arg) == 1 { diff --git a/misc/git/status.go b/misc/git/status.go index 8b450d3c..0af613a3 100644 --- a/misc/git/status.go +++ b/misc/git/status.go @@ -83,7 +83,7 @@ func _status_tags(m *ice.Message) { func _status_each(m *ice.Message, title string, cmds ...string) { web.GoToast(m, kit.Select(strings.Join(cmds, ice.SP), title), func(toast func(string, int, int)) { list, count, total := []string{}, 0, m.Cmd(REPOS).Length() - ReposList(m).Tables(func(value ice.Maps) { + ReposList(m).Table(func(value ice.Maps) { toast(value[REPOS], count, total) if msg := m.Cmd(cmds, kit.Dict(cli.CMD_DIR, value[nfs.PATH])); !cli.IsSuccess(msg) { web.Toast3s(m, msg.Append(cli.CMD_ERR)+msg.Append(cli.CMD_OUT), "error: "+value[REPOS]).Sleep3s() @@ -115,7 +115,7 @@ func _status_stat(m *ice.Message, files, adds, dels int) (int, int, int) { func _status_list(m *ice.Message) (files, adds, dels int, last time.Time) { onlychange := m.Option(ice.MSG_MODE) == mdb.ZONE || m.Option("view") == "change" defer m.Option(cli.CMD_DIR, "") - ReposList(m).Tables(func(value ice.Maps) { + ReposList(m).Table(func(value ice.Maps) { m.Option(cli.CMD_DIR, value[nfs.PATH]) files, adds, dels = _status_stat(m, files, adds, dels) if repos, e := gogit.OpenRepository(_git_dir(value[nfs.PATH])); e == nil { @@ -329,7 +329,6 @@ func init() { if _configs_get(m, USER_EMAIL) == "" { m.Echo("please config user.email").Action(CONFIGS) } else if len(arg) == 0 { - defer web.ToastProcess(m)() files, adds, dels, last := _status_list(m) m.StatusTimeCount("files", files, "adds", adds, "dels", dels, "last", last.Format(ice.MOD_TIME), "origin", _git_cmds(m, "remote", "get-url", "origin")) m.Action(PULL, PUSH, "insteadof", "oauth") diff --git a/misc/git/total.go b/misc/git/total.go index a1af2b22..a09c0ad7 100644 --- a/misc/git/total.go +++ b/misc/git/total.go @@ -39,7 +39,7 @@ func init() { }}, }, ctx.ConfAction("skip", kit.DictList("wubi-dict", "word-dict", "websocket", "go-qrcode", "go-sql-mysql", "echarts"))), Hand: func(m *ice.Message, arg ...string) { if len(arg) > 0 { - ReposList(m).Tables(func(value ice.Maps) { + ReposList(m).Table(func(value ice.Maps) { kit.If(value[REPOS] == arg[0], func() { m.Cmdy("_sum", value[nfs.PATH], arg[1:]) }) }) m.StatusTimeCount(m.AppendSimple(FROM)) @@ -52,7 +52,7 @@ func init() { } msg := m.Cmd("_sum", value[nfs.PATH], mdb.TOTAL, "10000") defer lock.Lock()() - msg.Tables(func(value ice.Maps) { + msg.Table(func(value ice.Maps) { if kit.Int(value[DAYS]) > days { from, days = value[FROM], kit.Int(value[DAYS]) } @@ -128,9 +128,9 @@ func init() { func TableGo(m *ice.Message, cb ice.Any) *ice.Message { wg, lock := sync.WaitGroup{}, &task.Lock{} defer wg.Wait() - m.Tables(func(value ice.Maps) { + m.Table(func(value ice.Maps) { wg.Add(1) - task.Put(logs.FileLine(cb), func(*task.Task) error { + task.Put(logs.FileLine(cb), func(*task.Task) { defer wg.Done() switch cb := cb.(type) { case func(ice.Maps, *task.Lock): @@ -140,7 +140,6 @@ func TableGo(m *ice.Message, cb ice.Any) *ice.Message { default: m.ErrorNotImplement(cb) } - return nil }) }) return m diff --git a/misc/lark/sso.go b/misc/lark/sso.go index 348cda68..59d7ddaf 100644 --- a/misc/lark/sso.go +++ b/misc/lark/sso.go @@ -15,7 +15,7 @@ func init() { Index.MergeCommands(ice.Commands{ web.P(SSO): {Hand: func(m *ice.Message, arg ...string) { if m.Option(ice.MSG_USERNAME) != "" { - web.RenderIndex(m) + web.RenderMain(m) return } appid := m.Cmd(APP).Append(APPID) diff --git a/misc/lark/talk.go b/misc/lark/talk.go index 3a8a813a..0dd193c2 100644 --- a/misc/lark/talk.go +++ b/misc/lark/talk.go @@ -23,7 +23,7 @@ func init() { return } } - if m.Cmdy(cmds); m.Result() != "" && m.Result(1) != ice.ErrNotFound { + if m.Cmdy(cmds); m.Result() != "" && !m.IsErrNotFound() { m.Cmd(SEND, m.Option(APP_ID), m.Option(OPEN_CHAT_ID), m.Result()) return } else if m.Length() == 0 { diff --git a/misc/ssh/channel.go b/misc/ssh/channel.go index 66e7bcdf..86c7206f 100644 --- a/misc/ssh/channel.go +++ b/misc/ssh/channel.go @@ -56,7 +56,7 @@ func init() { mdb.REPEAT: {Help: "执行", Hand: func(m *ice.Message, arg ...string) { m.Cmdy("", ctx.COMMAND, CMD, m.Option(mdb.TEXT)) }}, }, mdb.HashAction(mdb.FIELDS, "time,hash,status,tty,count,username,hostport", mdb.FIELD, "time,id,type,text")), Hand: func(m *ice.Message, arg ...string) { if mdb.ZoneSelect(m, arg...); len(arg) == 0 { - m.Tables(func(value ice.Maps) { + m.Table(func(value ice.Maps) { m.PushButton(kit.Select("", ctx.COMMAND, value[mdb.STATUS] == tcp.OPEN), mdb.REMOVE) }).Action(mdb.PRUNES) } else { diff --git a/misc/ssh/connect.go b/misc/ssh/connect.go index e0b0e4ed..b425199a 100644 --- a/misc/ssh/connect.go +++ b/misc/ssh/connect.go @@ -131,7 +131,7 @@ func init() { psh.Index.MergeCommands(ice.Commands{ CONNECT: {Name: "connect name auto", Help: "连接", Actions: ice.MergeActions(ice.Actions{ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { - mdb.HashSelect(m).Tables(func(value ice.Maps) { + mdb.HashSelect(m).Table(func(value ice.Maps) { if value[mdb.STATUS] == tcp.OPEN { m.Cmd("", tcp.DIAL, mdb.NAME, value[mdb.NAME], value) } @@ -147,7 +147,8 @@ func init() { mdb.HashCreate(m.Spawn(), m.OptionSimple(mdb.NAME, tcp.HOST, tcp.PORT, aaa.USERNAME), mdb.STATUS, tcp.OPEN, kit.Dict(mdb.TARGET, client)) m.Cmd("", SESSION, m.OptionSimple(mdb.NAME)) }, arg...) - }).Sleep300ms() + }) + m.Sleep300ms() }}, SESSION: {Help: "会话", Hand: func(m *ice.Message, arg ...string) { if c, e := _ssh_session(m, mdb.HashSelectTarget(m, m.Option(mdb.NAME), nil).(*ssh.Client)); !m.Warn(e, ice.ErrNotValid) { @@ -165,7 +166,7 @@ func init() { } }}, }, mdb.StatusHashAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,name,status,username,host,port")), Hand: func(m *ice.Message, arg ...string) { - if mdb.HashSelect(m, arg...).Tables(func(value ice.Maps) { + if mdb.HashSelect(m, arg...).Table(func(value ice.Maps) { m.PushButton(kit.Select("", "command,session", value[mdb.STATUS] == tcp.OPEN), mdb.REMOVE) }); len(arg) == 0 { m.Action(tcp.DIAL) diff --git a/misc/ssh/rsa.go b/misc/ssh/rsa.go index e6450895..4ff81901 100644 --- a/misc/ssh/rsa.go +++ b/misc/ssh/rsa.go @@ -47,7 +47,7 @@ func init() { } }}, mdb.EXPORT: {Name: "export key=.ssh/id_rsa pub=.ssh/id_rsa.pub", Hand: func(m *ice.Message, arg ...string) { - mdb.HashSelect(m, m.Option(mdb.HASH)).Tables(func(value ice.Maps) { + mdb.HashSelect(m, m.Option(mdb.HASH)).Table(func(value ice.Maps) { m.Cmd(nfs.SAVE, kit.HomePath(m.Option(KEY)), value[PRIVATE]) m.Cmd(nfs.SAVE, kit.HomePath(m.Option(PUB)), value[PUBLIC]) }) diff --git a/misc/ssh/service.go b/misc/ssh/service.go index 6935248e..8af57859 100644 --- a/misc/ssh/service.go +++ b/misc/ssh/service.go @@ -55,10 +55,10 @@ func _ssh_config(m *ice.Message, h string) *ssh.ServerConfig { }, PasswordCallback: func(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) { meta, err := _ssh_meta(conn), errors.New(ice.ErrNotRight) - if aaa.UserLogin(m, meta[aaa.USERNAME], string(password)) { - m.Auth(kit.SimpleKV(kit.Fields(aaa.USERNAME, tcp.HOSTPORT, tcp.HOSTNAME), meta)) - err = nil - } + // if aaa.UserLogin(m, meta[aaa.USERNAME], string(password)) { + // m.Auth(kit.SimpleKV(kit.Fields(aaa.USERNAME, tcp.HOSTPORT, tcp.HOSTNAME), meta)) + // err = nil + // } return &ssh.Permissions{Extensions: meta}, err }, } @@ -146,7 +146,7 @@ func init() { psh.Index.MergeCommands(ice.Commands{ SERVICE: {Name: "service port id auto listen prunes", Help: "服务", Actions: ice.MergeActions(ice.Actions{ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { - mdb.HashSelect(m).Tables(func(value ice.Maps) { + mdb.HashSelect(m).Table(func(value ice.Maps) { if value[mdb.STATUS] == tcp.OPEN { m.Cmd(SERVICE, tcp.LISTEN, tcp.PORT, value[tcp.PORT], value) } diff --git a/misc/ssh/session.go b/misc/ssh/session.go index 5f8610e4..15e2e820 100644 --- a/misc/ssh/session.go +++ b/misc/ssh/session.go @@ -62,11 +62,11 @@ func init() { }, mdb.PageZoneAction(mdb.SHORT, mdb.UNIQ, mdb.FIELD, "time,hash,count,status,connect", mdb.FIELDS, "time,id,type,text")), Hand: func(m *ice.Message, arg ...string) { m.Fields(len(kit.Slice(arg, 0, 2)), mdb.Config(m, mdb.FIELD), mdb.Config(m, mdb.FIELDS)) if mdb.PageZoneSelect(m, arg...); len(arg) == 0 { - m.Tables(func(value ice.Maps) { + m.Table(func(value ice.Maps) { m.PushButton(kit.Select("", ctx.COMMAND, value[mdb.STATUS] == tcp.OPEN), mdb.REMOVE) }) } else { - m.Tables(func(value ice.Maps) { m.PushButton(kit.Select("", mdb.REPEAT, value[mdb.TYPE] == CMD)) }).Action(ctx.COMMAND, mdb.PAGE) + m.Table(func(value ice.Maps) { m.PushButton(kit.Select("", mdb.REPEAT, value[mdb.TYPE] == CMD)) }).Action(ctx.COMMAND, mdb.PAGE) } }}, }) diff --git a/misc/tmux/session.go b/misc/tmux/session.go index 714df7d4..ccfdf5da 100644 --- a/misc/tmux/session.go +++ b/misc/tmux/session.go @@ -182,7 +182,7 @@ func init() { } else { m.Split(_tmux_cmd(m, LIST_SESSION, "-F", mdb.Config(m, FORMAT)).Result(), mdb.Config(m, FIELDS), ice.FS, ice.NL) } - m.Tables(func(value ice.Maps) { + m.Table(func(value ice.Maps) { kit.If(value["tag"] == "1", func() { m.PushButton("") }, func() { m.PushButton(code.XTERM, mdb.SELECT, mdb.REMOVE) }) }).StatusTimeCount() }}, diff --git a/misc/vim/tags.go b/misc/vim/tags.go index dd64bb58..1b2a9ebf 100644 --- a/misc/vim/tags.go +++ b/misc/vim/tags.go @@ -27,7 +27,7 @@ func _tags_input(m *ice.Message, arg ...string) { } switch name := kit.Select("", kit.Slice(kit.Split(arg[1], "\t \n."), -1), 0); name { case "can", "sup", "sub": - mdb.ZoneSelect(m).Tables(func(value ice.Maps) { + mdb.ZoneSelect(m).Table(func(value ice.Maps) { if strings.Contains(value[mdb.ZONE], arg[0]) || arg[0] == ice.PT { m.EchoLine(value[mdb.ZONE]) } @@ -77,12 +77,12 @@ func init() { Qrcode(m, args[1]) case wiki.FIELD: m.Search(kit.Select(args[1], args, 2), func(key string, cmd *ice.Command) { - ls := kit.Split(cmd.GetFileLines(), ice.DF) + ls := kit.Split(cmd.FileLine(), ice.DF) m.Echo("vi +%s %s", ls[1], ls[0]) }) default: m.Search(args[0], func(key string, cmd *ice.Command) { - ls := kit.Split(cmd.GetFileLines(), ice.DF) + ls := kit.Split(cmd.FileLine(), ice.DF) m.Echo("vi +%s %s", ls[1], ls[0]) }) } @@ -99,7 +99,7 @@ func init() { case "msg", "res": m.Echo("usr/volcanos/lib/misc.js") default: - if mdb.ZoneSelectAll(m, m.Option(mdb.ZONE)).Tables(func(value ice.Maps) { + if mdb.ZoneSelectAll(m, m.Option(mdb.ZONE)).Table(func(value ice.Maps) { kit.If(value[mdb.NAME] == m.Option(mdb.NAME), func() { m.Echo(path.Join(value[nfs.PATH], value[nfs.FILE])) }) }); m.Result() == "" { m.Echo("usr/volcanos/proto.js") diff --git a/misc/wx/favor.go b/misc/wx/favor.go index 6bb86783..2f85a0ac 100644 --- a/misc/wx/favor.go +++ b/misc/wx/favor.go @@ -14,7 +14,7 @@ func init() { FAVOR: {Name: "favor text:text auto create", Help: "收藏", Actions: mdb.HashAction( mdb.SHORT, mdb.TEXT, mdb.FIELD, "time,type,name,text", mdb.LINK, "https://open.weixin.qq.com/qr/code", ), Hand: func(m *ice.Message, arg ...string) { - mdb.HashSelect(m, arg...).Tables(func(value ice.Maps) { + mdb.HashSelect(m, arg...).Table(func(value ice.Maps) { m.PushQRCode(mdb.SCAN, kit.MergeURL(mdb.Config(m, mdb.LINK), aaa.USERNAME, value[mdb.TEXT])) }) }}, diff --git a/misc/wx/menu.go b/misc/wx/menu.go index 68783323..334f8899 100644 --- a/misc/wx/menu.go +++ b/misc/wx/menu.go @@ -16,10 +16,10 @@ func _wx_action(m *ice.Message) (count int) { %s `, m.Option("ToUserName"), m.Option("FromUserName"), m.Option("CreateTime"), "news") - m.Tables(func(value ice.Maps) { count++ }) + m.Table(func(value ice.Maps) { count++ }) m.Echo(`%d`, count).Echo(``) share := m.Cmdx(web.SHARE, mdb.CREATE, mdb.TYPE, web.LOGIN) - m.Tables(func(value ice.Maps) { + m.Table(func(value ice.Maps) { m.Echo(` <![CDATA[%s]]> diff --git a/misc/wx/text.go b/misc/wx/text.go index 4cd9e8cb..f12cd3c3 100644 --- a/misc/wx/text.go +++ b/misc/wx/text.go @@ -25,7 +25,7 @@ func init() { if m.Cmdy(arg); m.IsErrNotFound() { m.SetResult().Cmdy(cli.SYSTEM, arg) } - kit.If(m.Result() == "", func() { m.Table() }) + kit.If(m.Result() == "", func() { m.TableEcho() }) _wx_reply(m, m.CommandKey()) }}, }) diff --git a/option.go b/option.go index 996c3cf2..d378fb1a 100644 --- a/option.go +++ b/option.go @@ -1,6 +1,7 @@ package ice import ( + "strings" "time" kit "shylinux.com/x/toolkits" @@ -16,13 +17,14 @@ func (m *Message) OptionFields(arg ...string) string { kit.If(len(arg) > 0, func() { m.Option(MSG_FIELDS, kit.Join(arg)) }) return kit.Join(kit.Simple(m.Optionv(MSG_FIELDS))) } - func (m *Message) OptionDefault(arg ...string) string { kit.For(arg, func(k, v string) { kit.If(m.Option(k) == "" && v != "", func() { m.Option(k, v) }) }) return m.Option(arg[0]) } func (m *Message) OptionSimple(key ...string) (res []string) { - kit.If(len(key) == 0, func() { key = kit.Filters(kit.Split(kit.Select("type,name,text", m.Config(FIELD))), TIME, HASH) }) + kit.If(len(key) == 0, func() { + key = kit.Filters(kit.Split(kit.Select("type,name,text", m.Conf(m.PrefixKey(), kit.Keym(FIELD)))), TIME, HASH) + }) kit.For(kit.Filters(kit.Split(kit.Join(key)), ""), func(k string) { kit.If(m.Option(k), func(v string) { res = append(res, k, v) }) }) return } @@ -35,6 +37,19 @@ func (m *Message) OptionCB(key string, cb ...Any) Any { return m.Optionv(kit.Keycb(kit.Select(m.CommandKey(), key))) } +func (m *Message) MergePodCmd(pod, cmd string, arg ...Any) string { + ls := []string{"chat"} + kit.If(kit.Keys(m.Option(MSG_USERPOD), pod), func(p string) { ls = append(ls, POD, p) }) + if cmd == "" { + if _, ok := Info.Index[m.CommandKey()]; ok { + cmd = m.CommandKey() + } else { + cmd = m.PrefixKey() + } + } + ls = append(ls, CMD, cmd) + return kit.MergeURL2(strings.Split(kit.Select(Info.Domain, m.Option(MSG_USERWEB)), QS)[0], PS+kit.Join(ls, PS), arg...) +} func (m *Message) FieldsIsDetail() bool { return len(m.meta[MSG_APPEND]) == 2 && m.meta[MSG_APPEND][0] == KEY && m.meta[MSG_APPEND][1] == VALUE || m.OptionFields() == FIELDS_DETAIL } @@ -46,14 +61,8 @@ func (m *Message) Action(arg ...Any) *Message { return m.Options(MSG_ACTION, kit.Format(arg)) } func (m *Message) Status(arg ...Any) *Message { - list, args := kit.List(), kit.Simple(arg) - for i := 0; i < len(args)-1; i += 2 { - switch args[i+1] { - case "", "0": - continue - } - list = append(list, kit.Dict(NAME, args[i], VALUE, args[i+1])) - } + list := kit.List() + kit.For(kit.Simple(arg), func(k, v string) { list = append(list, kit.Dict(NAME, k, VALUE, v)) }) return m.Options(MSG_STATUS, kit.Format(list)) } func (m *Message) StatusTime(arg ...Any) *Message { @@ -67,8 +76,7 @@ func (m *Message) StatusTimeCountTotal(arg ...Any) *Message { } func (m *Message) Process(cmd string, arg ...Any) { - m.Option(MSG_PROCESS, cmd) - m.Option(PROCESS_ARG, arg...) + m.Options(MSG_PROCESS, cmd).Option(PROCESS_ARG, arg...) } func (m *Message) ProcessLocation(arg ...Any) { m.Process(PROCESS_LOCATION, arg...) @@ -95,10 +103,9 @@ func (m *Message) ProcessDisplay(arg ...Any) { m.Process(PROCESS_DISPLAY) m.Option(MSG_DISPLAY, arg...) } -func (m *Message) ProcessField(arg ...Any) *Message { +func (m *Message) ProcessField(arg ...Any) { m.Process(PROCESS_FIELD) m.Option(FIELD_PREFIX, arg...) - return m } func (m *Message) ProcessInner() { m.Process(PROCESS_INNER) } func (m *Message) ProcessAgain() { m.Process(PROCESS_AGAIN) } diff --git a/render.go b/render.go index 1a382d58..e447684a 100644 --- a/render.go +++ b/render.go @@ -103,14 +103,19 @@ func (m *Message) RenderVoid(arg ...Any) *Message { return m.Render(RENDER_VOID, arg...) } +func (m *Message) IsCliUA() bool { + return m.Option(MSG_USERUA) == "" || !strings.HasPrefix(m.Option(MSG_USERUA), "Mozilla") +} +func (m *Message) IsMobileUA() bool { + return strings.Contains(m.Option(MSG_USERUA), "Mobile") +} func (m *Message) PushSearch(arg ...Any) { data := kit.Dict(arg...) - for i := 0; i < len(arg); i += 2 { - switch k := arg[i].(type) { - case string: - kit.If(i+1 < len(arg), func() { data[k] = arg[i+1] }) + kit.For(arg, func(k, v Any) { + if k, ok := k.(string); ok { + data[k] = v } - } + }) for _, k := range kit.Split(m.OptionFields()) { switch k { case TIME: @@ -130,7 +135,7 @@ func (m *Message) PushAction(arg ...Any) *Message { if len(m.meta[MSG_APPEND]) == 0 { return m } - return m.Set(MSG_APPEND, ACTION).Tables(func(value Maps) { m.PushButton(arg...) }) + return m.Set(MSG_APPEND, ACTION).Table(func(value Maps) { m.PushButton(arg...) }) } func (m *Message) PushButton(arg ...Any) *Message { if !m.IsCliUA() { @@ -169,8 +174,9 @@ func (m *Message) PushIFrame(key, src string) { func (m *Message) PushScript(arg ...string) { kit.If(!m.IsCliUA(), func() { m.Push(SCRIPT, Render(m, RENDER_SCRIPT, arg)) }) } -func (m *Message) PushDownload(key string, arg ...string) { +func (m *Message) PushDownload(key string, arg ...string) *Message { kit.If(!m.IsCliUA(), func() { m.Push(key, Render(m, RENDER_DOWNLOAD, arg)) }) + return m } func (m *Message) EchoButton(arg ...Any) *Message { return m.Echo(Render(m, RENDER_BUTTON, arg...)) } diff --git a/type.go b/type.go index a1d09d6d..ffad0366 100644 --- a/type.go +++ b/type.go @@ -57,7 +57,7 @@ type Context struct { Configs Configs Commands Commands - Contexts Contexts + contexts Contexts context *Context root *Context server Server @@ -89,8 +89,8 @@ func (c *Context) Register(s *Context, x Server, cmd ...string) *Context { } Info.Index[cmd] = s }) - kit.If(c.Contexts == nil, func() { c.Contexts = Contexts{} }) - c.Contexts[s.Name] = s + kit.If(c.contexts == nil, func() { c.contexts = Contexts{} }) + c.contexts[s.Name] = s s.root = c.root s.context = c s.server = x @@ -154,9 +154,12 @@ func (c *Context) Merge(s *Context) *Context { } if s == c { for _, h := range Info.merges { - init, exit := h(c, key, cmd, sub, action) - merge(c.Commands[CTX_INIT], true, key, cmd, init) - merge(c.Commands[CTX_EXIT], false, key, cmd, exit) + switch h := h.(type) { + case func(c *Context, key string, cmd *Command, sub string, action *Action) Handler: + merge(c.Commands[CTX_INIT], true, key, cmd, h(c, key, cmd, sub, action)) + case func(c *Context, key string, cmd *Command, sub string, action *Action): + h(c, key, cmd, sub, action) + } } } if help := kit.Split(action.Help, " ::"); len(help) > 0 { @@ -196,13 +199,12 @@ func (c *Context) Close(m *Message, arg ...string) { type Message struct { time time.Time code int - Hand bool - meta map[string][]string data Map + meta map[string][]string - message *Message root *Message + message *Message _source string _target string @@ -227,21 +229,21 @@ func (m *Message) Time(arg ...string) string { } return t.Format(kit.Select(MOD_TIME, arg, 0)) } -func (m *Message) Target() *Context { return m.target } -func (m *Message) Source() *Context { return m.source } func (m *Message) Message() *Message { return m.message } -func (m *Message) Commands(key string) *Command { - return m.Target().Commands[key] -} -func (m *Message) Actions(key string) *Action { - return m._cmd.Actions[key] +func (m *Message) Source() *Context { return m.source } +func (m *Message) Target() *Context { return m.target } +func (m *Message) _fileline() string { + switch m.target.Name { + case MDB, AAA, GDB: + return m._source + default: + return m._target + } } func (m *Message) Spawn(arg ...Any) *Message { - msg := &Message{ - time: time.Now(), code: int(m.target.root.ID()), - meta: map[string][]string{}, data: Map{}, - message: m, root: m.root, _target: logs.FileLine(2), - source: m.target, target: m.target, _cmd: m._cmd, _key: m._key, _sub: m._sub, + msg := &Message{time: time.Now(), code: int(m.target.root.ID()), + meta: map[string][]string{}, data: Map{}, message: m, root: m.root, + _source: logs.FileLine(2), source: m.target, target: m.target, _cmd: m._cmd, _key: m._key, _sub: m._sub, W: m.W, R: m.R, O: m.O, I: m.I, } for _, val := range arg { @@ -288,7 +290,7 @@ func (m *Message) Travel(cb Any) *Message { default: m.ErrorNotImplement(cb) } - kit.For(kit.SortedKey(list[i].Contexts), func(k string) { list = append(list, list[i].Contexts[k]) }) + kit.For(kit.SortedKey(list[i].contexts), func(k string) { list = append(list, list[i].contexts[k]) }) } return m } @@ -310,7 +312,7 @@ func (m *Message) Search(key string, cb Any) *Message { continue } for _, k := range ls[:len(ls)-1] { - if p = p.Contexts[k]; p == nil { + if p = p.contexts[k]; p == nil { break } } @@ -357,13 +359,43 @@ func (m *Message) Search(key string, cb Any) *Message { } return m } +func (m *Message) Design(action Any, help string, input ...Any) { + list := kit.List() + for _, input := range input { + switch input := input.(type) { + case string: + list = append(list, SplitCmd("action "+input, nil)...) + case Map: + if kit.Format(input[TYPE]) != "" && kit.Format(input[NAME]) != "" { + list = append(list, input) + continue + } + kit.For(kit.KeyValue(nil, "", input), func(k string, v Any) { + list = append(list, kit.Dict(NAME, k, TYPE, TEXT, VALUE, v)) + }) + default: + m.ErrorNotImplement(input) + } + } + k := kit.Format(action) + if a, ok := m._cmd.Actions[k]; ok { + m._cmd.Meta[k], a.List = list, list + kit.Value(m._cmd.Meta, kit.Keys("_trans", k), help) + } +} +func (m *Message) Actions(key string) *Action { + return m._cmd.Actions[key] +} +func (m *Message) Commands(key string) *Command { + return m.Target().Commands[key] +} -func (m *Message) Cmd(arg ...Any) *Message { return m._command(arg...) } +func (m *Message) Cmd(arg ...Any) *Message { return m._command(arg...) } +func (m *Message) Cmdy(arg ...Any) *Message { return m.Copy(m._command(arg...)) } func (m *Message) Cmdx(arg ...Any) string { res := kit.Select("", m._command(arg...).meta[MSG_RESULT], 0) return kit.Select("", res, res != ErrWarn) } -func (m *Message) Cmdy(arg ...Any) *Message { return m.Copy(m._command(arg...)) } func (m *Message) Confv(arg ...Any) (val Any) { run := func(conf *Config) { if len(arg) == 1 {