diff --git a/base/cli/cli.go b/base/cli/cli.go index 6d8d6524..a20bdf50 100644 --- a/base/cli/cli.go +++ b/base/cli/cli.go @@ -53,6 +53,7 @@ var Index = &ice.Context{Name: "cli", Help: "命令模块", cmd := exec.Command(arg[0], arg[1:]...) cmd.Dir = m.Option("cmd_dir") + m.Log("info", "dir: %s", cmd.Dir) if m.Option("cmd_type") == "daemon" { m.Gos(m, func(m *ice.Message) { if e := cmd.Start(); e != nil { diff --git a/base/ctx/ctx.go b/base/ctx/ctx.go index 07fe4085..37a20e66 100644 --- a/base/ctx/ctx.go +++ b/base/ctx/ctx.go @@ -60,7 +60,11 @@ var Index = &ice.Context{Name: "ctx", Help: "元始模块", m.Push("meta", kit.Format(i.Meta)) m.Push("list", kit.Format(i.List)) } else { - m.Copy(m.Spawns(s).Runs(key, key, arg[3:]...)) + if i.Meta != nil && kit.Format(i.Meta["remote"]) == "true" && m.Option("you") != "" { + m.Copy(m.Spawns(s).Cmd("web.space", m.Option("you"), "ctx.command", arg[0], arg[1], "run", arg[3:])) + } else { + m.Copy(m.Spawns(s).Runs(key, key, arg[3:]...)) + } } } }) diff --git a/base/gdb/gdb.go b/base/gdb/gdb.go index c87feacd..e474a68a 100644 --- a/base/gdb/gdb.go +++ b/base/gdb/gdb.go @@ -17,20 +17,10 @@ func (f *Frame) Spawn(m *ice.Message, c *ice.Context, arg ...string) ice.Server return &Frame{} } func (f *Frame) Begin(m *ice.Message, arg ...string) ice.Server { - if f, p, e := kit.Create(m.Conf("logpid")); m.Assert(e) { - defer f.Close() - f.WriteString(kit.Format(os.Getpid())) - m.Log("info", "pid %d %s", os.Getpid(), p) - } + f.p = make(chan os.Signal, 10) return f } func (f *Frame) Start(m *ice.Message, arg ...string) bool { - f.p = make(chan os.Signal, 10) - m.Confm("signal", nil, func(sig string, action string) { - m.Log("signal", "add %s: %s", sig, action) - signal.Notify(f.p, syscall.Signal(kit.Int(sig))) - }) - m.Cap("stream", m.Conf("timer", "meta.tick")) tick := time.Tick(kit.Duration(m.Conf("timer", "meta.tick"))) for { @@ -42,7 +32,6 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool { m.Log("info", "signal %v", sig) m.Cmd(m.Confv("signal", kit.Format(sig))) case now, _ := <-tick: - // m.Log("info", "ticker %v", kit.Format(now)) stamp := int(now.Unix()) m.Confm("timer", "hash", func(key string, value map[string]interface{}) { if kit.Int(value["next"]) <= stamp { @@ -81,7 +70,17 @@ var Index = &ice.Context{Name: "gdb", Help: "调试模块", }, Commands: map[string]*ice.Command{ "_init": {Name: "_init", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Echo("hello %s world", c.Name) + if f, p, e := kit.Create(m.Conf("logpid")); m.Assert(e) { + defer f.Close() + f.WriteString(kit.Format(os.Getpid())) + m.Log("info", "pid %d %s", os.Getpid(), p) + } + + f := m.Target().Server().(*Frame) + m.Confm("signal", nil, func(sig string, action string) { + m.Log("signal", "add %s: %s", sig, action) + signal.Notify(f.p, syscall.Signal(kit.Int(sig))) + }) }}, "_exit": {Name: "_exit", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { f := m.Target().Server().(*Frame) diff --git a/base/log/log.go b/base/log/log.go index 0e8f6313..bb8f1a66 100644 --- a/base/log/log.go +++ b/base/log/log.go @@ -29,14 +29,6 @@ func (f *Frame) Begin(m *ice.Message, arg ...string) ice.Server { return f } func (f *Frame) Start(m *ice.Message, arg ...string) bool { - m.Confm("file", nil, func(key string, value map[string]interface{}) { - if f, p, e := kit.Create(kit.Format(value["path"])); m.Assert(e) { - m.Cap("stream", path.Base(p)) - m.Log("info", "log %s %s", key, p) - value["file"] = f - } - }) - for { if l, ok := <-f.p; !ok { break @@ -80,7 +72,13 @@ var Index = &ice.Context{Name: "log", Help: "日志模块", }, Commands: map[string]*ice.Command{ "_init": {Name: "_init", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Echo("hello %s world", c.Name) + m.Confm("file", nil, func(key string, value map[string]interface{}) { + if f, p, e := kit.Create(kit.Format(value["path"])); m.Assert(e) { + m.Cap("stream", path.Base(p)) + m.Log("info", "log %s %s", key, p) + value["file"] = f + } + }) }}, "_exit": {Name: "_exit", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { f := m.Target().Server().(*Frame) diff --git a/base/mdb/mdb.go b/base/mdb/mdb.go index 5998a0c8..d9bfdb12 100644 --- a/base/mdb/mdb.go +++ b/base/mdb/mdb.go @@ -15,6 +15,7 @@ var Index = &ice.Context{Name: "mdb", Help: "数据模块", index := kit.Int(arg[2]) - kit.Int(meta["offset"]) - 1 data := m.Confm(arg[0], arg[1]+".list."+kit.Format(index)) + m.Log("what", "%v %v", arg[0], arg[1]+".list."+kit.Format(index)) for i := 3; i < len(arg)-1; i += 2 { kit.Value(data, arg[i], arg[i+1]) } diff --git a/base/nfs/nfs.go b/base/nfs/nfs.go index 86b9068b..986cd71a 100644 --- a/base/nfs/nfs.go +++ b/base/nfs/nfs.go @@ -18,7 +18,7 @@ import ( func dir(m *ice.Message, root string, name string, level int, deep bool, dir_type string, dir_reg *regexp.Regexp, fields []string, format string) { - if fs, e := ioutil.ReadDir(name); m.Assert(e) { + if fs, e := ioutil.ReadDir(path.Join(root, name)); m.Assert(e) { for _, f := range fs { if f.Name() == "." || f.Name() == ".." { continue @@ -27,7 +27,7 @@ func dir(m *ice.Message, root string, name string, level int, deep bool, dir_typ continue } - p := path.Join(name, f.Name()) + p := path.Join(root, name, f.Name()) if f, e = os.Lstat(p); e != nil { m.Log("info", "%s", e) continue diff --git a/base/ssh/ssh.go b/base/ssh/ssh.go index fd4fb4b8..136cb0fb 100644 --- a/base/ssh/ssh.go +++ b/base/ssh/ssh.go @@ -66,7 +66,7 @@ var Index = &ice.Context{Name: "ssh", Help: "终端模块", "_exit": {Name: "_exit", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { f := m.Target().Server().(*Frame) f.in.Close() - m.Target().Done() + m.Done() }}, }, } diff --git a/base/web/web.go b/base/web/web.go index 07f7d63c..91b22713 100644 --- a/base/web/web.go +++ b/base/web/web.go @@ -47,7 +47,7 @@ func (web *WEB) Login(msg *ice.Message, w http.ResponseWriter, r *http.Request) msg.Runs("_login", msg.Option("url"), kit.Simple(msg.Optionv("cmds"))...) return true } -func (web *WEB) HandleWSS(m *ice.Message, safe bool, c *websocket.Conn) { +func (web *WEB) HandleWSS(m *ice.Message, safe bool, c *websocket.Conn) bool { for { if t, b, e := c.ReadMessage(); e != nil { m.Log("warn", "space recv %d msg %v", t, e) @@ -86,6 +86,9 @@ func (web *WEB) HandleWSS(m *ice.Message, safe bool, c *websocket.Conn) { // 本地执行 if safe { msg = msg.Cmd() + if msg.Detail() == "exit" { + return true + } } else { msg.Echo("no right") } @@ -102,6 +105,7 @@ func (web *WEB) HandleWSS(m *ice.Message, safe bool, c *websocket.Conn) { } } } + return false } func (web *WEB) HandleCGI(m *ice.Message, which string) *template.Template { cgi := template.FuncMap{ @@ -131,8 +135,8 @@ func (web *WEB) HandleCGI(m *ice.Message, which string) *template.Template { }(k, v) } tmpl = tmpl.Funcs(cgi) - tmpl = template.Must(tmpl.ParseGlob(path.Join(m.Conf("serve", "template.path"), "/*.tmpl"))) - tmpl = template.Must(tmpl.ParseGlob(path.Join(m.Conf("serve", "template.path"), m.Target().Name, "/*.tmpl"))) + // tmpl = template.Must(tmpl.ParseGlob(path.Join(m.Conf("serve", "template.path"), "/*.tmpl"))) + // tmpl = template.Must(tmpl.ParseGlob(path.Join(m.Conf("serve", "template.path"), m.Target().Name, "/*.tmpl"))) tmpl = template.Must(tmpl.ParseFiles(which)) m.Confm("serve", "template.list", func(index int, value string) { tmpl = template.Must(tmpl.Parse(value)) }) for i, v := range tmpl.Templates() { @@ -248,7 +252,7 @@ func (web *WEB) Start(m *ice.Message, arg ...string) bool { // 级联路由 route := "/" + s.Name + "/" if n, ok := p.Server().(*WEB); ok && n.ServeMux != nil { - msg.Log("route", "%s <- %s", p.Name, route) + msg.Log("route", "%s <= %s", p.Name, route) n.Handle(route, http.StripPrefix(path.Dir(route), w)) } @@ -259,12 +263,12 @@ func (web *WEB) Start(m *ice.Message, arg ...string) bool { }) // 命令路由 - for k, x := range s.Commands { - if k[0] == '/' { + m.Travel(func(p *ice.Context, sub *ice.Context, k string, x *ice.Command) { + if s == sub && k[0] == '/' { msg.Log("route", "%s <- %s", s.Name, k) w.HandleCmd(msg, k, x) } - } + }) } }) @@ -285,7 +289,7 @@ var Index = &ice.Context{Name: "web", Help: "网页模块", Caches: map[string]*ice.Cache{}, Configs: map[string]*ice.Config{ "spide": {Name: "客户端", Value: map[string]interface{}{ - "self": map[string]interface{}{"port": ":9020"}, + "self": map[string]interface{}{"port": "127.0.0.1:9020"}, }}, "serve": {Name: "服务端", Value: map[string]interface{}{ "static": map[string]interface{}{"/": "usr/volcanos/", @@ -313,7 +317,7 @@ var Index = &ice.Context{Name: "web", Help: "网页模块", m.Echo("hello %s world", c.Name) }}, "_exit": {Name: "_exit", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Target().Done() + m.Done() }}, "serve": {Name: "hi", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Conf("cli.runtime", "node.type", "server") @@ -350,6 +354,7 @@ var Index = &ice.Context{Name: "web", Help: "网页模块", }) return } + web := m.Target().Server().(*WEB) switch arg[0] { case "connect": @@ -369,11 +374,17 @@ var Index = &ice.Context{Name: "web", Help: "网页模块", web.send[id] = m s.WriteMessage(MSG_MAPS, []byte(m.Format("meta"))) - web.HandleWSS(m, true, s) + if web.HandleWSS(m, true, s) { + break + } + } else { + m.Log("warn", "wss %s", e) } + } else { + m.Log("warn", "dial %s", e) } time.Sleep(time.Duration(rand.Intn(m.Confi("web.space", "meta.redial"))) * time.Millisecond) - m.Log("info", "reconnect %v", host) + m.Log("info", "reconnect %v", u) } }) } @@ -382,6 +393,7 @@ var Index = &ice.Context{Name: "web", Help: "网页模块", m.Cmdy(arg[1:]) break } + target := strings.Split(arg[0], ".") if socket, ok := m.Confv("space", "hash."+target[0]+".socket").(*websocket.Conn); !ok { m.Echo("error").Echo("not found") @@ -389,13 +401,16 @@ var Index = &ice.Context{Name: "web", Help: "网页模块", id := kit.Format(c.ID()) m.Optionv("_source", []string{id, target[0]}) m.Optionv("_target", target[1:]) + m.Set("detail", arg[1:]...) web := m.Target().Server().(*WEB) web.send[id] = m - m.Set("detail", arg[1:]...) + + now := time.Now() socket.WriteMessage(MSG_MAPS, []byte(m.Format("meta"))) m.Call(true, func(msg *ice.Message) *ice.Message { m.Copy(msg) + m.Log("info", "cost %s", time.Now().Sub(now)) return nil }) } diff --git a/core/team/team.go b/core/team/team.go index 636d1f48..1ae87279 100644 --- a/core/team/team.go +++ b/core/team/team.go @@ -29,7 +29,7 @@ var Index = &ice.Context{Name: "team", Help: "团队模块", }, List: []interface{}{ map[string]interface{}{"type": "text", "value": "", "name": "name"}, map[string]interface{}{"type": "text", "value": "", "name": "type"}, - map[string]interface{}{"type": "button", "value": "创建"}, + map[string]interface{}{"type": "button", "value": "创建", "action": "auto"}, }, Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { if len(arg) > 1 { switch arg[1] { @@ -57,46 +57,55 @@ var Index = &ice.Context{Name: "team", Help: "团队模块", } } - m.Cmdy("nfs.dir", "", m.Conf("miss", "meta.path"), "time name") + m.Cmdy("nfs.dir", m.Conf("miss", "meta.path"), "", "time name") m.Table(func(index int, value map[string]string, head []string) { m.Push("status", kit.Select("stop", "start", m.Confs("web.space", "hash."+value["name"]))) }) }}, - "task": {Name: "task", Help: "任务", List: []interface{}{ - map[string]interface{}{"type": "select", "value": "create", "values": "create action cancel finish"}, - map[string]interface{}{"type": "text", "value": "", "name": "name"}, - map[string]interface{}{"type": "text", "value": "", "name": "text"}, - map[string]interface{}{"type": "button", "value": "创建"}, - }, Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { - switch arg[0] { - case "create": - meta := m.Grow("web.chat.group", []string{"hash", m.Option("sess.river"), "task"}, map[string]interface{}{ - "name": arg[1], - "text": kit.Select("", arg, 2), - "status": "准备", - "begin_time": m.Time(), - "close_time": m.Time("3h"), - }) - m.Log("info", "create task %v", kit.Format(meta)) - m.Echo("%v", meta["count"]) - case "action": - case "cancel": - } - }}, + "task": {Name: "task", Help: "任务", + Meta: map[string]interface{}{ + "remote": "true", + }, + List: []interface{}{ + map[string]interface{}{"type": "select", "value": "create", "values": "create action cancel finish"}, + map[string]interface{}{"type": "text", "value": "", "name": "name"}, + map[string]interface{}{"type": "text", "value": "", "name": "text"}, + map[string]interface{}{"type": "button", "value": "创建"}, + }, Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { + switch arg[0] { + case "create": + meta := m.Grow("web.chat.group", []string{"hash", m.Option("sess.river"), "task"}, map[string]interface{}{ + "name": arg[1], + "text": kit.Select("", arg, 2), + "status": "准备", + "begin_time": m.Time(), + "close_time": m.Time("3h"), + }) + m.Log("info", "create task %v", kit.Format(meta)) + m.Echo("%v", meta["count"]) + case "action": + case "cancel": + } + }}, "process": {Name: "process", Help: "任务进度", Meta: map[string]interface{}{ - "detail": []string{"准备", "开始", "取消", "完成"}, + "remote": "true", + "detail": []string{"编辑", "准备", "开始", "取消", "完成"}, }, List: []interface{}{ map[string]interface{}{"type": "text", "value": "0", "name": "offend"}, map[string]interface{}{"type": "text", "value": "10", "name": "limit"}, map[string]interface{}{"type": "text", "value": "", "name": "match"}, map[string]interface{}{"type": "text", "value": "", "name": "value"}, - map[string]interface{}{"type": "button", "value": "查看"}, + map[string]interface{}{"type": "button", "value": "查看", "action": "auto"}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - msg := m.Cmd("mdb.select", "web.chat.group", "hash."+m.Option("sess.river")+".task", arg[0]) switch arg[1] { + case "modify": + prefix := []string{"mdb.update", "web.chat.group", "hash." + m.Option("sess.river") + ".task", arg[0], arg[2], arg[3]} + m.Cmd(prefix) + arg = arg[4:] + case "准备", "开始", "取消", "完成": - msg.Log("what", "%v %v", msg.Append("status"), arg[1]) + msg := m.Cmd("mdb.select", "web.chat.group", "hash."+m.Option("sess.river")+".task", arg[0]) if msg.Append("status") == arg[1] { arg = arg[4:] break diff --git a/core/wiki/wiki.go b/core/wiki/wiki.go index 72ff4355..8dabe054 100644 --- a/core/wiki/wiki.go +++ b/core/wiki/wiki.go @@ -12,8 +12,16 @@ import ( ) var Index = &ice.Context{Name: "wiki", Help: "文档模块", - Caches: map[string]*ice.Cache{}, - Configs: map[string]*ice.Config{}, + Caches: map[string]*ice.Cache{}, + Configs: map[string]*ice.Config{ + "note": {Name: "note", Value: map[string]interface{}{ + "meta": map[string]interface{}{ + "path": "usr/local/wiki", + }, + "list": map[string]interface{}{}, + "hash": map[string]interface{}{}, + }}, + }, Commands: map[string]*ice.Command{ "chart": {Name: "chart", Help: "绘图", List: []interface{}{ map[string]interface{}{"type": "select", "value": "chain", "values": "chain table"}, @@ -43,10 +51,10 @@ var Index = &ice.Context{Name: "wiki", Help: "文档模块", }}, "_tree": {Name: "_tree", Help: "目录", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { - m.Cmdy("nfs.dir", "", arg[0]) + m.Cmdy("nfs.dir", m.Conf("note", "meta.path"), kit.Select("", arg, 0), "time size line path") }}, "_text": {Name: "_text", Help: "文章", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { - tmpl := m.Target().Server().(*web.WEB).HandleCGI(m, arg[0]) + tmpl := m.Target().Server().(*web.WEB).HandleCGI(m, path.Join(m.Conf("note", "meta.path"), arg[0])) m.Optionv("title", map[string]int{}) buffer := bytes.NewBuffer([]byte{}) @@ -64,9 +72,11 @@ var Index = &ice.Context{Name: "wiki", Help: "文档模块", }}, "note": {Name: "note file|favor|commit", Help: "笔记", Meta: map[string]interface{}{ "display": "inner", + "remote": "true", }, List: []interface{}{ - map[string]interface{}{"type": "text", "value": "miss.md"}, - map[string]interface{}{"type": "button", "value": "执行"}, + map[string]interface{}{"type": "text", "value": "miss.md", "name": "path"}, + map[string]interface{}{"type": "button", "value": "执行", "action": "auto"}, + map[string]interface{}{"type": "button", "value": "返回", "cb": "Last"}, }, Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { if len(arg) == 0 { m.Cmdy("_tree") diff --git a/demo/miss.md b/demo/usr/local/wiki/miss.md similarity index 100% rename from demo/miss.md rename to demo/usr/local/wiki/miss.md diff --git a/type.go b/type.go index c2df0ce9..0d249137 100644 --- a/type.go +++ b/type.go @@ -85,14 +85,6 @@ func (c *Context) Register(s *Context, x Server) *Context { return s } -func (c *Context) Done() bool { - if c.context != nil && c.context.wg != nil { - c.context.wg.Done() - } else { - c.root.wg.Done() - } - return true -} func (c *Context) Begin(m *Message, arg ...string) *Context { c.Caches["status"] = &Cache{Name: "status", Value: ""} c.Caches["stream"] = &Cache{Name: "stream", Value: ""} @@ -113,14 +105,17 @@ func (c *Context) Start(m *Message, arg ...string) bool { c.root.wg.Add(1) } + wait := make(chan bool) m.Gos(m, func(m *Message) { m.Log("start", "%s", c.Name) c.Cap("status", "start") + wait <- true c.server.Start(m, arg...) c.Cap("status", "close") - c.Done() + m.Done() }) + <-wait return true } func (c *Context) Close(m *Message, arg ...string) bool { @@ -485,6 +480,12 @@ func (m *Message) Resultv(arg ...interface{}) []string { func (m *Message) Result(arg ...interface{}) string { return strings.Join(m.Resultv(), "") } +func (m *Message) Detailv(arg ...interface{}) []string { + return m.meta["detail"] +} +func (m *Message) Detail(arg ...interface{}) string { + return kit.Select("", m.meta["detail"], 0) +} var Log func(*Message, string, string) @@ -541,10 +542,31 @@ func (m *Message) TryCatch(msg *Message, safe bool, hand ...func(msg *Message)) } return m } -func (m *Message) Travel(cb func(p *Context, s *Context)) *Message { +func (m *Message) Travel(cb interface{}) *Message { list := []*Context{m.target} for i := 0; i < len(list); i++ { - cb(list[i].context, list[i]) + switch cb := cb.(type) { + case func(*Context, *Context): + cb(list[i].context, list[i]) + case func(*Context, *Context, string, *Command): + ls := []string{} + for k := range list[i].Commands { + ls = append(ls, k) + } + sort.Strings(ls) + for _, k := range ls { + cb(list[i].context, list[i], k, list[i].Commands[k]) + } + case func(*Context, *Context, string, *Config): + ls := []string{} + for k := range list[i].Configs { + ls = append(ls, k) + } + 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 { @@ -601,6 +623,15 @@ func (m *Message) Runs(key string, cmd string, arg ...string) *Message { } return m } +func (m *Message) Done() bool { + defer func() { recover() }() + if m.target.context != nil && m.target.context.wg != nil { + m.target.context.wg.Done() + } else { + m.target.root.wg.Done() + } + return true +} func (m *Message) Start(key string, arg ...string) *Message { m.Travel(func(p *Context, s *Context) { if s.Name == key {