1
0
mirror of https://shylinux.com/x/icebergs synced 2025-04-26 17:44:05 +08:00

opt chat.go

This commit is contained in:
shaoying 2019-12-22 23:37:00 +08:00
parent bc53f6bb8d
commit e27c4c3502
17 changed files with 463 additions and 574 deletions

View File

@ -17,6 +17,7 @@ func (f *Frame) Spawn(m *Message, c *Context, arg ...string) Server {
return &Frame{} return &Frame{}
} }
func (f *Frame) Begin(m *Message, arg ...string) Server { func (f *Frame) Begin(m *Message, arg ...string) Server {
m.Log(LOG_BEGIN, "ice")
list := map[*Context]*Message{m.target: m} list := map[*Context]*Message{m.target: m}
m.Travel(func(p *Context, s *Context) { m.Travel(func(p *Context, s *Context) {
s.root = m.target s.root = m.target
@ -30,6 +31,7 @@ func (f *Frame) Begin(m *Message, arg ...string) Server {
return f return f
} }
func (f *Frame) Start(m *Message, arg ...string) bool { func (f *Frame) Start(m *Message, arg ...string) bool {
m.Log(LOG_START, "ice")
m.Cmd(ICE_INIT).Cmd("init", arg) m.Cmd(ICE_INIT).Cmd("init", arg)
return true return true
} }

View File

@ -8,86 +8,56 @@ import (
var Index = &ice.Context{Name: "aaa", Help: "认证模块", var Index = &ice.Context{Name: "aaa", Help: "认证模块",
Caches: map[string]*ice.Cache{}, Caches: map[string]*ice.Cache{},
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{
"role": {Name: "role", Help: "角色", Value: map[string]interface{}{ ice.AAA_ROLE: {Name: "role", Help: "角色", Value: kit.Data()},
ice.MDB_META: map[string]interface{}{}, ice.AAA_USER: {Name: "user", Help: "用户", Value: kit.Data("short", "username")},
ice.MDB_HASH: map[string]interface{}{ ice.AAA_SESS: {Name: "sess", Help: "会话", Value: kit.Data("short", "uniq", "expire", "720h")},
"root": map[string]interface{}{},
"tech": map[string]interface{}{},
"void": map[string]interface{}{},
},
ice.MDB_LIST: map[string]interface{}{},
}},
"user": {Name: "user", Help: "用户", Value: map[string]interface{}{
ice.MDB_META: map[string]interface{}{},
ice.MDB_HASH: map[string]interface{}{},
ice.MDB_LIST: map[string]interface{}{},
}},
"sess": {Name: "sess", Help: "会话", Value: map[string]interface{}{
ice.MDB_META: map[string]interface{}{"expire": "720h"},
ice.MDB_HASH: map[string]interface{}{},
ice.MDB_LIST: map[string]interface{}{},
}},
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
ice.AAA_ROLE: {Name: "role", Help: "角色", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
switch arg[0] {
case "check":
m.Echo(kit.Select("void", "root", arg[1] == m.Conf("cli.runtime", "boot.username")))
}
}}, }},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.AAA_USER: {Name: "user", Help: "用户", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
}},
"role": {Name: "role", Help: "角色", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
}},
"user": {Name: "user", Help: "用户", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
switch arg[0] { switch arg[0] {
case "login": case "login":
user := m.Confm("user", "hash."+arg[1]) // 用户认证
user := m.Richs(ice.AAA_USER, nil, arg[1], nil)
if user == nil { if user == nil {
m.Confv("user", "hash."+arg[1], map[string]interface{}{ m.Rich(ice.AAA_USER, nil, map[string]interface{}{
"create_time": m.Time(), "username": arg[1], "password": arg[2],
"password": arg[2], "usernode": m.Conf("cli.runtime", "boot.hostname"),
"userrole": kit.Select("void", "root", arg[1] == m.Conf("cli.runtime", "boot.username")),
}) })
m.Log("info", "create user %s %s", arg[1], m.Conf("user", "hash."+arg[1])) user = m.Richs(ice.AAA_USER, nil, arg[1], nil)
m.Info("create user: %s %s", arg[1], kit.Format(user))
} else if kit.Format(user["password"]) != arg[2] { } else if kit.Format(user["password"]) != arg[2] {
m.Log("warn", "login fail %s", arg[1]) m.Info("login fail user: %s", arg[1])
// 登录失败
break break
} }
// 用户授权
sessid := kit.Format(user[ice.WEB_SESS]) sessid := kit.Format(user[ice.WEB_SESS])
if sessid == "" { if sessid == "" {
sessid = m.Cmdx("aaa.sess", "login", arg[1]) role := m.Cmdx(ice.AAA_ROLE, "check", arg[1])
} sessid = m.Rich(ice.AAA_SESS, nil, map[string]interface{}{
"username": arg[1], "userrole": role,
m.Grow("user", nil, map[string]interface{}{
"create_time": m.Time(),
"remote_ip": m.Option("remote_ip"),
"username": arg[1],
ice.WEB_SESS: sessid,
}) })
// 登录成功 m.Info("user: %s role: %s sess: %s", arg[1], role, sessid)
}
m.Echo(sessid) m.Echo(sessid)
} }
}}, }},
"sess": {Name: "sess check|login", Help: "会话", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.AAA_SESS: {Name: "sess check|login", Help: "会话", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
switch arg[0] { switch arg[0] {
case "check": case "check":
user := m.Conf("sess", "hash."+arg[1]+".username") m.Richs(ice.AAA_SESS, nil, arg[1], func(value map[string]interface{}) {
if user != "" { m.Push(arg[1], value, []string{"username", "userrole"})
m.Confm("user", "hash."+user, func(value map[string]interface{}) { m.Echo("%s", value["username"])
m.Push("username", user)
m.Push("userrole", value["userrole"])
}) })
} }
m.Echo(user)
case "login":
sessid := kit.Hashs("uniq")
m.Conf("sess", "hash."+sessid, map[string]interface{}{
"create_time": m.Time(),
"username": arg[1],
})
m.Log("info", "create sess %s %s", arg[1], sessid)
m.Echo(sessid)
}
}}, }},
}, },
} }

View File

@ -53,9 +53,10 @@ var Index = &ice.Context{Name: "cli", Help: "命令模块",
"system": {Name: "system", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { "system": {Name: "system", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
cmd := exec.Command(arg[0], arg[1:]...) cmd := exec.Command(arg[0], arg[1:]...)
cmd.Dir = m.Option("cmd_dir") cmd.Dir = m.Option("cmd_dir")
m.Log("info", "dir: %s", cmd.Dir) m.Log("info", "dir: %s", cmd.Dir)
if m.Option("cmd_type") == "daemon" { if m.Option("cmd_type") == "daemon" {
// 守护进程
m.Gos(m, func(m *ice.Message) { m.Gos(m, func(m *ice.Message) {
if e := cmd.Start(); e != nil { if e := cmd.Start(); e != nil {
m.Log("warn", "%v start %s", arg, e) m.Log("warn", "%v start %s", arg, e)
@ -65,20 +66,19 @@ var Index = &ice.Context{Name: "cli", Help: "命令模块",
m.Log("info", "%v exit", arg) m.Log("info", "%v exit", arg)
} }
}) })
return } else {
} // 系统命令
out := bytes.NewBuffer(make([]byte, 0, 1024)) out := bytes.NewBuffer(make([]byte, 0, 1024))
err := bytes.NewBuffer(make([]byte, 0, 1024)) err := bytes.NewBuffer(make([]byte, 0, 1024))
cmd.Stdout = out cmd.Stdout = out
cmd.Stderr = err cmd.Stderr = err
if e := cmd.Run(); e != nil { if e := cmd.Run(); e != nil {
m.Echo("error: ").Echo(kit.Select(e.Error(), err.String())) m.Warn(e != nil, kit.Select(e.Error(), err.String()))
return } else {
}
m.Echo(out.String()) m.Echo(out.String())
}
m.Push("code", int(cmd.ProcessState.ExitCode()))
}
}}, }},
"timer": {Name: "timer", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { "timer": {Name: "timer", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
}}, }},

View File

@ -13,10 +13,10 @@ import (
var Index = &ice.Context{Name: "ctx", Help: "元始模块", var Index = &ice.Context{Name: "ctx", Help: "元始模块",
Caches: map[string]*ice.Cache{}, Caches: map[string]*ice.Cache{},
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{
ice.CTX_CONFIG: {Name: "config", Help: "配置", Value: ice.Data("path", "var/conf")}, ice.CTX_CONFIG: {Name: "config", Help: "配置", Value: kit.Data("path", "var/conf")},
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
"context": {Name: "context", Help: "模块", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.CTX_CONTEXT: {Name: "context", Help: "模块", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
ice.Pulse.Travel(func(p *ice.Context, s *ice.Context) { ice.Pulse.Travel(func(p *ice.Context, s *ice.Context) {
if p != nil { if p != nil {
m.Push("ups", p.Name) m.Push("ups", p.Name)
@ -29,7 +29,7 @@ var Index = &ice.Context{Name: "ctx", Help: "元始模块",
m.Push("help", s.Help) m.Push("help", s.Help)
}) })
}}, }},
"command": {Name: "command", Help: "命令", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.CTX_COMMAND: {Name: "command", Help: "命令", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 { if len(arg) == 0 {
ice.Pulse.Travel(func(p *ice.Context, s *ice.Context) { ice.Pulse.Travel(func(p *ice.Context, s *ice.Context) {
list := []string{} list := []string{}
@ -110,7 +110,7 @@ var Index = &ice.Context{Name: "ctx", Help: "元始模块",
} }
} }
default: default:
m.Echo(m.Conf(arg[0])) m.Echo(kit.Formats(m.Confv(arg[0])))
} }
}}, }},
}, },

View File

@ -29,12 +29,8 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool {
if !ok { if !ok {
return true return true
} }
m.Log(ice.LOG_INFO, "signal %v", s) m.Info("%s: %v", ice.GDB_SIGNAL, s)
m.Cmd(m.Confv(ice.GDB_SIGNAL, kit.Keys(ice.MDB_HASH, s))) m.Cmd(m.Confv(ice.GDB_SIGNAL, kit.Keys(kit.MDB_HASH, s)))
m.Grow(ice.GDB_SIGNAL, nil, map[string]interface{}{
"create_time": m.Time(), "signal": kit.Format(s),
"cmd": m.Confv(ice.GDB_SIGNAL, kit.Format(s)),
})
case t, ok := <-f.t: case t, ok := <-f.t:
if !ok { if !ok {
@ -42,7 +38,7 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool {
} }
break break
stamp := int(t.Unix()) stamp := int(t.Unix())
m.Confm(ice.GDB_TIMER, ice.MDB_HASH, func(key string, value map[string]interface{}) { m.Confm(ice.GDB_TIMER, kit.MDB_HASH, func(key string, value map[string]interface{}) {
if kit.Int(value["next"]) <= stamp { if kit.Int(value["next"]) <= stamp {
m.Log(ice.LOG_INFO, "timer %v %v", key, value["next"]) m.Log(ice.LOG_INFO, "timer %v %v", key, value["next"])
value["next"] = stamp + int(kit.Duration(value["interval"]))/int(time.Second) value["next"] = stamp + int(kit.Duration(value["interval"]))/int(time.Second)
@ -58,10 +54,9 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool {
if !ok { if !ok {
return true return true
} }
m.Log(ice.LOG_INFO, "event %v", d) m.Info("%s: %v", ice.GDB_EVENT, d)
m.Confm(ice.GDB_EVENT, kit.Keys(ice.MDB_HASH, d[0], d[1], ice.MDB_HASH), func(key string, value map[string]interface{}) { m.Grows(ice.GDB_EVENT, d[0], "", "", func(index int, value map[string]interface{}) {
m.Log(ice.LOG_INFO, "event %v %v", key, value) m.Cmd(value["cmd"], d[1:])
m.Cmd(value["cmd"], d[2:])
}) })
} }
} }
@ -75,10 +70,10 @@ var Index = &ice.Context{Name: "gdb", Help: "事件模块",
Caches: map[string]*ice.Cache{}, Caches: map[string]*ice.Cache{},
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{
ice.GDB_SIGNAL: {Name: "signal", Help: "信号器", Value: map[string]interface{}{ ice.GDB_SIGNAL: {Name: "signal", Help: "信号器", Value: map[string]interface{}{
ice.MDB_META: map[string]interface{}{ kit.MDB_META: map[string]interface{}{
"pid": "var/run/shy.pid", "pid": "var/run/shy.pid",
}, },
ice.MDB_HASH: map[string]interface{}{ kit.MDB_HASH: map[string]interface{}{
"2": []interface{}{"exit"}, "2": []interface{}{"exit"},
"3": []interface{}{"exit", "1"}, "3": []interface{}{"exit", "1"},
"15": []interface{}{"exit", "1"}, "15": []interface{}{"exit", "1"},
@ -86,24 +81,14 @@ var Index = &ice.Context{Name: "gdb", Help: "事件模块",
"31": []interface{}{"exit", "1"}, "31": []interface{}{"exit", "1"},
"28": "WINCH", "28": "WINCH",
}, },
ice.MDB_LIST: map[string]interface{}{}, kit.MDB_LIST: map[string]interface{}{},
}},
ice.GDB_TIMER: {Name: "timer", Help: "定时器", Value: map[string]interface{}{
ice.MDB_META: map[string]interface{}{
"tick": "100ms",
},
ice.MDB_HASH: map[string]interface{}{},
ice.MDB_LIST: map[string]interface{}{},
}},
ice.GDB_EVENT: {Name: "event", Help: "触发器", Value: map[string]interface{}{
ice.MDB_META: map[string]interface{}{},
ice.MDB_HASH: map[string]interface{}{},
ice.MDB_LIST: map[string]interface{}{},
}}, }},
ice.GDB_TIMER: {Name: "timer", Help: "定时器", Value: kit.Data("tick", "100ms")},
ice.GDB_EVENT: {Name: "event", Help: "触发器", Value: kit.Data()},
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if f, p, e := kit.Create(m.Conf(ice.GDB_SIGNAL, kit.Keys(ice.MDB_META, "pid"))); m.Assert(e) { if f, p, e := kit.Create(m.Conf(ice.GDB_SIGNAL, kit.Keys(kit.MDB_META, "pid"))); m.Assert(e) {
defer f.Close() defer f.Close()
f.WriteString(kit.Format(os.Getpid())) f.WriteString(kit.Format(os.Getpid()))
m.Log("info", "pid %d: %s", os.Getpid(), p) m.Log("info", "pid %d: %s", os.Getpid(), p)
@ -111,12 +96,12 @@ var Index = &ice.Context{Name: "gdb", Help: "事件模块",
if f, ok := m.Target().Server().(*Frame); ok { if f, ok := m.Target().Server().(*Frame); ok {
f.s = make(chan os.Signal, ice.ICE_CHAN) f.s = make(chan os.Signal, ice.ICE_CHAN)
m.Confm(ice.GDB_SIGNAL, ice.MDB_HASH, func(sig string, action string) { m.Confm(ice.GDB_SIGNAL, kit.MDB_HASH, func(sig string, action string) {
m.Log(ice.GDB_SIGNAL, "add %s: %s", sig, action) m.Log(ice.GDB_SIGNAL, "add %s: %s", sig, action)
signal.Notify(f.s, syscall.Signal(kit.Int(sig))) signal.Notify(f.s, syscall.Signal(kit.Int(sig)))
}) })
f.t = time.Tick(kit.Duration(m.Cap(ice.CTX_STREAM, m.Conf(ice.GDB_TIMER, kit.Keys(ice.MDB_META, "tick"))))) f.t = time.Tick(kit.Duration(m.Cap(ice.CTX_STREAM, m.Conf(ice.GDB_TIMER, kit.Keys(kit.MDB_META, "tick")))))
f.d = make(chan []string, ice.ICE_CHAN) f.d = make(chan []string, ice.ICE_CHAN)
} }
}}, }},
@ -127,7 +112,7 @@ var Index = &ice.Context{Name: "gdb", Help: "事件模块",
} }
}}, }},
ice.GDB_SIGNAL: {Name: "signal", Help: "信号器", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.GDB_SIGNAL: {Name: "signal", Help: "信号器", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Conf(ice.GDB_SIGNAL, kit.Keys(ice.MDB_META, arg[0]), arg[1:]) m.Conf(ice.GDB_SIGNAL, kit.Keys(kit.MDB_META, arg[0]), arg[1:])
}}, }},
ice.GDB_TIMER: {Name: "timer", Help: "定时器", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.GDB_TIMER: {Name: "timer", Help: "定时器", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
switch arg[0] { switch arg[0] {
@ -141,9 +126,8 @@ var Index = &ice.Context{Name: "gdb", Help: "事件模块",
ice.GDB_EVENT: {Name: "event", Help: "触发器", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.GDB_EVENT: {Name: "event", Help: "触发器", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
switch arg[0] { switch arg[0] {
case "listen": case "listen":
m.Rich(ice.GDB_EVENT, kit.Keys(ice.MDB_HASH, arg[1], arg[2]), map[string]interface{}{ m.Grow(ice.GDB_EVENT, arg[1], map[string]interface{}{"cmd": arg[2:]})
"create_time": m.Time(), "cmd": arg[3:],
})
case "action": case "action":
if f, ok := m.Target().Server().(*Frame); ok { if f, ok := m.Target().Server().(*Frame); ok {
f.d <- arg[1:] f.d <- arg[1:]

View File

@ -31,10 +31,8 @@ var Index = &ice.Context{Name: "mdb", Help: "数据模块",
} else { } else {
m.Option("cache.offend", kit.Select("0", arg, 3)) m.Option("cache.offend", kit.Select("0", arg, 3))
m.Option("cache.limit", kit.Select("10", arg, 4)) m.Option("cache.limit", kit.Select("10", arg, 4))
m.Option("cache.match", kit.Select("", arg, 5))
m.Option("cache.value", kit.Select("", arg, 6))
fields := strings.Split(arg[7], " ") fields := strings.Split(arg[7], " ")
m.Grows(arg[0], arg[1], func(index int, value map[string]interface{}) { m.Grows(arg[0], arg[1], kit.Select("", arg, 5), kit.Select("", arg, 6), func(index int, value map[string]interface{}) {
m.Push("id", value, fields) m.Push("id", value, fields)
}) })
} }

View File

@ -47,9 +47,9 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool {
res = msg.Result() res = msg.Result()
} }
fmt.Fprintf(f.out, res) fmt.Fprint(f.out, res)
if !strings.HasSuffix(res, "\n") { if !strings.HasSuffix(res, "\n") {
fmt.Fprintf(f.out, "\n") fmt.Fprint(f.out, "\n")
} }
fmt.Fprintf(f.out, m.Time(prompt, count, target.Name)) fmt.Fprintf(f.out, m.Time(prompt, count, target.Name))
count++ count++

View File

@ -32,16 +32,16 @@ type Frame struct {
func Cookie(msg *ice.Message, sessid string) string { func Cookie(msg *ice.Message, sessid string) string {
w := msg.Optionv("response").(http.ResponseWriter) w := msg.Optionv("response").(http.ResponseWriter)
expire := time.Now().Add(kit.Duration(msg.Conf("aaa.sess", "meta.expire"))) expire := time.Now().Add(kit.Duration(msg.Conf(ice.AAA_SESS, ice.Meta("expire"))))
msg.Log("cookie", "expire %v sessid %s", kit.Format(expire), sessid) msg.Log("cookie", "expire:%v sessid:%s", kit.Format(expire), sessid)
http.SetCookie(w, &http.Cookie{Name: ice.WEB_SESS, Value: sessid, Path: "/", Expires: expire}) http.SetCookie(w, &http.Cookie{Name: ice.WEB_SESS, Value: sessid, Path: "/", Expires: expire})
return sessid return sessid
} }
func (web *Frame) Login(msg *ice.Message, w http.ResponseWriter, r *http.Request) bool { func (web *Frame) Login(msg *ice.Message, w http.ResponseWriter, r *http.Request) bool {
if msg.Options(ice.WEB_SESS) { if msg.Options(ice.WEB_SESS) {
sub := msg.Cmd("aaa.sess", "check", msg.Option(ice.WEB_SESS)) sub := msg.Cmd("aaa.sess", "check", msg.Option(ice.WEB_SESS))
msg.Log("info", "role: %s user: %s", msg.Option("userrole", sub.Append("userrole")), msg.Log("info", "role: %s user: %s", msg.Option(ice.MSG_USERROLE, sub.Append("userrole")),
msg.Option("username", sub.Append("username"))) msg.Option(ice.MSG_USERNAME, sub.Append("username")))
} }
msg.Target().Runs(msg, msg.Option("url"), ice.WEB_LOGIN, kit.Simple(msg.Optionv("cmds"))...) msg.Target().Runs(msg, msg.Option("url"), ice.WEB_LOGIN, kit.Simple(msg.Optionv("cmds"))...)
@ -157,8 +157,8 @@ func (web *Frame) HandleCmd(m *ice.Message, key string, cmd *ice.Command) {
msg.Optionv("request", r) msg.Optionv("request", r)
msg.Optionv("response", w) msg.Optionv("response", w)
msg.Option("remote_ip", r.Header.Get("remote_ip")) msg.Option("user.agent", r.Header.Get("User-Agent"))
msg.Option("agent", r.Header.Get("User-Agent")) msg.Option("user.ip", r.Header.Get("user.ip"))
msg.Option("referer", r.Header.Get("Referer")) msg.Option("referer", r.Header.Get("Referer"))
msg.Option("accept", r.Header.Get("Accept")) msg.Option("accept", r.Header.Get("Accept"))
msg.Option("method", r.Method) msg.Option("method", r.Method)
@ -206,15 +206,13 @@ func (web *Frame) HandleCmd(m *ice.Message, key string, cmd *ice.Command) {
} }
} }
if web.Login(msg, w, r) { if web.Login(msg, w, r) && msg.Target().Run(msg, cmd, msg.Option("url"), kit.Simple(msg.Optionv("cmds"))...) != nil {
msg.Log("cmd", "%s %s", msg.Target().Name, key)
cmd.Hand(msg, msg.Target(), msg.Option("url"), kit.Simple(msg.Optionv("cmds"))...)
switch msg.Append("content-type") { switch msg.Append("content-type") {
case "text/html": case "text/html":
w.Header().Set("Content-Type", "text/html") w.Header().Set("Content-Type", "text/html")
fmt.Fprintf(w, msg.Result()) fmt.Fprint(w, msg.Result())
default: default:
fmt.Fprintf(w, msg.Formats("meta")) fmt.Fprint(w, msg.Formats("meta"))
} }
} }
}) })
@ -226,15 +224,15 @@ func (web *Frame) ServeHTTP(w http.ResponseWriter, r *http.Request) {
index := r.Header.Get("index.module") == "" index := r.Header.Get("index.module") == ""
if index { if index {
if ip := r.Header.Get("X-Forwarded-For"); ip != "" { if ip := r.Header.Get("X-Forwarded-For"); ip != "" {
r.Header.Set("remote_ip", ip) r.Header.Set("user.ip", ip)
} else if ip := r.Header.Get("X-Real-Ip"); ip != "" { } else if ip := r.Header.Get("X-Real-Ip"); ip != "" {
r.Header.Set("remote_ip", ip) r.Header.Set("user.ip", ip)
} else if strings.HasPrefix(r.RemoteAddr, "[") { } else if strings.HasPrefix(r.RemoteAddr, "[") {
r.Header.Set("remote_ip", strings.Split(r.RemoteAddr, "]")[0][1:]) r.Header.Set("user.ip", strings.Split(r.RemoteAddr, "]")[0][1:])
} else { } else {
r.Header.Set("remote_ip", strings.Split(r.RemoteAddr, ":")[0]) r.Header.Set("user.ip", strings.Split(r.RemoteAddr, ":")[0])
} }
m.Log("info", "").Log("info", "%v %s %s", r.Header.Get("remote_ip"), r.Method, r.URL) m.Log("info", "").Log("info", "%v %s %s", r.Header.Get("user.ip"), r.Method, r.URL)
r.Header.Set("index.module", "some") r.Header.Set("index.module", "some")
r.Header.Set("index.url", r.URL.String()) r.Header.Set("index.url", r.URL.String())
r.Header.Set("index.path", r.URL.Path) r.Header.Set("index.path", r.URL.Path)
@ -258,6 +256,11 @@ func (web *Frame) Start(m *ice.Message, arg ...string) bool {
} }
w.ServeMux = http.NewServeMux() w.ServeMux = http.NewServeMux()
msg := m.Spawns(s) msg := m.Spawns(s)
// 静态路由
m.Confm(ice.WEB_SERVE, ice.Meta("static"), func(key string, value string) {
m.Log("route", "%s <- %s <- %s", s.Name, key, value)
w.Handle(key, http.StripPrefix(key, http.FileServer(http.Dir(value))))
})
// 级联路由 // 级联路由
route := "/" + s.Name + "/" route := "/" + s.Name + "/"
@ -266,12 +269,6 @@ func (web *Frame) Start(m *ice.Message, arg ...string) bool {
n.Handle(route, http.StripPrefix(path.Dir(route), w)) n.Handle(route, http.StripPrefix(path.Dir(route), w))
} }
// 静态路由
m.Confm(ice.WEB_SERVE, ice.Meta("static"), func(key string, value string) {
msg.Log("route", "%s <- %s <- %s", s.Name, key, value)
w.Handle(key, http.StripPrefix(key, http.FileServer(http.Dir(value))))
})
// 命令路由 // 命令路由
m.Travel(func(p *ice.Context, sub *ice.Context, k string, x *ice.Command) { m.Travel(func(p *ice.Context, sub *ice.Context, k string, x *ice.Command) {
if s == sub && k[0] == '/' { if s == sub && k[0] == '/' {
@ -295,8 +292,8 @@ func (web *Frame) Close(m *ice.Message, arg ...string) bool {
var Index = &ice.Context{Name: "web", Help: "网页模块", var Index = &ice.Context{Name: "web", Help: "网页模块",
Caches: map[string]*ice.Cache{}, Caches: map[string]*ice.Cache{},
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{
ice.WEB_SPIDE: {Name: "spide", Help: "客户端", Value: ice.Data("self.port", ice.WEB_PORT)}, ice.WEB_SPIDE: {Name: "spide", Help: "客户端", Value: kit.Data("self.port", ice.WEB_PORT)},
ice.WEB_SERVE: {Name: "serve", Help: "服务器", Value: ice.Data( ice.WEB_SERVE: {Name: "serve", Help: "服务器", Value: kit.Data(
"static", map[string]interface{}{"/": "usr/volcanos/", "static", map[string]interface{}{"/": "usr/volcanos/",
"/static/volcanos/": "usr/volcanos/", "/static/volcanos/": "usr/volcanos/",
}, },
@ -304,15 +301,16 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
`{{define "raw"}}{{.Result}}{{end}}`, `{{define "raw"}}{{.Result}}{{end}}`,
}}, }},
)}, )},
ice.WEB_SPACE: {Name: "space", Help: "空间站", Value: ice.Data("buffer", 4096, "redial", 3000)}, ice.WEB_SPACE: {Name: "space", Help: "空间站", Value: kit.Data("buffer", 4096, "redial", 3000)},
ice.WEB_STORY: {Name: "story", Help: "故事会", Value: ice.Data("short", "data")}, ice.WEB_STORY: {Name: "story", Help: "故事会", Value: kit.Data("short", "data")},
ice.WEB_CACHE: {Name: "cache", Help: "缓存", Value: ice.Data( ice.WEB_CACHE: {Name: "cache", Help: "缓存", Value: kit.Data(
"short", "text", "path", "var/file", "short", "text", "path", "var/file",
"store", "var/data", "limit", "30", "least", "10", "store", "var/data", "limit", "30", "least", "10",
)}, )},
ice.WEB_ROUTE: {Name: "route", Help: "路由", Value: ice.Data()}, ice.WEB_ROUTE: {Name: "route", Help: "路由", Value: kit.Data()},
ice.WEB_PROXY: {Name: "proxy", Help: "代理", Value: ice.Data()}, ice.WEB_PROXY: {Name: "proxy", Help: "代理", Value: kit.Data()},
ice.WEB_SHARE: {Name: "share", Help: "共享", Value: ice.Data()}, ice.WEB_FAVOR: {Name: "favor", Help: "收藏", Value: kit.Data()},
ice.WEB_SHARE: {Name: "share", Help: "共享", Value: kit.Data()},
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}}, ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
@ -322,11 +320,17 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
ice.WEB_SERVE: {Name: "serve", Help: "服务器", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.WEB_SERVE: {Name: "serve", Help: "服务器", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Conf("cli.runtime", "node.name", m.Conf("cli.runtime", "boot.hostname")) m.Conf("cli.runtime", "node.name", m.Conf("cli.runtime", "boot.hostname"))
m.Conf("cli.runtime", "node.type", "server") m.Conf("cli.runtime", "node.type", "server")
m.Rich(ice.WEB_SPACE, nil, map[string]interface{}{
"type": "myself",
"node": m.Conf("cli.runtime", "boot.hostname"),
"user": m.Conf("cli.runtime", "boot.username"),
})
m.Target().Start(m, arg...) m.Target().Start(m, arg...)
}}, }},
ice.WEB_SPACE: {Name: "space", Help: "空间站", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.WEB_SPACE: {Name: "space", Help: "空间站", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 { if len(arg) == 0 {
m.Conf(ice.WEB_SPACE, ice.MDB_HASH, func(key string, value map[string]interface{}) { m.Conf(ice.WEB_SPACE, kit.MDB_HASH, func(key string, value map[string]interface{}) {
m.Push(key, value) m.Push(key, value)
}) })
return return
@ -366,7 +370,8 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
}) })
} }
default: default:
if arg[0] == "" { // 本地命令
if arg[0] == "" || arg[0] == m.Conf("cli.runtime", "node.name") {
m.Cmdy(arg[1:]) m.Cmdy(arg[1:])
break break
} }
@ -518,7 +523,16 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
}}, }},
ice.WEB_PROXY: {Name: "proxy", Help: "代理", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.WEB_PROXY: {Name: "proxy", Help: "代理", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
}}, }},
ice.WEB_SHARE: {Name: "share type name value", Help: "共享", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.WEB_FAVOR: {Name: "favor", Help: "收藏", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 {
m.Confm(ice.WEB_SHARE, "hash", func(key string, value map[string]interface{}) {
m.Push(key, value)
})
return
}
}},
ice.WEB_SHARE: {Name: "share", Help: "共享", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 { if len(arg) == 0 {
m.Confm(ice.WEB_SHARE, "hash", func(key string, value map[string]interface{}) { m.Confm(ice.WEB_SHARE, "hash", func(key string, value map[string]interface{}) {
m.Push(key, value) m.Push(key, value)
@ -563,14 +577,14 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
"type": m.Option("node"), "type": m.Option("node"),
"name": m.Option("name"), "name": m.Option("name"),
} }
m.Confv(ice.WEB_SPACE, []string{ice.MDB_HASH, h}, meta) m.Confv(ice.WEB_SPACE, []string{kit.MDB_HASH, h}, meta)
m.Log("space", "conn %v %v", h, kit.Formats(m.Confv(ice.WEB_SPACE))) m.Log("space", "conn %v %v", h, kit.Formats(m.Confv(ice.WEB_SPACE)))
web := m.Target().Server().(*Frame) web := m.Target().Server().(*Frame)
m.Gos(m, func(m *ice.Message) { m.Gos(m, func(m *ice.Message) {
web.HandleWSS(m, false, s) web.HandleWSS(m, false, s)
m.Log("space", "close %v %v", h, kit.Formats(m.Confv(ice.WEB_SPACE))) m.Log("space", "close %v %v", h, kit.Formats(m.Confv(ice.WEB_SPACE)))
m.Confv(ice.WEB_SPACE, []string{ice.MDB_HASH, h}, "") m.Confv(ice.WEB_SPACE, []string{kit.MDB_HASH, h}, "")
}) })
} }
}}, }},

47
conf.go
View File

@ -11,19 +11,26 @@ const (
CTX_STATUS = "status" CTX_STATUS = "status"
CTX_STREAM = "stream" CTX_STREAM = "stream"
CTX_CONFIG = "config" CTX_CONFIG = "config"
CTX_COMMAND = "command"
CTX_CONTEXT = "context"
) )
const ( const (
MSG_DETAIL = "detail" MSG_DETAIL = "detail"
MSG_OPTION = "option" MSG_OPTION = "option"
MSG_APPEND = "append" MSG_APPEND = "append"
MSG_RESULT = "result" MSG_RESULT = "result"
MSG_SESSID = "sessid"
MSG_USERNAME = "user.name"
MSG_USERROLE = "user.role"
MSG_RIVER = "sess.river"
MSG_STORM = "sess.storm"
) )
const ( const (
MDB_META = "meta" AAA_ROLE = "role"
MDB_LIST = "list" AAA_USER = "user"
MDB_HASH = "hash" AAA_SESS = "sess"
MDB_TYPE = "_type"
) )
const ( const (
WEB_PORT = ":9020" WEB_PORT = ":9020"
@ -38,13 +45,9 @@ const (
WEB_CACHE = "cache" WEB_CACHE = "cache"
WEB_ROUTE = "route" WEB_ROUTE = "route"
WEB_PROXY = "proxy" WEB_PROXY = "proxy"
WEB_FAVOR = "favor"
WEB_SHARE = "share" WEB_SHARE = "share"
) )
const (
GDB_SIGNAL = "signal"
GDB_TIMER = "timer"
GDB_EVENT = "event"
)
const ( const (
LOG_CMD = "cmd" LOG_CMD = "cmd"
LOG_INFO = "info" LOG_INFO = "info"
@ -57,13 +60,24 @@ const (
LOG_BENCH = "bench" LOG_BENCH = "bench"
LOG_CLOSE = "close" LOG_CLOSE = "close"
) )
const (
GDB_SIGNAL = "signal"
GDB_TIMER = "timer"
GDB_EVENT = "event"
)
const (
CHAT_GROUP = "group"
)
var Alias = map[string]string{ var Alias = map[string]string{
CTX_CONFIG: "ctx.config", CTX_CONFIG: "ctx.config",
CTX_COMMAND: "ctx.command",
CTX_CONTEXT: "ctx.context",
GDB_SIGNAL: "gdb.signal", AAA_ROLE: "aaa.role",
GDB_TIMER: "gdb.timer", AAA_USER: "aaa.user",
GDB_EVENT: "gdb.event", AAA_SESS: "aaa.sess",
WEB_SPIDE: "web.spide", WEB_SPIDE: "web.spide",
WEB_SERVE: "web.serve", WEB_SERVE: "web.serve",
@ -72,7 +86,14 @@ var Alias = map[string]string{
WEB_CACHE: "web.cache", WEB_CACHE: "web.cache",
WEB_ROUTE: "web.route", WEB_ROUTE: "web.route",
WEB_PROXY: "web.proxy", WEB_PROXY: "web.proxy",
WEB_FAVOR: "web.favor",
WEB_SHARE: "web.share", WEB_SHARE: "web.share",
GDB_SIGNAL: "gdb.signal",
GDB_TIMER: "gdb.timer",
GDB_EVENT: "gdb.event",
CHAT_GROUP: "web.chat.group",
"note": "web.wiki.note", "note": "web.wiki.note",
} }

View File

@ -10,7 +10,7 @@ import (
var Index = &ice.Context{Name: "chat", Help: "聊天模块", var Index = &ice.Context{Name: "chat", Help: "聊天模块",
Caches: map[string]*ice.Cache{}, Caches: map[string]*ice.Cache{},
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{
"group": {Name: "group", Help: "群组", Value: ice.Data()}, ice.CHAT_GROUP: {Name: "group", Help: "群组", Value: kit.Data()},
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
@ -19,173 +19,181 @@ var Index = &ice.Context{Name: "chat", Help: "聊天模块",
m.Cmd(ice.CTX_CONFIG, "load", "chat.json") m.Cmd(ice.CTX_CONFIG, "load", "chat.json")
}}, }},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmd(ice.CTX_CONFIG, "save", "chat.json", "web.chat.group") m.Cmd(ice.CTX_CONFIG, "save", "chat.json", ice.CHAT_GROUP)
m.Cmd(ice.CTX_CONFIG, "save", "web.json", "web.story", "web.cache", "web.share") m.Cmd(ice.CTX_CONFIG, "save", "web.json", ice.WEB_STORY, ice.WEB_CACHE, ice.WEB_SHARE)
m.Cmd(ice.CTX_CONFIG, "save", "aaa.json", "aaa.role", "aaa.user", "aaa.sess") m.Cmd(ice.CTX_CONFIG, "save", "aaa.json", ice.AAA_ROLE, ice.AAA_USER, ice.AAA_SESS)
}}, }},
ice.WEB_LOGIN: {Name: "login", Help: "登录", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.WEB_LOGIN: {Name: "login", Help: "登录", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if cmd != "/login" { if len(arg) > 0 {
if m.Warn(!m.Options(ice.WEB_SESS) || !m.Options("username"), "not login") { switch arg[0] {
// 检查失败 case "login":
m.Option("path", "") // 用户登录
m.Option(ice.MSG_SESSID, (web.Cookie(m, m.Cmdx(ice.AAA_USER, "login", m.Option(ice.MSG_USERNAME, arg[1]), arg[2]))))
default:
// 用户群组
m.Richs(ice.CHAT_GROUP, nil, arg[0], func(value map[string]interface{}) {
m.Option(ice.MSG_RIVER, arg[0])
if len(arg) > 1 {
m.Richs(ice.CHAT_GROUP, kit.Keys(kit.MDB_HASH, arg[0], "tool"), arg[1], func(value map[string]interface{}) {
m.Option(ice.MSG_STORM, arg[1])
})
}
m.Info("river: %s storm: %s", m.Option(ice.MSG_RIVER), m.Option(ice.MSG_STORM))
})
}
}
if cmd == "/login" {
return return
} }
}
// 查询群组 // 登录检查
if len(arg) > 0 && m.Confs("group", kit.Keys("hash", arg[0])) { if m.Warn(!m.Options(ice.MSG_SESSID) || !m.Options(ice.MSG_USERNAME), "not login") {
m.Option("sess.river", arg[0]) m.Option("path", "")
if len(arg) > 1 && m.Confs("group", kit.Keys("hash", arg[0], "tool", "hash", arg[1])) {
m.Option("sess.storm", arg[1])
} }
}
m.Log("info", "river: %s storm: %s", m.Option("sess.river"), m.Option("sess.storm"))
}}, }},
"/toast": {Name: "/toast", Help: "提示", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
"/tutor": {Name: "/tutor", Help: "向导", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
"/debug": {Name: "/debug", Help: "调试", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
"/carte": {Name: "/carte", Help: "菜单", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
"/favor": {Name: "/favor", Help: "收藏", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
"/login": {Name: "/login", Help: "登录", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { "/login": {Name: "/login", Help: "登录", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
switch arg[0] { switch arg[0] {
case "check": case "check":
m.Push("username", m.Option("username")) m.Echo(m.Option(ice.MSG_USERNAME))
m.Push("userrole", m.Option("userrole"))
m.Echo(m.Option("username"))
case "login": case "login":
m.Echo(web.Cookie(m, m.Cmdx("aaa.user", "login", arg[1], arg[2]))) m.Echo(m.Option(ice.MSG_SESSID))
} }
}}, }},
"/favor": {Name: "/favor", Help: "登录", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmdy("cli.system", arg)
}},
"/ocean": {Name: "/ocean", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { "/ocean": {Name: "/ocean", Help: "大海洋", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 { if len(arg) == 0 {
m.Confm("aaa.user", ice.MDB_HASH, func(key string, value map[string]interface{}) { // 用户列表
m.Push("key", key) m.Richs(ice.AAA_USER, nil, "", func(key string, value map[string]interface{}) {
m.Push("user.route", m.Conf("cli.runtime", "node.name")) m.Push(key, value, []string{"username", "usernode"})
}) })
return return
} }
switch arg[0] { switch arg[0] {
case "spawn": case "spawn":
if arg[1] == "" { // 创建群组
arg[1] = kit.ShortKey(m.Confm("group", ice.MDB_HASH), 6) river := m.Rich(ice.CHAT_GROUP, nil, kit.Data(kit.MDB_NAME, arg[1]))
} m.Info("create river: %v name: %v", river, arg[1])
user := map[string]interface{}{ m.Cmd("/river", river, "add", arg[2:])
ice.MDB_META: map[string]interface{}{},
ice.MDB_HASH: map[string]interface{}{},
ice.MDB_LIST: []interface{}{},
}
tool := map[string]interface{}{
ice.MDB_META: map[string]interface{}{},
ice.MDB_HASH: map[string]interface{}{},
ice.MDB_LIST: []interface{}{},
}
for _, v := range arg[3:] {
kit.Value(user, "hash."+v, map[string]interface{}{
"create_time": m.Time(),
})
kit.Value(user, "list."+v+".-2", map[string]interface{}{
"create_time": m.Time(),
"operation": "add",
"username": v,
})
}
m.Conf("group", "hash."+arg[1], map[string]interface{}{
ice.MDB_META: map[string]interface{}{
"create_time": m.Time(),
"name": arg[2],
},
"user": user,
"tool": tool,
})
m.Log("info", "river create %v %v", arg[1], kit.Formats(m.Confv("group", "hash."+arg[1])))
m.Echo(arg[1])
} }
}}, }},
"/river": {Name: "/river", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { "/river": {Name: "/river", Help: "小河流", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 { switch len(arg) {
m.Confm("group", ice.MDB_HASH, func(key string, value map[string]interface{}) { case 0:
m.Push("key", key) // 群组列表
m.Push("name", kit.Value(value[ice.MDB_META], "name")) m.Richs(ice.CHAT_GROUP, nil, "", func(key string, value map[string]interface{}) {
m.Push(key, value["meta"], []string{kit.MDB_KEY, kit.MDB_NAME})
})
case 1:
// 群组详情
m.Richs(ice.CHAT_GROUP, nil, arg[0], func(key string, value map[string]interface{}) {
m.Push(key, value["meta"], []string{kit.MDB_KEY, kit.MDB_NAME})
})
default:
switch arg[1] {
case "add":
// 添加用户
for _, v := range arg[2:] {
user := m.Rich(ice.CHAT_GROUP, kit.Keys(kit.MDB_HASH, arg[0], "user"), kit.Data("username", v))
m.Info("add river: %s user: %s name: %s", arg[0], user, v)
}
}
}
}},
"/storm": {Name: "/storm", Help: "暴风雨", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
prefix := kit.Keys(kit.MDB_HASH, arg[0], "tool")
if len(arg) < 2 {
// 应用列表
m.Richs(ice.CHAT_GROUP, prefix, "", func(key string, value map[string]interface{}) {
m.Push(key, value["meta"], []string{kit.MDB_KEY, kit.MDB_NAME})
}) })
return return
} }
switch arg[2] {
case "add":
// 添加命令
for i := 3; i < len(arg)-3; i += 4 {
id := m.Grow(ice.CHAT_GROUP, kit.Keys(prefix, kit.MDB_HASH, arg[1]), kit.Data(
"pod", arg[i], "ctx", arg[i+1], "cmd", arg[i+2], "key", arg[i+3],
))
m.Info("create tool %d %v", id, arg[i:i+4])
}
case "rename":
// 重命名应用
old := m.Conf(ice.CHAT_GROUP, kit.Keys(prefix, kit.MDB_HASH, arg[1], kit.MDB_META, kit.MDB_NAME))
m.Info("rename storm: %s %s->%s", arg[1], old, arg[3])
m.Conf(ice.CHAT_GROUP, kit.Keys(prefix, kit.MDB_HASH, arg[1], kit.MDB_META, kit.MDB_NAME), arg[3])
case "remove":
// 删除应用
m.Richs(ice.CHAT_GROUP, kit.Keys(prefix), arg[1], func(value map[string]interface{}) {
m.Info("remove storm: %s %s", arg[1], kit.Format(value))
})
m.Conf(ice.CHAT_GROUP, kit.Keys(prefix, kit.MDB_HASH, arg[1]), "")
}
}}, }},
"/action": {Name: "/action", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { "/steam": {Name: "/steam", Help: "大气层", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) < 2 {
// 设备列表
m.Richs(ice.WEB_SPACE, nil, "", func(key string, value map[string]interface{}) {
m.Push(key, value, []string{"user", "node"})
})
return
}
switch arg[1] {
case "spawn":
// 创建应用
storm := m.Rich(ice.CHAT_GROUP, kit.Keys(kit.MDB_HASH, arg[0], "tool"), kit.Data(kit.MDB_NAME, arg[2]))
m.Info("create river: %s storm: %s name: %v", arg[0], storm, arg[2])
m.Cmd("/storm", arg[0], storm, "add", arg[3:])
default:
// 命令列表
m.Cmdy(ice.WEB_SPACE, arg[2], ice.CTX_COMMAND)
}
}},
"/action": {Name: "/action", Help: "小工具", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
prefix := kit.Keys(kit.MDB_HASH, arg[0], "tool", kit.MDB_HASH, arg[1])
if len(arg) == 2 { if len(arg) == 2 {
// 命令列表
m.Set(ice.MSG_OPTION) m.Set(ice.MSG_OPTION)
m.Confm("group", "hash."+arg[0]+".tool.hash."+arg[1]+".list", func(index int, value map[string]interface{}) { m.Grows(ice.CHAT_GROUP, prefix, "", "", func(index int, value map[string]interface{}) {
if meta, ok := kit.Value(value, "meta").(map[string]interface{}); ok {
m.Push("river", arg[0]) m.Push("river", arg[0])
m.Push("storm", arg[1]) m.Push("storm", arg[1])
m.Push("action", index) m.Push("action", index)
m.Push("node", value["pod"]) m.Push("node", meta["pod"])
m.Push("group", value["ctx"]) m.Push("group", meta["ctx"])
m.Push("index", value["cmd"]) m.Push("index", meta["cmd"])
msg := m.Cmd("web.space", value["pod"], "ctx.command", value["ctx"], value["cmd"]) msg := m.Cmd(ice.WEB_SPACE, meta["pod"], ice.CTX_COMMAND, meta["ctx"], meta["cmd"])
m.Push("name", value["cmd"]) m.Push("name", meta["cmd"])
m.Push("help", msg.Append("help")) m.Push("help", msg.Append("help"))
m.Push("inputs", msg.Append("list")) m.Push("inputs", msg.Append("list"))
m.Push("feature", msg.Append("meta")) m.Push("feature", msg.Append("meta"))
}
}) })
return return
} }
m.Confm("group", "hash."+arg[0]+".tool.hash."+arg[1]+".list."+arg[2], func(value map[string]interface{}) { // 执行命令
m.Cmdy("web.space", value["pod"], "ctx.command", value["ctx"], value["cmd"], "run", arg[3:]) m.Grows(ice.CHAT_GROUP, prefix, kit.MDB_ID, kit.Format(kit.Int(arg[2])+1), func(index int, value map[string]interface{}) {
if meta, ok := kit.Value(value, "meta").(map[string]interface{}); ok {
m.Cmdy(ice.WEB_SPACE, meta["pod"], ice.CTX_COMMAND, meta["ctx"], meta["cmd"], "run", arg[3:])
}
}) })
}}, }},
"/storm": {Name: "/storm", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) < 2 {
m.Confm("group", "hash."+arg[0]+".tool.hash", func(key string, value map[string]interface{}) {
m.Push("key", key).Push("count", len(value[ice.MDB_LIST].([]interface{})))
})
return
}
}},
"/steam": {Name: "/steam", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) < 2 {
m.Push("user", m.Conf("cli.runtime", "boot.username"))
m.Push("node", m.Conf("cli.runtime", "node.name"))
m.Confm("web.space", ice.MDB_HASH, func(key string, value map[string]interface{}) {
m.Push("user", m.Conf("cli.runtime", "boot.username"))
m.Push("node", value["name"])
})
return
}
switch arg[1] {
case "spawn":
list := []interface{}{}
for i := 3; i < len(arg)-3; i += 4 {
if arg[i] == m.Conf("cli.runtime", "node.name") {
arg[i] = ""
}
list = append(list, map[string]interface{}{
"pod": arg[i],
"ctx": arg[i+1],
"cmd": arg[i+2],
"key": arg[i+3],
})
}
m.Conf("group", "hash."+arg[0]+".tool.hash."+arg[2], map[string]interface{}{
ice.MDB_META: map[string]interface{}{
"create_time": m.Time(),
},
ice.MDB_HASH: map[string]interface{}{},
ice.MDB_LIST: list,
})
m.Log("info", "steam spawn %v %v %v", arg[0], arg[2], list)
default:
if arg[2] == m.Conf("cli.runtime", "node.name") {
arg[2] = ""
}
m.Cmdy("web.space", arg[2], "ctx.command")
}
}},
}, },
} }

View File

@ -56,7 +56,7 @@ var Index = &ice.Context{Name: "code", Help: "编程模块",
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmd(ice.GDB_EVENT, "listen", "miss", "start", "web.code.docker", "image") m.Cmd(ice.GDB_EVENT, "listen", "miss.start", "web.code.docker", "image")
}}, }},
"tmux": {Name: "tmux [session [window [pane cmd]]]", Help: "窗口", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { "tmux": {Name: "tmux [session [window [pane cmd]]]", Help: "窗口", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
prefix := kit.Simple(m.Confv("prefix", "tmux")) prefix := kit.Simple(m.Confv("prefix", "tmux"))
@ -64,25 +64,6 @@ var Index = &ice.Context{Name: "code", Help: "编程模块",
switch arg[1] { switch arg[1] {
case "cmd": case "cmd":
case "pane":
prefix = append(prefix, "list-panes")
if arg[0] == "" {
prefix = append(prefix, "-a")
} else {
prefix = append(prefix, "-s", "-t", arg[0])
}
m.Cmd(prefix, "cmd_parse", "cut", " ", "8", "pane_name size some lines bytes haha pane_id tag").Table(func(index int, value map[string]string) {
m.Push("pane_id", strings.TrimPrefix(value["pane_id"], "%"))
m.Push("pane_name", strings.TrimSuffix(value["pane_name"], ":"))
m.Push("size", value["size"])
m.Push("lines", strings.TrimSuffix(value["lines"], ","))
m.Push("bytes", kit.FmtSize(kit.Int64(value["bytes"])))
m.Push("tag", value["tag"])
})
m.Sort("pane_name")
return
case "favor": case "favor":
env := m.Cmdx(prefix, "show-environment", "-g") + m.Cmdx(prefix, "show-environment", "-t", arg[0]) env := m.Cmdx(prefix, "show-environment", "-g") + m.Cmdx(prefix, "show-environment", "-t", arg[0])
for _, l := range strings.Split(env, "\n") { for _, l := range strings.Split(env, "\n") {
@ -107,143 +88,8 @@ var Index = &ice.Context{Name: "code", Help: "编程模块",
}) })
m.Echo(strings.TrimSpace(m.Cmdx(prefix, "capture-pane", "-pt", arg[0]))) m.Echo(strings.TrimSpace(m.Cmdx(prefix, "capture-pane", "-pt", arg[0])))
return return
case "buffer":
// 写缓存
if len(arg) > 5 {
switch arg[3] {
case "modify":
switch arg[4] {
case "text":
m.Cmdy(prefix, "set-buffer", "-b", arg[2], arg[5])
} }
} }
} else if len(arg) > 3 {
m.Cmd(prefix, "set-buffer", "-b", arg[2], arg[3])
}
// 读缓存
if len(arg) > 2 {
m.Cmdy(prefix, "show-buffer", "-b", arg[2])
return
}
m.Cmd(prefix, "list-buffers", "cmd_parse", "cut", ": ", "3", "buffer size text").Table(func(index int, value map[string]string, head []string) {
m.Push("buffer", value["buffer"])
m.Push("size", value["size"])
if index < 3 {
m.Push("text", m.Cmdx(prefix, "show-buffer", "-b", value["buffer"]))
} else {
m.Push("text", value["text"][2:len(value["text"])-1])
}
})
return
case "select":
// 切换会话
if m.Options("session") {
m.Cmd(prefix, "switch-client", "-t", arg[0])
arg = arg[:0]
break
}
m.Cmd(prefix, "switch-client", "-t", m.Option("session"))
// 切换窗口
if !m.Options("window") {
m.Cmd(prefix, "select-window", "-t", m.Option("session")+":"+arg[0])
arg = []string{m.Option("session")}
break
}
m.Cmd(prefix, "select-window", "-t", m.Option("session")+":"+m.Option("window"))
// 切换终端
m.Cmd(prefix, "select-pane", "-t", m.Option("session")+":"+m.Option("window")+"."+arg[0])
arg = []string{m.Option("session"), m.Option("window")}
case "modify":
switch arg[2] {
case "session":
// 重命名会话
m.Cmdy(prefix, "rename-session", "-t", arg[0], arg[3])
arg = arg[:0]
case "window":
// 重命名窗口
m.Cmdy(prefix, "rename-window", "-t", m.Option("session")+":"+arg[0], arg[3])
arg = []string{m.Option("session")}
default:
return
}
case "delete":
// 删除会话
if !m.Options("session") {
m.Cmdy(prefix, "kill-session", "-t", arg[0])
arg = arg[:0]
break
}
// 删除窗口
if !m.Options("window") {
m.Cmdy(prefix, "kill-window", "-t", m.Option("session")+":"+arg[0])
arg = []string{m.Option("session")}
break
}
// 删除终端
m.Cmd(prefix, "kill-pane", "-t", m.Option("session")+":"+m.Option("window")+"."+arg[3])
arg = []string{m.Option("session"), m.Option("window")}
}
}
// 查看会话
if x := m.Cmdx(prefix, "list-session", "-F", "#{session_id},#{session_attached},#{session_name},#{session_windows},#{session_height},#{session_width}"); len(arg) == 0 {
for _, l := range kit.Split(x, "\n") {
ls := kit.Split(l, ",")
m.Push("id", ls[0])
m.Push("tag", ls[1])
m.Push("session", ls[2])
m.Push("windows", ls[3])
m.Push("height", ls[4])
m.Push("width", ls[5])
}
return
}
// 创建会话
if arg[0] != "" && kit.IndexOf(m.Appendv("session"), arg[0]) == -1 {
m.Cmdy(prefix, "new-session", "-ds", arg[0])
}
m.Set(ice.MSG_APPEND).Set(ice.MSG_RESULT)
// 查看窗口
if m.Cmdy(prefix, "list-windows", "-t", arg[0], "-F", "#{window_id},#{window_active},#{window_name},#{window_panes},#{window_height},#{window_width}",
"cmd_parse", "cut", ",", "6", "id tag window panes height width"); len(arg) == 1 {
return
}
// 创建窗口
if arg[1] != "" && kit.IndexOf(m.Appendv("window"), arg[1]) == -1 {
m.Cmdy(prefix, "new-window", "-dt", arg[0], "-n", arg[1])
}
m.Set(ice.MSG_APPEND).Set(ice.MSG_RESULT)
// 查看面板
if len(arg) == 2 {
m.Cmdy(prefix, "list-panes", "-t", arg[0]+":"+arg[1], "-F", "#{pane_id},#{pane_active},#{pane_index},#{pane_tty},#{pane_height},#{pane_width}",
"cmd_parse", "cut", ",", "6", "id tag pane tty height width")
return
}
// 执行命令
target := arg[0] + ":" + arg[1] + "." + arg[2]
if len(arg) > 3 {
m.Cmdy(prefix, "send-keys", "-t", target, strings.Join(arg[3:], " "), "Enter")
time.Sleep(1 * time.Second)
}
// 查看终端
m.Echo(strings.TrimSpace(m.Cmdx(prefix, "capture-pane", "-pt", target)))
return return
}}, }},
"docker": {Name: "docker image|volume|network|container", Help: "容器", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { "docker": {Name: "docker image|volume|network|container", Help: "容器", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {

View File

@ -14,16 +14,7 @@ import (
var Index = &ice.Context{Name: "mall", Help: "团队模块", var Index = &ice.Context{Name: "mall", Help: "团队模块",
Caches: map[string]*ice.Cache{}, Caches: map[string]*ice.Cache{},
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{},
"miss": {Value: map[string]interface{}{
ice.MDB_META: map[string]interface{}{
"path": "usr/local/work",
"cmd": []interface{}{"cli.system", "sh", "ice.sh", "start", "web.space", "connect"},
},
ice.MDB_LIST: map[string]interface{}{},
ice.MDB_HASH: map[string]interface{}{},
}},
},
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
"miss": {Name: "miss", Help: "任务", Meta: map[string]interface{}{ "miss": {Name: "miss", Help: "任务", Meta: map[string]interface{}{
"exports": []interface{}{"you", "name"}, "exports": []interface{}{"you", "name"},
@ -76,15 +67,15 @@ var Index = &ice.Context{Name: "mall", Help: "团队模块",
}, Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
switch arg[0] { switch arg[0] {
case "create": case "create":
meta := m.Grow("web.chat.group", []string{ice.MDB_HASH, m.Option("sess.river"), "task"}, map[string]interface{}{ id := m.Grow("web.chat.group", []string{kit.MDB_HASH, m.Option("sess.river"), "task"}, map[string]interface{}{
"name": arg[1], "name": arg[1],
"text": kit.Select("", arg, 2), "text": kit.Select("", arg, 2),
"status": "准备", "status": "准备",
"begin_time": m.Time(), "begin_time": m.Time(),
"close_time": m.Time("3h"), "close_time": m.Time("3h"),
}) })
m.Log("info", "create task %v", kit.Format(meta)) m.Log("info", "create task %v", id)
m.Echo("%v", meta["count"]) m.Echo("%d", id)
case "action": case "action":
case "cancel": case "cancel":
} }

View File

@ -1,11 +1,10 @@
package team package team
import ( import (
"github.com/shylinux/toolkits"
"github.com/shylinux/icebergs" "github.com/shylinux/icebergs"
_ "github.com/shylinux/icebergs/base" _ "github.com/shylinux/icebergs/base"
"github.com/shylinux/icebergs/base/web" "github.com/shylinux/icebergs/base/web"
"github.com/shylinux/toolkits"
"os" "os"
"path" "path"
@ -15,55 +14,55 @@ import (
var Index = &ice.Context{Name: "team", Help: "团队模块", var Index = &ice.Context{Name: "team", Help: "团队模块",
Caches: map[string]*ice.Cache{}, Caches: map[string]*ice.Cache{},
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{
"miss": {Value: map[string]interface{}{ "miss": {Name: "miss", Help: "任务", Value: kit.Data(
ice.MDB_META: map[string]interface{}{ "path", "usr/local/work",
"path": "usr/local/work", "cmd", []interface{}{"cli.system", "sh", "ice.sh", "start", "web.space", "connect"},
"cmd": []interface{}{"cli.system", "sh", "ice.sh", "start", "web.space", "connect"}, )},
},
ice.MDB_LIST: map[string]interface{}{},
ice.MDB_HASH: map[string]interface{}{},
}},
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
"miss": {Name: "miss", Help: "任务", Meta: map[string]interface{}{ "miss": {Name: "miss", Help: "任务", Meta: map[string]interface{}{
"exports": []interface{}{"you", "name"}, "exports": []interface{}{"you", "name"},
"detail": []interface{}{"启动", "停止"}, "detail": []interface{}{"启动", "停止"},
}, List: []interface{}{ }, List: kit.List(
map[string]interface{}{"type": "text", "value": "", "name": "name"}, kit.MDB_TYPE, "text", "value", "", "name", "name",
map[string]interface{}{"type": "text", "value": "", "name": "type"}, kit.MDB_TYPE, "text", "value", "", "name", "type",
map[string]interface{}{"type": "button", "value": "创建", "action": "auto"}, kit.MDB_TYPE, "button", "value", "创建", "action", "auto",
}, Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { ), Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
if len(arg) > 1 { if len(arg) > 1 {
switch arg[1] { switch arg[1] {
case "启动": case "启动":
case "停止": case "停止":
m.Cmd("web.space", arg[0], "exit", "1") m.Cmd(ice.WEB_SPACE, arg[0], "exit", "1")
m.Cmd(ice.GDB_EVENT, "action", "miss", "stop", arg[0]) m.Cmd(ice.GDB_EVENT, "action", "miss.stop", arg[0])
return return
} }
} }
if len(arg) > 0 { if len(arg) > 0 {
// 规范命名
if !strings.Contains(arg[0], "-") { if !strings.Contains(arg[0], "-") {
arg[0] = m.Time("20060102-") + arg[0] arg[0] = m.Time("20060102-") + arg[0]
} }
// 创建目录
p := path.Join(m.Conf("miss", "meta.path"), arg[0]) p := path.Join(m.Conf("miss", "meta.path"), arg[0])
if _, e := os.Stat(p); e != nil { if _, e := os.Stat(p); e != nil {
os.MkdirAll(p, 0777) os.MkdirAll(p, 0777)
} }
if !m.Confs("web.space", "hash."+arg[0]) { if !m.Confs(ice.WEB_SPACE, kit.Keys("hash", arg[0])) {
// 启动任务
m.Option("cmd_dir", p) m.Option("cmd_dir", p)
m.Option("cmd_type", "daemon") m.Option("cmd_type", "daemon")
m.Cmd(ice.GDB_EVENT, "action", "miss", "start", arg[0]) m.Cmd(ice.GDB_EVENT, "action", "miss.start", arg[0])
m.Cmd(m.Confv("miss", "meta.cmd")) m.Cmd(m.Confv("miss", "meta.cmd"))
} }
} }
// 任务列表
m.Cmdy("nfs.dir", m.Conf("miss", "meta.path"), "", "time name") m.Cmdy("nfs.dir", m.Conf("miss", "meta.path"), "", "time name")
m.Table(func(index int, value map[string]string, head []string) { m.Table(func(index int, value map[string]string, head []string) {
m.Push("status", kit.Select("stop", "start", m.Confs("web.space", "hash."+value["name"]))) m.Push("status", kit.Select("stop", "start", m.Confs(ice.WEB_SPACE, kit.Keys("hash", value["name"]))))
}) })
}}, }},
}, },

View File

@ -150,14 +150,14 @@ func (b *Chain) show(m *ice.Message, str string) (res []string) {
// 输出节点 // 输出节点
word := kit.Split(line) word := kit.Split(line)
res = append(res, "{", ice.MDB_META, "{", "text") res = append(res, "{", kit.MDB_META, "{", "text")
res = append(res, word...) res = append(res, word...)
res = append(res, "}", ice.MDB_LIST, "[") res = append(res, "}", kit.MDB_LIST, "[")
} }
return return
} }
func (b *Chain) size(m *ice.Message, root map[string]interface{}, depth int, width map[int]int) int { func (b *Chain) size(m *ice.Message, root map[string]interface{}, depth int, width map[int]int) int {
meta := root[ice.MDB_META].(map[string]interface{}) meta := root[kit.MDB_META].(map[string]interface{})
// 最大宽度 // 最大宽度
text := kit.Format(meta["text"]) text := kit.Format(meta["text"])
@ -167,8 +167,8 @@ func (b *Chain) size(m *ice.Message, root map[string]interface{}, depth int, wid
// 计算高度 // 计算高度
height := 0 height := 0
if list, ok := root[ice.MDB_LIST].([]interface{}); ok && len(list) > 0 { if list, ok := root[kit.MDB_LIST].([]interface{}); ok && len(list) > 0 {
kit.Fetch(root[ice.MDB_LIST], func(index int, value map[string]interface{}) { kit.Fetch(root[kit.MDB_LIST], func(index int, value map[string]interface{}) {
height += b.size(m, value, depth+1, width) height += b.size(m, value, depth+1, width)
}) })
} else { } else {
@ -179,7 +179,7 @@ func (b *Chain) size(m *ice.Message, root map[string]interface{}, depth int, wid
return height return height
} }
func (b *Chain) draw(m *ice.Message, root map[string]interface{}, depth int, width map[int]int, x, y int, p *Block) Chart { func (b *Chain) draw(m *ice.Message, root map[string]interface{}, depth int, width map[int]int, x, y int, p *Block) Chart {
meta := root[ice.MDB_META].(map[string]interface{}) meta := root[kit.MDB_META].(map[string]interface{})
b.Width, b.Height = 0, 0 b.Width, b.Height = 0, 0
// 当前节点 // 当前节点
@ -193,11 +193,11 @@ func (b *Chain) draw(m *ice.Message, root map[string]interface{}, depth int, wid
Width: b.GetWidth(strings.Repeat(" ", width[depth])), Width: b.GetWidth(strings.Repeat(" ", width[depth])),
} }
block.Data(root[ice.MDB_META]) block.Data(root[kit.MDB_META])
block.Init(m, kit.Format(meta["text"])).Draw(m, x, y+(kit.Int(meta["height"])-1)*b.GetHeights()/2) block.Init(m, kit.Format(meta["text"])).Draw(m, x, y+(kit.Int(meta["height"])-1)*b.GetHeights()/2)
// 递归节点 // 递归节点
kit.Fetch(root[ice.MDB_LIST], func(index int, value map[string]interface{}) { kit.Fetch(root[kit.MDB_LIST], func(index int, value map[string]interface{}) {
b.draw(m, value, depth+1, width, x+b.GetWidths(strings.Repeat(" ", width[depth])), y, block) b.draw(m, value, depth+1, width, x+b.GetWidths(strings.Repeat(" ", width[depth])), y, block)
y += kit.Int(kit.Value(value, "meta.height")) * b.GetHeights() y += kit.Int(kit.Value(value, "meta.height")) * b.GetHeights()
}) })

View File

@ -16,7 +16,7 @@ import (
var Index = &ice.Context{Name: "wiki", Help: "文档模块", var Index = &ice.Context{Name: "wiki", Help: "文档模块",
Caches: map[string]*ice.Cache{}, Caches: map[string]*ice.Cache{},
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{
"note": {Name: "note", Help: "笔记", Value: ice.Data( "note": {Name: "note", Help: "笔记", Value: kit.Data(
"temp", "var/tmp/file", "temp", "var/tmp/file",
"path", "usr/local/wiki", "path", "usr/local/wiki",
"head", "time size line path", "head", "time size line path",
@ -28,19 +28,19 @@ var Index = &ice.Context{Name: "wiki", Help: "文档模块",
"section": []interface{}{"title", "section"}, "section": []interface{}{"title", "section"},
}, },
)}, )},
"title": {Name: "title", Help: "标题", Value: ice.Data("template", title)}, "title": {Name: "title", Help: "标题", Value: kit.Data("template", title)},
"shell": {Name: "shell", Help: "命令", Value: ice.Data("template", shell)}, "shell": {Name: "shell", Help: "命令", Value: kit.Data("template", shell)},
"order": {Name: "order", Help: "列表", Value: ice.Data("template", order)}, "order": {Name: "order", Help: "列表", Value: kit.Data("template", order)},
"table": {Name: "table", Help: "表格", Value: ice.Data("template", table)}, "table": {Name: "table", Help: "表格", Value: kit.Data("template", table)},
"chart": {Name: "chart", Help: "绘图", Value: ice.Data("prefix", prefix, "suffix", `</svg>`)}, "chart": {Name: "chart", Help: "绘图", Value: kit.Data("prefix", prefix, "suffix", `</svg>`)},
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
"chart": {Name: "chart block|chain|table name text [fg bg fs ls p m]", Help: "绘图", Meta: map[string]interface{}{ "chart": {Name: "chart block|chain|table name text [fg bg fs ls p m]", Help: "绘图", Meta: map[string]interface{}{
"display": "inner", "display": "inner",
}, List: ice.List( }, List: kit.List(
ice.MDB_TYPE, "select", "value", "chain", "values", "block chain table", kit.MDB_TYPE, "select", "value", "chain", "values", "block chain table",
ice.MDB_TYPE, "text", "value", "", kit.MDB_TYPE, "text", "value", "",
ice.MDB_TYPE, "button", "value", "生成", kit.MDB_TYPE, "button", "value", "生成",
), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
// 创建类型 // 创建类型
var chart Chart var chart Chart
@ -164,10 +164,10 @@ var Index = &ice.Context{Name: "wiki", Help: "文档模块",
"note": {Name: "note file", Help: "笔记", Meta: map[string]interface{}{ "note": {Name: "note file", Help: "笔记", Meta: map[string]interface{}{
"remote": "true", "display": "inner", "remote": "true", "display": "inner",
"detail": []string{"add", "commit", "history", "share"}, "detail": []string{"add", "commit", "history", "share"},
}, List: ice.List( }, List: kit.List(
ice.MDB_TYPE, "text", "value", "miss.md", "name", "path", kit.MDB_TYPE, "text", "value", "miss.md", "name", "path",
ice.MDB_TYPE, "button", "value", "执行", "action", "auto", kit.MDB_TYPE, "button", "value", "执行", "action", "auto",
ice.MDB_TYPE, "button", "value", "返回", "cb", "Last", kit.MDB_TYPE, "button", "value", "返回", "cb", "Last",
), Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { ), Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
if len(arg) > 0 { if len(arg) > 0 {
switch arg[0] { switch arg[0] {

View File

@ -2,7 +2,9 @@ package main
import ( import (
"github.com/shylinux/icebergs" "github.com/shylinux/icebergs"
_ "github.com/shylinux/icebergs/base"
_ "github.com/shylinux/icebergs/core" _ "github.com/shylinux/icebergs/core"
_ "github.com/shylinux/icebergs/misc"
) )
func main() { func main() {

192
type.go
View File

@ -8,6 +8,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"math/rand"
"os" "os"
"path" "path"
"runtime" "runtime"
@ -186,7 +187,7 @@ func (m *Message) Format(key interface{}) string {
case string: case string:
switch key { switch key {
case "cost": case "cost":
return time.Now().Sub(m.time).String() return kit.FmtTime(kit.Int64(time.Now().Sub(m.time)))
case "meta": case "meta":
return kit.Format(m.meta) return kit.Format(m.meta)
case "time": case "time":
@ -367,7 +368,10 @@ func (m *Message) Push(key string, value interface{}, arg ...interface{}) *Messa
return m.Add(MSG_APPEND, key, kit.Format(value)) return m.Add(MSG_APPEND, key, kit.Format(value))
} }
func (m *Message) Echo(str string, arg ...interface{}) *Message { func (m *Message) Echo(str string, arg ...interface{}) *Message {
m.meta[MSG_RESULT] = append(m.meta[MSG_RESULT], fmt.Sprintf(str, arg...)) if len(arg) > 0 {
str = fmt.Sprintf(str, arg...)
}
m.meta[MSG_RESULT] = append(m.meta[MSG_RESULT], str)
return m return m
} }
func (m *Message) Sort(key string, arg ...string) *Message { func (m *Message) Sort(key string, arg ...string) *Message {
@ -523,6 +527,15 @@ func (m *Message) Render(str string) *Message {
} }
return m return m
} }
func (m *Message) Split(str string, field string, space string, enter string) *Message {
fields := kit.Split(field, space)
for _, l := range kit.Split(str, enter) {
for i, v := range kit.Split(l, space) {
m.Push(kit.Select("some", fields, i), v)
}
}
return m
}
func (m *Message) Detail(arg ...interface{}) string { func (m *Message) Detail(arg ...interface{}) string {
return kit.Select("", m.meta[MSG_DETAIL], 0) return kit.Select("", m.meta[MSG_DETAIL], 0)
@ -790,85 +803,131 @@ func (m *Message) Search(key interface{}, cb interface{}) *Message {
} }
func Meta(arg ...interface{}) string { func Meta(arg ...interface{}) string {
return MDB_META + "." + kit.Keys(arg...) return kit.MDB_META + "." + kit.Keys(arg...)
} }
func Data(arg ...interface{}) map[string]interface{} { func (m *Message) Richs(key string, chain interface{}, raw interface{}, cb interface{}) (res map[string]interface{}) {
meta := map[string]interface{}{} // 数据结构
data := map[string]interface{}{ cache := m.Confm(key, chain)
MDB_META: meta, MDB_LIST: []interface{}{}, MDB_HASH: map[string]interface{}{},
}
for i := 0; i < len(arg)-1; i += 2 {
kit.Value(meta, arg[i], arg[i+1])
}
return data
}
func List(arg ...interface{}) []interface{} {
list, data := []interface{}{}, map[string]interface{}{}
for i := 0; i < len(arg)-1; i += 2 {
if arg[i] == MDB_TYPE {
data = map[string]interface{}{}
list = append(list, data)
}
kit.Value(data, arg[i], arg[i+1])
}
return list
}
func (m *Message) Rich(key string, args interface{}, data interface{}) string {
cache := m.Confm(key, args)
if cache == nil { if cache == nil {
cache = map[string]interface{}{} return nil
} }
meta, ok := cache[MDB_META].(map[string]interface{}) meta, ok := cache[kit.MDB_META].(map[string]interface{})
hash, ok := cache[kit.MDB_HASH].(map[string]interface{})
if !ok { if !ok {
meta = map[string]interface{}{} return nil
}
hash, ok := cache[MDB_HASH].(map[string]interface{})
if !ok {
hash = map[string]interface{}{}
} }
switch h := kit.Format(raw); h {
case "*", "":
// 全部遍历
switch cb := cb.(type) {
case func(string, map[string]interface{}):
for k, v := range hash {
cb(k, v.(map[string]interface{}))
}
}
case "%":
// 随机选取
list := []string{}
for k := range hash {
list = append(list, k)
}
h = list[rand.Intn(len(list))]
res, _ = hash[h].(map[string]interface{})
default:
// 单个查询
switch kit.Format(kit.Value(meta, "short")) {
case "", "uniq":
default:
h = kit.Hashs(h)
}
res, _ = hash[h].(map[string]interface{})
}
// 返回数据
if res != nil {
switch cb := cb.(type) {
case func(map[string]interface{}):
cb(res)
}
}
return res
}
func (m *Message) Rich(key string, chain interface{}, data interface{}) string {
// 数据结构
cache := m.Confm(key, chain)
if cache == nil {
cache = map[string]interface{}{}
m.Confv(key, chain, cache)
}
meta, ok := cache[kit.MDB_META].(map[string]interface{})
if !ok {
meta = map[string]interface{}{}
cache[kit.MDB_META] = meta
}
hash, ok := cache[kit.MDB_HASH].(map[string]interface{})
if !ok {
hash = map[string]interface{}{}
cache[kit.MDB_HASH] = hash
}
// 通用数据
if kit.Value(data, "meta") != nil {
kit.Value(data, "meta.create_time", m.Time())
} else {
kit.Value(data, "create_time", m.Time())
}
// 生成键值
h := "" h := ""
switch short := kit.Format(kit.Value(meta, "short")); short { switch short := kit.Format(kit.Value(meta, "short")); short {
case "": case "":
h = kit.ShortKey(hash, 6) h = kit.ShortKey(hash, 6)
case "uniq":
h = kit.Hashs("uniq")
case "data": case "data":
h = kit.Hashs(kit.Format(data)) h = kit.Hashs(kit.Format(data))
default: default:
h = kit.Hashs(kit.Format(kit.Value(data, short))) h = kit.Hashs(kit.Format(kit.Value(data, short)))
} }
hash[h] = data
cache[MDB_HASH] = hash // 添加数据
cache[MDB_META] = meta hash[h] = data
if args == nil {
m.Conf(key, cache)
} else {
m.Conf(key, args, cache)
}
return h return h
} }
func (m *Message) Grow(key string, args interface{}, data interface{}) map[string]interface{} { func (m *Message) Grow(key string, chain interface{}, data interface{}) int {
cache := m.Confm(key, args) // 数据结构
cache := m.Confm(key, chain)
if cache == nil { if cache == nil {
cache = map[string]interface{}{} cache = map[string]interface{}{}
m.Confv(key, chain, cache)
} }
meta, ok := cache[MDB_META].(map[string]interface{}) meta, ok := cache[kit.MDB_META].(map[string]interface{})
if !ok { if !ok {
meta = map[string]interface{}{} meta = map[string]interface{}{}
cache[kit.MDB_META] = meta
}
list, _ := cache[kit.MDB_LIST].([]interface{})
// 通用数据
id := kit.Int(meta["count"]) + 1
if kit.Value(data, "meta") != nil {
kit.Value(data, "meta.id", id)
} else {
kit.Value(data, "id", id)
} }
list, _ := cache[MDB_LIST].([]interface{})
// 添加数据 // 添加数据
list = append(list, data) list = append(list, data)
meta["count"] = kit.Int(meta["count"]) + 1 cache[kit.MDB_LIST] = list
kit.Value(data, "id", meta["count"]) meta["count"] = id
// 保存数据 // 保存数据
if len(list) > kit.Int(kit.Select(m.Conf("cache", Meta("limit")), meta["limit"])) { if len(list) > kit.Int(kit.Select(m.Conf(WEB_CACHE, Meta("limit")), meta["limit"])) {
least := kit.Int(kit.Select(m.Conf("cache", Meta("least")), meta["least"])) least := kit.Int(kit.Select(m.Conf(WEB_CACHE, Meta("least")), meta["least"]))
// 创建文件 // 创建文件
name := kit.Select(path.Join(m.Conf("cache", Meta("store")), key+".csv"), meta["store"]) name := kit.Select(path.Join(m.Conf(WEB_CACHE, Meta("store")), kit.Keys(key, chain, "csv")), meta["store"])
f, e := os.OpenFile(name, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666) f, e := os.OpenFile(name, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666)
if e != nil { if e != nil {
f, _, e = kit.Create(name) f, _, e = kit.Create(name)
@ -929,39 +988,30 @@ func (m *Message) Grow(key string, args interface{}, data interface{}) map[strin
list = list[:least] list = list[:least]
w.Flush() w.Flush()
} }
return id
// 更新数据
cache[MDB_LIST] = list
cache[MDB_META] = meta
if args == nil {
m.Conf(key, cache)
} else {
m.Conf(key, args, cache)
}
return meta
} }
func (m *Message) Grows(key string, args interface{}, cb interface{}) map[string]interface{} { func (m *Message) Grows(key string, args interface{}, match string, value string, cb interface{}) map[string]interface{} {
cache := m.Confm(key, args) cache := m.Confm(key, args)
if cache == nil { if cache == nil {
return nil return nil
} }
meta, ok := cache[MDB_META].(map[string]interface{}) meta, ok := cache[kit.MDB_META].(map[string]interface{})
if !ok { list, ok := cache[kit.MDB_LIST].([]interface{})
return nil if !ok || len(list) == 0 {
}
list, ok := cache[MDB_LIST].([]interface{})
if !ok {
return nil return nil
} }
offend := kit.Int(kit.Select("0", m.Option("cache.offend"))) offend := kit.Int(kit.Select("0", m.Option("cache.offend")))
limit := kit.Int(kit.Select("10", m.Option("cache.limit"))) limit := kit.Int(kit.Select("10", m.Option("cache.limit")))
match := kit.Select("", m.Option("cache.match"))
value := kit.Select("", m.Option("cache.value"))
current := kit.Int(meta["offset"]) current := kit.Int(meta["offset"])
end := current + len(list) - offend end := current + len(list) - offend
begin := end - limit begin := end - limit
if match == kit.MDB_ID {
begin, end = kit.Int(value)-1, kit.Int(value)
match, value = "", ""
}
data := make([]interface{}, 0, limit) data := make([]interface{}, 0, limit)
m.Log(LOG_INFO, "read %v-%v from %v-%v", begin, end, current, current+len(list)) m.Log(LOG_INFO, "read %v-%v from %v-%v", begin, end, current, current+len(list))
if begin < current { if begin < current {
@ -1067,8 +1117,12 @@ func (m *Message) Confv(arg ...interface{}) (val interface{}) {
m.Search(arg[0], func(p *Context, s *Context, key string, conf *Config) { m.Search(arg[0], func(p *Context, s *Context, key string, conf *Config) {
if len(arg) > 1 { if len(arg) > 1 {
if len(arg) > 2 { if len(arg) > 2 {
if arg[1] == nil {
conf.Value = arg[2]
} else {
kit.Value(conf.Value, arg[1:]...) kit.Value(conf.Value, arg[1:]...)
} }
}
val = kit.Value(conf.Value, arg[1]) val = kit.Value(conf.Value, arg[1])
} else { } else {
val = conf.Value val = conf.Value