forked from x/ContextOS
opt context
This commit is contained in:
parent
4842117198
commit
abdf1711bb
2
Makefile
2
Makefile
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
BENCH=src/examples/app/bench.go
|
BENCH=src/extend/bench.go
|
||||||
upgrade=usr/upgrade/
|
upgrade=usr/upgrade/
|
||||||
|
|
||||||
install:
|
install:
|
||||||
|
@ -46,9 +46,9 @@ hup() {
|
|||||||
}
|
}
|
||||||
main() {
|
main() {
|
||||||
trap HUP hup
|
trap HUP hup
|
||||||
|
log "\nstarting..."
|
||||||
while true; do
|
while true; do
|
||||||
date
|
date && ${ctx_bin} "$@" && break
|
||||||
${ctx_bin} "$@" && break
|
|
||||||
log "\nrestarting..." && sleep 1
|
log "\nrestarting..." && sleep 1
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
@ -36,13 +36,10 @@ type AAA struct {
|
|||||||
|
|
||||||
func Auto(m *ctx.Message, arg ...string) {
|
func Auto(m *ctx.Message, arg ...string) {
|
||||||
msg := m.Spawn().Add("option", "auto_cmd", "").Cmd("auth", arg)
|
msg := m.Spawn().Add("option", "auto_cmd", "").Cmd("auth", arg)
|
||||||
msg.Table(func(maps map[string]string, list []string, line int) bool {
|
msg.Table(func(line int, maps map[string]string) {
|
||||||
if line >= 0 {
|
m.Add("append", "value", maps["key"])
|
||||||
m.Add("append", "value", maps["key"])
|
m.Add("append", "name", fmt.Sprintf("%s: %s", maps["type"], maps["meta"]))
|
||||||
m.Add("append", "name", fmt.Sprintf("%s: %s", maps["type"], maps["meta"]))
|
m.Add("append", "help", fmt.Sprintf("%s", maps["create_time"]))
|
||||||
m.Add("append", "help", fmt.Sprintf("%s", maps["create_time"]))
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
|||||||
},
|
},
|
||||||
}, Help: "运行环境"},
|
}, Help: "运行环境"},
|
||||||
"compile": &ctx.Config{Name: "compile", Value: map[string]interface{}{
|
"compile": &ctx.Config{Name: "compile", Value: map[string]interface{}{
|
||||||
"bench": "src/examples/app/bench.go",
|
"bench": "src/extend/bench.go",
|
||||||
"tmp": "var/tmp/go",
|
"tmp": "var/tmp/go",
|
||||||
"env": []interface{}{"GOPATH", "PATH"},
|
"env": []interface{}{"GOPATH", "PATH"},
|
||||||
}, Help: "运行环境"},
|
}, Help: "运行环境"},
|
||||||
@ -444,7 +444,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
|||||||
m.Echo(h)
|
m.Echo(h)
|
||||||
|
|
||||||
// 执行命令
|
// 执行命令
|
||||||
m.GoFunc(m, func(m *ctx.Message) {
|
m.Gos(m, func(m *ctx.Message) {
|
||||||
if e := cmd.Start(); e != nil {
|
if e := cmd.Start(); e != nil {
|
||||||
m.Echo("error: ").Echo("%s\n", e)
|
m.Echo("error: ").Echo("%s\n", e)
|
||||||
} else if e := cmd.Wait(); e != nil {
|
} else if e := cmd.Wait(); e != nil {
|
||||||
@ -457,7 +457,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
|||||||
|
|
||||||
// 管道命令
|
// 管道命令
|
||||||
wait := make(chan bool, 1)
|
wait := make(chan bool, 1)
|
||||||
m.GoFunc(m, func(m *ctx.Message) {
|
m.Gos(m, func(m *ctx.Message) {
|
||||||
defer func() { wait <- true }()
|
defer func() { wait <- true }()
|
||||||
|
|
||||||
out := bytes.NewBuffer(make([]byte, 0, 1024))
|
out := bytes.NewBuffer(make([]byte, 0, 1024))
|
||||||
@ -745,17 +745,30 @@ var version = struct {
|
|||||||
"missyou": &ctx.Command{Name: "missyou", Help: "服务升级", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
"missyou": &ctx.Command{Name: "missyou", Help: "服务升级", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||||
if len(arg) == 0 {
|
if len(arg) == 0 {
|
||||||
m.Option("dir_root", "")
|
m.Option("dir_root", "")
|
||||||
m.Cmdy("nfs.dir", m.Conf("missyou", "path"))
|
m.Cmd("nfs.dir", m.Conf("missyou", "path")).Table(func() {
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
p := path.Join(m.Conf("missyou", "path"), m.Time("20060102-")+arg[0])
|
if !strings.Contains(arg[0], "-") {
|
||||||
m.Cmd("nfs.copy", path.Join(p, "etc/local.shy"), "usr/missyou/job.shy")
|
arg[0] = m.Time("20060102-") + arg[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.Confs("ssh.node", arg[0]) {
|
||||||
|
m.Echo(arg[0])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
p := path.Join(m.Conf("missyou", "path"), arg[0])
|
||||||
|
if s, e := os.Stat(p); e == nil && s.IsDir() {
|
||||||
|
m.Cmdy("cli.system", "node.sh", "create", p, "daemon", "cmd_daemon", "true")
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
m.Cmdy("nfs.copy", path.Join(p, "etc/local.shy"), "usr/missyou/job.shy")
|
||||||
m.Confm("missyou", "local", func(index string, local string) {
|
m.Confm("missyou", "local", func(index string, local string) {
|
||||||
m.Cmd("nfs.git", "clone", local, path.Join(p, "usr/local", index))
|
m.Cmd("nfs.git", "clone", local, path.Join(p, "usr/local", index))
|
||||||
})
|
})
|
||||||
m.Cmdy("cli.system", "node.sh", "create", p, "daemon", "cmd_daemon", "true")
|
|
||||||
return
|
return
|
||||||
}},
|
}},
|
||||||
"quit": &ctx.Command{Name: "quit code", Help: "停止服务", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
"quit": &ctx.Command{Name: "quit code", Help: "停止服务", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||||
@ -779,7 +792,7 @@ var version = struct {
|
|||||||
m.Append("code", code)
|
m.Append("code", code)
|
||||||
m.Echo(", wait 1s\n").Table()
|
m.Echo(", wait 1s\n").Table()
|
||||||
|
|
||||||
m.GoFunc(m, func(m *ctx.Message) {
|
m.Gos(m, func(m *ctx.Message) {
|
||||||
defer func() {
|
defer func() {
|
||||||
os.Exit(kit.Int(code))
|
os.Exit(kit.Int(code))
|
||||||
}()
|
}()
|
||||||
@ -798,25 +811,25 @@ var version = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
begin := time.Now()
|
begin := time.Now()
|
||||||
f, e := os.Open(args[0])
|
f, e := os.Open(args[0])
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
bio := bufio.NewScanner(f)
|
bio := bufio.NewScanner(f)
|
||||||
output := map[string]*os.File{}
|
output := map[string]*os.File{}
|
||||||
nreq := 0
|
nreq := 0
|
||||||
|
|
||||||
for bio.Scan() {
|
for bio.Scan() {
|
||||||
word := strings.Split(bio.Text(), " ")
|
word := strings.Split(bio.Text(), " ")
|
||||||
if len(word) != 2 {
|
if len(word) != 2 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
uri := word[0][prefix0:len(word[0])-1]
|
uri := word[0][prefix0 : len(word[0])-1]
|
||||||
arg := word[1][prefix1:len(word[1])-1]
|
arg := word[1][prefix1 : len(word[1])-1]
|
||||||
if output[uri] == nil {
|
if output[uri] == nil {
|
||||||
output[uri], e = os.Create(path.Join("tmp", strings.Replace(uri, "/", "_", -1)+".txt"))
|
output[uri], e = os.Create(path.Join("tmp", strings.Replace(uri, "/", "_", -1)+".txt"))
|
||||||
defer output[uri].Close()
|
defer output[uri].Close()
|
||||||
}
|
}
|
||||||
nreq++
|
nreq++
|
||||||
br := bytes.NewReader([]byte(arg))
|
br := bytes.NewReader([]byte(arg))
|
||||||
res, e := http.Post(args[1]+uri, "application/json", br)
|
res, e := http.Post(args[1]+uri, "application/json", br)
|
||||||
fmt.Fprintf(output[uri], uri)
|
fmt.Fprintf(output[uri], uri)
|
||||||
fmt.Fprintf(output[uri], " ")
|
fmt.Fprintf(output[uri], " ")
|
||||||
|
@ -4,5 +4,5 @@ var version = struct {
|
|||||||
host string
|
host string
|
||||||
self int
|
self int
|
||||||
}{
|
}{
|
||||||
"2019-06-28 19:50:49", "ZYB-20190522USI", 24,
|
"2019-06-30 12:52:58", "com", 26,
|
||||||
}
|
}
|
||||||
|
@ -554,21 +554,19 @@ var CGI = template.FuncMap{
|
|||||||
if len(cli.Meta["append"]) > 0 {
|
if len(cli.Meta["append"]) > 0 {
|
||||||
result = append(result, "<table>")
|
result = append(result, "<table>")
|
||||||
result = append(result, "<caption>", cmd, "</caption>")
|
result = append(result, "<caption>", cmd, "</caption>")
|
||||||
cli.Table(func(maps map[string]string, list []string, line int) bool {
|
cli.Table(func(line int, maps map[string]string) {
|
||||||
if line == -1 {
|
if line == 0 {
|
||||||
result = append(result, "<tr>")
|
result = append(result, "<tr>")
|
||||||
for _, v := range list {
|
for _, v := range cli.Meta["append"] {
|
||||||
result = append(result, "<th>", v, "</th>")
|
result = append(result, "<th>", v, "</th>")
|
||||||
}
|
}
|
||||||
result = append(result, "</tr>")
|
result = append(result, "</tr>")
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
result = append(result, "<tr>")
|
result = append(result, "<tr>")
|
||||||
for _, v := range list {
|
for _, k := range cli.Meta["append"] {
|
||||||
result = append(result, "<td>", v, "</td>")
|
result = append(result, "<td>", maps[k], "</td>")
|
||||||
}
|
}
|
||||||
result = append(result, "</tr>")
|
result = append(result, "</tr>")
|
||||||
return true
|
|
||||||
})
|
})
|
||||||
result = append(result, "</table>")
|
result = append(result, "</table>")
|
||||||
} else {
|
} else {
|
||||||
|
391
src/contexts/ctx/core.go
Normal file
391
src/contexts/ctx/core.go
Normal file
@ -0,0 +1,391 @@
|
|||||||
|
package ctx
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
"toolkit"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c *Context) Register(s *Context, x Server, args ...interface{}) {
|
||||||
|
force := false
|
||||||
|
if len(args) > 0 {
|
||||||
|
switch arg := args[0].(type) {
|
||||||
|
case bool:
|
||||||
|
force = arg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.contexts == nil {
|
||||||
|
c.contexts = make(map[string]*Context)
|
||||||
|
}
|
||||||
|
if x, ok := c.contexts[s.Name]; ok && !force {
|
||||||
|
panic(errors.New(c.Name + "上下文中已存在模块:" + x.Name))
|
||||||
|
}
|
||||||
|
|
||||||
|
c.contexts[s.Name] = s
|
||||||
|
s.context = c
|
||||||
|
s.Server = x
|
||||||
|
}
|
||||||
|
func (c *Context) Plugin(args []string) string {
|
||||||
|
Index.Register(c, nil)
|
||||||
|
m := &Message{code: 0, time: time.Now(), source: c, target: c, Meta: map[string][]string{}}
|
||||||
|
if len(args) == 0 {
|
||||||
|
m.Echo("%s: %s\n", c.Name, c.Help)
|
||||||
|
for k, v := range c.Commands {
|
||||||
|
m.Echo("%s: %s %v\n", k, v.Name, v.Help)
|
||||||
|
}
|
||||||
|
} else if cs, ok := c.Commands[args[0]]; ok {
|
||||||
|
h := cs.Hand
|
||||||
|
if e := h(m, c, args[0], args[1:]...); e != nil {
|
||||||
|
m.Echo("error: ").Echo("%v\n", e)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m.Echo("error: ").Echo("not found: %v\n", args[0])
|
||||||
|
}
|
||||||
|
return strings.Join(m.Meta["result"], "")
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
|
||||||
|
/*
|
||||||
|
m.Log("begin", "%d context %v %v", m.Capi("ncontext", 1), m.Meta["detail"], m.Meta["option"])
|
||||||
|
for k, x := range c.Configs {
|
||||||
|
if x.Hand != nil {
|
||||||
|
m.Log("begin", "%s config %v", k, m.Conf(k, x.Value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
if c.Server != nil {
|
||||||
|
c.Server.Begin(m, m.Meta["detail"]...)
|
||||||
|
}
|
||||||
|
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...) {
|
||||||
|
m.Log("close", "request %d/%d", i, len(c.requests)-1)
|
||||||
|
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) 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) 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) Gos(msg *Message, hand ...func(msg *Message)) *Message {
|
||||||
|
go func() {
|
||||||
|
msg.Option("routine", m.Capi("ngo", 1))
|
||||||
|
m.TryCatch(msg, true, hand...)
|
||||||
|
}()
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Message) Spawn(arg ...interface{}) *Message {
|
||||||
|
temp := false
|
||||||
|
c := m.target
|
||||||
|
if len(arg) > 0 {
|
||||||
|
switch v := arg[0].(type) {
|
||||||
|
case *Context:
|
||||||
|
c = v
|
||||||
|
case *Message:
|
||||||
|
c = v.target
|
||||||
|
case string:
|
||||||
|
temp = kit.Right(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := &Message{
|
||||||
|
time: time.Now(),
|
||||||
|
code: m.Capi("nmessage", 1),
|
||||||
|
source: m.target,
|
||||||
|
target: c,
|
||||||
|
message: m,
|
||||||
|
root: m.root,
|
||||||
|
}
|
||||||
|
|
||||||
|
if temp {
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for msg := m; msg != nil; msg = msg.message {
|
||||||
|
if x, ok := msg.Sessions[key]; ok {
|
||||||
|
if spawn {
|
||||||
|
x = m.Spawn(x.target)
|
||||||
|
x.callback = func(sub *Message) *Message { return sub }
|
||||||
|
}
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
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 || 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.Gos(m, func(m *Message) {
|
||||||
|
m.Call(func(sub *Message) *Message {
|
||||||
|
msg := cb(sub)
|
||||||
|
m.Log("sync", m.Format("done", "result", "append"))
|
||||||
|
wait <- m
|
||||||
|
return msg
|
||||||
|
}, arg...)
|
||||||
|
// })
|
||||||
|
|
||||||
|
m.Log("sync", m.Format("wait", "result", "append"))
|
||||||
|
select {
|
||||||
|
case <-time.After(kit.Duration(m.Conf("call_timeout"))):
|
||||||
|
m.Log("sync", m.Format("timeout", "result", "append"))
|
||||||
|
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
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,12 @@
|
|||||||
package ctx
|
package ctx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
"toolkit"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Cache struct {
|
type Cache struct {
|
||||||
@ -48,6 +53,14 @@ type Server interface {
|
|||||||
Start(m *Message, arg ...string) bool
|
Start(m *Message, arg ...string) bool
|
||||||
Close(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 {
|
type Message struct {
|
||||||
time time.Time
|
time time.Time
|
||||||
code int
|
code int
|
||||||
@ -55,19 +68,17 @@ type Message struct {
|
|||||||
source *Context
|
source *Context
|
||||||
target *Context
|
target *Context
|
||||||
|
|
||||||
|
Hand bool
|
||||||
Meta map[string][]string
|
Meta map[string][]string
|
||||||
Data map[string]interface{}
|
Data map[string]interface{}
|
||||||
|
|
||||||
callback func(msg *Message) (sub *Message)
|
callback func(msg *Message) (sub *Message)
|
||||||
freedoms []func(msg *Message) (done bool)
|
freeback []func(msg *Message) (done bool)
|
||||||
Sessions map[string]*Message
|
Sessions map[string]*Message
|
||||||
|
|
||||||
messages []*Message
|
messages []*Message
|
||||||
message *Message
|
message *Message
|
||||||
root *Message
|
root *Message
|
||||||
|
|
||||||
Remote chan bool
|
|
||||||
Hand bool
|
|
||||||
}
|
}
|
||||||
type LOGGER interface {
|
type LOGGER interface {
|
||||||
Log(*Message, string, string, ...interface{})
|
Log(*Message, string, string, ...interface{})
|
||||||
@ -76,3 +87,789 @@ type DEBUG interface {
|
|||||||
Wait(*Message, ...interface{}) interface{}
|
Wait(*Message, ...interface{}) interface{}
|
||||||
Goon(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 = 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) Message() *Message {
|
||||||
|
return m.message
|
||||||
|
}
|
||||||
|
|
||||||
|
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) Detaili(arg ...interface{}) int {
|
||||||
|
return kit.Int(m.Detail(arg...))
|
||||||
|
}
|
||||||
|
func (m *Message) Details(arg ...interface{}) bool {
|
||||||
|
return kit.Right(m.Detail(arg...))
|
||||||
|
}
|
||||||
|
func (m *Message) Option(key string, arg ...interface{}) string {
|
||||||
|
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:
|
||||||
|
// case []string:
|
||||||
|
// m.Option(key, v...)
|
||||||
|
// case string:
|
||||||
|
// m.Option(key, v)
|
||||||
|
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) Optionx(key string, arg ...string) interface{} {
|
||||||
|
value := m.Conf(key)
|
||||||
|
if value == "" {
|
||||||
|
value = m.Option(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(arg) > 0 {
|
||||||
|
value = fmt.Sprintf(arg[0], value)
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
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) Appendv(key string, arg ...interface{}) interface{} {
|
||||||
|
if len(arg) > 0 {
|
||||||
|
m.Put("append", key, arg[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
if v, ok := ms[i].Data[key]; ok {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
return ms[i].Meta[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
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) Resulti(arg ...interface{}) int {
|
||||||
|
return kit.Int(m.Result(arg...))
|
||||||
|
}
|
||||||
|
func (m *Message) Results(arg ...interface{}) bool {
|
||||||
|
return kit.Right(m.Result(arg...))
|
||||||
|
}
|
||||||
|
|
||||||
|
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] = 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 := m.Confx("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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 回调函数
|
||||||
|
var cb func(maps map[string]string, list []string, line int) (goon bool)
|
||||||
|
if len(cbs) > 0 {
|
||||||
|
cb = cbs[0].(func(maps map[string]string, list []string, line int) (goon bool))
|
||||||
|
} else {
|
||||||
|
row := m.Confx("table_row_sep")
|
||||||
|
col := m.Confx("table_col_sep")
|
||||||
|
compact := kit.Right(m.Confx("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(col)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m.Echo(row)
|
||||||
|
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))))
|
||||||
|
}
|
||||||
|
m.Log("fuck", "waht %v", row)
|
||||||
|
if !cb(row, wor, i) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
func (m *Message) Sort(key string, arg ...string) *Message {
|
||||||
|
cmp := "str"
|
||||||
|
if len(arg) > 0 {
|
||||||
|
cmp = arg[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
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) 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(strings.Join(head, " "), "...\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
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) Cmdm(args ...interface{}) *Message {
|
||||||
|
m.Log("info", "current: %v", m.Magic("session", "current"))
|
||||||
|
|
||||||
|
arg := []string{}
|
||||||
|
if pod := kit.Format(m.Magic("session", "current.pod")); pod != "" {
|
||||||
|
arg = append(arg, "context", "ssh", "remote", pod)
|
||||||
|
}
|
||||||
|
if ctx := kit.Format(m.Magic("session", "current.ctx")); ctx != "" {
|
||||||
|
arg = append(arg, "context", ctx)
|
||||||
|
}
|
||||||
|
arg = append(arg, kit.Trans(args...)...)
|
||||||
|
|
||||||
|
m.Spawn().Cmd(arg).CopyTo(m)
|
||||||
|
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 m.Cmd(args...).Results(0)
|
||||||
|
}
|
||||||
|
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:]
|
||||||
|
|
||||||
|
msg := m
|
||||||
|
if strings.Contains(key, ":") {
|
||||||
|
ps := strings.Split(key, ":")
|
||||||
|
msg, key, arg = msg.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, ".")
|
||||||
|
msg, key = msg.Sess(arg[0]), arg[1]
|
||||||
|
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"])
|
||||||
|
|
||||||
|
for _, form := range []map[string]int{map[string]int{"page.limit": 1, "page.offset": 1}, 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) {
|
||||||
|
msg.Add("option", arg[i], arg[i+1:])
|
||||||
|
} else {
|
||||||
|
msg.Add("option", arg[i], arg[i+1:i+1+n])
|
||||||
|
}
|
||||||
|
i += n
|
||||||
|
} else {
|
||||||
|
args = append(args, arg[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
arg = args
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
target := msg.target
|
||||||
|
msg.target = s
|
||||||
|
|
||||||
|
msg.Hand = true
|
||||||
|
switch v := msg.Gdb("command", key, arg).(type) {
|
||||||
|
case string:
|
||||||
|
msg.Echo(v)
|
||||||
|
case nil:
|
||||||
|
if msg.Options("auto_cmd") {
|
||||||
|
if x.Auto != nil {
|
||||||
|
x.Auto(msg, c, key, arg...)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
x.Hand(msg, c, key, arg...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if msg.target == s {
|
||||||
|
msg.target = target
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return msg.Hand
|
||||||
|
})
|
||||||
|
|
||||||
|
if !msg.Hand {
|
||||||
|
msg.Log("error", "cmd run error %s", msg.Format())
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
table, _ := v.([]interface{})
|
||||||
|
value, _ := v.(map[string]interface{})
|
||||||
|
if len(args) == 0 {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
switch fun := args[0].(type) {
|
||||||
|
case func(int, string):
|
||||||
|
for i, v := range table {
|
||||||
|
fun(i, kit.Format(v))
|
||||||
|
}
|
||||||
|
case func(int, string) bool:
|
||||||
|
for i, v := range table {
|
||||||
|
if fun(i, kit.Format(v)) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case func(string, string):
|
||||||
|
for k, v := range value {
|
||||||
|
fun(k, kit.Format(v))
|
||||||
|
}
|
||||||
|
case func(string, string) bool:
|
||||||
|
for k, v := range value {
|
||||||
|
if fun(k, kit.Format(v)) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case func(map[string]interface{}):
|
||||||
|
if len(value) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
fun(value)
|
||||||
|
case func(string, map[string]interface{}):
|
||||||
|
switch random {
|
||||||
|
case "%":
|
||||||
|
n, i := rand.Intn(len(value)), 0
|
||||||
|
for k, v := range value {
|
||||||
|
if val, ok := v.(map[string]interface{}); i == n && ok {
|
||||||
|
fun(k, val)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
case "*":
|
||||||
|
fallthrough
|
||||||
|
default:
|
||||||
|
for k, v := range value {
|
||||||
|
if val, ok := v.(map[string]interface{}); ok {
|
||||||
|
fun(k, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case func(string, int, map[string]interface{}):
|
||||||
|
for k, v := range value {
|
||||||
|
if val, ok := v.([]interface{}); ok {
|
||||||
|
for i, v := range val {
|
||||||
|
if val, ok := v.(map[string]interface{}); ok {
|
||||||
|
fun(k, i, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case func(string, map[string]interface{}) bool:
|
||||||
|
for k, v := range value {
|
||||||
|
if val, ok := v.(map[string]interface{}); ok {
|
||||||
|
if fun(k, val) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case func(int, map[string]interface{}):
|
||||||
|
for i := m.Optioni("page.begin"); i < len(table); i++ {
|
||||||
|
if val, ok := table[i].(map[string]interface{}); ok {
|
||||||
|
fun(i, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
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) 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) 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) 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
|
||||||
|
}
|
||||||
|
660
src/contexts/ctx/what.go
Normal file
660
src/contexts/ctx/what.go
Normal file
@ -0,0 +1,660 @@
|
|||||||
|
package ctx
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"regexp"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"sort"
|
||||||
|
"toolkit"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c *Context) Has(key ...string) bool {
|
||||||
|
switch len(key) {
|
||||||
|
case 2:
|
||||||
|
if _, ok := c.Commands[key[0]]; ok && key[1] == "command" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if _, ok := c.Configs[key[0]]; ok && key[1] == "config" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if _, ok := c.Caches[key[0]]; ok && key[1] == "cache" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
if _, ok := c.Commands[key[0]]; ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if _, ok := c.Configs[key[0]]; ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if _, ok := c.Caches[key[0]]; ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
func (c *Context) Sub(key string) *Context {
|
||||||
|
return c.contexts[key]
|
||||||
|
}
|
||||||
|
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) Format(arg ...interface{}) string {
|
||||||
|
if len(arg) == 0 {
|
||||||
|
arg = append(arg, "time", "ship")
|
||||||
|
}
|
||||||
|
|
||||||
|
meta := []string{}
|
||||||
|
for _, v := range arg {
|
||||||
|
switch kit.Format(v) {
|
||||||
|
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 "code":
|
||||||
|
meta = append(meta, kit.Format(m.code))
|
||||||
|
case "ship":
|
||||||
|
meta = append(meta, fmt.Sprintf("%s:%d(%s->%s)", m.Option("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\n", msg.Format("time", "ship")))
|
||||||
|
if len(msg.Meta["detail"]) > 0 {
|
||||||
|
meta = append(meta, fmt.Sprintf(" detail: %d %v\n", 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.Data[k]; ok {
|
||||||
|
meta = append(meta, fmt.Sprintf(" %s: %v\n", k, kit.Format(v)))
|
||||||
|
} else if v, ok := msg.Meta[k]; ok {
|
||||||
|
meta = append(meta, fmt.Sprintf(" %s: %d %v\n", k, len(v), v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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.Data[k]; ok {
|
||||||
|
meta = append(meta, fmt.Sprintf(" %s: %v\n", k, kit.Format(v)))
|
||||||
|
} else 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(6, 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.FileName(kit.Format(v), "time"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strings.Join(meta, " ")
|
||||||
|
}
|
||||||
|
func (m *Message) Tree(code int) *Message {
|
||||||
|
ms := []*Message{m}
|
||||||
|
for i := 0; i < len(ms); i++ {
|
||||||
|
if ms[i].Code() == code {
|
||||||
|
return ms[i]
|
||||||
|
}
|
||||||
|
ms = append(ms, ms[i].messages...)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
delete(m.Meta, kit.Format(arg[0]))
|
||||||
|
} 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) Auto(arg ...string) *Message {
|
||||||
|
for i := 0; i < len(arg); i += 3 {
|
||||||
|
m.Add("append", "value", arg[i])
|
||||||
|
m.Add("append", "name", arg[i+1])
|
||||||
|
m.Add("append", "help", arg[i+2])
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Message) Insert(meta string, index int, arg ...interface{}) string {
|
||||||
|
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) 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) Current(text string) string {
|
||||||
|
cs := []string{}
|
||||||
|
if pod := kit.Format(m.Magic("session", "current.pod")); pod != "" {
|
||||||
|
cs = append(cs, "context", "ssh", "remote", "'"+pod+"'")
|
||||||
|
}
|
||||||
|
if ctx := kit.Format(m.Magic("session", "current.ctx")); ctx != "" {
|
||||||
|
cs = append(cs, "context", ctx)
|
||||||
|
}
|
||||||
|
if cmd := kit.Format(m.Magic("session", "current.cmd")); cmd != "" {
|
||||||
|
cs = append(cs, cmd)
|
||||||
|
}
|
||||||
|
m.Log("info", "%s %s current %v", m.Option("username"), m.Option("sessid"), cs)
|
||||||
|
cs = append(cs, text)
|
||||||
|
return strings.Join(cs, " ")
|
||||||
|
}
|
||||||
|
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) ToHTML(style string) string {
|
||||||
|
cmd := strings.Join(m.Meta["detail"], " ")
|
||||||
|
result := []string{}
|
||||||
|
if len(m.Meta["append"]) > 0 {
|
||||||
|
result = append(result, fmt.Sprintf("<table class='%s'>", style))
|
||||||
|
result = append(result, "<caption>", cmd, "</caption>")
|
||||||
|
m.Table(func(line int, maps map[string]string) {
|
||||||
|
if line == 0 {
|
||||||
|
result = append(result, "<tr>")
|
||||||
|
for _, v := range m.Meta["append"] {
|
||||||
|
result = append(result, "<th>", v, "</th>")
|
||||||
|
}
|
||||||
|
result = append(result, "</tr>")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
result = append(result, "<tr>")
|
||||||
|
for _, k := range m.Meta["append"] {
|
||||||
|
result = append(result, "<td>", maps[k], "</td>")
|
||||||
|
}
|
||||||
|
result = append(result, "</tr>")
|
||||||
|
})
|
||||||
|
result = append(result, "</table>")
|
||||||
|
} else {
|
||||||
|
result = append(result, "<pre><code>")
|
||||||
|
result = append(result, fmt.Sprintf("%s", m.Find("shy", false).Conf("prompt")), cmd, "\n")
|
||||||
|
result = append(result, m.Meta["result"]...)
|
||||||
|
result = append(result, "</code></pre>")
|
||||||
|
}
|
||||||
|
return strings.Join(result, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Message) Gdb(arg ...interface{}) interface{} {
|
||||||
|
if g := m.Sess("gdb", false); g != nil {
|
||||||
|
if gdb, ok := g.target.Server.(DEBUG); ok {
|
||||||
|
return gdb.Wait(m, arg...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (m *Message) Log(action string, str string, arg ...interface{}) *Message {
|
||||||
|
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"))
|
||||||
|
}
|
||||||
|
log.Log(m, action, str, arg...)
|
||||||
|
if action == "error" {
|
||||||
|
log.Log(m, "error", "stack: %s", m.Format("stack"))
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Printf(str, arg...)
|
||||||
|
}
|
||||||
|
|
||||||
|
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")))
|
||||||
|
}
|
||||||
|
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
func (m *Message) Show(args ...interface{}) *Message {
|
||||||
|
if m.Option("cli.modal") == "action" {
|
||||||
|
fmt.Printf(kit.Format(args...))
|
||||||
|
} else if kit.STDIO != nil {
|
||||||
|
kit.STDIO.Show(args...)
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
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) 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) Close(arg ...string) bool {
|
||||||
|
return m.Target().Close(m, arg...)
|
||||||
|
}
|
||||||
|
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 {
|
||||||
|
m.Log("error", "context not find %s", name)
|
||||||
|
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) != "" {
|
||||||
|
m.Log("search", "%d %s match [%s]", len(cs), m.target.Name, key)
|
||||||
|
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 (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 []string{"aaa", "ssh", "cli", "nfs"} {
|
||||||
|
if msg := m.Sess(v, false); msg != nil && msg.target != nil {
|
||||||
|
context = append(context, msg.target)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if m.target.root != nil && m.target.root.Configs != nil && m.target.root.Configs["search"] != nil && m.target.root.Configs["search"].Value != nil {
|
||||||
|
// target := m.target
|
||||||
|
// for _, v := range kit.Trans(kit.Chain(m.target.root.Configs["search"].Value, "context")) {
|
||||||
|
// if t := m.Find(v, true, true); t != nil {
|
||||||
|
// kit.Log("error", "%v", t)
|
||||||
|
// // // context = append(context, t.target)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// m.target = 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) Backs(msg *Message) *Message {
|
||||||
|
m.Back(msg)
|
||||||
|
return msg
|
||||||
|
}
|
@ -452,16 +452,13 @@ func (nfs *NFS) Auto(what []rune, trigger string, index int) (change bool, frame
|
|||||||
}
|
}
|
||||||
|
|
||||||
table = []map[string]string{}
|
table = []map[string]string{}
|
||||||
m.Spawn(auto_target).Cmd(cmd...).Table(func(maps map[string]string, list []string, line int) bool {
|
m.Spawn(auto_target).Cmd(cmd...).Table(func(line int, maps map[string]string) {
|
||||||
if line >= 0 {
|
fields := []interface{}{}
|
||||||
fields := []interface{}{}
|
for _, v := range auto["fields"].([]interface{}) {
|
||||||
for _, v := range auto["fields"].([]interface{}) {
|
fields = append(fields, maps[kit.Format(v)])
|
||||||
fields = append(fields, maps[kit.Format(v)])
|
|
||||||
}
|
|
||||||
maps["format"] = fmt.Sprintf(kit.Format(auto["format"]), fields...)
|
|
||||||
table = append(table, maps)
|
|
||||||
}
|
}
|
||||||
return true
|
maps["format"] = fmt.Sprintf(kit.Format(auto["format"]), fields...)
|
||||||
|
table = append(table, maps)
|
||||||
})
|
})
|
||||||
m.Conf("term", []interface{}{"help_table", auto["table"]}, table)
|
m.Conf("term", []interface{}{"help_table", auto["table"]}, table)
|
||||||
|
|
||||||
@ -996,14 +993,14 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
|
|||||||
if head == "detail" { // 接收请求
|
if head == "detail" { // 接收请求
|
||||||
msg.Detail(-1, "_route")
|
msg.Detail(-1, "_route")
|
||||||
msg.Option("remote_code", code)
|
msg.Option("remote_code", code)
|
||||||
m.GoFunc(msg, func(msg *ctx.Message) {
|
m.Gos(msg, func(msg *ctx.Message) {
|
||||||
msg.Call(func(msg *ctx.Message) *ctx.Message {
|
msg.Call(func(msg *ctx.Message) *ctx.Message {
|
||||||
nfs.echo <- msg
|
nfs.echo <- msg
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
} else { // 接收响应
|
} else { // 接收响应
|
||||||
m.Set("option", "code", code).GoFunc(msg, func(msg *ctx.Message) {
|
m.Set("option", "code", code).Gos(msg, func(msg *ctx.Message) {
|
||||||
if h, ok := nfs.hand[kit.Int(m.Option("code"))]; ok {
|
if h, ok := nfs.hand[kit.Int(m.Option("code"))]; ok {
|
||||||
h.CopyFuck(msg, "result").CopyFuck(msg, "append").Back(h)
|
h.CopyFuck(msg, "result").CopyFuck(msg, "append").Back(h)
|
||||||
}
|
}
|
||||||
@ -1405,7 +1402,9 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
|
|||||||
|
|
||||||
for _, from := range arg[1:] {
|
for _, from := range arg[1:] {
|
||||||
f, e := os.Open(from)
|
f, e := os.Open(from)
|
||||||
m.Assert(e)
|
if e != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
n, e := io.Copy(to, f)
|
n, e := io.Copy(to, f)
|
||||||
|
@ -164,9 +164,10 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
|
|||||||
"favor": []interface{}{
|
"favor": []interface{}{
|
||||||
map[string]interface{}{"componet_name": "clip", "componet_help": "粘贴板",
|
map[string]interface{}{"componet_name": "clip", "componet_help": "粘贴板",
|
||||||
"componet_tmpl": "componet", "componet_view": "Context", "componet_init": "",
|
"componet_tmpl": "componet", "componet_view": "Context", "componet_init": "",
|
||||||
"componet_type": "public", "componet_ctx": "aaa", "componet_cmd": "clip",
|
"componet_type": "public", "componet_ctx": "ssh", "componet_cmd": "_route",
|
||||||
"componet_args": []interface{}{}, "inputs": []interface{}{
|
"componet_args": []interface{}{"$$", "context", "aaa", "clip"}, "inputs": []interface{}{
|
||||||
map[string]interface{}{"type": "text", "name": "content", "view": "long"},
|
map[string]interface{}{"type": "text", "name": "you", "imports": "plugin_you"},
|
||||||
|
map[string]interface{}{"type": "text", "name": "txt", "view": "long"},
|
||||||
map[string]interface{}{"type": "button", "value": "运行"},
|
map[string]interface{}{"type": "button", "value": "运行"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -25,7 +25,7 @@ func (tcp *TCP) Fuck(address []string, action func(address string) (net.Conn, er
|
|||||||
for i := 0; i < m.Confi("retry", "counts"); i++ {
|
for i := 0; i < m.Confi("retry", "counts"); i++ {
|
||||||
for _, p := range address {
|
for _, p := range address {
|
||||||
m.Cap("address", p)
|
m.Cap("address", p)
|
||||||
m.GoFunc(m, func(m *ctx.Message) {
|
m.Gos(m, func(m *ctx.Message) {
|
||||||
p := m.Cap("address")
|
p := m.Cap("address")
|
||||||
if c, e := action(p); e == nil {
|
if c, e := action(p); e == nil {
|
||||||
tcp.Conn = c
|
tcp.Conn = c
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
// 数据层
|
|
||||||
_ "contexts/mdb" //数据中心
|
|
||||||
_ "contexts/nfs" //存储中心
|
|
||||||
_ "contexts/ssh" //集群中心
|
|
||||||
_ "contexts/tcp" //网络中心
|
|
||||||
// 控制层
|
|
||||||
_ "contexts/gdb" //调试中心
|
|
||||||
_ "contexts/lex" //词法中心
|
|
||||||
_ "contexts/log" //日志中心
|
|
||||||
_ "contexts/yac" //语法中心
|
|
||||||
// 服务层
|
|
||||||
_ "contexts/aaa" //认证中心
|
|
||||||
_ "contexts/cli" //管理中心
|
|
||||||
c "contexts/ctx" //模块中心
|
|
||||||
_ "contexts/web" //应用中心
|
|
||||||
|
|
||||||
// 应用层
|
|
||||||
_ "examples/chat" //会议中心
|
|
||||||
_ "examples/code" //代码中心
|
|
||||||
_ "examples/wiki" //文档中心
|
|
||||||
// _ "examples/jira" //任务中心
|
|
||||||
// _ "examples/mall" //交易中心
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
c.Start()
|
|
||||||
}
|
|
@ -1,83 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"regexp"
|
|
||||||
"toolkit"
|
|
||||||
)
|
|
||||||
|
|
||||||
var files = ".*\\.(xml|html|css|js)$"
|
|
||||||
var words = "[[:^ascii:]]+"
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
if len(os.Args) == 1 {
|
|
||||||
fmt.Println("usage", os.Args[0], "dirs [files [words]]")
|
|
||||||
fmt.Println("在目录dirs中,查找匹配files的文件,并查找匹配words的单词")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(os.Args) > 2 {
|
|
||||||
files = os.Args[2]
|
|
||||||
}
|
|
||||||
if len(os.Args) > 3 {
|
|
||||||
words = os.Args[3]
|
|
||||||
}
|
|
||||||
|
|
||||||
word, e := regexp.Compile(words)
|
|
||||||
kit.Check(e)
|
|
||||||
// out, e := os.Create(os.Args[2])
|
|
||||||
// kit.Check(e)
|
|
||||||
out := os.Stdout
|
|
||||||
|
|
||||||
total := 0
|
|
||||||
count := 0
|
|
||||||
chars := 0
|
|
||||||
kit.DirWalk(os.Args[1], func(file string) {
|
|
||||||
s, _ := os.Stat(file)
|
|
||||||
if s.IsDir() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if m, e := regexp.MatchString(files, file); !kit.Check(e) || !m {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
f, e := os.Open(file)
|
|
||||||
kit.Check(e)
|
|
||||||
bio := bufio.NewReader(f)
|
|
||||||
|
|
||||||
fmt.Fprintln(out, kit.FmtSize(s.Size()), file)
|
|
||||||
line := 0
|
|
||||||
|
|
||||||
cs := 0
|
|
||||||
for i := 1; true; i++ {
|
|
||||||
l, e := bio.ReadString('\n')
|
|
||||||
if e == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
kit.Check(e)
|
|
||||||
if i == 1 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
a := word.FindAllString(l, 20)
|
|
||||||
for _, v := range a {
|
|
||||||
n := len([]rune(v))
|
|
||||||
fmt.Fprintf(out, "l:%d c:%d %s\n", i, n, v)
|
|
||||||
total++
|
|
||||||
line++
|
|
||||||
chars += n
|
|
||||||
cs += n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fmt.Fprintln(out, "lines:", line, "chars:", cs, file)
|
|
||||||
fmt.Fprintln(out)
|
|
||||||
if line > 0 {
|
|
||||||
count++
|
|
||||||
}
|
|
||||||
})
|
|
||||||
fmt.Fprintln(out, "files:", count, "lines:", total, "chars:", chars, os.Args[1])
|
|
||||||
return
|
|
||||||
}
|
|
@ -1,68 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
if len(os.Args) < 3 {
|
|
||||||
fmt.Printf("usage: %s file server", os.Args[0])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
prefix0 := len("uri[")
|
|
||||||
prefix1 := len("request_param[")
|
|
||||||
|
|
||||||
if os.Mkdir("tmp", 0777) != nil {
|
|
||||||
}
|
|
||||||
|
|
||||||
begin := time.Now()
|
|
||||||
f, e := os.Open(os.Args[1])
|
|
||||||
if e != nil {
|
|
||||||
fmt.Printf("%s\n", e)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
bio := bufio.NewScanner(f)
|
|
||||||
output := map[string]*os.File{}
|
|
||||||
nreq := 0
|
|
||||||
|
|
||||||
for bio.Scan() {
|
|
||||||
word := strings.Split(bio.Text(), " ")
|
|
||||||
if len(word) != 2 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
uri := word[0][prefix0:len(word[0])-1]
|
|
||||||
arg := word[1][prefix1:len(word[1])-1]
|
|
||||||
if output[uri] == nil {
|
|
||||||
name := path.Join("tmp", strings.Replace(uri, "/", "_", -1)+".txt")
|
|
||||||
f, e = os.Create(name)
|
|
||||||
output[uri] = f
|
|
||||||
}
|
|
||||||
nreq++
|
|
||||||
br := bytes.NewReader([]byte(arg))
|
|
||||||
fmt.Printf("%d post: %v\n", nreq, os.Args[2]+uri)
|
|
||||||
res, e := http.Post(os.Args[2]+uri, "application/json", br)
|
|
||||||
fmt.Fprintf(output[uri], uri)
|
|
||||||
fmt.Fprintf(output[uri], " arguments:")
|
|
||||||
fmt.Fprintf(output[uri], arg)
|
|
||||||
fmt.Fprintf(output[uri], " result:")
|
|
||||||
if e != nil {
|
|
||||||
fmt.Fprintf(output[uri], "%v", e)
|
|
||||||
} else if res.StatusCode != http.StatusOK {
|
|
||||||
fmt.Fprintf(output[uri], res.Status)
|
|
||||||
} else {
|
|
||||||
io.Copy(output[uri], res.Body)
|
|
||||||
}
|
|
||||||
fmt.Fprintf(output[uri], "\n")
|
|
||||||
}
|
|
||||||
fmt.Printf("nuri: %v nreq: %v cost: %v", len(output), nreq, time.Since(begin))
|
|
||||||
}
|
|
@ -153,11 +153,10 @@ var Index = &ctx.Context{Name: "wiki", Help: "文档中心",
|
|||||||
m.Sort(sort_field, sort_order).Table()
|
m.Sort(sort_field, sort_order).Table()
|
||||||
|
|
||||||
m.Target().Configs["wiki_list"].Value = []interface{}{}
|
m.Target().Configs["wiki_list"].Value = []interface{}{}
|
||||||
m.Table(func(maps map[string]string, list []string, line int) bool {
|
m.Table(func(line int, maps map[string]string) {
|
||||||
if line > 0 {
|
if line > 1 {
|
||||||
m.Confv("wiki_list", -2, maps)
|
m.Confv("wiki_list", -2, maps)
|
||||||
}
|
}
|
||||||
return true
|
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}},
|
}},
|
||||||
|
298
src/toolkit/core.go
Normal file
298
src/toolkit/core.go
Normal file
@ -0,0 +1,298 @@
|
|||||||
|
package kit
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"math/rand"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var DisableLog = false
|
||||||
|
|
||||||
|
func Env(key string) {
|
||||||
|
os.Getenv(key)
|
||||||
|
}
|
||||||
|
func Log(action string, str string, args ...interface{}) {
|
||||||
|
if DisableLog {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(args) > 0 {
|
||||||
|
str = fmt.Sprintf(str, args...)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(os.Stderr, "%s: %s\n", action, str)
|
||||||
|
}
|
||||||
|
func Errorf(str string, args ...interface{}) {
|
||||||
|
Log("error", str, args...)
|
||||||
|
}
|
||||||
|
func Debugf(str string, args ...interface{}) {
|
||||||
|
Log("debug", str, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Time(arg ...string) int {
|
||||||
|
if len(arg) == 0 {
|
||||||
|
return Int(time.Now())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(arg) > 1 {
|
||||||
|
if t, e := time.ParseInLocation(arg[1], arg[0], time.Local); e == nil {
|
||||||
|
return Int(t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range []string{
|
||||||
|
"2006-01-02 15:04:05",
|
||||||
|
"2006-01-02 15:04",
|
||||||
|
"2006-01-02",
|
||||||
|
"2006/01/02",
|
||||||
|
"01-02 15:04",
|
||||||
|
} {
|
||||||
|
if t, e := time.ParseInLocation(v, arg[0], time.Local); e == nil {
|
||||||
|
return Int(t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
func Duration(arg ...string) time.Duration {
|
||||||
|
d, _ := time.ParseDuration(arg[0])
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
func Hash(arg ...interface{}) (string, []string) {
|
||||||
|
args := []string{}
|
||||||
|
for _, v := range Trans(arg...) {
|
||||||
|
switch v {
|
||||||
|
case "time":
|
||||||
|
args = append(args, Format(time.Now()))
|
||||||
|
case "rand":
|
||||||
|
args = append(args, Format(rand.Int()))
|
||||||
|
case "uniq":
|
||||||
|
args = append(args, Format(time.Now()))
|
||||||
|
args = append(args, Format(rand.Int()))
|
||||||
|
default:
|
||||||
|
if s, e := os.Stat(v); e == nil && !s.IsDir() {
|
||||||
|
if f, e := os.Open(v); e == nil {
|
||||||
|
defer f.Close()
|
||||||
|
m := md5.New()
|
||||||
|
io.Copy(m, f)
|
||||||
|
h := m.Sum(nil)
|
||||||
|
args = append(args, hex.EncodeToString(h[:]))
|
||||||
|
return hex.EncodeToString(h[:]), args
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args = append(args, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h := md5.Sum([]byte(strings.Join(args, "")))
|
||||||
|
return hex.EncodeToString(h[:]), args
|
||||||
|
}
|
||||||
|
func Hashs(arg ...interface{}) string {
|
||||||
|
h, _ := Hash(arg...)
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
func Chain(root interface{}, args ...interface{}) interface{} {
|
||||||
|
for i := 0; i < len(args); i += 2 {
|
||||||
|
if arg, ok := args[i].(map[string]interface{}); ok {
|
||||||
|
argn := []interface{}{}
|
||||||
|
for k, v := range arg {
|
||||||
|
argn = append(argn, k, v)
|
||||||
|
}
|
||||||
|
argn = append(argn, args[i+1:])
|
||||||
|
args, i = argn, -2
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var parent interface{}
|
||||||
|
parent_key, parent_index := "", 0
|
||||||
|
|
||||||
|
keys := []string{}
|
||||||
|
for _, v := range Trans(args[i]) {
|
||||||
|
keys = append(keys, strings.Split(v, ".")...)
|
||||||
|
}
|
||||||
|
|
||||||
|
data := root
|
||||||
|
for j, key := range keys {
|
||||||
|
index, e := strconv.Atoi(key)
|
||||||
|
|
||||||
|
// Log("error", "chain [%v %v] [%v %v] [%v/%v %v/%v] %v", parent_key, parent_index, key, index, i, len(args), j, len(keys), data)
|
||||||
|
|
||||||
|
var next interface{}
|
||||||
|
switch value := data.(type) {
|
||||||
|
case nil:
|
||||||
|
if i == len(args)-1 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if j == len(keys)-1 {
|
||||||
|
next = args[i+1]
|
||||||
|
}
|
||||||
|
|
||||||
|
if e == nil {
|
||||||
|
data, index = []interface{}{next}, 0
|
||||||
|
} else {
|
||||||
|
data = map[string]interface{}{key: next}
|
||||||
|
}
|
||||||
|
case []string:
|
||||||
|
index = (index+2+len(value)+2)%(len(value)+2) - 2
|
||||||
|
|
||||||
|
if j == len(keys)-1 {
|
||||||
|
if i == len(args)-1 {
|
||||||
|
if index < 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return value[index]
|
||||||
|
}
|
||||||
|
next = args[i+1]
|
||||||
|
}
|
||||||
|
|
||||||
|
if index == -1 {
|
||||||
|
data, index = append([]string{Format(next)}, value...), 0
|
||||||
|
} else {
|
||||||
|
data, index = append(value, Format(next)), len(value)
|
||||||
|
}
|
||||||
|
next = value[index]
|
||||||
|
case map[string]string:
|
||||||
|
if j == len(keys)-1 {
|
||||||
|
if i == len(args)-1 {
|
||||||
|
return value[key] // 读取数据
|
||||||
|
}
|
||||||
|
value[key] = Format(next) // 修改数据
|
||||||
|
}
|
||||||
|
next = value[key]
|
||||||
|
case map[string]interface{}:
|
||||||
|
if j == len(keys)-1 {
|
||||||
|
if i == len(args)-1 {
|
||||||
|
return value[key] // 读取数据
|
||||||
|
}
|
||||||
|
value[key] = args[i+1] // 修改数据
|
||||||
|
if !Right(args[i+1]) {
|
||||||
|
delete(value, key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
next = value[key]
|
||||||
|
case []interface{}:
|
||||||
|
index = (index+2+len(value)+2)%(len(value)+2) - 2
|
||||||
|
|
||||||
|
if j == len(keys)-1 {
|
||||||
|
if i == len(args)-1 {
|
||||||
|
if index < 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return value[index] // 读取数据
|
||||||
|
}
|
||||||
|
next = args[i+1] // 修改数据
|
||||||
|
}
|
||||||
|
|
||||||
|
if index == -1 {
|
||||||
|
value, index = append([]interface{}{next}, value...), 0
|
||||||
|
} else if index == -2 {
|
||||||
|
value, index = append(value, next), len(value)
|
||||||
|
} else if j == len(keys)-1 {
|
||||||
|
value[index] = next
|
||||||
|
}
|
||||||
|
data, next = value, value[index]
|
||||||
|
}
|
||||||
|
|
||||||
|
switch p := parent.(type) {
|
||||||
|
case map[string]interface{}:
|
||||||
|
p[parent_key] = data
|
||||||
|
case []interface{}:
|
||||||
|
p[parent_index] = data
|
||||||
|
case nil:
|
||||||
|
root = data
|
||||||
|
}
|
||||||
|
|
||||||
|
parent, data = data, next
|
||||||
|
parent_key, parent_index = key, index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return root
|
||||||
|
}
|
||||||
|
func Chains(root interface{}, args ...interface{}) string {
|
||||||
|
return Format(Chain(root, args...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func Select(value string, args ...interface{}) string {
|
||||||
|
if len(args) == 0 {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
switch arg := args[0].(type) {
|
||||||
|
case string:
|
||||||
|
if len(args) > 1 {
|
||||||
|
switch b := args[1].(type) {
|
||||||
|
case bool:
|
||||||
|
if b && arg != "" {
|
||||||
|
return arg
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if arg != "" {
|
||||||
|
return arg
|
||||||
|
}
|
||||||
|
case []interface{}:
|
||||||
|
index := 0
|
||||||
|
if len(args) > 1 {
|
||||||
|
index = Int(args[1])
|
||||||
|
}
|
||||||
|
if index < len(arg) && Format(arg[index]) != "" {
|
||||||
|
return Format(arg[index])
|
||||||
|
}
|
||||||
|
case []string:
|
||||||
|
index := 0
|
||||||
|
if len(args) > 1 {
|
||||||
|
index = Int(args[1])
|
||||||
|
}
|
||||||
|
if index < len(arg) && arg[index] != "" {
|
||||||
|
return arg[index]
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if v := Format(args...); v != "" {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
func Slice(arg []string, args ...interface{}) ([]string, string) {
|
||||||
|
if len(arg) == 0 {
|
||||||
|
return arg, ""
|
||||||
|
}
|
||||||
|
if len(args) == 0 {
|
||||||
|
return arg[1:], arg[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
result := ""
|
||||||
|
switch v := args[0].(type) {
|
||||||
|
case int:
|
||||||
|
case string:
|
||||||
|
if arg[0] == v && len(arg) > 1 {
|
||||||
|
return arg[2:], arg[1]
|
||||||
|
}
|
||||||
|
if len(args) > 1 {
|
||||||
|
return arg, Format(args[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return arg, result
|
||||||
|
}
|
||||||
|
func View(args []string, conf map[string]interface{}) []string {
|
||||||
|
if len(args) == 0 {
|
||||||
|
args = append(args, "default")
|
||||||
|
}
|
||||||
|
|
||||||
|
keys := []string{}
|
||||||
|
for _, k := range args {
|
||||||
|
if v, ok := conf[k]; ok {
|
||||||
|
keys = append(keys, Trans(v)...)
|
||||||
|
} else {
|
||||||
|
keys = append(keys, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return keys
|
||||||
|
}
|
@ -1,764 +0,0 @@
|
|||||||
package kit
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/md5"
|
|
||||||
"encoding/hex"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"io/ioutil"
|
|
||||||
"math/rand"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type TERM interface {
|
|
||||||
Show(...interface{}) bool
|
|
||||||
}
|
|
||||||
|
|
||||||
var STDIO TERM
|
|
||||||
|
|
||||||
var DisableLog = false
|
|
||||||
var EnableDebug = false
|
|
||||||
|
|
||||||
func Log(action string, str string, args ...interface{}) {
|
|
||||||
if DisableLog {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(args) > 0 {
|
|
||||||
str = fmt.Sprintf(str, args...)
|
|
||||||
}
|
|
||||||
fmt.Fprintf(os.Stderr, "%s: %s\n", action, str)
|
|
||||||
}
|
|
||||||
func Errorf(str string, args ...interface{}) {
|
|
||||||
Log("error", str, args...)
|
|
||||||
}
|
|
||||||
func Debugf(str string, args ...interface{}) {
|
|
||||||
Log("debug", str, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Key(name string) string {
|
|
||||||
return strings.Replace(name, ".", "_", -1)
|
|
||||||
}
|
|
||||||
func Env(key string) {
|
|
||||||
os.Getenv(key)
|
|
||||||
}
|
|
||||||
func Width(str string, mul int) int {
|
|
||||||
return len([]rune(str)) + (len(str)-len([]rune(str)))/2/mul
|
|
||||||
}
|
|
||||||
func Len(arg interface{}) int {
|
|
||||||
switch arg := arg.(type) {
|
|
||||||
case []interface{}:
|
|
||||||
return len(arg)
|
|
||||||
case map[string]interface{}:
|
|
||||||
return len(arg)
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
func Int(arg ...interface{}) int {
|
|
||||||
result := 0
|
|
||||||
for _, v := range arg {
|
|
||||||
switch val := v.(type) {
|
|
||||||
case int:
|
|
||||||
result += val
|
|
||||||
case int8:
|
|
||||||
result += int(val)
|
|
||||||
case int16:
|
|
||||||
result += int(val)
|
|
||||||
// case int32:
|
|
||||||
// result += int(val)
|
|
||||||
case int64:
|
|
||||||
result += int(val)
|
|
||||||
// case uint8:
|
|
||||||
// result += int(val)
|
|
||||||
case uint16:
|
|
||||||
result += int(val)
|
|
||||||
case uint32:
|
|
||||||
result += int(val)
|
|
||||||
case uint64:
|
|
||||||
result += int(val)
|
|
||||||
case float64:
|
|
||||||
result += int(val)
|
|
||||||
case byte: // uint8
|
|
||||||
result += int(val)
|
|
||||||
case rune: // int32
|
|
||||||
result += int(val)
|
|
||||||
case string:
|
|
||||||
if i, e := strconv.Atoi(val); e == nil {
|
|
||||||
result += i
|
|
||||||
}
|
|
||||||
case bool:
|
|
||||||
if val {
|
|
||||||
result += 1
|
|
||||||
}
|
|
||||||
case time.Time:
|
|
||||||
result += int(val.Unix())
|
|
||||||
case []string:
|
|
||||||
result += len(val)
|
|
||||||
case map[string]string:
|
|
||||||
result += len(val)
|
|
||||||
case []interface{}:
|
|
||||||
result += len(val)
|
|
||||||
case map[string]interface{}:
|
|
||||||
result += len(val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
func Int64(arg ...interface{}) int64 {
|
|
||||||
var result int64
|
|
||||||
for _, v := range arg {
|
|
||||||
switch val := v.(type) {
|
|
||||||
case int:
|
|
||||||
result += int64(val)
|
|
||||||
case int8:
|
|
||||||
result += int64(val)
|
|
||||||
case int16:
|
|
||||||
result += int64(val)
|
|
||||||
// case int32:
|
|
||||||
// result += int64(val)
|
|
||||||
case int64:
|
|
||||||
result += int64(val)
|
|
||||||
// case uint8:
|
|
||||||
// result += int64(val)
|
|
||||||
case uint16:
|
|
||||||
result += int64(val)
|
|
||||||
case uint32:
|
|
||||||
result += int64(val)
|
|
||||||
case uint64:
|
|
||||||
result += int64(val)
|
|
||||||
case float64:
|
|
||||||
result += int64(val)
|
|
||||||
case byte: // uint8
|
|
||||||
result += int64(val)
|
|
||||||
case rune: // int32
|
|
||||||
result += int64(val)
|
|
||||||
case string:
|
|
||||||
if i, e := strconv.ParseInt(val, 10, 64); e == nil {
|
|
||||||
result += i
|
|
||||||
}
|
|
||||||
case bool:
|
|
||||||
if val {
|
|
||||||
result += 1
|
|
||||||
}
|
|
||||||
case time.Time:
|
|
||||||
result += int64(val.Unix())
|
|
||||||
case []string:
|
|
||||||
result += int64(len(val))
|
|
||||||
case map[string]string:
|
|
||||||
result += int64(len(val))
|
|
||||||
case []interface{}:
|
|
||||||
result += int64(len(val))
|
|
||||||
case map[string]interface{}:
|
|
||||||
result += int64(len(val))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
func Right(arg ...interface{}) bool {
|
|
||||||
result := false
|
|
||||||
for _, v := range arg {
|
|
||||||
switch val := v.(type) {
|
|
||||||
case int:
|
|
||||||
result = result || val != 0
|
|
||||||
case bool:
|
|
||||||
result = result || val
|
|
||||||
case string:
|
|
||||||
switch val {
|
|
||||||
case "", "0", "false", "off", "no", "error: ":
|
|
||||||
result = result || false
|
|
||||||
default:
|
|
||||||
result = result || true
|
|
||||||
}
|
|
||||||
case error:
|
|
||||||
result = result || false
|
|
||||||
case []string:
|
|
||||||
result = result || len(val) > 0
|
|
||||||
case map[string]string:
|
|
||||||
result = result || len(val) > 0
|
|
||||||
case []interface{}:
|
|
||||||
result = result || len(val) > 0
|
|
||||||
case map[string]interface{}:
|
|
||||||
result = result || len(val) > 0
|
|
||||||
default:
|
|
||||||
result = result || val != nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
func Format(arg ...interface{}) string {
|
|
||||||
result := []string{}
|
|
||||||
for _, v := range arg {
|
|
||||||
switch val := v.(type) {
|
|
||||||
case nil:
|
|
||||||
result = result[:0]
|
|
||||||
case int, int8, int16, int32, int64:
|
|
||||||
result = append(result, fmt.Sprintf("%d", val))
|
|
||||||
case uint, uint8, uint16, uint32, uint64:
|
|
||||||
result = append(result, fmt.Sprintf("%d", val))
|
|
||||||
case float64:
|
|
||||||
result = append(result, fmt.Sprintf("%d", int(val)))
|
|
||||||
case bool:
|
|
||||||
result = append(result, fmt.Sprintf("%t", val))
|
|
||||||
case string:
|
|
||||||
result = append(result, val)
|
|
||||||
case []byte:
|
|
||||||
result = append(result, string(val))
|
|
||||||
case []rune:
|
|
||||||
result = append(result, string(val))
|
|
||||||
case []string:
|
|
||||||
result = append(result, val...)
|
|
||||||
// case []interface{}:
|
|
||||||
//
|
|
||||||
// result = append(result, "[")
|
|
||||||
// for i, value := range val {
|
|
||||||
// result = append(result, Format(value))
|
|
||||||
// if i < len(val)-1 {
|
|
||||||
// result = append(result, ",")
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// result = append(result, "]")
|
|
||||||
case time.Time:
|
|
||||||
result = append(result, fmt.Sprintf("%s", val.Format("2006-01-02 15:03:04")))
|
|
||||||
case *os.File:
|
|
||||||
if s, e := val.Stat(); e == nil {
|
|
||||||
result = append(result, fmt.Sprintf("%T [name: %s]", v, s.Name()))
|
|
||||||
} else {
|
|
||||||
result = append(result, fmt.Sprintf("%T", v))
|
|
||||||
}
|
|
||||||
// case error:
|
|
||||||
// result = append(result, fmt.Sprintf("%v", val))
|
|
||||||
default:
|
|
||||||
if b, e := json.Marshal(val); e == nil {
|
|
||||||
result = append(result, string(b))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(result) > 1 {
|
|
||||||
args := []interface{}{}
|
|
||||||
if n := strings.Count(result[0], "%") - strings.Count(result[0], "%%"); len(result) > n {
|
|
||||||
for i := 1; i < n+1; i++ {
|
|
||||||
args = append(args, result[i])
|
|
||||||
}
|
|
||||||
return fmt.Sprintf(result[0], args...) + strings.Join(result[n+1:], "")
|
|
||||||
} else if len(result) == n+1 {
|
|
||||||
for i := 1; i < len(result); i++ {
|
|
||||||
args = append(args, result[i])
|
|
||||||
}
|
|
||||||
return fmt.Sprintf(result[0], args...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return strings.Join(result, "")
|
|
||||||
}
|
|
||||||
func Simple(str string) string {
|
|
||||||
return strings.Replace(strings.TrimSpace(str), "\n", "\\n", -1)
|
|
||||||
}
|
|
||||||
func Formats(arg ...interface{}) string {
|
|
||||||
result := []string{}
|
|
||||||
for _, v := range arg {
|
|
||||||
switch val := v.(type) {
|
|
||||||
// case []interface{}:
|
|
||||||
// for _, v := range val {
|
|
||||||
// result = append(result, Format(v))
|
|
||||||
// }
|
|
||||||
default:
|
|
||||||
if b, e := json.MarshalIndent(val, "", " "); e == nil {
|
|
||||||
result = append(result, string(b))
|
|
||||||
} else {
|
|
||||||
result = append(result, fmt.Sprintf("%#v", val))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return strings.Join(result, " ")
|
|
||||||
}
|
|
||||||
func Trans(arg ...interface{}) []string {
|
|
||||||
ls := []string{}
|
|
||||||
for _, v := range arg {
|
|
||||||
switch val := v.(type) {
|
|
||||||
// case *Message:
|
|
||||||
// if val.Hand {
|
|
||||||
// ls = append(ls, val.Meta["result"]...)
|
|
||||||
// } else {
|
|
||||||
// ls = append(ls, val.Meta["detail"]...)
|
|
||||||
// }
|
|
||||||
case nil:
|
|
||||||
case []float64:
|
|
||||||
for _, v := range val {
|
|
||||||
ls = append(ls, fmt.Sprintf("%d", int(v)))
|
|
||||||
}
|
|
||||||
case []int:
|
|
||||||
for _, v := range val {
|
|
||||||
ls = append(ls, fmt.Sprintf("%d", v))
|
|
||||||
}
|
|
||||||
case []bool:
|
|
||||||
for _, v := range val {
|
|
||||||
ls = append(ls, fmt.Sprintf("%t", v))
|
|
||||||
}
|
|
||||||
case []string:
|
|
||||||
ls = append(ls, val...)
|
|
||||||
case map[string]string:
|
|
||||||
for k, v := range val {
|
|
||||||
ls = append(ls, k, v)
|
|
||||||
}
|
|
||||||
case map[string]interface{}:
|
|
||||||
for k, v := range val {
|
|
||||||
ls = append(ls, k, Format(v))
|
|
||||||
}
|
|
||||||
case []interface{}:
|
|
||||||
for _, v := range val {
|
|
||||||
ls = append(ls, Format(v))
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
ls = append(ls, Format(val))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ls
|
|
||||||
}
|
|
||||||
func Struct(arg ...interface{}) map[string]interface{} {
|
|
||||||
value := map[string]interface{}{}
|
|
||||||
if len(arg) == 0 {
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
switch val := arg[0].(type) {
|
|
||||||
case map[string]interface{}:
|
|
||||||
return val
|
|
||||||
case string:
|
|
||||||
json.Unmarshal([]byte(val), value)
|
|
||||||
}
|
|
||||||
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
func Structm(args ...interface{}) map[string]interface{} {
|
|
||||||
value := Struct(args...)
|
|
||||||
for _, arg := range args {
|
|
||||||
switch val := arg.(type) {
|
|
||||||
case func(k string, v string):
|
|
||||||
for k, v := range value {
|
|
||||||
val(k, Format(v))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
func Array(list []string, index int, arg ...interface{}) []string {
|
|
||||||
if len(arg) == 0 {
|
|
||||||
if -1 < index && index < len(list) {
|
|
||||||
return []string{list[index]}
|
|
||||||
}
|
|
||||||
return []string{""}
|
|
||||||
}
|
|
||||||
|
|
||||||
str := Trans(arg...)
|
|
||||||
|
|
||||||
index = (index+2)%(len(list)+2) - 2
|
|
||||||
if index == -1 {
|
|
||||||
list = append(str, list...)
|
|
||||||
} else if index == -2 {
|
|
||||||
list = append(list, str...)
|
|
||||||
} else {
|
|
||||||
if index < -2 {
|
|
||||||
index += len(list) + 2
|
|
||||||
}
|
|
||||||
if index < 0 {
|
|
||||||
index = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := len(list); i < index+len(str); i++ {
|
|
||||||
list = append(list, "")
|
|
||||||
}
|
|
||||||
for i := 0; i < len(str); i++ {
|
|
||||||
list[index+i] = str[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return list
|
|
||||||
}
|
|
||||||
func Slice(arg []string, args ...interface{}) ([]string, string) {
|
|
||||||
if len(arg) == 0 {
|
|
||||||
return arg, ""
|
|
||||||
}
|
|
||||||
if len(args) == 0 {
|
|
||||||
return arg[1:], arg[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
result := ""
|
|
||||||
switch v := args[0].(type) {
|
|
||||||
case int:
|
|
||||||
case string:
|
|
||||||
if arg[0] == v && len(arg) > 1 {
|
|
||||||
return arg[2:], arg[1]
|
|
||||||
}
|
|
||||||
if len(args) > 1 {
|
|
||||||
return arg, Format(args[1])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return arg, result
|
|
||||||
}
|
|
||||||
func Elect(last interface{}, args ...interface{}) string {
|
|
||||||
if len(args) > 0 {
|
|
||||||
switch arg := args[0].(type) {
|
|
||||||
case []string:
|
|
||||||
index := 0
|
|
||||||
if len(args) > 1 {
|
|
||||||
switch a := args[1].(type) {
|
|
||||||
case string:
|
|
||||||
i, e := strconv.Atoi(a)
|
|
||||||
if e == nil {
|
|
||||||
index = i
|
|
||||||
}
|
|
||||||
case int:
|
|
||||||
index = a
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if 0 <= index && index < len(arg) && arg[index] != "" {
|
|
||||||
return arg[index]
|
|
||||||
}
|
|
||||||
case string:
|
|
||||||
if arg != "" {
|
|
||||||
return arg
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch l := last.(type) {
|
|
||||||
case string:
|
|
||||||
return l
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
func Select(value string, args ...interface{}) string {
|
|
||||||
if len(args) == 0 {
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
|
|
||||||
switch arg := args[0].(type) {
|
|
||||||
case string:
|
|
||||||
if len(args) > 1 {
|
|
||||||
switch b := args[1].(type) {
|
|
||||||
case bool:
|
|
||||||
if b && arg != "" {
|
|
||||||
return arg
|
|
||||||
}
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if arg != "" {
|
|
||||||
return arg
|
|
||||||
}
|
|
||||||
case []interface{}:
|
|
||||||
index := 0
|
|
||||||
if len(args) > 1 {
|
|
||||||
index = Int(args[1])
|
|
||||||
}
|
|
||||||
if index < len(arg) && Format(arg[index]) != "" {
|
|
||||||
return Format(arg[index])
|
|
||||||
}
|
|
||||||
case []string:
|
|
||||||
index := 0
|
|
||||||
if len(args) > 1 {
|
|
||||||
index = Int(args[1])
|
|
||||||
}
|
|
||||||
if index < len(arg) && arg[index] != "" {
|
|
||||||
return arg[index]
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
if v := Format(args...); v != "" {
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
func Chain(root interface{}, args ...interface{}) interface{} {
|
|
||||||
for i := 0; i < len(args); i += 2 {
|
|
||||||
if arg, ok := args[i].(map[string]interface{}); ok {
|
|
||||||
argn := []interface{}{}
|
|
||||||
for k, v := range arg {
|
|
||||||
argn = append(argn, k, v)
|
|
||||||
}
|
|
||||||
argn = append(argn, args[i+1:])
|
|
||||||
args, i = argn, -2
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
var parent interface{}
|
|
||||||
parent_key, parent_index := "", 0
|
|
||||||
|
|
||||||
keys := []string{}
|
|
||||||
for _, v := range Trans(args[i]) {
|
|
||||||
keys = append(keys, strings.Split(v, ".")...)
|
|
||||||
}
|
|
||||||
|
|
||||||
data := root
|
|
||||||
for j, key := range keys {
|
|
||||||
index, e := strconv.Atoi(key)
|
|
||||||
|
|
||||||
// Log("error", "chain [%v %v] [%v %v] [%v/%v %v/%v] %v", parent_key, parent_index, key, index, i, len(args), j, len(keys), data)
|
|
||||||
|
|
||||||
var next interface{}
|
|
||||||
switch value := data.(type) {
|
|
||||||
case nil:
|
|
||||||
if i == len(args)-1 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if j == len(keys)-1 {
|
|
||||||
next = args[i+1]
|
|
||||||
}
|
|
||||||
|
|
||||||
if e == nil {
|
|
||||||
data, index = []interface{}{next}, 0
|
|
||||||
} else {
|
|
||||||
data = map[string]interface{}{key: next}
|
|
||||||
}
|
|
||||||
case []string:
|
|
||||||
index = (index+2+len(value)+2)%(len(value)+2) - 2
|
|
||||||
|
|
||||||
if j == len(keys)-1 {
|
|
||||||
if i == len(args)-1 {
|
|
||||||
if index < 0 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return value[index]
|
|
||||||
}
|
|
||||||
next = args[i+1]
|
|
||||||
}
|
|
||||||
|
|
||||||
if index == -1 {
|
|
||||||
data, index = append([]string{Format(next)}, value...), 0
|
|
||||||
} else {
|
|
||||||
data, index = append(value, Format(next)), len(value)
|
|
||||||
}
|
|
||||||
next = value[index]
|
|
||||||
case map[string]string:
|
|
||||||
if j == len(keys)-1 {
|
|
||||||
if i == len(args)-1 {
|
|
||||||
return value[key] // 读取数据
|
|
||||||
}
|
|
||||||
value[key] = Format(next) // 修改数据
|
|
||||||
}
|
|
||||||
next = value[key]
|
|
||||||
case map[string]interface{}:
|
|
||||||
if j == len(keys)-1 {
|
|
||||||
if i == len(args)-1 {
|
|
||||||
return value[key] // 读取数据
|
|
||||||
}
|
|
||||||
value[key] = args[i+1] // 修改数据
|
|
||||||
if !Right(args[i+1]) {
|
|
||||||
delete(value, key)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
next = value[key]
|
|
||||||
case []interface{}:
|
|
||||||
index = (index+2+len(value)+2)%(len(value)+2) - 2
|
|
||||||
|
|
||||||
if j == len(keys)-1 {
|
|
||||||
if i == len(args)-1 {
|
|
||||||
if index < 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return value[index] // 读取数据
|
|
||||||
}
|
|
||||||
next = args[i+1] // 修改数据
|
|
||||||
}
|
|
||||||
|
|
||||||
if index == -1 {
|
|
||||||
value, index = append([]interface{}{next}, value...), 0
|
|
||||||
} else if index == -2 {
|
|
||||||
value, index = append(value, next), len(value)
|
|
||||||
} else if j == len(keys)-1 {
|
|
||||||
value[index] = next
|
|
||||||
}
|
|
||||||
data, next = value, value[index]
|
|
||||||
}
|
|
||||||
|
|
||||||
switch p := parent.(type) {
|
|
||||||
case map[string]interface{}:
|
|
||||||
p[parent_key] = data
|
|
||||||
case []interface{}:
|
|
||||||
p[parent_index] = data
|
|
||||||
case nil:
|
|
||||||
root = data
|
|
||||||
}
|
|
||||||
|
|
||||||
parent, data = data, next
|
|
||||||
parent_key, parent_index = key, index
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return root
|
|
||||||
}
|
|
||||||
func Chains(root interface{}, args ...interface{}) string {
|
|
||||||
return Format(Chain(root, args...))
|
|
||||||
}
|
|
||||||
|
|
||||||
func View(args []string, conf map[string]interface{}) []string {
|
|
||||||
if len(args) == 0 {
|
|
||||||
args = append(args, "default")
|
|
||||||
}
|
|
||||||
|
|
||||||
keys := []string{}
|
|
||||||
for _, k := range args {
|
|
||||||
if v, ok := conf[k]; ok {
|
|
||||||
keys = append(keys, Trans(v)...)
|
|
||||||
} else {
|
|
||||||
keys = append(keys, k)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return keys
|
|
||||||
}
|
|
||||||
|
|
||||||
func Link(name string, url string) string {
|
|
||||||
return fmt.Sprintf("<a href=\"%s\" target=\"_blank\">%s</a>", url, name)
|
|
||||||
}
|
|
||||||
func Time(arg ...string) int {
|
|
||||||
if len(arg) == 0 {
|
|
||||||
return Int(time.Now())
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(arg) > 1 {
|
|
||||||
if t, e := time.ParseInLocation(arg[1], arg[0], time.Local); e == nil {
|
|
||||||
return Int(t)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, v := range []string{
|
|
||||||
"2006-01-02 15:04:05",
|
|
||||||
"2006-01-02 15:04",
|
|
||||||
"2006-01-02",
|
|
||||||
"2006/01/02",
|
|
||||||
"01-02 15:04",
|
|
||||||
} {
|
|
||||||
if t, e := time.ParseInLocation(v, arg[0], time.Local); e == nil {
|
|
||||||
return Int(t)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
func Duration(arg ...string) time.Duration {
|
|
||||||
d, _ := time.ParseDuration(arg[0])
|
|
||||||
return d
|
|
||||||
}
|
|
||||||
func FileName(name string, meta ...string) string {
|
|
||||||
result, app := strings.Split(name, "."), ""
|
|
||||||
if len(result) > 1 {
|
|
||||||
app, result = result[len(result)-1], result[:len(result)-1]
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, v := range meta {
|
|
||||||
switch v {
|
|
||||||
case "year":
|
|
||||||
result = append(result, "_", time.Now().Format("2006"))
|
|
||||||
case "date":
|
|
||||||
result = append(result, "_", time.Now().Format("0102"))
|
|
||||||
case "time":
|
|
||||||
result = append(result, "_", time.Now().Format("2006_0102_1504"))
|
|
||||||
case "rand":
|
|
||||||
result = append(result, "_", Format(rand.Int()))
|
|
||||||
case "uniq":
|
|
||||||
result = append(result, "_", Format(Time()))
|
|
||||||
result = append(result, "_", Format(rand.Int()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if app != "" {
|
|
||||||
result = append(result, ".", app)
|
|
||||||
}
|
|
||||||
return strings.Join(result, "")
|
|
||||||
}
|
|
||||||
func FmtSize(size uint64) string {
|
|
||||||
if size > 1<<30 {
|
|
||||||
return fmt.Sprintf("%d.%dG", size>>30, (size>>20)%1024*100/1024)
|
|
||||||
}
|
|
||||||
|
|
||||||
if size > 1<<20 {
|
|
||||||
return fmt.Sprintf("%d.%dM", size>>20, (size>>10)%1024*100/1024)
|
|
||||||
}
|
|
||||||
|
|
||||||
if size > 1<<10 {
|
|
||||||
return fmt.Sprintf("%d.%dK", size>>10, size%1024*100/1024)
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Sprintf("%dB", size)
|
|
||||||
}
|
|
||||||
func FmtNano(nano int64) string {
|
|
||||||
if nano > 1000000000 {
|
|
||||||
return fmt.Sprintf("%d.%ds", nano/1000000000, nano/100000000%100)
|
|
||||||
}
|
|
||||||
|
|
||||||
if nano > 1000000 {
|
|
||||||
return fmt.Sprintf("%d.%dms", nano/100000, nano/100000%100)
|
|
||||||
}
|
|
||||||
|
|
||||||
if nano > 1000 {
|
|
||||||
return fmt.Sprintf("%d.%dus", nano/1000, nano/100%100)
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Sprintf("%dns", nano)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Hash(arg ...interface{}) (string, []string) {
|
|
||||||
args := []string{}
|
|
||||||
for _, v := range Trans(arg...) {
|
|
||||||
switch v {
|
|
||||||
case "time":
|
|
||||||
args = append(args, Format(time.Now()))
|
|
||||||
case "rand":
|
|
||||||
args = append(args, Format(rand.Int()))
|
|
||||||
case "uniq":
|
|
||||||
args = append(args, Format(time.Now()))
|
|
||||||
args = append(args, Format(rand.Int()))
|
|
||||||
default:
|
|
||||||
if s, e := os.Stat(v); e == nil && !s.IsDir() {
|
|
||||||
if f, e := os.Open(v); e == nil {
|
|
||||||
defer f.Close()
|
|
||||||
m := md5.New()
|
|
||||||
io.Copy(m, f)
|
|
||||||
h := m.Sum(nil)
|
|
||||||
args = append(args, hex.EncodeToString(h[:]))
|
|
||||||
return hex.EncodeToString(h[:]), args
|
|
||||||
}
|
|
||||||
}
|
|
||||||
args = append(args, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
h := md5.Sum([]byte(strings.Join(args, "")))
|
|
||||||
return hex.EncodeToString(h[:]), args
|
|
||||||
}
|
|
||||||
func Hashs(arg ...interface{}) string {
|
|
||||||
h, _ := Hash(arg...)
|
|
||||||
return h
|
|
||||||
}
|
|
||||||
|
|
||||||
func Block(root interface{}, args ...interface{}) interface{} {
|
|
||||||
|
|
||||||
return root
|
|
||||||
}
|
|
||||||
|
|
||||||
func Check(e error) bool {
|
|
||||||
if e != nil {
|
|
||||||
panic(e)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
func DirWalk(file string, hand func(file string)) {
|
|
||||||
s, e := os.Stat(file)
|
|
||||||
Check(e)
|
|
||||||
hand(file)
|
|
||||||
|
|
||||||
if s.IsDir() {
|
|
||||||
fs, e := ioutil.ReadDir(file)
|
|
||||||
Check(e)
|
|
||||||
|
|
||||||
for _, v := range fs {
|
|
||||||
DirWalk(path.Join(file, v.Name()), hand)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
246
src/toolkit/type.go
Normal file
246
src/toolkit/type.go
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
package kit
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Right(arg ...interface{}) bool {
|
||||||
|
result := false
|
||||||
|
for _, v := range arg {
|
||||||
|
switch val := v.(type) {
|
||||||
|
case int:
|
||||||
|
result = result || val != 0
|
||||||
|
case bool:
|
||||||
|
result = result || val
|
||||||
|
case string:
|
||||||
|
switch val {
|
||||||
|
case "", "0", "false", "off", "no", "error: ":
|
||||||
|
result = result || false
|
||||||
|
default:
|
||||||
|
result = result || true
|
||||||
|
}
|
||||||
|
case error:
|
||||||
|
result = result || false
|
||||||
|
case []string:
|
||||||
|
result = result || len(val) > 0
|
||||||
|
case map[string]string:
|
||||||
|
result = result || len(val) > 0
|
||||||
|
case []interface{}:
|
||||||
|
result = result || len(val) > 0
|
||||||
|
case map[string]interface{}:
|
||||||
|
result = result || len(val) > 0
|
||||||
|
default:
|
||||||
|
result = result || val != nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
func Int64(arg ...interface{}) int64 {
|
||||||
|
var result int64
|
||||||
|
for _, v := range arg {
|
||||||
|
switch val := v.(type) {
|
||||||
|
case int:
|
||||||
|
result += int64(val)
|
||||||
|
case int8:
|
||||||
|
result += int64(val)
|
||||||
|
case int16:
|
||||||
|
result += int64(val)
|
||||||
|
// case int32:
|
||||||
|
// result += int64(val)
|
||||||
|
case int64:
|
||||||
|
result += int64(val)
|
||||||
|
// case uint8:
|
||||||
|
// result += int64(val)
|
||||||
|
case uint16:
|
||||||
|
result += int64(val)
|
||||||
|
case uint32:
|
||||||
|
result += int64(val)
|
||||||
|
case uint64:
|
||||||
|
result += int64(val)
|
||||||
|
case float64:
|
||||||
|
result += int64(val)
|
||||||
|
case byte: // uint8
|
||||||
|
result += int64(val)
|
||||||
|
case rune: // int32
|
||||||
|
result += int64(val)
|
||||||
|
case string:
|
||||||
|
if i, e := strconv.ParseInt(val, 10, 64); e == nil {
|
||||||
|
result += i
|
||||||
|
}
|
||||||
|
case bool:
|
||||||
|
if val {
|
||||||
|
result += 1
|
||||||
|
}
|
||||||
|
case time.Time:
|
||||||
|
result += int64(val.Unix())
|
||||||
|
case []string:
|
||||||
|
result += int64(len(val))
|
||||||
|
case map[string]string:
|
||||||
|
result += int64(len(val))
|
||||||
|
case []interface{}:
|
||||||
|
result += int64(len(val))
|
||||||
|
case map[string]interface{}:
|
||||||
|
result += int64(len(val))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
func Int(arg ...interface{}) int {
|
||||||
|
return int(Int64(arg...))
|
||||||
|
}
|
||||||
|
func Key(name string) string {
|
||||||
|
return strings.Replace(name, ".", "_", -1)
|
||||||
|
}
|
||||||
|
func Format(arg ...interface{}) string {
|
||||||
|
result := []string{}
|
||||||
|
for _, v := range arg {
|
||||||
|
switch val := v.(type) {
|
||||||
|
case nil:
|
||||||
|
result = result[:0]
|
||||||
|
case int, int8, int16, int32, int64:
|
||||||
|
result = append(result, fmt.Sprintf("%d", val))
|
||||||
|
case uint, uint8, uint16, uint32, uint64:
|
||||||
|
result = append(result, fmt.Sprintf("%d", val))
|
||||||
|
case float64:
|
||||||
|
result = append(result, fmt.Sprintf("%d", int(val)))
|
||||||
|
case bool:
|
||||||
|
result = append(result, fmt.Sprintf("%t", val))
|
||||||
|
case string:
|
||||||
|
result = append(result, val)
|
||||||
|
case []byte:
|
||||||
|
result = append(result, string(val))
|
||||||
|
case []rune:
|
||||||
|
result = append(result, string(val))
|
||||||
|
case []string:
|
||||||
|
result = append(result, val...)
|
||||||
|
// case []interface{}:
|
||||||
|
//
|
||||||
|
// result = append(result, "[")
|
||||||
|
// for i, value := range val {
|
||||||
|
// result = append(result, Format(value))
|
||||||
|
// if i < len(val)-1 {
|
||||||
|
// result = append(result, ",")
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// result = append(result, "]")
|
||||||
|
case time.Time:
|
||||||
|
result = append(result, fmt.Sprintf("%s", val.Format("2006-01-02 15:03:04")))
|
||||||
|
case *os.File:
|
||||||
|
if s, e := val.Stat(); e == nil {
|
||||||
|
result = append(result, fmt.Sprintf("%T [name: %s]", v, s.Name()))
|
||||||
|
} else {
|
||||||
|
result = append(result, fmt.Sprintf("%T", v))
|
||||||
|
}
|
||||||
|
// case error:
|
||||||
|
// result = append(result, fmt.Sprintf("%v", val))
|
||||||
|
default:
|
||||||
|
if b, e := json.Marshal(val); e == nil {
|
||||||
|
result = append(result, string(b))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(result) > 1 {
|
||||||
|
args := []interface{}{}
|
||||||
|
if n := strings.Count(result[0], "%") - strings.Count(result[0], "%%"); len(result) > n {
|
||||||
|
for i := 1; i < n+1; i++ {
|
||||||
|
args = append(args, result[i])
|
||||||
|
}
|
||||||
|
return fmt.Sprintf(result[0], args...) + strings.Join(result[n+1:], "")
|
||||||
|
} else if len(result) == n+1 {
|
||||||
|
for i := 1; i < len(result); i++ {
|
||||||
|
args = append(args, result[i])
|
||||||
|
}
|
||||||
|
return fmt.Sprintf(result[0], args...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strings.Join(result, "")
|
||||||
|
}
|
||||||
|
func Formats(arg ...interface{}) string {
|
||||||
|
result := []string{}
|
||||||
|
for _, v := range arg {
|
||||||
|
switch val := v.(type) {
|
||||||
|
default:
|
||||||
|
if b, e := json.MarshalIndent(val, "", " "); e == nil {
|
||||||
|
result = append(result, string(b))
|
||||||
|
} else {
|
||||||
|
result = append(result, fmt.Sprintf("%#v", val))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strings.Join(result, " ")
|
||||||
|
}
|
||||||
|
func Trans(arg ...interface{}) []string {
|
||||||
|
ls := []string{}
|
||||||
|
for _, v := range arg {
|
||||||
|
switch val := v.(type) {
|
||||||
|
// case *Message:
|
||||||
|
// if val.Hand {
|
||||||
|
// ls = append(ls, val.Meta["result"]...)
|
||||||
|
// } else {
|
||||||
|
// ls = append(ls, val.Meta["detail"]...)
|
||||||
|
// }
|
||||||
|
case nil:
|
||||||
|
case []float64:
|
||||||
|
for _, v := range val {
|
||||||
|
ls = append(ls, fmt.Sprintf("%d", int(v)))
|
||||||
|
}
|
||||||
|
case []int:
|
||||||
|
for _, v := range val {
|
||||||
|
ls = append(ls, fmt.Sprintf("%d", v))
|
||||||
|
}
|
||||||
|
case []bool:
|
||||||
|
for _, v := range val {
|
||||||
|
ls = append(ls, fmt.Sprintf("%t", v))
|
||||||
|
}
|
||||||
|
case []string:
|
||||||
|
ls = append(ls, val...)
|
||||||
|
case map[string]string:
|
||||||
|
for k, v := range val {
|
||||||
|
ls = append(ls, k, v)
|
||||||
|
}
|
||||||
|
case map[string]interface{}:
|
||||||
|
for k, v := range val {
|
||||||
|
ls = append(ls, k, Format(v))
|
||||||
|
}
|
||||||
|
case []interface{}:
|
||||||
|
for _, v := range val {
|
||||||
|
ls = append(ls, Format(v))
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
ls = append(ls, Format(val))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ls
|
||||||
|
}
|
||||||
|
func Struct(arg ...interface{}) map[string]interface{} {
|
||||||
|
value := map[string]interface{}{}
|
||||||
|
if len(arg) == 0 {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
switch val := arg[0].(type) {
|
||||||
|
case map[string]interface{}:
|
||||||
|
return val
|
||||||
|
case string:
|
||||||
|
json.Unmarshal([]byte(val), value)
|
||||||
|
}
|
||||||
|
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
func Structm(args ...interface{}) map[string]interface{} {
|
||||||
|
value := Struct(args...)
|
||||||
|
for _, arg := range args {
|
||||||
|
switch val := arg.(type) {
|
||||||
|
case func(k string, v string):
|
||||||
|
for k, v := range value {
|
||||||
|
val(k, Format(v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
190
src/toolkit/what.go
Normal file
190
src/toolkit/what.go
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
package kit
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"io/ioutil"
|
||||||
|
"math/rand"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TERM interface {
|
||||||
|
Show(...interface{}) bool
|
||||||
|
}
|
||||||
|
|
||||||
|
var STDIO TERM
|
||||||
|
|
||||||
|
var EnableDebug = false
|
||||||
|
|
||||||
|
func Width(str string, mul int) int {
|
||||||
|
return len([]rune(str)) + (len(str)-len([]rune(str)))/2/mul
|
||||||
|
}
|
||||||
|
func Len(arg interface{}) int {
|
||||||
|
switch arg := arg.(type) {
|
||||||
|
case []interface{}:
|
||||||
|
return len(arg)
|
||||||
|
case map[string]interface{}:
|
||||||
|
return len(arg)
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
func Simple(str string) string {
|
||||||
|
return strings.Replace(strings.TrimSpace(str), "\n", "\\n", -1)
|
||||||
|
}
|
||||||
|
func Array(list []string, index int, arg ...interface{}) []string {
|
||||||
|
if len(arg) == 0 {
|
||||||
|
if -1 < index && index < len(list) {
|
||||||
|
return []string{list[index]}
|
||||||
|
}
|
||||||
|
return []string{""}
|
||||||
|
}
|
||||||
|
|
||||||
|
str := Trans(arg...)
|
||||||
|
|
||||||
|
index = (index+2)%(len(list)+2) - 2
|
||||||
|
if index == -1 {
|
||||||
|
list = append(str, list...)
|
||||||
|
} else if index == -2 {
|
||||||
|
list = append(list, str...)
|
||||||
|
} else {
|
||||||
|
if index < -2 {
|
||||||
|
index += len(list) + 2
|
||||||
|
}
|
||||||
|
if index < 0 {
|
||||||
|
index = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := len(list); i < index+len(str); i++ {
|
||||||
|
list = append(list, "")
|
||||||
|
}
|
||||||
|
for i := 0; i < len(str); i++ {
|
||||||
|
list[index+i] = str[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
func Elect(last interface{}, args ...interface{}) string {
|
||||||
|
if len(args) > 0 {
|
||||||
|
switch arg := args[0].(type) {
|
||||||
|
case []string:
|
||||||
|
index := 0
|
||||||
|
if len(args) > 1 {
|
||||||
|
switch a := args[1].(type) {
|
||||||
|
case string:
|
||||||
|
i, e := strconv.Atoi(a)
|
||||||
|
if e == nil {
|
||||||
|
index = i
|
||||||
|
}
|
||||||
|
case int:
|
||||||
|
index = a
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if 0 <= index && index < len(arg) && arg[index] != "" {
|
||||||
|
return arg[index]
|
||||||
|
}
|
||||||
|
case string:
|
||||||
|
if arg != "" {
|
||||||
|
return arg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch l := last.(type) {
|
||||||
|
case string:
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func Link(name string, url string) string {
|
||||||
|
return fmt.Sprintf("<a href=\"%s\" target=\"_blank\">%s</a>", url, name)
|
||||||
|
}
|
||||||
|
func FileName(name string, meta ...string) string {
|
||||||
|
result, app := strings.Split(name, "."), ""
|
||||||
|
if len(result) > 1 {
|
||||||
|
app, result = result[len(result)-1], result[:len(result)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range meta {
|
||||||
|
switch v {
|
||||||
|
case "year":
|
||||||
|
result = append(result, "_", time.Now().Format("2006"))
|
||||||
|
case "date":
|
||||||
|
result = append(result, "_", time.Now().Format("0102"))
|
||||||
|
case "time":
|
||||||
|
result = append(result, "_", time.Now().Format("2006_0102_1504"))
|
||||||
|
case "rand":
|
||||||
|
result = append(result, "_", Format(rand.Int()))
|
||||||
|
case "uniq":
|
||||||
|
result = append(result, "_", Format(Time()))
|
||||||
|
result = append(result, "_", Format(rand.Int()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if app != "" {
|
||||||
|
result = append(result, ".", app)
|
||||||
|
}
|
||||||
|
return strings.Join(result, "")
|
||||||
|
}
|
||||||
|
func FmtSize(size uint64) string {
|
||||||
|
if size > 1<<30 {
|
||||||
|
return fmt.Sprintf("%d.%dG", size>>30, (size>>20)%1024*100/1024)
|
||||||
|
}
|
||||||
|
|
||||||
|
if size > 1<<20 {
|
||||||
|
return fmt.Sprintf("%d.%dM", size>>20, (size>>10)%1024*100/1024)
|
||||||
|
}
|
||||||
|
|
||||||
|
if size > 1<<10 {
|
||||||
|
return fmt.Sprintf("%d.%dK", size>>10, size%1024*100/1024)
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("%dB", size)
|
||||||
|
}
|
||||||
|
func FmtNano(nano int64) string {
|
||||||
|
if nano > 1000000000 {
|
||||||
|
return fmt.Sprintf("%d.%ds", nano/1000000000, nano/100000000%100)
|
||||||
|
}
|
||||||
|
|
||||||
|
if nano > 1000000 {
|
||||||
|
return fmt.Sprintf("%d.%dms", nano/100000, nano/100000%100)
|
||||||
|
}
|
||||||
|
|
||||||
|
if nano > 1000 {
|
||||||
|
return fmt.Sprintf("%d.%dus", nano/1000, nano/100%100)
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("%dns", nano)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Block(root interface{}, args ...interface{}) interface{} {
|
||||||
|
|
||||||
|
return root
|
||||||
|
}
|
||||||
|
|
||||||
|
func Check(e error) bool {
|
||||||
|
if e != nil {
|
||||||
|
panic(e)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
func DirWalk(file string, hand func(file string)) {
|
||||||
|
s, e := os.Stat(file)
|
||||||
|
Check(e)
|
||||||
|
hand(file)
|
||||||
|
|
||||||
|
if s.IsDir() {
|
||||||
|
fs, e := ioutil.ReadDir(file)
|
||||||
|
Check(e)
|
||||||
|
|
||||||
|
for _, v := range fs {
|
||||||
|
DirWalk(path.Join(file, v.Name()), hand)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -123,6 +123,8 @@ var page = Page({
|
|||||||
page.onlayout()
|
page.onlayout()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
ctx.Search("layout") == "max" && (page.Conf("tree.display", "none"), page.Conf("menu.display", "none"))
|
||||||
|
|
||||||
ctx.Runs(page, form, function(msg) {
|
ctx.Runs(page, form, function(msg) {
|
||||||
ui.menu.innerHTML = "", ui.text.innerHTML = msg.result? msg.result.join(""): ""
|
ui.menu.innerHTML = "", ui.text.innerHTML = msg.result? msg.result.join(""): ""
|
||||||
kit.AppendChild(ui.menu, [{"tree": kit.OrderText(field, ui.text)}])
|
kit.AppendChild(ui.menu, [{"tree": kit.OrderText(field, ui.text)}])
|
||||||
@ -144,6 +146,10 @@ var page = Page({
|
|||||||
case "tree":
|
case "tree":
|
||||||
page.tree.Pane.Tree()
|
page.tree.Pane.Tree()
|
||||||
break
|
break
|
||||||
|
case "title":
|
||||||
|
ctx.Search("layout", ctx.Search("layout")? "": "max")
|
||||||
|
break
|
||||||
|
|
||||||
default:
|
default:
|
||||||
page.confirm("logout?") && page.login.Pane.Exit()
|
page.confirm("logout?") && page.login.Pane.Exit()
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,113 @@
|
|||||||
## golang
|
## golang
|
||||||
|
|
||||||
- 官网: <https://golang.org/>
|
- 官网: <https://golang.google.cn>
|
||||||
- 文档: <https://golang.org/doc/>
|
- 下载: <https://golang.google.cn/dl>
|
||||||
|
- 文档: <https://golang.google.cn/doc/>
|
||||||
- 源码: <https://dl.google.com/go/go1.11.1.src.tar.gz>
|
- 源码: <https://dl.google.com/go/go1.11.1.src.tar.gz>
|
||||||
- 开源: <https://github.com/golang>
|
- 开源: <https://github.com/golang/go>
|
||||||
|
|
||||||
## 基本命令
|
bash tmux golang git vim
|
||||||
|
|
||||||
|
## 命令
|
||||||
|
|
||||||
|
```
|
||||||
|
env help version
|
||||||
|
run test install
|
||||||
|
get list
|
||||||
|
```
|
||||||
|
|
||||||
|
## 文件
|
||||||
|
```
|
||||||
|
package
|
||||||
|
import
|
||||||
|
const
|
||||||
|
type
|
||||||
|
func
|
||||||
|
var
|
||||||
|
```
|
||||||
|
|
||||||
|
## 语句
|
||||||
|
```
|
||||||
|
if else for range break continue
|
||||||
|
switch case default fallthrough
|
||||||
|
defer recover panic
|
||||||
|
goto return
|
||||||
|
go select
|
||||||
|
```
|
||||||
|
|
||||||
|
## 表达式
|
||||||
|
```
|
||||||
|
//
|
||||||
|
```
|
||||||
|
```
|
||||||
|
0 iota true false nil "" '' ``
|
||||||
|
|
||||||
|
int float
|
||||||
|
bool error
|
||||||
|
rune string
|
||||||
|
byte uintptr
|
||||||
|
|
||||||
|
interface struct
|
||||||
|
map chan
|
||||||
|
|
||||||
|
make len cap
|
||||||
|
append copy delete close
|
||||||
|
new complex real imag
|
||||||
|
```
|
||||||
|
|
||||||
|
## 官方包
|
||||||
|
```
|
||||||
|
os flag path time
|
||||||
|
io bufio
|
||||||
|
fmt
|
||||||
|
sync
|
||||||
|
|
||||||
|
math
|
||||||
|
bytes
|
||||||
|
image
|
||||||
|
unicode
|
||||||
|
strings
|
||||||
|
strconv
|
||||||
|
|
||||||
|
net
|
||||||
|
log
|
||||||
|
```
|
||||||
|
|
||||||
|
io fmt log net bufio bytes database
|
||||||
|
os flag time path errors syscall plugin
|
||||||
|
runtime context sync expvar testing debug reflect unsafe
|
||||||
|
math hash crypto sort container index
|
||||||
|
unicode strings strconv regexp
|
||||||
|
encoding archive compress
|
||||||
|
mime text html image
|
||||||
|
|
||||||
|
go/ast
|
||||||
|
go/build
|
||||||
|
go/constant
|
||||||
|
go/doc
|
||||||
|
go/format
|
||||||
|
go/importer
|
||||||
|
go/internal/gccgoimporter
|
||||||
|
go/internal/gcimporter
|
||||||
|
go/internal/srcimporter
|
||||||
|
go/parser
|
||||||
|
go/printer
|
||||||
|
go/scanner
|
||||||
|
go/token
|
||||||
|
go/types
|
||||||
|
internal/bytealg
|
||||||
|
internal/cpu
|
||||||
|
internal/nettrace
|
||||||
|
internal/poll
|
||||||
|
internal/race
|
||||||
|
internal/singleflight
|
||||||
|
internal/syscall/unix
|
||||||
|
internal/syscall/windows
|
||||||
|
internal/syscall/windows/registry
|
||||||
|
internal/syscall/windows/sysdll
|
||||||
|
internal/testenv
|
||||||
|
internal/testlog
|
||||||
|
internal/trace
|
||||||
```
|
```
|
||||||
run clean build install
|
run clean build install
|
||||||
fmt fix vet bug
|
fmt fix vet bug
|
||||||
@ -13,6 +115,7 @@ mod get doc list
|
|||||||
env help version
|
env help version
|
||||||
test tool generate
|
test tool generate
|
||||||
```
|
```
|
||||||
|
|
||||||
## 编译过程
|
## 编译过程
|
||||||
```
|
```
|
||||||
main() // cmd/compile/main.go:40
|
main() // cmd/compile/main.go:40
|
||||||
|
Loading…
x
Reference in New Issue
Block a user