1
0
mirror of https://shylinux.com/x/ContextOS synced 2025-04-25 16:58:06 +08:00
This commit is contained in:
shaoying 2019-11-23 20:28:06 +08:00
parent 39e7945187
commit 048ccaec34
15 changed files with 434 additions and 421 deletions

View File

@ -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

View File

@ -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("<afile>")})
call ShySend({"cmd": a:target, "arg": expand("<afile>")})
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 <C-g><C-g> :call ShyGrep(expand("<cword>"))<CR>
" nnoremap <C-g><C-t> :call ShyTag(expand("<cword>"))<CR>
nnoremap <C-g><C-t> :call ShyTask()<CR>
nnoremap <C-g><C-r> :call ShyCheck("cache")<CR>
nnoremap <C-g><C-f> :call ShyFavor("note")<CR>
nnoremap <C-g>f :call ShyFavor("")<CR>
nnoremap <C-g>F :call ShyFavors()<CR>
"
" command! ShyHelp echo ShyPost({"cmd": "help"})
"
" nnoremap <C-g><C-g> :call ShyGrep(expand("<cword>"))<CR>
" " nnoremap <C-g><C-t> :call ShyTag(expand("<cword>"))<CR>
" nnoremap <C-g><C-t> :call ShyTask()<CR>
" nnoremap <C-g><C-r> :call ShyCheck("cache")<CR>
" nnoremap <C-g><C-f> :call ShyFavor("note")<CR>
" nnoremap <C-g>f :call ShyFavor("")<CR>
" nnoremap <C-g>F :call ShyFavors()<CR>
"
" autocmd BufUnload * call Shy("close", expand("<afile>")) | call ShySync("bufs")
" autocmd CmdlineLeave *
" autocmd CompleteDone * call Shy("sync", "regs")

View File

@ -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

View File

@ -28,6 +28,6 @@
# 终端配置
~cli
~code
~wiki
~chat
~code

View File

@ -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)

View File

@ -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)
}

View File

@ -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)
}
})

View File

@ -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()

View File

@ -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(`<a href="/download/%s" target="_blank">%s</a>`, 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(`<a href="/download/%s" target="_blank">%s</a>`, 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(`<a href="/download/%s" target="_blank">%s</a>`, 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)
}

View File

@ -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(`<a href="/download/%s" target="_blank">%s</a>`, 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")}, "")

View File

@ -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]}

View File

@ -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 \

View File

@ -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

View File

@ -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") {

View File

@ -2,6 +2,8 @@
{{runs "help"}}
命令 参数 选项 配置
## 消息队列
## 应用开发