diff --git a/base/aaa/aaa.go b/base/aaa/aaa.go index 6861c815..c2bcd59d 100644 --- a/base/aaa/aaa.go +++ b/base/aaa/aaa.go @@ -3,19 +3,29 @@ package aaa import ( "github.com/shylinux/icebergs" "github.com/shylinux/toolkits" + "math" "strings" ) +func distance(lat1, long1, lat2, long2 float64) float64 { + lat1 = lat1 * math.Pi / 180 + long1 = long1 * math.Pi / 180 + lat2 = lat2 * math.Pi / 180 + long2 = long2 * math.Pi / 180 + return 2 * 6371 * math.Asin(math.Sqrt(math.Pow(math.Sin(math.Abs(lat1-lat2)/2), 2)+math.Cos(lat1)*math.Cos(lat2)*math.Pow(math.Sin(math.Abs(long1-long2)/2), 2))) +} + 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_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")}, }, 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", "aaa.json") + m.Cmd(ice.CTX_CONFIG, "load", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json")) // 权限索引 m.Conf(ice.AAA_ROLE, "black.tech.meta.short", "chain") m.Conf(ice.AAA_ROLE, "white.tech.meta.short", "chain") @@ -23,7 +33,47 @@ 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", "aaa.json", ice.AAA_ROLE, ice.AAA_USER, ice.AAA_SESS) + 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"), + ) + }}, + "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{}) { + m.Push("", value) + }) + return + } + if len(arg) == 1 { + m.Richs("location", nil, arg[0], func(key string, value map[string]interface{}) { + m.Info("what %v", value) + m.Push("detail", value) + }) + return + } + if len(arg) == 2 { + m.Richs("aaa.location", nil, "*", func(key string, value map[string]interface{}) { + m.Push("name", value["name"]) + m.Push("distance", kit.Int(distance( + float64(kit.Int(arg[0]))/100000, + float64(kit.Int(arg[1]))/100000, + float64(kit.Int(value["latitude"]))/100000, + float64(kit.Int(value["longitude"]))/100000, + )*1000)) + }) + m.Sort("distance", "int") + return + } + + data := m.Richs("location", nil, arg[0], nil) + if data != nil { + data["count"] = kit.Int(data["count"]) + 1 + } else { + data = kit.Dict("name", arg[0], "address", arg[1], "latitude", arg[2], "longitude", arg[3], "count", 1) + m.Rich("location", nil, data) + } + m.Grow("location", nil, data) }}, ice.AAA_ROLE: {Name: "role", Help: "角色", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { diff --git a/base/ssh/ssh.go b/base/ssh/ssh.go index 8d51eae0..5613355c 100644 --- a/base/ssh/ssh.go +++ b/base/ssh/ssh.go @@ -71,6 +71,14 @@ func (f *Frame) parse(m *ice.Message, line string) *Frame { if len(ls) == 0 { continue } + if m.Option("scan_mode") == "scan" { + f.printf(m, ls[0]) + f.printf(m, "`") + f.printf(m, strings.Join(ls[1:], "` `")) + f.printf(m, "`") + f.printf(m, "\n") + continue + } // 命令替换 if alias, ok := m.Optionv(ice.MSG_ALIAS).(map[string]interface{}); ok { @@ -201,7 +209,7 @@ var Index = &ice.Context{Name: "ssh", Help: "终端模块", f.parse(m, kit.Format(value["line"])) }) }}, - "scan": {Name: "scan", Help: "解析", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + "scan": {Name: "scan name help file", Help: "解析", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { buf := bytes.NewBuffer(make([]byte, 4096)) m.Optionv(ice.MSG_STDOUT, buf) diff --git a/base/web/web.go b/base/web/web.go index cbf0606e..59bbcfed 100644 --- a/base/web/web.go +++ b/base/web/web.go @@ -409,8 +409,6 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", } }}, ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Done() - m.Done() p := m.Conf(ice.WEB_CACHE, "meta.store") m.Richs(ice.WEB_CACHE, nil, "*", func(key string, value map[string]interface{}) { if f, _, e := kit.Create(path.Join(p, key[:2], key)); e == nil { @@ -419,7 +417,15 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", } }) // m.Conf(ice.WEB_CACHE, "hash", kit.Dict()) - m.Cmd(ice.CTX_CONFIG, "save", "web.json", ice.WEB_SPIDE, ice.WEB_FAVOR, ice.WEB_CACHE, ice.WEB_STORY, ice.WEB_SHARE) + 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.Done() + m.Richs(ice.WEB_SPACE, nil, "*", func(key string, value map[string]interface{}) { + if kit.Format(value["type"]) == "master" { + m.Done() + } + }) }}, ice.WEB_SPIDE: {Name: "spide", Help: "蜘蛛侠", List: kit.List( @@ -649,27 +655,35 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", }) } }}, - ice.WEB_SERVE: {Name: "serve", Help: "服务器", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + ice.WEB_SERVE: {Name: "serve [shy|dev|self]", Help: "服务器", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { // 节点信息 m.Conf(ice.CLI_RUNTIME, "node.name", m.Conf(ice.CLI_RUNTIME, "boot.hostname")) m.Conf(ice.CLI_RUNTIME, "node.type", ice.WEB_SERVER) - // 启动服务 - switch kit.Select("self", arg, 0) { + switch kit.Select("def", arg, 0) { + case "shy": + // 连接根服务 + m.Richs(ice.WEB_SPIDE, nil, "shy", func(key string, value map[string]interface{}) { + m.Cmd(ice.WEB_SPACE, "connect", "shy") + }) + fallthrough case "dev": + // 系统初始化 m.Event(ice.SYSTEM_INIT) fallthrough case "self": + // 启动服务 m.Target().Start(m, "self") fallthrough default: + // 连接上游服务 m.Richs(ice.WEB_SPIDE, nil, "dev", func(key string, value map[string]interface{}) { m.Cmd(ice.WEB_SPACE, "connect", "dev") }) } }}, ice.WEB_SPACE: {Name: "space", Help: "空间站", Meta: kit.Dict("exports", []string{"pod", "name"}), List: kit.List( - kit.MDB_INPUT, "text", "name", "pod", + kit.MDB_INPUT, "text", "name", "name", kit.MDB_INPUT, "button", "value", "查看", "action", "auto", kit.MDB_INPUT, "button", "value", "返回", "cb", "Last", ), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { diff --git a/conf.go b/conf.go index b23d8f95..80d69b84 100644 --- a/conf.go +++ b/conf.go @@ -131,7 +131,7 @@ const ( // MDB ) const ( // APP - APP_NOTE = "note" + APP_MIND = "mind" APP_MISS = "miss" ) const ( // ROLE @@ -218,8 +218,8 @@ var Alias = map[string]string{ CHAT_RIVER: "web.chat.river", - APP_NOTE: "web.wiki.note", APP_MISS: "web.team.miss", + APP_MIND: "web.wiki.mind", "compile": "web.code.compile", "publish": "web.code.publish", diff --git a/core/chat/chat.go b/core/chat/chat.go index 306af112..6c3fac4c 100644 --- a/core/chat/chat.go +++ b/core/chat/chat.go @@ -35,7 +35,7 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心", 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") @@ -319,6 +319,23 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心", } }) + // 命令补全 + if len(cmds) > 1 && cmds[1] == "action" { + switch cmds[2] { + case "location": + // 记录位置 + m.Cmdy("aaa.location", cmds[3:]) + return + case "input": + switch cmds[3] { + case "location": + // 查询位置 + m.Copy(m.Cmd("aaa.location"), "append", "name") + return + } + } + } + // 执行命令 if m.Right(cmds) { m.Cmdy(cmds).Option("cmds", cmds) diff --git a/core/team/team.go b/core/team/team.go index 457f95b0..b1f4282e 100644 --- a/core/team/team.go +++ b/core/team/team.go @@ -14,31 +14,21 @@ import ( var Index = &ice.Context{Name: "team", Help: "团队中心", Caches: map[string]*ice.Cache{}, Configs: map[string]*ice.Config{ - ice.APP_MISS: {Name: "miss", Help: "任务", Value: kit.Data(kit.MDB_SHORT, "miss", - "mis", []interface{}{"已取消", "准备中", "开发中", "测试中", "发布中", "已完成"}, "fsm", kit.Dict( - "准备中", kit.Dict("next", "开发中"), - "开发中", kit.Dict("next", "测试中", "prev", "准备中"), - "测试中", kit.Dict("next", "发布中", "prev", "开发中"), - "发布中", kit.Dict("next", "已完成", "prev", "测试中"), - "已完成", kit.Dict(), - "已取消", kit.Dict(), - ), - )}, - "plan": {Name: "plan", Help: "计划", Value: kit.Data()}, + "task": {Name: "task", Help: "任务", Value: kit.Data(kit.MDB_SHORT, "zone")}, + "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.Watch(ice.MISS_CREATE, ice.APP_MISS) m.Cmd(ice.CTX_CONFIG, "load", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json")) }}, 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), ice.APP_MISS)) + m.Cmd(ice.CTX_CONFIG, "save", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json"), kit.Keys(m.Cap(ice.CTX_FOLLOW), "task")) }}, - ice.APP_MISS: {Name: "miss", Help: "任务", Meta: kit.Dict("remote", "you"), List: kit.List( - kit.MDB_INPUT, "text", "name", "miss", "action", "auto", + "task": {Name: "task", 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", - kit.MDB_INPUT, "button", "name", "查看", + kit.MDB_INPUT, "button", "name", "查看", "action", "auto", kit.MDB_INPUT, "button", "name", "返回", "cb", "Last", ), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Option("cache.limit", "10000") @@ -46,7 +36,7 @@ var Index = &ice.Context{Name: "team", Help: "团队中心", if len(arg) > 0 && arg[0] == "action" { switch arg[1] { case "modify": - m.Richs(cmd, nil, m.Option("miss"), func(key string, account map[string]interface{}) { + m.Richs(cmd, nil, m.Option("zone"), func(key string, account map[string]interface{}) { m.Grows(cmd, kit.Keys("hash", key), "id", arg[5], func(index int, current map[string]interface{}) { kit.Value(current, arg[2], arg[3]) }) @@ -65,8 +55,8 @@ var Index = &ice.Context{Name: "team", Help: "团队中心", if m.Richs(cmd, nil, arg[0], nil) == nil { // 添加任务 - m.Rich(cmd, nil, kit.Data("miss", arg[0])) - m.Log(ice.LOG_CREATE, "miss: %s", arg[0]) + m.Rich(cmd, nil, kit.Data("zone", arg[0])) + m.Log(ice.LOG_CREATE, "zone: %s", arg[0]) } m.Richs(cmd, nil, arg[0], func(key string, value map[string]interface{}) { @@ -110,10 +100,17 @@ var Index = &ice.Context{Name: "team", Help: "团队中心", "begin_time", m.Time(), "close_time", m.Time(), "status", "prepare", "extra", extra, ) + + count := kit.Int(m.Conf("task", kit.Keys("meta.word", "type", arg[2]))) + m.Conf("task", kit.Keys("meta.word", "type", arg[2]), count+1) + count = kit.Int(m.Conf("task", kit.Keys("meta.word", "name", arg[3]))) + m.Conf("task", kit.Keys("meta.word", "name", arg[3]), count+1) + for i := 5; i < len(arg); i += 2 { - if arg[i] == "time" { + switch arg[i] { + case "begin_time", "close_time", "status": kit.Value(data, arg[i], arg[i+1]) - } else { + default: kit.Value(extra, arg[i], arg[i+1]) } } @@ -124,10 +121,10 @@ var Index = &ice.Context{Name: "team", Help: "团队中心", "plan": {Name: "plan day|week|month|year", Help: "计划", Meta: kit.Dict("display", "team/plan"), List: kit.List( kit.MDB_INPUT, "select", "name", "scale", "values", []string{"day", "week", "month"}, "action", "auto", kit.MDB_INPUT, "text", "name", "begin_time", "action", "auto", "figure", "date", - kit.MDB_INPUT, "button", "name", "查看", + kit.MDB_INPUT, "button", "name", "查看", "action", "auto", ), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if len(arg) == 0 { - arg = append(arg, "week") + arg = append(arg, "day") } // 起始日期 @@ -147,11 +144,14 @@ var Index = &ice.Context{Name: "team", Help: "团队中心", switch arg[0] { case "action": switch arg[1] { + case "insert": + m.Cmdy("task", arg[2], "", arg[3:]) + case "modify": switch arg[2] { case "begin_time": - m.Richs(ice.APP_MISS, nil, arg[6], func(key string, value map[string]interface{}) { - m.Grows(ice.APP_MISS, kit.Keys("hash", key), "id", arg[5], func(index int, value map[string]interface{}) { + m.Richs("task", nil, arg[6], func(key string, value map[string]interface{}) { + m.Grows("task", kit.Keys("hash", key), "id", arg[5], func(index int, value map[string]interface{}) { m.Log(ice.LOG_MODIFY, "%s: %s begin_time: %s", arg[6], arg[5], arg[3]) value["begin_time"] = arg[3] }) @@ -162,15 +162,15 @@ var Index = &ice.Context{Name: "team", Help: "团队中心", case "day": for i := 6; i < 24; i++ { m.Push("hour", i) - m.Push("miss", "") + m.Push("task", "") } match := first.Format("2006-01-02") - m.Richs(ice.APP_MISS, nil, "*", func(key string, value map[string]interface{}) { - m.Grows(ice.APP_MISS, kit.Keys("hash", key), "", "", func(index int, value 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 now := kit.Format(value["begin_time"]); strings.Split(now, " ")[0] == match { m.Push("hour", strings.Split(now, " ")[1][:2]) - m.Push("miss", kit.Format(`
%s: %s
`, + m.Push("task", kit.Format(`
%s: %s
`, key, kit.Int(value["id"]), value["begin_time"], value["name"], value["text"])) } }) @@ -183,8 +183,8 @@ var Index = &ice.Context{Name: "team", Help: "团队中心", list := map[int][]map[string]interface{}{} name := map[int][]string{} - m.Richs(ice.APP_MISS, nil, "*", func(key string, value map[string]interface{}) { - m.Grows(ice.APP_MISS, kit.Keys("hash", key), "", "", func(index int, value 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 t.After(one) && t.Before(end) { index := t.Hour()*10 + int(t.Weekday()) @@ -201,7 +201,7 @@ var Index = &ice.Context{Name: "team", Help: "团队中心", index := i*10 + int(t.Weekday()) note := []string{} for i, v := range list[index] { - note = append(note, kit.Format(`
%s
`, + note = append(note, kit.Format(`
%s
`, name[index][i], kit.Int(v["id"]), v["begin_time"], v["text"], v["name"])) } m.Push(meta[int(t.Weekday())], strings.Join(note, "")) @@ -214,8 +214,8 @@ var Index = &ice.Context{Name: "team", Help: "团队中心", end := last.AddDate(0, 1, -last.Day()+1) list := map[string][]map[string]interface{}{} - m.Richs(ice.APP_MISS, nil, "*", func(key string, value map[string]interface{}) { - m.Grows(ice.APP_MISS, kit.Keys("hash", key), "", "", func(index int, value 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 t.After(one) && t.Before(end) { index := t.Format("2006-01-02") @@ -261,12 +261,12 @@ var Index = &ice.Context{Name: "team", Help: "团队中心", } }}, "stat": {Name: "stat", Help: "统计", Meta: kit.Dict(), Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { - m.Richs(ice.APP_MISS, nil, kit.Select("*", arg, 0), func(key string, value map[string]interface{}) { + m.Richs("task", nil, kit.Select("*", arg, 0), func(key string, value map[string]interface{}) { stat := map[string]int{} - m.Grows(ice.APP_MISS, kit.Keys("hash", key), "", "", func(index int, value map[string]interface{}) { + m.Grows("task", kit.Keys("hash", key), "", "", func(index int, value map[string]interface{}) { stat[kit.Format(value["status"])] += 1 }) - m.Push("miss", kit.Value(value, "meta.miss")) + m.Push("task", kit.Value(value, "meta.task")) for _, k := range []string{"prepare", "process", "cancel", "finish"} { m.Push(k, stat[k]) } @@ -366,6 +366,42 @@ var Index = &ice.Context{Name: "team", Help: "团队中心", }) }) }}, + + "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.Cmd("task", arg[0], "", arg[1:]) + m.Cmdy("task", arg[0]) + }}, }, } diff --git a/core/wiki/wiki.go b/core/wiki/wiki.go index 15762f28..5131a5d5 100644 --- a/core/wiki/wiki.go +++ b/core/wiki/wiki.go @@ -31,6 +31,7 @@ var Index = &ice.Context{Name: "wiki", Help: "文档中心", "premenu": []interface{}{"title", "premenu"}, }, )}, + "title": {Name: "title", Help: "标题", Value: kit.Data("template", title)}, "brief": {Name: "brief", Help: "摘要", Value: kit.Data("template", brief)}, "refer": {Name: "refer", Help: "参考", Value: kit.Data("template", refer)}, @@ -43,8 +44,8 @@ var Index = &ice.Context{Name: "wiki", Help: "文档中心", "stack": {Name: "stack", Help: "结构", Value: kit.Data("template", stack)}, "chart": {Name: "chart", Help: "绘图", Value: kit.Data("prefix", prefix, "suffix", ``)}, - "mind": {Name: "mind", Help: "思维导图", Value: kit.Data(kit.MDB_SHORT, "name", "path", "usr/local", "regs", ".*\\.svg", "prefix", ``, "suffix", ``)}, - "word": {Name: "word", Help: "语言文字", Value: kit.Data(kit.MDB_SHORT, "name", "path", "usr/local", "regs", ".*\\.shy")}, + "draw": {Name: "draw", Help: "思维导图", Value: kit.Data(kit.MDB_SHORT, "name", "path", "usr/local", "regs", ".*\\.svg", "prefix", ``, "suffix", ``)}, + "word": {Name: "word", Help: "语言文字", Value: kit.Data(kit.MDB_SHORT, "name", "path", "usr/learning", "regs", ".*\\.shy")}, "data": {Name: "data", Help: "数据表格", Value: kit.Data(kit.MDB_SHORT, "name", "path", "usr/local", "regs", ".*\\.csv")}, "feel": {Name: "feel", Help: "影音媒体", Value: kit.Data(kit.MDB_SHORT, "name", "path", "usr/local", "regs", ".*\\.(png|JPG|MOV|m4v)")}, "walk": {Name: "walk", Help: "走遍世界", Value: kit.Data(kit.MDB_SHORT, "name", "path", "usr/local", "regs", ".*\\.csv")}, @@ -58,6 +59,243 @@ var Index = &ice.Context{Name: "wiki", Help: "文档中心", m.Cmd(ice.CTX_CONFIG, "save", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json"), kit.Keys(m.Cap(ice.CTX_FOLLOW), "feel")) }}, + "note": {Name: "note file", Help: "笔记", Meta: kit.Dict("remote", "you", "display", "inner"), List: kit.List( + kit.MDB_INPUT, "text", "name", "path", "value", "README.md", + kit.MDB_INPUT, "button", "name", "执行", "action", "auto", + kit.MDB_INPUT, "button", "name", "返回", "cb", "Last", + ), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if len(arg) > 1 { + switch arg[1] { + case "运行": + switch arg[2] { + case "shell": + m.Cmdy(ice.CLI_SYSTEM, "sh", "-c", arg[4]) + } + + case "favor": + m.Cmdy(ice.WEB_FAVOR, kit.Select("story", m.Option("hot")), arg[2:]) + case "share": + m.Cmdy(ice.WEB_SHARE, "add", arg[2:]) + default: + m.Cmdy(arg) + } + return + } + if len(arg) > 0 && strings.HasSuffix(arg[0], ".md") { + arg[0] = path.Join(m.Conf("note", "meta.path"), arg[0]) + } + 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_reg", ".*\\.md") + m.Cmdy("nfs.dir", kit.Select(m.Conf("note", "meta.path"), arg, 0), m.Conf("note", "meta.head")) + }}, + "_text": {Name: "_text file", Help: "文章", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Option(ice.WEB_TMPL, "raw") + m.Optionv("title", map[string]int{}) + m.Optionv("menu", map[string]interface{}{"list": []interface{}{}}) + if strings.HasSuffix(arg[0], ".shy") { + m.Optionv(ice.MSG_ALIAS, m.Confv("note", "meta.alias")) + m.Cmdy("ssh.scan", arg[0], arg[0], arg[0]) + return + } + + // 生成文章 + buffer := bytes.NewBuffer([]byte{}) + f := m.Target().Server().(*web.Frame) + tmpl := f.HandleCGI(m, m.Confm("note", ice.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 { + defer f.Close() + if n, e := f.Write(buffer.Bytes()); e == nil { + m.Log("info", "save %d %v", n, p) + } + } + + // 生成网页 + data := buffer.Bytes() + // if strings.HasSuffix(arg[0], ".md") { + data = markdown.ToHTML(buffer.Bytes(), nil, nil) + // } + m.Echo(string(data)) + }}, + + "title": {Name: "title [chapter|section|endmenu|premenu] text", Help: "标题", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + title, _ := m.Optionv("title").(map[string]int) + switch arg[0] { + case "endmenu": + // 后置目录 + m.Render(endmenu) + return + case "premenu": + // 前置目录 + m.Render(premenu) + return + case "section": + arg = arg[1:] + title["section"]++ + m.Option("level", "h3") + m.Option("prefix", fmt.Sprintf("%d.%d", title["chapter"], title["section"])) + case "chapter": + arg = arg[1:] + title["chapter"]++ + title["section"] = 0 + m.Option("level", "h2") + m.Option("prefix", fmt.Sprintf("%d", title["chapter"])) + default: + m.Option("level", "h1") + m.Option("prefix", "") + } + m.Option(kit.MDB_TYPE, cmd) + m.Option(kit.MDB_NAME, arg[0]) + m.Option(kit.MDB_TEXT, arg[0]) + + // 添加目录 + ns := strings.Split(m.Conf("runtime", "node.name"), "-") + menu, _ := m.Optionv("menu").(map[string]interface{}) + menu["list"] = append(menu["list"].([]interface{}), map[string]interface{}{ + "content": m.Option("content", kit.Select(ns[len(ns)-1], arg, 0)), + "prefix": m.Option("prefix"), + "level": m.Option("level"), + }) + + // 生成网页 + m.Render(m.Conf("title", "meta.template")) + }}, + "brief": {Name: "brief name text", Help: "摘要", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Option(kit.MDB_TYPE, cmd) + m.Option(kit.MDB_NAME, arg[0]) + m.Option(kit.MDB_TEXT, arg[1]) + m.Render(m.Conf(cmd, "meta.template")) + }}, + "refer": {Name: "refer name text", Help: "参考", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Option(kit.MDB_TYPE, cmd) + m.Option(kit.MDB_NAME, arg[0]) + m.Option(kit.MDB_TEXT, arg[1]) + + list := [][]string{} + for _, v := range kit.Split(strings.TrimSpace(arg[1]), "\n") { + list = append(list, kit.Split(v, " ")) + } + m.Optionv("list", list) + m.Render(m.Conf(cmd, "meta.template")) + }}, + "spark": {Name: "spark name text", Help: "感悟", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if len(arg) == 0 { + m.Echo(`
`) + return + } + if len(arg) == 1 { + arg = []string{"", arg[0]} + } + + m.Option(kit.MDB_TYPE, cmd) + m.Option(kit.MDB_NAME, arg[0]) + m.Option(kit.MDB_TEXT, arg[1]) + m.Optionv("list", kit.Split(arg[1], "\n")) + m.Render(m.Conf(cmd, "meta.template")) + }}, + + "local": {Name: "local name text", Help: "文件", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Option(kit.MDB_TYPE, cmd) + m.Option(kit.MDB_NAME, arg[0]) + m.Option(kit.MDB_TEXT, arg[1]) + m.Option("input", m.Cmdx("nfs.cat", arg[1])) + + switch ls := strings.Split(arg[1], "."); ls[len(ls)-1] { + case "csv": + list := []string{""} + m.Spawn().CSV(m.Option("input")).Table(func(index int, value map[string]string, head []string) { + if index == 0 { + list = append(list, "") + for _, k := range head { + list = append(list, "") + } + list = append(list, "") + } + + list = append(list, "") + for _, k := range head { + list = append(list, "") + } + list = append(list, "") + }) + list = append(list, "
", k, "
", value[k], "
") + m.Optionv("input", list) + } + m.Render(m.Conf(cmd, "meta.template")) + }}, + "shell": {Name: "shell name dir cmd", Help: "命令", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Option(kit.MDB_TYPE, cmd) + m.Option(kit.MDB_NAME, arg[0]) + m.Option("cmd_dir", arg[1]) + + input, output := "", "" + switch arg = arg[2:]; arg[0] { + case "install", "compile": + input = strings.Join(arg[1:], " ") + default: + input = strings.Join(arg, " ") + output = m.Cmdx(ice.CLI_SYSTEM, "sh", "-c", input) + } + + m.Option("input", input) + m.Option("output", output) + m.Render(m.Conf(cmd, "meta.template")) + }}, + "order": {Name: "order name text", Help: "列表", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Option(kit.MDB_TYPE, cmd) + m.Option(kit.MDB_NAME, arg[0]) + m.Option(kit.MDB_TEXT, arg[1]) + m.Optionv("list", kit.Split(strings.TrimSpace(arg[1]), "\n")) + m.Render(m.Conf(cmd, "meta.template")) + }}, + "table": {Name: "table name text", Help: "表格", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Option(kit.MDB_TYPE, cmd) + m.Option(kit.MDB_NAME, arg[0]) + m.Option(kit.MDB_TEXT, arg[1]) + + head, list := []string{}, [][]string{} + for i, v := range kit.Split(strings.TrimSpace(arg[1]), "\n") { + if i == 0 { + head = kit.Split(v) + } else { + line := kit.Split(v) + for i, v := range line { + if ls := kit.Split(v); len(ls) > 1 { + style := []string{} + for i := 1; i < len(ls)-1; i += 2 { + switch ls[i] { + case "bg": + ls[i] = "background-color" + case "fg": + ls[i] = "color" + } + style = append(style, ls[i]+":"+ls[i+1]) + } + line[i] = kit.Format(`%s`, strings.Join(style, ";"), ls[0]) + } + } + list = append(list, line) + } + } + m.Optionv("head", head) + m.Optionv("list", list) + m.Render(m.Conf(cmd, "meta.template")) + }}, + "stack": {Name: "stack name text", Help: "结构", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Option(kit.MDB_TYPE, cmd) + m.Option(kit.MDB_NAME, arg[0]) + m.Option(kit.MDB_TEXT, arg[1]) + + chain := &Chain{} + m.Render(m.Conf(cmd, "meta.template")) + 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( @@ -101,224 +339,8 @@ var Index = &ice.Context{Name: "wiki", Help: "文档中心", chart.Draw(m, 4, 4) m.Render(m.Conf("chart", ice.Meta("suffix"))) }}, - "stack": {Name: "stack name text", Help: "结构", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Option(kit.MDB_TYPE, cmd) - m.Option(kit.MDB_NAME, arg[0]) - m.Option(kit.MDB_TEXT, arg[1]) - chain := &Chain{} - m.Render(m.Conf(cmd, "meta.template")) - Stack(m, cmd, 0, kit.Parse(nil, "", chain.show(m, arg[1])...)) - m.Echo("") - }}, - "table": {Name: "table name text", Help: "表格", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Option(kit.MDB_TYPE, cmd) - m.Option(kit.MDB_NAME, arg[0]) - m.Option(kit.MDB_TEXT, arg[1]) - - head, list := []string{}, [][]string{} - for i, v := range kit.Split(strings.TrimSpace(arg[1]), "\n") { - if i == 0 { - head = kit.Split(v) - } else { - list = append(list, kit.Split(v)) - } - } - m.Optionv("head", head) - m.Optionv("list", list) - m.Render(m.Conf(cmd, "meta.template")) - }}, - "order": {Name: "order name text", Help: "列表", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Option(kit.MDB_TYPE, cmd) - m.Option(kit.MDB_NAME, arg[0]) - m.Option(kit.MDB_TEXT, arg[1]) - m.Optionv("list", kit.Split(strings.TrimSpace(arg[1]), "\n")) - m.Render(m.Conf(cmd, "meta.template")) - }}, - "shell": {Name: "shell name dir cmd", Help: "命令", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Option(kit.MDB_TYPE, cmd) - m.Option(kit.MDB_NAME, arg[0]) - m.Option("cmd_dir", arg[1]) - - input, output := "", "" - switch arg = arg[2:]; arg[0] { - case "install", "compile": - input = strings.Join(arg[1:], " ") - default: - input = strings.Join(arg, " ") - output = m.Cmdx(ice.CLI_SYSTEM, "sh", "-c", input) - } - - m.Option("input", input) - m.Option("output", output) - m.Render(m.Conf(cmd, "meta.template")) - }}, - "local": {Name: "local name text", Help: "文件", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Option(kit.MDB_TYPE, cmd) - m.Option(kit.MDB_NAME, arg[0]) - m.Option(kit.MDB_TEXT, arg[1]) - m.Option("input", m.Cmdx("nfs.cat", arg[1])) - - switch ls := strings.Split(arg[1], "."); ls[len(ls)-1] { - case "csv": - list := []string{""} - m.Spawn().CSV(m.Option("input")).Table(func(index int, value map[string]string, head []string) { - if index == 0 { - list = append(list, "") - for _, k := range head { - list = append(list, "") - } - list = append(list, "") - } - - list = append(list, "") - for _, k := range head { - list = append(list, "") - } - list = append(list, "") - }) - list = append(list, "
", k, "
", value[k], "
") - m.Optionv("input", list) - } - m.Render(m.Conf(cmd, "meta.template")) - }}, - - "spark": {Name: "spark name text", Help: "感悟", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Option(kit.MDB_TYPE, cmd) - m.Option(kit.MDB_NAME, arg[0]) - m.Option(kit.MDB_TEXT, arg[1]) - m.Optionv("list", kit.Split(arg[1], "\n")) - m.Render(m.Conf(cmd, "meta.template")) - }}, - "refer": {Name: "refer name text", Help: "参考", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Option(kit.MDB_TYPE, cmd) - m.Option(kit.MDB_NAME, arg[0]) - m.Option(kit.MDB_TEXT, arg[1]) - - list := [][]string{} - for _, v := range kit.Split(strings.TrimSpace(arg[1]), "\n") { - list = append(list, kit.Split(v, " ")) - } - m.Optionv("list", list) - m.Render(m.Conf(cmd, "meta.template")) - }}, - "brief": {Name: "brief name text", Help: "摘要", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Option(kit.MDB_TYPE, cmd) - m.Option(kit.MDB_NAME, arg[0]) - m.Option(kit.MDB_TEXT, arg[1]) - m.Render(m.Conf(cmd, "meta.template")) - }}, - "title": {Name: "title [chapter|section|endmenu|premenu] text", Help: "标题", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - title, _ := m.Optionv("title").(map[string]int) - switch arg[0] { - case "endmenu": - // 后置目录 - m.Render(endmenu) - return - case "premenu": - // 前置目录 - m.Render(premenu) - return - case "section": - arg = arg[1:] - title["section"]++ - m.Option("level", "h3") - m.Option("prefix", fmt.Sprintf("%d.%d", title["chapter"], title["section"])) - case "chapter": - arg = arg[1:] - title["chapter"]++ - title["section"] = 0 - m.Option("level", "h2") - m.Option("prefix", fmt.Sprintf("%d", title["chapter"])) - default: - m.Option("level", "h1") - m.Option("prefix", "") - } - m.Option(kit.MDB_TYPE, cmd) - m.Option(kit.MDB_NAME, arg[0]) - m.Option(kit.MDB_TEXT, arg[0]) - - // 添加目录 - ns := strings.Split(m.Conf("runtime", "node.name"), "-") - menu, _ := m.Optionv("menu").(map[string]interface{}) - menu["list"] = append(menu["list"].([]interface{}), map[string]interface{}{ - "content": m.Option("content", kit.Select(ns[len(ns)-1], arg, 0)), - "prefix": m.Option("prefix"), - "level": m.Option("level"), - }) - - // 生成网页 - m.Render(m.Conf("title", "meta.template")) - }}, - - "index": {Name: "index hash", Help: "索引", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Cmd(ice.WEB_STORY, "index", arg) - }}, - "_text": {Name: "_text file", Help: "文章", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Option(ice.WEB_TMPL, "raw") - m.Optionv("title", map[string]int{}) - m.Optionv("menu", map[string]interface{}{"list": []interface{}{}}) - if strings.HasSuffix(arg[0], ".shy") { - m.Optionv(ice.MSG_ALIAS, m.Confv("note", "meta.alias")) - m.Cmdy("ssh.scan", arg[0], arg[0], arg[0]) - return - } - - // 生成文章 - buffer := bytes.NewBuffer([]byte{}) - f := m.Target().Server().(*web.Frame) - tmpl := f.HandleCGI(m, m.Confm("note", ice.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 { - defer f.Close() - if n, e := f.Write(buffer.Bytes()); e == nil { - m.Log("info", "save %d %v", n, p) - } - } - - // 生成网页 - data := buffer.Bytes() - // if strings.HasSuffix(arg[0], ".md") { - data = markdown.ToHTML(buffer.Bytes(), nil, nil) - // } - m.Echo(string(data)) - }}, - "_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_reg", ".*\\.md") - m.Cmdy("nfs.dir", kit.Select(m.Conf("note", "meta.path"), arg, 0), m.Conf("note", "meta.head")) - }}, - "note": {Name: "note file", Help: "笔记", Meta: kit.Dict("remote", "you", "display", "inner"), List: kit.List( - kit.MDB_INPUT, "text", "name", "path", "value", "README.md", - kit.MDB_INPUT, "button", "name", "执行", "action", "auto", - kit.MDB_INPUT, "button", "name", "返回", "cb", "Last", - ), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - if len(arg) > 1 { - switch arg[1] { - case "运行": - switch arg[2] { - case "shell": - m.Cmdy(ice.CLI_SYSTEM, "sh", "-c", arg[4]) - } - - case "favor": - m.Cmdy(ice.WEB_FAVOR, kit.Select("story", m.Option("hot")), arg[2:]) - case "share": - m.Cmdy(ice.WEB_SHARE, "add", arg[2:]) - default: - m.Cmdy(arg) - } - return - } - if len(arg) > 0 && strings.HasSuffix(arg[0], ".md") { - arg[0] = path.Join(m.Conf("note", "meta.path"), arg[0]) - } - m.Cmdy(kit.Select("_tree", "_text", len(arg) > 0 && strings.HasSuffix(arg[0], ".md")), arg) - }}, - - "mind": {Name: "mind", Help: "思维导图", Meta: kit.Dict("display", "wiki/mind"), List: kit.List( + "draw": {Name: "draw", Help: "思维导图", Meta: kit.Dict("display", "wiki/draw"), List: kit.List( kit.MDB_INPUT, "text", "name", "name", "value", "what/he.svg", kit.MDB_INPUT, "button", "name", "执行", "action", "auto", kit.MDB_INPUT, "button", "name", "返回", "cb", "Last", @@ -363,6 +385,32 @@ var Index = &ice.Context{Name: "wiki", Help: "文档中心", if len(arg) > 0 && arg[0] == "action" { switch arg[1] { + case "追加": + if f, e := os.OpenFile(path.Join(m.Conf(cmd, "meta.path"), arg[2]), os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666); m.Assert(e) { + defer f.Close() + f.WriteString("\n") + f.WriteString(arg[3]) + + if len(arg) > 4 { + f.WriteString(` "`) + f.WriteString(arg[4]) + f.WriteString(`"`) + } + if len(arg) > 5 { + f.WriteString(" `") + f.WriteString(arg[5]) + f.WriteString("`") + } + for _, v := range arg[6:] { + f.WriteString(" `") + f.WriteString(v) + f.WriteString("`") + } + + f.WriteString("\n") + f.WriteString("\n") + } + case "保存": m.Cmd("nfs.save", path.Join(m.Conf(cmd, "meta.path"), arg[2]), arg[3]) } @@ -499,6 +547,50 @@ var Index = &ice.Context{Name: "wiki", Help: "文档中心", m.Option("title", "我走过的世界") m.CSV(m.Result()) }}, + + "mind": {Name: "mind zone type name text", Help: "思考", List: kit.List( + kit.MDB_INPUT, "text", "name", "path", "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, cmd string, arg ...string) { + if len(arg) > 0 && arg[0] == "action" { + switch arg[1] { + case "input": + // 输入补全 + switch arg[2] { + case "type": + m.Push("type", []string{"spark", "label", "refer", "brief", "chapter", "section", "title"}) + case "path": + m.Option("_refresh", "true") + // 文件列表 + m.Option("dir_root", m.Conf("word", "meta.path")) + m.Option("dir_reg", m.Conf("word", "meta.regs")) + m.Cmdy("nfs.dir", kit.Select("./", arg, 3), "path") + m.Sort("time", "time_r") + if len(arg) == 3 || strings.HasSuffix(arg[3], "/") { + // 目录列表 + m.Option("dir_reg", "") + m.Option("dir_type", "dir") + m.Cmdy("nfs.dir", kit.Select("./", arg, 3), "path") + return + } + } + return + } + } + + if len(arg) < 2 { + m.Cmdy("word", arg) + return + } + + m.Cmd("word", "action", "追加", arg) + m.Option("scan_mode", "scan") + m.Cmdy("ssh.scan", "some", "some", path.Join(m.Conf("word", "meta.path"), arg[0])) + }}, }, } diff --git a/misc/git/git.go b/misc/git/git.go index 7450bd73..fcb0289d 100644 --- a/misc/git/git.go +++ b/misc/git/git.go @@ -32,6 +32,14 @@ var Index = &ice.Context{Name: "git", Help: "代码管理", "remote", m.Conf("repos", "meta.owner")+"/"+repos, )) } + m.Cmd("nfs.dir", "usr", "name path").Table(func(index int, value map[string]string, head []string) { + 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", m.Cmdx(ice.CLI_SYSTEM, "git", "remote", "get-url", "origin"), + )) + } + }) // 应用代码 m.Cmd("nfs.dir", m.Conf(ice.WEB_DREAM, "meta.path"), "name path").Table(func(index int, value map[string]string, head []string) { if s, e := os.Stat(m.Option("cmd_dir", path.Join(value["path"], ".git"))); e == nil && s.IsDir() { diff --git a/type.go b/type.go index f6cc7f54..acbce4d2 100644 --- a/type.go +++ b/type.go @@ -378,10 +378,19 @@ func (m *Message) Set(key string, arg ...string) *Message { } return m.Add(key, arg...) } -func (m *Message) Copy(msg *Message) *Message { +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) @@ -803,20 +812,25 @@ func (m *Message) Run(arg ...string) *Message { return m } func (m *Message) Hold(n int) *Message { + ctx := m.target.root if c := m.target; c.context != nil && c.context.wg != nil { - c.context.wg.Add(n) - } else { - c.root.wg.Add(n) + ctx = c.context } + + ctx.wg.Add(n) + m.Log(LOG_TRACE, "%s wait %s %v", ctx.Name, m.target.Name, ctx.wg) 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() + + ctx := m.target.root + if c := m.target; c.context != nil && c.context.wg != nil { + ctx = c.context } + + m.Log(LOG_TRACE, "%s done %s %v", ctx.Name, m.target.Name, ctx.wg) + ctx.wg.Done() return true } func (m *Message) Start(key string, arg ...string) *Message { @@ -946,7 +960,7 @@ func (m *Message) Search(key interface{}, cb interface{}) *Message { for c := p; c != nil; c = c.context { if cmd, ok := c.Configs[key]; ok { cb(c.context, c, key, cmd) - break + return m } } }