1
0
forked from x/icebergs

add inner.go

This commit is contained in:
shaoying 2020-05-28 23:00:15 +08:00
parent 7b71098b83
commit b2b608e5f7
7 changed files with 641 additions and 520 deletions

View File

@ -11,37 +11,192 @@ import (
"strings" "strings"
) )
func _parse_arg_all(m *ice.Message, arg ...string) (bool, []string) {
if len(arg) > 0 && arg[0] == "all" {
return true, arg[1:]
}
return false, arg
}
func _parse_arg_chain(m *ice.Message, arg ...string) (string, []string) {
if len(arg) > 1 {
return kit.Keys(arg[0], arg[1]), arg[2:]
}
return arg[0], arg[1:]
}
func _config_list(m *ice.Message, all bool) {
p := m.Spawn(m.Source())
if all {
p = ice.Pulse
}
p.Travel(func(p *ice.Context, s *ice.Context, key string, conf *ice.Config) {
m.Push("key", key)
m.Push("name", conf.Name)
m.Push("value", kit.Format(conf.Value))
})
}
func _config_save(m *ice.Message, name string, arg ...string) {
msg := m.Spawn(m.Source())
// 保存配置
if m.Cap(ice.CTX_STATUS) != ice.ICE_START {
return
}
name = path.Join(msg.Conf(ice.CTX_CONFIG, "meta.path"), name)
if f, p, e := kit.Create(name); m.Assert(e) {
data := map[string]interface{}{}
for _, k := range arg {
data[k] = msg.Confv(k)
}
if s, e := json.MarshalIndent(data, "", " "); m.Assert(e) {
if n, e := f.Write(s); m.Assert(e) {
m.Log("info", "save %d %s", n, p)
}
}
m.Echo(p)
}
}
func _config_load(m *ice.Message, name string, arg ...string) {
msg := m.Spawn(m.Source())
// 加载配置
name = path.Join(msg.Conf(ice.CTX_CONFIG, "meta.path"), name)
if f, e := os.Open(name); e == nil {
data := map[string]interface{}{}
json.NewDecoder(f).Decode(&data)
for k, v := range data {
msg.Search(k, func(p *ice.Context, s *ice.Context, key string) {
m.Log("info", "load %s.%s %v", s.Name, key, kit.Format(v))
s.Configs[key].Value = v
})
}
}
}
func _config_make(m *ice.Message, chain string, arg ...string) {
msg := m.Spawn(m.Source())
if len(arg) > 1 {
if strings.HasPrefix(arg[1], "@") {
msg.Conf(chain, arg[0], msg.Cmdx("nfs.cat", arg[1][1:]))
} else {
msg.Conf(chain, arg[0], kit.Parse(nil, "", arg[1:]...))
}
}
if len(arg) > 0 {
// 读取配置
m.Echo(kit.Formats(msg.Confv(chain, arg[0])))
} else {
// 读取配置
m.Echo(kit.Formats(msg.Confv(chain)))
}
}
func _command_list(m *ice.Message, all bool) {
p := m.Spawn(m.Source())
if all {
p = ice.Pulse
}
// 命令列表
p.Travel(func(p *ice.Context, s *ice.Context) {
list := []string{}
for k := range s.Commands {
if k[0] == '/' || k[0] == '_' {
// 内部命令
continue
}
list = append(list, k)
}
sort.Strings(list)
for _, k := range list {
v := s.Commands[k]
m.Push("key", s.Cap(ice.CTX_FOLLOW))
m.Push("index", k)
m.Push("name", kit.Format(v.Name))
m.Push("help", kit.Simple(v.Help)[0])
// m.Push("list", kit.Format(v.List))
}
})
}
func _command_make(m *ice.Message, cmd *ice.Command) {
var list []string
switch name := cmd.Name.(type) {
case []string, []interface{}:
list = kit.Split(kit.Simple(name)[0])
default:
list = kit.Split(strings.Split(kit.Format(name), ";")[0])
}
button := false
for i, v := range list {
if i > 0 {
switch ls := kit.Split(v, ":="); ls[0] {
case "[", "]":
case "auto":
cmd.List = append(cmd.List, kit.List(kit.MDB_INPUT, "button", "name", "查看", "value", "auto")...)
cmd.List = append(cmd.List, kit.List(kit.MDB_INPUT, "button", "name", "返回", "value", "Last")...)
button = true
default:
kind, value := "text", ""
if len(ls) == 3 {
kind, value = ls[1], ls[2]
} else if len(ls) == 2 {
if strings.Contains(v, "=") {
value = ls[1]
} else {
kind = ls[1]
}
}
if kind == "button" {
button = true
}
cmd.List = append(cmd.List, kit.List(kit.MDB_INPUT, kind, "name", ls[0], "value", value)...)
}
}
}
if len(cmd.List) == 0 {
cmd.List = append(cmd.List, kit.List(kit.MDB_INPUT, "text", "name", "name")...)
}
if !button {
cmd.List = append(cmd.List, kit.List(kit.MDB_INPUT, "button", "name", "查看")...)
cmd.List = append(cmd.List, kit.List(kit.MDB_INPUT, "button", "name", "返回", "value", "Last")...)
}
}
func _context_list(m *ice.Message, all bool) {
p := m.Spawn(m.Source())
if all {
p = ice.Pulse
}
p.Travel(func(p *ice.Context, s *ice.Context) {
if p != nil {
m.Push("ups", kit.Select("shy", p.Cap(ice.CTX_FOLLOW)))
} else {
m.Push("ups", "shy")
}
m.Push("name", s.Name)
m.Push(ice.CTX_STATUS, s.Cap(ice.CTX_STATUS))
m.Push(ice.CTX_STREAM, s.Cap(ice.CTX_STREAM))
m.Push("help", s.Help)
})
}
var Index = &ice.Context{Name: "ctx", Help: "配置模块", var Index = &ice.Context{Name: "ctx", Help: "配置模块",
Caches: map[string]*ice.Cache{}, Caches: map[string]*ice.Cache{},
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{
ice.CTX_CONFIG: {Name: "config", Help: "配置", Value: kit.Data("path", "var/conf")}, ice.CTX_CONFIG: {Name: "config", Help: "配置", Value: kit.Data("path", "var/conf")},
"demo": {Name: "demo", Help: "配置", Value: kit.Data("path", "var/conf")},
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ice.CTX_CONTEXT: {Name: "context [all]", Help: "模块", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.CTX_CONTEXT: {Name: "context [all]", Help: "模块", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
all := false if all, arg := _parse_arg_all(m, arg...); len(arg) == 0 {
if len(arg) > 0 && arg[0] == "all" { _context_list(m, all)
all, arg = true, arg[1:] return
} }
if p := m.Spawn(m.Source()); len(arg) == 0 { if len(arg) == 1 {
if all == true {
p = ice.Pulse
}
// 模块列表
p.Travel(func(p *ice.Context, s *ice.Context) {
if p != nil {
m.Push("ups", kit.Select("shy", p.Cap(ice.CTX_FOLLOW)))
} else {
m.Push("ups", "shy")
}
m.Push("name", s.Name)
m.Push(ice.CTX_STATUS, s.Cap(ice.CTX_STATUS))
m.Push(ice.CTX_STREAM, s.Cap(ice.CTX_STREAM))
m.Push("help", s.Help)
})
return
} else if len(arg) == 1 {
m.Cmdy(ice.CTX_COMMAND, arg[0]+".") m.Cmdy(ice.CTX_COMMAND, arg[0]+".")
} else { } else {
m.Search(arg[0]+".", func(p *ice.Context, s *ice.Context, key string) { m.Search(arg[0]+".", func(p *ice.Context, s *ice.Context, key string) {
@ -51,7 +206,6 @@ var Index = &ice.Context{Name: "ctx", Help: "配置模块",
msg.Cmdy(ice.CTX_COMMAND, arg[0], arg[2:]) msg.Cmdy(ice.CTX_COMMAND, arg[0], arg[2:])
case "config": case "config":
msg.Cmdy(ice.CTX_CONFIG, arg[2:]) msg.Cmdy(ice.CTX_CONFIG, arg[2:])
case "cache":
} }
m.Copy(msg) m.Copy(msg)
}) })
@ -59,45 +213,12 @@ var Index = &ice.Context{Name: "ctx", Help: "配置模块",
}}, }},
ice.CTX_COMMAND: {Name: "command [all] [context [command run arg...]]", Help: "命令", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.CTX_COMMAND: {Name: "command [all] [context [command run arg...]]", Help: "命令", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
all := false if all, arg := _parse_arg_all(m, arg...); len(arg) == 0 {
if len(arg) > 0 && arg[0] == "all" { _command_list(m, all)
all, arg = true, arg[1:]
}
if p := m.Spawn(m.Source()); len(arg) == 0 {
if all == true {
p = ice.Pulse
}
// 命令列表
p.Travel(func(p *ice.Context, s *ice.Context) {
list := []string{}
for k := range s.Commands {
if k[0] == '/' || k[0] == '_' {
// 内部命令
continue
}
list = append(list, k)
}
sort.Strings(list)
for _, k := range list {
v := s.Commands[k]
m.Push("key", s.Cap(ice.CTX_FOLLOW))
m.Push("index", k)
m.Push("name", kit.Format(v.Name))
m.Push("help", kit.Simple(v.Help)[0])
m.Push("list", kit.Format(v.List))
}
})
return return
} }
chain := arg[0] chain, arg := _parse_arg_chain(m, arg...)
if len(arg) > 1 {
chain = kit.Keys(arg[0], arg[1])
arg = arg[1:]
}
arg = arg[1:]
m.Search(chain, func(p *ice.Context, s *ice.Context, key string, cmd *ice.Command) { m.Search(chain, func(p *ice.Context, s *ice.Context, key string, cmd *ice.Command) {
if len(arg) == 0 { if len(arg) == 0 {
// 命令列表 // 命令列表
@ -106,54 +227,13 @@ var Index = &ice.Context{Name: "ctx", Help: "配置模块",
m.Push("help", kit.Simple(cmd.Help)[0]) m.Push("help", kit.Simple(cmd.Help)[0])
m.Push("meta", kit.Format(cmd.Meta)) m.Push("meta", kit.Format(cmd.Meta))
if len(cmd.List) == 0 { if len(cmd.List) == 0 {
var list []string _command_make(m, cmd)
switch name := cmd.Name.(type) {
case []string, []interface{}:
list = kit.Split(kit.Simple(name)[0])
default:
list = kit.Split(strings.Split(kit.Format(name), ";")[0])
}
button := false
for i, v := range list {
if i > 0 {
switch ls := kit.Split(v, ":="); ls[0] {
case "[", "]":
case "auto":
cmd.List = append(cmd.List, kit.List(kit.MDB_INPUT, "button", "name", "查看", "value", "auto")...)
cmd.List = append(cmd.List, kit.List(kit.MDB_INPUT, "button", "name", "返回", "value", "Last")...)
button = true
default:
kind, value := "text", ""
if len(ls) == 3 {
kind, value = ls[1], ls[2]
} else if len(ls) == 2 {
if strings.Contains(v, "=") {
value = ls[1]
} else {
kind = ls[1]
}
}
if kind == "button" {
button = true
}
cmd.List = append(cmd.List, kit.List(kit.MDB_INPUT, kind, "name", ls[0], "value", value)...)
}
}
}
if len(cmd.List) == 0 {
cmd.List = append(cmd.List, kit.List(kit.MDB_INPUT, "text", "name", "name")...)
}
if !button {
cmd.List = append(cmd.List, kit.List(kit.MDB_INPUT, "button", "name", "查看")...)
cmd.List = append(cmd.List, kit.List(kit.MDB_INPUT, "button", "name", "返回", "value", "Last")...)
}
} }
m.Push("list", kit.Format(cmd.List)) m.Push("list", kit.Format(cmd.List))
} else { } else {
if you := m.Option(kit.Format(kit.Value(cmd.Meta, "remote"))); you != "" { if you := m.Option(kit.Format(kit.Value(cmd.Meta, "remote"))); you != "" {
// 远程命令 // 远程命令
m.Copy(m.Spawns(s).Cmd(ice.WEB_SPACE, you, "ctx.command", chain, "run", arg[1:])) m.Copy(m.Spawns(s).Cmd(ice.WEB_SPACE, you, ice.CTX_COMMAND, chain, "run", arg[1:]))
} else { } else {
// 本地命令 // 本地命令
m.Copy(s.Run(m.Spawns(s), cmd, key, arg[1:]...)) m.Copy(s.Run(m.Spawns(s), cmd, key, arg[1:]...))
@ -161,75 +241,19 @@ var Index = &ice.Context{Name: "ctx", Help: "配置模块",
} }
}) })
}}, }},
ice.CTX_CONFIG: {Name: "config [all] [save|load] chain key arg...", Help: "配置", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.CTX_CONFIG: {Name: "config [all] [chain [key [arg...]]]", Help: "配置", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
all := false if all, arg := _parse_arg_all(m, arg...); len(arg) == 0 {
if len(arg) > 0 && arg[0] == "all" { _config_list(m, all)
all, arg = true, arg[1:]
}
msg := m.Spawn(m.Source())
if len(arg) == 0 {
if all == true {
msg = ice.Pulse
}
// 配置列表
msg.Travel(func(p *ice.Context, s *ice.Context, key string, conf *ice.Config) {
m.Push("key", key)
m.Push("name", conf.Name)
m.Push("value", kit.Format(conf.Value))
})
return return
} }
switch arg[0] { switch arg[0] {
case "save": case "save":
// 保存配置 _config_save(m, arg[1], arg[2:]...)
if m.Cap(ice.CTX_STATUS) != ice.ICE_START {
break
}
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:] {
data[k] = msg.Confv(k)
}
if s, e := json.MarshalIndent(data, "", " "); m.Assert(e) {
if n, e := f.Write(s); m.Assert(e) {
m.Log("info", "save %d %s", n, p)
}
}
m.Echo(p)
}
case "load": case "load":
// 加载配置 _config_load(m, arg[1], arg[2:]...)
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)
for k, v := range data {
msg.Search(k, func(p *ice.Context, s *ice.Context, key string) {
m.Log("info", "load %s.%s %v", s.Name, key, kit.Format(v))
s.Configs[key].Value = v
})
}
}
default: default:
if len(arg) > 2 { _config_make(m, arg[0], arg[1:]...)
if strings.HasPrefix(arg[2], "@") {
msg.Conf(arg[0], arg[1], msg.Cmdx("nfs.cat", arg[2][1:]))
} else {
msg.Conf(arg[0], arg[1], kit.Parse(nil, "", arg[2:]...))
}
}
if len(arg) > 1 {
// 读取配置
m.Echo(kit.Formats(msg.Confv(arg[0], arg[1])))
} else {
// 读取配置
m.Echo(kit.Formats(msg.Confv(arg[0])))
}
} }
}}, }},
}, },

View File

@ -6,9 +6,367 @@ import (
"os" "os"
"path" "path"
"strings"
"time" "time"
) )
func _story_share(m *ice.Message, story string, list string, arg ...string) {
if m.Echo("share: "); list == "" {
msg := m.Cmd(ice.WEB_STORY, ice.STORY_INDEX, story)
m.Cmdy(ice.WEB_SHARE, "add", "story", story, msg.Append("list"))
} else {
msg := m.Cmd(ice.WEB_STORY, ice.STORY_INDEX, list)
m.Cmdy(ice.WEB_SHARE, "add", msg.Append("scene"), msg.Append("story"), msg.Append("text"))
}
}
func _story_list(m *ice.Message, arg ...string) {
// 故事列表
m.Richs(ice.WEB_STORY, "head", "*", func(key string, value map[string]interface{}) {
m.Push(key, value, []string{"time", "story", "count"})
})
m.Sort("time", "time_r")
}
func _story_show(m *ice.Message, arg ...string) {
if len(arg) == 1 {
// 故事记录
m.Cmdy(ice.WEB_STORY, "history", arg)
return
}
// 故事详情
m.Cmd(ice.WEB_STORY, ice.STORY_INDEX, arg[1]).Table(func(index int, value map[string]string, head []string) {
for k, v := range value {
m.Push("key", k)
m.Push("value", v)
}
m.Sort("key")
})
}
func _story_pull(m *ice.Message, arg ...string) {
// 起止节点
prev, begin, end := "", arg[3], ""
repos := kit.Keys("remote", arg[2], arg[3])
m.Richs(ice.WEB_STORY, "head", arg[1], func(key string, val map[string]interface{}) {
end = kit.Format(kit.Value(val, kit.Keys(repos, "pull", "list")))
prev = kit.Format(val["list"])
})
pull := end
var first map[string]interface{}
for begin != "" && begin != end {
if m.Cmd(ice.WEB_SPIDE, arg[2], "msg", "/story/pull", "begin", begin, "end", end).Table(func(index int, value map[string]string, head []string) {
if m.Richs(ice.WEB_CACHE, nil, value["data"], nil) == nil {
m.Log(ice.LOG_IMPORT, "%v: %v", value["data"], value["save"])
if node := kit.UnMarshal(value["save"]); kit.Format(kit.Value(node, "file")) != "" {
// 下载文件
m.Cmd(ice.WEB_SPIDE, arg[2], "cache", "GET", "/story/download/"+value["data"])
} else {
// 导入缓存
m.Conf(ice.WEB_CACHE, kit.Keys("hash", value["data"]), node)
}
}
node := kit.UnMarshal(value["node"]).(map[string]interface{})
if m.Richs(ice.WEB_STORY, nil, value["list"], nil) == nil {
// 导入节点
m.Log(ice.LOG_IMPORT, "%v: %v", value["list"], value["node"])
m.Conf(ice.WEB_STORY, kit.Keys("hash", value["list"]), node)
}
if first == nil {
if m.Richs(ice.WEB_STORY, "head", arg[1], nil) == nil {
// 自动创建
h := m.Rich(ice.WEB_STORY, "head", kit.Dict(
"scene", node["scene"], "story", arg[1],
"count", node["count"], "list", value["list"],
))
m.Log(ice.LOG_CREATE, "%v: %v", h, node["story"])
}
pull, first = kit.Format(value["list"]), node
m.Richs(ice.WEB_STORY, "head", arg[1], func(key string, val map[string]interface{}) {
prev = kit.Format(val["list"])
if kit.Int(node["count"]) > kit.Int(kit.Value(val, kit.Keys(repos, "pull", "count"))) {
// 更新分支
m.Log(ice.LOG_IMPORT, "%v: %v", arg[2], pull)
kit.Value(val, kit.Keys(repos, "pull"), kit.Dict(
"head", arg[3], "time", node["time"], "list", pull, "count", node["count"],
))
}
})
}
if prev == kit.Format(node["prev"]) || prev == kit.Format(node["push"]) {
// 快速合并
m.Log(ice.LOG_IMPORT, "%v: %v", pull, arg[2])
m.Richs(ice.WEB_STORY, "head", arg[1], func(key string, val map[string]interface{}) {
val["count"] = first["count"]
val["time"] = first["time"]
val["list"] = pull
})
prev = pull
}
begin = kit.Format(node["prev"])
}).Appendv("list") == nil {
break
}
}
}
func _story_push(m *ice.Message, arg ...string) {
// 更新分支
m.Cmdx(ice.WEB_STORY, "pull", arg[1:])
repos := kit.Keys("remote", arg[2], arg[3])
// 查询索引
prev, pull, some, list := "", "", "", ""
m.Richs(ice.WEB_STORY, "head", arg[1], func(key string, val map[string]interface{}) {
prev = kit.Format(val["list"])
pull = kit.Format(kit.Value(val, kit.Keys(repos, "pull", "list")))
for some = pull; prev != some && some != ""; {
local := m.Richs(ice.WEB_STORY, nil, prev, nil)
remote := m.Richs(ice.WEB_STORY, nil, some, nil)
if diff := kit.Time(kit.Format(remote["time"])) - kit.Time(kit.Format(local["time"])); diff > 0 {
some = kit.Format(remote["prev"])
} else if diff < 0 {
prev = kit.Format(local["prev"])
}
}
if prev = kit.Format(val["list"]); prev == pull {
// 相同节点
return
}
if some != pull {
// 合并节点
local := m.Richs(ice.WEB_STORY, nil, prev, nil)
remote := m.Richs(ice.WEB_STORY, nil, pull, nil)
list = m.Rich(ice.WEB_STORY, nil, kit.Dict(
"scene", val["scene"], "story", val["story"], "count", kit.Int(remote["count"])+1,
"data", local["data"], "prev", pull, "push", prev,
))
m.Log(ice.LOG_CREATE, "merge: %s %s->%s", list, prev, pull)
val["list"] = list
prev = list
val["count"] = kit.Int(remote["count"]) + 1
}
// 查询节点
nodes := []string{}
for list = prev; list != some; {
m.Richs(ice.WEB_STORY, nil, list, func(key string, value map[string]interface{}) {
nodes, list = append(nodes, list), kit.Format(value["prev"])
})
}
for _, v := range kit.Revert(nodes) {
m.Richs(ice.WEB_STORY, nil, v, func(list string, node map[string]interface{}) {
m.Richs(ice.WEB_CACHE, nil, node["data"], func(data string, save map[string]interface{}) {
if kit.Format(save["file"]) != "" {
// 推送缓存
m.Cmd(ice.WEB_SPIDE, arg[2], "/story/upload",
"part", "upload", "@"+kit.Format(save["file"]),
)
}
// 推送节点
m.Log(ice.LOG_EXPORT, "%s: %s", v, kit.Format(node))
m.Cmd(ice.WEB_SPIDE, arg[2], "/story/push",
"story", arg[3], "list", v, "node", kit.Format(node),
"data", node["data"], "save", kit.Format(save),
)
})
})
}
})
// 更新分支
m.Cmd(ice.WEB_STORY, "pull", arg[1:])
}
func _story_commit(m *ice.Message, arg ...string) {
// 查询索引
head, prev, value, count := "", "", map[string]interface{}{}, 0
m.Richs(ice.WEB_STORY, "head", arg[1], func(key string, val map[string]interface{}) {
head, prev, value, count = key, kit.Format(val["list"]), val, kit.Int(val["count"])
m.Log("info", "head: %v prev: %v count: %v", head, prev, count)
})
// 提交信息
arg[2] = m.Cmdx(ice.WEB_STORY, "add", "submit", arg[2], "hostname,username")
// 节点信息
menu := map[string]string{}
for i := 3; i < len(arg); i++ {
menu[arg[i]] = m.Cmdx(ice.WEB_STORY, ice.STORY_INDEX, arg[i])
}
// 添加节点
list := m.Rich(ice.WEB_STORY, nil, kit.Dict(
"scene", "commit", "story", arg[1], "count", count+1, "data", arg[2], "list", menu, "prev", prev,
))
m.Log(ice.LOG_CREATE, "commit: %s %s: %s", list, arg[1], arg[2])
m.Push("list", list)
if head == "" {
// 添加索引
m.Rich(ice.WEB_STORY, "head", kit.Dict("scene", "commit", "story", arg[1], "count", count+1, "list", list))
} else {
// 更新索引
value["count"] = count + 1
value["time"] = m.Time()
value["list"] = list
}
m.Echo(list)
}
func _story_trash(m *ice.Message, arg ...string) {
bak := kit.Select(kit.Keys(arg[1], "bak"), arg, 2)
os.Remove(bak)
os.Rename(arg[1], bak)
}
func _story_watch(m *ice.Message, arg ...string) {
// 备份文件
name := kit.Select(arg[1], arg, 2)
m.Cmd(ice.WEB_STORY, ice.STORY_TRASH, name)
if msg := m.Cmd(ice.WEB_STORY, ice.STORY_INDEX, arg[1]); msg.Append("file") != "" {
p := path.Dir(name)
os.MkdirAll(p, 0777)
// 导出文件
os.Link(msg.Append("file"), name)
m.Log(ice.LOG_EXPORT, "%s: %s", msg.Append("file"), name)
} else {
if f, p, e := kit.Create(name); m.Assert(e) {
defer f.Close()
// 导出数据
f.WriteString(msg.Append("text"))
m.Log(ice.LOG_EXPORT, "%s: %s", msg.Append("text"), p)
}
}
m.Echo(name)
}
func _story_catch(m *ice.Message, arg ...string) {
if last := m.Richs(ice.WEB_STORY, "head", arg[2], nil); last != nil {
if t, e := time.ParseInLocation(ice.ICE_TIME, kit.Format(last["time"]), time.Local); e == nil {
// 文件对比
if s, e := os.Stat(arg[2]); e == nil && s.ModTime().Before(t) {
m.Info("%s last: %s", arg[2], kit.Format(t))
m.Echo("%s", last["list"])
return
}
}
}
_story_add(m, arg...)
}
func _story_add(m *ice.Message, arg ...string) {
if m.Richs(ice.WEB_CACHE, nil, kit.Select("", arg, 3), func(key string, value map[string]interface{}) {
// 复用缓存
arg[3] = key
}) == nil {
// 添加缓存
m.Cmdy(ice.WEB_CACHE, arg)
arg = []string{arg[0], m.Append("type"), m.Append("name"), m.Append("data")}
}
// 查询索引
head, prev, value, count := "", "", map[string]interface{}{}, 0
m.Richs(ice.WEB_STORY, "head", arg[2], func(key string, val map[string]interface{}) {
head, prev, value, count = key, kit.Format(val["list"]), val, kit.Int(val["count"])
m.Log("info", "head: %v prev: %v count: %v", head, prev, count)
})
if last := m.Richs(ice.WEB_STORY, nil, prev, nil); prev != "" && last != nil && last["data"] == arg[3] {
// 重复提交
m.Echo(prev)
} else {
// 添加节点
list := m.Rich(ice.WEB_STORY, nil, kit.Dict(
"scene", arg[1], "story", arg[2], "count", count+1, "data", arg[3], "prev", prev,
))
m.Log(ice.LOG_CREATE, "story: %s %s: %s", list, arg[1], arg[2])
m.Push("list", list)
if head == "" {
// 添加索引
m.Rich(ice.WEB_STORY, "head", kit.Dict("scene", arg[1], "story", arg[2], "count", count+1, "list", list))
} else {
// 更新索引
value["count"] = count + 1
value["time"] = m.Time()
value["list"] = list
}
m.Echo(list)
}
// 分发数据
if p := kit.Select(m.Conf(ice.WEB_FAVOR, "meta.proxy"), m.Option("you")); p != "" {
m.Info("what %v", p)
m.Option("you", "")
m.Cmd(ice.WEB_PROXY, p, ice.WEB_STORY, ice.STORY_PULL, arg[2], "dev", arg[2])
}
}
func _story_index(m *ice.Message, arg ...string) {
m.Richs(ice.WEB_STORY, "head", arg[1], func(key string, value map[string]interface{}) {
// 查询索引
arg[1] = kit.Format(value["list"])
})
m.Richs(ice.WEB_STORY, nil, arg[1], func(key string, value map[string]interface{}) {
// 查询节点
m.Push("list", key)
m.Push(key, value, []string{"scene", "story"})
arg[1] = kit.Format(value["data"])
})
m.Richs(ice.WEB_CACHE, nil, arg[1], func(key string, value map[string]interface{}) {
// 查询数据
m.Push("data", key)
m.Push(key, value, []string{"text", "time", "size", "type", "name", "file"})
m.Echo("%s", value["text"])
})
}
func _story_history(m *ice.Message, arg ...string) {
// 历史记录
list := m.Cmd(ice.WEB_STORY, ice.STORY_INDEX, arg[1]).Append("list")
for i := 0; i < kit.Int(kit.Select("30", m.Option("cache.limit"))) && list != ""; i++ {
m.Richs(ice.WEB_STORY, nil, list, func(key string, value map[string]interface{}) {
// 直连节点
m.Push(key, value, []string{"time", "key", "count", "scene", "story"})
m.Richs(ice.WEB_CACHE, nil, value["data"], func(key string, value map[string]interface{}) {
m.Push("drama", value["text"])
m.Push("data", key)
})
kit.Fetch(value["list"], func(key string, val string) {
m.Richs(ice.WEB_STORY, nil, val, func(key string, value map[string]interface{}) {
// 复合节点
m.Push(key, value, []string{"time", "key", "count", "scene", "story"})
m.Richs(ice.WEB_CACHE, nil, value["data"], func(key string, value map[string]interface{}) {
m.Push("drama", value["text"])
m.Push("data", key)
})
})
})
// 切换节点
list = kit.Format(value["prev"])
})
}
}
func StoryWatch(m *ice.Message, file string, name string) { _story_watch(m, file, name) }
func StoryCatch(m *ice.Message, mime string, file string) {
_story_catch(m, "catch", kit.Select(mime, strings.TrimPrefix(path.Ext(file), ".")), file)
}
func init() { func init() {
Index.Merge(&ice.Context{ Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{
@ -33,361 +391,46 @@ func init() {
switch arg[1] { switch arg[1] {
case "share", "共享": case "share", "共享":
if m.Echo("share: "); list == "" { _story_share(m, story, list, arg...)
msg := m.Cmd(ice.WEB_STORY, ice.STORY_INDEX, story)
m.Cmdy(ice.WEB_SHARE, "add", "story", story, msg.Append("list"))
} else {
msg := m.Cmd(ice.WEB_STORY, ice.STORY_INDEX, list)
m.Cmdy(ice.WEB_SHARE, "add", msg.Append("scene"), msg.Append("story"), msg.Append("text"))
}
} }
return return
} }
if len(arg) == 0 { if len(arg) == 0 {
// 故事列表 _story_list(m, arg...)
m.Richs(ice.WEB_STORY, "head", "*", func(key string, value map[string]interface{}) {
m.Push(key, value, []string{"time", "story", "count"})
})
m.Sort("time", "time_r")
return return
} }
switch arg[0] { switch arg[0] {
case ice.STORY_PULL: // story [spide [story]] case ice.STORY_PULL: // story [spide [story]]
// 起止节点 _story_pull(m, arg...)
prev, begin, end := "", arg[3], ""
repos := kit.Keys("remote", arg[2], arg[3])
m.Richs(ice.WEB_STORY, "head", arg[1], func(key string, val map[string]interface{}) {
end = kit.Format(kit.Value(val, kit.Keys(repos, "pull", "list")))
prev = kit.Format(val["list"])
})
pull := end
var first map[string]interface{}
for begin != "" && begin != end {
if m.Cmd(ice.WEB_SPIDE, arg[2], "msg", "/story/pull", "begin", begin, "end", end).Table(func(index int, value map[string]string, head []string) {
if m.Richs(ice.WEB_CACHE, nil, value["data"], nil) == nil {
m.Log(ice.LOG_IMPORT, "%v: %v", value["data"], value["save"])
if node := kit.UnMarshal(value["save"]); kit.Format(kit.Value(node, "file")) != "" {
// 下载文件
m.Cmd(ice.WEB_SPIDE, arg[2], "cache", "GET", "/story/download/"+value["data"])
} else {
// 导入缓存
m.Conf(ice.WEB_CACHE, kit.Keys("hash", value["data"]), node)
}
}
node := kit.UnMarshal(value["node"]).(map[string]interface{})
if m.Richs(ice.WEB_STORY, nil, value["list"], nil) == nil {
// 导入节点
m.Log(ice.LOG_IMPORT, "%v: %v", value["list"], value["node"])
m.Conf(ice.WEB_STORY, kit.Keys("hash", value["list"]), node)
}
if first == nil {
if m.Richs(ice.WEB_STORY, "head", arg[1], nil) == nil {
// 自动创建
h := m.Rich(ice.WEB_STORY, "head", kit.Dict(
"scene", node["scene"], "story", arg[1],
"count", node["count"], "list", value["list"],
))
m.Log(ice.LOG_CREATE, "%v: %v", h, node["story"])
}
pull, first = kit.Format(value["list"]), node
m.Richs(ice.WEB_STORY, "head", arg[1], func(key string, val map[string]interface{}) {
prev = kit.Format(val["list"])
if kit.Int(node["count"]) > kit.Int(kit.Value(val, kit.Keys(repos, "pull", "count"))) {
// 更新分支
m.Log(ice.LOG_IMPORT, "%v: %v", arg[2], pull)
kit.Value(val, kit.Keys(repos, "pull"), kit.Dict(
"head", arg[3], "time", node["time"], "list", pull, "count", node["count"],
))
}
})
}
if prev == kit.Format(node["prev"]) || prev == kit.Format(node["push"]) {
// 快速合并
m.Log(ice.LOG_IMPORT, "%v: %v", pull, arg[2])
m.Richs(ice.WEB_STORY, "head", arg[1], func(key string, val map[string]interface{}) {
val["count"] = first["count"]
val["time"] = first["time"]
val["list"] = pull
})
prev = pull
}
begin = kit.Format(node["prev"])
}).Appendv("list") == nil {
break
}
}
case ice.STORY_PUSH: case ice.STORY_PUSH:
// 更新分支 _story_push(m, arg...)
m.Cmdx(ice.WEB_STORY, "pull", arg[1:])
repos := kit.Keys("remote", arg[2], arg[3])
// 查询索引
prev, pull, some, list := "", "", "", ""
m.Richs(ice.WEB_STORY, "head", arg[1], func(key string, val map[string]interface{}) {
prev = kit.Format(val["list"])
pull = kit.Format(kit.Value(val, kit.Keys(repos, "pull", "list")))
for some = pull; prev != some && some != ""; {
local := m.Richs(ice.WEB_STORY, nil, prev, nil)
remote := m.Richs(ice.WEB_STORY, nil, some, nil)
if diff := kit.Time(kit.Format(remote["time"])) - kit.Time(kit.Format(local["time"])); diff > 0 {
some = kit.Format(remote["prev"])
} else if diff < 0 {
prev = kit.Format(local["prev"])
}
}
if prev = kit.Format(val["list"]); prev == pull {
// 相同节点
return
}
if some != pull {
// 合并节点
local := m.Richs(ice.WEB_STORY, nil, prev, nil)
remote := m.Richs(ice.WEB_STORY, nil, pull, nil)
list = m.Rich(ice.WEB_STORY, nil, kit.Dict(
"scene", val["scene"], "story", val["story"], "count", kit.Int(remote["count"])+1,
"data", local["data"], "prev", pull, "push", prev,
))
m.Log(ice.LOG_CREATE, "merge: %s %s->%s", list, prev, pull)
val["list"] = list
prev = list
val["count"] = kit.Int(remote["count"]) + 1
}
// 查询节点
nodes := []string{}
for list = prev; list != some; {
m.Richs(ice.WEB_STORY, nil, list, func(key string, value map[string]interface{}) {
nodes, list = append(nodes, list), kit.Format(value["prev"])
})
}
for _, v := range kit.Revert(nodes) {
m.Richs(ice.WEB_STORY, nil, v, func(list string, node map[string]interface{}) {
m.Richs(ice.WEB_CACHE, nil, node["data"], func(data string, save map[string]interface{}) {
if kit.Format(save["file"]) != "" {
// 推送缓存
m.Cmd(ice.WEB_SPIDE, arg[2], "/story/upload",
"part", "upload", "@"+kit.Format(save["file"]),
)
}
// 推送节点
m.Log(ice.LOG_EXPORT, "%s: %s", v, kit.Format(node))
m.Cmd(ice.WEB_SPIDE, arg[2], "/story/push",
"story", arg[3], "list", v, "node", kit.Format(node),
"data", node["data"], "save", kit.Format(save),
)
})
})
}
})
// 更新分支
m.Cmd(ice.WEB_STORY, "pull", arg[1:])
case "commit": case "commit":
// 查询索引 _story_commit(m, arg...)
head, prev, value, count := "", "", map[string]interface{}{}, 0
m.Richs(ice.WEB_STORY, "head", arg[1], func(key string, val map[string]interface{}) {
head, prev, value, count = key, kit.Format(val["list"]), val, kit.Int(val["count"])
m.Log("info", "head: %v prev: %v count: %v", head, prev, count)
})
// 提交信息
arg[2] = m.Cmdx(ice.WEB_STORY, "add", "submit", arg[2], "hostname,username")
// 节点信息
menu := map[string]string{}
for i := 3; i < len(arg); i++ {
menu[arg[i]] = m.Cmdx(ice.WEB_STORY, ice.STORY_INDEX, arg[i])
}
// 添加节点
list := m.Rich(ice.WEB_STORY, nil, kit.Dict(
"scene", "commit", "story", arg[1], "count", count+1, "data", arg[2], "list", menu, "prev", prev,
))
m.Log(ice.LOG_CREATE, "commit: %s %s: %s", list, arg[1], arg[2])
m.Push("list", list)
if head == "" {
// 添加索引
m.Rich(ice.WEB_STORY, "head", kit.Dict("scene", "commit", "story", arg[1], "count", count+1, "list", list))
} else {
// 更新索引
value["count"] = count + 1
value["time"] = m.Time()
value["list"] = list
}
m.Echo(list)
case ice.STORY_TRASH: case ice.STORY_TRASH:
bak := kit.Select(kit.Keys(arg[1], "bak"), arg, 2) _story_trash(m, arg...)
os.Remove(bak)
os.Rename(arg[1], bak)
case ice.STORY_WATCH: case ice.STORY_WATCH:
// 备份文件 _story_watch(m, arg...)
name := kit.Select(arg[1], arg, 2)
m.Cmd(ice.WEB_STORY, ice.STORY_TRASH, name)
if msg := m.Cmd(ice.WEB_STORY, ice.STORY_INDEX, arg[1]); msg.Append("file") != "" {
p := path.Dir(name)
os.MkdirAll(p, 0777)
// 导出文件
os.Link(msg.Append("file"), name)
m.Log(ice.LOG_EXPORT, "%s: %s", msg.Append("file"), name)
} else {
if f, p, e := kit.Create(name); m.Assert(e) {
defer f.Close()
// 导出数据
f.WriteString(msg.Append("text"))
m.Log(ice.LOG_EXPORT, "%s: %s", msg.Append("text"), p)
}
}
m.Echo(name)
case ice.STORY_CATCH: case ice.STORY_CATCH:
if last := m.Richs(ice.WEB_STORY, "head", arg[2], nil); last != nil { _story_catch(m, arg...)
if t, e := time.ParseInLocation(ice.ICE_TIME, kit.Format(last["time"]), time.Local); e == nil {
// 文件对比
if s, e := os.Stat(arg[2]); e == nil && s.ModTime().Before(t) {
m.Info("%s last: %s", arg[2], kit.Format(t))
m.Echo("%s", last["list"])
break
}
}
}
fallthrough
case "add", ice.STORY_UPLOAD, ice.STORY_DOWNLOAD: case "add", ice.STORY_UPLOAD, ice.STORY_DOWNLOAD:
if m.Richs(ice.WEB_CACHE, nil, kit.Select("", arg, 3), func(key string, value map[string]interface{}) { _story_add(m, arg...)
// 复用缓存
arg[3] = key
}) == nil {
// 添加缓存
m.Cmdy(ice.WEB_CACHE, arg)
arg = []string{arg[0], m.Append("type"), m.Append("name"), m.Append("data")}
}
// 查询索引
head, prev, value, count := "", "", map[string]interface{}{}, 0
m.Richs(ice.WEB_STORY, "head", arg[2], func(key string, val map[string]interface{}) {
head, prev, value, count = key, kit.Format(val["list"]), val, kit.Int(val["count"])
m.Log("info", "head: %v prev: %v count: %v", head, prev, count)
})
if last := m.Richs(ice.WEB_STORY, nil, prev, nil); prev != "" && last != nil && last["data"] == arg[3] {
// 重复提交
m.Echo(prev)
} else {
// 添加节点
list := m.Rich(ice.WEB_STORY, nil, kit.Dict(
"scene", arg[1], "story", arg[2], "count", count+1, "data", arg[3], "prev", prev,
))
m.Log(ice.LOG_CREATE, "story: %s %s: %s", list, arg[1], arg[2])
m.Push("list", list)
if head == "" {
// 添加索引
m.Rich(ice.WEB_STORY, "head", kit.Dict("scene", arg[1], "story", arg[2], "count", count+1, "list", list))
} else {
// 更新索引
value["count"] = count + 1
value["time"] = m.Time()
value["list"] = list
}
m.Echo(list)
}
// 分发数据
if p := kit.Select(m.Conf(ice.WEB_FAVOR, "meta.proxy"), m.Option("you")); p != "" {
m.Info("what %v", p)
m.Option("you", "")
m.Cmd(ice.WEB_PROXY, p, ice.WEB_STORY, ice.STORY_PULL, arg[2], "dev", arg[2])
}
case ice.STORY_INDEX: case ice.STORY_INDEX:
m.Richs(ice.WEB_STORY, "head", arg[1], func(key string, value map[string]interface{}) { _story_index(m, arg...)
// 查询索引
arg[1] = kit.Format(value["list"])
})
m.Richs(ice.WEB_STORY, nil, arg[1], func(key string, value map[string]interface{}) {
// 查询节点
m.Push("list", key)
m.Push(key, value, []string{"scene", "story"})
arg[1] = kit.Format(value["data"])
})
m.Richs(ice.WEB_CACHE, nil, arg[1], func(key string, value map[string]interface{}) {
// 查询数据
m.Push("data", key)
m.Push(key, value, []string{"text", "time", "size", "type", "name", "file"})
m.Echo("%s", value["text"])
})
case ice.STORY_HISTORY: case ice.STORY_HISTORY:
// 历史记录 _story_history(m, arg...)
list := m.Cmd(ice.WEB_STORY, ice.STORY_INDEX, arg[1]).Append("list")
for i := 0; i < kit.Int(kit.Select("30", m.Option("cache.limit"))) && list != ""; i++ {
m.Richs(ice.WEB_STORY, nil, list, func(key string, value map[string]interface{}) {
// 直连节点
m.Push(key, value, []string{"time", "key", "count", "scene", "story"})
m.Richs(ice.WEB_CACHE, nil, value["data"], func(key string, value map[string]interface{}) {
m.Push("drama", value["text"])
m.Push("data", key)
})
kit.Fetch(value["list"], func(key string, val string) {
m.Richs(ice.WEB_STORY, nil, val, func(key string, value map[string]interface{}) {
// 复合节点
m.Push(key, value, []string{"time", "key", "count", "scene", "story"})
m.Richs(ice.WEB_CACHE, nil, value["data"], func(key string, value map[string]interface{}) {
m.Push("drama", value["text"])
m.Push("data", key)
})
})
})
// 切换节点
list = kit.Format(value["prev"])
})
}
default: default:
if len(arg) == 1 { _story_show(m, arg...)
// 故事记录
m.Cmdy(ice.WEB_STORY, "history", arg)
break
}
// 故事详情
m.Cmd(ice.WEB_STORY, ice.STORY_INDEX, arg[1]).Table(func(index int, value map[string]string, head []string) {
for k, v := range value {
m.Push("key", k)
m.Push("value", v)
}
m.Sort("key")
})
} }
}}, }},
"/story/": {Name: "/story/", Help: "故事会", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { "/story/": {Name: "/story/", Help: "故事会", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
switch arg[0] { switch arg[0] {
case ice.STORY_PULL: case ice.STORY_PULL:
// 下载节点
list := m.Cmd(ice.WEB_STORY, ice.STORY_INDEX, m.Option("begin")).Append("list") list := m.Cmd(ice.WEB_STORY, ice.STORY_INDEX, m.Option("begin")).Append("list")
for i := 0; i < 10 && list != "" && list != m.Option("end"); i++ { for i := 0; i < 10 && list != "" && list != m.Option("end"); i++ {
if m.Richs(ice.WEB_STORY, nil, list, func(key string, value map[string]interface{}) { if m.Richs(ice.WEB_STORY, nil, list, func(key string, value map[string]interface{}) {
@ -404,8 +447,6 @@ func init() {
m.Log(ice.LOG_EXPORT, "%s %s", m.Option("begin"), m.Format("append")) m.Log(ice.LOG_EXPORT, "%s %s", m.Option("begin"), m.Format("append"))
case ice.STORY_PUSH: case ice.STORY_PUSH:
// 上传节点
if m.Richs(ice.WEB_CACHE, nil, m.Option("data"), nil) == nil { if m.Richs(ice.WEB_CACHE, nil, m.Option("data"), nil) == nil {
// 导入缓存 // 导入缓存
m.Log(ice.LOG_IMPORT, "%v: %v", m.Option("data"), m.Option("save")) m.Log(ice.LOG_IMPORT, "%v: %v", m.Option("data"), m.Option("save"))

View File

@ -46,7 +46,9 @@ func Format(key string, arg ...interface{}) string {
return "" return ""
} }
func Render(msg *ice.Message, cmd string, args ...interface{}) { func Render(msg *ice.Message, cmd string, args ...interface{}) {
msg.Log(ice.LOG_EXPORT, "%s: %v", cmd, args) if cmd != "" {
msg.Log(ice.LOG_EXPORT, "%s: %v", cmd, args)
}
switch arg := kit.Simple(args...); cmd { switch arg := kit.Simple(args...); cmd {
case ice.RENDER_OUTPUT: case ice.RENDER_OUTPUT:
case "redirect": case "redirect":

View File

@ -5,7 +5,7 @@ import (
"github.com/shylinux/toolkits" "github.com/shylinux/toolkits"
) )
func _action_share_create(m *ice.Message, c *ice.Context, cmd string, arg ...string) { func _action_share_create(m *ice.Message, arg ...string) {
if m.Option("index") != "" { if m.Option("index") != "" {
arg = append(arg, "tool.0.pod", m.Option("node")) arg = append(arg, "tool.0.pod", m.Option("node"))
arg = append(arg, "tool.0.ctx", m.Option("group")) arg = append(arg, "tool.0.ctx", m.Option("group"))
@ -96,7 +96,7 @@ func init() {
"/action": {Name: "/action", 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) {
switch arg[0] { switch arg[0] {
case "share": case "share":
_action_share_create(m, c, cmd, arg...) _action_share_create(m, arg...)
return return
} }
if len(arg) == 0 || arg[0] == "" { if len(arg) == 0 || arg[0] == "" {

44
core/wiki/inner.go Normal file
View File

@ -0,0 +1,44 @@
package wiki
import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/web"
kit "github.com/shylinux/toolkits"
"os"
)
func _inner_save(m *ice.Message, name, text string) {
if f, e := os.Create(name); m.Assert(e) {
defer f.Close()
if n, e := f.WriteString(text); m.Assert(e) {
m.Logs(ice.LOG_EXPORT, "file", name, "size", n)
}
}
}
func init() {
const (
INNER = "inner"
SAVE = "save"
COMMIT = "commit"
)
Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{
INNER: {Name: "inner", Help: "编辑器", Value: kit.Data(kit.MDB_SHORT, INNER)},
},
Commands: map[string]*ice.Command{
INNER: {Name: "inner path=auto auto", Help: "编辑器", Action: map[string]*ice.Action{
SAVE: {Name: "save name content", Help: "保存", Hand: func(m *ice.Message, arg ...string) {
_inner_save(m, arg[0], kit.Select(m.Option("content"), arg, 1))
}},
COMMIT: {Name: "commit name", Help: "提交", Hand: func(m *ice.Message, arg ...string) {
web.StoryCatch(m, "", arg[0])
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmdy("nfs.dir", arg)
}},
},
}, nil)
}

18
info.go
View File

@ -14,7 +14,7 @@ func (m *Message) Logs(level string, arg ...interface{}) *Message {
for i := 0; i < len(arg)-1; i += 2 { for i := 0; i < len(arg)-1; i += 2 {
list = append(list, fmt.Sprintf("%v: %v", arg[i], arg[i+1])) list = append(list, fmt.Sprintf("%v: %v", arg[i], arg[i+1]))
} }
m.Log(level, strings.Join(list, " ")) m.log(level, strings.Join(list, " "))
return m return m
} }
func (m *Message) Log(level string, str string, arg ...interface{}) *Message { func (m *Message) Log(level string, str string, arg ...interface{}) *Message {
@ -43,18 +43,22 @@ func (m *Message) log(level string, str string, arg ...interface{}) *Message {
prefix, suffix = "\033[31m", "\033[0m" prefix, suffix = "\033[31m", "\033[0m"
} }
_, file, line, _ := runtime.Caller(2) switch level {
ls := strings.Split(file, "/") case LOG_CMDS, LOG_INFO, LOG_WARN, LOG_COST:
if len(ls) > 2 { default:
ls = ls[len(ls)-2:] _, file, line, _ := runtime.Caller(2)
ls := strings.Split(file, "/")
if len(ls) > 2 {
ls = ls[len(ls)-2:]
}
suffix += fmt.Sprintf(" %s:%d", strings.Join(ls, "/"), line)
} }
if os.Getenv("ctx_mod") != "" && m != nil { if os.Getenv("ctx_mod") != "" && m != nil {
// 输出日志 // 输出日志
fmt.Fprintf(os.Stderr, "%s %02d %9s %s%s %s%s %s\n", fmt.Fprintf(os.Stderr, "%s %02d %9s %s%s %s%s\n",
m.time.Format(ICE_TIME), m.code, fmt.Sprintf("%4s->%-4s", m.source.Name, m.target.Name), m.time.Format(ICE_TIME), m.code, fmt.Sprintf("%4s->%-4s", m.source.Name, m.target.Name),
prefix, level, str, suffix, prefix, level, str, suffix,
fmt.Sprintf("%s:%d", strings.Join(ls, "/"), line),
) )
} }
return m return m

40
type.go
View File

@ -29,12 +29,18 @@ type Config struct {
Help string Help string
Value interface{} Value interface{}
} }
type Action struct {
Name string
Help string
Hand func(m *Message, arg ...string)
}
type Command struct { type Command struct {
Name interface{} // string []string Name interface{} // string []string
Help interface{} // string []string Help interface{} // string []string
List []interface{} List []interface{}
Meta map[string]interface{} Meta map[string]interface{}
Hand func(m *Message, c *Context, key string, arg ...string) Hand func(m *Message, c *Context, key string, arg ...string)
Action map[string]*Action
} }
type Context struct { type Context struct {
Name string Name string
@ -73,8 +79,19 @@ func (c *Context) Cap(key string, arg ...interface{}) string {
return c.Caches[key].Value return c.Caches[key].Value
} }
func (c *Context) Run(m *Message, cmd *Command, key string, arg ...string) *Message { 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) m.Log(LOG_CMDS, "%s.%s %d %v", c.Name, key, len(arg), arg)
if m.Hand = true; len(arg) > 1 && arg[0] == "action" && cmd.Action != nil {
if h, ok := cmd.Action[arg[1]]; ok {
h.Hand(m, arg[2:]...)
return m
}
for _, h := range cmd.Action {
if h.Name == arg[1] || h.Help == arg[1] {
h.Hand(m, arg[2:]...)
return m
}
}
}
cmd.Hand(m, c, key, arg...) cmd.Hand(m, c, key, arg...)
return m return m
} }
@ -654,17 +671,6 @@ func (m *Message) Cmd(arg ...interface{}) *Message {
m.Hand, msg.Hand = true, true m.Hand, msg.Hand = true, true
msg.meta[MSG_DETAIL] = list msg.meta[MSG_DETAIL] = list
// _key := kit.Format(kit.Value(cmd.Meta, "remote"))
// if you := m.Option(_key); you != "" {
// // 远程命令
// msg.Option(_key, "")
// msg.Option("_option", m.Optionv("option"))
// msg.Copy(msg.Spawns(c).Cmd(WEB_LABEL, you, list[0], list[1:]))
// } else {
// // 本地命令
// p.Run(msg, cmd, key, list[1:]...)
// }
p.Run(msg, cmd, key, list[1:]...) p.Run(msg, cmd, key, list[1:]...)
m.Hand, msg.Hand, m = true, true, msg m.Hand, msg.Hand, m = true, true, msg
}) })