diff --git a/base.go b/base.go index cc5b3b62..da1dddd4 100644 --- a/base.go +++ b/base.go @@ -18,37 +18,37 @@ func (f *Frame) Spawn(m *Message, c *Context, arg ...string) Server { } func (f *Frame) Begin(m *Message, arg ...string) Server { m.Log(LOG_BEGIN, "ice") + list := map[*Context]*Message{m.target: m} m.Travel(func(p *Context, s *Context) { s.root = m.target if msg, ok := list[p]; ok && msg != nil { - sub := msg.Spawns(s) - s.Begin(sub, arg...) - list[s] = sub + list[s] = msg.Spawns(s) + s.Begin(list[s], arg...) } }) - m.target.wg = &sync.WaitGroup{} m.root.Cost("begin") return f } func (f *Frame) Start(m *Message, arg ...string) bool { + m.Log(LOG_START, "ice") m.Cap(CTX_STATUS, "start") m.Cap(CTX_STREAM, strings.Split(m.Time(), " ")[1]) - m.Log(LOG_START, "ice") - m.Cmd(ICE_INIT).Cmd("init", arg) m.root.Cost("start") + + m.Cmd("init", arg) return true } func (f *Frame) Close(m *Message, arg ...string) bool { m.TryCatch(m, true, func(m *Message) { m.target.wg.Wait() }) + list := map[*Context]*Message{m.target: m} m.Travel(func(p *Context, s *Context) { if msg, ok := list[p]; ok && msg != nil { - sub := msg.Spawns(s) - s.Close(sub, arg...) - list[s] = sub + list[s] = msg.Spawns(s) + s.Close(list[s], arg...) } }) return true @@ -56,14 +56,11 @@ func (f *Frame) Close(m *Message, arg ...string) bool { var Index = &Context{Name: "ice", Help: "冰山模块", Caches: map[string]*Cache{ - CTX_STATUS: {Value: "begin"}, - CTX_STREAM: {Value: "shy"}, CTX_FOLLOW: {Value: ""}, + CTX_STREAM: {Value: "shy"}, + CTX_STATUS: {Value: "begin"}, }, Configs: map[string]*Config{ - "table": {Name: "数据缓存", Value: map[string]interface{}{ - "compact": "false", - }}, "help": {Value: map[string]interface{}{ "index": []interface{}{ "^_^ 欢迎使用冰山框架 ^_^", @@ -84,22 +81,27 @@ var Index = &Context{Name: "ice", Help: "冰山模块", } }) }}, - "init": {Name: "init", Help: "hello", Hand: func(m *Message, c *Context, cmd string, arg ...string) { + "init": {Name: "init", Help: "启动", Hand: func(m *Message, c *Context, cmd string, arg ...string) { + m.root.Cmd(ICE_INIT) m.root.Cost("_init") - m.Start("log") - m.Start("gdb") - m.Start("ssh") + + m.target.root.wg = &sync.WaitGroup{} + for _, k := range []string{"log", "gdb", "ssh"} { + m.Start(k) + } + m.Cmd("ssh.scan", "init.shy", "启动配置", "etc/init.shy") m.Cmd(arg) }}, "help": {Name: "help", Help: "帮助", Hand: func(m *Message, c *Context, cmd string, arg ...string) { m.Echo(strings.Join(kit.Simple(m.Confv("help", "index")), "\n")) }}, - "exit": {Name: "exit", Help: "hello", Hand: func(m *Message, c *Context, cmd string, arg ...string) { + "exit": {Name: "exit", Help: "结束", Hand: func(m *Message, c *Context, cmd string, arg ...string) { + m.root.target.server.(*Frame).code = kit.Int(kit.Select("0", arg, 0)) m.Cmd("ssh.scan", "exit.shy", "退出配置", "etc/exit.shy") - f := m.root.target.server.(*Frame) - f.code = kit.Int(kit.Select("0", arg, 0)) + m.root.Cmd(ICE_EXIT) + m.root.Cost("_exit") }}, ICE_EXIT: {Hand: func(m *Message, c *Context, cmd string, arg ...string) { m.root.Travel(func(p *Context, c *Context) { @@ -118,8 +120,8 @@ var Pulse = &Message{ meta: map[string][]string{}, data: map[string]interface{}{}, - messages: []*Message{}, message: nil, root: nil, source: Index, target: Index, Hand: true, + messages: []*Message{}, message: nil, root: nil, } var Log func(*Message, string, string) @@ -142,6 +144,7 @@ func Run(arg ...string) string { if frame.Begin(Pulse.Spawns(), arg...).Start(Pulse.Spawns(), arg...) { frame.Close(Pulse.Spawns(), arg...) } + time.Sleep(time.Second) os.Exit(frame.code) return Pulse.Result() diff --git a/base/aaa/aaa.go b/base/aaa/aaa.go index c2bcd59d..3f879d9f 100644 --- a/base/aaa/aaa.go +++ b/base/aaa/aaa.go @@ -18,14 +18,15 @@ func distance(lat1, long1, lat2, long2 float64) float64 { var Index = &ice.Context{Name: "aaa", Help: "认证模块", Caches: map[string]*ice.Cache{}, Configs: map[string]*ice.Config{ - ice.AAA_ROLE: {Name: "role", Help: "角色", Value: kit.Data(kit.MDB_SHORT, "chain", "root", kit.Dict(), "tech", kit.Dict())}, + ice.AAA_ROLE: {Name: "role", Help: "角色", Value: kit.Data(kit.MDB_SHORT, "chain")}, ice.AAA_USER: {Name: "user", Help: "用户", Value: kit.Data(kit.MDB_SHORT, "username")}, ice.AAA_SESS: {Name: "sess", Help: "会话", Value: kit.Data(kit.MDB_SHORT, "uniq", "expire", "720h")}, - "location": {Name: "location", Help: "location", Value: kit.Data(kit.MDB_SHORT, "name")}, + + "location": {Name: "location", Help: "定位", Value: kit.Data(kit.MDB_SHORT, "name")}, }, Commands: map[string]*ice.Command{ ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Cmd(ice.CTX_CONFIG, "load", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json")) + m.Load() // 权限索引 m.Conf(ice.AAA_ROLE, "black.tech.meta.short", "chain") m.Conf(ice.AAA_ROLE, "white.tech.meta.short", "chain") @@ -33,11 +34,9 @@ var Index = &ice.Context{Name: "aaa", Help: "认证模块", m.Conf(ice.AAA_ROLE, "white.void.meta.short", "chain") }}, ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Cmd(ice.CTX_CONFIG, "save", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json"), - ice.AAA_ROLE, ice.AAA_USER, ice.AAA_SESS, - kit.Keys(m.Cap(ice.CTX_FOLLOW), "location"), - ) + m.Save(ice.AAA_ROLE, ice.AAA_USER, ice.AAA_SESS, m.Prefix("location")) }}, + "location": {Name: "location", Help: "location", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if len(arg) == 0 { m.Grows("location", nil, "", "", func(index int, value map[string]interface{}) { diff --git a/base/cli/cli.go b/base/cli/cli.go index a90309d8..c81f3f24 100644 --- a/base/cli/cli.go +++ b/base/cli/cli.go @@ -22,7 +22,7 @@ var Index = &ice.Context{Name: "cli", Help: "命令模块", }, Commands: map[string]*ice.Command{ ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Cmd(ice.CTX_CONFIG, "load", "cli.json") + m.Load() // 启动配置 m.Conf(ice.CLI_RUNTIME, "conf.ctx_self", os.Getenv("ctx_self")) @@ -59,7 +59,7 @@ var Index = &ice.Context{Name: "cli", Help: "命令模块", m.Log("info", "runtime %v", kit.Formats(m.Confv(ice.CLI_RUNTIME))) }}, ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Cmd(ice.CTX_CONFIG, "save", "cli.json", ice.CLI_RUNTIME, ice.CLI_SYSTEM) + m.Save(ice.CLI_RUNTIME, ice.CLI_SYSTEM) }}, ice.CLI_RUNTIME: {Name: "runtime", Help: "运行环境", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { diff --git a/base/ctx/ctx.go b/base/ctx/ctx.go index 871d2970..063885a7 100644 --- a/base/ctx/ctx.go +++ b/base/ctx/ctx.go @@ -137,7 +137,7 @@ var Index = &ice.Context{Name: "ctx", Help: "配置模块", switch arg[0] { case "save": // 保存配置 - arg[1] = path.Join(msg.Conf(ice.CTX_CONFIG, ice.Meta("path")), arg[1]) + arg[1] = path.Join(msg.Conf(ice.CTX_CONFIG, "meta.path"), arg[1]) if f, p, e := kit.Create(arg[1]); m.Assert(e) { data := map[string]interface{}{} for _, k := range arg[2:] { @@ -152,7 +152,7 @@ var Index = &ice.Context{Name: "ctx", Help: "配置模块", } case "load": // 加载配置 - arg[1] = path.Join(msg.Conf(ice.CTX_CONFIG, ice.Meta("path")), arg[1]) + arg[1] = path.Join(msg.Conf(ice.CTX_CONFIG, "meta.path"), arg[1]) if f, e := os.Open(arg[1]); e == nil { data := map[string]interface{}{} json.NewDecoder(f).Decode(&data) diff --git a/base/gdb/gdb.go b/base/gdb/gdb.go index 7d44458e..b612a842 100644 --- a/base/gdb/gdb.go +++ b/base/gdb/gdb.go @@ -111,6 +111,7 @@ var Index = &ice.Context{Name: "gdb", Help: "事件模块", close(f.d) } }}, + ice.GDB_SIGNAL: {Name: "signal", Help: "信号器", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { switch arg[0] { case "listen": diff --git a/base/lex/lex.go b/base/lex/lex.go index 8e973ddc..0f486400 100644 --- a/base/lex/lex.go +++ b/base/lex/lex.go @@ -8,11 +8,6 @@ var Index = &ice.Context{Name: "lex", Help: "词法模块", Caches: map[string]*ice.Cache{}, Configs: map[string]*ice.Config{}, Commands: map[string]*ice.Command{ - 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) { - }}, - "hi": {Name: "hi", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Echo("hello %s world", c.Name) }}, diff --git a/base/mdb/mdb.go b/base/mdb/mdb.go index 7310a992..d0d91779 100644 --- a/base/mdb/mdb.go +++ b/base/mdb/mdb.go @@ -16,11 +16,6 @@ var Index = &ice.Context{Name: "mdb", Help: "数据模块", Caches: map[string]*ice.Cache{}, Configs: map[string]*ice.Config{}, Commands: map[string]*ice.Command{ - 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) { - }}, - "update": {Name: "update config table index key value", Help: "修改数据", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { meta := m.Confm(arg[0], arg[1]+".meta") index := kit.Int(arg[2]) - kit.Int(meta["offset"]) - 1 diff --git a/base/nfs/nfs.go b/base/nfs/nfs.go index a53d4a34..95653e30 100644 --- a/base/nfs/nfs.go +++ b/base/nfs/nfs.go @@ -141,9 +141,6 @@ var Index = &ice.Context{Name: "nfs", Help: "存储模块", Caches: map[string]*ice.Cache{}, Configs: map[string]*ice.Config{}, Commands: map[string]*ice.Command{ - 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) {}}, - "dir": {Name: "dir", Help: "目录", List: kit.List( kit.MDB_INPUT, "text", "name", "path", "action", "auto", kit.MDB_INPUT, "button", "name", "查看", diff --git a/base/ssh/ssh.go b/base/ssh/ssh.go index d6ce87c1..584f6da3 100644 --- a/base/ssh/ssh.go +++ b/base/ssh/ssh.go @@ -158,9 +158,14 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool { line += "\n" continue } - m.Option(ice.MSG_PROMPT, m.Confv("prompt", "meta.PS1")) - m.Log(ice.LOG_IMPORT, "stdin: %v", line) + if strings.HasPrefix(strings.TrimSpace(line), "#") { + // 注释 + line = "" + continue + } + m.Grow("history", nil, kit.Dict("line", line)) + m.Option(ice.MSG_PROMPT, m.Confv("prompt", "meta.PS1")) if f.out == os.Stdout { f.printf(m, "\033[0m") @@ -188,10 +193,10 @@ var Index = &ice.Context{Name: "ssh", Help: "终端模块", }, Commands: map[string]*ice.Command{ ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Cmd(ice.CTX_CONFIG, "load", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json")) + m.Load() }}, ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Cmd(ice.CTX_CONFIG, "save", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json"), kit.Keys(m.Cap(ice.CTX_FOLLOW), "history")) + m.Save("history") if f, ok := m.Target().Server().(*Frame); ok { // 关闭终端 diff --git a/base/tcp/tcp.go b/base/tcp/tcp.go index 61e6aa85..03ce1032 100644 --- a/base/tcp/tcp.go +++ b/base/tcp/tcp.go @@ -11,11 +11,6 @@ var Index = &ice.Context{Name: "tcp", Help: "通信模块", Caches: map[string]*ice.Cache{}, Configs: map[string]*ice.Config{}, Commands: map[string]*ice.Command{ - 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) { - }}, - "ifconfig": {Name: "ifconfig [name]", Help: "网络配置", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if ifs, e := net.Interfaces(); m.Assert(e) { for _, v := range ifs { diff --git a/base/web/web.go b/base/web/web.go index de7f23ed..dc9ba0a0 100644 --- a/base/web/web.go +++ b/base/web/web.go @@ -35,8 +35,13 @@ type Frame struct { send map[string]*ice.Message } +func Redirect(msg *ice.Message, url string, arg ...interface{}) *ice.Message { + msg.Push("_output", "redirect") + msg.Echo(kit.MergeURL(url, arg...)) + return msg +} func Cookie(msg *ice.Message, sessid string) string { - expire := time.Now().Add(kit.Duration(msg.Conf(ice.AAA_SESS, ice.Meta("expire")))) + expire := time.Now().Add(kit.Duration(msg.Conf(ice.AAA_SESS, "meta.expire"))) msg.Log("cookie", "expire:%v sessid:%s", kit.Format(expire), sessid) http.SetCookie(msg.W, &http.Cookie{Name: ice.WEB_SESS, Value: sessid, Path: "/", Expires: expire}) return sessid @@ -219,6 +224,9 @@ func (web *Frame) HandleCmd(m *ice.Message, key string, cmd *ice.Command) { // 请求参数 for k, v := range r.Form { msg.Optionv(k, v) + if k == ice.MSG_SESSID { + Cookie(msg, v[0]) + } } if msg.Optionv("cmds") == nil { @@ -322,7 +330,7 @@ func (web *Frame) Start(m *ice.Message, arg ...string) bool { // 静态路由 msg := m.Spawns(s) - m.Confm(ice.WEB_SERVE, ice.Meta("static"), func(key string, value string) { + m.Confm(ice.WEB_SERVE, "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)))) }) @@ -389,9 +397,10 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", ice.WEB_DREAM: {Name: "dream", Help: "梦想家", Value: kit.Data("path", "usr/local/work", "cmd", []interface{}{ice.CLI_SYSTEM, "ice.sh", "start", ice.WEB_SPACE, "connect"}, )}, + ice.WEB_FAVOR: {Name: "favor", Help: "收藏夹", Value: kit.Data(kit.MDB_SHORT, kit.MDB_NAME)}, ice.WEB_CACHE: {Name: "cache", Help: "缓存池", Value: kit.Data( - kit.MDB_SHORT, "text", "path", "var/file", "store", "var/data", "limit", "30", "least", "10", "fsize", "100000", + kit.MDB_SHORT, "text", "path", "var/file", "store", "var/data", "limit", "50", "least", "30", "fsize", "100000", )}, ice.WEB_STORY: {Name: "story", Help: "故事会", Value: kit.Dict( kit.MDB_META, kit.Dict(kit.MDB_SHORT, "data"), @@ -399,6 +408,7 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", "mime", kit.Dict("md", "txt"), )}, ice.WEB_SHARE: {Name: "share", Help: "共享链", Value: kit.Data("template", share_template)}, + ice.WEB_ROUTE: {Name: "route", Help: "路由", Value: kit.Data()}, ice.WEB_PROXY: {Name: "proxy", Help: "代理", Value: kit.Data()}, ice.WEB_GROUP: {Name: "group", Help: "分组", Value: kit.Data()}, @@ -406,7 +416,7 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", }, Commands: map[string]*ice.Command{ ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Cmd(ice.CTX_CONFIG, "load", "web.json") + m.Load() if m.Richs(ice.WEB_SPIDE, nil, "self", nil) == nil { m.Cmd(ice.WEB_SPIDE, "add", "self", kit.Select("http://:9020", m.Conf(ice.CLI_RUNTIME, "conf.ctx_self"))) @@ -427,8 +437,7 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", } }) // m.Conf(ice.WEB_CACHE, "hash", kit.Dict()) - m.Cmd(ice.CTX_CONFIG, "save", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json"), - ice.WEB_SPIDE, ice.WEB_FAVOR, ice.WEB_CACHE, ice.WEB_STORY, ice.WEB_SHARE) + m.Save(ice.WEB_SPIDE, ice.WEB_FAVOR, ice.WEB_CACHE, ice.WEB_STORY, ice.WEB_SHARE) m.Done() m.Richs(ice.WEB_SPACE, nil, "*", func(key string, value map[string]interface{}) { @@ -1007,7 +1016,7 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", defer f.Close() h := kit.Hashs(f) - if o, p, e := kit.Create(path.Join(m.Conf(ice.WEB_CACHE, ice.Meta("path")), h[:2], h)); m.Assert(e) { + if o, p, e := kit.Create(path.Join(m.Conf(ice.WEB_CACHE, "meta.path"), h[:2], h)); m.Assert(e) { defer o.Close() f.Seek(0, os.SEEK_SET) @@ -1026,7 +1035,7 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", // 创建文件 file := kit.Hashs(f) - if o, p, e := kit.Create(path.Join(m.Conf(ice.WEB_CACHE, ice.Meta("path")), file[:2], file)); m.Assert(e) { + if o, p, e := kit.Create(path.Join(m.Conf(ice.WEB_CACHE, "meta.path"), file[:2], file)); m.Assert(e) { defer o.Close() // 保存文件 @@ -1040,7 +1049,7 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", } else if r, ok := m.Optionv("response").(*http.Response); ok { if buf, e := ioutil.ReadAll(r.Body); m.Assert(e) { file := kit.Hashs(string(buf)) - if o, p, e := kit.Create(path.Join(m.Conf(ice.WEB_CACHE, ice.Meta("path")), file[:2], file)); m.Assert(e) { + if o, p, e := kit.Create(path.Join(m.Conf(ice.WEB_CACHE, "meta.path"), file[:2], file)); m.Assert(e) { defer o.Close() if n, e := o.Write(buf); m.Assert(e) { m.Info("download: %s file: %s", kit.FmtSize(int64(n)), p) @@ -1062,7 +1071,7 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", // 保存数据 if arg[0] == "add" && len(arg) == 4 { - p := path.Join(m.Conf(ice.WEB_CACHE, ice.Meta("path")), h[:2], h) + p := path.Join(m.Conf(ice.WEB_CACHE, "meta.path"), h[:2], h) if m.Cmd("nfs.save", p, arg[3]); kit.Int(size) > 512 { data["text"], data["file"], arg[3] = p, p, p } @@ -1326,7 +1335,7 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", case "commit": // 查询索引 head := kit.Hashs(arg[1]) - prev := m.Conf("story", ice.Meta("head", head, "list")) + prev := m.Conf("story", kit.Keys("meta.head", head, "list")) m.Log("info", "head: %v prev: %v", head, prev) // 查询节点 @@ -1336,7 +1345,7 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", menu[arg[i]] = arg[i+1] i++ } else if head := kit.Hashs(arg[i]); m.Confs("story", kit.Keys("meta", "head", head)) { - menu[arg[i]] = m.Conf(ice.WEB_STORY, ice.Meta("head", head, "list")) + menu[arg[i]] = m.Conf(ice.WEB_STORY, kit.Keys("meta.head", head, "list")) } else { m.Error(true, "not found %v", arg[i]) return @@ -1355,7 +1364,7 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", m.Log("info", "list: %v meta: %v", list, kit.Format(meta)) // 添加索引 - m.Conf("story", ice.Meta("head", head), map[string]interface{}{ + m.Conf("story", kit.Keys("meta.head", head), map[string]interface{}{ "time": m.Time(), "scene": "commit", "story": arg[1], "list": list, }) m.Echo(list) @@ -1509,14 +1518,15 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", default: m.Richs(ice.WEB_SHARE, nil, arg[0], func(key string, value map[string]interface{}) { + m.Info("share %s %v", arg, kit.Format(value)) switch kit.Select("", arg, 1) { case "qrcode": + // 显示共享码 m.Push("_output", "qrcode") m.Echo("%s/%s/", m.Conf(ice.WEB_SHARE, "meta.domain"), key) return } - m.Info("share %s %v", arg, kit.Format(value)) switch value["type"] { case ice.TYPE_STORY: if m.Cmdy(ice.WEB_STORY, "index", kit.Value(value, "text")).Append("text") == "" { @@ -1543,19 +1553,29 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", } } + case "river": + // 共享群组 + Redirect(m, "/", "share", key, "river", value["text"]) + case "storm": + // 共享应用 + Redirect(m, "/", "share", key, "storm", value["text"], "river", kit.Value(value, "extra.river")) + + case "action": if len(arg) == 1 { - m.Push("_output", "redirect") - m.Echo("/share/%s/", arg[0]) + // 跳转主页 + Redirect(m, "/share/"+arg[0]+"/", "title", value["name"]) break } if arg[1] == "" { + // 返回主页 http.ServeFile(m.W, m.R, "usr/volcanos/share.html") break } if len(arg) == 2 { + // 应用列表 value["count"] = kit.Int(value["count"]) + 1 kit.Fetch(kit.Value(value, "extra.tool"), func(index int, value map[string]interface{}) { m.Push("river", arg[0]) @@ -1565,7 +1585,6 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", m.Push("node", value["pod"]) m.Push("group", value["ctx"]) m.Push("index", value["cmd"]) - m.Push("args", value["args"]) msg := m.Cmd(m.Space(value["pod"]), ice.CTX_COMMAND, value["ctx"], value["cmd"]) @@ -1577,47 +1596,25 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", break } + // 执行命令 meta := kit.Value(value, kit.Format("extra.tool.%s", arg[2])).(map[string]interface{}) + if meta["single"] == "yes" { + arg = append(arg[:3], kit.Simple(kit.UnMarshal(kit.Format(meta["args"])))...) + for i := len(arg) - 1; i >= 0; i-- { + if arg[i] != "" { + break + } + arg = arg[:i] + } + } cmds := kit.Simple(m.Space(meta["pod"]), kit.Keys(meta["ctx"], meta["cmd"]), arg[3:]) m.Cmdy(cmds).Option("cmds", cmds) - - case "action": - if len(arg) == 1 { - m.Push("_output", "redirect") - m.Echo("/share/%s/", arg[0]) - break - } - - if arg[1] == "" { - http.ServeFile(m.W, m.R, "usr/volcanos/share.html") - break - } - - meta := kit.Value(value, "extra").(map[string]interface{}) - if len(arg) == 2 { - m.Push("river", arg[0]) - m.Push("storm", arg[1]) - m.Push("action", "0") - - msg := m.Cmd(m.Space(meta["pod"]), ice.CTX_COMMAND, meta["ctx"], meta["cmd"]) - m.Push("name", meta["cmd"]) - m.Push("help", kit.Select(msg.Append("help"), kit.Format(meta["help"]))) - m.Push("inputs", msg.Append("list")) - m.Push("feature", msg.Append("meta")) - break - } - - cmds := kit.Simple(m.Space(meta["pod"]), kit.Keys(meta["ctx"], meta["cmd"]), arg[3:]) - m.Cmdy(cmds).Option("cmds", cmds) + m.Option("title", value["name"]) case "active": m.Push("_output", "qrcode") m.Echo(kit.Format(value)) - case "qrcode": - m.Push("_output", "qrcode") - m.Echo("%s", value["text"]) - default: if m.Cmdy(ice.WEB_STORY, "index", value["data"]); m.Append("file") != "" { m.Push("_output", "file") diff --git a/base/yac/yac.go b/base/yac/yac.go index c4cd95c5..17b431ae 100644 --- a/base/yac/yac.go +++ b/base/yac/yac.go @@ -8,11 +8,6 @@ var Index = &ice.Context{Name: "yac", Help: "语法模块", Caches: map[string]*ice.Cache{}, Configs: map[string]*ice.Config{}, Commands: map[string]*ice.Command{ - 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) { - }}, - "hi": {Name: "hi", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Echo("hello %s world", c.Name) }}, diff --git a/conf.go b/conf.go index 80d69b84..01bb4ca5 100644 --- a/conf.go +++ b/conf.go @@ -6,18 +6,11 @@ const ( // ICE ICE_EXIT = "_exit" ICE_DATE = "2006-01-02" ICE_TIME = "2006-01-02 15:04:05" -) -const ( // CTX - CTX_STATUS = "status" - CTX_STREAM = "stream" - CTX_FOLLOW = "follow" - CTX_CONFIG = "config" - CTX_COMMAND = "command" - CTX_CONTEXT = "context" -) -const ( // CLI - CLI_RUNTIME = "runtime" - CLI_SYSTEM = "system" + + ICE_BEGIN = "begin" + ICE_START = "start" + ICE_SERVE = "serve" + ICE_CLOSE = "close" ) const ( // MSG MSG_DETAIL = "detail" @@ -25,11 +18,11 @@ const ( // MSG MSG_APPEND = "append" MSG_RESULT = "result" - MSG_ACTION = "_action" - MSG_SOURCE = "_source" MSG_TARGET = "_target" + MSG_ACTION = "_action" MSG_HANDLE = "_handle" + MSG_STDOUT = "_stdout" MSG_PROMPT = "_prompt" MSG_ALIAS = "_alias" @@ -44,6 +37,18 @@ const ( // MSG MSG_RIVER = "sess.river" MSG_STORM = "sess.storm" ) +const ( // CTX + CTX_STATUS = "status" + CTX_STREAM = "stream" + CTX_FOLLOW = "follow" + CTX_CONFIG = "config" + CTX_COMMAND = "command" + CTX_CONTEXT = "context" +) +const ( // CLI + CLI_RUNTIME = "runtime" + CLI_SYSTEM = "system" +) const ( // AAA AAA_ROLE = "role" AAA_USER = "user" @@ -60,10 +65,12 @@ const ( // WEB WEB_SERVE = "serve" WEB_SPACE = "space" WEB_DREAM = "dream" + WEB_FAVOR = "favor" WEB_CACHE = "cache" WEB_STORY = "story" WEB_SHARE = "share" + WEB_ROUTE = "route" WEB_PROXY = "proxy" WEB_GROUP = "group" @@ -77,9 +84,12 @@ const ( // WEB const ( // LOG LOG_ENABLE = "enable" LOG_IMPORT = "import" - LOG_MODIFY = "modify" LOG_CREATE = "create" LOG_INSERT = "insert" + LOG_SELECT = "select" + LOG_MODIFY = "modify" + LOG_DELETE = "delete" + LOG_REMOVE = "remove" LOG_EXPORT = "export" LOG_LISTEN = "listen" @@ -114,7 +124,9 @@ const ( // GDB DREAM_CLOSE = "dream.close" USER_CREATE = "user.create" + CHAT_CREATE = "chat.create" MISS_CREATE = "miss.create" + MIND_CREATE = "mind.create" ) const ( // MDB MDB_REDIS = "redis" @@ -144,11 +156,11 @@ const ( // CHAT ) const ( // TYPE TYPE_SPACE = "space" + TYPE_STORY = "story" TYPE_RIVER = "river" TYPE_STORM = "storm" TYPE_DRIVE = "drive" - TYPE_STORY = "story" TYPE_SHELL = "shell" TYPE_VIMRC = "vimrc" TYPE_TABLE = "table" @@ -159,7 +171,6 @@ const ( // FAVOR FAVOR_CHAT = "chat.init" FAVOR_TMUX = "tmux.init" FAVOR_START = "favor.start" - FAVOR_MISS = "miss" ) const ( // STORY STORY_CATCH = "catch" @@ -176,9 +187,9 @@ const ( // STORY ) var Alias = map[string]string{ - CTX_CONFIG: "ctx.config", - CTX_COMMAND: "ctx.command", CTX_CONTEXT: "ctx.context", + CTX_COMMAND: "ctx.command", + CTX_CONFIG: "ctx.config", CLI_RUNTIME: "cli.runtime", CLI_SYSTEM: "cli.system", @@ -191,10 +202,12 @@ var Alias = map[string]string{ WEB_SERVE: "web.serve", WEB_SPACE: "web.space", WEB_DREAM: "web.dream", + WEB_FAVOR: "web.favor", WEB_CACHE: "web.cache", WEB_STORY: "web.story", WEB_SHARE: "web.share", + WEB_ROUTE: "web.route", WEB_PROXY: "web.proxy", WEB_GROUP: "web.group", diff --git a/core/chat/chat.go b/core/chat/chat.go index 18eecaab..24f917fc 100644 --- a/core/chat/chat.go +++ b/core/chat/chat.go @@ -10,83 +10,143 @@ import ( var Index = &ice.Context{Name: "chat", Help: "聊天中心", Caches: map[string]*ice.Cache{}, Configs: map[string]*ice.Config{ - ice.CHAT_RIVER: {Name: "river", Help: "群组", Value: kit.Data()}, + ice.CHAT_RIVER: {Name: "river", Help: "群组", Value: kit.Data( + "template", kit.Dict("root", []interface{}{ + []interface{}{"storm", "mall", "mall"}, + []interface{}{"field", "asset", "web.mall"}, + []interface{}{"field", "bonus", "web.mall"}, + []interface{}{"field", "trans", "web.mall"}, + []interface{}{"field", "spend", "web.mall"}, + + []interface{}{"storm", "team", "team"}, + []interface{}{"field", "miss", "web.team"}, + []interface{}{"field", "task", "web.team"}, + []interface{}{"field", "stat", "web.team"}, + []interface{}{"field", "plan", "web.team"}, + + []interface{}{"storm", "wiki", "wiki"}, + []interface{}{"field", "draw", "web.wiki"}, + []interface{}{"field", "word", "web.wiki"}, + []interface{}{"field", "data", "web.wiki"}, + []interface{}{"field", "feel", "web.wiki"}, + []interface{}{"field", "walk", "web.wiki"}, + + []interface{}{"storm", "code", "code"}, + []interface{}{"field", "buffer", "web.code.tmux"}, + []interface{}{"field", "session", "web.code.tmux"}, + []interface{}{"field", "image", "web.code.docker"}, + []interface{}{"field", "container", "web.code.docker"}, + []interface{}{"field", "command", "web.code.docker"}, + []interface{}{"field", "repos", "web.code.git"}, + []interface{}{"field", "total", "web.code.git"}, + []interface{}{"field", "branch", "web.code.git"}, + []interface{}{"field", "status", "web.code.git"}, + + []interface{}{"storm", "root"}, + []interface{}{"field", "spide"}, + []interface{}{"field", "space"}, + []interface{}{"field", "dream"}, + []interface{}{"field", "favor"}, + []interface{}{"field", "story"}, + []interface{}{"field", "share"}, + }, "void", []interface{}{ + []interface{}{"storm", "wiki", "wiki"}, + []interface{}{"field", "note", "web.wiki"}, + }), + "black", kit.Dict("void", []interface{}{ + []interface{}{"/river", "add"}, + []interface{}{"/river", "share"}, + []interface{}{"/river", "rename"}, + []interface{}{"/river", "remove"}, + []interface{}{"/storm", "remove"}, + []interface{}{"/storm", "rename"}, + []interface{}{"/storm", "share"}, + []interface{}{"/storm", "add"}, + }), + "white", kit.Dict("void", []interface{}{ + []interface{}{"/river"}, + []interface{}{"/storm"}, + []interface{}{"/action"}, + []interface{}{"web.wiki.note"}, + }), + "fe", "volcanos", + )}, }, Commands: map[string]*ice.Command{ ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Cap(ice.CTX_STATUS, "start") - m.Cap(ice.CTX_STREAM, "volcanos") - m.Watch(ice.SYSTEM_INIT, "web.chat.init") - m.Watch(ice.USER_CREATE, "web.chat./tutor", "init") - m.Cmd(ice.CTX_CONFIG, "load", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json")) + m.Watch(ice.USER_CREATE, m.Prefix(ice.WEB_LOGIN), "init") + m.Watch(ice.SYSTEM_INIT, m.Prefix("init")) + m.Load() }}, ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Cmd(ice.CTX_CONFIG, "save", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json"), kit.Keys(m.Cap(ice.CTX_FOLLOW), "river")) + m.Save("river") }}, "init": {Name: "init", Help: "初始化", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if len(m.Confm(ice.CHAT_RIVER, "hash")) == 0 { - // 系统群组 if m.Richs(ice.WEB_FAVOR, nil, "river.root", nil) == nil { - m.Cmd(ice.WEB_FAVOR, "river.root", "storm", "mall", "mall") - m.Cmd(ice.WEB_FAVOR, "river.root", "field", "asset", "web.mall") - m.Cmd(ice.WEB_FAVOR, "river.root", "field", "bonus", "web.mall") - m.Cmd(ice.WEB_FAVOR, "river.root", "field", "trans", "web.mall") - m.Cmd(ice.WEB_FAVOR, "river.root", "field", "spend", "web.mall") - - m.Cmd(ice.WEB_FAVOR, "river.root", "storm", "team", "team") - m.Cmd(ice.WEB_FAVOR, "river.root", "field", "miss", "web.team") - m.Cmd(ice.WEB_FAVOR, "river.root", "field", "task", "web.team") - m.Cmd(ice.WEB_FAVOR, "river.root", "field", "stat", "web.team") - m.Cmd(ice.WEB_FAVOR, "river.root", "field", "plan", "web.team") - - m.Cmd(ice.WEB_FAVOR, "river.root", "storm", "wiki", "wiki") - m.Cmd(ice.WEB_FAVOR, "river.root", "field", "mind", "web.wiki") - m.Cmd(ice.WEB_FAVOR, "river.root", "field", "word", "web.wiki") - m.Cmd(ice.WEB_FAVOR, "river.root", "field", "data", "web.wiki") - m.Cmd(ice.WEB_FAVOR, "river.root", "field", "feel", "web.wiki") - m.Cmd(ice.WEB_FAVOR, "river.root", "field", "walk", "web.wiki") - - m.Cmd(ice.WEB_FAVOR, "river.root", "storm", "code", "code") - m.Cmd(ice.WEB_FAVOR, "river.root", "field", "buffer", "web.code.tmux") - m.Cmd(ice.WEB_FAVOR, "river.root", "field", "session", "web.code.tmux") - m.Cmd(ice.WEB_FAVOR, "river.root", "field", "image", "web.code.docker") - m.Cmd(ice.WEB_FAVOR, "river.root", "field", "container", "web.code.docker") - m.Cmd(ice.WEB_FAVOR, "river.root", "field", "command", "web.code.docker") - m.Cmd(ice.WEB_FAVOR, "river.root", "field", "repos", "web.code.git") - m.Cmd(ice.WEB_FAVOR, "river.root", "field", "total", "web.code.git") - m.Cmd(ice.WEB_FAVOR, "river.root", "field", "branch", "web.code.git") - m.Cmd(ice.WEB_FAVOR, "river.root", "field", "status", "web.code.git") - - m.Cmd(ice.WEB_FAVOR, "river.root", "storm", "root") - m.Cmd(ice.WEB_FAVOR, "river.root", "field", "spide") - m.Cmd(ice.WEB_FAVOR, "river.root", "field", "space") - m.Cmd(ice.WEB_FAVOR, "river.root", "field", "dream") - m.Cmd(ice.WEB_FAVOR, "river.root", "field", "favor") - m.Cmd(ice.WEB_FAVOR, "river.root", "field", "story") - m.Cmd(ice.WEB_FAVOR, "river.root", "field", "share") + // 系统群组 + kit.Fetch(m.Confv(ice.CHAT_RIVER, "meta.template.root"), func(index int, value interface{}) { + m.Cmd(ice.WEB_FAVOR, "river.root", value) + }) + // 默认群组 + kit.Fetch(m.Confv(ice.CHAT_RIVER, "meta.template.void"), func(index int, value interface{}) { + m.Cmd(ice.WEB_FAVOR, "river.void", value) + }) + // 黑名单 + kit.Fetch(m.Confv(ice.CHAT_RIVER, "meta.black.void"), func(index int, value interface{}) { + m.Cmd(ice.AAA_ROLE, "black", ice.ROLE_VOID, "enable", value) + }) + // 白名单 + kit.Fetch(m.Confv(ice.CHAT_RIVER, "meta.white.void"), func(index int, value interface{}) { + m.Cmd(ice.AAA_ROLE, "white", ice.ROLE_VOID, "enable", value) + }) } // 用户权限 - m.Cmd(ice.AAA_ROLE, "white", ice.ROLE_VOID, "enable", "/river") - m.Cmd(ice.AAA_ROLE, "white", ice.ROLE_VOID, "enable", "/storm") - m.Cmd(ice.AAA_ROLE, "black", ice.ROLE_VOID, "enable", "/storm", "rename") - m.Cmd(ice.AAA_ROLE, "black", ice.ROLE_VOID, "enable", "/storm", "remove") - - m.Cmd(ice.AAA_ROLE, "white", ice.ROLE_VOID, "enable", "/action") - m.Cmd(ice.AAA_ROLE, "white", ice.ROLE_VOID, "enable", "dream") - m.Cmd(ice.AAA_ROLE, "black", ice.ROLE_VOID, "enable", "dream.停止") - m.Cmd(ice.AAA_USER, "first", m.Conf(ice.CLI_RUNTIME, "boot.username")) } + // 前端框架 + m.Cmd("web.code.git.check", m.Conf(ice.CHAT_RIVER, "meta.fe")) + m.Cap(ice.CTX_STREAM, m.Conf(ice.CHAT_RIVER, "meta.fe")) + m.Cap(ice.CTX_STATUS, "start") }}, - 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 len(arg) > 0 { switch arg[0] { case "login": // 用户登录 m.Option(ice.MSG_SESSID, web.Cookie(m, m.Cmdx(ice.AAA_USER, "login", m.Option(ice.MSG_USERNAME, arg[1]), arg[2]))) + + case "init": + // 用户创建 + m.Richs(ice.AAA_USER, nil, arg[1], func(key string, value map[string]interface{}) { + m.Option(ice.MSG_USERNAME, value["username"]) + m.Option(ice.MSG_USERROLE, m.Cmdx(ice.AAA_ROLE, "check", value["username"])) + + name := kit.Select(arg[1], value["nickname"]) + "@" + m.Conf(ice.CLI_RUNTIME, "boot.hostname") + if len(arg[1]) > 8 { + name = kit.Select(arg[1][:8], value["nickname"]) + "@" + m.Conf(ice.CLI_RUNTIME, "boot.hostname") + } + + // 创建群组 + storm, river := "", m.Option(ice.MSG_RIVER, m.Cmdx("/ocean", "spawn", name, m.Option(ice.MSG_USERNAME))) + + // 创建应用 + m.Option("cache.limit", "100") + m.Richs(ice.WEB_FAVOR, nil, kit.Keys("river", m.Option(ice.MSG_USERROLE)), func(key string, value map[string]interface{}) { + m.Grows(ice.WEB_FAVOR, kit.Keys("hash", key), "", "", func(index int, value map[string]interface{}) { + switch value["type"] { + case "storm": + storm = m.Option(ice.MSG_STORM, m.Cmdx("/steam", river, "spawn", value["name"])) + case "field": + m.Cmd("/storm", river, storm, "add", "", kit.Select("", value["text"]), value["name"], "") + } + }) + }) + }) + default: // 用户群组 m.Richs(ice.CHAT_RIVER, nil, arg[0], func(value map[string]interface{}) { @@ -116,33 +176,14 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心", m.Option(ice.MSG_USERURL, "") m.Push("_output", "status") m.Set("result").Echo("403") + return } }}, "/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) { - switch arg[0] { - case "init": - m.Richs(ice.AAA_USER, nil, arg[1], func(key string, value map[string]interface{}) { - m.Option(ice.MSG_USERNAME, value["username"]) - m.Option(ice.MSG_USERROLE, m.Cmdx(ice.AAA_ROLE, "check", value["username"])) - storm, river := "", m.Option(ice.MSG_RIVER, m.Cmdx("/ocean", "spawn", kit.Select(arg[1], value["nickname"])+"@"+m.Conf(ice.CLI_RUNTIME, "boot.hostname"), m.Option(ice.MSG_USERNAME))) - m.Richs(ice.WEB_FAVOR, nil, kit.Keys("river", m.Option(ice.MSG_USERROLE)), func(key string, value map[string]interface{}) { - m.Option("cache.limit", "100") - m.Grows(ice.WEB_FAVOR, kit.Keys("hash", key), "", "", func(index int, value map[string]interface{}) { - switch value["type"] { - case "storm": - storm = m.Option(ice.MSG_STORM, m.Cmdx("/steam", river, "spawn", value["name"])) - case "field": - m.Cmd("/storm", river, storm, "add", "", kit.Select("", value["text"]), value["name"], "") - } - }) - }) - }) - } - }}, - "/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) {}}, + "/debug": {Name: "/debug", 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) {}}, "/favor": {Name: "/favor", Help: "收藏", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Hand = false if msg := m.Cmd(arg); !msg.Hand { @@ -158,8 +199,33 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心", m.Push("nickname", value["nickname"]) }) m.Echo(m.Option(ice.MSG_USERNAME)) + case "login": m.Echo(m.Option(ice.MSG_SESSID)) + + case "share": + switch arg[1] { + case "river": + case "storm": + case "action": + if m.Option("index") != "" { + arg = append(arg, "tool.0.pod", m.Option("node")) + arg = append(arg, "tool.0.ctx", m.Option("group")) + arg = append(arg, "tool.0.cmd", m.Option("index")) + arg = append(arg, "tool.0.args", m.Option("args")) + arg = append(arg, "tool.0.single", "yes") + } else { + m.Cmd("/action", arg[5], arg[7]).Table(func(index int, value map[string]string, head []string) { + arg = append(arg, kit.Format("tool.%d.pod", index), value["node"]) + arg = append(arg, kit.Format("tool.%d.ctx", index), value["group"]) + arg = append(arg, kit.Format("tool.%d.cmd", index), value["index"]) + arg = append(arg, kit.Format("tool.%d.args", index), value["args"]) + }) + } + default: + return + } + m.Cmdy(ice.WEB_SHARE, "add", arg[1], arg[2], arg[3], arg[4:]) } }}, @@ -180,7 +246,8 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心", "user", kit.Data(kit.MDB_SHORT, "username"), "tool", kit.Data(), )) - m.Log("create", "river: %v name: %v", river, arg[1]) + m.Log(ice.LOG_CREATE, "river: %v name: %v", river, arg[1]) + // 添加用户 m.Cmd("/river", river, "add", arg[2:]) m.Echo(river) } @@ -200,14 +267,33 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心", m.Push(key, value["meta"], []string{kit.MDB_KEY, kit.MDB_NAME}) }) default: + if !m.Right(cmd, arg[1]) { + // 没有权限 + m.Push("_output", "status") + m.Set("result").Echo("403") + break + } + switch arg[1] { case "add": m.Rich(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0], "user"), kit.Data("username", m.Conf(ice.CLI_RUNTIME, "boot.username"))) // 添加用户 for _, v := range arg[2:] { user := m.Rich(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0], "user"), kit.Data("username", v)) - m.Log("insert", "river: %s user: %s name: %s", arg[0], user, v) + m.Log(ice.LOG_INSERT, "river: %s user: %s name: %s", arg[0], user, v) } + case "rename": + // 重命名群组 + old := m.Conf(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0], kit.MDB_META, kit.MDB_NAME)) + m.Log(ice.LOG_MODIFY, "river: %s %s->%s", arg[0], old, arg[2]) + m.Conf(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0], kit.MDB_META, kit.MDB_NAME), arg[2]) + + case "remove": + // 删除群组 + m.Richs(ice.CHAT_RIVER, nil, arg[0], func(value map[string]interface{}) { + m.Log(ice.LOG_REMOVE, "river: %s value: %s", arg[0], kit.Format(value)) + }) + m.Conf(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0]), "") } } }}, @@ -221,6 +307,20 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心", m.Sort(kit.MDB_NAME) return } + if len(arg) == 2 { + // 应用详情 + m.Richs(ice.CHAT_RIVER, prefix, arg[1], func(key string, value map[string]interface{}) { + m.Push(key, value["meta"], []string{kit.MDB_KEY, kit.MDB_NAME}) + }) + return + } + + if !m.Right(cmd, arg[2]) { + // 没有权限 + m.Push("_output", "status") + m.Set("result").Echo("403") + return + } switch arg[2] { case "add": @@ -229,21 +329,19 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心", id := m.Grow(ice.CHAT_RIVER, kit.Keys(prefix, kit.MDB_HASH, arg[1]), kit.Data( "pod", arg[i], "ctx", arg[i+1], "cmd", arg[i+2], "help", arg[i+3], )) - m.Log("insert", "storm: %s %d: %v", arg[1], id, arg[i:i+4]) + m.Log(ice.LOG_INSERT, "storm: %s %d: %v", arg[1], id, arg[i:i+4]) } - case "share": - m.Cmdy(ice.WEB_SHARE, "add", arg[3:]) case "rename": // 重命名应用 old := m.Conf(ice.CHAT_RIVER, 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.Log(ice.LOG_MODIFY, "storm: %s %s->%s", arg[1], old, arg[3]) m.Conf(ice.CHAT_RIVER, kit.Keys(prefix, kit.MDB_HASH, arg[1], kit.MDB_META, kit.MDB_NAME), arg[3]) case "remove": // 删除应用 m.Richs(ice.CHAT_RIVER, kit.Keys(prefix), arg[1], func(value map[string]interface{}) { - m.Log("remove", "storm: %s value: %s", arg[1], kit.Format(value)) + m.Log(ice.LOG_REMOVE, "storm: %s value: %s", arg[1], kit.Format(value)) }) m.Conf(ice.CHAT_RIVER, kit.Keys(prefix, kit.MDB_HASH, arg[1]), "") } @@ -251,6 +349,7 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心", "/steam": {Name: "/steam", Help: "大气层", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if len(arg) < 2 { if pod := m.Option("pod"); pod != "" { + // 远程命令 m.Option("pod", "") list := []string{} m.Cmdy(ice.WEB_SPACE, pod, "web.chat./steam").Table(func(index int, value map[string]string, head []string) { @@ -259,6 +358,7 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心", m.Append("name", list) return } + // 设备列表 m.Richs(ice.WEB_SPACE, nil, "*", func(key string, value map[string]interface{}) { m.Push(key, value, []string{"type", "name", "user"}) @@ -272,11 +372,13 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心", storm := m.Rich(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0], "tool"), kit.Dict( kit.MDB_META, kit.Dict(kit.MDB_NAME, arg[2]), )) - m.Log("create", "storm: %s name: %v", storm, arg[2]) + m.Log(ice.LOG_CREATE, "storm: %s name: %v", storm, arg[2]) + // 添加工具 m.Cmd("/storm", arg[0], storm, "add", arg[3:]) m.Echo(storm) case "append": + // 追加工具 m.Cmd("/storm", arg[0], arg[2], "add", arg[3:]) default: @@ -285,7 +387,12 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心", } }}, - "/action": {Name: "/action", Help: "小工具", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + "/header": {Name: "/header", Help: "菜单栏", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}}, + "/footer": {Name: "/footer", Help: "状态栏", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}}, + + "/target": {Name: "/target", Help: "对话框", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}}, + "/source": {Name: "/source", Help: "输入框", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}}, + "/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 { // 命令列表 @@ -299,37 +406,28 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心", m.Push("node", meta["pod"]) m.Push("group", meta["ctx"]) m.Push("index", meta["cmd"]) - m.Push("args", kit.Select("[]", kit.Format(meta["args"]))) msg := m.Cmd(m.Space(meta["pod"]), ice.CTX_COMMAND, meta["ctx"], meta["cmd"]) m.Push("name", meta["cmd"]) m.Push("help", kit.Select(msg.Append("help"), kit.Format(meta["help"]))) - m.Push("inputs", msg.Append("list")) m.Push("feature", msg.Append("meta")) + m.Push("inputs", msg.Append("list")) } }) return } switch arg[2] { - case "share": - list := []string{} - m.Grows(ice.CHAT_RIVER, prefix, "", "", func(index int, value map[string]interface{}) { - for k, v := range value["meta"].(map[string]interface{}) { - list = append(list, kit.Format("tool.%d.%v", index, k), kit.Format(v)) - } - }) - m.Cmdy(ice.WEB_SHARE, "add", "storm", arg[3], arg[4], list) - case "save": + // 保存应用 m.Conf(ice.CHAT_RIVER, kit.Keys(prefix, "list"), "") for i := 3; i < len(arg)-4; i += 5 { id := m.Grow(ice.CHAT_RIVER, kit.Keys(prefix), kit.Data( "pod", arg[i], "ctx", arg[i+1], "cmd", arg[i+2], "help", arg[i+3], "args", arg[i+4], )) - m.Log("insert", "storm: %s %d: %v", arg[1], id, arg[i:i+5]) + m.Log(ice.LOG_INSERT, "storm: %s %d: %v", arg[1], id, arg[i:i+5]) } return } @@ -338,8 +436,6 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心", cmds := []string{} m.Grows(ice.CHAT_RIVER, 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 { - cmds = kit.Simple(m.Space(meta["pod"]), kit.Keys(meta["ctx"], meta["cmd"]), arg[3:]) - // 命令补全 if len(arg) > 3 && arg[3] == "action" { switch arg[4] { @@ -347,6 +443,14 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心", // 记录位置 m.Cmdy("aaa.location", arg[5:]) return + case "share": + list := []string{} + for k, v := range meta { + list = append(list, k, kit.Format(v)) + } + // 共享命令 + m.Cmdy(ice.WEB_SHARE, "add", "action", arg[5], arg[6], list) + return case "input": switch arg[5] { case "location": @@ -354,22 +458,27 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心", m.Copy(m.Cmd("aaa.location"), "append", "name") return } - case "share": - list := []string{} - for k, v := range meta { - list = append(list, k, kit.Format(v)) - } - m.Cmdy(ice.WEB_SHARE, "add", "action", arg[5], arg[6], list) - return } } + + // 组装命令 + cmds = kit.Simple(m.Space(meta["pod"]), kit.Keys(meta["ctx"], meta["cmd"]), arg[3:]) } }) - // 执行命令 - if len(cmds) > 0 && m.Right(cmds) { - m.Cmdy(cmds).Option("cmds", cmds) + if len(cmds) == 0 { + return } + + if !m.Right(cmd, arg[2]) { + // 没有权限 + m.Push("_output", "status") + m.Set("result").Echo("403") + return + } + + // 执行命令 + m.Cmdy(cmds).Option("cmds", cmds) }}, }, } diff --git a/core/code/code.go b/core/code/code.go index 937f4c48..1d17c0e4 100644 --- a/core/code/code.go +++ b/core/code/code.go @@ -42,7 +42,8 @@ var Index = &ice.Context{Name: "code", Help: "编程中心", }, Commands: map[string]*ice.Command{ ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Cmd(ice.CTX_CONFIG, "load", "code.json") + m.Load() + m.Watch(ice.SYSTEM_INIT, "compile", "linux") m.Watch(ice.SYSTEM_INIT, "publish", "bin/ice.sh") @@ -55,7 +56,7 @@ var Index = &ice.Context{Name: "code", Help: "编程中心", } }}, ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Cmd(ice.CTX_CONFIG, "save", "code.json", "web.code.login") + m.Save("login") }}, "compile": {Name: "compile", Help: "编译", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { diff --git a/core/mall/mall.go b/core/mall/mall.go index cf1e61e2..a87e2fdd 100644 --- a/core/mall/mall.go +++ b/core/mall/mall.go @@ -28,7 +28,7 @@ var Index = &ice.Context{Name: "mall", Help: "贸易中心", }, Commands: map[string]*ice.Command{ ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Cmd(ice.CTX_CONFIG, "load", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json")) + m.Load() // m.Cmd(ice.CTX_CONFIG, "load", "mall.json") // if m.Richs(ice.WEB_SPIDE, nil, "12306", nil) == nil { @@ -36,7 +36,7 @@ var Index = &ice.Context{Name: "mall", Help: "贸易中心", // } }}, ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Cmd(ice.CTX_CONFIG, "save", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json"), kit.Keys(m.Cap(ice.CTX_FOLLOW), "asset")) + m.Save("asset") // m.Cmd(ice.CTX_CONFIG, "save", "mall.json", "web.mall.railway") }}, diff --git a/core/shy.go b/core/shy.go index ca832118..88bd58be 100644 --- a/core/shy.go +++ b/core/shy.go @@ -3,9 +3,13 @@ package shy import ( _ "github.com/shylinux/icebergs/base" - _ "github.com/shylinux/icebergs/core/chat" _ "github.com/shylinux/icebergs/core/code" - _ "github.com/shylinux/icebergs/core/mall" - _ "github.com/shylinux/icebergs/core/team" + _ "github.com/shylinux/icebergs/core/wiki" + + _ "github.com/shylinux/icebergs/core/chat" + + _ "github.com/shylinux/icebergs/core/team" + + _ "github.com/shylinux/icebergs/core/mall" ) diff --git a/core/team/team.go b/core/team/team.go index 65a180a6..c6005c66 100644 --- a/core/team/team.go +++ b/core/team/team.go @@ -11,6 +11,20 @@ import ( "time" ) +func ShowDay(m *ice.Message, day time.Time) string { + if day.Day() == 1 { + if day.Month() == 1 { + return kit.Format(`%d年`, + day.Year(), day.Month(), day.Day(), day.Year()) + } else { + return kit.Format(`%d月`, + day.Year(), day.Month(), day.Day(), day.Month()) + } + } + return kit.Format(`%d`, + day.Year(), day.Month(), day.Day(), day.Day()) +} + var Index = &ice.Context{Name: "team", Help: "团队中心", Caches: map[string]*ice.Cache{}, Configs: map[string]*ice.Config{ @@ -20,55 +34,19 @@ var Index = &ice.Context{Name: "team", Help: "团队中心", "template", kit.Dict( "day", `
{{.name}}: {{.text}}
`, "week", `
{{.name}}
`, + "month", `
{{.name}}
`, "year", `
{{.name}}: {{.text}}
`, ), )}, - - "location": {Name: "location", Help: "位置", Value: kit.Data(kit.MDB_SHORT, "name")}, }, Commands: map[string]*ice.Command{ ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Cmd(ice.CTX_CONFIG, "load", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json")) + m.Load() }}, ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Cmd(ice.CTX_CONFIG, "save", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json"), - kit.Keys(m.Cap(ice.CTX_FOLLOW), "task")) + m.Save("task") }}, - "miss": {Name: "miss zone type name text", Help: "任务", List: kit.List( - kit.MDB_INPUT, "text", "name", "zone", "action", "auto", "figure", "key", - kit.MDB_INPUT, "text", "name", "type", "figure", "key", - kit.MDB_INPUT, "text", "name", "name", "figure", "key", - kit.MDB_INPUT, "button", "name", "添加", - kit.MDB_INPUT, "textarea", "name", "text", - kit.MDB_INPUT, "text", "name", "location", "figure", "key", "cb", "location", - ), Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { - if len(arg) > 0 && arg[0] == "action" { - switch arg[1] { - case "input": - switch arg[2] { - case "type", "name": - m.Confm("task", kit.Keys("meta.word", arg[2]), func(key string, value string) { - m.Push(arg[2], key) - m.Push("count", value) - }) - m.Sort("count", "int_r") - case "zone": - m.Richs("task", nil, "*", func(key string, value map[string]interface{}) { - m.Push("zone", kit.Value(value, "meta.zone")) - m.Push("count", kit.Value(value, "meta.count")) - }) - } - return - } - } - - if len(arg) < 2 { - m.Cmdy("task", arg) - return - } - m.Cmdy("task", arg[0], "", arg[1:]) - }}, "task": {Name: "task [zone [id [type [name [text args...]]]]]", Help: "任务", Meta: kit.Dict("remote", "you"), List: kit.List( kit.MDB_INPUT, "text", "name", "zone", "action", "auto", kit.MDB_INPUT, "text", "name", "id", "action", "auto", @@ -79,7 +57,7 @@ var Index = &ice.Context{Name: "team", Help: "团队中心", switch arg[1] { case "export": // 导出数据 - m.Option("cache.limit", "10000") + m.Option("cache.limit", -2) if f, p, e := kit.Create(arg[2]); m.Assert(e) { defer f.Close() @@ -106,7 +84,6 @@ var Index = &ice.Context{Name: "team", Help: "团队中心", case "import": // 导入数据 - m.Option("cache.limit", "10000") m.CSV(m.Cmdx("nfs.cat", arg[2])).Table(func(index int, data map[string]string, head []string) { item := kit.Dict("time", data["time"], "type", data["type"], "name", data["name"], "text", data["text"], "extra", kit.UnMarshal(data["extra"]), @@ -129,7 +106,7 @@ var Index = &ice.Context{Name: "team", Help: "团队中心", // 任务修改 m.Richs(cmd, nil, kit.Select(m.Option("zone"), arg, 6), func(key string, account map[string]interface{}) { m.Grows(cmd, kit.Keys("hash", key), "id", arg[5], func(index int, current map[string]interface{}) { - m.Log(ice.LOG_MODIFY, "%s: %s %s: %s->%s", key, index, kit.Value(current, arg[2]), arg[2], arg[3]) + m.Log(ice.LOG_MODIFY, "%s: %d %s: %s->%s", key, index, kit.Value(current, arg[2]), arg[2], arg[3]) kit.Value(current, arg[2], arg[3]) }) }) @@ -169,7 +146,7 @@ var Index = &ice.Context{Name: "team", Help: "团队中心", m.Log(ice.LOG_CREATE, "zone: %s", arg[0]) } - field := []string{"begin_time", "close_time", "id", "status", "type", "name", "text"} + field := []string{"begin_time", "id", "status", "type", "name", "text"} m.Richs(cmd, nil, arg[0], func(key string, value map[string]interface{}) { if len(arg) == 1 { // 任务列表 @@ -234,13 +211,13 @@ var Index = &ice.Context{Name: "team", Help: "团队中心", m.Echo("%s: %d", kit.Value(value, "meta.zone"), n) }) }}, - "plan": {Name: "plan day|week|month|year", Help: "计划", Meta: kit.Dict("display", "team/plan"), List: kit.List( - kit.MDB_INPUT, "select", "name", "scale", "value", "week", "values", []string{"day", "week", "month", "year", "long"}, "action", "auto", + "plan": {Name: "plan day|week|month|year", Help: "计划", Meta: kit.Dict("remote", "you", "display", "team/plan"), List: kit.List( + kit.MDB_INPUT, "select", "name", "scale", "value", "week", "values", []string{"day", "week", "month", "months", "year", "long"}, "action", "auto", kit.MDB_INPUT, "text", "name", "begin_time", "figure", "date", "action", "auto", kit.MDB_INPUT, "text", "name", "end_time", "figure", "date", "action", "auto", kit.MDB_INPUT, "button", "name", "查看", "action", "auto", ), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Option("cache.limit", "10000") + m.Option("cache.limit", -1) // 起始日期 first := time.Now() @@ -326,17 +303,22 @@ var Index = &ice.Context{Name: "team", Help: "团队中心", } case "month": + fallthrough + case "months": // 月计划 one := first.AddDate(0, 0, -first.Day()+1) end := last.AddDate(0, 1, -last.Day()+1) + template := m.Conf("plan", "meta.template.month") // 查询任务 + name := map[string][]string{} list := map[string][]map[string]interface{}{} m.Richs("task", nil, "*", func(key string, value map[string]interface{}) { m.Grows("task", kit.Keys("hash", key), "", "", func(index int, value map[string]interface{}) { if t, e := time.ParseInLocation(ice.ICE_TIME, kit.Format(value["begin_time"]), time.Local); e == nil { if index := t.Format("2006-01-02"); t.After(one) && t.Before(end) { list[index] = append(list[index], value) + name[index] = append(name[index], key) } } }) @@ -345,18 +327,21 @@ var Index = &ice.Context{Name: "team", Help: "团队中心", // 上月结尾 last := one.AddDate(0, 0, -int(one.Weekday())) for day := last; day.Before(one); day = day.AddDate(0, 0, 1) { - m.Push(head[int(day.Weekday())], day.Day()) + m.Push(head[int(day.Weekday())], ShowDay(m, day)) } // 本月日期 for day := one; day.Before(end); day = day.AddDate(0, 0, 1) { - note := []string{} - if day.Day() == 1 { - note = append(note, kit.Format("%d月", day.Month())) - } else { - note = append(note, kit.Format("%d", day.Day())) - } + note := []string{ShowDay(m, day)} index := day.Format("2006-01-02") + if arg[0] == "month" { + for i, v := range list[index] { + b, _ := kit.Render(kit.Format(template, name[index][i]), v) + note = append(note, string(b)) + } + m.Push(head[int(day.Weekday())], strings.Join(note, "")) + continue + } for _, v := range list[index] { note = append(note, kit.Format(`%s: %s`, v["name"], v["text"])) } @@ -366,12 +351,11 @@ var Index = &ice.Context{Name: "team", Help: "团队中心", note[0] = kit.Format(`%s%s`, note[0], "") } m.Push(head[int(day.Weekday())], note[0]) - } // 下月开头 tail := end.AddDate(0, 0, 6-int(end.Weekday())+1) for day := end; end.Weekday() != 0 && day.Before(tail); day = day.AddDate(0, 0, 1) { - m.Push(head[int(day.Weekday())], day.Day()) + m.Push(head[int(day.Weekday())], ShowDay(m, day)) } case "year": @@ -420,71 +404,92 @@ var Index = &ice.Context{Name: "team", Help: "团队中心", m.Sort("year", "int") } }}, - "stat": {Name: "stat", Help: "统计", Meta: kit.Dict(), Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { - m.Option("cache.limit", "10000") - m.Richs("task", nil, kit.Select("*", arg, 0), func(key string, value map[string]interface{}) { + "stat": {Name: "stat", Help: "统计", Meta: kit.Dict("remote", "you"), List: kit.List( + kit.MDB_INPUT, "text", "name", "begin_time", "figure", "date", "action", "auto", + kit.MDB_INPUT, "text", "name", "end_time", "figure", "date", "action", "auto", + kit.MDB_INPUT, "button", "name", "查看", "action", "auto", + ), Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { + begin_time := kit.Time(kit.Select("1990-07-30", arg, 0)) + end_time := kit.Time(kit.Select("1990-07-30", arg, 1)) + now_time := kit.Time(m.Time()) + + m.Option("cache.limit", -1) + m.Richs("task", nil, "*", func(key string, value map[string]interface{}) { stat := map[string]int{} m.Grows("task", kit.Keys("hash", key), "", "", func(index int, value map[string]interface{}) { - stat[kit.Format(value["status"])] += 1 + if len(arg) > 1 && kit.Time(kit.Format(value["begin_time"])) > end_time { + return + } + if len(arg) > 0 && kit.Time(kit.Format(value["begin_time"])) < begin_time { + return + } + + if stat[kit.Format(value["status"])] += 1; value["status"] != "prepare" { + use := kit.Time(kit.Format(value["close_time"])) - kit.Time(kit.Format(value["begin_time"])) + if value["status"] == "process" { + use = now_time - kit.Time(kit.Format(value["begin_time"])) + } + + stat["sum"] += use + if use > stat["max"] { + stat["max"] = use + } + if use < stat["min"] { + stat["min"] = use + } + } + stat["total"] += 1 }) + m.Push("zone", kit.Value(value, "meta.zone")) - for _, k := range []string{"prepare", "process", "cancel", "finish"} { + for _, k := range []string{"prepare", "process", "cancel", "finish", "total"} { m.Push(k, stat[k]) } + m.Push("sum", kit.FmtTime(int64(stat["sum"])*int64(time.Second))) + if stat["finish"] == 0 { + stat["finish"] = 1 + } + m.Push("avg", kit.FmtTime(int64(stat["sum"]/stat["finish"])*int64(time.Second))) + m.Push("min", kit.FmtTime(int64(stat["min"])*int64(time.Second))) + m.Push("max", kit.FmtTime(int64(stat["max"])*int64(time.Second))) }) }}, - - "progress": {Name: "progress", Help: "进度", Meta: kit.Dict( - "remote", "you", "display", "team/miss", - "detail", []string{"回退", "前进", "取消", "完成"}, - ), List: kit.List( - kit.MDB_INPUT, "text", "value", "", - kit.MDB_INPUT, "button", "value", "查看", "action", "auto", + "miss": {Name: "miss zone type name text", Help: "任务", Meta: kit.Dict("remote", "you"), List: kit.List( + kit.MDB_INPUT, "text", "name", "zone", "figure", "key", "action", "auto", + kit.MDB_INPUT, "text", "name", "type", "figure", "key", + kit.MDB_INPUT, "text", "name", "name", "figure", "key", + kit.MDB_INPUT, "button", "name", "添加", + kit.MDB_INPUT, "textarea", "name", "text", + kit.MDB_INPUT, "text", "name", "location", "figure", "key", "cb", "location", ), Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { - hot := kit.Select(ice.FAVOR_MISS, m.Option("hot")) - if len(arg) > 0 { - m.Richs(ice.WEB_FAVOR, nil, hot, func(key string, value map[string]interface{}) { - m.Grows(ice.WEB_FAVOR, kit.Keys("hash", key), "id", arg[0], func(index int, value map[string]interface{}) { - switch value = value["extra"].(map[string]interface{}); arg[1] { - case "前进": - if value["status"] == "准备中" { - value["begin_time"] = m.Time() - value["close_time"] = m.Time("30m") - } - if next := m.Conf(ice.APP_MISS, kit.Keys("meta.fsm", value["status"], "next")); next != "" { - value["status"] = next - kit.Value(value, "change.-2", kit.Dict("time", m.Time(), "status", next)) - } - - case "回退": - if prev := m.Conf(ice.APP_MISS, kit.Keys("meta.fsm", value["status"], "prev")); prev != "" { - value["status"] = prev - kit.Value(value, "change.-2", kit.Dict("time", m.Time(), "status", prev)) - } - - case "取消": - value["status"] = "已取消" - value["close_time"] = m.Time() - - case "完成": - value["status"] = "已完成" - value["close_time"] = m.Time() - } - }) - }) + if len(arg) > 0 && arg[0] == "action" { + switch arg[1] { + case "input": + // 输入补全 + switch arg[2] { + case "zone": + m.Richs("task", nil, "*", func(key string, value map[string]interface{}) { + m.Push("zone", kit.Value(value, "meta.zone")) + m.Push("count", kit.Value(value, "meta.count")) + }) + case "type", "name": + m.Confm("task", kit.Keys("meta.word", arg[2]), func(key string, value string) { + m.Push(arg[2], key) + m.Push("count", value) + }) + } + m.Sort("count", "int_r") + return + } } - m.Confm(ice.APP_MISS, "meta.mis", func(index int, value string) { - m.Push(value, "") - }) - m.Richs(ice.WEB_FAVOR, nil, hot, func(key string, value map[string]interface{}) { - m.Grows(ice.WEB_FAVOR, kit.Keys("hash", key), "", "", func(index int, value map[string]interface{}) { - m.Push(kit.Format(kit.Value(value, "extra.status")), - kit.Format(`%v`, - kit.Format("%s-%s\n%s", kit.Value(value, "extra.begin_time"), kit.Value(value, "extra.close_time"), value["text"]), - value["id"], value["name"])) - }) - }) + if len(arg) < 2 { + // 查询任务 + m.Cmdy("task", arg) + return + } + // 创建任务 + m.Cmdy("task", arg[0], "", arg[1:]) }}, }, } diff --git a/core/wiki/wiki.go b/core/wiki/wiki.go index 417157e1..5d5fc9bb 100644 --- a/core/wiki/wiki.go +++ b/core/wiki/wiki.go @@ -18,8 +18,7 @@ var Index = &ice.Context{Name: "wiki", Help: "文档中心", Caches: map[string]*ice.Cache{}, Configs: map[string]*ice.Config{ "note": {Name: "note", Help: "笔记", Value: kit.Data( - "temp", "var/tmp/file", - "path", "", + "path", "", "temp", "var/tmp/file", "head", "time size line path", "alias", map[string]interface{}{ "label": []interface{}{"chart", "label"}, @@ -52,11 +51,10 @@ var Index = &ice.Context{Name: "wiki", Help: "文档中心", }, Commands: map[string]*ice.Command{ ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Cmd(ice.CTX_CONFIG, "load", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json")) - + m.Load() }}, ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Cmd(ice.CTX_CONFIG, "save", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json"), kit.Keys(m.Cap(ice.CTX_FOLLOW), "feel")) + m.Save("feel") }}, "note": {Name: "note file", Help: "笔记", Meta: kit.Dict("remote", "you", "display", "inner"), List: kit.List( @@ -87,7 +85,7 @@ var Index = &ice.Context{Name: "wiki", Help: "文档中心", m.Cmdy(kit.Select("_tree", "_text", len(arg) > 0 && strings.HasSuffix(arg[0], ".md")), arg) }}, "_tree": {Name: "_tree path", Help: "文库", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Option("dir_deep", "true") + // m.Option("dir_deep", "true") m.Option("dir_reg", ".*\\.md") m.Cmdy("nfs.dir", kit.Select(m.Conf("note", "meta.path"), arg, 0), m.Conf("note", "meta.head")) }}, @@ -104,11 +102,11 @@ var Index = &ice.Context{Name: "wiki", Help: "文档中心", // 生成文章 buffer := bytes.NewBuffer([]byte{}) f := m.Target().Server().(*web.Frame) - tmpl := f.HandleCGI(m, m.Confm("note", ice.Meta("alias")), arg[0]) + tmpl := f.HandleCGI(m, m.Confm("note", "meta.alias"), arg[0]) m.Assert(tmpl.ExecuteTemplate(buffer, m.Option("filename", path.Base(arg[0])), m)) // 缓存文章 - if f, p, e := kit.Create(path.Join(m.Conf("note", ice.Meta("temp")), arg[0])); e == nil { + if f, p, e := kit.Create(path.Join(m.Conf("note", "meta.temp"), arg[0])); e == nil { defer f.Close() if n, e := f.Write(buffer.Bytes()); e == nil { m.Log("info", "save %d %v", n, p) @@ -303,9 +301,7 @@ var Index = &ice.Context{Name: "wiki", Help: "文档中心", Stack(m, cmd, 0, kit.Parse(nil, "", chain.show(m, arg[1])...)) m.Echo("") }}, - "chart": {Name: "chart label|chain|table name text [fg bg fs ls p m]", Help: "绘图", Meta: map[string]interface{}{ - "display": "inner", - }, List: kit.List( + "chart": {Name: "chart label|chain|table name text [fg bg fs ls p m]", Help: "绘图", Meta: map[string]interface{}{}, List: kit.List( kit.MDB_INPUT, "select", "value", "chain", "values", "block chain table", kit.MDB_INPUT, "text", "value", "", kit.MDB_INPUT, "button", "value", "生成", @@ -342,9 +338,9 @@ var Index = &ice.Context{Name: "wiki", Help: "文档中心", m.Option("height", chart.GetHeight()) // 生成网页 - m.Render(m.Conf("chart", ice.Meta("prefix"))) + m.Render(m.Conf("chart", "meta.prefix")) chart.Draw(m, 4, 4) - m.Render(m.Conf("chart", ice.Meta("suffix"))) + m.Render(m.Conf("chart", "meta.suffix")) }}, "draw": {Name: "draw", Help: "思维导图", Meta: kit.Dict("display", "wiki/draw"), List: kit.List( @@ -598,6 +594,19 @@ var Index = &ice.Context{Name: "wiki", Help: "文档中心", m.Option("scan_mode", "scan") m.Cmdy("ssh.scan", "some", "some", path.Join(m.Conf("word", "meta.path"), arg[0])) }}, + + "qrcode": {Name: "qrcode", Help: "扫码", Meta: kit.Dict("display", "wiki/image"), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + data := map[string]interface{}{} + for i := 0; i < len(arg)-1; i += 2 { + kit.Value(data, arg[i], arg[i+1]) + } + m.Push("_output", "qrcode") + m.Echo(kit.Format(data)) + }}, + "qrcode2": {Name: "qrcode2", Help: "扫码", Meta: kit.Dict("display", "wiki/image"), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Push("_output", "qrcode") + m.Echo(kit.MergeURL(arg[0], arg[1:])) + }}, }, } diff --git a/misc/alpha/alpha.go b/misc/alpha/alpha.go index cda7697e..c13703b8 100644 --- a/misc/alpha/alpha.go +++ b/misc/alpha/alpha.go @@ -20,10 +20,10 @@ var Index = &ice.Context{Name: "alpha", Help: "英汉词典", }, Commands: map[string]*ice.Command{ ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Cmd(ice.CTX_CONFIG, "load", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json")) + m.Load() }}, ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Cmd(ice.CTX_CONFIG, "save", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json"), kit.Keys(m.Cap(ice.CTX_FOLLOW), "alpha")) + m.Save("alpha") }}, "alpha": {Name: "alpha [load|list]", Help: "英汉词典", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { diff --git a/misc/chrome/chrome.go b/misc/chrome/chrome.go index cd7e86b0..f0df2374 100644 --- a/misc/chrome/chrome.go +++ b/misc/chrome/chrome.go @@ -15,10 +15,10 @@ var Index = &ice.Context{Name: "chrome", Help: "chrome", }, Commands: map[string]*ice.Command{ ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Cmd(ice.CTX_CONFIG, "load", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json")) + m.Load() }}, ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Cmd(ice.CTX_CONFIG, "save", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json"), kit.Keys(m.Cap(ice.CTX_FOLLOW), "history")) + m.Save("history") }}, "/crx": {Name: "/crx", Help: "/crx", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { diff --git a/misc/git/git.go b/misc/git/git.go index 9c54b382..ca3ca1a2 100644 --- a/misc/git/git.go +++ b/misc/git/git.go @@ -23,7 +23,7 @@ var Index = &ice.Context{Name: "git", Help: "代码管理", if s, e := os.Stat(".git"); e == nil && s.IsDir() { m.Rich("repos", nil, kit.Data( "name", path.Base(wd), "path", wd, "branch", "master", - "remote", strings.TrimSpace(m.Cmdx(ice.CLI_SYSTEM, "git", "remote", "get-url", "origin")), + "remote", strings.TrimSpace(m.Cmdx(ice.CLI_SYSTEM, "git", "remote", "-v")), )) } @@ -32,7 +32,7 @@ var Index = &ice.Context{Name: "git", Help: "代码管理", if s, e := os.Stat(m.Option("cmd_dir", path.Join(value["path"], ".git"))); e == nil && s.IsDir() { m.Rich("repos", nil, kit.Data( "name", value["name"], "path", value["path"], "branch", "master", - "remote", strings.TrimSpace(m.Cmdx(ice.CLI_SYSTEM, "git", "remote", "get-url", "origin")), + "remote", strings.TrimSpace(m.Cmdx(ice.CLI_SYSTEM, "git", "remote", "-v")), )) } }) @@ -42,11 +42,10 @@ var Index = &ice.Context{Name: "git", Help: "代码管理", if s, e := os.Stat(m.Option("cmd_dir", path.Join(value["path"], ".git"))); e == nil && s.IsDir() { m.Rich("repos", nil, kit.Data( "name", value["name"], "path", value["path"], "branch", "master", - "remote", strings.TrimSpace(m.Cmdx(ice.CLI_SYSTEM, "git", "remote", "get-url", "origin")), + "remote", strings.TrimSpace(m.Cmdx(ice.CLI_SYSTEM, "git", "remote", "-v")), )) } }) - m.Watch(ice.SYSTEM_INIT, "web.code.git.check", "volcanos") }}, ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}}, diff --git a/misc/input/input.go b/misc/input/input.go index fcb3d0ca..31760c77 100644 --- a/misc/input/input.go +++ b/misc/input/input.go @@ -24,11 +24,11 @@ var Index = &ice.Context{Name: "input", Help: "输入法", }, Commands: map[string]*ice.Command{ ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Cmd(ice.CTX_CONFIG, "load", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json")) + m.Load() m.Cmd("web.code.git.repos", m.Conf("input", "meta.repos")) }}, ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Cmd(ice.CTX_CONFIG, "save", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json"), kit.Keys(m.Cap(ice.CTX_FOLLOW), "input")) + m.Save("input") }}, "load": {Name: "load file [name]", Help: "加载词库", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { diff --git a/misc/lark/lark.go b/misc/lark/lark.go index 72d2a46a..c3665144 100644 --- a/misc/lark/lark.go +++ b/misc/lark/lark.go @@ -56,15 +56,16 @@ var Index = &ice.Context{Name: "lark", Help: "lark", }, Commands: map[string]*ice.Command{ ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Cmd(ice.CTX_CONFIG, "load", "lark.json") + m.Load() m.Confm("app", "meta.userrole", func(key string, value string) { m.Cmd(ice.AAA_ROLE, value, key) }) m.Cmd(ice.WEB_SPIDE, "add", "lark", m.Conf("app", "meta.lark")) }}, ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Cmd(ice.CTX_CONFIG, "save", "lark.json", "web.chat.lark.app") + m.Save("app") }}, + "app": {Name: "app login|token bot", Help: "应用", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { if len(arg) == 0 { m.Richs("app", nil, "*", func(key string, value map[string]interface{}) { diff --git a/misc/mp/mp.go b/misc/mp/mp.go index c6e74632..118b6193 100644 --- a/misc/mp/mp.go +++ b/misc/mp/mp.go @@ -20,14 +20,14 @@ var Index = &ice.Context{Name: "mp", Help: "小程序", }, Commands: map[string]*ice.Command{ ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Cmd(ice.CTX_CONFIG, "load", "mp.json") + m.Load() m.Confm("login", "meta.userrole", func(key string, value string) { m.Cmd(ice.AAA_ROLE, value, key) }) m.Cmd(ice.WEB_SPIDE, "add", "weixin", m.Conf("login", "meta.weixin")) }}, ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Cmd(ice.CTX_CONFIG, "save", "mp.json", "web.chat.mp.login") + m.Save("login") }}, "/login/": {Name: "/login/", Help: "登录", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { switch arg[0] { @@ -77,8 +77,6 @@ var Index = &ice.Context{Name: "mp", Help: "小程序", m.Echo(m.Option("scan")).Push("_output", "qrcode") case "auth": - m.Log("fuck", "what %v", m.Option(ice.MSG_USERNAME)) - m.Log("fuck", "what %v", m.Option(ice.MSG_SESSID)) if !m.Options(ice.MSG_USERNAME) || !m.Options(ice.MSG_SESSID) { m.Echo("401").Push("_output", "status") break diff --git a/misc/pi/pi.go b/misc/pi/pi.go index b7077374..0fc30e58 100644 --- a/misc/pi/pi.go +++ b/misc/pi/pi.go @@ -14,9 +14,6 @@ var Index = &ice.Context{Name: "pi", Help: "pi", "pi": {Name: "pi", Help: "pi", Value: kit.Data(kit.MDB_SHORT, "name")}, }, Commands: map[string]*ice.Command{ - 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) {}}, - "GPIO": {Name: "GPIO", Help: "GPIO", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { p := kit.Format("/sys/class/gpio/gpio%s", arg[0]) if _, e := os.Stat(p); e != nil { diff --git a/misc/shy.go b/misc/shy.go index 07533dcd..70443071 100644 --- a/misc/shy.go +++ b/misc/shy.go @@ -1,7 +1,9 @@ package misc import ( + _ "github.com/shylinux/icebergs/misc/chrome" _ "github.com/shylinux/icebergs/misc/docker" _ "github.com/shylinux/icebergs/misc/git" + _ "github.com/shylinux/icebergs/misc/input" _ "github.com/shylinux/icebergs/misc/tmux" ) diff --git a/misc/wx/wx.go b/misc/wx/wx.go index 702198ed..2f6ba964 100644 --- a/misc/wx/wx.go +++ b/misc/wx/wx.go @@ -1,56 +1,167 @@ package wx import ( + "crypto/sha1" + "encoding/hex" + "encoding/xml" "github.com/shylinux/icebergs" + "github.com/shylinux/icebergs/base/web" "github.com/shylinux/icebergs/core/chat" "github.com/shylinux/toolkits" - "regexp" + "sort" + "strings" ) -var Index = &ice.Context{Name: "wx", Help: "wx", +func reply(m *ice.Message) { + m.Push("_output", "result") + m.Render(m.Conf("login", "meta.template.text")) +} +func action(m *ice.Message) { + m.Push("_output", "result") + + m.Echo(` + + +%s + +`, m.Option("FromUserName"), m.Option("ToUserName"), m.Option("CreateTime")) + + count := 0 + m.Table(func(index int, value map[string]string, head []string) { + count++ + }) + m.Echo(`%d +`, count) + + m.Echo(` +`) + m.Table(func(index int, value map[string]string, head []string) { + m.Echo(` + <![CDATA[%s]]> + + + + +`, value["name"], value["text"], value["view"], value["link"]) + }) + + m.Echo(` +`) + m.Echo(` +`) + m.Info("what %v", m.Result()) +} + +var Index = &ice.Context{Name: "wx", Help: "公众号", Caches: map[string]*ice.Cache{}, Configs: map[string]*ice.Config{ - "login": {Name: "login", Help: "认证", Value: kit.Data("wechat", "https://login.weixin.qq.com")}, + "login": {Name: "login", Help: "认证", Value: kit.Data( + "auth", "/sns/jscode2session?grant_type=authorization_code", + "weixin", "https://api.weixin.qq.com", + "appid", "", "appmm", "", "token", "", + "userrole", kit.Dict(), + "template", kit.Dict( + "text", ` + + + {{.Option "CreateTime"}} + + + `, + ), + "menu", []interface{}{ + kit.Dict("name", "home", "text", "主页", "view", "https://shylinux.com/static/volcanos/favicon.ico", "link", "https://shylinux.com"), + kit.Dict("name", "sub", "text", "工具", "view", "https://shylinux.com/static/volcanos/favicon.ico", "link", "https://shylinux.com"), + }, + )}, }, Commands: map[string]*ice.Command{ ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Cmd(ice.WEB_SPIDE, "add", "wechat", m.Conf("login", "meta.wechat")) + m.Load() + m.Confm("login", "meta.userrole", func(key string, value string) { + m.Cmd(ice.AAA_ROLE, value, key) + }) + }}, + ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Save("login") }}, - ice.ICE_EXIT: {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) { - what := m.Cmdx(ice.WEB_SPIDE, "wechat", "raw", "GET", "/jslogin", "appid", "wx782c26e4c19acffb", "fun", "new") - // what := `window.QRLogin.code = 200; window.QRLogin.uuid = "gZUohppbCw==";` - reg, _ := regexp.Compile(`window.QRLogin.code = (\d+); window.QRLogin.uuid = "(\S+?)";`) - if list := reg.FindStringSubmatch(what); list[1] == "200" { - m.Richs(ice.WEB_SPIDE, nil, "wechat", func(key string, value map[string]interface{}) { - if qrcode := kit.Format("%s/l/%s", kit.Value(value, "client.url"), list[2]); m.R == nil { - m.Cmdy("cli.python", "qrcode", qrcode) - } else { - m.Push("_output", "qrcode").Echo(qrcode) - } - - m.Gos(m, func(m *ice.Message) { - reg, _ := regexp.Compile(`window.code=(\d+)`) - for i := 0; i < 1000; i++ { - what := m.Cmdx(ice.WEB_SPIDE, "wechat", "raw", "GET", "/cgi-bin/mmwebwx-bin/login", "loginicon", "true", "uuid", list[2], "tip", "1", "r", kit.Int(m.Time("stamp"))/1579, "_", m.Time("stamp")) - // window.code=200; window.redirect_uri="https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket=A7_l6ng7wSjNbs7-qD3ArIRJ@qrticket_0&uuid=Ia1-kbZ0wA==&lang=zh_CN&scan=1579005657"; - if list := reg.FindStringSubmatch(what); list[1] == "200" { - reg, _ := regexp.Compile(`window.redirect_uri="(\S+)";`) - if list := reg.FindStringSubmatch(what); len(list) > 1 { - what := m.Cmdx(ice.WEB_SPIDE, "wechat", "raw", "GET", list[1]) - m.Info("what %s", what) - break - } - } - m.Info("wait scan %v", list) - m.Sleep("1s") - } - }) - }) + "/login/": {Name: "/login/", Help: "认证", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + check := []string{m.Conf("login", "meta.token"), m.Option("timestamp"), m.Option("nonce")} + sort.Strings(check) + b := sha1.Sum([]byte(strings.Join(check, ""))) + if m.Warn(m.Option("signature") != hex.EncodeToString(b[:]), "error") { + // 验证失败 + return } + + if m.Option("echostr") != "" { + m.Push("_output", "result") + m.Echo(m.Option("echostr")) + // 绑定验证 + return + } + + // 解析数据 + data := struct { + ToUserName string + FromUserName string + CreateTime int + MsgType string + Content string + MsgId int64 + }{} + xml.NewDecoder(m.R.Body).Decode(&data) + m.Option("ToUserName", data.ToUserName) + m.Option("FromUserName", data.FromUserName) + m.Option("CreateTime", data.CreateTime) + + m.Option(ice.MSG_USERNAME, data.FromUserName) + if m.Richs(ice.AAA_USER, nil, m.Option(ice.MSG_USERNAME), nil) == nil { + // 创建用户 + m.Rich(ice.AAA_USER, nil, kit.Dict( + "username", m.Option(ice.MSG_USERNAME), + "usernode", m.Conf(ice.CLI_RUNTIME, "boot.hostname"), + )) + m.Event(ice.USER_CREATE, m.Option(ice.MSG_USERNAME)) + } + + m.Option(ice.MSG_USERROLE, m.Cmdx(ice.AAA_ROLE, "check", data.FromUserName)) + m.Info("%s: %s", m.Option(ice.MSG_USERROLE), m.Option(ice.MSG_USERNAME)) + + m.Option(ice.MSG_SESSID, m.Cmdx(ice.AAA_SESS, "create", m.Option(ice.MSG_USERNAME), m.Option(ice.MSG_USERROLE))) + m.Info("sessid: %s", m.Option(ice.MSG_SESSID)) + + switch m.Option("MsgType", data.MsgType) { + case "text": + if cmds := kit.Split(data.Content); !m.Right(cmds) { + action(m.Cmdy("menu")) + } else { + switch cmds[0] { + case "menu": + action(m.Cmdy("menu")) + default: + msg := m.Cmd(cmds) + if m.Hand = false; !msg.Hand { + msg = m.Cmd(ice.CLI_SYSTEM, cmds) + } + if msg.Result() == "" { + msg.Table() + } + reply(m.Push("reply", msg.Result())) + } + } + } + + }}, + + "menu": {Name: "menu", Help: "菜单", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + kit.Fetch(m.Confv("login", "meta.menu"), func(index int, value map[string]interface{}) { + m.Push("", value, []string{"name", "text", "view"}) + m.Push("link", kit.MergeURL(kit.Format(value["link"]), ice.MSG_SESSID, m.Option(ice.MSG_SESSID))) + }) }}, }, } -func init() { chat.Index.Register(Index, nil) } +func init() { chat.Index.Register(Index, &web.Frame{}) } diff --git a/type.go b/type.go index 3b2d9717..65d6595c 100644 --- a/type.go +++ b/type.go @@ -34,8 +34,8 @@ type Config struct { type Command struct { Name string Help interface{} - Meta map[string]interface{} List []interface{} + Meta map[string]interface{} Hand func(m *Message, c *Context, key string, arg ...string) } type Context struct { @@ -74,9 +74,6 @@ func (c *Context) Cap(key string, arg ...interface{}) string { } return c.Caches[key].Value } -func (c *Context) Server() Server { - return c.server -} func (c *Context) Run(m *Message, cmd *Command, key string, arg ...string) *Message { m.Hand = true m.Log(LOG_CMDS, "%s.%s %d %v", c.Name, key, len(arg), arg) @@ -89,6 +86,9 @@ func (c *Context) Runs(m *Message, cmd string, key string, arg ...string) { } return } +func (c *Context) Server() Server { + return c.server +} func (c *Context) Register(s *Context, x Server) *Context { Pulse.Log("register", "%s <- %s", c.Name, s.Name) if c.contexts == nil { @@ -112,21 +112,24 @@ func (c *Context) Spawn(m *Message, name string, help string, arg ...string) *Co return s } func (c *Context) Begin(m *Message, arg ...string) *Context { - c.Caches[CTX_STATUS] = &Cache{Name: CTX_STATUS, Value: ""} - c.Caches[CTX_STREAM] = &Cache{Name: CTX_STREAM, Value: ""} c.Caches[CTX_FOLLOW] = &Cache{Name: CTX_FOLLOW, Value: ""} + c.Caches[CTX_STREAM] = &Cache{Name: CTX_STREAM, Value: ""} + c.Caches[CTX_STATUS] = &Cache{Name: CTX_STATUS, Value: ""} - m.Log(LOG_BEGIN, "%s", c.Name) - if c.begin = m; c.server != nil { - m.TryCatch(m, true, func(m *Message) { - c.server.Begin(m, arg...) - }) - } if c.context == Index { c.Cap(CTX_FOLLOW, c.Name) } else if c.context != nil { c.Cap(CTX_FOLLOW, kit.Keys(c.context.Cap(CTX_FOLLOW), c.Name)) } + m.Log(LOG_BEGIN, "%s", c.Cap(CTX_FOLLOW)) + c.Cap(CTX_STATUS, ICE_BEGIN) + + if c.begin = m; c.server != nil { + m.TryCatch(m, true, func(m *Message) { + // 初始化模块 + c.server.Begin(m, arg...) + }) + } return c } func (c *Context) Start(m *Message, arg ...string) bool { @@ -135,12 +138,12 @@ func (c *Context) Start(m *Message, arg ...string) bool { wait := make(chan bool) m.Gos(m, func(m *Message) { - m.Log(LOG_START, "%s", c.Name) - - c.Cap(CTX_STATUS, "start") + m.Log(LOG_START, "%s", c.Cap(CTX_FOLLOW)) + c.Cap(CTX_STATUS, ICE_START) wait <- true + + // 启动模块 c.server.Start(m, arg...) - c.Cap(CTX_STATUS, "close") if m.Done(); m.wait != nil { m.wait <- true } @@ -149,8 +152,11 @@ func (c *Context) Start(m *Message, arg ...string) bool { return true } func (c *Context) Close(m *Message, arg ...string) bool { - m.Log(LOG_CLOSE, "%s", c.Name) + m.Log(LOG_CLOSE, "%s", c.Cap(CTX_FOLLOW)) + c.Cap(CTX_STATUS, ICE_CLOSE) + if c.server != nil { + // 结束模块 return c.server.Close(m, arg...) } return true @@ -178,11 +184,13 @@ type Message struct { } func (m *Message) Time(args ...interface{}) string { + // [duration] [format [args...]] t := m.time if len(args) > 0 { switch arg := args[0].(type) { case string: if d, e := time.ParseDuration(arg); e == nil { + // 时间偏移 t, args = t.Add(d), args[1:] } } @@ -193,6 +201,7 @@ func (m *Message) Time(args ...interface{}) string { case string: f = arg if len(args) > 1 { + // 时间格式 f = fmt.Sprintf(f, args[1:]...) } } @@ -219,13 +228,16 @@ func (m *Message) Format(key interface{}) string { } else { return fmt.Sprintf("%dx%d %s", len(m.meta[m.meta["append"][0]]), len(m.meta["append"]), kit.Format(m.meta["append"])) } + case "time": return m.Time() case "ship": return fmt.Sprintf("%s->%s", m.source.Name, m.target.Name) case "prefix": return fmt.Sprintf("%s %d %s->%s", m.Time(), m.code, m.source.Name, m.target.Name) + case "chain": + // 调用链 ms := []*Message{} for msg := m; msg != nil; msg = msg.message { ms = append(ms, msg) @@ -265,6 +277,7 @@ func (m *Message) Format(key interface{}) string { } return strings.Join(meta, "") case "stack": + // 调用栈 pc := make([]uintptr, 100) pc = pc[:runtime.Callers(5, pc)] frames := runtime.CallersFrames(pc) @@ -290,10 +303,14 @@ func (m *Message) Formats(key string) string { switch key { case "meta": return kit.Formats(m.meta) - default: - return m.Format(key) } - return m.time.Format(ICE_TIME) + return m.Format(key) +} +func (m *Message) Spawns(arg ...interface{}) *Message { + msg := m.Spawn(arg...) + msg.code = m.target.root.ID() + m.messages = append(m.messages, msg) + return msg } func (m *Message) Spawn(arg ...interface{}) *Message { msg := &Message{ @@ -322,28 +339,7 @@ func (m *Message) Spawn(arg ...interface{}) *Message { } return msg } -func (m *Message) Spawns(arg ...interface{}) *Message { - msg := m.Spawn(arg...) - msg.code = m.target.root.ID() - m.messages = append(m.messages, msg) - return msg -} -func (m *Message) CSV(text string) *Message { - bio := bytes.NewBufferString(text) - r := csv.NewReader(bio) - heads, _ := r.Read() - for { - lines, e := r.Read() - if e != nil { - break - } - for i, k := range heads { - m.Push(k, kit.Select("", lines, i)) - } - } - return m -} func (m *Message) Add(key string, arg ...string) *Message { switch key { case MSG_DETAIL, MSG_RESULT: @@ -378,41 +374,16 @@ func (m *Message) Set(key string, arg ...string) *Message { } return m.Add(key, arg...) } -func (m *Message) Copy(msg *Message, arg ...string) *Message { - if msg == nil { - return m - } - if len(arg) > 0 { - for _, k := range arg[1:] { - if kit.IndexOf(m.meta[arg[0]], k) == -1 { - m.meta[arg[0]] = append(m.meta[arg[0]], k) - } - m.meta[k] = append(m.meta[k], msg.meta[k]...) - } - return m - } - for _, k := range msg.meta[MSG_OPTION] { - if kit.IndexOf(m.meta[MSG_OPTION], k) == -1 { - m.meta[MSG_OPTION] = append(m.meta[MSG_OPTION], k) - } - m.meta[k] = append(m.meta[k], msg.meta[k]...) - } - for _, k := range msg.meta[MSG_APPEND] { - if kit.IndexOf(m.meta[MSG_APPEND], k) == -1 { - m.meta[MSG_APPEND] = append(m.meta[MSG_APPEND], k) - } - m.meta[k] = append(m.meta[k], msg.meta[k]...) - } - m.meta[MSG_RESULT] = append(m.meta[MSG_RESULT], msg.meta[MSG_RESULT]...) - return m -} func (m *Message) Push(key string, value interface{}, arg ...interface{}) *Message { switch value := value.(type) { case map[string]string: case map[string]interface{}: if key == "detail" { + // 格式转换 value = kit.KeyValue(map[string]interface{}{}, "", value) } + + // 键值排序 list := []string{} if len(arg) > 0 { list = kit.Simple(arg[0]) @@ -423,6 +394,7 @@ func (m *Message) Push(key string, value interface{}, arg ...interface{}) *Messa sort.Strings(list) } + // 追加数据 for _, k := range list { switch key { case "detail": @@ -438,6 +410,7 @@ func (m *Message) Push(key string, value interface{}, arg ...interface{}) *Messa } return m } + for _, v := range kit.Simple(value) { m.Add(MSG_APPEND, key, v) } @@ -450,7 +423,40 @@ func (m *Message) Echo(str string, arg ...interface{}) *Message { m.meta[MSG_RESULT] = append(m.meta[MSG_RESULT], str) return m } +func (m *Message) Copy(msg *Message, arg ...string) *Message { + if len(arg) > 0 { + // 精确复制 + for _, k := range arg[1:] { + if kit.IndexOf(m.meta[arg[0]], k) == -1 { + m.meta[arg[0]] = append(m.meta[arg[0]], k) + } + m.meta[k] = append(m.meta[k], msg.meta[k]...) + } + return m + } + + // 复制选项 + for _, k := range msg.meta[MSG_OPTION] { + if kit.IndexOf(m.meta[MSG_OPTION], k) == -1 { + m.meta[MSG_OPTION] = append(m.meta[MSG_OPTION], k) + } + m.meta[k] = append(m.meta[k], msg.meta[k]...) + } + + // 复制数据 + for _, k := range msg.meta[MSG_APPEND] { + if kit.IndexOf(m.meta[MSG_APPEND], k) == -1 { + m.meta[MSG_APPEND] = append(m.meta[MSG_APPEND], k) + } + m.meta[k] = append(m.meta[k], msg.meta[k]...) + } + + // 复制文本 + m.meta[MSG_RESULT] = append(m.meta[MSG_RESULT], msg.meta[MSG_RESULT]...) + return m +} func (m *Message) Sort(key string, arg ...string) *Message { + // 排序方法 cmp := "str" if len(arg) > 0 && arg[0] != "" { cmp = arg[0] @@ -463,6 +469,7 @@ func (m *Message) Sort(key string, arg ...string) *Message { } } + // 排序因子 number := map[int]int{} table := []map[string]string{} m.Table(func(index int, line map[string]string, head []string) { @@ -479,6 +486,7 @@ func (m *Message) Sort(key string, arg ...string) *Message { } }) + // 排序数据 for i := 0; i < len(table)-1; i++ { for j := i + 1; j < len(table); j++ { result := false @@ -504,10 +512,10 @@ func (m *Message) Sort(key string, arg ...string) *Message { } } + // 输出数据 for _, k := range m.meta[MSG_APPEND] { delete(m.meta, k) } - for _, v := range table { for _, k := range m.meta[MSG_APPEND] { m.Add(MSG_APPEND, k, v[k]) @@ -525,11 +533,13 @@ func (m *Message) Table(cbs ...interface{}) *Message { nrow = len(m.meta[k]) } } + for i := 0; i < nrow; i++ { line := map[string]string{} for _, k := range m.meta[MSG_APPEND] { line[k] = kit.Select("", m.meta[k], i) } + // 依次回调 cb(i, line, m.meta[MSG_APPEND]) } } @@ -554,7 +564,7 @@ func (m *Message) Table(cbs ...interface{}) *Message { // 回调函数 rows := kit.Select("\n", m.Option("table.row_sep")) cols := kit.Select(" ", m.Option("table.col_sep")) - compact := kit.Select(m.Conf("table", "compact"), m.Option("table.compact")) == "true" + compact := m.Option("table.compact") == "true" cb := func(maps map[string]string, lists []string, line int) bool { for i, v := range lists { if k := m.meta[MSG_APPEND][i]; compact { @@ -591,6 +601,7 @@ func (m *Message) Table(cbs ...interface{}) *Message { row[k], wor = data, append(wor, data+strings.Repeat(space, width[k]-kit.Width(data, len(space)))) } + // 依次回调 if !cb(row, wor, i) { break } @@ -606,11 +617,15 @@ func (m *Message) Render(str string, arg ...interface{}) *Message { } return m } +func (m *Message) Qrcode(str string, arg ...interface{}) *Message { + return m +} func (m *Message) Split(str string, field string, space string, enter string) *Message { indexs := []int{} fields := kit.Split(field, space) for i, l := range kit.Split(str, enter) { if i == 0 && (field == "" || field == "index") { + // 表头行 fields = kit.Split(l, space) if field == "index" { for _, v := range fields { @@ -621,6 +636,7 @@ func (m *Message) Split(str string, field string, space string, enter string) *M } if len(indexs) > 0 { + // 数据行 for i, v := range indexs { if i == len(indexs)-1 { m.Push(kit.Select("some", fields, i), l[v:]) @@ -637,6 +653,21 @@ func (m *Message) Split(str string, field string, space string, enter string) *M } return m } +func (m *Message) CSV(text string) *Message { + bio := bytes.NewBufferString(text) + r := csv.NewReader(bio) + heads, _ := r.Read() + for { + lines, e := r.Read() + if e != nil { + break + } + for i, k := range heads { + m.Push(k, kit.Select("", lines, i)) + } + } + return m +} func (m *Message) Detail(arg ...interface{}) string { return kit.Select("", m.meta[MSG_DETAIL], 0) @@ -646,6 +677,7 @@ func (m *Message) Detailv(arg ...interface{}) []string { } func (m *Message) Optionv(key string, arg ...interface{}) interface{} { if len(arg) > 0 { + // 写数据 if kit.IndexOf(m.meta[MSG_OPTION], key) == -1 { m.meta[MSG_OPTION] = append(m.meta[MSG_OPTION], key) } @@ -662,9 +694,11 @@ func (m *Message) Optionv(key string, arg ...interface{}) interface{} { for msg := m; msg != nil; msg = msg.message { if list, ok := msg.data[key]; ok { + // 读数据 return list } if list, ok := msg.meta[key]; ok { + // 读选项 return list } } @@ -692,7 +726,7 @@ func (m *Message) Result(arg ...interface{}) string { if len(arg) > 0 { switch v := arg[0].(type) { case int: - return kit.Select("", m.Meta[MSG_RESULT], v) + return kit.Select("", m.meta[MSG_RESULT], v) } } return strings.Join(m.Resultv(), "") @@ -700,9 +734,11 @@ func (m *Message) Result(arg ...interface{}) string { func (m *Message) Log(level string, str string, arg ...interface{}) *Message { if str = strings.TrimSpace(fmt.Sprintf(str, arg...)); Log != nil { + // 日志模块 Log(m, level, str) } + // 日志颜色 prefix, suffix := "", "" switch level { case LOG_ENABLE, LOG_IMPORT, LOG_CREATE, LOG_INSERT, LOG_EXPORT: @@ -756,36 +792,6 @@ func (m *Message) Trace(key string, str string, arg ...interface{}) *Message { return m } -func (m *Message) Space(arg interface{}) []string { - if arg == nil || kit.Format(arg) == m.Conf(CLI_RUNTIME, "node.name") { - return nil - } - return []string{WEB_SPACE, kit.Format(arg)} -} -func (m *Message) Right(arg ...interface{}) bool { - return m.Option(MSG_USERROLE) == ROLE_ROOT || !m.Warn(m.Cmdx(AAA_ROLE, "right", m.Option(MSG_USERROLE), kit.Keys(arg...)) != "ok", "no right") -} -func (m *Message) Event(key string, arg ...string) *Message { - m.Cmd(GDB_EVENT, "action", key, arg) - return m -} -func (m *Message) Watch(key string, arg ...string) *Message { - m.Cmd(GDB_EVENT, "listen", key, arg) - return m -} - -func (m *Message) Assert(arg interface{}) bool { - switch arg := arg.(type) { - case nil: - return true - case bool: - if arg == true { - return true - } - } - - panic(errors.New(fmt.Sprintf("error %v", arg))) -} func (m *Message) TryCatch(msg *Message, safe bool, hand ...func(msg *Message)) *Message { defer func() { switch e := recover(); e { @@ -797,24 +803,36 @@ func (m *Message) TryCatch(msg *Message, safe bool, hand ...func(msg *Message)) m.Log(LOG_WARN, "catch: %s", e) m.Log(LOG_INFO, "stack: %s", msg.Format("stack")) if m.Log(LOG_WARN, "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, cb func(*Message)) *Message { - go func() { msg.TryCatch(msg, true, func(msg *Message) { cb(msg) }) }() - return m +func (m *Message) Assert(arg interface{}) bool { + switch arg := arg.(type) { + case nil: + return true + case bool: + if arg == true { + return true + } + } + + // 抛出异常 + panic(errors.New(fmt.Sprintf("error %v", arg))) } -func (m *Message) Run(arg ...string) *Message { - m.target.server.Start(m, arg...) +func (m *Message) Sleep(arg string) *Message { + time.Sleep(kit.Duration(arg)) return m } func (m *Message) Hold(n int) *Message { @@ -839,21 +857,6 @@ func (m *Message) Done() bool { ctx.wg.Done() return true } -func (m *Message) Start(key string, arg ...string) *Message { - m.Travel(func(p *Context, s *Context) { - if s.Name == key { - s.Start(m.Spawns(s), arg...) - } - }) - return m -} - -func (m *Message) Starts(name string, help string, arg ...string) *Message { - m.wait = make(chan bool) - m.target.Spawn(m, name, help, arg...).Begin(m, arg...).Start(m, arg...) - <-m.wait - return m -} func (m *Message) Call(sync bool, cb func(*Message) *Message) *Message { if sync { wait := make(chan bool) @@ -871,8 +874,65 @@ func (m *Message) Back(sub *Message) *Message { } return m } -func (m *Message) Sleep(arg string) *Message { - time.Sleep(kit.Duration(arg)) +func (m *Message) Gos(msg *Message, cb func(*Message)) *Message { + go func() { msg.TryCatch(msg, true, func(msg *Message) { cb(msg) }) }() + return m +} + +func (m *Message) Run(arg ...string) *Message { + m.target.server.Start(m, arg...) + return m +} +func (m *Message) Start(key string, arg ...string) *Message { + m.Travel(func(p *Context, s *Context) { + if s.Name == key { + s.Start(m.Spawns(s), arg...) + } + }) + return m +} +func (m *Message) Starts(name string, help string, arg ...string) *Message { + m.wait = make(chan bool) + m.target.Spawn(m, name, help, arg...).Begin(m, arg...).Start(m, arg...) + <-m.wait + return m +} + +func (m *Message) Space(arg interface{}) []string { + if arg == nil || kit.Format(arg) == m.Conf(CLI_RUNTIME, "node.name") { + return nil + } + return []string{WEB_SPACE, kit.Format(arg)} +} +func (m *Message) Right(arg ...interface{}) bool { + return m.Option(MSG_USERROLE) == ROLE_ROOT || !m.Warn(m.Cmdx(AAA_ROLE, "right", m.Option(MSG_USERROLE), kit.Keys(arg...)) != "ok", "no right") +} +func (m *Message) Event(key string, arg ...string) *Message { + m.Cmd(GDB_EVENT, "action", key, arg) + return m +} +func (m *Message) Watch(key string, arg ...string) *Message { + m.Cmd(GDB_EVENT, "listen", key, arg) + return m +} + +func (m *Message) Prefix(arg ...string) string { + return kit.Keys(m.Cap(CTX_FOLLOW), arg) +} +func (m *Message) Save(arg ...string) *Message { + list := []string{} + for _, k := range arg { + list = append(list, kit.Keys(m.Cap(CTX_FOLLOW), k)) + } + m.Cmd(CTX_CONFIG, "save", kit.Keys(m.Cap(CTX_FOLLOW), "json"), list) + return m +} +func (m *Message) Load(arg ...string) *Message { + list := []string{} + for _, k := range arg { + list = append(list, kit.Keys(m.Cap(CTX_FOLLOW), k)) + } + m.Cmd(CTX_CONFIG, "load", kit.Keys(m.Cap(CTX_FOLLOW), "json"), list) return m } @@ -881,6 +941,7 @@ func (m *Message) Travel(cb interface{}) *Message { for i := 0; i < len(list); i++ { switch cb := cb.(type) { case func(*Context, *Context): + // 模块回调 cb(list[i].context, list[i]) case func(*Context, *Context, string, *Command): ls := []string{} @@ -889,6 +950,7 @@ func (m *Message) Travel(cb interface{}) *Message { } sort.Strings(ls) for _, k := range ls { + // 命令回调 cb(list[i].context, list[i], k, list[i].Commands[k]) } case func(*Context, *Context, string, *Config): @@ -898,10 +960,12 @@ func (m *Message) Travel(cb interface{}) *Message { } sort.Strings(ls) for _, k := range ls { + // 配置回调 cb(list[i].context, list[i], k, list[i].Configs[k]) } } + // 下级模块 ls := []string{} for k := range list[i].contexts { ls = append(ls, k) @@ -920,6 +984,7 @@ func (m *Message) Search(key interface{}, cb interface{}) *Message { key = k } + // 查找模块 p := m.target.root if strings.Contains(key, ":") { @@ -951,6 +1016,7 @@ func (m *Message) Search(key interface{}, cb interface{}) *Message { p = m.target } + // 遍历命令 switch cb := cb.(type) { case func(p *Context, s *Context, key string, cmd *Command): if key == "" { @@ -984,9 +1050,6 @@ func (m *Message) Search(key interface{}, cb interface{}) *Message { return m } -func Meta(arg ...interface{}) string { - return kit.MDB_META + "." + kit.Keys(arg...) -} func (m *Message) Richs(key string, chain interface{}, raw interface{}, cb interface{}) (res map[string]interface{}) { // 数据结构 cache := m.Confm(key, chain) @@ -1122,7 +1185,7 @@ func (m *Message) Grow(key string, chain interface{}, data interface{}) int { least := kit.Int(kit.Select(m.Conf(WEB_CACHE, "meta.least"), kit.Select(kit.Format(meta["least"]), m.Option("cache.least")))) // 创建文件 - name := path.Join(kit.Select(m.Conf(WEB_CACHE, Meta("store")), kit.Select(kit.Format(meta["store"]), m.Option("cache.store"))), kit.Keys(key, chain, "csv")) + name := path.Join(kit.Select(m.Conf(WEB_CACHE, "meta.store"), kit.Select(kit.Format(meta["store"]), m.Option("cache.store"))), kit.Keys(key, chain, "csv")) if s, e := os.Stat(name); e == nil { if s.Size() > kit.Int64(kit.Select(m.Conf(WEB_CACHE, "meta.fsize"), kit.Select(kit.Format(meta["fsize"]), m.Option("cache.fsize")))) { name = strings.Replace(name, ".csv", fmt.Sprintf("_%d.csv", kit.Int(meta["offset"])), -1) @@ -1199,6 +1262,7 @@ func (m *Message) Grow(key string, chain interface{}, data interface{}) int { return id } func (m *Message) Grows(key string, chain interface{}, match string, value string, cb interface{}) map[string]interface{} { + // 数据结构 cache := m.Confm(key, chain) if cache == nil { return nil @@ -1209,11 +1273,18 @@ func (m *Message) Grows(key string, chain interface{}, match string, value strin return nil } + // 数据范围 offend := kit.Int(kit.Select("0", m.Option("cache.offend"))) limit := kit.Int(kit.Select("10", m.Option("cache.limit"))) current := kit.Int(meta["offset"]) end := current + len(list) - offend begin := end - limit + switch limit { + case -1: + begin = current + case -2: + begin = 0 + } if match == kit.MDB_ID { begin, end = kit.Int(value)-1, kit.Int(value) @@ -1222,9 +1293,11 @@ func (m *Message) Grows(key string, chain interface{}, match string, value strin order := 0 if begin < current { + // 读取磁盘 m.Log(LOG_INFO, "%s.%v read %v-%v from %v-%v", key, chain, begin, end, current, current+len(list)) store, _ := meta["record"].([]interface{}) for s := len(store) - 1; s > -1; s-- { + // 查找索引 item, _ := store[s].(map[string]interface{}) line := kit.Int(item["offset"]) m.Log(LOG_INFO, "check history %v %v %v", s, line, item) @@ -1237,6 +1310,7 @@ func (m *Message) Grows(key string, chain interface{}, match string, value strin break } + // 查找偏移 item, _ := store[s].(map[string]interface{}) name := kit.Format(item["file"]) pos := kit.Int(item["position"]) @@ -1246,6 +1320,7 @@ func (m *Message) Grows(key string, chain interface{}, match string, value strin continue } + // 打开文件 m.Log(LOG_IMPORT, "load history %v %v %v", s, offset, item) if f, e := os.Open(name); m.Assert(e) { defer f.Close() @@ -1336,8 +1411,10 @@ func (m *Message) Cmd(arg ...interface{}) *Message { msg.meta[MSG_DETAIL] = list m.Hand, msg.Hand, m = true, true, msg if you := m.Option(kit.Format(kit.Value(cmd.Meta, "remote"))); you != "" { + // 远程命令 msg.Copy(msg.Spawns(c).Cmd(WEB_SPACE, you, list[0], list[1:])) } else { + // 本地命令 p.Run(msg, cmd, key, list[1:]...) } m.Hand, msg.Hand = true, true @@ -1352,13 +1429,17 @@ func (m *Message) Confv(arg ...interface{}) (val interface{}) { if len(arg) > 1 { if len(arg) > 2 { if arg[1] == nil { + // 写配置 conf.Value = arg[2] } else { + // 写修改项 kit.Value(conf.Value, arg[1:]...) } } + // 读配置项 val = kit.Value(conf.Value, arg[1]) } else { + // 读配置 val = conf.Value } }) @@ -1392,8 +1473,10 @@ func (m *Message) Capv(arg ...interface{}) interface{} { for c := s; c != nil; c = c.context { if caps, ok := c.Caches[key]; ok { if len(arg) > 0 { + // 写数据 caps.Value = kit.Format(arg[0]) } + // 读数据 return caps.Value } }