From e749472a9e61052fc6b2358038d951ffaf85e825 Mon Sep 17 00:00:00 2001 From: shaoying Date: Thu, 19 Mar 2020 15:51:37 +0800 Subject: [PATCH] opt render --- base/cli/cli.go | 6 ++- base/ssh/ssh.go | 43 +++++++++++---- base/web/web.go | 42 +++++++-------- conf.go | 20 +++++-- core/chat/chat.go | 2 +- core/code/code.go | 5 ++ go.sum | 2 - misc/lark/lark.go | 2 +- misc/tmux/auto.tmux | 2 +- misc/tmux/tmux.go | 74 +++++++++++--------------- misc/totp/totp.go | 18 +++---- misc/vim/vim.go | 2 +- misc/wx/wx.go | 4 +- misc/zsh/zsh.go | 4 +- type.go | 124 ++++++++++++++++++++++++-------------------- 15 files changed, 193 insertions(+), 157 deletions(-) diff --git a/base/cli/cli.go b/base/cli/cli.go index 30d7fe7f..65a267fd 100644 --- a/base/cli/cli.go +++ b/base/cli/cli.go @@ -19,8 +19,8 @@ var Index = &ice.Context{Name: "cli", Help: "命令模块", Configs: map[string]*ice.Config{ ice.CLI_RUNTIME: {Name: "runtime", Help: "运行环境", Value: kit.Dict()}, ice.CLI_SYSTEM: {Name: "system", Help: "系统命令", Value: kit.Data()}, - "python": {Name: "python", Help: "系统命令", Value: kit.Data("python", "python", "pip", "pip")}, "daemon": {Name: "daemon", Help: "守护进程", Value: kit.Data(kit.MDB_SHORT, "name")}, + "python": {Name: "python", Help: "系统命令", Value: kit.Data("python", "python", "pip", "pip")}, }, Commands: map[string]*ice.Command{ ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { @@ -145,6 +145,10 @@ var Index = &ice.Context{Name: "cli", Help: "命令模块", m.Cmdy(prefix, arg) } }}, + + "qrcode": {Name: "qrcode text", Help: "二", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Render(ice.RENDER_QRCODE, kit.Select("hello world", arg, 0)) + }}, }, } diff --git a/base/ssh/ssh.go b/base/ssh/ssh.go index e26f5162..53acb6b2 100644 --- a/base/ssh/ssh.go +++ b/base/ssh/ssh.go @@ -9,6 +9,7 @@ import ( "fmt" "io" "os" + "path" "strconv" "strings" "time" @@ -23,6 +24,35 @@ type Frame struct { exit bool } +func Render(msg *ice.Message, cmd string, args ...interface{}) { + msg.Log(ice.LOG_EXPORT, "%s: %v", cmd, args) + switch arg := kit.Simple(args...); cmd { + case ice.RENDER_OUTPUT: + + case ice.RENDER_DOWNLOAD: + os.Link(kit.Select(path.Base(arg[0]), arg, 2), arg[0]) + + case ice.RENDER_RESULT: + fmt.Fprintf(msg.O, msg.Result()) + + case ice.RENDER_QRCODE: + msg.Cmdy("cli.python", "qrcode", kit.Format(args[0], args[1:]...)) + fallthrough + default: + // 转换结果 + res := msg.Result() + if res == "" { + res = msg.Table().Result() + } + + // 输出结果 + if fmt.Fprintf(msg.O, res); !strings.HasSuffix(res, "\n") { + fmt.Fprintf(msg.O, "\n") + } + } + msg.Append(ice.MSG_OUTPUT, ice.RENDER_OUTPUT) +} + func (f *Frame) prompt(m *ice.Message) *Frame { if f.out == os.Stdout { for _, v := range kit.Simple(m.Optionv(ice.MSG_PROMPT)) { @@ -119,16 +149,10 @@ func (f *Frame) parse(m *ice.Message, line string) *Frame { // 执行命令 msg.Cmdy(ln[0], ln[1:]) - // 转换结果 - res := msg.Result() - if res == "" { - res = msg.Table().Result() - } + // 渲染引擎 + _args, _ := msg.Optionv(ice.MSG_ARGS).([]interface{}) + Render(msg, msg.Option(ice.MSG_OUTPUT), _args...) - // 输出结果 - if f.printf(msg, res); !strings.HasSuffix(res, "\n") { - f.printf(msg, "\n") - } } return f } @@ -162,6 +186,7 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool { m.Cap(ice.CTX_STREAM, arg[0]) } } + m.I, m.O = f.in, f.out line := "" bio := bufio.NewScanner(f.in) diff --git a/base/web/web.go b/base/web/web.go index a2dc207d..1be3b926 100644 --- a/base/web/web.go +++ b/base/web/web.go @@ -40,9 +40,10 @@ func Count(m *ice.Message, cmd, key, name string) int { m.Conf(cmd, kit.Keys(key, name), count+1) return count } -func Render(msg *ice.Message, cmd string, args ...interface{}) *ice.Message { +func Render(msg *ice.Message, cmd string, args ...interface{}) { msg.Log(ice.LOG_EXPORT, "%s: %v", cmd, args) switch arg := kit.Simple(args...); cmd { + case ice.RENDER_OUTPUT: case "redirect": http.Redirect(msg.W, msg.R, kit.MergeURL(arg[0], arg[1:]), 307) @@ -56,27 +57,32 @@ func Render(msg *ice.Message, cmd string, args ...interface{}) *ice.Message { msg.W.WriteHeader(kit.Int(kit.Select("200", arg, 0))) msg.W.Write([]byte(kit.Select("", arg, 1))) - case "result": - msg.W.Write([]byte(kit.Format(arg[0], args[1:]...))) - case "cookie": expire := time.Now().Add(kit.Duration(msg.Conf(ice.AAA_SESS, "meta.expire"))) http.SetCookie(msg.W, &http.Cookie{Value: arg[0], Name: kit.Select(ice.MSG_SESSID, arg, 1), Path: "/", Expires: expire}) - case "qrcode": + case ice.RENDER_DOWNLOAD: + msg.W.Header().Set("Content-Disposition", fmt.Sprintf("filename=%s", kit.Select(path.Base(arg[0]), arg, 2))) + msg.W.Header().Set("Content-Type", kit.Select("text/html", arg, 1)) + http.ServeFile(msg.W, msg.R, arg[0]) + + case ice.RENDER_RESULT: + if len(arg) > 0 { + msg.W.Write([]byte(kit.Format(arg[0], args[1:]...))) + } else { + msg.W.Write([]byte(msg.Result())) + } + + case ice.RENDER_QRCODE: if qr, e := qrcode.New(arg[0], qrcode.Medium); msg.Assert(e) { msg.W.Header().Set("Content-Type", "image/png") msg.Assert(qr.Write(256, msg.W)) } - case "download": - msg.W.Header().Set("Content-Disposition", fmt.Sprintf("filename=%s", kit.Select(path.Base(arg[0]), arg, 2))) - msg.W.Header().Set("Content-Type", kit.Select("text/html", arg, 1)) - http.ServeFile(msg.W, msg.R, arg[0]) default: - msg.W.Write([]byte(kit.Format(cmd, args...))) + msg.W.Header().Set("Content-Type", "application/json") + fmt.Fprint(msg.W, msg.Formats("meta")) } - msg.Append("_output", "render") - return msg + msg.Append(ice.MSG_OUTPUT, ice.RENDER_OUTPUT) } func IsLocalIP(msg *ice.Message, ip string) (ok bool) { if ip == "::1" || strings.HasPrefix(ip, "127.") { @@ -301,14 +307,8 @@ func (web *Frame) HandleCmd(m *ice.Message, key string, cmd *ice.Command) { msg.Target().Run(msg, cmd, msg.Option(ice.MSG_USERURL), cmds...) // 渲染引擎 - switch msg.Append("_output") { - case "render": - case "result": - fmt.Fprint(w, msg.Result()) - default: - w.Header().Set("Content-Type", "application/json") - fmt.Fprint(w, msg.Formats("meta")) - } + _args, _ := msg.Optionv(ice.MSG_ARGS).([]interface{}) + Render(msg, msg.Option(ice.MSG_OUTPUT), _args...) }) }) } @@ -1778,7 +1778,7 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", m.Option("name", value["name"]) m.Option("text", value["text"]) m.Render(m.Conf(ice.WEB_SHARE, "meta.template.simple")) - m.Append("_output", "result") + m.Option(ice.MSG_OUTPUT, ice.RENDER_RESULT) } }) }}, diff --git a/conf.go b/conf.go index ae6c3dbc..612701f9 100644 --- a/conf.go +++ b/conf.go @@ -20,8 +20,10 @@ const ( // MSG MSG_SOURCE = "_source" MSG_TARGET = "_target" - MSG_ACTION = "_action" MSG_HANDLE = "_handle" + MSG_ACTION = "_action" + MSG_OUTPUT = "_output" + MSG_ARGS = "_args" MSG_STDOUT = "_stdout" MSG_PROMPT = "_prompt" @@ -37,6 +39,7 @@ const ( // MSG MSG_RIVER = "sess.river" MSG_STORM = "sess.storm" ) + const ( // CTX CTX_STATUS = "status" CTX_STREAM = "stream" @@ -163,10 +166,6 @@ const ( // ROLE ROLE_TECH = "tech" ROLE_VOID = "void" ) -const ( // CHAT - CHAT_RIVER = "river" - CHAT_STORM = "storm" -) const ( // TYPE TYPE_SPIDE = "spide" TYPE_SPACE = "space" @@ -184,6 +183,10 @@ const ( // TYPE TYPE_INNER = "inner" TYPE_MEDIA = "media" ) +const ( // CHAT + CHAT_RIVER = "river" + CHAT_STORM = "storm" +) const ( // FAVOR FAVOR_CHAT = "chat.init" FAVOR_TMUX = "tmux.init" @@ -205,6 +208,13 @@ const ( // STORY STORY_UPLOAD = "upload" STORY_DOWNLOAD = "download" ) +const ( // RENDER + RENDER_OUTPUT = "_output" + RENDER_TEMPLATE = "_template" + RENDER_DOWNLOAD = "_download" + RENDER_RESULT = "_result" + RENDER_QRCODE = "_qrcode" +) var Alias = map[string]string{ CTX_CONTEXT: "ctx.context", diff --git a/core/chat/chat.go b/core/chat/chat.go index 056508ee..b29b4d81 100644 --- a/core/chat/chat.go +++ b/core/chat/chat.go @@ -153,7 +153,7 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心", case "login": // 密码登录 if len(arg) > 2 { - m.Option(ice.MSG_SESSID, web.Render(m, "cookie", m.Cmdx(ice.AAA_USER, "login", m.Option(ice.MSG_USERNAME, arg[1]), arg[2]))) + web.Render(m, "cookie", m.Option(ice.MSG_SESSID, m.Cmdx(ice.AAA_USER, "login", m.Option(ice.MSG_USERNAME, arg[1]), arg[2]))) } default: diff --git a/core/code/code.go b/core/code/code.go index f96e94b8..483d754f 100644 --- a/core/code/code.go +++ b/core/code/code.go @@ -102,6 +102,11 @@ var Index = &ice.Context{Name: "code", Help: "编程中心", }) case "prune": + if len(arg) > 1 && arg[1] == "all" { + m.Conf("login", "hash", "") + break + } + list := []string{} m.Richs("login", nil, "*", func(key string, value map[string]interface{}) { if len(arg) > 1 && arg[1] == "all" || value["status"] == "logout" { diff --git a/go.sum b/go.sum index 2ab98fcf..d45f1445 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,6 @@ github.com/gomarkdown/markdown v0.0.0-20200127000047-1813ea067497 h1:wJkj+x9gPYl github.com/gomarkdown/markdown v0.0.0-20200127000047-1813ea067497/go.mod h1:aii0r/K0ZnHv7G0KF7xy1v0A7s2Ljrb5byB7MO5p6TU= github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/shylinux/toolkits v0.1.2 h1:yP24DXfcU5c7u3NVAxCGiMy5UMBRQH4gkKUZXOIN5fk= -github.com/shylinux/toolkits v0.1.2/go.mod h1:Y68Ot6xOmo1bun67YvqC3chDGeU2gDxtsUnvVDGJm4g= github.com/shylinux/toolkits v0.1.3 h1:bqxmbPFBKkOpv9uEb4bbeeovowsiBK7zDrPrQMUDlSc= github.com/shylinux/toolkits v0.1.3/go.mod h1:Y68Ot6xOmo1bun67YvqC3chDGeU2gDxtsUnvVDGJm4g= github.com/skip2/go-qrcode v0.0.0-20191027152451-9434209cb086 h1:RYiqpb2ii2Z6J4x0wxK46kvPBbFuZcdhS+CIztmYgZs= diff --git a/misc/lark/lark.go b/misc/lark/lark.go index baf62486..0da67ace 100644 --- a/misc/lark/lark.go +++ b/misc/lark/lark.go @@ -276,7 +276,7 @@ var Index = &ice.Context{Name: "lark", Help: "机器人", switch parse(m); m.Option("msg.type") { case "url_verification": // 绑定验证 - m.Append("_output", "result") + m.Option(ice.MSG_OUTPUT, ice.RENDER_RESULT) m.Echo(kit.Format(map[string]interface{}{"challenge": m.Option("msg.challenge")})) case "event_callback": diff --git a/misc/tmux/auto.tmux b/misc/tmux/auto.tmux index 661b788e..0c2df0bb 100644 --- a/misc/tmux/auto.tmux +++ b/misc/tmux/auto.tmux @@ -1 +1 @@ -bind C-F command-prompt -p "send favor:" -I "tmux.auto" 'run-shell -b "curl $ctx_dev/code/tmux/favor?cmds=%%"' +bind C-F command-prompt -p "send favor:" -I "tmux.auto" 'run-shell -b "curl $ctx_dev/code/tmux/favor?cmds=`echo %%|sed \"s/ /%20/g\"`"' diff --git a/misc/tmux/tmux.go b/misc/tmux/tmux.go index adc00636..b095bc78 100644 --- a/misc/tmux/tmux.go +++ b/misc/tmux/tmux.go @@ -15,8 +15,9 @@ import ( var Index = &ice.Context{Name: "tmux", Help: "工作台", Caches: map[string]*ice.Cache{}, Configs: map[string]*ice.Config{ - "prefix": {Name: "buffer", Help: "缓存", Value: kit.Data("cmd", []interface{}{ice.CLI_SYSTEM, "tmux"})}, + "prefix": {Name: "prefix", Help: "前缀", Value: kit.Data("cmd", []interface{}{ice.CLI_SYSTEM, "tmux"})}, "buffer": {Name: "buffer", Help: "缓存", Value: kit.Data()}, + "session": {Name: "session", Help: "会话", Value: kit.Data( "format", "#{session_id},#{session_attached},#{session_name},#{session_windows},#{session_height},#{session_width}", "fields", "id,tag,session,windows,height,width", @@ -29,11 +30,10 @@ var Index = &ice.Context{Name: "tmux", Help: "工作台", "format", "#{pane_id},#{pane_active},#{pane_index},#{pane_tty},#{pane_height},#{pane_width}", "fields", "id,tag,pane,tty,height,width", )}, - "view": {Name: "pane", Help: "终端", Value: kit.Data( - "format", "#{pane_id},#{pane_active},#{pane_index},#{pane_tty},#{pane_height},#{pane_width}", - "fields", "id,tag,pane,tty,height,width", - )}, - "relay": {Name: "relay", Help: "跳板", Value: kit.Data(kit.MDB_SHORT, kit.MDB_NAME, + "view": {Name: "pane", Help: "终端", Value: kit.Data()}, + + "local": {Name: "local", Help: "虚拟机", Value: kit.Data(kit.MDB_SHORT, kit.MDB_NAME)}, + "relay": {Name: "relay", Help: "跳板机", Value: kit.Data(kit.MDB_SHORT, kit.MDB_NAME, "count", 100, "sleep", "100ms", "tail", kit.Dict( "verify", "Verification code:", "password", "Password:", @@ -99,7 +99,7 @@ var Index = &ice.Context{Name: "tmux", Help: "工作台", m.Cmd(ice.WEB_FAVOR, kit.Select("tmux.auto", arg, 1)).Table(func(index int, value map[string]string, head []string) { switch value["type"] { - case "shell": + case ice.TYPE_SHELL: // 发送命令 m.Cmdy(prefix, "send-keys", "-t", arg[0], value["text"], "Enter") time.Sleep(10 * time.Millisecond) @@ -112,7 +112,7 @@ var Index = &ice.Context{Name: "tmux", Help: "工作台", } }}, - "text": {Name: "text", Help: "文本", List: kit.List( + "text": {Name: "text", Help: "文本", Meta: kit.Dict("remote", "pod"), List: kit.List( kit.MDB_INPUT, "text", "name", "name", kit.MDB_INPUT, "button", "value", "保存", kit.MDB_INPUT, "textarea", "name", "text", @@ -121,11 +121,9 @@ var Index = &ice.Context{Name: "tmux", Help: "工作台", if len(arg) > 1 && arg[1] != "" { m.Cmd(prefix, "set-buffer", arg[1]) } - m.Cmdy(prefix, "show-buffer").Set("append") + m.Cmdy(prefix, "show-buffer").Set(ice.MSG_APPEND) }}, - "buffer": {Name: "buffer", Help: "缓存", Meta: kit.Dict( - "remote", "pod", - ), List: kit.List( + "buffer": {Name: "buffer", Help: "缓存", Meta: kit.Dict("remote", "pod"), List: kit.List( kit.MDB_INPUT, "text", "name", "buffer", "action", "auto", kit.MDB_INPUT, "text", "name", "value", kit.MDB_INPUT, "button", "value", "查看", "action", "auto", @@ -139,7 +137,7 @@ var Index = &ice.Context{Name: "tmux", Help: "工作台", if len(arg) > 0 { // 查看缓存 - m.Cmdy(prefix, "show-buffer", "-b", arg[0]).Set("append") + m.Cmdy(prefix, "show-buffer", "-b", arg[0]).Set(ice.MSG_APPEND) return } @@ -155,7 +153,7 @@ var Index = &ice.Context{Name: "tmux", Help: "工作台", } } }}, - "session": {Name: "session", Help: "会话", Meta: kit.Dict("detail", []string{"选择", "运行", "编辑", "删除", "下载"}), List: kit.List( + "session": {Name: "session [session [window [pane [cmd]]]]", Help: "会话", Meta: kit.Dict("detail", []string{"选择", "编辑", "删除", "下载"}), List: kit.List( kit.MDB_INPUT, "text", "name", "session", "action", "auto", kit.MDB_INPUT, "text", "name", "window", "action", "auto", kit.MDB_INPUT, "text", "name", "pane", "action", "auto", @@ -166,68 +164,51 @@ var Index = &ice.Context{Name: "tmux", Help: "工作台", if len(arg) > 1 && arg[0] == "action" { switch arg[1] { - case "运行": - target := "" - switch arg[2] { - case "session": - target = arg[3] - } - m.Cmd("auto", target, m.Option("hot")) - arg = arg[:0] - - case "select": + case "select", "选择": if arg[2] == "session" { // 选择会话 m.Cmd(prefix, "switch-client", "-t", arg[3]) - arg = arg[:0] break } if m.Cmd(prefix, "switch-client", "-t", m.Option("session")); arg[2] == "window" { // 选择窗口 m.Cmd(prefix, "select-window", "-t", m.Option("session")+":"+arg[3]) - arg = []string{m.Option("session")} break } if m.Cmd(prefix, "select-window", "-t", m.Option("session")+":"+m.Option("window")); arg[2] == "pane" { // 选择终端 m.Cmd(prefix, "select-pane", "-t", m.Option("session")+":"+m.Option("window")+"."+arg[3]) - arg = []string{m.Option("session"), m.Option("window")} } - case "modify": + case "modify", "编辑": switch arg[2] { case "session": // 重命名会话 m.Cmd(prefix, "rename-session", "-t", arg[4], arg[3]) - arg = arg[:0] case "window": // 重命名窗口 m.Cmd(prefix, "rename-window", "-t", m.Option("session")+":"+arg[4], arg[3]) - arg = []string{m.Option("session")} } - case "delete": + case "delete", "删除": switch arg[2] { case "session": // 删除会话 m.Cmd(prefix, "kill-session", "-t", arg[3]) - arg = arg[:0] case "window": // 删除窗口 m.Cmd(prefix, "kill-window", "-t", m.Option("session")+":"+arg[3]) - arg = []string{m.Option("session")} case "pane": // 删除终端 m.Cmd(prefix, "kill-pane", "-t", m.Option("session")+":"+m.Option("window")+"."+arg[3]) - arg = []string{m.Option("session"), m.Option("window")} } } + return } if len(arg) == 0 { // 会话列表 - m.Split(m.Cmdx(prefix, "list-session", - "-F", m.Conf(cmd, "meta.format")), m.Conf(cmd, "meta.fields"), ",", "\n") + m.Split(m.Cmdx(prefix, "list-session", "-F", m.Conf(cmd, "meta.format")), m.Conf(cmd, "meta.fields"), ",", "\n") return } @@ -237,8 +218,7 @@ var Index = &ice.Context{Name: "tmux", Help: "工作台", m.Option("cmd_env", "TMUX", "") m.Option("cmd_dir", m.Conf(ice.WEB_DREAM, "meta.path")) m.Cmd(prefix, "new-session", "-ds", arg[0]) - m.Cmd("auto", arg[0], arg[1:]) - arg = arg[:1] + m.Cmd("auto", arg[0]) } if len(arg) == 1 { @@ -280,15 +260,15 @@ var Index = &ice.Context{Name: "tmux", Help: "工作台", }}, "view": {Name: "view", Help: "终端", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { prefix := kit.Simple(m.Confv("prefix", "meta.cmd")) - m.Cmdy(prefix, "capture-pane", "-pt", kit.Select("", arg, 0)).Set("append") + m.Cmdy(prefix, "capture-pane", "-pt", kit.Select("", arg, 0)).Set(ice.MSG_APPEND) }}, - "local": {Name: "local which target", Help: "虚拟机", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + "local": {Name: "local name name", Help: "虚拟机", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { prefix := kit.Simple(m.Confv("prefix", "meta.cmd")) m.Cmd("web.code.docker.auto", arg[1]) m.Cmdy(prefix, "send-keys", "-t", arg[1], "docker exec -it ", arg[1], " bash", "Enter") }}, - "relay": {Name: "relay which target", Help: "跳板机", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + "relay": {Name: "relay [name [favor]]", Help: "跳板机", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { prefix := kit.Simple(m.Confv("prefix", "meta.cmd")) if len(arg) == 0 { // 认证列表 @@ -304,10 +284,10 @@ var Index = &ice.Context{Name: "tmux", Help: "工作台", }) return } + if len(arg) > 4 { // 添加认证 - m.Rich(cmd, nil, kit.Dict( - kit.MDB_NAME, arg[0], kit.MDB_TEXT, arg[1], + m.Rich(cmd, nil, kit.Dict(kit.MDB_NAME, arg[0], kit.MDB_TEXT, arg[1], "username", arg[2], "website", arg[3], "password", arg[4], )) return @@ -335,18 +315,22 @@ var Index = &ice.Context{Name: "tmux", Help: "工作台", } }) }}, + "/favor": {Name: "/favor", Help: "收藏", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { current := "" m.Cmd("session").Table(func(index int, value map[string]string, head []string) { if value["tag"] == "1" { - // 当前会话 current = value["session"] } }) + m.Option(ice.MSG_OUTPUT, ice.RENDER_RESULT) switch arg = kit.Split(kit.Select("tmux.auto", arg, 0)); arg[0] { + case "ice": + if m.Cmdy(arg[1:]); len(m.Resultv()) == 0 { + m.Table() + } default: - m.Append("_output", "result") m.Cmd("auto", current, arg) } }}, diff --git a/misc/totp/totp.go b/misc/totp/totp.go index 8f450f63..173dd920 100644 --- a/misc/totp/totp.go +++ b/misc/totp/totp.go @@ -43,15 +43,11 @@ func get(key string) string { var Index = &ice.Context{Name: "totp", Help: "动态码", Caches: map[string]*ice.Cache{}, Configs: map[string]*ice.Config{ - "totp": {Name: "totp", Help: "动态码", Value: kit.Data(kit.MDB_SHORT, "name")}, + "totp": {Name: "totp", Help: "动态码", Value: kit.Data(kit.MDB_SHORT, "name", "share", "otpauth://totp/%s?secret=%s")}, }, Commands: map[string]*ice.Command{ - ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Load() - }}, - ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Save("totp") - }}, + ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}}, + ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}}, "new": {Name: "new user [secret]", Help: "创建密钥", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if len(arg) == 0 { @@ -64,7 +60,11 @@ var Index = &ice.Context{Name: "totp", Help: "动态码", if m.Richs("totp", nil, arg[0], func(key string, value map[string]interface{}) { // 密钥详情 - m.Push("detail", value) + if len(arg) > 1 { + m.Render(ice.RENDER_QRCODE, kit.Format(m.Conf("totp", "meta.share"), value["name"], value["text"])) + } else { + m.Push("detail", value) + } }) != nil { return } @@ -80,7 +80,7 @@ var Index = &ice.Context{Name: "totp", Help: "动态码", ))) // 创建共享 - defer m.Cmdy(ice.WEB_SHARE, "optauth", arg[0], kit.Format("otpauth://totp/%s?secret=%s", arg[0], arg[1])) + defer m.Cmdy(ice.WEB_SHARE, "optauth", arg[0], kit.Format(m.Conf("totp", "meta.share"), arg[0], arg[1])) }}, "get": {Name: "get user [secret]", Help: "获取密码", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if len(arg) == 0 { diff --git a/misc/vim/vim.go b/misc/vim/vim.go index b8dee27e..9d7bf14f 100644 --- a/misc/vim/vim.go +++ b/misc/vim/vim.go @@ -32,7 +32,7 @@ var Index = &ice.Context{Name: "vim", Help: "编辑器", }) m.Info("%s %s cmd: %v sub: %v", m.Option("you"), m.Option(ice.MSG_USERURL), m.Optionv("cmds"), m.Optionv("sub")) - m.Append("_output", "result") + m.Option(ice.MSG_OUTPUT, ice.RENDER_RESULT) }}, "/help": {Name: "/help", Help: "帮助", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Cmdy("help") diff --git a/misc/wx/wx.go b/misc/wx/wx.go index b8c84bb4..6edfe7f1 100644 --- a/misc/wx/wx.go +++ b/misc/wx/wx.go @@ -32,11 +32,11 @@ func parse(m *ice.Message) { } func reply(m *ice.Message) { - m.Append("_output", "result") + m.Option(ice.MSG_OUTPUT, ice.RENDER_RESULT) m.Render(m.Conf("login", "meta.template.text")) } func action(m *ice.Message) { - m.Append("_output", "result") + m.Option(ice.MSG_OUTPUT, ice.RENDER_RESULT) m.Echo(` diff --git a/misc/zsh/zsh.go b/misc/zsh/zsh.go index 18dde773..df1eb91c 100644 --- a/misc/zsh/zsh.go +++ b/misc/zsh/zsh.go @@ -33,7 +33,7 @@ var Index = &ice.Context{Name: "zsh", Help: "命令行", }) m.Info("%s %s cmd: %v sub: %v", m.Option("you"), m.Option(ice.MSG_USERURL), m.Optionv("cmds"), m.Optionv("sub")) - m.Append("_output", "result") + m.Option(ice.MSG_OUTPUT, ice.RENDER_RESULT) }}, "/help": {Name: "/help", Help: "帮助", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { @@ -197,7 +197,7 @@ var Index = &ice.Context{Name: "zsh", Help: "命令行", } // 下载文件 - web.Render(m, "download", kit.Select("file", "result", m.Append("file") == "")) + m.Render(kit.Select(ice.RENDER_DOWNLOAD, ice.RENDER_RESULT, m.Append("file") == ""), m.Append("text")) }}, "/upload": {Name: "/upload", Help: "上传", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { // 缓存文件 diff --git a/type.go b/type.go index 34883838..9926451e 100644 --- a/type.go +++ b/type.go @@ -179,10 +179,13 @@ type Message struct { source *Context target *Context + frames interface{} cb func(*Message) *Message W http.ResponseWriter R *http.Request + O io.Writer + I io.Reader wait chan bool } @@ -317,19 +320,18 @@ func (m *Message) Spawns(arg ...interface{}) *Message { } func (m *Message) Spawn(arg ...interface{}) *Message { msg := &Message{ - time: time.Now(), - code: -1, + code: -1, time: time.Now(), meta: map[string][]string{}, data: map[string]interface{}{}, - message: m, - root: m.root, + message: m, root: m.root, source: m.target, target: m.target, - R: m.R, - W: m.W, + + W: m.W, R: m.R, + O: m.O, I: m.I, } if len(arg) > 0 { @@ -451,7 +453,11 @@ func (m *Message) Copy(msg *Message, arg ...string) *Message { if kit.IndexOf(m.meta[MSG_OPTION], k) == -1 { m.meta[MSG_OPTION] = append(m.meta[MSG_OPTION], k) } - m.meta[k] = append(m.meta[k], msg.meta[k]...) + if _, ok := msg.meta[k]; ok { + m.meta[k] = msg.meta[k] + } else { + m.data[k] = msg.data[k] + } } // 复制数据 @@ -619,16 +625,20 @@ func (m *Message) Table(cbs ...interface{}) *Message { } return m } -func (m *Message) Render(str string, arg ...interface{}) *Message { - if len(arg) == 0 { - arg = append(arg, m) +func (m *Message) Render(cmd string, args ...interface{}) *Message { + m.Log(LOG_EXPORT, "%s: %v", cmd, args) + m.Optionv(MSG_OUTPUT, cmd) + m.Optionv(MSG_ARGS, args) + + switch cmd { + case RENDER_TEMPLATE: + if len(args) == 0 { + args = append(args, m) + } + if res, err := kit.Render(cmd, args[0]); m.Assert(err) { + m.Echo(string(res)) + } } - if res, err := kit.Render(str, arg[0]); m.Assert(err) { - m.Echo(string(res)) - } - return m -} -func (m *Message) Qrcode(str string, arg ...interface{}) *Message { return m } func (m *Message) Parse(meta string, key string, arg ...string) *Message { @@ -948,15 +958,15 @@ func (m *Message) Starts(name string, help string, arg ...string) *Message { return m } +func (m *Message) Right(arg ...interface{}) bool { + return m.Option(MSG_USERROLE) == ROLE_ROOT || !m.Warn(m.Cmdx(AAA_ROLE, "right", m.Option(MSG_USERROLE), kit.Keys(arg...)) != "ok", "no right") +} func (m *Message) Space(arg interface{}) []string { if arg == nil || kit.Format(arg) == m.Conf(CLI_RUNTIME, "node.name") { return nil } return []string{WEB_SPACE, kit.Format(arg)} } -func (m *Message) Right(arg ...interface{}) bool { - return m.Option(MSG_USERROLE) == ROLE_ROOT || !m.Warn(m.Cmdx(AAA_ROLE, "right", m.Option(MSG_USERROLE), kit.Keys(arg...)) != "ok", "no right") -} func (m *Message) Event(key string, arg ...string) *Message { m.Cmd(GDB_EVENT, "action", key, arg) return m @@ -966,44 +976,6 @@ func (m *Message) Watch(key string, arg ...string) *Message { return m } -func (m *Message) Preview(arg string) (res string) { - list := kit.Split(arg) - m.Search(list[0], func(p *Context, s *Context, key string, cmd *Command) { - res = kit.Format(kit.Dict("feature", cmd.Meta, "inputs", cmd.List)) - }) - return res -} -func (m *Message) Prefile(favor string, id string) map[string]string { - res := map[string]string{} - m.Option("render", "") - m.Option("_action", "") - m.Cmd(WEB_FAVOR, kit.Select(m.Option("favor"), favor), id).Table(func(index int, value map[string]string, head []string) { - res[value["key"]] = value["value"] - }) - - res["content"] = m.Cmdx(CLI_SYSTEM, "sed", "-n", kit.Format("%d,%dp", kit.Int(res["extra.row"]), kit.Int(res["extra.row"])+3), res["extra.buf"]) - return res -} -func (m *Message) Prefix(arg ...string) string { - return kit.Keys(m.Cap(CTX_FOLLOW), arg) -} -func (m *Message) Save(arg ...string) *Message { - list := []string{} - for _, k := range arg { - list = append(list, kit.Keys(m.Cap(CTX_FOLLOW), k)) - } - m.Cmd(CTX_CONFIG, "save", kit.Keys(m.Cap(CTX_FOLLOW), "json"), list) - return m -} -func (m *Message) Load(arg ...string) *Message { - list := []string{} - for _, k := range arg { - list = append(list, kit.Keys(m.Cap(CTX_FOLLOW), k)) - } - m.Cmd(CTX_CONFIG, "load", kit.Keys(m.Cap(CTX_FOLLOW), "json"), list) - return m -} - func (m *Message) Travel(cb interface{}) *Message { list := []*Context{m.target} for i := 0; i < len(list); i++ { @@ -1117,6 +1089,44 @@ func (m *Message) Search(key interface{}, cb interface{}) *Message { } return m } +func (m *Message) Preview(arg string) (res string) { + list := kit.Split(arg) + m.Search(list[0], func(p *Context, s *Context, key string, cmd *Command) { + res = kit.Format(kit.Dict("feature", cmd.Meta, "inputs", cmd.List)) + }) + return res +} + +func (m *Message) Prefile(favor string, id string) map[string]string { + res := map[string]string{} + m.Option("render", "") + m.Option("_action", "") + m.Cmd(WEB_FAVOR, kit.Select(m.Option("favor"), favor), id).Table(func(index int, value map[string]string, head []string) { + res[value["key"]] = value["value"] + }) + + res["content"] = m.Cmdx(CLI_SYSTEM, "sed", "-n", kit.Format("%d,%dp", kit.Int(res["extra.row"]), kit.Int(res["extra.row"])+3), res["extra.buf"]) + return res +} +func (m *Message) Prefix(arg ...string) string { + return kit.Keys(m.Cap(CTX_FOLLOW), arg) +} +func (m *Message) Save(arg ...string) *Message { + list := []string{} + for _, k := range arg { + list = append(list, kit.Keys(m.Cap(CTX_FOLLOW), k)) + } + m.Cmd(CTX_CONFIG, "save", kit.Keys(m.Cap(CTX_FOLLOW), "json"), list) + return m +} +func (m *Message) Load(arg ...string) *Message { + list := []string{} + for _, k := range arg { + list = append(list, kit.Keys(m.Cap(CTX_FOLLOW), k)) + } + m.Cmd(CTX_CONFIG, "load", kit.Keys(m.Cap(CTX_FOLLOW), "json"), list) + return m +} func (m *Message) Richs(key string, chain interface{}, raw interface{}, cb interface{}) (res map[string]interface{}) { // 数据结构