From 3de5a538320cd4baf1480bac248e2b501b522261 Mon Sep 17 00:00:00 2001
From: harveyshao
-` \ No newline at end of file +` diff --git a/core/wiki/wiki.go b/core/wiki/wiki.go index 9ff70c85..7d66890b 100644 --- a/core/wiki/wiki.go +++ b/core/wiki/wiki.go @@ -78,6 +78,7 @@ func init() { FEEL, DRAW, DATA, WORD, ) } +func Prefix(arg ...string) string { return web.Prefix(WIKI, kit.Keys(arg)) } func WikiAction(dir string, ext ...string) ice.Actions { return ice.Actions{ice.CTX_INIT: mdb.AutoConfig(nfs.PATH, dir, lex.REGEXP, kit.FileReg(ext...)), diff --git a/logs.go b/logs.go index 2b9d8561..1534da56 100644 --- a/logs.go +++ b/logs.go @@ -37,7 +37,7 @@ func (m *Message) join(arg ...Any) (string, []Any) { case time.Time: arg[i+1] = v.Format(MOD_TIME) case []string: - arg[i+1] = kit.Join(v, " ") + arg[i+1] = kit.Join(v, SP) } list = append(list, key+kit.Select("", DF, !strings.Contains(key, DF)), kit.Format(arg[i+1])) } diff --git a/meta.go b/meta.go index cda1c77b..49e629ed 100644 --- a/meta.go +++ b/meta.go @@ -507,3 +507,6 @@ 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()) +} diff --git a/misc.go b/misc.go index 423b393b..4287a780 100644 --- a/misc.go +++ b/misc.go @@ -105,7 +105,7 @@ func (m *Message) RenameAppend(arg ...string) *Message { func (m *Message) AppendSimple(key ...string) (res []string) { if len(key) == 0 { if m.FieldsIsDetail() { - key = append(key, m.Appendv(KEY)...) + key = append(key, m.meta[KEY]...) } else { key = append(key, m.Appendv(MSG_APPEND)...) } @@ -173,7 +173,7 @@ func (m *Message) _fileline() string { } } func (m *Message) ActionHand(cmd *Command, key, sub string, arg ...string) *Message { - if action, ok := cmd.Actions[sub]; !m.Warn(!ok, ErrNotFound, sub, cmd.GetFileLines()) { + 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 diff --git a/misc/alpha/alpha.go b/misc/alpha/alpha.go index e0453feb..08f359ad 100644 --- a/misc/alpha/alpha.go +++ b/misc/alpha/alpha.go @@ -20,62 +20,43 @@ const ( type alpha struct { ice.Zone field string `data:"word,translation,definition"` - store string `data:"usr/local/export"` + store string `data:"usr/local/export/"` fsize string `data:"300000"` limit string `data:"50000"` least string `data:"1000"` - - load string `name:"load file=usr/word-dict/ecdict name=ecdict" help:"加载"` - list string `name:"list method=word,line word auto" help:"词典"` + load string `name:"load file=usr/word-dict/ecdict zone=ecdict"` + list string `name:"list method=word,line word auto load" help:"词典"` } func (s alpha) Load(m *ice.Message, arg ...string) { - // 清空数据 lib := kit.Select(path.Base(m.Option(nfs.FILE)), m.Option(mdb.ZONE)) - m.Assert(nfs.RemoveAll(m.Message, path.Join(m.Config(mdb.STORE), lib))) + m.Assert(nfs.RemoveAll(m, path.Join(m.Config(mdb.STORE), lib))) s.Zone.Remove(m, mdb.ZONE, lib) s.Zone.Create(m, kit.Simple(mdb.ZONE, lib, m.ConfigSimple(mdb.FIELD, mdb.LIMIT, mdb.LEAST, mdb.STORE, mdb.FSIZE))...) prefix := kit.Keys(mdb.HASH, m.Result()) - - // 加载配置 m.Cmd(mdb.IMPORT, m.PrefixKey(), prefix, mdb.LIST, m.Option(nfs.FILE)) - - // 保存词库 m.Conf(m.PrefixKey(), kit.Keys(prefix, kit.Keym(mdb.LIMIT)), 0) m.Conf(m.PrefixKey(), kit.Keys(prefix, kit.Keym(mdb.LEAST)), 0) - m.Echo("%s: %d", lib, mdb.Grow(m.Message, m.PrefixKey(), prefix, kit.Dict(WORD, ice.SP))) + m.Echo("%s: %d", lib, mdb.Grow(m, m.PrefixKey(), prefix, kit.Dict(WORD, ice.SP))) } func (s alpha) List(m *ice.Message, arg ...string) { if len(arg) < 2 || arg[1] == "" { m.Cmdy(cache{}, kit.Slice(arg, 1)) - return // 缓存列表 + return } - switch arg[1] = strings.TrimSpace(arg[1]); arg[0] { case LINE: case WORD: if m.Cmdy(cache{}, kit.Slice(arg, 1)); m.Length() > 0 { - return // 查询缓存 + return } - defer func() { - if m.Length() > 0 { // 写入缓存 - m.Cmd(cache{}, mdb.CREATE, m.AppendSimple()) - } - }() - - // 精确匹配 + defer func() { kit.If(m.Length() > 0, func() { m.Cmd(cache{}, mdb.CREATE, m.AppendSimple()) }) }() m.OptionFields(ice.FIELDS_DETAIL) arg[1] = "^" + arg[1] + ice.FS } - - // 搜索词汇 - wiki.CSV(m.Message, m.Cmdx(cli.SYSTEM, "grep", "-rih", arg[1], m.Config(mdb.STORE)), kit.Split(m.Config(mdb.FIELD))...).Tables(func(value ice.Maps) { - if m.FieldsIsDetail() { - m.PushDetail(value, m.Config(mdb.FIELD)) - } else { - m.PushRecord(value, m.Config(mdb.FIELD)) - } + wiki.CSV(m.Message.Spawn(), m.Cmdx(cli.SYSTEM, "grep", "-rih", arg[1], m.Config(mdb.STORE)), kit.Split(m.Config(mdb.FIELD))...).Tables(func(value ice.Maps) { + kit.If(m.FieldsIsDetail(), func() { m.PushDetail(value, m.Config(mdb.FIELD)) }, func() { m.PushRecord(value, m.Config(mdb.FIELD)) }) }).StatusTimeCount() } -func init() { ice.Cmd("web.wiki.alpha.alpha", alpha{}) } +func init() { ice.WikiCtxCmd(alpha{}) } diff --git a/misc/alpha/alpha.shy b/misc/alpha/alpha.shy deleted file mode 100644 index b1ab4b99..00000000 --- a/misc/alpha/alpha.shy +++ /dev/null @@ -1,3 +0,0 @@ -chapter "alpha" - -field web.wiki.alpha.alpha diff --git a/misc/alpha/cache.go b/misc/alpha/cache.go index e5185f34..c6d1ac27 100644 --- a/misc/alpha/cache.go +++ b/misc/alpha/cache.go @@ -11,4 +11,4 @@ type cache struct { list string `name:"list word auto create prunes" help:"缓存"` } -func init() { ice.Cmd("web.wiki.alpha.cache", cache{}) } +func init() { ice.WikiCtxCmd(cache{}) } diff --git a/misc/bash/bash.go b/misc/bash/bash.go index 85bf61d4..d90b61cc 100644 --- a/misc/bash/bash.go +++ b/misc/bash/bash.go @@ -12,11 +12,11 @@ const BASH = "bash" var Index = &ice.Context{Name: BASH, Help: "命令行", Commands: ice.Commands{ BASH: {Name: "bash path auto order build download", Help: "命令行", Actions: ice.MergeActions(ice.Actions{ - cli.ORDER: {Name: "order", Help: "加载", Hand: func(m *ice.Message, arg ...string) { + cli.ORDER: {Hand: func(m *ice.Message, arg ...string) { m.Cmdy(code.INSTALL, cli.ORDER, m.Config(nfs.SOURCE), "_install/bin") }}, }, code.InstallAction(nfs.SOURCE, "http://mirrors.tencent.com/macports/distfiles/bash/5.1_1/bash-5.1.tar.gz")), Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(code.INSTALL, nfs.SOURCE, m.Config(nfs.SOURCE), arg) + m.Cmdy(code.INSTALL, m.ConfigSimple(nfs.SOURCE), arg) }}, }} diff --git a/misc/bash/bash.shy b/misc/bash/bash.shy index 441aaeb5..19de1913 100644 --- a/misc/bash/bash.shy +++ b/misc/bash/bash.shy @@ -28,7 +28,6 @@ cd ./_install ` chapter "应用" -field "文件夹" web.chat.files field "命令行" web.code.bash.bash field "会话流" web.code.bash.sess field "同步流" web.code.bash.sync diff --git a/misc/bash/configs.go b/misc/bash/configs.go index c0a01589..aca4ea86 100644 --- a/misc/bash/configs.go +++ b/misc/bash/configs.go @@ -4,18 +4,19 @@ import ( "strings" ice "shylinux.com/x/icebergs" - "shylinux.com/x/icebergs/base/mdb" + "shylinux.com/x/icebergs/base/cli" + "shylinux.com/x/icebergs/base/web" ) +const CONFIGS = "configs" + func init() { Index.MergeCommands(ice.Commands{ - "/configs": {Name: "/configs", Help: "配置", Hand: func(m *ice.Message, arg ...string) { - m.Cmd("web.code.git.configs", func(value ice.Maps) { - if strings.HasPrefix(value[mdb.NAME], "url") { - m.Echo(`git config --global "%s" "%s"`, value[mdb.NAME], value[mdb.VALUE]) - m.Echo(ice.NL) - } - }) + web.P(CONFIGS): {Hand: func(m *ice.Message, arg ...string) { + if strings.Contains(m.Option(cli.RELEASE), cli.ALPINE) { + m.Echo("sed -i 's/dl-cdn.alpinelinux.org/mirrors.tencent.com/g' /etc/apk/repositories && apk update").Echo(ice.NL) + m.Echo("TZ=Asia/Shanghai; apk add tzdata && cp /usr/share/zoneinfo/${TZ} /etc/localtime && echo ${TZ} > /etc/timezone").Echo(ice.NL) + } }}, }) } diff --git a/misc/bash/download.go b/misc/bash/download.go index df201f2b..ede7a279 100644 --- a/misc/bash/download.go +++ b/misc/bash/download.go @@ -2,29 +2,34 @@ package bash import ( ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/aaa" + "shylinux.com/x/icebergs/base/cli" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" + "shylinux.com/x/icebergs/base/tcp" "shylinux.com/x/icebergs/base/web" kit "shylinux.com/x/toolkits" ) +const ( + _DOWNLOAD = "_download" +) + func init() { Index.MergeCommands(ice.Commands{ - "/download": {Name: "/download", Help: "下载", Hand: func(m *ice.Message, arg ...string) { + web.P(web.DOWNLOAD): {Hand: func(m *ice.Message, arg ...string) { if len(arg) == 0 || arg[0] == "" { - m.Cmdy("web.chat.files").Table() - return // 文件列表 + m.Cmdy(FAVOR, _DOWNLOAD).Table() + } 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)) } - - // 下载文件 - m.Cmdy(web.CACHE, m.Cmd("web.chat.files", arg[0]).Append(mdb.DATA)) - m.Render(kit.Select(ice.RENDER_DOWNLOAD, ice.RENDER_RESULT, m.Append(nfs.FILE) == ""), m.Append(mdb.TEXT)) }}, - "/upload": {Name: "/upload", Help: "上传", Hand: func(m *ice.Message, arg ...string) { - msg := m.Cmd("web.chat.files", web.UPLOAD) // 上传文件 - for _, k := range []string{mdb.DATA, mdb.TIME, mdb.TYPE, mdb.NAME, nfs.SIZE} { - m.Echo("%s: %s\n", k, msg.Append(k)) - } + web.P(web.UPLOAD): {Hand: func(m *ice.Message, arg ...string) { + m.Optionv(ice.MSG_UPLOAD, web.UPLOAD) + up := web.Upload(m) + m.Cmd(FAVOR, mdb.INSERT, _DOWNLOAD, mdb.TYPE, kit.Ext(up[1]), mdb.NAME, up[1], mdb.TEXT, up[0], m.OptionSimple(cli.PWD, aaa.USERNAME, tcp.HOSTNAME)) + m.Echo(up[0]).Echo(ice.NL) }}, }) } diff --git a/misc/bash/favor.go b/misc/bash/favor.go index f9ee76a0..39b73adb 100644 --- a/misc/bash/favor.go +++ b/misc/bash/favor.go @@ -5,6 +5,8 @@ import ( "shylinux.com/x/icebergs/base/cli" "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" + "shylinux.com/x/icebergs/base/nfs" + "shylinux.com/x/icebergs/base/web" kit "shylinux.com/x/toolkits" ) @@ -12,30 +14,34 @@ const FAVOR = "favor" func init() { Index.MergeCommands(ice.Commands{ - "/favor": {Name: "/favor", Help: "收藏", Actions: ice.Actions{ - mdb.EXPORT: {Name: "export zone name", Help: "导出", Hand: func(m *ice.Message, arg ...string) { - m.Echo("#!/bin/sh\n\n") - m.Cmdy(FAVOR, m.Option(mdb.ZONE), func(value ice.Maps) { + FAVOR: {Name: "favor zone id auto insert", Help: "收藏夹", Actions: ice.MergeActions(ice.Actions{ + mdb.INSERT: {Name: "insert zone*=demo type=shell name=1 text=pwd pwd=/home"}, + cli.SYSTEM: {Hand: func(m *ice.Message, arg ...string) { + if len(arg) > 0 && arg[0] == ice.RUN { + if msg := mdb.ZoneSelect(m.Spawn(), m.Option(mdb.ZONE), m.Option(mdb.ID)); nfs.ExistsFile(m, msg.Append(cli.PWD)) { + m.Option(cli.CMD_DIR, msg.Append(cli.PWD)) + } + ctx.ProcessField(m, cli.SYSTEM, nil, arg...) + } else { + ctx.ProcessField(m, cli.SYSTEM, kit.Split(m.Option(mdb.TEXT))) + } + }}, + web.DOWNLOAD: {Hand: func(m *ice.Message, arg ...string) { web.RenderCache(m, m.Option(mdb.TEXT)) }}, + }, mdb.ZoneAction(mdb.FIELD, "time,id,type,name,text,pwd,username,hostname")), Hand: func(m *ice.Message, arg ...string) { + if mdb.ZoneSelect(m, arg...); len(arg) == 0 { + m.Action(mdb.EXPORT, mdb.IMPORT) + } else { + m.PushAction(kit.Select(cli.SYSTEM, web.DOWNLOAD, arg[0] == _DOWNLOAD)) + } + }}, + web.PP(FAVOR): {Actions: ice.Actions{ + mdb.EXPORT: {Name: "export zone* name", Hand: func(m *ice.Message, arg ...string) { + m.Echo("#!/bin/sh\n\n").Cmdy(FAVOR, m.Option(mdb.ZONE), func(value ice.Maps) { if m.Option(mdb.NAME) == "" || m.Option(mdb.NAME) == value[mdb.NAME] { - m.Echo("# %v\n%v\n\n", value[mdb.NAME], value[mdb.TEXT]) + m.Echo("# %s\n%s\n\n", value[mdb.NAME], value[mdb.TEXT]) } }) }}, }, Hand: func(m *ice.Message, arg ...string) { m.Cmdy(FAVOR).Table() }}, - FAVOR: {Name: "favor zone id auto", Help: "收藏夹", Actions: ice.MergeActions(ice.Actions{ - mdb.INSERT: {Name: "insert zone=系统命令 type=shell name=1 text=pwd pwd=/home", Help: "添加"}, - cli.SYSTEM: {Name: "system", Help: "命令", Hand: func(m *ice.Message, arg ...string) { - m.Option(cli.CMD_DIR, m.Option(cli.PWD)) - ctx.ProcessCommand(m, cli.SYSTEM, kit.Split(m.Option(mdb.TEXT)), arg...) - ctx.ProcessCommandOpt(m, arg, cli.PWD) - }}, - }, mdb.ZoneAction(mdb.SHORT, mdb.ZONE, mdb.FIELD, "time,id,type,name,text,pwd,username,hostname")), Hand: func(m *ice.Message, arg ...string) { - if mdb.ZoneSelect(m, arg...); len(arg) == 0 { - m.Action(mdb.CREATE, mdb.EXPORT, mdb.IMPORT) - } else { - m.PushAction(cli.SYSTEM) - m.StatusTimeCount() - } - }}, }) } diff --git a/misc/bash/grant.go b/misc/bash/grant.go index 5e82d230..c56b17d4 100644 --- a/misc/bash/grant.go +++ b/misc/bash/grant.go @@ -2,7 +2,9 @@ package bash import ( ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/aaa" "shylinux.com/x/icebergs/base/mdb" + "shylinux.com/x/icebergs/base/tcp" kit "shylinux.com/x/toolkits" ) @@ -10,20 +12,14 @@ const GRANT = "grant" func init() { Index.MergeCommands(ice.Commands{ - GRANT: {Name: "grant hash auto", Help: "授权", Actions: ice.MergeActions(ice.Actions{ - "confirm": {Name: "confirm", Help: "同意", Hand: func(m *ice.Message, arg ...string) { - m.Cmd(SESS, mdb.MODIFY, GRANT, m.Option(ice.MSG_USERNAME)) - }}, - "revert": {Name: "revert", Help: "撤销", Hand: func(m *ice.Message, arg ...string) { - m.Cmd(SESS, mdb.MODIFY, GRANT, "") - }}, - }, mdb.HashAction()), Hand: func(m *ice.Message, arg ...string) { + GRANT: {Name: "grant hash auto", Help: "授权", Actions: ice.Actions{ + mdb.MODIFY: {Help: "同意", Hand: func(m *ice.Message, arg ...string) { m.Cmd(SESS, mdb.MODIFY, GRANT, m.Option(ice.MSG_USERNAME)) }}, + mdb.REVERT: {Help: "撤销", Hand: func(m *ice.Message, arg ...string) { m.Cmd(SESS, mdb.MODIFY, GRANT, "") }}, + }, Hand: func(m *ice.Message, arg ...string) { if m.Cmdy(SESS, arg); len(arg) > 0 && m.Append(GRANT) == "" { - m.ProcessConfirm("授权设备") + m.Echo("请授权 %s@%s 访问 %s", m.Append(aaa.USERNAME), m.Append(tcp.HOSTNAME), m.Option(ice.MSG_USERHOST)) } - m.Tables(func(value ice.Maps) { - m.PushButton(kit.Select("revert", "confirm", value[GRANT] == ""), mdb.REMOVE) - }) + m.Tables(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 f2256278..9a4a36fe 100644 --- a/misc/bash/run.go +++ b/misc/bash/run.go @@ -14,8 +14,6 @@ import ( ) func _run_action(m *ice.Message, cmd *ice.Command, script string, arg ...string) { - m.SetResult().Echo("#/bin/bash\n") - list, args := []string{}, []string{} kit.Fetch(cmd.Meta["_trans"], func(k string, v string) { list = append(list, k) @@ -25,7 +23,7 @@ func _run_action(m *ice.Message, cmd *ice.Command, script string, arg ...string) }) args = append(args, kit.Format(` ;;`)) }) - + m.SetResult().Echo("#/bin/sh\n") m.Echo(` ish_sys_dev_run_source() { select action in %s; do @@ -37,7 +35,6 @@ ish_sys_dev_run_source() { done } `, kit.Join(list, ice.SP), arg[0], kit.Join(args, ice.NL)) - m.Echo(` ish_sys_dev_run_action() { select action in %s; do @@ -50,40 +47,73 @@ ish_sys_dev_run_action() { done } `, kit.Join(list, ice.SP), arg[0], kit.Join(args, ice.NL)) - m.Echo(` ish_sys_dev_run_command() { ish_sys_dev_run %s "$@" } `, arg[0]) - m.Echo(kit.Select("cat $1", script)) } +func _run_command(m *ice.Message, key string, arg ...string) { + m.Search(key, func(p *ice.Context, s *ice.Context, key string, cmd *ice.Command) { + m.Echo(kit.Join(m.Cmd(key, arg).Appendv(kit.Format(kit.Value(cmd.List, kit.Keys(len(arg), mdb.NAME)))), ice.SP)) + }) +} +func _run_actions(m *ice.Message, key, sub string, arg ...string) (res []string) { + m.Search(key, func(p *ice.Context, s *ice.Context, key string, cmd *ice.Command) { + if sub == "" { + res = kit.SortedKey(cmd.Meta) + } else if len(arg)%2 == 0 { + kit.Fetch(kit.Value(cmd.Meta, sub), func(value ice.Map) { res = append(res, kit.Format(value[mdb.NAME])) }) + kit.Fetch(arg, func(k, v string) { res[kit.IndexOf(res, k)] = "" }) + } else { + msg := m.Cmd(key, mdb.INPUTS, kit.Select("", arg, -1), kit.Dict(arg)) + res = msg.Appendv(kit.Select("", msg.Appendv(ice.MSG_APPEND), 0)) + } + m.Echo(kit.Join(res, ice.SP)) + }) + return nil +} + const RUN = "run" func init() { Index.MergeCommands(ice.Commands{ - "/run/": {Name: "/run/", Help: "执行", Actions: ice.Actions{ - ctx.COMMAND: {Name: "command", Help: "命令", Hand: func(m *ice.Message, arg ...string) { + web.PP(RUN): {Actions: ice.Actions{ + "check": {Name: "check sid*", Hand: func(m *ice.Message, arg ...string) { m.Echo(m.Cmd(SESS, m.Option(SID)).Append(GRANT)) }}, + "complete": {Hand: func(m *ice.Message, arg ...string) { + switch arg = kit.Split(m.Option("line")); m.Option("cword") { + case "1": + m.Echo("action ") + m.Echo(strings.Join(m.Cmd(ctx.COMMAND, mdb.SEARCH, ctx.COMMAND, ice.OptionFields(ctx.INDEX)).Appendv(ctx.INDEX), ice.SP)) + default: + if kit.Int(m.Option("cword"))+1 == len(arg) { + arg = kit.Slice(arg, 0, -1) + } + if kit.Select("", arg, 2) == ctx.ACTION { + _run_actions(m, arg[1], kit.Select("", arg, 3), kit.Slice(arg, 4)...) + } else { + _run_command(m, arg[1], arg[2:]...) + } + } + }}, + ctx.COMMAND: {Hand: func(m *ice.Message, arg ...string) { m.Search(arg[0], func(_ *ice.Context, s *ice.Context, key string, cmd *ice.Command) { - if p := strings.ReplaceAll(kit.Select("/app/cat.sh", cmd.Meta[ctx.DISPLAY]), ".js", ".sh"); strings.HasPrefix(p, ice.PS+ice.REQUIRE) { + if p := kit.ExtChange(kit.Select("/app/cat.sh", cmd.Meta[ctx.DISPLAY]), nfs.SH); strings.HasPrefix(p, ice.PS+ice.REQUIRE) { m.Cmdy(web.SPIDE, ice.DEV, web.SPIDE_RAW, p) } else { m.Cmdy(nfs.CAT, path.Join(ice.USR_INTSHELL, p)) } - if m.IsErrNotFound() { - m.SetResult() - } - _run_action(m, cmd, m.Result(), arg...) + _run_action(m, cmd, m.Results(), arg...) }) }}, - ice.RUN: {Name: "run", Help: "执行", Hand: func(m *ice.Message, arg ...string) { + ice.RUN: {Hand: func(m *ice.Message, arg ...string) { if !ctx.PodCmd(m, arg) && aaa.Right(m, arg) { m.Cmdy(arg) } - if m.Result() == "" { - m.Table() + if m.Result() != "" && !strings.HasSuffix(m.Result(), ice.NL) { + m.Echo(ice.NL) } }}, }}, diff --git a/misc/bash/sess.go b/misc/bash/sess.go index 4e64db4f..a0221ca2 100644 --- a/misc/bash/sess.go +++ b/misc/bash/sess.go @@ -10,6 +10,8 @@ import ( "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/tcp" "shylinux.com/x/icebergs/base/web" + "shylinux.com/x/icebergs/core/code" + kit "shylinux.com/x/toolkits" ) const ( @@ -25,48 +27,42 @@ func init() { if f, _, e := m.R.FormFile(SUB); e == nil { defer f.Close() if b, e := ioutil.ReadAll(f); e == nil { - m.Option(SUB, string(b)) // 文件参数 + m.Option(SUB, string(b)) } } - switch m.RenderResult(); arg[0] { - case "/qrcode", "/sess": - return // 登录入口 + case web.P(cli.QRCODE), web.PP(SESS): + return } - if m.Warn(m.Option(SID, strings.TrimSpace(m.Option(SID))) == "", ice.ErrNotLogin, arg) { return + } else if msg := m.Cmd(SESS, m.Option(SID)); msg.Append(GRANT) == "" { + aaa.SessAuth(m, ice.Maps{aaa.USERNAME: msg.Append(aaa.USERNAME), aaa.USERNICK: msg.Append(aaa.USERNAME), aaa.USERROLE: aaa.VOID}).Options(msg.AppendSimple(aaa.USERNAME, tcp.HOSTNAME, cli.RELEASE)) + } else { + aaa.SessAuth(m, kit.Dict(aaa.USERNAME, msg.Append(GRANT), aaa.USERNICK, aaa.UserNick(m, msg.Append(GRANT)), aaa.USERROLE, aaa.UserRole(m, msg.Append(GRANT)))).Options(msg.AppendSimple(aaa.USERNAME, tcp.HOSTNAME, cli.RELEASE)) } - - msg := m.Cmd(SESS, m.Option(SID)) - m.Option(ice.MSG_USERNAME, msg.Append(GRANT)) - m.Option(ice.MSG_USERROLE, aaa.UserRole(m, msg.Append(GRANT))) - m.Option(tcp.HOSTNAME, msg.Append(tcp.HOSTNAME)) - m.Auth(aaa.USERROLE, m.Option(ice.MSG_USERROLE), aaa.USERNAME, m.Option(ice.MSG_USERNAME)) - if arg[0] == "/run/" { - return - } - m.Warn(m.Option(ice.MSG_USERNAME) == "", ice.ErrNotLogin, arg) }}, - "/qrcode": {Name: "/qrcode", Help: "二维码", Hand: func(m *ice.Message, arg ...string) { + web.P(cli.QRCODE): {Hand: func(m *ice.Message, arg ...string) { m.Cmdy(cli.QRCODE, m.Option(mdb.TEXT), m.Option(cli.FG), m.Option(cli.BG)) }}, - "/sess": {Name: "/sess", Help: "会话", Actions: ice.Actions{ - aaa.LOGOUT: {Name: "logout", Help: "退出", Hand: func(m *ice.Message, arg ...string) { - mdb.HashModify(m, mdb.HASH, m.Option(SID), mdb.STATUS, aaa.LOGOUT) + web.PP(SESS): {Actions: ice.Actions{ + aaa.LOGOUT: {Hand: func(m *ice.Message, arg ...string) { + if !m.Warn(m.Option(SID) == "", ice.ErrNotValid, SID) { + mdb.HashModify(m, mdb.HASH, m.Option(SID), mdb.STATUS, aaa.LOGOUT) + } }}, }, Hand: func(m *ice.Message, arg ...string) { - if m.Option(SID) == "" { // 终端登录 - m.Option(SID, mdb.HashCreate(m, mdb.STATUS, aaa.LOGIN, m.OptionSimple(aaa.USERNAME, tcp.HOSTNAME, cli.PID, cli.PWD))) - } else { // 更新状态 + if m.Option(SID) == "" { + m.Option(SID, mdb.HashCreate(m, mdb.STATUS, aaa.LOGIN, m.OptionSimple(aaa.USERNAME, tcp.HOSTNAME, cli.PID, cli.PWD, cli.RELEASE))) + } else { mdb.HashModify(m, mdb.HASH, m.Option(SID), mdb.STATUS, aaa.LOGIN) m.Echo(m.Option(SID)) } }}, - SESS: {Name: "sess hash auto prunes", Help: "会话流", Actions: ice.MergeActions(ice.Actions{ - mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) { - mdb.HashPrunesValue(m, mdb.STATUS, aaa.LOGOUT) + SESS: {Name: "sess hash auto invite prunes", Help: "会话流", Actions: ice.MergeActions(ice.Actions{ + aaa.INVITE: {Hand: func(m *ice.Message, arg ...string) { + code.PublishScript(m, `export ctx_dev={{.Option "httphost"}}; ctx_temp=$(mktemp); curl -o $ctx_temp -fsSL $ctx_dev; source $ctx_temp`) }}, - }, mdb.HashAction(mdb.FIELD, "time,hash,status,username,hostname,pid,pwd,grant"))}, + }, mdb.HashAction(mdb.FIELD, "time,hash,status,username,hostname,release,pid,pwd,grant"))}, }) } diff --git a/misc/bash/sync.go b/misc/bash/sync.go index 5815a1bc..d8456c8e 100644 --- a/misc/bash/sync.go +++ b/misc/bash/sync.go @@ -8,41 +8,45 @@ import ( "shylinux.com/x/icebergs/base/cli" "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" + "shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/base/tcp" + "shylinux.com/x/icebergs/base/web" kit "shylinux.com/x/toolkits" ) const SYNC = "sync" func init() { + const ( + HISTORY = "history" + SHELL = "shell" + ) Index.MergeCommands(ice.Commands{ - "/sync": {Name: "/sync", Help: "同步", Actions: ice.Actions{ - "history": {Name: "history", Help: "历史", Hand: func(m *ice.Message, arg ...string) { + SYNC: {Name: "sync id auto page export import", Help: "同步流", Actions: ice.MergeActions(ice.Actions{ + mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) { m.Cmdy(FAVOR, mdb.INPUTS, arg) }}, + cli.SYSTEM: {Hand: func(m *ice.Message, arg ...string) { + if len(arg) > 0 && arg[0] == ice.RUN { + if msg := mdb.ListSelect(m.Spawn(), m.Option(mdb.ID)); nfs.ExistsFile(m, msg.Append(cli.PWD)) { + m.Option(cli.CMD_DIR, msg.Append(cli.PWD)) + } + ctx.ProcessField(m, cli.SYSTEM, nil, arg...) + } else { + ctx.ProcessField(m, cli.SYSTEM, kit.Split(m.Option(mdb.TEXT))) + } + }}, + FAVOR: {Name: "favor zone=demo type name text pwd", Help: "收藏", Hand: func(m *ice.Message, arg ...string) { + m.Cmdy(FAVOR, mdb.INSERT, arg, m.OptionSimple(aaa.USERNAME, tcp.HOSTNAME)) + }}, + }, mdb.PageListAction(mdb.FIELD, "time,id,type,name,text,pwd,username,hostname")), Hand: func(m *ice.Message, arg ...string) { + mdb.PageListSelect(m, arg...).PushAction(cli.SYSTEM, FAVOR) + }}, + web.PP(SYNC): {Actions: ice.Actions{ + HISTORY: {Hand: func(m *ice.Message, arg ...string) { ls := strings.SplitN(strings.TrimSpace(m.Option(ARG)), ice.SP, 4) if text := strings.TrimSpace(strings.Join(ls[3:], ice.SP)); text != "" { - m.Cmd(SYNC, mdb.INSERT, mdb.TIME, ls[1]+ice.SP+ls[2], - mdb.TYPE, "shell", mdb.NAME, ls[0], mdb.TEXT, text, - m.OptionSimple(cli.PWD, aaa.USERNAME, tcp.HOSTNAME, tcp.HOSTNAME)) + m.Cmd(SYNC, mdb.INSERT, mdb.TIME, ls[1]+ice.SP+ls[2], mdb.TYPE, SHELL, mdb.NAME, ls[0], mdb.TEXT, text, m.OptionSimple(cli.PWD, aaa.USERNAME, tcp.HOSTNAME)) } }}, }}, - SYNC: {Name: "sync id auto page export import", Help: "同步流", Actions: ice.MergeActions(ice.Actions{ - cli.SYSTEM: {Name: "system", Help: "命令", Hand: func(m *ice.Message, arg ...string) { - m.Option(cli.CMD_DIR, m.Option(cli.PWD)) - ctx.ProcessCommand(m, cli.SYSTEM, kit.Split(m.Option(mdb.TEXT)), arg...) - ctx.ProcessCommandOpt(m, arg, cli.PWD) - }}, - mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(FAVOR, mdb.INPUTS, arg) - }}, - FAVOR: {Name: "favor zone=some@key type name text pwd", Help: "收藏", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(FAVOR, mdb.INSERT) - }}, - }, mdb.ListAction(mdb.FIELD, "time,id,type,name,text,pwd,username,hostname")), Hand: func(m *ice.Message, arg ...string) { - mdb.OptionPage(m, kit.Slice(arg, 1)...) - mdb.ListSelect(m, kit.Slice(arg, 0, 1)...) - m.PushAction(cli.SYSTEM, FAVOR) - m.StatusTimeCountTotal(m.Config(mdb.COUNT)) - }}, }) } diff --git a/misc/bash/trash.go b/misc/bash/trash.go index c97ef3c9..17682256 100644 --- a/misc/bash/trash.go +++ b/misc/bash/trash.go @@ -3,51 +3,35 @@ package bash import ( ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/aaa" - "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/base/tcp" "shylinux.com/x/icebergs/base/web" + kit "shylinux.com/x/toolkits" ) -const ( - FROM = "from" - TO = "to" -) const TRASH = "trash" func init() { + const ( + FROM = "from" + TO = "to" + ) Index.MergeCommands(ice.Commands{ - TRASH: {Name: "TRASH hash path auto prunes", Help: "回收站", Actions: ice.MergeActions(ice.Actions{ - mdb.INSERT: {Name: "insert from to", Help: "添加", Hand: func(m *ice.Message, arg ...string) { + TRASH: {Name: "trash hash path auto", Help: "回收站", Actions: mdb.HashAction(mdb.FIELD, "time,hash,username,hostname,size,from,to")}, + web.PP(TRASH): {Actions: ice.MergeActions(ice.Actions{ + mdb.INSERT: {Name: "insert from to", Hand: func(m *ice.Message, arg ...string) { mdb.HashCreate(m, m.OptionSimple(aaa.USERNAME, tcp.HOSTNAME, nfs.SIZE, FROM, TO)) }}, - mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { - if !m.Warn(m.Option(TO) == "", ice.ErrNotValid, TO) { - mdb.HashRemove(m, m.OptionSimple(mdb.HASH)) - nfs.RemoveAll(m, m.Option(TO)) - } + mdb.REVERT: {Hand: func(m *ice.Message, arg ...string) { + mdb.HashSelect(m, m.Option(mdb.HASH)) + defer mdb.HashRemove(m, m.OptionSimple(mdb.HASH)) + m.Echo("mv %s %s", m.Append(TO), m.Append(FROM)) }}, - mdb.REVERT: {Name: "revert", Help: "恢复", Hand: func(m *ice.Message, arg ...string) { - if !m.Warn(m.Option(FROM) == "" && m.Option(TO) == "", ice.ErrNotValid, FROM, TO) { - nfs.Rename(m, m.Option(TO), m.Option(FROM)) - mdb.HashRemove(m, m.OptionSimple(mdb.HASH)) - } - }}, - mdb.PRUNES: {Name: "prunes before@date", Help: "清理", Hand: func(m *ice.Message, arg ...string) { - mdb.HashPrunes(m, func(value ice.Map) bool { - return true - }).Tables(func(value ice.Maps) { - nfs.RemoveAll(m, value[TO]) - }) - }}, - nfs.CAT: {Name: "cat", Help: "查看", Hand: func(m *ice.Message, arg ...string) { - m.Option(nfs.DIR_ROOT, m.Option(TO)) - ctx.ProcessCommand(m, nfs.CAT, []string{}, arg...) - ctx.ProcessCommandOpt(m, arg, TO) - }}, - }, mdb.HashAction(mdb.FIELD, "time,hash,username,hostname,size,from,to"), web.ApiAction("/trash")), Hand: func(m *ice.Message, arg ...string) { - mdb.HashSelect(m, arg...).PushAction(nfs.CAT, mdb.REVERT, mdb.REMOVE) + }), Hand: func(m *ice.Message, arg ...string) { + mdb.HashSelectValue(m, func(key string, fields []string, value, val ice.Map) { + kit.If(value[tcp.HOSTNAME] == m.Option(tcp.HOSTNAME), func() { m.Push(key, value, fields, val) }) + }) }}, }) } diff --git a/misc/bash/zsh.go b/misc/bash/zsh.go index c7a8917e..79eac7ff 100644 --- a/misc/bash/zsh.go +++ b/misc/bash/zsh.go @@ -12,11 +12,11 @@ const ZSH = "zsh" func init() { Index.MergeCommands(ice.Commands{ ZSH: {Name: "zsh path auto order build download", Help: "命令行", Actions: ice.MergeActions(ice.Actions{ - cli.ORDER: {Name: "order", Help: "加载", Hand: func(m *ice.Message, arg ...string) { + cli.ORDER: {Hand: func(m *ice.Message, arg ...string) { m.Cmdy(code.INSTALL, cli.ORDER, m.Config(nfs.SOURCE), "_install/bin") }}, }, code.InstallAction(nfs.SOURCE, "https://nchc.dl.sourceforge.net/project/zsh/zsh/5.8/zsh-5.8.tar.xz")), Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(code.INSTALL, nfs.SOURCE, m.Config(nfs.SOURCE), arg) + m.Cmdy(code.INSTALL, m.ConfigSimple(nfs.SOURCE), arg) }}, }) } diff --git a/misc/git/git.go b/misc/git/git.go index d31d825f..1e2316ef 100644 --- a/misc/git/git.go +++ b/misc/git/git.go @@ -2,23 +2,20 @@ package git import ( "path" - "strings" ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/cli" "shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/base/web" "shylinux.com/x/icebergs/core/code" - kit "shylinux.com/x/toolkits" ) -func _git_url(m *ice.Message, repos string) string { return web.MergeLink(m, "/x/"+path.Join(repos)+".git") } +func _git_url(m *ice.Message, repos string) string { + return web.MergeLink(m, "/x/"+path.Join(repos)+".git") +} func _git_dir(arg ...string) string { return path.Join(path.Join(arg...), ".git") } func _git_cmd(m *ice.Message, arg ...string) *ice.Message { return m.Cmd(cli.SYSTEM, GIT, arg) } -func _git_cmds(m *ice.Message, arg ...string) string { - msg := _git_cmd(m, arg...) - return kit.Select("", strings.TrimSpace(msg.Result()), !msg.IsErr()) -} +func _git_cmds(m *ice.Message, arg ...string) string { return _git_cmd(m, arg...).Results() } const GIT = "git" diff --git a/misc/git/status.go b/misc/git/status.go index 4e1bfcab..38ed57ab 100644 --- a/misc/git/status.go +++ b/misc/git/status.go @@ -2,7 +2,6 @@ package git import ( "path" - "runtime" "strings" "time" @@ -114,9 +113,8 @@ 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) { ReposList(m).Tables(func(value ice.Maps) { - if m.Option(cli.CMD_DIR, value[nfs.PATH]); runtime.GOOS != cli.DARWIN { - files, adds, dels = _status_stat(m, files, adds, dels) - } + 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 { if ci, e := repos.GetCommit(); e == nil && ci.Author.When.After(last) { last = ci.Author.When diff --git a/misc/input/input.go b/misc/input/input.go index 39957550..7cbfa003 100644 --- a/misc/input/input.go +++ b/misc/input/input.go @@ -27,24 +27,28 @@ const ( type input struct { ice.Zone - insert string `name:"insert zone=person text code weight" help:"添加"` - load string `name:"load file=usr/wubi-dict/wubi86 zone=wubi86" help:"加载"` - save string `name:"save file=usr/wubi-dict/person zone=person" help:"保存"` - list string `name:"list method code auto" help:"输入法"` + insert string `name:"insert zone=person text code weight"` + load string `name:"load file=usr/wubi-dict/wubi86 zone=wubi86"` + save string `name:"save file=usr/wubi-dict/person zone=person"` + list string `name:"list method code auto load" help:"输入法"` } +func (s input) Inputs(m *ice.Message, arg ...string) { + switch s.Zone.Inputs(m, arg...); arg[0] { + case nfs.FILE: + m.Cmdy(nfs.DIR, "usr/wubi-dict/", nfs.PATH) + case mdb.ZONE: + m.Push(arg[0], path.Base(m.Option(nfs.FILE))) + } +} func (s input) Load(m *ice.Message, arg ...string) { - if f, e := nfs.OpenFile(m.Message, m.Option(nfs.FILE)); !m.Warn(e) { + if f, e := nfs.OpenFile(m, m.Option(nfs.FILE)); !m.Warn(e) { defer f.Close() - - // 清空数据 lib := kit.Select(path.Base(m.Option(nfs.FILE)), m.Option(mdb.ZONE)) - m.Assert(nfs.RemoveAll(m.Message, path.Join(m.Config(mdb.STORE), lib))) + m.Assert(nfs.RemoveAll(m, path.Join(m.Config(mdb.STORE), lib))) s.Zone.Remove(m, mdb.ZONE, lib) s.Zone.Create(m, kit.Simple(mdb.ZONE, lib, m.ConfigSimple(mdb.LIMIT, mdb.LEAST, mdb.STORE, mdb.FSIZE))...) prefix := kit.Keys(mdb.HASH, m.Result()) - - // 加载词库 for bio := bufio.NewScanner(f); bio.Scan(); { if strings.HasPrefix(bio.Text(), "# ") { continue @@ -55,17 +59,14 @@ func (s input) Load(m *ice.Message, arg ...string) { } mdb.Grow(m.Message, m.PrefixKey(), prefix, kit.Dict(TEXT, line[0], CODE, line[1], WEIGHT, kit.Select("999999", line, 2))) } - - // 保存词库 m.Conf(m.PrefixKey(), kit.Keys(prefix, kit.Keym(mdb.LIMIT)), 0) m.Conf(m.PrefixKey(), kit.Keys(prefix, kit.Keym(mdb.LEAST)), 0) m.Echo("%s: %d", lib, mdb.Grow(m.Message, m.PrefixKey(), prefix, kit.Dict(TEXT, "成功", CODE, "z", WEIGHT, "0"))) } } -func (s input) Save(m *ice.Message, arg ...string) { +func (s input) Save(m *ice.Message, arg ...string) (n int) { if f, p, e := nfs.CreateFile(m.Message, m.Option(nfs.FILE)); m.Assert(e) { defer f.Close() - n := 0 m.Option(mdb.CACHE_LIMIT, -2) for _, lib := range kit.Split(m.Option(mdb.ZONE)) { mdb.Richs(m.Message, m.PrefixKey(), "", lib, func(key string, value ice.Map) { @@ -80,6 +81,7 @@ func (s input) Save(m *ice.Message, arg ...string) { m.Logs(mdb.EXPORT, nfs.FILE, p, mdb.COUNT, n) m.Echo("%s: %d", p, n) } + return } func (s input) List(m *ice.Message, arg ...string) { if len(arg) < 2 || arg[1] == "" { @@ -90,23 +92,14 @@ func (s input) List(m *ice.Message, arg ...string) { case WORD: arg[1] = "^" + arg[1] + ice.FS } - - // 搜索词汇 res := m.Cmdx(cli.SYSTEM, "grep", "-rn", arg[1], m.Config(mdb.STORE)) - bio := csv.NewReader(bytes.NewBufferString(strings.Replace(res, ":", ",", -1))) - + bio := csv.NewReader(bytes.NewBufferString(strings.Replace(res, ice.DF, ice.FS, -1))) for i := 0; i < kit.Int(10); i++ { if line, e := bio.Read(); e != nil { break - } else if len(line) < 3 { - - } else { // 输出词汇 - m.Push(mdb.ID, line[3]) - m.Push(CODE, line[2]) - m.Push(TEXT, line[4]) - m.Push(WEIGHT, line[6]) + } else if len(line) > 3 { + m.Push(mdb.ID, line[3]).Push(CODE, line[2]).Push(TEXT, line[4]).Push(WEIGHT, line[6]) } } - m.SortIntR(WEIGHT) - m.StatusTimeCount() + m.StatusTimeCount().SortIntR(WEIGHT) } diff --git a/misc/input/input.shy b/misc/input/input.shy deleted file mode 100644 index 05767c86..00000000 --- a/misc/input/input.shy +++ /dev/null @@ -1,4 +0,0 @@ -section "input" - -field web.code.input.wubi - diff --git a/misc/input/wubi.go b/misc/input/wubi.go index e5774a66..603fbc40 100644 --- a/misc/input/wubi.go +++ b/misc/input/wubi.go @@ -11,31 +11,26 @@ import ( type wubi struct { input - short string `data:"zone"` - field string `data:"time,zone,id,text,code,weight"` store string `data:"usr/local/export/"` + field string `data:"time,id,text,code,weight"` fsize string `data:"100000"` limit string `data:"10000"` least string `data:"1000"` - - load string `name:"load file=usr/wubi-dict/wubi86 zone=wubi86" help:"加载"` - save string `name:"save file=usr/wubi-dict/person zone=person" help:"保存"` - list string `name:"list method=word,line code auto" help:"五笔"` + load string `name:"load file=usr/wubi-dict/wubi86 zone=wubi86"` + save string `name:"save file=usr/wubi-dict/person zone=person"` + list string `name:"list method=word,line code auto load" help:"五笔"` } func (w wubi) Input(m *ice.Message, arg ...string) { if arg[0] = strings.TrimSpace(arg[0]); strings.HasPrefix(arg[0], "ice") { switch list := kit.Split(arg[0]); list[1] { case "add": // ice add 想你 shwq [9999 [person]] - m.Cmd(w, mdb.INSERT, mdb.TEXT, list[2], cli.CODE, list[3], mdb.VALUE, kit.Select("999999", list, 4), mdb.ZONE, kit.Select("person", list, 5)) + w.Insert(m, mdb.ZONE, kit.Select("person", list, 5), mdb.TEXT, list[2], cli.CODE, list[3], mdb.VALUE, kit.Select("999999", list, 4)) m.Echo(list[3] + ice.NL) } return } - - m.Cmd(w, WORD, arg[0], func(value ice.Maps) { - m.Echo(value[mdb.TEXT] + ice.NL) - }) + m.Cmd(w, WORD, arg[0], func(value ice.Maps) { m.Echo(value[mdb.TEXT] + ice.NL) }) } func init() { ice.CodeCtxCmd(wubi{}) } diff --git a/misc/misc.shy b/misc/misc.shy index 9235d7e8..e2810ef7 100644 --- a/misc/misc.shy +++ b/misc/misc.shy @@ -1,16 +1,18 @@ git ssh +input +alpha +tmux + vim bash -tmux +coder +java +node + mp wx lark wework -webview chrome -alpha -input -coder -java -node +webview diff --git a/misc/ssh/channel.go b/misc/ssh/channel.go index 79bc9534..66e7bcdf 100644 --- a/misc/ssh/channel.go +++ b/misc/ssh/channel.go @@ -16,7 +16,6 @@ func _ssh_watch(m *ice.Message, h string, output io.Writer, input io.Reader) io. r, w := io.Pipe() bio := io.TeeReader(input, w) m.Go(func() { io.Copy(output, r) }) - i, buf := 0, make([]byte, ice.MOD_BUFS) m.Go(func() { for { @@ -24,7 +23,6 @@ func _ssh_watch(m *ice.Message, h string, output io.Writer, input io.Reader) io. if e != nil { break } - switch buf[i] { case '\r', '\n': cmd := strings.TrimSpace(string(buf[:i])) @@ -46,9 +44,7 @@ func init() { psh.Index.MergeCommands(ice.Commands{ CHANNEL: {Name: "channel hash id auto", Help: "通道", Actions: ice.MergeActions(ice.Actions{ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { - mdb.HashSelectUpdate(m, mdb.FOREACH, func(value ice.Map) { - kit.Value(value, mdb.STATUS, tcp.CLOSE) - }) + mdb.HashSelectUpdate(m, mdb.FOREACH, func(value ice.Map) { kit.Value(value, mdb.STATUS, tcp.CLOSE) }) }}, ctx.COMMAND: {Name: "command cmd=pwd", Help: "命令", Hand: func(m *ice.Message, arg ...string) { mdb.ZoneInsert(m, m.OptionSimple(mdb.HASH), mdb.TYPE, CMD, mdb.TEXT, m.Option(CMD)) @@ -57,23 +53,15 @@ func init() { m.Sleep300ms() } }}, - mdb.REPEAT: {Name: "repeat", Help: "执行", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy("", ctx.COMMAND, CMD, m.Option(mdb.TEXT)) - }}, - }, mdb.HashAction(mdb.FIELD, "time,hash,status,tty,count,username,hostport")), Hand: func(m *ice.Message, arg ...string) { - if len(arg) == 0 { // 通道列表 - m.Action(mdb.PRUNES) - mdb.HashSelect(m, arg...).Tables(func(value ice.Maps) { + 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.PushButton(kit.Select("", ctx.COMMAND, value[mdb.STATUS] == tcp.OPEN), mdb.REMOVE) - }) - return + }).Action(mdb.PRUNES) + } else { + m.PushAction(mdb.REPEAT).Action(ctx.COMMAND) } - - // 通道命令 - m.Action(ctx.COMMAND) - m.Fields(len(arg[1:]), "time,id,type,text") - mdb.ZoneSelect(m, arg...) - m.PushAction(mdb.REPEAT) }}, }) } diff --git a/misc/ssh/connect.go b/misc/ssh/connect.go index e07fda23..d8e674f8 100644 --- a/misc/ssh/connect.go +++ b/misc/ssh/connect.go @@ -24,22 +24,16 @@ import ( func _ssh_open(m *ice.Message, arg ...string) { _ssh_dial(m, func(c net.Conn) { - // 保存界面 fd := int(os.Stdin.Fd()) if oldState, err := terminal.MakeRaw(fd); err == nil { defer terminal.Restore(fd, oldState) } - - // 设置宽高 w, h, _ := terminal.GetSize(fd) c.Write([]byte(fmt.Sprintf("#height:%d,width:%d\n", h, w))) - - // 初始命令 - for _, item := range kit.Simple(m.Optionv("init")) { + for _, item := range kit.Simple(m.Optionv(ice.INIT)) { m.Sleep300ms() c.Write([]byte(item + ice.NL)) } - m.Go(func() { io.Copy(c, os.Stdin) }) io.Copy(os.Stdout, c) }, arg...) @@ -48,62 +42,58 @@ func _ssh_dial(m *ice.Message, cb func(net.Conn), arg ...string) { p := kit.HomePath(".ssh", fmt.Sprintf("%s@%s:%s", m.Option(aaa.USERNAME), m.Option(tcp.HOST), m.Option(tcp.PORT))) if nfs.ExistsFile(m, p) { if c, e := net.Dial("unix", p); e == nil { - cb(c) // 会话复用 + cb(c) return } nfs.Remove(m, p) } - _ssh_conn(m, func(client *ssh.Client) { - if l, e := net.Listen("unix", p); m.Assert(e) { + if l, e := net.Listen("unix", p); !m.Warn(e, ice.ErrNotValid) { defer func() { nfs.Remove(m, p) }() defer l.Close() - m.Go(func() { for { c, e := l.Accept() if e != nil { break } - func(c net.Conn) { w, h, _ := terminal.GetSize(int(os.Stdin.Fd())) buf := make([]byte, ice.MOD_BUFS) if n, e := c.Read(buf); m.Assert(e) { fmt.Sscanf(string(buf[:n]), "#height:%d,width:%d", &h, &w) } - m.Go(func() { defer c.Close() - s, e := client.NewSession() if e != nil { return } - s.Stdin, s.Stdout, s.Stderr = c, c, c s.RequestPty(kit.Env(cli.TERM), h, w, ssh.TerminalModes{ssh.ECHO: 1, ssh.TTY_OP_ISPEED: 14400, ssh.TTY_OP_OSPEED: 14400}) defer s.Wait() - gdb.SignalNotify(m, 28, func() { w, h, _ := terminal.GetSize(int(os.Stdin.Fd())) s.WindowChange(h, w) }) - s.Shell() }) }(c) } }) } - if c, e := net.Dial("unix", p); e == nil { - cb(c) // 会话连接 + cb(c) } }, arg...) } func _ssh_conn(m *ice.Message, cb func(*ssh.Client), arg ...string) { methods := []ssh.AuthMethod{} + methods = append(methods, ssh.PublicKeysCallback(func() ([]ssh.Signer, error) { + key, err := ssh.ParsePrivateKey([]byte(m.Cmdx(nfs.CAT, kit.HomePath(m.Option(PRIVATE))))) + return []ssh.Signer{key}, err + })) + methods = append(methods, ssh.PasswordCallback(func() (string, error) { return m.Option(aaa.PASSWORD), nil })) methods = append(methods, ssh.KeyboardInteractive(func(user, instruction string, questions []string, echos []bool) (res []string, err error) { for _, q := range questions { p := strings.TrimSpace(strings.ToLower(q)) @@ -114,7 +104,7 @@ func _ssh_conn(m *ice.Message, cb func(*ssh.Client), arg ...string) { fmt.Scanf("%s\n", &verify) res = append(res, verify) } else { - res = append(res, aaa.TOTP_GET(verify, 6, 30)) + res = append(res, aaa.TOTP_GET(verify, 30, 6)) } case strings.HasSuffix(p, "password:"): res = append(res, m.Option(aaa.PASSWORD)) @@ -123,21 +113,14 @@ func _ssh_conn(m *ice.Message, cb func(*ssh.Client), arg ...string) { } return })) - methods = append(methods, ssh.PublicKeysCallback(func() ([]ssh.Signer, error) { - key, err := ssh.ParsePrivateKey([]byte(m.Cmdx(nfs.CAT, kit.HomePath(m.Option(PRIVATE))))) - return []ssh.Signer{key}, err - })) - methods = append(methods, ssh.PasswordCallback(func() (string, error) { - return m.Option(aaa.PASSWORD), nil - })) - m.Cmdy(tcp.CLIENT, tcp.DIAL, mdb.TYPE, SSH, mdb.NAME, m.Option(tcp.HOST), m.OptionSimple(tcp.HOST, tcp.PORT), arg, func(c net.Conn) { conn, chans, reqs, err := ssh.NewClientConn(c, m.Option(tcp.HOST)+ice.DF+m.Option(tcp.PORT), &ssh.ClientConfig{ User: m.Option(aaa.USERNAME), Auth: methods, BannerCallback: func(message string) error { return nil }, HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error { return nil }, }) - m.Assert(err) - cb(ssh.NewClient(conn, chans, reqs)) + if !m.Warn(err) { + cb(ssh.NewClient(conn, chans, reqs)) + } }) } @@ -147,6 +130,13 @@ const CONNECT = "connect" 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) { + if value[mdb.STATUS] == tcp.OPEN { + m.Cmd("", tcp.DIAL, mdb.NAME, value[mdb.NAME], value) + } + }) + }}, tcp.OPEN: {Name: "open authfile username=shy password verfiy host=shylinux.com port=22 private=.ssh/id_rsa", Help: "终端", Hand: func(m *ice.Message, arg ...string) { defer m.Echo("exit %s@%s:%s\n", m.Option(aaa.USERNAME), m.Option(tcp.HOST), m.Option(tcp.PORT)) _ssh_open(nfs.OptionLoad(m, m.Option("authfile")), arg...) @@ -157,20 +147,19 @@ 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...) - }) - m.Sleep300ms() + }).Sleep300ms() }}, - SESSION: {Name: "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.Assert(e) { + 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) { defer c.Wait() c.Shell() } }}, ctx.COMMAND: {Name: "command cmd=pwd", Help: "命令", Hand: func(m *ice.Message, arg ...string) { client := mdb.HashSelectTarget(m, m.Option(mdb.NAME), nil).(*ssh.Client) - if s, e := client.NewSession(); m.Assert(e) { + if s, e := client.NewSession(); !m.Warn(e, ice.ErrNotValid) { defer s.Close() - if b, e := s.CombinedOutput(m.Option(ice.CMD)); m.Assert(e) { + if b, e := s.CombinedOutput(m.Option(ice.CMD)); !m.Warn(e, ice.ErrNotValid) { m.Echo(string(b)) } } diff --git a/misc/ssh/rsa.go b/misc/ssh/rsa.go index fd28a452..cb0ea640 100644 --- a/misc/ssh/rsa.go +++ b/misc/ssh/rsa.go @@ -23,31 +23,37 @@ const ( const RSA = "rsa" func init() { + const ( + TITLE = "title" + BITS = "bits" + KEY = "key" + PUB = "pub" + ) aaa.Index.MergeCommands(ice.Commands{ RSA: {Name: "rsa hash auto", Help: "密钥", Actions: ice.MergeActions(ice.Actions{ - mdb.CREATE: {Name: "create bits=2048,4096 title=some", Help: "创建", Hand: func(m *ice.Message, arg ...string) { - if key, err := rsa.GenerateKey(rand.Reader, kit.Int(m.Option("bits"))); m.Assert(err) { - if pub, err := ssh.NewPublicKey(key.Public()); m.Assert(err) { - mdb.HashCreate(m, m.OptionSimple("title"), PUBLIC, string(ssh.MarshalAuthorizedKey(pub)), + mdb.CREATE: {Name: "create bits=2048,4096 title=some", Hand: func(m *ice.Message, arg ...string) { + if key, err := rsa.GenerateKey(rand.Reader, kit.Int(m.Option(BITS))); !m.Warn(err, ice.ErrNotValid) { + if pub, err := ssh.NewPublicKey(key.Public()); !m.Warn(err, ice.ErrNotValid) { + mdb.HashCreate(m, m.OptionSimple(TITLE), PUBLIC, string(ssh.MarshalAuthorizedKey(pub)), PRIVATE, string(pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(key)})), ) } } }}, - mdb.EXPORT: {Name: "export key=.ssh/id_rsa pub=.ssh/id_rsa.pub", Help: "导出", Hand: func(m *ice.Message, arg ...string) { + 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) { - m.Cmdx(nfs.SAVE, kit.HomePath(m.Option("key")), value[PRIVATE]) - m.Cmdx(nfs.SAVE, kit.HomePath(m.Option("pub")), value[PUBLIC]) + m.Cmd(nfs.SAVE, kit.HomePath(m.Option(KEY)), value[PRIVATE]) + m.Cmd(nfs.SAVE, kit.HomePath(m.Option(PUB)), value[PUBLIC]) }) }}, - mdb.IMPORT: {Name: "import key=.ssh/id_rsa pub=.ssh/id_rsa.pub", Help: "导入", Hand: func(m *ice.Message, arg ...string) { - m.Conf("", kit.Keys(mdb.HASH, path.Base(m.Option("key"))), kit.Data(mdb.TIME, m.Time(), - "title", kit.Format("%s@%s", ice.Info.Username, ice.Info.Hostname), - PRIVATE, m.Cmdx(nfs.CAT, kit.HomePath(m.Option("key"))), - PUBLIC, m.Cmdx(nfs.CAT, kit.HomePath(m.Option("pub"))), + mdb.IMPORT: {Name: "import key=.ssh/id_rsa pub=.ssh/id_rsa.pub", Hand: func(m *ice.Message, arg ...string) { + m.Conf("", kit.Keys(mdb.HASH, path.Base(m.Option(KEY))), kit.Data(mdb.TIME, m.Time(), + TITLE, kit.Format("%s@%s", ice.Info.Username, ice.Info.Hostname), + PRIVATE, m.Cmdx(nfs.CAT, kit.HomePath(m.Option(KEY))), + PUBLIC, m.Cmdx(nfs.CAT, kit.HomePath(m.Option(PUB))), )) }}, - }, mdb.HashAction(mdb.SHORT, mdb.HASH, mdb.FIELD, "time,hash,title,public,private")), Hand: func(m *ice.Message, arg ...string) { + }, mdb.HashAction(mdb.SHORT, PRIVATE, mdb.FIELD, "time,hash,title,public,private")), Hand: func(m *ice.Message, arg ...string) { if mdb.HashSelect(m, arg...).PushAction(mdb.EXPORT, mdb.REMOVE); len(arg) == 0 { m.Action(mdb.CREATE, mdb.IMPORT) } diff --git a/misc/ssh/service.go b/misc/ssh/service.go index e99c8a02..67d80e1a 100644 --- a/misc/ssh/service.go +++ b/misc/ssh/service.go @@ -32,20 +32,19 @@ func _ssh_config(m *ice.Message, h string) *ssh.ServerConfig { PublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { meta, err := _ssh_meta(conn), errors.New(ice.ErrNotRight) if tcp.IsLocalHost(m, meta[tcp.HOSTPORT]) { - m.Auth(aaa.USERNAME, meta[aaa.USERNAME], tcp.HOSTPORT, meta[tcp.HOSTPORT]) - err = nil // 本机用户 + m.Auth(kit.SimpleKV(kit.Fields(aaa.USERNAME, tcp.HOSTPORT), meta)) + err = nil } else { mdb.ZoneSelectCB(m, h, func(value ice.Maps) { if !strings.HasPrefix(value[mdb.NAME], meta[aaa.USERNAME]+"@") { return } - if s, e := base64.StdEncoding.DecodeString(value[mdb.TEXT]); !m.Warn(e) { - if pub, e := ssh.ParsePublicKey([]byte(s)); !m.Warn(e) { - + if s, e := base64.StdEncoding.DecodeString(value[mdb.TEXT]); !m.Warn(e, ice.ErrNotValid, value[mdb.TEXT]) { + if pub, e := ssh.ParsePublicKey([]byte(s)); !m.Warn(e, ice.ErrNotValid, value[mdb.TEXT]) { if bytes.Compare(pub.Marshal(), key.Marshal()) == 0 { meta[tcp.HOSTNAME] = kit.Select("", kit.Split(value[mdb.NAME], "@"), 1) - m.Auth(aaa.USERNAME, meta[aaa.USERNAME], tcp.HOSTPORT, meta[tcp.HOSTPORT], tcp.HOSTNAME, meta[tcp.HOSTNAME]) - err = nil // 认证成功 + m.Auth(kit.SimpleKV(kit.Fields(aaa.USERNAME, tcp.HOSTPORT, tcp.HOSTNAME), meta)) + err = nil } } } @@ -55,16 +54,14 @@ 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) - m.Debug("what %v", string(password)) if aaa.UserLogin(m, meta[aaa.USERNAME], string(password)) { - m.Auth(aaa.USERNAME, meta[aaa.USERNAME], tcp.HOSTPORT, meta[tcp.HOSTPORT], aaa.PASSWORD, strings.Repeat("*", len(string(password)))) - err = nil // 密码登录 + m.Auth(kit.SimpleKV(kit.Fields(aaa.USERNAME, tcp.HOSTPORT, tcp.HOSTNAME), meta)) + err = nil } return &ssh.Permissions{Extensions: meta}, err }, } - - if key, err := ssh.ParsePrivateKey([]byte(m.Cmdx(nfs.CAT, kit.HomePath(m.Option(PRIVATE))))); !m.Warn(err) { + if key, err := ssh.ParsePrivateKey([]byte(m.Cmdx(nfs.CAT, kit.HomePath(m.Option(PRIVATE))))); !m.Warn(err, ice.ErrNotValid, m.Option(PRIVATE)) { config.AddHostKey(key) } return config @@ -75,15 +72,14 @@ func _ssh_accept(m *ice.Message, h string, c net.Conn) { return } m.Go(func() { ssh.DiscardRequests(reqs) }) - for ch := range chans { channel, requests, err := ch.Accept() if m.Warn(err) { continue } m.Go(func() { - m.Logs(CHANNEL, tcp.HOSTPORT, c.RemoteAddr().String(), "->", c.LocalAddr().String()) - defer m.Logs("dischan", tcp.HOSTPORT, c.RemoteAddr().String(), "->", c.LocalAddr().String()) + m.Logs(CHANNEL, tcp.HOSTPORT, c.RemoteAddr().String()+" -> "+c.LocalAddr().String()) + defer m.Logs("dischan", tcp.HOSTPORT, c.RemoteAddr().String()+" -> "+c.LocalAddr().String()) _ssh_prepare(m.Spawn(conn.Permissions.Extensions), channel, requests) }) } @@ -94,47 +90,40 @@ func _ssh_prepare(m *ice.Message, channel ssh.Channel, requests <-chan *ssh.Requ return } defer tty.Close() - - list := []string{cli.PATH + "=" + kit.Env(cli.PATH)} - + list := kit.EnvSimple(cli.PATH) for request := range requests { - m.Logs(REQUEST, tcp.HOSTPORT, m.Option(tcp.HOSTPORT), mdb.TYPE, request.Type) - + m.Logs(REQUEST, m.OptionSimple(tcp.HOSTPORT), mdb.TYPE, request.Type) switch request.Type { case "pty-req": termLen := request.Payload[3] termEnv := string(request.Payload[4 : termLen+4]) _ssh_size(pty.Fd(), request.Payload[termLen+4:]) - list = append(list, "TERM="+termEnv) + list = append(list, cli.TERM, termEnv) case "window-change": _ssh_size(pty.Fd(), request.Payload) - case "env": var env struct{ Name, Value string } if err := ssh.Unmarshal(request.Payload, &env); err != nil { continue } - list = append(list, env.Name+"="+env.Value) - + list = append(list, env.Name, env.Value) case "shell": - _ssh_handle(m, channel, pty, tty) + _ssh_handle(m, channel, pty, tty, list) case "exec": defer channel.Close() - m.Optionv(cli.CMD_OUTPUT, channel) + m.Options(cli.CMD_OUTPUT, channel, cli.CMD_ENV, list) m.Cmd(cli.SYSTEM, kit.Select("sh", kit.Env(cli.SHELL)), "-c", string(request.Payload[4:request.Payload[3]+4])) return } request.Reply(true, nil) } } -func _ssh_handle(m *ice.Message, channel ssh.Channel, pty, tty *os.File) { +func _ssh_handle(m *ice.Message, channel ssh.Channel, pty, tty *os.File, list []string) { h := m.Cmdx(mdb.INSERT, m.Prefix(CHANNEL), "", mdb.HASH, mdb.STATUS, tcp.OPEN, TTY, tty.Name(), m.OptionSimple(aaa.USERNAME, tcp.HOSTPORT), kit.Dict(mdb.TARGET, pty)) - m.Go(func() { io.Copy(channel, pty) }) p := _ssh_watch(m, h, pty, channel) - - m.Optionv(cli.CMD_INPUT, tty) - m.Optionv(cli.CMD_OUTPUT, tty) + m.Go(func() { io.Copy(channel, pty) }) channel.Write([]byte(m.Config(WELCOME))) + m.Options(cli.CMD_INPUT, tty, cli.CMD_OUTPUT, tty) m.Cmd(cli.DAEMON, kit.Select("sh", kit.Env(cli.SHELL)), func() { defer m.Cmd(mdb.MODIFY, m.Prefix(CHANNEL), "", mdb.HASH, mdb.HASH, h, mdb.STATUS, tcp.CLOSE) channel.Write([]byte(m.Config(GOODBYE))) @@ -161,31 +150,26 @@ func init() { } }) }}, - tcp.LISTEN: {Name: "listen port=9022 private=.ssh/id_rsa authkey=.ssh/authorized_keys", Help: "添加", Hand: func(m *ice.Message, arg ...string) { + tcp.LISTEN: {Name: "listen port=9022 private=.ssh/id_rsa authkey=.ssh/authorized_keys", Help: "启动", Hand: func(m *ice.Message, arg ...string) { if mdb.HashSelect(m, m.Option(tcp.PORT)).Length() > 0 { mdb.HashModify(m, m.Option(tcp.PORT), mdb.STATUS, tcp.OPEN) } else { mdb.HashCreate(m.Spawn(), m.OptionSimple(mdb.HashField(m)), mdb.STATUS, tcp.OPEN) m.Cmd("", ctx.LOAD, m.OptionSimple(AUTHKEY)) } - m.Go(func() { - m.Cmd(tcp.SERVER, tcp.LISTEN, mdb.TYPE, SSH, mdb.NAME, tcp.PORT, m.OptionSimple(tcp.PORT), func(c net.Conn) { + m.Cmd(tcp.SERVER, tcp.LISTEN, mdb.TYPE, SSH, mdb.NAME, m.Option(tcp.PORT), m.OptionSimple(tcp.PORT), func(c net.Conn) { m.Go(func() { _ssh_accept(m, kit.Hashs(m.Option(tcp.PORT)), c) }) }) }) }}, - mdb.INSERT: {Name: "insert text:textarea", Help: "添加", Hand: func(m *ice.Message, arg ...string) { if ls := kit.Split(m.Option(mdb.TEXT)); len(ls) > 2 { - m.Cmdy(mdb.INSERT, m.Prefix(SERVICE), kit.Keys(mdb.HASH, kit.Hashs(m.Option(tcp.PORT))), mdb.LIST, - mdb.TYPE, ls[0], mdb.NAME, ls[len(ls)-1], mdb.TEXT, strings.Join(ls[1:len(ls)-1], "+")) + mdb.ZoneInsert(m, m.OptionSimple(tcp.PORT), mdb.TYPE, ls[0], mdb.NAME, ls[len(ls)-1], mdb.TEXT, strings.Join(ls[1:len(ls)-1], "+")) } }}, ctx.LOAD: {Name: "load authkey=.ssh/authorized_keys", Help: "加载", Hand: func(m *ice.Message, arg ...string) { - m.Cmd(nfs.CAT, kit.HomePath(m.Option(AUTHKEY)), func(pub string) { - m.Cmd(SERVICE, mdb.INSERT, mdb.TEXT, pub) - }) + m.Cmd(nfs.CAT, kit.HomePath(m.Option(AUTHKEY)), func(pub string) { m.Cmd(SERVICE, mdb.INSERT, mdb.TEXT, pub) }) }}, ctx.SAVE: {Name: "save authkey=.ssh/authorized_keys", Help: "保存", Hand: func(m *ice.Message, arg ...string) { list := []string{} @@ -196,24 +180,20 @@ func init() { m.Cmdy(nfs.SAVE, kit.HomePath(m.Option(AUTHKEY)), strings.Join(list, ice.NL)+ice.NL) } }}, - aaa.INVITE: {Name: "invite", Help: "邀请", Hand: func(m *ice.Message, arg ...string) { - m.Option(cli.HOSTNAME, web.OptionUserWeb(m).Hostname()) + aaa.INVITE: {Help: "邀请", Hand: func(m *ice.Message, arg ...string) { + m.Option(cli.HOSTNAME, tcp.PublishLocalhost(m, web.OptionUserWeb(m).Hostname())) if buf, err := kit.Render(`ssh -p {{.Option "port"}} {{.Option "user.name"}}@{{.Option "hostname"}}`, m); err == nil { m.EchoScript(string(buf)) } }}, }, mdb.StatusHashAction( - mdb.SHORT, tcp.PORT, mdb.FIELD, "time,port,status,private,authkey,count", + mdb.SHORT, tcp.PORT, mdb.FIELD, "time,port,status,private,authkey,count", mdb.FIELDS, "time,id,type,name,text", WELCOME, "welcome to contexts world\r\n", GOODBYE, "goodbye of contexts world\r\n", )), Hand: func(m *ice.Message, arg ...string) { - if len(arg) == 0 { // 服务列表 - mdb.HashSelect(m, arg...).PushAction(aaa.INVITE, mdb.INSERT, ctx.LOAD, ctx.SAVE) - return + m.Fields(len(arg), m.Config(mdb.FIELD), m.Config(mdb.FIELDS)) + if mdb.ZoneSelect(m, arg...); len(arg) == 0 { + m.PushAction(aaa.INVITE, mdb.INSERT, ctx.LOAD, ctx.SAVE) } - - // 公钥列表 - m.Fields(len(arg[1:]), "time,id,type,name,text") - mdb.ZoneSelect(m, arg...) }}, }) } diff --git a/misc/ssh/service_darwin.go b/misc/ssh/service_darwin.go index c40dd543..a18f9fb0 100644 --- a/misc/ssh/service_darwin.go +++ b/misc/ssh/service_darwin.go @@ -11,7 +11,6 @@ type Winsize struct{ Height, Width, x, y uint16 } func _ssh_size(fd uintptr, b []byte) { w := binary.BigEndian.Uint32(b) h := binary.BigEndian.Uint32(b[4:]) - ws := &Winsize{Width: uint16(w), Height: uint16(h)} syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TIOCSWINSZ), uintptr(unsafe.Pointer(ws))) } diff --git a/misc/ssh/session.go b/misc/ssh/session.go index ddef0dba..168c4ff4 100644 --- a/misc/ssh/session.go +++ b/misc/ssh/session.go @@ -20,9 +20,7 @@ func _ssh_session(m *ice.Message, client *ssh.Client) (*ssh.Session, error) { m.Assert(e) in, e := s.StdinPipe() m.Assert(e) - h := m.Cmdx(SESSION, mdb.CREATE, mdb.STATUS, tcp.OPEN, CONNECT, m.Option(mdb.NAME), kit.Dict(mdb.TARGET, in)) - m.Go(func() { buf := make([]byte, ice.MOD_BUFS) for { @@ -53,29 +51,23 @@ const SESSION = "session" func init() { psh.Index.MergeCommands(ice.Commands{ SESSION: {Name: "session hash id auto", Help: "会话", Actions: ice.MergeActions(ice.Actions{ - mdb.REPEAT: {Name: "repeat", Help: "执行", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy("", ctx.COMMAND, CMD, m.Option(mdb.TEXT)) - }}, + mdb.REPEAT: {Help: "执行", Hand: func(m *ice.Message, arg ...string) { m.Cmdy("", ctx.ACTION, ctx.COMMAND, CMD, m.Option(mdb.TEXT)) }}, ctx.COMMAND: {Name: "command cmd=pwd", Help: "命令", Hand: func(m *ice.Message, arg ...string) { - m.Cmd("", mdb.INSERT, m.OptionSimple(mdb.HASH), mdb.TYPE, CMD, mdb.TEXT, m.Option(CMD)) - w := mdb.HashSelectTarget(m, m.Option(mdb.HASH), nil).(io.Writer) - w.Write([]byte(m.Option(CMD) + ice.NL)) - m.Sleep300ms() + mdb.ZoneInsert(m, m.OptionSimple(mdb.HASH), mdb.TYPE, CMD, mdb.TEXT, m.Option(CMD)) + if w, ok := mdb.HashSelectTarget(m, m.Option(mdb.HASH), nil).(io.Writer); ok { + w.Write([]byte(m.Option(CMD) + ice.NL)) + m.Sleep300ms() + } }}, - }, mdb.ZoneAction(mdb.FIELD, "time,hash,count,status,connect")), Hand: func(m *ice.Message, arg ...string) { - if len(arg) == 0 { - mdb.HashSelect(m, arg...).Tables(func(value ice.Maps) { + }, mdb.PageZoneAction(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)), m.Config(mdb.FIELD), m.Config(mdb.FIELDS)) + if mdb.PageZoneSelect(m, arg...); len(arg) == 0 { + m.Tables(func(value ice.Maps) { m.PushButton(kit.Select("", ctx.COMMAND, value[mdb.STATUS] == tcp.OPEN), mdb.REMOVE) }) - return + } else { + m.Tables(func(value ice.Maps) { m.PushButton(kit.Select("", mdb.REPEAT, value[mdb.TYPE] == CMD)) }).Action(ctx.COMMAND, mdb.PAGE) } - - m.Action(ctx.COMMAND, mdb.PAGE) - mdb.OptionPage(m, kit.Slice(arg, 2)...) - m.Fields(len(kit.Slice(arg, 1, 2)), "time,id,type,text") - mdb.ZoneSelect(m, kit.Slice(arg, 0, 2)...).Tables(func(value ice.Maps) { - m.PushButton(kit.Select("", mdb.REPEAT, value[mdb.TYPE] == CMD)) - }) }}, }) } diff --git a/misc/tmux/buffer.go b/misc/tmux/buffer.go index 6fabdfdb..d02d63d9 100644 --- a/misc/tmux/buffer.go +++ b/misc/tmux/buffer.go @@ -4,6 +4,7 @@ import ( "strings" ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/cli" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" kit "shylinux.com/x/toolkits" @@ -14,55 +15,39 @@ const ( TEXT = "text" ) const ( - SET_BUFFER = "set-buffer" - SHOW_BUFFER = "show-buffer" - LIST_BUFFER = "list-buffers" + SET_BUFFER = "set-buffer" + SHOW_BUFFER = "show-buffer" + LIST_BUFFER = "list-buffers" + DELETE_BUFFER = "delete-buffer" ) func init() { Index.MergeCommands(ice.Commands{ BUFFER: {Name: "buffer name value auto", Help: "缓存", Actions: ice.Actions{ - mdb.MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) { - switch arg[0] { - case mdb.TEXT: - _tmux_cmd(m, SET_BUFFER, "-b", m.Option(mdb.NAME), arg[1]) - } + mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {}}, + mdb.CREATE: {Name: "create value*", Hand: func(m *ice.Message, arg ...string) { _tmux_cmd(m, SET_BUFFER, m.Option(mdb.VALUE)) }}, + mdb.REMOVE: {Hand: func(m *ice.Message, arg ...string) { _tmux_cmd(m, DELETE_BUFFER, "-b", m.Option(mdb.NAME)) }}, + mdb.MODIFY: {Hand: func(m *ice.Message, arg ...string) { + kit.If(arg[0] == mdb.VALUE, func() { _tmux_cmd(m, SET_BUFFER, "-b", m.Option(mdb.NAME), arg[1]) }) }}, }, Hand: func(m *ice.Message, arg ...string) { - if len(arg) > 1 && arg[1] != "" { // 设置缓存 - _tmux_cmd(m, SET_BUFFER, "-b", arg[0], arg[1]) - } - if len(arg) > 0 { // 查看缓存 - m.Echo(_tmux_cmd(m, SHOW_BUFFER, "-b", arg[0]).Result()) + if kit.If(len(arg) > 1 && arg[0] != "" && arg[1] != "", func() { _tmux_cmd(m, SET_BUFFER, "-b", arg[0], arg[1]) }); len(arg) > 0 && arg[0] != "" { + cli.PushText(m, _tmux_cmds(m, SHOW_BUFFER, "-b", arg[0])) return } - - // 缓存列表 - for i, v := range kit.Split(_tmux_cmd(m, LIST_BUFFER).Result(), ice.NL, ice.NL, ice.NL) { + for i, v := range kit.SplitLine(_tmux_cmd(m, LIST_BUFFER).Result()) { ls := strings.SplitN(v, ": ", 3) - m.Push(mdb.NAME, ls[0]) - m.Push(nfs.SIZE, ls[1]) - if i < 3 { - m.Push(mdb.TEXT, _tmux_cmd(m, SHOW_BUFFER, "-b", ls[0]).Result()) + if m.Push(mdb.NAME, ls[0]).Push(nfs.SIZE, ls[1]); i < 3 { + m.Push(mdb.VALUE, _tmux_cmd(m, SHOW_BUFFER, "-b", ls[0]).Result()) } else { - m.Push(mdb.TEXT, ls[2][1:len(ls[2])-1]) + m.Push(mdb.VALUE, ls[2][1:len(ls[2])-1]) } } + m.StatusTimeCount().PushAction(mdb.REMOVE).Action(mdb.CREATE) }}, - TEXT: {Name: "text auto save text:textarea", Help: "文本", Actions: ice.Actions{ - nfs.SAVE: {Name: "save", Help: "保存", Hand: func(m *ice.Message, arg ...string) { - if len(arg) > 0 && arg[0] != "" { - _tmux_cmd(m, SET_BUFFER, arg[0]) - } - m.Cmdy(TEXT) - }}, - }, Hand: func(m *ice.Message, arg ...string) { - text := _tmux_cmd(m, SHOW_BUFFER).Result() - if m.EchoQRCode(text).Echo(ice.NL); strings.HasPrefix(text, ice.HTTP) { - m.EchoAnchor(text) - } else { - m.EchoScript(text) - } + TEXT: {Name: "text auto text:textarea", Help: "文本", Hand: func(m *ice.Message, arg ...string) { + kit.If(len(arg) > 0, func() { _tmux_cmd(m, SET_BUFFER, arg[0]) }) + cli.PushText(m, _tmux_cmds(m, SHOW_BUFFER)) }}, }) } diff --git a/misc/tmux/script.go b/misc/tmux/script.go index 222c05fa..5c175697 100644 --- a/misc/tmux/script.go +++ b/misc/tmux/script.go @@ -10,7 +10,7 @@ const SCRIPT = "script" func init() { Index.MergeCommands(ice.Commands{ SCRIPT: {Name: "script name auto create export import", Help: "脚本", Actions: ice.MergeActions(ice.Actions{ - mdb.CREATE: {Name: "create type=shell,tmux,vim name=hi text:textarea=pwd", Help: "添加"}, + mdb.CREATE: {Name: "create type=shell,tmux,vim name=hi text:textarea=pwd"}, }, mdb.HashAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,type,name,text"))}, }) } diff --git a/misc/tmux/session.go b/misc/tmux/session.go index 2b2410cb..2b96e8a9 100644 --- a/misc/tmux/session.go +++ b/misc/tmux/session.go @@ -9,7 +9,6 @@ import ( "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/web" - "shylinux.com/x/icebergs/core/code" kit "shylinux.com/x/toolkits" ) @@ -24,12 +23,8 @@ func _tmux_key(arg ...string) string { return "miss" } } -func _tmux_cmd(m *ice.Message, arg ...string) *ice.Message { - return m.Cmd(cli.SYSTEM, TMUX, arg) -} -func _tmux_cmds(m *ice.Message, arg ...string) string { - return _tmux_cmd(m, arg...).Result() -} +func _tmux_cmd(m *ice.Message, arg ...string) *ice.Message { return m.Cmd(cli.SYSTEM, TMUX, arg) } +func _tmux_cmds(m *ice.Message, arg ...string) string { return _tmux_cmd(m, arg...).Results() } const ( FORMAT = "format" @@ -69,24 +64,22 @@ const ( func init() { Index.Merge(&ice.Context{Configs: ice.Configs{ - SESSION: {Name: SESSION, Help: "会话", Value: kit.Data( + SESSION: {Value: kit.Data( FORMAT, "#{session_id},#{session_attached},#{session_name},#{session_windows},#{session_height},#{session_width}", FIELDS, "id,tag,session,windows,height,width", )}, - WINDOW: {Name: WINDOW, Help: "窗口", Value: kit.Data( + WINDOW: {Value: kit.Data( FORMAT, "#{window_id},#{window_active},#{window_name},#{window_panes},#{window_height},#{window_width}", FIELDS, "id,tag,window,panes,height,width", )}, - PANE: {Name: PANE, Help: "终端", Value: kit.Data( + PANE: {Value: kit.Data( FORMAT, "#{pane_id},#{pane_active},#{pane_index},#{pane_tty},#{pane_height},#{pane_width},#{pane_current_command}", FIELDS, "id,tag,pane,tty,height,width,cmd", )}, }, Commands: ice.Commands{ - SESSION: {Name: "session session window pane cmd auto", Help: "会话管理", Actions: ice.Actions{ - web.DREAM_CREATE: {Name: "dream.create", Help: "梦想", Hand: func(m *ice.Message, arg ...string) { - if m.Cmd("", m.Option(mdb.NAME)).Length() == 0 { - m.Cmd("", mdb.CREATE) - } + SESSION: {Name: "session session window pane cmd auto", Help: "会话管理", Actions: ice.MergeActions(ice.Actions{ + web.DREAM_CREATE: {Hand: func(m *ice.Message, arg ...string) { + kit.If(m.Cmd("", m.Option(mdb.NAME)).Length() == 0, func() { m.Cmd("", mdb.CREATE) }) }}, mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) { if m.Option(ctx.ACTION) == SCRIPT { @@ -98,24 +91,18 @@ func init() { m.Cmdy(web.DREAM).Cut("name,size,time") } }}, - mdb.CREATE: {Name: "create name", Help: "添加", Hand: func(m *ice.Message, arg ...string) { - m.Option(cli.CMD_ENV, "TMUX", "") - if m.Option(PANE) != "" { // 创建终端 + mdb.CREATE: {Name: "create name", Hand: func(m *ice.Message, arg ...string) { + if m.Option(cli.CMD_ENV, "TMUX", ""); m.Option(PANE) != "" { _tmux_cmd(m, SPLIT_WINDOW, "-t", _tmux_key(m.Option(SESSION), m.Option(WINDOW), m.Option(PANE))) - - } else if m.Option(WINDOW) != "" { // 创建终端 + } else if m.Option(WINDOW) != "" { _tmux_cmd(m, SPLIT_WINDOW, "-t", _tmux_key(m.Option(SESSION), m.Option(WINDOW))) - - } else if m.Option(SESSION) != "" { // 创建窗口 + } else if m.Option(SESSION) != "" { _tmux_cmd(m, NEW_WINDOW, "-d", "-t", m.Option(SESSION), "-n", m.Option(mdb.NAME)) - - } else { // 创建会话 + } else { m.Option(cli.CMD_DIR, path.Join(ice.USR_LOCAL_WORK, m.Option(mdb.NAME))) - ls := kit.Split(m.Option(mdb.NAME), "-") name := kit.Select(ls[0], ls, 1) _tmux_cmd(m, NEW_SESSION, "-d", "-s", m.Option(mdb.NAME), "-n", name) - name = _tmux_key(m.Option(mdb.NAME), name) _tmux_cmd(m, SPLIT_WINDOW, "-t", kit.Keys(name, "1"), "-p", "40") m.Go(func() { @@ -123,103 +110,76 @@ func init() { _tmux_cmd(m, SEND_KEYS, "-t", kit.Keys(name, "2"), "ish_miss_log", ENTER) _tmux_cmd(m, SEND_KEYS, "-t", kit.Keys(name, "1"), "vi etc/miss.sh", ENTER) }) - - _tmux_cmd(m, LINK_WINDOW, "-s", name, "-t", "miss:") + if m.Cmd(PANE, _tmux_key("miss", name)).Length() == 0 { + _tmux_cmd(m, LINK_WINDOW, "-s", name, "-t", "miss:") + } } }}, - mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { - if m.Option(PANE) != "" { // 删除终端 - _tmux_cmd(m, KILL_PANE, "-t", _tmux_key(m.Option(SESSION), m.Option(WINDOW), m.Option(PANE))) - - } else if m.Option(WINDOW) != "" { // 删除窗口 - // _tmux_cmd(m, KILL_WINDOW, "-t", _tmux_key(m.Option(SESSION), m.Option(WINDOW))) - _tmux_cmd(m, KILL_WINDOW, "-t", _tmux_key(m.Option(SESSION), m.Option(mdb.ID))) - - } else if m.Option(SESSION) != "" { // 删除会话 + mdb.REMOVE: {Hand: func(m *ice.Message, arg ...string) { + if m.Option(PANE) != "" { + _tmux_cmd(m, KILL_PANE, "-t", kit.Select(_tmux_key(m.Option(SESSION), m.Option(WINDOW), m.Option(PANE)), m.Option(mdb.ID))) + } else if m.Option(WINDOW) != "" { + _tmux_cmd(m, KILL_WINDOW, "-t", kit.Select(_tmux_key(m.Option(SESSION), m.Option(WINDOW)), m.Option(mdb.ID))) + } else if m.Option(SESSION) != "" { _tmux_cmd(m, KILL_SESSION, "-t", m.Option(SESSION)) } }}, - mdb.MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) { + mdb.MODIFY: {Hand: func(m *ice.Message, arg ...string) { switch arg[0] { - case WINDOW: // 重命名窗口 + case WINDOW: _tmux_cmd(m, RENAME_WINDOW, "-t", _tmux_key(m.Option(SESSION), m.Option(WINDOW)), arg[1]) - - case SESSION: // 重命名会话 + case SESSION: _tmux_cmd(m, RENAME_SESSION, "-t", m.Option(SESSION), arg[1]) } }}, - mdb.SELECT: {Name: "select", Help: "进入", Hand: func(m *ice.Message, arg ...string) { - _tmux_cmd(m, SWITCH_CLIENT, "-t", m.Option(SESSION)) - if m.Option(WINDOW) != "" { // 切换窗口 - _tmux_cmd(m, SELECT_WINDOW, "-t", _tmux_key(m.Option(SESSION), m.Option(WINDOW))) + mdb.SELECT: {Help: "切入", Hand: func(m *ice.Message, arg ...string) { + if _tmux_cmd(m, SWITCH_CLIENT, "-t", m.Option(SESSION)); m.Option(WINDOW) != "" { + _tmux_cmd(m, SELECT_WINDOW, "-t", kit.Select(_tmux_key(m.Option(SESSION), m.Option(WINDOW)), m.Option(mdb.ID))) } - if m.Option(PANE) != "" { // 切换终端 + if m.Option(PANE) != "" { _tmux_cmd(m, SELECT_PANE, "-t", _tmux_key(m.Option(SESSION), m.Option(WINDOW), m.Option(PANE))) } }}, - - code.XTERM: {Name: "xterm", Help: "终端", Hand: func(m *ice.Message, arg ...string) { - ctx.Process(m, code.XTERM, []string{mdb.TYPE, "tmux attach -t " + m.Option(SESSION)}, arg...) - }}, SCRIPT: {Name: "script name", Help: "脚本", Hand: func(m *ice.Message, arg ...string) { m.Cmd(SCRIPT, m.Option(mdb.NAME), func(value ice.Maps) { - switch value[mdb.TYPE] { - case "shell": - for _, line := range kit.Split(value[mdb.TEXT], ice.NL, ice.NL, ice.NL) { - m.Cmd(CMD, _tmux_key(m.Option(SESSION), m.Option(WINDOW), m.Option(PANE)), line) - } - case "vim": - for _, line := range kit.Split(value[mdb.TEXT], ice.NL, ice.NL, ice.NL) { - m.Cmd(CMD, _tmux_key(m.Option(SESSION), m.Option(WINDOW), m.Option(PANE)), line) - } - case "tmux": - for _, line := range kit.Split(value[mdb.TEXT], ice.NL, ice.NL, ice.NL) { - _tmux_cmd(m, line) - } - } - }) - m.Sleep30ms() + kit.Fetch(kit.SplitLine(value[mdb.TEXT]), func(line string) { + kit.Switch(value[mdb.TYPE], + "shell", func() { m.Cmd(CMD, _tmux_key(m.Option(SESSION), m.Option(WINDOW), m.Option(PANE)), line) }, + "vim", func() { m.Cmd(CMD, _tmux_key(m.Option(SESSION), m.Option(WINDOW), m.Option(PANE)), line) }, + "tmux", func() { _tmux_cmd(m, line) }, + ) + }) + }).Sleep30ms() }}, - }, Hand: func(m *ice.Message, arg ...string) { - m.Action(SCRIPT) - if len(arg) > 3 { // 执行命令 + }, ctx.CmdAction()), Hand: func(m *ice.Message, arg ...string) { + if m.Action(SCRIPT); len(arg) > 3 { m.Cmd(CMD, _tmux_key(arg[0], arg[1], arg[2]), arg[3:]) } - if len(arg) > 2 { // 终端内容 + if len(arg) > 2 { m.Echo(strings.TrimSpace(m.Cmdx(VIEW, _tmux_key(arg[0], arg[1], arg[2])))) return } - - m.Action(mdb.CREATE) - if len(arg) > 1 { // 终端列表 + if m.Action(mdb.CREATE); len(arg) > 1 { m.Cmdy(PANE, _tmux_key(arg[0], arg[1])) - - } else if len(arg) > 0 { // 窗口列表 + } else if len(arg) > 0 { m.Cmdy(WINDOW, arg[0]) - - } else { // 会话列表 + } else { m.Split(_tmux_cmd(m, LIST_SESSION, "-F", m.Config(FORMAT)).Result(), m.Config(FIELDS), ice.FS, ice.NL) } - m.Tables(func(value ice.Maps) { - switch value["tag"] { - case "1": - m.PushButton(code.XTERM, "") - default: - m.PushButton(code.XTERM, mdb.SELECT, mdb.REMOVE) - } - }) + kit.If(value["tag"] == "1", func() { m.PushButton("") }, func() { m.PushButton(mdb.SELECT, mdb.REMOVE) }) + }).StatusTimeCount() }}, - WINDOW: {Name: "windows", Help: "窗口", Hand: func(m *ice.Message, arg ...string) { + WINDOW: {Hand: func(m *ice.Message, arg ...string) { m.Split(m.Cmdx(cli.SYSTEM, TMUX, LIST_WINDOWS, "-t", kit.Select("", arg, 0), "-F", m.Config(FORMAT)), m.Config(FIELDS), ice.FS, ice.NL) }}, - PANE: {Name: "panes", Help: "终端", Hand: func(m *ice.Message, arg ...string) { + PANE: {Hand: func(m *ice.Message, arg ...string) { m.Split(_tmux_cmds(m, LIST_PANES, "-t", kit.Select("", arg, 0), "-F", m.Config(FORMAT)), m.Config(FIELDS), ice.FS, ice.NL) }}, - VIEW: {Name: "view", Help: "内容", Hand: func(m *ice.Message, arg ...string) { + VIEW: {Hand: func(m *ice.Message, arg ...string) { m.Echo(_tmux_cmds(m, CAPTURE_PANE, "-p", "-t", kit.Select("", arg, 0))) }}, - CMD: {Name: "cmd", Help: "命令", Hand: func(m *ice.Message, arg ...string) { + CMD: {Hand: func(m *ice.Message, arg ...string) { _tmux_cmd(m, SEND_KEYS, "-t", arg[0], strings.Join(arg[1:], ice.SP), ENTER) }}, }}) diff --git a/misc/tmux/tmux.go b/misc/tmux/tmux.go index 5b7eb525..3f943625 100644 --- a/misc/tmux/tmux.go +++ b/misc/tmux/tmux.go @@ -13,14 +13,14 @@ const TMUX = "tmux" var Index = &ice.Context{Name: TMUX, Help: "工作台", Commands: ice.Commands{ TMUX: {Name: "tmux path auto start order build download", Help: "服务", Actions: ice.MergeActions(ice.Actions{ - cli.START: {Name: "start", Help: "启动", Hand: func(m *ice.Message, arg ...string) { + cli.START: {Help: "启动", Hand: func(m *ice.Message, arg ...string) { m.Optionv(code.PREPARE, func(p string) []string { return []string{"-S", kit.Path(m.Option(cli.CMD_DIR, p), "tmux.socket"), NEW_SESSION, "-d", "-n", "miss"} }) m.Cmdy(code.INSTALL, cli.START, m.Config(nfs.SOURCE), "bin/tmux") }}, }, code.InstallAction(nfs.SOURCE, "http://mirrors.tencent.com/macports/distfiles/tmux/tmux-3.2.tar.gz")), Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(code.INSTALL, nfs.SOURCE, m.Config(nfs.SOURCE), arg) + m.Cmdy(code.INSTALL, m.ConfigSimple(nfs.SOURCE), arg) }}, }} diff --git a/misc/webview/webview.go b/misc/webview/webview.go index 72d86d17..9f0b6a84 100644 --- a/misc/webview/webview.go +++ b/misc/webview/webview.go @@ -17,22 +17,18 @@ type WebView struct { } func (w WebView) Menu() bool { - list := []string{} - link := "" + link, list := "", []string{} w.Cmd(nfs.CAT, w.Source, func(ls []string, line string) { if strings.HasPrefix(line, "# ") { return - } - if len(ls) > 1 { - list = append(list, kit.Format(``, ls[0], ls[0])) + } else if len(ls) > 1 { + link, list = ls[1], append(list, kit.Format(``, ls[0], ls[0])) w.WebView.Bind(ls[0], func() { w.navigate(ls[1]) }) - link = ls[1] } }) if len(list) == 0 { return false - } - if len(list) == 1 { + } else if len(list) == 1 { if ls := kit.Split(w.Cmdx(nfs.CAT, "etc/webview.size")); len(ls) > 1 { w.WebView.SetSize(kit.Int(ls[0]), kit.Int(ls[1])+28, webview.HintNone) } else { @@ -40,11 +36,57 @@ func (w WebView) Menu() bool { } w.WebView.Navigate(link) return true + } else { + w.WebView.SetTitle(ice.CONTEXTS) + w.WebView.SetSize(200, 60*len(list), webview.HintNone) + w.WebView.Navigate(kit.Format(_menu_template, kit.Join(list, ice.NL))) + return true } +} +func (w WebView) Title(text string) { w.WebView.SetTitle(text) } +func (w WebView) Webview(url string) { w.WebView.Navigate(url) } +func (w WebView) Open(url string) { w.WebView.Navigate(url) } +func (w WebView) OpenUrl(url string) { w.Cmd(cli.SYSTEM, cli.OPEN, url) } +func (w WebView) OpenApp(app string) { w.Cmd(cli.SYSTEM, cli.OPEN, "-a", app) } +func (w WebView) OpenCmd(cmd string) { + w.Cmd(nfs.SAVE, kit.HomePath(".bash_temp"), cmd) + w.Cmd(cli.SYSTEM, cli.OPEN, "-a", "Terminal") +} +func (w WebView) SetSize(width, height int) { + w.Cmd(nfs.SAVE, "etc/webview.size", kit.Format("%v,%v", width, height)) +} +func (w WebView) System(arg ...string) string { return w.Cmdx(cli.SYSTEM, arg) } +func (w WebView) Power() string { + ls := strings.Split(w.Cmdx(cli.SYSTEM, "pmset", "-g", "ps"), ice.NL) + for _, line := range ls[1:] { + ls := kit.Split(line, "\t ;", "\t ;") + return ls[2] + } + return "" +} +func (w WebView) Close() { + if !w.Menu() { + w.WebView.Terminate() + } +} +func (w WebView) Terminate() { w.WebView.Terminate() } +func (w WebView) navigate(url string) { + w.WebView.SetSize(1200, 800, webview.HintNone) + w.WebView.Navigate(url) +} - w.WebView.SetTitle(ice.CONTEXTS) - w.WebView.SetSize(200, 60*len(list), webview.HintNone) - w.WebView.Navigate(kit.Format(`data:text/html, +func Run(cb func(*WebView) ice.Any) { + w := webview.New(true) + defer w.Destroy() + defer w.Run() + view := &WebView{Source: "etc/webview.txt", WebView: w, Message: ice.Pulse} + kit.Reflect(cb(view), func(name string, value ice.Any) { w.Bind(name, value) }) + if !view.Menu() { + view.navigate("http://localhost:9020") + } +} + +var _menu_template = `data:text/html,
@@ -60,52 +102,4 @@ func (w WebView) Menu() bool {
-