From 3b73de53685721f4dcefc87384e14d9a033a2a47 Mon Sep 17 00:00:00 2001 From: harveyshao Date: Mon, 31 May 2021 17:06:35 +0800 Subject: [PATCH] opt base --- base/aaa/totp.go | 2 +- base/base.shy | 18 +- base/cli/cli.go | 4 +- base/cli/qrcode.go | 61 +++-- base/cli/system.go | 10 +- base/gdb/event.go | 7 +- base/gdb/gdb.go | 15 +- base/gdb/routine.go | 6 +- base/gdb/signal.go | 10 +- base/gdb/timer.go | 9 +- base/mdb/mdb.go | 18 +- base/mdb/search.go | 4 +- base/nfs/dir.go | 9 +- base/nfs/tail.go | 4 +- base/nfs/trash.go | 14 +- base/ssh/connect.go | 174 ++++++------ base/ssh/scripts.go | 12 +- base/ssh/service.go | 2 +- base/ssh/service_darwin.go | 6 +- base/ssh/service_linux.go | 12 +- base/ssh/service_windows.go | 3 +- base/tcp/client.go | 32 +-- base/tcp/host.go | 45 ++-- base/tcp/port.go | 25 +- base/tcp/server.go | 32 +-- base/tcp/tcp.go | 8 +- base/web/cache.go | 49 ++-- base/web/dream.go | 15 +- base/web/route.go | 8 +- base/web/serve.go | 8 +- base/web/share.go | 24 +- base/web/space.go | 15 +- base/web/spide.go | 514 ++++++++++++++++++------------------ base/web/story.go | 24 +- base/web/web.go | 24 +- base/web/web.shy | 14 +- conf.go | 36 +-- core/chat/river.go | 3 +- core/code/autogen.go | 2 +- core/code/bench.go | 2 +- core/code/install.go | 2 +- core/code/pprof.go | 4 +- core/mall/asset.go | 2 +- core/team/plan.go | 6 +- misc.go | 13 +- misc/bash/sync.go | 1 - misc/chrome/cache.go | 2 +- misc/git/status.go | 6 +- misc/lark/lark.go | 29 +- misc/tmux/tmux.go | 2 +- misc/vim/sync.go | 1 - type.go | 4 +- 52 files changed, 695 insertions(+), 657 deletions(-) diff --git a/base/aaa/totp.go b/base/aaa/totp.go index 33b18d69..081e4180 100644 --- a/base/aaa/totp.go +++ b/base/aaa/totp.go @@ -69,7 +69,7 @@ func init() { m.Cmd(mdb.INSERT, TOTP, "", mdb.HASH, kit.MDB_NAME, m.Option(kit.MDB_NAME), SECRET, m.Option(SECRET), PERIOD, m.Option(PERIOD), NUMBER, m.Option(NUMBER), ) - m.Option(ice.MSG_PROCESS, ice.PROCESS_REFRESH) + m.ProcessRefresh("1ms") }}, mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(mdb.DELETE, TOTP, "", mdb.HASH, kit.MDB_NAME, m.Option(kit.MDB_NAME)) diff --git a/base/base.shy b/base/base.shy index 5701ecd0..b10512cf 100644 --- a/base/base.shy +++ b/base/base.shy @@ -1,15 +1,21 @@ -source aaa/aaa.shy -source cli/cli.shy +label "base" ` +ctx cli web aaa +lex yac gdb log +tcp nfs ssh mdb +` + source ctx/ctx.shy +source cli/cli.shy source web/web.shy +source aaa/aaa.shy -source gdb/gdb.shy source lex/lex.shy -source log/log.shy source yac/yac.shy +source gdb/gdb.shy +source log/log.shy -source mdb/mdb.shy +source tcp/tcp.shy source nfs/nfs.shy source ssh/ssh.shy -source tcp/tcp.shy +source mdb/mdb.shy diff --git a/base/cli/cli.go b/base/cli/cli.go index e8333736..0d390a05 100644 --- a/base/cli/cli.go +++ b/base/cli/cli.go @@ -19,7 +19,9 @@ func NodeInfo(m *ice.Message, kind, name string) { ice.Info.NodeType = kind } -var Index = &ice.Context{Name: "cli", Help: "命令模块", +const CLI = "cli" + +var Index = &ice.Context{Name: CLI, Help: "命令模块", Commands: map[string]*ice.Command{ ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Load() diff --git a/base/cli/qrcode.go b/base/cli/qrcode.go index a9b562f0..0f374589 100644 --- a/base/cli/qrcode.go +++ b/base/cli/qrcode.go @@ -14,18 +14,18 @@ import ( ) var _trans_web = map[string]color.Color{ - "black": color.RGBA{0, 0, 0, 255}, - "red": color.RGBA{255, 0, 0, 255}, - "green": color.RGBA{0, 255, 0, 255}, - "yellow": color.RGBA{255, 255, 0, 255}, - "blue": color.RGBA{0, 0, 255, 255}, - "magenta": color.RGBA{255, 0, 255, 255}, - "cyan": color.RGBA{0, 255, 255, 255}, - "white": color.RGBA{255, 255, 255, 255}, + BLACK: color.RGBA{0, 0, 0, DARK}, + RED: color.RGBA{DARK, 0, 0, DARK}, + YELLOW: color.RGBA{DARK, DARK, 0, DARK}, + GREEN: color.RGBA{0, DARK, 0, DARK}, + CYAN: color.RGBA{0, DARK, DARK, DARK}, + BLUE: color.RGBA{0, 0, DARK, DARK}, + MAGENTA: color.RGBA{DARK, 0, DARK, DARK}, + WHITE: color.RGBA{DARK, DARK, DARK, DARK}, } func _parse_color(str string) color.Color { - if str == "random" { + if str == RANDOM { list := []string{} for k := range _trans_web { list = append(list, k) @@ -50,13 +50,13 @@ func _parse_color(str string) color.Color { func _trans_cli(str string) string { res := 0 r, g, b, _ := _parse_color(str).RGBA() - if r > 128 { + if r > LIGHT { res += 1 } - if g > 128 { + if g > LIGHT { res += 2 } - if b > 128 { + if b > LIGHT { res += 4 } return kit.Format(res) @@ -64,8 +64,8 @@ func _trans_cli(str string) string { func _qrcode_cli(m *ice.Message, text string, arg ...string) { qr, _ := qrcode.New(text, qrcode.Medium) - fg := _trans_cli(m.Option("fg")) - bg := _trans_cli(m.Option("bg")) + fg := _trans_cli(m.Option(FG)) + bg := _trans_cli(m.Option(BG)) data := qr.Bitmap() for i, row := range data { @@ -84,26 +84,45 @@ func _qrcode_cli(m *ice.Message, text string, arg ...string) { } func _qrcode_web(m *ice.Message, text string, arg ...string) { qr, _ := qrcode.New(text, qrcode.Medium) - qr.ForegroundColor = _parse_color(m.Option("fg")) - qr.BackgroundColor = _parse_color(m.Option("bg")) + qr.ForegroundColor = _parse_color(m.Option(FG)) + qr.BackgroundColor = _parse_color(m.Option(BG)) - if data, err := qr.PNG(kit.Int(m.Option("size"))); m.Assert(err) { + if data, err := qr.PNG(kit.Int(m.Option(SIZE))); m.Assert(err) { m.Echo(``, base64.StdEncoding.EncodeToString(data), text) } } +const ( + FG = "fg" + BG = "bg" + SIZE = "size" + + DARK = 255 + LIGHT = 127 +) +const ( + BLACK = "black" + RED = "red" + YELLOW = "yellow" + GREEN = "green" + CYAN = "cyan" + BLUE = "blue" + MAGENTA = "magenta" + WHITE = "white" + RANDOM = "random" +) const QRCODE = "qrcode" func init() { Index.Merge(&ice.Context{ Configs: map[string]*ice.Config{ - QRCODE: {Name: "qrcode", Help: "二维码", Value: kit.Data()}, + QRCODE: {Name: QRCODE, Help: "二维码", Value: kit.Data()}, }, Commands: map[string]*ice.Command{ QRCODE: {Name: "qrcode text fg bg size auto", Help: "二维码", Action: map[string]*ice.Action{}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Option("fg", kit.Select("blue", arg, 1)) - m.Option("bg", kit.Select("white", arg, 2)) - m.Option("size", kit.Select("240", arg, 3)) + m.Option(FG, kit.Select(BLUE, arg, 1)) + m.Option(BG, kit.Select(WHITE, arg, 2)) + m.Option(SIZE, kit.Select("240", arg, 3)) if aaa.SessIsCli(m) { _qrcode_cli(m, arg[0]) diff --git a/base/cli/system.go b/base/cli/system.go index 8df1bdc8..65a6eea5 100644 --- a/base/cli/system.go +++ b/base/cli/system.go @@ -25,8 +25,8 @@ func _system_show(m *ice.Message, cmd *exec.Cmd) { } } else { - out := bytes.NewBuffer(make([]byte, 0, 1024)) - err := bytes.NewBuffer(make([]byte, 0, 1024)) + out := bytes.NewBuffer(make([]byte, 0, ice.MOD_BUFS)) + err := bytes.NewBuffer(make([]byte, 0, ice.MOD_BUFS)) defer func() { m.Push(CMD_ERR, err.String()) m.Push(CMD_OUT, out.String()) @@ -66,8 +66,10 @@ const ( DARWIN = "darwin" WINDOWS = "windows" SOURCE = "source" - HOME = "home" - PATH = "path" + + USER = "USER" + HOME = "HOME" + PATH = "PATH" ) const SYSTEM = "system" diff --git a/base/gdb/event.go b/base/gdb/event.go index b187a629..fcd6abed 100644 --- a/base/gdb/event.go +++ b/base/gdb/event.go @@ -36,18 +36,15 @@ func init() { m.Cmdy(mdb.DELETE, EVENT, "", mdb.HASH, EVENT, m.Option(EVENT)) }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - if len(arg) == 0 { + if len(arg) == 0 { // 事件列表 m.Option(mdb.FIELDS, "time,event,count") m.Cmdy(mdb.SELECT, EVENT, "", mdb.HASH) m.PushAction(ACTION, mdb.REMOVE) return } - m.Option(mdb.FIELDS, kit.Select("time,id,cmd", mdb.DETAIL, len(arg) > 1)) + m.Fields(len(arg) == 1, "time,id,cmd") m.Cmdy(mdb.SELECT, EVENT, kit.Keys(kit.MDB_HASH, kit.Hashs(arg[0])), mdb.LIST, kit.MDB_ID, arg[1:]) - if len(arg) == 1 { - m.Sort(kit.MDB_ID) - } }}, }, }) diff --git a/base/gdb/gdb.go b/base/gdb/gdb.go index e55891b3..f4420723 100644 --- a/base/gdb/gdb.go +++ b/base/gdb/gdb.go @@ -1,13 +1,13 @@ package gdb import ( + "os" + "time" + ice "github.com/shylinux/icebergs" "github.com/shylinux/icebergs/base/cli" "github.com/shylinux/icebergs/base/nfs" kit "github.com/shylinux/toolkits" - - "os" - "time" ) type Frame struct { @@ -53,10 +53,11 @@ const ( STATUS = "status" RESTART = "restart" RELOAD = "reload" - BENCH = "bench" - PPROF = "pprof" - BEGIN = "begin" - END = "end" + + BENCH = "bench" + PPROF = "pprof" + BEGIN = "begin" + END = "end" ) const GDB = "gdb" diff --git a/base/gdb/routine.go b/base/gdb/routine.go index 5eeda582..f601791a 100644 --- a/base/gdb/routine.go +++ b/base/gdb/routine.go @@ -1,11 +1,11 @@ package gdb import ( + "strings" + ice "github.com/shylinux/icebergs" "github.com/shylinux/icebergs/base/mdb" kit "github.com/shylinux/toolkits" - - "strings" ) const ( @@ -55,7 +55,7 @@ func init() { } }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Option(mdb.FIELDS, kit.Select("time,hash,status,fileline", mdb.DETAIL, len(arg) > 0)) + m.Fields(len(arg) == 0, "time,hash,status,fileline") m.Cmdy(mdb.SELECT, ROUTINE, "", mdb.HASH, kit.MDB_HASH, arg) m.PushAction(INNER, mdb.REMOVE) }}, diff --git a/base/gdb/signal.go b/base/gdb/signal.go index a08f66de..2eecb441 100644 --- a/base/gdb/signal.go +++ b/base/gdb/signal.go @@ -1,12 +1,12 @@ package gdb import ( + "os/signal" + "syscall" + ice "github.com/shylinux/icebergs" "github.com/shylinux/icebergs/base/mdb" kit "github.com/shylinux/toolkits" - - "os/signal" - "syscall" ) func _signal_listen(m *ice.Message, s int, arg ...string) { @@ -37,7 +37,7 @@ func init() { )}, }, Commands: map[string]*ice.Command{ - SIGNAL: {Name: "signal auto listen", Help: "信号器", Action: map[string]*ice.Action{ + SIGNAL: {Name: "signal signal auto listen", Help: "信号器", Action: map[string]*ice.Action{ LISTEN: {Name: "listen signal name cmd", Help: "监听", Hand: func(m *ice.Message, arg ...string) { _signal_listen(m, kit.Int(m.Option(SIGNAL)), arg...) }}, @@ -48,7 +48,7 @@ func init() { m.Cmdy(mdb.DELETE, SIGNAL, "", mdb.HASH, SIGNAL, m.Option(SIGNAL)) }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Option(mdb.FIELDS, "time,signal,name,cmd") + m.Fields(len(arg) == 0, "time,signal,name,cmd") m.Cmdy(mdb.SELECT, SIGNAL, "", mdb.HASH, SIGNAL, arg) m.PushAction(ACTION, mdb.REMOVE) m.Sort(SIGNAL) diff --git a/base/gdb/timer.go b/base/gdb/timer.go index 62272ce4..83488e2c 100644 --- a/base/gdb/timer.go +++ b/base/gdb/timer.go @@ -1,11 +1,11 @@ package gdb import ( + "time" + ice "github.com/shylinux/icebergs" "github.com/shylinux/icebergs/base/mdb" kit "github.com/shylinux/toolkits" - - "time" ) func _timer_create(m *ice.Message, arg ...string) { @@ -61,15 +61,14 @@ func init() { }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if len(arg) == 0 { - m.Option(mdb.FIELDS, kit.Select("time,hash,delay,interval,order,next,cmd", mdb.DETAIL, len(arg) > 0)) + m.Fields(len(arg) == 0, "time,hash,delay,interval,order,next,cmd") m.Cmdy(mdb.SELECT, TIMER, "", mdb.HASH, kit.MDB_HASH, arg) m.PushAction(mdb.REMOVE) return } - m.Option(mdb.FIELDS, kit.Select("time,id,res", mdb.DETAIL, len(arg) > 1)) + m.Fields(len(arg) == 1, "time,id,res") m.Cmdy(mdb.SELECT, TIMER, kit.Keys(kit.MDB_HASH, arg[0]), mdb.LIST, kit.MDB_ID, arg[1:]) - return }}, }, }) diff --git a/base/mdb/mdb.go b/base/mdb/mdb.go index 79cc7a42..78d1fe49 100644 --- a/base/mdb/mdb.go +++ b/base/mdb/mdb.go @@ -1,15 +1,15 @@ package mdb import ( - ice "github.com/shylinux/icebergs" - kit "github.com/shylinux/toolkits" - "encoding/csv" "encoding/json" "os" "path" "sort" "strings" + + ice "github.com/shylinux/icebergs" + kit "github.com/shylinux/toolkits" ) func _file_name(m *ice.Message, arg ...string) string { @@ -41,7 +41,7 @@ func _hash_select(m *ice.Message, prefix, chain, field, value string) { value = kit.MDB_RANDOMS } fields := _hash_fields(m) - cb := m.Optionv(SELECT_CB) + cb := m.Optionv(kit.Keycb(SELECT)) m.Richs(prefix, chain, value, func(key string, val map[string]interface{}) { val = kit.GetMeta(val) switch cb := cb.(type) { @@ -156,7 +156,7 @@ func _list_select(m *ice.Message, prefix, chain, field, value string) { field = "" } fields := _list_fields(m) - cb := m.Optionv(SELECT_CB) + cb := m.Optionv(kit.Keycb(SELECT)) m.Grows(prefix, chain, kit.Select(m.Option("cache.field"), field), kit.Select(m.Option(CACHE_VALUE), value), func(index int, val map[string]interface{}) { val = kit.GetMeta(val) switch cb := cb.(type) { @@ -275,7 +275,7 @@ func _zone_select(m *ice.Message, prefix, chain, zone string, id string) { } fields := _zone_fields(m) - cb := m.Optionv(SELECT_CB) + cb := m.Optionv(kit.Keycb(SELECT)) m.Richs(prefix, chain, kit.Select(kit.MDB_FOREACH, zone), func(key string, val map[string]interface{}) { val = kit.GetMeta(val) if zone == "" { @@ -405,16 +405,10 @@ const ( DELETE = "delete" REMOVE = "remove" - SELECT_CB = "select.cb" - EXPORT = "export" IMPORT = "import" PRUNES = "prunes" INPUTS = "inputs" - SCRIPT = "script" - COMMIT = "commit" - SOURCE = "source" - UPLOAD = "upload" ) const ( CACHE_LIMIT = "cache.limit" diff --git a/base/mdb/search.go b/base/mdb/search.go index 15b2e395..9631803a 100644 --- a/base/mdb/search.go +++ b/base/mdb/search.go @@ -1,10 +1,10 @@ package mdb import ( + "strings" + ice "github.com/shylinux/icebergs" kit "github.com/shylinux/toolkits" - - "strings" ) const SEARCH = "search" diff --git a/base/nfs/dir.go b/base/nfs/dir.go index 212af533..10f26504 100644 --- a/base/nfs/dir.go +++ b/base/nfs/dir.go @@ -182,13 +182,8 @@ func init() { nil, kit.Split("time,size,type,path")) }}, - mdb.UPLOAD: {Name: "upload", Help: "上传", Hand: func(m *ice.Message, arg ...string) { - up := kit.Simple(m.Optionv(ice.MSG_UPLOAD)) - if p := path.Join(m.Option(kit.MDB_PATH), up[1]); m.Option(ice.MSG_USERPOD) == "" { - m.Cmdy("web.cache", "watch", up[0], p) - } else { - m.Cmdy("web.spide", "dev", "save", p, "GET", kit.MergeURL2(m.Option(ice.MSG_USERWEB), "/share/cache/"+up[0])) - } + "upload": {Name: "upload", Help: "上传", Hand: func(m *ice.Message, arg ...string) { + m.Upload(m.Option(kit.MDB_PATH)) }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if len(arg) == 0 { diff --git a/base/nfs/tail.go b/base/nfs/tail.go index beda5563..f13cfc7d 100644 --- a/base/nfs/tail.go +++ b/base/nfs/tail.go @@ -56,7 +56,7 @@ func init() { m.Toast("已经是最后一页啦!") } - m.Process("_rewrite", "offend", offend) + m.ProcessRewrite("offend", offend) }}, "next": {Name: "next", Help: "下一页", Hand: func(m *ice.Message, arg ...string) { offend := kit.Int(kit.Select("0", arg, 3)) - kit.Int(kit.Select("10", arg, 2)) @@ -64,7 +64,7 @@ func init() { offend = 0 m.Toast("已经是第一页啦!") } - m.Process("_rewrite", "offend", offend) + m.ProcessRewrite("offend", offend) }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Option(mdb.FIELDS, kit.Select("time,hash,count,name,file", kit.Select("time,id,file,text", mdb.DETAIL, len(arg) > 1 && arg[1] != ""), len(arg) > 0)) diff --git a/base/nfs/trash.go b/base/nfs/trash.go index 51f85b86..2b316c9f 100644 --- a/base/nfs/trash.go +++ b/base/nfs/trash.go @@ -29,6 +29,9 @@ func _trash_create(m *ice.Message, name string) { } } } +func _trash_prunes(m *ice.Message) { + m.Cmd(mdb.DELETE, TRASH, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH)) +} const TRASH = "trash" @@ -40,16 +43,23 @@ func init() { )}, }, Commands: map[string]*ice.Command{ - TRASH: {Name: "trash file auto", Help: "回收站", Action: map[string]*ice.Action{ + TRASH: {Name: "trash file auto prunes", Help: "回收站", Action: map[string]*ice.Action{ "recover": {Name: "recover", Help: "恢复", Hand: func(m *ice.Message, arg ...string) { os.Rename(m.Option(kit.MDB_FILE), m.Option(kit.MDB_FROM)) m.Cmd(mdb.DELETE, TRASH, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH)) }}, + mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { + os.Remove(m.Option(kit.MDB_FILE)) + m.Cmd(mdb.DELETE, TRASH, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH)) + }}, + mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) { + _trash_prunes(m) + }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if len(arg) == 0 { m.Option(mdb.FIELDS, "time,hash,file,from") m.Cmdy(mdb.SELECT, TRASH, "", mdb.HASH) - m.PushAction("recover") + m.PushAction("recover", mdb.REMOVE) return } _trash_create(m, arg[0]) diff --git a/base/ssh/connect.go b/base/ssh/connect.go index c1ef746e..2ca212bb 100644 --- a/base/ssh/connect.go +++ b/base/ssh/connect.go @@ -12,6 +12,7 @@ import ( ice "github.com/shylinux/icebergs" "github.com/shylinux/icebergs/base/aaa" + "github.com/shylinux/icebergs/base/cli" "github.com/shylinux/icebergs/base/mdb" "github.com/shylinux/icebergs/base/nfs" "github.com/shylinux/icebergs/base/tcp" @@ -111,7 +112,7 @@ func _ssh_conn(m *ice.Message, conn net.Conn, username, hostport string) *ssh.Cl })) methods = append(methods, ssh.PublicKeysCallback(func() ([]ssh.Signer, error) { - key, err := ssh.ParsePrivateKey([]byte(m.Cmdx(nfs.CAT, path.Join(os.Getenv("HOME"), m.Option("private"))))) + key, err := ssh.ParsePrivateKey([]byte(m.Cmdx(nfs.CAT, path.Join(os.Getenv(cli.HOME), m.Option("private"))))) return []ssh.Signer{key}, err })) methods = append(methods, ssh.PasswordCallback(func() (string, error) { @@ -127,6 +128,76 @@ func _ssh_conn(m *ice.Message, conn net.Conn, username, hostport string) *ssh.Cl return ssh.NewClient(c, chans, reqs) } +func _ssh_open(m *ice.Message, arg ...string) { + var client *ssh.Client + w, h, _ := terminal.GetSize(int(os.Stdin.Fd())) + + _ssh_password(m, m.Option("authfile")) + p := path.Join(os.Getenv("HOME"), ".ssh/", fmt.Sprintf("%s@%s", m.Option("username"), m.Option("host"))) + if _, e := os.Stat(p); e == nil { + if c, e := net.Dial("unix", p); e == nil { + + pr, pw := _ssh_stream(m, os.Stdin) + defer _ssh_store(os.Stdout)() + defer _ssh_store(os.Stdin)() + + c.Write([]byte(fmt.Sprintf("height:%d,width:%d\n", h, w))) + + m.Go(func() { io.Copy(c, pr) }) + _ssh_init(m, pw) + m.Echo("logout\n") + io.Copy(os.Stdout, c) + return + } else { + os.Remove(p) + } + } + + if l, e := net.Listen("unix", p); m.Assert(e) { + defer func() { os.Remove(p) }() + defer l.Close() + + m.Go(func() { + for { + if c, e := l.Accept(); e == nil { + buf := make([]byte, 1024) + if n, e := c.Read(buf); m.Assert(e) { + fmt.Sscanf(string(buf[:n]), "height:%d,width:%d", &h, &w) + } + + session := _ssh_session(m, client, w, h, c, c, c) + func(session *ssh.Session) { + m.Go(func() { + defer c.Close() + session.Wait() + }) + }(session) + } else { + break + } + } + }) + } + + m.Option(kit.Keycb(tcp.DIAL), func(c net.Conn) { + client = _ssh_conn(m, c, m.Option(aaa.USERNAME), m.Option(tcp.HOST)+":"+m.Option(tcp.PORT)) + + pr, pw := _ssh_stream(m, os.Stdin) + defer _ssh_store(os.Stdout)() + defer _ssh_store(os.Stdin)() + + session := _ssh_session(m, client, w, h, pr, os.Stdout, os.Stderr) + _ssh_init(m, pw) + _ssh_tick(m, pw) + session.Wait() + }) + + m.Cmdy(tcp.CLIENT, tcp.DIAL, kit.MDB_TYPE, "ssh", kit.MDB_NAME, m.Option(tcp.HOST), + tcp.PORT, m.Option(tcp.PORT), tcp.HOST, m.Option(tcp.HOST), arg) + + m.Echo("exit %s\n", m.Option(tcp.HOST)) +} + const CONNECT = "connect" func init() { @@ -137,25 +208,34 @@ func init() { Commands: map[string]*ice.Command{ CONNECT: {Name: "connect hash auto dial prunes", Help: "连接", Action: map[string]*ice.Action{ tcp.DIAL: {Name: "dial username=shy host=shylinux.com port=22 private=.ssh/id_rsa", Help: "添加", Hand: func(m *ice.Message, arg ...string) { - m.Option(tcp.DIAL_CB, func(c net.Conn) { + m.Option(kit.Keycb(tcp.DIAL), func(c net.Conn) { client := _ssh_conn(m, c, kit.Select("shy", m.Option(aaa.USERNAME)), kit.Select("shylinux.com", m.Option(tcp.HOST))+":"+kit.Select("22", m.Option(tcp.PORT)), ) h := m.Rich(CONNECT, "", kit.Dict( aaa.USERNAME, m.Option(aaa.USERNAME), - tcp.HOST, m.Option(tcp.HOST), - tcp.PORT, m.Option(tcp.PORT), - kit.MDB_STATUS, tcp.OPEN, - CONNECT, client, + tcp.HOST, m.Option(tcp.HOST), tcp.PORT, m.Option(tcp.PORT), + kit.MDB_STATUS, tcp.OPEN, CONNECT, client, )) m.Cmd(CONNECT, SESSION, kit.MDB_HASH, h) m.Echo(h) }) - m.Cmds(tcp.CLIENT, tcp.DIAL, kit.MDB_TYPE, SSH, kit.MDB_NAME, m.Option(aaa.USERNAME), tcp.PORT, m.Option(tcp.PORT), tcp.HOST, m.Option(tcp.HOST)) - m.Sleep("100ms") + m.Cmds(tcp.CLIENT, tcp.DIAL, kit.MDB_TYPE, SSH, kit.MDB_NAME, m.Option(aaa.USERNAME), + tcp.PORT, m.Option(tcp.PORT), tcp.HOST, m.Option(tcp.HOST)) }}, + tcp.OPEN: {Name: "open authfile= username=shy password= verfiy= host=shylinux.com port=22 private=.ssh/id_rsa tick=", Help: "终端", Hand: func(m *ice.Message, arg ...string) { + _ssh_open(m, arg...) + }}, + mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { + m.Cmdy(mdb.DELETE, CONNECT, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH)) + }}, + mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) { + m.Cmdy(mdb.PRUNES, CONNECT, "", mdb.HASH, kit.MDB_STATUS, tcp.ERROR) + m.Cmdy(mdb.PRUNES, CONNECT, "", mdb.HASH, kit.MDB_STATUS, tcp.CLOSE) + }}, + SESSION: {Name: "session hash", Help: "会话", Hand: func(m *ice.Message, arg ...string) { m.Richs(CONNECT, "", m.Option(kit.MDB_HASH), func(key string, value map[string]interface{}) { client, ok := value[CONNECT].(*ssh.Client) @@ -169,84 +249,8 @@ func init() { } }) }}, - - "open": {Name: "open authfile= username=shy password= verfiy= host=shylinux.com port=22 private=.ssh/id_rsa tick=", Help: "终端", Hand: func(m *ice.Message, arg ...string) { - var client *ssh.Client - w, h, _ := terminal.GetSize(int(os.Stdin.Fd())) - - _ssh_password(m, m.Option("authfile")) - p := path.Join(os.Getenv("HOME"), ".ssh/", fmt.Sprintf("%s@%s", m.Option("username"), m.Option("host"))) - if _, e := os.Stat(p); e == nil { - if c, e := net.Dial("unix", p); e == nil { - - pr, pw := _ssh_stream(m, os.Stdin) - defer _ssh_store(os.Stdout)() - defer _ssh_store(os.Stdin)() - - c.Write([]byte(fmt.Sprintf("height:%d,width:%d\n", h, w))) - - m.Go(func() { io.Copy(c, pr) }) - _ssh_init(m, pw) - m.Echo("logout\n") - io.Copy(os.Stdout, c) - return - } else { - os.Remove(p) - } - } - - if l, e := net.Listen("unix", p); m.Assert(e) { - defer func() { os.Remove(p) }() - defer l.Close() - - m.Go(func() { - for { - if c, e := l.Accept(); e == nil { - buf := make([]byte, 1024) - if n, e := c.Read(buf); m.Assert(e) { - fmt.Sscanf(string(buf[:n]), "height:%d,width:%d", &h, &w) - } - - session := _ssh_session(m, client, w, h, c, c, c) - func(session *ssh.Session) { - m.Go(func() { - defer c.Close() - session.Wait() - }) - }(session) - } else { - break - } - } - }) - } - - m.Option(tcp.DIAL_CB, func(c net.Conn) { - client = _ssh_conn(m, c, m.Option(aaa.USERNAME), m.Option(tcp.HOST)+":"+m.Option(tcp.PORT)) - - pr, pw := _ssh_stream(m, os.Stdin) - defer _ssh_store(os.Stdout)() - defer _ssh_store(os.Stdin)() - - session := _ssh_session(m, client, w, h, pr, os.Stdout, os.Stderr) - _ssh_init(m, pw) - _ssh_tick(m, pw) - session.Wait() - }) - - m.Cmdy(tcp.CLIENT, tcp.DIAL, kit.MDB_TYPE, "ssh", kit.MDB_NAME, m.Option(tcp.HOST), - tcp.PORT, m.Option(tcp.PORT), tcp.HOST, m.Option(tcp.HOST), arg) - - m.Echo("exit %s\n", m.Option(tcp.HOST)) - }}, - mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(mdb.DELETE, CONNECT, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH)) - }}, - mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(mdb.PRUNES, CONNECT, "", mdb.HASH, kit.MDB_STATUS, tcp.CLOSE) - }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Option(mdb.FIELDS, kit.Select("time,hash,status,username,host,port", mdb.DETAIL, len(arg) > 0)) + m.Fields(len(arg) == 0, "time,hash,status,username,host,port") if m.Cmdy(mdb.SELECT, CONNECT, "", mdb.HASH, kit.MDB_HASH, arg); len(arg) == 0 { m.Table(func(index int, value map[string]string, head []string) { m.PushButton(kit.Select("", mdb.REMOVE, value[kit.MDB_STATUS] == tcp.CLOSE)) diff --git a/base/ssh/scripts.go b/base/ssh/scripts.go index 64772255..d600505e 100644 --- a/base/ssh/scripts.go +++ b/base/ssh/scripts.go @@ -1,12 +1,6 @@ package ssh import ( - ice "github.com/shylinux/icebergs" - "github.com/shylinux/icebergs/base/aaa" - "github.com/shylinux/icebergs/base/mdb" - "github.com/shylinux/icebergs/base/nfs" - kit "github.com/shylinux/toolkits" - "bufio" "bytes" "fmt" @@ -15,6 +9,12 @@ import ( "path" "strings" "time" + + ice "github.com/shylinux/icebergs" + "github.com/shylinux/icebergs/base/aaa" + "github.com/shylinux/icebergs/base/mdb" + "github.com/shylinux/icebergs/base/nfs" + kit "github.com/shylinux/toolkits" ) func Render(msg *ice.Message, cmd string, args ...interface{}) { diff --git a/base/ssh/service.go b/base/ssh/service.go index 8d9f3a76..b9f0b58f 100644 --- a/base/ssh/service.go +++ b/base/ssh/service.go @@ -113,7 +113,7 @@ func init() { m.Cmd(SERVICE, mdb.IMPORT, kit.MDB_FILE, m.Option("auth")) } - m.Option(tcp.LISTEN_CB, func(c net.Conn) { m.Go(func() { _ssh_accept(m, kit.Hashs(m.Option(tcp.PORT)), c) }) }) + m.Option(kit.Keycb(tcp.LISTEN), func(c net.Conn) { m.Go(func() { _ssh_accept(m, kit.Hashs(m.Option(tcp.PORT)), c) }) }) m.Go(func() { m.Cmdy(tcp.SERVER, tcp.LISTEN, kit.MDB_TYPE, SSH, kit.MDB_NAME, tcp.PORT, tcp.PORT, m.Option(tcp.PORT)) }) diff --git a/base/ssh/service_darwin.go b/base/ssh/service_darwin.go index c5e7740f..272b1f8e 100644 --- a/base/ssh/service_darwin.go +++ b/base/ssh/service_darwin.go @@ -1,13 +1,13 @@ package ssh import ( - ice "github.com/shylinux/icebergs" - "golang.org/x/crypto/ssh" - "encoding/binary" "net" "syscall" "unsafe" + + ice "github.com/shylinux/icebergs" + "golang.org/x/crypto/ssh" ) func _ssh_size(fd uintptr, b []byte) { diff --git a/base/ssh/service_linux.go b/base/ssh/service_linux.go index 73773596..789a1877 100644 --- a/base/ssh/service_linux.go +++ b/base/ssh/service_linux.go @@ -1,12 +1,6 @@ package ssh import ( - ice "github.com/shylinux/icebergs" - "github.com/shylinux/icebergs/base/mdb" - "github.com/shylinux/icebergs/base/tcp" - kit "github.com/shylinux/toolkits" - "golang.org/x/crypto/ssh" - "encoding/binary" "github.com/kr/pty" "io" @@ -14,6 +8,12 @@ import ( "os" "syscall" "unsafe" + + ice "github.com/shylinux/icebergs" + "github.com/shylinux/icebergs/base/mdb" + "github.com/shylinux/icebergs/base/tcp" + kit "github.com/shylinux/toolkits" + "golang.org/x/crypto/ssh" ) func _ssh_size(fd uintptr, b []byte) { diff --git a/base/ssh/service_windows.go b/base/ssh/service_windows.go index 0064d21e..5d1e3495 100644 --- a/base/ssh/service_windows.go +++ b/base/ssh/service_windows.go @@ -1,9 +1,10 @@ package ssh import ( + "net" + ice "github.com/shylinux/icebergs" "golang.org/x/crypto/ssh" - "net" ) func _ssh_size(fd uintptr, b []byte) { diff --git a/base/tcp/client.go b/base/tcp/client.go index aa3876f8..8c457418 100644 --- a/base/tcp/client.go +++ b/base/tcp/client.go @@ -1,11 +1,11 @@ package tcp import ( + "net" + ice "github.com/shylinux/icebergs" "github.com/shylinux/icebergs/base/mdb" kit "github.com/shylinux/toolkits" - - "net" ) type Stat struct { @@ -23,32 +23,27 @@ type Conn struct { func (c *Conn) Read(b []byte) (int, error) { n, e := c.Conn.Read(b) c.s.nr += n - // c.m.Conf(CLIENT, kit.Keys(kit.MDB_HASH, c.h, kit.MDB_META, "nread"), c.s.nr) return n, e } func (c *Conn) Write(b []byte) (int, error) { n, e := c.Conn.Write(b) c.s.nw += n - // c.m.Conf(CLIENT, kit.Keys(kit.MDB_HASH, c.h, kit.MDB_META, "nwrite"), c.s.nw) return n, e } func (c *Conn) Close() error { - // c.m.Cmd(mdb.MODIFY, CLIENT, "", mdb.HASH, kit.MDB_HASH, c.h, kit.MDB_STATUS, CLOSE, "nread", c.s.nr, "nwrite", c.s.nw) + c.m.Cmd(mdb.MODIFY, CLIENT, "", mdb.HASH, kit.MDB_HASH, c.h, kit.MDB_STATUS, CLOSE, "nread", c.s.nr, "nwrite", c.s.nw) return c.Conn.Close() } const ( - SOCKET = "socket" - OPEN = "open" - START = "start" - ERROR = "error" CLOSE = "close" + ERROR = "error" + START = "start" STOP = "stop" ) const ( - DIAL_CB = "dial.cb" - DIAL = "dial" + DIAL = "dial" ) const CLIENT = "client" @@ -62,17 +57,16 @@ func init() { CLIENT: {Name: "client hash auto prunes", Help: "客户端", Action: map[string]*ice.Action{ DIAL: {Name: "dial type name port=9010 host=", Help: "连接", Hand: func(m *ice.Message, arg ...string) { c, e := net.Dial(TCP, m.Option(HOST)+":"+m.Option(PORT)) - // h := m.Cmdx(mdb.INSERT, CLIENT, "", mdb.HASH, PORT, m.Option(PORT), HOST, m.Option(HOST), - // kit.MDB_TYPE, m.Option(kit.MDB_TYPE), kit.MDB_NAME, m.Option(kit.MDB_NAME), - // kit.MDB_STATUS, kit.Select(ERROR, OPEN, e == nil), kit.MDB_ERROR, kit.Format(e)) - // - // c = &Conn{m: m, h: h, s: &Stat{}, Conn: c} - c = &Conn{m: m, s: &Stat{}, Conn: c} + h := m.Cmdx(mdb.INSERT, CLIENT, "", mdb.HASH, PORT, m.Option(PORT), HOST, m.Option(HOST), + kit.MDB_TYPE, m.Option(kit.MDB_TYPE), kit.MDB_NAME, m.Option(kit.MDB_NAME), + kit.MDB_STATUS, kit.Select(ERROR, OPEN, e == nil), kit.MDB_ERROR, kit.Format(e)) + + c = &Conn{m: m, h: h, s: &Stat{}, Conn: c} if e == nil { defer c.Close() } - switch cb := m.Optionv(DIAL_CB).(type) { + switch cb := m.Optionv(kit.Keycb(DIAL)).(type) { case func(net.Conn, error): cb(c, e) case func(net.Conn): @@ -98,7 +92,7 @@ func init() { m.Cmdy(mdb.PRUNES, CLIENT, "", mdb.HASH, kit.MDB_STATUS, CLOSE) }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Option(mdb.FIELDS, kit.Select("time,hash,status,type,name,host,port,error,nread,nwrite", mdb.DETAIL, len(arg) > 0)) + m.Fields(len(arg) == 0, "time,hash,status,type,name,host,port,error,nread,nwrite") if m.Cmdy(mdb.SELECT, CLIENT, "", mdb.HASH, kit.MDB_HASH, arg); len(arg) == 0 { m.Table(func(index int, value map[string]string, head []string) { m.PushButton(kit.Select("", mdb.REMOVE, value[kit.MDB_STATUS] == OPEN)) diff --git a/base/tcp/host.go b/base/tcp/host.go index ce5408a2..82545f11 100644 --- a/base/tcp/host.go +++ b/base/tcp/host.go @@ -1,18 +1,18 @@ package tcp import ( + "net" + "strings" + ice "github.com/shylinux/icebergs" "github.com/shylinux/icebergs/base/aaa" kit "github.com/shylinux/toolkits" - - "net" - "strings" ) -func _host_list(m *ice.Message, ifname string) { +func _host_list(m *ice.Message, name string) { if ifs, e := net.Interfaces(); m.Assert(e) { for _, v := range ifs { - if ifname != "" && !strings.Contains(v.Name, ifname) { + if name != "" && !strings.Contains(v.Name, name) { continue } if len(v.HardwareAddr.String()) == 0 { @@ -26,22 +26,22 @@ func _host_list(m *ice.Message, ifname string) { continue } - m.Push("index", v.Index) - m.Push("name", v.Name) - m.Push("ip", ip[0]) - m.Push("mask", ip[1]) - m.Push("hard", v.HardwareAddr.String()) + m.Push(kit.MDB_INDEX, v.Index) + m.Push(kit.MDB_NAME, v.Name) + m.Push(IP, ip[0]) + m.Push(MASK, ip[1]) + m.Push(HARD, v.HardwareAddr.String()) } } } } - if len(m.Appendv("ip")) == 0 { - m.Push("index", -1) - m.Push("name", "local") - m.Push("ip", "127.0.0.1") - m.Push("mask", "255.0.0.0") - m.Push("hard", "") + if len(m.Appendv(IP)) == 0 { + m.Push(kit.MDB_INDEX, -1) + m.Push(kit.MDB_NAME, LOCALHOST) + m.Push(IP, "127.0.0.1") + m.Push(MASK, "255.0.0.0") + m.Push(HARD, "") } } @@ -49,10 +49,10 @@ func _islocalhost(m *ice.Message, ip string) (ok bool) { if ip == "::1" || strings.HasPrefix(ip, "127.") { return true } - if m.Richs(HOST, kit.Keys("meta.black"), ip, nil) != nil { + if m.Richs(HOST, kit.Keym(aaa.BLACK), ip, nil) != nil { return false } - if m.Richs(HOST, kit.Keys("meta.white"), ip, nil) != nil { + if m.Richs(HOST, kit.Keym(aaa.WHITE), ip, nil) != nil { m.Log_AUTH(aaa.WHITE, ip) return true } @@ -66,7 +66,10 @@ const ( PROTOCOL = "protocol" LOCALHOST = "localhost" - IP = "ip" + + HARD = "hard" + MASK = "mask" + IP = "ip" ) const HOST = "host" @@ -81,10 +84,10 @@ func init() { Commands: map[string]*ice.Command{ HOST: {Name: "host name auto", Help: "主机", Action: map[string]*ice.Action{ aaa.BLACK: {Name: "black", Help: "黑名单", Hand: func(m *ice.Message, arg ...string) { - m.Rich(HOST, kit.Keys("meta.black"), kit.Dict(kit.MDB_TEXT, arg[0])) + m.Rich(HOST, kit.Keym(aaa.BLACK), kit.Dict(kit.MDB_TEXT, arg[0])) }}, aaa.WHITE: {Name: "white", Help: "白名单", Hand: func(m *ice.Message, arg ...string) { - m.Rich(HOST, kit.Keys("meta.white"), kit.Dict(kit.MDB_TEXT, arg[0])) + m.Rich(HOST, kit.Keym(aaa.WHITE), kit.Dict(kit.MDB_TEXT, arg[0])) }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { _host_list(m, kit.Select("", arg, 0)) diff --git a/base/tcp/port.go b/base/tcp/port.go index 16290a53..cfb9ed81 100644 --- a/base/tcp/port.go +++ b/base/tcp/port.go @@ -1,15 +1,15 @@ package tcp import ( + "net" + "os" + "path" + ice "github.com/shylinux/icebergs" "github.com/shylinux/icebergs/base/aaa" "github.com/shylinux/icebergs/base/cli" "github.com/shylinux/icebergs/base/nfs" kit "github.com/shylinux/toolkits" - - "net" - "os" - "path" ) func _port_list(m *ice.Message, port string, dir string) { @@ -20,15 +20,15 @@ func _port_list(m *ice.Message, port string, dir string) { m.Cmd(nfs.DIR, "./").Table(func(index int, value map[string]string, head []string) { m.Push(kit.MDB_TIME, value[kit.MDB_TIME]) - m.Push(kit.MDB_SIZE, value[kit.MDB_SIZE]) m.Push(PORT, path.Base(value[kit.MDB_PATH])) + m.Push(kit.MDB_SIZE, value[kit.MDB_SIZE]) }) } func _port_right(m *ice.Message, begin string) string { - current := kit.Int(kit.Select(m.Conf(PORT, "meta.current"), begin)) - end := kit.Int(m.Conf(PORT, "meta.end")) + current := kit.Int(kit.Select(m.Conf(PORT, kit.Keym(CURRENT)), begin)) + end := kit.Int(m.Conf(PORT, kit.Keym(END))) if current >= end { - current = kit.Int(m.Conf(PORT, "meta.begin")) + current = kit.Int(m.Conf(PORT, kit.Keym(BEGIN))) } for i := current; i < end; i++ { @@ -39,14 +39,17 @@ func _port_right(m *ice.Message, begin string) string { } m.Log_SELECT(PORT, i) - m.Conf(PORT, "meta.current", i) + m.Conf(PORT, kit.Keym(CURRENT), i) return kit.Format("%d", i) } return "" } const ( - RANDOM = "random" + RANDOM = "random" + CURRENT = "current" + BEGIN = "begin" + END = "end" ) const PORT = "port" @@ -54,7 +57,7 @@ func init() { Index.Merge(&ice.Context{ Configs: map[string]*ice.Config{ PORT: {Name: PORT, Help: "端口", Value: kit.Data( - "begin", 10000, "current", 10000, "end", 20000, + BEGIN, 10000, CURRENT, 10000, END, 20000, )}, }, Commands: map[string]*ice.Command{ diff --git a/base/tcp/server.go b/base/tcp/server.go index 30ce2a1e..65262825 100644 --- a/base/tcp/server.go +++ b/base/tcp/server.go @@ -1,12 +1,11 @@ package tcp import ( + "net" + ice "github.com/shylinux/icebergs" "github.com/shylinux/icebergs/base/mdb" kit "github.com/shylinux/toolkits" - - "net" - // "strings" ) type Listener struct { @@ -20,17 +19,6 @@ type Listener struct { func (l Listener) Accept() (net.Conn, error) { c, e := l.Listener.Accept() l.s.nc += 1 - l.m.Conf(SERVER, kit.Keys(kit.MDB_HASH, l.h, kit.MDB_META, "nconn"), l.s.nc) - - // ls := strings.Split(c.RemoteAddr().String(), ":") - // if strings.Contains(c.RemoteAddr().String(), "[") { - // ls = strings.Split(strings.TrimPrefix(c.RemoteAddr().String(), "["), "]:") - // } - // h := l.m.Cmdx(mdb.INSERT, CLIENT, "", mdb.HASH, HOST, ls[0], PORT, ls[1], - // kit.MDB_TYPE, l.m.Option(kit.MDB_TYPE), kit.MDB_NAME, l.m.Option(kit.MDB_NAME), - // kit.MDB_STATUS, kit.Select(ERROR, OPEN, e == nil), kit.MDB_ERROR, kit.Format(e)) - - // return &Conn{m: l.m, h: h, s: &Stat{}, Conn: c}, e return &Conn{m: l.m, h: "", s: &Stat{}, Conn: c}, e } func (l Listener) Close() error { @@ -39,8 +27,7 @@ func (l Listener) Close() error { } const ( - LISTEN_CB = "listen.cb" - LISTEN = "listen" + LISTEN = "listen" ) const SERVER = "server" @@ -54,16 +41,15 @@ func init() { SERVER: {Name: "server hash auto prunes", Help: "服务器", Action: map[string]*ice.Action{ LISTEN: {Name: "LISTEN type name port=9010 host=", Help: "监听", Hand: func(m *ice.Message, arg ...string) { l, e := net.Listen(TCP, m.Option(HOST)+":"+m.Option(PORT)) - // h := m.Cmdx(mdb.INSERT, SERVER, "", mdb.HASH, arg, - // kit.MDB_STATUS, kit.Select(ERROR, OPEN, e == nil), kit.MDB_ERROR, kit.Format(e)) - // - // l = &Listener{m: m, h: h, s: &Stat{}, Listener: l} - l = &Listener{m: m, s: &Stat{}, Listener: l} + h := m.Cmdx(mdb.INSERT, SERVER, "", mdb.HASH, arg, + kit.MDB_STATUS, kit.Select(ERROR, OPEN, e == nil), kit.MDB_ERROR, kit.Format(e)) + + l = &Listener{m: m, h: h, s: &Stat{}, Listener: l} if e == nil { defer l.Close() } - switch cb := m.Optionv(LISTEN_CB).(type) { + switch cb := m.Optionv(kit.Keycb(LISTEN)).(type) { case func(net.Listener, error): cb(l, e) case func(net.Listener): @@ -108,7 +94,7 @@ func init() { m.Cmdy(mdb.PRUNES, SERVER, "", mdb.HASH, kit.MDB_STATUS, CLOSE) }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Option(mdb.FIELDS, kit.Select("time,hash,status,type,name,host,port,error,nconn", mdb.DETAIL, len(arg) > 0)) + m.Fields(len(arg) == 0, "time,hash,status,type,name,host,port,error,nconn") if m.Cmdy(mdb.SELECT, SERVER, "", mdb.HASH, kit.MDB_HASH, arg); len(arg) == 0 { m.Table(func(index int, value map[string]string, head []string) { m.PushButton(kit.Select("", mdb.REMOVE, value[kit.MDB_STATUS] == CLOSE)) diff --git a/base/tcp/tcp.go b/base/tcp/tcp.go index ba4188fd..d3c14c8f 100644 --- a/base/tcp/tcp.go +++ b/base/tcp/tcp.go @@ -13,17 +13,17 @@ var Index = &ice.Context{Name: TCP, Help: "通信模块", ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Load() m.Cmd(HOST).Table(func(index int, value map[string]string, head []string) { - m.Cmd(HOST, aaa.WHITE, value["ip"]) + m.Cmd(HOST, aaa.WHITE, value[IP]) }) }}, ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Richs(CLIENT, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) { - kit.Value(value, "meta.status", CLOSE) + kit.Value(value, kit.Keym(kit.MDB_STATUS), CLOSE) }) m.Richs(SERVER, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) { - kit.Value(value, "meta.status", CLOSE) + kit.Value(value, kit.Keym(kit.MDB_STATUS), CLOSE) }) - m.Save() + m.Save(PORT) }}, }, } diff --git a/base/web/cache.go b/base/web/cache.go index 2aff9661..241efc42 100644 --- a/base/web/cache.go +++ b/base/web/cache.go @@ -1,15 +1,15 @@ package web import ( - ice "github.com/shylinux/icebergs" - "github.com/shylinux/icebergs/base/mdb" - "github.com/shylinux/icebergs/base/nfs" - kit "github.com/shylinux/toolkits" - "io" "net/http" "os" "path" + + ice "github.com/shylinux/icebergs" + "github.com/shylinux/icebergs/base/mdb" + "github.com/shylinux/icebergs/base/nfs" + kit "github.com/shylinux/toolkits" ) func _cache_name(m *ice.Message, h string) string { @@ -62,7 +62,6 @@ func _cache_catch(m *ice.Message, name string) (file, size string) { } return "", "0" } - func _cache_upload(m *ice.Message, r *http.Request) (kind, name, file, size string) { if buf, h, e := r.FormFile(UPLOAD); e == nil { defer buf.Close() @@ -84,7 +83,7 @@ func _cache_upload(m *ice.Message, r *http.Request) (kind, name, file, size stri func _cache_download(m *ice.Message, r *http.Response) (file, size string) { defer r.Body.Close() - if f, p, e := kit.Create(path.Join("var/tmp", kit.Hashs("uniq"))); m.Assert(e) { + if f, p, e := kit.Create(path.Join(ice.VAR_TMP, kit.Hashs("uniq"))); m.Assert(e) { step, total := 0, kit.Int(kit.Select("1", r.Header.Get(ContentLength))) size, buf := 0, make([]byte, ice.MOD_BUFS) @@ -94,7 +93,7 @@ func _cache_download(m *ice.Message, r *http.Response) (file, size string) { f.Write(buf[0:n]) s := size * 100 / total - switch cb := m.Optionv(DOWNLOAD_CB).(type) { + switch cb := m.Optionv(kit.Keycb(DOWNLOAD)).(type) { case func(int, int): cb(size, total) case []string: @@ -129,13 +128,11 @@ func _cache_download(m *ice.Message, r *http.Response) (file, size string) { } const ( - WATCH = "watch" - CATCH = "catch" - WRITE = "write" - - UPLOAD = "upload" - DOWNLOAD = "download" - DOWNLOAD_CB = "download.cb" + WATCH = "watch" + CATCH = "catch" + WRITE = "write" + UPLOAD = "upload" + DOWNLOAD = "download" ) const CACHE = "cache" @@ -143,8 +140,8 @@ func init() { Index.Merge(&ice.Context{ Configs: map[string]*ice.Config{ CACHE: {Name: CACHE, Help: "缓存池", Value: kit.Data( - kit.MDB_SHORT, kit.MDB_TEXT, kit.MDB_PATH, "var/file", - kit.MDB_STORE, "var/data", kit.MDB_FSIZE, "200000", + kit.MDB_SHORT, kit.MDB_TEXT, kit.MDB_PATH, ice.VAR_FILE, + kit.MDB_STORE, ice.VAR_DATA, kit.MDB_FSIZE, "200000", kit.MDB_LIMIT, "50", kit.MDB_LEAST, "30", )}, }, @@ -171,21 +168,21 @@ func init() { } }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Option(mdb.FIELDS, kit.Select("time,hash,size,type,name,text", mdb.DETAIL, len(arg) > 0)) - m.Cmdy(mdb.SELECT, CACHE, "", mdb.HASH, kit.MDB_HASH, arg) + m.Fields(len(arg) == 0, "time,hash,size,type,name,text") + if m.Cmdy(mdb.SELECT, CACHE, "", mdb.HASH, kit.MDB_HASH, arg); len(arg) == 0 { + return + } - if len(arg) > 0 { - if m.Append(kit.MDB_FILE) == "" { - m.Push(kit.MDB_LINK, m.Append(kit.MDB_TEXT)) - } else { - m.PushAnchor(DOWNLOAD, kit.MergeURL2(m.Option(ice.MSG_USERWEB), "/share/cache/"+arg[0])) - } + if m.Append(kit.MDB_FILE) == "" { + m.Push(kit.MDB_LINK, m.Append(kit.MDB_TEXT)) + } else { + m.PushAnchor(DOWNLOAD, kit.MergeURL2(m.Option(ice.MSG_USERWEB), "/share/cache/"+arg[0])) } }}, "/cache/": {Name: "/cache/", Help: "缓存池", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Richs(CACHE, nil, arg[0], func(key string, value map[string]interface{}) { - if value[kit.MDB_FILE] == nil { + if kit.Format(value[kit.MDB_FILE]) == "" { m.Render(ice.RENDER_DOWNLOAD, value[kit.MDB_FILE]) } else { m.Render(ice.RENDER_RESULT, value[kit.MDB_TEXT]) diff --git a/base/web/dream.go b/base/web/dream.go index 5786f973..510e6eba 100644 --- a/base/web/dream.go +++ b/base/web/dream.go @@ -1,6 +1,11 @@ package web import ( + "io/ioutil" + "os" + "path" + "strings" + ice "github.com/shylinux/icebergs" "github.com/shylinux/icebergs/base/cli" "github.com/shylinux/icebergs/base/gdb" @@ -8,11 +13,6 @@ import ( "github.com/shylinux/icebergs/base/nfs" "github.com/shylinux/icebergs/base/tcp" kit "github.com/shylinux/toolkits" - - "io/ioutil" - "os" - "path" - "strings" ) func _dream_list(m *ice.Message) { @@ -73,9 +73,8 @@ func _dream_show(m *ice.Message, name string) { if m.Richs(SPACE, nil, name, nil) == nil { m.Option(cli.CMD_DIR, p) m.Optionv(cli.CMD_ENV, kit.Simple( - // "ctx_dev", m.Conf(cli.RUNTIME, "conf.ctx_dev"), "ctx_dev", "http://:"+m.Cmd(SERVE).Append(tcp.PORT), - "PATH", kit.Path(path.Join(p, kit.SSH_BIN))+":"+kit.Path(kit.SSH_BIN)+":"+os.Getenv("PATH"), + cli.PATH, kit.Path(path.Join(p, kit.SSH_BIN))+":"+kit.Path(kit.SSH_BIN)+":"+os.Getenv(cli.PATH), "USER", ice.Info.UserName, m.Confv(DREAM, kit.Keym(kit.SSH_ENV)), )) // 启动任务 @@ -111,7 +110,7 @@ func init() { }}, mdb.CREATE: {Name: "create main=src/main.go@key name=hi@key from=usr/icebergs/misc/bash/bash.go@key", Help: "添加", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(SPACE, m.Option(ROUTE), "web.code.autogen", mdb.CREATE, arg) - m.Option(ice.MSG_PROCESS, ice.PROCESS_INNER) + m.ProcessInner() }}, tcp.START: {Name: "start name repos", Help: "启动", Hand: func(m *ice.Message, arg ...string) { if m.Option(kit.MDB_NAME) == SPIDE_SELF { diff --git a/base/web/route.go b/base/web/route.go index da42d3e4..69034e3b 100644 --- a/base/web/route.go +++ b/base/web/route.go @@ -51,14 +51,14 @@ func _route_list(m *ice.Message) { m.Cmd(tcp.HOST).Table(func(index int, value map[string]string, head []string) { m.Push(kit.MDB_TYPE, MYSELF) m.Push(kit.SSH_ROUTE, ice.Info.NodeName) - m.PushAnchor(value["ip"], kit.Format("%s://%s:%s", u.Scheme, value["ip"], u.Port())) + m.PushAnchor(value[tcp.IP], kit.Format("%s://%s:%s", u.Scheme, value[tcp.IP], u.Port())) m.PushButton(tcp.START) }) // 本机信息 m.Push(kit.MDB_TYPE, MYSELF) m.Push(kit.SSH_ROUTE, ice.Info.NodeName) - m.PushAnchor("localhost", kit.Format("%s://%s:%s", u.Scheme, "localhost", u.Port())) + m.PushAnchor(tcp.LOCALHOST, kit.Format("%s://%s:%s", u.Scheme, tcp.LOCALHOST, u.Port())) m.PushButton(tcp.START) m.Sort(kit.SSH_ROUTE) @@ -108,11 +108,11 @@ func init() { mdb.CREATE: {Name: "create main=src/main.go@key name=hi@key from=usr/icebergs/misc/bash/bash.go@key", Help: "添加", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(SPACE, m.Option(ROUTE), "web.code.autogen", mdb.CREATE, arg) - m.Option(ice.MSG_PROCESS, ice.PROCESS_INNER) + m.ProcessInner() }}, tcp.START: {Name: "start name repos template", Help: "启动", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(SPACE, m.Option(ROUTE), DREAM, tcp.START, arg) - m.Option(ice.MSG_PROCESS, ice.PROCESS_INNER) + m.ProcessInner() }}, ctx.COMMAND: {Name: "command", Help: "命令", Hand: func(m *ice.Message, arg ...string) { m.Debug(m.Option(ROUTE)) diff --git a/base/web/serve.go b/base/web/serve.go index 281889ad..b9d6f6e5 100644 --- a/base/web/serve.go +++ b/base/web/serve.go @@ -35,7 +35,7 @@ func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool { m.Info("").Info("%s %s %s", r.Header.Get(ice.MSG_USERIP), r.Method, r.URL) // 参数日志 - if m.Conf(SERVE, kit.Keym("logheaders")) == "true" { + if m.Conf(SERVE, kit.Keym(LOGHEADERS)) == "true" { for k, v := range r.Header { m.Info("%s: %v", k, kit.Format(v)) } @@ -56,7 +56,7 @@ func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool { } // 主页接口 - if r.Method == "GET" && r.URL.Path == "/" { + if r.Method == SPIDE_GET && r.URL.Path == "/" { msg := m.Spawn() msg.W, msg.R = w, r repos := kit.Select(ice.INTSHELL, ice.VOLCANOS, strings.Contains(r.Header.Get("User-Agent"), "Mozilla/5.0")) @@ -211,14 +211,14 @@ func init() { LOGIN, true, SPACE, true, SHARE, true, ice.VOLCANOS, true, ice.INTSHELL, true, ice.REQUIRE, true, ice.PUBLISH, true, - ), "logheaders", false, + ), LOGHEADERS, false, kit.SSH_STATIC, kit.Dict("/", ice.USR_VOLCANOS), ice.VOLCANOS, kit.Dict(kit.MDB_PATH, ice.USR_VOLCANOS, kit.SSH_INDEX, "page/index.html", kit.SSH_REPOS, "https://github.com/shylinux/volcanos", kit.SSH_BRANCH, kit.SSH_MASTER, ), ice.PUBLISH, ice.USR_PUBLISH, - ice.INTSHELL, kit.Dict(kit.MDB_PATH, ice.USR_INTSHELL, kit.SSH_INDEX, "index.sh", + ice.INTSHELL, kit.Dict(kit.MDB_PATH, ice.USR_INTSHELL, kit.SSH_INDEX, ice.INDEX_SH, kit.SSH_REPOS, "https://github.com/shylinux/intshell", kit.SSH_BRANCH, kit.SSH_MASTER, ), ice.REQUIRE, ".ish/pluged", )}, diff --git a/base/web/share.go b/base/web/share.go index 531ad216..4b702a42 100644 --- a/base/web/share.go +++ b/base/web/share.go @@ -1,17 +1,17 @@ package web import ( - ice "github.com/shylinux/icebergs" - "github.com/shylinux/icebergs/base/aaa" - "github.com/shylinux/icebergs/base/mdb" - "github.com/shylinux/icebergs/base/tcp" - kit "github.com/shylinux/toolkits" - "net/http" "os" "path" "strings" "time" + + ice "github.com/shylinux/icebergs" + "github.com/shylinux/icebergs/base/aaa" + "github.com/shylinux/icebergs/base/mdb" + "github.com/shylinux/icebergs/base/tcp" + kit "github.com/shylinux/toolkits" ) func _share_domain(m *ice.Message) string { @@ -47,7 +47,7 @@ func _share_local(m *ice.Message, arg ...string) { } if m.Option(kit.SSH_POD) != "" { // 远程文件 - pp := path.Join("var/proxy", m.Option(kit.SSH_POD), p) + pp := path.Join(ice.VAR_PROXY, m.Option(kit.SSH_POD), p) cache := time.Now().Add(-time.Hour * 240000) if s, e := os.Stat(pp); e == nil { cache = s.ModTime() @@ -61,7 +61,7 @@ func _share_local(m *ice.Message, arg ...string) { } } - if p == "usr/publish/order.js" { + if p == path.Join(ice.USR_PUBLISH, ice.ORDER_JS) { if _, e := os.Stat(p); os.IsNotExist(e) { m.Render(ice.RENDER_RESULT, "") return @@ -72,16 +72,16 @@ func _share_local(m *ice.Message, arg ...string) { func _share_proxy(m *ice.Message, arg ...string) { switch m.R.Method { case http.MethodGet: // 下发文件 - m.Render(ice.RENDER_DOWNLOAD, path.Join("var/proxy", path.Join(m.Option(kit.SSH_POD), m.Option(kit.MDB_PATH), m.Option(kit.MDB_NAME)))) + m.Render(ice.RENDER_DOWNLOAD, path.Join(ice.VAR_PROXY, path.Join(m.Option(kit.SSH_POD), m.Option(kit.MDB_PATH), m.Option(kit.MDB_NAME)))) case http.MethodPost: // 上传文件 m.Cmdy(CACHE, UPLOAD) - m.Cmdy(CACHE, WATCH, m.Option("data"), path.Join("var/proxy", m.Option(kit.SSH_POD), m.Option(kit.MDB_PATH))) + m.Cmdy(CACHE, WATCH, m.Option(kit.MDB_DATA), path.Join(ice.VAR_PROXY, m.Option(kit.SSH_POD), m.Option(kit.MDB_PATH))) m.Render(ice.RENDER_RESULT, m.Option(kit.MDB_PATH)) } } func _share_repos(m *ice.Message, repos string, arg ...string) { - prefix := kit.Path(m.Conf(SERVE, "meta.require")) + prefix := kit.Path(m.Conf(SERVE, kit.Keym(ice.REQUIRE))) if _, e := os.Stat(path.Join(prefix, repos)); e != nil { m.Cmd("web.code.git.repos", mdb.CREATE, kit.SSH_REPOS, "https://"+repos, kit.MDB_PATH, path.Join(prefix, repos)) } @@ -104,7 +104,7 @@ func init() { Commands: map[string]*ice.Command{ SHARE: {Name: "share hash auto", Help: "共享链", Action: map[string]*ice.Action{ mdb.CREATE: {Name: "create type name text", Help: "创建", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(mdb.INSERT, SHARE, "", mdb.HASH, kit.MDB_TIME, m.Time(m.Conf(SHARE, "meta.expire")), + m.Cmdy(mdb.INSERT, SHARE, "", mdb.HASH, kit.MDB_TIME, m.Time(m.Conf(SHARE, kit.Keym(kit.MDB_EXPIRE))), aaa.USERROLE, m.Option(ice.MSG_USERROLE), aaa.USERNAME, m.Option(ice.MSG_USERNAME), RIVER, m.Option(ice.MSG_RIVER), STORM, m.Option(ice.MSG_STORM), arg) }}, diff --git a/base/web/space.go b/base/web/space.go index af9ca6a8..2bfc347e 100644 --- a/base/web/space.go +++ b/base/web/space.go @@ -43,13 +43,13 @@ func _space_dial(m *ice.Message, dev, name string, arg ...string) { m.Go(func() { for i := 0; i >= 0 && i < kit.Int(redial["c"]); i++ { msg := m.Spawn() - msg.Option(tcp.DIAL_CB, func(s net.Conn, e error) { + msg.Option(kit.Keycb(tcp.DIAL), func(s net.Conn, e error) { if msg.Warn(e != nil, e) { return } if s, _, e := websocket.NewClient(s, u, nil, kit.Int(redial["r"]), kit.Int(redial["w"])); !msg.Warn(e != nil, e) { - msg.Rich(SPACE, nil, kit.Dict(tcp.SOCKET, s, kit.MDB_TYPE, MASTER, kit.MDB_NAME, dev, kit.MDB_TEXT, host)) + msg.Rich(SPACE, nil, kit.Dict(SOCKET, s, kit.MDB_TYPE, MASTER, kit.MDB_NAME, dev, kit.MDB_TEXT, host)) msg.Log_CREATE(SPACE, dev, "retry", i, "uri", uri) // 连接成功 @@ -78,7 +78,7 @@ func _space_send(m *ice.Message, space string, arg ...string) { target := kit.Split(space, ".", ".") m.Warn(m.Richs(SPACE, nil, target[0], func(key string, value map[string]interface{}) { - if socket, ok := value[tcp.SOCKET].(*websocket.Conn); !m.Warn(!ok, ice.ErrNotFound, tcp.SOCKET) { + if socket, ok := value[SOCKET].(*websocket.Conn); !m.Warn(!ok, ice.ErrNotFound, SOCKET) { // 复制选项 for _, k := range kit.Simple(m.Optionv(ice.MSG_OPTS)) { @@ -148,7 +148,7 @@ func _space_handle(m *ice.Message, safe bool, send map[string]*ice.Message, c *w } } else if msg.Richs(SPACE, nil, target[0], func(key string, value map[string]interface{}) { - if s, ok := value[tcp.SOCKET].(*websocket.Conn); ok { + if s, ok := value[SOCKET].(*websocket.Conn); ok { socket, source, target = s, source, target[1:] _space_echo(msg, source, target, socket, kit.Select("", target)) return // 转发报文 @@ -188,9 +188,6 @@ func _space_search(m *ice.Message, kind, name, text string, arg ...string) { switch value[kit.MDB_TYPE] { case MASTER: - m.Debug("what %v", m.Cmd(SPIDE, value[kit.MDB_NAME]).Append("client.url")) - m.Debug("what %v", m.Cmd(SPIDE, value[kit.MDB_NAME])) - m.PushSearch(kit.SSH_CMD, SPACE, kit.MDB_TYPE, value[kit.MDB_TYPE], kit.MDB_NAME, value[kit.MDB_NAME], kit.MDB_TEXT, m.Cmd(SPIDE, value[kit.MDB_NAME], ice.OptionFields("client.url")).Append("client.url"), value) @@ -223,6 +220,8 @@ const ( const ( SPACE_START = "space.start" SPACE_STOP = "space.stop" + + SOCKET = "socket" ) const SPACE = "space" @@ -260,7 +259,7 @@ func init() { river := m.Option("river") // 添加节点 - h := m.Rich(SPACE, nil, kit.Dict(tcp.SOCKET, s, "share", share, "river", river, + h := m.Rich(SPACE, nil, kit.Dict(SOCKET, s, "share", share, "river", river, kit.MDB_TYPE, kind, kit.MDB_NAME, name, kit.MDB_TEXT, s.RemoteAddr().String(), )) diff --git a/base/web/spide.go b/base/web/spide.go index 0aac2fe9..2fccf440 100644 --- a/base/web/spide.go +++ b/base/web/spide.go @@ -14,7 +14,6 @@ import ( "time" ice "github.com/shylinux/icebergs" - "github.com/shylinux/icebergs/base/cli" "github.com/shylinux/icebergs/base/mdb" kit "github.com/shylinux/toolkits" ) @@ -27,17 +26,243 @@ func _spide_create(m *ice.Message, name, address string) { }) == nil { dir, file := path.Split(uri.EscapedPath()) m.Echo(m.Rich(SPIDE, nil, kit.Dict( - "cookie", kit.Dict(), "header", kit.Dict(), "client", kit.Dict( + SPIDE_COOKIE, kit.Dict(), SPIDE_HEADER, kit.Dict(), SPIDE_CLIENT, kit.Dict( "name", name, "url", address, "method", SPIDE_POST, "protocol", uri.Scheme, "hostname", uri.Host, "path", dir, "file", file, "query", uri.RawQuery, - "timeout", "600s", "logheaders", false, + "timeout", "600s", LOGHEADERS, false, ), ))) } m.Log_CREATE(SPIDE, name, ADDRESS, address) } } +func _spide_show(m *ice.Message, arg ...string) { + m.Richs(SPIDE, nil, arg[0], func(key string, value map[string]interface{}) { + // 缓存方式 + cache, save := "", "" + switch arg[1] { + case SPIDE_RAW: + cache, arg = arg[1], arg[1:] + case SPIDE_MSG: + cache, arg = arg[1], arg[1:] + case SPIDE_SAVE: + cache, save, arg = arg[1], arg[2], arg[2:] + case SPIDE_CACHE: + cache, arg = arg[1], arg[1:] + } + + // 请求方法 + client := value[SPIDE_CLIENT].(map[string]interface{}) + method := kit.Select(SPIDE_POST, client[SPIDE_METHOD]) + switch arg = arg[1:]; arg[0] { + case SPIDE_GET: + method, arg = SPIDE_GET, arg[1:] + case SPIDE_PUT: + method, arg = SPIDE_PUT, arg[1:] + case SPIDE_POST: + method, arg = SPIDE_POST, arg[1:] + case SPIDE_DELETE: + method, arg = SPIDE_DELETE, arg[1:] + } + + // 请求地址 + uri, arg := arg[0], arg[1:] + + // 请求参数 + body, head, arg := _spide_body(m, method, arg...) + + // 构造请求 + req, e := http.NewRequest(method, kit.MergeURL2(kit.Format(client["url"]), uri, arg), body) + if m.Warn(e != nil, ice.ErrNotFound, e) { + return + } + + // 请求配置 + _spide_head(m, req, head, value) + + // 发送请求 + res, e := _spide_send(m, req, kit.Format(client["timeout"])) + if m.Warn(e != nil, ice.ErrNotFound, e) { + return + } + + // 检查结果 + defer res.Body.Close() + m.Cost(kit.MDB_STATUS, res.Status, kit.MDB_SIZE, res.Header.Get(ContentLength), kit.MDB_TYPE, res.Header.Get(ContentType)) + + // 缓存配置 + for _, v := range res.Cookies() { + kit.Value(value, kit.Keys(SPIDE_COOKIE, v.Name), v.Value) + m.Log(ice.LOG_IMPORT, "%s: %s", v.Name, v.Value) + } + + // 错误信息 + if m.Warn(res.StatusCode != http.StatusOK, res.Status) { + switch m.Set(ice.MSG_RESULT); res.StatusCode { + case http.StatusNotFound: + return + default: + } + } + + // 解析结果 + _spide_save(m, cache, save, uri, res) + }) + +} +func _spide_body(m *ice.Message, method string, arg ...string) (io.Reader, map[string]string, []string) { + head := map[string]string{} + body, ok := m.Optionv(SPIDE_BODY).(io.Reader) + if !ok && len(arg) > 0 && method != SPIDE_GET { + switch arg[0] { + case SPIDE_FORM: + data := []string{} + for i := 1; i < len(arg)-1; i += 2 { + data = append(data, url.QueryEscape(arg[i])+"="+url.QueryEscape(arg[i+1])) + } + body = bytes.NewBufferString(strings.Join(data, "&")) + head[ContentType] = ContentFORM + + case SPIDE_PART: + body, head[ContentType] = _spide_part(m, arg...) + + case SPIDE_DATA: + body, arg = bytes.NewBufferString(arg[1]), arg[2:] + + case SPIDE_FILE: + if f, e := os.Open(arg[1]); m.Assert(e) { + defer f.Close() + body, arg = f, arg[2:] + } + + case SPIDE_JSON: + arg = arg[1:] + fallthrough + default: + data := map[string]interface{}{} + for i := 0; i < len(arg)-1; i += 2 { + kit.Value(data, arg[i], arg[i+1]) + } + if b, e := json.Marshal(data); m.Assert(e) { + head[ContentType] = ContentJSON + body = bytes.NewBuffer(b) + } + m.Log_EXPORT(SPIDE_JSON, kit.Format(data)) + } + arg = arg[:0] + } else { + body = bytes.NewBuffer([]byte{}) + } + return body, head, arg +} +func _spide_part(m *ice.Message, arg ...string) (io.Reader, string) { + buf := &bytes.Buffer{} + mp := multipart.NewWriter(buf) + defer mp.Close() + + cache := time.Now().Add(-time.Hour * 240000) + for i := 1; i < len(arg)-1; i += 2 { + if arg[i] == SPIDE_CACHE { + if t, e := time.ParseInLocation(ice.MOD_TIME, arg[i+1], time.Local); e == nil { + cache = t + } + } + if strings.HasPrefix(arg[i+1], "@") { + if s, e := os.Stat(arg[i+1][1:]); e == nil { + if s.ModTime().Before(cache) { + break + } + } + if f, e := os.Open(arg[i+1][1:]); m.Assert(e) { + defer f.Close() + if p, e := mp.CreateFormFile(arg[i], path.Base(arg[i+1][1:])); m.Assert(e) { + io.Copy(p, f) + } + } + } else { + mp.WriteField(arg[i], arg[i+1]) + } + } + return buf, mp.FormDataContentType() +} +func _spide_head(m *ice.Message, req *http.Request, head map[string]string, value map[string]interface{}) { + m.Info("%s %s", req.Method, req.URL) + kit.Fetch(value[SPIDE_HEADER], func(key string, value string) { + req.Header.Set(key, value) + }) + kit.Fetch(value[SPIDE_COOKIE], func(key string, value string) { + req.AddCookie(&http.Cookie{Name: key, Value: value}) + m.Info("%s: %s", key, value) + }) + list := kit.Simple(m.Optionv(SPIDE_HEADER)) + for i := 0; i < len(list)-1; i += 2 { + req.Header.Set(list[i], list[i+1]) + m.Info("%s: %s", list[i], list[i+1]) + } + for k, v := range head { + req.Header.Set(k, v) + } + if req.Method == SPIDE_POST { + m.Info("%s: %s", req.Header.Get(ContentLength), req.Header.Get(ContentType)) + } +} +func _spide_send(m *ice.Message, req *http.Request, timeout string) (*http.Response, error) { + web := m.Target().Server().(*Frame) + if web.Client == nil { + web.Client = &http.Client{Timeout: kit.Duration(timeout)} + } + return web.Client.Do(req) +} +func _spide_save(m *ice.Message, cache, save, uri string, res *http.Response) { + switch cache { + case SPIDE_RAW: + b, _ := ioutil.ReadAll(res.Body) + if strings.HasPrefix(res.Header.Get(ContentType), ContentJSON) { + m.Echo(kit.Formats(kit.UnMarshal(string(b)))) + } else { + m.Echo(string(b)) + } + + case SPIDE_MSG: + var data map[string][]string + m.Assert(json.NewDecoder(res.Body).Decode(&data)) + for _, k := range data[ice.MSG_APPEND] { + for i := range data[k] { + m.Push(k, data[k][i]) + } + } + m.Resultv(data[ice.MSG_RESULT]) + + case SPIDE_SAVE: + if f, p, e := kit.Create(save); m.Assert(e) { + defer f.Close() + + if n, e := io.Copy(f, res.Body); m.Assert(e) { + m.Log_EXPORT(kit.MDB_SIZE, n, kit.MDB_FILE, p) + m.Echo(p) + } + } + + case SPIDE_CACHE: + m.Optionv(RESPONSE, res) + m.Cmdy(CACHE, DOWNLOAD, res.Header.Get(ContentType), uri) + m.Echo(m.Append(DATA)) + + default: + b, _ := ioutil.ReadAll(res.Body) + + var data interface{} + if e := json.Unmarshal(b, &data); e != nil { + m.Echo(string(b)) + break + } + + m.Optionv(SPIDE_RES, data) + data = kit.KeyValue(map[string]interface{}{}, "", data) + m.Push("", data) + } +} const ( SPIDE_SHY = "shy" @@ -48,8 +273,6 @@ const ( SPIDE_MSG = "msg" SPIDE_SAVE = "save" SPIDE_CACHE = "cache" - SPIDE_PROXY = "proxy" - SPIDE_CB = "spide.cb" SPIDE_GET = "GET" SPIDE_PUT = "PUT" @@ -58,11 +281,13 @@ const ( SPIDE_FORM = "form" SPIDE_PART = "part" - SPIDE_JSON = "json" SPIDE_DATA = "data" SPIDE_FILE = "file" + SPIDE_JSON = "json" SPIDE_BODY = "body" + SPIDE_RES = "content_data" + SPIDE_CLIENT = "client" SPIDE_METHOD = "method" SPIDE_HEADER = "header" @@ -81,271 +306,56 @@ const ( REQUEST = "request" RESPONSE = "response" PROTOCOL = "protocol" + + CLIENT_NAME = "client.name" + LOGHEADERS = "logheaders" ) const SPIDE = "spide" func init() { Index.Merge(&ice.Context{ Configs: map[string]*ice.Config{ - SPIDE: {Name: SPIDE, Help: "蜘蛛侠", Value: kit.Data(kit.MDB_SHORT, "client.name")}, + SPIDE: {Name: SPIDE, Help: "蜘蛛侠", Value: kit.Data(kit.MDB_SHORT, CLIENT_NAME)}, }, Commands: map[string]*ice.Command{ + SPIDE: {Name: "spide client.name action=raw,msg,save,cache method=GET,PUT,POST,DELETE url format=form,part,data,file,json arg 执行:button create", Help: "蜘蛛侠", Action: map[string]*ice.Action{ + mdb.CREATE: {Name: "create name address", Help: "添加", Hand: func(m *ice.Message, arg ...string) { + if arg[0] != kit.MDB_NAME { + m.Option(kit.MDB_NAME, arg[0]) + m.Option(ADDRESS, arg[1]) + } + _spide_create(m, m.Option(kit.MDB_NAME), m.Option(ADDRESS)) + }}, + mdb.MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) { + m.Cmdy(mdb.MODIFY, SPIDE, "", mdb.HASH, CLIENT_NAME, m.Option(CLIENT_NAME), arg) + }}, + mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { + m.Cmdy(mdb.DELETE, SPIDE, "", mdb.HASH, CLIENT_NAME, m.Option(CLIENT_NAME)) + }}, + }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if len(arg) < 2 || arg[0] == "" || (len(arg) > 3 && arg[3] == "") { + m.Fields(len(arg) == 0 || arg[0] == "", "time,client.name,client.url") + m.Cmdy(mdb.SELECT, SPIDE, "", mdb.HASH, CLIENT_NAME, arg) + m.PushAction(mdb.REMOVE) + return + } + + _spide_show(m, arg...) + }}, + SPIDE_GET: {Name: "GET url key value 执行:button", Help: "蜘蛛侠", Action: map[string]*ice.Action{ mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(mdb.DELETE, SPIDE, "", mdb.HASH, "client.name", m.Option("client.name")) + m.Cmdy(mdb.DELETE, SPIDE, "", mdb.HASH, CLIENT_NAME, m.Option(CLIENT_NAME)) }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Echo(kit.Formats(kit.UnMarshal(m.Cmdx(SPIDE, SPIDE_DEV, SPIDE_RAW, SPIDE_GET, arg[0], arg[1:])))) }}, SPIDE_POST: {Name: "POST url key value 执行:button", Help: "蜘蛛侠", Action: map[string]*ice.Action{ mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(mdb.DELETE, SPIDE, "", mdb.HASH, "client.name", m.Option("client.name")) + m.Cmdy(mdb.DELETE, SPIDE, "", mdb.HASH, CLIENT_NAME, m.Option(CLIENT_NAME)) }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Echo(kit.Formats(kit.UnMarshal(m.Cmdx(SPIDE, SPIDE_DEV, SPIDE_RAW, SPIDE_POST, arg[0], SPIDE_JSON, arg[1:])))) }}, - - SPIDE: {Name: "spide client.name action=raw,msg,save,cache method=GET,PUT,POST,DELETE url format=form,part,json,data,file arg 执行:button create", Help: "蜘蛛侠", Action: map[string]*ice.Action{ - mdb.CREATE: {Name: "create name address", Help: "添加", Hand: func(m *ice.Message, arg ...string) { - if arg[0] != "name" { - m.Option("name", arg[0]) - m.Option(ADDRESS, arg[1]) - } - _spide_create(m, m.Option(kit.MDB_NAME), m.Option(ADDRESS)) - }}, - mdb.MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(mdb.MODIFY, SPIDE, "", mdb.HASH, "client.name", m.Option("client.name"), arg) - }}, - mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(mdb.DELETE, SPIDE, "", mdb.HASH, "client.name", m.Option("client.name")) - }}, - }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - if len(arg) < 2 || arg[0] == "" || (len(arg) > 3 && arg[3] == "") { - m.Fields(len(arg) == 0 || arg[0] == "", "time,client.name,client.url") - m.Cmdy(mdb.SELECT, SPIDE, "", mdb.HASH, "client.name", arg) - m.PushAction(mdb.REMOVE) - return - } - - m.Richs(SPIDE, nil, arg[0], func(key string, value map[string]interface{}) { - client := value[SPIDE_CLIENT].(map[string]interface{}) - // 缓存数据 - cache, save := "", "" - switch arg[1] { - case SPIDE_RAW, SPIDE_PROXY: - cache, arg = arg[1], arg[1:] - case SPIDE_MSG: - cache, arg = arg[1], arg[1:] - case SPIDE_SAVE: - cache, save, arg = arg[1], arg[2], arg[2:] - case SPIDE_CACHE: - cache, arg = arg[1], arg[1:] - } - - // 请求方法 - method := kit.Select(SPIDE_POST, client[SPIDE_METHOD]) - switch arg = arg[1:]; arg[0] { - case SPIDE_GET: - method, arg = SPIDE_GET, arg[1:] - case SPIDE_PUT: - method, arg = SPIDE_PUT, arg[1:] - case SPIDE_POST: - method, arg = SPIDE_POST, arg[1:] - case SPIDE_DELETE: - method, arg = SPIDE_DELETE, arg[1:] - } - - // 请求地址 - uri, arg := arg[0], arg[1:] - if strings.HasPrefix(uri, "ftp") { - m.Cmdy(cli.SYSTEM, "wget", uri, arg) - return - } - - // 渲染引擎 - head := map[string]string{} - body, ok := m.Optionv(SPIDE_BODY).(io.Reader) - if !ok && len(arg) > 0 && method != SPIDE_GET { - switch arg[0] { - case SPIDE_FILE: - if f, e := os.Open(arg[1]); m.Assert(e) { - defer f.Close() - body, arg = f, arg[2:] - } - case SPIDE_DATA: - body, arg = bytes.NewBufferString(arg[1]), arg[2:] - case SPIDE_PART: - buf := &bytes.Buffer{} - mp := multipart.NewWriter(buf) - cache := time.Now().Add(-time.Hour * 240000) - for i := 1; i < len(arg)-1; i += 2 { - if arg[i] == "cache" { - if t, e := time.ParseInLocation(ice.MOD_TIME, arg[i+1], time.Local); e == nil { - cache = t - } - } - if strings.HasPrefix(arg[i+1], "@") { - if s, e := os.Stat(arg[i+1][1:]); e == nil { - if s.ModTime().Before(cache) { - return - } - } - if f, e := os.Open(arg[i+1][1:]); m.Assert(e) { - defer f.Close() - if p, e := mp.CreateFormFile(arg[i], path.Base(arg[i+1][1:])); m.Assert(e) { - io.Copy(p, f) - } - } - } else { - mp.WriteField(arg[i], arg[i+1]) - } - } - mp.Close() - head[ContentType] = mp.FormDataContentType() - body = buf - case SPIDE_FORM: - data := []string{} - for i := 1; i < len(arg)-1; i += 2 { - data = append(data, url.QueryEscape(arg[i])+"="+url.QueryEscape(arg[i+1])) - } - body = bytes.NewBufferString(strings.Join(data, "&")) - head[ContentType] = ContentFORM - case SPIDE_JSON: - arg = arg[1:] - fallthrough - default: - data := map[string]interface{}{} - for i := 0; i < len(arg)-1; i += 2 { - kit.Value(data, arg[i], arg[i+1]) - } - if b, e := json.Marshal(data); m.Assert(e) { - head[ContentType] = ContentJSON - body = bytes.NewBuffer(b) - } - m.Log_EXPORT(SPIDE_JSON, kit.Format(data)) - } - arg = arg[:0] - } else { - body = bytes.NewBuffer([]byte{}) - } - - // 请求地址 - uri = kit.MergeURL2(kit.Format(client["url"]), uri, arg) - req, e := http.NewRequest(method, uri, body) - m.Info("%s %s", req.Method, req.URL) - m.Assert(e) - - // 请求变量 - kit.Fetch(value[SPIDE_HEADER], func(key string, value string) { - req.Header.Set(key, value) - }) - kit.Fetch(value[SPIDE_COOKIE], func(key string, value string) { - req.AddCookie(&http.Cookie{Name: key, Value: value}) - m.Info("%s: %s", key, value) - }) - list := kit.Simple(m.Optionv(SPIDE_HEADER)) - for i := 0; i < len(list)-1; i += 2 { - req.Header.Set(list[i], list[i+1]) - m.Info("%s: %s", list[i], list[i+1]) - } - for k, v := range head { - req.Header.Set(k, v) - } - - // 请求代理 - web := m.Target().Server().(*Frame) - if web.Client == nil { - web.Client = &http.Client{Timeout: kit.Duration(kit.Format(client["timeout"]))} - } - if req.Method == SPIDE_POST { - m.Info("%s: %s", req.Header.Get(ContentLength), req.Header.Get(ContentType)) - } - - // 发送请求 - res, e := web.Client.Do(req) - if m.Warn(e != nil, ice.ErrNotFound, e) { - return - } - - // 检查结果 - defer res.Body.Close() - m.Cost("status", res.Status, "length", res.Header.Get(ContentLength), "type", res.Header.Get(ContentType)) - - switch cb := m.Optionv(SPIDE_CB).(type) { - case func(*ice.Message, *http.Request, *http.Response): - cb(m, req, res) - return - } - - if m.Warn(res.StatusCode != http.StatusOK, res.Status) { - m.Set(ice.MSG_RESULT) - // return - switch res.StatusCode { - case http.StatusNotFound: - return - default: - } - - } - - // 缓存变量 - for _, v := range res.Cookies() { - kit.Value(value, "cookie."+v.Name, v.Value) - m.Log(ice.LOG_IMPORT, "%s: %s", v.Name, v.Value) - } - - // 解析引擎 - switch cache { - case SPIDE_PROXY: - m.Optionv(RESPONSE, res) - m.Cmdy(CACHE, DOWNLOAD, res.Header.Get(ContentType), uri) - m.Echo(m.Append(DATA)) - - case SPIDE_CACHE: - m.Optionv(RESPONSE, res) - m.Cmdy(CACHE, DOWNLOAD, res.Header.Get(ContentType), uri) - m.Echo(m.Append(DATA)) - - case SPIDE_SAVE: - if f, p, e := kit.Create(save); m.Assert(e) { - if n, e := io.Copy(f, res.Body); m.Assert(e) { - m.Log_EXPORT(kit.MDB_SIZE, n, kit.MDB_FILE, p) - m.Echo(p) - } - } - - case SPIDE_RAW: - b, _ := ioutil.ReadAll(res.Body) - if strings.HasPrefix(res.Header.Get(ContentType), ContentJSON) { - m.Echo(kit.Formats(kit.UnMarshal(string(b)))) - } else { - m.Echo(string(b)) - } - - case SPIDE_MSG: - var data map[string][]string - m.Assert(json.NewDecoder(res.Body).Decode(&data)) - for _, k := range data[ice.MSG_APPEND] { - for i := range data[k] { - m.Push(k, data[k][i]) - } - } - m.Resultv(data[ice.MSG_RESULT]) - - default: - b, _ := ioutil.ReadAll(res.Body) - - var data interface{} - if e := json.Unmarshal(b, &data); e != nil { - m.Echo(string(b)) - break - } - - m.Optionv("content_data", data) - data = kit.KeyValue(map[string]interface{}{}, "", data) - m.Push("", data) - } - }) - }}, }}) } diff --git a/base/web/story.go b/base/web/story.go index 102bf60c..f9fa28f1 100644 --- a/base/web/story.go +++ b/base/web/story.go @@ -1,12 +1,13 @@ package web import ( - ice "github.com/shylinux/icebergs" - "github.com/shylinux/icebergs/base/nfs" - kit "github.com/shylinux/toolkits" - "os" "time" + + ice "github.com/shylinux/icebergs" + "github.com/shylinux/icebergs/base/mdb" + "github.com/shylinux/icebergs/base/nfs" + kit "github.com/shylinux/toolkits" ) func _story_list(m *ice.Message, name string, key string) { @@ -14,7 +15,7 @@ func _story_list(m *ice.Message, name string, key string) { m.Richs(STORY, HEAD, kit.MDB_FOREACH, func(key string, value map[string]interface{}) { m.Push(key, value, []string{kit.MDB_TIME, kit.MDB_COUNT, STORY}) }) - m.Sort(kit.MDB_TIME, "time_r") + m.SortTimeR(kit.MDB_TIME) return } if key == "" { @@ -23,7 +24,7 @@ func _story_list(m *ice.Message, name string, key string) { } m.Richs(STORY, nil, key, func(key string, value map[string]interface{}) { - m.Push("detail", value) + m.Push(mdb.DETAIL, value) }) } @@ -57,7 +58,7 @@ func _story_index(m *ice.Message, name string, withdata bool) { func _story_history(m *ice.Message, name string) { // 历史记录 list := m.Cmd(STORY, INDEX, name).Append(LIST) - for i := 0; i < kit.Int(kit.Select("30", m.Option("cache.limit"))) && list != ""; i++ { + for i := 0; i < kit.Int(kit.Select("30", m.Option(mdb.CACHE_LIMIT))) && list != ""; i++ { m.Richs(STORY, nil, list, func(key string, value map[string]interface{}) { // 直连节点 m.Push(key, value, []string{kit.MDB_TIME, kit.MDB_KEY, kit.MDB_COUNT, SCENE, STORY}) @@ -155,9 +156,11 @@ const ( PUSH = "push" COMMIT = "commit" ) -const SCENE = "scene" +const ( + SCENE = "scene" + DRAMA = "drama" +) const STORY = "story" -const DRAMA = "drama" func init() { Index.Merge(&ice.Context{ @@ -184,9 +187,6 @@ func init() { HISTORY: {Name: "history name", Help: "历史", Hand: func(m *ice.Message, arg ...string) { _story_history(m, arg[0]) }}, - "add": {Name: "add type name text arg...", Help: "淘汰", Hand: func(m *ice.Message, arg ...string) { - panic(m) - }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { _story_list(m, kit.Select("", arg, 0), kit.Select("", arg, 1)) }}, diff --git a/base/web/web.go b/base/web/web.go index 724ed536..4b3a092f 100644 --- a/base/web/web.go +++ b/base/web/web.go @@ -1,15 +1,15 @@ package web import ( + "net" + "net/http" + "path" + ice "github.com/shylinux/icebergs" "github.com/shylinux/icebergs/base/cli" "github.com/shylinux/icebergs/base/mdb" "github.com/shylinux/icebergs/base/tcp" kit "github.com/shylinux/toolkits" - - "net" - "net/http" - "path" ) type Frame struct { @@ -43,16 +43,16 @@ func (web *Frame) Start(m *ice.Message, arg ...string) bool { // 静态路由 msg := m.Spawn(s) - m.Confm(SERVE, "meta.static", func(key string, value string) { + m.Confm(SERVE, kit.Keym("static"), func(key string, value string) { m.Log("route", "%s <- %s <- %s", s.Name, key, value) w.Handle(key, http.StripPrefix(key, http.FileServer(http.Dir(value)))) }) // 级联路由 route := "/" + s.Name + "/" - if n, ok := p.Server().(*Frame); ok && n.ServeMux != nil { + if f, ok := p.Server().(*Frame); ok && f.ServeMux != nil { msg.Log("route", "%s <= %s", p.Name, route) - n.Handle(route, http.StripPrefix(path.Dir(route), w)) + f.Handle(route, http.StripPrefix(path.Dir(route), w)) } // 命令路由 @@ -70,7 +70,7 @@ func (web *Frame) Start(m *ice.Message, arg ...string) bool { }) web.m, web.Server = m, &http.Server{Handler: web} - m.Option(tcp.LISTEN_CB, func(l net.Listener) { + m.Option(kit.Keycb(tcp.LISTEN), func(l net.Listener) { m.Cmdy(mdb.INSERT, SERVE, "", mdb.HASH, arg, kit.MDB_STATUS, tcp.START, kit.MDB_PROTO, m.Option(kit.MDB_PROTO), SPIDE_DEV, m.Option(SPIDE_DEV)) defer m.Cmd(mdb.MODIFY, SERVE, "", mdb.HASH, kit.MDB_NAME, m.Option(kit.MDB_NAME), kit.MDB_STATUS, tcp.STOP) @@ -93,18 +93,18 @@ var Index = &ice.Context{Name: WEB, Help: "网络模块", ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Load() m.Conf(SPACE, kit.MDB_HASH, "") + m.Cmd(mdb.SEARCH, mdb.CREATE, SPACE, m.Prefix(SPACE)) m.Cmd(SPIDE, mdb.CREATE, SPIDE_DEV, kit.Select("http://:9020", m.Conf(cli.RUNTIME, "conf.ctx_dev"))) m.Cmd(SPIDE, mdb.CREATE, SPIDE_SELF, kit.Select("http://:9020", m.Conf(cli.RUNTIME, "conf.ctx_self"))) m.Cmd(SPIDE, mdb.CREATE, SPIDE_SHY, kit.Select("https://shylinux.com:443", m.Conf(cli.RUNTIME, "conf.ctx_shy"))) - m.Cmd(mdb.SEARCH, mdb.CREATE, SPACE, m.Prefix(SPACE)) }}, ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Save() m.Done(true) m.Cmd(SERVE).Table(func(index int, value map[string]string, head []string) { - m.Done(value[kit.MDB_STATUS] == "start") + m.Done(value[kit.MDB_STATUS] == tcp.START) }) }}, }, @@ -112,7 +112,7 @@ var Index = &ice.Context{Name: WEB, Help: "网络模块", func init() { ice.Index.Register(Index, &Frame{}, - ROUTE, SERVE, SPACE, DREAM, - SPIDE, SHARE, CACHE, STORY, + SPIDE, CACHE, STORY, ROUTE, + SHARE, SERVE, SPACE, DREAM, ) } diff --git a/base/web/web.shy b/base/web/web.shy index b6c214d3..9e534ebf 100644 --- a/base/web/web.shy +++ b/base/web/web.shy @@ -1,12 +1,16 @@ chapter "web" +label "web" ` +spide cache story route +share serve space dream +` +field "蜘蛛侠" web.spide +field "缓存池" web.cache +field "故事会" web.story field "路由器" web.route + +field "共享链" web.share field "服务器" web.serve field "空间站" web.space field "梦想家" web.dream -field "蜘蛛侠" web.spide -field "共享链" web.share -field "缓存池" web.cache -field "故事会" web.story - diff --git a/conf.go b/conf.go index 4c0e11f5..6ddb3773 100644 --- a/conf.go +++ b/conf.go @@ -14,11 +14,11 @@ const ( // MOD const ( // REPOS VOLCANOS = "volcanos" ICEBERGS = "icebergs" - CONTEXTS = "contexts" INTSHELL = "intshell" + CONTEXTS = "contexts" - REQUIRE = "require" PUBLISH = "publish" + REQUIRE = "require" SUCCESS = "success" FAILURE = "failure" @@ -26,6 +26,7 @@ const ( // REPOS ) const ( // DIR USR_VOLCANOS = "usr/volcanos" + USR_ICEBERGS = "usr/icebergs" USR_INTSHELL = "usr/intshell" USR_PUBLISH = "usr/publish" USR_INSTALL = "usr/install" @@ -33,23 +34,30 @@ const ( // DIR PROTO_JS = "proto.js" FRAME_JS = "frame.js" + INDEX_JS = "index.js" + ORDER_JS = "order.js" + ORDER_SH = "order.sh" + INDEX_SH = "index.sh" + VAR_TMP = "var/tmp" VAR_LOG = "var/log" VAR_CONF = "var/conf" + VAR_DATA = "var/data" + VAR_FILE = "var/file" + VAR_PROXY = "var/proxy" VAR_TRASH = "var/trash" - ETC_MISS = "etc/miss.sh" + BIN_ICE = "bin/ice.sh" + BIN_ICE_BIN = "bin/ice.bin" + BIN_BOOTLOG = "bin/boot.log" ETC_INIT = "etc/init.shy" ETC_EXIT = "etc/exit.shy" + ETC_MISS = "etc/miss.sh" + SRC_MAIN = "src/main.shy" SRC_MAIN_GO = "src/main.go" SRC_VERSION = "src/version.go" SRC_BINPACK = "src/binpack.go" - BIN_BOOTLOG = "bin/boot.log" - BIN_ICE_BIN = "bin/ice.bin" - BIN_ICE = "bin/ice.sh" MAKEFILE = "makefile" - ORDER_SH = "order.sh" - ORDER_JS = "order.js" GO_MOD = "go.mod" GO_SUM = "go.sum" @@ -75,9 +83,8 @@ const ( // MSG MSG_ACTION = "_action" MSG_STATUS = "_status" - MSG_CONTROL = "_control" - MSG_PROCESS = "_process" MSG_DISPLAY = "_display" + MSG_PROCESS = "_process" MSG_CMDS = "cmds" MSG_SESSID = "sessid" @@ -113,10 +120,10 @@ const ( // RENDER RENDER_TEMPLATE = "_template" ) const ( // PROCESS - PROCESS_PROGRESS = "_progress" - PROCESS_REFRESH = "_refresh" - PROCESS_FIELD = "_field" - PROCESS_INNER = "_inner" + PROCESS_REFRESH = "_refresh" + PROCESS_REWRITE = "_rewrite" + PROCESS_FIELD = "_field" + PROCESS_INNER = "_inner" PROCESS_HOLD = "_hold" PROCESS_BACK = "_back" @@ -124,7 +131,6 @@ const ( // PROCESS PROCESS_OPEN = "_open" FIELD_PREFIX = "_prefix" - CONTROL_PAGE = "_page" ) const ( // LOG // 数据 diff --git a/core/chat/river.go b/core/chat/river.go index 6425b179..7158fc5d 100644 --- a/core/chat/river.go +++ b/core/chat/river.go @@ -241,8 +241,7 @@ func init() { } // 命令插件 - m.Option(ice.MSG_PROCESS, "_field") - m.Option("_prefix", arg[0], arg[1], "run") + m.ProcessField(arg[0], arg[1], "run") m.Table(func(index int, value map[string]string, head []string) { m.Cmdy(web.SPACE, value[POD], ctx.CONTEXT, value[CTX], ctx.COMMAND, value[CMD]) }) diff --git a/core/code/autogen.go b/core/code/autogen.go index 5af232c1..b344456f 100644 --- a/core/code/autogen.go +++ b/core/code/autogen.go @@ -140,7 +140,7 @@ func init() { _autogen_version(m) m.Cmd(BINPACK, mdb.CREATE) }}, - mdb.SCRIPT: {Name: "script", Help: "脚本", Hand: func(m *ice.Message, arg ...string) { + "script": {Name: "script", Help: "脚本", Hand: func(m *ice.Message, arg ...string) { _autogen_miss(m) }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { diff --git a/core/code/bench.go b/core/code/bench.go index a04ea2de..1bd4472a 100644 --- a/core/code/bench.go +++ b/core/code/bench.go @@ -50,7 +50,7 @@ func _bench_http(m *ice.Message, name, target string, arg ...string) { m.Echo(s.Show()) m.Echo("body: %d\n", body) - m.Option(ice.MSG_PROCESS, ice.PROCESS_INNER) + m.ProcessInner() } func _bench_redis(m *ice.Message, name, target string, arg ...string) { } diff --git a/core/code/install.go b/core/code/install.go index e420c9e6..143ab7d2 100644 --- a/core/code/install.go +++ b/core/code/install.go @@ -46,7 +46,7 @@ func init() { value = kit.GetMeta(value) p := 0 - m.Optionv(web.DOWNLOAD_CB, func(size int, total int) { + m.Optionv(kit.Keycb(web.DOWNLOAD), func(size int, total int) { if n := size * 100 / total; p != n { value[kit.SSH_STEP], value[kit.MDB_SIZE], value[kit.MDB_TOTAL] = n, size, total toast(name, size, total) diff --git a/core/code/pprof.go b/core/code/pprof.go index 057aa8d6..e087b012 100644 --- a/core/code/pprof.go +++ b/core/code/pprof.go @@ -73,15 +73,15 @@ func init() { m.Cmd(mdb.INSERT, PPROF, _sub_key(m, m.Option(kit.MDB_ZONE)), mdb.LIST, kit.MDB_TEXT, strings.Join(res, "\n"), kit.MDB_FILE, msg.Append(kit.MDB_FILE)) m.Echo(strings.Join(res, "\n")) - m.Option(ice.MSG_PROCESS, ice.PROCESS_INNER) + m.ProcessInner() }}, web.SERVE: {Name: "serve", Help: "展示", Hand: func(m *ice.Message, arg ...string) { - m.Option(ice.MSG_PROCESS, ice.PROCESS_INNER) u := kit.ParseURL(m.Option(ice.MSG_USERWEB)) p := u.Hostname() + ":" + m.Cmdx(tcp.PORT, aaa.RIGHT) m.Cmd(cli.DAEMON, m.Confv(PPROF, "meta.pprof"), "-http="+p, m.Option(BINNARY), m.Option(kit.MDB_FILE)) m.Echo("http://%s/ui/top", p) + m.ProcessInner() }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Option(mdb.FIELDS, kit.Select("time,count,zone,binnary,service,seconds", kit.Select("time,id,text,binnary,file", mdb.DETAIL, len(arg) > 1), len(arg) > 0)) diff --git a/core/mall/asset.go b/core/mall/asset.go index fc9ef662..c1aac26d 100644 --- a/core/mall/asset.go +++ b/core/mall/asset.go @@ -47,7 +47,7 @@ func _asset_list(m *ice.Message, account string, id string) { func _asset_check(m *ice.Message, account string) { amount := 0 m.Option(mdb.FIELDS, "time,id,type,amount,name,text") - m.Option(mdb.SELECT_CB, func(fields []string, value map[string]interface{}) { + m.Option(kit.Keycb(mdb.SELECT), func(fields []string, value map[string]interface{}) { amount += kit.Int(kit.Value(value, AMOUNT)) }) m.Cmd(mdb.SELECT, ASSET, _sub_key(m, account), mdb.LIST) diff --git a/core/team/plan.go b/core/team/plan.go index 6a137a63..7236f0e7 100644 --- a/core/team/plan.go +++ b/core/team/plan.go @@ -21,7 +21,7 @@ func init() { mdb.INSERT: {Name: "insert zone type=once,step,week name text begin_time@date close_time@date", Help: "添加", Hand: func(m *ice.Message, arg ...string) { _task_create(m, arg[1]) _task_insert(m, arg[1], arg[2:]...) - m.Option(ice.MSG_PROCESS, ice.PROCESS_REFRESH) + m.ProcessRefresh("1ms") }}, mdb.MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) { _task_modify(m, m.Option(kit.MDB_ZONE), m.Option(kit.MDB_ID), arg[0], arg[1]) @@ -31,7 +31,7 @@ func init() { }}, mdb.IMPORT: {Name: "import", Help: "导入", Hand: func(m *ice.Message, arg ...string) { _task_import(m, "") - m.Option(ice.MSG_PROCESS, ice.PROCESS_REFRESH) + m.ProcessRefresh("1ms") }}, mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) { _task_inputs(m, kit.Select("", arg, 0), kit.Select("", arg, 1)) @@ -61,7 +61,7 @@ func init() { begin_time, end_time := _task_scope(m, 8, arg...) m.Option(mdb.CACHE_LIMIT, "100") m.Option(mdb.FIELDS, "begin_time,close_time,zone,id,level,status,score,type,name,text,extra") - m.Option(mdb.SELECT_CB, func(key string, fields []string, value, val map[string]interface{}) { + m.Option(kit.Keycb(mdb.SELECT), func(key string, fields []string, value, val map[string]interface{}) { begin, _ := time.ParseInLocation(ice.MOD_TIME, kit.Format(value[TaskField.BEGIN_TIME]), time.Local) if begin_time.After(begin) || begin.After(end_time) { return diff --git a/misc.go b/misc.go index 244d815b..500df056 100644 --- a/misc.go +++ b/misc.go @@ -314,14 +314,23 @@ func (m *Message) Process(action string, arg ...interface{}) { m.Option(MSG_PROCESS, action) m.Option("_arg", arg...) } +func (m *Message) ProcessRewrite(arg ...interface{}) { + m.Process(PROCESS_REWRITE) + m.Option("_arg", arg...) +} func (m *Message) ProcessRefresh(delay string) { if d, e := time.ParseDuration(delay); e == nil { m.Option("_delay", int(d/time.Millisecond)) } m.Process(PROCESS_REFRESH) } -func (m *Message) ProcessHold() { m.Process(PROCESS_HOLD) } -func (m *Message) ProcessBack() { m.Process(PROCESS_BACK) } +func (m *Message) ProcessField(arg ...interface{}) { + m.Process(PROCESS_FIELD) + m.Option("_prefix", arg...) +} +func (m *Message) ProcessInner() { m.Process(PROCESS_INNER) } +func (m *Message) ProcessHold() { m.Process(PROCESS_HOLD) } +func (m *Message) ProcessBack() { m.Process(PROCESS_BACK) } func (m *Message) Upload(dir string) { up := kit.Simple(m.Optionv(MSG_UPLOAD)) diff --git a/misc/bash/sync.go b/misc/bash/sync.go index 5b297ad5..fcac2dec 100644 --- a/misc/bash/sync.go +++ b/misc/bash/sync.go @@ -56,7 +56,6 @@ func init() { m.Option(mdb.FIELDS, mdb.DETAIL) } else { m.Option(mdb.FIELDS, m.Conf(SYNC, kit.META_FIELD)) - m.Option(ice.MSG_CONTROL, ice.CONTROL_PAGE) defer m.PushAction(cli.SYSTEM, FAVOR) } diff --git a/misc/chrome/cache.go b/misc/chrome/cache.go index 0ca06872..da4057ff 100644 --- a/misc/chrome/cache.go +++ b/misc/chrome/cache.go @@ -35,7 +35,7 @@ func init() { ) m.Option("progress", m.Prefix(CACHE), "", m.Option(kit.MDB_LINK)) - m.Option(web.DOWNLOAD_CB, m.Prefix(CACHE), "", kit.Keys(kit.MDB_HASH, h)) + m.Option(kit.Keycb(web.DOWNLOAD), m.Prefix(CACHE), "", kit.Keys(kit.MDB_HASH, h)) msg := m.Cmd("web.spide", web.SPIDE_DEV, web.SPIDE_CACHE, web.SPIDE_GET, m.Option(kit.MDB_LINK)) p := path.Join(m.Conf(m.Prefix(CACHE), kit.META_PATH), m.Option(kit.MDB_NAME)) diff --git a/misc/git/status.go b/misc/git/status.go index 4fb86567..1437981e 100644 --- a/misc/git/status.go +++ b/misc/git/status.go @@ -109,8 +109,8 @@ func init() { m.ProcessHold() }}, MAKE: {Name: "make", Help: "编译", Hand: func(m *ice.Message, arg ...string) { - m.Toast("doing", "make", 100000) - defer m.Toast("success", "make", 1000) + m.Toast("building", MAKE, 100000) + defer m.Toast("success", MAKE, 1000) m.Cmdy(cli.SYSTEM, MAKE) }}, @@ -143,7 +143,7 @@ func init() { }}, mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) { switch arg[0] { - case "name": + case kit.MDB_NAME: m.OptionFields("name,time") m.Cmdy(REPOS) diff --git a/misc/lark/lark.go b/misc/lark/lark.go index 2ba85f82..461b410e 100644 --- a/misc/lark/lark.go +++ b/misc/lark/lark.go @@ -17,9 +17,10 @@ import ( "time" ) -func _lark_get(m *ice.Message, bot string, arg ...interface{}) *ice.Message { +func _lark_get(m *ice.Message, bot string, arg ...interface{}) (*ice.Message, interface{}) { m.Option(web.SPIDE_HEADER, "Authorization", "Bearer "+m.Cmdx(APP, TOKEN, bot), web.ContentType, web.ContentJSON) - return m.Cmd(web.SPIDE, LARK, http.MethodGet, arg) + msg := m.Cmd(web.SPIDE, LARK, http.MethodGet, arg) + return msg, msg.Optionv(web.SPIDE_RES) } func _lark_post(m *ice.Message, bot string, arg ...interface{}) *ice.Message { m.Option(web.SPIDE_HEADER, "Authorization", "Bearer "+m.Cmdx(APP, TOKEN, bot), web.ContentType, web.ContentJSON) @@ -125,16 +126,16 @@ var Index = &ice.Context{Name: LARK, Help: "机器人", }}, COMPANY: {Name: "company ship_id open_id text auto", Help: "组织", Action: map[string]*ice.Action{ "info": {Name: "info ship_id", Hand: func(m *ice.Message, arg ...string) { - msg := _lark_get(m, "bot", "/open-apis/contact/v1/department/detail/batch_get", "department_ids", m.Option(SHIP_ID)) - kit.Fetch(kit.Value(msg.Optionv("content_data"), "data.department_infos"), func(index int, value map[string]interface{}) { + _, data := _lark_get(m, "bot", "/open-apis/contact/v1/department/detail/batch_get", "department_ids", m.Option(SHIP_ID)) + kit.Fetch(kit.Value(data, "data.department_infos"), func(index int, value map[string]interface{}) { m.Push("", value) }) }}, "list": {Name: "list ship_id", Hand: func(m *ice.Message, arg ...string) { - msg := _lark_get(m, "bot", "/open-apis/contact/v1/department/user/list", + _, data := _lark_get(m, "bot", "/open-apis/contact/v1/department/user/list", "department_id", m.Option(SHIP_ID), "page_size", "100", "fetch_child", "true") - kit.Fetch(kit.Value(msg.Optionv("content_data"), "data.user_list"), func(index int, value map[string]interface{}) { + kit.Fetch(kit.Value(data, "data.user_list"), func(index int, value map[string]interface{}) { msg := m.Cmd(EMPLOYEE, value[OPEN_ID]) m.PushImages(aaa.AVATAR, msg.Append("avatar_72")) m.Push(aaa.GENDER, kit.Select("女", "男", msg.Append(aaa.GENDER) == "1")) @@ -145,8 +146,8 @@ var Index = &ice.Context{Name: LARK, Help: "机器人", }}, }, Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { if len(arg) == 0 { // 组织列表 - msg := _lark_get(m, "bot", "/open-apis/contact/v1/scope/get/") - kit.Fetch(kit.Value(msg.Optionv("content_data"), "data.authed_departments"), func(index int, value string) { + _, data := _lark_get(m, "bot", "/open-apis/contact/v1/scope/get/") + kit.Fetch(kit.Value(data, "data.authed_departments"), func(index int, value string) { m.Push(SHIP_ID, value) msg := m.Cmd(COMPANY, "info", value) m.Push(kit.MDB_NAME, msg.Append(kit.MDB_NAME)) @@ -170,8 +171,8 @@ var Index = &ice.Context{Name: LARK, Help: "机器人", return } if strings.HasPrefix(arg[0], "ou_") { - msg := _lark_get(m, "bot", "/open-apis/contact/v1/user/batch_get", "open_ids", arg[0]) - kit.Fetch(kit.Value(msg.Optionv("content_data"), "data.user_infos"), func(index int, value map[string]interface{}) { + _, data := _lark_get(m, "bot", "/open-apis/contact/v1/user/batch_get", "open_ids", arg[0]) + kit.Fetch(kit.Value(data, "data.user_infos"), func(index int, value map[string]interface{}) { m.Push(mdb.DETAIL, value) }) return @@ -189,8 +190,8 @@ var Index = &ice.Context{Name: LARK, Help: "机器人", }}, GROUP: {Name: "group chat_id open_id text auto", Help: "群组", Action: map[string]*ice.Action{ "list": {Name: "list chat_id", Hand: func(m *ice.Message, arg ...string) { - msg := _lark_get(m, "bot", "/open-apis/chat/v4/info", "chat_id", m.Option(CHAT_ID)) - kit.Fetch(kit.Value(msg.Optionv("content_data"), "data.members"), func(index int, value map[string]interface{}) { + _, data := _lark_get(m, "bot", "/open-apis/chat/v4/info", "chat_id", m.Option(CHAT_ID)) + kit.Fetch(kit.Value(data, "data.members"), func(index int, value map[string]interface{}) { msg := m.Cmd(EMPLOYEE, value[OPEN_ID]) m.PushImages(aaa.AVATAR, msg.Append("avatar_72")) m.Push(aaa.GENDER, kit.Select("女", "男", msg.Append(aaa.GENDER) == "1")) @@ -201,8 +202,8 @@ var Index = &ice.Context{Name: LARK, Help: "机器人", }}, }, Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { if len(arg) == 0 { // 群组列表 - msg := _lark_get(m, "bot", "/open-apis/chat/v4/list") - kit.Fetch(kit.Value(msg.Optionv("content_data"), "data.groups"), func(index int, value map[string]interface{}) { + _, data := _lark_get(m, "bot", "/open-apis/chat/v4/list") + kit.Fetch(kit.Value(data, "data.groups"), func(index int, value map[string]interface{}) { m.Push(CHAT_ID, value[CHAT_ID]) m.PushImages(aaa.AVATAR, kit.Format(value[aaa.AVATAR]), "72") m.Push(kit.MDB_NAME, value[kit.MDB_NAME]) diff --git a/misc/tmux/tmux.go b/misc/tmux/tmux.go index bcabe347..f228f8a0 100644 --- a/misc/tmux/tmux.go +++ b/misc/tmux/tmux.go @@ -192,7 +192,7 @@ var Index = &ice.Context{Name: TMUX, Help: "工作台", m.Cmdy(cli.SYSTEM, TMUX, "link-window", "-s", name, "-t", "miss:") } - m.Option(ice.MSG_PROCESS, "_refresh") + m.ProcessRefresh("1ms") }}, mdb.MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) { switch arg[0] { diff --git a/misc/vim/sync.go b/misc/vim/sync.go index c5cd1cb0..b9dd9cc5 100644 --- a/misc/vim/sync.go +++ b/misc/vim/sync.go @@ -24,7 +24,6 @@ func init() { m.Option(mdb.FIELDS, mdb.DETAIL) } else { m.Option(mdb.FIELDS, m.Conf(SYNC, kit.META_FIELD)) - m.Option(ice.MSG_CONTROL, ice.CONTROL_PAGE) } m.Cmdy(mdb.SELECT, m.Prefix(SYNC), "", mdb.LIST, kit.MDB_ID, arg) diff --git a/type.go b/type.go index 0f7c242e..80f23545 100644 --- a/type.go +++ b/type.go @@ -1,8 +1,6 @@ package ice import ( - kit "github.com/shylinux/toolkits" - "encoding/json" "fmt" "io" @@ -15,6 +13,8 @@ import ( "sync" "sync/atomic" "time" + + kit "github.com/shylinux/toolkits" ) type Cache struct {