diff --git a/etc/conf/auto.sh b/etc/conf/auto.sh index 2466c3fc..c724cd13 100644 --- a/etc/conf/auto.sh +++ b/etc/conf/auto.sh @@ -101,16 +101,18 @@ ShyLogout() { } ShyLogin() { HOST=`hostname` ctx_sid=`ShyPost cmd login share "${ctx_share}" pid "$$" pane "${TMUX_PANE}" hostname "${HOST}" username "${USER}"` - echo "sid: ${ctx_sid:0:6}" + [ "$ctx_begin" = "" ] && ctx_begin=`history|tail -n1|awk '{print $1}'` && echo "begin: ${ctx_begin}" + echo "sid: ${ctx_sid}" } ShyFavor() { [ "$READLINE_LINE" != "" ] && set $READLINE_LINE && READLINE_LINE="" - [ "$1" != "" ] && ctx_tab=$1; [ "$2" != "" ] && ctx_note=$2 - ShyPost cmd favor arg "`history|tail -n1|head -n1`" tab "${ctx_tab}" note "${ctx_note}" + [ "$1" != "" ] && ctx_tab=$1 && shift; [ "$1" != "" ] && ctx_note=$1 && shift + [ "$1" != "" ] && ctx_word=$1 || ctx_word=`history|tail -n1|head -n1` + ShyPost cmd favor arg "${ctx_word}" tab "${ctx_tab}" note "${ctx_note}" } ShyFavors() { [ "$READLINE_LINE" != "" ] && set $READLINE_LINE && READLINE_LINE="" - ShyPost cmd favor tab "$1" + ShyPost cmd favor tab "$1" limit "$2" } ShySync() { [ "$ctx_sid" = "" ] && ShyLogin @@ -122,10 +124,11 @@ ShySync() { ctx_count=`expr $ctx_end - $ctx_begin` ShyEcho "sync $ctx_begin-$ctx_end count $ctx_count to $ctx_dev" history|tail -n $ctx_count |while read line; do - ShySends historys sub "$line" + ShySends history sub "$line" done ctx_begin=$ctx_end ;; + ps) ShySend ps -ef ;; *) ShySend "$@" esac } @@ -133,6 +136,7 @@ ShySyncs() { case "$1" in "base") ShySync df &>/dev/null + ShySync ps &>/dev/null ShySync env &>/dev/null ShySync free &>/dev/null ShySync history diff --git a/etc/conf/auto.vim b/etc/conf/auto.vim index 588b2464..7b4f2f8f 100644 --- a/etc/conf/auto.vim +++ b/etc/conf/auto.vim @@ -1,45 +1,63 @@ let ctx_url = (len($ctx_dev) > 1? $ctx_dev: "http://127.0.0.1:9095") . "/code/vim" -let ctx_head = "Content-Type: application/json" if !exists("g:ctx_sid") | let ctx_sid = "" | end -fun! ShyPost(arg) - let a:arg["buf"] = bufname("%") +fun! ShySend(arg) + if has_key(a:arg, "sub") && a:arg["sub"] != "" + let temp = tempname() + call writefile([a:arg["sub"]], temp) + let a:arg["sub"] = "@" . temp + endif + let a:arg["buf"] = bufname("%") let a:arg["pwd"] = getcwd() let a:arg["sid"] = g:ctx_sid + let args = "" for k in keys(a:arg) - let a:arg[k] = substitute(a:arg[k], "'", "XXXXXsingleXXXXX", "g") + let args = args . " -F '" . k . "=" . a:arg[k] . "' " endfor - return system("curl -s '" . g:ctx_url . "' -H '" . g:ctx_head . "' -d '" . json_encode(a:arg) . "' 2>/dev/null") + return system("curl -s " . g:ctx_url . args . " 2>/dev/null") endfun fun! ShyLogout() - if g:ctx_sid != "" - let g:ctx_sid = ShyPost({"cmd": "logout"}) - endif + if g:ctx_sid == "" | return | endif + call ShySend({"cmd": "logout"}) endfun fun! ShyLogin() - if g:ctx_sid == "" - let g:ctx_sid = ShyPost({"cmd": "login", "share": $ctx_share, "pid": getpid(), "pane": $TMUX_PANE, "hostname": hostname(), "username": $USER}) - endif + let g:ctx_sid = ShySend({"cmd": "login", "share": $ctx_share, "pid": getpid(), "pane": $TMUX_PANE, "hostname": hostname(), "username": $USER}) +endfun +fun! ShyFavor() + if !exists("g:favor_tab") | let g:favor_tab = "" | endif + if !exists("g:favor_note") | let g:favor_note = "" | endif + let g:favor_tab = input("tab: ", g:favor_tab) + let g:favor_note = input("note: ", g:favor_note) + call ShySend({"cmd": "favor", "tab": g:favor_tab, "note": g:favor_note, "arg": getline("."), "line": getpos(".")[1], "col": getpos(".")[2]}) +endfun +fun! ShyFavors() + let res = split(ShySend({"cmd": "favor", "tab": input("tab: ")}), "\n") + let page = "" | let note = "" + for i in range(0, len(res)-1, 2) + if res[i] != page + if note != "" | lexpr note | lopen | let note = "" | endif + execute exists(":TabooOpen")? "TabooOpen " . res[i]: "tabnew" + endif + let page = res[i] | let note .= res[i+1] . "\n" + endfor + if note != "" | lexpr note | lopen | let note = "" | endif endfun -fun! ShyDream(target) - call ShyPost({"cmd": "dream", "arg": a:target}) -endfun fun! ShySync(target) if bufname("%") == "ControlP" | return | end if a:target == "read" || a:target == "write" - call ShyPost({"cmd": a:target, "arg": expand("")}) + call ShySend({"cmd": a:target, "arg": expand("")}) elseif a:target == "exec" - call ShyPost({"cmd": a:target, "arg": getcmdline()}) + call ShySend({"cmd": a:target, "sub": getcmdline()}) elseif a:target == "insert" - call ShyPost({"cmd": a:target, "arg": getreg("."), "row": line("."), "col": col(".")}) + call ShySend({"cmd": a:target, "sub": getreg("."), "row": line("."), "col": col(".")}) else let cmd = {"bufs": "buffers", "regs": "registers", "marks": "marks", "tags": "tags", "fixs": "clist"} - call ShyPost({"cmd": "sync", "arg": a:target, "sub": execute(cmd[a:target])}) + call ShySend({"cmd": "sync", "arg": a:target, "sub": execute(cmd[a:target])}) endif endfun fun! ShyCheck(target) @@ -69,33 +87,8 @@ fun! ShyCheck(target) end endfun -fun! ShyFavors() - let msg = json_decode(ShyPost({"cmd": "favors"})) - let i = 0 - for i in range(len(msg["tab"])) - if msg["tab"][i] == "" - continue - endif - if exists(":TabooOpen") - execute "TabooOpen " . msg["tab"][i] - else - tabnew - endif - lexpr msg["fix"][i] - lopen - endfor -endfun -fun! ShyFavor(note) - if !exists("g:favor_tab") | let g:favor_tab = "" | endif - if !exists("g:favor_note") | let g:favor_note = "" | endif - if a:note != "" - let g:favor_tab = input("tab: ", g:favor_tab) - let g:favor_note = input("note: ", g:favor_note) - endif - call ShyPost({"cmd": "favor", "tab": g:favor_tab, "note": g:favor_note, "arg": getline("."), "line": getpos(".")[1], "col": getpos(".")[2]}) -endfun fun! ShyTask() - call ShyPost({"cmd": "tasklet", "arg": input("target: "), "sub": input("detail: ")}) + call ShySend({"cmd": "tasklet", "arg": input("target: "), "sub": input("detail: ")}) endfun fun! ShyGrep(word) if !exists("g:grep_dir") | let g:grep_dir = "./" | endif @@ -107,34 +100,35 @@ fun! ShyTag(word) endfun fun! ShyHelp() - echo ShyPost({"cmd": "help"}) + echo ShySend({"cmd": "help"}) endfun call ShyLogin() -" call ShySync("bufs") -call ShySync("regs") -call ShySync("marks") -call ShySync("tags") -" call ShySync("fixs") - -autocmd VimLeave * call ShyLogout() -autocmd BufReadPost * call ShySync("bufs") +" " call ShySync("bufs") +" call ShySync("regs") +" call ShySync("marks") +" call ShySync("tags") +" " call ShySync("fixs") +" +" autocmd VimLeave * call ShyLogout() +" autocmd BufReadPost * call ShySync("bufs") +" hello autocmd BufReadPost * call ShySync("read") autocmd BufWritePre * call ShySync("write") autocmd CmdlineLeave * call ShyCheck("exec") -autocmd QuickFixCmdPost * call ShyCheck("fixs") +" autocmd QuickFixCmdPost * call ShyCheck("fixs") autocmd InsertLeave * call ShySync("insert") - -command ShyHelp echo ShyPost({"cmd": "help"}) - -nnoremap :call ShyGrep(expand("")) -" nnoremap :call ShyTag(expand("")) -nnoremap :call ShyTask() -nnoremap :call ShyCheck("cache") -nnoremap :call ShyFavor("note") -nnoremap f :call ShyFavor("") -nnoremap F :call ShyFavors() - +" +" command! ShyHelp echo ShyPost({"cmd": "help"}) +" +" nnoremap :call ShyGrep(expand("")) +" " nnoremap :call ShyTag(expand("")) +" nnoremap :call ShyTask() +" nnoremap :call ShyCheck("cache") +" nnoremap :call ShyFavor("note") +" nnoremap f :call ShyFavor("") +" nnoremap F :call ShyFavors() +" " autocmd BufUnload * call Shy("close", expand("")) | call ShySync("bufs") " autocmd CmdlineLeave * " autocmd CompleteDone * call Shy("sync", "regs") diff --git a/etc/conf/tmux.conf b/etc/conf/tmux.conf index 2a3cf95d..94a8301d 100644 --- a/etc/conf/tmux.conf +++ b/etc/conf/tmux.conf @@ -90,5 +90,5 @@ bind -t vi-edit C-f cursor-right bind -t vi-edit C-j enter # }}} -bind C-r send-keys "export ctx_dev=$ctx_self ctx_share=$ctx_share\ncurl -s \$ctx_dev/publish/auto.sh >auto.sh\nsource auto.sh\n" +bind C-r send-keys "export ctx_dev=$ctx_self ctx_share=$ctx_share\ncurl -s \$ctx_dev/publish/auto.sh >auto.sh\nsource auto.sh\nShyLogin\n" source-file ~/.tmux_local diff --git a/etc/init.shy b/etc/init.shy index 829e67e8..62e61a74 100644 --- a/etc/init.shy +++ b/etc/init.shy @@ -28,6 +28,6 @@ # 终端配置 ~cli -~code ~wiki ~chat +~code diff --git a/src/contexts/cli/cli.go b/src/contexts/cli/cli.go index 3d38c45c..0803fad3 100644 --- a/src/contexts/cli/cli.go +++ b/src/contexts/cli/cli.go @@ -1303,7 +1303,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", m.Confv("imq", imq) m.Gos(m.Spawn(), func(msg *ctx.Message) { for <-imq.q { - m.Option("cache.offset", 0) + m.Option("cache.offend", 0) m.Option("cache.limit", m.Confi("imq", "meta.count")-m.Confi("imq", "meta.current")+1) m.Grows("imq", "data", func(meta map[string]interface{}, index int, value map[string]interface{}) { m.Log("info", "imq %d %v", index, value) diff --git a/src/contexts/ctx/misc.go b/src/contexts/ctx/misc.go index ded070e4..92205942 100644 --- a/src/contexts/ctx/misc.go +++ b/src/contexts/ctx/misc.go @@ -606,10 +606,12 @@ func (m *Message) Grows(key string, args interface{}, cb interface{}) map[string return nil } - offset := kit.Int(kit.Select("0", m.Option("cache.offset"))) + offend := kit.Int(kit.Select("0", m.Option("cache.offend"))) limit := kit.Int(kit.Select("10", m.Option("cache.limit"))) + match := kit.Select("", m.Option("cache.match")) + value := kit.Select("", m.Option("cache.value")) current := kit.Int(meta["offset"]) - end := current + len(list) - offset + end := current + len(list) - offend begin := end - limit data := make([]interface{}, 0, limit) @@ -657,7 +659,9 @@ func (m *Message) Grows(key string, args interface{}, cb interface{}) map[string item[heads[i]] = lines[i] } m.Log("info", "load line %v %v %v", i, len(data), item) - data = append(data, item) + if match == "" || strings.Contains(kit.Format(item[match]), value) { + data = append(data, item) + } begin = i + 1 } else { m.Log("info", "skip line %v", i) @@ -674,7 +678,9 @@ func (m *Message) Grows(key string, args interface{}, cb interface{}) map[string } m.Log("info", "cache %v-%v", begin-current, end-current) for i := begin - current; i < end-current; i++ { - data = append(data, list[i]) + if match == "" || strings.Contains(kit.Format(kit.Chain(list[i], match)), value) { + data = append(data, list[i]) + } } return kit.Map(map[string]interface{}{"meta": meta, "list": data}, "", cb) } diff --git a/src/contexts/nfs/nfs.go b/src/contexts/nfs/nfs.go index 3fd7768b..e6be05e8 100644 --- a/src/contexts/nfs/nfs.go +++ b/src/contexts/nfs/nfs.go @@ -2,6 +2,7 @@ package nfs import ( "bufio" + "bytes" "contexts/ctx" "crypto/md5" "crypto/sha1" @@ -234,7 +235,7 @@ func (nfs *NFS) Recv(line string) (field string, value string) { m.Assert(e) return } -func (nfs *NFS) Send(meta string, arg ...interface{}) *NFS { +func (nfs *NFS) Send(w io.Writer, meta string, arg ...interface{}) *NFS { m := nfs.Context.Message() line := "\n" @@ -247,7 +248,7 @@ func (nfs *NFS) Send(meta string, arg ...interface{}) *NFS { j = len(text) } line = fmt.Sprintf("%s: %s\n", url.QueryEscape(meta), url.QueryEscape(kit.Format(text[i:j]))) - n, e := fmt.Fprint(nfs.io, line) + n, e := fmt.Fprint(w, line) m.Assert(e) m.Capi("nwrite", n) m.Log("send", "%d [%s]", len(line), line) @@ -258,7 +259,7 @@ func (nfs *NFS) Send(meta string, arg ...interface{}) *NFS { } } - n, e := fmt.Fprint(nfs.io, line) + n, e := fmt.Fprint(w, line) m.Assert(e) m.Capi("nwrite", n) m.Log("send", "%d [%s]", len(line), line) @@ -383,16 +384,18 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { code, meta, body = msg.Optioni("remote_code"), "result", "append" } - nfs.Send("code", code) + buf := bytes.NewBuffer(make([]byte, 0, 1024)) + nfs.Send(buf, "_code", code) for _, v := range msg.Meta[meta] { - nfs.Send(meta, v) + nfs.Send(buf, meta, v) } for _, k := range msg.Meta[body] { for _, v := range msg.Meta[k] { - nfs.Send(k, v) + nfs.Send(buf, k, v) } } - nfs.Send("") + nfs.Send(buf, "") + buf.WriteTo(nfs.io) }) // 消息接收队列 @@ -403,7 +406,7 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { m.TryCatch(m, true, func(m *ctx.Message) { switch field, value := nfs.Recv(bio.Text()); field { - case "code": + case "_code": msg, code = m.Sess("ms_target"), value msg.Meta = map[string][]string{} @@ -427,8 +430,8 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { }) }) } else { // 接收响应 - m.Set("option", "code", code).Gos(msg, func(msg *ctx.Message) { - if h, ok := nfs.hand[kit.Int(m.Option("code"))]; ok { + m.Set("option", "_code", code).Gos(msg, func(msg *ctx.Message) { + if h, ok := nfs.hand[kit.Int(m.Option("_code"))]; ok { h.CopyFuck(msg, "result").CopyFuck(msg, "append").Back(h) } }) diff --git a/src/contexts/ssh/ssh.go b/src/contexts/ssh/ssh.go index 9d38799c..f8ace77e 100644 --- a/src/contexts/ssh/ssh.go +++ b/src/contexts/ssh/ssh.go @@ -440,34 +440,7 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", m.Push("count", len(value["list"].([]interface{}))) }) - case 2: // 关系表 - hide := map[string]bool{"create_time": true, "update_time": true, "extra": true} - m.Grows("flow", []string{m.Option("river"), "data", arg[1]}, func(meta map[string]interface{}, index int, value map[string]interface{}) { - for k := range value { - if !hide[k] { - hide[k] = false - } - } - }) - - keys := []string{} - for k, hide := range hide { - if !hide { - keys = append(keys, k) - } - } - sort.Strings(keys) - - if m.Meta["append"] = []string{"id", "when"}; m.Has("fields") { - keys = kit.Trans(m.Optionv("fields")) - } - m.Grows("flow", []string{m.Option("river"), "data", arg[1]}, func(meta map[string]interface{}, index int, value map[string]interface{}) { - for _, k := range keys { - m.Push(k, kit.Format(value[k])) - } - }) - - default: // 记录值 + case 3: // 记录行 index := kit.Int(arg[2]) - 1 - m.Confi("flow", []string{m.Option("river"), "data", arg[1], "meta", "offset"}) switch m.Option("format") { case "object": @@ -492,6 +465,40 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", }) m.Sort("key") } + default: // 关系表 + m.Option("cache.limit", kit.Select("10", arg, 3)) + m.Option("cache.offend", kit.Select("0", arg, 4)) + m.Option("cache.match", kit.Select("", arg, 5)) + m.Option("cache.value", kit.Select("", arg, 6)) + + keys := []string{} + if m.Meta["append"] = []string{"id", "when"}; m.Has("fields") { + keys = kit.Trans(m.Optionv("fields")) + } else { + // 字段查询 + hide := map[string]bool{"create_time": true, "update_time": true, "extra": true} + m.Grows("flow", []string{m.Option("river"), "data", arg[1]}, func(meta map[string]interface{}, index int, value map[string]interface{}) { + for k := range value { + if !hide[k] { + hide[k] = false + } + } + }) + // 字段排序 + for k, hide := range hide { + if !hide { + keys = append(keys, k) + } + } + sort.Strings(keys) + } + + // 查询数据 + m.Grows("flow", []string{m.Option("river"), "data", arg[1]}, func(meta map[string]interface{}, index int, value map[string]interface{}) { + for _, k := range keys { + m.Push(k, kit.Format(value[k])) + } + }) } m.Table() diff --git a/src/contexts/web/web.go b/src/contexts/web/web.go index 69344be2..f07472c8 100644 --- a/src/contexts/web/web.go +++ b/src/contexts/web/web.go @@ -952,22 +952,22 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", } return }}, - "/upload": &ctx.Command{Name: "/upload", Help: "上传文件", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + "/upload": &ctx.Command{Name: "/upload key", Help: "上传文件", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { r := m.Optionv("request").(*http.Request) - if f, h, e := r.FormFile("upload"); m.Assert(e) { + if f, h, e := r.FormFile(kit.Select("upload", arg, 0)); m.Assert(e) { defer f.Close() + // 上传文件 name := kit.Hashx(f) if o, p, e := kit.Create(path.Join(m.Conf("web.upload", "path"), "list", name)); m.Assert(e) { defer o.Close() f.Seek(0, os.SEEK_SET) if n, e := io.Copy(o, f); m.Assert(e) { - m.Log("upload", "file: %s %d", p, n) - - kind := h.Header.Get("Content-Type") - kind = strings.Split(kind, "/")[0] + m.Log("upload", "list: %s %d", p, n) + // 文件摘要 + kind := strings.Split(h.Header.Get("Content-Type"), "/")[0] buf := bytes.NewBuffer(make([]byte, 0, 1024)) fmt.Fprintf(buf, "create_time: %s\n", m.Time("2006-01-02 15:04")) fmt.Fprintf(buf, "create_user: %s\n", m.Option("username")) @@ -977,82 +977,81 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", fmt.Fprintf(buf, "size: %d\n", n) b := buf.Bytes() + // 保存摘要 code := kit.Hashs(string(b)) - if m.Options("river") { - prefix := []string{"ssh._route", m.Option("dream"), "ssh.data", "insert"} - m.Cmd(prefix, kit.Select(kind, m.Option("table")), "name", h.Filename, "kind", kind, "hash", name, "size", n) - m.Cmd(prefix, "file", "name", h.Filename, "kind", kind, "hash", name, "size", n, "code", code) - } - if o, p, e := kit.Create(path.Join(m.Conf("web.upload", "path"), "meta", code)); m.Assert(e) { defer o.Close() if n, e := o.Write(b); m.Assert(e) { - m.Log("upload", "file: %s %d", p, n) - + m.Log("upload", "meta: %s %d", p, n) m.Cmd("nfs.copy", path.Join(m.Conf("web.upload", "path"), kind, code), p) } } - if strings.HasPrefix(m.Option("agent"), "favor") { - m.Append("code", code) - m.Append("hash", name) - m.Append("name", h.Filename) - m.Append("time", m.Time("2006-01-02 15:04")) - m.Append("type", kind) - m.Append("size", kit.FmtSize(n)) - } else if !strings.HasPrefix(m.Option("agent"), "curl") { + // 文件索引 + if m.Options("river") { + prefix := []string{"ssh._route", m.Option("dream"), "ssh.data", "insert"} + suffix := []string{"code", code, "kind", kind, "name", h.Filename, "hash", name, "size", kit.Format(n), "upload_time", m.Time("2006-01-02 15:04")} + m.Cmd(prefix, kit.Select(kind, m.Option("table")), suffix) + m.Cmd(prefix, "file", suffix) + } + + // 返回信息 + if !strings.HasPrefix(m.Option("agent"), "curl") { m.Append("size", kit.FmtSize(n)) m.Append("link", fmt.Sprintf(`%s`, code, h.Filename)) m.Append("type", kind) m.Append("hash", name) - m.Table() } else { - m.Echo("code: %s\n", code) - m.Echo("hash: %s\n", name) - m.Echo("time: %s\n", m.Time("2006-01-02 15:04")) - m.Echo("type: %s\n", kind) - m.Echo("size: %s\n", kit.FmtSize(n)) + m.Append("code", code) + m.Append("type", kind) + m.Append("name", h.Filename) + m.Append("size", kit.FmtSize(n)) + m.Append("time", m.Time("2006-01-02 15:04")) + m.Append("hash", name) } } } } return }}, - "/download/": &ctx.Command{Name: "/download/", Help: "下载文件", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + "/download/": &ctx.Command{Name: "/download/hash [meta [hash]]", Help: "下载文件", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { r := m.Optionv("request").(*http.Request) w := m.Optionv("response").(http.ResponseWriter) kind := kit.Select("meta", kit.Select(m.Option("meta"), arg, 0)) file := kit.Select(strings.TrimPrefix(key, "/download/"), arg, 1) - // 文件列表 if file == "" { - if fs, e := ioutil.ReadDir(path.Join(m.Conf("web.upload", "path"), kind)); e == nil { - for _, f := range fs { - meta := kit.Linex(path.Join(m.Conf("web.upload", "path"), kind, f.Name())) - m.Push("time", meta["create_time"]) - m.Push("user", meta["create_user"]) - m.Push("size", kit.FmtSize(int64(kit.Int(meta["size"])))) - if kind == "image" { - m.Push("name", f.Name()) - } else { - m.Push("name", fmt.Sprintf(`%s`, f.Name(), meta["name"])) - } - m.Push("hash", meta["hash"][:8]) - } - m.Sort("time", "time_r").Table() + if m.Option("userrole") != "root" { + return } + // 文件列表 + m.Cmd("nfs.dir", path.Join(m.Conf("web.upload", "path"), kind)).Table(func(index int, value map[string]string) { + name := path.Base(value["path"]) + meta := kit.Linex(value["path"]) + m.Push("time", meta["create_time"]) + m.Push("user", meta["create_user"]) + m.Push("size", kit.FmtSize(int64(kit.Int(meta["size"])))) + if kind == "image" { + m.Push("name", name) + } else { + m.Push("name", fmt.Sprintf(`%s`, name, meta["name"])) + } + m.Push("hash", meta["hash"][:8]) + + }) + m.Sort("time", "time_r").Table() return } - // 直接下载 if p := m.Cmdx("nfs.path", path.Join(m.Conf("web.upload", "path"), "list", file)); p != "" { + // 直接下载 m.Log("info", "download %s direct", p) http.ServeFile(w, r, p) return } - // 下载文件 if p := m.Cmdx("nfs.path", path.Join(m.Conf("web.upload", "path"), kind, file)); p != "" { + // 下载文件 meta := kit.Linex(p) if p := m.Cmdx("nfs.path", path.Join(m.Conf("web.upload", "path"), "list", meta["hash"])); p != "" { m.Log("info", "download %s %s", p, m.Cmdx("nfs.hash", meta["hash"])) @@ -1068,8 +1067,8 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", return } - // 任意文件 if p := m.Cmdx("nfs.path", file); p != "" { + // 任意文件 m.Log("info", "download %s %s", p, m.Cmdx("nfs.hash", p)) http.ServeFile(w, r, p) } diff --git a/src/examples/code/code.go b/src/examples/code/code.go index bc13d9da..9b7bca90 100644 --- a/src/examples/code/code.go +++ b/src/examples/code/code.go @@ -30,9 +30,6 @@ CMD sh bin/boot.sh var Index = &ctx.Context{Name: "code", Help: "代码中心", Caches: map[string]*ctx.Cache{}, Configs: map[string]*ctx.Config{ - "login": {Name: "login", Value: map[string]interface{}{"check": false, "local": true, "expire": "720h", "meta": map[string]interface{}{ - "fields": "time sid type status ship.dream ship.stage pwd pid pane hostname username", - }}, Help: "用户登录"}, "prefix": {Name: "prefix", Help: "外部命令", Value: map[string]interface{}{ "zsh": []interface{}{"cli.system", "zsh"}, "tmux": []interface{}{"cli.system", "tmux"}, @@ -70,10 +67,10 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心", "fields": "sid name value", }}, "ps": map[string]interface{}{"meta": map[string]interface{}{ - "fields": "PID TIME COMMAND", + "fields": "sid UID PID PPID TTY CMD", }}, "df": map[string]interface{}{"meta": map[string]interface{}{ - "fields": "fs size used rest per pos", + "fields": "sid fs size used rest per pos", }}, }}, "vim": {Name: "vim", Help: "编辑器", Value: map[string]interface{}{ @@ -117,6 +114,11 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心", "limit": 6, "least": 3, }}, + + "login": {Name: "login", Value: map[string]interface{}{"check": false, "local": true, "expire": "720h", "meta": map[string]interface{}{ + "fields": "time sid type status ship.dream ship.stage pwd pid pane hostname username", + "script": "usr/script", + }}, Help: "用户登录"}, "dream": {Name: "dream", Help: "使命必达", Value: map[string]interface{}{ "layout": map[string]interface{}{ "three": []interface{}{ @@ -148,6 +150,9 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心", "share": map[string]interface{}{"meta": map[string]interface{}{ "fields": "river dream favor story stage order expire", }}, + "favor": map[string]interface{}{"meta": map[string]interface{}{ + "fields": "tab note word file line col", + }}, }}, }, Commands: map[string]*ctx.Command{ @@ -164,21 +169,21 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心", home := path.Join(m.Conf("missyou", "path"), arg[1], m.Conf("missyou", "local")) topic := kit.Select("index", kit.Select(m.Option("topic"), arg, 2)) git := kit.Trans(m.Confv("prefix", "git"), "cmd_dir", home) - m.Confm("dream", []string{"topic", topic, "git"}, func(index int, value string) { + m.Confm(cmd, []string{"topic", topic, "git"}, func(index int, value string) { value = strings.Replace(value, "$dream", arg[1], -1) m.Cmd(git, strings.Split(value, " ")) }) // 创建终端 - share := m.Cmdx("dream", "share", topic) + share := m.Cmdx(cmd, "share", topic) m.Cmd(tmux, "set-environment", "-g", "ctx_share", share) m.Cmd(tmux, "new-session", "-ds", arg[1], "cmd_dir", home, "cmd_env", "TMUX", "") m.Cmd(tmux, "set-environment", "-t", arg[1], "ctx_share", share) - m.Confm("dream", []string{"layout", m.Conf("dream", []string{"topic", topic, "layout", "0"})}, func(index int, value string) { + m.Confm(cmd, []string{"layout", m.Conf(cmd, []string{"topic", topic, "layout", "0"})}, func(index int, value string) { value = strings.Replace(value, "$dream", arg[1], -1) m.Cmd(tmux, strings.Split(value, " "), "cmd_dir", home) }) - m.Confm("dream", []string{"topic", topic, "tmux"}, func(index int, value string) { + m.Confm(cmd, []string{"topic", topic, "tmux"}, func(index int, value string) { value = strings.Replace(value, "$dream", arg[1], -1) m.Cmd(tmux, strings.Split(value, " "), "cmd_dir", home) }) @@ -187,7 +192,7 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心", case "share": // 模板参数 topic := kit.Select("index", kit.Select(m.Option("topic"), arg, 1)) - m.Confm("dream", []string{"topic", topic, "ship"}, func(index int, value string) { + m.Confm(cmd, []string{"topic", topic, "ship"}, func(index int, value string) { if len(arg) < index+3 { arg = append(arg, value) } else if arg[index+2] == "" { @@ -195,17 +200,17 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心", } }) // 共享链接 - h := kit.ShortKey(m.Confm("dream", []string{"share", "hash"}), 6) - m.Confv("dream", []string{"share", "hash", h}, map[string]interface{}{ + h := kit.ShortKey(m.Confm(cmd, []string{"share", "hash"}), 6) + m.Confv(cmd, []string{"share", "hash", h}, map[string]interface{}{ "river": m.Option("river"), "dream": m.Option("dream"), "favor": arg[2], "story": arg[3], "stage": arg[4], "order": arg[5], - "expire": m.Time("10m", "stamp"), + "topic": topic, "share": h, "expire": m.Time("10m", "stamp"), }) m.Echo(h) case "list": - m.Confm("dream", "share.hash", func(key string, value map[string]interface{}) { - m.Push("key", key).Push(m.Conf("dream", "share.meta.fields"), value) + m.Confm(cmd, "share.hash", func(key string, value map[string]interface{}) { + m.Push("key", key).Push(m.Conf(cmd, "share.meta.fields"), value) }) m.Table() @@ -218,17 +223,20 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心", switch kit.Select("list", arg, 0) { case "open": case "init": - if m.Option("sid") != "" && m.Confs(cmd, []string{"hash", m.Option("sid")}) { - m.Echo(m.Option("sid")) - return + if m.Option("sid") != "" { + if m.Confs(cmd, []string{"hash", m.Option("sid"), "status"}) { + m.Conf(cmd, []string{"hash", m.Option("sid"), "status"}, "login") + m.Echo(m.Option("sid")) + return + } } // 添加终端 - name := kit.Hashs(m.Option("pid"), m.Option("hostname"), m.Option("username")) - m.Conf(cmd, []string{"hash", name}, map[string]interface{}{ + h := kit.ShortKey(m.Confm(cmd, "hash"), 6, m.Option("pid"), m.Option("hostname"), m.Option("username")) + m.Conf(cmd, []string{"hash", h}, map[string]interface{}{ "time": m.Time(), - "type": kit.Select("vim", arg, 1), "status": "login", + "type": kit.Select("vim", arg, 1), "ship": m.Confv("dream", []string{"share", "hash", m.Option("share")}), "pwd": m.Option("pwd"), "pid": m.Option("pid"), @@ -236,50 +244,52 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心", "hostname": m.Option("hostname"), "username": m.Option("username"), }) - m.Echo(name) + m.Echo(h) case "list": - // 清理终端 - if len(arg) > 3 && arg[3] == "prune" { - m.Cmd(".prune", m.Conf("login", []string{"hash", arg[2], "type"}), arg[2]) - arg = arg[:1] + if len(arg) > 4 { + sid := kit.Select(m.Option("sid"), arg[3]) + switch arg[4] { + case "prune": + // 清理终端 + m.Cmd(".prune", m.Conf("login", []string{"hash", sid, "type"}), sid) + arg = arg[:2] + case "modify": + // 修改终端 + m.Conf(cmd, []string{"hash", sid, arg[5]}, arg[6]) + arg = arg[:2] + } } // 终端列表 - if len(arg) == 1 || arg[1] == "" { + if len(arg) == 2 || arg[2] == "" { fields := strings.Split(m.Conf(cmd, "meta.fields"), " ") m.Confm(cmd, "hash", func(key string, value map[string]interface{}) { - value["sid"] = key - m.Push(fields, kit.Shortm(value, "times", "files", "sids")) + if arg[1] == "" || arg[1] == kit.Format(value["type"]) { + value["sid"] = key + m.Push(fields, value) + } }) m.Table() break } - // 终端数据 - if len(arg) > 6 && arg[6] != "" { - m.Conf(cmd, []string{"hash", arg[1], "ship", "order"}, arg[6]) - } - if len(arg) > 5 && arg[5] != "" { - m.Conf(cmd, []string{"hash", arg[1], "ship", "stage"}, arg[5]) - } - if len(arg) > 4 && arg[4] != "" { - m.Conf(cmd, []string{"hash", arg[1], "ship", "story"}, arg[4]) + // 终端绑定 + if len(arg) > 4 && arg[4] != "" && arg[4] != m.Conf(cmd, []string{"hash", arg[2], "ship", "topic"}) && m.Confs(cmd, []string{"hash", arg[2]}) { + share := m.Cmdx("dream", "share", arg[4:]) + m.Conf(cmd, []string{"hash", arg[2], "ship"}, + m.Confv("dream", []string{"share", "hash", share})) } if len(arg) > 3 && arg[3] != "" { - m.Conf(cmd, []string{"hash", arg[1], "ship", "favor"}, arg[3]) - m.Conf(cmd, []string{"hash", arg[1], "ship", "river"}, m.Option("river")) - } - if len(arg) > 2 && arg[2] != "" { - m.Conf(cmd, []string{"hash", arg[1], "ship", "dream"}, arg[2]) + m.Conf(cmd, []string{"hash", arg[2], "ship", "dream"}, arg[3]) } // 终端详情 m.Option("table.format", "table") - m.Confm(cmd, []string{"hash", arg[1], "ship"}, func(key string, value string) { + m.Confm(cmd, []string{"hash", arg[2], "ship"}, func(key string, value string) { m.Push("ship."+key, value) }) - m.Confm(cmd, []string{"hash", arg[1]}, func(key string, value string) { + m.Confm(cmd, []string{"hash", arg[2]}, func(key string, value string) { if key != "ship" { m.Push(key, value) } @@ -288,13 +298,15 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心", case "exit": // 退出终端 - m.Conf(cmd, []string{"hash", m.Option("sid"), "status"}, "logout") - m.Conf(cmd, []string{"hash", m.Option("sid"), "time"}, m.Time()) + if m.Confs(cmd, []string{"hash", m.Option("sid")}) { + m.Conf(cmd, []string{"hash", m.Option("sid"), "status"}, "logout") + m.Conf(cmd, []string{"hash", m.Option("sid"), "time"}, m.Time()) + } case "quit": } return }}, - "favor": {Name: "favor post|list", Help: "收藏", Hand: func(m *ctx.Message, c *ctx.Context, cmd string, arg ...string) (e error) { + "favor": {Name: "favor download|upload|file|post|list", Help: "收藏", Hand: func(m *ctx.Message, c *ctx.Context, cmd string, arg ...string) (e error) { switch arg[0] { case "download": // 下载文件 @@ -304,16 +316,19 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心", } // 下载列表 m.Cmd("ssh._route", m.Option("dream"), "ssh.data", "show", "file").Table(func(index int, value map[string]string) { - m.Echo("%v %v %v\n", value["hash"], kit.FmtSize(int64(kit.Int(value["size"]))), value["name"]) + m.Push("hash", value["hash"]) + m.Push("time", value["upload_time"]) + m.Push("size", kit.FmtSize(int64(kit.Int(value["size"])))) + m.Push("name", value["name"]) }) + m.Table().Set("append") case "upload": // 上传文件 - m.Option("agent", "favor") if m.Cmd("/upload"); m.Options("dream") { - // 转发文件 - m.Cmd("ssh._route", m.Option("dream"), "web.get", "dev", - "/download/"+m.Append("hash"), "save", "usr/script/"+m.Append("name")) + // 下发文件 + m.Cmd("ssh._route", m.Option("dream"), "web.get", "dev", "/download/"+m.Append("hash"), + "save", m.Conf("login", "script")+"/"+m.Append("name")) } m.Echo("code: %s\n", m.Append("code")) m.Echo("hash: %s\n", m.Append("hash")) @@ -321,71 +336,80 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心", m.Echo("type: %s\n", m.Append("type")) m.Echo("size: %s\n", m.Append("size")) m.Set("append") + case "file": // 文件列表 - m.Cmd("ssh.data", "show", arg[1]).Table(func(index int, value map[string]string) { + if len(arg) > 2 && arg[2] != "" { + m.Cmdy("ssh.data", "show", arg[1:3]) + break + } + m.Cmd("ssh.data", "show", arg[1:]).Table(func(index int, value map[string]string) { m.Push("id", value["id"]) - m.Push("time", value["create_time"]) - m.Push("kind", value["kind"]) + m.Push("time", value["upload_time"]) m.Push("name", value["name"]) m.Push("size", kit.FmtSize(int64(kit.Int(value["size"])))) m.Push("file", fmt.Sprintf(`%s`, kit.Select(value["hash"], value["code"]), value["name"])) - m.Push("hash", value["hash"]) + m.Push("hash", kit.Short(value["hash"], 6)) }) m.Table() case "post": // 上传记录 - m.Log("info", "river: %v dream: %v favor: %v", m.Option("river"), m.Option("dream"), m.Option("favor")) - - if prefix := []string{"ssh._route", m.Option("dream"), "ssh.data"}; len(arg) > 1 { - m.Cmdy(prefix, "insert", m.Option("favor"), arg[1:]) - } else { - m.Cmdy(prefix, "show", m.Option("favor")) + if len(arg) < 3 || arg[2] == "" { + break } + args := []string{} + for i, v := range strings.Split(kit.Select("tab note word file line", m.Conf("dream", "favor.meta.fields")), " ") { + args = append(args, v, kit.Select("", arg, i+2)) + } + m.Cmdy("ssh.data", "insert", arg[1], args) case "list": - if len(arg) > 2 && arg[2] == "modify" { - m.Cmdy("ssh.data", "update", m.Option("favor"), arg[1], arg[3], arg[4]) - arg = []string{"list", m.Option("favor"), arg[1]} + if len(arg) > 3 && arg[3] == "modify" { + m.Cmd("ssh.data", "update", arg[1], arg[2], arg[4], arg[5]) + arg = arg[:3] } m.Cmdy("ssh.data", "show", arg[1:]) } return }}, - "trend": {Name: "trend type item limit offset fields...", Help: "趋势", Hand: func(m *ctx.Message, c *ctx.Context, cmd string, arg ...string) (e error) { - if len(arg) > 4 { - arg[4] = strings.Join(arg[4:], " ") - } - m.Option("cache.limit", kit.Select("10", arg, 2)) - m.Option("cache.offset", kit.Select("0", arg, 3)) - fields := strings.Split(kit.Select(m.Conf(arg[0], arg[1]+".meta.fields"), arg, 4), " ") + "trend": {Name: "trend post|list", Help: "趋势", Hand: func(m *ctx.Message, c *ctx.Context, cmd string, arg ...string) (e error) { + switch arg[0] { + case "post": + m.Cmdy("ssh.data", "insert", arg[1], arg[2:]) - m.Grows(arg[0], arg[1], func(meta map[string]interface{}, index int, value map[string]interface{}) { - m.Push(fields, kit.Shortm(value, "times", "files", "sids")) - }) - - if m.Appends("time") { - m.Sort("time", "time_r") - } else if m.Appends("times") { - m.Sort("times", "time_r") + case "list": + if len(arg) > 3 && arg[3] == "modify" { + m.Cmd("ssh.data", "update", arg[1], arg[2], arg[4], arg[5]) + arg = arg[:3] + } + m.Cmdy("ssh.data", "show", arg[1:]) } - if m.Appends("index") { - // m.Sort("index", "int_r") - } - m.Table() return }}, - "state": {Name: "trend type item sid key value fields...", Help: "趋势", Hand: func(m *ctx.Message, c *ctx.Context, cmd string, arg ...string) (e error) { - if len(arg) > 5 { - arg[5] = strings.Join(arg[5:], " ") - } - fields := strings.Split(kit.Select(m.Conf(arg[0], arg[1]+".meta.fields"), arg, 5), " ") - m.Confm(arg[0], []string{arg[1], "hash"}, func(key string, index int, value map[string]interface{}) { - if value["sid"] = key; len(arg) == 2 || arg[2] == "" || strings.HasPrefix(kit.Format(value[arg[3]]), arg[4]) { - m.Push(fields, kit.Shortm(value, "times", "files", "sids")) + "state": {Name: "state post|list", Help: "状态", Hand: func(m *ctx.Message, c *ctx.Context, cmd string, arg ...string) (e error) { + switch arg[0] { + case "post": + data := map[string]interface{}{} + for i := 3; i < len(arg)-1; i += 2 { + kit.Chain(data, arg[i], arg[i+1]) } - }) + m.Confv(arg[1], []string{arg[2], "hash", m.Option("sid"), "-2"}, data) + + case "list": + if len(arg) > 6 { + arg[6] = strings.Join(arg[6:], " ") + } + fields := strings.Split(kit.Select(m.Conf(arg[1], arg[2]+".meta.fields"), arg, 6), " ") + m.Confm(arg[1], []string{arg[2], "hash"}, func(key string, index int, value map[string]interface{}) { + if arg[3] != "" && key != arg[3] { + return + } + if value["sid"] = key; len(arg) < 6 || arg[4] == "" || strings.HasPrefix(kit.Format(value[arg[4]]), arg[5]) { + m.Push(fields, value) + } + }) + } return }}, "prune": {Name: "prune type sid...", Help: "清理", Hand: func(m *ctx.Message, c *ctx.Context, cmd string, arg ...string) (e error) { @@ -433,91 +457,52 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心", case "download": m.Cmd("favor", "download", m.Option("arg")) case "favor": + m.Log("info", "river: %v dream: %v favor: %v", m.Option("river"), m.Option("dream"), m.Option("favor")) // 添加收藏 + prefix := []string{"ssh._route", m.Option("dream"), "web.code.favor"} if m.Options("arg") { m.Option("arg", strings.SplitN(strings.TrimSpace(m.Option("arg")), " ", 2)[1]) - m.Cmd("favor", "post", "tab", m.Option("tab"), "note", m.Option("note"), "word", m.Option("arg")) + m.Cmdy(prefix, "post", m.Option("favor"), m.Option("tab"), m.Option("note"), m.Option("arg")) m.Set("append") break } // 生成脚本 m.Echo("#/bin/sh\n\n") - m.Cmd(".favor", "post").Table(func(index int, value map[string]string) { - if !m.Options("tab") || value["tab"] == m.Option("tab") { - m.Echo("# %v:%v\n%v\n\n", value["tab"], value["note"], value["word"]) - } + m.Cmd(prefix, "list", m.Option("favor"), "", kit.Select("10", m.Option("limit")), "0", "tab", m.Option("tab")).Table(func(index int, value map[string]string) { + m.Echo("# %v:%v\n%v\n\n", value["tab"], value["note"], value["word"]) }) - case "historys": - vs := strings.SplitN(strings.TrimSpace(m.Option("arg")), " ", 2) - m.Grow(cmd, "history", map[string]interface{}{ - "time": m.Time(), - "sid": m.Option("sid"), - "index": vs[0], - "cmd": kit.Select("", vs, 1), - "pwd": m.Option("pwd"), - }) case "history": - switch path.Base(m.Option("SHELL")) { - case "zsh": - m.Option("arg", strings.SplitN(m.Option("arg"), ";", 2)[1]) - default: - m.Option("arg", strings.SplitN(strings.TrimSpace(m.Option("arg")), " ", 2)[1]) - } - m.Grow(cmd, "history", map[string]interface{}{ - "time": m.Time(), - "sid": m.Option("sid"), - "cmd": m.Option("arg"), - "pwd": m.Option("pwd"), - }) + vs := strings.SplitN(strings.TrimSpace(m.Option("arg")), " ", 2) + m.Cmd("trend", "post", "zsh.history", "sid", m.Option("sid"), + "num", vs[0], "cmd", kit.Select("", vs, 1), "pwd", m.Option("pwd")) + m.Set("append").Set("result") case "sync": - m.Confv(cmd, []string{m.Option("arg"), "hash", m.Option("sid")}, "") + m.Confv(cmd, []string{m.Option("arg"), "hash", m.Option("sid")}, []interface{}{}) switch m.Option("arg") { case "free": sub := strings.Replace(m.Option("sub"), " ", "type", 1) m.Split(sub, " ", "7", "type total used free shared buffer available").Table(func(index int, value map[string]string) { if index == 1 { - m.Confv(cmd, []string{m.Option("arg"), "list", "-2"}, map[string]interface{}{ - "time": m.Time(), - "sid": m.Option("sid"), - "type": value["type"], - "total": value["total"], - "used": value["used"], - "free": value["free"], - "shared": value["shared"], - "buffer": value["buffer"], - "available": value["available"], - }) + m.Cmd("trend", "post", "zsh.free", value) } }) case "env": m.Split(strings.TrimPrefix(m.Option("sub"), "\n"), "=", "2", "name value").Table(func(index int, value map[string]string) { - m.Confv(cmd, []string{m.Option("arg"), "hash", m.Option("sid"), "-2"}, map[string]interface{}{ - "name": value["name"], - "value": value["value"], - }) + m.Cmd("state", "post", cmd, m.Option("arg"), value) }) case "ps": - m.Split(m.Option("sub"), " ").Table(func(index int, value map[string]string) { - m.Confv(cmd, []string{m.Option("arg"), "hash", m.Option("sid"), "-2"}, map[string]interface{}{ - "PID": value["PID"], - "TIME": value["TIME"], - "COMMAND": value["COMMAND"], - }) + m.Split(m.Option("sub"), " ", "8", "UID PID PPID C STIME TTY TIME CMD").Table(func(index int, value map[string]string) { + if index > 0 { + m.Cmd("state", "post", cmd, m.Option("arg"), value) + } }) case "df": m.Split(m.Option("sub"), " ", "6", "fs size used rest per pos").Table(func(index int, value map[string]string) { if index > 0 { - m.Confv(cmd, []string{m.Option("arg"), "hash", m.Option("sid"), "-2"}, map[string]interface{}{ - "fs": value["fs"], - "size": value["size"], - "used": value["used"], - "rest": value["rest"], - "per": value["per"], - "pos": value["pos"], - }) + m.Cmd("state", "post", cmd, m.Option("arg"), value) } }) } @@ -972,8 +957,12 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心", }}, "/vim": {Name: "/vim sid pwd cmd arg sub", Help: "编辑器", Hand: func(m *ctx.Message, c *ctx.Context, cmd string, arg ...string) (e error) { cmd = strings.TrimPrefix(cmd, "/") - m.Option("arg", strings.Replace(m.Option("arg"), "XXXXXsingleXXXXX", "'", -1)) - m.Option("sub", strings.Replace(m.Option("sub"), "XXXXXsingleXXXXX", "'", -1)) + if f, _, e := m.Optionv("request").(*http.Request).FormFile("sub"); e == nil { + defer f.Close() + if b, e := ioutil.ReadAll(f); e == nil { + m.Option("sub", string(b)) + } + } m.Log("info", "%v %v %v %v", cmd, m.Option("cmd"), m.Option("arg"), m.Option("sub")) m.Confm("login", []string{"hash", m.Option("sid"), "ship"}, func(key string, value string) { m.Option(key, value) }) @@ -982,63 +971,35 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心", m.Echo(strings.Join(kit.Trans(m.Confv("help", "index")), "\n")) case "login": m.Cmd("login", "init", cmd) - case "dream": - m.Cmd("dream", "bind", m.Option("arg")) case "logout": m.Cmd("login", "exit") - case "tasklet": - m.Cmd("ssh._route", m.Option("dream"), "web.team.task", "create", "task", "3", "add", "action", m.Time(), m.Time("10m"), m.Option("arg"), m.Option("sub")) - - case "favors": - data := map[string][]string{} - m.Cmd(".favor", "post").Table(func(index int, value map[string]string) { - data[value["tab"]] = append(data[value["tab"]], - fmt.Sprintf("%v:%v:0:(%v): %v", value["file"], value["line"], value["note"], value["word"])) - }) - - for k, v := range data { - m.Push("tab", k) - m.Push("fix", strings.Join(v, "\n")) - } - return case "favor": - if m.Options("tab") { - m.Cmd("favor", "post", "tab", m.Option("tab"), "note", m.Option("note"), "word", m.Option("arg"), - "file", m.Option("buf"), "line", m.Option("line"), "col", m.Option("col"), - ) - return + m.Log("info", "river: %v dream: %v favor: %v", m.Option("river"), m.Option("dream"), m.Option("favor")) + prefix := []string{"ssh._route", m.Option("dream"), "web.code.favor"} + if m.Options("arg") { + m.Cmd(prefix, "post", m.Option("favor"), m.Option("tab"), m.Option("note"), m.Option("arg"), + m.Option("buf"), m.Option("line"), m.Option("col")) + m.Set("append") + break } - m.Cmd(".favor", "post").Table(func(index int, value map[string]string) { - m.Echo("%v:%v:0:(%v): %v\n", value["file"], value["line"], value["note"], value["word"]) + + m.Cmd(prefix, "list", m.Option("favor"), "", kit.Select("10", m.Option("limit")), "0", "tab", m.Option("tab")).Table(func(index int, value map[string]string) { + m.Echo("%v\n", value["tab"]).Echo("%v:%v:%v:(%v): %v\n", value["file"], value["line"], value["col"], value["note"], value["word"]) }) - return case "read", "write": - m.Grow(cmd, "opens", map[string]interface{}{ - "time": m.Time(), - "sid": m.Option("sid"), - "action": m.Option("cmd"), - "file": m.Option("arg"), - "pwd": m.Option("pwd"), - }) + m.Cmd("trend", "post", "vim.opens", "sid", m.Option("sid"), + "action", m.Option("cmd"), "file", m.Option("arg"), "pwd", m.Option("pwd")) + case "exec": - m.Grow(cmd, "cmds", map[string]interface{}{ - "time": m.Time(), - "sid": m.Option("sid"), - "cmd": m.Option("arg"), - "file": m.Option("buf"), - "pwd": m.Option("pwd"), - }) + m.Cmd("trend", "post", "vim.cmds", "sid", m.Option("sid"), + "cmd", m.Option("sub"), "file", m.Option("buf"), "pwd", m.Option("pwd")) case "insert": - m.Grow(cmd, "txts", map[string]interface{}{ - "time": m.Time(), - "sid": m.Option("sid"), - "word": m.Option("arg"), - "line": m.Option("row"), - "col": m.Option("col"), - "file": m.Option("buf"), - "pwd": m.Option("pwd"), - }) + m.Cmd("trend", "post", "vim.txts", "sid", m.Option("sid"), + "word", m.Option("sub"), "line", m.Option("row"), "col", m.Option("col"), "file", m.Option("buf"), "pwd", m.Option("pwd")) + + case "tasklet": + m.Cmd("ssh._route", m.Option("dream"), "web.team.task", "create", "task", "3", "add", "action", m.Time(), m.Time("10m"), m.Option("arg"), m.Option("sub")) case "sync": m.Conf(cmd, []string{m.Option("arg"), "hash", m.Option("sid")}, "") diff --git a/src/examples/team/team.go b/src/examples/team/team.go index f2e56f35..eee08308 100644 --- a/src/examples/team/team.go +++ b/src/examples/team/team.go @@ -35,7 +35,7 @@ var Index = &ctx.Context{Name: "team", Help: "团队中心", } // 任务进度 m.Option("cache.limit", kit.Select("30", arg, 2)) - m.Option("cache.offset", kit.Select("0", arg, 3)) + m.Option("cache.offend", kit.Select("0", arg, 3)) m.Meta["append"] = []string{"prepare", "action", "cancel", "finish"} m.Cmd("ssh.data", "show", arg[1]).Table(func(index int, value map[string]string) { m.Push(value["status"], @@ -52,6 +52,7 @@ var Index = &ctx.Context{Name: "team", Help: "团队中心", m.Cmdy("ssh.data", "insert", arg[1], "level", arg[2], "class", arg[3], "status", arg[4], "begin_time", arg[5], "close_time", arg[6], "target", arg[7], "detail", arg[8], arg[9:]) + break } arg = []string{arg[1]} diff --git a/src/plugin/vim/index.shy b/src/plugin/vim/index.shy index cea36438..ccd994bf 100644 --- a/src/plugin/vim/index.shy +++ b/src/plugin/vim/index.shy @@ -1,39 +1,57 @@ kit tips "便签" private "_:web.code.favor" list \ text "" name dream imports plugin_you action auto \ - text "tip" name favor imports plugin_vim_favor action auto \ - text "" name index imports plugin_tip_id view tiny action auto \ + text "tip" name favor view tiny \ + text "" name index imports plugin_vim_favor view tiny action auto \ + text "" name limit view tiny \ + text "" name offend view tiny \ feature detail "修改" "复制" "下载" \ - exports vim_favor table "" tip_id id "" \ - button "记录" action auto \ + exports vim_favor id \ + button "查看" action auto \ button "返回" cb Last -kit editor "编辑器" private "web.code.login" list \ +kit favor "收藏" private "_:web.code.favor" post \ + text "" name dream imports plugin_you \ + text "tip" name table view tiny \ + text "" name tab \ + text "" name note \ + text "" name word imports plugin_vim_word \ + text "" name file imports plugin_vim_file \ + text "" name line imports plugin_vim_line view tiny \ + text "" name col imports plugin_vim_col view tiny \ + button "添加" + +kit editor "编辑器" private "web.code.login" list vim \ text "" name sid imports plugin_vim_sid action auto \ text "" name dream imports plugin_you \ text "" name topic imports plugin_see \ feature detail "prune" "复制" "下载" \ exports vim_sid sid \ - button "查看" action auto + button "查看" action auto \ + button "返回" cb Last -kit opens "文件记录" private "web.code.trend" vim opens \ - text "10" name limit view tiny \ - text "0" name offset view tiny \ - text "times sids action files" name fields \ - button "查看" action auto +kit opens "文件记录" private "web.code.trend" list "vim.opens" \ + text "" name index imports plugin_vim_opens view tiny action auto \ + text "" name limit view tiny \ + text "" name offend view tiny \ + exports vim_opens id "" vim_file file \ + button "查看" action auto \ + button "返回" cb Last -kit cmds "命令记录" private "web.code.trend" vim cmds \ - text "10" name limit view tiny \ - text "0" name offset view tiny \ - text "times sids cmd files" name fields \ - exports vim_word cmd \ - button "查看" action auto +kit cmds "命令记录" private "web.code.trend" list "vim.cmds" \ + text "" name index imports plugin_vim_cmds view tiny action auto \ + text "" name limit view tiny \ + text "" name offend view tiny \ + exports vim_cmds id "" vim_file file \ + button "查看" action auto \ + button "返回" cb Last -kit txts "插入记录" private "web.code.trend" vim txts \ - text "10" name limit view tiny \ - text "0" name offset view tiny \ - text "times sids word files line" name fields \ - exports vim_word word \ - button "查看" action auto +kit txts "插入记录" private "web.code.trend" list "vim.txts" \ + text "" name index imports plugin_vim_txts view tiny action auto \ + text "" name limit view tiny \ + text "" name offend view tiny \ + exports vim_txts id "" vim_word word "" vim_file file "" vim_line line "" vim_col col "" \ + button "查看" action auto \ + button "返回" cb Last kit bufs "文件缓存" private "web.code.state" vim bufs \ text "" name sid imports plugin_vim_sid action auto \ diff --git a/src/plugin/zsh/index.shy b/src/plugin/zsh/index.shy index 3a5abbcb..b21851e7 100644 --- a/src/plugin/zsh/index.shy +++ b/src/plugin/zsh/index.shy @@ -1,56 +1,73 @@ kit file "文件" private "_:web.code.favor" file \ text "" name dream imports plugin_you action auto \ - text "file" name type \ - button "查看" action auto - -kit taps "便签" private "_:web.code.favor" list \ - text "" name dream imports plugin_you action auto \ - text "tap" name favor imports plugin_zsh_favor action auto \ - text "" name index imports plugin_tap_id view tiny action auto \ - feature detail "修改" "复制" "下载" \ - exports zsh_favor table "" tap_id id "" \ - button "记录" action auto \ + text "file" name table view tiny \ + text "" name index imports plugin_zsh_block action auto view tiny \ + text "" name limit view tiny \ + text "" name offend view tiny \ + exports zsh_block id \ + button "查看" action auto \ button "返回" cb Last -kit terminal "终端" private "web.code.login" list \ +kit tips "便签" private "_:web.code.favor" list \ + text "" name dream imports plugin_you action auto \ + text "tip" name table view tiny \ + text "" name index imports plugin_zsh_favor view tiny action auto \ + text "" name limit view tiny \ + text "" name offend view tiny \ + feature detail "修改" "复制" "下载" \ + exports zsh_favor id \ + button "查看" action auto \ + button "返回" cb Last + +kit favor "收藏" private "_:web.code.favor" post \ + text "" name dream imports plugin_you \ + text "tip" name table view tiny \ + text "" name tab \ + text "" name note \ + text "" name word imports plugin_zsh_cmd \ + button "添加" + +kit terminal "终端" private "web.code.login" list zsh \ text "" name sid imports plugin_zsh_sid action auto \ text "" name dream imports plugin_you \ text "" name topic imports plugin_see \ - feature detail "prune" "复制" "下载" \ + feature detail "prune" "修改" "复制" "下载" \ exports zsh_sid sid \ - button "查看" action auto + button "查看" action auto \ + button "返回" cb Last -kit history "命令" private "web.code.trend" zsh history \ - text "10" name limit view tiny \ - text "0" name offset view tiny \ - text "times sids index cmd pwd" name fields \ - button "查看" action auto +kit history "命令" private "web.code.trend" list "zsh.history" \ + text "" name index imports plugin_zsh_history view tiny action auto \ + text "" name limit view tiny \ + text "" name offend view tiny \ + exports zsh_history id "" zsh_cmd cmd "" \ + button "查看" action auto \ + button "返回" cb Last -kit free "内存" private "web.code.trend" zsh free \ - text "10" name limit view tiny \ - text "0" name offset view tiny \ - text "times sids type total used free" name fields \ - button "查看" action auto +kit free "内存" private "web.code.trend" list "zsh.free" \ + text "" name index imports plugin_zsh_free view tiny action auto \ + text "" name limit view tiny \ + text "" name offend view tiny \ + exports zsh_free id \ + button "查看" action auto \ + button "返回" cb Last -kit env "环境" private "web.code.state" zsh env \ +kit env "环境" private "web.code.state" list zsh env \ text "" name sid imports plugin_zsh_sid action auto \ - text "name" name limit view tiny \ - text "" name offset view tiny \ - text "sids name value" name fields \ + text "name" name match view tiny \ + text "" name value view tiny \ button "查看" action auto -kit ps "进程" private "web.code.state" zsh ps \ +kit ps "进程" private "web.code.state" list zsh ps \ text "" name sid imports plugin_zsh_sid action auto \ - text "COMMAND" name limit view tiny \ - text "" name offset view tiny \ - text "sids PID TIME COMMAND" name fields \ + text "PPID" name match view tiny \ + text "" name value view tiny \ button "查看" action auto -kit df "磁盘" private "web.code.state" zsh df \ +kit df "磁盘" private "web.code.state" list zsh df \ text "" name sid imports plugin_zsh_sid action auto \ - text "fs" name limit view tiny \ - text "" name offset view tiny \ - text "sids fs size used rest per pos" name fields \ + text "fs" name match view tiny \ + text "" name value view tiny \ button "查看" action auto diff --git a/usr/librarys/example.js b/usr/librarys/example.js index faf61eac..0ead3aed 100644 --- a/usr/librarys/example.js +++ b/usr/librarys/example.js @@ -1495,6 +1495,7 @@ function Output(plugin, type, msg, cb, target, option) { }) var cmd = [] option.dream && cmd.push(option.dream.value) + option.table && cmd.push(option.table.value) if (item == "修改") { text = kit.AppendChilds(td, [{type: "input", value: text, style: {width: td.clientWidth+"px"}, data: {onkeydown: function(event) { if (event.key == "Enter") { diff --git a/usr/local/wiki/miss.md b/usr/local/wiki/miss.md index 330b0a95..4f582172 100644 --- a/usr/local/wiki/miss.md +++ b/usr/local/wiki/miss.md @@ -2,6 +2,8 @@ {{runs "help"}} +命令 参数 选项 配置 + ## 消息队列 ## 应用开发