From e73ac8b419e7497d2d59e6e1387b0794e4330ae0 Mon Sep 17 00:00:00 2001 From: shaoying Date: Wed, 6 Nov 2019 03:30:15 +0800 Subject: [PATCH] add auto.vim --- Makefile | 2 +- bin/boot.sh | 9 +- etc/conf/auto.vim | 36 +++ etc/conf/tmux.conf | 4 + etc/conf/vimrc | 3 + etc/exit.shy | 2 + etc/init.shy | 4 + src/contexts/cli/version.go | 2 +- src/contexts/ctx/ctx.go | 2 +- src/contexts/ctx/type.go | 44 +++- src/contexts/ssh/ssh.go | 3 +- src/contexts/web/web.go | 5 +- src/examples/chat/chat.go | 2 +- src/examples/code/code.go | 272 ++++++++++++++++++-- src/examples/mall/mall.go | 45 +++- src/examples/team/team.go | 474 +--------------------------------- src/examples/trash/team.go | 485 +++++++++++++++++++++++++++++++++++ src/extend/shy.go | 4 +- src/plugin/docker/index.shy | 20 +- src/plugin/storage/index.shy | 19 -- src/plugin/task/index.css | 3 + src/plugin/task/index.go | 36 +++ src/plugin/task/index.js | 3 + src/plugin/task/index.shy | 14 + usr/librarys/chat.js | 9 +- usr/librarys/context.js | 8 +- usr/librarys/example.css | 1 + usr/librarys/example.js | 99 +++---- 28 files changed, 1027 insertions(+), 583 deletions(-) create mode 100644 etc/conf/auto.vim create mode 100644 src/examples/trash/team.go create mode 100644 src/plugin/task/index.css create mode 100644 src/plugin/task/index.go create mode 100644 src/plugin/task/index.js create mode 100644 src/plugin/task/index.shy diff --git a/Makefile b/Makefile index dad2afc7..12972512 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ prepare: @go get gopkg.in/gomail.v2 linux: - GOOS=linux $(BUILD)$(TARGET).linux.$(shell go env GOARCH) $(BENCH) + GOPATH=$(PWD):$(GOPATH) GOOS=linux $(BUILD)$(TARGET).linux.$(shell go env GOARCH) $(BENCH) linux_arm: GOARCH=arm GOOS=linux $(BUILD)$(TARGET).linux.arm $(BENCH) linux32: diff --git a/bin/boot.sh b/bin/boot.sh index a62d17e9..348c30cc 100755 --- a/bin/boot.sh +++ b/bin/boot.sh @@ -48,14 +48,18 @@ install() { echo echo - wget -O ${ctx_app} "$ctx_dev/publish/bench?GOOS=$GOOS&GOARCH=$GOARCH" && chmod a+x ${ctx_app} || return + + + which wget && get="wget -q -O" || get="curl -o" + $get ${ctx_app} "$ctx_dev/publish/bench?GOOS=$GOOS&GOARCH=$GOARCH" && chmod a+x ${ctx_app} || return target=install && [ -n "$1" ] && target=$1 - ${md5} ${ctx_app} && ./${ctx_app} upgrade ${target} || return + ${md5} ${ctx_app} && $(pwd)/${ctx_app} upgrade ${target} || return mv ${ctx_app} bin/${ctx_app} # && bin/boot.sh } + main() { trap HUP hup log "\nstarting..." @@ -91,6 +95,7 @@ case $1 in echo " term 停止服务" ;; install) shift && install "$@";; + installs) shift && install "$@" && bin/boot.sh ;; start) shift && main "$@";; "") main "$@";; create) mkdir -p $2; cd $2 && shift && shift && main "$@";; diff --git a/etc/conf/auto.vim b/etc/conf/auto.vim new file mode 100644 index 00000000..e0436d11 --- /dev/null +++ b/etc/conf/auto.vim @@ -0,0 +1,36 @@ +let ctx_dev = (len($ctx_dev) > 1? $ctx_dev: "http://localhost:9095") . "/code/vim" + +fun! ShyPost(arg) + return system("curl -s '" . g:ctx_dev . "' -H 'Content-Type: application/json' -d '" . json_encode(a:arg) . "' 2>/dev/null") +endfun + +fun! Shy(action, target) + let arg = {"arg": a:target, "cmd": a:action, "pwd": getcwd(), "pid": getpid(), "pane": $TMUX_PANE, "hostname": hostname(), "username": $USER} + if a:action == "sync" + let cmd = {"tags": "tags", "bufs": "buffers", "regs": "registers", "marks": "marks"} + let arg[a:target] = execute(cmd[a:target]) + endif + + let cmd = ShyPost(arg) + if cmd != "" + let arg["res"] = execute(cmd) + let res = ShyPost(arg) + endif +endfun + +autocmd BufReadPost * call Shy("read", expand("")) +autocmd BufWritePre * call Shy("write", expand("")) +autocmd BufUnload * call Shy("close", expand("")) + +autocmd BufWritePost * call Shy("sync", "regs") +autocmd BufWritePost * call Shy("sync", "bufs") +autocmd BufWritePost * call Shy("sync", "tags") + +" autocmd BufWinEnter * call Shy("enter", expand("")) +" autocmd WinEnter * call Shy("enter", expand("")) +" autocmd WinLeave * call Shy("leave", expand("")) +" +" autocmd InsertEnter * call Shy("line", getcurpos()[1]) +" autocmd CursorMoved * call Shy("line", getcurpos()[1]) + +" autocmd InsertCharPre * call Shy("char", v:char) diff --git a/etc/conf/tmux.conf b/etc/conf/tmux.conf index ba1fe12f..ffe37439 100644 --- a/etc/conf/tmux.conf +++ b/etc/conf/tmux.conf @@ -72,6 +72,10 @@ bind C-d clear-history bind \; paste-buffer bind r choose-buffer +bind a paste-buffer +bind -t vi-copy s begin-selection +bind -t vi-copy a copy-selection + # }}} # 命令管理{{{ bind Space command-prompt diff --git a/etc/conf/vimrc b/etc/conf/vimrc index 63aafe47..663fc319 100644 --- a/etc/conf/vimrc +++ b/etc/conf/vimrc @@ -218,6 +218,9 @@ endfunction highlight Comment cterm=reverse ctermfg=yellow +source ~/context/etc/conf/auto.vim + + " autocmd BufReadPost * call BenchCode("counter", ["nopen", 1]) " autocmd BufWritePost * call BenchCode("counter", ["nsave", 1]) "}}} diff --git a/etc/exit.shy b/etc/exit.shy index 814f280f..d2612bdb 100644 --- a/etc/exit.shy +++ b/etc/exit.shy @@ -1,3 +1,5 @@ +~code + config save var/tmp/vim.json vim ~ssh config save var/data/flow.json flow config save var/data/work.json work diff --git a/etc/init.shy b/etc/init.shy index eb43e308..dc1cc88c 100644 --- a/etc/init.shy +++ b/etc/init.shy @@ -14,5 +14,9 @@ ~nfs source local.shy +~code + config load tmp/vim.json vim + ~cli + diff --git a/src/contexts/cli/version.go b/src/contexts/cli/version.go index b9074099..e13405cb 100644 --- a/src/contexts/cli/version.go +++ b/src/contexts/cli/version.go @@ -7,5 +7,5 @@ var version = struct { self int }{ []string{"2017-11-01 01:02:03", "2019-07-13 18:02:21"}, - `2019-11-03 00:13:51`, `mac`, 659, + `2019-11-04 11:25:56`, `centos`, 655, } diff --git a/src/contexts/ctx/ctx.go b/src/contexts/ctx/ctx.go index 7c79e8b7..9a9795bf 100644 --- a/src/contexts/ctx/ctx.go +++ b/src/contexts/ctx/ctx.go @@ -31,7 +31,7 @@ func (ctx *CTX) Begin(m *Message, arg ...string) Server { m.Option("table.offset", 0) m.Option("table.format", "object") m.Optionv("ctx.form", map[string]int{ - "table.limit": 1, "table.offset": 1, "table.format": 1, + "table.format": 1, "table.offset": 1, "table.limit": 1, }) m.root = m diff --git a/src/contexts/ctx/type.go b/src/contexts/ctx/type.go index 8ba6ad1e..ba4dc843 100644 --- a/src/contexts/ctx/type.go +++ b/src/contexts/ctx/type.go @@ -313,6 +313,48 @@ func (m *Message) Sort(key string, arg ...string) *Message { } return m } +func (m *Message) Split(str string, arg ...string) *Message { + c := byte(kit.Select(" ", arg, 0)[0]) + + lines := strings.Split(str, "\n") + + pos := []int{} + heads := []string{} + if h := kit.Select("", arg, 2); h != "" { + heads = strings.Split(h, " ") + } else { + h, lines = lines[0], lines[1:] + v := kit.Trans(m.Optionv("cmd_headers")) + for i := 0; i < len(v)-1; i += 2 { + h = strings.Replace(h, v[i], v[i+1], 1) + } + + heads = kit.Split(h, c, kit.Int(kit.Select("-1", arg, 1))) + for _, v := range heads { + pos = append(pos, strings.Index(h, v)) + } + } + + for _, l := range lines { + if len(pos) > 0 { + for i, v := range pos { + if len(l) < v { + m.Add("append", heads[i], "") + } else if i == len(pos)-1 { + m.Add("append", heads[i], l[v:]) + } else { + m.Add("append", heads[i], l[v:pos[i+1]]) + } + } + continue + } + for i, v := range kit.Split(l, c, len(heads)) { + m.Add("append", heads[i], v) + } + } + m.Table() + return m +} func (m *Message) Limit(offset, limit int) *Message { l := len(m.Meta[m.Meta["append"][0]]) if offset < 0 { @@ -613,7 +655,7 @@ func (m *Message) Cmd(args ...interface{}) *Message { } else if strings.Contains(key, ".") { arg := strings.Split(key, ".") - if msg, key = m.Sess(arg[0]), arg[1]; msg != nil { + if msg, key = m.Sess(arg[0]), arg[1]; len(arg) == 2 && msg != nil { msg.Option("remote_code", "") } else if msg, key = m.Find(strings.Join(arg[0:len(arg)-1], "."), true), arg[len(arg)-1]; msg != nil { diff --git a/src/contexts/ssh/ssh.go b/src/contexts/ssh/ssh.go index eda6f618..e545ad37 100644 --- a/src/contexts/ssh/ssh.go +++ b/src/contexts/ssh/ssh.go @@ -361,7 +361,8 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", args = append(args, msg.Parse(v)) } } - msg.Cmd(tool["cmd"], args, arg).CopyTo(m) + msg.Cmd(tool["cmd"], args, arg) + msg.CopyTo(m) default: m.Confm("componet", arg[0:], func(value map[string]interface{}) { diff --git a/src/contexts/web/web.go b/src/contexts/web/web.go index 90b272fa..344bd099 100644 --- a/src/contexts/web/web.go +++ b/src/contexts/web/web.go @@ -207,8 +207,11 @@ func (web *WEB) HandleCmd(m *ctx.Message, key string, cmd *ctx.Command) { switch r.Header.Get("Content-Type") { case "application/json": var data interface{} - json.NewDecoder(r.Body).Decode(&data) + if e := json.NewDecoder(r.Body).Decode(&data); e != nil { + m.Log("warn", "%v", e) + } msg.Optionv("content_data", data) + m.Log("info", "%v", kit.Formats(data)) switch d := data.(type) { case map[string]interface{}: diff --git a/src/examples/chat/chat.go b/src/examples/chat/chat.go index 70d9a32c..032a31f4 100644 --- a/src/examples/chat/chat.go +++ b/src/examples/chat/chat.go @@ -426,7 +426,7 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心", m.Push("node", value["user"]) }) m.Confm("ssh.node", func(key string, value map[string]interface{}) { - m.Push("user", "") + m.Push("user", value["type"]) m.Push("node", value["name"]) }) m.Table() diff --git a/src/examples/code/code.go b/src/examples/code/code.go index 50ad0c95..2d478e4a 100644 --- a/src/examples/code/code.go +++ b/src/examples/code/code.go @@ -3,6 +3,8 @@ package code import ( "contexts/ctx" "contexts/web" + "os" + "os/exec" "path" "regexp" "strings" @@ -13,6 +15,14 @@ import ( var Index = &ctx.Context{Name: "code", Help: "代码中心", Caches: map[string]*ctx.Cache{}, Configs: map[string]*ctx.Config{ + "login": &ctx.Config{Name: "login", Value: map[string]interface{}{"check": false, "local": true, "expire": "720h"}, Help: "用户登录"}, + "package": {Name: "package", Help: "软件包", Value: map[string]interface{}{ + "udpate": []interface{}{"apk", "update"}, + "install": []interface{}{"apk", "add"}, + "build": []interface{}{"build-base"}, + "develop": []interface{}{"zsh", "tmux", "git", "vim", "golang"}, + "product": []interface{}{"nginx", "redis", "mysql"}, + }}, "docker": {Name: "docker", Help: "容器", Value: map[string]interface{}{ "shy": ` FROM {{options . "base"}} @@ -26,35 +36,39 @@ CMD sh bin/boot.sh `, }}, + "git": {Name: "git", Help: "记录", Value: map[string]interface{}{ + "alias": map[string]interface{}{ + "s": "status", + }, + }}, + "vim": {Name: "vim", Help: "记录", Value: map[string]interface{}{ + "opens": map[string]interface{}{}, + }}, }, Commands: map[string]*ctx.Command{ "zsh": {Name: "zsh dir grep key [split reg fields] [filter reg fields] [order key method] [group keys method] [sort keys method]", - Form: map[string]int{"split": 2, "filter": 2, "order": 2, "group": 2, "sort": 2}, + Form: map[string]int{"split": 2, "filter": 2, "order": 2, "group": 2, "sort": 2, "limit": 2}, Help: "终端", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { p, arg := kit.Select(".", arg[0]), arg[1:] switch arg[0] { case "init": - m.Cmd("cli.system", "apk", "update") - switch arg[1] { - case "build": - m.Cmd("cli.system", "apk", "add", "nginx") - m.Cmd("cli.system", "apk", "add", "redis") - m.Cmd("cli.system", "apk", "add", "tmux") - m.Cmd("cli.system", "apk", "add", "zsh") - m.Cmd("cli.system", "apk", "add", "git") - m.Cmd("cli.system", "apk", "add", "vim") - m.Cmd("cli.system", "apk", "add", "build-base") - m.Cmd("cli.system", "apk", "add", "golang") - m.Cmd("cli.system", "apk", "add", "mysql") + m.Cmd("cli.system", m.Confv("package", "upadte")) + for _, v := range kit.View(arg[1:], m.Confm("package")) { + m.Cmd("cli.system", m.Confv("package", "install"), v) } case "list": m.Cmdy("nfs.dir", p, "time", "size", "path") case "find": - m.Cmdy("cli.system", "find", p, "-name", arg[1]) + m.Cmdy("cli.system", "find", p, "-name", arg[1], "cmd_parse", "cut", "", "1", "path") + + case "tail": + m.Cmdy("cli.system", "tail", path.Join(p, arg[1])) case "grep": + s, _ := os.Stat(p) + prefix := []string{"cli.system", "grep", "-rn", arg[1], p, "cmd_parse", "cut", ":", kit.Select("2", "3", s.IsDir()), kit.Select("line text", "path line text", s.IsDir())} if m.Options("split") { re, _ := regexp.Compile(kit.Select("", m.Optionv("split"), 0)) fields := map[string]bool{} @@ -64,7 +78,7 @@ CMD sh bin/boot.sh } } - m.Cmd("cli.system", "grep", "-rn", arg[1], p, "cmd_parse", "cut", ":", "3", "path line text").Table(func(index int, line map[string]string) { + m.Cmd(prefix).Table(func(index int, line map[string]string) { if ls := re.FindAllStringSubmatch(line["text"], -1); len(ls) > 0 { m.Push("path", line["path"]) m.Push("line", line["line"]) @@ -77,7 +91,7 @@ CMD sh bin/boot.sh }) m.Table() } else { - m.Cmdy("cli.system", "grep", "-rn", arg[1], p, "cmd_parse", "cut", ":", "3", "path line text") + m.Cmdy(prefix) } if m.Has("filter") { @@ -92,9 +106,9 @@ CMD sh bin/boot.sh if m.Has("sort") { m.Sort(kit.Select("", m.Optionv("sort"), 0), kit.Select("", m.Optionv("sort"), 1)) } - - case "tail": - m.Cmdy("cli.system", "tail", path.Join(p, arg[1])) + if m.Has("limit") { + m.Limit(kit.Int(kit.Select("0", m.Optionv("limit"), 0)), kit.Int(kit.Select("10", m.Optionv("limit"), 1))) + } default: m.Cmdy("cli.system", arg) @@ -177,7 +191,19 @@ CMD sh bin/boot.sh } } return - case "layout": + case "pane": + m.Cmdy(prefix, "list-panes", "-a", "cmd_parse", "cut", " ", "8", "pane_name size some lines bytes haha pane_id tag") + m.Meta["append"] = []string{"pane_id", "pane_name", "size", "lines", "bytes", "tag"} + m.Table(func(index int, value map[string]string) { + m.Meta["pane_name"][index] = strings.TrimSuffix(value["pane_name"], ":") + m.Meta["pane_id"][index] = strings.TrimPrefix(value["pane_id"], "%") + m.Meta["lines"][index] = strings.TrimSuffix(value["lines"], ",") + m.Meta["bytes"][index] = kit.FmtSize(kit.Int64(value["bytes"])) + }) + m.Sort("pane_name") + m.Table() + return + default: m.Cmdy(prefix, "send-keys", "-t", target, strings.Join(arg[3:], " "), "Enter") time.Sleep(1 * time.Second) @@ -267,7 +293,6 @@ CMD sh bin/boot.sh m.Cmd(prefix, "rename", arg[1], arg[4:]) } - // 删除容器 case "delete": m.Cmd(prefix, "rm", arg[1]) @@ -309,18 +334,215 @@ CMD sh bin/boot.sh return }}, "git": {Name: "git", Help: "版本", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - prefix := []string{"cli.system", "git"} + prefix, arg := []string{"cli.system", "git", "cmd_dir", kit.Select(".", arg[0])}, arg[1:] + switch arg[0] { case "init": - m.Cmdy(prefix, "config", "alias.s", "status") + m.Confm("git", "alias", func(key string, value string) { + m.Cmdy(prefix, "config", "alias."+key, value) + }) + case "diff": + m.Cmdy(prefix, "diff") + case "status": + m.Cmdy(prefix, "status", "-sb", "cmd_parse", "cut", " ", "2") + case "commit": + if m.Cmds(prefix, "commit", "-am") { + break + } + fallthrough + case "sum": + total := false + if len(arg) > 1 && arg[1] == "total" { + total, arg = true, arg[1:] + } + + args := []string{} + if args = append(args, "log", "--shortstat", "--pretty=commit: %ad %n%s", "--date=iso"); len(arg) > 1 { + args = append(args, "--reverse") + args = append(args, "--since") + args = append(args, arg[1:]...) + } else { + args = append(args, "-n", "30") + } + + var total_day time.Duration + count, count_add, count_del := 0, 0, 0 + if out, e := exec.Command("git", args...).CombinedOutput(); e == nil { + for i, v := range strings.Split(string(out), "commit: ") { + if i > 0 { + l := strings.Split(v, "\n") + hs := strings.Split(l[0], " ") + + add, del := "0", "0" + if len(l) > 3 { + fs := strings.Split(strings.TrimSpace(l[3]), ", ") + if adds := strings.Split(fs[1], " "); len(fs) > 2 { + dels := strings.Split(fs[2], " ") + add = adds[0] + del = dels[0] + } else if adds[1] == "insertions(+)" { + add = adds[0] + } else { + del = adds[0] + } + } + + if total { + if count++; i == 1 { + if t, e := time.Parse("2006-01-02", hs[0]); e == nil { + total_day = time.Now().Sub(t) + m.Append("from", hs[0]) + } + } + count_add += kit.Int(add) + count_del += kit.Int(del) + continue + } + + m.Push("date", hs[0]) + m.Push("adds", add) + m.Push("dels", del) + m.Push("rest", kit.Int(add)-kit.Int(del)) + m.Push("note", l[1]) + m.Push("hour", strings.Split(hs[1], ":")[0]) + m.Push("time", hs[1]) + } + } + if total { + m.Append("days", int(total_day.Hours())/24) + m.Append("commit", count) + m.Append("adds", count_add) + m.Append("dels", count_del) + m.Append("rest", count_add-count_del) + } + m.Table() + } else { + m.Log("warn", "%v", string(out)) + } + + default: + m.Cmdy(prefix, arg) } - m.Echo("git") return }}, "vim": {Name: "vim", Help: "编辑器", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - m.Echo("vim") + switch arg[0] { + case "opens": + m.Confm("vim", "opens", func(key string, value map[string]interface{}) { + m.Push("time", value["time"]) + m.Push("action", value["action"]) + m.Push("file", value["file"]) + m.Push("pid", value["pid"]) + m.Push("pane", value["pane"]) + m.Push("hostname", value["hostname"]) + m.Push("username", value["username"]) + }) + m.Sort("time", "time_r").Table() + case "bufs": + m.Confm("vim", "buffer", func(key string, index int, value map[string]interface{}) { + m.Push("id", value["id"]) + m.Push("name", value["name"]) + m.Push("line", value["line"]) + m.Push("hostname", value["hostname"]) + m.Push("username", value["username"]) + }) + m.Table() + case "regs": + m.Confm("vim", "register", func(key string, index int, value map[string]interface{}) { + m.Push("name", value["name"]) + m.Push("text", value["text"]) + m.Push("hostname", value["hostname"]) + m.Push("username", value["username"]) + }) + m.Table() + case "tags": + m.Confm("vim", "tag", func(key string, index int, value map[string]interface{}) { + m.Push("tag", value["tag"]) + m.Push("line", value["line"]) + m.Push("file", value["in file/text"]) + m.Push("hostname", value["hostname"]) + m.Push("username", value["username"]) + }) + m.Table() + } return }}, + "/vim": {Name: "/vim", Help: "编辑器", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + if !m.Has("res") { + switch m.Option("cmd") { + case "read", "enter", "leave", "write", "close", "unload": + file := m.Option("arg") + if !path.IsAbs(m.Option("arg")) { + file = path.Join(m.Option("pwd"), m.Option("arg")) + } + + name := kit.Hashs(file, m.Option("hostname"), m.Option("username")) + m.Conf("vim", []string{"opens", name, "path"}, file) + m.Conf("vim", []string{"opens", name, "file"}, m.Option("arg")) + m.Conf("vim", []string{"opens", name, "time"}, m.Time()) + m.Conf("vim", []string{"opens", name, "action"}, m.Option("cmd")) + m.Conf("vim", []string{"opens", name, "pid"}, m.Option("pid")) + m.Conf("vim", []string{"opens", name, "pwd"}, m.Option("pwd")) + m.Conf("vim", []string{"opens", name, "pane"}, m.Option("pane")) + m.Conf("vim", []string{"opens", name, "hostname"}, m.Option("hostname")) + m.Conf("vim", []string{"opens", name, "username"}, m.Option("username")) + return + case "sync": + switch m.Option("arg") { + case "tags": + name := kit.Hashs(m.Option("hostname"), m.Option("username")) + m.Conf("vim", []string{"tag", name}, "") + + m.Split(strings.TrimPrefix(m.Option("tags"), "\n"), " ", "6").Table(func(index int, value map[string]string) { + m.Conf("vim", []string{"tag", name, "-1"}, map[string]interface{}{ + "hostname": m.Option("hostname"), + "username": m.Option("username"), + "tag": value["tag"], + "line": value["line"], + "in file/text": value["in file/text"], + }) + }) + m.Set("append").Set("result") + case "bufs": + name := kit.Hashs(m.Option("hostname"), m.Option("username")) + m.Conf("vim", []string{"buffer", name}, "") + + m.Split(m.Option("bufs"), " ", "5", "id tag name some line").Table(func(index int, value map[string]string) { + m.Conf("vim", []string{"buffer", name, "-1"}, map[string]interface{}{ + "hostname": m.Option("hostname"), + "username": m.Option("username"), + "id": value["id"], + "name": value["name"], + "line": value["line"], + }) + }) + m.Set("append").Set("result") + case "regs": + name := kit.Hashs(m.Option("hostname"), m.Option("username")) + m.Conf("vim", []string{"register", name}, "") + + m.Split(strings.TrimPrefix(m.Option("regs"), "\n--- Registers ---\n"), " ", "2", "name text").Table(func(index int, value map[string]string) { + m.Conf("vim", []string{"register", name, "-1"}, map[string]interface{}{ + "hostname": m.Option("hostname"), + "username": m.Option("username"), + "text": strings.Replace(strings.Replace(value["text"], "^I", "\t", -1), "^J", "\n", -1), + "name": strings.TrimPrefix(value["name"], "\""), + }) + }) + m.Set("append").Set("result") + } + return + default: + return + } + } + + switch m.Option("cmd") { + case "read", "enter", "leave", "write": + } + return + + }}, }, } diff --git a/src/examples/mall/mall.go b/src/examples/mall/mall.go index 1fc7ba97..c549944b 100644 --- a/src/examples/mall/mall.go +++ b/src/examples/mall/mall.go @@ -3,16 +3,49 @@ package mall import ( "contexts/ctx" "contexts/web" + "toolkit" ) var Index = &ctx.Context{Name: "mall", Help: "交易中心", - Caches: map[string]*ctx.Cache{}, - Configs: map[string]*ctx.Config{}, - Commands: map[string]*ctx.Command{}, + Caches: map[string]*ctx.Cache{}, + Configs: map[string]*ctx.Config{}, + Commands: map[string]*ctx.Command{ + "salary": {Name: "salary table month total base tax", Help: "工资", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + if len(arg) < 3 || arg[2] == "" { + m.Cmdy("ssh.data", "show", arg[0], "fields", "id", "month", + "total", "base", "zhu", "old", "bad", "mis", "tax", "rest") + return + } + + total := kit.Int(arg[2]) + base := kit.Int(kit.Select(arg[2], arg, 3)) + tax := kit.Int(kit.Select("0", arg, 4)) + + zhu := base * 120 / 1000 + if len(arg) > 5 { + zhu = kit.Int(arg[5]) + } + old := base * 80 / 1000 + if len(arg) > 6 { + old = kit.Int(arg[6]) + } + bad := base * 20 / 1000 + if len(arg) > 7 { + bad = kit.Int(arg[7]) + } + mis := base * 5 / 1000 + if len(arg) > 8 { + mis = kit.Int(arg[8]) + } + + rest := total - zhu - old - bad - mis - tax + m.Cmdy("ssh.data", "insert", arg[0], "month", arg[1], "total", total, "base", base, "tax", + tax, "zhu", zhu, "old", old, "bad", bad, "mis", mis, "rest", rest) + return + }}, + }, } func init() { - mall := &web.WEB{} - mall.Context = Index - web.Index.Register(Index, mall) + web.Index.Register(Index, &web.WEB{Context: Index}) } diff --git a/src/examples/team/team.go b/src/examples/team/team.go index ed1eb2a4..4e702a06 100644 --- a/src/examples/team/team.go +++ b/src/examples/team/team.go @@ -3,483 +3,23 @@ package team import ( "contexts/ctx" "contexts/web" - "fmt" - "path" - "plugin" - "runtime" - "strconv" - "strings" - "time" - "toolkit" ) var Index = &ctx.Context{Name: "team", Help: "团队中心", - Caches: map[string]*ctx.Cache{}, - Configs: map[string]*ctx.Config{ - "skip_login": &ctx.Config{Name: "skip_login", Value: map[string]interface{}{"/consul": "true"}, Help: "免密登录"}, - "componet": &ctx.Config{Name: "componet", Value: map[string]interface{}{ - "login": []interface{}{ - map[string]interface{}{"componet_name": "code", "componet_tmpl": "head", "metas": []interface{}{ - map[string]interface{}{"name": "viewport", "content": "width=device-width, initial-scale=0.7, user-scalable=no"}, - }, "favicon": "favicon.ico", "styles": []interface{}{"example.css", "code.css"}}, - - map[string]interface{}{"componet_name": "login", "componet_help": "login", - "componet_tmpl": "componet", "componet_init": "initLogin", - "componet_ctx": "aaa", "componet_cmd": "auth", "componet_args": []interface{}{"@sessid", "ship", "username", "@username", "password", "@password"}, "inputs": []interface{}{ - map[string]interface{}{"type": "text", "name": "username", "value": "", "label": "username"}, - map[string]interface{}{"type": "password", "name": "password", "value": "", "label": "password"}, - map[string]interface{}{"type": "button", "value": "login"}, - }, - "display_append": "", "display_result": "", - }, - - map[string]interface{}{"componet_name": "tail", "componet_tmpl": "tail", - "scripts": []interface{}{"toolkit.js", "context.js", "example.js", "code.js"}, - }, - }, - "flash": []interface{}{ - map[string]interface{}{"componet_name": "flash", "componet_tmpl": "head", "metas": []interface{}{ - map[string]interface{}{"name": "viewport", "content": "width=device-width, initial-scale=0.7, user-scalable=no"}, - }, "favicon": "favicon.ico", "styles": []interface{}{"example.css", "code.css"}}, - - map[string]interface{}{"componet_name": "ask", "componet_help": "ask", "componet_tmpl": "componet", - "componet_view": "FlashText", "componet_init": "initFlashText", - "componet_ctx": "web.code", "componet_cmd": "flash", "componet_args": []interface{}{"text", "@text"}, "inputs": []interface{}{ - map[string]interface{}{"type": "textarea", "name": "text", "value": "", "cols": 50, "rows": 5}, - map[string]interface{}{"type": "button", "value": "添加请求"}, - }, - "display_result": "", "display_append": "", - }, - map[string]interface{}{"componet_name": "tip", "componet_help": "tip", "componet_tmpl": "componet", - "componet_view": "FlashList", "componet_init": "initFlashList", - "componet_ctx": "web.code", "componet_cmd": "flash", - "display_result": "", "display_append": "", - }, - - map[string]interface{}{"componet_name": "tail", "componet_tmpl": "tail", - "scripts": []interface{}{"toolkit.js", "context.js", "example.js", "code.js"}, - }, - }, - "schedule": []interface{}{ - map[string]interface{}{"componet_name": "flash", "componet_tmpl": "head", "metas": []interface{}{ - map[string]interface{}{"name": "viewport", "content": "width=device-width, initial-scale=0.7, user-scalable=no"}, - }, "favicon": "favicon.ico", "styles": []interface{}{"example.css", "code.css"}}, - - map[string]interface{}{"componet_name": "com", "componet_help": "com", "componet_tmpl": "componet", - "componet_view": "ComList", "componet_init": "initComList", - "componet_ctx": "web.code", "componet_cmd": "componet", "componet_args": []interface{}{"share", "@role", "@componet_group", "@tips"}, "inputs": []interface{}{ - map[string]interface{}{"type": "text", "name": "role", "value": "tech", "label": "role"}, - map[string]interface{}{"type": "text", "name": "tips", "value": "schedule", "label": "tips"}, - map[string]interface{}{"type": "button", "value": "共享页面"}, - }, - }, - - map[string]interface{}{"componet_name": "text", "componet_help": "text", "componet_tmpl": "componet", - "componet_view": "ScheduleText", "componet_init": "initScheduleText", - "componet_ctx": "web.code", "componet_cmd": "schedule", - "componet_args": []interface{}{"@time", "@name", "@place"}, "inputs": []interface{}{ - map[string]interface{}{"type": "text", "name": "time", "value": "", "label": "time"}, - map[string]interface{}{"type": "text", "name": "name", "value": "", "label": "name"}, - map[string]interface{}{"type": "text", "name": "place", "value": "", "label": "place"}, - map[string]interface{}{"type": "button", "value": "添加行程"}, - }, - "display_result": "", "display_append": "", - }, - map[string]interface{}{"componet_name": "list", "componet_help": "list", "componet_tmpl": "componet", - "componet_view": "ScheduleList", "componet_init": "initScheduleList", - "componet_ctx": "web.code", "componet_cmd": "schedule", - "inputs": []interface{}{ - map[string]interface{}{"type": "choice", "name": "view", "value": "default", "label": "显示字段", "choice": []interface{}{ - map[string]interface{}{"name": "默认", "value": "default"}, - map[string]interface{}{"name": "行程", "value": "order"}, - map[string]interface{}{"name": "总结", "value": "summary"}, - }}, - map[string]interface{}{"type": "button", "value": "刷新行程"}, - }, - "display_result": "", - }, - - map[string]interface{}{"componet_name": "tail", "componet_tmpl": "tail", - "scripts": []interface{}{"toolkit.js", "context.js", "example.js", "code.js"}, - }, - }, - "index": []interface{}{ - map[string]interface{}{"componet_name": "code", "componet_tmpl": "head", "metas": []interface{}{ - map[string]interface{}{"name": "viewport", "content": "width=device-width, initial-scale=0.7, user-scalable=no"}, - }, "favicon": "favicon.ico", "styles": []interface{}{"example.css", "code.css"}}, - map[string]interface{}{"componet_name": "banner", "componet_help": "banner", "componet_tmpl": "banner", - "componet_view": "Banner", "componet_init": "initBanner", - }, - - map[string]interface{}{"componet_name": "toolkit", "componet_help": "Ctrl+B", "componet_tmpl": "toolkit", - "componet_view": "KitList", "componet_init": "initKitList", - }, - // map[string]interface{}{"componet_name": "login", "componet_help": "login", "componet_tmpl": "componet", - // "componet_ctx": "aaa", "componet_cmd": "login", "componet_args": []interface{}{"@username", "@password"}, - // "inputs": []interface{}{ - // map[string]interface{}{"type": "text", "name": "username", "label": "username"}, - // map[string]interface{}{"type": "password", "name": "password", "label": "password"}, - // map[string]interface{}{"type": "button", "value": "login"}, - // }, - // "display_append": "", "display_result": "", - // }, - // map[string]interface{}{"componet_name": "userinfo", "componet_help": "userinfo", "componet_tmpl": "componet", - // "componet_ctx": "aaa", "componet_cmd": "login", "componet_args": []interface{}{"@sessid"}, - // "pre_run": true, - // }, - map[string]interface{}{"componet_name": "buffer", "componet_help": "buffer", "componet_tmpl": "componet", - "componet_view": "BufList", "componet_init": "initBufList", - "componet_ctx": "cli", "componet_cmd": "tmux", "componet_args": []interface{}{"buffer"}, "inputs": []interface{}{ - map[string]interface{}{"type": "text", "name": "limit", "value": "3", "label": "limit"}, - map[string]interface{}{"type": "text", "name": "index", "value": "0", "label": "index"}, - map[string]interface{}{"type": "button", "value": "refresh"}, - }, - "pre_run": true, - }, - map[string]interface{}{"componet_name": "dir", "componet_help": "dir", "componet_tmpl": "componet", - "componet_view": "DirList", "componet_init": "initDirList", - "componet_ctx": "nfs", "componet_cmd": "dir", "componet_args": []interface{}{"@dir", "dir_sort", "@sort_field", "@sort_order"}, "inputs": []interface{}{ - map[string]interface{}{"type": "choice", "name": "dir_type", "value": "both", "label": "dir_type", "choice": []interface{}{ - map[string]interface{}{"name": "all", "value": "all"}, - map[string]interface{}{"name": "both", "value": "both"}, - map[string]interface{}{"name": "file", "value": "file"}, - map[string]interface{}{"name": "dir", "value": "dir"}, - }}, - map[string]interface{}{"type": "text", "name": "dir", "value": "@current.dir", "label": "dir"}, - map[string]interface{}{"type": "button", "value": "refresh"}, - }, - "pre_run": false, "display_result": "", - }, - map[string]interface{}{"componet_name": "upload", "componet_help": "upload", "componet_tmpl": "componet", - "componet_view": "PutFile", "componet_init": "initPutFile", - "componet_ctx": "web", "componet_cmd": "upload", "form_type": "upload", "inputs": []interface{}{ - map[string]interface{}{"type": "file", "name": "upload"}, - map[string]interface{}{"type": "submit", "value": "submit"}, - }, - "display_result": "", - }, - map[string]interface{}{"componet_name": "pod", "componet_help": "pod", "componet_tmpl": "componet", - "componet_view": "PodList", "componet_init": "initPodList", - "componet_ctx": "ssh", "componet_cmd": "node", "inputs": []interface{}{ - map[string]interface{}{"type": "text", "name": "pod", "value": "@current.pod"}, - map[string]interface{}{"type": "button", "value": "refresh"}, - }, - "pre_run": true, "display_result": "", - }, - map[string]interface{}{"componet_name": "ctx", "componet_help": "ctx", "componet_tmpl": "componet", - "componet_view": "CtxList", "componet_init": "initCtxList", - "componet_pod": "true", "componet_ctx": "ssh", "componet_cmd": "context", "componet_args": []interface{}{"@ctx", "list"}, "inputs": []interface{}{ - map[string]interface{}{"type": "text", "name": "ctx", "value": "@current.ctx"}, - map[string]interface{}{"type": "button", "value": "refresh"}, - }, - "display_result": "", - }, - map[string]interface{}{"componet_name": "cmd", "componet_help": "cmd", "componet_tmpl": "componet", - "componet_view": "CmdList", "componet_init": "initCmdList", - "componet_ctx": "cli.shy", "componet_cmd": "source", "componet_args": []interface{}{"@cmd"}, "inputs": []interface{}{ - map[string]interface{}{"type": "text", "name": "cmd", "value": "", "class": "cmd", "clipstack": "void"}, - }, - }, - // map[string]interface{}{"componet_name": "mp", "componet_tmpl": "mp"}, - map[string]interface{}{"componet_name": "tail", "componet_tmpl": "tail", - "scripts": []interface{}{"toolkit.js", "context.js", "example.js", "code.js"}, - }, - }, - }, Help: "组件列表"}, - "componet_group": &ctx.Config{Name: "component_group", Value: "index", Help: "默认组件"}, - - "make": &ctx.Config{Name: "make", Value: map[string]interface{}{ - "go": map[string]interface{}{ - "build": []interface{}{"go", "build"}, - "plugin": []interface{}{"go", "build", "-buildmode=plugin"}, - "load": []interface{}{"load"}, - }, - "so": map[string]interface{}{ - "load": []interface{}{"load"}, - }, - }, Help: "免密登录"}, - - "flash": &ctx.Config{Name: "flash", Value: map[string]interface{}{ - "data": []interface{}{}, - "view": map[string]interface{}{"default": []interface{}{"index", "time", "text", "code", "output"}}, - }, Help: "闪存"}, - "schedule": &ctx.Config{Name: "schedule", Value: map[string]interface{}{ - "data": []interface{}{}, - "view": map[string]interface{}{ - "default": []interface{}{"面试时间", "面试公司", "面试地点", "面试轮次", "题目类型", "面试题目", "面试总结"}, - "summary": []interface{}{"面试公司", "面试轮次", "题目类型", "面试题目", "面试总结"}, - "order": []interface{}{"面试时间", "面试公司", "面试地点"}, - }, - "maps": map[string]interface{}{"baidu": "%s"}, - }, Help: "闪存"}, - - "counter": &ctx.Config{Name: "counter", Value: map[string]interface{}{ - "nopen": "0", "nsave": "0", - }, Help: "counter"}, - "counter_service": &ctx.Config{Name: "counter_service", Value: "http://localhost:9094/code/counter", Help: "counter"}, - }, + Caches: map[string]*ctx.Cache{}, + Configs: map[string]*ctx.Config{}, Commands: map[string]*ctx.Command{ - "make": &ctx.Command{Name: "make [action] file [args...]", Help: "更新代码", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - target, action, suffix := path.Join(m.Conf("runtime", "boot.ctx_home"), "src/examples/app/bench.go"), "build", "go" - if len(arg) == 0 { - arg = append(arg, target) - } - - if cs := strings.Split(arg[0], "."); len(cs) > 1 { - suffix = cs[len(cs)-1] - } else if cs := strings.Split(arg[1], "."); len(cs) > 1 { - action, suffix, arg = arg[0], cs[len(cs)-1], arg[1:] - } - - target = m.Cmdx("nfs.path", arg[0]) - if target == "" { - target = m.Cmdx("nfs.path", path.Join("src/plugin/", arg[0])) - } - - cook := m.Confv("make", []string{suffix, action}) - switch kit.Chains(cook, "0") { - case "load": - if suffix == "go" { - so := strings.Replace(target, ".go", ".so", -1) - m.Cmd("cli.system", m.Confv("make", "go.plugin"), "-o", so, target) - arg[0] = so - } - - if p, e := plugin.Open(arg[0]); m.Assert(e) { - s, e := p.Lookup("Index") - m.Assert(e) - w := *(s.(**ctx.Context)) - c.Register(w, nil, true) - } - default: - m.Cmdy("cli.system", cook, arg) - } - return - }}, - "flash": &ctx.Command{Name: "flash", Help: "闪存", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - total := len(m.Confv("flash", "data").([]interface{})) - // 查看列表 - if len(arg) == 0 { - if index := m.Option("flash_index"); index != "" { - arg = append(arg, index) - } else { - m.Confm("flash", "data", func(index int, item map[string]interface{}) { - for _, k := range kit.View([]string{}, m.Confm("flash", "view")) { - m.Add("append", k, kit.Format(item[k])) - } - }) - m.Table() - return - } - - } - - index, item := -1, map[string]interface{}{"time": m.Time()} - if i, e := strconv.Atoi(arg[0]); e == nil && 0 <= i && i < total { - // 查看索引 - index, arg = total-1-i, arg[1:] - if item = m.Confm("flash", []interface{}{"data", index}); len(arg) == 0 { - // 查看数据 - for _, k := range kit.View([]string{}, m.Confm("flash", "view")) { - m.Add("append", k, kit.Format(item[k])) - } - m.Table() - return e - } - } - - switch arg[0] { - case "vim": // 编辑数据 - name := m.Cmdx("nfs.temp", kit.Format(item[kit.Select("code", arg, 1)])) - m.Cmd("cli.system", "vi", name) - item[kit.Select("code", arg, 1)] = m.Cmdx("nfs.load", name) - m.Cmd("nfs.trash", name) - - case "run": // 运行代码 - code := kit.Format(item[kit.Select("code", arg, 1)]) - if code == "" { - break - } - name := m.Cmdx("nfs.temp", code) - m.Cmdy("cli.system", "python", name) - item["output"] = m.Result(0) - m.Cmd("nfs.trash", name) - - default: - // 修改数据 - for i := 0; i < len(arg)-1; i += 2 { - item[arg[i]] = arg[i+1] - } - m.Conf("flash", []interface{}{"data", index}, item) - item["index"] = total - 1 - index - m.Echo("%d", total-1-index) - } - - return - }}, - "schedule": &ctx.Command{Name: "schedule [time name place]", Help: "行程安排", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if len(arg) == 0 { // 会话列表 - m.Confm("schedule", "data", func(index int, value map[string]interface{}) { - for _, v := range kit.View([]string{m.Option("view")}, m.Confm("schedule", "view")) { - if v == "面试地点" { - m.Add("append", "面试地点", fmt.Sprintf(m.Conf("schedule", "maps.baidu"), value["面试地点"], value["面试地点"])) - continue - } - m.Add("append", v, kit.Format(value[v])) - } - }) - m.Table() + "task": {Name: "task table title content", Help: "任务", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + if len(arg) == 1 { + m.Cmdy("ssh.data", "show", arg[0], "fields", "id", "title", "content") return } - - view := "default" - if m.Confs("schedule", arg[0]) { - view, arg = arg[0], arg[1:] - } - - data := map[string]interface{}{} - for _, k := range kit.View([]string{view}, m.Confm("schedule", "view")) { - if len(arg) == 0 { - data[k] = "" - continue - } - data[k], arg = arg[0], arg[1:] - } - - extra := map[string]interface{}{} - for i := 0; i < len(arg)-1; i += 2 { - data[arg[i]] = arg[i+1] - } - data["extra"] = extra - - m.Conf("schedule", []string{"data", "-1"}, data) - return - }}, - "12306": &ctx.Command{Name: "12306", Help: "12306", Form: map[string]int{"fields": 1, "limit": 1, "offset": 1}, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - date := time.Now().Add(time.Hour * 24).Format("2006-01-02") - if len(arg) > 0 { - date, arg = arg[0], arg[1:] - } - to := "QFK" - if len(arg) > 0 { - to, arg = arg[0], arg[1:] - } - from := "BJP" - if len(arg) > 0 { - from, arg = arg[0], arg[1:] - } - m.Echo("%s->%s %s\n", from, to, date) - - m.Cmd("web.get", fmt.Sprintf("https://kyfw.12306.cn/otn/leftTicket/queryX?leftTicketDTO.train_date=%s&leftTicketDTO.from_station=%s&leftTicketDTO.to_station=%s&purpose_codes=ADULT", date, from, to), "temp", "data.result") - for _, v := range m.Meta["value"] { - fields := strings.Split(v, "|") - m.Add("append", "车次--", fields[3]) - m.Add("append", "出发----", fields[8]) - m.Add("append", "到站----", fields[9]) - m.Add("append", "时长----", fields[10]) - m.Add("append", "二等座", fields[30]) - m.Add("append", "一等座", fields[31]) - } - m.Table() - return - }}, - "brow": &ctx.Command{Name: "brow url", Help: "浏览网页", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if len(arg) == 0 { - m.Cmd("tcp.ifconfig").Table(func(index int, value map[string]string) { - m.Append("index", index) - m.Append("site", fmt.Sprintf("%s://%s%s", m.Conf("serve", "protocol"), value["ip"], m.Conf("runtime", "boot.web_port"))) - }) - m.Table() - return - } - - switch runtime.GOOS { - case "windows": - m.Cmd("cli.system", "explorer", arg[0]) - case "darwin": - m.Cmd("cli.system", "open", arg[0]) - default: - m.Cmd("web.get", arg[0]) - } - return - }}, - - "/counter": &ctx.Command{Name: "/counter", Help: "/counter", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if len(arg) > 0 { - m.Option("name", arg[0]) - } - if len(arg) > 1 { - m.Option("count", arg[1]) - } - - count := m.Optioni("count") - switch v := m.Confv("counter", m.Option("name")).(type) { - case string: - i, e := strconv.Atoi(v) - m.Assert(e) - count += i - } - m.Log("info", "%v: %v", m.Option("name"), m.Confv("counter", m.Option("name"), fmt.Sprintf("%d", count))) - m.Echo("%d", count) - return - }}, - "counter": &ctx.Command{Name: "counter name count", Help: "counter", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if len(arg) > 1 { - m.Copy(m.Spawn().Cmd("get", m.Conf("counter_service"), "name", arg[0], "count", arg[1]), "result") - } - return - }}, - "tmux": &ctx.Command{Name: "tmux buffer", Help: "终端管理, buffer: 查看复制", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - switch arg[0] { - case "buffer": - bufs := strings.Split(m.Spawn().Cmd("system", "tmux", "list-buffers").Result(0), "\n") - - n := 3 - if m.Option("limit") != "" { - n = m.Optioni("limit") - } - - for i, b := range bufs { - if i >= n { - break - } - bs := strings.SplitN(b, ": ", 3) - if len(bs) > 1 { - m.Add("append", "buffer", bs[0][:len(bs[0])]) - m.Add("append", "length", bs[1][:len(bs[1])-6]) - m.Add("append", "strings", bs[2][1:len(bs[2])-1]) - } - } - - if m.Option("index") == "" { - m.Echo(m.Spawn().Cmd("system", "tmux", "show-buffer").Result(0)) - } else { - m.Echo(m.Spawn().Cmd("system", "tmux", "show-buffer", "-b", m.Option("index")).Result(0)) - } - } - return - }}, - "windows": &ctx.Command{Name: "windows", Help: "windows", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - m.Append("nclient", strings.Count(m.Spawn().Cmd("system", "tmux", "list-clients").Result(0), "\n")) - m.Append("nsession", strings.Count(m.Spawn().Cmd("system", "tmux", "list-sessions").Result(0), "\n")) - m.Append("nwindow", strings.Count(m.Spawn().Cmd("system", "tmux", "list-windows", "-a").Result(0), "\n")) - m.Append("npane", strings.Count(m.Spawn().Cmd("system", "tmux", "list-panes", "-a").Result(0), "\n")) - - m.Append("nbuf", strings.Count(m.Spawn().Cmd("system", "tmux", "list-buffers").Result(0), "\n")) - m.Append("ncmd", strings.Count(m.Spawn().Cmd("system", "tmux", "list-commands").Result(0), "\n")) - m.Append("nkey", strings.Count(m.Spawn().Cmd("system", "tmux", "list-keys").Result(0), "\n")) - m.Table() - return - }}, - "notice": &ctx.Command{Name: "notice", Help: "睡眠, time(ns/us/ms/s/m/h): 时间值(纳秒/微秒/毫秒/秒/分钟/小时)", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - m.Cmd("cli.system", "osascript", "-e", fmt.Sprintf("display notification \"%s\"", kit.Select("", arg, 0))) + m.Cmdy("ssh.data", "insert", arg[0], "title", arg[1], "content", arg[2], arg[3:]) return }}, }, } func init() { - code := &web.WEB{} - code.Context = Index - web.Index.Register(Index, code) + web.Index.Register(Index, &web.WEB{Context: Index}) } diff --git a/src/examples/trash/team.go b/src/examples/trash/team.go new file mode 100644 index 00000000..ed1eb2a4 --- /dev/null +++ b/src/examples/trash/team.go @@ -0,0 +1,485 @@ +package team + +import ( + "contexts/ctx" + "contexts/web" + "fmt" + "path" + "plugin" + "runtime" + "strconv" + "strings" + "time" + "toolkit" +) + +var Index = &ctx.Context{Name: "team", Help: "团队中心", + Caches: map[string]*ctx.Cache{}, + Configs: map[string]*ctx.Config{ + "skip_login": &ctx.Config{Name: "skip_login", Value: map[string]interface{}{"/consul": "true"}, Help: "免密登录"}, + "componet": &ctx.Config{Name: "componet", Value: map[string]interface{}{ + "login": []interface{}{ + map[string]interface{}{"componet_name": "code", "componet_tmpl": "head", "metas": []interface{}{ + map[string]interface{}{"name": "viewport", "content": "width=device-width, initial-scale=0.7, user-scalable=no"}, + }, "favicon": "favicon.ico", "styles": []interface{}{"example.css", "code.css"}}, + + map[string]interface{}{"componet_name": "login", "componet_help": "login", + "componet_tmpl": "componet", "componet_init": "initLogin", + "componet_ctx": "aaa", "componet_cmd": "auth", "componet_args": []interface{}{"@sessid", "ship", "username", "@username", "password", "@password"}, "inputs": []interface{}{ + map[string]interface{}{"type": "text", "name": "username", "value": "", "label": "username"}, + map[string]interface{}{"type": "password", "name": "password", "value": "", "label": "password"}, + map[string]interface{}{"type": "button", "value": "login"}, + }, + "display_append": "", "display_result": "", + }, + + map[string]interface{}{"componet_name": "tail", "componet_tmpl": "tail", + "scripts": []interface{}{"toolkit.js", "context.js", "example.js", "code.js"}, + }, + }, + "flash": []interface{}{ + map[string]interface{}{"componet_name": "flash", "componet_tmpl": "head", "metas": []interface{}{ + map[string]interface{}{"name": "viewport", "content": "width=device-width, initial-scale=0.7, user-scalable=no"}, + }, "favicon": "favicon.ico", "styles": []interface{}{"example.css", "code.css"}}, + + map[string]interface{}{"componet_name": "ask", "componet_help": "ask", "componet_tmpl": "componet", + "componet_view": "FlashText", "componet_init": "initFlashText", + "componet_ctx": "web.code", "componet_cmd": "flash", "componet_args": []interface{}{"text", "@text"}, "inputs": []interface{}{ + map[string]interface{}{"type": "textarea", "name": "text", "value": "", "cols": 50, "rows": 5}, + map[string]interface{}{"type": "button", "value": "添加请求"}, + }, + "display_result": "", "display_append": "", + }, + map[string]interface{}{"componet_name": "tip", "componet_help": "tip", "componet_tmpl": "componet", + "componet_view": "FlashList", "componet_init": "initFlashList", + "componet_ctx": "web.code", "componet_cmd": "flash", + "display_result": "", "display_append": "", + }, + + map[string]interface{}{"componet_name": "tail", "componet_tmpl": "tail", + "scripts": []interface{}{"toolkit.js", "context.js", "example.js", "code.js"}, + }, + }, + "schedule": []interface{}{ + map[string]interface{}{"componet_name": "flash", "componet_tmpl": "head", "metas": []interface{}{ + map[string]interface{}{"name": "viewport", "content": "width=device-width, initial-scale=0.7, user-scalable=no"}, + }, "favicon": "favicon.ico", "styles": []interface{}{"example.css", "code.css"}}, + + map[string]interface{}{"componet_name": "com", "componet_help": "com", "componet_tmpl": "componet", + "componet_view": "ComList", "componet_init": "initComList", + "componet_ctx": "web.code", "componet_cmd": "componet", "componet_args": []interface{}{"share", "@role", "@componet_group", "@tips"}, "inputs": []interface{}{ + map[string]interface{}{"type": "text", "name": "role", "value": "tech", "label": "role"}, + map[string]interface{}{"type": "text", "name": "tips", "value": "schedule", "label": "tips"}, + map[string]interface{}{"type": "button", "value": "共享页面"}, + }, + }, + + map[string]interface{}{"componet_name": "text", "componet_help": "text", "componet_tmpl": "componet", + "componet_view": "ScheduleText", "componet_init": "initScheduleText", + "componet_ctx": "web.code", "componet_cmd": "schedule", + "componet_args": []interface{}{"@time", "@name", "@place"}, "inputs": []interface{}{ + map[string]interface{}{"type": "text", "name": "time", "value": "", "label": "time"}, + map[string]interface{}{"type": "text", "name": "name", "value": "", "label": "name"}, + map[string]interface{}{"type": "text", "name": "place", "value": "", "label": "place"}, + map[string]interface{}{"type": "button", "value": "添加行程"}, + }, + "display_result": "", "display_append": "", + }, + map[string]interface{}{"componet_name": "list", "componet_help": "list", "componet_tmpl": "componet", + "componet_view": "ScheduleList", "componet_init": "initScheduleList", + "componet_ctx": "web.code", "componet_cmd": "schedule", + "inputs": []interface{}{ + map[string]interface{}{"type": "choice", "name": "view", "value": "default", "label": "显示字段", "choice": []interface{}{ + map[string]interface{}{"name": "默认", "value": "default"}, + map[string]interface{}{"name": "行程", "value": "order"}, + map[string]interface{}{"name": "总结", "value": "summary"}, + }}, + map[string]interface{}{"type": "button", "value": "刷新行程"}, + }, + "display_result": "", + }, + + map[string]interface{}{"componet_name": "tail", "componet_tmpl": "tail", + "scripts": []interface{}{"toolkit.js", "context.js", "example.js", "code.js"}, + }, + }, + "index": []interface{}{ + map[string]interface{}{"componet_name": "code", "componet_tmpl": "head", "metas": []interface{}{ + map[string]interface{}{"name": "viewport", "content": "width=device-width, initial-scale=0.7, user-scalable=no"}, + }, "favicon": "favicon.ico", "styles": []interface{}{"example.css", "code.css"}}, + map[string]interface{}{"componet_name": "banner", "componet_help": "banner", "componet_tmpl": "banner", + "componet_view": "Banner", "componet_init": "initBanner", + }, + + map[string]interface{}{"componet_name": "toolkit", "componet_help": "Ctrl+B", "componet_tmpl": "toolkit", + "componet_view": "KitList", "componet_init": "initKitList", + }, + // map[string]interface{}{"componet_name": "login", "componet_help": "login", "componet_tmpl": "componet", + // "componet_ctx": "aaa", "componet_cmd": "login", "componet_args": []interface{}{"@username", "@password"}, + // "inputs": []interface{}{ + // map[string]interface{}{"type": "text", "name": "username", "label": "username"}, + // map[string]interface{}{"type": "password", "name": "password", "label": "password"}, + // map[string]interface{}{"type": "button", "value": "login"}, + // }, + // "display_append": "", "display_result": "", + // }, + // map[string]interface{}{"componet_name": "userinfo", "componet_help": "userinfo", "componet_tmpl": "componet", + // "componet_ctx": "aaa", "componet_cmd": "login", "componet_args": []interface{}{"@sessid"}, + // "pre_run": true, + // }, + map[string]interface{}{"componet_name": "buffer", "componet_help": "buffer", "componet_tmpl": "componet", + "componet_view": "BufList", "componet_init": "initBufList", + "componet_ctx": "cli", "componet_cmd": "tmux", "componet_args": []interface{}{"buffer"}, "inputs": []interface{}{ + map[string]interface{}{"type": "text", "name": "limit", "value": "3", "label": "limit"}, + map[string]interface{}{"type": "text", "name": "index", "value": "0", "label": "index"}, + map[string]interface{}{"type": "button", "value": "refresh"}, + }, + "pre_run": true, + }, + map[string]interface{}{"componet_name": "dir", "componet_help": "dir", "componet_tmpl": "componet", + "componet_view": "DirList", "componet_init": "initDirList", + "componet_ctx": "nfs", "componet_cmd": "dir", "componet_args": []interface{}{"@dir", "dir_sort", "@sort_field", "@sort_order"}, "inputs": []interface{}{ + map[string]interface{}{"type": "choice", "name": "dir_type", "value": "both", "label": "dir_type", "choice": []interface{}{ + map[string]interface{}{"name": "all", "value": "all"}, + map[string]interface{}{"name": "both", "value": "both"}, + map[string]interface{}{"name": "file", "value": "file"}, + map[string]interface{}{"name": "dir", "value": "dir"}, + }}, + map[string]interface{}{"type": "text", "name": "dir", "value": "@current.dir", "label": "dir"}, + map[string]interface{}{"type": "button", "value": "refresh"}, + }, + "pre_run": false, "display_result": "", + }, + map[string]interface{}{"componet_name": "upload", "componet_help": "upload", "componet_tmpl": "componet", + "componet_view": "PutFile", "componet_init": "initPutFile", + "componet_ctx": "web", "componet_cmd": "upload", "form_type": "upload", "inputs": []interface{}{ + map[string]interface{}{"type": "file", "name": "upload"}, + map[string]interface{}{"type": "submit", "value": "submit"}, + }, + "display_result": "", + }, + map[string]interface{}{"componet_name": "pod", "componet_help": "pod", "componet_tmpl": "componet", + "componet_view": "PodList", "componet_init": "initPodList", + "componet_ctx": "ssh", "componet_cmd": "node", "inputs": []interface{}{ + map[string]interface{}{"type": "text", "name": "pod", "value": "@current.pod"}, + map[string]interface{}{"type": "button", "value": "refresh"}, + }, + "pre_run": true, "display_result": "", + }, + map[string]interface{}{"componet_name": "ctx", "componet_help": "ctx", "componet_tmpl": "componet", + "componet_view": "CtxList", "componet_init": "initCtxList", + "componet_pod": "true", "componet_ctx": "ssh", "componet_cmd": "context", "componet_args": []interface{}{"@ctx", "list"}, "inputs": []interface{}{ + map[string]interface{}{"type": "text", "name": "ctx", "value": "@current.ctx"}, + map[string]interface{}{"type": "button", "value": "refresh"}, + }, + "display_result": "", + }, + map[string]interface{}{"componet_name": "cmd", "componet_help": "cmd", "componet_tmpl": "componet", + "componet_view": "CmdList", "componet_init": "initCmdList", + "componet_ctx": "cli.shy", "componet_cmd": "source", "componet_args": []interface{}{"@cmd"}, "inputs": []interface{}{ + map[string]interface{}{"type": "text", "name": "cmd", "value": "", "class": "cmd", "clipstack": "void"}, + }, + }, + // map[string]interface{}{"componet_name": "mp", "componet_tmpl": "mp"}, + map[string]interface{}{"componet_name": "tail", "componet_tmpl": "tail", + "scripts": []interface{}{"toolkit.js", "context.js", "example.js", "code.js"}, + }, + }, + }, Help: "组件列表"}, + "componet_group": &ctx.Config{Name: "component_group", Value: "index", Help: "默认组件"}, + + "make": &ctx.Config{Name: "make", Value: map[string]interface{}{ + "go": map[string]interface{}{ + "build": []interface{}{"go", "build"}, + "plugin": []interface{}{"go", "build", "-buildmode=plugin"}, + "load": []interface{}{"load"}, + }, + "so": map[string]interface{}{ + "load": []interface{}{"load"}, + }, + }, Help: "免密登录"}, + + "flash": &ctx.Config{Name: "flash", Value: map[string]interface{}{ + "data": []interface{}{}, + "view": map[string]interface{}{"default": []interface{}{"index", "time", "text", "code", "output"}}, + }, Help: "闪存"}, + "schedule": &ctx.Config{Name: "schedule", Value: map[string]interface{}{ + "data": []interface{}{}, + "view": map[string]interface{}{ + "default": []interface{}{"面试时间", "面试公司", "面试地点", "面试轮次", "题目类型", "面试题目", "面试总结"}, + "summary": []interface{}{"面试公司", "面试轮次", "题目类型", "面试题目", "面试总结"}, + "order": []interface{}{"面试时间", "面试公司", "面试地点"}, + }, + "maps": map[string]interface{}{"baidu": "%s"}, + }, Help: "闪存"}, + + "counter": &ctx.Config{Name: "counter", Value: map[string]interface{}{ + "nopen": "0", "nsave": "0", + }, Help: "counter"}, + "counter_service": &ctx.Config{Name: "counter_service", Value: "http://localhost:9094/code/counter", Help: "counter"}, + }, + Commands: map[string]*ctx.Command{ + "make": &ctx.Command{Name: "make [action] file [args...]", Help: "更新代码", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + target, action, suffix := path.Join(m.Conf("runtime", "boot.ctx_home"), "src/examples/app/bench.go"), "build", "go" + if len(arg) == 0 { + arg = append(arg, target) + } + + if cs := strings.Split(arg[0], "."); len(cs) > 1 { + suffix = cs[len(cs)-1] + } else if cs := strings.Split(arg[1], "."); len(cs) > 1 { + action, suffix, arg = arg[0], cs[len(cs)-1], arg[1:] + } + + target = m.Cmdx("nfs.path", arg[0]) + if target == "" { + target = m.Cmdx("nfs.path", path.Join("src/plugin/", arg[0])) + } + + cook := m.Confv("make", []string{suffix, action}) + switch kit.Chains(cook, "0") { + case "load": + if suffix == "go" { + so := strings.Replace(target, ".go", ".so", -1) + m.Cmd("cli.system", m.Confv("make", "go.plugin"), "-o", so, target) + arg[0] = so + } + + if p, e := plugin.Open(arg[0]); m.Assert(e) { + s, e := p.Lookup("Index") + m.Assert(e) + w := *(s.(**ctx.Context)) + c.Register(w, nil, true) + } + default: + m.Cmdy("cli.system", cook, arg) + } + return + }}, + "flash": &ctx.Command{Name: "flash", Help: "闪存", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + total := len(m.Confv("flash", "data").([]interface{})) + // 查看列表 + if len(arg) == 0 { + if index := m.Option("flash_index"); index != "" { + arg = append(arg, index) + } else { + m.Confm("flash", "data", func(index int, item map[string]interface{}) { + for _, k := range kit.View([]string{}, m.Confm("flash", "view")) { + m.Add("append", k, kit.Format(item[k])) + } + }) + m.Table() + return + } + + } + + index, item := -1, map[string]interface{}{"time": m.Time()} + if i, e := strconv.Atoi(arg[0]); e == nil && 0 <= i && i < total { + // 查看索引 + index, arg = total-1-i, arg[1:] + if item = m.Confm("flash", []interface{}{"data", index}); len(arg) == 0 { + // 查看数据 + for _, k := range kit.View([]string{}, m.Confm("flash", "view")) { + m.Add("append", k, kit.Format(item[k])) + } + m.Table() + return e + } + } + + switch arg[0] { + case "vim": // 编辑数据 + name := m.Cmdx("nfs.temp", kit.Format(item[kit.Select("code", arg, 1)])) + m.Cmd("cli.system", "vi", name) + item[kit.Select("code", arg, 1)] = m.Cmdx("nfs.load", name) + m.Cmd("nfs.trash", name) + + case "run": // 运行代码 + code := kit.Format(item[kit.Select("code", arg, 1)]) + if code == "" { + break + } + name := m.Cmdx("nfs.temp", code) + m.Cmdy("cli.system", "python", name) + item["output"] = m.Result(0) + m.Cmd("nfs.trash", name) + + default: + // 修改数据 + for i := 0; i < len(arg)-1; i += 2 { + item[arg[i]] = arg[i+1] + } + m.Conf("flash", []interface{}{"data", index}, item) + item["index"] = total - 1 - index + m.Echo("%d", total-1-index) + } + + return + }}, + "schedule": &ctx.Command{Name: "schedule [time name place]", Help: "行程安排", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + if len(arg) == 0 { // 会话列表 + m.Confm("schedule", "data", func(index int, value map[string]interface{}) { + for _, v := range kit.View([]string{m.Option("view")}, m.Confm("schedule", "view")) { + if v == "面试地点" { + m.Add("append", "面试地点", fmt.Sprintf(m.Conf("schedule", "maps.baidu"), value["面试地点"], value["面试地点"])) + continue + } + m.Add("append", v, kit.Format(value[v])) + } + }) + m.Table() + return + } + + view := "default" + if m.Confs("schedule", arg[0]) { + view, arg = arg[0], arg[1:] + } + + data := map[string]interface{}{} + for _, k := range kit.View([]string{view}, m.Confm("schedule", "view")) { + if len(arg) == 0 { + data[k] = "" + continue + } + data[k], arg = arg[0], arg[1:] + } + + extra := map[string]interface{}{} + for i := 0; i < len(arg)-1; i += 2 { + data[arg[i]] = arg[i+1] + } + data["extra"] = extra + + m.Conf("schedule", []string{"data", "-1"}, data) + return + }}, + "12306": &ctx.Command{Name: "12306", Help: "12306", Form: map[string]int{"fields": 1, "limit": 1, "offset": 1}, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + date := time.Now().Add(time.Hour * 24).Format("2006-01-02") + if len(arg) > 0 { + date, arg = arg[0], arg[1:] + } + to := "QFK" + if len(arg) > 0 { + to, arg = arg[0], arg[1:] + } + from := "BJP" + if len(arg) > 0 { + from, arg = arg[0], arg[1:] + } + m.Echo("%s->%s %s\n", from, to, date) + + m.Cmd("web.get", fmt.Sprintf("https://kyfw.12306.cn/otn/leftTicket/queryX?leftTicketDTO.train_date=%s&leftTicketDTO.from_station=%s&leftTicketDTO.to_station=%s&purpose_codes=ADULT", date, from, to), "temp", "data.result") + for _, v := range m.Meta["value"] { + fields := strings.Split(v, "|") + m.Add("append", "车次--", fields[3]) + m.Add("append", "出发----", fields[8]) + m.Add("append", "到站----", fields[9]) + m.Add("append", "时长----", fields[10]) + m.Add("append", "二等座", fields[30]) + m.Add("append", "一等座", fields[31]) + } + m.Table() + return + }}, + "brow": &ctx.Command{Name: "brow url", Help: "浏览网页", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + if len(arg) == 0 { + m.Cmd("tcp.ifconfig").Table(func(index int, value map[string]string) { + m.Append("index", index) + m.Append("site", fmt.Sprintf("%s://%s%s", m.Conf("serve", "protocol"), value["ip"], m.Conf("runtime", "boot.web_port"))) + }) + m.Table() + return + } + + switch runtime.GOOS { + case "windows": + m.Cmd("cli.system", "explorer", arg[0]) + case "darwin": + m.Cmd("cli.system", "open", arg[0]) + default: + m.Cmd("web.get", arg[0]) + } + return + }}, + + "/counter": &ctx.Command{Name: "/counter", Help: "/counter", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + if len(arg) > 0 { + m.Option("name", arg[0]) + } + if len(arg) > 1 { + m.Option("count", arg[1]) + } + + count := m.Optioni("count") + switch v := m.Confv("counter", m.Option("name")).(type) { + case string: + i, e := strconv.Atoi(v) + m.Assert(e) + count += i + } + m.Log("info", "%v: %v", m.Option("name"), m.Confv("counter", m.Option("name"), fmt.Sprintf("%d", count))) + m.Echo("%d", count) + return + }}, + "counter": &ctx.Command{Name: "counter name count", Help: "counter", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + if len(arg) > 1 { + m.Copy(m.Spawn().Cmd("get", m.Conf("counter_service"), "name", arg[0], "count", arg[1]), "result") + } + return + }}, + "tmux": &ctx.Command{Name: "tmux buffer", Help: "终端管理, buffer: 查看复制", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + switch arg[0] { + case "buffer": + bufs := strings.Split(m.Spawn().Cmd("system", "tmux", "list-buffers").Result(0), "\n") + + n := 3 + if m.Option("limit") != "" { + n = m.Optioni("limit") + } + + for i, b := range bufs { + if i >= n { + break + } + bs := strings.SplitN(b, ": ", 3) + if len(bs) > 1 { + m.Add("append", "buffer", bs[0][:len(bs[0])]) + m.Add("append", "length", bs[1][:len(bs[1])-6]) + m.Add("append", "strings", bs[2][1:len(bs[2])-1]) + } + } + + if m.Option("index") == "" { + m.Echo(m.Spawn().Cmd("system", "tmux", "show-buffer").Result(0)) + } else { + m.Echo(m.Spawn().Cmd("system", "tmux", "show-buffer", "-b", m.Option("index")).Result(0)) + } + } + return + }}, + "windows": &ctx.Command{Name: "windows", Help: "windows", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + m.Append("nclient", strings.Count(m.Spawn().Cmd("system", "tmux", "list-clients").Result(0), "\n")) + m.Append("nsession", strings.Count(m.Spawn().Cmd("system", "tmux", "list-sessions").Result(0), "\n")) + m.Append("nwindow", strings.Count(m.Spawn().Cmd("system", "tmux", "list-windows", "-a").Result(0), "\n")) + m.Append("npane", strings.Count(m.Spawn().Cmd("system", "tmux", "list-panes", "-a").Result(0), "\n")) + + m.Append("nbuf", strings.Count(m.Spawn().Cmd("system", "tmux", "list-buffers").Result(0), "\n")) + m.Append("ncmd", strings.Count(m.Spawn().Cmd("system", "tmux", "list-commands").Result(0), "\n")) + m.Append("nkey", strings.Count(m.Spawn().Cmd("system", "tmux", "list-keys").Result(0), "\n")) + m.Table() + return + }}, + "notice": &ctx.Command{Name: "notice", Help: "睡眠, time(ns/us/ms/s/m/h): 时间值(纳秒/微秒/毫秒/秒/分钟/小时)", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + m.Cmd("cli.system", "osascript", "-e", fmt.Sprintf("display notification \"%s\"", kit.Select("", arg, 0))) + return + }}, + }, +} + +func init() { + code := &web.WEB{} + code.Context = Index + web.Index.Register(Index, code) +} diff --git a/src/extend/shy.go b/src/extend/shy.go index 93f89699..c5606a65 100644 --- a/src/extend/shy.go +++ b/src/extend/shy.go @@ -20,9 +20,9 @@ import ( // 应用层 _ "examples/chat" //会议中心 _ "examples/code" //代码中心 + _ "examples/mall" //交易中心 + _ "examples/team" //团队中心 _ "examples/wiki" //文档中心 - // _ "examples/jira" //任务中心 - // _ "examples/mall" //交易中心 // 应用层 _ "examples/chat/feishu" //飞书 diff --git a/src/plugin/docker/index.shy b/src/plugin/docker/index.shy index ac602af3..78fc89ac 100644 --- a/src/plugin/docker/index.shy +++ b/src/plugin/docker/index.shy @@ -1,14 +1,14 @@ -kit shell "命令" private "ssh._route" _ "context" "find" "web.code" "zsh" \ +kit shell "命令行" private "ssh._route" _ "context" "find" "web.code" "zsh" \ text "" name pod imports plugin_pod \ text "" name dir imports plugin_path action auto \ - select "" name cmd values list values find values grep values tail values init \ + select "" name cmd values list values find values tail values grep values init \ exports path path \ text "" name txt \ feature display editor \ button "搜索" \ button "返回" cb Last -kit clip "文本" private "web.code.tmux" "" "" "" "buffer" \ +kit clip "粘贴板" private "web.code.tmux" "" "" "" "buffer" \ text "" name tag imports plugin_buffer action auto \ text "" name txt \ exports buffer buffer \ @@ -23,7 +23,8 @@ kit tmux "终端" private "web.code.tmux" \ text "" name cmd \ exports session session "" window window "" pane pane "" \ feature detail "复制" "下载" "修改" \ - button "查看" action auto + button "查看" action auto \ + button "返回" cb Last kit image "镜像" private "web.code.docker" "image" \ text "" name pos imports plugin_REPOSITORY \ @@ -53,3 +54,14 @@ kit volume "存储" private "web.code.docker" "volume" \ exports CONTAINER_ID CONTAINER_ID \ button "查看" +kit git "记录" private "ssh._route" _ "web.code.git" \ + text "" name pod imports plugin_pod \ + text "" name dir imports plugin_path action auto \ + select "" name cmd values diff values status values commit values sum values init \ + button "查看" + +kit vim "编辑器" private "ssh._route" _ "web.code.vim" \ + text "" name pod imports plugin_pod \ + select "" name cmd values opens values bufs values regs values tags \ + button "查看" + diff --git a/src/plugin/storage/index.shy b/src/plugin/storage/index.shy index 5a028499..6bece2b6 100644 --- a/src/plugin/storage/index.shy +++ b/src/plugin/storage/index.shy @@ -1,23 +1,4 @@ - -fun buffer "粘贴板" private \ - text "" name index imports plugin_tmux_bindex action auto \ - text "" name txt view long \ - button "查看" action auto \ - button "返回" cb Last \ - exports tmux_bindex cur - - let index = $1 - if $1 == "" - copy skip cli.system tmux "list-buffer" cmd_parse cut 3 ":" "cur bytes text" - return - end - if $2 != "" - copy cli.system tmux "set-buffer" "-b" - end - return $(cli.system tmux "show-buffer" "-b" $index) -end - fun clip "剪切板" public \ text "" name you imports plugin_you action auto \ text "" name tag \ diff --git a/src/plugin/task/index.css b/src/plugin/task/index.css new file mode 100644 index 00000000..69a9f84a --- /dev/null +++ b/src/plugin/task/index.css @@ -0,0 +1,3 @@ +fieldset.item.task div.output { +} + diff --git a/src/plugin/task/index.go b/src/plugin/task/index.go new file mode 100644 index 00000000..fc532458 --- /dev/null +++ b/src/plugin/task/index.go @@ -0,0 +1,36 @@ +package main + +import ( + "contexts/cli" + "contexts/ctx" + "toolkit" + + "fmt" + "os" +) + +var Index = &ctx.Context{Name: `task`, Help: `plugin`, + Caches: map[string]*ctx.Cache{}, + Configs: map[string]*ctx.Config{ + "_index": &ctx.Config{Name: "index", Value: []interface{}{ + map[string]interface{}{"name": "demo", "help": "demo", + "tmpl": "componet", "view": "", "init": "", + "type": "public", "ctx": "demo", "cmd": "demo", + "args": []interface{}{}, "inputs": []interface{}{ + map[string]interface{}{"type": "text", "name": "pod", "value": "hello world"}, + map[string]interface{}{"type": "button", "value": "执行"}, + }, + }, + }}, + }, + Commands: map[string]*ctx.Command{ + "demo": {Name: "demo", Help: "demo", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + m.Echo(kit.Select("hello world", arg, 0)) + return + }}, + }, +} + +func main() { + fmt.Print(cli.Index.Plugin(Index, os.Args[1:])) +} diff --git a/src/plugin/task/index.js b/src/plugin/task/index.js new file mode 100644 index 00000000..bbfeca5c --- /dev/null +++ b/src/plugin/task/index.js @@ -0,0 +1,3 @@ +Script["task/index.js"] = function(field, option, output) {return { +}} + diff --git a/src/plugin/task/index.shy b/src/plugin/task/index.shy new file mode 100644 index 00000000..dd8c298c --- /dev/null +++ b/src/plugin/task/index.shy @@ -0,0 +1,14 @@ +kit task "任务" public "web.team.task" \ + text "task" name table \ + text "" name title \ + text "" name content \ + button "执行" + +kit salary "工资" public "web.mall.salary" \ + text "salary" name table \ + text "2019-10" name month init month \ + text "" name total \ + text "" name base \ + text "" name tax \ + button "执行" + diff --git a/usr/librarys/chat.js b/usr/librarys/chat.js index d571440c..3dfdb13e 100644 --- a/usr/librarys/chat.js +++ b/usr/librarys/chat.js @@ -97,6 +97,13 @@ var page = Page({ meta[value](event) })) }, + get: function(event, item, value, page) { + page.toast.Pane.Show( + "export ctx_dev="+location.protocol+"//"+location.host+" && curl $ctx_dev/publish/boot.sh | bash -s installs context" + "
" + + "export ctx_dev="+location.protocol+"//"+location.host+" && bin/boot.sh" + "
" + + "export ctx_box="+location.protocol+"//"+location.host+" && bin/node.sh" + "
", + "Copy to ClipBorad!", 30000) + }, "工作": function(event, value) { page.which.set(value) @@ -125,7 +132,7 @@ var page = Page({ page.onlayout(event, {header:0, footer:0, river:0, storm:0, action: -1}) }, }, - Button: shy({"title": "github.com/shylinux/context", "user": "", "time": ""}, ["time", "user"], function(key, value) {var meta = arguments.callee.meta + Button: shy({"title": "github.com/shylinux/context", "user": "", "time": "", "get": "下载"}, ["time", "user", "get"], function(key, value) {var meta = arguments.callee.meta return kit.isNone(key)? meta: kit.isNone(value)? meta[key]: (meta[key] = value, page.header.Pane.Show()) }), Status: shy({title: 'shylinux@163.com', "ncmd": "0", "ntxt": "0"}, ["ncmd", "ntxt"], function(key, value) {var meta = arguments.callee.meta diff --git a/usr/librarys/context.js b/usr/librarys/context.js index 496ae4ba..2ef63f63 100644 --- a/usr/librarys/context.js +++ b/usr/librarys/context.js @@ -61,11 +61,11 @@ ctx = context = (function(kit) {var ctx = {__proto__: kit, kit.Log("event", ++arguments.callee.meta.order, event.type, (proto.name||[document.title]).join("."), msg) return msg }), - Share: shy("共享链接", function(objs, clear) {objs = objs || {} - !clear && kit.Item(this.Search(), function(key, value) {objs[key] || (objs[key] = value)}) - return location.origin+location.pathname+"?"+kit.Item(objs, function(key, value) { + Share: shy("共享链接", function(objs, clear) {var obj = objs || {} + !clear && kit.Item(this.Search(), function(key, value) {obj[key] || (obj[key] = value)}) + return location.origin+location.pathname+(objs? "?"+kit.Item(obj, function(key, value) { return kit.List(value, function(value) {return key+"="+encodeURIComponent(value)}).join("&") - }).join("&") + }).join("&"): "") }), Search: shy("请求变量", function(key, value) {var args = {} diff --git a/usr/librarys/example.css b/usr/librarys/example.css index 5ac4e7bf..392e5bbb 100644 --- a/usr/librarys/example.css +++ b/usr/librarys/example.css @@ -424,6 +424,7 @@ fieldset table td { max-width:1200px; font-family:monospace; padding: 0 6px; + white-space: pre; } fieldset table td.clip { background-color:red; diff --git a/usr/librarys/example.js b/usr/librarys/example.js index 1ace51ff..3458bcc1 100644 --- a/usr/librarys/example.js +++ b/usr/librarys/example.js @@ -116,6 +116,10 @@ function Meta(zone, target, obj) { Event: shy("事件入口", {name: zone}, function(event, msg, proto) { return ctx.Event(event, msg, proto||arguments.callee.meta) }), + _call: function(key) { + kit._call(meta, typeof key == "function"? key: meta[key], kit.List(arguments).slice(1)) + return true + }, Zones: function(name) {return zone.concat(kit.List(arguments)).join(".")}, Zone: function(name) {return zone.concat(kit.List(arguments))}, } @@ -1000,11 +1004,17 @@ function Pane(page, field) { ctx.Run(event, option.dataset, cmds, cb||pane.ondaemon) }), + onchoice: shy("菜单列表", { + "删除": "_table", + "修改": "_canvas", + }, ["删除", "修改"], function(event, value, meta) { + return pane._call(meta[value], event) + }), onaction: shy("事件列表", { oncontextmenu: function(event) { - pane.Choice && page.carte.Pane.Show(event, shy({}, pane.Choice, function(event, value, meta) { + page.carte.Pane.Show(event, pane.Choice? shy({}, pane.Choice, function(event, value, meta) { pane.Check(event, value) - })) + }): pane.onchoice) }, }, function(event, key, cb) {cb(event)}), which: page.Sync(name), Listen: {}, Action: {}, Button: [], Choice: [], @@ -1028,7 +1038,7 @@ function Plugin(page, pane, field, inits, runs) { kit.classList.add(field, meta.group, name, feature.style) var plugin = Meta(pane.Zone(name), field, inits && inits(field, option, output) || {}, {Inputs: {}, Outputs: {}, - Appends: shy("添加控件", function(inputs) { + Appends: shy("添加控件", function(event, inputs) { if (inputs) {return inputs.map(function(item) {plugin.Append(item)})} var name = "args"+kit.Selector(option, "input.args.temp").length @@ -1080,8 +1090,11 @@ function Plugin(page, pane, field, inits, runs) { return JSON.stringify(field.Meta) }), Clone: shy("复制插件", function() { - return pane.Append("field", {text: plugin.Reveal(), init: meta.init, view: meta.view, group: meta.group}, [], "") + return pane.Append("field", {text: plugin.Reveal(), init: meta.init, view: meta.view, group: meta.group}, [], "").item.Plugin.Select(null, true) }), + clear: function() { + plugin.Save(""), output.innerHTML = "" + }, Move: function() { return field.nextSibling || field.parentNode.firstChild @@ -1229,13 +1242,11 @@ function Plugin(page, pane, field, inits, runs) { }), onchoice: shy("菜单列表", { "返回": "Last", - "复制": "Clone", - "加参": "Appends", - "减参": "Remove", + "清空": "clear", + "克隆": "Clone", "删除": "Delete", - }, ["返回", "复制", "加参", "减参", "删除"], function(event, value, meta) { - kit._call(plugin, plugin[meta[value]], [event]) - return true + }, ["返回", "清空", "克隆", "删除"], function(event, value, meta) { + return plugin._call(meta[value], event) }), onaction: shy("事件列表", { oncontextmenu: function(event) { @@ -1247,7 +1258,7 @@ function Plugin(page, pane, field, inits, runs) { kit.Log("init", "plugin", name, plugin) plugin.which = plugin.Sync("input") page[field.id] = pane[field.id] = pane[name] = field, field.Plugin = plugin - plugin.Appends(inputs) + plugin.Appends(null, inputs) return plugin } function Inputs(plugin, meta, item, target, option) { @@ -1273,6 +1284,9 @@ function Inputs(plugin, meta, item, target, option) { page.openLocation && page.openLocation(res.latitude+y, res.longitude+x, option.pos.value) }) }, + clear: function() { + target.value = "" + }, Jshy: function(event, args) { // 内部命令 @@ -1286,6 +1300,7 @@ function Inputs(plugin, meta, item, target, option) { onformat: shy("数据转换", { none: function(value) {return value||""}, date: function(value) {return kit.time()}, + month: function(value) {return kit.time().slice(0, 7)}, }, function(which, value) {var meta = arguments.callee.meta return (meta[which||"none"]||meta["none"])(value) }), @@ -1298,18 +1313,17 @@ function Inputs(plugin, meta, item, target, option) { }) }), item.type == "button" && item.action == "auto" && target.click() }), - clear: function() { - target.value = "" - }, onchoice: shy("菜单列表", { + "返回": "Last", "清空": "clear", - }, ["清空", "清空", "清空", "清空", "清空"], function(event, value, meta) { - kit._call(input, input[meta[value]]) - return true + "加参": "Appends", + "减参": "Remove", + }, ["返回", "清空", "加参", "减参"], function(event, value, meta) { + return input._call(meta[value], event) }), onaction: shy("事件列表", { oncontextmenu: function(event) { - plugin.oncarte(event, input.onchoice) + item.type != "button" && plugin.oncarte(event, input.onchoice) }, onfocus: function(event) {plugin.Select(target)}, onblur: function(event) {type == "text" && input.which.set(target.value)}, @@ -1363,7 +1377,7 @@ function Inputs(plugin, meta, item, target, option) { target.scrollTo(0, plugin.target.offsetTop) break case "b": - plugin.Appends() + plugin.Appends(event) break case "m": plugin.Clone() @@ -1401,13 +1415,13 @@ function Inputs(plugin, meta, item, target, option) { }, function(event, key, cb) {cb(event)}), which: plugin.Sync(name), }, plugin) + kit.Log("init", "input", input.Zones(), input) input.onimport() target.value = input.onformat(item.init, item.value) type == "text" && !target.placeholder && (target.placeholder = item.name) type == "text" && !target.title && (target.title = item.placeholder || item.name || "") - return plugin.Inputs[item.name] = target, target.Input = input } function Output(plugin, type, msg, cb, target, option) { @@ -1416,9 +1430,6 @@ function Output(plugin, type, msg, cb, target, option) { var exports = JSON.parse(plugin.target.Meta.exports||'{}') var output = Meta(plugin.Zone(type), target, { - _table: function() {plugin.onfigure("table")}, - _canvas: function() {plugin.onfigure("canvas")}, - clear: function() {target.innerHTML = ""}, Format: function() { var ext = ".csv", txt = kit.Selector(target, "tr", function(tr) { return kit.Selector(tr, "td,th", function(td) { @@ -1429,6 +1440,12 @@ function Output(plugin, type, msg, cb, target, option) { !txt && (ext = ".txt", txt = msg.result.join("")) return [name, ext, txt] }, + Download: function() { + var ps = output.Format() + + plugin.ontoast({text:''+ps[0]+ps[1]+'', title: "下载中...", width: 200}) + kit.Selector(page.toast, "a", function(item) {item.click()}) + }, Copy: function(event) { kit.CopyText(output.Format()[2]) }, @@ -1442,12 +1459,6 @@ function Output(plugin, type, msg, cb, target, option) { return (target.value = args[0]) || plugin.Zone("value", args[0]) }, - Download: function() { - var ps = output.Format() - - plugin.ontoast({text:''+ps[0]+ps[1]+'', title: "下载中...", width: 200}) - kit.Selector(page.toast, "a", function(item) {item.click()}) - }, onimport: shy("导入数据", { _table: function(msg, list) { return list && list.length > 0 && kit.OrderTable(kit.AppendTable(kit.AppendChild(target, "table"), msg.Table(), list), "", output.onexport, function(event, value, name, line, index) { @@ -1485,11 +1496,6 @@ function Output(plugin, type, msg, cb, target, option) { _code: function(msg) { return msg.result && msg.result.length > 0 && kit.OrderCode(kit.AppendChild(target, [{view: ["code", "div", msg.Results()]}]).first) }, - inner: function(msg, cb) { - target.innerHTML = "", plugin.onfigure.meta.max(target) - output.onimport.meta._table(msg, msg.append) || kit.OrderCode(kit.ModifyNode(target, msg.result.join(""))) - kit._call(cb, [msg]) - }, code: function(msg, cb) { target.innerHTML = "", output.onimport.meta._code(msg) typeof cb == "function" && cb(msg) @@ -1499,9 +1505,14 @@ function Output(plugin, type, msg, cb, target, option) { output.onimport.meta._table(msg, msg.append) || output.onimport.meta._code(msg) typeof cb == "function" && cb(msg) }, + inner: function(msg, cb) { + target.innerHTML = "", plugin.onfigure.meta.max(target) + output.onimport.meta._table(msg, msg.append) || kit.OrderCode(kit.ModifyNode(target, msg.result.join(""))) + kit._call(cb, [msg]) + }, editor: function(msg, cb) { - target.innerHTML = "" - output.onimport.meta._table(msg, msg.append) + output.onimport.meta.table(msg, cb) + var current = page.Sync("plugin_editor_index").get() target.style.maxHeight = "" if (msg.file) { @@ -1519,9 +1530,6 @@ function Output(plugin, type, msg, cb, target, option) { tr.scrollIntoView() }) } - typeof cb == "function" && cb(msg) - return - (target.innerHTML = "", Editor(plugin.Run, plugin, option, target, target.clientWidth-40, 400, 10, msg)) }, canvas: function(msg, cb) { target.innerHTML = "", plugin.onfigure.meta.size(function(width, height) { @@ -1540,15 +1548,14 @@ function Output(plugin, type, msg, cb, target, option) { return true }), onchoice: shy("菜单列表", { - "表格": "_table", - "绘图": "_canvas", - "复制": "Copy", - "下载": "Download", "返回": "Last", "清空": "clear", - }, ["表格", "绘图", "复制", "下载", "返回", "清空"], function(event, value, meta) { - kit._call(output, output[meta[value]], [event]) - return true + "复制": "Copy", + "下载": "Download", + "绘图": function() {plugin.onfigure("canvas")}, + "表格": function() {plugin.onfigure("table")}, + }, ["返回", "清空", "复制", "下载", "绘图", "表格"], function(event, value, meta) { + return output._call(meta[value], event) }), onaction: shy("事件列表", { oncontextmenu: function(event) {