diff --git a/go.mod b/go.mod index bfaf41ad..bb8c153e 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ replace ( ) require ( - shylinux.com/x/ice v1.4.5 - shylinux.com/x/icebergs v1.8.5 - shylinux.com/x/toolkits v1.0.0 + shylinux.com/x/ice v1.4.6 + shylinux.com/x/icebergs v1.8.6 + shylinux.com/x/toolkits v1.0.1 ) diff --git a/go.sum b/go.sum index e9157b3d..5894873e 100644 --- a/go.sum +++ b/go.sum @@ -2,18 +2,12 @@ shylinux.com/x/go-git/v5 v5.6.7 h1:WD5QSco7m3QooPCgdvQ6/GyGIFPun8C+hex5N41LYlk= shylinux.com/x/go-git/v5 v5.6.7/go.mod h1:Qb0lA+uIrofZg8NQerhYcJHgGWixFqvS6p3aJ/L5Nlk= shylinux.com/x/go-qrcode v0.0.3 h1:RMo+Vidbgq3HatLBj7DDXcTbTLFUwzis5K7TqBkD38U= shylinux.com/x/go-qrcode v0.0.3/go.mod h1:KAbtU+KwiiABMZ/CJ0zh9PI2AX82Uf9rRYcQ4ODm4po= -shylinux.com/x/ice v1.4.4 h1:ycQ3MJ0vdzoieAKrXaAS9BPuuWKpunIIDc82ZvQDUhY= -shylinux.com/x/ice v1.4.4/go.mod h1:L6Ey1W3XMAZLvlVAXTaiurrCD0OR/5QfxXEDot3mbHw= -shylinux.com/x/ice v1.4.5 h1:y+L7PK3Lf/N/clOHd0tD0QUh7xHDWLLYIHXEovz40pw= -shylinux.com/x/ice v1.4.5/go.mod h1:gGMjGWvuvr8vRTPZI3DqSkvdtX3eOEKss2QIP4sH5TE= -shylinux.com/x/icebergs v1.8.4 h1:ak7ZteykXBCWjhSwFyC2JjASfigZrpm9BtN9mn/6E5M= -shylinux.com/x/icebergs v1.8.4/go.mod h1:9iX2Tg2y4THWiW6+BBUgFt5vMCoFWDtiIPw4lfMP+rI= -shylinux.com/x/icebergs v1.8.5 h1:z0aNKY8rGQivpv8L/OWpG8AIr07ndN7j9kF+WTM072s= -shylinux.com/x/icebergs v1.8.5/go.mod h1:Ob8PHoRK4MQXzj4dqWaSQGdwHo5yhuOAaGgGM9eXaoY= +shylinux.com/x/ice v1.4.6 h1:9bZ1MIht3J20mIpPWwrbMLOfZqnfBjX2lsDQSUU1w2c= +shylinux.com/x/ice v1.4.6/go.mod h1:or84ZamFWv4uln4CnzJHlBMl/O11RPwecm4WlE6IXUc= +shylinux.com/x/icebergs v1.8.6 h1:/LhsXE9S384BQdutgDqo9X3HETq41LWDmO8zRwOesos= +shylinux.com/x/icebergs v1.8.6/go.mod h1:4E+FVUqqnCfeQr8Dsh9T2jOl9tEWaXFS+5R1GFwky2g= shylinux.com/x/toolkits v0.7.10/go.mod h1:CHDJarGlDkg60kVsvMLYL/a5hAnRLEOShiEsMOuEp0Q= -shylinux.com/x/toolkits v0.8.4 h1:EEF+49x9a0gvtth15RZR1e+eutRFFf4F77QDjXN6DDM= -shylinux.com/x/toolkits v0.8.4/go.mod h1:CHDJarGlDkg60kVsvMLYL/a5hAnRLEOShiEsMOuEp0Q= -shylinux.com/x/toolkits v1.0.0 h1:6QaJtX7KMSGXEtN04GcQqTxS1PcrMMgKbp+qYv+yowU= -shylinux.com/x/toolkits v1.0.0/go.mod h1:CHDJarGlDkg60kVsvMLYL/a5hAnRLEOShiEsMOuEp0Q= +shylinux.com/x/toolkits v1.0.1 h1:qG0Do0mDxObMwNa8KqCIT8RAn+7T2dWXTYGeAQX4o6c= +shylinux.com/x/toolkits v1.0.1/go.mod h1:CHDJarGlDkg60kVsvMLYL/a5hAnRLEOShiEsMOuEp0Q= shylinux.com/x/websocket v0.0.3 h1:edhLwCp0Mv1ITXqIwbVWdXdX2+vui/jRnS25K89k68I= shylinux.com/x/websocket v0.0.3/go.mod h1:3UGWkjTu3ie5NAZen7J+uLPBrO7DFeKloj6Jxo13Oiw= diff --git a/usr/local/honor/src/contexts/aaa/aaa.go b/usr/local/honor/src/contexts/aaa/aaa.go deleted file mode 100644 index df6b3f97..00000000 --- a/usr/local/honor/src/contexts/aaa/aaa.go +++ /dev/null @@ -1,1061 +0,0 @@ -package aaa - -import ( - "gopkg.in/gomail.v2" - "strconv" - - "contexts/ctx" - "toolkit" - - "crypto" - "crypto/aes" - "crypto/cipher" - "crypto/md5" - crand "crypto/rand" - "crypto/rsa" - "crypto/x509" - "crypto/x509/pkix" - "encoding/base64" - "encoding/hex" - "encoding/json" - "encoding/pem" - "fmt" - "io/ioutil" - "math/big" - "math/rand" - "os" - "strings" - "time" -) - -type AAA struct { - certificate *x509.Certificate - public *rsa.PublicKey - private *rsa.PrivateKey - encrypt cipher.BlockMode - decrypt cipher.BlockMode - - *ctx.Context -} - -func Input(stream string) []byte { - if b, e := ioutil.ReadFile(stream); e == nil { - return b - } - return []byte(stream) -} -func Decode(stream string) []byte { - block, _ := pem.Decode(Input(stream)) - return block.Bytes -} -func Password(pwd string) string { - bs := md5.Sum([]byte(fmt.Sprintln("password:%s", pwd))) - return hex.EncodeToString(bs[:]) -} - -func (aaa *AAA) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { - return &AAA{Context: c} -} -func (aaa *AAA) Begin(m *ctx.Message, arg ...string) ctx.Server { - return aaa -} -func (aaa *AAA) Start(m *ctx.Message, arg ...string) bool { - stream := arg[1] - switch arg[0] { - case "cert": - cert, e := x509.ParseCertificate(Decode(stream)) - m.Assert(e) - - aaa.certificate = cert - aaa.public = cert.PublicKey.(*rsa.PublicKey) - stream = Password(stream) - case "pub": - public, e := x509.ParsePKIXPublicKey(Decode(stream)) - m.Assert(e) - - aaa.public = public.(*rsa.PublicKey) - stream = Password(stream) - case "key": - private, e := x509.ParsePKCS1PrivateKey(Decode(stream)) - m.Assert(e) - - aaa.private = private - aaa.public = &aaa.private.PublicKey - stream = Password(stream) - } - m.Log("info", "%d login %s", m.Capi("nuser"), m.Cap("stream", stream)) - return false -} -func (aaa *AAA) Close(m *ctx.Message, arg ...string) bool { - return false -} - -var Index = &ctx.Context{Name: "aaa", Help: "认证中心", - Caches: map[string]*ctx.Cache{}, - Configs: map[string]*ctx.Config{ - "hash": &ctx.Config{Name: "hash", Value: map[string]interface{}{}, Help: "散列"}, - "auth": &ctx.Config{Name: "auth", Value: map[string]interface{}{}, Help: "散列"}, - "auth_type": &ctx.Config{Name: "auth_type", Value: map[string]interface{}{ - "unique": map[string]interface{}{"session": true, "relay": true}, - "public": map[string]interface{}{"userrole": true, "username": true, "cert": true, "access": true}, - "single": map[string]interface{}{"password": true, "token": true, "uuid": true, "ppid": true}, - "secrete": map[string]interface{}{"password": true, "token": true, "uuid": true, "ppid": true}, - }, Help: "散列"}, - - "short": &ctx.Config{Name: "short", Value: map[string]interface{}{}, Help: "散列"}, - "email": &ctx.Config{Name: "email", Value: map[string]interface{}{ - "self": "shylinux@163.com", "smtp": "smtp.163.com", "port": "25", - }, Help: "邮件服务"}, - }, - Commands: map[string]*ctx.Command{ - "_init": &ctx.Command{Name: "_init", Help: "初始化", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - m.Conf("runtime", "node.cert", m.Cmdx("nfs.load", os.Getenv("node_cert"))) - m.Conf("runtime", "node.key", m.Cmdx("nfs.load", os.Getenv("node_key"))) - return - }}, - "hash": &ctx.Command{Name: "hash [meta...]", Help: "数字摘要", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if len(arg) == 0 { - m.Cmdy("ctx.config", "hash") - return - } - - hs, meta := kit.Hash(arg) - m.Log("info", "%s: %v", hs, meta) - m.Confv("hash", hs, meta) - m.Echo(hs) - return - }}, - "auth": &ctx.Command{Name: "auth [id|(key val)]... [node|ship|data] [check|delete] key [val]", - Help: "权限区块链", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - // 节点列表 - if len(arg) == 0 { - m.Confm("auth", func(key string, node map[string]interface{}) { - up := false - if ship, ok := node["ship"].(map[string]interface{}); ok { - for k, v := range ship { - val := v.(map[string]interface{}) - switch val["ship"].(string) { - case "0": - if !up { - up = true - m.Push("up_key", k[:8]) - m.Push("up_type", val["type"]) - } - } - } - } - if !up { - m.Push("up_key", "") - m.Push("up_type", "") - } - - m.Push("key", key) - m.Push("type", node["type"]) - m.Push("meta", node["meta"]) - }) - m.Sort("type").Table() - return - } - - p, t, a := "", "", "" - s, route, block, chain := "", "ship", []map[string]string{}, []map[string]string{} - for i := 0; i < len(arg); i += 2 { - // 查找节点 - if node := m.Confm("auth", arg[i]); node != nil { - // 切换节点 - p, t, a = arg[i], node["type"].(string), node["meta"].(string) - - // 一级节点 - if i++; s == "" { - s = p - } - } - - // 切换类型 - if i < len(arg) { - switch arg[i] { - case "data", "node", "ship": - route, i = arg[i], i+1 - } - } - - if p == "" && route != "ship" { - return - } - - switch route { - // 链接操作 - case "ship": - // 节点列表 - if i >= len(arg)-1 { - if p == "" { - // 所有节点 - m.Confm("auth", func(k string, node map[string]interface{}) { - if t, _ := node["type"].(string); i > len(arg)-1 || t == arg[i] || strings.HasSuffix(k, arg[i]) || strings.HasPrefix(k, arg[i]) { - m.Push("create_time", node["create_time"]) - m.Push("key", k) - m.Push("type", node["type"]) - m.Push("meta", node["meta"]) - } - }) - } else { - // 添加关系 - if i == len(arg)-1 { - m.Confm("auth", []string{arg[i]}, func(node map[string]interface{}) { - m.Confv("auth", []string{p, "ship", arg[i]}, node) - }) - } - - // 关联节点 - m.Confm("auth", []string{p, "ship"}, func(k string, ship map[string]interface{}) { - if node := m.Confm("auth", k); i > len(arg)-1 || ship["type"].(string) == arg[i] || strings.HasSuffix(k, arg[i]) || strings.HasPrefix(k, arg[i]) { - m.Push("create_time", node["create_time"]) - m.Push("key", k) - m.Push("ship", ship["ship"]) - m.Push("type", node["type"]) - m.Push("meta", node["meta"]) - } - }) - } - m.Sort("create_time", "time_r").Set("result").Table() - return - } - - // 删除链接 - if arg[i] == "delete" { - m.Confm("auth", []string{p, "ship"}, func(ship map[string]interface{}) { - for _, k := range arg[i+1:] { - m.Confm("auth", []string{k, "ship"}, func(peer map[string]interface{}) { - m.Log("info", "delete peer %s %s %s", k, s, kit.Formats(peer[s])) - delete(peer, s) - }) - m.Log("info", "delete ship %s %s %s", s, k, kit.Formats(ship[k])) - delete(ship, k) - } - }) - return - } - - // 检查链接 - if arg[i] == "check" { - has := "false" - m.Confm("auth", []string{p, "ship"}, func(k string, ship map[string]interface{}) { - if i == len(arg)-2 && (ship["meta"] != arg[i+1] && k != arg[i+1]) { - return - } - if i == len(arg)-3 && (ship["type"] != arg[i+1] || ship["meta"] != arg[i+2]) { - return - } - - if ship["expire_time"] == nil || int64(kit.Int(ship["expire_time"])) > time.Now().Unix() { - has = k - } - }) - m.Set("result").Echo(has) - return - } - - // 节点哈希 - meta := []string{arg[i]} - // 加密节点 - if m.Confs("auth_type", []string{"secrete", arg[i]}) { - meta = append(meta, Password(arg[i+1])) - } else { - meta = append(meta, arg[i+1]) - } - // 私有节点 - if !m.Confs("auth_type", []string{"public", arg[i]}) { - if m.Confs("auth_type", []string{"unique", arg[i]}) { - meta = append(meta, "uniq") - } else { - meta = append(meta, p) - } - } - h := kit.Hashs(meta) - - // 新的节点 - if !m.Confs("auth", h) { - // 单点认证 - if m.Set("result"); m.Confs("auth_type", []string{"single", arg[i]}) && m.Confs("auth", p) && m.Cmds("aaa.auth", p, arg[i]) { - m.Log("fuck", "password %s", h) - // 认证失败 - return - } - - // 创建节点 - block = append(block, map[string]string{"hash": h, "type": arg[i], "meta": meta[1]}) - } - - // 祖孙链接 - if s != "" { - chain = append(chain, map[string]string{"node": s, "ship": "3", "hash": h, "type": arg[i], "meta": meta[1]}) - chain = append(chain, map[string]string{"node": h, "ship": "2", "hash": s, "type": arg[i], "meta": meta[1]}) - } - // 父子链接 - if p != "" { - chain = append(chain, map[string]string{"node": p, "ship": "1", "hash": h, "type": arg[i], "meta": meta[1]}) - chain = append(chain, map[string]string{"node": h, "ship": "0", "hash": p, "type": t, "meta": a}) - } - // 切换节点 - p, t, a = h, arg[i], meta[1] - m.Echo(h) - - // 节点操作 - case "node": - if i > len(arg)-1 { - // 查看节点 - m.Set("result").Cmdy("aaa.config", "auth", p) - - } else if arg[i] == "delete" { - // 删除节点 - m.Confm("auth", []string{p, "ship"}, func(ship map[string]interface{}) { - for k, _ := range ship { - m.Confm("auth", []string{k, "ship"}, func(peer map[string]interface{}) { - m.Log("info", "delete peer %s %s %s", k, s, kit.Formats(peer[s])) - delete(peer, s) - }) - m.Log("info", "delete ship %s %s %s", s, k, kit.Formats(ship[k])) - delete(ship, k) - } - m.Log("info", "delete node %s %s", s, kit.Formats(m.Confm("auth", s))) - delete(m.Confm("auth"), s) - }) - - } else if i < len(arg)-1 { - // 修改属性 - m.Confv("auth", []string{p, arg[i]}, arg[i+1]) - break - - } else { - // 搜索属性 - ps := []string{p} - for j := 0; j < len(ps); j++ { - if value := m.Confv("auth", []string{ps[j], arg[i]}); value != nil { - m.Put("option", "data", value).Cmdy("ctx.trans", "data") - break - } - m.Confm("auth", []string{ps[j], "ship"}, func(key string, ship map[string]interface{}) { - if ship["ship"] != "0" { - ps = append(ps, key) - } - }) - } - } - return - - // 数据操作 - case "data": - if i > len(arg)-1 { - // 查看数据 - m.Set("result").Echo(m.Conf("auth", strings.Join([]string{p, "data"}, "."))) - - } else if i == len(arg)-1 { - // 查看数据 - m.Set("result").Echo(m.Conf("auth", strings.Join([]string{p, "data", arg[i]}, "."))) - - } else if arg[i] == "delete" { - // 删除数据 - m.Confm("auth", []string{s, "data"}, func(data map[string]interface{}) { - for _, k := range arg[i+1:] { - m.Log("info", "delete data %s %s %s", s, k, kit.Formats(data[k])) - delete(data, k) - } - }) - - } else if i < len(arg)-1 { - // 修改数据 - if m.Set("result"); arg[i] == "option" { - m.Confv("auth", []string{p, "data", arg[i+1]}, m.Optionv(arg[i+1])) - } else { - m.Confv("auth", []string{p, "data", arg[i]}, arg[i+1]) - } - m.Echo(arg[i+1]) - break - - } else { - // 搜索数据 - ps := []string{p} - for j := 0; j < len(ps); j++ { - if value := m.Confv("auth", []string{ps[j], "data", arg[i]}); value != nil { - m.Set("append").Set("result").Put("option", "data", value).Cmdy("ctx.trans", "data") - break - } - m.Confm("auth", []string{ps[j], "ship"}, func(key string, ship map[string]interface{}) { - if ship["ship"] != "0" { - ps = append(ps, key) - } - }) - } - } - return - } - } - - // 添加节点 - for _, b := range block { - m.Confv("auth", b["hash"], map[string]interface{}{"create_time": m.Time(), "type": b["type"], "meta": b["meta"]}) - } - // 添加链接 - for _, c := range chain { - m.Confv("auth", []interface{}{c["node"], "ship", c["hash"]}, map[string]interface{}{"ship": c["ship"], "type": c["type"], "meta": c["meta"]}) - } - m.Log("debug", "block: %v chain: %v", len(block), len(chain)) - return - }}, - - "role": &ctx.Command{Name: "role [name [componet [name [command [name]]]]|[check [componet [command]]]|[user [name [password|cert|uuid code]]]]", - Help: []string{"用户角色, name", - "权限管理, componet [name [command name]]", - "权限检查, check [componet [command]]", - "用户管理, user [name [password|cert|uuid code]]", - }, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - // 角色列表 - if len(arg) == 0 { - m.Cmdy("aaa.auth", "ship", "userrole") - return - } - - role, arg := kit.Select("void", arg[0]), arg[1:] - switch arg[0] { - // 权限管理 - case "componet", "command": - // 解析参数 - componets, commands := []string{}, []string{} - for i := 0; i < len(arg); i++ { - if arg[i] == "command" { - for i = i + 1; i < len(arg); i++ { - if arg[i] == "componet" { - break - } - commands = append(commands, arg[i]) - } - continue - } - if arg[i] == "componet" { - continue - } - componets = append(componets, arg[i]) - } - m.Log("info", "componet: %v, command: %v", componets, commands) - - // 组件列表 - if len(componets) == 0 { - m.Cmdy("aaa.auth", "ship", "userrole", role, "componet") - return - } - - for i := 0; i < len(componets); i++ { - // 命令列表 - if len(commands) == 0 { - m.Cmdy("aaa.auth", "ship", "userrole", role, "componet", componets[i], "command") - continue - } - // 添加命令 - for j := 0; j < len(commands); j++ { - m.Cmd("aaa.auth", "ship", "userrole", role, "componet", componets[i], "command", commands[j]) - } - } - - // 检查权限 - case "check": - switch len(arg) { - case 1: // 超级权限 - m.Echo("%t", role == "root") - case 2: // 组件权限 - m.Echo("%t", role == "root" || m.Cmds("aaa.auth", "userrole", role, "check", "componet", arg[1])) - case 3: // 命令权限 - m.Echo("%t", role == "root" || m.Cmds("aaa.auth", "userrole", role, "componet", arg[1], "check", "command", arg[2])) - default: // 参数权限 - m.Echo("%t", role == "root" || m.Cmds("aaa.auth", "userrole", role, "componet", arg[1], "check", "command", arg[2])) - } - m.Log("right", "%v %v: %v %v %v", m.Result(0), m.Option("sessid"), m.Option("username"), role, arg[1:]) - - // 用户管理 - case "user": - // 用户列表 - if len(arg) == 1 { - m.Cmdy("aaa.auth", "ship", "userrole", role, "username") - break - } - - // 添加用户 - for i := 1; i < len(arg); i++ { - if m.Cmd("aaa.auth", "ship", "username", arg[i], "userrole", role); i < len(arg)-2 { - switch arg[i+1] { - case "password", "cert", "uuid": - // 添加认证 - m.Cmd("aaa.auth", "ship", "username", arg[i], arg[i+1], arg[i+2]) - i += 2 - } - } - } - } - return - }}, - "user": &ctx.Command{Name: "user role|login|cookie|session|key", Help: []string{"用户管理", - "role: 查看角色", - "login [password|cert|uuid [code]]: 用户登录", - "cookie [spide [key [value]]]: 读写缓存", - "session [select|create [meta]]: 会话管理", - "key [value]: 用户数据", - }, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - // 用户列表 - if len(arg) == 0 { - m.Cmdy("aaa.auth", "ship", "username") - return - } - - switch arg[0] { - // 角色列表 - case "role": - m.Cmdy("aaa.auth", "ship", "username", m.Option("username"), "userrole") - - // 用户登录 - case "login": - m.Cmdy("aaa.auth", "username", m.Option("username"), arg[1], arg[2]) - - case "cookie": - // 设置缓存 - if len(arg) > 3 { - m.Cmdy("aaa.auth", "username", m.Option("username"), "data", strings.Join(arg[:3], "."), arg[3]) - arg = arg[:3] - } - - // 查看缓存 - m.Cmdy("aaa.auth", "username", m.Option("username"), "data", strings.Join(arg, ".")) - - case "session": - // 查看会话 - if len(arg) == 1 { - m.Cmdy("aaa.auth", "ship", "username", m.Option("username"), "session") - return - } - - switch arg[1] { - case "select": - defer func() { m.Log("info", "sessid: %s", m.Result(0)) }() - - // 检查会话 - if m.Options("sessid") && m.Cmds("aaa.auth", "ship", "username", m.Option("username"), "check", m.Option("sessid")) { - m.Echo(m.Option("sessid")) - return - } - // 选择会话 - if m.Cmdy("aaa.auth", "ship", "username", m.Option("username"), "session"); m.Appends("key") { - m.Set("result").Echo(m.Append("key")) - return - } - fallthrough - case "create": - // 创建会话 - m.Cmdy("aaa.auth", "ship", "username", m.Option("username"), "session", kit.Select("web", arg, 2)) - m.Cmd("aaa.auth", m.Result(0), "data", "current.ctx", "mdb") - } - default: - // 读写数据 - m.Option("format", "object") - m.Cmdy("aaa.auth", "username", m.Option("username"), "data", arg) - } - return - }}, - "sess": &ctx.Command{Name: "sess [sid] [user|access|key [val]]", Help: "会话管理, user: 用户列表, access: 访问管理, key [val]: 读写数据", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - // 会话列表 - if len(arg) == 0 { - m.Cmdy("aaa.auth", "ship", "session") - return - } - - // 查找会话 - sid := m.Option("sessid") - if m.Conf("auth", []string{arg[0], "type"}) == "session" { - if sid, arg = arg[0], arg[1:]; len(arg) == 0 { - m.Echo(sid) - return - } - } - - switch arg[0] { - // 查看用户 - case "user": - m.Cmdy("aaa.auth", sid, "ship", "username") - - case "access": - // 查看访问 - if len(arg) == 1 { - m.Cmdy("aaa.auth", sid, "access") - break - } - // 添加访问 - if sid != "" { - m.Cmdy("aaa.auth", sid, "access", arg[1]) - } - // 查看会话 - if len(arg) == 2 { - m.Cmdy("aaa.auth", "access", arg[1], "ship", "session") - break - } - // 读写数据 - m.Cmdy("aaa.auth", "access", arg[1], "data", arg[2:]) - - default: - // 读写数据 - m.Option("format", "object") - m.Cmdy("aaa.auth", sid, "data", arg) - } - return - }}, - "short": &ctx.Command{Name: "short", Help: "短码", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - // cc2309e0cb95ab3cabced1b3e7141105 - if len(arg) == 0 { - return - } - length := 6 - short := arg[0][:length] - - if len(arg[0]) == 32 { - m.Confm("aaa.short", short, func(index int, value string) { - if value == arg[0] { - m.Echo("%s%02x", short, index) - } - }) - if m.Result() != "" { - return - } - - m.Confv("aaa.short", []string{short, "-2"}, arg[0]) - if v, ok := m.Confv("aaa.short", short).([]interface{}); ok { - m.Echo("%s%02x", short, len(v)-1) - } - - } else if len(arg[0]) > 0 { - if i, e := strconv.ParseInt(arg[0][length:], 16, 64); e == nil { - m.Echo(m.Conf("aaa.short", []interface{}{short, int(i)})) - } else { - m.Echo(arg[0]) - } - } - return - }}, - "relay": &ctx.Command{Name: "relay [rid] [check userrole]|[count num]|[share [type [role [name [count]]]]]", Help: "授权", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - // 授权列表 - if len(arg) == 0 { - m.Cmdy("aaa.auth", "relay") - return - } - - rid := m.Option("relay") - if m.Confm("auth", arg[0]) != nil { - if rid, arg = arg[0], arg[1:]; len(arg) == 0 { - m.Echo(rid) - return - } - } - - switch arg[0] { - // 检查授权 - case "check": - if relay := m.Confm("auth", []string{rid, "data"}); relay != nil { - if kit.Select("", arg, 1) == "userrole" && kit.Int(relay["count"]) > 0 { - m.Echo("%s", relay["userrole"]) - } - for k, v := range relay { - m.Append(k, v) - } - if kit.Int(relay["count"]) > 0 { - relay["count"] = kit.Int(relay["count"]) - 1 - } - } - - // 分享权限 - case "share": - if len(arg) == 1 { - m.Cmdy("aaa.auth", "username", m.Option("username"), "relay") - break - } - relay := m.Cmdx("aaa.auth", "username", m.Option("username"), "relay", arg[1]) - m.Cmd("aaa.auth", relay, "data", "from", m.Option("username"), "count", "1", arg[2:]) - m.Echo(relay) - - // 授权计数 - case "count": - m.Cmdy("aaa.auth", rid, "data", "count", kit.Select("1", arg, 1)) - - case "clear": - m.Cmdy("aaa.auth", "relay") - - default: - m.Cmdy("aaa.auth", rid, "data", arg) - } - return - }}, - "email": &ctx.Command{Name: "email name title content", Help: "发送邮件", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - msg := gomail.NewMessage() - msg.SetHeader("From", m.Conf("email", "self")) - msg.SetHeader("To", arg[0]) - msg.SetHeader("Subject", arg[1]) - msg.SetBody("text/html", strings.Join(arg[2:], "")) - m.Assert(gomail.NewDialer(m.Conf("email", "smtp"), kit.Int(m.Conf("email", "port")), m.Conf("email", "self"), m.Conf("email", "code")).DialAndSend(msg)) - m.Echo("success") - return - }}, - "location": &ctx.Command{Name: "location [latitude [longitude [location]]]", Help: "地理位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - h := m.Cmdx("aaa.auth", "username", m.Option("username")) - - // 位置列表 - if len(arg) < 2 { - m.Confm("auth", []string{h, "data", "location"}, func(index int, value map[string]interface{}) { - m.Push("create_time", value["create_time"]) - m.Push("index", index) - m.Push("location", value["location"]) - m.Push("latitude", value["latitude"]) - m.Push("longitude", value["longitude"]) - }) - m.Table() - return - } - - switch arg[0] { - // 添加位置 - default: - m.Conf("auth", []string{h, "data", "location", "-2"}, map[string]interface{}{ - "create_time": m.Time(), - "location": kit.Select("", arg, 2), - "latitude": arg[0], "longitude": arg[1], - }) - m.Echo("%d", len(m.Confv("auth", []string{h, "data", "location"}).([]interface{}))-1) - } - return - }}, - "clip": &ctx.Command{Name: "clip", Help: "粘贴板", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - // 文本列表 - h := m.Cmdx("aaa.auth", "username", m.Option("username")) - if len(arg) == 0 { - m.Cmdy("aaa.config", "auth", h+".data.clip") - return - } - - switch arg[0] { - // 清空列表 - case "clear": - m.Conf("auth", []string{h, "data", "clip"}, []interface{}{}) - - // 添加文本 - default: - m.Conf("auth", []string{h, "data", "clip", kit.Select("-2", arg, 1)}, arg[0]) - m.Echo("%d", len(m.Confv("auth", []string{h, "data", "clip"}).([]interface{}))-1) - } - return - }}, - - "rsa": &ctx.Command{Name: "rsa gen|sign|verify|encrypt|decrypt|cert", - Form: map[string]int{"common": -1}, - Help: []string{"gen: 生成密钥, sgin: 私钥签名, verify: 公钥验签, encrypt: 公钥加密, decrypt: 私钥解密", - "密钥: rsa gen [keyfile [pubfile [certfile]]]", - "加密: rsa encrypt pub content [enfile]", - "解密: rsa decrypt key content [defile]", - "签名: rsa sign key content [signfile]", - "验签: rsa verify pub content", - }, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - switch arg[0] { - case "gen": - // 生成私钥 - keys, e := rsa.GenerateKey(crand.Reader, 1024) - m.Assert(e) - - private := string(pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(keys)})) - m.Echo(m.Append("private", private)) - - // 生成公钥 - pub, e := x509.MarshalPKIXPublicKey(&keys.PublicKey) - m.Assert(e) - - public := string(pem.EncodeToMemory(&pem.Block{Type: "RSA PUBLIC KEY", Bytes: pub})) - m.Echo(m.Append("public", public)) - - common := map[string]interface{}{} - for i := 0; i < len(m.Meta["common"]); i += 2 { - kit.Chain(common, m.Meta["common"][i], m.Meta["common"][i+1]) - } - - // 生成证书 - template := x509.Certificate{ - SerialNumber: big.NewInt(1), - IsCA: true, - BasicConstraintsValid: true, - KeyUsage: x509.KeyUsageCertSign, - Subject: pkix.Name{CommonName: kit.Format(common)}, - } - cert, e := x509.CreateCertificate(crand.Reader, &template, &template, &keys.PublicKey, keys) - m.Assert(e) - - certificate := string(pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert})) - m.Echo(m.Append("certificate", certificate)) - - // 输出文件 - if len(arg) > 1 { - ioutil.WriteFile(arg[1], []byte(private), 0666) - } - if len(arg) > 2 { - ioutil.WriteFile(arg[2], []byte(public), 0666) - } - if len(arg) > 3 { - ioutil.WriteFile(arg[3], []byte(certificate), 0666) - } - case "sign": - private, e := x509.ParsePKCS1PrivateKey(Decode(arg[1])) - m.Assert(e) - - h := md5.Sum(Input(arg[2])) - b, e := rsa.SignPKCS1v15(crand.Reader, private, crypto.MD5, h[:]) - m.Assert(e) - - res := base64.StdEncoding.EncodeToString(b) - if m.Echo(res); len(arg) > 3 { - ioutil.WriteFile(arg[3], []byte(res), 0666) - } - case "verify": - public, e := x509.ParsePKIXPublicKey(Decode(arg[1])) - if e != nil { - cert, e := x509.ParseCertificate(Decode(arg[1])) - m.Assert(e) - public = cert.PublicKey - } - - buf := make([]byte, 1024) - n, e := base64.StdEncoding.Decode(buf, Input(arg[2])) - m.Assert(e) - buf = buf[:n] - - h := md5.Sum(Input(arg[3])) - m.Echo("%t", rsa.VerifyPKCS1v15(public.(*rsa.PublicKey), crypto.MD5, h[:], buf) == nil) - case "encrypt": - public, e := x509.ParsePKIXPublicKey(Decode(arg[1])) - m.Assert(e) - - b, e := rsa.EncryptPKCS1v15(crand.Reader, public.(*rsa.PublicKey), Input(arg[2])) - m.Assert(e) - - res := base64.StdEncoding.EncodeToString(b) - if m.Echo(res); len(arg) > 3 { - ioutil.WriteFile(arg[3], []byte(res), 0666) - } - case "decrypt": - private, e := x509.ParsePKCS1PrivateKey(Decode(arg[1])) - m.Assert(e) - - buf := make([]byte, 1024) - n, e := base64.StdEncoding.Decode(buf, Input(arg[2])) - m.Assert(e) - buf = buf[:n] - - b, e := rsa.DecryptPKCS1v15(crand.Reader, private, buf) - m.Assert(e) - - if m.Echo(string(b)); len(arg) > 3 { - ioutil.WriteFile(arg[3], b, 0666) - } - case "cert": - private, e := x509.ParsePKCS1PrivateKey(Decode(arg[1])) - m.Assert(e) - - cert, e := x509.ParseCertificate(Decode(arg[2])) - m.Assert(e) - - public, e := x509.ParsePKIXPublicKey(Decode(arg[3])) - m.Assert(e) - - template := &x509.Certificate{ - SerialNumber: big.NewInt(rand.Int63()), - NotBefore: time.Now(), - NotAfter: time.Now().AddDate(1, 0, 0), - } - buf, e := x509.CreateCertificate(crand.Reader, template, cert, public, private) - - certificate := string(pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: buf})) - if m.Echo(certificate); len(arg) > 4 { - ioutil.WriteFile(arg[4], []byte(certificate), 0666) - } - case "info": - cert, e := x509.ParseCertificate(Decode(arg[1])) - m.Assert(e) - - var common interface{} - json.Unmarshal([]byte(cert.Subject.CommonName), &common) - m.Put("option", "common", common).Cmdy("ctx.trans", "common", "format", "object") - case "grant": - private, e := x509.ParsePKCS1PrivateKey(Decode(arg[1])) - m.Assert(e) - - parent, e := x509.ParseCertificate(Decode(arg[2])) - m.Assert(e) - - for _, v := range arg[3:] { - template, e := x509.ParseCertificate(Decode(v)) - m.Assert(e) - - cert, e := x509.CreateCertificate(crand.Reader, template, parent, template.PublicKey, private) - m.Assert(e) - - certificate := string(pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert})) - m.Echo(certificate) - } - case "check": - parent, e := x509.ParseCertificate(Decode(arg[1])) - m.Assert(e) - - for _, v := range arg[2:] { - template, e := x509.ParseCertificate(Decode(v)) - m.Assert(e) - - if e = template.CheckSignatureFrom(parent); e != nil { - m.Echo("error: ").Echo("%v", e) - } - } - m.Echo("true") - } - return - }}, - "keys": &ctx.Command{Name: "keys [filename]", Help: "导出私钥", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) && aaa.private != nil { - private := string(pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(aaa.private)})) - if m.Echo(private); len(arg) > 0 { - m.Assert(ioutil.WriteFile(arg[0], []byte(private), 0666)) - } - } - return - }}, - "cert": &ctx.Command{Name: "cert [filename]", Help: "导出证书", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) && aaa.certificate != nil { - certificate := string(pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: aaa.certificate.Raw})) - if m.Echo(certificate); len(arg) > 0 { - m.Assert(ioutil.WriteFile(arg[0], []byte(certificate), 0666)) - } - } - return - }}, - "pub": &ctx.Command{Name: "pub [filename]", Help: "导出公钥", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) && aaa.public != nil { - pub, e := x509.MarshalPKIXPublicKey(aaa.public) - m.Assert(e) - public := string(pem.EncodeToMemory(&pem.Block{Type: "RSA PUBLIC KEY", Bytes: pub})) - if m.Echo(public); len(arg) > 0 { - m.Assert(ioutil.WriteFile(arg[0], []byte(public), 0666)) - } - } - return - }}, - "sign": &ctx.Command{Name: "sign content [signfile]", Help: "数字签名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) && aaa.private != nil { - h := md5.Sum(Input(arg[0])) - b, e := rsa.SignPKCS1v15(crand.Reader, aaa.private, crypto.MD5, h[:]) - m.Assert(e) - - res := base64.StdEncoding.EncodeToString(b) - if m.Echo(res); len(arg) > 1 { - m.Assert(ioutil.WriteFile(arg[1], []byte(res), 0666)) - } - } - return - }}, - "verify": &ctx.Command{Name: "verify content signature", Help: "数字验签", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) && aaa.public != nil { - buf := make([]byte, 1024) - n, e := base64.StdEncoding.Decode(buf, Input(arg[1])) - m.Assert(e) - buf = buf[:n] - - h := md5.Sum(Input(arg[0])) - m.Echo("%t", rsa.VerifyPKCS1v15(aaa.public, crypto.MD5, h[:], buf) == nil) - } - return - }}, - "seal": &ctx.Command{Name: "seal content [sealfile]", Help: "数字加密", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) && aaa.public != nil { - b, e := rsa.EncryptPKCS1v15(crand.Reader, aaa.public, Input(arg[0])) - m.Assert(e) - - res := base64.StdEncoding.EncodeToString(b) - if m.Echo(res); len(arg) > 1 { - m.Assert(ioutil.WriteFile(arg[1], []byte(res), 0666)) - } - } - return - }}, - "deal": &ctx.Command{Name: "deal content", Help: "数字解密", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) && aaa.private != nil { - buf := make([]byte, 1024) - n, e := base64.StdEncoding.Decode(buf, Input(arg[0])) - m.Assert(e) - buf = buf[:n] - - b, e := rsa.DecryptPKCS1v15(crand.Reader, aaa.private, buf) - m.Assert(e) - m.Echo(string(b)) - } - return - }}, - - "newcipher": &ctx.Command{Name: "newcipher salt", Help: "加密算法", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) { - salt := md5.Sum(Input(arg[0])) - block, e := aes.NewCipher(salt[:]) - m.Assert(e) - aaa.encrypt = cipher.NewCBCEncrypter(block, salt[:]) - aaa.decrypt = cipher.NewCBCDecrypter(block, salt[:]) - } - return - }}, - "encrypt": &ctx.Command{Name: "encrypt content [enfile]", Help: "加密数据", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) && aaa.encrypt != nil { - content := Input(arg[0]) - - bsize := aaa.encrypt.BlockSize() - size := (len(content) / bsize) * bsize - if len(content)%bsize != 0 { - size += bsize - } - - buf := make([]byte, size) - for pos := 0; pos < len(content); pos += bsize { - end := pos + bsize - if end > len(content) { - end = len(content) - } - - b := make([]byte, bsize) - copy(b, content[pos:end]) - - aaa.encrypt.CryptBlocks(buf[pos:pos+bsize], b) - } - - res := base64.StdEncoding.EncodeToString(buf) - if m.Echo(res); len(arg) > 1 { - m.Assert(ioutil.WriteFile(arg[1], []byte(res), 0666)) - } - } - return - }}, - "decrypt": &ctx.Command{Name: "decrypt content [defile]", Help: "解密数据", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) && aaa.decrypt != nil { - content := Input(arg[0]) - - buf := make([]byte, 1024) - n, e := base64.StdEncoding.Decode(buf, content) - m.Assert(e) - buf = buf[:n] - - res := make([]byte, n) - aaa.decrypt.CryptBlocks(res, buf) - - if m.Echo(string(res)); len(arg) > 1 { - m.Assert(ioutil.WriteFile(arg[1], res, 0666)) - } - } - return - }}, - }, -} - -func init() { - ctx.Index.Register(Index, &AAA{Context: Index}) -} diff --git a/usr/local/honor/src/contexts/cli/cli.go b/usr/local/honor/src/contexts/cli/cli.go deleted file mode 100644 index 4c7dd82b..00000000 --- a/usr/local/honor/src/contexts/cli/cli.go +++ /dev/null @@ -1,1324 +0,0 @@ -package cli - -import ( - "contexts/ctx" - "toolkit" - - "bufio" - "bytes" - "encoding/csv" - "encoding/json" - "fmt" - "os" - "os/exec" - "os/user" - "path" - "plugin" - "reflect" - "runtime" - "strconv" - "strings" - "time" -) - -type CLI struct { - *time.Timer - Context *ctx.Context -} - -func format(m *ctx.Message, out *bytes.Buffer) { - switch m.Option("cmd_parse") { - case "format": - var data interface{} - if json.Unmarshal(out.Bytes(), &data) == nil { - if b, e := json.MarshalIndent(data, "", " "); e == nil { - m.Echo(string(b)) - break - } - } - m.Echo(out.String()) - case "json": - var data interface{} - if json.Unmarshal(out.Bytes(), &data) == nil { - msg := m.Spawn().Put("option", "data", data).Cmd("trans", "data", "") - m.Copy(msg, "append").Copy(msg, "result") - } else { - m.Echo(out.String()) - } - - case "csv": - data, e := csv.NewReader(out).ReadAll() - m.Assert(e) - for i := 1; i < len(data); i++ { - for j := 0; j < len(data[i]); j++ { - m.Add("append", data[0][j], data[i][j]) - } - } - m.Table() - case "cli": - read := csv.NewReader(out) - read.Comma = ' ' - read.TrimLeadingSpace = true - read.FieldsPerRecord = 4 - data, e := read.ReadAll() - m.Assert(e) - for i := 1; i < len(data); i++ { - for j := 0; j < len(data[i]); j++ { - m.Add("append", data[0][j], data[i][j]) - } - } - m.Table() - case "cut": - c := rune(kit.Select(" ", m.Optionv("cmd_parse"), 1)[0]) - - bio := bufio.NewScanner(out) - - pos := []int{} - heads := []string{} - if h := kit.Select("", m.Optionv("cmd_parse"), 3); h != "" { - heads = strings.Split(h, " ") - } else if bio.Scan() { - h := bio.Text() - 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", m.Optionv("cmd_parse"), 2))) - for _, v := range heads { - pos = append(pos, strings.Index(h, v)) - } - } - - for bio.Scan() { - if len(pos) > 0 { - for i, v := range pos { - if i == len(pos)-1 { - m.Add("append", heads[i], bio.Text()[v:]) - } else { - m.Add("append", heads[i], bio.Text()[v:pos[i+1]]) - } - } - continue - } - for i, v := range kit.Split(bio.Text(), c, len(heads)) { - m.Add("append", heads[i], v) - } - } - m.Table() - - default: - var data interface{} - if json.Unmarshal(out.Bytes(), &data) == nil { - if b, e := json.MarshalIndent(data, "", " "); e == nil { - m.Echo(string(b)) - break - } - } - m.Echo(out.String()) - } -} -func (cli *CLI) schedule(m *ctx.Message) string { - first, timer := "", int64(1<<50) - for k, v := range m.Confv("timer", "list").(map[string]interface{}) { - val := v.(map[string]interface{}) - if val["action_time"].(int64) < timer && !val["done"].(bool) { - first, timer = k, val["action_time"].(int64) - } - } - cli.Timer.Reset(time.Until(time.Unix(0, timer/int64(m.Confi("time", "unit"))*1000000000))) - return m.Conf("timer", "next", first) -} - -func (cli *CLI) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { - c.Configs["_index"] = &ctx.Config{Name: "_index", Value: []interface{}{}, Help: "_index"} - return &CLI{Context: c} -} -func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server { - return cli -} -func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { - return false -} -func (cli *CLI) Close(m *ctx.Message, arg ...string) bool { - return true -} - -var Index = &ctx.Context{Name: "cli", Help: "管理中心", - Caches: map[string]*ctx.Cache{}, - Configs: map[string]*ctx.Config{ - "runtime": {Name: "runtime", Value: map[string]interface{}{ - "init": []interface{}{"ctx_log", - "ctx_cas", "ctx_ups", "ctx_box", "ctx_dev", - "ctx_app", "ctx_bin", "ctx_root", "ctx_home", - "ctx_type", "ssh_port", "web_port", - }, - "boot": map[string]interface{}{ - "web_port": ":9095", - "ssh_port": ":9090", - "username": "shy", - "version": "2.1", - }, - }, Help: "运行环境, host, init, boot, node, user, work"}, - "system": {Name: "system", Value: map[string]interface{}{ - "timeout": "180s", - "env": map[string]interface{}{}, - "shell": map[string]interface{}{ - "sh": map[string]interface{}{"cmd": "bash"}, - "py": map[string]interface{}{"cmd": "python"}, - "vi": map[string]interface{}{"active": true}, - "top": map[string]interface{}{"active": true}, - "ls": map[string]interface{}{"arg": []interface{}{"-l"}}, - }, - "script": map[string]interface{}{ - "sh": "bash", "shy": "source", "py": "python", - "init": "etc/init.shy", "exit": "etc/exit.shy", - }, - }, Help: "系统环境, shell: path, cmd, arg, dir, env, active, daemon; "}, - "daemon": {Name: "daemon", Value: map[string]interface{}{}, Help: "守护任务"}, - "timer": {Name: "timer", Value: map[string]interface{}{ - "list": map[string]interface{}{}, "next": "", - }, Help: "定时器"}, - - "project": {Name: "project", Value: map[string]interface{}{ - "github": "https://github.com/shylinux/context", - "goproxy": "https://goproxy.cn", - "template": map[string]interface{}{ - "path": "usr/template", - }, - "plugin": map[string]interface{}{ - "path": "src/plugin", "template": "usr/template/plugin", - "list": []interface{}{"local.shy", "index.shy", "index.css", "index.js"}, - }, "script": map[string]interface{}{ - "path": "usr/script", - }, "trash": map[string]interface{}{ - "path": "usr/trash", - }, - }, Help: "项目管理"}, - "compile": {Name: "compile", Value: map[string]interface{}{ - "bench": "src/extend/shy.go", "list": []interface{}{ - map[string]interface{}{"os": "linux", "cpu": "arm"}, - map[string]interface{}{"os": "linux", "cpu": "386"}, - map[string]interface{}{"os": "linux", "cpu": "amd64"}, - map[string]interface{}{"os": "windows", "cpu": "386"}, - map[string]interface{}{"os": "windows", "cpu": "amd64"}, - map[string]interface{}{"os": "darwin", "cpu": "amd64"}, - }, "tmp": "var/tmp/go", "dep": []interface{}{ - "github.com/nfs/termbox-go", - "github.com/gorilla/websocket", - "github.com/go-sql-driver/mysql", - "github.com/redigo/redis", - "github.com/gomarkdown/markdown", - "github.com/skip2/go-qrcode", - "gopkg.in//gomail.v2", - }, - }, Help: "源码编译"}, - "publish": {Name: "publish", Value: map[string]interface{}{ - "path": "usr/publish", "list": map[string]interface{}{ - "boot_sh": "bin/boot.sh", - "zone_sh": "bin/zone.sh", - "user_sh": "bin/user.sh", - "node_sh": "bin/node.sh", - - "init_shy": "etc/init.shy", - "common_shy": "etc/common.shy", - "exit_shy": "etc/exit.shy", - - "template_tar_gz": "usr/template", - "librarys_tar_gz": "usr/librarys", - }, - "script": map[string]interface{}{ - "worker": "usr/publish/hello/local.shy", - "server": "usr/publish/docker/local.shy", - }, - }, Help: "版本发布"}, - "upgrade": {Name: "upgrade", Value: map[string]interface{}{ - "install": []interface{}{"context", "love"}, - "system": []interface{}{"boot.sh", "zone.sh", "user.sh", "node.sh", "init.shy", "common.shy", "exit.shy"}, - "portal": []interface{}{"template.tar.gz", "librarys.tar.gz"}, - "script": []interface{}{"test.php"}, - "list": map[string]interface{}{ - "bench": "bin/bench.new", - - "boot_sh": "bin/boot.sh", - "zone_sh": "bin/zone.sh", - "user_sh": "bin/user.sh", - "node_sh": "bin/node.sh", - - "init_shy": "etc/init.shy", - "common_shy": "etc/common.shy", - "exit_shy": "etc/exit.shy", - - "template_tar_gz": "usr/template.tar.gz", - "librarys_tar_gz": "usr/librarys.tar.gz", - }, - }, Help: "服务升级"}, - "missyou": {Name: "missyou", Value: map[string]interface{}{ - "path": "usr/local/work", "local": "usr/local", - }, Help: "任务管理"}, - "imq": {Name: "imq", Value: map[string]interface{}{ - "data": map[string]interface{}{ - "meta": map[string]interface{}{ - "least": 10, "limit": 100, - "store": "var/tmp/imq.csv", - }, - "list": map[string]interface{}{}, - }, - "topic": map[string]interface{}{ - "hello": []interface{}{ - map[string]interface{}{ - "cmd": "pwd", - }, - map[string]interface{}{ - "cmd": "help", - }, - }, - }, - }, Help: "消息队列"}, - }, - Commands: map[string]*ctx.Command{ - "_init": {Name: "_init", Help: "环境初始化", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - m.Conf("runtime", "host.GOARCH", runtime.GOARCH) - m.Conf("runtime", "host.GOOS", runtime.GOOS) - m.Conf("runtime", "host.pid", os.Getpid()) - - m.Confm("runtime", "init", func(index int, key string) { - if value := os.Getenv(key); value != "" { - m.Conf("runtime", "boot."+key, kit.Select("", value, value != "-")) - } - }) - - if name, e := os.Hostname(); e == nil { - m.Conf("runtime", "boot.hostname", kit.Select(name, os.Getenv("HOSTNAME"))) - } - if user, e := user.Current(); e == nil { - ns := strings.Split(user.Username, "\\") - name := ns[len(ns)-1] - m.Conf("runtime", "boot.username", kit.Select(name, os.Getenv("USER"))) - } - if name, e := os.Getwd(); e == nil { - _, file := path.Split(kit.Select(name, os.Getenv("PWD"))) - ns := strings.Split(file, "\\") - m.Conf("runtime", "boot.pathname", ns[len(ns)-1]) - m.Conf("runtime", "boot.ctx_path", name) - } - return - }}, - "runtime": {Name: "runtime [host|boot|node|user|work [name [value]]]", Help: "运行环境", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if len(arg) == 0 { - m.Cmdy("ctx.config", "runtime") - return - } - - switch arg[0] { - case "system": - mem := &runtime.MemStats{} - runtime.ReadMemStats(mem) - m.Append("NumCPU", runtime.NumCPU()) - m.Append("NumGo", runtime.NumGoroutine()) - m.Append("NumGC", mem.NumGC) - m.Append("other", kit.FmtSize(int64(mem.OtherSys))) - m.Append("stack", kit.FmtSize(int64(mem.StackSys))) - m.Append("heapsys", kit.FmtSize(int64(mem.HeapSys))) - m.Append("heapidle", kit.FmtSize(int64(mem.HeapIdle))) - m.Append("heapinuse", kit.FmtSize(int64(mem.HeapInuse))) - m.Append("heapalloc", kit.FmtSize(int64(mem.HeapAlloc))) - m.Append("objects", mem.HeapObjects) - m.Append("lookups", mem.Lookups) - m.Table() - - default: - if len(arg) == 1 { - m.Cmdy("ctx.config", "runtime", arg[0]) - return - } - - m.Conf("runtime", arg[0], arg[1]) - if arg[0] == "node.route" && m.Confs("runtime", "work.serve") { - m.Conf("runtime", "work.route", arg[1]) - return - } - m.Echo(arg[1]) - } - return - }}, - "system": {Name: "system word...", Help: []string{"调用系统命令, word: 命令", - "cmd_timeout: 命令超时", - "cmd_active(true/false): 是否交互", - "cmd_daemon(true/false): 是否守护", - "cmd_env key value: 环境变量", - "cmd_dir: 工作目录", - "cmd_log: 输出日志", - "cmd_error: 输出错误", - "cmd_temp arg...: 缓存结果", - "cmd_parse format|json|csv|cli|cut [count sep headers]: 解析结果", - "cmd_headers", - }, Form: map[string]int{ - "cmd_timeout": 1, - "cmd_active": 1, - "cmd_daemon": 1, - "cmd_dir": 1, - "cmd_env": 2, - "cmd_log": 1, - "cmd_temp": -1, - "cmd_parse": 4, - "cmd_error": 0, - "cmd_select": -1, - "cmd_headers": 2, - "app_log": 1, - }, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - // 管道参数 - for _, v := range m.Meta["result"] { - if strings.TrimSpace(v) != "" { - arg = append(arg, v) - } - } - - // 命令配置 - conf := m.Confm("system", []string{"shell", arg[0]}) - if as := strings.Split(arg[0], "."); conf == nil && len(as) > 0 { - if conf = m.Confm("system", []string{"shell", as[len(as)-1]}); conf != nil { - arg = append([]string{kit.Format(kit.Chain(conf, "cmd"))}, arg...) - } - } - - // 命令替换 - args := []string{kit.Select(arg[0], kit.Format(kit.Chain(conf, "cmd")))} - if list, ok := kit.Chain(conf, "arg").([]interface{}); ok { - for _, v := range list { - args = append(args, m.Parse(v)) - } - } - - // 命令解析 - args = append(args, arg[1:]...) - cmd := exec.Command(args[0], args[1:]...) - cmd.Path = kit.Select(cmd.Path, kit.Format(kit.Chain(conf, "path"))) - if cmd.Path != "" || len(cmd.Args) > 0 { - m.Log("info", "cmd %v %v", cmd.Path, cmd.Args) - } - - // 工作目录 - cmd.Dir = kit.Select(kit.Chains(conf, "dir"), m.Option("cmd_dir")) - if cmd.Dir != "" { - os.MkdirAll(cmd.Dir, 0777) - m.Log("info", "dir %v", cmd.Dir) - } - - // 环境变量 - m.Confm("system", "env", func(key string, value string) { - cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", key, m.Parse(value))) - }) - kit.Structm(kit.Chain(conf, "env"), func(key string, value string) { - cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", key, m.Parse(value))) - }) - for i := 0; i < len(m.Meta["cmd_env"])-1; i += 2 { - cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", m.Meta["cmd_env"][i], m.Parse(m.Meta["cmd_env"][i+1]))) - } - if len(cmd.Env) > 0 { - m.Log("info", "env %v", cmd.Env) - } - - // 交互命令 - if m.Options("cmd_active") || kit.Right(conf["active"]) { - cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr - if e := cmd.Start(); e != nil { - m.Echo("error: ").Echo("%s\n", e) - } else if e := cmd.Wait(); e != nil { - m.Echo("error: ").Echo("%s\n", e) - } - return - } - - // 守护命令 - if m.Options("cmd_daemon") || kit.Right(conf["daemon"]) { - // 创建日志 - if m.Options("cmd_log") { - log := fmt.Sprintf("var/log/%s.log", m.Option("cmd_log")) - if e := os.Rename(log, fmt.Sprintf("var/log/%s_%s.log", m.Option("cmd_log"), m.Time("2006_0102_1504"))); e != nil { - m.Log("info", "mv %s error %s", log, e) - } - if l, e := os.Create(log); m.Assert(e) { - cmd.Stdout = l - } - - err := fmt.Sprintf("var/log/%s.err", m.Option("cmd_log")) - if e := os.Rename(err, fmt.Sprintf("var/log/%s_%s.err", m.Option("cmd_log"), m.Time("2006_0102_1504"))); e != nil { - m.Log("info", "mv %s error %s", err, e) - } - if l, e := os.Create(err); m.Assert(e) { - cmd.Stderr = l - } - } - - // 守护列表 - h, _ := kit.Hash("uniq") - m.Conf("daemon", h, map[string]interface{}{ - "create_time": m.Time(), "log": kit.Select(m.Option("cmd_log"), m.Option("app_log")), "sub": cmd, - }) - m.Echo(h) - - // 执行命令 - m.Gos(m, func(m *ctx.Message) { - if e := cmd.Start(); e != nil { - m.Log("warn", "%v", e).Echo("error: ").Echo("%s\n", e) - } else if e := cmd.Wait(); e != nil { - m.Log("warn", "%v", e).Echo("error: ").Echo("%s\n", e) - } - m.Conf("daemon", []string{h, "finish_time"}, time.Now().Format(m.Conf("time", "format"))) - }) - return e - } - - // 管道命令 - wait := make(chan bool, 1) - m.Gos(m, func(m *ctx.Message) { - defer func() { wait <- true }() - - out := bytes.NewBuffer(make([]byte, 0, 1024)) - err := bytes.NewBuffer(make([]byte, 0, 1024)) - cmd.Stdout = out - cmd.Stderr = err - - // 运行命令 - if e := cmd.Run(); e != nil { - m.Echo("error: ").Echo(kit.Select(e.Error(), err.String())) - return - } - - // 输出错误 - if m.Has("cmd_error") { - m.Echo(err.String()) - return - } - - // 解析结果 - if format(m, out); m.Has("cmd_select") { - m.Cmd("select", m.Meta["cmd_select"]) - } - - // 缓存结果 - if m.Options("cmd_temp") { - m.Put("option", "data", out.String()).Cmdy("mdb.temp", "script", strings.Join(arg, " "), "data", "data", m.Meta["cmd_temp"]) - } - }) - - // 命令超时 - timeout := kit.Duration(kit.Select(m.Conf("system", "timeout"), kit.Select(kit.Chains(conf, "timeout"), m.Option("cmd_timeout")))) - select { - case <-time.After(timeout): - m.Log("warn", "%s: %v timeout", arg[0], timeout) - m.Echo("%s: %v timeout", arg[0], timeout) - cmd.Process.Kill() - case <-wait: - } - return - }}, - "daemon": {Name: "daemon", Help: "守护任务", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - pid := "" - if len(arg) > 0 && m.Confs("daemon", arg[0]) { - pid, arg = arg[0], arg[1:] - } - - if len(arg) == 0 { - m.Confm("daemon", func(key string, info map[string]interface{}) { - if pid != "" && key != pid { - return - } - - m.Add("append", "key", key) - m.Add("append", "log", info["log"]) - m.Add("append", "create_time", info["create_time"]) - m.Add("append", "finish_time", info["finish_time"]) - - if cmd, ok := info["sub"].(*exec.Cmd); ok { - info["pid"] = cmd.Process.Pid - info["cmd"] = kit.Select(cmd.Args[0], cmd.Args, 1) - if cmd.ProcessState != nil { - info["str"] = cmd.ProcessState.String() - } - } - m.Add("append", "pid", kit.Format(info["pid"])) - m.Add("append", "cmd", kit.Format(info["cmd"])) - m.Add("append", "str", kit.Format(info["str"])) - }) - m.Table() - return - } - - if pid != "" { - if cmd, ok := m.Confm("daemon", pid)["sub"].(*exec.Cmd); ok { - switch arg[0] { - case "stop": - m.Echo("%s", cmd.Process.Signal(os.Interrupt)) - default: - m.Echo("%v", cmd) - } - } - return - } - return - }}, - "sleep": {Name: "sleep time", Help: "睡眠, time(ns/us/ms/s/m/h): 时间值(纳秒/微秒/毫秒/秒/分钟/小时)", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if d, e := time.ParseDuration(arg[0]); m.Assert(e) { - m.Log("info", "sleep %v", d) - time.Sleep(d) - m.Log("info", "sleep %v done", d) - } - return - }}, - "timer": {Name: "timer [begin time] [repeat] [order time] time cmd", Help: "定时任务", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if cli, ok := c.Server.(*CLI); m.Assert(ok) { - // 定时列表 - if len(arg) == 0 { - m.Confm("timer", "list", func(key string, timer map[string]interface{}) { - m.Add("append", "key", key) - m.Add("append", "action_time", time.Unix(0, timer["action_time"].(int64)/int64(m.Confi("time", "unit"))*1000000000).Format(m.Conf("time", "format"))) - m.Add("append", "order", timer["order"]) - m.Add("append", "time", timer["time"]) - m.Add("append", "cmd", timer["cmd"]) - m.Add("append", "msg", timer["msg"]) - m.Add("append", "results", kit.Format(timer["result"])) - }) - m.Table() - return - } - - switch arg[0] { - case "stop": - if timer := m.Confm("timer", "list", arg[1]); timer != nil { - timer["stop"] = true - } - cli.schedule(m) - return - case "start": - if timer := m.Confm("timer", "list", arg[1]); timer != nil { - timer["stop"] = false - } - cli.schedule(m) - return - case "delete": - delete(m.Confm("timer", "list"), arg[1]) - cli.schedule(m) - return - } - - now := m.Sess("cli").Cmd("time").Appendi("timestamp") - begin := now - if len(arg) > 0 && arg[0] == "begin" { - begin, arg = int64(m.Sess("cli").Cmd("time", arg[1]).Appendi("timestamp")), arg[2:] - } - - repeat := false - if len(arg) > 0 && arg[0] == "repeat" { - repeat, arg = true, arg[1:] - } - - order := "" - if len(arg) > 0 && arg[0] == "order" { - order, arg = arg[1], arg[2:] - } - - action := int64(m.Sess("cli").Cmd("time", begin, order, arg[0]).Appendi("timestamp")) - - // 创建任务 - hash := m.Sess("aaa").Cmd("hash", "timer", arg, "time", "rand").Result(0) - m.Confv("timer", []string{"list", hash}, map[string]interface{}{ - "create_time": now, - "begin_time": begin, - "action_time": action, - "repeat": repeat, - "order": order, - "done": false, - "stop": false, - "time": arg[0], - "cmd": arg[1:], - "msg": 0, - "result": "", - }) - - if cli.Timer == nil { // 创建时间队列 - cli.Timer = time.NewTimer((time.Duration)((action - now) / int64(m.Confi("time", "unit")) * 1000000000)) - m.GoLoop(m, func(m *ctx.Message) { - select { - case <-cli.Timer.C: - if m.Conf("timer", "next") == "" { - break - } - - if timer := m.Confm("timer", []string{"list", m.Conf("timer", "next")}); timer != nil && !kit.Right(timer["stop"]) { - m.Log("info", "timer %s %v", m.Conf("timer", "next"), timer["cmd"]) - - msg := m.Cmd("nfs.source", timer["cmd"]) - timer["result"] = msg.Meta["result"] - timer["msg"] = msg.Code() - - if timer["repeat"].(bool) { - timer["action_time"] = int64(m.Sess("cli").Cmd("time", msg.Time(), timer["order"], timer["time"]).Appendi("timestamp")) - } else { - timer["done"] = true - } - } - - cli.schedule(m) - } - }) - } - - // 调度任务 - cli.schedule(m) - m.Echo(hash) - } - return - }}, - "time": {Name: "time when [begin|end|yestoday|tommorow|monday|sunday|first|last|new|eve] [offset]", - Help: "查看时间, when: 输入的时间戳, 剩余参数是时间偏移", - Form: map[string]int{"time_format": 1, "time_close": 1}, - Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - format := kit.Select(m.Conf("time", "format"), m.Option("time_format")) - t, stamp := time.Now(), true - if len(arg) > 0 { - if arg[0] == "show" { - stamp = false - } else if i, e := strconv.ParseInt(arg[0], 10, 64); e == nil { - t, stamp, arg = time.Unix(int64(i/int64(m.Confi("time", "unit"))), 0), false, arg[1:] - } else if n, e := time.ParseInLocation(format, arg[0], time.Local); e == nil { - t, arg = n, arg[1:] - } else { - for _, v := range []string{"01-02", "2006-01-02", "15:04:05", "15:04"} { - if n, e := time.ParseInLocation(v, arg[0], time.Local); e == nil { - t, arg = n, arg[1:] - break - } - } - } - } - - if len(arg) > 0 { - switch arg[0] { - case "begin": - d, e := time.ParseDuration(fmt.Sprintf("%dh%dm%ds", t.Hour(), t.Minute(), t.Second())) - m.Assert(e) - t, arg = t.Add(-d), arg[1:] - case "end": - d, e := time.ParseDuration(fmt.Sprintf("%dh%dm%ds%dns", t.Hour(), t.Minute(), t.Second(), t.Nanosecond())) - m.Assert(e) - t, arg = t.Add(time.Duration(24*time.Hour)-d), arg[1:] - if kit.Select(m.Conf("time", "close"), m.Option("time_close")) == "close" { - t = t.Add(-time.Second) - } - case "yestoday": - t, arg = t.Add(-time.Duration(24*time.Hour)), arg[1:] - case "tomorrow": - t, arg = t.Add(time.Duration(24*time.Hour)), arg[1:] - case "monday": - d, e := time.ParseDuration(fmt.Sprintf("%dh%dm%ds", int((t.Weekday()-time.Monday+7)%7)*24+t.Hour(), t.Minute(), t.Second())) - m.Assert(e) - t, arg = t.Add(-d), arg[1:] - case "sunday": - d, e := time.ParseDuration(fmt.Sprintf("%dh%dm%ds", int((t.Weekday()-time.Monday+7)%7)*24+t.Hour(), t.Minute(), t.Second())) - m.Assert(e) - t, arg = t.Add(time.Duration(7*24*time.Hour)-d), arg[1:] - if kit.Select(m.Conf("time", "close"), m.Option("time_close")) == "close" { - t = t.Add(-time.Second) - } - case "first": - t, arg = time.Date(t.Year(), t.Month(), 1, 0, 0, 0, 0, time.Local), arg[1:] - case "last": - month, year := t.Month()+1, t.Year() - if month >= 13 { - month, year = 1, year+1 - } - t, arg = time.Date(year, month, 1, 0, 0, 0, 0, time.Local), arg[1:] - if kit.Select(m.Conf("time", "close"), m.Option("time_close")) == "close" { - t = t.Add(-time.Second) - } - case "new": - t, arg = time.Date(t.Year(), 1, 1, 0, 0, 0, 0, time.Local), arg[1:] - case "eve": - t, arg = time.Date(t.Year()+1, 1, 1, 0, 0, 0, 0, time.Local), arg[1:] - if kit.Select(m.Conf("time", "close"), m.Option("time_close")) == "close" { - t = t.Add(-time.Second) - } - case "": - arg = arg[1:] - } - } - - if len(arg) > 0 { - if d, e := time.ParseDuration(arg[0]); e == nil { - t, arg = t.Add(d), arg[1:] - } - } - - m.Append("datetime", t.Format(format)) - m.Append("timestamp", t.Unix()*int64(m.Confi("time", "unit"))) - - if stamp { - m.Echo("%d", t.Unix()*int64(m.Confi("time", "unit"))) - } else { - m.Echo(t.Format(format)) - } - return - }}, - "date": {Name: "date", Help: "日历", Form: map[string]int{"space": 1, "format": 2, "count": 1, "nature": 1, "cmd": -1}, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - show := map[int]string{0: "周日", 1: "周一", 2: "周二", 3: "周三", 4: "周四", 5: "周五", 6: "周六"} - - space := m.Options("space") - format, format_time := "", "" - if m.Has("format") { - format, format_time = kit.Select("%s", m.Meta["format"], 0), kit.Select("20060102", m.Meta["format"], 1) - } - - today := time.Now() - now := kit.Times(m.Cmd("cli.time", arg).Append("datetime")) - n := kit.Int(kit.Select("1", m.Option("count"))) - if m.Has("nature") { - n = 0 - nature := kit.Times(m.Option("nature")) - for cur := now; cur.Before(nature); cur = cur.AddDate(0, 1, 0) { - n++ - } - if now.Day() > nature.Day() { - n++ - } - } - - cur := now - for i := 0; i < n; i, now = i+1, now.AddDate(0, 1, 0) { - begin := time.Unix(now.Unix()-int64(now.Day()-1)*24*3600, 0) - last := time.Unix(begin.Unix()-int64(begin.Weekday())*24*3600, 0) - cur = last - - if last.Month() != now.Month() { - for month := cur.Month(); cur.Month() == month; cur = cur.AddDate(0, 0, 1) { - if space || i == 0 { - m.Push(show[int(cur.Weekday())], "") - } - } - } - for month := cur.Month(); cur.Month() == month; cur = cur.AddDate(0, 0, 1) { - data := fmt.Sprintf("%d", cur.Day()) - if cur.Year() == today.Year() && cur.YearDay() == today.YearDay() { - data = fmt.Sprintf(">%d<", cur.Day()) - } - if cur.Day() == 1 { - if cur.Month() == 1 { - data = fmt.Sprintf("%d年", cur.Year()) - } else { - data = fmt.Sprintf("%d月", cur.Month()) - } - } - if format != "" { - data = fmt.Sprintf(format, cur.Format(format_time), data) - } - m.Push(show[int(cur.Weekday())], data) - } - if space || i == n-1 { - for ; cur.Weekday() > 0; cur = cur.AddDate(0, 0, 1) { - m.Push(show[int(cur.Weekday())], "") - } - } - } - - m.Table() - return - }}, - "proc": {Name: "proc", Help: "进程管理", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - m.Cmdy("cli.system", "ps", kit.Select("ax", arg, 0), "cmd_parse", "cut") - if len(arg) > 1 { - m.Cmd("select", "reg", "COMMAND", arg[1]) - } - return - }}, - "quit": {Name: "quit code", Help: "停止服务", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - m.Conf("runtime", "boot.count", m.Confi("runtime", "boot.count")+1) - code := kit.Select("0", arg, 0) - switch code { - case "0": - m.Cmd("nfs.source", m.Conf("system", "script.exit")) - m.Echo("quit") - - case "1": - if m.Option("bio.modal") != "action" { - m.Cmd("nfs.source", m.Conf("system", "script.exit")) - m.Echo("restart") - } - - case "2": - m.Echo("term") - } - - m.Append("time", m.Time()) - m.Append("code", code) - m.Echo(", wait 1s\n").Table() - m.Gos(m, func(m *ctx.Message) { - m.Cmd("ctx._exit") - time.Sleep(time.Second) - os.Exit(kit.Int(code)) - }) - return - }}, - "_exit": {Name: "_exit", Help: "退出命令", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - m.Confm("daemon", func(key string, info map[string]interface{}) { - m.Cmd("cli.daemon", key, "stop") - }) - return - }}, - - "project": {Name: "project init|stat|stats|trend|trends|submit|review|plugin [args...]", - Help: "项目管理", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - switch arg[0] { - case "init": - if _, e := os.Stat(".git"); e == nil { - // 更新代码 - m.Cmdp(0, []string{"git update"}, []string{"web.code.git", ""}, [][]string{ - []string{"stash"}, []string{"pull"}, []string{"stash", "pop"}, - }) - - // 代码状态 - m.Cmdy("web.code.git", "", "status") - return e - } - - // 创建项目 - m.Cmdp(0, []string{"git init"}, []string{"web.code.git", ""}, [][]string{ - []string{"init"}, []string{"remote", "add", kit.Select("origin", arg, 1), kit.Select(m.Conf("project", "github"), arg, 2)}, - []string{"stash"}, []string{"pull"}, []string{"checkout", "-f", "master"}, []string{"stash", "pop"}, - }) - - // 下载依赖 - list := [][]string{} - m.Confm("compile", "dep", func(index int, value string) { - list = append(list, []string{value}) - }) - m.Cmdp(0, []string{"go build"}, []string{"cli.system", "go", "get"}, list) - - case "stat": - // 代码统计 - m.Cmdy("nfs.dir", "src", "dir_deep", "dir_type", "file", "dir_sort", "line", "int_r") - - case "stats": - // 代码统计 - m.Cmdy("nfs.dir", kit.Select("src", arg, 1), "dir_deep", "dir_type", "file", "dir_sort", "line", "int_r", "dir_select", "group", "") - - case "trend": - // 提交记录 - m.Cmdy("web.code.git", "", "sum", arg[1:]) - - case "trends": - // 提交记录 - if len(arg) == 1 { - arg = append(arg, "2017-11-01") - } - m.Cmdy("web.code.git", "", "sum", "total", arg[1:]) - - case "submit": - // 提交代码 - if len(arg) > 1 { - m.Cmdp(0, []string{"git submit"}, []string{"web.code.git", ""}, [][]string{ - []string{"commit", arg[1]}, []string{"push"}, - }) - } - // 提交记录 - m.Cmdy("web.code.git", "", "log", "--stat", "-n", "3") - - case "review": - // 代码修改 - m.Cmdy("web.code.git", "", "diff") - - case "plugin": - // 查看插件 - if arg = arg[1:]; len(arg) == 0 { - m.Cmdy("nfs.dir", m.Conf("project", "plugin.path"), "time", "line", "name") - break - } - fallthrough - default: - m.Option("name", arg[0]) - m.Option("help", kit.Select("plugin", arg, 1)) - m.Cmdy("nfs.template", path.Join(m.Conf("project", "plugin.path"), arg[0])+"/", path.Join(m.Conf("project", "plugin.template"))+"/") - } - return - }}, - "compile": {Name: "compile all|self|linux|windows|darwin|restart|plugin", Help: "项目编译", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - switch arg[0] { - case "all": - // 所有版本 - list := [][]string{} - m.Confm("compile", "list", func(index int, value map[string]interface{}) { - list = append(list, []string{kit.Format(value["os"]), kit.Format(value["cpu"])}) - }) - m.Cmdp(0, []string{"go build"}, []string{"cli.compile"}, list) - - case "self": - // 编译版本 - m.Cmd("cli.version", "create") - - // 编译项目 - if m.Cmdy("cli.compile", ""); m.Has("bin") { - target := path.Join(kit.Select(os.Getenv("GOBIN"), ""), m.Conf("runtime", "boot.ctx_app")) - os.Remove(target) - m.Append("bin", m.Cmdx("nfs.copy", target, m.Append("bin"))) - os.Chmod(target, 0777) - m.Cmd("cli.quit", 1) - } - - case "restart": - // 重启项目 - m.Cmdy("cli.quit", "1") - - case "plugin": - // 插件列表 - if arg = arg[1:]; len(arg) == 0 { - m.Cmdy("nfs.dir", m.Conf("publish", "path"), "dir_deep", "dir_reg", ".*\\.so", "time", "size", "hashs", "path") - break - } - fallthrough - default: - // 编译插件 - p, q, o := path.Join(m.Conf("project", "plugin.path"), arg[0], "index.go"), "", []string{} - if _, e := os.Stat(p); e == nil { - q = path.Join(m.Conf("publish", "path"), arg[0], "index.so") - o = append(o, "-buildmode=plugin") - arg = arg[1:] - } - - // 目标系统 - goos := kit.Select(m.Conf("runtime", "host.GOOS"), arg, 0) - arch := kit.Select(m.Conf("runtime", "host.GOARCH"), arg, 1) - - // 编译环境 - tmp := path.Join(kit.Pwd(), m.Conf("compile", "tmp")) - os.MkdirAll(m.Conf("compile", "tmp"), 0777) - env := []string{ - "cmd_env", "GOOS", goos, "cmd_env", "GOARCH", arch, - "cmd_env", "GOTMPDIR", tmp, "cmd_env", "GOCACHE", tmp, - "cmd_env", "GOPATH", m.Conf("runtime", "boot.ctx_home") + string(os.PathListSeparator) + os.Getenv("GOPATH"), - "cmd_env", "PATH", os.Getenv("PATH"), - } - - // 编译目标 - if q == "" { - q = path.Join(m.Conf("publish", "path"), strings.Join([]string{m.Conf("runtime", "boot.ctx_app"), goos, arch}, ".")) - p = m.Cmdx("nfs.path", m.Conf("compile", "bench")) - } - - // 编译项目 - if m.Cmdy("cli.system", env, "go", "build", o, "-o", q, p); m.Result(0) == "" { - m.Append("time", m.Time()) - m.Append("cost", m.Format("cost")) - m.Append("hash", m.Cmdx("nfs.hash", q)[:8]) - m.Append("bin", q) - m.Table() - } - } - return - }}, - "publish": {Name: "publish [args...]", Help: "项目发布", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if len(arg) == 0 { - m.Confm("publish", "list", func(key string, value string) { - arg = append(arg, strings.Replace(key, "_", ".", -1)) - }) - } - - // 发布插件 - p := path.Join(m.Conf("project", "plugin.path"), arg[0]) - q := path.Join(m.Conf("publish", "path"), arg[0]) - if _, e := os.Stat(p); e == nil && m.Assert(os.MkdirAll(q, 0777)) { - m.Confm("project", "plugin.list", func(index int, value string) { - m.Cmd("nfs.copy", path.Join(q, value), path.Join(p, value)) - }) - for _, v := range arg[1:] { - m.Cmd("nfs.copy", path.Join(q, v), path.Join(p, v)) - } - m.Cmd("cli.system", "tar", "-zcf", q+".tar.gz", "-C", m.Conf("publish", "path"), arg[0]) - m.Cmdy("nfs.dir", q, "time", "size", "hashs", "path", "dir_sort", "path", "str") - return e - } - - // 发布文件 - for _, key := range arg { - p := m.Cmdx("nfs.path", m.Conf("publish", []string{"list", kit.Key(key)})) - q := path.Join(m.Conf("publish", "path"), key) - if s, e := os.Stat(p); e == nil { - if s.IsDir() { - m.Cmd("cli.system", "tar", "-zcf", q, "-C", path.Dir(p), path.Base(p)) - } else { - m.Cmd("nfs.copy", q, p) - } - - m.Push("time", s.ModTime()) - m.Push("size", s.Size()) - m.Push("hash", kit.Hashs(p)[:8]) - m.Push("file", q) - } - } - m.Sort("file").Table() - return - }}, - "upgrade": {Name: "upgrade install|bench|system|portal|script|plugin|restart|package|project", Help: "服务升级", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if len(arg) == 0 { - m.Cmdy("ctx.config", "upgrade") - return - } - - switch arg[0] { - case "install": - m.Cmd("cli.upgrade", "system") - m.Cmd("cli.upgrade", "portal") - m.Confm("upgrade", "install", func(index int, value string) { - m.Cmd("cli.upgrade", "package", value) - }) - - case "script": - // 脚本列表 - if len(arg) == 1 { - m.Cmdy("nfs.dir", m.Conf("project", "script.path"), "time", "line", "hashs", "path") - break - } - - // 局部脚本 - miss := "" - if len(arg) > 2 { - miss, arg = arg[1], arg[1:] - } - // 下载脚本 - for _, v := range arg[1:] { - m.Cmdy("web.get", "dev", fmt.Sprintf("publish/%s", v), "upgrade", "script", - "missyou", miss, "save", path.Join(m.Conf("project", "script.path"), v)) - } - - case "plugin": - // 模块列表 - if arg = arg[1:]; len(arg) == 0 { - m.Cmdy("cli.context") - break - } - - // 加载模块 - msg := m.Find(arg[0], false) - if p, e := plugin.Open(path.Join(m.Conf("publish", "path"), arg[0], "index.so")); e == nil { - if s, e := p.Lookup("Index"); m.Assert(e) { - t, _ := p.Lookup("Target") - tt, _ := t.(ctx.Server) - if len(arg) > 1 { - c = m.Find(arg[1], true).Target() - } - msg = m.Spawn(c.Register(*(s.(**ctx.Context)), tt, arg[0]).Begin(m, arg[1:]...)).Cmd("_init", arg[1:]) - m.Log("info", "plugin %v", msg.Cap("module")) - } - } else { - m.Log("warn", "plugin %v %v", arg[0], e) - } - - // 查找模块 - if msg == nil { - m.Log("info", "not find %s", arg[0]) - m.Start(arg[0], "shy") - msg = m - } - - // 查找脚本 - p := m.Cmdx("nfs.path", path.Join(msg.Conf("project", "plugin.path"), arg[0], "index.shy")) - if p == "" { - p = m.Cmdx("nfs.path", path.Join(msg.Conf("publish", "path"), arg[0], "index.shy")) - } - if p == "" { - p = m.Cmdx("nfs.hash", m.Cmdx("web.get", "dev", fmt.Sprintf("publish/%s", arg[0]), - "GOARCH", m.Conf("runtime", "host.GOARCH"), - "GOOS", m.Conf("runtime", "host.GOOS"), - "upgrade", "plugin")) - } - - // 加载脚本 - if p != "" { - msg.Target().Configs["_index"] = &ctx.Config{Name: "_index", Value: []interface{}{}} - msg.Optionv("bio.ctx", msg.Target()) - msg.Cmdy("nfs.source", p) - msg.Confv("ssh.componet", arg[0], msg.Confv("_index")) - } - - // 组件列表 - m.Confm("ssh.componet", arg[0], func(index int, value map[string]interface{}) { - m.Push("index", index) - m.Push("name", value["name"]) - m.Push("help", value["help"]) - m.Push("ctx", value["ctx"]) - m.Push("cmd", value["cmd"]) - }) - m.Table() - - case "restart": - m.Cmdy("cli.quit", "1") - - case "package": - name := arg[1] + ".tar.gz" - p := path.Join(m.Conf("publish", "path"), name) - - m.Cmd("web.get", "dev", fmt.Sprintf("publish/%s", name), "save", p, - "GOARCH", m.Conf("runtime", "host.GOARCH"), "GOOS", m.Conf("runtime", "host.GOOS")) - - m.Cmd("cli.system", "tar", "-xvf", p, "-C", path.Dir(p)) - - case "project": - m.Cmd("cli.project", "init") - m.Cmd("cli.compile", "all") - m.Cmd("cli.publish") - - default: - restart := false - for _, link := range kit.View([]string{arg[0]}, m.Confm("upgrade")) { - file := kit.Select(link, m.Conf("upgrade", []string{"list", strings.Replace(link, ".", "_", -1)})) - - // 下载文件 - m.Cmd("web.get", "dev", fmt.Sprintf("publish/%s", link), - "GOARCH", m.Conf("runtime", "host.GOARCH"), - "GOOS", m.Conf("runtime", "host.GOOS"), - "upgrade", arg[0], "save", file) - - // 执行文件 - if strings.HasPrefix(file, "bin/") { - if m.Cmd("cli.system", "chmod", "a+x", file); link == "bench" { - file = "bin/" + m.Conf("runtime", "boot.ctx_app") - m.Cmd("cli.system", "mv", file, file+m.Time("_20060102_150405")) - m.Cmd("cli.system", "mv", m.Conf("upgrade", "list.bench"), file) - } - restart = true - } - - // 输出信息 - m.Push("time", m.Time()) - m.Push("cost", m.Format("cost")) - m.Push("hash", kit.Hashs(file)[:8]) - m.Push("file", file) - - // 压缩文件 - if strings.HasSuffix(link, ".tar.gz") { - m.Cmd("cli.system", "tar", "-xvf", file, "-C", path.Dir(file)) - os.Remove(file) - } - } - - // 重启服务 - if m.Table(); restart { - m.Cmd("cli.quit", 1) - } - } - return - }}, - "missyou": {Name: "missyou [name [topic|action]]", Help: "任务管理", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - // 任务列表 - if len(arg) == 0 || arg[0] == "" { - m.Cmd("nfs.dir", m.Conf("missyou", "path"), "time", "name").Table(func(value map[string]string) { - name := strings.TrimSuffix(value["name"], "/") - m.Push("create_time", value["time"]) - m.Push("you", name) - m.Push("status", kit.Select("stop", "start", m.Confs("ssh.node", name))) - }) - m.Sort("you", "str_r").Sort("status").Table() - return - } - - // 任务命名 - if !strings.Contains(arg[0], "-") { - arg[0] = m.Time("20060102-") + arg[0] - } - - // 任务管理 - if m.Option("dream", arg[0]); m.Confs("ssh.node", arg[0]) { - switch kit.Select("", arg, 1) { - case "stop": - m.Cmdy("ssh._route", arg[0], "cli.quit", 0) - default: - m.Echo(arg[0]) - } - return - } - - // 启动目录 - p := path.Join(m.Conf("missyou", "path"), arg[0]) - m.Assert(os.MkdirAll(p, 0777)) - - // 启动参数 - args := []string{ - "daemon", - "cmd_dir", p, - "cmd_daemon", "true", - "cmd_env", "PATH", os.Getenv("PATH"), - "cmd_env", "ctx_home", m.Conf("runtime", "boot.ctx_home"), - "cmd_env", "ctx_type", m.Option("topic", kit.Select("index", arg, 1)), - "cmd_env", "ctx_ups", fmt.Sprintf("127.0.0.1%s", m.Conf("runtime", "boot.ssh_port")), - "cmd_env", "ctx_box", fmt.Sprintf("http://127.0.0.1%s", m.Conf("runtime", "boot.web_port")), - "cmd_env", "ctx_bin", m.Conf("runtime", "boot.ctx_bin"), - } - - // 启动服务 - m.Cmdy("cli.system", path.Join(m.Conf("runtime", "boot.ctx_home"), "bin/node.sh"), "start", args) - if share := m.Cmdx("web.code.dream", "init", arg[0]); share != "" { - m.Cmd("nfs.save", path.Join(p, m.Conf("missyou", "local"), "share.txt"), share) - } - return - }}, - "version": {Name: "version", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if len(arg) == 0 { - types := reflect.TypeOf(version) - value := reflect.ValueOf(version) - for i := 0; i < types.NumField(); i++ { - key := types.Field(i) - val := value.Field(i) - m.Add("append", "name", key.Name) - m.Add("append", "type", key.Type.Name()) - m.Add("append", "value", fmt.Sprintf("%v", val)) - } - - m.Table() - return - } - - m.Option("time", m.Time()) - m.Option("host", m.Conf("runtime", "node.route")) - m.Option("self", version.self+1) - m.Cmdy("nfs.template", "force", path.Join(m.Conf("runtime", "boot.ctx_home"), "src/contexts/cli/version.go"), path.Join(m.Conf("project", "template.path"), "version/")) - return - }}, - - "imq": {Name: "imq cmd", Help: "消息队列", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - m.Grow("imq", "data", map[string]interface{}{ - "time": m.Time(), "cmd": arg, - }) - if imq, ok := m.Confv("imq", "work").(*IMQ); ok { - imq.q <- true - return - } - - imq := &IMQ{make(chan bool, 10)} - imq.q <- true - - m.Confv("imq", imq) - m.Gos(m.Spawn(), func(msg *ctx.Message) { - for <-imq.q { - m.Option("cache.offend", 0) - m.Option("cache.limit", m.Confi("imq", "meta.count")-m.Confi("imq", "meta.current")+1) - m.Grows("imq", "data", func(meta map[string]interface{}, index int, value map[string]interface{}) { - m.Log("info", "imq %d %v", index, value) - if cmd := kit.Trans(value["cmd"]); m.Confm("imq", []string{"topic", cmd[0]}, func(index int, value map[string]interface{}) { - m.Cmd(value["cmd"], cmd[1:]) - }) == nil { - m.Cmd(cmd) - } - }) - } - }) - return - }}, - }, -} - -type IMQ struct { - q chan bool -} - -func init() { - ctx.Index.Register(Index, &CLI{Context: Index}) -} diff --git a/usr/local/honor/src/contexts/cli/version.go b/usr/local/honor/src/contexts/cli/version.go deleted file mode 100644 index 6307dd27..00000000 --- a/usr/local/honor/src/contexts/cli/version.go +++ /dev/null @@ -1,11 +0,0 @@ -package cli - -var version = struct { - init []string - time string - host string - self int -}{ - []string{"2017-11-01 01:02:03", "2019-07-13 18:02:21"}, - `2019-11-29 12:39:40`, `mac`, 658, -} diff --git a/usr/local/honor/src/contexts/ctx/cgi.go b/usr/local/honor/src/contexts/ctx/cgi.go deleted file mode 100644 index 94d01808..00000000 --- a/usr/local/honor/src/contexts/ctx/cgi.go +++ /dev/null @@ -1,240 +0,0 @@ -package ctx - -import ( - "text/template" - - "bytes" - "io" - "path" - "strings" - "toolkit" -) - -func index(name string, arg ...interface{}) interface{} { - if len(arg) == 0 { - return "" - } - - switch m := arg[0].(type) { - case *Message: - if len(arg) == 1 { - return m.Meta[name] - } - - switch value := arg[1].(type) { - case int: - if 0 <= value && value < len(m.Meta[name]) { - return m.Meta[name][value] - } - case string: - if len(arg) == 2 { - if name == "option" { - return m.Optionv(value) - } else { - return m.Append(value) - } - } - - switch val := arg[2].(type) { - case int: - switch list := m.Optionv(value).(type) { - case []string: - if 0 <= val && val < len(list) { - return list[val] - } - case []interface{}: - if 0 <= val && val < len(list) { - return list[val] - } - } - } - } - case map[string][]string: - if len(arg) == 1 { - return m[name] - } - - switch value := arg[1].(type) { - case int: - return m[name][value] - case string: - if len(arg) == 2 { - return m[value] - } - switch val := arg[2].(type) { - case int: - return m[value][val] - } - } - case []string: - if len(arg) == 1 { - return m - } - switch value := arg[1].(type) { - case int: - return m[value] - } - default: - return m - } - return "" -} - -var CGI = template.FuncMap{ - "options": func(arg ...interface{}) string { - switch value := index("option", arg...).(type) { - case string: - return value - case []string: - return strings.Join(value, "") - } - return "" - }, - "option": func(arg ...interface{}) interface{} { - return index("option", arg...) - }, - "conf": func(arg ...interface{}) interface{} { - switch m := arg[0].(type) { - case *Message: - switch c := arg[1].(type) { - case string: - if len(arg) == 2 { - return m.Confv(c) - } - if len(arg) == 3 { - return m.Confv(c, arg[2]) - } - } - } - return nil - }, - "cmd": func(arg ...interface{}) interface{} { - switch m := arg[0].(type) { - case *Message: - switch c := arg[1].(type) { - case string: - return m.Cmd(c, arg[2:]) - } - } - return nil - }, - "appends": func(arg ...interface{}) interface{} { - switch value := index("append", arg...).(type) { - case string: - return value - case []string: - return strings.Join(value, "") - } - return "" - }, - "append": func(arg ...interface{}) interface{} { - switch m := arg[0].(type) { - case *Message: - if len(arg) == 1 { - return m.Meta["append"] - } - if len(arg) > 1 { - switch c := arg[1].(type) { - case string: - if len(arg) > 2 { - switch i := arg[2].(type) { - case int: - return kit.Select("", m.Meta[c], i) - } - } - return m.Meta[c] - } - } - } - return nil - }, - "trans": func(arg ...interface{}) interface{} { - switch m := arg[0].(type) { - case *Message: - list := [][]string{m.Meta["append"]} - m.Table(func(index int, value map[string]string) { - line := []string{} - for _, k := range m.Meta["append"] { - line = append(line, value[k]) - } - list = append(list, line) - }) - return list - } - return nil - }, - "result": func(arg ...interface{}) interface{} { - switch m := arg[0].(type) { - case *Message: - return m.Meta["result"] - } - return nil - }, - "results": func(arg ...interface{}) interface{} { - switch m := arg[0].(type) { - case *Message: - return strings.Join(m.Meta["result"], "") - } - return nil - }, -} - -func LocalCGI(m *Message, c *Context) *template.FuncMap { - cgi := template.FuncMap{ - "format": func(arg ...interface{}) interface{} { - switch msg := arg[0].(type) { - case *Message: - buffer := bytes.NewBuffer([]byte{}) - tmpl := m.Optionv("tmpl").(*template.Template) - m.Assert(tmpl.ExecuteTemplate(buffer, kit.Select("table", arg, 1), msg)) - return string(buffer.Bytes()) - } - return nil - }, - } - for k, v := range c.Commands { - if strings.HasPrefix(k, "/") || strings.HasPrefix(k, "_") { - continue - } - func(k string, v *Command) { - cgi[k] = func(arg ...interface{}) (res interface{}) { - m.TryCatch(m.Spawn(), true, func(msg *Message) { - - v.Hand(msg, c, k, msg.Form(v, kit.Trans(arg))...) - - buffer := bytes.NewBuffer([]byte{}) - m.Assert(m.Optionv("tmpl").(*template.Template).ExecuteTemplate(buffer, - kit.Select(kit.Select("code", "table", len(msg.Meta["append"]) > 0), msg.Option("render")), msg)) - res = string(buffer.Bytes()) - }) - return - } - }(k, v) - } - for k, v := range CGI { - cgi[k] = v - } - return &cgi -} -func ExecuteFile(m *Message, w io.Writer, p string) error { - tmpl := template.New("render").Funcs(CGI) - tmpl.ParseGlob(p) - return tmpl.ExecuteTemplate(w, path.Base(p), m) -} -func ExecuteStr(m *Message, w io.Writer, p string) error { - tmpl := template.New("render").Funcs(CGI) - tmpl, _ = tmpl.Parse(p) - return tmpl.Execute(w, m) -} -func Execute(m *Message, p string) string { - m.Log("fuck", "waht %v", path.Join(m.Conf("route", "template_dir"), "/*.tmpl")) - t := template.Must(template.New("render").Funcs(CGI).ParseGlob(path.Join(m.Conf("route", "template_dir"), "/*.tmpl"))) - for _, v := range t.Templates() { - m.Log("fuck", "waht %v", v.Name()) - } - buf := bytes.NewBuffer(make([]byte, 0, 1024)) - t.ExecuteTemplate(buf, p, m) - m.Log("fuck", "waht %v", p) - m.Log("fuck", "waht %v", buf) - return buf.String() -} diff --git a/usr/local/honor/src/contexts/ctx/core.go b/usr/local/honor/src/contexts/ctx/core.go deleted file mode 100644 index 672e941c..00000000 --- a/usr/local/honor/src/contexts/ctx/core.go +++ /dev/null @@ -1,574 +0,0 @@ -package ctx - -import ( - "errors" - "fmt" - "io" - "strings" - "time" - "toolkit" -) - -func (c *Context) Register(s *Context, x Server, args ...interface{}) *Context { - name, force := s.Name, false - if len(args) > 0 { - switch arg := args[0].(type) { - case bool: - force = arg - case string: - force = true - name, s.Name = arg, arg - } - } - - if c.contexts == nil { - c.contexts = make(map[string]*Context) - } - if x, ok := c.contexts[name]; ok && !force { - panic(errors.New(c.Name + "上下文中已存在模块:" + x.Name)) - } - - c.contexts[name] = s - s.context = c - s.Server = x - s.root = c.root - return s -} -func (c *Context) Plugin(s *Context, args []string) string { - c.Register(s, nil) - m := Pulse.Spawn(s) - // m := &Message{code: 0, time: time.Now(), source: s, target: s, Meta: map[string][]string{}} - // kit.DisableLog = true - m.Option("log.disable", false) - m.Option("bio.modal", "action") - - if len(args) == 0 { - m.Echo("%s: %s\n\n", s.Name, s.Help) - m.Echo("命令列表:\n") - for k, v := range s.Commands { - if !strings.HasPrefix(k, "_") { - m.Echo("--%s: %s\n %v\n\n", k, v.Name, v.Help) - } - } - m.Echo("配置列表:\n") - for k, v := range s.Configs { - if !strings.HasPrefix(k, "_") { - m.Echo("--%s(%v): %s\n", k, kit.Formats(v.Value), v.Help) - } - } - } else { - if Index.Begin(Pulse, args...); Index.Start(Pulse, args...) { - } - m.Cmd(args) - } - for _, v := range m.Meta["result"] { - fmt.Printf(v) - } - return "" -} -func (c *Context) Spawn(m *Message, name string, help string) *Context { - s := &Context{Name: name, Help: help, root: c.root, context: c, message: m, - Caches: map[string]*Cache{}, - Configs: map[string]*Config{}, - Commands: map[string]*Command{}, - } - - if m.target = s; c.Server != nil { - c.Register(s, c.Server.Spawn(m, s, m.Meta["detail"]...)) - } else { - c.Register(s, nil) - } - return s -} -func (c *Context) Begin(m *Message, arg ...string) *Context { - if len(arg) > 0 { - m.Set("detail", arg) - } - - module := c.Name - if c.context != nil && c.context.Caches != nil && c.context.Caches["module"] != nil { - module = c.context.Caches["module"].Value + "." + c.Name - } - - c.Caches["module"] = &Cache{Name: "module", Value: module, Help: "模块域名"} - c.Caches["status"] = &Cache{Name: "status(begin/start/close)", Value: "begin", Help: "模块状态, begin: 初始完成, start: 正在运行, close: 运行结束"} - c.Caches["stream"] = &Cache{Name: "stream", Value: "", Help: "模块数据"} - - c.message = m - c.requests = append(c.requests, m) - m.source.sessions = append(m.source.sessions, m) - c.exit = make(chan bool, 3) - - if c.Server != nil { - c.Server.Begin(m, m.Meta["detail"]...) - } - m.root.Capi("ncontext", 1) - return c -} -func (c *Context) Start(m *Message, arg ...string) bool { - sync := false - if len(arg) > 0 && arg[0] == "sync" { - sync, arg = true, arg[1:] - } - if len(arg) > 0 { - m.Set("detail", arg) - } - - c.requests = append(c.requests, m) - m.source.sessions = append(m.source.sessions, m) - - if m.Hand = true; m.Cap("status") == "start" { - return true - } - - m.Gos(m, func(m *Message) { - m.Log(m.Cap("status", "start"), "%d server %v %v", m.Capi("nserver", 1), m.Meta["detail"], m.Meta["option"]) - - c.message = m - if c.exit <- false; c.Server == nil || c.Server.Start(m, m.Meta["detail"]...) { - c.Close(m, m.Meta["detail"]...) - c.exit <- true - } - }, func(m *Message) { - c.Close(m, m.Meta["detail"]...) - c.exit <- true - }) - - if sync { - for !<-c.exit { - } - return true - } - return <-c.exit -} -func (c *Context) Close(m *Message, arg ...string) bool { - if len(c.requests) == 0 { - return true - } - - if m.target == c { - for i := len(c.requests) - 1; i >= 0; i-- { - if msg := c.requests[i]; msg.code == m.code { - if c.Server == nil || c.Server.Close(m, arg...) { - msg.Free() - for j := i; j < len(c.requests)-1; j++ { - c.requests[j] = c.requests[j+1] - } - c.requests = c.requests[:len(c.requests)-1] - } - } - } - } - - if len(c.requests) > 0 { - return false - } - - if m.Cap("status") == "start" { - m.Log(m.Cap("status", "close"), "%d server %v", m.root.Capi("nserver", -1), arg) - for _, msg := range c.sessions { - if msg.Cap("status") != "close" { - msg.target.Close(msg, arg...) - } - } - } - - if c.context != nil { - m.Log("close", "%d context %v", m.root.Capi("ncontext", -1), arg) - delete(c.context.contexts, c.Name) - c.exit <- true - } - return true -} - -func (m *Message) TryCatch(msg *Message, safe bool, hand ...func(msg *Message)) *Message { - defer func() { - switch e := recover(); e { - case io.EOF: - case nil: - default: - m.Log("bench", "chain: %s", msg.Format("chain")) - m.Log("bench", "catch: %s", e) - m.Log("bench", "stack: %s", msg.Format("stack")) - - if m.Log("error", "catch: %s", e); len(hand) > 1 { - m.TryCatch(msg, safe, hand[1:]...) - } else if !safe { - m.Assert(e) - } - } - }() - - if len(hand) > 0 { - hand[0](msg) - } - return m -} -func (m *Message) Assert(e interface{}, msg ...string) bool { - switch v := e.(type) { - case nil: - return true - case *Message: - if v.Result(0) != "error: " { - return true - } - e = errors.New(strings.Join(v.Meta["result"], "")) - default: - if kit.Right(v) { - return true - } - } - - switch e.(type) { - case error: - default: - e = errors.New(kit.Format(msg)) - } - - kit.Log("error", "%v", e) - panic(e) -} -func (m *Message) GoLoop(msg *Message, hand ...func(msg *Message)) *Message { - m.Gos(msg, func(msg *Message) { - for { - hand[0](msg) - } - }) - return m -} -func (m *Message) Gos(msg *Message, hand ...func(msg *Message)) *Message { - go func() { - msg.Option("ctx.routine", m.Capi("ngo", 1)) - m.TryCatch(msg, true, hand...) - }() - return m -} - -func (m *Message) Spawn(arg ...interface{}) *Message { - temp := false - c := m.target - for i := 0; i < len(arg); i++ { - switch v := arg[i].(type) { - case *Context: - c = v - case *Message: - c = v.target - case string: - temp = kit.Right(v) - case bool: - temp = v - } - } - - msg := &Message{ - time: time.Now(), - code: -1, - source: m.target, - target: c, - message: m, - root: m.root, - } - - if temp { - return msg - } - - msg.code = m.Capi("nmessage", 1) - m.messages = append(m.messages, msg) - return msg -} -func (m *Message) Sess(key string, arg ...interface{}) *Message { - if key == "" { - return m.Spawn() - } - - spawn := true - if len(arg) > 0 { - switch v := arg[0].(type) { - case bool: - spawn, arg = v, arg[1:] - } - } - - if len(arg) > 0 { - if m.Sessions == nil { - m.Sessions = make(map[string]*Message) - } - - switch value := arg[0].(type) { - case *Message: - m.Sessions[key] = value - return m.Sessions[key] - case *Context: - m.Sessions[key] = m.Spawn(value) - return m.Sessions[key] - case string: - root := len(arg) < 3 || kit.Right(arg[2]) - - method := "find" - if len(arg) > 1 { - method = kit.Format(arg[1]) - } - - switch method { - case "find": - m.Sessions[key] = m.Find(value, root) - case "search": - m.Sessions[key] = m.Search(value, root)[0] - } - return m.Sessions[key] - case nil: - delete(m.Sessions, key) - return nil - } - } - - temp := false - if len(arg) > 0 { - switch v := arg[0].(type) { - case bool: - temp, arg = v, arg[1:] - } - } - - for msg := m; msg != nil; msg = msg.message { - if x, ok := msg.Sessions[key]; ok { - if spawn { - x = m.Spawn(x.target, temp) - x.callback = func(sub *Message) *Message { return sub } - } - return x - } - } - - return nil -} -func (m *Message) Form(x *Command, arg []string) []string { - form, ok := m.Optionv("ctx.form").(map[string]int) - if !ok { - return arg - } - for _, form := range []map[string]int{form, x.Form} { - - if args := []string{}; form != nil { - for i := 0; i < len(arg); i++ { - if n, ok := form[arg[i]]; ok { - if n < 0 { - n += len(arg) - i - } - for j := i + 1; j <= i+n && j < len(arg); j++ { - if _, ok := form[arg[j]]; ok { - n = j - i - 1 - } - } - if i+1+n > len(arg) { - m.Add("option", arg[i], arg[i+1:]) - } else { - m.Add("option", arg[i], arg[i+1:i+1+n]) - } - i += n - } else { - args = append(args, arg[i]) - } - } - arg = args - } - } - - return arg -} -func (m *Message) Call(cb func(msg *Message) (sub *Message), arg ...interface{}) *Message { - if m == nil { - return m - } - if m.callback = cb; len(arg) > 0 && kit.Format(arg[0]) == "skip" { - return m - } - if len(arg) > 0 || len(m.Meta["detail"]) > 0 { - m.Log("call", m.Format("detail", "option")) - m.Cmd(arg...) - } - return m -} -func (m *Message) Back(ms ...*Message) *Message { - if m.callback == nil { - return m - } - - if len(ms) == 0 { - ms = append(ms, m.Spawn(m.source).Copy(m, "append").Copy(m, "result")) - } - - ns := []*Message{} - - for _, msg := range ms { - if msg.Hand { - m.Log("back", msg.Format("ship", "result", "append")) - } else { - m.Log("back", msg.Format("ship", "detail", "option")) - } - - if sub := m.callback(msg); sub != nil && m.message != nil && m.message != m { - ns = append(ns, sub) - } - } - - if len(ns) > 0 { - m.message.Back(ns...) - } - return m -} -func (m *Message) CallBack(sync bool, cb func(msg *Message) (sub *Message), arg ...interface{}) *Message { - if !sync { - return m.Call(cb, arg...) - } - - wait := make(chan *Message, 10) - m.Call(func(sub *Message) *Message { - msg := cb(sub) - wait <- m - return msg - }, arg...) - - select { - case <-time.After(kit.Duration(m.Confx("call_timeout"))): - m.Log("sync", m.Format("timeout", "detail", "option")) - m.Echo("time out %v", m.Confx("call_timeout")) - case <-wait: - } - return m -} -func (m *Message) Free(cbs ...func(msg *Message) (done bool)) *Message { - if len(cbs) == 0 { - for i := len(m.freeback) - 1; i >= 0; i-- { - m.Log("free", "%d/%d", i, len(m.freeback)-1) - if !m.freeback[i](m) { - break - } - m.freeback = m.freeback[:i] - } - return m - } - - m.freeback = append(m.freeback, cbs...) - return m -} - -func (m *Message) Match(key string, spawn bool, hand func(m *Message, s *Context, c *Context, key string) bool) *Message { - if m == nil { - return m - } - - context := []*Context{m.target} - for _, v := range kit.Trans(m.Optionv("ctx.chain")) { - if msg := m.Sess(v, false); msg != nil && msg.target != nil { - if msg.target != m.target && msg.target != m.source { - context = append(context, msg.target) - } - } - } - context = append(context, m.source) - - for _, s := range context { - for c := s; c != nil; c = c.context { - if hand(m, s, c, key) { - return m - } - } - } - return m -} -func (m *Message) Magic(begin string, chain interface{}, args ...interface{}) interface{} { - auth := []string{"bench", "session", "user", "role", "componet", "command"} - key := []string{"bench", "sessid", "username", "role", "componet", "command"} - aaa := m.Sess("aaa", false) - for i, v := range auth { - if v == begin { - h := m.Option(key[i]) - if v == "user" { - h, _ = kit.Hash("username", m.Option("username")) - } - - data := aaa.Confv("auth", []string{h, "data"}) - - if kit.Format(chain) == "" { - return data - } - - if len(args) > 0 { - value := kit.Chain(data, chain, args[0]) - aaa.Conf("auth", []string{m.Option(key[i]), "data"}, value) - return value - } - - value := kit.Chain(data, chain) - if value != nil { - return value - } - - if i < len(auth)-1 { - begin = auth[i+1] - } - } - } - return nil -} -func (m *Message) Parse(arg interface{}) string { - switch str := arg.(type) { - case string: - if len(str) > 1 && str[0] == '$' { - return m.Cap(str[1:]) - } - if len(str) > 1 && str[0] == '@' { - if v := m.Option(str[1:]); v != "" { - return v - } - if v := kit.Format(m.Magic("bench", str[1:])); v != "" { - return v - } - v := m.Conf(str[1:]) - return v - } - return str - } - return "" -} -func (m *Message) Goshy(input []string, index int, stack *kit.Stack, cb func(*Message)) bool { - m.Optionv("bio.msg", m) - if stack == nil { - stack = &kit.Stack{} - stack.Push("source", true, 0) - } - m.Optionv("bio.stack", stack) - m.Optionv("bio.input", input) - - for i := index; i < len(input); i++ { - line := input[i] - m.Optioni("stack.pos", i) - - // 执行语句 - msg := m.Sess("yac").Cmd("parse", line+"\n") - if cb != nil { - cb(msg) - } - - // 切换模块 - if v := msg.Optionv("bio.ctx"); v != nil { - m.Optionv("bio.ctx", v) - } - - // 跳转语句 - if msg.Appends("bio.pos0") { - i = int(msg.Appendi("bio.pos0")) - 1 - msg.Append("bio.pos0", "") - } - - // 结束脚本 - if msg.Appends("bio.end") { - m.Copy(msg, "append").Copy(msg, "result") - msg.Appends("bio.end", "") - return true - } - } - return false -} diff --git a/usr/local/honor/src/contexts/ctx/ctx.go b/usr/local/honor/src/contexts/ctx/ctx.go deleted file mode 100644 index d422cf9d..00000000 --- a/usr/local/honor/src/contexts/ctx/ctx.go +++ /dev/null @@ -1,1381 +0,0 @@ -package ctx - -import ( - "runtime" - "toolkit" - - "encoding/json" - "fmt" - "math/rand" - "os" - "regexp" - "sort" - "strconv" - "strings" - "time" -) - -type CTX struct { - *Context -} - -func (ctx *CTX) Spawn(m *Message, c *Context, arg ...string) Server { - return &CTX{Context: c} -} -func (ctx *CTX) Begin(m *Message, arg ...string) Server { - m.Option("ctx.routine", 0) - m.Option("log.disable", true) - m.Option("ctx.chain", "aaa", "ssh", "nfs", "cli", "web") - - m.Option("table.limit", 30) - m.Option("table.offset", 0) - m.Option("table.format", "object") - m.Optionv("ctx.form", map[string]int{ - "table.format": 1, "table.offset": 1, "table.limit": 1, - }) - - m.root = m - m.Sess(m.target.Name, m) - for _, msg := range m.Search("") { - if msg.target.root = m.target; msg.target == m.target { - continue - } - msg.target.Begin(msg, arg...) - m.Sess(msg.target.Name, msg) - } - return ctx -} -func (ctx *CTX) Start(m *Message, arg ...string) bool { - if m.Optionv("bio.ctx", Index); len(arg) == 0 { - kit.DisableLog = false - m.Option("log.debug", kit.Right(os.Getenv("ctx_log_debug"))) - m.Option("log.disable", kit.Right(os.Getenv("ctx_log_disable"))) - m.Option("gdb.enable", kit.Right(os.Getenv("ctx_gdb_enable"))) - m.Cmd("log._init") - m.Cmd("gdb._init") - m.Cmd("ctx._init") - m.Option("bio.modal", "active") - - m.Optionv("bio.ctx", m.Target()) - m.Optionv("bio.msg", m) - m.Cap("stream", "stdio") - m.Cmd("aaa.role", m.Option("userrole", "root"), "user", m.Option("username", m.Conf("runtime", "boot.username"))) - m.Option("sessid", m.Cmdx("aaa.user", "session", "select")) - - m.Cmd("nfs.source", m.Conf("cli.system", "script.init")).Cmd("nfs.source", "stdio").Cmd("nfs.source", m.Conf("cli.system", "script.exit")) - } else { - m.Cmd("ctx._init") - m.Option("bio.modal", "action") - for _, v := range m.Sess("cli").Cmd(arg).Meta["result"] { - fmt.Printf("%s", v) - } - } - m.Cmd("ctx._exit") - return true -} -func (ctx *CTX) Close(m *Message, arg ...string) bool { - return true -} - -var Pulse = &Message{code: 0, time: time.Now(), source: Index, target: Index, Meta: map[string][]string{}} -var Index = &Context{Name: "ctx", Help: "模块中心", Server: &CTX{}, - Caches: map[string]*Cache{ - "ngo": &Cache{Name: "ngo", Value: "0", Help: "协程数量"}, - "nserver": &Cache{Name: "nserver", Value: "0", Help: "服务数量"}, - "ncontext": &Cache{Name: "ncontext", Value: "0", Help: "模块数量"}, - "nmessage": &Cache{Name: "nmessage", Value: "1", Help: "消息数量"}, - }, - Configs: map[string]*Config{ - "help": &Config{Name: "help", Value: map[string]interface{}{ - "index": []interface{}{ - "^_^ 欢迎来到云境世界 ^_^", - "^_^ Welcome to Context world ^_^", - "", - "V2.1: Miss You Forever", - "Date: 2019.10.29 13:14:21", - "From: 2017.11.01 00:08:21", - "", - "Meet: shylinuxc@gmail.com", - "More: https://shylinux.com", - "More: https://github.com/shylinux/context", - "", - }, - }, Help: "帮助"}, - "time": &Config{Name: "timer", Value: map[string]interface{}{ - "unit": 1000, "close": "open", "format": "2006-01-02 15:04:05", - }, Help: "时间参数"}, - "table": &Config{Name: "table", Value: map[string]interface{}{ - "space": " ", "compact": "false", "col_sep": " ", "row_sep": "\n", - "offset": 0, "limit": 30, - }, Help: "制表"}, - "call_timeout": &Config{Name: "call_timeout", Value: "60s", Help: "回调超时"}, - }, - Commands: map[string]*Command{ - "_init": &Command{Name: "_init", Help: "启动", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) { - for _, x := range []string{"lex", "cli", "yac", "nfs", "aaa", "ssh", "web"} { - m.Cmd(x + "._init") - } - return - }}, - "_exit": &Command{Name: "_exit", Help: "退出", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) { - for _, x := range []string{"nfs", "cli"} { - m.Cmd(x + "._exit") - } - return - }}, - - "help": &Command{Name: "help topic", Help: "帮助", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) { - if len(arg) == 0 { - m.Confm("help", "index", func(index int, value string) { - m.Echo(value).Echo("\n") - }) - return - } - - switch arg[0] { - case "context": - switch len(arg) { - case 1: - keys := []string{} - values := map[string]*Context{} - m.Target().root.Travel(m, func(m *Message, i int) bool { - if _, ok := values[m.Cap("module")]; !ok { - keys = append(keys, m.Cap("module")) - values[m.Cap("module")] = m.Target() - } - return false - }) - - sort.Strings(keys) - for _, k := range keys { - m.Echo("%s: %s %s\n", k, values[k].Name, values[k].Help) - } - break - case 2: - if msg := m.Find(arg[1]); msg != nil { - m.Echo("%s: %s %s\n", arg[1], msg.Target().Name, msg.Target().Help) - m.Echo("commands:\n") - for k, v := range msg.Target().Commands { - m.Echo(" %s: %s\n", k, v.Name) - } - m.Echo("configs:\n") - for k, v := range msg.Target().Configs { - m.Echo(" %s: %s\n", k, v.Name) - } - m.Echo("caches:\n") - for k, v := range msg.Target().Caches { - m.Echo(" %s: %s\n", k, v.Name) - } - } - default: - if msg := m.Find(arg[1]); msg != nil { - m.Echo("%s: %s %s\n", arg[1], msg.Target().Name, msg.Target().Help) - switch arg[2] { - case "command": - for k, v := range msg.Target().Commands { - if k == arg[3] { - m.Echo("%s: %s\n%s\n", k, v.Name, v.Help) - } - } - case "config": - for k, v := range msg.Target().Configs { - if k == arg[3] { - m.Echo("%s: %s\n %s\n", k, v.Name, v.Help) - } - } - case "cache": - for k, v := range msg.Target().Caches { - if k == arg[3] { - m.Echo("%s: %s\n %s\n", k, v.Name, v.Help) - } - } - } - } - } - case "command": - keys := []string{} - values := map[string]*Command{} - for s := m.Target(); s != nil; s = s.context { - for k, v := range s.Commands { - if _, ok := values[k]; ok { - continue - } - if len(arg) > 1 && k == arg[1] { - switch help := v.Help.(type) { - case []string: - m.Echo("%s: %s\n", k, v.Name) - for _, v := range help { - m.Echo(" %s\n", v) - } - case string: - m.Echo("%s: %s\n%s\n", k, v.Name, v.Help) - } - return - } - keys = append(keys, k) - values[k] = v - } - } - sort.Strings(keys) - for _, k := range keys { - m.Echo("%s: %s\n", k, values[k].Name) - } - case "config": - keys := []string{} - values := map[string]*Config{} - for s := m.Target(); s != nil; s = s.context { - for k, v := range s.Configs { - if _, ok := values[k]; ok { - continue - } - if len(arg) > 1 && k == arg[1] { - m.Echo("%s(%s): %s %s\n", k, v.Value, v.Name, v.Help) - return - } - keys = append(keys, k) - values[k] = v - } - } - sort.Strings(keys) - for _, k := range keys { - m.Echo("%s(%s): %s\n", k, values[k].Value, values[k].Name) - } - case "cache": - keys := []string{} - values := map[string]*Cache{} - for s := m.Target(); s != nil; s = s.context { - for k, v := range s.Caches { - if _, ok := values[k]; ok { - continue - } - if len(arg) > 1 && k == arg[1] { - m.Echo("%s(%s): %s %s\n", k, v.Value, v.Name, v.Help) - return - } - keys = append(keys, k) - values[k] = v - } - } - sort.Strings(keys) - for _, k := range keys { - m.Echo("%s(%s): %s\n", k, values[k].Value, values[k].Name) - } - } - - return - }}, - "cache": &Command{Name: "cache [all] |key [value]|key = value|key name value help|delete key]", Help: "查看、读写、赋值、新建、删除缓存变量", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) { - all := false - if len(arg) > 0 && arg[0] == "all" { - arg, all = arg[1:], true - } - - switch len(arg) { - case 0: - c.BackTrace(m, func(m *Message) bool { - for k, v := range m.target.Caches { - m.Add("append", "key", k) - m.Add("append", "value", m.Cap(k)) - m.Add("append", "name", v.Name) - } - return !all - }) - m.Sort("key", "str").Table() - return - case 1: - m.Echo(m.Cap(arg[0])) - case 2: - if arg[0] == "delete" { - delete(m.target.Caches, arg[1]) - return - } - m.Cap(arg[0], arg[1]) - case 3: - m.Cap(arg[0], arg[0], arg[2], arg[0]) - default: - m.Echo(m.Cap(arg[0], arg[1:])) - return - } - return - }}, - "config": &Command{Name: "config [all]", Help: []string{"配置管理", - "brow: 配置列表", - "key [chain [value]]: 读写配置", - "export key...: 导出配置", - "save|load file key...: 保存、加载配置", - "create map|list|string key name help: 创建配置", - "delete key: 删除配置", - }, Form: map[string]int{"format": 1, "fields": -1}, Hand: func(m *Message, c *Context, key string, arg ...string) (e error) { - all := false - if len(arg) > 0 && arg[0] == "all" { - arg, all = arg[1:], true - } - if len(arg) == 0 { - arg = append(arg, "brow") - } - - action, which := "", "-1" - have := map[string]bool{} - switch arg[0] { - case "brow": - case "export": - action, arg = arg[0], arg[1:] - for _, v := range arg { - have[v] = true - } - case "save", "load": - action, which, arg = arg[0], arg[1], arg[2:] - for _, v := range arg { - have[v] = true - } - case "create", "delete": - action, arg = arg[0], arg[1:] - - default: - var value interface{} - if len(arg) > 2 && arg[2] == "map" { - for i := 3; i < len(arg)-1; i += 2 { - m.Confv(arg[0], []interface{}{arg[1], arg[i]}, arg[i+1]) - } - value = m.Confv(arg[0], arg[1]) - } else if len(arg) > 2 && arg[2] == "list" { - for i := 3; i < len(arg); i += 1 { - m.Confv(arg[0], []interface{}{arg[1], -2}, arg[i]) - } - return - } else if len(arg) > 1 && arg[1] == "list" { - for i := 2; i < len(arg)-1; i += 1 { - m.Confv(arg[0], -2, arg[i]) - } - value = m.Confv(arg[0]) - } else if len(arg) > 1 && arg[1] == "map" { - for i := 2; i < len(arg)-1; i += 2 { - m.Confv(arg[0], arg[i], arg[i+1]) - } - value = m.Confv(arg[0]) - } else if len(arg) > 2 { - value = m.Confv(arg[0], arg[1], arg[2]) - } else if len(arg) > 1 { - value = m.Confv(arg[0], arg[1]) - } else { - value = m.Confv(arg[0]) - } - - msg := m.Spawn().Put("option", "_cache", value).Cmd("trans", "_cache") - m.Copy(msg, "append").Copy(msg, "result") - return - } - - save := map[string]interface{}{} - if action == "load" { - f, e := os.Open(m.Cmdx("nfs.path", which)) - if e != nil { - return e - } - defer f.Close() - - de := json.NewDecoder(f) - if e = de.Decode(&save); e != nil { - m.Log("info", "e: %v", e) - } - } - - c.BackTrace(m, func(m *Message) bool { - for k, v := range m.target.Configs { - switch action { - case "export", "save": - if len(have) == 0 || have[k] { - save[k] = v.Value - } - case "load": - if x, ok := save[k]; ok && (len(have) == 0 || have[k]) { - v.Value = x - } - case "create": - m.Assert(k != arg[1], "%s exists", arg[1]) - case "delete": - if k == arg[0] { - m.Echo(kit.Formats(v.Value)) - delete(m.target.Configs, k) - } - default: - m.Add("append", "key", k) - m.Add("append", "value", strings.Replace(strings.Replace(m.Conf(k), "\n", "\\n", -1), "\t", "\\t", -1)) - m.Add("append", "name", v.Name) - } - } - switch action { - case "create": - var value interface{} - switch arg[0] { - case "map": - value = map[string]interface{}{} - case "list": - value = []interface{}{} - default: - value = "" - } - m.target.Configs[arg[1]] = &Config{Name: arg[2], Value: value, Help: arg[3]} - m.Echo(arg[1]) - return true - } - return !all - }) - m.Sort("key", "str").Table() - - switch action { - case "save": - buf, e := json.MarshalIndent(save, "", " ") - m.Assert(e) - m.Sess("nfs").Add("option", "data", string(buf)).Cmd("save", which) - case "export": - buf, e := json.MarshalIndent(save, "", " ") - m.Assert(e) - m.Echo("%s", string(buf)) - } - return - }}, - "command": &Command{Name: "command", Help: []string{"查看或操作命令", - "brow [all|cmd]: 查看命令", - "help cmd: 查看帮助", - "cmd...: 执行命令", - "list [begin [end]] [prefix] [test [key value]...]: 命令列表", - "add [list_name name] [list_help help] [cmd|__|_|_val]...: 添加命令, __: 可选参数, _: 必选参数, _val: 默认参数", - }, Hand: func(m *Message, c *Context, key string, arg ...string) (e error) { - if len(arg) == 0 { - arg = append(arg, "brow") - } - - switch arg[0] { - case "brow": - c.BackTrace(m, func(m *Message) bool { - for k, v := range m.target.Commands { - if strings.HasPrefix(k, "_") { - continue - } - if len(arg) == 1 || arg[1] == "all" { - m.Add("append", "cmd", k) - m.Add("append", "name", v.Name) - } else if arg[1] == k { - m.Add("append", "cmd", k) - m.Add("append", "name", v.Name) - m.Add("append", "help", v.Name) - } - } - return len(arg) == 1 || arg[1] != "all" - }) - m.Sort("cmd").Table() - - case "help": - m.Cmdy("ctx.help", "command", arg[1:]) - - case "list": - arg = arg[1:] - if m.Cap("list_count") == "" { - break - } - begin, end := 0, m.Capi("list_count") - if len(arg) > 0 { - if n, e := strconv.Atoi(arg[0]); e == nil { - begin, arg = n, arg[1:] - } - } - if len(arg) > 0 { - if n, e := strconv.Atoi(arg[0]); e == nil { - end, arg = n, arg[1:] - } - } - prefix := "" - if len(arg) > 0 && arg[0] != "test" { - prefix, arg = arg[0], arg[1:] - } - - test := false - if len(arg) > 0 && arg[0] == "test" { - test, arg = true, arg[1:] - for i := 0; i < len(arg)-1; i += 2 { - m.Add("option", arg[i], arg[i+1]) - } - } - - for i := begin; i < end; i++ { - index := fmt.Sprintf("%d", i) - if c, ok := m.target.Commands[index]; ok { - if prefix != "" && !strings.HasPrefix(c.Help.(string), prefix) { - continue - } - - if test { - msg := m.Spawn().Cmd(index) - m.Add("append", "index", i) - m.Add("append", "help", c.Help) - m.Add("append", "msg", msg.messages[0].code) - m.Add("append", "res", msg.Result(0)) - } else { - m.Add("append", "index", i) - m.Add("append", "help", c.Help) - m.Add("append", "command", fmt.Sprintf("%s", strings.Replace(c.Name, "\n", "\\n", -1))) - } - } - } - m.Table() - - case "add": - if m.target.Caches == nil { - m.target.Caches = map[string]*Cache{} - } - if _, ok := m.target.Caches["list_count"]; !ok { - m.target.Caches["list_count"] = &Cache{Name: "list_count", Value: "0", Help: "list_count"} - } - if m.target.Commands == nil { - m.target.Commands = map[string]*Command{} - } - - arg = arg[1:] - list_name, list_help := "", "list_cmd" - if len(arg) > 1 && arg[0] == "list_name" { - list_name, arg = arg[1], arg[2:] - } - if len(arg) > 1 && arg[0] == "list_help" { - list_help, arg = arg[1], arg[2:] - } - - m.target.Commands[m.Cap("list_count")] = &Command{Name: strings.Join(arg, " "), Help: list_help, Hand: func(cmd *Message, c *Context, key string, args ...string) (e error) { - list := []string{} - for _, v := range arg { - if v == "__" { - if len(args) > 0 { - v, args = args[0], args[1:] - } else { - continue - } - } else if strings.HasPrefix(v, "_") { - if len(args) > 0 { - v, args = args[0], args[1:] - } else if len(v) > 1 { - v = v[1:] - } else { - v = "''" - } - } - list = append(list, v) - } - list = append(list, args...) - - msg := cmd.Sess("cli").Set("option", "current_ctx", m.target.Name).Cmd("source", strings.Join(list, " ")) - cmd.Copy(msg, "append").Copy(msg, "result").Copy(msg, "target") - return - }} - - if list_name != "" { - m.target.Commands[list_name] = m.target.Commands[m.Cap("list_count")] - } - m.Capi("list_count", 1) - - default: - m.Cmdy(arg) - } - return - }}, - "context": &Command{Name: "context [find|search] [root|back|home] [first|last|rand|magic] [module] [cmd...|switch|list|spawn|start|close]", - Help: []string{"查找并操作模块", - "查找方法, find: 精确查找, search: 模糊搜索", - "查找起点, root: 根模块, back: 父模块, home: 本模块", - "过滤结果, first: 取第一个, last: 取最后一个, rand: 随机选择, magics: 智能选择", - "操作方法, cmd...: 执行命令, switch: 切换为当前, list: 查看所有子模块, spwan: 创建子模块并初始化, start: 启动模块, close: 结束模块", - }, Hand: func(m *Message, c *Context, key string, arg ...string) (e error) { - action := "switch" - if len(arg) == 0 { - action = "list" - } - - method := "search" - if len(arg) > 0 { - switch arg[0] { - case "find", "search": - method, arg = arg[0], arg[1:] - } - } - - root := true - if len(arg) > 0 { - switch arg[0] { - case "root": - root, arg = true, arg[1:] - case "home": - root, arg = false, arg[1:] - case "back": - root, arg = false, arg[1:] - if m.target.context != nil { - m.target = m.target.context - } - } - } - - ms := []*Message{} - if len(arg) > 0 { - switch method { - case "find": - if msg := m.Find(arg[0], root); msg != nil { - ms, arg = append(ms, msg), arg[1:] - } - case "search": - msg := m.Search(arg[0], root) - if len(msg) > 1 || msg[0] != nil { - if len(arg) > 1 { - switch arg[1] { - case "first": - ms, arg = append(ms, msg[0]), arg[2:] - case "last": - ms, arg = append(ms, msg[len(msg)-1]), arg[2:] - case "rand": - ms, arg = append(ms, msg[rand.Intn(len(msg))]), arg[2:] - case "magics": - ms, arg = append(ms, msg...), arg[2:] - default: - ms, arg = append(ms, msg[0]), arg[1:] - } - } else { - ms, arg = append(ms, msg[0]), arg[1:] - } - } - - } - } - - if len(ms) == 0 { - ms = append(ms, m) - } - - if len(arg) > 0 { - switch arg[0] { - case "switch", "list", "spawn", "start", "close": - action, arg = arg[0], arg[1:] - default: - action = "cmd" - } - } - - for _, msg := range ms { - if msg == nil { - continue - } - - switch action { - case "cmd": - if len(arg) == 0 { - arg = append(arg, "command") - } else if arg[0] == "command" && len(arg) > 1 { - arg = arg[1:] - } - if msg.Cmd(arg); !msg.Hand { - msg = msg.Cmd("nfs.cmd", arg) - } - msg.CopyTo(m) - - case "switch": - m.target = msg.target - - case "list": - cs := []*Context{} - if msg.target.Name != "ctx" { - cs = append(cs, msg.target.context) - } - msg.target.Travel(msg, func(msg *Message, n int) bool { - cs = append(cs, msg.target) - return false - }) - msg = m.Spawn() - - for _, v := range cs { - if msg.target = v; v == nil { - m.Add("append", "names", "") - m.Add("append", "ctx", "") - m.Add("append", "msg", "") - m.Add("append", "status", "") - m.Add("append", "stream", "") - m.Add("append", "helps", "") - continue - } - - m.Add("append", "names", msg.target.Name) - if msg.target.context != nil { - m.Add("append", "ctx", msg.target.context.Name) - } else { - m.Add("append", "ctx", "") - } - if msg.target.message != nil { - m.Add("append", "msg", msg.target.message.code) - } else { - m.Add("append", "msg", "") - } - m.Add("append", "status", msg.Cap("status")) - m.Add("append", "stream", msg.Cap("stream")) - m.Add("append", "helps", msg.target.Help) - } - m.Table() - - case "spawn": - msg.target.Spawn(msg, arg[0], arg[1]).Begin(msg, arg[2:]...) - m.Copy(msg, "append").Copy(msg, "result").Copy(msg, "target") - - case "start": - msg.target.Start(msg, arg...) - m.Copy(msg, "append").Copy(msg, "result").Copy(msg, "target") - - case "close": - msg := m.Spawn() - m.target = msg.target.context - msg.target.Close(msg.target.message, arg...) - } - } - return - }}, - - "message": &Command{Name: "message [code] [cmd...]", Help: "查看消息", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) { - msg := m - if len(arg) > 0 { - if code, e := strconv.Atoi(arg[0]); e == nil { - ms := []*Message{m.root} - for i := 0; i < len(ms); i++ { - if ms[i].Code() == code { - msg = ms[i] - arg = arg[1:] - break - } - ms = append(ms, ms[i].messages...) - } - } - } - m.Optionv("bio.msg", msg) - - if len(arg) == 0 { - ms := []*Message{msg.message, msg} - for i := 0; i < len(ms); i++ { - if ms[i] == nil { - continue - } - if ms[i].message != nil { - m.Push("msg", ms[i].message.code) - } else { - m.Push("msg", 0) - } - - m.Push("code", ms[i].code) - m.Push("time", ms[i].Time()) - m.Push("source", ms[i].source.Name) - m.Push("target", ms[i].target.Name) - m.Push("details", kit.Format(ms[i].Meta["detail"])) - if i > 0 { - ms = append(ms, ms[i].messages...) - } - } - m.Table() - return - } - - switch arg[0] { - case "time", "code", "ship", "full", "chain", "stack": - m.Echo(msg.Format(arg[0])) - case "spawn": - sub := msg.Spawn() - m.Echo("%d", sub.code) - case "call": - case "back": - msg.Back(m) - case "free": - msg.Free() - default: - m.Cmd(arg) - } - return - }}, - "detail": &Command{Name: "detail [index] [value...]", Help: "查看或添加参数", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) { - msg := m.Optionv("bio.msg").(*Message) - if len(arg) == 0 { - for i, v := range msg.Meta["detail"] { - m.Push("index", i) - m.Push("value", v) - } - m.Table() - return - } - - index := 0 - if i, e := strconv.Atoi(arg[0]); e == nil { - index, arg = i, arg[1:] - } - m.Echo("%s", msg.Detail(index, arg)) - return - }}, - "copy": &Command{Name: "copy", Help: "查看或添加选项", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) { - skip := false - if arg[0] == "skip" { - skip, arg = true, arg[1:] - } - msg := m.Optionv("bio.msg").(*Message) - // 去年尾参 - for i := len(arg) - 1; i >= 0; i-- { - if arg[i] == "" { - arg = arg[:i] - } else { - break - } - } - // 默认参数 - args, j := make([]string, 0, len(arg)), 1 - for i := 0; i < len(arg); i++ { - if strings.HasPrefix(arg[i], "__") { - if j < len(msg.Meta["detail"]) { - args = append(args, msg.Meta["detail"][j:]...) - } - j = len(msg.Meta["detail"]) - } else if strings.HasPrefix(arg[i], "_") { - args = append(args, kit.Select(arg[i][1:], msg.Detail(j))) - j++ - } else { - args = append(args, arg[i]) - } - } - if !skip && j < len(msg.Meta["detail"]) { - args = append(args, msg.Meta["detail"][j:]...) - } - msg.Cmdy(args) - return - }}, - "table": &Command{Name: "table", Help: "查看或添加选项", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) { - msg := m.Optionv("bio.msg").(*Message) - if len(msg.Meta["append"]) == 0 { - msg.Meta["append"] = arg - } else { - for i, k := range msg.Meta["append"] { - msg.Push(k, kit.Select("", arg, i)) - } - } - return - }}, - "option": &Command{Name: "option", Help: "查看或添加选项", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) { - all := false - if len(arg) > 0 && arg[0] == "all" { - all, arg = true, arg[1:] - } - - msg := m.Optionv("bio.msg").(*Message) - switch len(arg) { - case 0: - vals := map[string]interface{}{} - list := []string{} - - for back := msg; back != nil; back = back.message { - for _, k := range back.Meta["option"] { - if _, ok := vals[k]; !ok { - if _, ok := back.Data[k]; ok { - vals[k] = back.Data[k] - } else { - vals[k] = back.Meta[k] - } - list = append(list, k) - } - } - if !all { - break - } - } - sort.Strings(list) - - for _, k := range list { - m.Push("key", k) - m.Push("val", kit.Format(vals[k])) - } - m.Table() - case 1: - switch v := msg.Optionv(arg[0]).(type) { - case []string: - m.Echo(strings.Join(v, "")) - default: - m.Echo(kit.Format(v)) - } - default: - m.Echo(m.Option(arg[0], arg[1])) - } - return - }}, - "append": &Command{Name: "append", Help: "查看或添加附加值", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) { - msg := m.Optionv("bio.msg").(*Message) - if len(arg) == 0 { - m.Copy(msg, "append") - m.Table() - return - } - if len(arg) == 1 { - for i, v := range msg.Meta[arg[0]] { - m.Push("index", i) - m.Push("value", v) - } - m.Table() - return - } - msg.Push(arg[0], arg[1]) - return - }}, - "result": &Command{Name: "result [index] [value...]", Help: "查看或添加返回值", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) { - msg := m.Optionv("bio.msg").(*Message) - if len(arg) == 0 { - for i, v := range msg.Meta["result"] { - m.Push("index", i) - m.Push("value", strings.Replace(v, "\n", "\\n", -1)) - } - m.Table() - return - } - - index := -2 - if i, e := strconv.Atoi(arg[0]); e == nil { - index, arg = i, arg[1:] - } - m.Echo("%s", msg.Result(index, arg)) - return - }}, - - "trans": &Command{Name: "trans option [type|data|json] limit 10 [index...]", Help: "数据转换", - Form: map[string]int{"format": 1, "fields": -1}, - Hand: func(m *Message, c *Context, key string, arg ...string) (e error) { - value, arg := m.Optionv(arg[0]), arg[1:] - if v, ok := value.(string); ok { - json.Unmarshal([]byte(v), &value) - } - - view := "data" - if len(arg) > 0 { - switch arg[0] { - case "type", "data", "json": - view, arg = arg[0], arg[1:] - } - } - - limit := kit.Int(kit.Select(m.Conf("table", "limit"), m.Option("table.limit"))) - if len(arg) > 0 && arg[0] == "limit" { - limit, arg = kit.Int(arg[1]), arg[2:] - } - - chain := strings.Join(arg, ".") - if chain != "" { - value = kit.Chain(value, chain) - } - - switch view { - case "type": // 查看数据类型 - switch value := value.(type) { - case map[string]interface{}: - for k, v := range value { - m.Add("append", "key", k) - m.Add("append", "type", fmt.Sprintf("%T", v)) - } - m.Sort("key", "str").Table() - case []interface{}: - for k, v := range value { - m.Add("append", "key", k) - m.Add("append", "type", fmt.Sprintf("%T", v)) - } - m.Sort("key", "int").Table() - case nil: - default: - m.Add("append", "key", chain) - m.Add("append", "type", fmt.Sprintf("%T", value)) - m.Sort("key", "str").Table() - } - return - case "data": - case "json": // 查看文本数据 - b, e := json.MarshalIndent(value, "", " ") - m.Assert(e) - m.Echo(string(b)) - return nil - } - - switch val := value.(type) { - case map[string]interface{}: - if m.Option("format") == "table" { - fields := []string{} - has := map[string]bool{} - if m.Options("fields") { - fields = m.Optionv("fields").([]string) - } else { - i := 0 - for _, v := range val { - if i++; i > kit.Int(kit.Select(m.Conf("table", "limit"), m.Option("table.limit"))) { - break - } - if line, ok := v.(map[string]interface{}); ok { - for k, _ := range line { - if h, ok := has[k]; ok && h { - continue - } - has[k], fields = true, append(fields, k) - } - } - } - sort.Strings(fields) - } - - i := 0 - for k, v := range val { - if i++; i > kit.Int(kit.Select(m.Conf("table", "limit"), m.Option("table.limit"))) { - break - } - if line, ok := v.(map[string]interface{}); ok { - m.Add("append", "key", k) - for _, field := range fields { - m.Add("append", field, kit.Format(line[field])) - } - } - } - m.Table() - break - } - - for k, v := range val { - if m.Option("format") == "object" { - m.Add("append", k, v) - continue - } - - m.Add("append", "key", k) - switch val := v.(type) { - case nil: - m.Add("append", "value", "") - case string: - m.Add("append", "value", val) - case float64: - m.Add("append", "value", fmt.Sprintf("%d", int(val))) - default: - b, _ := json.Marshal(val) - m.Add("append", "value", fmt.Sprintf("%s", string(b))) - } - } - if m.Option("format") != "object" { - m.Sort("key", "str") - } - m.Table() - case map[string]string: - for k, v := range val { - m.Add("append", "key", k) - m.Add("append", "value", v) - } - m.Sort("key", "str").Table() - case []interface{}: - fields := map[string]int{} - for i, v := range val { - if i >= limit { - break - } - switch val := v.(type) { - case map[string]interface{}: - for k, _ := range val { - fields[k]++ - } - } - } - - if len(fields) > 0 { - for i, v := range val { - if i >= limit { - break - } - switch val := v.(type) { - case map[string]interface{}: - for k, _ := range fields { - switch value := val[k].(type) { - case nil: - m.Add("append", k, "") - case string: - m.Add("append", k, value) - case float64: - m.Add("append", k, fmt.Sprintf("%d", int(value))) - default: - b, _ := json.Marshal(value) - m.Add("append", k, fmt.Sprintf("%v", string(b))) - } - } - } - } - } else { - for i, v := range val { - switch val := v.(type) { - case nil: - m.Add("append", "index", i) - m.Add("append", "value", "") - case string: - m.Add("append", "index", i) - m.Add("append", "value", val) - case float64: - m.Add("append", "index", i) - m.Add("append", "value", fmt.Sprintf("%v", int(val))) - default: - m.Add("append", "index", i) - b, _ := json.Marshal(val) - m.Add("append", "value", fmt.Sprintf("%v", string(b))) - } - } - } - m.Table() - case []string: - for i, v := range val { - m.Add("append", "index", i) - m.Add("append", "value", v) - } - m.Table() - case string: - m.Echo("%s", val) - case float64: - m.Echo("%d", int(val)) - case nil: - default: - b, _ := json.Marshal(val) - m.Echo("%s", string(b)) - } - return - }}, - "select": &Command{Name: "select field...", - Form: map[string]int{"reg": 2, "eq": 2, "expand": 2, "hide": -1, "fields": -1, "group": 1, "order": 2, "limit": 1, "offset": 1, "format": -1, "trans_map": -1, "vertical": 0}, - Help: "选取数据", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) { - msg := m.Set("result").Spawn() - - // 解析 - if len(m.Meta["append"]) == 0 { - return - } - nrow := len(m.Meta[m.Meta["append"][0]]) - keys := []string{} - for i := 0; i < nrow; i++ { - for j := 0; j < len(m.Meta["expand"]); j += 2 { - var value interface{} - json.Unmarshal([]byte(m.Meta[m.Meta["expand"][j]][i]), &value) - if m.Meta["expand"][j+1] != "" { - value = kit.Chain(value, m.Meta["expand"][j+1]) - } - - switch val := value.(type) { - case map[string]interface{}: - for k, _ := range val { - keys = append(keys, k) - } - default: - keys = append(keys, m.Meta["expand"][j+1]) - } - } - } - for i := 0; i < nrow; i++ { - for _, k := range keys { - m.Add("append", k, "") - } - } - for i := 0; i < nrow; i++ { - for j := 0; j < len(m.Meta["expand"]); j += 2 { - var value interface{} - json.Unmarshal([]byte(m.Meta[m.Meta["expand"][j]][i]), &value) - if m.Meta["expand"][j+1] != "" { - value = kit.Chain(value, m.Meta["expand"][j+1]) - } - - switch val := value.(type) { - case map[string]interface{}: - for k, v := range val { - switch val := v.(type) { - case string: - m.Meta[k][i] = val - case float64: - m.Meta[k][i] = fmt.Sprintf("%d", int(val)) - default: - b, _ := json.Marshal(val) - m.Meta[k][i] = string(b) - } - } - case string: - m.Meta[m.Meta["expand"][j+1]][i] = val - default: - m.Meta[m.Meta["expand"][j+1]][i] = kit.Format(val) - } - } - } - - // 隐藏列 - hides := map[string]bool{} - for _, k := range m.Meta["hide"] { - hides[k] = true - } - if len(arg) == 0 { - arg = append(arg, m.Meta["append"]...) - } - for i := 0; i < nrow; i++ { - // if len(arg) == 0 || strings.Contains(m.Meta[arg[0]][i], arg[1]) { - if m.Has("eq") { - if m.Meta[m.Meta["eq"][0]][i] != m.Meta["eq"][1] { - continue - } - } - if m.Has("reg") { - if b, e := regexp.MatchString(m.Meta["reg"][1], m.Meta[m.Meta["reg"][0]][i]); e != nil || !b { - continue - } - } - for _, k := range arg { - if hides[k] { - continue - } - msg.Add("append", k, kit.Select("", m.Meta[k], i)) - } - } - if len(msg.Meta["append"]) == 0 { - return - } - if len(msg.Meta[msg.Meta["append"][0]]) == 0 { - return - } - - // 聚合 - if m.Set("append"); m.Has("group") { - group := m.Option("group") - nrow := len(msg.Meta[msg.Meta["append"][0]]) - - for i := 0; i < nrow; i++ { - count := 1 - - if group != "" && msg.Meta[group][i] == "" { - msg.Add("append", "count", 0) - continue - } - - for j := i + 1; j < nrow; j++ { - if group == "" || msg.Meta[group][i] == msg.Meta[group][j] { - count++ - for _, k := range msg.Meta["append"] { - if k == "count" { - continue - } - if k == group { - continue - } - m, e := strconv.Atoi(msg.Meta[k][i]) - if e != nil { - continue - } - n, e := strconv.Atoi(msg.Meta[k][j]) - if e != nil { - continue - } - msg.Meta[k][i] = fmt.Sprintf("%d", m+n) - - } - - if group != "" { - msg.Meta[group][j] = "" - } - } - } - - msg.Add("append", "count", count) - for _, k := range msg.Meta["append"] { - m.Add("append", k, msg.Meta[k][i]) - } - if group == "" { - break - } - } - } else { - m.Copy(msg, "append") - } - - // 排序 - if m.Has("order") { - m.Sort(m.Option("order"), kit.Select("str", m.Meta["order"], 1)) - } - - // 分页 - offset := kit.Int(kit.Select("0", m.Option("offset"))) - limit := kit.Int(kit.Select(m.Conf("table", "limit"), m.Option("table.limit"))) - - nrow = len(m.Meta[m.Meta["append"][0]]) - if offset > nrow { - offset = nrow - } - if limit+offset > nrow { - limit = nrow - offset - } - for _, k := range m.Meta["append"] { - m.Meta[k] = m.Meta[k][offset : offset+limit] - } - - // 值转换 - for i := 0; i < len(m.Meta["trans_map"]); i += 3 { - trans := m.Meta["trans_map"][i:] - for j := 0; j < len(m.Meta[trans[0]]); j++ { - if m.Meta[trans[0]][j] == trans[1] { - m.Meta[trans[0]][j] = trans[2] - } - } - } - - // 格式化 - for i := 0; i < len(m.Meta["format"])-1; i += 2 { - format := m.Meta["format"] - for j, v := range m.Meta[format[i]] { - if v != "" { - m.Meta[format[i]][j] = fmt.Sprintf(format[i+1], v) - } - } - } - - // 变换列 - if m.Has("vertical") { - msg := m.Spawn() - nrow := len(m.Meta[m.Meta["append"][0]]) - sort.Strings(m.Meta["append"]) - msg.Add("append", "field", "") - msg.Add("append", "value", "") - for i := 0; i < nrow; i++ { - for _, k := range m.Meta["append"] { - msg.Add("append", "field", k) - msg.Add("append", "value", m.Meta[k][i]) - } - msg.Add("append", "field", "") - msg.Add("append", "value", "") - } - m.Set("append").Copy(msg, "append") - } - - // 取单值 - // if len(arg) > 2 { - // if len(m.Meta[arg[2]]) > 0 { - // m.Echo(m.Meta[arg[2]][0]) - // } - // return - // } - - m.Set("result").Table() - return - }}, - }, -} - -func Start(args ...string) bool { - runtime.GOMAXPROCS(1) - - if len(args) == 0 { - args = append(args, os.Args[1:]...) - } - if len(args) > 0 && args[0] == "start" { - args = args[1:] - } - if len(args) > 0 && args[0] == "daemon" { - Pulse.Options("bio.modal", "daemon") - Pulse.Options("daemon", true) - args = args[1:] - } - - kit.DisableLog = true - if Index.Begin(Pulse, args...); Index.Start(Pulse, args...) { - return Index.Close(Pulse, args...) - } - return Index.message.Wait() -} diff --git a/usr/local/honor/src/contexts/ctx/misc.go b/usr/local/honor/src/contexts/ctx/misc.go deleted file mode 100644 index 92205942..00000000 --- a/usr/local/honor/src/contexts/ctx/misc.go +++ /dev/null @@ -1,686 +0,0 @@ -package ctx - -import ( - "encoding/csv" - "fmt" - "os" - "regexp" - "runtime" - "sort" - "strings" - "time" - "toolkit" -) - -func (m *Message) Log(action string, str string, arg ...interface{}) *Message { - if action == "error" { - kit.Log("error", fmt.Sprintf("chain: %s", m.Format("chain"))) - kit.Log("error", fmt.Sprintf("%s %s %s", m.Format(), action, fmt.Sprintf(str, arg...))) - kit.Log("error", fmt.Sprintf("stack: %s", m.Format("stack"))) - } - - // if m.Options("log.disable") { - // return m - // } - - if l := m.Sess("log", false); l != nil { - if log, ok := l.target.Server.(LOGGER); ok { - if action == "error" { - log.Log(m, "error", "chain: %s", m.Format("chain")) - } - if log.Log(m, action, str, arg...); action == "error" { - log.Log(m, "error", "stack: %s", m.Format("stack")) - } - return m - } - } else { - fmt.Fprintf(os.Stderr, str, arg...) - } - - return m -} -func (m *Message) Gdb(arg ...interface{}) interface{} { - // if !m.Options("log.enable") { - // return "" - // } - - if g := m.Sess("gdb", false); g != nil { - if gdb, ok := g.target.Server.(DEBUG); ok { - return gdb.Wait(m, arg...) - } - } - return "" -} -func (m *Message) Show(str string, args ...interface{}) *Message { - res := fmt.Sprintf(str, args...) - - if m.Option("bio.modal") == "action" { - fmt.Fprintf(os.Stderr, res) - } else if kit.STDIO != nil { - kit.STDIO.Show(res) - } else { - m.Log("info", "show: %v", res) - } - return m -} -func (m *Message) Format(arg ...interface{}) string { - if len(arg) == 0 { - arg = append(arg, "time", "ship") - } - - meta := []string{} - for _, v := range arg { - switch kit.Format(v) { - case "cost": - meta = append(meta, kit.FmtTime(time.Now().Sub(m.time).Nanoseconds())) - - case "summary": - msg := arg[1].(*Message) - ms := make([]*Message, 0, 1024) - ms = append(ms, msg.message, msg) - - for i := 0; i < len(ms); i++ { - msg := ms[i] - if m.Add("append", "index", i); msg == nil { - m.Add("append", "message", "") - m.Add("append", "time", "") - m.Add("append", "code", "") - m.Add("append", "source", "") - m.Add("append", "target", "") - m.Add("append", "details", "") - m.Add("append", "options", "") - continue - } - - if msg.message != nil { - m.Add("append", "message", msg.message.code) - } else { - m.Add("append", "message", "") - } - m.Add("append", "time", msg.time.Format("15:04:05")) - m.Add("append", "code", msg.code) - m.Add("append", "source", msg.source.Name) - m.Add("append", "target", msg.target.Name) - m.Add("append", "details", fmt.Sprintf("%v", msg.Meta["detail"])) - m.Add("append", "options", fmt.Sprintf("%v", msg.Meta["option"])) - - if i == 0 { - continue - } - - if len(ms) < 30 && len(arg) > 2 && arg[2] == "deep" { - ms = append(ms, ms[i].messages...) - } - } - m.Table() - case "time": - meta = append(meta, m.Time()) - case "mill": - meta = append(meta, fmt.Sprintf("%d", int64(m.time.UnixNano())/1000%1000000)) - case "code": - meta = append(meta, kit.Format(m.code)) - case "ship": - meta = append(meta, fmt.Sprintf("%s:%d(%s->%s)", m.Option("ctx.routine"), m.code, m.source.Name, m.target.Name)) - case "source": - target := m.target - m.target = m.source - meta = append(meta, m.Cap("module")) - m.target = target - case "target": - meta = append(meta, m.Cap("module")) - - case "detail": - meta = append(meta, fmt.Sprintf("%v", m.Meta["detail"])) - case "option": - meta = append(meta, fmt.Sprintf("%v", m.Meta["option"])) - case "append": - meta = append(meta, fmt.Sprintf("%v", m.Meta["append"])) - case "result": - meta = append(meta, fmt.Sprintf("%v", m.Meta["result"])) - - case "full": - case "chain": - ms := []*Message{} - if v == "full" { - ms = append(ms, m) - } else { - for msg := m; msg != nil; msg = msg.message { - ms = append(ms, msg) - } - } - - meta = append(meta, "\n") - for i := len(ms) - 1; i >= 0; i-- { - msg := ms[i] - - meta = append(meta, fmt.Sprintf("%s", msg.Format("time", "ship"))) - if len(msg.Meta["detail"]) > 0 { - meta = append(meta, fmt.Sprintf("detail:%d %v", len(msg.Meta["detail"]), msg.Meta["detail"])) - } - - if len(msg.Meta["option"]) > 0 { - meta = append(meta, fmt.Sprintf("option:%d %v\n", len(msg.Meta["option"]), msg.Meta["option"])) - for _, k := range msg.Meta["option"] { - if v, ok := msg.Meta[k]; ok { - meta = append(meta, fmt.Sprintf(" %s: %d %v\n", k, len(v), v)) - } - } - } else { - meta = append(meta, "\n") - } - - if len(msg.Meta["append"]) > 0 { - meta = append(meta, fmt.Sprintf(" append:%d %v\n", len(msg.Meta["append"]), msg.Meta["append"])) - for _, k := range msg.Meta["append"] { - if v, ok := msg.Meta[k]; ok { - meta = append(meta, fmt.Sprintf(" %s: %d %v\n", k, len(v), v)) - } - } - } - if len(msg.Meta["result"]) > 0 { - meta = append(meta, fmt.Sprintf(" result:%d %v\n", len(msg.Meta["result"]), msg.Meta["result"])) - } - } - case "stack": - pc := make([]uintptr, 100) - pc = pc[:runtime.Callers(5, pc)] - frames := runtime.CallersFrames(pc) - - for { - frame, more := frames.Next() - file := strings.Split(frame.File, "/") - name := strings.Split(frame.Function, "/") - meta = append(meta, fmt.Sprintf("\n%s:%d\t%s", file[len(file)-1], frame.Line, name[len(name)-1])) - if !more { - break - } - } - - default: - meta = append(meta, kit.Format(v)) - } - } - return strings.Join(meta, " ") -} -func (m *Message) Short(arg ...string) { - for _, k := range arg { - if v := m.Option(k); v != "" && len(v) != 32 { - m.Option(k, m.Cmdx("aaa.short", v)) - } - } -} -func (m *Message) Err(str string, arg ...interface{}) { - m.Echo("").Echo("error: ").Echo(str, arg...) -} - -func (m *Message) Start(name string, help string, arg ...string) bool { - return m.Set("detail", arg).target.Spawn(m, name, help).Begin(m).Start(m) -} -func (m *Message) Wait() bool { - if m.target.exit != nil { - return <-m.target.exit - } - return true -} -func (m *Message) Find(name string, root ...bool) *Message { - if name == "" { - return m.Spawn() - } - target := m.target.root - if len(root) > 0 && !root[0] { - target = m.target - } - - cs := target.contexts - for _, v := range strings.Split(name, ".") { - if x, ok := cs[v]; ok { - target, cs = x, x.contexts - } else if target.Name == v { - continue - } else { - return nil - } - } - - if len(root) > 1 && root[1] { - m.target = target - return m - } - - return m.Spawn(target) -} -func (m *Message) Search(key string, root ...bool) []*Message { - reg, e := regexp.Compile(key) - m.Assert(e) - - target := m.target - if target == nil { - return []*Message{nil} - } - if len(root) > 0 && root[0] { - target = m.target.root - } - - cs := make([]*Context, 0, 3) - target.Travel(m, func(m *Message, i int) bool { - if reg.MatchString(m.target.Name) || reg.FindString(m.target.Help) != "" { - cs = append(cs, m.target) - } - return false - }) - - ms := make([]*Message, len(cs)) - for i := 0; i < len(cs); i++ { - ms[i] = m.Spawn(cs[i]) - } - if len(ms) == 0 { - ms = append(ms, nil) - } - - return ms -} -func (c *Context) Travel(m *Message, hand func(m *Message, n int) (stop bool)) *Context { - if c == nil { - return nil - } - target := m.target - - cs := []*Context{c} - for i := 0; i < len(cs); i++ { - if m.target = cs[i]; hand(m, i) { - return cs[i] - } - - keys := []string{} - for k, _ := range cs[i].contexts { - keys = append(keys, k) - } - sort.Strings(keys) - for _, k := range keys { - cs = append(cs, cs[i].contexts[k]) - } - } - - m.target = target - return target -} -func (c *Context) BackTrace(m *Message, hand func(m *Message) (stop bool)) *Context { - target := m.target - - for s := m.target; s != nil; s = s.context { - if m.target = s; hand(m) { - return s - } - } - - m.target = target - return target -} - -func (m *Message) Add(meta string, key string, value ...interface{}) *Message { - if m.Meta == nil { - m.Meta = make(map[string][]string) - } - if _, ok := m.Meta[meta]; !ok { - m.Meta[meta] = make([]string, 0, 3) - } - - switch meta { - case "detail", "result": - m.Meta[meta] = append(m.Meta[meta], key) - m.Meta[meta] = append(m.Meta[meta], kit.Trans(value...)...) - - case "option", "append": - if _, ok := m.Meta[key]; !ok { - m.Meta[key] = make([]string, 0, 3) - } - m.Meta[key] = append(m.Meta[key], kit.Trans(value...)...) - - for _, v := range m.Meta[meta] { - if v == key { - return m - } - } - m.Meta[meta] = append(m.Meta[meta], key) - - default: - m.Log("error", "add meta error %s %s %v", meta, key, value) - } - - return m -} -func (m *Message) Set(meta string, arg ...interface{}) *Message { - switch meta { - case "detail", "result": - if m != nil && m.Meta != nil { - delete(m.Meta, meta) - } - case "option", "append": - if len(arg) > 0 { - for _, k := range arg { - delete(m.Data, kit.Format(k)) - delete(m.Meta, kit.Format(k)) - } - } else { - for _, k := range m.Meta[meta] { - delete(m.Data, k) - delete(m.Meta, k) - } - delete(m.Meta, meta) - } - default: - m.Log("error", "set meta error %s %s %v", meta, arg) - } - - if args := kit.Trans(arg...); len(args) > 0 { - m.Add(meta, args[0], args[1:]) - } - return m -} -func (m *Message) Put(meta string, key string, value interface{}) *Message { - switch meta { - case "option", "append": - if m.Set(meta, key); m.Data == nil { - m.Data = make(map[string]interface{}) - } - m.Data[key] = value - - default: - m.Log("error", "put data error %s %s %v", meta, key, value) - } - return m -} -func (m *Message) Get(key string, arg ...interface{}) string { - if meta, ok := m.Meta[key]; ok && len(meta) > 0 { - index := 0 - if len(arg) > 0 { - index = kit.Int(arg[0]) - } - - index = (index+2)%(len(meta)+2) - 2 - if index >= 0 && index < len(meta) { - return meta[index] - } - } - return "" -} -func (m *Message) Has(key ...string) bool { - switch len(key) { - case 1: - if _, ok := m.Data[key[0]]; ok { - return true - } - if _, ok := m.Meta[key[0]]; ok { - return true - } - } - return false -} -func (m *Message) CopyTo(msg *Message, arg ...string) *Message { - msg.Copy(m, "append").Copy(m, "result") - return m -} -func (m *Message) CopyFuck(msg *Message, arg ...string) *Message { - if m == msg { - return m - } - - for i := 0; i < len(arg); i++ { - meta := arg[i] - - switch meta { - case "target": - m.target = msg.target - case "callback": - m.callback = msg.callback - case "detail", "result": - if len(msg.Meta[meta]) > 0 { - m.Add(meta, msg.Meta[meta][0], msg.Meta[meta][1:]) - } - case "option", "append": - if msg.Meta == nil { - msg.Meta = map[string][]string{} - } - if msg.Meta[meta] == nil { - break - } - if i == len(arg)-1 { - arg = append(arg, msg.Meta[meta]...) - } - - for i++; i < len(arg); i++ { - if v, ok := msg.Data[arg[i]]; ok { - m.Put(meta, arg[i], v) - } else if v, ok := msg.Meta[arg[i]]; ok { - m.Add(meta, arg[i], v) // TODO fuck Add - } - } - default: - if msg.Hand { - meta = "append" - } else { - meta = "option" - } - - if v, ok := msg.Data[arg[i]]; ok { - m.Put(meta, arg[i], v) - } - if v, ok := msg.Meta[arg[i]]; ok { - m.Add(meta, arg[i], v) - } - } - } - - return m -} -func (m *Message) ToHTML(style string) string { - cmd := strings.Join(m.Meta["detail"], " ") - result := []string{} - if len(m.Meta["append"]) > 0 { - result = append(result, fmt.Sprintf("
", v, " | ") - } - result = append(result, "
---|
", maps[k], " | ") - } - result = append(result, "
")
- result = append(result, fmt.Sprintf("%s", m.Find("shy", false).Conf("prompt")), cmd, "\n")
- result = append(result, m.Meta["result"]...)
- result = append(result, "
")
- }
- return strings.Join(result, "")
-}
-
-func (m *Message) Grow(key string, args interface{}, data interface{}) interface{} {
- cache := m.Confm(key, args)
- if args == nil {
- cache = m.Confm(key)
- }
- if cache == nil {
- cache = map[string]interface{}{}
- }
- meta, ok := cache["meta"].(map[string]interface{})
- if !ok {
- meta = map[string]interface{}{}
- }
- list, _ := cache["list"].([]interface{})
-
- list = append(list, data)
- if len(list) > kit.Int(kit.Select(m.Conf("cache", "limit"), meta["limit"])) {
- offset := kit.Int(meta["offset"])
- least := kit.Int(kit.Select(m.Conf("cache", "least"), meta["least"]))
-
- name := kit.Select(m.Option("cache.store"), meta["store"])
- f, e := os.OpenFile(name, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666)
- if e != nil {
- f, _, e = kit.Create(name)
- }
- defer f.Close()
- s, e := f.Stat()
- m.Assert(e)
-
- keys := []string{}
- w := csv.NewWriter(f)
- if s.Size() == 0 {
- for k := range list[0].(map[string]interface{}) {
- keys = append(keys, k)
- }
- sort.Strings(keys)
- w.Write(keys)
- w.Flush()
- s, e = f.Stat()
- } else {
- r := csv.NewReader(f)
- keys, e = r.Read()
- }
-
- count := len(list) - least
- record, _ := meta["record"].([]interface{})
- meta["record"] = append(record, map[string]interface{}{
- "time": m.Time(),
- "offset": offset,
- "position": s.Size(),
- "count": count,
- "file": name,
- })
-
- for i, v := range list {
- if i >= count {
- break
- }
-
- val := v.(map[string]interface{})
-
- values := []string{}
- for _, k := range keys {
- values = append(values, kit.Format(val[k]))
- }
- w.Write(values)
-
- if i < least {
- list[i] = list[count+i]
- }
- }
-
- m.Log("info", "save %s offset %v+%v", name, offset, count)
- meta["offset"] = offset + count
- list = list[:least]
- w.Flush()
- }
- cache["meta"] = meta
- cache["list"] = list
- if args == nil {
- m.Conf(key, cache)
- } else {
- m.Conf(key, args, cache)
- }
- return list
-}
-func (m *Message) Grows(key string, args interface{}, cb interface{}) map[string]interface{} {
- cache := m.Confm(key, args)
- if args == nil {
- cache = m.Confm(key)
- }
- if cache == nil {
- return nil
- }
- meta, ok := cache["meta"].(map[string]interface{})
- if !ok {
- return nil
- }
- list, ok := cache["list"].([]interface{})
- if !ok {
- return nil
- }
-
- offend := kit.Int(kit.Select("0", m.Option("cache.offend")))
- limit := kit.Int(kit.Select("10", m.Option("cache.limit")))
- match := kit.Select("", m.Option("cache.match"))
- value := kit.Select("", m.Option("cache.value"))
- current := kit.Int(meta["offset"])
- end := current + len(list) - offend
- begin := end - limit
-
- data := make([]interface{}, 0, limit)
- m.Log("info", "read %v-%v from %v-%v", begin, end, current, current+len(list))
- if begin < current {
- store, _ := meta["record"].([]interface{})
- for s := len(store) - 1; s > -1; s-- {
- item, _ := store[s].(map[string]interface{})
- line := kit.Int(item["offset"])
- m.Log("info", "check history %v %v %v", s, line, item)
- if begin < line && s > 0 {
- continue
- }
-
- for ; s < len(store); s++ {
- if begin >= end {
- break
- }
- item, _ := store[s].(map[string]interface{})
- if line+kit.Int(item["count"]) < begin {
- continue
- }
-
- name := kit.Format(item["file"])
- pos := kit.Int(item["position"])
- line := kit.Int(item["offset"])
- m.Log("info", "load history %v %v %v", s, line, item)
- if f, e := os.Open(name); m.Assert(e) {
- defer f.Close()
- r := csv.NewReader(f)
- heads, _ := r.Read()
- m.Log("info", "load head %v", heads)
-
- f.Seek(int64(pos), os.SEEK_SET)
- r = csv.NewReader(f)
- for i := line; i < end; i++ {
- lines, e := r.Read()
- if e != nil {
- break
- }
-
- if i >= begin {
- item := map[string]interface{}{}
- for i := range heads {
- item[heads[i]] = lines[i]
- }
- m.Log("info", "load line %v %v %v", i, len(data), item)
- if match == "" || strings.Contains(kit.Format(item[match]), value) {
- data = append(data, item)
- }
- begin = i + 1
- } else {
- m.Log("info", "skip line %v", i)
- }
- }
- }
- }
- break
- }
- }
-
- if begin < current {
- begin = current
- }
- m.Log("info", "cache %v-%v", begin-current, end-current)
- for i := begin - current; i < end-current; i++ {
- if match == "" || strings.Contains(kit.Format(kit.Chain(list[i], match)), value) {
- data = append(data, list[i])
- }
- }
- return kit.Map(map[string]interface{}{"meta": meta, "list": data}, "", cb)
-}
diff --git a/usr/local/honor/src/contexts/ctx/type.go b/usr/local/honor/src/contexts/ctx/type.go
deleted file mode 100644
index eece3e93..00000000
--- a/usr/local/honor/src/contexts/ctx/type.go
+++ /dev/null
@@ -1,879 +0,0 @@
-package ctx
-
-import (
- "fmt"
- _ "github.com/shylinux/icebergs"
- "strconv"
- "strings"
- "time"
- "toolkit"
-)
-
-type Cache struct {
- Value string
- Name string
- Help string
- Hand func(m *Message, x *Cache, arg ...string) string
-}
-type Config struct {
- Value interface{}
- Name string
- Help string
- Hand func(m *Message, x *Config, arg ...string) string
-}
-type Command struct {
- Form map[string]int
- Name string
- Help interface{}
- Auto func(m *Message, c *Context, key string, arg ...string) (ok bool)
- Hand func(m *Message, c *Context, key string, arg ...string) (e error)
-}
-type Context struct {
- Name string
- Help string
-
- Caches map[string]*Cache
- Configs map[string]*Config
- Commands map[string]*Command
-
- message *Message
- requests []*Message
- sessions []*Message
-
- contexts map[string]*Context
- context *Context
- root *Context
-
- exit chan bool
- Server
-}
-type Server interface {
- Spawn(m *Message, c *Context, arg ...string) Server
- Begin(m *Message, arg ...string) Server
- Start(m *Message, arg ...string) bool
- Close(m *Message, arg ...string) bool
-}
-
-func (c *Context) Context() *Context {
- return c.context
-}
-func (c *Context) Message() *Message {
- return c.message
-}
-
-type Message struct {
- time time.Time
- code int
-
- source *Context
- target *Context
-
- Hand bool
- Meta map[string][]string
- Data map[string]interface{}
- Sync chan bool
-
- callback func(msg *Message) (sub *Message)
- freeback []func(msg *Message) (done bool)
- Sessions map[string]*Message
-
- messages []*Message
- message *Message
- root *Message
-}
-type LOGGER interface {
- Log(*Message, string, string, ...interface{})
-}
-type DEBUG interface {
- Wait(*Message, ...interface{}) interface{}
- Goon(interface{}, ...interface{})
-}
-
-func (m *Message) Time(arg ...interface{}) string {
- t := m.time
- if len(arg) > 0 {
- if d, e := time.ParseDuration(arg[0].(string)); e == nil {
- arg, t = arg[1:], t.Add(d)
- }
- }
-
- str := m.Conf("time", "format")
- if len(arg) > 1 {
- str = fmt.Sprintf(arg[0].(string), arg[1:]...)
- } else if len(arg) > 0 {
- str = fmt.Sprintf("%v", arg[0])
- }
-
- if str == "stamp" {
- return kit.Format(t.Unix())
- }
- return t.Format(str)
-}
-func (m *Message) Code() int {
- return m.code
-}
-func (m *Message) Source() *Context {
- return m.source
-}
-func (m *Message) Target() *Context {
- return m.target
-}
-
-func (m *Message) Insert(meta string, index int, arg ...interface{}) string {
- if m == nil {
- return ""
- }
- if m.Meta == nil {
- m.Meta = make(map[string][]string)
- }
- m.Meta[meta] = kit.Array(m.Meta[meta], index, arg)
-
- if -1 < index && index < len(m.Meta[meta]) {
- return m.Meta[meta][index]
- }
- return ""
-}
-func (m *Message) Detail(arg ...interface{}) string {
- noset, index := true, 0
- if len(arg) > 0 {
- switch v := arg[0].(type) {
- case int:
- noset, index, arg = false, v, arg[1:]
- }
- }
- if noset && len(arg) > 0 {
- index = -2
- }
-
- return m.Insert("detail", index, arg...)
-}
-func (m *Message) Option(key string, arg ...interface{}) string {
- if m == nil {
- return ""
- }
- if len(arg) > 0 {
- m.Insert(key, 0, arg...)
- if _, ok := m.Meta[key]; ok {
- m.Add("option", key)
- }
- }
-
- for msg := m; msg != nil; msg = msg.message {
- if !msg.Has(key) {
- continue
- }
- for _, k := range msg.Meta["option"] {
- if k == key {
- return msg.Get(key)
- }
- }
- }
- return ""
-}
-func (m *Message) Optioni(key string, arg ...interface{}) int {
- return kit.Int(m.Option(key, arg...))
-
-}
-func (m *Message) Options(key string, arg ...interface{}) bool {
- return kit.Right(m.Option(key, arg...))
-}
-func (m *Message) Optionv(key string, arg ...interface{}) interface{} {
- if len(arg) > 0 {
- switch arg[0].(type) {
- case nil:
- default:
- m.Put("option", key, arg[0])
- }
- }
-
- for msg := m; msg != nil; msg = msg.message {
- if msg.Meta == nil || !msg.Has(key) {
- continue
- }
- for _, k := range msg.Meta["option"] {
- if k == key {
- if v, ok := msg.Data[key]; ok {
- return v
- }
- return msg.Meta[key]
- }
- }
- }
- return nil
-}
-func (m *Message) Append(key string, arg ...interface{}) string {
- if len(arg) > 0 {
- m.Insert(key, 0, arg...)
- if _, ok := m.Meta[key]; ok {
- m.Add("append", key)
- }
- }
-
- ms := []*Message{m}
- for i := 0; i < len(ms); i++ {
- ms = append(ms, ms[i].messages...)
- if !ms[i].Has(key) {
- continue
- }
- for _, k := range ms[i].Meta["append"] {
- if k == key {
- return ms[i].Get(key)
- }
- }
- }
- return ""
-}
-func (m *Message) Appendi(key string, arg ...interface{}) int64 {
- i, _ := strconv.ParseInt(m.Append(key, arg...), 10, 64)
- return i
-}
-func (m *Message) Appends(key string, arg ...interface{}) bool {
- return kit.Right(m.Append(key, arg...))
-}
-func (m *Message) Result(arg ...interface{}) string {
- noset, index := true, 0
- if len(arg) > 0 {
- switch v := arg[0].(type) {
- case int:
- noset, index, arg = false, v, arg[1:]
- }
- }
- if noset && len(arg) > 0 {
- index = -2
- }
-
- return m.Insert("result", index, arg...)
-}
-
-func (m *Message) Push(key interface{}, arg ...interface{}) *Message {
- keys := []string{}
- switch key := key.(type) {
- case string:
- keys = strings.Split(key, " ")
- case []string:
- keys = key
- }
-
- for _, key := range keys {
- switch m.Option("table.format") {
- case "table":
- m.Add("append", "key", key)
- key = "value"
- }
- switch value := arg[0].(type) {
- case map[string]interface{}:
- m.Add("append", key, kit.Select(" ", kit.Format(kit.Chain(value, key))))
- default:
- m.Add("append", key, arg...)
- }
- }
- return m
-}
-func (m *Message) Sort(key string, arg ...string) *Message {
- cmp := "str"
- if len(arg) > 0 && arg[0] != "" {
- cmp = arg[0]
- } else {
- cmp = "int"
- for _, v := range m.Meta[key] {
- if _, e := strconv.Atoi(v); e != nil {
- cmp = "str"
- }
- }
- }
-
- number := map[int]int{}
- table := []map[string]string{}
- m.Table(func(index int, line map[string]string) {
- table = append(table, line)
- switch cmp {
- case "int":
- number[index] = kit.Int(line[key])
- case "int_r":
- number[index] = -kit.Int(line[key])
- case "time":
- number[index] = kit.Time(line[key])
- case "time_r":
- number[index] = -kit.Time(line[key])
- }
- })
-
- for i := 0; i < len(table)-1; i++ {
- for j := i + 1; j < len(table); j++ {
- result := false
- switch cmp {
- case "", "str":
- if table[i][key] > table[j][key] {
- result = true
- }
- case "str_r":
- if table[i][key] < table[j][key] {
- result = true
- }
- default:
- if number[i] > number[j] {
- result = true
- }
- }
-
- if result {
- table[i], table[j] = table[j], table[i]
- number[i], number[j] = number[j], number[i]
- }
- }
- }
-
- for _, k := range m.Meta["append"] {
- delete(m.Meta, k)
- }
-
- for _, v := range table {
- for _, k := range m.Meta["append"] {
- m.Add("append", k, v[k])
- }
- }
- return m
-}
-func (m *Message) Split(str string, arg ...string) *Message {
- c := rune(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(l) == 0 {
- continue
- }
- if len(pos) > 0 {
- for i, v := range pos {
- if v < len(l) && i == len(pos)-1 {
- m.Add("append", heads[i], strings.TrimSpace(l[v:]))
- } else if v < len(l) && i+1 < len(pos) && pos[i+1] < len(l) {
- m.Add("append", heads[i], strings.TrimSpace(l[v:pos[i+1]]))
- } else {
- m.Add("append", heads[i], "")
- }
- }
- continue
- }
- ls := kit.Split(l, c, len(heads))
- for i, v := range heads {
- m.Add("append", v, kit.Select("", ls, i))
- }
- }
- m.Table()
- return m
-}
-func (m *Message) Limit(offset, limit int) *Message {
- l := len(m.Meta[m.Meta["append"][0]])
- if offset < 0 {
- offset = 0
- }
- if offset > l {
- offset = l
- }
- if offset+limit > l {
- limit = l - offset
- }
- for _, k := range m.Meta["append"] {
- m.Meta[k] = m.Meta[k][offset : offset+limit]
- }
- return m
-}
-func (m *Message) Filter(value string) *Message {
-
- return m
-}
-func (m *Message) Group(method string, args ...string) *Message {
-
- nrow := len(m.Meta[m.Meta["append"][0]])
-
- keys := map[string]bool{}
- for _, v := range args {
- keys[v] = true
- }
-
- counts := []int{}
- mis := map[int]bool{}
- for i := 0; i < nrow; i++ {
- counts = append(counts, 1)
- if mis[i] {
- continue
- }
- next:
- for j := i + 1; j < nrow; j++ {
- if mis[j] {
- continue
- }
- for key := range keys {
- if m.Meta[key][i] != m.Meta[key][j] {
- continue next
- }
- }
- for _, k := range m.Meta["append"] {
- if !keys[k] {
- switch method {
- case "sum", "avg":
- v1, e1 := strconv.Atoi(m.Meta[k][i])
- v2, e2 := strconv.Atoi(m.Meta[k][j])
- if e1 == nil && e2 == nil {
- m.Meta[k][i] = fmt.Sprintf("%d", v1+v2)
- }
- }
- }
- }
- mis[j] = true
- counts[i]++
- }
- }
-
- for i := 0; i < nrow; i++ {
- for _, k := range m.Meta["append"] {
- if !keys[k] {
- switch method {
- case "avg":
- if v1, e1 := strconv.Atoi(m.Meta[k][i]); e1 == nil {
- m.Meta[k][i] = strconv.Itoa(v1 / counts[i])
- }
- }
- }
- }
- }
- for i := 0; i < nrow; i++ {
- m.Push("_counts", counts[i])
- }
-
- for i := 0; i < nrow; i++ {
- if mis[i] {
- for j := i + 1; j < nrow; j++ {
- if !mis[j] {
- for _, k := range m.Meta["append"] {
- m.Meta[k][i] = m.Meta[k][j]
- }
- mis[i], mis[j] = false, true
- break
- }
- }
- }
- if mis[i] {
- for _, k := range m.Meta["append"] {
- m.Meta[k] = m.Meta[k][0:i]
- }
- break
- }
- }
- return m
-}
-func (m *Message) Table(cbs ...interface{}) *Message {
- if len(m.Meta["append"]) == 0 {
- return m
- }
-
- // 遍历函数
- if len(cbs) > 0 {
- nrow := len(m.Meta[m.Meta["append"][0]])
- for i := 0; i < nrow; i++ {
- line := map[string]string{}
- for _, k := range m.Meta["append"] {
- line[k] = kit.Select("", m.Meta[k], i)
- }
-
- switch cb := cbs[0].(type) {
- case func(map[string]string):
- cb(line)
- case func(map[string]string) bool:
- if !cb(line) {
- return m
- }
- case func(int, map[string]string):
- cb(i, line)
- }
- }
- return m
- }
-
- //计算列宽
- space := kit.Select(m.Conf("table", "space"), m.Option("table.space"))
- depth, width := 0, map[string]int{}
- for _, k := range m.Meta["append"] {
- if len(m.Meta[k]) > depth {
- depth = len(m.Meta[k])
- }
- width[k] = kit.Width(k, len(space))
- for _, v := range m.Meta[k] {
- if kit.Width(v, len(space)) > width[k] {
- width[k] = kit.Width(v, len(space))
- }
- }
- }
-
- // 回调函数
- rows := kit.Select(m.Conf("table", "row_sep"), m.Option("table.row_sep"))
- cols := kit.Select(m.Conf("table", "col_sep"), m.Option("table.col_sep"))
- compact := kit.Right(kit.Select(m.Conf("table", "compact"), m.Option("table.compact")))
- cb := func(maps map[string]string, lists []string, line int) bool {
- for i, v := range lists {
- if k := m.Meta["append"][i]; compact {
- v = maps[k]
- }
-
- if m.Echo(v); i < len(lists)-1 {
- m.Echo(cols)
- }
- }
- m.Echo(rows)
- return true
- }
-
- // 输出表头
- row := map[string]string{}
- wor := []string{}
- for _, k := range m.Meta["append"] {
- row[k], wor = k, append(wor, k+strings.Repeat(space, width[k]-kit.Width(k, len(space))))
- }
- if !cb(row, wor, -1) {
- return m
- }
-
- // 输出数据
- for i := 0; i < depth; i++ {
- row := map[string]string{}
- wor := []string{}
- for _, k := range m.Meta["append"] {
- data := ""
- if i < len(m.Meta[k]) {
- data = m.Meta[k][i]
- }
-
- row[k], wor = data, append(wor, data+strings.Repeat(space, width[k]-kit.Width(data, len(space))))
- }
- if !cb(row, wor, i) {
- break
- }
- }
-
- return m
-}
-func (m *Message) Copy(msg *Message, arg ...string) *Message {
- if msg == nil || m == msg {
- return m
- }
-
- for i := 0; i < len(arg); i++ {
- meta := arg[i]
-
- switch meta {
- case "target":
- m.target = msg.target
- case "callback":
- m.callback = msg.callback
- case "detail", "result":
- if len(msg.Meta[meta]) > 0 {
- m.Add(meta, msg.Meta[meta][0], msg.Meta[meta][1:])
- }
- case "option", "append":
- if msg.Meta == nil {
- msg.Meta = map[string][]string{}
- }
- if msg.Meta[meta] == nil {
- break
- }
- if i == len(arg)-1 {
- arg = append(arg, msg.Meta[meta]...)
- }
-
- for i++; i < len(arg); i++ {
- if v, ok := msg.Data[arg[i]]; ok {
- m.Put(meta, arg[i], v)
- } else if v, ok := msg.Meta[arg[i]]; ok {
- m.Set(meta, arg[i], v) // TODO fuck Add
- }
- }
- default:
- if msg.Hand {
- meta = "append"
- } else {
- meta = "option"
- }
-
- if v, ok := msg.Data[arg[i]]; ok {
- m.Put(meta, arg[i], v)
- }
- if v, ok := msg.Meta[arg[i]]; ok {
- m.Add(meta, arg[i], v)
- }
- }
- }
-
- return m
-}
-func (m *Message) Echo(str string, arg ...interface{}) *Message {
- if len(arg) > 0 {
- return m.Add("result", fmt.Sprintf(str, arg...))
- }
- return m.Add("result", str)
-}
-
-func (m *Message) Cmdp(t time.Duration, head []string, prefix []string, suffix [][]string) *Message {
- if head != nil && len(head) > 0 {
- m.Show(fmt.Sprintf("[%s]...\n", strings.Join(head, " ")))
- }
-
- for i, v := range suffix {
- m.Show(fmt.Sprintf("%v/%v %v...\n", i+1, len(suffix), v))
- m.CopyFuck(m.Cmd(prefix, v), "append")
- time.Sleep(t)
- }
- m.Show("\n")
- m.Table()
- return m
-}
-func (m *Message) Cmdy(args ...interface{}) *Message {
- m.Cmd(args...).CopyTo(m)
- return m
-}
-func (m *Message) Cmdx(args ...interface{}) string {
- msg := m.Cmd(args...)
- if msg.Result(0) == "error: " {
- return msg.Result(1)
- }
- return msg.Result(0)
-}
-func (m *Message) Cmds(args ...interface{}) bool {
- return kit.Right(m.Cmdx(args...))
-}
-func (m *Message) Cmd(args ...interface{}) *Message {
- if m == nil {
- return m
- }
-
- if len(args) > 0 {
- m.Set("detail", kit.Trans(args...))
- }
- key, arg := m.Meta["detail"][0], m.Meta["detail"][1:]
- if key == "_" {
- return m
- }
-
- msg := m
- if strings.Contains(key, ":") {
- ps := strings.Split(key, ":")
- if ps[0] == "_" {
- ps[0], arg = arg[0], arg[1:]
- }
- msg, key, arg = m.Sess("ssh"), "_route", append([]string{"sync", ps[0], ps[1]}, arg...)
- defer func() { m.Copy(msg, "append").Copy(msg, "result") }()
- m.Hand = true
-
- } else if strings.Contains(key, ".") {
- arg := strings.Split(key, ".")
- 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 {
- msg.Option("remote_code", "")
-
- }
- }
- if msg == nil {
- return msg
- }
-
- msg = msg.Match(key, true, func(msg *Message, s *Context, c *Context, key string) bool {
- msg.Hand = false
- if x, ok := c.Commands[key]; ok && x.Hand != nil {
- msg.TryCatch(msg, true, func(msg *Message) {
- msg.Log("cmd", "%s %s %v %v", c.Name, key, arg, msg.Meta["option"])
- msg.Hand = true
- x.Hand(msg, c, key, msg.Form(x, arg)...)
- })
- }
- return msg.Hand
- })
- return msg
-}
-
-func (m *Message) Confm(key string, args ...interface{}) map[string]interface{} {
- random := ""
-
- var chain interface{}
- if len(args) > 0 {
- switch arg := args[0].(type) {
- case []interface{}:
- chain, args = arg, args[1:]
- case []string:
- chain, args = arg, args[1:]
- case string:
- switch arg {
- case "%", "*":
- random, args = arg, args[1:]
- default:
- chain, args = arg, args[1:]
- }
- }
- }
-
- var v interface{}
- if chain == nil {
- v = m.Confv(key)
- } else {
- v = m.Confv(key, chain)
- }
- return kit.Map(v, random, args...)
-}
-func (m *Message) Confx(key string, args ...interface{}) string {
- value := kit.Select(m.Conf(key), m.Option(key))
- if len(args) == 0 {
- return value
- }
-
- switch arg := args[0].(type) {
- case []string:
- if len(args) > 1 {
- value = kit.Select(value, arg, args[1])
- } else {
- value = kit.Select(value, arg)
- }
- args = args[1:]
- case map[string]interface{}:
- value = kit.Select(value, kit.Format(arg[key]))
- case string:
- value = kit.Select(value, arg)
- case nil:
- default:
- value = kit.Select(value, args[0])
- }
-
- format := "%s"
- if args = args[1:]; len(args) > 0 {
- format, args = kit.Format(args[0]), args[1:]
- }
- arg := []interface{}{format, value}
- for _, v := range args {
- arg = append(arg, v)
- }
-
- return kit.Format(arg...)
-}
-func (m *Message) Confv(key string, args ...interface{}) interface{} {
- if strings.Contains(key, ".") {
- target := m.target
- defer func() { m.target = target }()
-
- ps := strings.Split(key, ".")
- if msg := m.Sess(ps[0], false); msg != nil {
- m.target, key = msg.target, ps[1]
- }
- }
-
- var config *Config
- m.Match(key, false, func(m *Message, s *Context, c *Context, key string) bool {
- if x, ok := c.Configs[key]; ok {
- config = x
- return true
- }
- return false
- })
-
- if len(args) == 0 {
- if config == nil {
- return nil
- }
- return config.Value
- }
-
- if config == nil {
- config = &Config{}
- m.target.Configs[key] = config
- }
-
- switch config.Value.(type) {
- case string:
- config.Value = kit.Format(args...)
- case bool:
- config.Value = kit.Right(args...)
- case int:
- config.Value = kit.Int(args...)
- case nil:
- config.Value = args[0]
- default:
- for i := 0; i < len(args); i += 2 {
- if i < len(args)-1 {
- config.Value = kit.Chain(config.Value, args[i], args[i+1])
- } else {
- return kit.Chain(config.Value, args[i])
- }
- }
- }
-
- return config.Value
-}
-func (m *Message) Confs(key string, arg ...interface{}) bool {
- return kit.Right(m.Confv(key, arg...))
-}
-func (m *Message) Confi(key string, arg ...interface{}) int {
- return kit.Int(m.Confv(key, arg...))
-}
-func (m *Message) Conf(key string, args ...interface{}) string {
- return kit.Format(m.Confv(key, args...))
-}
-func (m *Message) Caps(key string, arg ...interface{}) bool {
- if len(arg) > 0 {
- return kit.Right(m.Cap(key, arg...))
- }
- return kit.Right(m.Cap(key))
-}
-func (m *Message) Capi(key string, arg ...interface{}) int {
- n := kit.Int(m.Cap(key))
- if len(arg) > 0 {
- return kit.Int(m.Cap(key, n+kit.Int(arg...)))
- }
- return n
-}
-func (m *Message) Cap(key string, arg ...interface{}) string {
- var cache *Cache
- m.Match(key, false, func(m *Message, s *Context, c *Context, key string) bool {
- if x, ok := c.Caches[key]; ok {
- cache = x
- return true
- }
- return false
- })
-
- if len(arg) == 0 {
- if cache == nil {
- return ""
- }
- if cache.Hand != nil {
- return cache.Hand(m, cache)
- }
- return cache.Value
- }
-
- if cache == nil {
- cache = &Cache{}
- m.target.Caches[key] = cache
- }
-
- if cache.Hand != nil {
- cache.Value = cache.Hand(m, cache, kit.Format(arg...))
- } else {
- cache.Value = kit.Format(arg...)
- }
- return cache.Value
-}
diff --git a/usr/local/honor/src/contexts/gdb/gdb.go b/usr/local/honor/src/contexts/gdb/gdb.go
deleted file mode 100644
index 93c95d7f..00000000
--- a/usr/local/honor/src/contexts/gdb/gdb.go
+++ /dev/null
@@ -1,218 +0,0 @@
-package gdb
-
-import (
- "contexts/ctx"
- "toolkit"
-
- "os"
- "os/signal"
- "syscall"
- "time"
-)
-
-type GDB struct {
- feed map[string]chan interface{}
- wait chan interface{}
- goon chan os.Signal
-
- *ctx.Context
-}
-
-func (gdb *GDB) Value(m *ctx.Message, arg ...interface{}) bool {
- if value, ok := kit.Chain(gdb.Configs["debug"].Value, kit.Trans(arg, "value")).(map[string]interface{}); ok {
- if !kit.Right(value["enable"]) {
- return false
- }
-
- if kit.Right(value["source"]) && kit.Format(value["source"]) != m.Source().Name {
- return false
- }
-
- if kit.Right(value["target"]) && kit.Format(value["target"]) != m.Target().Name {
- return false
- }
-
- m.Log("error", "value %v %v", arg, kit.Formats(value))
- return true
- }
- return false
-}
-func (gdb *GDB) Wait(msg *ctx.Message, arg ...interface{}) interface{} {
- m := gdb.Message()
- if m.Cap("status") != "start" {
- return nil
- }
-
- for i := len(arg); i > 0; i-- {
- if gdb.Value(m, arg[:i]...) {
- if result := kit.Chain(kit.Chain(gdb.Configs["debug"].Value, arg[:i]), []string{"value", "result"}); result != nil {
- m.Log("error", "done %d %v", len(arg[:i]), arg)
- return result
- }
-
- feed := kit.Select("web", kit.Format(kit.Chain(kit.Chain(gdb.Configs["debug"].Value, arg[:i]), []string{"value", "feed"})))
-
- c, ok := gdb.feed[feed]
- if !ok {
- c = make(chan interface{})
- gdb.feed[feed] = c
- }
-
- m.Log("error", "wait %d %v", len(arg[:i]), arg)
- result := <-c
- m.Log("error", "done %d %v %v", len(arg[:i]), arg, result)
- return result
- }
- }
- return nil
-}
-func (gdb *GDB) Goon(result interface{}, arg ...interface{}) {
- m := gdb.Message()
- if m.Cap("status") != "start" {
- return
- }
-
- if m.Log("error", "goon %v %v", arg, result); len(arg) > 0 {
- if c, ok := gdb.feed[kit.Format(arg[0])]; ok {
- c <- result
- return
- }
- }
- gdb.wait <- result
-}
-
-func (gdb *GDB) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server {
- return &GDB{Context: c}
-}
-func (gdb *GDB) Begin(m *ctx.Message, arg ...string) ctx.Server {
- return gdb
-}
-func (gdb *GDB) Start(m *ctx.Message, arg ...string) bool {
- m.Cmd("nfs.save", m.Conf("logpid"), os.Getpid())
- gdb.wait = make(chan interface{}, 10)
- gdb.goon = make(chan os.Signal, 10)
- gdb.feed = map[string]chan interface{}{}
-
- m.Confm("signal", func(sig string, action string) {
- m.Log("signal", "add %s: %s", action, sig)
- signal.Notify(gdb.goon, syscall.Signal(kit.Int(sig)))
- })
-
- for {
- select {
- case sig := <-gdb.goon:
- action := m.Conf("signal", sig)
- m.Log("signal", "%v: %v", action, sig)
-
- switch action {
- case "QUIT", "INT":
- m.Cmd("cli.quit", 0)
- case "restart":
- m.Cmd("cli.quit", 1)
- case "TERM":
- m.Cmd("cli.quit", 2)
- case "upgrade":
- m.Cmd("cli.upgrade", "bench")
- m.Cmd("cli.upgrade", "system")
- case "WINCH":
- m.Cmd("nfs.term", "init")
- case "CONT":
- gdb.wait <- time.Now().Format("2006-01-02 15:04:05")
- default:
- // gdb.Goon(nil, "cache", "read", "value")
- }
- }
- }
- return true
-}
-func (gdb *GDB) Close(m *ctx.Message, arg ...string) bool {
- return false
-}
-
-var Index = &ctx.Context{Name: "gdb", Help: "调试中心",
- Caches: map[string]*ctx.Cache{},
- Configs: map[string]*ctx.Config{
- "logpid": &ctx.Config{Name: "logpid", Value: "var/run/bench.pid", Help: ""},
- "signal": &ctx.Config{Name: "signal", Value: map[string]interface{}{
- "2": "INT",
- "3": "QUIT",
- "15": "TERM",
- "28": "WINCH",
- "30": "restart",
- "31": "upgrade",
- "5": "TRAP",
-
- "1": "HUP",
- // "9": "KILL",
- // "10": "BUS",
- // "11": "SEGV",
- // "17": "STOP",
- // "23": "IO",
- // "29": "INFO",
-
- "18": "TSTP",
- "19": "CONT",
-
- "6": "ABRT",
-
- "14": "ALRM",
- "20": "CHLD",
- "21": "TTIN",
- "22": "TTOUT",
-
- "13": "PIPE",
- "16": "URG",
-
- "4": "ILL",
- "7": "EMT",
- "8": "FPE",
- "12": "SYS",
- "24": "XCPU",
- "25": "XFSZ",
- "26": "VTALRM",
- "27": "PROF",
- }, Help: "信号"},
- "debug": &ctx.Config{Name: "debug", Value: map[string]interface{}{"value": map[string]interface{}{"enable": false},
- "trace": map[string]interface{}{"value": map[string]interface{}{"enable": true}},
- "context": map[string]interface{}{"value": map[string]interface{}{"enable": false},
- "begin": map[string]interface{}{"value": map[string]interface{}{"enable": false}},
- "start": map[string]interface{}{"value": map[string]interface{}{"enable": false}},
- },
- "command": map[string]interface{}{"value": map[string]interface{}{"enable": false},
- "shit": map[string]interface{}{"value": map[string]interface{}{"enable": true}},
- },
- "config": map[string]interface{}{"value": map[string]interface{}{"enable": true}},
- "cache": map[string]interface{}{"value": map[string]interface{}{"enable": false},
- "read": map[string]interface{}{"value": map[string]interface{}{"enable": false},
- "ncontext": map[string]interface{}{"value": map[string]interface{}{"enable": false}},
- },
- },
- "web": map[string]interface{}{"value": map[string]interface{}{"enable": true, "feed": "web"}},
- }},
- },
- Commands: map[string]*ctx.Command{
- "_init": &ctx.Command{Name: "_init", Help: "等待调试", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- m.Target().Start(m)
- return
- }},
- "wait": &ctx.Command{Name: "wait arg...", Help: "等待调试", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if gdb, ok := m.Target().Server.(*GDB); m.Assert(ok) {
- go func() {
- m.Log("info", "wait %v", arg)
- m.Log("info", "done %v", gdb.Wait(m, arg))
- }()
- }
- return
- }},
- "goon": &ctx.Command{Name: "goon arg...", Help: "继续运行", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if gdb, ok := m.Target().Server.(*GDB); m.Assert(ok) {
- gdb.Goon(arg[0], arg[1])
- }
- return
- }},
- },
-}
-
-func init() {
- ctx.Index.Register(Index, &GDB{Context: Index})
-}
diff --git a/usr/local/honor/src/contexts/lex/lex.go b/usr/local/honor/src/contexts/lex/lex.go
deleted file mode 100644
index 6e22237b..00000000
--- a/usr/local/honor/src/contexts/lex/lex.go
+++ /dev/null
@@ -1,512 +0,0 @@
-package lex
-
-import (
- "contexts/ctx"
- "toolkit"
-
- "fmt"
- "strconv"
- "strings"
-)
-
-type Seed struct {
- page int
- hash int
- word string
-}
-type Point struct {
- s int
- c byte
-}
-type State struct {
- star bool
- next int
- hash int
-}
-
-type LEX struct {
- seed []*Seed
- hash map[string]int
- word map[int]string
- hand map[int]string
- page map[string]int
-
- char map[byte][]byte
- state map[State]*State
- mat []map[byte]*State
-
- *ctx.Context
-}
-
-func (lex *LEX) charset(c byte) []byte {
- if cs, ok := lex.char[c]; ok {
- return cs
- }
- return []byte{c}
-}
-func (lex *LEX) index(m *ctx.Message, hash string, h string) int {
- which, names := lex.hash, lex.word
- if hash == "npage" {
- which, names = lex.page, lex.hand
- }
-
- if x, e := strconv.Atoi(h); e == nil {
- if hash == "npage" {
- m.Assert(x <= m.Capi("npage"), "语法集合未创建")
- } else {
- lex.hash[h] = x
- }
- return x
- }
-
- if x, ok := which[h]; ok {
- return x
- }
-
- which[h] = m.Capi(hash, 1)
- names[which[h]] = h
- m.Assert(hash != "npage" || m.Capi("npage") < m.Confi("meta", "nlang"), "语法集合超过上限")
- return which[h]
-}
-func (lex *LEX) train(m *ctx.Message, page int, hash int, seed []byte) int {
- m.Log("debug", "%s %s page: %v hash: %v seed: %v", "train", "lex", page, hash, string(seed))
-
- ss := []int{page}
- cn := make([]bool, m.Confi("meta", "ncell"))
- cc := make([]byte, 0, m.Confi("meta", "ncell"))
- sn := make([]bool, m.Capi("nline"))
-
- points := []*Point{}
-
- for p := 0; p < len(seed); p++ {
-
- switch seed[p] {
- case '[':
- set := true
- if p++; seed[p] == '^' {
- set, p = false, p+1
- }
-
- for ; seed[p] != ']'; p++ {
- if seed[p] == '\\' {
- p++
- for _, c := range lex.charset(seed[p]) {
- cn[c] = true
- }
- continue
- }
-
- if seed[p+1] == '-' {
- begin, end := seed[p], seed[p+2]
- if begin > end {
- begin, end = end, begin
- }
- for c := begin; c <= end; c++ {
- cn[c] = true
- }
- p += 2
- continue
- }
-
- cn[seed[p]] = true
- }
-
- for c := 0; c < len(cn); c++ {
- if (set && cn[c]) || (!set && !cn[c]) {
- cc = append(cc, byte(c))
- }
- cn[c] = false
- }
-
- case '.':
- for c := 0; c < len(cn); c++ {
- cc = append(cc, byte(c))
- }
-
- case '\\':
- p++
- for _, c := range lex.charset(seed[p]) {
- cc = append(cc, c)
- }
- default:
- cc = append(cc, seed[p])
- }
-
- m.Log("debug", "page: \033[31m%d %v\033[0m", len(ss), ss)
- m.Log("debug", "cell: \033[32m%d %v\033[0m", len(cc), cc)
-
- flag := '\000'
- if p+1 < len(seed) {
- flag = rune(seed[p+1])
- switch flag {
- case '+', '*', '?':
- p++
- }
- }
-
- for _, s := range ss {
- line := 0
- for _, c := range cc {
-
- state := &State{}
- if lex.mat[s][c] != nil {
- *state = *lex.mat[s][c]
- } else {
- m.Capi("nnode", 1)
- }
- m.Log("debug", "GET(%d,%d): %v", s, c, state)
-
- switch flag {
- case '+':
- state.star = true
- case '*':
- state.star = true
- sn[s] = true
- case '?':
- sn[s] = true
- }
-
- if state.next == 0 {
- if line == 0 || !m.Confs("meta", "compact") {
- lex.mat = append(lex.mat, make(map[byte]*State))
- line = m.Capi("nline", 1) - 1
- sn = append(sn, false)
- }
- state.next = line
- }
- sn[state.next] = true
-
- lex.mat[s][c] = state
- points = append(points, &Point{s, c})
- m.Log("debug", "SET(%d,%d): %v(%s,%s)", s, c, state, m.Cap("nnode"), m.Cap("nreal"))
- }
- }
-
- cc, ss = cc[:0], ss[:0]
- for s, b := range sn {
- if sn[s] = false; b {
- ss = append(ss, s)
- }
- }
- }
-
- for _, s := range ss {
- if s < m.Confi("meta", "nlang") || s >= len(lex.mat) {
- continue
- }
-
- if len(lex.mat[s]) == 0 {
- last := m.Capi("nline") - 1
- m.Cap("nline", "0")
- m.Log("debug", "DEL: %d-%d", last, m.Capi("nline", s))
- lex.mat = lex.mat[:s]
- }
- }
-
- for _, s := range ss {
- for _, p := range points {
- state := &State{}
- *state = *lex.mat[p.s][p.c]
-
- if state.next == s {
- m.Log("debug", "GET(%d, %d): %v", p.s, p.c, state)
- if state.hash = hash; state.next >= len(lex.mat) {
- state.next = 0
- }
- lex.mat[p.s][p.c] = state
- m.Log("debug", "SET(%d, %d): %v", p.s, p.c, state)
- }
-
- if x, ok := lex.state[*state]; !ok {
- lex.state[*state] = lex.mat[p.s][p.c]
- m.Capi("nreal", 1)
- } else {
- lex.mat[p.s][p.c] = x
- }
- }
- }
-
- m.Log("debug", "%s %s npage: %v nhash: %v nseed: %v", "train", "lex", m.Capi("npage"), m.Capi("nhash"), m.Capi("nseed"))
- return hash
-}
-func (lex *LEX) parse(m *ctx.Message, page int, line []byte) (hash int, rest []byte, word []byte) {
- m.Log("debug", "%s %s page: %v line: %v", "parse", "lex", page, line)
-
- pos := 0
- for star, s := 0, page; s != 0 && pos < len(line); pos++ {
-
- c := line[pos]
- if c == '\\' && pos < len(line)-1 { //跳过转义
- pos++
- c = lex.charset(line[pos])[0]
- }
- if c > 127 { //跳过中文
- word = append(word, c)
- continue
- }
-
- state := lex.mat[s][c]
- if state == nil {
- s, star, pos = star, 0, pos-1
- continue
- }
- m.Log("debug", "GET (%d,%d): %v", s, c, state)
-
- word = append(word, c)
-
- if state.star {
- star = s
- } else if x, ok := lex.mat[star][c]; !ok || !x.star {
- star = 0
- }
-
- if s, hash = state.next, state.hash; s == 0 {
- s, star = star, 0
- }
- }
-
- if pos == len(line) {
- // hash, pos, word = -1, 0, word[:0]
- } else if hash == 0 {
- pos, word = 0, word[:0]
- }
- rest = line[pos:]
-
- m.Log("debug", "%s %s hash: %v word: %v rest: %v", "parse", "lex", hash, word, rest)
- return
-}
-func (lex *LEX) Parse(m *ctx.Message, line []byte, page string) (hash int, rest []byte, word []byte) {
- hash, rest, word = lex.parse(m, lex.index(m, "npage", page), line)
- return hash, rest, word
-}
-
-func (lex *LEX) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server {
- return &LEX{Context: c}
-}
-func (lex *LEX) Begin(m *ctx.Message, arg ...string) ctx.Server {
- lex.Caches["nseed"] = &ctx.Cache{Name: "种子数量", Value: "0", Help: "词法模板的数量"}
- lex.Caches["npage"] = &ctx.Cache{Name: "集合数量", Value: "0", Help: "词法集合的数量"}
- lex.Caches["nhash"] = &ctx.Cache{Name: "类型数量", Value: "0", Help: "词法类型的数量"}
-
- lex.Caches["nline"] = &ctx.Cache{Name: "状态数量", Value: m.Conf("meta", "nlang"), Help: "状态机状态的数量"}
- lex.Caches["nnode"] = &ctx.Cache{Name: "节点数量", Value: "0", Help: "状态机连接的逻辑数量"}
- lex.Caches["nreal"] = &ctx.Cache{Name: "实点数量", Value: "0", Help: "状态机连接的存储数量"}
-
- lex.page = map[string]int{"nil": 0}
- lex.hash = map[string]int{"nil": 0}
- lex.word = map[int]string{0: "nil"}
- lex.hand = map[int]string{0: "nil"}
-
- lex.char = map[byte][]byte{
- 't': []byte{'\t'},
- 'n': []byte{'\n'},
- 'b': []byte{'\t', ' '},
- 's': []byte{'\t', ' ', '\n'},
- 'd': []byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'},
- 'x': []byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F'},
- }
- lex.state = make(map[State]*State)
- lex.mat = make([]map[byte]*State, m.Capi("nline"))
-
- return lex
-}
-func (lex *LEX) Start(m *ctx.Message, arg ...string) bool {
- return false
-}
-func (lex *LEX) Close(m *ctx.Message, arg ...string) bool {
- return true
-}
-
-var Index = &ctx.Context{Name: "lex", Help: "词法中心",
- Caches: map[string]*ctx.Cache{
- "nmat": &ctx.Cache{Name: "nmat", Value: "0", Help: "矩阵数量"},
- },
- Configs: map[string]*ctx.Config{
- "npage": &ctx.Config{Name: "npage", Value: "1", Help: "默认页"},
- "nhash": &ctx.Config{Name: "nhash", Value: "1", Help: "默认值"},
- "meta": &ctx.Config{Name: "meta", Value: map[string]interface{}{
- "ncell": 128, "nlang": 64, "compact": true,
- "name": "mat%d", "help": "matrix",
- }, Help: "初始参数"},
- },
- Commands: map[string]*ctx.Command{
- "_init": &ctx.Command{Name: "_init", Help: "默认矩阵", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if _, ok := m.Target().Server.(*LEX); m.Assert(ok) {
- m.Spawn().Cmd("train", "-?[a-zA-Z_0-9:/.]+", "key", "cmd")
- m.Spawn().Cmd("train", "\"[^\"]*\"", "str", "cmd")
- m.Spawn().Cmd("train", "'[^']*'", "str", "cmd")
- m.Spawn().Cmd("train", "#[^\n]*", "com", "cmd")
- m.Spawn().Cmd("train", "[~!@$%()]", "ops", "cmd")
- }
- return
- }},
- "spawn": &ctx.Command{Name: "spawn [help [name]]", Help: "创建矩阵", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if _, ok := m.Target().Server.(*LEX); m.Assert(ok) {
- m.Start(fmt.Sprintf(kit.Select(m.Conf("lex.meta", "name"), arg, 1), m.Capi("nmat", 1)),
- kit.Select(m.Conf("lex.meta", "help"), arg, 0))
- }
- return
- }},
- "train": &ctx.Command{Name: "train seed [hash [page]", Help: "词法训练", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if lex, ok := m.Target().Server.(*LEX); m.Assert(ok) {
- hash := lex.index(m, "nhash", m.Confx("nhash", arg, 1))
- page := lex.index(m, "npage", m.Confx("npage", arg, 2))
- if lex.mat[page] == nil {
- lex.mat[page] = map[byte]*State{}
- }
- m.Result(0, lex.train(m, page, hash, []byte(arg[0])))
-
- lex.seed = append(lex.seed, &Seed{page, hash, arg[0]})
- m.Cap("stream", fmt.Sprintf("%s,%s,%s", m.Cap("nseed", len(lex.seed)),
- m.Cap("npage"), m.Cap("nhash", len(lex.hash)-1)))
- }
- return
- }},
- "parse": &ctx.Command{Name: "parse line [page]", Help: "词法解析", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if lex, ok := m.Target().Server.(*LEX); m.Assert(ok) {
- hash, rest, word := lex.parse(m, lex.index(m, "npage", m.Confx("npage", arg, 1)), []byte(arg[0]))
- m.Result(0, hash, string(rest), string(word))
- }
- return
- }},
- "split": &ctx.Command{Name: "split line [page]", Help: "词法分隔", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if lex, ok := m.Target().Server.(*LEX); m.Assert(ok) {
- for input := []byte(arg[0]); len(input) > 0; {
- hash, rest, word := lex.parse(m, lex.index(m, "npage", m.Confx("npage", arg, 1)), input)
- m.Log("fuck", "what %v %v %v", hash, rest, word)
- if hash == 0 || len(word) == 0 || len(rest) == len(input) {
- if len(input) > 0 {
- input = input[1:]
- }
- continue
- }
-
- m.Push("word", string(word))
- m.Push("hash", lex.word[hash])
- m.Push("rest", string(rest))
- input = rest
- }
- m.Table()
- }
- return
- }},
- "show": &ctx.Command{Name: "show seed|page|hash|mat|node", Help: "查看信息", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if lex, ok := m.Target().Server.(*LEX); m.Assert(ok) {
- if len(arg) == 0 {
- m.Push("seed", len(lex.seed))
- m.Push("page", len(lex.page))
- m.Push("hash", len(lex.hash))
- m.Push("nmat", len(lex.mat))
- m.Push("node", len(lex.state))
- m.Table()
- return
- }
- switch arg[0] {
- case "seed":
- for _, v := range lex.seed {
- m.Push("page", lex.hand[v.page])
- m.Push("word", strings.Replace(strings.Replace(v.word, "\n", "\\n", -1), "\t", "\\t", -1))
- m.Push("hash", lex.word[v.hash])
- }
- m.Sort("page", "int").Table()
-
- case "page":
- for k, v := range lex.page {
- m.Push("page", k)
- m.Push("code", v)
- }
- m.Sort("code", "int").Table()
-
- case "hash":
- for k, v := range lex.hash {
- m.Push("hash", k)
- m.Push("code", v)
- }
- m.Sort("code", "int").Table()
-
- case "node":
- for _, v := range lex.state {
- m.Push("star", v.star)
- m.Push("next", v.next)
- m.Push("hash", v.hash)
- }
- m.Table()
-
- case "mat":
- for i, v := range lex.mat {
- if i <= m.Capi("npage") {
- m.Push("index", lex.hand[i])
- } else if i < m.Confi("meta", "nlang") {
- continue
- } else {
- m.Push("index", i)
- }
-
- for j := byte(0); j < byte(m.Confi("meta", "ncell")); j++ {
- c := fmt.Sprintf("%c", j)
- switch c {
- case "\n":
- c = "\\n"
- case "\t":
- c = "\\t"
- case " ":
- default:
- if j < 0x20 {
- c = fmt.Sprintf("\\%x", j)
- }
- }
-
- if s := v[j]; s == nil {
- m.Push(c, "")
- } else {
- star := 0
- if s.star {
- star = 1
- }
- m.Push(c, fmt.Sprintf("%d,%d,%d", star, s.next, s.hash))
- }
- }
- }
-
- ncol := len(m.Meta["append"])
- nrow := len(m.Meta[m.Meta["append"][0]])
- for i := 0; i < ncol-1; i++ {
- for j := i + 1; j < ncol; j++ {
- same := true
- void := true
- for n := 0; n < nrow; n++ {
- if m.Meta[m.Meta["append"][i]][n] != "" {
- void = false
- }
- if m.Meta[m.Meta["append"][i]][n] != m.Meta[m.Meta["append"][j]][n] {
- same = false
- break
- }
- }
-
- if same {
- if !void {
- key = m.Meta["append"][i] + m.Meta["append"][j]
- m.Meta[key] = m.Meta[m.Meta["append"][i]]
- m.Meta["append"][i] = key
- }
- for k := j; k < ncol-1; k++ {
- m.Meta["append"][k] = m.Meta["append"][k+1]
- }
- ncol--
- j--
- }
- }
- }
- m.Meta["append"] = m.Meta["append"][:ncol]
- m.Table()
- }
- }
- return
- }},
- },
-}
-
-func init() {
- ctx.Index.Register(Index, &LEX{Context: Index})
-}
diff --git a/usr/local/honor/src/contexts/log/log.go b/usr/local/honor/src/contexts/log/log.go
deleted file mode 100644
index b077c340..00000000
--- a/usr/local/honor/src/contexts/log/log.go
+++ /dev/null
@@ -1,201 +0,0 @@
-package log
-
-import (
- "contexts/ctx"
- "toolkit"
-
- "fmt"
- "os"
- "path"
-)
-
-type LOG struct {
- queue chan map[string]interface{}
- file map[string]*os.File
- *ctx.Context
-}
-
-func (log *LOG) Log(msg *ctx.Message, action string, str string, arg ...interface{}) {
- if log.queue != nil {
- log.queue <- map[string]interface{}{"action": action, "str": str, "arg": arg, "msg": msg}
- }
-}
-
-func (log *LOG) Value(msg *ctx.Message, arg ...interface{}) []string {
- args := append(kit.Trans(arg...))
-
- if value, ok := kit.Chain(log.Configs["output"].Value, args).(map[string]interface{}); ok {
- if kit.Right(value["source"]) && kit.Format(value["source"]) != msg.Source().Name {
- return nil
- }
-
- if kit.Right(value["target"]) && kit.Format(value["target"]) != msg.Target().Name {
- return nil
- }
- return kit.Trans(value["value"])
- }
- return nil
-}
-
-func (log *LOG) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server {
- return &LOG{Context: c}
-}
-func (log *LOG) Begin(m *ctx.Message, arg ...string) ctx.Server {
- return log
-}
-func (log *LOG) Start(m *ctx.Message, arg ...string) bool {
- // 创建文件
- log.file = map[string]*os.File{}
- m.Assert(os.MkdirAll(m.Conf("logdir"), 0770))
- m.Confm("output", "file", func(key string, value string) {
- switch value {
- case "":
- case "stderr":
- log.file[key] = os.Stderr
- case "stdout":
- log.file[key] = os.Stdout
- default:
- if f, e := os.Create(path.Join(m.Conf("logdir"), value)); m.Assert(e) {
- log.file[key] = f
- }
- }
- })
-
- // 创建队列
- log.queue = make(chan map[string]interface{}, m.Confi("logbuf"))
- m.Cap("stream", m.Conf("output", []string{"bench", "value", "file"}))
-
- for {
- select {
- case l := <-log.queue:
- m.Capi("nlog", 1)
- msg := l["msg"].(*ctx.Message)
- args := kit.Trans(l["arg"].([]interface{})...)
-
- loop:
- for _, v := range []string{kit.Format(l["action"]), "bench"} {
- for i := len(args); i >= 0; i-- {
- value := log.Value(msg, append([]string{v}, args[:i]...))
- if !kit.Right(value) {
- continue
- }
-
- if value[0] == "debug" && !m.Options("log.debug") {
- break loop
- }
-
- // 日志文件
- file := os.Stderr
- if f, ok := log.file[value[0]]; ok {
- file = f
- } else {
- break loop
- }
-
- // 日志格式
- font := m.Conf("output", []string{"font", kit.Select("", value, 1)})
- meta := msg.Format(m.Confv("output", []string{"meta", kit.Select("short", value, 2)}).([]interface{})...)
-
- str := fmt.Sprintf("%d %s %s%s %s%s", m.Capi("nout", 1), meta, font,
- kit.Format(l["action"]), fmt.Sprintf(kit.Format(l["str"]), l["arg"].([]interface{})...),
- kit.Select("", "\033[0m", font != ""))
-
- // 输出日志
- if fmt.Fprintln(file, str); m.Confs("output", []string{"stdio", value[0]}) {
- fmt.Println(str)
- }
- break loop
- }
- }
- }
- }
- return true
-}
-func (log *LOG) Close(m *ctx.Message, arg ...string) bool {
- return false
-}
-
-var Index = &ctx.Context{Name: "log", Help: "日志中心",
- Caches: map[string]*ctx.Cache{
- "nlog": &ctx.Cache{Name: "nlog", Value: "0", Help: "日志调用数量"},
- "nout": &ctx.Cache{Name: "nout", Value: "0", Help: "日志输出数量"},
- },
- Configs: map[string]*ctx.Config{
- "logbuf": &ctx.Config{Name: "logbuf", Value: "1024", Help: "日志队列长度"},
- "logdir": &ctx.Config{Name: "logdir", Value: "var/log", Help: "日志目录"},
-
- "output": &ctx.Config{Name: "output", Value: map[string]interface{}{
- "stdio": map[string]interface{}{
- "bench": false,
- },
- "file": map[string]interface{}{
- "debug": "debug.log",
- "bench": "bench.log",
- "right": "right.log",
- "error": "error.log",
- },
- "font": map[string]interface{}{
- "red": "\033[31m",
- "green": "\033[32m",
- "yellow": "\033[33m",
- },
- "meta": map[string]interface{}{
- "short": []interface{}{"time", "ship"},
- "long": []interface{}{"time", "ship"},
- "cost": []interface{}{"time", "ship", "mill"},
- },
-
- "debug": map[string]interface{}{"value": []interface{}{"debug"}},
- "search": map[string]interface{}{"value": []interface{}{"debug"}},
- "call": map[string]interface{}{"value": []interface{}{"debug"}},
- "back": map[string]interface{}{"value": []interface{}{"debug"}},
- "send": map[string]interface{}{"value": []interface{}{"debug"}},
- "recv": map[string]interface{}{"value": []interface{}{"debug"}},
-
- "bench": map[string]interface{}{"value": []interface{}{"bench"}},
- "begin": map[string]interface{}{"value": []interface{}{"bench", "red"}},
- "start": map[string]interface{}{"value": []interface{}{"bench", "red"}},
- "close": map[string]interface{}{"value": []interface{}{"bench", "red"}},
- "stack": map[string]interface{}{"value": []interface{}{"bench", "yellow"}},
- "warn": map[string]interface{}{"value": []interface{}{"bench", "yellow"}},
- "time": map[string]interface{}{"value": []interface{}{"bench", "red"}},
-
- "right": map[string]interface{}{"value": []interface{}{"right"}},
-
- "error": map[string]interface{}{"value": []interface{}{"error", "red"}},
- "trace": map[string]interface{}{"value": []interface{}{"error", "red"}},
-
- "cmd": map[string]interface{}{"value": []interface{}{"bench", "green"},
- "lex": map[string]interface{}{"value": []interface{}{"debug", "green"}},
- "yac": map[string]interface{}{"value": []interface{}{"debug", "green"}},
- "cli": map[string]interface{}{
- "cmd": map[string]interface{}{"value": []interface{}{"debug", "red"}},
- },
- "mdb": map[string]interface{}{
- "note": map[string]interface{}{"value": []interface{}{"debug", "red"}},
- },
- "aaa": map[string]interface{}{
- "auth": map[string]interface{}{"value": []interface{}{"debug", "red"}},
- "hash": map[string]interface{}{"value": []interface{}{"debug", "red"}},
- "rsa": map[string]interface{}{"value": []interface{}{"debug", "red"}},
- },
- },
- }, Help: "日志输出配置"},
- },
- Commands: map[string]*ctx.Command{
- "_init": &ctx.Command{Name: "_init", Help: "初始化", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- m.Target().Start(m)
- return
- }},
- "log": &ctx.Command{Name: "log level string...", Help: "输出日志, level: 日志类型, string: 日志内容", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if log, ok := m.Target().Server.(*LOG); m.Assert(ok) {
- log.Log(m, arg[0], arg[1], arg[2:])
- }
- return
- }},
- },
-}
-
-func init() {
- ctx.Index.Register(Index, &LOG{Context: Index})
-}
diff --git a/usr/local/honor/src/contexts/mdb/mdb.go b/usr/local/honor/src/contexts/mdb/mdb.go
deleted file mode 100644
index 40960f58..00000000
--- a/usr/local/honor/src/contexts/mdb/mdb.go
+++ /dev/null
@@ -1,803 +0,0 @@
-package mdb
-
-import (
- _ "github.com/go-sql-driver/mysql"
- "github.com/gomodule/redigo/redis"
-
- "contexts/ctx"
- "toolkit"
-
- "database/sql"
- "encoding/json"
- "fmt"
- "strings"
- "time"
-)
-
-type MDB struct {
- conn redis.Conn
- *sql.DB
- *ctx.Context
-}
-
-func (mdb *MDB) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server {
- c.Caches = map[string]*ctx.Cache{
- "database": &ctx.Cache{Name: "database", Value: m.Confx("database", arg, 0), Help: "数据库"},
- "username": &ctx.Cache{Name: "username", Value: m.Confx("username", arg, 1), Help: "用户名"},
- "password": &ctx.Cache{Name: "password", Value: m.Confx("password", arg, 2), Help: "密码"},
- "address": &ctx.Cache{Name: "address", Value: m.Confx("address", arg, 3), Help: "地址"},
- "protocol": &ctx.Cache{Name: "protocol(tcp)", Value: m.Confx("protocol", arg, 4), Help: "协议"},
- "driver": &ctx.Cache{Name: "driver(mysql)", Value: m.Confx("driver", arg, 5), Help: "驱动"},
- "redis": &ctx.Cache{Name: "redis", Value: "", Help: "数据缓存"},
- }
- c.Configs = map[string]*ctx.Config{
- "dbs": &ctx.Config{Name: "dbs", Value: []string{}, Help: "数据库"},
- "tabs": &ctx.Config{Name: "tabs", Value: []string{}, Help: "关系表"},
- "limit": &ctx.Config{Name: "limit", Value: "10", Help: "分页"},
- "offset": &ctx.Config{Name: "offset", Value: "0", Help: "偏移"},
- }
-
- return &MDB{Context: c}
-}
-func (mdb *MDB) Begin(m *ctx.Message, arg ...string) ctx.Server {
- return mdb
-}
-func (mdb *MDB) Start(m *ctx.Message, arg ...string) bool {
- if db, e := sql.Open(m.Cap("driver"), fmt.Sprintf("%s:%s@%s(%s)/%s", m.Cap("username"), m.Cap("password"),
- m.Cap("protocol"), m.Cap("address"), m.Cap("database"))); m.Assert(e) {
- m.Log("info", "mdb open %s", m.Cap("stream", m.Cap("database")))
- mdb.DB = db
- }
- return false
-}
-func (mdb *MDB) Close(m *ctx.Message, arg ...string) bool {
- return false
-}
-
-var Index = &ctx.Context{Name: "mdb", Help: "数据中心",
- Caches: map[string]*ctx.Cache{
- "nsource": &ctx.Cache{Name: "nsource", Value: "0", Help: "已打开数据库的数量"},
- },
- Configs: map[string]*ctx.Config{
- "database": &ctx.Config{Name: "database", Value: "demo", Help: "默认数据库"},
- "username": &ctx.Config{Name: "username", Value: "demo", Help: "默认账户"},
- "password": &ctx.Config{Name: "password", Value: "demo", Help: "默认密码"},
- "address": &ctx.Config{Name: "address", Value: ":6379", Help: "默认地址"},
- "protocol": &ctx.Config{Name: "protocol(tcp)", Value: "tcp", Help: "默认协议"},
- "driver": &ctx.Config{Name: "driver(mysql)", Value: "mysql", Help: "默认驱动"},
-
- "ktv": &ctx.Config{Name: "ktv", Value: map[string]interface{}{
- "conf": map[string]interface{}{"expire": "24h"}, "data": map[string]interface{}{},
- }, Help: "缓存数据"},
-
- "temp": &ctx.Config{Name: "temp", Value: map[string]interface{}{}, Help: "缓存数据"},
- "temp_view": &ctx.Config{Name: "temp_view", Value: map[string]interface{}{}, Help: "缓存数据"},
- "temp_expire": &ctx.Config{Name: "temp_expire(s)", Value: "3000", Help: "缓存数据"},
-
- "note": &ctx.Config{Name: "note", Value: map[string]interface{}{
- "faa01a8fc2fc92dae3fbc02ac1b4ec75": map[string]interface{}{
- "create_time": "1990-07-30 07:08:09", "access_time": "2017-11-01 02:03:04",
- "type": "index", "name": "shy", "data": "", "ship": map[string]interface{}{
- "prev": map[string]interface{}{"type": "index", "data": ""},
- },
- },
- "81c5709d091eb04bd31ee751c3f81023": map[string]interface{}{
- "create_time": "1990-07-30 07:08:09", "access_time": "2017-11-01 02:03:04",
- "meta": []interface{}{"text", "text", "place", "place", "label", "label", "friend", "friend", "username", "username"},
- "view": map[string]interface{}{
- "list": map[string]interface{}{"name": "left", "create_date": "right"},
- "edit": map[string]interface{}{"model": "hidden", "username": "hidden"},
- },
- "bind": map[string]interface{}{},
- "type": "model", "name": "shy", "data": "", "ship": map[string]interface{}{
- "prev": map[string]interface{}{"type": "model", "data": ""},
- },
- },
- }, Help: "数据结构"},
- "note_view": &ctx.Config{Name: "note_view", Value: map[string]interface{}{
- "default": []interface{}{"key", "create_time", "type", "name", "model", "value"},
- "base": []interface{}{"key", "create_time", "type", "name", "model", "value"},
- "full": []interface{}{"key", "create_time", "access_time", "type", "name", "model", "value", "view", "data", "ship"},
- }, Help: "数据视图"},
- },
- Commands: map[string]*ctx.Command{
- "open": &ctx.Command{Name: "open [database [username [password [address [protocol [driver]]]]]]",
- Help: "打开数据库, database: 数据库名, username: 用户名, password: 密码, address: 服务地址, protocol: 服务协议, driver: 数据库类型",
- Form: map[string]int{"dbname": 1, "dbhelp": 1}, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- m.Start(kit.Select(fmt.Sprintf("db%d", m.Capi("nsource", 1)), m.Option("dbname")),
- kit.Select("数据源", m.Option("dbhelp")), arg...)
- return
- }},
- "exec": &ctx.Command{Name: "exec sql [arg]", Help: "操作数据库, sql: SQL语句, arg: 操作参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if mdb, ok := m.Target().Server.(*MDB); m.Assert(ok) && mdb.DB != nil {
- which := make([]interface{}, 0, len(arg))
- for _, v := range arg[1:] {
- which = append(which, v)
- }
-
- if ret, e := mdb.Exec(arg[0], which...); m.Assert(e) {
- id, _ := ret.LastInsertId()
- n, _ := ret.RowsAffected()
- m.Log("info", "last(%s) nrow(%s)", m.Append("last", id), m.Append("nrow", n))
- m.Echo("%d", n)
- }
- }
- return
- }},
- "query": &ctx.Command{Name: "query sql [arg]", Help: "查询数据库, sql: SQL语句, arg: 查询参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if mdb, ok := m.Target().Server.(*MDB); m.Assert(ok) && mdb.DB != nil {
- which := make([]interface{}, 0, len(arg))
- for _, v := range arg[1:] {
- which = append(which, v)
- }
-
- if rows, e := mdb.Query(arg[0], which...); m.Assert(e) {
- defer rows.Close()
- if cols, e := rows.Columns(); m.Assert(e) {
- num := len(cols)
-
- for rows.Next() {
- vals := make([]interface{}, num)
- ptrs := make([]interface{}, num)
- for i := range vals {
- ptrs[i] = &vals[i]
- }
- rows.Scan(ptrs...)
-
- for i, k := range cols {
- m.Push(k, vals[i])
- }
- }
-
- if len(m.Meta["append"]) > 0 {
- m.Log("info", "rows(%d) cols(%d)", len(m.Meta[m.Meta["append"][0]]), len(m.Meta["append"]))
- } else {
- m.Log("info", "rows(0) cols(0)")
- }
- m.Table()
- }
- }
-
- }
- return
- }},
- "redis": &ctx.Command{Name: "redis [open address]|[cmd...]", Help: "缓存数据库", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if mdb, ok := m.Target().Server.(*MDB); m.Assert(ok) {
- switch arg[0] {
- case "open":
- if mdb.conn, e = redis.Dial("tcp", m.Cap("redis", arg[1]), redis.DialKeepAlive(time.Second*10)); m.Assert(e) {
- m.Log("info", "redis: %v", arg[1])
- }
-
- default:
- if mdb.conn == nil || mdb.conn.Err() != nil {
- if m.Caps("redis") {
- m.Cmd("mdb.redis", "open", m.Cap("redis"))
- } else {
- m.Echo("not open")
- break
- }
- }
-
- args := []interface{}{}
- for _, v := range arg[1:] {
- args = append(args, v)
- }
-
- if res, err := mdb.conn.Do(arg[0], args...); m.Assert(err) {
- switch val := res.(type) {
- case redis.Error:
- m.Echo("%v", val)
-
- case []interface{}:
- for i, v := range val {
- m.Add("append", "index", i)
- m.Add("append", "value", v)
- }
- m.Table()
-
- default:
- var data interface{}
- if str := kit.Format(res); json.Unmarshal([]byte(str), &data) == nil {
- m.Echo(kit.Formats(data))
- } else {
- m.Echo(str)
- }
- }
- }
- }
- }
- return
- }},
-
- "db": &ctx.Command{Name: "db [which]", Help: "查看或选择数据库", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if len(arg) == 0 {
- m.Cmdy(".query", "show databases").Table()
- return
- }
-
- m.Assert(m.Cmdy("exec", fmt.Sprintf("use %s", arg[0])))
- m.Echo(m.Cap("database", arg[0]))
- return
- }},
- "tab": &ctx.Command{Name: "tab [which [field]]", Help: "查看关系表,which: 表名, field: 字段名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- switch len(arg) {
- case 0:
- m.Cmdy(".query", "show tables").Table()
- case 1:
- m.Cmdy(".query", fmt.Sprintf("desc %s", arg[0])).Table()
- case 2:
- m.Cmdy(".query", fmt.Sprintf("desc %s", arg[0])).Cmd("select", "Field", arg[1]).CopyTo(m)
- }
- return
- }},
- "show": &ctx.Command{Name: "show table fields...", Help: "查询数据, table: 表名, fields: 字段, where: 查询条件, group: 聚合字段, order: 排序字段",
- Form: map[string]int{"where": 1, "eq": 2, "ne": 2, "in": 2, "like": 2, "begin": 2, "group": 1, "order": 1, "desc": 0, "limit": 1, "offset": 1, "other": -1},
- Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if len(arg) == 0 {
- m.Cmdy(".query", "show tables")
- return
- }
-
- stmt := []string{
- fmt.Sprintf("select %s", kit.Select("*", strings.Join(arg[1:], ","))),
- fmt.Sprintf("from %s", arg[0]),
- }
-
- where := []string{}
- if m.Has("where") {
- where = append(where, m.Option("where"))
- }
- for i := 0; i < len(m.Meta["eq"]); i += 2 {
- where = append(where, fmt.Sprintf("%s='%s'", m.Meta["eq"][i], m.Meta["eq"][i+1]))
- }
- for i := 0; i < len(m.Meta["ne"]); i += 2 {
- where = append(where, fmt.Sprintf("%s!='%s'", m.Meta["ne"][i], m.Meta["ne"][i+1]))
- }
- for i := 0; i < len(m.Meta["in"]); i += 2 {
- where = append(where, fmt.Sprintf("%s in (%s)", m.Meta["in"][i], m.Meta["in"][i+1]))
- }
- for i := 0; i < len(m.Meta["like"]); i += 2 {
- where = append(where, fmt.Sprintf("%s like '%s'", m.Meta["like"][i], m.Meta["like"][i+1]))
- }
- for i := 0; i < len(m.Meta["begin"]); i += 2 {
- where = append(where, fmt.Sprintf("%s like '%s%%'", m.Meta["begin"][i], m.Meta["begin"][i+1]))
- }
- if len(where) > 0 {
- stmt = append(stmt, "where", strings.Join(where, " and "))
- }
-
- if m.Has("group") {
- stmt = append(stmt, fmt.Sprintf("group by %s", m.Option("group")))
- }
- if m.Has("order") {
- stmt = append(stmt, fmt.Sprintf("order by %s", m.Option("order")))
- }
- if m.Has("desc") {
- stmt = append(stmt, "desc")
- }
-
- stmt = append(stmt, fmt.Sprintf("limit %s", m.Confx("limit")))
- stmt = append(stmt, fmt.Sprintf("offset %s", m.Confx("offset")))
-
- for _, v := range m.Meta["other"] {
- stmt = append(stmt, m.Parse(v))
- }
-
- m.Cmdy(".query", strings.Join(stmt, " "))
- return
- }},
- "update": &ctx.Command{Name: "update [table [condition [field [value]]...]]",
- Help: "修改数据, table: 关系表, condition: 条件语句, field: 字段名, value: 字段值",
- Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- switch len(arg) {
- case 0:
- m.Cmdy(".show")
- case 1:
- m.Cmdy(".show", arg[0])
- case 2:
- m.Cmdy(".show", arg[0], "where", arg[1])
- case 3:
- m.Cmdy(".show", arg[0], arg[2], "where", arg[1])
- default:
- fields := []string{}
- values := []string{}
- for i := 2; i < len(arg)-1; i += 2 {
- fields = append(fields, arg[i])
- values = append(values, fmt.Sprintf("%s='%s'", arg[i], arg[i+1]))
- }
-
- stmt := []string{"update", arg[0]}
- stmt = append(stmt, "set", strings.Join(values, ","))
- stmt = append(stmt, "where", arg[1])
- m.Cmd(".exec", strings.Join(stmt, " "))
-
- m.Cmdy(".show", arg[0], fields, "where", arg[1])
- }
- return
- }},
-
- "ktv": &ctx.Command{Name: "ktv", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if len(arg) == 0 {
- now := kit.Int(m.Time("stamp"))
- m.Confm("ktv", "data", func(key string, value map[string]interface{}) {
- m.Push("key", key)
- m.Push("expire", kit.Int(value["expire"])-now)
- m.Push("value", value["value"])
- })
- m.Table()
- return
- }
- if len(arg) == 1 {
- if m.Confi("ktv", []string{"data", arg[0], "expire"}) < kit.Int(m.Time("stamp")) {
- m.Conf("ktv", []string{"data", arg[0]}, "")
- }
- m.Echo(m.Conf("ktv", []string{"data", arg[0], "value"}))
- return
- }
- m.Confv("ktv", []string{"data", arg[0]}, map[string]interface{}{
- "expire": m.Time(kit.Select(m.Conf("ktv", "conf.expire"), arg, 2), "stamp"),
- "value": arg[1],
- })
- m.Echo(arg[1])
- return
- }},
- "temp": &ctx.Command{Name: "temp [type [meta [data]]] [tid [node|ship|data] [chain... [select ...]]]",
- Form: map[string]int{"select": -1, "limit": 1}, Help: "缓存数据", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if len(arg) > 0 && arg[0] == "check" {
- h := ""
- for i := 1; i < len(arg)-1; i += 2 {
- switch arg[i] {
- case "url", "trans":
- h = ""
- }
- if h = m.Cmdx("aaa.hash", arg[i], arg[i+1], h); !m.Confs("temp", h) {
- return
- }
- expire := kit.Time(m.Conf("temp", []string{h, "create_time"})) + kit.Int(m.Confx("temp_expire")) - kit.Time(m.Time())
- m.Log("info", "expire: %ds", expire)
- if expire < 0 {
- return
- }
- }
- m.Echo(h)
- return
- }
-
- if len(arg) > 2 { // 添加数据
- if temp := m.Confm("temp", arg[0]); temp == nil {
- h := m.Cmdx("aaa.hash", arg[0], arg[1])
- m.Confv("temp", h, map[string]interface{}{
- "create_time": m.Time(), "expire_time": m.Time("60s"),
- "type": arg[0], "meta": arg[1], "data": m.Optionv(arg[2]),
- })
- arg[2], arg = h, arg[2:]
- }
- }
-
- if len(arg) > 1 {
- if temp, msg := m.Confm("temp", arg[0]), m; temp != nil {
- hash, arg := arg[0], arg[1:]
- switch arg[0] {
- case "node": // 查看节点
- m.Put("option", "temp", temp).Cmdy("ctx.trans", "temp")
- return
- case "ship": //查看链接
- for k, v := range temp {
- val := v.(map[string]interface{})
- m.Add("append", "key", k)
- m.Add("append", "create_time", val["create_time"])
- m.Add("append", "type", val["type"])
- m.Add("append", "meta", val["meta"])
- }
- m.Sort("create_time", "time_r").Table()
- return
- case "data": // 查看数据
- arg = arg[1:]
- }
-
- trans := strings.Join(append([]string{hash, "data"}, arg...), ".")
- h := m.Cmdx("aaa.hash", "trans", trans)
-
- if len(arg) == 0 || temp["type"].(string) == "trans" {
- h = hash
- } else { // 转换数据
- if view := m.Confm("temp", h); view != nil && false { // 加载缓存
- msg = m.Spawn()
- switch data := view["data"].(type) {
- case map[string][]string:
- msg.Meta = data
- case map[string]interface{}:
- for k, v := range data {
- switch val := v.(type) {
- case []interface{}:
- msg.Add("append", k, val)
- }
- }
- m.Confv("temp", []string{h, "data"}, msg.Meta)
- }
- temp = view
- } else if arg[0] == "hash" { // 添加缓存
- m.Echo(hash)
- } else if arg[0] == "" { // 添加缓存
- b, _ := json.MarshalIndent(temp["data"], "", " ")
- m.Echo(string(b))
- } else {
- msg = m.Put("option", "temp", temp["data"]).Cmd("ctx.trans", "temp", arg)
-
- m.Confv("temp", h, map[string]interface{}{
- "create_time": m.Time(), "expire_time": m.Time("60s"),
- "type": "trans", "meta": trans, "data": msg.Meta,
- "ship": map[string]interface{}{
- hash: map[string]interface{}{"create_time": m.Time(), "ship": "0", "type": temp["type"], "meta": temp["meta"]},
- },
- })
- m.Confv("temp", []string{hash, "ship", h}, map[string]interface{}{
- "create_time": m.Time(), "ship": "1", "type": "trans", "meta": trans,
- })
- temp = m.Confm("temp", h)
- }
- }
-
- if m.Options("select") { // 过滤数据
- chain := strings.Join(m.Optionv("select").([]string), " ")
- hh := m.Cmdx("aaa.hash", "select", chain, h)
-
- if view := m.Confm("temp", hh); view != nil && false { // 加载缓存
- msg = msg.Spawn()
- switch data := view["data"].(type) {
- case map[string][]string:
- msg.Meta = data
- case map[string]interface{}:
- for k, v := range data {
- switch val := v.(type) {
- case []interface{}:
- msg.Add("append", k, val)
- }
- }
- m.Confv("temp", []string{h, "data"}, msg.Meta)
- }
- } else { // 添加缓存
- msg = msg.Spawn().Copy(msg, "append").Cmd("select", m.Optionv("select"))
-
- m.Confv("temp", hh, map[string]interface{}{
- "create_time": m.Time(), "expire_time": m.Time("60s"),
- "type": "select", "meta": chain, "data": msg.Meta,
- "ship": map[string]interface{}{
- h: map[string]interface{}{"create_time": m.Time(), "ship": "0", "type": temp["type"], "meta": temp["meta"]},
- },
- })
-
- m.Confv("temp", []string{h, "ship", hh}, map[string]interface{}{
- "create_time": m.Time(), "ship": "1", "type": "select", "meta": chain,
- })
- }
- }
-
- msg.CopyTo(m)
- return
- }
- }
-
- h, arg := arg[0], arg[1:]
- if h != "" {
- if temp := m.Confm("temp", h); temp != nil {
- m.Echo(h)
- return
- }
- }
-
- // 缓存列表
- m.Confm("temp", func(key string, temp map[string]interface{}) {
- if len(arg) == 0 || strings.HasPrefix(key, arg[0]) || strings.HasSuffix(key, arg[0]) || (temp["type"].(string) == arg[0] && (len(arg) == 1 || strings.Contains(temp["meta"].(string), arg[1]))) {
- m.Add("append", "key", key)
- m.Add("append", "create_time", temp["create_time"])
- m.Add("append", "type", temp["type"])
- m.Add("append", "meta", temp["meta"])
- }
- })
- m.Sort("create_time", "time_r").Table().Cmd("select", m.Optionv("select"))
- return
- }},
- "note": &ctx.Command{Name: "note [model [name [type name]...]]|[index [name data...]]|[value name data...]|[name model data...]",
- Form: map[string]int{"eq": 2, "begin": 2, "offset": 1, "limit": 1}, Help: "记事", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- offset := kit.Int(kit.Select(m.Conf("table", "offset"), m.Option("table.offset")))
- limit := kit.Int(kit.Select(m.Conf("table", "limit"), m.Option("table.limit")))
-
- // 节点列表
- if len(arg) == 0 {
- m.CopyFuck(m.Cmd("mdb.config", "note", "format", "table", "fields", "create_time", "access_time", "type", "name", "data", "ship"), "append").Set("result").Table()
- return
- }
-
- // 节点详情
- if note := m.Confm("note", arg[0]); note != nil {
- m.CopyFuck(m.Cmd("mdb.config", "note", arg[0]), "append").Set("result").Table()
- return
- }
-
- // 节点列表
- hm, _ := kit.Hash("type", arg[0], "name", "shy")
- if len(arg) == 2 && arg[0] == "value" {
- hm, _ = kit.Hash("type", "index", "name", arg[1])
- hm = m.Conf("note", []string{hm, "ship", "value", "data"})
- arg = arg[1:]
- } else if len(arg) == 2 && arg[0] == "note" {
- hm, _ = kit.Hash("type", "model", "name", arg[1])
- hm = m.Conf("note", []string{hm, "ship", "note", "data"})
- arg = arg[1:]
- }
- if len(arg) == 1 && arg[0] != "show" {
- for i := offset; hm != "" && i < limit+offset; hm, i = m.Conf("note", []string{hm, "ship", "prev", "data"}), i+1 {
- model := m.Confm("note", hm)
- m.Add("append", "key", hm)
- m.Add("append", "create_time", model["create_time"])
- m.Add("append", "access_time", model["access_time"])
- m.Add("append", "type", model["type"])
- m.Add("append", "name", model["name"])
- m.Add("append", "view", kit.Format(model["view"]))
- m.Add("append", "data", kit.Format(model["data"]))
- m.Add("append", "ship", kit.Format(model["ship"]))
- }
- m.Table()
- return
- }
-
- switch arg[0] {
- case "show":
- if len(arg) == 1 { // 查看索引
- m.Cmdy("mdb.note", "index")
- break
- }
- if len(arg) == 2 {
- if arg[1] == "model" { // 查看模型
- m.Cmdy("mdb.note", "model")
- } else { // 查看数值
- m.Cmdy("mdb.note", "value", arg[1])
- }
- break
- }
-
- fields := kit.View(arg[3:], m.Confm("note_view"))
-
- hv, _ := kit.Hash("type", "value", "name", arg[1], "data", kit.Select(arg[2], m.Option(arg[2])))
- hn := m.Conf("note", []string{hv, "ship", "note", "data"})
- if arg[1] == "model" {
- hm, _ := kit.Hash("type", "model", "name", arg[2])
- hv, hn = "prev", m.Conf("note", []string{hm, "ship", "note", "data"})
- }
-
- fuck := 0
- for i := 0; hn != "" && i < limit+offset; hn, i = m.Conf("note", []string{hn, "ship", hv, "data"}), i+1 {
- m.Log("fuck", "what %d %d %d %s", offset, limit, i, hn)
- // m.Log("fuck", "what hn: %v %v", hn, kit.Formats(m.Confv("note", hn)))
- // 翻页
- if fuck++; fuck > 1000 {
- break
- }
-
- if i < offset {
- continue
- }
-
- // 关系表
- note := m.Confm("note", hn)
- hvs := kit.Trans(note["data"])
- hm := kit.Format(kit.Chain(note, "ship.model.data"))
-
- // 值转换
- value := []interface{}{}
- values := map[string]interface{}{}
- m.Confm("note", []string{hm, "data"}, func(i int, model map[string]interface{}) {
- v := m.Conf("note", []string{hvs[i], "data"})
- value = append(value, map[string]interface{}{"type": model["type"], "name": model["name"], "value": v})
- values[kit.Format(model["name"])] = v
- })
-
- // 行筛选
- miss := false
- if !miss && m.Has("eq") {
- for j := 0; j < len(m.Meta["eq"]); j += 2 {
- if kit.Select(kit.Format(note[m.Meta["eq"][j]]), kit.Format(values[m.Meta["eq"][j]])) != m.Meta["eq"][j+1] {
- miss = true
- break
- }
- }
- }
- if !miss && m.Has("begin") {
- for j := 0; j < len(m.Meta["begin"]); j += 2 {
- if !strings.HasPrefix(kit.Select(kit.Format(note[m.Meta["begin"][j]]),
- kit.Format(values[m.Meta["begin"][j]])), m.Meta["begin"][j+1]) {
- miss = true
- break
- }
- }
- }
- if miss {
- i--
- continue
- }
-
- // 列筛选
- for j := 0; j < len(fields); j++ {
- switch fields[j] {
- case "key":
- m.Add("append", "key", hn)
- case "create_time", "access_time", "type", "name":
- m.Add("append", fields[j], note[fields[j]])
- case "model":
- m.Add("append", "model", m.Conf("note", []string{hm, "name"}))
- case "view":
- m.Add("append", "view", kit.Format(m.Conf("note", []string{hm, "view"})))
- case "value":
- m.Add("append", "value", kit.Format(value))
- case "data", "ship":
- m.Add("append", fields[j], kit.Format(note[fields[j]]))
- default:
- m.Add("append", fields[j], kit.Format(values[fields[j]]))
- }
- }
- }
- m.Table()
-
- case "model":
- // 模板详情
- hm, _ := kit.Hash("type", arg[0], "name", arg[1])
- if len(arg) == 2 {
- m.CopyFuck(m.Cmd("mdb.config", "note", hm), "append").Set("result").Table()
- break
- }
-
- // 模板视图
- if arg[2] == "view" {
- for i := 4; i < len(arg)-1; i += 2 {
- m.Conf("note", []string{hm, "view", arg[3], arg[i]}, arg[i+1])
- }
- break
- }
-
- // 操作模板
- data := []interface{}{}
- if model := m.Confm("note", hm); model == nil { // 添加模板
- view := map[string]interface{}{}
- m.Confm("note", "81c5709d091eb04bd31ee751c3f81023.view", func(key string, fields map[string]interface{}) {
- vs := map[string]interface{}{}
- for k, v := range fields {
- vs[k] = v
- }
- view[key] = vs
- })
-
- prev := m.Conf("note", []string{"81c5709d091eb04bd31ee751c3f81023", "ship", "prev", "data"})
- m.Confv("note", hm, map[string]interface{}{
- "type": "model", "name": arg[1], "data": data, "view": view,
- "create_time": m.Time(), "access_time": m.Time(),
- "ship": map[string]interface{}{
- "prev": map[string]interface{}{"type": "model", "data": prev},
- "note": map[string]interface{}{"type": "note", "data": ""},
- },
- })
- m.Conf("note", []string{"81c5709d091eb04bd31ee751c3f81023", "ship", "prev", "data"}, hm)
- } else { // 修改模板
- data = m.Confv("note", []string{hm, "data"}).([]interface{})
- m.Confv("note", []string{hm, "access_time"}, m.Time())
- }
-
- // 操作元素
- if len(data) == 0 {
- arg = append(arg, kit.Trans(m.Confv("note", "81c5709d091eb04bd31ee751c3f81023.meta"))...)
- for i := 2; i < len(arg)-1; i += 2 {
- data = append(data, map[string]interface{}{"name": arg[i], "type": arg[i+1]})
-
- hi, _ := kit.Hash("type", "index", "name", arg[i+1])
- if index := m.Confm("note", hi); index == nil {
- m.Cmd("mdb.note", "index", arg[i+1])
- }
- }
- }
-
- m.Confv("note", []string{hm, "data"}, data)
- m.Echo(hm)
-
- case "index":
- // 操作索引
- data := arg[2:]
- hi, _ := kit.Hash("type", arg[0], "name", arg[1])
- if index := m.Confm("note", hi); index == nil { // 添加索引
- prev := m.Conf("note", []string{"faa01a8fc2fc92dae3fbc02ac1b4ec75", "ship", "prev", "data"})
- m.Confv("note", hi, map[string]interface{}{
- "create_time": m.Time(), "access_time": m.Time(),
- "type": "index", "name": arg[1], "data": data, "ship": map[string]interface{}{
- "prev": map[string]interface{}{"type": "index", "data": prev},
- "value": map[string]interface{}{"type": "value", "data": ""},
- },
- })
- m.Confv("note", []string{"faa01a8fc2fc92dae3fbc02ac1b4ec75", "ship", "prev", "data"}, hi)
- } else { // 修改索引
- m.Confv("note", []string{hi, "access_time"}, m.Time())
- data, _ = m.Confv("note", []string{hi, "data"}).([]string)
- }
-
- // 操作元素
- m.Confv("note", []string{hi, "data"}, data)
- m.Echo(hi)
-
- case "value":
- hi := m.Cmdx("mdb.note", "index", arg[1])
- hv, _ := kit.Hash("type", arg[0], "name", arg[1], "data", arg[2])
- if value := m.Confm("note", hv); value == nil {
- prev := m.Conf("note", []string{hi, "ship", "value", "data"})
- m.Confv("note", hv, map[string]interface{}{
- "create_time": m.Time(), "access_time": m.Time(),
- "type": arg[0], "name": arg[1], "data": arg[2], "ship": map[string]interface{}{
- "prev": map[string]interface{}{"type": "value", "data": prev},
- "index": map[string]interface{}{"type": "index", "data": hi},
- "note": map[string]interface{}{"type": "note", "data": ""},
- },
- })
- m.Conf("note", []string{hi, "ship", "value", "data"}, hv)
- } else {
- m.Confv("note", []string{hv, "access_time"}, m.Time())
- }
- m.Echo(hv)
-
- default:
- if len(arg) == 2 {
- }
-
- hm, _ := kit.Hash("type", "model", "name", arg[1])
- hn, _ := kit.Hash("type", "note", "name", arg[0], "uniq")
- hp := m.Conf("note", []string{hm, "ship", "note", "data"})
- if hp == hn {
- hp = ""
- }
- ship := map[string]interface{}{
- "prev": map[string]interface{}{"type": "note", "data": hp},
- "model": map[string]interface{}{"type": "model", "data": hm},
- }
-
- data := []interface{}{}
- m.Confm("note", []string{hm, "data"}, func(i int, index map[string]interface{}) {
- hv := m.Cmdx("mdb.note", "value", index["type"], kit.Select(m.Option(kit.Format(index["name"])), arg, i+2))
- data = append(data, hv)
-
- ship[hv] = map[string]interface{}{"type": "note", "data": m.Conf("note", []string{hv, "ship", "note", "data"})}
- m.Conf("note", []string{hv, "ship", "note", "data"}, hn)
- })
-
- m.Confv("note", hn, map[string]interface{}{
- "create_time": m.Time(), "access_time": m.Time(),
- "type": "note", "name": arg[0], "data": data, "ship": ship,
- })
- m.Conf("note", []string{hm, "ship", "note", "data"}, hn)
- m.Echo(hn)
- }
- return
-
- sync := len(arg) > 0 && arg[0] == "sync"
- if sync {
- m.Cmdy("ssh.sh", "sub", "context", "mdb", "note", arg)
- m.Set("result").Table()
- arg = arg[1:]
- }
-
- h, _ := kit.Hash("uniq")
- data := map[string]interface{}{
- "create_time": m.Time(),
- "type": arg[0],
- "title": arg[1],
- "content": arg[2],
- }
- for i := 3; i < len(arg)-1; i += 2 {
- kit.Chain(data, data[arg[i]], arg[i+1])
- }
- m.Conf("note", h, data)
- m.Echo(h)
- return
- }},
- },
-}
-
-func init() {
- ctx.Index.Register(Index, &MDB{Context: Index})
-}
diff --git a/usr/local/honor/src/contexts/nfs/nfs.go b/usr/local/honor/src/contexts/nfs/nfs.go
deleted file mode 100644
index e6be05e8..00000000
--- a/usr/local/honor/src/contexts/nfs/nfs.go
+++ /dev/null
@@ -1,1325 +0,0 @@
-package nfs
-
-import (
- "bufio"
- "bytes"
- "contexts/ctx"
- "crypto/md5"
- "crypto/sha1"
- "encoding/csv"
- "encoding/hex"
- "encoding/json"
- "fmt"
- "io"
- "io/ioutil"
- "net/url"
- "os"
- "os/exec"
- "path"
- "regexp"
- "sort"
- "strings"
- "time"
- "toolkit"
-)
-
-type NFS struct {
- in *os.File
- out *os.File
- io io.ReadWriter
-
- send chan *ctx.Message
- echo chan *ctx.Message
- hand map[int]*ctx.Message
-
- *ctx.Context
-}
-
-func dir(m *ctx.Message, root string, name string, level int, deep bool, dir_type string, dir_reg *regexp.Regexp, fields []string, format string) {
-
- if fs, e := ioutil.ReadDir(name); m.Assert(e) {
- for _, f := range fs {
- if f.Name() == "." || f.Name() == ".." {
- continue
- }
- if strings.HasPrefix(f.Name(), ".") && dir_type != "all" {
- continue
- }
-
- p := path.Join(name, f.Name())
- if f, e = os.Lstat(p); e != nil {
- m.Log("info", "%s", e)
- continue
- } else if (f.Mode()&os.ModeSymlink) != 0 && f.IsDir() {
- continue
- }
-
- if !(dir_type == "file" && f.IsDir() || dir_type == "dir" && !f.IsDir()) && (dir_reg == nil || dir_reg.MatchString(f.Name())) {
- for _, field := range fields {
- switch field {
- case "time":
- m.Add("append", "time", f.ModTime().Format(format))
- case "type":
- if m.Assert(e) && f.IsDir() {
- m.Add("append", "type", "dir")
- } else {
- m.Add("append", "type", "file")
- }
- case "full":
- if f.IsDir() {
- m.Add("append", "full", path.Join(root, name, f.Name())+"/")
- } else {
- m.Add("append", "full", path.Join(root, name, f.Name()))
- }
- case "path":
- if f.IsDir() {
- m.Add("append", "path", path.Join(name, f.Name())+"/")
- } else {
- m.Add("append", "path", path.Join(name, f.Name()))
- }
- case "file":
- if f.IsDir() {
- m.Add("append", "file", f.Name()+"/")
- } else {
- m.Add("append", "file", f.Name())
- }
- case "name":
- m.Add("append", "name", f.Name())
- case "tree":
- if level == 0 {
- m.Add("append", "tree", f.Name())
- } else {
- m.Add("append", "tree", strings.Repeat("| ", level-1)+"|-"+f.Name())
- }
- case "size":
- m.Add("append", "size", f.Size())
- case "line":
- if f.IsDir() {
- if d, e := ioutil.ReadDir(p); m.Assert(e) {
- count := 0
- for _, f := range d {
- if strings.HasPrefix(f.Name(), ".") {
- continue
- }
- count++
- }
- m.Add("append", "line", count)
- }
- } else {
- nline := 0
- if f, e := os.Open(p); m.Assert(e) {
- defer f.Close()
- for bio := bufio.NewScanner(f); bio.Scan(); nline++ {
- bio.Text()
- }
- }
- m.Add("append", "line", nline)
- }
- case "hash", "hashs":
- var h [20]byte
- if f.IsDir() {
- if d, e := ioutil.ReadDir(p); m.Assert(e) {
- meta := []string{}
- for _, v := range d {
- meta = append(meta, fmt.Sprintf("%s%d%s", v.Name(), v.Size(), v.ModTime()))
- }
- sort.Strings(meta)
- h = sha1.Sum([]byte(strings.Join(meta, "")))
- }
- } else {
- if f, e := ioutil.ReadFile(path.Join(name, f.Name())); m.Assert(e) {
- h = sha1.Sum(f)
- }
- }
- if field == "hash" {
- m.Add("append", "hash", hex.EncodeToString(h[:]))
- } else {
- m.Add("append", "hash", hex.EncodeToString(h[:4]))
- }
- }
- }
- }
- if f.IsDir() && deep {
- dir(m, root, p, level+1, deep, dir_type, dir_reg, fields, format)
- }
- }
- }
-}
-func sed(m *ctx.Message, p string, args []string) error {
- p0 := p + ".tmp0"
- p1 := p + ".tmp1"
- if _, e := os.Stat(p1); e == nil {
- return e
- }
- out, e := os.Create(p1)
- defer os.Remove(p1)
- defer out.Close()
- m.Log("info", "open %v", p1)
-
- if _, e := os.Stat(p0); e != nil {
- m.Cmd("nfs.copy", p0, p)
- }
- in, e := os.Open(p0)
- defer in.Close()
- m.Log("info", "open %v", p0)
-
- switch args[0] {
- case "set":
- defer os.Rename(p1, p0)
- defer os.Remove(p0)
-
- index := kit.Int(args[1])
- for bio, i := bufio.NewScanner(in), 0; bio.Scan(); i++ {
- if i == index {
- out.WriteString(args[2])
- } else {
- out.WriteString(bio.Text())
- }
- out.WriteString("\n")
- }
- return e
-
- case "add":
- out0, _ := os.OpenFile(p0, os.O_WRONLY|os.O_APPEND, 0666)
- defer out0.Close()
- out0.WriteString("\n")
-
- case "put":
- defer os.Rename(p0, p)
- }
- return nil
-}
-func open(m *ctx.Message, name string, arg ...int) (string, *os.File, error) {
- if !path.IsAbs(name) {
- m.Confm("pwd", func(i int, v string) bool {
- p := path.Join(v, name)
- if s, e := os.Stat(p); e == nil && !s.IsDir() {
- name = p
- return true
- }
- return false
- })
- }
-
- flag := os.O_RDONLY
- if len(arg) > 0 {
- flag = arg[0]
- }
-
- f, e := os.OpenFile(name, flag, 0660)
- if e == nil {
- m.Log("info", "open %s", name)
- } else {
- m.Log("warn", "%v", e)
- }
- return name, f, e
-}
-
-func (nfs *NFS) Recv(line string) (field string, value string) {
- m := nfs.Context.Message()
-
- m.Log("recv", "%d [%s]", len(line), line)
- m.Capi("nread", len(line)+1)
-
- word := strings.Split(line, ": ")
- field, e := url.QueryUnescape(word[0])
- m.Assert(e)
- if len(word) == 1 {
- return
- }
- if len(word[1]) == 0 {
- return
- }
-
- value, e = url.QueryUnescape(word[1])
- m.Assert(e)
- return
-}
-func (nfs *NFS) Send(w io.Writer, meta string, arg ...interface{}) *NFS {
- m := nfs.Context.Message()
-
- line := "\n"
- if meta != "" {
- if text, ok := arg[0].(string); ok && meta == "result" && len(text) > 1024 {
- text := arg[0].(string)
- for i := 0; i < len(text); i += 1024 {
- j := i + 1024
- if j >= len(text) {
- j = len(text)
- }
- line = fmt.Sprintf("%s: %s\n", url.QueryEscape(meta), url.QueryEscape(kit.Format(text[i:j])))
- n, e := fmt.Fprint(w, line)
- m.Assert(e)
- m.Capi("nwrite", n)
- m.Log("send", "%d [%s]", len(line), line)
- }
- return nfs
- } else {
- line = fmt.Sprintf("%s: %s\n", url.QueryEscape(meta), url.QueryEscape(kit.Format(arg[0])))
- }
- }
-
- n, e := fmt.Fprint(w, line)
- m.Assert(e)
- m.Capi("nwrite", n)
- m.Log("send", "%d [%s]", len(line), line)
-
- return nfs
-}
-
-func (nfs *NFS) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server {
- if len(arg) > 0 && (arg[0] == "scan" || arg[0] == "open" || arg[0] == "append") {
- c.Caches = map[string]*ctx.Cache{
- "pos": &ctx.Cache{Name: "pos", Value: "0", Help: "pos"},
- "size": &ctx.Cache{Name: "size", Value: "0", Help: "size"},
- "nread": &ctx.Cache{Name: "nread", Value: "0", Help: "nread"},
- "nwrite": &ctx.Cache{Name: "nwrite", Value: "0", Help: "nwrite"},
- }
- c.Configs = map[string]*ctx.Config{}
- } else {
- c.Caches = map[string]*ctx.Cache{
- "nsend": &ctx.Cache{Name: "消息发送数量", Value: "0", Help: "消息发送数量"},
- "nrecv": &ctx.Cache{Name: "消息接收数量", Value: "0", Help: "消息接收数量"},
- "nread": &ctx.Cache{Name: "nread", Value: "0", Help: "nread"},
- "nwrite": &ctx.Cache{Name: "nwrite", Value: "0", Help: "nwrite"},
- }
- c.Configs = map[string]*ctx.Config{}
- }
-
- return &NFS{Context: c}
-
-}
-func (nfs *NFS) Begin(m *ctx.Message, arg ...string) ctx.Server {
- return nfs
-}
-func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
-
- if len(arg) > 0 && (arg[0] == "open" || arg[0] == "append") {
- nfs.out = m.Optionv("out").(*os.File)
- nfs.in = m.Optionv("in").(*os.File)
- m.Cap("stream", arg[1])
-
- if s, e := nfs.in.Stat(); m.Assert(e) {
- if m.Capi("size", int(s.Size())); arg[0] == "append" {
- m.Capi("pos", int(s.Size()))
- }
- }
- return false
- }
-
- if len(arg) > 0 && arg[0] == "scan" {
- m.Cap("stream", arg[1])
- nfs.Caches["ninput"] = &ctx.Cache{Value: "0"}
- nfs.Caches["noutput"] = &ctx.Cache{Value: "0"}
- nfs.Caches["termbox"] = &ctx.Cache{Value: "0"}
- nfs.Configs["input"] = &ctx.Config{Value: []interface{}{}}
- nfs.Configs["output"] = &ctx.Config{Value: []interface{}{}}
- nfs.Configs["prompt"] = &ctx.Config{Value: ""}
-
- // 终端控制
- if nfs.in = m.Optionv("bio.in").(*os.File); m.Has("bio.out") {
- if nfs.out = m.Optionv("bio.out").(*os.File); m.Options("daemon") {
- return false
- }
- if m.Conf("runtime", "host.GOOS") != "windows" {
- m.Conf("term", "use", nfs.Term(m, "init") != nil)
- defer nfs.Term(m, "exit")
- kit.STDIO = nfs
- }
- }
-
- // 语句堆栈
- stack := &kit.Stack{}
- stack.Push(m.Option("stack.key", "source"), m.Options("stack.run", true), m.Optioni("stack.pos", 0))
-
- input := make([]string, 0, 128)
-
- line, bio := "", bufio.NewScanner(nfs)
- for nfs.prompt(); ; nfs.prompt() {
-
- // 读取数据
- for bio.Scan() {
- if text := bio.Text(); text == "" {
- continue
- } else if !strings.HasSuffix(text, "\\") {
- line += text
- break
- } else {
- line += strings.TrimSuffix(text, "\\")
- }
- }
- if line == "" {
- break
- }
- m.Log("debug", "%s %d %d [%s]", "input", m.Capi("ninput", 1), len(line), line)
- m.Confv("input", -2, map[string]interface{}{"time": time.Now().Unix(), "line": line})
-
- if input = append(input, line); m.Goshy(input, len(input)-1, stack, func(msg *ctx.Message) {
- if m.Confs("term", "use") {
- nfs.print(m.Conf("prompt"), line)
- }
- nfs.print(msg.Meta["result"]...)
- }) {
- break
- }
- line = ""
- }
- return true
- }
-
- m.Cap("stream", m.Option("ms_source"))
- nfs.io, _ = m.Optionv("io").(io.ReadWriter)
- nfs.send = make(chan *ctx.Message, 10)
- nfs.echo = make(chan *ctx.Message, 10)
- nfs.hand = map[int]*ctx.Message{}
-
- // 消息发送队列
- m.GoLoop(m, func(m *ctx.Message) {
- msg, code, meta, body := m, 0, "detail", "option"
- select {
- case msg = <-nfs.send: // 发送请求
- code = msg.Code()
- nfs.hand[code] = msg
- case msg = <-nfs.echo: // 发送响应
- code, meta, body = msg.Optioni("remote_code"), "result", "append"
- }
-
- buf := bytes.NewBuffer(make([]byte, 0, 1024))
- nfs.Send(buf, "_code", code)
- for _, v := range msg.Meta[meta] {
- nfs.Send(buf, meta, v)
- }
- for _, k := range msg.Meta[body] {
- for _, v := range msg.Meta[k] {
- nfs.Send(buf, k, v)
- }
- }
- nfs.Send(buf, "")
- buf.WriteTo(nfs.io)
- })
-
- // 消息接收队列
- msg, code, head, body := m, "0", "result", "append"
- bio := bufio.NewScanner(nfs.io)
- bio.Buffer(make([]byte, m.Confi("buf", "size")), m.Confi("buf", "size"))
- for bio.Scan() {
-
- m.TryCatch(m, true, func(m *ctx.Message) {
- switch field, value := nfs.Recv(bio.Text()); field {
- case "_code":
- msg, code = m.Sess("ms_target"), value
- msg.Meta = map[string][]string{}
-
- case "detail":
- head, body = "detail", "option"
- msg.Add(field, value)
-
- case "result":
- head, body = "result", "append"
- msg.Add(field, value)
-
- case "":
- if head == "detail" { // 接收请求
- msg.Detail(-1, "_route")
- msg.Option("remote_code", code)
- m.Gos(msg, func(msg *ctx.Message) {
- msg.Log("time", "parse %v", msg.Format("cost", "detail"))
- msg.Call(func(msg *ctx.Message) *ctx.Message {
- nfs.echo <- msg
- return nil
- })
- })
- } else { // 接收响应
- m.Set("option", "_code", code).Gos(msg, func(msg *ctx.Message) {
- if h, ok := nfs.hand[kit.Int(m.Option("_code"))]; ok {
- h.CopyFuck(msg, "result").CopyFuck(msg, "append").Back(h)
- }
- })
- }
- msg, code, head, body = nil, "0", "result", "append"
-
- default:
- msg.Add(body, field, value)
- }
- }, func(m *ctx.Message) {
- for bio.Scan() {
- if text := bio.Text(); text == "" {
- break
- }
- }
- })
- }
-
- msg = m.Sess("tcp", false)
- msg.Target().Close(msg)
- return true
-}
-func (nfs *NFS) Close(m *ctx.Message, arg ...string) bool {
- return true
-}
-
-var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
- Caches: map[string]*ctx.Cache{
- "bio": &ctx.Cache{Name: "bio", Value: "0", Help: "文件数量"},
- },
- Configs: map[string]*ctx.Config{
- "term": &ctx.Config{Name: "term", Value: map[string]interface{}{
- "use": "false",
- "mouse": map[string]interface{}{
- "resize": false,
- },
- "width": 80, "height": "24",
-
- "left": 0, "top": 0, "right": 80, "bottom": 24,
- "cursor_x": 0, "cursor_y": 0, "fgcolor": -1, "bgcolor": -1,
- "prompt": "", "wrap": "false",
- "scroll_count": "5",
- "scroll_lines": "5",
- "begin_row": 0, "begin_col": 0,
-
- "shadow": "hello",
- "show_shadow": "false",
-
- "rest_fg": "0",
- "rest_bg": "7",
- "pick_fg": "0",
- "pick_bg": "7",
- "pick": "",
-
- "help_index": 0,
- "help_state": "command",
- "help_next_auto": "=",
- "help_stack": []interface{}{},
- "help_table": map[string]interface{}{},
- }, Help: "终端管理"},
- "auto": &ctx.Config{Name: "auto", Value: map[string]interface{}{
- "!": map[string]interface{}{
- "state": "message",
- "next_auto": ":",
- "color": 2, "cmd": "message",
- "table": "message", "field": "code",
- "format": "%s(%s) %s->%s %s %s", "fields": []interface{}{"code", "time", "source", "target", "details", "options"},
- },
- "~": map[string]interface{}{
- "state": "context", "next_auto": ":",
- "color": 2, "cmd": "context",
- "table": "context", "field": "name",
- "format": "%s(%s) %s %s", "fields": []interface{}{"name", "status", "stream", "help"},
- },
- "": map[string]interface{}{
- "state": "command", "next_auto": "=",
- "color": 3, "cmd": "command",
- "table": "command", "field": "key",
- "format": "%s %s", "fields": []interface{}{"key", "name"},
- },
- ":": map[string]interface{}{
- "state": "command", "next_auto": "=",
- "color": 3, "cmd": "command",
- "table": "command", "field": "key",
- "format": "%s %s", "fields": []interface{}{"key", "name"},
- },
- "=": map[string]interface{}{
- "cmd": "help",
- "format": "%s %s %s ", "fields": []interface{}{"value", "name", "help"},
- "color": 3, "table": "command", "field": "value",
- "state": "argument", "next_auto": "=",
- },
- "@": map[string]interface{}{
- "state": "config", "next_auto": "@",
- "color": 4, "cmd": "config",
- "table": "config", "field": "key",
- "format": "%s(%s) %s", "fields": []interface{}{"key", "value", "name"},
- },
- "$": map[string]interface{}{
- "state": "cache", "next_auto": "$",
- "color": 7, "cmd": "cache",
- "table": "cache", "field": "key",
- "format": "%s(%s) %s", "fields": []interface{}{"key", "value", "name"},
- },
- }, Help: "自动补全"},
-
- "buf": &ctx.Config{Name: "buf", Value: map[string]interface{}{
- "size": "81920",
- }, Help: "文件缓存"},
- "grep": &ctx.Config{Name: "grep", Value: map[string]interface{}{}, Help: "文件搜索"},
- "git": &ctx.Config{Name: "git", Value: map[string]interface{}{
- "args": []interface{}{},
- "info": map[string]interface{}{"cmds": []interface{}{"log", "status", "branch"}},
- "update": map[string]interface{}{"cmds": []interface{}{"stash", "pull", "pop"}},
- "pop": map[string]interface{}{"args": []interface{}{"stash", "pop"}},
- "commit": map[string]interface{}{"args": []interface{}{"commit", "-am"}},
- "branch": map[string]interface{}{"args": []interface{}{"branch", "-v"}},
- "status": map[string]interface{}{"args": []interface{}{"status", "-sb"}},
- "log": map[string]interface{}{"args": []interface{}{"log", "-n", "@table.limit", "--skip", "@table.offset", "pretty", "cmd_parse", "cut", "5", "date"}},
- "logs": map[string]interface{}{"args": []interface{}{"log", "-n", "@table.limit", "--skip", "@table.offset", "--stat"}},
- "trans": map[string]interface{}{
- "date": "--date=format:%m/%d %H:%M",
- "pretty": "--pretty=format:%h %ad %an %s",
- },
- "local": "usr/local",
- }, Help: "版本管理"},
- "dir": &ctx.Config{Name: "dir", Value: map[string]interface{}{
- "fields": "time size line path",
- "type": "both",
- "temp": "var/tmp/file",
- "trash": "var/tmp/trash",
- "mime": map[string]interface{}{
- "js": "txt",
- "css": "txt",
- "html": "txt",
- "shy": "txt",
- "py": "txt",
- "go": "txt",
- "h": "txt",
- "c": "txt",
- "gz": "bin",
- },
- }, Help: "目录管理"},
- "pwd": &ctx.Config{Name: "pwd", Value: []interface{}{
- "", "usr/local", "usr", "var", "bin", "etc", "src", "src/plugin",
- }, Help: "当前目录"},
- },
- Commands: map[string]*ctx.Command{
- "_init": &ctx.Command{Name: "_init", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- m.Conf("pwd", -2, m.Conf("runtime", "boot.ctx_home"))
- m.Conf("pwd", -2, m.Conf("runtime", "boot.ctx_root"))
- return
- }},
- "_exit": &ctx.Command{Name: "_init", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- m.Cmd("nfs.term", "exit")
- return
- }},
- "path": &ctx.Command{Name: "path filename", Help: "查找文件路径", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if len(arg) == 0 {
- return
- }
-
- file := path.Join(arg...)
- p := path.Join("src/plugin", m.Option("plugin"), file)
- if _, e := os.Stat(p); e == nil {
- m.Echo(p)
- return e
- }
-
- m.Confm("pwd", func(index int, value string) bool {
- p := path.Join(value, file)
- if _, e := os.Stat(p); e == nil {
- m.Echo(p)
- return true
- }
- return false
- })
- return
- }},
- "pwd": &ctx.Command{Name: "pwd [all] | [[index] path] ", Help: "当前目录,all: 查看所有, index path: 设置路径, path: 设置当前路径", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if len(arg) > 0 && arg[0] == "all" {
- m.Cmdy("nfs.config", "pwd")
- return
- }
-
- index := 0
- if len(arg) > 1 {
- index, arg = kit.Int(arg[0]), arg[1:]
- }
- for i, v := range arg {
- m.Log("info", "pwd %s %s", index+i, v)
- m.Confv("pwd", index+i, v)
- }
-
- if p := m.Conf("pwd", index); path.IsAbs(p) {
- m.Echo("%s", p)
- } else if wd, e := os.Getwd(); m.Assert(e) {
- m.Echo("%s", path.Join(wd, p))
- }
- return
- }},
- "dir": &ctx.Command{Name: "dir [path [fields...]]", Help: []string{
- "查看目录, path: 路径, fields...: 查询字段, time|type|full|path|name|tree|size|line|hash|hashs",
- "dir_deep: 递归查询", "dir_type both|file|dir|all: 文件类型", "dir_reg reg: 正则表达式", "dir_sort field order: 排序"},
- Form: map[string]int{"dir_deep": 0, "dir_type": 1, "dir_reg": 1, "dir_sort": 2, "dir_sed": -1, "dir_select": -1,
- "offset": 1, "limit": 1,
- "match_begin": 1,
- "match_end": 1,
- },
- Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if len(arg) == 0 {
- arg = append(arg, "")
- }
-
- if args := kit.Trans(m.Optionv("dir_sed")); len(args) > 0 {
- return sed(m, arg[0], args)
- }
-
- mime := m.Conf("dir", []string{"mime", strings.TrimPrefix(path.Ext(arg[0]), ".")})
-
- skip, find := false, false
- m.Confm("pwd", func(index int, value string) bool {
- p := kit.Select("./", path.Join(value, arg[0]))
- if s, e := os.Stat(p); e == nil {
- if s.IsDir() {
- rg, _ := regexp.Compile(m.Option("dir_reg"))
- dir_type := kit.Select(m.Conf("dir", "type"), m.Option("dir_type"))
- fields := strings.Split(kit.Select(m.Conf("dir", "fields"), strings.Join(arg[1:], " ")), " ")
-
- dir(m, kit.Pwd(), p, 0, kit.Right(m.Has("dir_deep")),
- dir_type, rg, fields, m.Conf("time", "format"))
-
- } else if mime != "txt" && (mime == "bin" || s.Size() > int64(m.Confi("buf", "size"))) {
- m.Append("directory", p)
-
- } else {
- p0 := p + ".tmp0"
- f, e := os.Open(p0)
- if e != nil {
- if f, e = os.Open(p); e == nil {
- p0 = p
- }
- }
- m.Log("info", "open %v", p0)
- m.Append("file", p)
-
- if m.Has("match_begin") {
- m.Option("match_begin")
- begin, _ := regexp.Compile(m.Option("match_begin"))
- end, _ := regexp.Compile(m.Option("match_end"))
- start := false
- for bio := bufio.NewScanner(f); bio.Scan(); {
- if start = start || begin.MatchString(bio.Text()); m.Option("match_begin") == "" || start {
- if m.Echo(bio.Text()); m.Option("match_end") != "" && end.MatchString(bio.Text()) {
- break
- }
- }
- }
-
- } else {
- offset := m.Optioni("offset")
- limit := m.Optioni("limit")
- for bio, i := bufio.NewScanner(f), 0; bio.Scan(); i++ {
- if i >= offset && (limit == 0 || i < offset+limit) {
- m.Echo(bio.Text())
- }
- m.Append("line", i+1)
- m.Append("offset", offset)
- m.Append("limit", limit)
- }
- }
-
- m.Append("size", s.Size())
- m.Append("time", s.ModTime().Format(m.Conf("time", "format")))
- skip = true
- }
-
- find = true
- return true
- }
- return false
- })
-
- // if !find && arg[0] != "" {
- // if strings.HasSuffix(arg[0], "/") {
- // m.Assert(os.MkdirAll(arg[0], 0777))
- // m.Echo(arg[0])
- // } else if f, p, e := kit.Create(arg[0]); m.Assert(e) {
- // f.Close()
- // m.Echo(p)
- // }
- // }
- //
- if m.Has("dir_sort") {
- m.Sort(m.Meta["dir_sort"][0], m.Meta["dir_sort"][1:]...)
- }
-
- if len(m.Meta["append"]) == 1 {
- for _, v := range m.Meta[m.Meta["append"][0]] {
- m.Echo(v).Echo(" ")
- }
- } else if !skip {
- if m.Has("dir_select") {
- m.Cmd("select", m.Meta["dir_select"])
- } else {
- m.Table()
- }
- }
- return
- }},
- "git": &ctx.Command{Name: "git sum", Help: "版本控制", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if len(arg) == 0 {
- m.Cmdy("nfs.config", "git")
- return
- }
-
- if p := m.Cmdx("nfs.path", arg[0]); p != "" && !m.Confs("git", arg[0]) {
- m.Option("git_dir", p)
- arg = arg[1:]
- }
-
- if len(arg) > 0 {
- switch arg[0] {
- case "local":
- m.Cmd("cli.system", "git", "clone", arg[1], "cmd_dir", m.Conf("git", "local"))
- return
- case "sum":
- ts := false
- if len(arg) > 1 && arg[1] == "total" {
- ts, arg = true, arg[1:]
- }
-
- args := []string{}
- if m.Options("git_dir") {
- args = append(args, "-C", m.Option("git_dir"))
- }
- if args = append(args, "log", "--shortstat", "--pretty=commit: %ad %n%s", "--date=iso"); len(arg) > 1 {
- args = append(args, arg[1:]...)
- } else {
- args = append(args, "--reverse")
- }
-
- var total_day time.Duration
- begin := ""
- total := 0
- total_add := 0
- total_del := 0
- if out, e := exec.Command("git", args...).CombinedOutput(); e == nil {
- for _, v := range strings.Split(string(out), "commit: ") {
- if l := strings.Split(v, "\n"); len(l) > 3 {
- fs := strings.Split(strings.TrimSpace(l[3]), ", ")
- hs := strings.Split(l[0], " ")
- m.Push("date", hs[0])
- if total_day == 0 {
- if t, e := time.Parse("2006-01-02", hs[0]); e == nil {
- begin, total_day = hs[0], time.Now().Sub(t)
- }
- }
-
- if adds := strings.Split(fs[1], " "); len(fs) > 2 {
- dels := strings.Split(fs[2], " ")
- total_del += kit.Int(dels[0])
- total_add += kit.Int(adds[0])
- m.Push("adds", adds[0])
- m.Push("dels", dels[0])
- } else if adds[1] == "insertions(+)" {
- total_add += kit.Int(adds[0])
- m.Push("adds", adds[0])
- m.Push("dels", "0")
- } else {
- m.Push("adds", "0")
- m.Push("dels", adds[0])
- }
- total++
- m.Push("note", l[1])
- m.Push("hour", strings.Split(hs[1], ":")[0])
- m.Push("time", hs[1])
- } else if len(l[0]) > 0 {
- total++
- hs := strings.Split(l[0], " ")
- m.Push("date", hs[0])
- m.Push("adds", 0)
- m.Push("dels", 0)
- m.Push("note", l[1])
- m.Push("hour", strings.Split(hs[1], ":")[0])
- m.Push("time", hs[1])
- }
- }
- if ts {
- m.Set("append")
- m.Append("from", begin)
- m.Append("days", int(total_day.Hours())/24)
- m.Append("commit", total)
- m.Append("adds", total_add)
- m.Append("dels", total_del)
- m.Append("rest", total_add-total_del)
- }
- m.Table()
- } else {
- m.Log("warn", "%v", string(out))
- }
- return
- }
- }
-
- cmds := []string{}
- if v := m.Confv("git", []string{arg[0], "cmds"}); v != nil {
- cmds = append(cmds, kit.Trans(v)...)
- } else {
- cmds = append(cmds, arg[0])
- }
-
- for _, cmd := range cmds {
- args := append([]string{}, kit.Trans(m.Confv("git", "args"))...)
- if m.Options("git_dir") {
- args = append(args, "-C", m.Option("git_dir"))
- }
- if v := m.Confv("git", []string{cmd, "args"}); v != nil {
- args = append(args, kit.Trans(v)...)
- } else {
- args = append(args, cmd)
- }
- args = append(args, arg[1:]...)
-
- for i, _ := range args {
- if v := m.Parse(args[i]); v == args[i] || v == "" {
- args[i] = kit.Select(args[i], m.Conf("git", []string{"trans", args[i]}))
- } else {
- args[i] = v
- }
- }
-
- m.Cmd("cli.system", "git", args).Echo("\n\n").CopyTo(m)
- }
- return
- }},
-
- "template": &ctx.Command{Name: "template [force] target source...", Help: "生成模板", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- force := false
- if arg[0] == "force" {
- force, arg = true, arg[1:]
- }
-
- if _, e := os.Stat(arg[0]); os.IsNotExist(e) || force {
- if strings.HasSuffix(arg[0], "/") && m.Assert(os.MkdirAll(arg[0], 0777)) {
-
- kit.List(arg[1:], func(p string) {
- m.Cmd("nfs.dir", p, "name", "path").Table(func(line map[string]string) {
- if w, _, e := kit.Create(path.Join(arg[0], line["name"])); m.Assert(e) {
- defer w.Close()
-
- m.Assert(ctx.ExecuteFile(m, w, line["path"]))
- }
- })
- })
- } else if w, _, e := kit.Create(arg[0]); m.Assert(e) {
- defer w.Close()
-
- kit.List(arg[1:], func(p string) {
- m.Cmd("nfs.dir", p).Table(func(line map[string]string) {
- m.Assert(ctx.ExecuteFile(m, w, line["path"]))
- })
- })
- }
- }
-
- m.Cmdy("nfs.dir", arg[0], "time", "line", "hashs", "path")
- return
- }},
- "temp": &ctx.Command{Name: "temp data", Help: "查找文件路径", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if f, p, e := kit.Create(path.Join(m.Conf("dir", "temp"), kit.Hashs(arg[0]))); m.Assert(e) {
- defer f.Close()
-
- for _, v := range arg {
- if n, e := f.WriteString(v); e == nil {
- m.Log("info", "save %v %v", n, p)
- }
- }
- m.Echo(p)
- }
- return
- }},
- "hash": &ctx.Command{Name: "hash file", Help: "文件哈希", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- p := m.Append("name", m.Cmdx("nfs.path", arg[0]))
- if s, e := os.Stat(p); e == nil && !s.IsDir() {
- m.Append("size", s.Size())
- if f, e := os.Open(p); e == nil {
- defer f.Close()
-
- md := md5.New()
- io.Copy(md, f)
- h := md.Sum(nil)
- m.Echo(hex.EncodeToString(h[:]))
- }
- } else if f, p, e := kit.Create(path.Join(m.Conf("dir", "temp"), kit.Hashs(arg[0]))); m.Assert(e) {
- defer f.Close()
- if n, e := f.WriteString(arg[0]); m.Assert(e) {
- m.Log("info", "save %v %v", n, p)
- m.Echo(p)
- }
- }
- return
- }},
- "copy": &ctx.Command{Name: "copy to from", Help: "查找文件路径", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if to, p, e := kit.Create(arg[0]); m.Assert(e) {
- defer to.Close()
-
- for _, from := range arg[1:] {
- if f, e := os.Open(m.Cmdx("nfs.path", from)); e == nil {
- defer f.Close()
-
- if n, e := io.Copy(to, f); m.Assert(e) {
- m.Log("info", "copy %d to %s from %s", n, p, from)
- }
- }
- }
- m.Echo(p)
- }
- return
- }},
- "grep": &ctx.Command{Name: "grep head|tail|hold|more table arg", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- hold := false
- switch arg[0] {
- case "search":
- m.Cmdy("cli.system", "grep", arg[1:])
-
- case "add":
- m.Confv("grep", []string{arg[1], "list", "-2"}, map[string]interface{}{
- "pos": 0, "offset": 0, "file": arg[2],
- })
- return
-
- case "head":
- m.Confm("grep", []string{arg[1], "list"}, func(index int, value map[string]interface{}) {
- if len(arg) == 2 {
- value["offset"] = 0
- value["pos"] = 0
- }
- })
- return
-
- case "tail":
- m.Confm("grep", []string{arg[1], "list"}, func(index int, value map[string]interface{}) {
- if len(arg) == 2 {
- value["pos"] = -1
- value["offset"] = 0
- }
- })
- return
-
- case "hold":
- hold, arg = true, arg[1:]
-
- case "more":
- hold, arg = false, arg[1:]
- }
-
- m.Confm("grep", []string{arg[0], "list"}, func(index int, value map[string]interface{}) {
- f, e := os.Open(kit.Format(value["file"]))
- if e != nil {
- m.Log("warn", "%v", e)
- return
- }
- defer f.Close()
-
- s, e := f.Stat()
- if e != nil {
- m.Log("warn", "%v", e)
- return
- }
-
- offset := kit.Int(value["offset"])
- begin, e := f.Seek(int64(kit.Int(value["pos"])), 0)
- if kit.Int(value["pos"]) == -1 {
- begin, e = f.Seek(0, 2)
- }
- m.Assert(e)
- file := path.Base(kit.Format(value["file"]))
-
- bio := bufio.NewScanner(f)
- for i := 0; i < m.Optioni("table.limit") && bio.Scan(); i++ {
- text := bio.Text()
- if len(arg) == 1 || strings.Contains(text, arg[1]) {
- m.Add("append", "file", file)
- m.Add("append", "pos", fmt.Sprintf("%d%%", (begin+int64(len(text)+1))*100/s.Size()))
- m.Add("append", "line", offset)
- m.Add("append", "text", text)
- } else {
- i--
- }
- begin += int64(len(text)) + 1
- offset += 1
- }
-
- if !hold {
- value["offset"] = offset
- value["pos"] = begin
- }
- })
- m.Table()
- return
- }},
- "trash": &ctx.Command{Name: "trash file", Help: "查找文件路径", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if len(arg) == 0 {
- m.Cmdy("nfs.dir", m.Conf("dir", "trash"))
- return
- }
- m.Assert(os.Mkdir(m.Conf("dir", "trash"), 0777))
- m.Assert(os.Rename(arg[0], path.Join(m.Conf("dir", "trash"), arg[0])))
- return
- }},
-
- "load": &ctx.Command{Name: "load file [buf_size [pos]]", Help: "加载文件, buf_size: 加载大小, pos: 加载位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if p, f, e := open(m, arg[0]); e == nil {
- defer f.Close()
-
- size := kit.Int(kit.Select(m.Conf("buf", "size"), arg, 1))
- if size == -1 {
- if s, e := f.Stat(); m.Assert(e) {
- size = int(s.Size())
- }
- }
- buf := make([]byte, size)
-
- pos := kit.Int(kit.Select("0", arg, 2))
- if l, e := f.ReadAt(buf, int64(pos)); e == io.EOF || m.Assert(e) {
- m.Log("info", "load %s %d %d", p, l, pos)
- m.Echo(string(buf[:l]))
- }
- }
- return
- }},
- "save": &ctx.Command{Name: "save file string...", Help: "保存文件, file: 保存的文件, string: 保存的内容", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if len(arg) == 1 && m.Has("data") {
- arg = append(arg, m.Option("data"))
- }
-
- if f, p, e := kit.Create(arg[0]); m.Assert(e) {
- defer f.Close()
-
- for _, v := range arg[1:] {
- if n, e := f.WriteString(v); m.Assert(e) {
- m.Log("info", "save %s %d", p, n)
- }
- }
- m.Echo(p)
- }
- return
- }},
- "import": &ctx.Command{Name: "import filename [index]", Help: "导入数据", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- p, f, e := open(m, arg[0])
- m.Assert(e)
- defer f.Close()
-
- s, e := f.Stat()
- m.Option("filepath", p)
- m.Option("filename", s.Name())
- m.Option("filesize", s.Size())
- m.Option("filetime", s.ModTime().Format(m.Conf("time", "format")))
-
- switch {
- case strings.HasSuffix(arg[0], ".json"):
- var data interface{}
- json.NewDecoder(f).Decode(&data)
- m.Put("option", "filedata", data).Cmdy("ctx.trans", "filedata", arg[1:]).CopyTo(m)
-
- case strings.HasSuffix(arg[0], ".csv"):
- r := csv.NewReader(f)
- if l, e := r.Read(); m.Assert(e) {
- m.Meta["append"] = l
-
- for l, e = r.Read(); e == nil; l, e = r.Read() {
- for i, v := range l {
- m.Add("append", m.Meta["append"][i], v)
- }
- }
- }
- m.Table()
-
- default:
- if b, e := ioutil.ReadAll(f); m.Assert(e) {
- m.Echo(string(b))
- }
- }
- return
- }},
- "export": &ctx.Command{Name: "export filename", Help: "导出数据", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- tp := false
- if len(arg) > 0 && arg[0] == "time" {
- tp, arg = true, arg[1:]
- }
-
- f, p, e := kit.Create(kit.Select(arg[0], m.Format(arg[0]), tp))
- m.Assert(e)
- defer f.Close()
-
- data := m.Optionv(kit.Select("data", arg, 1))
- if len(arg) > 0 && arg[0] == "all" {
- data, arg = m.Meta, arg[1:]
- }
-
- switch {
- case strings.HasSuffix(arg[0], ".json"):
- if data == nil && len(m.Meta["append"]) > 0 {
- lines := []interface{}{}
- nrow := len(m.Meta[m.Meta["append"][0]])
- for i := 0; i < nrow; i++ {
- line := map[string]interface{}{}
- for _, k := range m.Meta["append"] {
- line[k] = m.Meta[k][i]
- }
-
- lines = append(lines, line)
- data = lines
- }
- }
-
- en := json.NewEncoder(f)
- en.SetIndent("", " ")
- en.Encode(data)
-
- case strings.HasSuffix(arg[0], ".csv"):
- fields := m.Meta["append"]
- if m.Options("fields") {
- fields = m.Meta["fields"]
- }
-
- if data == nil && len(m.Meta["append"]) > 0 {
- lines := []interface{}{}
- nrow := len(m.Meta[m.Meta["append"][0]])
- for i := 0; i < nrow; i++ {
- line := []string{}
- for _, k := range fields {
- line = append(line, m.Meta[k][i])
- }
- lines = append(lines, line)
- data = lines
- }
- }
-
- if data, ok := data.([]interface{}); ok {
- w := csv.NewWriter(f)
- w.Write(fields)
- for _, v := range data {
- w.Write(kit.Trans(v))
- }
- w.Flush()
- }
-
- default:
- f.WriteString(kit.Format(m.Meta["result"]))
- }
-
- m.Set("append").Add("append", "directory", p)
- m.Set("result").Echo(p)
- return
- }},
- "json": &ctx.Command{Name: "json str", Help: "导入数据", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- var data interface{}
- m.Assert(json.Unmarshal([]byte(kit.Select("{}", arg, 0)), &data))
- if b, e := json.MarshalIndent(data, "", " "); m.Assert(e) {
- m.Echo(string(b))
- }
- return
- }},
-
- "open": &ctx.Command{Name: "open file", Help: "打开文件, file: 文件名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if m.Has("io") {
- } else if p, f, e := open(m, arg[0], os.O_RDWR|os.O_CREATE|os.O_TRUNC); e == nil {
- m.Put("option", "in", f).Put("option", "out", f)
- arg[0] = p
- } else {
- return nil
- }
-
- m.Start(fmt.Sprintf("file%d", m.Capi("nfile", 1)), fmt.Sprintf("file %s", arg[0]), "open", arg[0])
- m.Append("bio.ctx1", m.Cap("module"))
- m.Echo(m.Cap("module"))
- return
- }},
- "read": &ctx.Command{Name: "read [buf_size [pos]]", Help: "读取文件, buf_size: 读取大小, pos: 读取位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && nfs.in != nil {
- if len(arg) > 1 {
- m.Cap("pos", arg[1])
- }
-
- buf := make([]byte, kit.Int(kit.Select(m.Conf("buf", "size"), arg, 0)))
- if n, e := nfs.in.ReadAt(buf, int64(m.Capi("pos"))); e == io.EOF || m.Assert(e) {
- m.Capi("nread", n)
- if m.Capi("pos", n); n == 0 {
- m.Cap("pos", "0")
- }
- }
- m.Echo(string(buf))
- }
- return
- }},
- "write": &ctx.Command{Name: "write string [pos]", Help: "写入文件, string: 写入内容, pos: 写入位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && nfs.out != nil {
- if len(arg[0]) == 0 {
- m.Assert(nfs.out.Truncate(int64(m.Capi("pos"))))
- m.Cap("size", m.Cap("pos"))
- m.Cap("pos", "0")
- } else {
- for _, v := range arg {
- n, e := nfs.out.WriteAt([]byte(v), int64(m.Capi("pos")))
- if m.Capi("nwrite", n); m.Assert(e) && m.Capi("pos", n) > m.Capi("size") {
- m.Cap("size", m.Cap("pos"))
- }
- }
- nfs.out.Sync()
- }
-
- m.Echo(m.Cap("pos"))
- }
- return
- }},
-
- "source": &ctx.Command{Name: "source [script|stdio|snippet]", Help: "解析脚本, script: 脚本文件, stdio: 命令终端, snippet: 代码片段", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if len(arg) == 0 {
- m.Cmdy("dir", "src", "time", "line", "path", "dir_deep", "dir_reg", ".*\\.(sh|shy|py)$")
- return
- }
-
- m.Optionv("bio.args", arg)
- if help := fmt.Sprintf("scan %s", arg[0]); arg[0] == "stdio" {
- m.Put("option", "bio.in", os.Stdin).Put("option", "bio.out", os.Stdout)
- m.Start(arg[0], help, "scan", arg[0])
- m.Wait()
-
- } else if p, f, e := open(m, arg[0]); e == nil {
- m.Put("option", "bio.in", f).Start(fmt.Sprintf("file%d", m.Capi("nfile", 1)), help, "scan", p)
- m.Wait()
-
- } else {
- m.Cmdy("yac.parse", strings.Join(arg, " ")+"\n")
- }
- return
- }},
- "prompt": &ctx.Command{Name: "prompt arg", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) {
- nfs.prompt(strings.Join(arg, ""))
- }
- return
- }},
- "printf": &ctx.Command{Name: "printf arg", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) {
- nfs.print(arg...)
- }
- return
- }},
- "action": &ctx.Command{Name: "action cmd", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) {
- msg := m.Cmd("nfs.source", arg)
- nfs.print(msg.Meta["result"]...)
- }
- return
- }},
- "term": &ctx.Command{Name: "term action args...", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) {
- nfs.Term(m, arg[0], arg[1:])
- }
- return
- }},
-
- "socket": &ctx.Command{Name: "remote listen|dial args...", Help: "启动文件服务, args: 参考tcp模块, listen命令的参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if _, ok := m.Target().Server.(*NFS); m.Assert(ok) {
- m.Sess("tcp").Call(func(msg *ctx.Message) *ctx.Message {
- if msg.Has("node.port") {
- return msg
- }
- msg.Sess("ms_source", msg)
- msg.Sess("ms_target", m.Source())
- msg.Start(fmt.Sprintf("file%d", m.Capi("nfile", 1)), "远程文件")
- return msg
- }, arg)
- }
- return
- }},
- "send": &ctx.Command{Name: "send [file] args...", Help: "连接文件服务, args: 参考tcp模块, dial命令的参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && nfs.io != nil {
- nfs.send <- m.Set("detail", arg)
- }
- return
- }},
- },
-}
-
-func init() {
- ctx.Index.Register(Index, &NFS{Context: Index})
-}
diff --git a/usr/local/honor/src/contexts/nfs/term.go b/usr/local/honor/src/contexts/nfs/term.go
deleted file mode 100644
index 7632bcef..00000000
--- a/usr/local/honor/src/contexts/nfs/term.go
+++ /dev/null
@@ -1,647 +0,0 @@
-package nfs
-
-import (
- "github.com/nsf/termbox-go"
-
- "contexts/ctx"
- "toolkit"
-
- "fmt"
- "strings"
- "time"
-)
-
-func (nfs *NFS) Read(p []byte) (n int, err error) {
- m := nfs.Context.Message()
- if !m.Caps("termbox") {
- return nfs.in.Read(p)
- }
-
- m.TryCatch(m, true, func(m *ctx.Message) {
- scroll_count := 0
- scroll_lines := m.Confi("term", "scroll_lines")
- which := m.Capi("ninput")
- what := make([]rune, 0, 1024)
- rest := make([]rune, 0, 1024)
- back := make([]rune, 0, 1024)
-
- m.Option("bio.cmd", "")
- m.Options("bio.shadow", m.Confs("show_shadow"))
-
- defer func() { m.Option("bio.cmd", "") }()
-
- frame, table, index, pick := map[string]interface{}{}, []map[string]string{}, 0, 0
- if change, f, t, i := nfs.Auto(what, ":", 0); change {
- frame, table, index, pick = f, t, i, 0
- }
-
- for {
- switch ev := termbox.PollEvent(); ev.Type {
- case termbox.EventInterrupt:
- case termbox.EventResize:
- nfs.Term(m, "resize")
- case termbox.EventMouse:
- switch ev.Key {
- case termbox.MouseLeft:
- if m.Confs("term", "mouse.resize") {
- nfs.Term(m, "window", ev.MouseX, ev.MouseY)
- nfs.prompt(what).shadow(rest)
- }
-
- case termbox.MouseMiddle:
- case termbox.MouseRight:
- if m.Confs("term", "mouse.resize") {
- nfs.Term(m, "resize", ev.MouseX, ev.MouseY)
- }
- case termbox.MouseRelease:
- case termbox.MouseWheelUp:
- if scroll_count++; scroll_count > m.Confi("term", "scroll_count") {
- nfs.Term(m, "scroll", -1).Term(m, "flush")
- scroll_count = 0
- }
- case termbox.MouseWheelDown:
- if scroll_count++; scroll_count > m.Confi("term", "scroll_count") {
- nfs.Term(m, "scroll", 1).Term(m, "flush")
- scroll_count = 0
- }
- }
- case termbox.EventError:
- case termbox.EventNone:
- case termbox.EventRaw:
- case termbox.EventKey:
-
- switch ev.Key {
- case termbox.KeyCtrlP:
- if which--; which < 0 {
- which = m.Capi("ninput") - 1
- }
- if v := m.Conf("input", []interface{}{which, "line"}); v != "" {
- what, rest = append(what[:0], []rune(v)...), rest[:0]
- nfs.prompt(what).shadow(rest)
- }
- case termbox.KeyCtrlN:
- if which++; which >= m.Capi("ninput") {
- which = 0
- }
- if v := m.Conf("input", []interface{}{which, "line"}); v != "" {
- what, rest = append(what[:0], []rune(v)...), rest[:0]
- nfs.prompt(what).shadow(rest)
- }
-
- case termbox.KeyCtrlA:
- if len(what) > 0 {
- what, rest = append(what, rest...), rest[:0]
- rest, what = append(rest, what...), what[:0]
- nfs.prompt(what).shadow(rest)
- }
- case termbox.KeyCtrlF:
- if len(rest) > 0 {
- pos := len(what) + 1
- what, rest = append(what, rest...), rest[:0]
- rest, what = append(rest, what[pos:]...), what[:pos]
- nfs.prompt(what).shadow(rest)
- }
- case termbox.KeyCtrlB:
- if len(what) > 0 {
- pos := len(what) - 1
- what, rest = append(what, rest...), rest[:0]
- rest, what = append(rest, what[pos:]...), what[:pos]
- nfs.prompt(what).shadow(rest)
- }
- case termbox.KeyCtrlE:
- if len(rest) > 0 {
- what, rest = append(what, rest...), rest[:0]
- nfs.prompt(what).shadow(rest)
- }
-
- case termbox.KeyCtrlU:
- back = back[:0]
- back, what = append(back, what...), what[:0]
- nfs.prompt(what).shadow(rest)
- case termbox.KeyCtrlD: // termbox.KeyBackspace
- if len(rest) > 0 {
- pos := len(what)
- what, rest = append(what, rest[1:]...), rest[:0]
- rest, what = append(rest, what[pos:]...), what[:pos]
- nfs.prompt(what).shadow(rest)
- }
- case termbox.KeyCtrlH: // termbox.KeyBackspace
- if len(what) > 0 {
- what = what[:len(what)-1]
- nfs.prompt(what).shadow(rest)
- }
- case termbox.KeyCtrlK:
- back = back[:0]
- back, rest = append(back, rest...), rest[:0]
- nfs.prompt(what).shadow(rest)
-
- case termbox.KeyCtrlW:
- if len(what) > 0 {
- pos := len(what) - 1
- for space := what[pos] == ' '; pos >= 0; pos-- {
- if (space && what[pos] != ' ') || (!space && what[pos] == ' ') {
- break
- }
- }
- back = back[:0]
- back, what = append(back, what[pos+1:]...), what[:pos+1]
- nfs.prompt(what).shadow(rest)
- }
- case termbox.KeyCtrlY:
- what = append(what, back...)
- nfs.prompt(what).shadow(rest)
-
- case termbox.KeyCtrlR:
- nfs.Term(m, "refresh").Term(m, "flush")
- nfs.prompt(what).shadow(rest)
- case termbox.KeyCtrlL:
- m.Confi("term", "begin_row", m.Capi("noutput"))
- m.Confi("term", "begin_col", 0)
- nfs.Term(m, "clear", "all").Term(m, "flush")
- nfs.prompt(what).shadow(rest)
-
- case termbox.KeyCtrlT:
- m.Option("scroll", true)
- nfs.Term(m, "scroll", scroll_lines).Term(m, "flush")
- m.Option("scroll", false)
- case termbox.KeyCtrlO:
- m.Option("scroll", true)
- nfs.Term(m, "scroll", -scroll_lines).Term(m, "flush")
- m.Option("scroll", false)
-
- case termbox.KeyCtrlJ, termbox.KeyEnter:
- what = append(what, '\n')
- n = copy(p, []byte(string(what)))
- return
- case termbox.KeyCtrlQ, termbox.KeyCtrlC:
- nfs.Term(m, "exit")
- n = copy(p, []byte("return\n"))
- return
-
- case termbox.KeyCtrlV:
-
- for i := -1; i < 8; i++ {
- nfs.Term(m, "color", i, m.Confi("term", "rest_fg"), fmt.Sprintf("\nhello bg %d", i))
- }
-
- for i := -1; i < 8; i++ {
- nfs.Term(m, "color", m.Confi("term", "rest_bg"), i, fmt.Sprintf("\nhello fg %d", i))
- }
- nfs.Term(m, "flush")
-
- case termbox.KeyCtrlG:
- case termbox.KeyCtrlX:
- m.Options("bio.shadow", !m.Options("bio.shadow"))
- case termbox.KeyCtrlS:
-
- case termbox.KeyCtrlZ:
-
- case termbox.KeyTab:
- m.Options("bio.shadow", true)
- // if index > len(what) {
- // nfs.shadow("", table, frame)
- // } else {
- // if lines := kit.Int(frame["lines"]); lines > 0 {
- // pick = (pick + 1) % lines
- // }
- // nfs.shadow(what[index:], table, frame, pick)
- // rest = append(rest[:0], []rune(kit.Format(frame["pick"]))[len(what)-index:]...)
- // nfs.prompt(what).shadow(rest)
- // nfs.shadow(what[index:], table, frame, pick)
- // }
- //
- case termbox.KeySpace:
- what = append(what, ' ')
- nfs.prompt(what).shadow(rest)
- if !m.Options("bio.shadow") {
- break
- }
-
- if index > len(what) {
- nfs.shadow("", table, frame)
- } else {
- m.Option("auto_key", strings.TrimSpace(string(what[index:])))
- if change, f, t, i := nfs.Auto(what, " ", len(what)); change {
- frame, table, index, pick = f, t, i, 0
- }
-
- if nfs.shadow(what[index:], table, frame); len(table) > 0 {
- rest = append(rest[:0], []rune(table[0][kit.Format(frame["field"])])...)
- nfs.prompt(what).shadow(rest)
- nfs.shadow(what[index:], table, frame)
- }
- }
-
- default:
- what = append(what, ev.Ch)
- nfs.prompt(what).shadow(rest)
- if !m.Options("bio.shadow") {
- break
- }
-
- if change, f, t, i := nfs.Auto(what, kit.Format(ev.Ch), len(what)); change {
- frame, table, index, pick = f, t, i, 0
- }
-
- if index > len(what) {
- nfs.shadow("", table, frame)
- } else {
- nfs.shadow(what[index:], table, frame, pick)
- if pos, word := len(what)-index, kit.Format(frame["pick"]); len(table) > 0 && pos < len(word) {
- rest = append(rest[:0], []rune(word)[pos:]...)
- } else {
- }
- nfs.prompt(what).shadow(rest)
- nfs.shadow(what[index:], table, frame, pick)
- }
- }
- }
- }
- })
- return
-}
-func (nfs *NFS) Auto(what []rune, trigger string, index int) (change bool, frame map[string]interface{}, table []map[string]string, nindex int) {
- return
- m := nfs.Context.Message()
-
- auto_target := m.Optionv("bio.ctx").(*ctx.Context)
- auto_cmd := ""
- auto_arg := []string{}
-
- switch trigger {
- case " ":
- switch m.Conf("term", "help_state") {
- case "context":
- // auto_target = auto_target.Sub(m.Option("auto_key"))
- m.Optionv("bio.ctx", auto_target)
- trigger = ":"
- case "command":
- m.Option("arg_index", index)
- auto_cmd = m.Option("bio.cmd", m.Option("auto_key"))
- trigger = "="
- case "argument":
- auto_cmd = m.Option("bio.cmd")
- auto_arg = strings.Split(strings.TrimSpace(string(what[m.Optioni("arg_index"):])), " ")
- trigger = "="
- }
- }
-
- auto := m.Confm("auto", trigger)
- if auto == nil {
- return false, nil, nil, 0
- }
-
- cmd := []interface{}{kit.Select(kit.Format(auto["cmd"]), auto_cmd)}
- if len(auto_arg) == 0 {
- auto_arg = kit.Trans(auto["arg"])
- }
- for _, v := range auto_arg {
- cmd = append(cmd, m.Parse(v))
- }
-
- table = []map[string]string{}
- m.Spawn(auto_target).Cmd(cmd...).Table(func(line int, maps map[string]string) {
- fields := []interface{}{}
- for _, v := range auto["fields"].([]interface{}) {
- fields = append(fields, maps[kit.Format(v)])
- }
- maps["format"] = fmt.Sprintf(kit.Format(auto["format"]), fields...)
- table = append(table, maps)
- })
- m.Conf("term", []interface{}{"help_table", auto["table"]}, table)
-
- frame = map[string]interface{}{
- "color": auto["color"],
- "table": auto["table"],
- "field": auto["field"],
- }
-
- if m.Conf("term", []interface{}{"help_index"}, index); index == 0 {
- m.Conf("term", "help_stack", []interface{}{frame})
- } else {
- m.Conf("term", []interface{}{"help_stack", -2}, frame)
- }
-
- m.Conf("term", "help_next_auto", auto["next_auto"])
- m.Conf("term", "help_state", auto["state"])
- return true, frame, table, index
-}
-func (nfs *NFS) Term(msg *ctx.Message, action string, args ...interface{}) *NFS {
- m := nfs.Context.Message()
- // m.Log("debug", "%s %v", action, args)
-
- switch action {
- case "exit":
- if m.Caps("termbox") {
- termbox.Close()
- }
- m.Caps("termbox", false)
- return nfs
-
- case "init":
- defer func() {
- if e := recover(); e != nil {
- m.Log("warn", "term init %s", e)
- }
- }()
- termbox.Init()
- termbox.SetInputMode(termbox.InputEsc)
- termbox.SetInputMode(termbox.InputMouse)
- m.Cap("termbox", "true")
- }
-
- width, height := termbox.Size()
- msg.Conf("term", "width", width)
- msg.Conf("term", "height", height)
-
- left := msg.Confi("term", "left")
- top := msg.Confi("term", "top")
- right := msg.Confi("term", "right")
- bottom := msg.Confi("term", "bottom")
-
- x := m.Confi("term", "cursor_x")
- y := m.Confi("term", "cursor_y")
- bg := termbox.Attribute(msg.Confi("term", "bgcolor"))
- fg := termbox.Attribute(msg.Confi("term", "fgcolor"))
-
- begin_row := m.Confi("term", "begin_row")
- begin_col := m.Confi("term", "begin_col")
-
- switch action {
- case "init":
- m.Conf("term", "left", 0)
- m.Conf("term", "top", 0)
- m.Conf("term", "right", width)
- m.Conf("term", "bottom", height)
-
- case "exit":
- m.Cap("termbox", "false")
- termbox.Close()
-
- case "window":
- if len(args) > 1 {
- msg.Conf("term", "left", args[0])
- msg.Conf("term", "top", args[1])
- }
- if len(args) > 3 {
- msg.Conf("term", "right", args[2])
- msg.Conf("term", "bottom", args[3])
- } else {
- msg.Conf("term", "right", width)
- msg.Conf("term", "bottom", height)
- }
-
- case "resize":
- if len(args) > 1 {
- msg.Conf("term", "right", args[0])
- msg.Conf("term", "bottom", args[1])
- right = msg.Confi("term", "right")
- bottom = msg.Confi("term", "bottom")
- } else {
- msg.Conf("term", "right", right)
- msg.Conf("term", "bottom", bottom)
- }
-
- fallthrough
- case "clear":
- if len(args) == 0 {
- top = m.Confi("term", "prompt_y")
- } else if kit.Format(args[0]) == "all" {
- // nothing
- }
-
- for x := left; x < right; x++ {
- for y := top; y < bottom; y++ {
- termbox.SetCell(x, y, ' ', fg, bg)
- }
- }
- m.Conf("term", "cursor_x", left)
- m.Conf("term", "cursor_y", top)
- termbox.SetCursor(left, top)
-
- case "cursor":
- m.Conf("term", "cursor_x", kit.Format(args[0]))
- m.Conf("term", "cursor_y", kit.Format(args[1]))
- termbox.SetCursor(m.Confi("term", "cursor_x"), m.Confi("term", "cursor_y"))
-
- case "flush":
- termbox.Flush()
-
- case "scroll":
- n := 1
- if len(args) > 0 {
- n = kit.Int(args[0])
- }
- m.Options("on_scroll", true)
-
- // 向下滚动
- for i := begin_row; n > 0 && i < m.Capi("noutput"); i++ {
- line := []rune(m.Conf("output", []interface{}{i, "line"}))
-
- for j, l := begin_col, left; n > 0; j, l = j+1, l+1 {
- if j >= len(line)-1 {
- begin_row, begin_col = i+1, 0
- n--
- break
- } else if line[j] == '\n' {
- begin_row, begin_col = i, j+1
- n--
- } else if l >= right-1 && m.Confs("term", "wrap") {
- begin_row, begin_col = i, j
- n--
- }
- }
- }
-
- // 向上滚动
- for i := begin_row; n < 0 && i >= 0; i-- {
- line := []rune(m.Conf("output", []interface{}{i, "line"}))
- if begin_col == 0 {
- i--
- line = []rune(m.Conf("output", []interface{}{i, "line"}))
- begin_col = len(line)
- }
-
- for j, l := begin_col-1, right-1; n < 0; j, l = j-1, l-1 {
- if j <= 0 {
- begin_row, begin_col = i, 0
- n++
- break
- } else if line[j-1] == '\n' {
- begin_row, begin_col = i, j
- n++
- } else if l < left && m.Confs("term", "wrap") {
- begin_row, begin_col = i, j
- n++
- }
- }
- }
-
- m.Conf("term", "begin_row", begin_row)
- m.Conf("term", "begin_col", begin_col)
-
- fallthrough
- case "refresh":
-
- nfs.Term(m, "clear", "all")
- for i := begin_row; i < m.Capi("noutput"); i++ {
- if line := m.Conf("output", []interface{}{i, "line"}); begin_col < len(line) {
- nfs.Term(m, "print", line[begin_col:])
- }
- begin_col = 0
- }
- // nfs.Term(m, "print", "\n")
- // nfs.Term(m, "print", m.Conf("prompt"))
- m.Options("on_scroll", false)
-
- case "print":
- list := kit.Format(args...)
- n := strings.Count(list, "\n") + y - bottom
-
- for _, v := range list {
- if x < right {
- if termbox.SetCell(x, y, v, fg, bg); v > 255 {
- x++
- }
- }
-
- if x++; v == '\n' || (x >= right && m.Confs("term", "wrap")) {
- x, y = left, y+1
- if y >= bottom {
- if m.Options("on_scroll") {
- break
- }
- if n%bottom > 0 {
-
- nfs.Term(m, "scroll", n%bottom+1)
- n -= n % bottom
- x = m.Confi("term", "cursor_x")
- y = m.Confi("term", "cursor_y")
-
- } else if n > 0 {
-
- nfs.Term(m, "scroll", bottom)
- n -= bottom
- x = m.Confi("term", "cursor_x")
- y = m.Confi("term", "cursor_y")
-
- }
- }
- }
-
- if x < right {
- m.Conf("term", "cursor_x", x)
- m.Conf("term", "cursor_y", y)
- termbox.SetCursor(x, y)
- }
- }
-
- if m.Options("on_scroll") {
- x = 0
- y = y + 1
- m.Conf("term", "cursor_x", x)
- m.Conf("term", "cursor_y", y)
- termbox.SetCursor(x, y)
- }
-
- case "color":
- msg.Conf("term", "bgcolor", kit.Int(args[0])+1)
- msg.Conf("term", "fgcolor", kit.Int(args[1])+1)
- nfs.Term(m, "print", args[2:]...)
- msg.Conf("term", "fgcolor", fg)
- msg.Conf("term", "bgcolor", bg)
-
- case "shadow":
- x := m.Confi("term", "cursor_x")
- y := m.Confi("term", "cursor_y")
- nfs.Term(m, "color", args...)
- nfs.Term(m, "cursor", x, y).Term(m, "flush")
- }
- return nfs
-}
-func (nfs *NFS) prompt(arg ...interface{}) *NFS {
- m := nfs.Context.Message()
- target, _ := m.Optionv("bio.ctx").(*ctx.Context)
- if target == nil {
- target = nfs.Context
- }
-
- line := fmt.Sprintf("%d[%s]%s> ", m.Capi("ninput"), time.Now().Format("15:04:05"), target.Name)
- m.Conf("prompt", line)
-
- line += kit.Format(arg...)
- if m.Caps("termbox") {
- m.Conf("term", "prompt_y", m.Conf("term", "cursor_y"))
- nfs.Term(m, "clear").Term(m, "print", line).Term(m, "flush")
- } else if nfs.out != nil {
- nfs.out.WriteString(line)
- }
- return nfs
-}
-func (nfs *NFS) shadow(args ...interface{}) *NFS {
- if len(args) == 0 {
- return nfs
- }
-
- m := nfs.Context.Message()
- x := m.Confi("term", "cursor_x")
- y := m.Confi("term", "cursor_y")
- defer func() { nfs.Term(m, "cursor", x, y).Term(m, "flush") }()
-
- switch arg := args[0].(type) {
- case []rune:
- if len(args) == 1 {
- nfs.Term(m, "color", m.Confi("term", "rest_bg"), m.Confi("term", "rest_fg"), string(arg))
- } else {
- cmd := strings.Split(string(arg), " ")
- switch table := args[1].(type) {
- case []map[string]string:
- frame := args[2].(map[string]interface{})
- field := kit.Format(frame["field"])
- fg := kit.Int(frame["color"])
- pick := kit.Int(kit.Select("0", args, 3))
-
- i := 0
- for _, line := range table {
- if strings.Contains(kit.Format(line[field]), cmd[0]) {
- if i == pick {
- frame["pick"] = line[field]
- nfs.Term(m, "color", m.Confi("term", "pick_bg"), m.Confi("term", "pick_fg"), "\n", kit.Format(line["format"]))
- } else {
- nfs.Term(m, "color", 0, fg, "\n", kit.Format(line["format"]))
- }
- i++
- if i > 10 {
- break
- }
- }
- }
- frame["lines"] = i
- }
- }
-
- }
-
- return nfs
-}
-func (nfs *NFS) print(arg ...string) *NFS {
- m := nfs.Context.Message()
-
- line := strings.TrimRight(strings.Join(arg, ""), "\n")
- m.Log("debug", "noutput %s", m.Cap("noutput", m.Capi("noutput")+1))
- m.Confv("output", -2, map[string]interface{}{"time": time.Now().Unix(), "line": line})
-
- if m.Caps("termbox") {
- nfs.Term(m, "clear").Term(m, "print", line).Term(m, "flush")
- m.Conf("term", "prompt_y", m.Confi("term", "cursor_y")+1)
- m.Conf("term", "cursor_y", m.Confi("term", "cursor_y")+1)
- } else {
- nfs.out.WriteString(line)
- nfs.out.WriteString("\n")
- }
- return nfs
-}
-func (nfs *NFS) Show(arg ...interface{}) bool {
- nfs.prompt(arg...)
- return true
-}
diff --git a/usr/local/honor/src/contexts/ssh/ssh.go b/usr/local/honor/src/contexts/ssh/ssh.go
deleted file mode 100644
index 2838ab02..00000000
--- a/usr/local/honor/src/contexts/ssh/ssh.go
+++ /dev/null
@@ -1,1300 +0,0 @@
-package ssh
-
-import (
- "bufio"
- "contexts/ctx"
- "fmt"
- "os/exec"
- "sort"
- "time"
- "toolkit"
-
- "encoding/hex"
- "io"
- "os"
- "path"
- "strings"
-)
-
-type SSH struct {
- relay chan *ctx.Message
- *ctx.Context
-}
-
-func (ssh *SSH) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server {
- return &SSH{Context: c}
-}
-func (ssh *SSH) Begin(m *ctx.Message, arg ...string) ctx.Server {
- return ssh
-}
-func (ssh *SSH) Start(m *ctx.Message, arg ...string) bool {
- ir, iw := io.Pipe()
- or, ow := io.Pipe()
- er, ew := io.Pipe()
- cmd := exec.Command("ssh", arg[0])
- cmd.Stdin, cmd.Stdout, cmd.Stderr = ir, ow, ew
- cmd.Start()
-
- relay := m
- done := false
- ssh.relay = make(chan *ctx.Message, 10)
- m.Gos(m.Spawn(), func(msg *ctx.Message) {
- for relay = range ssh.relay {
- done = false
- for _, v := range relay.Meta["detail"][1:] {
- msg.Log("info", "%v", v)
- fmt.Fprint(iw, v, " ")
- }
- fmt.Fprintln(iw)
-
- ticker, delay := kit.Duration(msg.Conf("ssh.login", "ticker")), kit.Duration(msg.Conf("ssh.login", "ticker"))
- for i := 0; i < msg.Confi("ssh.login", "count"); i++ {
- msg.Log("done", "%d %v", i, done)
- if time.Sleep(ticker); done {
- time.Sleep(delay)
- relay.Back(relay)
- break
- }
- }
- }
- })
- m.Gos(m.Spawn(), func(msg *ctx.Message) {
- for bio := bufio.NewScanner(er); bio.Scan(); {
- msg.Log("warn", "what %v", bio.Text())
- relay.Echo(bio.Text()).Echo("\n")
- done = true
- }
- })
- for bio := bufio.NewScanner(or); bio.Scan(); {
- m.Log("info", "what %v", bio.Text())
- relay.Echo(bio.Text()).Echo("\n")
- done = true
- }
- return false
-}
-func (ssh *SSH) Close(m *ctx.Message, arg ...string) bool {
- return false
-}
-
-var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
- Caches: map[string]*ctx.Cache{
- "nnode": {Name: "nnode", Value: "0", Help: "节点数量"},
- },
- Configs: map[string]*ctx.Config{
- "componet": {Name: "componet", Value: map[string]interface{}{
- "index": []interface{}{
- map[string]interface{}{"name": "ifconfig", "help": "网卡",
- "tmpl": "componet", "view": "", "init": "",
- "type": "protected", "ctx": "ssh", "cmd": "_route",
- "args": []interface{}{"_", "tcp.ifconfig"}, "inputs": []interface{}{
- map[string]interface{}{"type": "text", "name": "pod", "value": "", "imports": "plugin_pod"},
- map[string]interface{}{"type": "button", "value": "查看", "action": "auto"},
- },
- },
- map[string]interface{}{"name": "proc", "help": "进程",
- "tmpl": "componet", "view": "", "init": "",
- "type": "protected", "ctx": "ssh", "cmd": "_route",
- "args": []interface{}{"_", "cli.proc"}, "inputs": []interface{}{
- map[string]interface{}{"type": "text", "name": "pod", "value": "", "imports": "plugin_pod"},
- map[string]interface{}{"type": "text", "name": "arg", "value": ""},
- map[string]interface{}{"type": "text", "name": "filter", "view": "long"},
- map[string]interface{}{"type": "button", "value": "执行"},
- },
- },
- map[string]interface{}{"name": "spide", "help": "爬虫",
- "tmpl": "componet", "view": "Context", "init": "",
- "type": "protected", "ctx": "ssh", "cmd": "_route",
- "args": []interface{}{"_", "context", "web", "spide"}, "inputs": []interface{}{
- map[string]interface{}{"type": "text", "name": "pod", "imports": "plugin_pod"},
- map[string]interface{}{"type": "button", "value": "执行"},
- },
- "exports": []interface{}{"site", "key"},
- },
- map[string]interface{}{"name": "post", "help": "请求",
- "tmpl": "componet", "view": "Context", "init": "",
- "type": "protected", "ctx": "ssh", "cmd": "_route",
- "args": []interface{}{"_", "web.post", "__", "content_type", "application/json", "parse", "json"}, "inputs": []interface{}{
- map[string]interface{}{"type": "text", "name": "pod", "imports": "plugin_pod"},
- map[string]interface{}{"type": "text", "name": "spide", "value": "dev", "imports": "plugin_site"},
- map[string]interface{}{"type": "text", "name": "url", "value": "/", "view": "long"},
- map[string]interface{}{"type": "button", "value": "执行"},
- },
- },
- map[string]interface{}{"name": "get", "help": "请求",
- "tmpl": "componet", "view": "Context", "init": "",
- "type": "protected", "ctx": "ssh", "cmd": "_route",
- "args": []interface{}{"_", "web.get", "__", "method", "GET", "parse", "json"}, "inputs": []interface{}{
- map[string]interface{}{"type": "text", "name": "pod", "imports": "plugin_pod"},
- map[string]interface{}{"type": "text", "name": "spide", "value": "dev", "imports": "plugin_site"},
- map[string]interface{}{"type": "text", "name": "url", "value": "/", "view": "long"},
- map[string]interface{}{"type": "button", "value": "执行"},
- },
- },
- },
- }, Help: "组件列表"},
-
- "data": {Name: "data", Value: map[string]interface{}{"path": "var/data"}, Help: "聊天数据"},
- "flow": {Name: "flow", Value: map[string]interface{}{}, Help: "聊天群组"},
- "work": {Name: "work", Value: map[string]interface{}{}, Help: "工作信息"},
- "node": {Name: "node", Value: map[string]interface{}{}, Help: "节点信息"},
- "timer": {Name: "timer", Value: map[string]interface{}{"interval": "10s", "timer": ""}, Help: "断线重连"},
- "trust": {Name: "trust", Value: map[string]interface{}{
- "renew": true, "fresh": false, "user": true, "up": true,
- }, Help: "可信节点"},
- "login": {Name: "login", Value: map[string]interface{}{
- "ticker": "10ms",
- "count": 100,
- "delay": "10ms",
- }, Help: "聊天群组"},
- },
- Commands: map[string]*ctx.Command{
- "_init": {Name: "_init", Help: "启动初始化", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if m.Confs("runtime", "boot.ctx_box") {
- m.Conf("runtime", "node.type", "worker")
- m.Conf("runtime", "node.name", m.Conf("runtime", "boot.pathname"))
- } else {
- m.Conf("runtime", "node.type", "server")
- m.Conf("runtime", "node.name", kit.Key(strings.TrimSuffix(m.Conf("runtime", "boot.hostname"), ".local")))
- }
- m.Conf("runtime", "node.route", m.Conf("runtime", "node.name"))
- m.Conf("runtime", "user.name", m.Conf("runtime", "boot.username"))
-
- m.Cmd("aaa.role", "tech", "componet", "remote", "command", "tool")
- m.Cmd("aaa.role", "tech", "componet", "source", "command", "tool")
- return
- }},
- "_node": {Name: "_node [init|create name type module|delete name]", Help: "节点", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if len(arg) == 0 {
- m.Confm("ssh.node", func(key string, value map[string]interface{}) {
- m.Push("create_time", value["create_time"])
- m.Push("node", key)
- m.Push("type", value["type"])
- })
- m.Sort("node").Table()
- return
- }
-
- switch arg[0] {
- // 节点证书
- case "init":
- if !m.Confs("runtime", "node.cert") || !m.Confs("runtime", "node.key") {
- msg := m.Cmd("aaa.rsa", "gen")
- m.Conf("runtime", "node.cert", msg.Append("certificate"))
- m.Conf("runtime", "node.key", msg.Append("private"))
- m.Echo(m.Conf("runtime", "node.cert"))
- }
-
- // 创建节点
- case "create":
- name := arg[1]
- if arg[2] != "master" {
- for node := m.Confm("node", name); node != nil; node = m.Confm("node", name) {
- name = kit.Format("%s_%s", arg[1], m.Capi("nnode", 1))
- }
- }
-
- m.Log("info", "create node %s %s", name, arg[2])
- m.Confv("node", name, map[string]interface{}{
- "create_time": m.Time(), "name": name, "type": arg[2], "module": arg[3],
- })
- m.Echo(name)
-
- // 删除节点
- case "delete":
- m.Log("info", "delete node %s %s", arg[1], kit.Formats(m.Conf("node", arg[1])))
- m.Cmd("aaa.auth", m.Cmdx("aaa.auth", "nodes", arg[1]), "delete", "node")
- delete(m.Confm("node"), arg[1])
- }
- return
- }},
- "user": {Name: "user [init|create|trust [node]]", Help: "用户管理, init: 用户节点, create: 用户创建, trust: 用户授权", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if len(arg) == 0 {
- m.Echo(m.Conf("runtime", "user.route"))
- return
- }
- switch arg[0] {
- // 用户证书
- case "init":
- if m.Confs("runtime", "user.cert") && m.Confs("runtime", "user.key") {
- break
- }
- fallthrough
- // 创建用户
- case "create":
- m.Cmd("aaa.auth", "username", m.Conf("runtime", "user.name"), "delete", "node")
-
- if len(arg) == 1 { // 本地用户
- msg := m.Cmd("aaa.rsa", "gen")
- m.Conf("runtime", "user.route", m.Conf("runtime", "node.route"))
- m.Conf("runtime", "user.name", m.Conf("runtime", "boot.username"))
- m.Conf("runtime", "user.cert", msg.Append("certificate"))
- m.Conf("runtime", "user.key", msg.Append("private"))
-
- } else { // 远程用户
- msg := m.Cmd("ssh._route", arg[1], "_check", "user")
- m.Conf("runtime", "user.route", msg.Append("user.route"))
- m.Conf("runtime", "user.name", msg.Append("user.name"))
- m.Conf("runtime", "user.cert", msg.Append("user.cert"))
- m.Conf("runtime", "user.key", "")
- }
- m.Cmd("aaa.user", "root", m.Conf("runtime", "user.name"))
- m.Echo(m.Conf("runtime", "user.cert"))
-
- case "trust":
- if len(arg) > 1 {
- m.Conf("trust", arg[1], kit.Right(kit.Select("true", arg, 2)))
- }
- if len(arg) > 1 {
- m.Cmdy("ctx.config", "trust", arg[1])
- } else {
- m.Cmdy("ctx.config", "trust")
- }
- }
- m.Append("user.route", m.Conf("runtime", "user.route"))
- return
- }},
- "work": {Name: "work [serve|create|search]", Help: "工作管理, serve: 创建组织, create: 创建员工, search: 搜索员工", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if len(arg) == 0 {
- m.Confm("work", func(key string, value map[string]interface{}) {
- m.Add("append", "key", key)
- m.Add("append", "user", value["user"])
- })
- m.Table()
- return
- }
-
- switch arg[0] {
- // 创建组织
- case "serve":
- m.Conf("runtime", "work.serve", true)
- m.Conf("runtime", "work.route", m.Conf("runtime", "node.route"))
- m.Conf("runtime", "work.name", m.Conf("runtime", "user.name"))
- m.Conf("work", m.Conf("runtime", "user.name"), map[string]interface{}{
- "create_time": m.Time(), "user": m.Cmd("ssh.user", "init").Append("user.route"),
- })
-
- // 创建员工
- case "create":
- m.Cmd("ssh.user", "init")
- name := kit.Select(m.Conf("runtime", "user.name"), arg, 1)
- work := kit.Select(m.Conf("runtime", "work.route"), arg, 2)
-
- if n := m.Cmdx("ssh._route", work, "_check", "work", "create", name, m.Conf("runtime", "user.route")); n != "" {
- m.Conf("runtime", "work.route", work)
- m.Conf("runtime", "work.name", n)
- m.Echo(n)
- } else {
- m.Err("%s from %s", name, work)
- }
-
- // 共享用户
- case "share":
- name := kit.Select(m.Conf("runtime", "user.name"), arg, 1)
- work := kit.Select(m.Conf("runtime", "work.route"), arg, 2)
-
- if n := m.Cmdx("ssh._route", work, "_check", "work", name, m.Conf("runtime", "node.route")); n != "" {
- m.Echo(n)
- }
-
- case "search":
- m.Cmdy("ssh._route", m.Conf("runtime", "work.route"), "_check", "work", "search", arg[1:])
- }
- return
- }},
- "tool": {Name: "tool [group index][run group index chatid arg...]", Help: "工具", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if len(arg) == 0 {
- m.Confm("componet", func(key string, index int, value map[string]interface{}) {
- if kit.Format(value["type"]) != "public" && m.Option("userrole") != "root" {
- return
- }
-
- m.Push("key", key)
- m.Push("index", index)
- m.Push("name", value["name"])
- m.Push("help", value["help"])
- })
- m.Table()
- return
- }
-
- switch arg[0] {
- case "run":
- m.Option("plugin", arg[1])
- tool := m.Confm("componet", []string{arg[1], arg[2]})
- if m.Option("userrole") != "root" {
- switch kit.Format(tool["type"]) {
- case "private":
- m.Echo("private componet of %s", m.Conf("runtime", "work.name"))
- return
- case "protected":
- if !m.Confs("flow", []string{arg[3], "user", m.Option("username")}) {
- m.Echo("protected componet of %s", m.Conf("runtime", "work.name"))
- return
- }
- }
- }
-
- prefix := []string{}
- msg := m.Find(kit.Format(tool["ctx"]))
- if strings.Contains(kit.Format(tool["ctx"]), ":") {
- ps := strings.Split(kit.Format(tool["ctx"]), ":")
- prefix = append(prefix, "_route", ps[0], "context", "find", ps[1])
- msg = m.Sess("ssh")
- }
-
- if option, ok := tool["options"].(map[string]interface{}); ok {
- for k, v := range option {
- msg.Option(k, v)
- }
- }
-
- msg.Option("river", arg[3])
- msg.Option("storm", arg[1])
- kit.Map(tool["inputs"], "", func(index int, value map[string]interface{}) {
- if name := kit.Format(value["name"]); name != "" && m.Option(name) != "" {
- m.Log("info", "%v: %v", name, m.Option(name))
- msg.Option(name, m.Option(name))
- }
- })
-
- arg = arg[4:]
- args := []string{}
- for _, v := range kit.Trans(tool["args"]) {
- if strings.HasPrefix(v, "__") {
- if len(arg) > 0 {
- args, arg = append(args, arg...), nil
- }
- } else if strings.HasPrefix(v, "_") {
- if len(arg) > 0 {
- args, arg = append(args, arg[0]), arg[1:]
- } else {
- args = append(args, "")
- }
- } else {
- args = append(args, msg.Parse(v))
- }
- }
-
- if len(prefix) > 0 && prefix[1] == "_" {
- if len(args) > 0 {
- prefix[1], args = args[0], args[1:]
- } else if len(arg) > 0 {
- prefix[1], arg = arg[0], arg[1:]
- } else {
- prefix[1] = ""
- }
- }
-
- msg.Cmd(prefix, tool["cmd"], args, arg)
- msg.CopyTo(m)
-
- default:
- m.Confm("componet", arg[0:], func(value map[string]interface{}) {
- if kit.Format(value["type"]) == "private" && m.Option("userrole") != "root" {
- m.Log("warn", "%v private", arg)
- return
- }
-
- m.Push("name", value["name"])
- m.Push("help", value["help"])
- m.Push("init", value["init"])
- m.Push("view", value["view"])
-
- // if kit.Right(value["init"]) {
- // script := m.Cmdx("nfs.load", path.Join(m.Conf("cli.project", "plugin.path"), arg[0], kit.Format(value["init"])), -1)
- // if script == "" {
- // script = m.Cmdx("nfs.load", path.Join("usr/librarys/plugin", kit.Format(value["init"])), -1)
- // }
- // m.Push("init", script)
- // } else {
- // m.Push("init", "")
- // }
- // if kit.Right(value["view"]) {
- // script := m.Cmdx("nfs.load", path.Join(m.Conf("cli.project", "plugin.path"), arg[0], kit.Format(value["view"])), -1)
- // if script == "" {
- // script = m.Cmdx("nfs.load", path.Join("usr/librarys/plugin", kit.Format(value["view"])), -1)
- // }
- // m.Push("view", script)
- // } else {
- // m.Push("view", "")
- // }
- m.Push("inputs", kit.Format(value["inputs"]))
- m.Push("feature", kit.Format(value["feature"]))
- m.Push("exports", kit.Format(value["exports"]))
- m.Push("display", kit.Format(value["display"]))
- })
- m.Table()
- }
- return
- }},
- "data": {Name: "data show|insert|update [table [index] [key value]...]", Help: "数据", Form: map[string]int{
- "format": 1, "fields": -1,
- }, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if len(arg) == 0 {
- arg = append(arg, "show")
- }
-
- if m.Conf("data", "local") == "single" {
- m.Confm("flow", func(key string, value map[string]interface{}) {
- m.Log("info", "river map %v->%v", m.Option("river"), key)
- m.Option("river", key)
- })
- }
-
- switch arg[0] {
- case "show":
- if len(arg) > 1 && arg[1] == "" {
- arg = arg[:1]
- }
- switch len(arg) {
- case 1: // 数据库
- m.Confm("flow", []string{m.Option("river"), "data"}, func(key string, value map[string]interface{}) {
- m.Push("create_time", kit.Chains(value, "meta.create_time"))
- m.Push("create_user", kit.Chains(value, "meta.create_user"))
- m.Push("table", key)
- m.Push("count", len(value["list"].([]interface{})))
- })
-
- case 3: // 记录行
- index := kit.Int(arg[2]) - 1 - m.Confi("flow", []string{m.Option("river"), "data", arg[1], "meta", "offset"})
- switch m.Option("format") {
- case "object":
- m.Confm("flow", []string{m.Option("river"), "data", arg[1], "list", kit.Format(index)}, func(key string, value string) {
- if key != "extra" {
- m.Push(key, value)
- }
- })
- m.Confm("flow", []string{m.Option("river"), "data", arg[1], "list", kit.Format(index), "extra"}, func(key string, value string) {
- m.Push("extra."+key, value)
- })
- default:
- m.Confm("flow", []string{m.Option("river"), "data", arg[1], "list", kit.Format(index)}, func(key string, value string) {
- if key != "extra" {
- m.Push("key", key)
- m.Push("value", value)
- }
- })
- m.Confm("flow", []string{m.Option("river"), "data", arg[1], "list", kit.Format(index), "extra"}, func(key string, value string) {
- m.Push("key", "extra."+key)
- m.Push("value", value)
- })
- m.Sort("key")
- }
- default: // 关系表
- m.Option("cache.limit", kit.Select("10", arg, 3))
- m.Option("cache.offend", kit.Select("0", arg, 4))
- m.Option("cache.match", kit.Select("", arg, 5))
- m.Option("cache.value", kit.Select("", arg, 6))
-
- keys := []string{}
- if m.Meta["append"] = []string{"id", "when"}; m.Has("fields") {
- keys = kit.Trans(m.Optionv("fields"))
- } else {
- // 字段查询
- hide := map[string]bool{"create_time": true, "update_time": true, "extra": true}
- m.Grows("flow", []string{m.Option("river"), "data", arg[1]}, func(meta map[string]interface{}, index int, value map[string]interface{}) {
- for k := range value {
- if !hide[k] {
- hide[k] = false
- }
- }
- })
- // 字段排序
- for k, hide := range hide {
- if !hide {
- keys = append(keys, k)
- }
- }
- sort.Strings(keys)
- }
-
- // 查询数据
- m.Grows("flow", []string{m.Option("river"), "data", arg[1]}, func(meta map[string]interface{}, index int, value map[string]interface{}) {
- for _, k := range keys {
- m.Push(k, kit.Format(value[k]))
- }
- })
- }
- m.Table()
-
- case "save":
- if len(arg) == 1 {
- m.Confm("flow", []string{m.Option("river"), "data"}, func(key string, value map[string]interface{}) {
- arg = append(arg, key)
- })
- }
-
- for _, v := range arg[1:] {
- data := m.Confm("flow", []string{m.Option("river"), "data", v})
- kit.Marshal(data["meta"], path.Join(m.Conf("ssh.data", "path"), m.Option("river"), v, "/meta.json"))
- kit.Marshal(data["list"], path.Join(m.Conf("ssh.data", "path"), m.Option("river"), v, "/list.csv"))
-
- l := len(data["list"].([]interface{}))
- m.Push("table", v).Push("count", l+kit.Int(kit.Chain(data["meta"], "offset")))
- m.Log("info", "save table %s:%s %d", m.Option("river"), v, l)
- }
- m.Table()
-
- case "create":
- if m.Confs("flow", []string{m.Option("river"), "data", arg[1]}) {
- break
- }
-
- tmpl := map[string]interface{}{"create_time": m.Time(), "update_time": m.Time(), "extra": "{}", "id": 0}
- for i := 2; i < len(arg)-1; i += 2 {
- tmpl[arg[i]] = arg[i+1]
- }
-
- m.Confv("flow", []string{m.Option("river"), "data", arg[1]}, map[string]interface{}{
- "meta": map[string]interface{}{
- "create_user": m.Option("username"),
- "create_time": m.Time(),
- "create_tmpl": tmpl,
- "store": path.Join(m.Conf("ssh.data", "path"), m.Option("river"), arg[1], "/auto.csv"),
- "limit": "30",
- "least": "10",
- },
- "list": []interface{}{},
- })
- m.Log("info", "create table %s:%s", m.Option("river"), arg[1])
-
- case "insert":
- if len(arg) == 2 {
- m.Cmd("ssh.data", "show", arg[1])
- break
- }
- if !m.Confs("flow", []string{m.Option("river"), "data", arg[1]}) {
- m.Cmd("ssh.data", "create", arg[1:])
- }
-
- id := m.Confi("flow", []string{m.Option("river"), "data", arg[1], "meta", "count"}) + 1
- m.Confi("flow", []string{m.Option("river"), "data", arg[1], "meta", "count"}, id)
-
- data := map[string]interface{}{}
- extra := map[string]interface{}{}
- tmpl := m.Confm("flow", []string{m.Option("river"), "data", arg[1], "meta", "create_tmpl"})
- for k, v := range tmpl {
- data[k] = v
- }
- for i := 2; i < len(arg)-1; i += 2 {
- if _, ok := tmpl[arg[i]]; ok {
- data[arg[i]] = arg[i+1]
- } else {
- extra[arg[i]] = arg[i+1]
- }
- }
- data["create_time"] = m.Time()
- data["update_time"] = m.Time()
- data["extra"] = extra
- data["id"] = id
-
- m.Log("info", "insert %s:%s %s", m.Option("river"), arg[1], kit.Format(data))
- m.Grow("flow", []string{m.Option("river"), "data", arg[1]}, data)
- m.Cmdy("ssh.data", "save", arg[1])
-
- case "update":
- if arg[2] == "" {
- break
- }
- offset := m.Confi("flow", []string{m.Option("river"), "data", arg[1], "meta", "offset"})
- index := kit.Int(arg[2]) - 1 - offset
- table, prefix, arg := arg[1], "", arg[3:]
- if index >= 0 {
- if arg[0] == "extra" {
- prefix, arg = "extra.", arg[1:]
- }
- for i := 0; i < len(arg)-1; i += 2 {
- m.Confv("flow", []string{m.Option("river"), "data", table, "list", kit.Format(index), prefix + arg[i]}, arg[i+1])
- }
- }
- m.Cmdy("ssh.data", "show", table, index+1+offset)
-
- case "import":
- if len(arg) < 3 {
- m.Cmdy("ssh.data", "show", arg)
- return
- }
-
- id := m.Confi("flow", []string{m.Option("river"), "data", arg[1], "meta", "count"})
- m.Cmd("nfs.import", arg[2:]).Table(func(maps map[string]string) {
- data := map[string]interface{}{}
- for k, v := range maps {
- m.Push(k, v)
- data[k] = v
- }
-
- if id++; id == 1 {
- m.Cmd("ssh.data", "create", arg[1], data)
- }
-
- data["id"] = id
- data["extra"] = kit.UnMarshalm(maps["extra"])
- m.Confv("flow", []string{m.Option("river"), "data", arg[1], "list", "-2"}, data)
- })
- m.Confi("flow", []string{m.Option("river"), "data", arg[1], "meta", "count"}, id)
- m.Cmd("ssh.data", "save", arg[1])
- case "export":
- m.Append("directory", path.Join(m.Conf("ssh.data", "path"), m.Option("river"), arg[1], "/list.csv"))
- m.Table()
- }
- return
- }},
-
- "remote": {Name: "remote auto|dial|listen args...", Help: "连接", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if len(arg) == 0 {
- m.Cmd("_node")
- return
- }
-
- switch arg[0] {
- // 自动连接
- case "auto":
- switch m.Conf("runtime", "boot.ctx_type") {
- case "work":
- m.Cmd("ssh.work", "serve")
- case "user":
- m.Cmd("ssh.work", "create")
- case "node":
- }
-
- if m.Confs("runtime", "boot.ctx_ups") {
- m.Cmd("ssh.remote", "dial", m.Conf("runtime", "boot.ctx_ups"))
- m.Cmd("ssh.remote", "listen", m.Conf("runtime", "boot.ssh_port"))
- m.Cmd("web.serve", "usr", m.Conf("runtime", "boot.web_port"))
-
- } else if m.Cmd("ssh.remote", "dial", "dev", "/shadow"); !m.Confs("runtime", "boot.ctx_box") {
- m.Cmd("ssh.remote", "listen", m.Conf("runtime", "boot.ssh_port"))
- m.Cmd("web.serve", "usr", m.Conf("runtime", "boot.web_port"))
- }
-
- // 监听连接
- case "listen":
- m.Cmd("ssh._node", "init")
- m.Call(func(nfs *ctx.Message) *ctx.Message {
- if nfs.Has("node.port") {
- m.Log("info", "node.port %v", nfs.Optionv("node.port"))
- m.Conf("runtime", "node.port", nfs.Optionv("node.port"))
- }
- return nil
- }, "nfs.socket", arg)
-
- // 添加节点
- case "_add":
- name := m.Cmdx("ssh._node", "create", arg[1], arg[2], m.Format("source"), arg[4:])
- m.Sess("ms_source", false).Free(func(msg *ctx.Message) bool {
- m.Cmd("ssh._node", "delete", name)
- return true
- })
-
- // 下刷信息
- m.Append("node.name", m.Conf("runtime", "node.name"))
- m.Append("user.name", m.Conf("runtime", "user.name"))
- m.Append("work.name", m.Conf("runtime", "work.name"))
- m.Append("work.route", m.Conf("runtime", "work.route"))
- m.Append("user.route", m.Conf("runtime", "user.route"))
- m.Append("node.route", m.Conf("runtime", "node.route"))
- m.Append("work.script", m.Cmdx("nfs.load", path.Join(m.Conf("cli.publish", "path"), kit.Select("hello", arg[3]), "local.shy")))
- m.Echo(name).Back(m)
-
- // 断线重连
- case "_redial":
- if !m.Caps("stream") {
- m.Cmdx("ssh.remote", "dial", arg[1:])
- }
-
- // 连接主机
- case "dial":
- m.Cmd("ssh._node", "init")
- m.Call(func(nfs *ctx.Message) *ctx.Message {
- if m.Caps("stream") {
- return nil
- }
- // 删除重连
- if m.Confs("timer", "timer") {
- m.Conf("timer", "timer", m.Cmdx("cli.timer", "delete", m.Conf("timer", "timer")))
- }
-
- // 注册设备
- m.Spawn(nfs.Target()).Call(func(node *ctx.Message) *ctx.Message {
- if m.Caps("stream") {
- return nil
- }
- // 添加网关
- name := m.Cmd("ssh._node", "create", node.Append("node.name"), "master", m.Cap("stream", nfs.Format("target")))
-
- // 清理回调
- nfs.Free(func(nfs *ctx.Message) bool {
- m.Cmd("ssh._node", "delete", name)
-
- // 断线重连
- m.Cap("stream", "")
- m.Conf("timer", "timer", m.Cmdx("cli.timer", "repeat", m.Conf("timer", "interval"), "context", "ssh", "remote", "_redial", arg[1:]))
- return true
- })
-
- // 节点路由
- m.Cmd("cli.runtime", "node.route", node.Append("node.route")+"."+node.Result(0))
-
- // 用户路由
- if m.Confs("runtime", "user.cert") && m.Confs("runtime", "user.key") {
- m.Cmd("cli.runtime", "user.route", m.Conf("runtime", "node.route"))
-
- } else if node.Appends("user.route") && !m.Confs("runtime", "user.route") {
- m.Cmd("ssh.user", "create", node.Append("user.route"))
- }
-
- // 工作路由
- if node.Appends("work.route") && !m.Confs("runtime", "work.route") {
- m.Cmd("cli.runtime", "work.route", node.Append("work.route"))
- }
-
- // 注册脚本
- m.Cmd("nfs.source", m.Cmdx("nfs.temp", m.Append("work.script")))
- return nil
- }, "send", "", "_add", m.Conf("runtime", "node.name"), m.Conf("runtime", "node.type"), m.Conf("runtime", "boot.ctx_type"))
- return nil
- }, "nfs.socket", arg)
-
- default:
- m.Cmd("_route", arg)
- }
- return
- }},
- "_route": {Name: "_route", Help: "路由", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if len(arg) == 0 {
- return
- }
-
- // 同步异步
- sync := true
- switch arg[0] {
- case "async", "sync":
- sync, arg = arg[0] == "sync", arg[1:]
- }
-
- // 局域路由
- old := arg[0]
- if arg[0] == m.Conf("runtime", "node.name") || arg[0] == m.Conf("runtime", "node.route") {
- arg[0] = ""
- } else {
- arg[0] = strings.TrimPrefix(arg[0], m.Conf("runtime", "node.route")+".")
- arg[0] = strings.TrimPrefix(arg[0], m.Conf("runtime", "node.name")+".")
- }
-
- // 拆分路由
- route, names, arg := arg[0], strings.SplitN(arg[0], ".", 2), arg[1:]
- if len(names) > 1 && names[0] == "" && names[1] != "" {
- names[0], names[1] = names[1], names[0]
- }
-
- if rest := kit.Select("", names, 1); names[0] != "" {
- // 数字签名
- if !m.Options("remote_code") && arg[0] != "_check" {
- for _, k := range []string{"river"} {
- m.Option(k, m.Option(k))
- }
-
- hash, meta := kit.Hash("rand",
- m.Option("text.time", m.Time("stamp")),
- m.Option("text.cmd", strings.Join(arg, " ")),
- m.Option("text.route", route),
- m.Option("text.username", m.Option("username")),
- m.Option("node.route", m.Conf("runtime", "node.route")),
- m.Option("user.name", m.Conf("runtime", "user.name")),
- m.Option("user.route", m.Conf("runtime", "user.route")),
- m.Option("work.name", m.Conf("runtime", "work.name")),
- m.Option("work.route", m.Conf("runtime", "work.route")),
- )
- m.Option("text.rand", meta[0])
- m.Option("node.sign", m.Cmdx("aaa.rsa", "sign", m.Conf("runtime", "node.key"), m.Option("text.hash", hash)))
- }
-
- // 查找路由
- ps := []string{}
- if names[0] == "%" || names[0] == "*" {
- // 广播命令
- m.Confm("node", names[0], func(name string, node map[string]interface{}) {
- if kit.Format(node["type"]) != "master" {
- ps = append(ps, kit.Format(node["module"]))
- } else {
- ps = append(ps, "")
- }
- })
-
- } else if m.Confm("node", names[0], func(node map[string]interface{}) {
- // 单播命令
- ps = append(ps, kit.Format(node["module"]))
-
- }) == nil && m.Caps("stream") {
- // 上报命令
- rest, ps = old, append(ps, m.Cap("stream"))
- }
- if len(ps) == 0 {
- // 发送前端
- if m.Option("userrole") == "root" {
- if !strings.Contains(old, ".") {
- old = m.Option("username") + "." + old
- }
- m.CallBack(true, func(msg *ctx.Message) *ctx.Message {
- m.Copy(msg, "append")
- return nil
- }, "web.wss", old, "sync", arg)
- m.Table()
- return
- }
-
- // 查找失败
- m.Echo("error: not found %s", names[0]).Back(m)
- return
- }
-
- // 路由转发
- for _, p := range ps {
- m.Find(p, true).Copy(m, "option").CallBack(sync, func(sub *ctx.Message) *ctx.Message {
- m.Log("time", "remote: %v", sub.Format("cost"))
- return m.CopyFuck(sub, "append").CopyFuck(sub, "result")
- }, "send", rest, arg)
- }
- return
- }
-
- defer func() { m.Back(m) }()
-
- if !m.Options("remote_code") {
- // 本地调用
- m.Cmdy(arg)
-
- } else if arg[0] == "_check" {
- // 公有命令
- m.Cmd(arg)
-
- } else if arg[0] == "_add" {
- // 公有命令
- m.Cmd("remote", arg)
-
- } else if h := kit.Hashs(
- m.Option("text.rand"),
- m.Option("text.time"),
- m.Option("text.cmd"),
- m.Option("text.route"),
- m.Option("text.username"),
- m.Option("node.route"),
- m.Option("user.name"),
- m.Option("user.route"),
- m.Option("work.name"),
- m.Option("work.route"),
- ); h != m.Option("text.hash") {
- // 文本验签
- m.Echo("text error %s != %s", h, m.Option("text.hash"))
- m.Log("warn", "text error")
-
- } else if !m.Cmds("ssh._right", "node", "check", h) {
- // 设备验签
- m.Echo("node error of %s", m.Option("node.route"))
-
- } else if arg[0] == "tool" {
- m.Cmd("tool", arg[1:])
- } else {
- // 执行命令
- m.Log("time", "check: %v", m.Format("cost"))
- m.Cmd("_exec", arg)
- m.Log("time", "exec: %v", m.Format("cost"))
- }
- return
- }},
- "_right": {Name: "_right [node|user|work]", Help: []string{"认证",
- "node [check text|trust node]",
- "user [create|check text|share role node...|proxy node|trust node]",
- "work [create node name|check node name]",
- "file [import]",
- "tool ",
- }, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if len(arg) == 0 {
- m.Add("append", "key", "node.cert")
- m.Add("append", "route", m.Conf("runtime", "node.route"))
- m.Add("append", "value", m.Conf("runtime", "node.cert"))
- m.Add("append", "key", "user.cert")
- m.Add("append", "route", m.Conf("runtime", "user.route"))
- m.Add("append", "value", m.Conf("runtime", "user.cert"))
- m.Add("append", "key", "work.name")
- m.Add("append", "route", m.Conf("runtime", "work.route"))
- m.Add("append", "value", m.Conf("runtime", "work.name"))
- m.Table()
- return
- }
-
- switch arg[0] {
- // 节点认证
- case "node":
- if len(arg) == 1 {
- m.Echo(m.Conf("runtime", "node.cert"))
- break
- }
-
- switch arg[1] {
- // 数字验签
- case "check":
- if m.Option("node.cert", m.Cmd("aaa.auth", "nodes", m.Option("node.route"), "cert").Append("meta")); !m.Options("node.cert") {
- m.Option("node.cert", m.Cmdx("ssh._route", m.Option("node.route"), "_check", "node"))
- m.Cmd("aaa.auth", "nodes", m.Option("node.route"), "cert", m.Option("node.cert"))
- }
-
- if !m.Cmds("aaa.rsa", "verify", m.Option("node.cert"), m.Option("node.sign"), arg[2]) {
- if m.Log("warn", "node error"); m.Confs("trust", "renew") {
- m.Cmd("aaa.auth", "nodes", m.Option("node.route"), "node", "delete")
- }
- m.Echo("false")
- } else {
- m.Echo("true")
- }
-
- // 可信节点
- case "trust":
- if m.Confs("trust", arg[2]) {
- m.Echo("true")
-
- } else if m.Confs("trust", "user") && m.Conf("runtime", "user.route") == arg[2] {
- m.Echo("true")
-
- } else if m.Confs("trust", "up") && strings.HasPrefix(m.Conf("runtime", "node.route"), arg[2]) {
- m.Echo("true")
- }
- }
-
- // 用户认证
- case "user":
- if len(arg) == 1 {
- m.Echo(m.Conf("runtime", "user.cert"))
- break
- }
-
- switch arg[1] {
- // 数字验签
- case "check":
- if m.Option("user.cert", m.Cmd("aaa.auth", "username", m.Option("username"), "cert").Append("meta")); !m.Options("user.cert") {
- m.Option("user.cert", m.Cmd("ssh._route", m.Option("user.route"), "_check", "user").Append("user.cert"))
- m.Cmd("aaa.auth", "username", m.Option("username"), "cert", m.Option("user.cert"))
- }
-
- if !m.Options("user.cert") || !m.Cmds("aaa.rsa", "verify", m.Option("user.cert"), m.Option("user.sign"), arg[2]) {
- m.Log("warn", "user error")
- m.Echo("false")
- } else {
- m.Echo("true")
- }
-
- // 共享用户
- case "share":
- for _, route := range arg[3:] {
- user := m.Cmd("ssh._route", route, "_check", "user")
- if m.Cmd("aaa.role", arg[2], "user", user.Append("user.name"), "cert", user.Append("user.cert")); arg[2] == "root" && route != m.Conf("runtime", "node.route") {
- m.Conf("runtime", "user.route", user.Append("user.route"))
- m.Conf("runtime", "user.name", user.Append("user.name"))
- m.Conf("runtime", "user.cert", user.Append("user.cert"))
- m.Conf("runtime", "user.key", "")
- }
- }
-
- // 代理用户
- case "proxy":
- if len(arg) == 2 {
- m.Cmdy("aaa.auth", "proxy")
- break
- }
- if !m.Cmds("aaa.auth", "proxy", arg[2], "session") {
- m.Cmdy("aaa.sess", "proxy", "proxy", arg[2])
- }
-
- // 可信代理
- case "trust":
- hash := kit.Hashs("rand", m.Option("text.time", m.Time("stamp")), arg[2])
- m.Option("user.sign", m.Cmdx("ssh._route", m.Option("user.route"), "_check", "user", arg[2], hash))
- m.Echo("%v", m.Options("user.sign") && m.Cmds("ssh._right", "user", "check", hash))
- }
-
- // 公有认证
- case "work":
- if len(arg) == 1 {
- m.Echo(m.Conf("runtime", "work.name"))
- break
- }
-
- switch arg[1] {
- // 数字验签
- case "check":
- if arg[3] != m.Cmdx("ssh._route", kit.Select(m.Conf("runtime", "work.route"), m.Option("work.route")), "_check", "work", arg[2]) {
- m.Log("warn", "work error")
- m.Echo("false")
- } else {
- m.Echo("true")
- }
- }
-
- case "file":
- switch arg[1] {
- case "import":
- msg := m.Cmd("nfs.hash", arg[2])
- h := msg.Result(0)
- m.Conf("file", kit.Hashs(h, msg.Append("name")), map[string]interface{}{
- "create_time": m.Time(),
- "create_user": m.Option("username"),
- "name": msg.Append("name"),
- "type": msg.Append("type"),
- "size": msg.Append("size"),
- "hash": h,
- })
-
- m.Cmdy("nfs.copy", path.Join("var/file/hash", h[:2], h), arg[2])
-
- case "fetch":
- if m.Confs("file", arg[2]) {
- m.Echo(arg[2])
- break
- }
-
- msg := m.Cmd("ssh._route", arg[3], "_check", "file", arg[2])
- h := msg.Append("hash")
- m.Conf("file", arg[2], map[string]interface{}{
- "create_time": m.Time(),
- "create_user": m.Option("username"),
- "name": msg.Append("name"),
- "type": msg.Append("type"),
- "size": msg.Append("size"),
- "hash": h,
- })
-
- p := path.Join("var/file/hash", h[:2], h)
- if m.Cmds("nfs.path", p) {
- m.Echo(arg[2])
- break
- }
- m.Cmdy("nfs.copy", p)
- f, e := os.Create(p)
- m.Assert(e)
- for i := 0; int64(i) < msg.Appendi("size"); i += 1024 {
- msg := m.Cmd("ssh._route", arg[3], "_check", "file", arg[2], 1, 1024, i)
- for _, d := range msg.Meta["data"] {
- b, e := hex.DecodeString(d)
- m.Assert(e)
- _, e = f.Write(b)
- m.Assert(e)
- }
- }
-
- default:
- m.Confm("file", arg[1], func(file map[string]interface{}) {
- m.Append("hash", file["hash"])
- m.Append("size", file["size"])
- m.Append("type", file["type"])
- m.Append("name", file["name"])
- })
- m.Table()
- }
- }
- return
- }},
- "_check": {Name: "_check node|user|work", Help: []string{"验签",
- "node", "user [node text]", "work name [node cert]",
- }, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- switch arg[0] {
- // 节点验签
- case "node":
- m.Echo(m.Conf("runtime", "node.cert"))
-
- // 用户验签
- case "user":
- if len(arg) == 1 {
- m.Append("user.cert", m.Conf("runtime", "user.cert"))
- m.Append("user.name", m.Conf("runtime", "user.name"))
- m.Append("user.route", kit.Select(m.Conf("runtime", "node.route"), m.Conf("runtime", "user.route")))
- } else {
- // 代理签证
- if m.Confs("trust", arg[1]) {
- m.Echo(m.Cmdx("aaa.rsa", "sign", m.Conf("runtime", "user.key"), arg[2]))
- }
- }
-
- // 工作验签
- case "work":
- switch arg[1] {
- case "search":
- m.Confm("work", func(key string, value map[string]interface{}) {
- m.Add("append", "key", key)
- m.Add("append", "user.route", value["user"])
- m.Add("append", "create_time", value["create_time"])
- })
- m.Table()
-
- case "create":
- name := arg[2]
- if len(arg) == 3 {
- arg = append(arg, m.Conf("runtime", "node.route"))
- }
- if user := m.Conf("work", []string{name, "user"}); user != "" && user != arg[3] {
- for i := 1; i < 100; i++ {
- name = fmt.Sprintf("%s%02d", arg[2], i)
- if user := m.Conf("work", []string{name, "user"}); user == "" || user == arg[3] {
- break
- }
- name = ""
- }
- }
- if name != "" {
- m.Conf("work", name, map[string]interface{}{"create_time": m.Time(), "user": arg[3]})
- m.Echo(name)
- }
-
- default:
- if cert := m.Confm("work", arg[1]); len(arg) == 2 {
- if cert != nil {
- m.Echo("%s", cert["user"])
- }
- } else {
- // 工作签证
- if cert == nil {
- m.Conf("work", arg[1], map[string]interface{}{"create_time": m.Time(), "user": arg[2]})
- } else if cert["user"] != arg[2] {
- // 签证失败
- return
- }
- m.Echo(arg[1])
- }
- }
-
- case "file":
- if len(arg) == 2 {
- m.Confm("file", arg[1], func(file map[string]interface{}) {
- m.Append("hash", file["hash"])
- m.Append("size", file["size"])
- m.Append("type", file["type"])
- m.Append("name", file["name"])
- })
- m.Table()
- break
- }
-
- h := m.Conf("file", []string{arg[1], "hash"})
-
- if f, e := os.Open(path.Join("var/file/hash", h[:2], h)); e == nil {
- defer f.Close()
-
- pos := kit.Int(kit.Select("0", arg, 4))
- size := kit.Int(kit.Select("1024", arg, 3))
- count := kit.Int(kit.Select("3", arg, 2))
-
- buf := make([]byte, count*size)
-
- if l, e := f.ReadAt(buf, int64(pos)); e == io.EOF || m.Assert(e) {
- for i := 0; i < count; i++ {
- if l < (i+1)*size {
- m.Add("append", "data", hex.EncodeToString(buf[i*size:l]))
- break
- }
- m.Add("append", "data", hex.EncodeToString(buf[i*size:(i+1)*size]))
- }
- }
- }
- }
- return
- }},
- "_exec": {Name: "_exec", Help: "命令", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- access := m.Option("access", kit.Hashs(
- m.Option("node.route"),
- m.Option("user.route"),
- m.Option("work.route"),
- m.Option("work.name"),
- m.Option("user.name"),
- m.Option("text.username"),
- ))
-
- if m.Option("sessid", m.Cmd("aaa.auth", "access", access, "session").Append("key")) != "" &&
- m.Option("username", m.Cmd("aaa.sess", "user").Append("meta")) != "" {
- // 历史会话
- m.Log("warn", "access: %s", access)
- m.Log("info", "sessid: %s", m.Option("sessid"))
- m.Option("trust", m.Cmdx("aaa.auth", "access", access, "data", "trust"))
- m.Option("userrole", m.Cmdx("aaa.auth", "access", access, "data", "userrole"))
-
- } else if m.Option("username", m.Option("text.username")); !m.Confs("runtime", "user.route") && m.Confs("trust", "fresh") {
- // 免签节点
- m.Log("warn", "trust fresh %s", m.Option("node.route"))
- m.Option("trust", "fresh")
-
- } else if m.Cmds("ssh._right", "node", "trust", m.Option("node.route")) {
- // 可信节点
- m.Log("warn", "trust node %s", m.Option("node.route"))
- m.Option("trust", "node")
-
- } else if m.Options("user.route") && m.Cmds("ssh._right", "node", "trust", m.Option("user.route")) &&
- m.Cmds("ssh._right", "user", "trust", m.Option("node.route")) {
- // 可信用户
- m.Log("warn", "trust user %s", m.Option("user.route"))
- m.Option("trust", "user")
-
- } else if m.Options("work.route") && m.Cmds("ssh._right", "node", "trust", m.Option("work.route")) &&
- m.Cmds("ssh._right", "work", "check", m.Option("username"), m.Option("node.route")) {
- // 可信工作
- m.Log("warn", "trust work %s", m.Option("work.route"))
- m.Option("userrole", "tech")
- m.Option("trust", "work")
-
- } else if m.Option("userrole", "void"); m.Confs("trust", "none") {
- // 免签用户
- m.Log("warn", "trust none")
- m.Option("trust", "none")
-
- } else {
- // 验证失败
- m.Log("warn", "user error of %s", m.Option("node.route"))
- m.Echo("user error")
- return
- }
-
- // 用户角色
- if m.Log("info", "username: %s", m.Option("username")); !m.Options("userrole") {
- m.Option("userrole", kit.Select("void", m.Cmd("aaa.user", "role").Append("meta")))
- }
- m.Log("info", "userrole: %s", m.Option("userrole"))
-
- // 创建会话
- if !m.Options("sessid") {
- m.Option("sessid", m.Cmdx("aaa.user", "session", "select"))
- m.Cmd("aaa.auth", m.Cmdx("aaa.auth", m.Option("sessid"), "access", access),
- "data", "trust", m.Option("trust"), "userrole", m.Option("userrole"))
- }
-
- // 权限检查
- if !m.Cmds("aaa.role", m.Option("userrole"), "check", arg) {
- m.Echo("no right %s %s", "remote", arg[0])
- return
- }
-
- // 执行命令
- m.Log("time", "right: %v", m.Format("cost"))
- m.Cmdy(arg)
- return
- }},
-
- "login": {Name: "login address", Help: "网络连接", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if len(arg) == 0 {
- arg = append(arg, "shy@shylinux.com")
- }
- m.Start(arg[0], arg[0], arg...)
- time.Sleep(1000 * time.Millisecond)
- return
- }},
- "run": {Name: "run cmd", Help: "网络连接", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if ssh, ok := m.Target().Server.(*SSH); ok && ssh.relay != nil {
- ssh.relay <- m
- m.CallBack(true, func(msg *ctx.Message) (res *ctx.Message) {
- return nil
- }, append([]string{"_"}, arg...))
- }
- return
- }},
- },
-}
-
-func init() {
- ctx.Index.Register(Index, &SSH{Context: Index})
-}
diff --git a/usr/local/honor/src/contexts/tcp/tcp.go b/usr/local/honor/src/contexts/tcp/tcp.go
deleted file mode 100644
index 752852da..00000000
--- a/usr/local/honor/src/contexts/tcp/tcp.go
+++ /dev/null
@@ -1,309 +0,0 @@
-package tcp
-
-import (
- "contexts/ctx"
- "toolkit"
-
- "crypto/tls"
- "fmt"
- "io"
- "net"
- "strconv"
- "strings"
- "sync/atomic"
- "time"
-)
-
-type TCP struct {
- net.Conn
- net.Listener
- *ctx.Context
-}
-
-func (tcp *TCP) parse(m *ctx.Message, arg ...string) ([]string, []string, bool) {
- defer func() {
- if e := recover(); e != nil {
- m.Log("warn", "%v", e)
- }
- }()
-
- address := []string{}
- if arg[1] == "dev" {
- m.Cmd("web.get", arg[1], arg[2], "temp", "ports", "format", "object", "temp_expire", "10").Table(func(line map[string]string) {
- address = append(address, line["value"])
- })
- if len(address) == 0 {
- return nil, nil, false
- }
-
- for i := 2; i < len(arg)-1; i++ {
- arg[i] = arg[i+1]
- }
- if len(arg) > 2 {
- arg = arg[:len(arg)-1]
- }
- } else {
- address = append(address, m.Cap("address", m.Confx("address", arg, 1)))
- }
- return address, arg, true
-}
-func (tcp *TCP) retry(m *ctx.Message, address []string, action func(address string) (net.Conn, error)) net.Conn {
- var count int32
- cs := make(chan net.Conn)
-
- for i := 0; i < m.Confi("retry", "counts"); i++ {
- for _, p := range address {
- m.Gos(m.Spawn().Add("option", "address", p), func(msg *ctx.Message) {
- m.Log("info", "dial: %v", msg.Option("address"))
- if count >= 1 {
- msg.Log("info", "skip: %v", msg.Option("address"))
- } else if c, e := action(msg.Option("address")); e != nil {
- msg.Log("info", "%s", e)
- } else if atomic.AddInt32(&count, 1) > 1 {
- msg.Log("info", "close: %s", c.LocalAddr())
- c.Close()
- } else {
- cs <- c
- }
- })
- }
-
- select {
- case c := <-cs:
- return c
-
- case <-time.After(kit.Duration(m.Conf("retry", "interval"))):
- m.Log("info", "dial %s:%v timeout", m.Cap("protocol"), address)
- }
- }
- return nil
-}
-func (tcp *TCP) Read(b []byte) (n int, e error) {
- if m := tcp.Context.Message(); m.Assert(tcp.Conn != nil) {
- if n, e = tcp.Conn.Read(b); e == io.EOF || m.Assert(e) {
- m.Capi("nrecv", n)
- }
- }
- return
-}
-func (tcp *TCP) Write(b []byte) (n int, e error) {
- if m := tcp.Context.Message(); m.Assert(tcp.Conn != nil) {
- if n, e = tcp.Conn.Write(b); e == io.EOF || m.Assert(e) {
- m.Capi("nsend", n)
- }
- }
- return
-}
-
-func (tcp *TCP) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server {
- c.Caches = map[string]*ctx.Cache{
- "protocol": &ctx.Cache{Name: "protocol(tcp/tcp4/tcp6)", Value: "", Help: "网络协议"},
- "security": &ctx.Cache{Name: "security(true/false)", Value: "", Help: "加密通信"},
- "address": &ctx.Cache{Name: "address", Value: "", Help: "网络地址"},
- "nrecv": &ctx.Cache{Name: "nrecv", Value: "0", Help: "接收字节数"},
- "nsend": &ctx.Cache{Name: "nsend", Value: "0", Help: "发送字节数"},
- }
- return &TCP{Context: c}
-}
-func (tcp *TCP) Begin(m *ctx.Message, arg ...string) ctx.Server {
- return tcp
-}
-func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool {
- address, arg, ok := tcp.parse(m, arg...)
- if len(address) == 0 || !ok {
- return true
- }
- m.Cap("security", m.Confx("security", arg, 2))
- m.Cap("protocol", m.Confx("protocol", arg, 3))
-
- switch arg[0] {
- case "dial":
- if m.Caps("security") {
- cert, e := tls.LoadX509KeyPair(m.Cap("certfile"), m.Cap("keyfile"))
- m.Assert(e)
- conf := &tls.Config{Certificates: []tls.Certificate{cert}, InsecureSkipVerify: true}
-
- tcp.Conn = tcp.retry(m, address, func(p string) (net.Conn, error) {
- return tls.Dial(m.Cap("protocol"), p, conf)
- })
- } else {
- tcp.Conn = tcp.retry(m, address, func(p string) (net.Conn, error) {
- return net.DialTimeout(m.Cap("protocol"), p, kit.Duration(m.Conf("retry", "timeout")))
- })
- }
-
- m.Log("info", "%s connect %s", m.Cap("nclient"),
- m.Cap("stream", fmt.Sprintf("%s->%s", tcp.LocalAddr(), m.Cap("address", tcp.RemoteAddr().String()))))
-
- m.Sess("tcp", m)
- m.Option("ms_source", tcp.Context.Name)
- m.Put("option", "io", tcp).Back()
- return false
-
- case "accept":
- c, e := m.Optionv("io").(net.Conn)
- m.Assert(e)
- tcp.Conn = c
-
- m.Log("info", "%s accept %s", m.Cap("nclient"),
- m.Cap("stream", fmt.Sprintf("%s<-%s", tcp.LocalAddr(), tcp.RemoteAddr())))
-
- m.Sess("tcp", m)
- m.Option("ms_source", tcp.Context.Name)
- m.Put("option", "io", tcp).Back()
- return false
-
- case "listen":
- if m.Caps("security") {
- m.Sess("aaa", m.Sess("aaa").Cmd("login", "cert", m.Cap("certfile"), "key", m.Cap("keyfile"), "tcp"))
- cert, e := tls.LoadX509KeyPair(m.Cap("certfile"), m.Cap("keyfile"))
- m.Assert(e)
- conf := &tls.Config{Certificates: []tls.Certificate{cert}}
-
- l, e := tls.Listen(m.Cap("protocol"), m.Cap("address"), conf)
- m.Assert(e)
- tcp.Listener = l
- } else {
- l, e := net.Listen(m.Cap("protocol"), m.Cap("address"))
- m.Assert(e)
- tcp.Listener = l
- }
-
- m.Log("info", "%d listen %v", m.Capi("nlisten"), m.Cap("stream", fmt.Sprintf("%s", tcp.Addr())))
-
- addr := strings.Split(tcp.Addr().String(), ":")
- ports := []interface{}{}
- if m.Cmd("tcp.ifconfig").Table(func(line map[string]string) {
- ports = append(ports, fmt.Sprintf("%s:%s", line["ip"], addr[len(addr)-1]))
- }); len(ports) == 0 {
- ports = append(ports, fmt.Sprintf("%s:%s", "127.0.0.1", addr[len(addr)-1]))
- }
- m.Back(m.Spawn(m.Source()).Put("option", "node.port", ports))
- default:
- return true
- }
-
- for {
- if c, e := tcp.Accept(); m.Assert(e) {
- m.Spawn(Index).Put("option", "io", c).Call(func(sub *ctx.Message) *ctx.Message {
- return sub.Spawn(m.Source())
- }, "accept", c.RemoteAddr().String(), m.Cap("security"), m.Cap("protocol"))
- }
- }
-
- return true
-}
-func (tcp *TCP) Close(m *ctx.Message, arg ...string) bool {
- switch tcp.Context {
- case m.Target():
- if tcp.Listener != nil {
- m.Log("info", " close %v", m.Cap("stream"))
- tcp.Listener.Close()
- tcp.Listener = nil
- }
- if tcp.Conn != nil {
- m.Log("info", " close %v", m.Cap("stream"))
- tcp.Conn.Close()
- tcp.Conn = nil
- }
- case m.Source():
- }
- return true
-}
-
-var Index = &ctx.Context{Name: "tcp", Help: "网络中心",
- Caches: map[string]*ctx.Cache{
- "nlisten": &ctx.Cache{Name: "nlisten", Value: "0", Help: "监听数量"},
- "nclient": &ctx.Cache{Name: "nclient", Value: "0", Help: "连接数量"},
- },
- Configs: map[string]*ctx.Config{
- "address": &ctx.Config{Name: "address", Value: ":9090", Help: "网络地址"},
- "security": &ctx.Config{Name: "security(true/false)", Value: "false", Help: "加密通信"},
- "protocol": &ctx.Config{Name: "protocol(tcp/tcp4/tcp6)", Value: "tcp4", Help: "网络协议"},
- "retry": &ctx.Config{Name: "retry", Value: map[string]interface{}{
- "interval": "3s", "counts": 3, "timeout": "10s",
- }, Help: "网络重试"},
- },
- Commands: map[string]*ctx.Command{
- "listen": &ctx.Command{Name: "listen address [security [protocol]]", Help: "网络监听", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- m.Start(fmt.Sprintf("pub%d", m.Capi("nlisten", 1)), "网络监听", m.Meta["detail"]...)
- return
- }},
- "accept": &ctx.Command{Name: "accept address [security [protocol]]", Help: "网络连接", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- m.Start(fmt.Sprintf("sub%d", m.Capi("nclient", 1)), "网络连接", m.Meta["detail"]...)
- return
- }},
- "dial": &ctx.Command{Name: "dial address [security [protocol]]", Help: "网络连接", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- m.Start(fmt.Sprintf("com%d", m.Capi("nclient", 1)), "网络连接", m.Meta["detail"]...)
- return
- }},
-
- "send": &ctx.Command{Name: "send message", Help: "发送消息", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if tcp, ok := m.Target().Server.(*TCP); m.Assert(ok) {
- fmt.Fprint(tcp, arg[0])
- }
- return
- }},
- "recv": &ctx.Command{Name: "recv size", Help: "接收消息", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if tcp, ok := m.Target().Server.(*TCP); m.Assert(ok) {
- if n, e := strconv.Atoi(arg[0]); m.Assert(e) {
- buf := make([]byte, n)
- n, _ = tcp.Read(buf)
- m.Echo(string(buf[:n]))
- }
- }
- return
- }},
-
- "ifconfig": &ctx.Command{Name: "ifconfig [name]", Help: "网络配置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if ifs, e := net.Interfaces(); m.Assert(e) {
- for _, v := range ifs {
- if len(arg) > 0 && !strings.Contains(v.Name, arg[0]) {
- continue
- }
- if ips, e := v.Addrs(); m.Assert(e) {
- for _, x := range ips {
- ip := strings.Split(x.String(), "/")
- if strings.Contains(ip[0], ":") || len(ip) == 0 {
- continue
- }
- if len(v.HardwareAddr.String()) == 0 {
- 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.Table()
- }
- return
- }},
- "probe": &ctx.Command{Name: "probe [port]", Help: "端口检测", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if len(arg) == 0 {
- for i := 0; i < 1024; i++ {
- m.Show("port: %v", i)
- if t, e := net.DialTimeout("tcp", fmt.Sprintf(":%d", i), 3*time.Second); e == nil {
- m.Push("port", i)
- t.Close()
- }
- }
- m.Table()
- return
- }
- if t, e := net.DialTimeout("tcp", arg[0], 10*time.Second); e == nil {
- m.Echo("active")
- t.Close()
- }
- return
- }},
- },
-}
-
-func init() {
- ctx.Index.Register(Index, &TCP{Context: Index})
-}
diff --git a/usr/local/honor/src/contexts/web/parse.go b/usr/local/honor/src/contexts/web/parse.go
deleted file mode 100644
index 71b11061..00000000
--- a/usr/local/honor/src/contexts/web/parse.go
+++ /dev/null
@@ -1,56 +0,0 @@
-package web
-
-import (
-// "github.com/PuerkitoBio/goquery"
-)
-
-func parseHTML() {
- /*
- page, e := goquery.NewDocumentFromReader(res.Body)
- m.Assert(e)
-
- page.Find(kit.Select("html", m.Option("parse_chain"))).Each(func(n int, s *goquery.Selection) {
- if m.Options("parse_select") {
- for i := 0; i < len(m.Meta["parse_select"])-2; i += 3 {
- item := s.Find(m.Meta["parse_select"][i+1])
- if m.Meta["parse_select"][i+1] == "" {
- item = s
- }
- if v, ok := item.Attr(m.Meta["parse_select"][i+2]); ok {
- m.Add("append", m.Meta["parse_select"][i], v)
- m.Log("info", "item attr %v", v)
- } else {
- m.Add("append", m.Meta["parse_select"][i], strings.Replace(item.Text(), "\n", "", -1))
- m.Log("info", "item text %v", item.Text())
- }
- }
- return
- }
-
- s.Find("a").Each(func(n int, s *goquery.Selection) {
- if attr, ok := s.Attr("href"); ok {
- s.SetAttr("href", proxy(m, attr))
- }
- })
- s.Find("img").Each(func(n int, s *goquery.Selection) {
- if attr, ok := s.Attr("src"); ok {
- s.SetAttr("src", proxy(m, attr))
- }
- if attr, ok := s.Attr("r-lazyload"); ok {
- s.SetAttr("src", proxy(m, attr))
- }
- })
- s.Find("script").Each(func(n int, s *goquery.Selection) {
- if attr, ok := s.Attr("src"); ok {
- s.SetAttr("src", proxy(m, attr))
- }
- })
-
- if html, e := s.Html(); e == nil {
- m.Add("append", "html", html)
- }
- })
- m.Table()
-
- */
-}
diff --git a/usr/local/honor/src/contexts/web/web.go b/usr/local/honor/src/contexts/web/web.go
deleted file mode 100644
index 56ce6e86..00000000
--- a/usr/local/honor/src/contexts/web/web.go
+++ /dev/null
@@ -1,1309 +0,0 @@
-package web
-
-import (
- "github.com/gorilla/websocket"
- "github.com/skip2/go-qrcode"
- "time"
-
- "contexts/ctx"
- "toolkit"
-
- "bytes"
- "encoding/json"
- "fmt"
- "io"
- "io/ioutil"
- "mime/multipart"
- "net/http"
- "net/url"
- "os"
- "path"
- "path/filepath"
- "strconv"
- "strings"
- "text/template"
-)
-
-type MUX interface {
- Handle(string, http.Handler)
- HandleFunc(string, func(http.ResponseWriter, *http.Request))
- HandleCmd(*ctx.Message, string, *ctx.Command)
- ServeHTTP(http.ResponseWriter, *http.Request)
-}
-type WEB struct {
- *http.Client
-
- *http.Server
- *http.ServeMux
- *template.Template
-
- *ctx.Context
-}
-
-func Cookie(msg *ctx.Message, w http.ResponseWriter, r *http.Request) {
- expire := time.Now().Add(kit.Duration(msg.Conf("login", "expire")))
- msg.Log("info", "expire %v", expire)
- http.SetCookie(w, &http.Cookie{Name: "sessid",
- Value: msg.Cmdx("aaa.user", "session", "select"), Path: "/", Expires: expire})
- return
-}
-func proxy(m *ctx.Message, url string) string {
- if strings.HasPrefix(url, "//") {
- return "proxy/https:" + url
- }
-
- return "proxy/" + url
-}
-func merge(m *ctx.Message, uri string, arg ...string) string {
- add, e := url.Parse(uri)
- m.Assert(e)
-
- args := []interface{}{}
- for i := 0; i < strings.Count(add.RawQuery, "%s") && len(arg) > 0; i++ {
- args, arg = append(args, arg[0]), arg[1:]
- }
- add.RawQuery = fmt.Sprintf(add.RawQuery, args...)
-
- query := add.Query()
- for i := 0; i < len(arg)-1; i += 2 {
- value := m.Parse(arg[i+1])
-
- if value == "" {
- query.Del(arg[i])
- } else {
- // query.Set(arg[i], value)
- query.Add(arg[i], value)
- }
- }
- add.RawQuery = query.Encode()
- return add.String()
-}
-func Merge(m *ctx.Message, client map[string]interface{}, uri string, arg ...string) string {
- add, e := url.Parse(uri)
- m.Assert(e)
-
- add.Scheme = kit.Select(kit.Format(client["protocol"]), add.Scheme)
- add.Host = kit.Select(kit.Format(client["hostname"]), add.Host)
-
- if add.Path == "" {
- add.Path = path.Join(kit.Format(client["path"]), kit.Format(client["file"]))
- } else if !path.IsAbs(add.Path) {
- add.Path = path.Join(kit.Format(client["path"]), add.Path)
- if strings.HasSuffix(uri, "/") {
- add.Path += "/"
- }
- }
-
- add.RawQuery = kit.Select(kit.Format(client["query"]), add.RawQuery)
- return merge(m, add.String(), arg...)
-}
-
-func (web *WEB) Login(msg *ctx.Message, w http.ResponseWriter, r *http.Request) bool {
- if !msg.Has("username") || !msg.Options("username") {
- msg.Option("username", "")
- }
-
- // 用户登录
- if msg.Options("username") && msg.Options("password") {
- if msg.Cmds("aaa.auth", "username", msg.Option("username"), "password", msg.Option("password")) {
- msg.Log("info", "login: %s", msg.Option("username"))
- if Cookie(msg, w, r); msg.Options("relay") {
- if role := msg.Cmdx("aaa.relay", "check", msg.Option("relay"), "userrole"); role != "" {
- msg.Cmd("aaa.role", role, "user", msg.Option("username"))
- msg.Log("info", "relay: %s", role)
- }
- }
- } else {
- w.WriteHeader(http.StatusUnauthorized)
- }
- return false
-
- } else if msg.Options("relay") {
- msg.Short("relay")
-
- relay := msg.Cmd("aaa.relay", "check", msg.Option("relay"))
- if relay.Appendi("count") == 0 {
- msg.Err("共享失效")
- return false
- }
- if relay.Appends("username") {
- name := msg.Cmdx("ssh._route", msg.Conf("runtime", "work.route"), "_check", "work", "create", relay.Append("username"), msg.Conf("runtime", "node.route"))
- msg.Log("info", "login: %s", msg.Option("username", name))
- Cookie(msg, w, r)
- }
- if role := relay.Append("userrole"); role != "" {
- msg.Cmd("aaa.role", role, "user", msg.Option("username"))
- msg.Log("info", "relay: %s", role)
- }
- if relay.Appends("url") {
- msg.Append("redirect", relay.Append("url"))
- return false
- }
-
- if relay.Appends("form") {
- form := kit.UnMarshalm(relay.Append("form"))
- for k, v := range form {
- msg.Log("info", "form %s:%s", k, msg.Option(k, kit.Format(v)))
- }
- }
- }
-
- // 用户访问
- if msg.Log("info", "sessid: %s", msg.Option("sessid")); msg.Options("sessid") {
- msg.Log("info", "username: %s", msg.Option("username", msg.Cmd("aaa.sess", "user").Append("meta")))
- msg.Log("info", "userrole: %v", msg.Option("userrole", msg.Cmd("aaa.user", "role").Append("meta")))
- }
-
- // 本地用户
- if !msg.Options("username") && kit.IsLocalIP(msg.Option("remote_ip")) && msg.Confs("web.login", "local") && !strings.HasPrefix(msg.Option("agent"), "curl") {
- msg.Cmd("aaa.role", "root", "user", msg.Cmdx("ssh.work", "create"))
- msg.Log("info", "%s: %s", msg.Option("remote_ip"), msg.Option("username", msg.Conf("runtime", "work.name")))
- Cookie(msg, w, r)
- }
-
- return true
-}
-func (web *WEB) HandleCmd(m *ctx.Message, key string, cmd *ctx.Command) {
- web.HandleFunc(key, func(w http.ResponseWriter, r *http.Request) {
- m.TryCatch(m.Spawn(m.Conf("serve", "autofree")), true, func(msg *ctx.Message) {
- defer func() {
- msg.Log("time", "serve: %v", msg.Format("cost"))
- }()
- msg.Option("agent", r.Header.Get("User-Agent"))
- msg.Option("remote_addr", r.RemoteAddr)
- msg.Option("remote_ip", r.Header.Get("remote_ip"))
- msg.Option("index_url", r.Header.Get("index_url"))
- msg.Option("index_path", r.Header.Get("index_path"))
- msg.Option("referer", r.Header.Get("Referer"))
- msg.Option("accept", r.Header.Get("Accept"))
- msg.Option("method", r.Method)
- msg.Option("path", r.URL.Path)
- msg.Option("sessid", "")
-
- // 请求环境
- for _, v := range r.Cookies() {
- if v.Value != "" {
- msg.Option(v.Name, v.Value)
- }
- }
-
- // 请求参数
- r.ParseMultipartForm(int64(msg.Confi("serve", "form_size")))
- if r.ParseForm(); len(r.PostForm) > 0 {
- for k, v := range r.PostForm {
- msg.Log("info", "%s: %v", k, v)
- }
- msg.Log("info", "")
- }
- for k, v := range r.Form {
- msg.Add("option", k, v)
- }
-
- // 请求数据
- switch r.Header.Get("Content-Type") {
- case "application/json":
- var data interface{}
- 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{}:
- for k, v := range d {
- for _, v := range kit.Trans(v) {
- msg.Add("option", k, v)
- }
- }
- }
- }
-
- msg.Short("river")
-
- // 用户登录
- if msg.Put("option", "request", r).Put("option", "response", w).Sess("web", msg); web.Login(msg, w, r) {
- msg.Log("cmd", "%s [] %v", key, msg.Meta["option"])
- cmd.Hand(msg, msg.Target(), msg.Option("path"))
- }
-
- // 返回响应
- switch {
- case msg.Has("redirect"):
- http.Redirect(w, r, msg.Append("redirect"), http.StatusTemporaryRedirect)
-
- case msg.Has("directory"):
- http.ServeFile(w, r, msg.Append("directory"))
-
- case msg.Has("qrcode"):
- if qr, e := qrcode.New(msg.Append("qrcode"), qrcode.Medium); m.Assert(e) {
- w.Header().Set("Content-Type", "image/png")
- m.Assert(qr.Write(256, w))
- }
-
- case msg.Has("append"):
- meta := map[string]interface{}{}
- if len(msg.Meta["result"]) > 0 {
- meta["result"] = msg.Meta["result"]
- }
- if len(msg.Meta["append"]) > 0 {
- meta["append"] = msg.Meta["append"]
- for _, v := range msg.Meta["append"] {
- if _, ok := msg.Data[v]; ok {
- meta[v] = msg.Data[v]
- } else if _, ok := msg.Meta[v]; ok {
- meta[v] = msg.Meta[v]
- }
- }
- }
-
- if b, e := json.Marshal(meta); msg.Assert(e) {
- w.Header().Set("Content-Type", "application/javascript")
- w.Write(b)
- }
- default:
- for _, v := range msg.Meta["result"] {
- w.Write([]byte(v))
- }
- }
- })
- })
-}
-func (web *WEB) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- m := web.Message()
-
- index := r.Header.Get("index_module") == ""
- if index {
- if ip := r.Header.Get("X-Forwarded-For"); ip != "" {
- r.Header.Set("remote_ip", ip)
- } else if ip := r.Header.Get("X-Real-Ip"); ip != "" {
- r.Header.Set("remote_ip", ip)
- } else if strings.HasPrefix(r.RemoteAddr, "[") {
- r.Header.Set("remote_ip", strings.Split(r.RemoteAddr, "]")[0][1:])
- } else {
- r.Header.Set("remote_ip", strings.Split(r.RemoteAddr, ":")[0])
- }
-
- m.Log("info", "").Log("info", "%v %s %s", r.Header.Get("remote_ip"), r.Method, r.URL)
- r.Header.Set("index_module", m.Cap("module"))
- r.Header.Set("index_url", r.URL.String())
- r.Header.Set("index_path", r.URL.Path)
- if r.URL.Path == "/" && m.Confs("serve", "index") {
- r.URL.Path = m.Conf("serve", "index")
- }
- }
-
- if index && m.Confs("serve", "logheaders") {
- for k, v := range r.Header {
- m.Log("info", "%s: %v", k, v)
- }
- m.Log("info", "")
- }
-
- if r.URL.Path == "/" && m.Confs("route", "index") {
- r.URL.Path = m.Conf("route", "index")
- }
- web.ServeMux.ServeHTTP(w, r)
-
- if index && m.Confs("serve", "logheaders") {
- for k, v := range w.Header() {
- m.Log("info", "%s: %v", k, v)
- }
- m.Log("info", "")
- }
-}
-
-func (web *WEB) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server {
- return &WEB{Context: c}
-}
-func (web *WEB) Begin(m *ctx.Message, arg ...string) ctx.Server {
- web.Caches["master"] = &ctx.Cache{Name: "master(yes/no)", Value: "no", Help: "服务入口"}
- web.Caches["register"] = &ctx.Cache{Name: "register(yes/no)", Value: "no", Help: "是否已初始化"}
- web.Caches["route"] = &ctx.Cache{Name: "route", Value: "/" + web.Context.Name + "/", Help: "模块路由"}
-
- web.ServeMux = http.NewServeMux()
- web.Template = template.New("render").Funcs(ctx.CGI)
- web.Template.ParseGlob(path.Join(m.Conf("route", "template_dir"), "/*.tmpl"))
- web.Template.ParseGlob(path.Join(m.Conf("route", "template_dir"), m.Cap("route"), "/*.tmpl"))
- return web
-}
-func (web *WEB) Start(m *ctx.Message, arg ...string) bool {
- web.Caches["directory"] = &ctx.Cache{Name: "directory", Value: kit.Select(m.Conf("serve", "directory"), arg, 0), Help: "服务目录"}
- web.Caches["protocol"] = &ctx.Cache{Name: "protocol", Value: kit.Select(m.Conf("serve", "protocol"), arg, 2), Help: "服务协议"}
- web.Caches["address"] = &ctx.Cache{Name: "address", Value: kit.Select(m.Conf("runtime", "boot.web_port"), arg, 1), Help: "服务地址"}
- m.Log("info", "%d %s %s://%s", m.Capi("nserve", 1), m.Cap("directory"), m.Cap("protocol"), m.Cap("stream", m.Cap("address")))
-
- render := m.Target().Commands["/render"]
- proxy := m.Target().Commands["/proxy/"]
-
- m.Target().Travel(m, func(m *ctx.Message, i int) bool {
- if h, ok := m.Target().Server.(MUX); ok && m.Cap("register") == "no" {
- m.Cap("register", "yes")
-
- // 路由级联
- p := m.Target().Context()
- if s, ok := p.Server.(MUX); ok {
- m.Log("info", "route: /%s <- %s", p.Name, m.Cap("route"))
- s.Handle(m.Cap("route"), http.StripPrefix(path.Dir(m.Cap("route")), h))
- }
-
- // 模板文件
- if m.Target().Commands["/render"] == nil {
- m.Target().Commands["/render"] = render
- }
- if m.Target().Commands["/proxy/"] == nil {
- m.Target().Commands["/proxy/"] = proxy
- }
-
- // 动态文件
- msg := m.Target().Message()
- for k, x := range m.Target().Commands {
- if k[0] == '/' {
- m.Log("info", "%d route: %s", m.Capi("nroute", 1), k)
- h.HandleCmd(msg, k, x)
- }
- }
-
- // 静态文件
- if m.Cap("directory") != "" {
- m.Log("info", "route: %sstatic/ <- [%s]\n", m.Cap("route"), m.Cap("directory"))
- h.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir(m.Cap("directory")))))
- }
- }
- return false
- })
-
- // 启动服务
- m.Log("info", "web: %s", m.Cap("address"))
- web.Server = &http.Server{Addr: m.Cap("address"), Handler: web}
- if m.Caps("master", true); m.Cap("protocol") == "https" {
- web.Server.ListenAndServeTLS(m.Conf("runtime", "node.cert"), m.Conf("runtime", "node.key"))
- } else {
- web.Server.ListenAndServe()
- }
- return true
-}
-func (web *WEB) Close(m *ctx.Message, arg ...string) bool {
- return true
-}
-
-var Index = &ctx.Context{Name: "web", Help: "应用中心",
- Caches: map[string]*ctx.Cache{
- "nserve": &ctx.Cache{Name: "nserve", Value: "0", Help: "主机数量"},
- "nroute": &ctx.Cache{Name: "nroute", Value: "0", Help: "路由数量"},
- },
- Configs: map[string]*ctx.Config{
- "spide": &ctx.Config{Name: "spide", Value: map[string]interface{}{
- "": map[string]interface{}{
- "client": map[string]interface{}{},
- "header": map[string]interface{}{},
- "cookie": map[string]interface{}{},
- },
- }, Help: "爬虫配置"},
- "serve": &ctx.Config{Name: "serve", Value: map[string]interface{}{
- "autofree": false,
- "logheaders": false,
- "form_size": "102400",
- "directory": "usr",
- "protocol": "http",
- "cert": "etc/cert.pem",
- "key": "etc/key.pem",
- "site": "",
- // "index": "/chat/",
- "index": "/static/volcanos/",
- "open": []interface{}{},
- }, Help: "服务配置"},
- "route": &ctx.Config{Name: "route", Value: map[string]interface{}{
- "index": "/render",
- "template_dir": "usr/template",
- "template_debug": false,
- "componet_index": "index",
- "toolkit_view": map[string]interface{}{
- "top": 96, "left": 472, "width": 600, "height": 300,
- },
- }, Help: "功能配置"},
- "login": &ctx.Config{Name: "login", Value: map[string]interface{}{
- "expire": "240h",
- "local": true,
- "check": true,
- "sess_void": false,
- "cas_uuid": "email",
- }, Help: "认证配置"},
- "componet": &ctx.Config{Name: "componet", Value: map[string]interface{}{
- "login": []interface{}{},
- "index": []interface{}{
- map[string]interface{}{"name": "head", "template": "head"},
- map[string]interface{}{"name": "clipbaord", "template": "clipboard"},
- map[string]interface{}{"name": "tail", "template": "tail"},
- },
- }, Help: "组件列表"},
- "upload": &ctx.Config{Name: "upload", Value: map[string]interface{}{
- "path": "var/file",
- }, Help: "上件文件"},
- "toolkit": &ctx.Config{Name: "toolkit", Value: map[string]interface{}{
- "time": map[string]interface{}{"cmd": "time"},
- }, Help: "工具列表"},
- "wss": &ctx.Config{Name: "wss", Value: map[string]interface{}{}, Help: ""},
- },
- Commands: map[string]*ctx.Command{
- "_init": &ctx.Command{Name: "_init", Help: "post请求", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- m.Cmd("web.spide", "cas", "client", "new", m.Conf("runtime", "boot.ctx_cas"))
- m.Cmd("web.spide", "dev", "client", "new", kit.Select(m.Conf("runtime", "boot.ctx_dev"), m.Conf("runtime", "boot.ctx_box")))
- return
- }},
- "spide": &ctx.Command{Name: "spide [which [client|header|cookie [name|new [value]]]]", Help: "爬虫配置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- switch len(arg) {
- case 0:
- m.Confm("spide", func(key string, value map[string]interface{}) {
- m.Push("key", key)
- m.Push("protocol", kit.Chains(value, "client.protocol"))
- m.Push("hostname", kit.Chains(value, "client.hostname"))
- m.Push("path", kit.Chains(value, "client.path"))
- })
- m.Sort("key").Table()
- case 1:
- m.Cmdy("ctx.config", "spide", arg[0])
- case 2:
- m.Cmdy("ctx.config", "spide", strings.Join(arg[:2], "."))
- default:
- switch arg[1] {
- case "client":
- if len(arg) == 3 {
- m.Cmdy("ctx.config", "spide", strings.Join(arg[:3], "."))
- break
- }
-
- if arg[2] == "new" {
- if uri, e := url.Parse(arg[3]); e == nil && arg[3] != "" {
- dir, file := path.Split(uri.EscapedPath())
- m.Confv("spide", arg[0], map[string]interface{}{
- "cookie": map[string]interface{}{},
- "header": map[string]interface{}{},
- "client": map[string]interface{}{
- "logheaders": false,
- "timeout": "100s",
- "method": "GET",
- "protocol": uri.Scheme,
- "hostname": uri.Host,
- "path": dir,
- "file": file,
- "query": uri.RawQuery,
- "url": arg[3],
- },
- })
- }
- break
- }
-
- m.Cmd("ctx.config", "spide", strings.Join(arg[:3], "."), arg[3])
- case "merge":
- m.Echo(Merge(m, m.Confm("spide", []string{arg[0], "client"}), arg[2], arg[3:]...))
-
- case "cookie", "header":
- if len(arg) > 3 {
- m.Cmd("ctx.config", "spide", strings.Join(arg[:3], "."), arg[3])
- }
- m.Cmdy("ctx.config", "spide", strings.Join(arg[:3], "."))
-
- default:
- m.Cmd("ctx.config", "spide", strings.Join(arg[:2], "."), arg[2])
- }
- }
- return
- }},
- "post": &ctx.Command{Name: "post args...", Help: "post请求", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- m.Cmdy("web.get", "method", "POST", arg)
- return
- }},
- "get": &ctx.Command{Name: "get [which] name [method GET|POST] url arg...", Help: "访问服务, method: 请求方法, url: 请求地址, arg: 请求参数",
- Form: map[string]int{
- "which": 1, "method": 1, "args": 1, "headers": 2,
- "content_type": 1, "content_data": 1, "body": 1, "file": 2,
- "parse": 1, "temp": -1, "temp_expire": 1, "save": 1, "saves": 1,
- }, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- // 查看配置
- if len(arg) == 0 {
- m.Cmdy("web.spide")
- return
- }
- if len(arg) == 1 {
- m.Cmdy("web.spide", arg[0])
- return
- }
-
- web, ok := m.Target().Server.(*WEB)
- m.Assert(ok)
-
- // 查找配置
- which, client := m.Option("which"), m.Confm("spide", []string{m.Option("which"), "client"})
- if c := m.Confm("spide", []string{arg[0], "client"}); c != nil {
- which, client, arg = arg[0], c, arg[1:]
- }
-
- method := kit.Select(kit.Format(client["method"]), m.Option("method"))
- uri := Merge(m, client, arg[0], arg[1:]...)
- uri_arg := ""
-
- body, ok := m.Optionv("body").(io.Reader)
- if method == "POST" && !ok {
- uuu, e := url.Parse(uri)
- m.Assert(e)
-
- if m.Has("content_data") { // POST file
- body = bytes.NewReader([]byte(m.Option("content_data")))
-
- } else if m.Has("file") { // POST file
- writer := multipart.NewWriter(&bytes.Buffer{})
- defer writer.Close()
-
- for k, v := range uuu.Query() {
- for _, v := range v {
- writer.WriteField(k, v)
- }
- }
-
- if file, e := os.Open(m.Cmdx("nfs.path", m.Meta["file"][1])); m.Assert(e) {
- defer file.Close()
-
- if part, e := writer.CreateFormFile(m.Option("file"), filepath.Base(m.Meta["file"][1])); m.Assert(e) {
- io.Copy(part, file)
- m.Option("content_type", writer.FormDataContentType())
- }
- }
-
- } else if index := strings.Index(uri, "?"); index > 0 {
- switch m.Option("content_type") {
- case "application/json": // POST json
- var data interface{}
- for k, v := range uuu.Query() {
- if len(v) == 1 {
- if i, e := strconv.Atoi(v[0]); e == nil {
- data = kit.Chain(data, k, i)
- } else {
- data = kit.Chain(data, k, v[0])
- }
- } else {
- for i, val := range v {
- if i, e := strconv.Atoi(v[i]); e == nil {
- data = kit.Chain(data, []string{k, "-2"}, i)
- } else {
- data = kit.Chain(data, []string{k, "-2"}, val)
- }
- }
- }
- }
-
- if b, e := json.Marshal(data); m.Assert(e) {
- m.Log("info", "json %v", string(b))
-
- if body = bytes.NewReader(b); m.Has("args") {
- uri = uri[:index] + "?" + m.Option("args")
- index = len(uri)
- }
- }
-
- default: // POST form
- m.Log("info", "body %v", string(uri[index+1:]))
- body = strings.NewReader(uri[index+1:])
- m.Option("content_type", "application/x-www-form-urlencoded")
- m.Option("content_length", len(uri[index+1:]))
- }
- uri, uri_arg = uri[:index], "?"+uuu.RawQuery
- }
- }
-
- // 查找缓存
- if m.Options("temp_expire") {
- if h := m.Cmdx("mdb.temp", "check", "url", uri+uri_arg); h != "" {
- m.Cmdy("mdb.temp", h, "data", "data", m.Meta["temp"])
- return
- }
- }
-
- // 构造请求
- req, e := http.NewRequest(method, uri, body)
- m.Assert(e)
- m.Log("info", "%s %s", req.Method, req.URL)
-
- m.Confm("spide", []string{which, "header"}, func(key string, value string) {
- if key != "" {
- req.Header.Set(key, value)
- m.Log("info", "header %v %v", key, value)
- }
- })
- for i := 0; i < len(m.Meta["headers"]); i += 2 {
- req.Header.Set(m.Meta["headers"][i], m.Meta["headers"][i+1])
- }
- if m.Options("content_type") {
- req.Header.Set("Content-Type", m.Option("content_type"))
- }
- if m.Options("content_length") {
- req.Header.Set("Content-Length", m.Option("content_length"))
- }
- // 请求头
- if kit.Right(client["logheaders"]) {
- for k, v := range req.Header {
- m.Log("info", "%s: %s", k, v)
- }
- m.Log("info", "")
- }
-
- // 请求cookie
- kit.Structm(m.Magic("user", []string{"cookie", which}), func(key string, value string) {
- req.AddCookie(&http.Cookie{Name: key, Value: value})
- m.Log("info", "set-cookie %s: %v", key, value)
- })
-
- // 发送请求
- if web.Client == nil {
- web.Client = &http.Client{Timeout: kit.Duration(kit.Format(client["timeout"]))}
- }
- res, e := web.Client.Do(req)
- if e != nil {
- m.Log("warn", "%v", e)
- m.Echo("%v", e)
- return e
- }
-
- // 响应结果
- if res.StatusCode != http.StatusOK {
- m.Log("warn", "%d: %s\n", res.StatusCode, res.Status)
- m.Echo("%d: %s\n", res.StatusCode, res.Status)
- }
-
- // 保存cookie
- for _, v := range res.Cookies() {
- if m.Log("info", "get-cookie %s: %v", v.Name, v.Value); v.Value != "" {
- m.Magic("user", []string{"cookie", which, v.Name}, v.Value)
- }
- }
-
- // 响应头
- if kit.Right(client["logheaders"]) {
- for k, v := range res.Header {
- m.Log("info", "%s: %v", k, v)
- }
- }
-
- // 保存响应
- if res.StatusCode == http.StatusOK && m.Options("save") {
- if f, p, e := kit.Create(m.Option("save")); m.Assert(e) {
- defer f.Close()
-
- if n, e := io.Copy(f, res.Body); m.Assert(e) {
- m.Log("info", "save %d %s", n, p)
- m.Echo(p)
- }
- }
- return
- }
-
- // 解析响应
- var result interface{}
- ct := res.Header.Get("Content-Type")
- parse := kit.Select(kit.Format(client["parse"]), m.Option("parse"))
- m.Log("info", "parse: %s content: %s", parse, ct)
-
- switch {
- case parse == "json" || strings.HasPrefix(ct, "application/json") || strings.HasPrefix(ct, "application/javascript"):
- // 解析数据
- if json.NewDecoder(res.Body).Decode(&result); m.Options("temp_expire") {
- if m.Log("info", "res: %v", kit.Format(result)); !m.Has("temp") {
- m.Option("temp", "")
- }
- // m.Put("option", "data", result).Cmdy("mdb.temp", "url", uri+uri_arg, "data", "data", m.Meta["temp"])
- m.Put("option", "data", result).Cmdy("mdb.temp", "url", uri+uri_arg, "data", "data", m.Meta["temp"])
- break
- } else if result != nil {
- if b, e := json.MarshalIndent(result, "", " "); m.Assert(e) {
- m.Echo(string(b))
- }
- break
- }
- fallthrough
- default:
- // 输出数据
- if buf, e := ioutil.ReadAll(res.Body); m.Assert(e) {
- m.Echo(string(buf))
- }
- }
- if m.Options("saves") {
- f, p, e := kit.Create(m.Option("saves"))
- m.Assert(e)
- defer f.Close()
- for _, v := range m.Meta["result"] {
- f.WriteString(v)
- }
- m.Set("result").Echo(p)
- }
- return
- }},
-
- "serve": &ctx.Command{Name: "serve [directory [address [protocol [cert [key]]]]", Help: "启动服务, directory: 服务路径, address: 服务地址, protocol: 服务协议(https/http), cert: 服务证书, key: 服务密钥", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- m.Set("detail", arg).Target().Start(m)
- return
- }},
- "route": &ctx.Command{Name: "route index content [help]", Help: "添加路由响应, index: 路由, context: 响应, help: 说明", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if mux, ok := m.Target().Server.(MUX); m.Assert(ok) {
- switch len(arg) {
- case 0:
- for k, v := range m.Target().Commands {
- if k[0] == '/' {
- m.Add("append", "route", k)
- m.Add("append", "name", v.Name)
- }
- }
- m.Sort("route").Table()
- case 1:
- for k, v := range m.Target().Commands {
- if k == arg[0] {
- m.Echo("%s: %s\n%s", k, v.Name, v.Help)
- }
- }
- default:
- help := kit.Select("dynamic route", arg, 2)
- hand := func(m *ctx.Message, c *ctx.Context, key string, a ...string) (e error) {
- w := m.Optionv("response").(http.ResponseWriter)
- template.Must(template.New("temp").Parse(arg[1])).Execute(w, m)
- return
- }
-
- if s, e := os.Stat(arg[1]); e == nil {
- if s.IsDir() {
- mux.Handle(arg[0]+"/", http.StripPrefix(arg[0], http.FileServer(http.Dir(arg[1]))))
- } else if strings.HasSuffix(arg[1], ".shy") {
- hand = func(m *ctx.Message, c *ctx.Context, key string, a ...string) (e error) {
- m.Cmdy("cli.source", arg[1])
- return
- }
- } else {
- hand = func(m *ctx.Message, c *ctx.Context, key string, a ...string) (e error) {
- w := m.Optionv("response").(http.ResponseWriter)
- template.Must(template.ParseGlob(arg[1])).Execute(w, m)
- return
- }
- }
- }
-
- if _, ok := m.Target().Commands[arg[0]]; ok {
- m.Target().Commands[arg[0]].Help = help
- m.Target().Commands[arg[0]].Name = arg[1]
- m.Target().Commands[arg[0]].Hand = hand
- } else {
- cmd := &ctx.Command{Name: arg[1], Help: help, Hand: hand}
- m.Target().Commands[arg[0]] = cmd
- mux.HandleCmd(m, arg[0], cmd)
- }
- }
- }
- return
- }},
- "template": &ctx.Command{Name: "template [name [file...]]", Help: "模板管理, name: 模板名, file: 模板文件", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if web, ok := m.Target().Server.(*WEB); m.Assert(ok) {
- if len(arg) == 0 {
- for _, v := range web.Template.Templates() {
- m.Add("append", "name", v.Name())
- }
- m.Sort("name").Table()
- return
- }
-
- tmpl := web.Template
- if len(arg) > 1 {
- tmpl = template.Must(web.Template.Clone())
- tmpl = template.Must(tmpl.ParseFiles(arg[1:]...))
- }
-
- buf := bytes.NewBuffer(make([]byte, 1024))
- tmpl.ExecuteTemplate(buf, arg[0], m)
- m.Echo(string(buf.Bytes()))
- }
- return
- }},
- "componet": &ctx.Command{Name: "componet [group [order [arg...]]]", Help: "添加组件, group: 组件分组, arg...: 组件参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if len(arg) > 0 && arg[0] == "share" {
- m.Cmd("aaa.role", arg[1], "componet", arg[2], "command", arg[3:])
- m.Echo("%s%s?componet_group=%s&relay=%s", m.Conf("serve", "site"), m.Option("index_path"), arg[2], m.Cmdx("aaa.relay", "share", arg[1], "temp"))
- return
- }
-
- switch len(arg) {
- case 0:
- m.Cmdy("ctx.config", "componet")
- case 1:
- m.Confm("componet", arg[0], func(index int, val map[string]interface{}) {
- m.Add("append", "ctx", val["componet_ctx"])
- m.Add("append", "cmd", val["componet_cmd"])
- m.Add("append", "name", val["componet_name"])
- m.Add("append", "help", val["componet_help"])
- m.Add("append", "tmpl", val["componet_tmpl"])
- m.Add("append", "view", val["componet_view"])
- m.Add("append", "init", val["componet_init"])
- })
- m.Table()
- case 2:
- m.Cmdy("ctx.config", "componet", strings.Join(arg, "."))
- default:
- switch arg[0] {
- case "create":
- m.Confm("componet", arg[1:3], map[string]interface{}{
- "name": arg[3], "help": arg[4],
- "componet_ctx": arg[5], "componet_cmd": arg[6],
- })
- default:
- componet := m.Confm("componet", arg[:2])
- for i := 2; i < len(arg)-1; i += 2 {
- kit.Chain(componet, arg[i], arg[i+1])
- }
- }
- }
- return
- }},
-
- "/render": &ctx.Command{Name: "/render template", Help: "渲染模板, template: 模板名称", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- // 权限检查
- if m.Confs("login", "check") {
- if !m.Options("sessid") || !m.Options("username") || !m.Cmds("aaa.role", m.Option("userrole"), "check", m.Confx("group")) {
- m.Set("option", "group", "login").Set("option", "name", "")
- }
- }
-
- // 响应类型
- accept_json := strings.HasPrefix(m.Option("accept"), "application/json")
- w := m.Optionv("response").(http.ResponseWriter)
- if !accept_json {
- w.Header().Set("Content-Type", "text/html")
- } else {
- w.Header().Set("Content-Type", "application/json")
- }
- // w.Header().Set("Access-Control-Allow-Origin", "api.map.baidu.com")
-
- web, ok := m.Target().Server.(*WEB)
- m.Assert(ok)
-
- // 响应模板
- tmpl := web.Template
- if m.Confs("route", "template_debug") {
- tmpl = template.New("render").Funcs(ctx.CGI)
- tmpl.ParseGlob(path.Join(m.Conf("route", "template_dir"), "/*.tmpl"))
- tmpl.ParseGlob(path.Join(m.Conf("route", "template_dir"), m.Cap("route"), "/*.tmpl"))
- }
-
- m.Option("title", m.Conf("runtime", "boot.hostname"))
- // 响应数据
- group, order := m.Option("group", kit.Select(m.Conf("route", "componet_index"), m.Option("group"))), m.Option("names")
- list := []interface{}{}
-
- for _, v := range m.Confv("componet", group).([]interface{}) {
- val := v.(map[string]interface{})
- if order != "" && val["name"].(string) != order {
- continue
- }
-
- // 查找模块
- msg := m.Find(kit.Select(m.Cap("module"), val["ctx"]))
-
- // 默认变量
- for k, v := range val {
- switch value := v.(type) {
- case []string:
- msg.Set("option", k, value)
- case string:
- msg.Set("option", k, value)
- default:
- msg.Put("option", k, value)
- }
- }
-
- // 添加命令
- if kit.Right(val["cmd"]) {
- arg = append(arg, kit.Format(val["cmd"]))
- }
- // 添加参数
- if m.Has("cmds") {
- arg = append(arg, kit.Trans(m.Optionv("cmds"))...)
- } else {
- kit.Map(val["args"], "", func(index int, value map[string]interface{}) {
- if value["name"] != nil {
- arg = append(arg, kit.Select(msg.Option(value["name"].(string)), msg.Parse(value["value"])))
- }
- })
- }
-
- if len(arg) > 0 {
- if order != "" || kit.Right(val["pre_run"]) {
- // 权限检查
- if m.Confs("login", "check") && m.Cmds("aaa.role", m.Option("userrole"), "check", m.Option("componet_group"), arg[0]) {
- continue
- }
- // 执行命令
- msg.Cmd(arg)
- }
- }
-
- // 添加响应
- if msg.Appends("qrcode") {
- m.Append("qrcode", msg.Append("qrcode"))
- } else if msg.Appends("directory") {
- m.Append("download_file", fmt.Sprintf("/download/%s", msg.Append("directory")))
- return
- } else if accept_json {
- list = append(list, msg.Meta)
- } else if val["tmpl"] != nil {
- m.Assert(tmpl.ExecuteTemplate(w, val["tmpl"].(string), msg))
- }
- }
-
- // 生成响应
- if accept_json {
- en := json.NewEncoder(w)
- en.SetIndent("", " ")
- en.Encode(list)
- }
- return
- }},
- "/upload": &ctx.Command{Name: "/upload key", Help: "上传文件", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- r := m.Optionv("request").(*http.Request)
- if f, h, e := r.FormFile(kit.Select("upload", arg, 0)); m.Assert(e) {
- defer f.Close()
-
- // 上传文件
- name := kit.Hashx(f)
- if o, p, e := kit.Create(path.Join(m.Conf("web.upload", "path"), "list", name)); m.Assert(e) {
- defer o.Close()
-
- f.Seek(0, os.SEEK_SET)
- if n, e := io.Copy(o, f); m.Assert(e) {
- m.Log("upload", "list: %s %d", p, n)
-
- // 文件摘要
- kind := strings.Split(h.Header.Get("Content-Type"), "/")[0]
- buf := bytes.NewBuffer(make([]byte, 0, 1024))
- fmt.Fprintf(buf, "create_time: %s\n", m.Time("2006-01-02 15:04"))
- fmt.Fprintf(buf, "create_user: %s\n", m.Option("username"))
- fmt.Fprintf(buf, "name: %s\n", h.Filename)
- fmt.Fprintf(buf, "type: %s\n", kind)
- fmt.Fprintf(buf, "hash: %s\n", name)
- fmt.Fprintf(buf, "size: %d\n", n)
- b := buf.Bytes()
-
- // 保存摘要
- code := kit.Hashs(string(b))
- if o, p, e := kit.Create(path.Join(m.Conf("web.upload", "path"), "meta", code)); m.Assert(e) {
- defer o.Close()
-
- if n, e := o.Write(b); m.Assert(e) {
- m.Log("upload", "meta: %s %d", p, n)
- m.Cmd("nfs.copy", path.Join(m.Conf("web.upload", "path"), kind, code), p)
- }
- }
-
- // 文件索引
- if m.Options("river") {
- prefix := []string{"ssh._route", m.Option("dream"), "ssh.data", "insert"}
- suffix := []string{"code", code, "kind", kind, "name", h.Filename, "hash", name, "size", kit.Format(n), "upload_time", m.Time("2006-01-02 15:04")}
- m.Cmd(prefix, kit.Select(kind, m.Option("table")), suffix)
- m.Cmd(prefix, "file", suffix)
- }
-
- // 返回信息
- if !strings.HasPrefix(m.Option("agent"), "curl") {
- m.Append("size", kit.FmtSize(n))
- m.Append("link", fmt.Sprintf(`%s`, code, h.Filename))
- m.Append("type", kind)
- m.Append("hash", name)
- } else {
- m.Append("code", code)
- m.Append("type", kind)
- m.Append("name", h.Filename)
- m.Append("size", kit.FmtSize(n))
- m.Append("time", m.Time("2006-01-02 15:04"))
- m.Append("hash", name)
- }
- }
- }
- }
- return
- }},
- "/download/": &ctx.Command{Name: "/download/hash [meta [hash]]", Help: "下载文件", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- r := m.Optionv("request").(*http.Request)
- w := m.Optionv("response").(http.ResponseWriter)
-
- kind := kit.Select("meta", kit.Select(m.Option("meta"), arg, 0))
- file := kit.Select(strings.TrimPrefix(key, "/download/"), arg, 1)
- if file == "" {
- if m.Option("userrole") != "root" {
- return
- }
- // 文件列表
- m.Cmd("nfs.dir", path.Join(m.Conf("web.upload", "path"), kind)).Table(func(index int, value map[string]string) {
- name := path.Base(value["path"])
- meta := kit.Linex(value["path"])
- m.Push("time", meta["create_time"])
- m.Push("user", meta["create_user"])
- m.Push("size", kit.FmtSize(int64(kit.Int(meta["size"]))))
- if kind == "image" {
- m.Push("name", name)
- } else {
- m.Push("name", fmt.Sprintf(`%s`, name, meta["name"]))
- }
- m.Push("hash", meta["hash"][:8])
-
- })
- m.Sort("time", "time_r").Table()
- return
- }
-
- if p := m.Cmdx("nfs.path", path.Join(m.Conf("web.upload", "path"), "list", file)); p != "" {
- // 直接下载
- m.Log("info", "download %s direct", p)
- http.ServeFile(w, r, p)
- return
- }
- if p := m.Cmdx("nfs.path", path.Join(m.Conf("web.upload", "path"), kind, file)); p != "" {
- // 下载文件
- meta := kit.Linex(p)
- if p := m.Cmdx("nfs.path", path.Join(m.Conf("web.upload", "path"), "list", meta["hash"])); p != "" {
- m.Log("info", "download %s %s", p, m.Cmdx("nfs.hash", meta["hash"]))
- w.Header().Set("Content-Disposition", fmt.Sprintf("filename=%s", meta["name"]))
- http.ServeFile(w, r, p)
- } else {
- http.NotFound(w, r)
- }
- return
- }
-
- if m.Option("userrole") != "root" {
- return
- }
-
- if p := m.Cmdx("nfs.path", file); p != "" {
- // 任意文件
- m.Log("info", "download %s %s", p, m.Cmdx("nfs.hash", p))
- http.ServeFile(w, r, p)
- }
- return
- }},
- "/require/": &ctx.Command{Name: "/require/", Help: "加载脚本", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- r := m.Optionv("request").(*http.Request)
- w := m.Optionv("response").(http.ResponseWriter)
- file := strings.TrimPrefix(key, "/require/")
-
- if p := m.Cmdx("nfs.path", m.Conf("cli.project", "plugin.path"), file); p != "" {
- m.Log("info", "download %s direct", p)
- http.ServeFile(w, r, p)
- return
- }
- return
- }},
- "/proxy/": &ctx.Command{Name: "/proxy/which/method/url", Help: "服务代理", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- fields := strings.Split(key, "/")
- m.Cmdy("web.get", "which", fields[2], "method", fields[3], strings.Join(fields, "/"))
- return
- }},
- "/login": &ctx.Command{Name: "/login", Help: "认证", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- switch {
- case m.Options("cert"): // 注册证书
- msg := m.Cmd("aaa.rsa", "info", m.Option("cert"))
- m.Cmd("aaa.auth", "nodes", msg.Append("route"), "cert", m.Option("cert"))
- m.Append("sess", m.Cmdx("aaa.sess", "nodes", "nodes", msg.Append("route")))
-
- case m.Options("pull"): // 下载证书
- sess := m.Cmd("aaa.auth", "nodes", m.Option("pull"), "session").Append("key")
- m.Add("append", "username", m.Cmd("aaa.auth", sess, "username").Append("meta"))
- m.Add("append", "cert", (m.Cmd("aaa.auth", "nodes", m.Option("pull"), "cert").Append("meta")))
-
- case m.Options("bind"): // 绑定设备
- sess := m.Cmd("aaa.auth", "nodes", m.Option("bind"), "session").Append("key")
- if m.Cmd("aaa.auth", sess, "username").Appends("meta") {
- return // 已经绑定
- }
-
- if m.Cmds("aaa.rsa", "verify", m.Cmd("aaa.auth", "username", m.Option("username"), "cert").Append("meta"), m.Option("code"), m.Option("bind")) {
- m.Cmd("aaa.login", sess, "username", m.Option("username"))
- m.Append("userrole", "root")
- }
- case m.Options("user.cert"): // 用户注册
- if !m.Cmds("aaa.auth", "username", m.Option("username"), "cert") {
- m.Cmd("aaa.auth", "username", m.Option("username"), "cert", m.Option("user.cert"))
- }
- m.Append("username", m.Option("username"))
- }
- return
- }},
-
- "/publish/": &ctx.Command{Name: "/publish/filename [upgrade script|plugin]", Help: "下载项目", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- // 下载程序
- key = strings.TrimPrefix(key, "/publish/")
- if key == "bench" {
- key = m.Conf("runtime", "boot.ctx_app") + "." + kit.Select(m.Conf("runtime", "host.GOOS"), m.Option("GOOS")) +
- "." + kit.Select(m.Conf("runtime", "host.GOARCH"), m.Option("GOARCH"))
- }
-
- p := ""
- if m.Option("upgrade") == "script" {
- // 下载脚本
- if m.Options("missyou") {
- p = m.Cmdx("nfs.path", path.Join(m.Conf("missyou", "path"), m.Option("missyou"), "usr/script", key))
- } else {
- p = m.Cmdx("nfs.path", path.Join("usr/script", key))
- }
- } else if m.Option("upgrade") == "plugin" {
- // 下载插件
- p = m.Cmdx("nfs.path", path.Join(m.Conf("publish", "path"), key, kit.Select("index.shy", m.Option("index"))))
-
- } else {
- // 下载系统
- if p = m.Cmdx("nfs.path", path.Join(m.Conf("publish", "path"), key)); p == "" {
- p = m.Cmdx("nfs.path", m.Conf("publish", []string{"list", kit.Key(key)}))
- }
- }
-
- // 下载文件
- if s, e := os.Stat(p); e == nil && !s.IsDir() {
- m.Log("info", "publish %s %s", kit.Hashs(p), p)
- http.ServeFile(m.Optionv("response").(http.ResponseWriter), m.Optionv("request").(*http.Request), p)
- }
- return
- }},
- "/shadow": &ctx.Command{Name: "/shadow", Help: "暗网", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- m.Confm("runtime", "node.port", func(index int, value string) {
- m.Add("append", "ports", value)
- })
- return
- }},
-
- "/wss": &ctx.Command{Name: "/wss", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- r := m.Optionv("request").(*http.Request)
- w := m.Optionv("response").(http.ResponseWriter)
- agent := r.Header.Get("User-Agent")
-
- if s, e := websocket.Upgrade(w, r, nil, 4096, 4096); m.Assert(e) {
- h := m.Option("wssid")
- if h == "" || m.Confs("wss", h) {
- h = kit.Hashs("uniq")
- }
- p := make(chan *ctx.Message, 10)
- meta := map[string]interface{}{
- "create_time": m.Time(),
- "create_user": m.Option("username"),
- "agent": agent,
- "sessid": m.Option("sessid"),
- "socket": s,
- "channel": p,
- }
- m.Conf("wss", []string{m.Option("username"), h}, meta)
- m.Conf("wss", h, meta)
- p <- m.Spawn().Add("detail", "wssid", h)
-
- what := m
- m.Log("wss", "conn %v %s", h, agent)
- m.Gos(m.Spawn(), func(msg *ctx.Message) {
- for {
- if t, b, e := s.ReadMessage(); e == nil {
- var data interface{}
- if e := json.Unmarshal(b, &data); e == nil {
- m.Log("wss", "recv %s %d msg %v", h, t, data)
- } else {
- m.Log("wss", "recv %s %d msg %v", h, t, b)
- data = b
- }
-
- what.Optionv("data", data)
- what.Back(what)
- } else {
- m.Log("warn", "wss recv %s %d msg %v", h, t, e)
- close(p)
- break
- }
- }
- })
-
- for what = range p {
- s.WriteJSON(what.Meta)
- }
-
- m.Log("wss", "close %s %s", h, agent)
- m.Conf("wss", []string{m.Option("username"), h}, "")
- m.Conf("wss", h, "")
- s.Close()
- }
- return
- }},
- "wss": &ctx.Command{Name: "wss", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if len(arg) == 0 || arg[0] == "" {
- m.Confm("wss", func(key string, value map[string]interface{}) {
- if value["agent"] == nil {
- return
- }
- m.Push("key", m.Cmdx("aaa.short", key))
- m.Push("create_time", value["create_time"])
- m.Push("create_user", value["create_user"])
- m.Push("sessid", kit.Format(value["sessid"])[:6])
- m.Push("agent", value["agent"])
- })
- m.Table()
- return
- }
-
- list := []string{}
- if strings.Contains(arg[0], ".") {
- vs := strings.SplitN(arg[0], ".", 2)
- m.Confm("wss", vs[0], func(key string, value map[string]interface{}) {
- if len(vs) == 1 || vs[1] == "*" || strings.Contains(kit.Format(value["agent"]), vs[1]) {
- list = append(list, key)
- }
- })
- } else {
- if len(arg[0]) != 32 {
- arg[0] = m.Cmdx("aaa.short", arg[0])
- }
- list = append(list, arg[0])
- }
-
- if len(arg) == 1 {
- m.Cmdy(".config", "wss", arg[0])
- return
- }
-
- for _, v := range list {
- if p, ok := m.Confv("wss", []string{v, "channel"}).(chan *ctx.Message); ok {
- if msg := m.Spawn(); arg[1] == "sync" {
- p <- msg.Add("detail", arg[2], arg[3:])
- msg.CallBack(true, func(msg *ctx.Message) *ctx.Message {
- if data, ok := msg.Optionv("data").(map[string]interface{}); ok {
- if len(list) == 1 && data["append"] != nil {
- for _, k := range kit.Trans(data["append"]) {
- m.Push(k, kit.Trans(data[k]))
- }
- } else {
- m.Push("time", m.Time())
- m.Push("key", m.Cmdx("aaa.short", v))
- m.Push("action", kit.Format(arg[2:]))
-
- res := kit.Trans(data["result"])
- m.Push("return", kit.Format(res))
- m.Log("wss", "result: %v", res)
- }
-
- } else {
- m.Push("time", m.Time())
- m.Push("key", m.Cmdx("aaa.short", v))
- m.Push("action", kit.Format(arg[2:]))
- }
- return m
- }, "skip")
- m.Table()
- } else {
- p <- msg.Add("detail", arg[1], arg[2:])
- }
- }
- }
- return
- }},
- },
-}
-
-func init() {
- ctx.Index.Register(Index, &WEB{Context: Index})
-}
diff --git a/usr/local/honor/src/contexts/yac/yac.go b/usr/local/honor/src/contexts/yac/yac.go
deleted file mode 100644
index b8706873..00000000
--- a/usr/local/honor/src/contexts/yac/yac.go
+++ /dev/null
@@ -1,1244 +0,0 @@
-package yac
-
-import (
- "contexts/ctx"
- "sort"
- kit "toolkit"
-
- "fmt"
- "os"
- "regexp"
- "strconv"
- "strings"
-)
-
-type Seed struct {
- page int
- hash int
- word []string
-}
-type Point struct {
- s int
- c byte
-}
-type State struct {
- star int
- next int
- hash int
-}
-type YAC struct {
- seed []*Seed
- page map[string]int
- word map[int]string
- hand map[int]string
- hash map[string]int
-
- state map[State]*State
- mat []map[byte]*State
-
- lex *ctx.Message
-
- label map[string]string
- *ctx.Context
-}
-type Parser interface {
- Parse(m *ctx.Message, line []byte, page string) (hash int, rest []byte, word []byte)
-}
-
-func (yac *YAC) name(page int) string {
- if name, ok := yac.word[page]; ok {
- return name
- }
- return fmt.Sprintf("yac%d", page)
-}
-func (yac *YAC) index(m *ctx.Message, hash string, h string) int {
- which, names := yac.page, yac.word
- if hash == "nhash" {
- which, names = yac.hash, yac.hand
- }
-
- if x, ok := which[h]; ok {
- return x
- }
-
- which[h] = m.Capi(hash, 1)
- names[which[h]] = h
- m.Assert(hash != "npage" || m.Capi("npage") < m.Confi("meta", "nlang"), "语法集合超过上限")
- return which[h]
-}
-func (yac *YAC) train(m *ctx.Message, page, hash int, word []string, level int) (int, []*Point, []*Point) {
- m.Log("debug", "%s %s\\%d page: %v hash: %v word: %v", "train", strings.Repeat("#", level), level, page, hash, word)
-
- ss := []int{page}
- sn := make([]bool, m.Capi("nline"))
- points, ends := []*Point{}, []*Point{}
-
- for i, n, mul := 0, 1, false; i < len(word); i += n {
- if !mul {
- if hash <= 0 && word[i] == "}" {
- return i + 2, points, ends
- }
- ends = ends[:0]
- }
-
- for _, s := range ss {
- switch word[i] {
- case "opt{", "rep{":
- sn[s] = true
- num, point, end := yac.train(m, s, 0, word[i+1:], level+1)
- n, points = num, append(points, point...)
-
- for _, x := range end {
- state := &State{}
- *state = *yac.mat[x.s][x.c]
- for i := len(sn); i <= state.next; i++ {
- sn = append(sn, false)
- }
- sn[state.next] = true
-
- points = append(points, x)
- if word[i] == "rep{" {
- state.star = s
- yac.mat[x.s][x.c] = state
- m.Log("debug", "REP(%d, %d): %v", x.s, x.c, state)
- }
- }
- case "mul{":
- mul, n = true, 1
- goto next
- case "}":
- if mul {
- mul = false
- goto next
- }
- fallthrough
- default:
- x, ok := yac.page[word[i]]
- if !ok {
- if x = kit.Int(yac.lex.Spawn().Cmdx("parse", word[i], yac.name(s))); x == 0 {
- x = kit.Int(yac.lex.Spawn().Cmdx("train", word[i], len(yac.mat[s]), yac.name(s)))
- }
- }
-
- c := byte(x)
- state := &State{}
- if yac.mat[s][c] != nil {
- *state = *yac.mat[s][c]
- } else {
- m.Capi("nnode", 1)
- }
- if state.next == 0 {
- state.next = m.Capi("nline", 1) - 1
- yac.mat = append(yac.mat, map[byte]*State{})
- for i := 0; i < m.Capi("nline"); i++ {
- yac.mat[state.next][byte(i)] = nil
- }
- sn = append(sn, false)
- }
- sn[state.next] = true
- yac.mat[s][c] = state
- ends = append(ends, &Point{s, c})
- points = append(points, &Point{s, c})
- }
- }
- next:
- if !mul {
- ss = ss[:0]
- for s, b := range sn {
- if sn[s] = false; b {
- ss = append(ss, s)
- }
- }
- }
- }
- for _, s := range ss {
- if s < m.Confi("meta", "nlang") || s >= len(yac.mat) {
- continue
- }
- void := true
- for _, x := range yac.mat[s] {
- if x != nil {
- void = false
- break
- }
- }
- if void {
- last := m.Capi("nline") - 1
- m.Cap("nline", "0")
- m.Log("debug", "DEL: %d-%d", last, m.Capi("nline", s))
- yac.mat = yac.mat[:s]
- }
- }
- for _, s := range ss {
- for _, p := range points {
- state := &State{}
- *state = *yac.mat[p.s][p.c]
- if state.next == s {
- m.Log("debug", "GET(%d, %d): %v", p.s, p.c, state)
- if state.next >= len(yac.mat) {
- state.next = 0
- }
- if hash > 0 {
- state.hash = hash
- }
- yac.mat[p.s][p.c] = state
- m.Log("debug", "SET(%d, %d): %v", p.s, p.c, state)
- }
- if x, ok := yac.state[*state]; !ok {
- yac.state[*state] = yac.mat[p.s][p.c]
- m.Capi("nreal", 1)
- } else {
- yac.mat[p.s][p.c] = x
- }
- }
- }
-
- m.Log("debug", "%s %s/%d word: %d point: %d end: %d", "train", strings.Repeat("#", level), level, len(word), len(points), len(ends))
- return len(word), points, ends
-}
-func (yac *YAC) parse(m *ctx.Message, msg *ctx.Message, stack *kit.Stack, page int, void int, line []byte, level int) (rest []byte, word []string, hash int) {
- m.Log("debug", "%s %s\\%d %s(%d): %s", "parse", strings.Repeat("#", level), level, yac.name(page), page, string(line))
-
- h, r, w := 0, []byte{}, []byte{}
- p, _ := yac.lex.Target().Server.(Parser)
-
- for star, s := 0, page; s != 0 && len(line) > 0; {
- //解析空白
- if h, r, _ = p.Parse(m, line, yac.name(void)); h == -1 {
- break
- }
- //解析单词
- if h, r, w = p.Parse(m, r, yac.name(s)); h == -1 {
- break
- }
-
- //解析状态
- state := yac.mat[s][byte(h)]
-
- //全局语法检查
- if state != nil {
- if hh, _, ww := p.Parse(m, line, "key"); hh == 0 || len(ww) <= len(w) {
- line, word = r, append(word, string(w))
- } else {
- state = nil
- }
- }
- //嵌套语法递归解析
- if state == nil {
- for i := 0; i < m.Confi("meta", "ncell"); i++ {
- if x := yac.mat[s][byte(i)]; i < m.Confi("meta", "nlang") && x != nil {
- if l, w, _ := yac.parse(m, msg, stack, i, void, line, level+1); len(l) != len(line) {
- line, word, state = l, append(word, w...), x
- break
- }
- }
- }
- }
-
- //语法切换
- if state == nil {
- s, star = star, 0
- } else if s, star, hash = state.next, state.star, state.hash; s == 0 {
- s, star = star, 0
- }
- }
-
- if hash == 0 {
- word = word[:0]
-
- } else if !m.Confs("exec", []string{"disable", yac.hand[hash]}) {
- if stack == nil || stack.Peek().Run || m.Confs("exec", []string{"always", yac.hand[hash]}) {
- //执行命令
- cmd := msg.Spawn(m.Optionv("bio.ctx"))
- if cmd.Cmd(yac.hand[hash], word); cmd.Hand {
- word = cmd.Meta["result"]
- }
- //切换模块
- if v := cmd.Optionv("bio.ctx"); v != nil {
- m.Optionv("bio.ctx", v)
- }
- }
- }
-
- m.Log("debug", "%s %s/%d %s(%d): %v", "parse", strings.Repeat("#", level), level, yac.hand[hash], hash, word)
- return line, word, hash
-}
-
-func (yac *YAC) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server {
- return &YAC{Context: c}
-}
-func (yac *YAC) Begin(m *ctx.Message, arg ...string) ctx.Server {
- yac.Caches["nseed"] = &ctx.Cache{Name: "种子数量", Value: "0", Help: "语法模板的数量"}
- yac.Caches["npage"] = &ctx.Cache{Name: "集合数量", Value: "0", Help: "语法集合的数量"}
- yac.Caches["nhash"] = &ctx.Cache{Name: "类型数量", Value: "0", Help: "语句类型的数量"}
-
- yac.Caches["nline"] = &ctx.Cache{Name: "状态数量", Value: m.Conf("meta", "nlang"), Help: "状态机状态的数量"}
- yac.Caches["nnode"] = &ctx.Cache{Name: "节点数量", Value: "0", Help: "状态机连接的逻辑数量"}
- yac.Caches["nreal"] = &ctx.Cache{Name: "实点数量", Value: "0", Help: "状态机连接的存储数量"}
-
- yac.Caches["level"] = &ctx.Cache{Name: "level", Value: "0", Help: "嵌套层级"}
- yac.Caches["parse"] = &ctx.Cache{Name: "parse(true/false)", Value: "true", Help: "命令解析"}
-
- yac.page = map[string]int{"nil": 0}
- yac.word = map[int]string{0: "nil"}
- yac.hash = map[string]int{"nil": 0}
- yac.hand = map[int]string{0: "nil"}
-
- yac.state = map[State]*State{}
- yac.mat = make([]map[byte]*State, m.Capi("nline"))
- return yac
-}
-func (yac *YAC) Start(m *ctx.Message, arg ...string) (close bool) {
- return true
-}
-func (yac *YAC) Close(m *ctx.Message, arg ...string) bool {
- return false
-}
-
-var Index = &ctx.Context{Name: "yac", Help: "语法中心",
- Caches: map[string]*ctx.Cache{
- "nshy": &ctx.Cache{Name: "nshy", Value: "0", Help: "引擎数量"},
- },
- Configs: map[string]*ctx.Config{
- "nline": &ctx.Config{Name: "nline", Value: "line", Help: "默认页"},
- "nvoid": &ctx.Config{Name: "nvoid", Value: "void", Help: "默认值"},
- "meta": &ctx.Config{Name: "meta", Value: map[string]interface{}{
- "ncell": 128, "nlang": 64, "compact": true,
- "name": "shy%d", "help": "engine",
- }, Help: "初始参数"},
- "seed": &ctx.Config{Name: "seed", Value: []interface{}{
- map[string]interface{}{"page": "void", "hash": "void", "word": []interface{}{"[\t ]+"}},
-
- // 数据类型
- map[string]interface{}{"page": "num", "hash": "num", "word": []interface{}{"mul{", "0", "-?[1-9][0-9]*", "0[0-9]+", "0x[0-9]+", "}"}},
- map[string]interface{}{"page": "key", "hash": "key", "word": []interface{}{"[A-Za-z_][A-Za-z_0-9]*"}},
- map[string]interface{}{"page": "str", "hash": "str", "word": []interface{}{"mul{", "\"[^\"]*\"", "'[^']*'", "}"}},
- map[string]interface{}{"page": "exe", "hash": "exe", "word": []interface{}{"mul{", "$", "@", "}", "opt{", "key", "}"}},
- map[string]interface{}{"page": "exe", "hash": "exe", "word": []interface{}{"mul{", "$", "@", "}", "opt{", "num", "}"}},
-
- // 表达式语句
- map[string]interface{}{"page": "op1", "hash": "op1", "word": []interface{}{"mul{", "-", "+", "}"}},
- map[string]interface{}{"page": "op2", "hash": "op2", "word": []interface{}{"mul{", "~", "!~", "}"}},
- map[string]interface{}{"page": "op2", "hash": "op2", "word": []interface{}{"mul{", "+", "-", "*", "/", "%", "}"}},
- map[string]interface{}{"page": "op2", "hash": "op2", "word": []interface{}{"mul{", "<", "<=", ">", ">=", "==", "!=", "}"}},
- map[string]interface{}{"page": "val", "hash": "val", "word": []interface{}{"opt{", "op1", "}", "mul{", "num", "key", "str", "exe", "}"}},
- map[string]interface{}{"page": "exp", "hash": "exp", "word": []interface{}{"val", "rep{", "op2", "val", "}"}},
- map[string]interface{}{"page": "stm", "hash": "return", "word": []interface{}{"return", "rep{", "exp", "}"}},
-
- // 命令语句
- map[string]interface{}{"page": "word", "hash": "word", "word": []interface{}{"mul{", "~", "!", "\\?", "\\?\\?", "exe", "str", "[\\-a-zA-Z0-9_:/.%*]+", "=", "<", ">$", ">@", ">", "\\|", "}"}},
- map[string]interface{}{"page": "cmd", "hash": "cmd", "word": []interface{}{"rep{", "word", "}"}},
- map[string]interface{}{"page": "com", "hash": "cmd", "word": []interface{}{"rep{", ";", "cmd", "}"}},
- map[string]interface{}{"page": "com", "hash": "com", "word": []interface{}{"mul{", "#[^\n]*\n?", "\n", "}"}},
- map[string]interface{}{"page": "line", "hash": "line", "word": []interface{}{"opt{", "mul{", "stm", "cmd", "}", "}", "com"}},
-
- // 复合语句
- map[string]interface{}{"page": "op1", "hash": "op1", "word": []interface{}{"mul{", "!", "}"}},
- map[string]interface{}{"page": "op2", "hash": "op2", "word": []interface{}{"mul{", "&&", "||", "}"}},
- map[string]interface{}{"page": "exe", "hash": "exe", "word": []interface{}{"(", "exp", ")"}},
- map[string]interface{}{"page": "exe", "hash": "exe", "word": []interface{}{"$", "(", "cmd", ")"}},
- map[string]interface{}{"page": "stm", "hash": "var", "word": []interface{}{"var", "key", "opt{", "=", "exp", "}"}},
- map[string]interface{}{"page": "stm", "hash": "let", "word": []interface{}{"let", "key", "opt{", "=", "exp", "}"}},
- map[string]interface{}{"page": "stm", "hash": "let", "word": []interface{}{"let", "key", "=", "\\[", "rep{", "exp", "}", "\\]"}},
- map[string]interface{}{"page": "stm", "hash": "let", "word": []interface{}{"let", "key", "=", "\\{", "rep{", "exp", "}", "\\}"}},
- map[string]interface{}{"page": "stm", "hash": "if", "word": []interface{}{"if", "exp"}},
- map[string]interface{}{"page": "stm", "hash": "for", "word": []interface{}{"for", "rep{", "key", "}"}},
- map[string]interface{}{"page": "stm", "hash": "for", "word": []interface{}{"for", "rep{", "exp", "}"}},
- map[string]interface{}{"page": "stm", "hash": "fun", "word": []interface{}{"fun", "key", "rep{", "exp", "}"}},
- map[string]interface{}{"page": "stm", "hash": "kit", "word": []interface{}{"kit", "rep{", "exp", "}"}},
- map[string]interface{}{"page": "stm", "hash": "else", "word": []interface{}{"else", "opt{", "if", "exp", "}"}},
- map[string]interface{}{"page": "stm", "hash": "end", "word": []interface{}{"end"}},
-
- // 标签语句
- map[string]interface{}{"page": "stm", "hash": "label", "word": []interface{}{"label", "key"}},
- map[string]interface{}{"page": "stm", "hash": "goto", "word": []interface{}{"goto", "key"}},
- /*
-
- map[string]interface{}{"page": "op1", "hash": "op1", "word": []interface{}{"mul{", "-z", "-n", "}"}},
- map[string]interface{}{"page": "op1", "hash": "op1", "word": []interface{}{"mul{", "-e", "-f", "-d", "}"}},
- map[string]interface{}{"page": "op2", "hash": "op2", "word": []interface{}{"mul{", ":=", "=", "+=", "}"}},
-
- map[string]interface{}{"page": "exp", "hash": "exp", "word": []interface{}{"\\{", "rep{", "map", "}", "\\}"}},
- map[string]interface{}{"page": "val", "hash": "val", "word": []interface{}{"opt{", "op1", "}", "(", "exp", ")"}},
-
- map[string]interface{}{"page": "stm", "hash": "var", "word": []interface{}{"var", "key", "<-"}},
- map[string]interface{}{"page": "stm", "hash": "var", "word": []interface{}{"var", "key", "<-", "opt{", "exe", "}"}},
- map[string]interface{}{"page": "stm", "hash": "let", "word": []interface{}{"let", "key", "<-", "opt{", "exe", "}"}},
-
- map[string]interface{}{"page": "stm", "hash": "for", "word": []interface{}{"for", "opt{", "exp", ";", "}", "exp"}},
- map[string]interface{}{"page": "stm", "hash": "for", "word": []interface{}{"for", "index", "exp", "opt{", "exp", "}", "exp"}},
-
- */
-
- }, Help: "语法集合的最大数量"},
- "input": &ctx.Config{Name: "input", Value: map[string]interface{}{
- "text": true,
- "select": true,
- "button": true,
- "upfile": true,
- "textarea": true,
- "exports": true,
- "feature": true,
- }, Help: "控件类型"},
- "exec": &ctx.Config{Name: "info", Value: map[string]interface{}{
- "disable": map[string]interface{}{
- "void": true,
- "num": true,
- "key": true,
- "op1": true,
- "op2": true,
- "word": true,
- "line": true,
- },
- "always": map[string]interface{}{
- "if": true,
- "else": true,
- "end": true,
- "for": true,
- },
- }, Help: "嵌套层级日志的标记"},
-
- "alias": &ctx.Config{Name: "alias", Value: map[string]interface{}{
- "~": []string{"context"},
- "!": []string{"message"},
- ":": []string{"command"},
- "::": []string{"command", "list"},
-
- "note": []string{"mdb.note"},
- "pwd": []string{"nfs.pwd"},
- "path": []string{"nfs.path"},
- "dir": []string{"nfs.dir"},
- "brow": []string{"web.brow"},
- "ifconfig": []string{"tcp.ifconfig"},
- }, Help: "启动脚本"},
- },
- Commands: map[string]*ctx.Command{
- "_init": &ctx.Command{Name: "_init", Help: "添加语法规则, page: 语法集合, hash: 语句类型, word: 语法模板", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if yac, ok := m.Target().Server.(*YAC); m.Assert(ok) {
- yac.lex = m.Cmd("lex.spawn")
- m.Confm("seed", func(line int, seed map[string]interface{}) {
- m.Spawn().Cmd("train", seed["page"], seed["hash"], seed["word"])
- })
- }
- return
- }},
- "train": &ctx.Command{Name: "train page hash word...", Help: "添加语法规则, page: 语法集合, hash: 语句类型, word: 语法模板", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if yac, ok := m.Target().Server.(*YAC); m.Assert(ok) {
- page := yac.index(m, "npage", arg[0])
- hash := yac.index(m, "nhash", arg[1])
- if yac.mat[page] == nil {
- yac.mat[page] = map[byte]*State{}
- for i := 0; i < m.Confi("meta", "nlang"); i++ {
- yac.mat[page][byte(i)] = nil
- }
- }
- yac.train(m, page, hash, arg[2:], 1)
-
- yac.seed = append(yac.seed, &Seed{page, hash, arg[2:]})
- m.Cap("stream", fmt.Sprintf("%d,%s,%s", m.Cap("nseed", len(yac.seed)),
- m.Cap("npage"), m.Cap("nhash", len(yac.hash)-1)))
- }
- return
- }},
- "parse": &ctx.Command{Name: "parse line", Help: "解析语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if yac, ok := m.Target().Server.(*YAC); m.Assert(ok) {
- stack, _ := m.Optionv("bio.stack").(*kit.Stack)
- m.Optioni("yac.page", yac.page[m.Conf("nline")])
- m.Optioni("yac.void", yac.page[m.Conf("nvoid")])
-
- _, word, _ := yac.parse(m, m, stack, m.Optioni("yac.page"), m.Optioni("yac.void"), []byte(arg[0]), 1)
- m.Result(word)
- }
- return
- }},
- "show": &ctx.Command{Name: "show seed|page|hash|mat", Help: "查看信息", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if yac, ok := m.Target().Server.(*YAC); m.Assert(ok) {
- if len(arg) == 0 {
- m.Push("seed", len(yac.seed))
- m.Push("page", len(yac.page))
- m.Push("hash", len(yac.hash))
- m.Push("nmat", len(yac.mat))
- m.Push("node", len(yac.state))
- m.Table()
- return
- }
-
- switch arg[0] {
- case "seed":
- for _, v := range yac.seed {
- m.Push("page", yac.hand[v.page])
- m.Push("word", strings.Replace(strings.Replace(fmt.Sprint(v.word), "\n", "\\n", -1), "\t", "\\t", -1))
- m.Push("hash", yac.word[v.hash])
- }
- m.Sort("page", "int").Table()
-
- case "page":
- for k, v := range yac.page {
- m.Add("append", "page", k)
- m.Add("append", "code", v)
- }
- m.Sort("code", "int").Table()
-
- case "hash":
- for k, v := range yac.hash {
- m.Add("append", "hash", k)
- m.Add("append", "code", v)
- m.Add("append", "hand", yac.hand[v])
- }
- m.Sort("code", "int").Table()
-
- case "node":
- for _, v := range yac.state {
- m.Push("star", v.star)
- m.Push("next", v.next)
- m.Push("hash", v.hash)
- }
- m.Table()
-
- case "mat":
- for i, v := range yac.mat {
- if i <= m.Capi("npage") {
- m.Push("index", yac.hand[i])
- } else if i < m.Confi("meta", "nlang") {
- continue
- } else {
- m.Push("index", i)
- }
-
- for j := byte(0); j < byte(m.Confi("meta", "ncell")); j++ {
- c := fmt.Sprintf("%d", j)
- if s := v[j]; s == nil {
- m.Push(c, "")
- } else {
- m.Push(c, fmt.Sprintf("%d,%d,%d", s.star, s.next, s.hash))
- }
- }
- }
-
- ncol := len(m.Meta["append"])
- nrow := len(m.Meta[m.Meta["append"][0]])
- for i := 0; i < ncol-1; i++ {
- for j := i + 1; j < ncol; j++ {
- same := true
- void := true
- for n := 0; n < nrow; n++ {
- if m.Meta[m.Meta["append"][i]][n] != "" {
- void = false
- }
-
- if m.Meta[m.Meta["append"][i]][n] != m.Meta[m.Meta["append"][j]][n] {
- same = false
- break
- }
- }
-
- if same {
- if !void {
- key = m.Meta["append"][i] + "," + m.Meta["append"][j]
- m.Meta[key] = m.Meta[m.Meta["append"][i]]
- m.Meta["append"][i] = key
- }
-
- for k := j; k < ncol-1; k++ {
- m.Meta["append"][k] = m.Meta["append"][k+1]
- }
- ncol--
- j--
- }
- }
- }
- m.Meta["append"] = m.Meta["append"][:ncol]
- m.Table()
- }
- }
- return
- }},
-
- "str": &ctx.Command{Name: "str word", Help: "解析字符串", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- m.Echo(arg[0][1 : len(arg[0])-1])
- return
- }},
- "exe": &ctx.Command{Name: "exe $ ( cmd )", Help: "解析嵌套命令", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- switch len(arg) {
- case 1:
- m.Echo(arg[0])
- case 2:
- bio := m.Optionv("bio.msg").(*ctx.Message)
- msg := m.Spawn(m.Optionv("bio.ctx"))
- switch arg[0] {
- case "$":
- // 局部变量
- if stack, ok := m.Optionv("bio.stack").(*kit.Stack); ok {
- if v, ok := stack.Hash(arg[1]); ok {
- m.Echo("%v", v)
- break
- }
- }
-
- // 函数参数
- if i, e := strconv.Atoi(arg[1]); e == nil {
- m.Echo(bio.Detail(i))
- break
- }
- // 函数选项
- m.Echo(kit.Select(msg.Cap(arg[1]), bio.Option(arg[1])))
-
- case "@":
- // 局部变量
- if stack, ok := m.Optionv("bio.stack").(*kit.Stack); ok {
- if v, ok := stack.Hash(arg[1]); ok {
- m.Echo("%v", v)
- break
- }
- }
-
- // 函数参数
- if i, e := strconv.Atoi(arg[1]); e == nil {
- m.Echo(bio.Detail(i))
- break
- }
- // 函数配置
- m.Echo(kit.Select(msg.Conf(arg[1]), bio.Option(arg[1])))
-
- default:
- m.Echo(arg[0]).Echo(arg[1])
- }
- default:
- switch arg[0] {
- case "$", "@":
- m.Result(0, arg[2:len(arg)-1])
- case "(":
- m.Echo(arg[1])
- }
- }
- return
- }},
- "val": &ctx.Command{Name: "val exp", Help: "表达式运算", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- result := "false"
- switch len(arg) {
- case 0:
- result = ""
- case 1:
- result = arg[0]
- case 2:
- switch arg[0] {
- case "-z":
- if arg[1] == "" {
- result = "true"
- }
- case "-n":
- if arg[1] != "" {
- result = "true"
- }
-
- case "-e":
- if _, e := os.Stat(arg[1]); e == nil {
- result = "true"
- }
- case "-f":
- if info, e := os.Stat(arg[1]); e == nil && !info.IsDir() {
- result = "true"
- }
- case "-d":
- if info, e := os.Stat(arg[1]); e == nil && info.IsDir() {
- result = "true"
- }
- case "!":
- result = kit.Format(!kit.Right(arg[1]))
- case "+":
- result = arg[1]
- case "-":
- result = arg[1]
- if i, e := strconv.Atoi(arg[1]); e == nil {
- result = fmt.Sprintf("%d", -i)
- }
- }
- case 3:
- v1, e1 := strconv.Atoi(arg[0])
- v2, e2 := strconv.Atoi(arg[2])
- switch arg[1] {
- case "=":
- result = m.Cap(arg[0], arg[2])
- case "+=":
- if i, e := strconv.Atoi(m.Cap(arg[0])); e == nil && e2 == nil {
- result = m.Cap(arg[0], fmt.Sprintf("%d", v2+i))
- } else {
- result = m.Cap(arg[0], m.Cap(arg[0])+arg[2])
- }
- case "+":
- if e1 == nil && e2 == nil {
- result = fmt.Sprintf("%d", v1+v2)
- } else {
- result = arg[0] + arg[2]
- }
- case "-":
- if e1 == nil && e2 == nil {
- result = fmt.Sprintf("%d", v1-v2)
- } else {
- result = strings.Replace(arg[0], arg[2], "", -1)
- }
- case "*":
- result = arg[0]
- if e1 == nil && e2 == nil {
- result = fmt.Sprintf("%d", v1*v2)
- }
- case "/":
- result = arg[0]
- if e1 == nil && e2 == nil {
- result = fmt.Sprintf("%d", v1/v2)
- }
- case "%":
- result = arg[0]
- if e1 == nil && e2 == nil {
- result = fmt.Sprintf("%d", v1%v2)
- }
-
- case "<":
- if e1 == nil && e2 == nil {
- result = fmt.Sprintf("%t", v1 < v2)
- } else {
- result = fmt.Sprintf("%t", arg[0] < arg[2])
- }
- case "<=":
- if e1 == nil && e2 == nil {
- result = fmt.Sprintf("%t", v1 <= v2)
- } else {
- result = fmt.Sprintf("%t", arg[0] <= arg[2])
- }
- case ">":
- if e1 == nil && e2 == nil {
- result = fmt.Sprintf("%t", v1 > v2)
- } else {
- result = fmt.Sprintf("%t", arg[0] > arg[2])
- }
- case ">=":
- if e1 == nil && e2 == nil {
- result = fmt.Sprintf("%t", v1 >= v2)
- } else {
- result = fmt.Sprintf("%t", arg[0] >= arg[2])
- }
- case "==":
- if e1 == nil && e2 == nil {
- result = fmt.Sprintf("%t", v1 == v2)
- } else {
- result = fmt.Sprintf("%t", arg[0] == arg[2])
- }
- case "!=":
- if e1 == nil && e2 == nil {
- result = fmt.Sprintf("%t", v1 != v2)
- } else {
- result = fmt.Sprintf("%t", arg[0] != arg[2])
- }
- case "&&":
- if kit.Right(arg[0]) {
- result = arg[2]
- } else {
- result = arg[0]
- }
- case "||":
- if kit.Right(arg[0]) {
- result = arg[0]
- } else {
- result = arg[2]
- }
-
- case "~":
- if m, e := regexp.MatchString(arg[2], arg[0]); m && e == nil {
- result = "true"
- }
- case "!~":
- if m, e := regexp.MatchString(arg[2], arg[0]); !m || e != nil {
- result = "true"
- }
- }
- }
- m.Echo(result)
-
- return
- }},
- "exp": &ctx.Command{Name: "exp word", Help: "表达式运算", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if len(arg) > 0 && arg[0] == "{" {
- msg := m.Spawn()
- for i := 1; i < len(arg); i++ {
- key := arg[i]
- for i += 3; i < len(arg); i++ {
- if arg[i] == "]" {
- break
- }
- msg.Add("append", key, arg[i])
- }
- }
- m.Echo("%d", msg.Code())
- return
- }
-
- pre := map[string]int{
- "=": -1,
- "||": 0,
- "==": 1, "~": 1,
- "+": 2, "-": 2,
- "*": 3, "/": 3, "%": 3,
- }
- num, op := []string{arg[0]}, []string{}
-
- for i := 1; i < len(arg); i += 2 {
- if len(op) > 0 && pre[op[len(op)-1]] >= pre[arg[i]] {
- num[len(op)-1] = m.Cmdx("yac.val", num[len(op)-1], op[len(op)-1], num[len(op)])
- num, op = num[:len(num)-1], op[:len(op)-1]
- }
- num, op = append(num, arg[i+1]), append(op, arg[i])
- }
-
- for i := len(op) - 1; i >= 0; i-- {
- num[i] = m.Cmdx("yac.val", num[i], op[i], num[i+1])
- }
-
- m.Echo("%s", num[0])
- return
- }},
- "return": &ctx.Command{Name: "return result...", Help: "结束脚本, result: 返回值", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- m.Appends("bio.end", true)
- m.Result(arg[1:])
- return
- }},
- "com": &ctx.Command{Name: "com", Help: "解析注释", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- return
- }},
- "cmd": &ctx.Command{Name: "cmd word", Help: "解析命令", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- // 解析别名
- detail := []string{}
- if alias, ok := m.Confv("alias", arg[0]).([]string); ok {
- detail, arg = append(detail, alias...), arg[1:]
- }
- detail = append(detail, arg...)
-
- // 目标切换
- target := m.Optionv("bio.ctx")
- if detail[0] != "context" {
- defer func() { m.Optionv("bio.ctx", target) }()
- }
-
- // 解析脚本
- msg := m
- for k, v := range m.Confv("system", "script").(map[string]interface{}) {
- if strings.HasSuffix(detail[0], "."+k) {
- msg = m.Spawn(m.Optionv("bio.ctx"))
- detail[0] = m.Cmdx("nfs.path", detail[0])
- detail = append([]string{v.(string)}, detail...)
- break
- }
- }
-
- // 解析路由
- if msg == m {
- if routes := strings.Split(detail[0], "."); len(routes) > 1 && !strings.Contains(detail[0], ":") {
- route := strings.Join(routes[:len(routes)-1], ".")
- if msg = m.Find(route, false); msg == nil {
- msg = m.Find(route, true)
- }
-
- if msg == nil {
- m.Echo("%s not exist", route)
- return
- }
- detail[0] = routes[len(routes)-1]
- } else {
- msg = m.Spawn(m.Optionv("bio.ctx"))
- }
- }
- msg.Copy(m, "option").Copy(m, "append")
-
- // 解析命令
- args, rest := []string{}, []string{}
- exports := []map[string]string{}
- exec, execexec := true, false
- for i := 0; i < len(detail); i++ {
- switch detail[i] {
- case "?":
- if !kit.Right(detail[i+1]) {
- return
- }
- i++
- case "??":
- exec = false
- execexec = execexec || kit.Right(detail[i+1])
- i++
- case "<":
- m.Cmdy("nfs.import", detail[i+1])
- i++
- case ">":
- exports = append(exports, map[string]string{"file": detail[i+1]})
- i++
- case ">$":
- if i == len(detail)-2 {
- exports = append(exports, map[string]string{"cache": detail[i+1], "index": "result"})
- i += 1
- break
- }
- exports = append(exports, map[string]string{"cache": detail[i+1], "index": detail[i+2]})
- i += 2
- case ">@":
- if i == len(detail)-2 {
- exports = append(exports, map[string]string{"config": detail[i+1], "index": "result"})
- i += 1
- break
- }
- exports = append(exports, map[string]string{"config": detail[i+1], "index": detail[i+2]})
- i += 2
- case "|":
- detail, rest = detail[:i], detail[i+1:]
- case "%":
- rest = append(rest, "select")
- detail, rest = detail[:i], append(rest, detail[i+1:]...)
- default:
- args = append(args, detail[i])
- }
- }
- if !exec && !execexec {
- return
- }
-
- // 执行命令
- if msg.Set("detail", args).Cmd(); !msg.Hand {
- msg.Cmd("system", args)
- }
- if msg.Appends("bio.ctx1") {
- target = msg.Target()
- }
-
- // 管道命令
- if len(rest) > 0 {
- pipe := msg.Spawn()
- pipe.Copy(msg, "append").Copy(msg, "result").Cmd("cmd", rest)
- msg.Set("append").Copy(pipe, "append")
- msg.Set("result").Copy(pipe, "result")
- }
-
- // 导出结果
- for _, v := range exports {
- if v["file"] != "" {
- m.Sess("nfs").Copy(msg, "option").Copy(msg, "append").Copy(msg, "result").Cmd("export", v["file"])
- msg.Set("result")
- }
- if v["cache"] != "" {
- if v["index"] == "result" {
- m.Cap(v["cache"], strings.Join(msg.Meta["result"], ""))
- } else {
- m.Cap(v["cache"], msg.Append(v["index"]))
- }
- }
- if v["config"] != "" {
- if v["index"] == "result" {
- m.Conf(v["config"], strings.Join(msg.Meta["result"], ""))
- } else {
- m.Conf(v["config"], msg.Append(v["index"]))
- }
- }
- }
-
- // 返回结果
- m.Optionv("bio.ctx", msg.Target())
- m.Set("append").Copy(msg, "append")
- m.Set("result").Copy(msg, "result")
- return
- }},
- "alias": &ctx.Command{Name: "alias [short [long...]]|[delete short]|[import module [command [alias]]]",
- Help: "查看、定义或删除命令别名, short: 命令别名, long: 命令原名, delete: 删除别名, import导入模块所有命令",
- Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- switch len(arg) {
- case 0:
- m.Cmdy("ctx.config", "alias")
- case 1:
- m.Cmdy("ctx.config", "alias", arg[0])
- default:
- switch arg[0] {
- case "delete":
- alias := m.Confm("alias")
- m.Echo("delete: %s %v\n", arg[1], alias[arg[1]])
- delete(alias, arg[1])
- case "import":
- msg := m.Find(arg[1], false)
- if msg == nil {
- msg = m.Find(arg[1], true)
- }
- if msg == nil {
- m.Echo("%s not exist", arg[1])
- return
- }
-
- module := msg.Cap("module")
- for k, _ := range msg.Target().Commands {
- if len(k) > 0 && k[0] == '/' {
- continue
- }
-
- if len(arg) == 2 {
- m.Confv("alias", k, []string{module + "." + k})
- m.Log("info", "import %s.%s", module, k)
- continue
- }
-
- if key := k; k == arg[2] {
- if len(arg) > 3 {
- key = arg[3]
- }
- m.Confv("alias", key, []string{module + "." + k})
- m.Log("info", "import %s.%s as %s", module, k, key)
- break
- }
- }
- default:
- m.Confv("alias", arg[0], arg[1:])
- m.Log("info", "%s: %v", arg[0], arg[1:])
- }
- }
- return
- }},
-
- "var": &ctx.Command{Name: "var a [= exp]", Help: "定义变量, a: 变量名, exp: 表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if stack, ok := m.Optionv("bio.stack").(*kit.Stack); ok {
- m.Log("stack", "%v = %v", arg[1], arg[3])
- stack.Peek().Hash[arg[1]] = arg[3]
- }
- return
- }},
- "let": &ctx.Command{Name: "let a = exp", Help: "设置变量, a: 变量名, exp: 表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if stack, ok := m.Optionv("bio.stack").(*kit.Stack); ok {
- switch arg[3] {
- case "[":
- list := []interface{}{}
- for i := 4; i < len(arg)-1; i++ {
- list = append(list, arg[i])
- }
- m.Log("stack", "%v = %v", arg[1], list)
- stack.Hash(arg[1], list)
-
- case "{":
- list := map[string]interface{}{}
- for i := 4; i < len(arg)-2; i += 2 {
- list[arg[i]] = arg[i+1]
- }
- m.Log("stack", "%v = %v", arg[1], list)
- stack.Hash(arg[1], list)
-
- default:
- m.Log("stack", "%v = %v", arg[1], arg[3])
- stack.Hash(arg[1], arg[3])
- }
- }
- return
- }},
- "if": &ctx.Command{Name: "if exp", Help: "条件语句, exp: 表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- stack := m.Optionv("bio.stack").(*kit.Stack)
- o := stack.Peek()
- p := stack.Push(arg[0], o.Run && kit.Right(arg[1]), m.Optioni("stack.pos"))
- m.Log("stack", "push %v", p.String("\\"))
- if !o.Run || p.Run {
- p.Done = true
- }
- return
- }},
- "for": &ctx.Command{Name: "for exp | for index val... in list", Help: "循环语句",
- Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- stack := m.Optionv("bio.stack").(*kit.Stack)
- m.Log("stack", "push %v", stack.Push(arg[0], stack.Peek().Run && kit.Right(arg[1]), m.Optioni("stack.pos")).String("\\"))
-
- val, _ := stack.Hash(arg[len(arg)-1])
- index := kit.Int(stack.FS[len(stack.FS)-2].Hash["_index"])
- switch val := val.(type) {
- case map[string]interface{}:
- list := make([]string, 0, len(val))
- for k, _ := range val {
- list = append(list, k)
- }
- sort.Strings(list)
-
- if index < len(list) {
- stack.Hash(arg[1], list[index])
- }
- stack.Peek().Run = false
- for i, j := 2, index; i < len(arg)-2 && j < len(list); i, j = i+1, j+1 {
- stack.Peek().Run = true
- stack.Hash(arg[i], val[list[j]])
- stack.FS[len(stack.FS)-2].Hash["_index"] = j + 1
- }
-
- case []interface{}:
- stack.Hash(arg[1], index)
- stack.Peek().Run = false
- for i, j := 2, index; i < len(arg)-2 && j < len(val); i, j = i+1, j+1 {
- stack.Peek().Run = true
- stack.Hash(arg[i], val[j])
- stack.FS[len(stack.FS)-2].Hash["_index"] = j + 1
- }
- default:
- }
- if !stack.Peek().Run {
- stack.FS[len(stack.FS)-2].Hash["_index"] = 0
- }
- return
- }},
- "fun": &ctx.Command{Name: "fun name help", Help: "小函数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- p := m.Optionv("bio.stack").(*kit.Stack).Push(arg[0], false, m.Optioni("stack.pos"))
- m.Log("stack", "push %v", p.String("\\"))
-
- if len(arg) > 2 {
- m.Cmd("kit", "kit", arg[1:])
- }
- self := &ctx.Command{Name: strings.Join(arg[1:], " "), Help: []string{"pwd", "ls"}}
- self.Hand = func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- m.Goshy(self.Help.([]string), 0, nil, nil)
- m.Log("time", "parse: %v", m.Format("cost"))
- return
- }
- m.Target().Commands[arg[1]] = self
- m.Log("info", "fun: %v %v", arg[1], arg)
- p.Data = self
- return
- }},
- "kit": &ctx.Command{Name: "kit name help [init [view]] [public|protected|private] cmd arg... [input value [key val]...]...", Help: "小功能", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- m.Log("info", "_index: %v", arg)
-
- args := []interface{}{}
- inputs := []interface{}{}
- exports := []interface{}{}
- feature := map[string]interface{}{}
-
- init, view, right, cmd := "", "", "", ""
- begin := 3
-
- switch arg[3] {
- case "private", "protected", "public":
- begin, right, cmd = 5, arg[3], arg[4]
- default:
- switch arg[4] {
- case "private", "protected", "public":
- begin, init, right, cmd = 6, arg[3], arg[4], arg[5]
- default:
- begin, init, view, right, cmd = 7, arg[3], arg[4], arg[5], arg[6]
- }
- }
-
- if m.Confs("input", cmd) {
- cmd, begin = arg[1], begin-1
- }
-
- for i := begin; i < len(arg); i++ {
- if !m.Confs("input", arg[i]) {
- args = append(args, arg[i])
- continue
- }
- for j := i; j < len(arg); j++ {
- if j < len(arg)-1 && !m.Confs("input", arg[j+1]) {
- continue
- }
- args := arg[i : j+1]
- if arg[i] == "feature" {
- for k := 2; k < len(args); k++ {
- feature[args[1]] = kit.Merge(feature[args[1]], args[k])
- }
-
- } else if arg[i] == "exports" {
- for k := 1; k < len(args); k += 1 {
- exports = append(exports, args[k])
- }
- } else {
- input := map[string]interface{}{
- "type": kit.Select("", args, 0),
- "value": kit.Select("", args, 1),
- }
- for k := 2; k < len(args)-1; k += 2 {
- input[args[k]] = kit.Merge(input[args[k]], args[k+1])
- }
- inputs = append(inputs, input)
- }
- i = j
- break
- }
- }
-
- if len(inputs) == 0 {
- inputs = []interface{}{
- map[string]interface{}{"type": "text", "name": "arg"},
- map[string]interface{}{"type": "button", "value": "执行"},
- }
- }
-
- ctx := m.Cap("module")
- if strings.Contains(cmd, ".") {
- cs := strings.Split(cmd, ".")
- ctx = strings.Join(cs[:len(cs)-1], ".")
- cmd = cs[len(cs)-1]
- }
-
- m.Confv("_index", []interface{}{-2}, map[string]interface{}{
- "name": kit.Select("", arg, 1),
- "help": kit.Select("", arg, 2),
- "view": view,
- "init": init,
- "type": right,
-
- "ctx": ctx,
- "cmd": cmd,
- "args": args,
- "inputs": inputs,
- "exports": exports,
- "feature": feature,
- })
- return
- }},
- "else": &ctx.Command{Name: "else", Help: "条件语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- p := m.Optionv("bio.stack").(*kit.Stack).Peek()
- p.Run = !p.Done && !p.Run && (len(arg) == 1 || kit.Right(arg[2]))
- m.Log("stack", "set: %v", p.String("|"))
- if p.Run {
- p.Done = true
- }
- return
- }},
- "end": &ctx.Command{Name: "end", Help: "结束语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- p := m.Optionv("bio.stack").(*kit.Stack).Pop()
- m.Log("stack", "pop: %v", p.String("/"))
- switch p.Key {
- case "for":
- if p.Run {
- m.Appendi("bio.pos0", p.Pos)
- }
- case "fun":
- end := m.Optioni("stack.pos")
- self := p.Data.(*ctx.Command)
- help := []string{}
- for i, v := range m.Optionv("bio.input").([]string) {
- if p.Pos < i && i < end {
- help = append(help, v)
- }
- }
- self.Help = help
- }
-
- return
- }},
-
- "label": &ctx.Command{Name: "label name", Help: "记录当前脚本的位置, name: 位置名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- p := m.Optionv("bio.stack").(*kit.Stack).Peek()
- if p.Label == nil {
- p.Label = map[string]int{}
- }
- m.Log("stack", "%v <= %v", arg[1], m.Optioni("stack.pos")+1)
- p.Label[arg[1]] = m.Optioni("stack.pos") + 1
- return
- }},
- "goto": &ctx.Command{Name: "goto label [exp] condition", Help: "向上跳转到指定位置, label: 跳转位置, condition: 跳转条件", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- stack := m.Optionv("bio.stack").(*kit.Stack)
- if i, ok := stack.Label(arg[1]); ok {
- m.Log("stack", "%v => %v", arg[1], i)
- m.Append("bio.pos0", i)
- }
- return
- }},
- },
-}
-
-func init() {
- ctx.Index.Register(Index, &YAC{Context: Index})
-}
diff --git a/usr/local/honor/src/examples/chat/chat.go b/usr/local/honor/src/examples/chat/chat.go
deleted file mode 100644
index e29c212f..00000000
--- a/usr/local/honor/src/examples/chat/chat.go
+++ /dev/null
@@ -1,617 +0,0 @@
-package chat
-
-import (
- "contexts/ctx"
- "contexts/web"
- mis "github.com/shylinux/toolkits"
-
- "fmt"
- "net/http"
- "os"
- "path"
- "strings"
- "toolkit"
-)
-
-func check(m *ctx.Message, arg []string) ([]string, string, bool) {
- if !m.Options("sessid") || !m.Options("username") {
- return nil, "", false
- }
-
- rid := m.Option("river")
- if len(arg[0]) != 32 {
- arg[0] = m.Cmdx("aaa.short", arg[0])
- }
- if m.Confs("flow", arg[0]) {
- rid, arg = arg[0], arg[1:]
- }
- if rid != "" && len(rid) != 32 {
- rid = m.Cmdx("aaa.short", rid)
- }
- return arg, rid, true
-}
-
-var Index = &ctx.Context{Name: "chat", 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: "用户登录"},
- "componet": &ctx.Config{Name: "componet", Value: map[string]interface{}{
- "index": []interface{}{
- map[string]interface{}{"name": "head",
- "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", "chat.css",
- "can_style.css",
- }},
- map[string]interface{}{"name": "toast",
- "tmpl": "fieldset", "view": "Toast dialog", "init": "initToast",
- },
- map[string]interface{}{"name": "carte",
- "tmpl": "fieldset", "view": "Carte dialog", "init": "initCarte",
- },
- map[string]interface{}{"name": "debug",
- "tmpl": "fieldset", "view": "Debug dialog", "init": "initDebug",
- },
- map[string]interface{}{"name": "favor",
- "tmpl": "fieldset", "view": "Favor dialog", "init": "initFavor",
- "ctx": "web.chat", "cmd": "favor",
- },
- map[string]interface{}{"name": "tutor",
- "tmpl": "fieldset", "view": "Tutor dialog", "init": "initTutor",
- "ctx": "web.chat", "cmd": "tutor",
- },
-
- map[string]interface{}{"name": "login",
- "tmpl": "fieldset", "view": "Login dialog", "init": "initLogin",
- "ctx": "web.chat", "cmd": "login",
- },
- map[string]interface{}{"name": "header",
- "tmpl": "fieldset", "view": "Header", "init": "initHeader",
- "ctx": "web.chat", "cmd": "login",
- },
-
- map[string]interface{}{"name": "ocean",
- "tmpl": "fieldset", "view": "Ocean dialog", "init": "initOcean",
- "ctx": "web.chat", "cmd": "ocean",
- },
- map[string]interface{}{"name": "steam",
- "tmpl": "fieldset", "view": "Steam dialog", "init": "initSteam",
- "ctx": "web.chat", "cmd": "steam",
- },
- map[string]interface{}{"name": "river",
- "tmpl": "fieldset", "view": "River", "init": "initRiver",
- "ctx": "web.chat", "cmd": "river",
- },
- map[string]interface{}{"name": "storm",
- "tmpl": "fieldset", "view": "Storm", "init": "initStorm",
- "ctx": "web.chat", "cmd": "storm",
- },
-
- map[string]interface{}{"name": "target",
- "tmpl": "fieldset", "view": "Target", "init": "initTarget",
- "ctx": "web.chat", "cmd": "river",
- },
- map[string]interface{}{"name": "source",
- "tmpl": "fieldset", "view": "Source", "init": "initSource",
- "ctx": "web.chat", "cmd": "storm",
- },
- map[string]interface{}{"name": "action",
- "tmpl": "fieldset", "view": "Action", "init": "initAction",
- "ctx": "web.chat", "cmd": "storm",
- },
-
- map[string]interface{}{"name": "footer",
- "tmpl": "fieldset", "view": "Footer", "init": "initFooter",
- "ctx": "web.chat", "cmd": "login",
- },
- map[string]interface{}{"name": "tail",
- "tmpl": "tail", "scripts": []interface{}{
- // "toolkit.js", "context.js", "example.js", "chat.js",
- "can_proto.js", "can_order.js", "can_frame.js",
- },
- },
- },
- }, Help: "组件列表"},
- "share": &ctx.Config{Name: "share", Value: map[string]interface{}{
- "meta": map[string]interface{}{
- "fields": "id time share type code remote_ip",
- "store": "var/tmp/share.csv",
- "limit": 30, "least": 10,
- },
- "hash": map[string]interface{}{},
- "list": []interface{}{},
- }, Help: "共享链接"},
- },
- Commands: map[string]*ctx.Command{
- "login": &ctx.Command{Name: "login [username password]", Help: "登录", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if len(arg) > 0 {
- switch arg[0] {
- case "weixin":
- if msg := m.Find("cli.weixin", true); msg != nil {
- msg.Cmd("js_token")
- m.Copy(msg, "append")
- m.Append("remote_ip", m.Option("remote_ip"))
- m.Append("nickname", kit.Select(m.Option("username"), m.Option("nickname")))
- m.Table()
- }
- return
- }
- }
-
- // 非登录态
- if !m.Options("sessid") || !m.Options("username") {
- if len(arg) > 0 {
- // 用户登录
- if m.Cmds("ssh.work", "share", arg[0]) {
- if m.Cmds("aaa.auth", "username", arg[0], "password", arg[1]) {
- m.Option("username", arg[0])
- m.Option("sessid", m.Cmdx("aaa.user", "session", "select"))
- if !m.Cmds("aaa.auth", "username", arg[0], "data", "chat.default") && m.Option("username") != m.Conf("runtime", "work.name") {
- m.Cmd("aaa.auth", "username", arg[0], "data", "chat.default",
- m.Cmdx(".ocean", "spawn", "", m.Option("username")+"@"+m.Conf("runtime", "work.name"), m.Option("username")))
- }
- r := m.Optionv("request").(*http.Request)
- w := m.Optionv("response").(http.ResponseWriter)
-
- web.Cookie(m, w, r)
- m.Echo(m.Option("sessid"))
- }
- }
- }
- return
- }
-
- if len(arg) > 0 {
- switch arg[0] {
- case "share":
- m.Append("qrcode", arg[1])
- return
- case "relay":
- relay := m.Cmdx("aaa.relay", "share", arg[1:])
- m.Log("info", "relay: %s", relay)
- m.Echo(m.Cmdx("aaa.short", relay))
- return
- case "rename":
- m.Cmd("aaa.auth", "username", m.Option("username"), "data", "nickname", arg[1])
-
- }
- }
-
- // if m.Log("info", "nickname: %s", m.Option("nickname", m.Cmdx("aaa.auth", "username", m.Option("username"), "data", "nickname"))); !m.Options("nickname") {
- // m.Option("nickname", m.Option("username"))
- // }
- m.Append("remote_ip", m.Option("remote_ip"))
- m.Append("nickname", kit.Select(m.Option("username"), m.Option("nickname")))
- m.Echo(m.Option("username"))
- return
- }},
- "ocean": &ctx.Command{Name: "ocean [search [name]]|[spawn hash name user...]", Help: "海洋, search [name]: 搜索员工, spawn hash name user...: 创建群聊", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- // 登录失败
- if !m.Options("sessid") || !m.Options("username") {
- return
- }
-
- if len(arg) == 0 {
- arg = append(arg, "search")
- }
-
- switch arg[0] {
- // 搜索员工
- case "search":
- m.Cmdy("ssh.work", "search")
-
- // 创建群聊
- case "spawn":
- // 用户列表
- user := map[string]interface{}{}
- if len(arg) > 3 {
- arg = append(arg, m.Option("username"))
- arg = append(arg, m.Conf("runtime", "work.name"))
- for _, v := range arg[3:] {
- if p := m.Cmdx("ssh._route", m.Conf("runtime", "work.route"), "_check", "work", v); p != "" {
- user[v] = map[string]interface{}{"user": p}
- }
- }
- }
-
- // 添加群聊
- h := kit.Select(kit.Hashs("uniq"), arg, 1)
- m.Conf("flow", h, map[string]interface{}{
- "conf": map[string]interface{}{
- "create_user": m.Option("username"),
- "create_time": m.Time(),
- "update_time": m.Time(),
- "nick": kit.Select("what", arg, 2),
- "route": kit.Select(m.Conf("runtime", "node.route"), m.Option("node.route"), arg[1] != ""),
- },
- "user": user,
- "tool": map[string]interface{}{},
- "text": map[string]interface{}{},
- })
-
- if m.Echo(h); arg[1] != "" {
- return
- }
-
- m.Cmdx(".steam", h, "spawn", "index")
-
- // 分发群聊
- m.Confm("flow", []string{h, "user"}, func(key string, value map[string]interface{}) {
- if kit.Right(value["user"]) && kit.Format(value["user"]) != m.Conf("runtime", "node.route") {
- m.Cmd("ssh._route", value["user"], "context", "chat", "ocean", "spawn", h, arg[2])
- }
- })
- }
- return
- }},
- "river": &ctx.Command{Name: "river hash [brow begin]|[flow type text [index]]|[wave route group index args...]", Help: "河流", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- // 登录失败
- if !m.Options("sessid") || !m.Options("username") {
- return
- }
-
- // 自动入群
- if m.Options("river") {
- if m.Short("river"); m.Confs("flow", m.Option("river")) && !m.Confs("flow", []string{m.Option("river"), "user", m.Option("username")}) {
- u := m.Cmdx("ssh._route", m.Conf("runtime", "work.route"), "_check", "work", m.Option("username"))
- m.Conf("flow", []string{m.Option("river"), "user", m.Option("username"), "user"}, u)
- }
- }
-
- // 群聊列表
- if len(arg) == 0 {
- m.Confm("flow", func(key string, value map[string]interface{}) {
- if kit.Chain(value, []string{"user", m.Option("username")}) == nil {
- return
- }
-
- m.Push("key", m.Cmdx("aaa.short", key))
- m.Push("nick", kit.Chains(value, "conf.nick"))
- m.Push("create_user", kit.Chains(value, "conf.create_user"))
- m.Push("create_time", kit.Chains(value, "conf.create_time"))
- m.Push("update_time", kit.Chains(value, "conf.update_time"))
-
- if list, ok := kit.Chain(value, "text.list").([]interface{}); ok {
- m.Push("count", len(list))
- } else {
- m.Push("count", 0)
- }
- })
- if !m.Appends("key") {
- m.Cmd(".ocean", "spawn", "", "hello", m.Option("username"))
- m.Cmdy(".river")
- return
- }
- m.Sort("name").Sort("update_time", "time_r").Table()
- return
- }
-
- // 登录失败
- arg, rid, ok := check(m, arg)
- if !ok {
- return
- }
-
- switch arg[0] {
- // 消息列表
- case "brow":
- begin := kit.Int(kit.Select("0", arg, 1))
- m.Confm("flow", []string{rid, "text.list"}, func(index int, value map[string]interface{}) {
- if index < begin {
- return
- }
- m.Push("index", index)
- m.Push("type", value["type"])
- m.Push("text", value["text"])
- m.Push("create_time", value["create_time"])
- m.Push("create_user", value["create_user"])
- m.Push("create_nick", value["create_nick"])
- })
- m.Table()
- return
-
- // 推送消息
- case "flow":
- up := m.Conf("flow", []string{rid, "conf.route"})
-
- // 上传消息
- if len(arg) == 3 && up != m.Conf("runtime", "node.route") {
- m.Cmdy("ssh._route", up, "context", "chat", "river", rid, "flow", arg[1], arg[2])
- return
- }
-
- // 保存消息
- m.Conf("flow", []string{rid, "text.list.-2"}, map[string]interface{}{
- "create_nick": m.Option("nickname"),
- "create_user": m.Option("username"),
- "create_time": m.Time(),
- "type": arg[1],
- "text": arg[2],
- })
- m.Conf("flow", []string{rid, "conf.update_time"}, m.Time())
- count := m.Confi("flow", []string{rid, "text.count"}) + 1
- m.Confi("flow", []string{rid, "text.count"}, count)
-
- m.Append("create_user", m.Option("username"))
- m.Echo("%d", count)
-
- // 分发消息
- if up == m.Conf("runtime", "node.route") {
- m.Confm("flow", []string{rid, "user"}, func(key string, value map[string]interface{}) {
- if kit.Right(value["user"]) && kit.Format(value["user"]) != m.Conf("runtime", "node.route") {
- m.Cmd("ssh._route", value["user"], "context", "chat", "river", rid, "flow", arg[1], arg[2], count, "sync")
- }
- })
- }
-
- // 推送命令
- case "wave":
- m.Cmdy("ssh._route", arg[1], "tool", "run", arg[2], arg[3], rid, arg[4:])
- }
- return
- }},
- "storm": &ctx.Command{Name: "storm rid [[delete] group [index [arg...]]]", Help: "风雨", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- // 登录失败
- if len(arg[0]) != 32 {
- arg[0] = m.Cmdx("aaa.short", arg[0])
- }
- rid, arg := arg[0], arg[1:]
-
- m.Option("river", rid)
- // 命令列表
- if len(arg) == 0 {
- m.Confm("flow", []string{rid, "tool"}, func(key string, value map[string]interface{}) {
- m.Push("key", key)
- m.Push("count", len(value["list"].([]interface{})))
- m.Push("status", kit.Format(value["status"]))
- })
- m.Sort("key").Table()
- return
- }
-
- switch arg[0] {
- // 删除命令
- case "delete":
- str := m.Conf("flow", []string{rid, "tool", arg[1]})
- m.Log("info", "delete %v %v %v", rid, arg[1], str)
- m.Conf("flow", []string{rid, "tool", arg[1]}, "")
- m.Echo(str)
-
- case "clone":
- args := []string{}
- m.Confm("flow", []string{rid, "tool", arg[2], "list"}, func(index int, value map[string]interface{}) {
- args = append(args, kit.Format(value["node"]), kit.Format(value["group"]), kit.Format(value["index"]), kit.Format(value["name"]))
- })
- m.Cmdy(".steam", rid, "spawn", arg[1], args)
-
- arg[2] = m.Conf("flow", []string{rid, "tool", arg[2], "status"})
- fallthrough
- case "save":
- if arg[2] != "" {
- m.Cmdy("ssh._route", arg[2], "web.chat.storm", rid, arg[:2], "", arg[3:])
- break
- }
- if m.Confv("flow", []string{rid, "tool", arg[1], "status"}, arg[3]); kit.Select("", arg, 4) != "" {
- m.Confv("flow", []string{rid, "tool", arg[1], "list"}, kit.UnMarshal(arg[4]))
- }
- case "load":
- if len(arg) > 2 {
- m.Cmdy("ssh._route", arg[2], "web.chat.storm", rid, arg[:2])
- break
- }
- m.Confm("flow", []string{rid, "tool", arg[1]}, func(value map[string]interface{}) {
- m.Append("status", kit.Format(value["status"]))
- m.Append("list", kit.Format(value["list"]))
- })
-
- default:
- // 命令列表
- m.Set("option", "name")
- m.Set("option", "init")
- m.Set("option", "view")
- if len(arg) == 1 {
- list := m.Confv("flow", []string{rid, "tool", arg[0], "list"})
- if m.Option("you") != "" {
- if msg := m.Cmd("ssh._route", m.Option("you"), "web.chat.storm", rid, "load", arg[0]); msg.Appends("list") {
- list = kit.UnMarshal(msg.Append("list"))
- }
- }
-
- short := m.Cmdx("aaa.short", rid)
- kit.Map(list, "", func(index int, tool map[string]interface{}) {
- m.Push("river", short)
- m.Push("storm", arg[0])
- m.Push("action", index)
-
- m.Push("node", tool["node"])
- m.Push("group", tool["group"])
- m.Push("index", tool["index"])
-
- msg := m.Cmd("ssh._route", tool["node"], "tool", tool["group"], tool["index"])
-
- m.Push("name", msg.Append("name"))
- m.Push("help", msg.Append("help"))
- m.Push("view", msg.Append("view"))
- m.Push("init", msg.Append("init"))
- m.Push("inputs", msg.Append("inputs"))
- m.Push("exports", msg.Append("exports"))
- m.Push("display", msg.Append("display"))
- m.Push("feature", msg.Append("feature"))
- })
- m.Table()
- break
- }
-
- // 推送命令
- if tool := m.Confm("flow", []string{rid, "tool", arg[0], "list", arg[1]}); tool != nil {
- m.Cmdy("ssh._route", tool["node"], "tool", "run", tool["group"], tool["index"], rid, arg[2:])
- }
- }
-
- return
- }},
- "steam": &ctx.Command{Name: "steam rid [user node]|[spawn name [route group index name]...]", Help: "天空", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- // 登录失败
- arg, rid, ok := check(m, arg)
- if !ok {
- return
- }
-
- // 上传请求
- if up := m.Conf("flow", []string{rid, "conf.route"}); up != m.Conf("runtime", "node.route") {
- m.Cmdy("ssh._remote", up, "context", "chat", "steam", rid, arg)
- return
- }
-
- // 设备列表
- if len(arg) == 0 {
- m.Confm("flow", []string{rid, "user"}, func(key string, value map[string]interface{}) {
- m.Push("user", key)
- m.Push("node", value["user"])
- })
- m.Confm("ssh.node", func(key string, value map[string]interface{}) {
- m.Push("user", value["type"])
- m.Push("node", value["name"])
- })
- m.Table()
- return
- }
-
- switch arg[0] {
- // 创建命令
- case "spawn":
- if len(arg) == 2 {
- self := m.Conf("runtime", "node.route")
- m.Confm("ssh.componet", arg[1], func(index int, value map[string]interface{}) {
- arg = append(arg, self, arg[1], kit.Format(index), kit.Format(value["name"]))
- })
- }
-
- list := []interface{}{}
- for i := 2; i < len(arg)-3; i += 4 {
- list = append(list, map[string]interface{}{
- "node": arg[i], "group": arg[i+1], "index": arg[i+2], "name": arg[i+3],
- })
- }
-
- m.Conf("flow", []string{rid, "tool", arg[1]}, map[string]interface{}{
- "create_user": m.Option("username"),
- "create_time": m.Time(),
- "list": list,
- })
-
- // 命令列表
- default:
- m.Cmdy("ssh._route", arg[1], "tool")
- }
- return
- }},
-
- "favor": &ctx.Command{Name: "favor", Help: "命令", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- m.Cmdy(arg)
- return
- }},
- "tutor": &ctx.Command{Name: "tutor", Help: "向导", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- m.Cmdy(arg)
- return
- }},
-
- "/share/": &ctx.Command{Name: "/share/", Help: "共享链接", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- h := strings.TrimPrefix(key, "/share/")
- m.Confm("share", []string{"hash", h}, func(value map[string]interface{}) {
- switch kit.Format(value["type"]) {
- case "file":
- // 下载文件
- m.Cmdy("/download/" + h)
-
- case "wiki":
- // 查看文档
- p := path.Join(path.Join("var/share", h))
- if !m.Options("force") {
- if _, e := os.Stat(p); e == nil {
- // 读取缓存
- m.Log("info", "read cache %v", p)
- r := m.Optionv("request").(*http.Request)
- w := m.Optionv("response").(http.ResponseWriter)
- http.ServeFile(w, r, p)
- break
- }
- }
-
- m.Option("title", fmt.Sprintf("%v:%v", value["dream"], value["code"]))
- m.Option("favicon", "favicon.ico")
- // 生成模板
- m.Echo(ctx.Execute(m, "share.tmpl"))
-
- // 生成文档
- m.Cmdy("ssh._route", value["dream"], "web.wiki.note", value["code"])
- if f, _, e := kit.Create(p); e == nil {
- defer f.Close()
- for _, v := range m.Meta["result"] {
- f.WriteString(v)
- }
- }
- }
-
- // 访问记录
- m.Grow("share", nil, map[string]interface{}{
- "time": m.Time(),
- "share": h,
- "type": value["type"],
- "code": value["code"],
- "sid": m.Option("sid"),
- "agent": m.Option("agent"),
- "sessid": m.Option("sessid"),
- "username": m.Option("username"),
- "remote_ip": m.Option("remote_ip"),
- })
- })
- return
- }},
- "share": &ctx.Command{Name: "share type code", Help: "共享链接", Hand: func(m *ctx.Message, c *ctx.Context, cmd string, arg ...string) (e error) {
- if len(arg) > 2 {
- switch arg[1] {
- case "delete":
- // 删除共享
- switch arg[2] {
- case "key":
- m.Log("info", "delete share %v %v", arg[3], mis.Formats(m.Conf("share", "hash."+arg[3])))
- m.Conf("share", "hash."+arg[3], "")
- }
- return
- }
- }
-
- if len(arg) < 2 {
- // 共享列表
- m.Confm("share", "hash", func(key string, value map[string]interface{}) {
- m.Push("key", key)
- m.Push("time", value["time"])
- m.Push("type", value["type"])
- m.Push("code", value["code"])
- m.Push("dream", value["dream"])
- m.Push("link", fmt.Sprintf("%s/chat/share/%s", m.Cmdx(".spide", "self", "client", "url"), key))
- })
- m.Sort("time", "time_r")
- return
- }
-
- // 共享链接
- h := kit.ShortKey(m.Confm(cmd, "hash"), 6)
- m.Confv(cmd, []string{"hash", h}, map[string]interface{}{
- "from": m.Option("username"),
- "time": m.Time(),
- "type": arg[0],
- "code": arg[1],
- "dream": m.Option("you"),
- })
- m.Echo("%s/chat/share/%s", m.Cmdx(".spide", "self", "client", "url"), h)
- return
- }},
- },
-}
-
-func init() {
- web.Index.Register(Index, &web.WEB{Context: Index})
-}
diff --git a/usr/local/honor/src/examples/chat/feishu/chat.go b/usr/local/honor/src/examples/chat/feishu/chat.go
deleted file mode 100644
index 85162b4a..00000000
--- a/usr/local/honor/src/examples/chat/feishu/chat.go
+++ /dev/null
@@ -1,358 +0,0 @@
-package chat
-
-import (
- "contexts/ctx"
- "contexts/web"
- "examples/chat"
- "toolkit"
-
- "encoding/json"
- "net/http"
- "strings"
- "time"
-)
-
-func get(m *ctx.Message, arg ...string) *ctx.Message {
- m.Option("temp_expire", -1)
- m.Option("format", "object")
- m.Cmdy("web.get", "feishu", arg, "temp", "data")
- return m
-}
-func post(m *ctx.Message, arg ...string) *ctx.Message {
- m.Option("temp_expire", -1)
- m.Option("format", "object")
- m.Cmdy("web.get", "method", "POST", "feishu", arg,
- "content_type", "application/json",
- "temp", "data",
- )
- return m
-}
-func parse(m *ctx.Message) {
- data := m.Optionv("content_data")
- if data == nil {
- json.NewDecoder(m.Optionv("request").(*http.Request).Body).Decode(&data)
- m.Optionv("content_data", data)
-
- switch d := data.(type) {
- case map[string]interface{}:
- for k, v := range d {
- switch d := v.(type) {
- case map[string]interface{}:
- for k, v := range d {
- m.Add("option", k, v)
- }
- default:
- for _, v := range kit.Trans(v) {
- m.Add("option", "msg."+k, v)
- }
- }
- }
- }
- }
- if kit.Map(kit.Chain(data, "action.value"), "", func(key string, value string) {
- m.Add("option", key, value)
- }) != nil {
- m.Option("msg.type", "event_click")
- }
- m.Log("info", "msg: %v", kit.Formats(data))
-}
-
-var Index = &ctx.Context{Name: "feishu", Help: "飞书",
- Caches: map[string]*ctx.Cache{},
- Configs: map[string]*ctx.Config{
- "app": &ctx.Config{Name: "app", Value: map[string]interface{}{}, Help: "服务配置"},
- "user": &ctx.Config{Name: "user", Value: map[string]interface{}{}, Help: "服务配置"},
- },
- Commands: map[string]*ctx.Command{
- "app": &ctx.Command{Name: "app login|token bot", Help: "应用", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if len(arg) == 0 {
- m.Confm("app", func(key string, value map[string]interface{}) {
- m.Push("key", key)
- m.Push("id", value["id"])
- })
- m.Table()
- return
- }
-
- switch arg[0] {
- case "login":
- m.Confv("app", arg[1], map[string]interface{}{"id": arg[2], "mm": arg[3]})
- case "token":
- if now := time.Now().Unix(); !m.Confs("app", []string{arg[1], "token"}) || int64(m.Confi("app", []string{arg[1], "expire"})) < now {
- post(m, "auth/v3/tenant_access_token/internal/", "app_id", m.Conf("app", []string{arg[1], "id"}),
- "app_secret", m.Conf("app", []string{arg[1], "mm"}))
- m.Conf("app", []string{arg[1], "token"}, m.Append("tenant_access_token"))
- m.Conf("app", []string{arg[1], "expire"}, int64(m.Appendi("expire"))+now)
- m.Set("result")
- }
- m.Echo(m.Conf("app", []string{arg[1], "token"}))
- }
- return
- }},
- "ship": &ctx.Command{Name: "ship", Help: "组织", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- data := kit.UnMarshal(m.Cmdx("web.get", "feishu", "contact/v1/scope/get/",
- "headers", "Authorization", "Bearer "+m.Cmdx(".app", "token", "bot"),
- ))
- kit.Map(kit.Chain(data, "data.authed_departments"), "", func(index int, value string) {
- m.Push("type", "ship")
- m.Push("value", value)
- })
- kit.Map(kit.Chain(data, "data.authed_open_ids"), "", func(index int, value string) {
- m.Push("type", "user")
- m.Push("value", value)
- })
- m.Table()
- return
- }},
- "group": &ctx.Command{Name: "group", Help: "群组", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if len(arg) == 0 {
- kit.Map(kit.Chain(kit.UnMarshal(m.Cmdx("web.get", "feishu", "chat/v4/list", "headers", "Authorization", "Bearer "+m.Cmdx(".app", "token", "bot"))),
- "data.groups"), "", func(index int, value map[string]interface{}) {
- m.Push("key", value["chat_id"])
- m.Push("name", value["name"])
- m.Push("avatar", value["avatar"])
- })
- m.Table()
- }
- kit.Map(kit.Chain(kit.UnMarshal(m.Cmdx("web.get", "feishu", "chat/v4/info", "headers", "Authorization", "Bearer "+m.Cmdx(".app", "token", "bot"))),
- "data.members"), "", func(index int, value map[string]interface{}) {
- m.Push("key", value["open_id"])
- })
- m.Table()
- return
- }},
- "user": &ctx.Command{Name: "user code|email|mobile", Help: "用户", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- switch arg[0] {
- case "code":
- post(m, "/connect/qrconnect/oauth2/access_token/",
- "app_secret", m.Conf("app", []string{"bot", "mm"}), "app_id", m.Conf("app", []string{"bot", "id"}),
- "grant_type", "authorization_code", "code", arg[1],
- )
- msg := get(m.Spawn(), "/connect/qrconnect/oauth2/user_info/",
- "headers", "Authorization", "Bearer "+m.Append("access_token"),
- )
- m.Confv("user", m.Append("open_id"), map[string]interface{}{
- "name": m.Append("name"),
- "en_name": m.Append("en_name"),
- "avatar_url": m.Append("avatar_url"),
- "access_token": m.Append("access_token"),
- "token_type": m.Append("token_type"),
- "expire": int64(m.Appendi("expire")) + time.Now().Unix(),
- "refresh_token": m.Append("refresh_token"),
- "tenant_key": m.Append("tenant_key"),
-
- "email": msg.Append("Email"),
- "mobile": msg.Append("Mobile"),
- "status": msg.Append("status"),
- "employee": msg.Append("EmployeeID"),
- })
-
- default:
- us := []string{}
- ps := []string{}
- for i := 0; i < len(arg); i++ {
- us = append(us, kit.Select("mobiles", "emails", strings.Contains(arg[i], "@")), arg[i])
- ps = append(ps, kit.Select("mobile", "email", strings.Contains(arg[i], "@"))+"_users")
- }
-
- data := kit.UnMarshal(m.Cmdx("web.get", "feishu", "user/v1/batch_get_id", us,
- "headers", "Authorization", "Bearer "+m.Cmdx(".app", "token", "bot")))
-
- for i, v := range ps {
- m.Append(arg[i], kit.Chain(data, []string{"data", v, arg[i], "0", "open_id"}))
- }
- m.Table()
- }
- return
- }},
- "send": &ctx.Command{Name: "send [chat_id|open_id|user_id|email] who [menu] [title] text", Help: "消息", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- var form = map[string]interface{}{"content": map[string]interface{}{}}
- switch arg[0] {
- case "chat_id", "open_id", "user_id", "email":
- form[arg[0]], arg = arg[1], arg[2:]
- default:
- form["chat_id"], arg = arg[0], arg[1:]
- }
-
- switch arg[0] {
- case "menu":
- elements := []interface{}{}
- elements = append(elements, map[string]interface{}{
- "tag": "div",
- "text": map[string]interface{}{
- "tag": "plain_text",
- "content": arg[2],
- },
- })
-
- actions := []interface{}{}
- for i := 3; i < len(arg); i++ {
- button := map[string]interface{}{
- "tag": "button", "text": map[string]interface{}{
- "tag": "plain_text", "content": arg[i],
- },
- "type": "default",
- }
-
- switch arg[i+1] {
- case "confirm":
- button[arg[i+1]], i = map[string]interface{}{
- "title": map[string]interface{}{"tag": "lark_md", "content": arg[i+2]},
- "text": map[string]interface{}{"tag": "lark_md", "content": arg[i+3]},
- }, i+3
- case "value":
- button[arg[i+1]], i = map[string]interface{}{
- arg[i+2]: arg[i+3],
- }, i+3
- case "url":
- button[arg[i+1]], i = arg[i+2], i+2
- default:
- button["value"], i = map[string]interface{}{
- arg[i+1]: arg[i+2],
- }, i+2
- }
-
- actions = append(actions, button)
- }
- elements = append(elements, map[string]interface{}{
- "tag": "action", "actions": actions,
- })
-
- kit.Chain(form, "msg_type", "interactive")
- kit.Chain(form, "card", map[string]interface{}{
- "config": map[string]interface{}{
- "wide_screen_mode": true,
- // "title": map[string]interface{}{
- // "tag": "lark_md", "content": arg[1],
- // },
- },
- "header": map[string]interface{}{
- "title": map[string]interface{}{
- "tag": "lark_md", "content": arg[1],
- },
- },
- "elements": elements,
- })
- default:
- switch len(arg) {
- case 0:
- case 1:
- kit.Chain(form, "msg_type", "text")
- kit.Chain(form, "content.text", arg[0])
- default:
- content := []interface{}{}
- line := []interface{}{}
- for _, v := range arg[1:] {
- if v == "\n" {
- content, line = append(content, line), []interface{}{}
- continue
- }
- line = append(line, map[string]interface{}{
- "tag": "text", "text": v,
- })
- }
- content = append(content, line)
-
- kit.Chain(form, "msg_type", "post")
- kit.Chain(form, "content.post", map[string]interface{}{
- "zh_cn": map[string]interface{}{
- "title": arg[0],
- "content": content,
- },
- })
- }
-
- }
-
- m.Cmdy("web.get", "method", "POST", "feishu", "message/v4/send/",
- "headers", "Authorization", "Bearer "+m.Cmdx(".app", "token", "bot"),
- "content_data", kit.Formats(form), "content_type", "application/json",
- "temp", "data", "data.message_id",
- )
- return
- }},
- "/msg": &ctx.Command{Name: "/msg", Help: "消息", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- parse(m)
-
- switch m.Option("msg.type") {
- case "url_verification":
- m.Echo(kit.Format(map[string]interface{}{"challenge": m.Option("challenge")}))
-
- case "event_callback":
- switch m.Option("type") {
- case "chat_disband":
- case "p2p_chat_create":
- if m.Options("open_chat_id") {
- m.Cmdy(".send", m.Option("open_chat_id"), "我们做朋友吧~")
- }
- case "add_bot":
- if m.Options("open_chat_id") {
- m.Cmdy(".send", m.Option("open_chat_id"), "我来也~")
- }
- default:
- if m.Options("open_chat_id") {
- m.Option("username", m.Option("open_id"))
- m.Option("sessid", m.Cmdx("aaa.user", "session", "select"))
- m.Cmd("ssh._check", "work", "create", m.Option("username"))
- m.Goshy([]string{m.Option("text_without_at_bot")}, 0, nil, func(msg *ctx.Message) {
- m.Cmdy(".send", m.Option("open_chat_id"), kit.Select("你好", strings.Join(msg.Meta["result"], "")))
- })
- }
- }
- case "event_click":
- m.Echo(kit.Format(map[string]interface{}{
- "header": map[string]interface{}{
- "title": map[string]interface{}{
- "tag": "lark_md", "content": "haha",
- },
- },
- "elements": []interface{}{
- map[string]interface{}{
- "tag": "action",
- "actions": []interface{}{
- map[string]interface{}{
- "tag": "button",
- "type": "default",
- "text": map[string]interface{}{
- "tag": "plain_text",
- "content": m.Time(),
- },
- "value": map[string]interface{}{
- "hi": "hello",
- },
- },
- },
- },
- },
- }))
- }
- return
- }},
- "/sso": &ctx.Command{Name: "/sso", Help: "消息", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- if m.Options("code") {
- m.Option("username", m.Cmd(".user", "code", m.Option("code")).Append("open_id"))
- m.Option("sessid", m.Cmdx("aaa.user", "session", "select"))
- m.Cmd("ssh._check", "work", "create", m.Option("username"))
-
- w := m.Optionv("response").(http.ResponseWriter)
- r := m.Optionv("request").(*http.Request)
- web.Cookie(m, w, r)
- m.Append("redirect", m.Cmdx("web.spide", "serve", "merge", m.Option("index_path")), "code", "")
- return
- }
-
- if !m.Options("sessid") || !m.Options("username") {
- m.Append("redirect", m.Cmdx("web.spide", "feishu", "merge", "/connect/qrconnect/page/sso/",
- "redirect_uri", m.Cmdx("web.spide", "serve", "merge", m.Option("index_path")),
- "app_id", m.Conf("app", "bot.id"), "state", "ok"))
- return
- }
- m.Cmd("/render")
- return
- }},
- },
-}
-
-func init() {
- chat.Index.Register(Index, &web.WEB{Context: Index})
-}
diff --git a/usr/local/honor/src/examples/code/code.go b/usr/local/honor/src/examples/code/code.go
deleted file mode 100644
index 149bab01..00000000
--- a/usr/local/honor/src/examples/code/code.go
+++ /dev/null
@@ -1,1148 +0,0 @@
-package code
-
-import (
- "github.com/shylinux/icebergs/base/ctx"
- "github.com/shylinux/icebergs/base/web"
- kit "github.com/shylinux/toolkits"
-
- "fmt"
- "io/ioutil"
- "net/http"
- "os"
- "os/exec"
- "path"
- "regexp"
- "strings"
- "time"
-)
-
-var Dockfile = `
-FROM {{options . "base"}}
-
-WORKDIR /home/{{options . "user"}}/context
-Env ctx_dev {{options . "host"}}
-
-RUN wget -q -O - $ctx_dev/publish/boot.sh | sh -s install
-
-CMD sh bin/boot.sh
-
-`
-
-var Index = &ctx.Context{Name: "code", Help: "代码中心",
- Caches: map[string]*ctx.Cache{},
- Configs: map[string]*ctx.Config{
- "prefix": {Name: "prefix", Help: "外部命令", Value: map[string]interface{}{
- "zsh": []interface{}{"cli.system", "zsh"},
- "tmux": []interface{}{"cli.system", "tmux"},
- "docker": []interface{}{"cli.system", "docker"},
- "git": []interface{}{"cli.system", "git"},
- "vim": []interface{}{"cli.system", "vim"},
- }},
- "package": {Name: "package", Help: "软件包", Value: map[string]interface{}{
- "apk": map[string]interface{}{"update": "update", "install": "add",
- "base": []interface{}{"curl", "bash"},
- },
- "apt": map[string]interface{}{"update": "update", "install": "install -y",
- "base": []interface{}{"wget", "curl"},
- },
- "yum": map[string]interface{}{"update": "update -y", "install": "install",
- "base": []interface{}{"wget"},
- },
-
- "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{}{
- "template": map[string]interface{}{"shy": Dockfile},
- "output": "etc/Dockerfile",
- }},
- "tmux": {Name: "tmux", Help: "终端", Value: map[string]interface{}{
- "favor": map[string]interface{}{
- "index": []interface{}{
- "ctx_dev ctx_share",
- "curl -s $ctx_dev/publish/auto.sh >auto.sh",
- "source auto.sh",
- "ShyLogin",
- },
- },
- }},
- "git": {Name: "git", Help: "记录", Value: map[string]interface{}{
- "alias": map[string]interface{}{"s": "status", "b": "branch"},
- }},
- "cache": {Name: "cache", Help: "缓存默认的全局配置", Value: map[string]interface{}{
- "store": "var/tmp/hi.csv",
- "limit": 6,
- "least": 3,
- }},
-
- "zsh": {Name: "zsh", Help: "命令行", Value: map[string]interface{}{
- "history": map[string]interface{}{"meta": map[string]interface{}{
- "fields": "time sid cmd pwd",
- "store": "var/tmp/zsh/history.csv",
- "limit": "30",
- "least": "10",
- }},
- "free": map[string]interface{}{"meta": map[string]interface{}{
- "fields": "time sid type total used free shared buffer available",
- "store": "var/tmp/zsh/free.csv",
- "limit": "30",
- "least": "10",
- }},
- "env": map[string]interface{}{"meta": map[string]interface{}{
- "fields": "sid name value",
- }},
- "ps": map[string]interface{}{"meta": map[string]interface{}{
- "fields": "sid UID PID PPID TTY CMD",
- }},
- "df": map[string]interface{}{"meta": map[string]interface{}{
- "fields": "sid fs size used rest per pos",
- }},
- }},
- "vim": {Name: "vim", Help: "编辑器", Value: map[string]interface{}{
- "opens": map[string]interface{}{"meta": map[string]interface{}{
- "fields": "time sid action file pwd",
- "store": "var/tmp/vim/opens.csv",
- "limit": "30",
- "least": "10",
- }},
- "cmds": map[string]interface{}{"meta": map[string]interface{}{
- "fields": "time sid cmd file pwd",
- "store": "var/tmp/vim/cmds.csv",
- "limit": "30",
- "least": "10",
- }},
- "txts": map[string]interface{}{"meta": map[string]interface{}{
- "fields": "time sid word line col file pwd",
- "store": "var/tmp/vim/txts.csv",
- "limit": "30",
- "least": "10",
- }},
-
- "bufs": map[string]interface{}{"meta": map[string]interface{}{
- "fields": "buf tag file line",
- }},
- "regs": map[string]interface{}{"meta": map[string]interface{}{
- "fields": "reg word",
- }},
- "marks": map[string]interface{}{"meta": map[string]interface{}{
- "fields": "mark line col file",
- }},
- "tags": map[string]interface{}{"meta": map[string]interface{}{
- "fields": "tag line file",
- }},
- "fixs": map[string]interface{}{"meta": map[string]interface{}{
- "fields": "fix file line word",
- }},
- }},
-
- "login": {Name: "login", Value: map[string]interface{}{"check": false, "local": true, "expire": "720h", "meta": map[string]interface{}{
- "fields": "time sid type status ship.dream ship.stage pwd pid pane hostname username",
- "script": "usr/script",
- }, "hash": map[string]interface{}{}}, Help: "用户登录"},
- "dream": {Name: "dream", Help: "使命必达", Value: map[string]interface{}{
- "layout": map[string]interface{}{
- "three": []interface{}{
- "rename-window -t $dream:1 source",
- "split-window -t $dream:1.1",
- "split-window -v -t $dream:1.2",
- "select-layout -t $dream:1 main-horizontal",
-
- "new-window -t $dream:2 -n docker",
- "split-window -t $dream:2.1",
- "split-window -v -t $dream:2.2",
- "select-layout -t $dream:2 main-horizontal",
-
- "new-window -t $dream:3 -n online",
- "split-window -t $dream:3.1",
- "split-window -v -t $dream:3.2",
- "select-layout -t $dream:3 main-horizontal",
- },
- },
- "topic": map[string]interface{}{
- "index": map[string]interface{}{
- "ship": []interface{}{"tip", "miss.md", "task", "feed"},
- "git": []interface{}{},
- // "git": []interface{}{"clone https://github.com/shylinux/context"},
- "layout": []interface{}{"three"}, "tmux": []interface{}{
- "send-keys -t $dream.1.1 pwd",
- },
- },
- },
- "share": map[string]interface{}{"meta": map[string]interface{}{
- "fields": "river dream favor story stage order expire",
- }, "hash": map[string]interface{}{}},
- "favor": map[string]interface{}{"meta": map[string]interface{}{
- "fields": "tab note word file line col",
- }},
- }},
- },
- Commands: map[string]*ctx.Command{
- "dream": {Name: "dream init name [topic]", Help: "使命必达", Hand: func(m *ctx.Message, c *ctx.Context, cmd string, arg ...string) (e error) {
- switch arg[0] {
- case "init":
- // 检查会话
- tmux := kit.Trans(m.Confv("prefix", "tmux"))
- if !m.Cmds(tmux, "has-session", "-t", arg[1]) {
- break
- }
-
- // 下载代码
- home := path.Join(m.Conf("missyou", "path"), arg[1], m.Conf("missyou", "local"))
- topic := kit.Select("index", kit.Select(m.Option("topic"), arg, 2))
- git := kit.Trans(m.Confv("prefix", "git"), "cmd_dir", home)
- m.Confm(cmd, []string{"topic", topic, "git"}, func(index int, value string) {
- value = strings.Replace(value, "$dream", arg[1], -1)
- m.Cmd(git, strings.Split(value, " "))
- })
-
- // 创建文档
- m.Cmd("cli.system", "mkdir", "-p", path.Join(home, "wiki"))
- m.Cmd("cli.system", "touch", path.Join(home, "wiki/miss.md"))
-
- // 创建终端
- share := m.Cmdx(cmd, "share", topic)
- m.Cmd(tmux, "set-environment", "-g", "ctx_share", share)
- m.Cmd(tmux, "new-session", "-ds", arg[1], "cmd_dir", home, "cmd_env", "TMUX", "")
- m.Cmd(tmux, "set-environment", "-t", arg[1], "ctx_share", share)
- m.Cmd(tmux, "set-environment", "-t", arg[1], "ctx_dev", os.Getenv("ctx_self"))
- m.Confm(cmd, []string{"layout", m.Conf(cmd, []string{"topic", topic, "layout", "0"})}, func(index int, value string) {
- value = strings.Replace(value, "$dream", arg[1], -1)
- m.Cmd(tmux, strings.Split(value, " "), "cmd_dir", home)
- })
- m.Confm(cmd, []string{"topic", topic, "tmux"}, func(index int, value string) {
- value = strings.Replace(value, "$dream", arg[1], -1)
- m.Cmd(tmux, strings.Split(value, " "), "cmd_dir", home)
- })
- m.Echo(share)
-
- case "share":
- // 模板参数
- topic := kit.Select("index", kit.Select(m.Option("topic"), arg, 1))
- m.Confm(cmd, []string{"topic", topic, "ship"}, func(index int, value string) {
- if len(arg) < index+3 {
- arg = append(arg, value)
- } else if arg[index+2] == "" {
- arg[index+2] = value
- }
- })
- // 共享链接
- h := kit.ShortKey(m.Confm(cmd, []string{"share", "hash"}), 6)
- m.Confv(cmd, []string{"share", "hash", h}, map[string]interface{}{
- "river": m.Option("river"), "dream": m.Option("dream"),
- "favor": arg[2], "story": arg[3], "stage": arg[4], "order": arg[5],
- "topic": topic, "share": h, "expire": m.Time("10m", "stamp"),
- })
- m.Echo(h)
-
- case "list":
- m.Confm(cmd, "share.hash", func(key string, value map[string]interface{}) {
- m.Push("key", key).Push(m.Conf(cmd, "share.meta.fields"), value)
- })
- m.Table()
-
- case "exit":
- }
- return
- }},
- "login": {Name: "login open|init|list|exit|quit", Help: "登录", Hand: func(m *ctx.Message, c *ctx.Context, cmd string, arg ...string) (e error) {
-
- switch kit.Select("list", arg, 0) {
- case "open":
- case "init":
- if m.Option("sid") != "" {
- if m.Confs(cmd, []string{"hash", m.Option("sid"), "status"}) {
- m.Conf(cmd, []string{"hash", m.Option("sid"), "status"}, "login")
- m.Echo(m.Option("sid"))
- return
- }
- }
-
- // 添加终端
- h := kit.ShortKey(m.Confm(cmd, "hash"), 6, m.Option("pid"), m.Option("hostname"), m.Option("username"))
- m.Conf(cmd, []string{"hash", h}, map[string]interface{}{
- "time": m.Time(),
- "status": "login",
- "type": kit.Select("vim", arg, 1),
- "ship": m.Confv("dream", []string{"share", "hash", m.Option("share")}),
- "pwd": m.Option("pwd"),
- "pid": m.Option("pid"),
- "pane": m.Option("pane"),
- "hostname": m.Option("hostname"),
- "username": m.Option("username"),
- })
- m.Echo(h)
-
- case "list":
- if len(arg) > 4 {
- sid := kit.Select(m.Option("sid"), arg[3])
- switch arg[4] {
- case "prune":
- // 清理终端
- m.Cmd(".prune", m.Conf("login", []string{"hash", sid, "type"}), sid)
- arg = arg[:2]
- case "modify":
- // 修改终端
- m.Conf(cmd, []string{"hash", sid, arg[5]}, arg[6])
- arg = arg[:2]
- }
- }
-
- // 终端列表
- if len(arg) == 2 || arg[2] == "" {
- fields := strings.Split(m.Conf(cmd, "meta.fields"), " ")
- m.Confm(cmd, "hash", func(key string, value map[string]interface{}) {
- if arg[1] == "" || arg[1] == kit.Format(value["type"]) {
- value["sid"] = key
- m.Push(fields, value)
- }
- })
- m.Table()
- break
- }
-
- // 终端绑定
- if len(arg) > 4 && arg[4] != "" && arg[4] != m.Conf(cmd, []string{"hash", arg[2], "ship", "topic"}) && m.Confs(cmd, []string{"hash", arg[2]}) {
- share := m.Cmdx("dream", "share", arg[4:])
- m.Conf(cmd, []string{"hash", arg[2], "ship"},
- m.Confv("dream", []string{"share", "hash", share}))
- }
- if len(arg) > 3 && arg[3] != "" {
- m.Conf(cmd, []string{"hash", arg[2], "ship", "dream"}, arg[3])
- }
-
- // 终端详情
- m.Option("table.format", "table")
- m.Confm(cmd, []string{"hash", arg[2], "ship"}, func(key string, value string) {
- m.Push("ship."+key, value)
- })
- m.Confm(cmd, []string{"hash", arg[2]}, func(key string, value string) {
- if key != "ship" {
- m.Push(key, value)
- }
- })
- m.Sort("key")
-
- case "exit":
- // 退出终端
- if m.Confs(cmd, []string{"hash", m.Option("sid")}) {
- m.Conf(cmd, []string{"hash", m.Option("sid"), "status"}, "logout")
- m.Conf(cmd, []string{"hash", m.Option("sid"), "time"}, m.Time())
- }
- case "quit":
- }
- return
- }},
- "favor": {Name: "favor download|upload|file|post|list", Help: "收藏", Hand: func(m *ctx.Message, c *ctx.Context, cmd string, arg ...string) (e error) {
- switch arg[0] {
- case "download":
- // 下载文件
- if len(arg) > 1 && arg[1] != "" {
- m.Cmd("/download/", "", arg[1])
- break
- }
- // 下载列表
- m.Cmd("ssh._route", m.Option("dream"), "ssh.data", "show", "file").Table(func(index int, value map[string]string) {
- m.Push("hash", value["hash"])
- m.Push("time", value["upload_time"])
- m.Push("size", kit.FmtSize(int64(kit.Int(value["size"]))))
- m.Push("name", value["name"])
- })
- m.Table().Set("append")
-
- case "upload":
- // 上传文件
- if m.Cmd("/upload"); m.Options("dream") {
- // 下发文件
- m.Cmd("ssh._route", m.Option("dream"), "web.get", "dev", "/download/"+m.Append("hash"),
- "save", m.Conf("login", "meta.script")+"/"+m.Append("name"))
- }
- m.Echo("code: %s\n", m.Append("code"))
- m.Echo("hash: %s\n", m.Append("hash"))
- m.Echo("time: %s\n", m.Append("time"))
- m.Echo("type: %s\n", m.Append("type"))
- m.Echo("size: %s\n", m.Append("size"))
- m.Set("append")
-
- case "file":
- // 文件列表
- if len(arg) > 2 && arg[2] != "" {
- m.Cmdy("ssh.data", "show", arg[1:3])
- break
- }
- m.Cmd("ssh.data", "show", arg[1:]).Table(func(index int, value map[string]string) {
- m.Push("id", value["id"])
- m.Push("time", value["upload_time"])
- m.Push("name", value["name"])
- m.Push("size", kit.FmtSize(int64(kit.Int(value["size"]))))
- m.Push("file", fmt.Sprintf(`%s`, kit.Select(value["hash"], value["code"]), value["name"]))
- m.Push("hash", kit.Short(value["hash"], 6))
- })
- m.Table()
-
- case "post":
- // 上传记录
- if len(arg) < 3 || arg[2] == "" {
- break
- }
- args := []string{}
- for i, v := range strings.Split(kit.Select("tab note word file line", m.Conf("dream", "favor.meta.fields")), " ") {
- args = append(args, v, kit.Select("", arg, i+2))
- }
- m.Cmdy("ssh.data", "insert", arg[1], args)
-
- case "list":
- if len(arg) > 3 && arg[3] == "modify" {
- m.Cmd("ssh.data", "update", arg[1], arg[2], arg[4], arg[5])
- arg = arg[:3]
- }
- m.Cmdy("ssh.data", "show", arg[1:])
- }
- return
- }},
- "trend": {Name: "trend post|list", Help: "趋势", Hand: func(m *ctx.Message, c *ctx.Context, cmd string, arg ...string) (e error) {
- switch arg[0] {
- case "post":
- m.Cmdy("ssh.data", "insert", arg[1], arg[2:])
-
- case "list":
- if len(arg) > 3 && arg[3] == "modify" {
- m.Cmd("ssh.data", "update", arg[1], arg[2], arg[4], arg[5])
- arg = arg[:3]
- }
- m.Cmdy("ssh.data", "show", arg[1:])
- }
- return
- }},
- "state": {Name: "state post|list agent type", Help: "状态", Hand: func(m *ctx.Message, c *ctx.Context, cmd string, arg ...string) (e error) {
- switch arg[0] {
- case "post":
- data := map[string]interface{}{}
- for i := 3; i < len(arg)-1; i += 2 {
- kit.Chain(data, arg[i], arg[i+1])
- }
- m.Confv(arg[1], []string{arg[2], "hash", m.Option("sid"), "-2"}, data)
-
- case "list":
- if len(arg) > 6 {
- arg[6] = strings.Join(arg[6:], " ")
- }
- fields := strings.Split(kit.Select(m.Conf(arg[1], arg[2]+".meta.fields"), arg, 6), " ")
- m.Confm(arg[1], []string{arg[2], "hash"}, func(key string, index int, value map[string]interface{}) {
- if arg[3] != "" && key != arg[3] {
- return
- }
- if value["sid"] = key; len(arg) < 6 || arg[4] == "" || strings.HasPrefix(kit.Format(value[arg[4]]), arg[5]) {
- m.Push(fields, value)
- }
- })
- }
- return
- }},
- "prune": {Name: "prune type all|sid...", Help: "清理", Hand: func(m *ctx.Message, c *ctx.Context, cmd string, arg ...string) (e error) {
- ps := arg[1:]
- if len(ps) == 0 || ps[0] == "all" {
- m.Confm("login", "hash", func(key string, value map[string]interface{}) {
- if value["type"] == arg[0] && (kit.Format(value["status"]) == "logout" || len(ps) > 0) {
- ps = append(ps, key)
- }
- })
- }
-
- for _, p := range ps {
- m.Confm(arg[0], func(key string, value map[string]interface{}) {
- m.Log("info", "prune %v:%v %v:%v", arg[0], key, p, kit.Formats(kit.Chain(value, []string{"hash", p})))
- kit.Chain(value, []string{"hash", p}, "")
- })
-
- m.Log("info", "prune %v %v:%v", "login", p, kit.Formats(m.Confv("login", []string{"hash", p})))
- m.Confv("login", []string{"hash", p}, "")
- }
- return
- }},
-
- "/zsh": {Name: "/zsh sid pwd cmd arg", Help: "命令行", Hand: func(m *ctx.Message, c *ctx.Context, cmd string, arg ...string) (e error) {
- cmd = strings.TrimPrefix(cmd, "/")
- if f, _, e := m.Optionv("request").(*http.Request).FormFile("sub"); e == nil {
- defer f.Close()
- if b, e := ioutil.ReadAll(f); e == nil {
- m.Option("sub", string(b))
- }
- }
- m.Log("info", "%v %v %v %v", cmd, m.Option("cmd"), m.Option("arg"), m.Option("sub"))
- m.Confm("login", []string{"hash", m.Option("sid"), "ship"}, func(key string, value string) { m.Option(key, value) })
-
- switch m.Option("cmd") {
- case "help":
- m.Echo(strings.Join(kit.Trans(m.Confv("help", "index")), "\n"))
- case "login":
- m.Cmd("login", "init", cmd)
- case "logout":
- m.Cmd("login", "exit")
- case "upload":
- m.Cmd("favor", "upload")
- case "download":
- m.Cmd("favor", "download", m.Option("arg"))
- case "favor":
- m.Log("info", "river: %v dream: %v favor: %v", m.Option("river"), m.Option("dream"), m.Option("favor"))
- // 添加收藏
- prefix := []string{"ssh._route", m.Option("dream"), "web.code.favor"}
- if m.Options("arg") {
- m.Option("arg", strings.SplitN(strings.TrimSpace(m.Option("arg")), " ", 2)[1])
- m.Cmdy(prefix, "post", m.Option("favor"), m.Option("tab"), m.Option("note"), m.Option("arg"))
- m.Set("append")
- break
- }
-
- // 生成脚本
- m.Echo("#/bin/sh\n\n")
- m.Cmd(prefix, "list", m.Option("favor"), "", kit.Select("1000", m.Option("limit")), "0", "tab", m.Option("tab")).Table(func(index int, value map[string]string) {
- m.Echo("# %v:%v\n%v\n\n", value["tab"], value["note"], value["word"])
- })
-
- case "history":
- vs := strings.SplitN(strings.TrimSpace(m.Option("arg")), " ", 2)
- m.Cmd("trend", "post", "zsh.history", "sid", m.Option("sid"),
- "num", vs[0], "cmd", kit.Select("", vs, 1), "pwd", m.Option("pwd"))
- m.Set("append").Set("result")
-
- case "sync":
- m.Confv(cmd, []string{m.Option("arg"), "hash", m.Option("sid")}, []interface{}{})
- switch m.Option("arg") {
- case "free":
- sub := strings.Replace(m.Option("sub"), " ", "type", 1)
- m.Split(sub, " ", "7", "type total used free shared buffer available").Table(func(index int, value map[string]string) {
- if index == 1 {
- m.Cmd("trend", "post", "zsh.free", value)
- }
- })
- case "env":
- m.Split(strings.TrimPrefix(m.Option("sub"), "\n"), "=", "2", "name value").Table(func(index int, value map[string]string) {
- m.Cmd("state", "post", cmd, m.Option("arg"), value)
- })
- case "ps":
- m.Split(m.Option("sub"), " ", "8", "UID PID PPID C STIME TTY TIME CMD").Table(func(index int, value map[string]string) {
- if index > 0 {
- m.Cmd("state", "post", cmd, m.Option("arg"), value)
- }
- })
- case "df":
- m.Split(m.Option("sub"), " ", "6", "fs size used rest per pos").Table(func(index int, value map[string]string) {
- if index > 0 {
- m.Cmd("state", "post", cmd, m.Option("arg"), value)
- }
- })
- }
- m.Set("append").Set("result")
- }
- return
- }},
- "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, "limit": 2},
- Help: "终端", Hand: func(m *ctx.Message, c *ctx.Context, cmd string, arg ...string) (e error) {
- if len(arg) == 0 {
- arg = append(arg, "")
- }
- p, arg := kit.Select(".", arg[0]), arg[1:]
- switch arg[0] {
- case "init":
- 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 "git":
- if s, e := os.Stat(path.Join(p, ".git")); e == nil && s.IsDir() || arg[1] == "init" {
- m.Cmdy(".git", p, arg[1:])
- break
- }
-
- fallthrough
- case "list":
- m.Cmdy("nfs.dir", p, "time", "size", "path").Sort("time", "time_r").Table()
-
- case "find":
- 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{}
- for _, v := range strings.Split(kit.Select("", m.Optionv("split"), 1), " ") {
- if v != "" {
- fields[v] = true
- }
- }
-
- 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"])
- for _, v := range ls {
- if len(fields) == 0 || fields[v[1]] {
- m.Push(v[1], v[2])
- }
- }
- }
- })
- m.Table()
- } else {
- m.Cmdy(prefix)
- }
-
- if m.Has("filter") {
- m.Filter(m.Option("filter"))
- }
- if m.Has("order") {
- m.Sort(kit.Select("", m.Optionv("order"), 0), kit.Select("", m.Optionv("order"), 1))
- }
- if m.Has("group") {
- m.Group(kit.Select("sum", m.Optionv("group"), 1), strings.Split(kit.Select("", m.Option("group"), 0), " ")...)
- }
- if m.Has("sort") {
- m.Sort(kit.Select("", m.Optionv("sort"), 0), kit.Select("", m.Optionv("sort"), 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)
- }
- return
- }},
- "tmux": {Name: "tmux [session [window [pane cmd]]]", Help: "窗口", Hand: func(m *ctx.Message, c *ctx.Context, cmd string, arg ...string) (e error) {
- prefix := kit.Trans(m.Confv("prefix", "tmux"))
- if len(arg) > 1 {
- switch arg[1] {
- case "cmd":
-
- case "pane":
- prefix = append(prefix, "list-panes")
- if arg[0] == "" {
- prefix = append(prefix, "-a")
- } else {
- prefix = append(prefix, "-s", "-t", arg[0])
- }
- m.Cmdy(prefix, "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
-
- case "favor":
- env := m.Cmdx(prefix, "show-environment", "-g") + m.Cmdx(prefix, "show-environment", "-t", arg[0])
- for _, l := range strings.Split(env, "\n") {
- if strings.HasPrefix(l, "ctx_") {
- v := strings.SplitN(l, "=", 2)
- m.Option(v[0], v[1])
- }
- }
- m.Option("ctx_dev", m.Option("ctx_self"))
-
- m.Confm("tmux", "favor."+kit.Select("index", arg, 4), func(index int, value string) {
- if index == 0 {
- keys := strings.Split(value, " ")
- value = "export"
- for _, k := range keys {
- value += " " + k + "=" + m.Option(k)
- }
-
- }
- m.Cmdy(prefix, "send-keys", "-t", arg[0], value, "Enter")
- time.Sleep(100 * time.Millisecond)
- })
- m.Echo(strings.TrimSpace(m.Cmdx(prefix, "capture-pane", "-pt", arg[0])))
- return
-
- case "buffer":
- // 写缓存
- if len(arg) > 5 {
- switch arg[3] {
- case "modify":
- switch arg[4] {
- case "text":
- m.Cmdy(prefix, "set-buffer", "-b", arg[2], arg[5])
- }
- }
- } else if len(arg) > 3 {
- m.Cmd(prefix, "set-buffer", "-b", arg[2], arg[3])
- }
-
- // 读缓存
- if len(arg) > 2 {
- m.Cmdy(prefix, "show-buffer", "-b", arg[2])
- return
- }
-
- m.Cmdy(prefix, "list-buffers", "cmd_parse", "cut", ": ", "3", "buffer size text")
- for i, v := range m.Meta["text"] {
- if i < 3 {
- m.Meta["text"][i] = m.Cmdx(prefix, "show-buffer", "-b", m.Meta["buffer"][i])
- } else {
- m.Meta["text"][i] = v[2 : len(v)-1]
- }
- }
- return
-
- case "select":
- // 切换会话
- if !m.Has("session") {
- m.Cmd(prefix, "switch-client", "-t", arg[0])
- arg = arg[:0]
- break
- }
- m.Cmd(prefix, "switch-client", "-t", m.Option("session"))
-
- // 切换窗口
- if !m.Has("window") {
- m.Cmd(prefix, "select-window", "-t", m.Option("session")+":"+arg[0])
- arg = []string{m.Option("session")}
- break
- }
- m.Cmd(prefix, "select-window", "-t", m.Option("session")+":"+m.Option("window"))
-
- // 切换终端
- m.Cmd(prefix, "select-pane", "-t", m.Option("session")+":"+m.Option("window")+"."+arg[0])
- arg = []string{m.Option("session"), m.Option("window")}
-
- case "modify":
- switch arg[2] {
- case "session":
- // 重命名会话
- m.Cmdy(prefix, "rename-session", "-t", arg[0], arg[3])
- arg = arg[:0]
-
- case "window":
- // 重命名窗口
- m.Cmdy(prefix, "rename-window", "-t", m.Option("session")+":"+arg[0], arg[3])
- arg = []string{m.Option("session")}
-
- default:
- return
- }
- case "delete":
- // 删除会话
- if !m.Has("session") {
- m.Cmdy(prefix, "kill-session", "-t", arg[0])
- arg = arg[:0]
- break
- }
-
- // 删除窗口
- if !m.Has("window") {
- m.Cmdy(prefix, "kill-window", "-t", m.Option("session")+":"+arg[0])
- arg = []string{m.Option("session")}
- break
- }
-
- // 删除终端
- m.Cmd(prefix, "kill-pane", "-t", m.Option("session")+":"+m.Option("window")+"."+arg[3])
- arg = []string{m.Option("session"), m.Option("window")}
- }
- }
-
- // 查看会话
- if m.Cmdy(prefix, "list-session", "-F", "#{session_id},#{session_attached},#{session_name},#{session_windows},#{session_height},#{session_width}",
- "cmd_parse", "cut", ",", "6", "id tag session windows height width"); len(arg) == 0 {
- return
- }
-
- // 创建会话
- if arg[0] != "" && !kit.Contains(m.Meta["session"], arg[0]) {
- m.Cmdy(prefix, "new-session", "-ds", arg[0])
- }
- m.Set("append").Set("result")
-
- // 查看窗口
- if m.Cmdy(prefix, "list-windows", "-t", arg[0], "-F", "#{window_id},#{window_active},#{window_name},#{window_panes},#{window_height},#{window_width}",
- "cmd_parse", "cut", ",", "6", "id tag window panes height width"); len(arg) == 1 {
- return
- }
-
- // 创建窗口
- if arg[1] != "" && !kit.Contains(m.Meta["window"], arg[1]) {
- m.Cmdy(prefix, "new-window", "-dt", arg[0], "-n", arg[1])
- }
- m.Set("append").Set("result")
-
- // 查看面板
- if len(arg) == 2 {
- m.Cmdy(prefix, "list-panes", "-t", arg[0]+":"+arg[1], "-F", "#{pane_id},#{pane_active},#{pane_index},#{pane_tty},#{pane_height},#{pane_width}",
- "cmd_parse", "cut", ",", "6", "id tag pane tty height width")
- return
- }
-
- // 执行命令
- target := arg[0] + ":" + arg[1] + "." + arg[2]
- if len(arg) > 3 {
- m.Cmdy(prefix, "send-keys", "-t", target, strings.Join(arg[3:], " "), "Enter")
- time.Sleep(1 * time.Second)
- }
-
- // 查看终端
- m.Echo(strings.TrimSpace(m.Cmdx(prefix, "capture-pane", "-pt", target)))
- return
- }},
- "docker": {Name: "docker image|volume|network|container", Help: "容器", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- prefix := kit.Trans(m.Confv("prefix", "docker"))
- switch arg[0] {
- case "image":
- if prefix = append(prefix, "image"); len(arg) < 3 {
- m.Cmdy(prefix, "ls", "cmd_parse", "cut", "cmd_headers", "IMAGE ID", "IMAGE_ID")
- break
- }
-
- switch arg[2] {
- case "运行":
- m.Cmdy(prefix[:2], "run", "-dt", m.Option("REPOSITORY")+":"+m.Option("TAG"))
- case "清理":
- m.Cmdy(prefix, "prune", "-f")
- case "delete":
- m.Cmdy(prefix, "rm", m.Option("IMAGE_ID"))
- case "创建":
- m.Option("base", m.Option("REPOSITORY")+":"+m.Option("TAG"))
- app := m.Conf("runtime", "boot.ctx_app")
- m.Option("name", app+":"+m.Time("20060102"))
- m.Option("file", m.Conf("docker", "output"))
- m.Option("user", m.Conf("runtime", "boot.username"))
- m.Option("host", "http://"+m.Conf("runtime", "boot.hostname")+".local"+m.Conf("runtime", "boot.web_port"))
-
- if f, _, e := kit.Create(m.Option("file")); m.Assert(e) {
- defer f.Close()
- if m.Assert(ctx.ExecuteStr(m, f, m.Conf("docker", "template."+app))) {
- m.Cmdy(prefix, "build", "-f", m.Option("file"), "-t", m.Option("name"), ".")
- }
- }
-
- default:
- if len(arg) == 3 {
- m.Cmdy(prefix, "pull", arg[1]+":"+arg[2])
- break
- }
- }
-
- case "volume":
- if prefix = append(prefix, "volume"); len(arg) == 1 {
- m.Cmdy(prefix, "ls", "cmd_parse", "cut", "cmd_headers", "VOLUME NAME", "VOLUME_NAME")
- break
- }
-
- case "network":
- if prefix = append(prefix, "network"); len(arg) == 1 {
- m.Cmdy(prefix, "ls", "cmd_parse", "cut", "cmd_headers", "NETWORK ID", "NETWORK_ID")
- break
- }
-
- kit.Map(kit.Chain(kit.UnMarshal(m.Cmdx(prefix, "inspect", arg[1])), "0.Containers"), "", func(key string, value map[string]interface{}) {
- m.Push("CONTAINER_ID", key[:12])
- m.Push("name", value["Name"])
- m.Push("IPv4", value["IPv4Address"])
- m.Push("IPv6", value["IPV4Address"])
- m.Push("Mac", value["MacAddress"])
- })
- m.Table()
-
- case "container":
- if prefix = append(prefix, "container"); len(arg) > 1 {
- switch arg[2] {
- case "进入":
- m.Cmdy(m.Confv("prefix", "tmux"), "new-window", "-t", "", "-n", m.Option("CONTAINER_NAME"),
- "-PF", "#{session_name}:#{window_name}.1", "docker exec -it "+arg[1]+" sh")
- return
-
- case "停止":
- m.Cmd(prefix, "stop", arg[1])
-
- case "启动":
- m.Cmd(prefix, "start", arg[1])
-
- case "重启":
- m.Cmd(prefix, "restart", arg[1])
-
- case "清理":
- m.Cmd(prefix, "prune", "-f")
-
- case "modify":
- switch arg[3] {
- case "NAMES":
- m.Cmd(prefix, "rename", arg[1], arg[4:])
- }
-
- case "delete":
- m.Cmdy(prefix, "rm", arg[1])
-
- default:
- if len(arg) == 2 {
- m.Cmdy(prefix, "inspect", arg[1])
- return
- }
- m.Cmdy(prefix, "exec", arg[1], arg[2:])
- return
- }
- }
- m.Cmdy(prefix, "ls", "-a", "cmd_parse", "cut", "cmd_headers", "CONTAINER ID", "CONTAINER_ID")
-
- case "command":
- switch arg[3] {
- case "base":
- m.Echo("\n0[%s]$ %s %s\n", time.Now().Format("15:04:05"), arg[2], m.Conf("package", arg[2]+".update"))
- m.Cmdy(prefix, "exec", arg[1], arg[2], strings.Split(m.Conf("package", arg[2]+".update"), " "))
- m.Confm("package", []string{arg[2], arg[3]}, func(index int, value string) {
- m.Echo("\n%d[%s]$ %s %s %s\n", index+1, time.Now().Format("15:04:05"), arg[2], m.Conf("package", arg[2]+".install"), value)
- m.Cmdy(prefix, "exec", arg[1], arg[2], strings.Split(m.Conf("package", arg[2]+".install"), " "), value)
- })
- }
-
- default:
- m.Cmdy(prefix, arg)
- }
- return
- }},
- "git": {Name: "git init|diff|status|commit|branch|remote|pull|push|sum", Help: "版本", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- prefix, arg := append(kit.Trans(m.Confv("prefix", "git")), "cmd_dir", kit.Select(".", arg[0])), arg[1:]
-
- switch arg[0] {
- case "init":
- if _, e := os.Stat(path.Join(prefix[len(prefix)-1], ".git")); e != nil {
- m.Cmdy(prefix, "init")
- }
- if len(arg) > 1 {
- m.Cmdy(prefix, "remote", "add", "-f", kit.Select("origin", arg, 2), arg[1])
- m.Cmdy(prefix, "pull", kit.Select("origin", arg, 2), kit.Select("master", arg, 3))
- }
-
- 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", "tags file")
- case "commit":
- if len(arg) > 1 && m.Cmdy(prefix, "commit", "-am", arg[1]).Result() == "" {
- break
- }
- m.Cmdy(prefix, "log", "--stat", "-n", "3")
- case "branch":
- if len(arg) > 1 {
- m.Cmd(prefix, "branch", arg[1])
- m.Cmd(prefix, "checkout", arg[1])
- }
- for _, v := range strings.Split(m.Cmdx(prefix, "branch", "-v"), "\n") {
- if len(v) > 0 {
- m.Push("tags", v[:2])
- vs := strings.SplitN(strings.TrimSpace(v[2:]), " ", 2)
- m.Push("branch", vs[0])
- vs = strings.SplitN(strings.TrimSpace(vs[1]), " ", 2)
- m.Push("hash", vs[0])
- m.Push("note", strings.TrimSpace(vs[1]))
- }
- }
- m.Table()
- case "remote":
- m.Cmdy(prefix, "remote", "-v", "cmd_parse", "cut", " ", "3", "remote url tag")
-
- case "push":
- m.Cmdy(prefix, "push")
- case "sum":
- total := false
- if len(arg) > 1 && arg[1] == "total" {
- total, arg = true, arg[1:]
- }
-
- args := []string{"log", "--shortstat", "--pretty=commit: %ad %n%s", "--date=iso", "--reverse"}
- if len(arg) > 1 {
- args = append(args, kit.Select("-n", "--since", strings.Contains(arg[1], "-")))
- if strings.Contains(arg[1], "-") && !strings.Contains(arg[1], ":") {
- arg[1] = arg[1] + " 00:00:00"
- }
- 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)
- }
- return
- }},
- "tags": {Name: "tags", Help: "代码索引", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- m.Cmdy("cli.system", "gotags", "-f", kit.Select("tags", arg, 1), "-R", kit.Select("src", arg, 0))
- return
- }},
- "vim": {Name: "vim editor|prune|opens|cmds|txts|bufs|regs|marks|tags|fixs", Help: "编辑器", Hand: func(m *ctx.Message, c *ctx.Context, cmd string, arg ...string) (e error) {
- switch arg[0] {
- case "ctag":
- if f, p, e := kit.Create("etc/conf/tags"); m.Assert(e) {
- defer f.Close()
- for k, _ := range c.Commands {
- fmt.Fprintf(f, "%s\t%s\t/\"%s\": {Name/\n", k, "../../src/examples/code/code.go", k)
- }
- m.Echo(p)
- }
- return
- }
- return
- }},
- "/vim": {Name: "/vim sid pwd cmd arg sub", Help: "编辑器", Hand: func(m *ctx.Message, c *ctx.Context, cmd string, arg ...string) (e error) {
- cmd = strings.TrimPrefix(cmd, "/")
- if f, _, e := m.Optionv("request").(*http.Request).FormFile("sub"); e == nil {
- defer f.Close()
- if b, e := ioutil.ReadAll(f); e == nil {
- m.Option("sub", string(b))
- }
- }
- m.Log("info", "%v %v %v %v", cmd, m.Option("cmd"), m.Option("arg"), m.Option("sub"))
- m.Confm("login", []string{"hash", m.Option("sid"), "ship"}, func(key string, value string) { m.Option(key, value) })
-
- switch m.Option("cmd") {
- case "help":
- m.Echo(strings.Join(kit.Trans(m.Confv("help", "index")), "\n"))
- case "login":
- m.Cmd("login", "init", cmd)
- case "logout":
- m.Cmd("login", "exit")
- case "favor":
- m.Log("info", "river: %v dream: %v favor: %v", m.Option("river"), m.Option("dream"), m.Option("favor"))
- prefix := []string{"ssh._route", m.Option("dream"), "web.code.favor"}
- if m.Options("arg") {
- m.Cmd(prefix, "post", m.Option("favor"), m.Option("tab"), m.Option("note"), m.Option("arg"),
- m.Option("buf"), m.Option("line"), m.Option("col"))
- m.Set("append")
- break
- }
-
- m.Cmd(prefix, "list", m.Option("favor"), "", kit.Select("10", m.Option("limit")), "0", "tab", m.Option("tab")).Table(func(index int, value map[string]string) {
- m.Echo("%v\n", value["tab"]).Echo("%v:%v:%v:(%v): %v\n", value["file"], value["line"], value["col"], value["note"], value["word"])
- })
-
- case "read", "write":
- m.Cmd("trend", "post", "vim.opens", "sid", m.Option("sid"),
- "action", m.Option("cmd"), "file", m.Option("arg"), "pwd", m.Option("pwd"))
- case "exec":
- m.Cmd("trend", "post", "vim.cmds", "sid", m.Option("sid"),
- "cmd", m.Option("sub"), "file", m.Option("buf"), "pwd", m.Option("pwd"))
- case "insert":
- m.Cmd("trend", "post", "vim.txts", "sid", m.Option("sid"),
- "word", m.Option("sub"), "line", m.Option("row"), "col", m.Option("col"), "file", m.Option("buf"), "pwd", m.Option("pwd"))
- case "tasklet":
- m.Cmd("ssh._route", m.Option("dream"), "web.team.task", "create", "task",
- "3", "add", "action", m.Time(), m.Time("10m"), m.Option("arg"), m.Option("sub"))
-
- case "sync":
- m.Confv(cmd, []string{m.Option("arg"), "hash", m.Option("sid")}, []interface{}{})
- switch m.Option("arg") {
- case "bufs":
- m.Split(m.Option("sub"), " ", "5", "id tag name some line").Table(func(index int, value map[string]string) {
- m.Cmd("state", "post", cmd, m.Option("arg"),
- "buf", value["id"], "tag", value["tag"], "line", value["line"],
- "file", strings.TrimSuffix(strings.TrimPrefix(value["name"], "\""), "\""))
- })
- case "regs":
- m.Split(strings.TrimPrefix(m.Option("sub"), "--- Registers ---\n"), " ", "2", "name word").Table(func(index int, value map[string]string) {
- m.Cmd("state", "post", cmd, m.Option("arg"),
- "reg", strings.TrimPrefix(value["name"], "\""),
- "word", strings.Replace(strings.Replace(value["word"], "^I", "\t", -1), "^J", "\n", -1))
- })
- case "marks":
- m.Split(m.Option("sub"), " ", "4").Table(func(index int, value map[string]string) {
- m.Cmd("state", "post", cmd, m.Option("arg"),
- "mark", value["mark"], "line", value["line"], "col", value["col"],
- "file", value["file/text"])
- })
- case "tags":
- m.Split(strings.TrimSuffix(m.Option("sub"), ">"), " ", "6").Table(func(index int, value map[string]string) {
- m.Cmd("state", "post", cmd, m.Option("arg"),
- "tag", value["tag"], "line", value["line"], "file", value["in file/text"])
- })
- case "fixs":
- if strings.HasPrefix(m.Option("sub"), "\nError") {
- break
- }
- m.Split(m.Option("sub"), " ", "3", "id file word").Table(func(index int, value map[string]string) {
- vs := strings.Split(kit.Format(value["file"]), ":")
- m.Cmd("state", "post", cmd, m.Option("arg"),
- "fix", value["id"], "file", vs[0], "line", vs[1], "word", value["word"])
- })
- }
- m.Set("append").Set("result")
- }
- return
- }},
- },
-}
-
-func init() {
- web.Index.Register(Index, &web.WEB{Context: Index})
-}
diff --git a/usr/local/honor/src/examples/mall/mall.go b/usr/local/honor/src/examples/mall/mall.go
deleted file mode 100644
index c549944b..00000000
--- a/usr/local/honor/src/examples/mall/mall.go
+++ /dev/null
@@ -1,51 +0,0 @@
-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{
- "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() {
- web.Index.Register(Index, &web.WEB{Context: Index})
-}
diff --git a/usr/local/honor/src/examples/team/team.go b/usr/local/honor/src/examples/team/team.go
deleted file mode 100644
index 69a23889..00000000
--- a/usr/local/honor/src/examples/team/team.go
+++ /dev/null
@@ -1,79 +0,0 @@
-package team
-
-import (
- "contexts/ctx"
- "contexts/web"
- "fmt"
- "toolkit"
-)
-
-var Index = &ctx.Context{Name: "team", Help: "团队中心",
- Caches: map[string]*ctx.Cache{},
- Configs: map[string]*ctx.Config{},
- Commands: map[string]*ctx.Command{
- "task": {Name: "task create table level class status begin_time close_time target detail arg...", Help: "任务", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
- switch arg[0] {
- case "progress":
- if len(arg) > 3 && arg[1] != "" {
- switch arg[3] {
- case "prepare", "action", "cancel", "finish":
- time := "close_time"
- switch arg[3] {
- case "prepare", "action":
- time = "begin_time"
- case "cancel", "finish":
- time = "close_time"
- default:
- time = "update_time"
- }
-
- // 更新任务
- m.Cmd("ssh.data", "update", arg[1], arg[2], "status", arg[3], time, m.Time())
- arg = []string{arg[0], m.Option("table")}
- }
- }
- // 任务进度
- m.Option("cache.limit", kit.Select("30", arg, 2))
- m.Option("cache.offend", kit.Select("0", arg, 3))
- m.Meta["append"] = []string{"prepare", "action", "cancel", "finish"}
- m.Cmd("ssh.data", "show", arg[1]).Table(func(index int, value map[string]string) {
- m.Push(value["status"],
- fmt.Sprintf("%s", value["id"], value["detail"], value["target"]))
- })
- m.Table()
-
- case "create":
- // 创建任务
- if len(arg) > 7 {
- if len(arg) < 9 {
- arg = append(arg, "")
- }
- m.Cmdy("ssh.data", "insert", arg[1], "level", arg[2], "class", arg[3],
- "status", arg[4], "begin_time", arg[5], "close_time", arg[6],
- "target", arg[7], "detail", arg[8], arg[9:])
- break
- }
-
- arg = []string{arg[1]}
- fallthrough
- default:
- // 更新任务
- if len(arg) > 1 && arg[1] == "modify" {
- m.Cmdy("ssh.data", "update", m.Option("table"), arg[0], arg[2], arg[3])
- break
- }
-
- // 查看任务
- if len(arg) > 0 && arg[0] == "" {
- arg = arg[:0]
- }
- m.Cmdy("ssh.data", "show", arg, "fields", "id", "level", "class", "status", "target", "begin_time", "close_time")
- }
- return
- }},
- },
-}
-
-func init() {
- web.Index.Register(Index, &web.WEB{Context: Index})
-}
diff --git a/usr/local/honor/src/examples/wiki/chart.go b/usr/local/honor/src/examples/wiki/chart.go
deleted file mode 100644
index 9293cd9b..00000000
--- a/usr/local/honor/src/examples/wiki/chart.go
+++ /dev/null
@@ -1,277 +0,0 @@
-package wiki
-
-import (
- "contexts/ctx"
- mis "github.com/shylinux/toolkits"
- "strings"
- "toolkit"
-)
-
-// 图形接口
-type Chart interface {
- Init(*ctx.Message, ...string) Chart
- Draw(*ctx.Message, int, int) Chart
-
- GetWidth(...string) int
- GetHeight(...string) int
-}
-
-// 图形基类
-type Block struct {
- Text string
- FontColor string
- FontFamily string
- BackGround string
-
- FontSize int
- LineSize int
- Padding int
- Margin int
-
- Width, Height int
-
- TextData string
- RectData string
-}
-
-func (b *Block) Init(m *ctx.Message, arg ...string) Chart {
- b.Text = kit.Select(b.Text, arg, 0)
- b.FontColor = kit.Select("white", kit.Select(b.FontColor, arg, 1))
- b.BackGround = kit.Select("red", kit.Select(b.BackGround, arg, 2))
- b.FontSize = kit.Int(kit.Select("24", kit.Select(kit.Format(b.FontSize), arg, 3)))
- b.LineSize = kit.Int(kit.Select("12", kit.Select(kit.Format(b.LineSize), arg, 4)))
- return b
-}
-func (b *Block) Draw(m *ctx.Message, x, y int) Chart {
- m.Echo(`