1
0
mirror of https://shylinux.com/x/icebergs synced 2025-05-01 19:19:24 +08:00
This commit is contained in:
shylinux 2020-02-23 06:34:57 +08:00
parent 8cf26b0af8
commit 2f253c8668
29 changed files with 865 additions and 551 deletions

47
base.go
View File

@ -18,37 +18,37 @@ func (f *Frame) Spawn(m *Message, c *Context, arg ...string) Server {
} }
func (f *Frame) Begin(m *Message, arg ...string) Server { func (f *Frame) Begin(m *Message, arg ...string) Server {
m.Log(LOG_BEGIN, "ice") m.Log(LOG_BEGIN, "ice")
list := map[*Context]*Message{m.target: m} list := map[*Context]*Message{m.target: m}
m.Travel(func(p *Context, s *Context) { m.Travel(func(p *Context, s *Context) {
s.root = m.target s.root = m.target
if msg, ok := list[p]; ok && msg != nil { if msg, ok := list[p]; ok && msg != nil {
sub := msg.Spawns(s) list[s] = msg.Spawns(s)
s.Begin(sub, arg...) s.Begin(list[s], arg...)
list[s] = sub
} }
}) })
m.target.wg = &sync.WaitGroup{}
m.root.Cost("begin") m.root.Cost("begin")
return f return f
} }
func (f *Frame) Start(m *Message, arg ...string) bool { func (f *Frame) Start(m *Message, arg ...string) bool {
m.Log(LOG_START, "ice")
m.Cap(CTX_STATUS, "start") m.Cap(CTX_STATUS, "start")
m.Cap(CTX_STREAM, strings.Split(m.Time(), " ")[1]) m.Cap(CTX_STREAM, strings.Split(m.Time(), " ")[1])
m.Log(LOG_START, "ice")
m.Cmd(ICE_INIT).Cmd("init", arg)
m.root.Cost("start") m.root.Cost("start")
m.Cmd("init", arg)
return true return true
} }
func (f *Frame) Close(m *Message, arg ...string) bool { func (f *Frame) Close(m *Message, arg ...string) bool {
m.TryCatch(m, true, func(m *Message) { m.TryCatch(m, true, func(m *Message) {
m.target.wg.Wait() m.target.wg.Wait()
}) })
list := map[*Context]*Message{m.target: m} list := map[*Context]*Message{m.target: m}
m.Travel(func(p *Context, s *Context) { m.Travel(func(p *Context, s *Context) {
if msg, ok := list[p]; ok && msg != nil { if msg, ok := list[p]; ok && msg != nil {
sub := msg.Spawns(s) list[s] = msg.Spawns(s)
s.Close(sub, arg...) s.Close(list[s], arg...)
list[s] = sub
} }
}) })
return true return true
@ -56,14 +56,11 @@ func (f *Frame) Close(m *Message, arg ...string) bool {
var Index = &Context{Name: "ice", Help: "冰山模块", var Index = &Context{Name: "ice", Help: "冰山模块",
Caches: map[string]*Cache{ Caches: map[string]*Cache{
CTX_STATUS: {Value: "begin"},
CTX_STREAM: {Value: "shy"},
CTX_FOLLOW: {Value: ""}, CTX_FOLLOW: {Value: ""},
CTX_STREAM: {Value: "shy"},
CTX_STATUS: {Value: "begin"},
}, },
Configs: map[string]*Config{ Configs: map[string]*Config{
"table": {Name: "数据缓存", Value: map[string]interface{}{
"compact": "false",
}},
"help": {Value: map[string]interface{}{ "help": {Value: map[string]interface{}{
"index": []interface{}{ "index": []interface{}{
"^_^ 欢迎使用冰山框架 ^_^", "^_^ 欢迎使用冰山框架 ^_^",
@ -84,22 +81,27 @@ var Index = &Context{Name: "ice", Help: "冰山模块",
} }
}) })
}}, }},
"init": {Name: "init", Help: "hello", Hand: func(m *Message, c *Context, cmd string, arg ...string) { "init": {Name: "init", Help: "启动", Hand: func(m *Message, c *Context, cmd string, arg ...string) {
m.root.Cmd(ICE_INIT)
m.root.Cost("_init") m.root.Cost("_init")
m.Start("log")
m.Start("gdb") m.target.root.wg = &sync.WaitGroup{}
m.Start("ssh") for _, k := range []string{"log", "gdb", "ssh"} {
m.Start(k)
}
m.Cmd("ssh.scan", "init.shy", "启动配置", "etc/init.shy") m.Cmd("ssh.scan", "init.shy", "启动配置", "etc/init.shy")
m.Cmd(arg) m.Cmd(arg)
}}, }},
"help": {Name: "help", Help: "帮助", Hand: func(m *Message, c *Context, cmd string, arg ...string) { "help": {Name: "help", Help: "帮助", Hand: func(m *Message, c *Context, cmd string, arg ...string) {
m.Echo(strings.Join(kit.Simple(m.Confv("help", "index")), "\n")) m.Echo(strings.Join(kit.Simple(m.Confv("help", "index")), "\n"))
}}, }},
"exit": {Name: "exit", Help: "hello", Hand: func(m *Message, c *Context, cmd string, arg ...string) { "exit": {Name: "exit", Help: "结束", Hand: func(m *Message, c *Context, cmd string, arg ...string) {
m.root.target.server.(*Frame).code = kit.Int(kit.Select("0", arg, 0))
m.Cmd("ssh.scan", "exit.shy", "退出配置", "etc/exit.shy") m.Cmd("ssh.scan", "exit.shy", "退出配置", "etc/exit.shy")
f := m.root.target.server.(*Frame)
f.code = kit.Int(kit.Select("0", arg, 0))
m.root.Cmd(ICE_EXIT) m.root.Cmd(ICE_EXIT)
m.root.Cost("_exit")
}}, }},
ICE_EXIT: {Hand: func(m *Message, c *Context, cmd string, arg ...string) { ICE_EXIT: {Hand: func(m *Message, c *Context, cmd string, arg ...string) {
m.root.Travel(func(p *Context, c *Context) { m.root.Travel(func(p *Context, c *Context) {
@ -118,8 +120,8 @@ var Pulse = &Message{
meta: map[string][]string{}, meta: map[string][]string{},
data: map[string]interface{}{}, data: map[string]interface{}{},
messages: []*Message{}, message: nil, root: nil,
source: Index, target: Index, Hand: true, source: Index, target: Index, Hand: true,
messages: []*Message{}, message: nil, root: nil,
} }
var Log func(*Message, string, string) var Log func(*Message, string, string)
@ -142,6 +144,7 @@ func Run(arg ...string) string {
if frame.Begin(Pulse.Spawns(), arg...).Start(Pulse.Spawns(), arg...) { if frame.Begin(Pulse.Spawns(), arg...).Start(Pulse.Spawns(), arg...) {
frame.Close(Pulse.Spawns(), arg...) frame.Close(Pulse.Spawns(), arg...)
} }
time.Sleep(time.Second) time.Sleep(time.Second)
os.Exit(frame.code) os.Exit(frame.code)
return Pulse.Result() return Pulse.Result()

View File

@ -18,14 +18,15 @@ func distance(lat1, long1, lat2, long2 float64) float64 {
var Index = &ice.Context{Name: "aaa", Help: "认证模块", var Index = &ice.Context{Name: "aaa", Help: "认证模块",
Caches: map[string]*ice.Cache{}, Caches: map[string]*ice.Cache{},
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{
ice.AAA_ROLE: {Name: "role", Help: "角色", Value: kit.Data(kit.MDB_SHORT, "chain", "root", kit.Dict(), "tech", kit.Dict())}, ice.AAA_ROLE: {Name: "role", Help: "角色", Value: kit.Data(kit.MDB_SHORT, "chain")},
ice.AAA_USER: {Name: "user", Help: "用户", Value: kit.Data(kit.MDB_SHORT, "username")}, ice.AAA_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")}, ice.AAA_SESS: {Name: "sess", Help: "会话", Value: kit.Data(kit.MDB_SHORT, "uniq", "expire", "720h")},
"location": {Name: "location", Help: "location", Value: kit.Data(kit.MDB_SHORT, "name")},
"location": {Name: "location", Help: "定位", Value: kit.Data(kit.MDB_SHORT, "name")},
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmd(ice.CTX_CONFIG, "load", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json")) m.Load()
// 权限索引 // 权限索引
m.Conf(ice.AAA_ROLE, "black.tech.meta.short", "chain") m.Conf(ice.AAA_ROLE, "black.tech.meta.short", "chain")
m.Conf(ice.AAA_ROLE, "white.tech.meta.short", "chain") m.Conf(ice.AAA_ROLE, "white.tech.meta.short", "chain")
@ -33,11 +34,9 @@ var Index = &ice.Context{Name: "aaa", Help: "认证模块",
m.Conf(ice.AAA_ROLE, "white.void.meta.short", "chain") 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) { 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"), m.Save(ice.AAA_ROLE, ice.AAA_USER, ice.AAA_SESS, m.Prefix("location"))
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) { "location": {Name: "location", Help: "location", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 { if len(arg) == 0 {
m.Grows("location", nil, "", "", func(index int, value map[string]interface{}) { m.Grows("location", nil, "", "", func(index int, value map[string]interface{}) {

View File

@ -22,7 +22,7 @@ var Index = &ice.Context{Name: "cli", Help: "命令模块",
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmd(ice.CTX_CONFIG, "load", "cli.json") m.Load()
// 启动配置 // 启动配置
m.Conf(ice.CLI_RUNTIME, "conf.ctx_self", os.Getenv("ctx_self")) m.Conf(ice.CLI_RUNTIME, "conf.ctx_self", os.Getenv("ctx_self"))
@ -59,7 +59,7 @@ var Index = &ice.Context{Name: "cli", Help: "命令模块",
m.Log("info", "runtime %v", kit.Formats(m.Confv(ice.CLI_RUNTIME))) m.Log("info", "runtime %v", kit.Formats(m.Confv(ice.CLI_RUNTIME)))
}}, }},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmd(ice.CTX_CONFIG, "save", "cli.json", ice.CLI_RUNTIME, ice.CLI_SYSTEM) m.Save(ice.CLI_RUNTIME, ice.CLI_SYSTEM)
}}, }},
ice.CLI_RUNTIME: {Name: "runtime", Help: "运行环境", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.CLI_RUNTIME: {Name: "runtime", Help: "运行环境", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {

View File

@ -137,7 +137,7 @@ var Index = &ice.Context{Name: "ctx", Help: "配置模块",
switch arg[0] { switch arg[0] {
case "save": case "save":
// 保存配置 // 保存配置
arg[1] = path.Join(msg.Conf(ice.CTX_CONFIG, ice.Meta("path")), arg[1]) arg[1] = path.Join(msg.Conf(ice.CTX_CONFIG, "meta.path"), arg[1])
if f, p, e := kit.Create(arg[1]); m.Assert(e) { if f, p, e := kit.Create(arg[1]); m.Assert(e) {
data := map[string]interface{}{} data := map[string]interface{}{}
for _, k := range arg[2:] { for _, k := range arg[2:] {
@ -152,7 +152,7 @@ var Index = &ice.Context{Name: "ctx", Help: "配置模块",
} }
case "load": case "load":
// 加载配置 // 加载配置
arg[1] = path.Join(msg.Conf(ice.CTX_CONFIG, ice.Meta("path")), arg[1]) arg[1] = path.Join(msg.Conf(ice.CTX_CONFIG, "meta.path"), arg[1])
if f, e := os.Open(arg[1]); e == nil { if f, e := os.Open(arg[1]); e == nil {
data := map[string]interface{}{} data := map[string]interface{}{}
json.NewDecoder(f).Decode(&data) json.NewDecoder(f).Decode(&data)

View File

@ -111,6 +111,7 @@ var Index = &ice.Context{Name: "gdb", Help: "事件模块",
close(f.d) close(f.d)
} }
}}, }},
ice.GDB_SIGNAL: {Name: "signal", Help: "信号器", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.GDB_SIGNAL: {Name: "signal", Help: "信号器", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
switch arg[0] { switch arg[0] {
case "listen": case "listen":

View File

@ -8,11 +8,6 @@ var Index = &ice.Context{Name: "lex", Help: "词法模块",
Caches: map[string]*ice.Cache{}, Caches: map[string]*ice.Cache{},
Configs: map[string]*ice.Config{}, Configs: map[string]*ice.Config{},
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
}},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
}},
"hi": {Name: "hi", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { "hi": {Name: "hi", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Echo("hello %s world", c.Name) m.Echo("hello %s world", c.Name)
}}, }},

View File

@ -16,11 +16,6 @@ var Index = &ice.Context{Name: "mdb", Help: "数据模块",
Caches: map[string]*ice.Cache{}, Caches: map[string]*ice.Cache{},
Configs: map[string]*ice.Config{}, Configs: map[string]*ice.Config{},
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
}},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
}},
"update": {Name: "update config table index key value", Help: "修改数据", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { "update": {Name: "update config table index key value", Help: "修改数据", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
meta := m.Confm(arg[0], arg[1]+".meta") meta := m.Confm(arg[0], arg[1]+".meta")
index := kit.Int(arg[2]) - kit.Int(meta["offset"]) - 1 index := kit.Int(arg[2]) - kit.Int(meta["offset"]) - 1

View File

@ -141,9 +141,6 @@ var Index = &ice.Context{Name: "nfs", Help: "存储模块",
Caches: map[string]*ice.Cache{}, Caches: map[string]*ice.Cache{},
Configs: map[string]*ice.Config{}, Configs: map[string]*ice.Config{},
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
"dir": {Name: "dir", Help: "目录", List: kit.List( "dir": {Name: "dir", Help: "目录", List: kit.List(
kit.MDB_INPUT, "text", "name", "path", "action", "auto", kit.MDB_INPUT, "text", "name", "path", "action", "auto",
kit.MDB_INPUT, "button", "name", "查看", kit.MDB_INPUT, "button", "name", "查看",

View File

@ -158,9 +158,14 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool {
line += "\n" line += "\n"
continue continue
} }
m.Option(ice.MSG_PROMPT, m.Confv("prompt", "meta.PS1")) if strings.HasPrefix(strings.TrimSpace(line), "#") {
m.Log(ice.LOG_IMPORT, "stdin: %v", line) // 注释
line = ""
continue
}
m.Grow("history", nil, kit.Dict("line", line)) m.Grow("history", nil, kit.Dict("line", line))
m.Option(ice.MSG_PROMPT, m.Confv("prompt", "meta.PS1"))
if f.out == os.Stdout { if f.out == os.Stdout {
f.printf(m, "\033[0m") f.printf(m, "\033[0m")
@ -188,10 +193,10 @@ var Index = &ice.Context{Name: "ssh", Help: "终端模块",
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmd(ice.CTX_CONFIG, "load", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json")) m.Load()
}}, }},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmd(ice.CTX_CONFIG, "save", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json"), kit.Keys(m.Cap(ice.CTX_FOLLOW), "history")) m.Save("history")
if f, ok := m.Target().Server().(*Frame); ok { if f, ok := m.Target().Server().(*Frame); ok {
// 关闭终端 // 关闭终端

View File

@ -11,11 +11,6 @@ var Index = &ice.Context{Name: "tcp", Help: "通信模块",
Caches: map[string]*ice.Cache{}, Caches: map[string]*ice.Cache{},
Configs: map[string]*ice.Config{}, Configs: map[string]*ice.Config{},
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
}},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
}},
"ifconfig": {Name: "ifconfig [name]", Help: "网络配置", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { "ifconfig": {Name: "ifconfig [name]", Help: "网络配置", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if ifs, e := net.Interfaces(); m.Assert(e) { if ifs, e := net.Interfaces(); m.Assert(e) {
for _, v := range ifs { for _, v := range ifs {

View File

@ -35,8 +35,13 @@ type Frame struct {
send map[string]*ice.Message send map[string]*ice.Message
} }
func Redirect(msg *ice.Message, url string, arg ...interface{}) *ice.Message {
msg.Push("_output", "redirect")
msg.Echo(kit.MergeURL(url, arg...))
return msg
}
func Cookie(msg *ice.Message, sessid string) string { func Cookie(msg *ice.Message, sessid string) string {
expire := time.Now().Add(kit.Duration(msg.Conf(ice.AAA_SESS, ice.Meta("expire")))) expire := time.Now().Add(kit.Duration(msg.Conf(ice.AAA_SESS, "meta.expire")))
msg.Log("cookie", "expire:%v sessid:%s", kit.Format(expire), sessid) msg.Log("cookie", "expire:%v sessid:%s", kit.Format(expire), sessid)
http.SetCookie(msg.W, &http.Cookie{Name: ice.WEB_SESS, Value: sessid, Path: "/", Expires: expire}) http.SetCookie(msg.W, &http.Cookie{Name: ice.WEB_SESS, Value: sessid, Path: "/", Expires: expire})
return sessid return sessid
@ -219,6 +224,9 @@ func (web *Frame) HandleCmd(m *ice.Message, key string, cmd *ice.Command) {
// 请求参数 // 请求参数
for k, v := range r.Form { for k, v := range r.Form {
msg.Optionv(k, v) msg.Optionv(k, v)
if k == ice.MSG_SESSID {
Cookie(msg, v[0])
}
} }
if msg.Optionv("cmds") == nil { if msg.Optionv("cmds") == nil {
@ -322,7 +330,7 @@ func (web *Frame) Start(m *ice.Message, arg ...string) bool {
// 静态路由 // 静态路由
msg := m.Spawns(s) msg := m.Spawns(s)
m.Confm(ice.WEB_SERVE, ice.Meta("static"), func(key string, value string) { m.Confm(ice.WEB_SERVE, "meta.static", func(key string, value string) {
m.Log("route", "%s <- %s <- %s", s.Name, key, value) m.Log("route", "%s <- %s <- %s", s.Name, key, value)
w.Handle(key, http.StripPrefix(key, http.FileServer(http.Dir(value)))) w.Handle(key, http.StripPrefix(key, http.FileServer(http.Dir(value))))
}) })
@ -389,9 +397,10 @@ var Index = &ice.Context{Name: "web", Help: "网络模块",
ice.WEB_DREAM: {Name: "dream", Help: "梦想家", Value: kit.Data("path", "usr/local/work", ice.WEB_DREAM: {Name: "dream", Help: "梦想家", Value: kit.Data("path", "usr/local/work",
"cmd", []interface{}{ice.CLI_SYSTEM, "ice.sh", "start", ice.WEB_SPACE, "connect"}, "cmd", []interface{}{ice.CLI_SYSTEM, "ice.sh", "start", ice.WEB_SPACE, "connect"},
)}, )},
ice.WEB_FAVOR: {Name: "favor", Help: "收藏夹", Value: kit.Data(kit.MDB_SHORT, kit.MDB_NAME)}, ice.WEB_FAVOR: {Name: "favor", Help: "收藏夹", Value: kit.Data(kit.MDB_SHORT, kit.MDB_NAME)},
ice.WEB_CACHE: {Name: "cache", Help: "缓存池", Value: kit.Data( ice.WEB_CACHE: {Name: "cache", Help: "缓存池", Value: kit.Data(
kit.MDB_SHORT, "text", "path", "var/file", "store", "var/data", "limit", "30", "least", "10", "fsize", "100000", kit.MDB_SHORT, "text", "path", "var/file", "store", "var/data", "limit", "50", "least", "30", "fsize", "100000",
)}, )},
ice.WEB_STORY: {Name: "story", Help: "故事会", Value: kit.Dict( ice.WEB_STORY: {Name: "story", Help: "故事会", Value: kit.Dict(
kit.MDB_META, kit.Dict(kit.MDB_SHORT, "data"), kit.MDB_META, kit.Dict(kit.MDB_SHORT, "data"),
@ -399,6 +408,7 @@ var Index = &ice.Context{Name: "web", Help: "网络模块",
"mime", kit.Dict("md", "txt"), "mime", kit.Dict("md", "txt"),
)}, )},
ice.WEB_SHARE: {Name: "share", Help: "共享链", Value: kit.Data("template", share_template)}, ice.WEB_SHARE: {Name: "share", Help: "共享链", Value: kit.Data("template", share_template)},
ice.WEB_ROUTE: {Name: "route", Help: "路由", Value: kit.Data()}, ice.WEB_ROUTE: {Name: "route", Help: "路由", Value: kit.Data()},
ice.WEB_PROXY: {Name: "proxy", Help: "代理", Value: kit.Data()}, ice.WEB_PROXY: {Name: "proxy", Help: "代理", Value: kit.Data()},
ice.WEB_GROUP: {Name: "group", Help: "分组", Value: kit.Data()}, ice.WEB_GROUP: {Name: "group", Help: "分组", Value: kit.Data()},
@ -406,7 +416,7 @@ var Index = &ice.Context{Name: "web", Help: "网络模块",
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmd(ice.CTX_CONFIG, "load", "web.json") m.Load()
if m.Richs(ice.WEB_SPIDE, nil, "self", nil) == nil { if m.Richs(ice.WEB_SPIDE, nil, "self", nil) == nil {
m.Cmd(ice.WEB_SPIDE, "add", "self", kit.Select("http://:9020", m.Conf(ice.CLI_RUNTIME, "conf.ctx_self"))) m.Cmd(ice.WEB_SPIDE, "add", "self", kit.Select("http://:9020", m.Conf(ice.CLI_RUNTIME, "conf.ctx_self")))
@ -427,8 +437,7 @@ var Index = &ice.Context{Name: "web", Help: "网络模块",
} }
}) })
// m.Conf(ice.WEB_CACHE, "hash", kit.Dict()) // m.Conf(ice.WEB_CACHE, "hash", kit.Dict())
m.Cmd(ice.CTX_CONFIG, "save", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json"), m.Save(ice.WEB_SPIDE, ice.WEB_FAVOR, ice.WEB_CACHE, ice.WEB_STORY, ice.WEB_SHARE)
ice.WEB_SPIDE, ice.WEB_FAVOR, ice.WEB_CACHE, ice.WEB_STORY, ice.WEB_SHARE)
m.Done() m.Done()
m.Richs(ice.WEB_SPACE, nil, "*", func(key string, value map[string]interface{}) { m.Richs(ice.WEB_SPACE, nil, "*", func(key string, value map[string]interface{}) {
@ -1007,7 +1016,7 @@ var Index = &ice.Context{Name: "web", Help: "网络模块",
defer f.Close() defer f.Close()
h := kit.Hashs(f) h := kit.Hashs(f)
if o, p, e := kit.Create(path.Join(m.Conf(ice.WEB_CACHE, ice.Meta("path")), h[:2], h)); m.Assert(e) { if o, p, e := kit.Create(path.Join(m.Conf(ice.WEB_CACHE, "meta.path"), h[:2], h)); m.Assert(e) {
defer o.Close() defer o.Close()
f.Seek(0, os.SEEK_SET) f.Seek(0, os.SEEK_SET)
@ -1026,7 +1035,7 @@ var Index = &ice.Context{Name: "web", Help: "网络模块",
// 创建文件 // 创建文件
file := kit.Hashs(f) file := kit.Hashs(f)
if o, p, e := kit.Create(path.Join(m.Conf(ice.WEB_CACHE, ice.Meta("path")), file[:2], file)); m.Assert(e) { if o, p, e := kit.Create(path.Join(m.Conf(ice.WEB_CACHE, "meta.path"), file[:2], file)); m.Assert(e) {
defer o.Close() defer o.Close()
// 保存文件 // 保存文件
@ -1040,7 +1049,7 @@ var Index = &ice.Context{Name: "web", Help: "网络模块",
} else if r, ok := m.Optionv("response").(*http.Response); ok { } else if r, ok := m.Optionv("response").(*http.Response); ok {
if buf, e := ioutil.ReadAll(r.Body); m.Assert(e) { if buf, e := ioutil.ReadAll(r.Body); m.Assert(e) {
file := kit.Hashs(string(buf)) file := kit.Hashs(string(buf))
if o, p, e := kit.Create(path.Join(m.Conf(ice.WEB_CACHE, ice.Meta("path")), file[:2], file)); m.Assert(e) { if o, p, e := kit.Create(path.Join(m.Conf(ice.WEB_CACHE, "meta.path"), file[:2], file)); m.Assert(e) {
defer o.Close() defer o.Close()
if n, e := o.Write(buf); m.Assert(e) { if n, e := o.Write(buf); m.Assert(e) {
m.Info("download: %s file: %s", kit.FmtSize(int64(n)), p) m.Info("download: %s file: %s", kit.FmtSize(int64(n)), p)
@ -1062,7 +1071,7 @@ var Index = &ice.Context{Name: "web", Help: "网络模块",
// 保存数据 // 保存数据
if arg[0] == "add" && len(arg) == 4 { if arg[0] == "add" && len(arg) == 4 {
p := path.Join(m.Conf(ice.WEB_CACHE, ice.Meta("path")), h[:2], h) p := path.Join(m.Conf(ice.WEB_CACHE, "meta.path"), h[:2], h)
if m.Cmd("nfs.save", p, arg[3]); kit.Int(size) > 512 { if m.Cmd("nfs.save", p, arg[3]); kit.Int(size) > 512 {
data["text"], data["file"], arg[3] = p, p, p data["text"], data["file"], arg[3] = p, p, p
} }
@ -1326,7 +1335,7 @@ var Index = &ice.Context{Name: "web", Help: "网络模块",
case "commit": case "commit":
// 查询索引 // 查询索引
head := kit.Hashs(arg[1]) head := kit.Hashs(arg[1])
prev := m.Conf("story", ice.Meta("head", head, "list")) prev := m.Conf("story", kit.Keys("meta.head", head, "list"))
m.Log("info", "head: %v prev: %v", head, prev) m.Log("info", "head: %v prev: %v", head, prev)
// 查询节点 // 查询节点
@ -1336,7 +1345,7 @@ var Index = &ice.Context{Name: "web", Help: "网络模块",
menu[arg[i]] = arg[i+1] menu[arg[i]] = arg[i+1]
i++ i++
} else if head := kit.Hashs(arg[i]); m.Confs("story", kit.Keys("meta", "head", head)) { } else if head := kit.Hashs(arg[i]); m.Confs("story", kit.Keys("meta", "head", head)) {
menu[arg[i]] = m.Conf(ice.WEB_STORY, ice.Meta("head", head, "list")) menu[arg[i]] = m.Conf(ice.WEB_STORY, kit.Keys("meta.head", head, "list"))
} else { } else {
m.Error(true, "not found %v", arg[i]) m.Error(true, "not found %v", arg[i])
return return
@ -1355,7 +1364,7 @@ var Index = &ice.Context{Name: "web", Help: "网络模块",
m.Log("info", "list: %v meta: %v", list, kit.Format(meta)) m.Log("info", "list: %v meta: %v", list, kit.Format(meta))
// 添加索引 // 添加索引
m.Conf("story", ice.Meta("head", head), map[string]interface{}{ m.Conf("story", kit.Keys("meta.head", head), map[string]interface{}{
"time": m.Time(), "scene": "commit", "story": arg[1], "list": list, "time": m.Time(), "scene": "commit", "story": arg[1], "list": list,
}) })
m.Echo(list) m.Echo(list)
@ -1509,14 +1518,15 @@ var Index = &ice.Context{Name: "web", Help: "网络模块",
default: default:
m.Richs(ice.WEB_SHARE, nil, arg[0], func(key string, value map[string]interface{}) { m.Richs(ice.WEB_SHARE, nil, arg[0], func(key string, value map[string]interface{}) {
m.Info("share %s %v", arg, kit.Format(value))
switch kit.Select("", arg, 1) { switch kit.Select("", arg, 1) {
case "qrcode": case "qrcode":
// 显示共享码
m.Push("_output", "qrcode") m.Push("_output", "qrcode")
m.Echo("%s/%s/", m.Conf(ice.WEB_SHARE, "meta.domain"), key) m.Echo("%s/%s/", m.Conf(ice.WEB_SHARE, "meta.domain"), key)
return return
} }
m.Info("share %s %v", arg, kit.Format(value))
switch value["type"] { switch value["type"] {
case ice.TYPE_STORY: case ice.TYPE_STORY:
if m.Cmdy(ice.WEB_STORY, "index", kit.Value(value, "text")).Append("text") == "" { if m.Cmdy(ice.WEB_STORY, "index", kit.Value(value, "text")).Append("text") == "" {
@ -1543,19 +1553,29 @@ var Index = &ice.Context{Name: "web", Help: "网络模块",
} }
} }
case "river":
// 共享群组
Redirect(m, "/", "share", key, "river", value["text"])
case "storm": case "storm":
// 共享应用
Redirect(m, "/", "share", key, "storm", value["text"], "river", kit.Value(value, "extra.river"))
case "action":
if len(arg) == 1 { if len(arg) == 1 {
m.Push("_output", "redirect") // 跳转主页
m.Echo("/share/%s/", arg[0]) Redirect(m, "/share/"+arg[0]+"/", "title", value["name"])
break break
} }
if arg[1] == "" { if arg[1] == "" {
// 返回主页
http.ServeFile(m.W, m.R, "usr/volcanos/share.html") http.ServeFile(m.W, m.R, "usr/volcanos/share.html")
break break
} }
if len(arg) == 2 { if len(arg) == 2 {
// 应用列表
value["count"] = kit.Int(value["count"]) + 1 value["count"] = kit.Int(value["count"]) + 1
kit.Fetch(kit.Value(value, "extra.tool"), func(index int, value map[string]interface{}) { kit.Fetch(kit.Value(value, "extra.tool"), func(index int, value map[string]interface{}) {
m.Push("river", arg[0]) m.Push("river", arg[0])
@ -1565,7 +1585,6 @@ var Index = &ice.Context{Name: "web", Help: "网络模块",
m.Push("node", value["pod"]) m.Push("node", value["pod"])
m.Push("group", value["ctx"]) m.Push("group", value["ctx"])
m.Push("index", value["cmd"]) m.Push("index", value["cmd"])
m.Push("args", value["args"]) m.Push("args", value["args"])
msg := m.Cmd(m.Space(value["pod"]), ice.CTX_COMMAND, value["ctx"], value["cmd"]) msg := m.Cmd(m.Space(value["pod"]), ice.CTX_COMMAND, value["ctx"], value["cmd"])
@ -1577,47 +1596,25 @@ var Index = &ice.Context{Name: "web", Help: "网络模块",
break break
} }
// 执行命令
meta := kit.Value(value, kit.Format("extra.tool.%s", arg[2])).(map[string]interface{}) meta := kit.Value(value, kit.Format("extra.tool.%s", arg[2])).(map[string]interface{})
if meta["single"] == "yes" {
arg = append(arg[:3], kit.Simple(kit.UnMarshal(kit.Format(meta["args"])))...)
for i := len(arg) - 1; i >= 0; i-- {
if arg[i] != "" {
break
}
arg = arg[:i]
}
}
cmds := kit.Simple(m.Space(meta["pod"]), kit.Keys(meta["ctx"], meta["cmd"]), arg[3:]) cmds := kit.Simple(m.Space(meta["pod"]), kit.Keys(meta["ctx"], meta["cmd"]), arg[3:])
m.Cmdy(cmds).Option("cmds", cmds) m.Cmdy(cmds).Option("cmds", cmds)
m.Option("title", value["name"])
case "action":
if len(arg) == 1 {
m.Push("_output", "redirect")
m.Echo("/share/%s/", arg[0])
break
}
if arg[1] == "" {
http.ServeFile(m.W, m.R, "usr/volcanos/share.html")
break
}
meta := kit.Value(value, "extra").(map[string]interface{})
if len(arg) == 2 {
m.Push("river", arg[0])
m.Push("storm", arg[1])
m.Push("action", "0")
msg := m.Cmd(m.Space(meta["pod"]), ice.CTX_COMMAND, meta["ctx"], meta["cmd"])
m.Push("name", meta["cmd"])
m.Push("help", kit.Select(msg.Append("help"), kit.Format(meta["help"])))
m.Push("inputs", msg.Append("list"))
m.Push("feature", msg.Append("meta"))
break
}
cmds := kit.Simple(m.Space(meta["pod"]), kit.Keys(meta["ctx"], meta["cmd"]), arg[3:])
m.Cmdy(cmds).Option("cmds", cmds)
case "active": case "active":
m.Push("_output", "qrcode") m.Push("_output", "qrcode")
m.Echo(kit.Format(value)) m.Echo(kit.Format(value))
case "qrcode":
m.Push("_output", "qrcode")
m.Echo("%s", value["text"])
default: default:
if m.Cmdy(ice.WEB_STORY, "index", value["data"]); m.Append("file") != "" { if m.Cmdy(ice.WEB_STORY, "index", value["data"]); m.Append("file") != "" {
m.Push("_output", "file") m.Push("_output", "file")

View File

@ -8,11 +8,6 @@ var Index = &ice.Context{Name: "yac", Help: "语法模块",
Caches: map[string]*ice.Cache{}, Caches: map[string]*ice.Cache{},
Configs: map[string]*ice.Config{}, Configs: map[string]*ice.Config{},
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
}},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
}},
"hi": {Name: "hi", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { "hi": {Name: "hi", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Echo("hello %s world", c.Name) m.Echo("hello %s world", c.Name)
}}, }},

51
conf.go
View File

@ -6,18 +6,11 @@ const ( // ICE
ICE_EXIT = "_exit" ICE_EXIT = "_exit"
ICE_DATE = "2006-01-02" ICE_DATE = "2006-01-02"
ICE_TIME = "2006-01-02 15:04:05" ICE_TIME = "2006-01-02 15:04:05"
)
const ( // CTX ICE_BEGIN = "begin"
CTX_STATUS = "status" ICE_START = "start"
CTX_STREAM = "stream" ICE_SERVE = "serve"
CTX_FOLLOW = "follow" ICE_CLOSE = "close"
CTX_CONFIG = "config"
CTX_COMMAND = "command"
CTX_CONTEXT = "context"
)
const ( // CLI
CLI_RUNTIME = "runtime"
CLI_SYSTEM = "system"
) )
const ( // MSG const ( // MSG
MSG_DETAIL = "detail" MSG_DETAIL = "detail"
@ -25,11 +18,11 @@ const ( // MSG
MSG_APPEND = "append" MSG_APPEND = "append"
MSG_RESULT = "result" MSG_RESULT = "result"
MSG_ACTION = "_action"
MSG_SOURCE = "_source" MSG_SOURCE = "_source"
MSG_TARGET = "_target" MSG_TARGET = "_target"
MSG_ACTION = "_action"
MSG_HANDLE = "_handle" MSG_HANDLE = "_handle"
MSG_STDOUT = "_stdout" MSG_STDOUT = "_stdout"
MSG_PROMPT = "_prompt" MSG_PROMPT = "_prompt"
MSG_ALIAS = "_alias" MSG_ALIAS = "_alias"
@ -44,6 +37,18 @@ const ( // MSG
MSG_RIVER = "sess.river" MSG_RIVER = "sess.river"
MSG_STORM = "sess.storm" MSG_STORM = "sess.storm"
) )
const ( // CTX
CTX_STATUS = "status"
CTX_STREAM = "stream"
CTX_FOLLOW = "follow"
CTX_CONFIG = "config"
CTX_COMMAND = "command"
CTX_CONTEXT = "context"
)
const ( // CLI
CLI_RUNTIME = "runtime"
CLI_SYSTEM = "system"
)
const ( // AAA const ( // AAA
AAA_ROLE = "role" AAA_ROLE = "role"
AAA_USER = "user" AAA_USER = "user"
@ -60,10 +65,12 @@ const ( // WEB
WEB_SERVE = "serve" WEB_SERVE = "serve"
WEB_SPACE = "space" WEB_SPACE = "space"
WEB_DREAM = "dream" WEB_DREAM = "dream"
WEB_FAVOR = "favor" WEB_FAVOR = "favor"
WEB_CACHE = "cache" WEB_CACHE = "cache"
WEB_STORY = "story" WEB_STORY = "story"
WEB_SHARE = "share" WEB_SHARE = "share"
WEB_ROUTE = "route" WEB_ROUTE = "route"
WEB_PROXY = "proxy" WEB_PROXY = "proxy"
WEB_GROUP = "group" WEB_GROUP = "group"
@ -77,9 +84,12 @@ const ( // WEB
const ( // LOG const ( // LOG
LOG_ENABLE = "enable" LOG_ENABLE = "enable"
LOG_IMPORT = "import" LOG_IMPORT = "import"
LOG_MODIFY = "modify"
LOG_CREATE = "create" LOG_CREATE = "create"
LOG_INSERT = "insert" LOG_INSERT = "insert"
LOG_SELECT = "select"
LOG_MODIFY = "modify"
LOG_DELETE = "delete"
LOG_REMOVE = "remove"
LOG_EXPORT = "export" LOG_EXPORT = "export"
LOG_LISTEN = "listen" LOG_LISTEN = "listen"
@ -114,7 +124,9 @@ const ( // GDB
DREAM_CLOSE = "dream.close" DREAM_CLOSE = "dream.close"
USER_CREATE = "user.create" USER_CREATE = "user.create"
CHAT_CREATE = "chat.create"
MISS_CREATE = "miss.create" MISS_CREATE = "miss.create"
MIND_CREATE = "mind.create"
) )
const ( // MDB const ( // MDB
MDB_REDIS = "redis" MDB_REDIS = "redis"
@ -144,11 +156,11 @@ const ( // CHAT
) )
const ( // TYPE const ( // TYPE
TYPE_SPACE = "space" TYPE_SPACE = "space"
TYPE_STORY = "story"
TYPE_RIVER = "river" TYPE_RIVER = "river"
TYPE_STORM = "storm" TYPE_STORM = "storm"
TYPE_DRIVE = "drive" TYPE_DRIVE = "drive"
TYPE_STORY = "story"
TYPE_SHELL = "shell" TYPE_SHELL = "shell"
TYPE_VIMRC = "vimrc" TYPE_VIMRC = "vimrc"
TYPE_TABLE = "table" TYPE_TABLE = "table"
@ -159,7 +171,6 @@ const ( // FAVOR
FAVOR_CHAT = "chat.init" FAVOR_CHAT = "chat.init"
FAVOR_TMUX = "tmux.init" FAVOR_TMUX = "tmux.init"
FAVOR_START = "favor.start" FAVOR_START = "favor.start"
FAVOR_MISS = "miss"
) )
const ( // STORY const ( // STORY
STORY_CATCH = "catch" STORY_CATCH = "catch"
@ -176,9 +187,9 @@ const ( // STORY
) )
var Alias = map[string]string{ var Alias = map[string]string{
CTX_CONFIG: "ctx.config",
CTX_COMMAND: "ctx.command",
CTX_CONTEXT: "ctx.context", CTX_CONTEXT: "ctx.context",
CTX_COMMAND: "ctx.command",
CTX_CONFIG: "ctx.config",
CLI_RUNTIME: "cli.runtime", CLI_RUNTIME: "cli.runtime",
CLI_SYSTEM: "cli.system", CLI_SYSTEM: "cli.system",
@ -191,10 +202,12 @@ var Alias = map[string]string{
WEB_SERVE: "web.serve", WEB_SERVE: "web.serve",
WEB_SPACE: "web.space", WEB_SPACE: "web.space",
WEB_DREAM: "web.dream", WEB_DREAM: "web.dream",
WEB_FAVOR: "web.favor", WEB_FAVOR: "web.favor",
WEB_CACHE: "web.cache", WEB_CACHE: "web.cache",
WEB_STORY: "web.story", WEB_STORY: "web.story",
WEB_SHARE: "web.share", WEB_SHARE: "web.share",
WEB_ROUTE: "web.route", WEB_ROUTE: "web.route",
WEB_PROXY: "web.proxy", WEB_PROXY: "web.proxy",
WEB_GROUP: "web.group", WEB_GROUP: "web.group",

View File

@ -10,83 +10,143 @@ import (
var Index = &ice.Context{Name: "chat", Help: "聊天中心", var Index = &ice.Context{Name: "chat", Help: "聊天中心",
Caches: map[string]*ice.Cache{}, Caches: map[string]*ice.Cache{},
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{
ice.CHAT_RIVER: {Name: "river", Help: "群组", Value: kit.Data()}, ice.CHAT_RIVER: {Name: "river", Help: "群组", Value: kit.Data(
"template", kit.Dict("root", []interface{}{
[]interface{}{"storm", "mall", "mall"},
[]interface{}{"field", "asset", "web.mall"},
[]interface{}{"field", "bonus", "web.mall"},
[]interface{}{"field", "trans", "web.mall"},
[]interface{}{"field", "spend", "web.mall"},
[]interface{}{"storm", "team", "team"},
[]interface{}{"field", "miss", "web.team"},
[]interface{}{"field", "task", "web.team"},
[]interface{}{"field", "stat", "web.team"},
[]interface{}{"field", "plan", "web.team"},
[]interface{}{"storm", "wiki", "wiki"},
[]interface{}{"field", "draw", "web.wiki"},
[]interface{}{"field", "word", "web.wiki"},
[]interface{}{"field", "data", "web.wiki"},
[]interface{}{"field", "feel", "web.wiki"},
[]interface{}{"field", "walk", "web.wiki"},
[]interface{}{"storm", "code", "code"},
[]interface{}{"field", "buffer", "web.code.tmux"},
[]interface{}{"field", "session", "web.code.tmux"},
[]interface{}{"field", "image", "web.code.docker"},
[]interface{}{"field", "container", "web.code.docker"},
[]interface{}{"field", "command", "web.code.docker"},
[]interface{}{"field", "repos", "web.code.git"},
[]interface{}{"field", "total", "web.code.git"},
[]interface{}{"field", "branch", "web.code.git"},
[]interface{}{"field", "status", "web.code.git"},
[]interface{}{"storm", "root"},
[]interface{}{"field", "spide"},
[]interface{}{"field", "space"},
[]interface{}{"field", "dream"},
[]interface{}{"field", "favor"},
[]interface{}{"field", "story"},
[]interface{}{"field", "share"},
}, "void", []interface{}{
[]interface{}{"storm", "wiki", "wiki"},
[]interface{}{"field", "note", "web.wiki"},
}),
"black", kit.Dict("void", []interface{}{
[]interface{}{"/river", "add"},
[]interface{}{"/river", "share"},
[]interface{}{"/river", "rename"},
[]interface{}{"/river", "remove"},
[]interface{}{"/storm", "remove"},
[]interface{}{"/storm", "rename"},
[]interface{}{"/storm", "share"},
[]interface{}{"/storm", "add"},
}),
"white", kit.Dict("void", []interface{}{
[]interface{}{"/river"},
[]interface{}{"/storm"},
[]interface{}{"/action"},
[]interface{}{"web.wiki.note"},
}),
"fe", "volcanos",
)},
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cap(ice.CTX_STATUS, "start") m.Watch(ice.USER_CREATE, m.Prefix(ice.WEB_LOGIN), "init")
m.Cap(ice.CTX_STREAM, "volcanos") m.Watch(ice.SYSTEM_INIT, m.Prefix("init"))
m.Watch(ice.SYSTEM_INIT, "web.chat.init") m.Load()
m.Watch(ice.USER_CREATE, "web.chat./tutor", "init")
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) { ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmd(ice.CTX_CONFIG, "save", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json"), kit.Keys(m.Cap(ice.CTX_FOLLOW), "river")) m.Save("river")
}}, }},
"init": {Name: "init", Help: "初始化", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { "init": {Name: "init", Help: "初始化", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(m.Confm(ice.CHAT_RIVER, "hash")) == 0 { if len(m.Confm(ice.CHAT_RIVER, "hash")) == 0 {
// 系统群组
if m.Richs(ice.WEB_FAVOR, nil, "river.root", nil) == nil { if m.Richs(ice.WEB_FAVOR, nil, "river.root", nil) == nil {
m.Cmd(ice.WEB_FAVOR, "river.root", "storm", "mall", "mall") // 系统群组
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "asset", "web.mall") kit.Fetch(m.Confv(ice.CHAT_RIVER, "meta.template.root"), func(index int, value interface{}) {
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "bonus", "web.mall") m.Cmd(ice.WEB_FAVOR, "river.root", value)
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "trans", "web.mall") })
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "spend", "web.mall") // 默认群组
kit.Fetch(m.Confv(ice.CHAT_RIVER, "meta.template.void"), func(index int, value interface{}) {
m.Cmd(ice.WEB_FAVOR, "river.root", "storm", "team", "team") m.Cmd(ice.WEB_FAVOR, "river.void", value)
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") kit.Fetch(m.Confv(ice.CHAT_RIVER, "meta.black.void"), func(index int, value interface{}) {
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "plan", "web.team") m.Cmd(ice.AAA_ROLE, "black", ice.ROLE_VOID, "enable", value)
})
m.Cmd(ice.WEB_FAVOR, "river.root", "storm", "wiki", "wiki") // 白名单
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "mind", "web.wiki") kit.Fetch(m.Confv(ice.CHAT_RIVER, "meta.white.void"), func(index int, value interface{}) {
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "word", "web.wiki") m.Cmd(ice.AAA_ROLE, "white", ice.ROLE_VOID, "enable", value)
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "data", "web.wiki") })
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "feel", "web.wiki")
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "walk", "web.wiki")
m.Cmd(ice.WEB_FAVOR, "river.root", "storm", "code", "code")
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "buffer", "web.code.tmux")
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "session", "web.code.tmux")
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "image", "web.code.docker")
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "container", "web.code.docker")
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "command", "web.code.docker")
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "repos", "web.code.git")
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "total", "web.code.git")
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "branch", "web.code.git")
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "status", "web.code.git")
m.Cmd(ice.WEB_FAVOR, "river.root", "storm", "root")
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "spide")
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "space")
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "dream")
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "favor")
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "story")
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "share")
} }
// 用户权限 // 用户权限
m.Cmd(ice.AAA_ROLE, "white", ice.ROLE_VOID, "enable", "/river")
m.Cmd(ice.AAA_ROLE, "white", ice.ROLE_VOID, "enable", "/storm")
m.Cmd(ice.AAA_ROLE, "black", ice.ROLE_VOID, "enable", "/storm", "rename")
m.Cmd(ice.AAA_ROLE, "black", ice.ROLE_VOID, "enable", "/storm", "remove")
m.Cmd(ice.AAA_ROLE, "white", ice.ROLE_VOID, "enable", "/action")
m.Cmd(ice.AAA_ROLE, "white", ice.ROLE_VOID, "enable", "dream")
m.Cmd(ice.AAA_ROLE, "black", ice.ROLE_VOID, "enable", "dream.停止")
m.Cmd(ice.AAA_USER, "first", m.Conf(ice.CLI_RUNTIME, "boot.username")) m.Cmd(ice.AAA_USER, "first", m.Conf(ice.CLI_RUNTIME, "boot.username"))
} }
// 前端框架
m.Cmd("web.code.git.check", m.Conf(ice.CHAT_RIVER, "meta.fe"))
m.Cap(ice.CTX_STREAM, m.Conf(ice.CHAT_RIVER, "meta.fe"))
m.Cap(ice.CTX_STATUS, "start")
}}, }},
ice.WEB_LOGIN: {Name: "login", Help: "登录", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.WEB_LOGIN: {Name: "_login", Help: "登录", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) > 0 { if len(arg) > 0 {
switch arg[0] { switch arg[0] {
case "login": case "login":
// 用户登录 // 用户登录
m.Option(ice.MSG_SESSID, web.Cookie(m, m.Cmdx(ice.AAA_USER, "login", m.Option(ice.MSG_USERNAME, arg[1]), arg[2]))) m.Option(ice.MSG_SESSID, web.Cookie(m, m.Cmdx(ice.AAA_USER, "login", m.Option(ice.MSG_USERNAME, arg[1]), arg[2])))
case "init":
// 用户创建
m.Richs(ice.AAA_USER, nil, arg[1], func(key string, value map[string]interface{}) {
m.Option(ice.MSG_USERNAME, value["username"])
m.Option(ice.MSG_USERROLE, m.Cmdx(ice.AAA_ROLE, "check", value["username"]))
name := kit.Select(arg[1], value["nickname"]) + "@" + m.Conf(ice.CLI_RUNTIME, "boot.hostname")
if len(arg[1]) > 8 {
name = kit.Select(arg[1][:8], value["nickname"]) + "@" + m.Conf(ice.CLI_RUNTIME, "boot.hostname")
}
// 创建群组
storm, river := "", m.Option(ice.MSG_RIVER, m.Cmdx("/ocean", "spawn", name, m.Option(ice.MSG_USERNAME)))
// 创建应用
m.Option("cache.limit", "100")
m.Richs(ice.WEB_FAVOR, nil, kit.Keys("river", m.Option(ice.MSG_USERROLE)), func(key string, value map[string]interface{}) {
m.Grows(ice.WEB_FAVOR, kit.Keys("hash", key), "", "", func(index int, value map[string]interface{}) {
switch value["type"] {
case "storm":
storm = m.Option(ice.MSG_STORM, m.Cmdx("/steam", river, "spawn", value["name"]))
case "field":
m.Cmd("/storm", river, storm, "add", "", kit.Select("", value["text"]), value["name"], "")
}
})
})
})
default: default:
// 用户群组 // 用户群组
m.Richs(ice.CHAT_RIVER, nil, arg[0], func(value map[string]interface{}) { m.Richs(ice.CHAT_RIVER, nil, arg[0], func(value map[string]interface{}) {
@ -116,33 +176,14 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心",
m.Option(ice.MSG_USERURL, "") m.Option(ice.MSG_USERURL, "")
m.Push("_output", "status") m.Push("_output", "status")
m.Set("result").Echo("403") m.Set("result").Echo("403")
return
} }
}}, }},
"/toast": {Name: "/toast", Help: "提示", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}}, "/toast": {Name: "/toast", Help: "提示", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
"/tutor": {Name: "/tutor", Help: "向导", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
switch arg[0] {
case "init":
m.Richs(ice.AAA_USER, nil, arg[1], func(key string, value map[string]interface{}) {
m.Option(ice.MSG_USERNAME, value["username"])
m.Option(ice.MSG_USERROLE, m.Cmdx(ice.AAA_ROLE, "check", value["username"]))
storm, river := "", m.Option(ice.MSG_RIVER, m.Cmdx("/ocean", "spawn", kit.Select(arg[1], value["nickname"])+"@"+m.Conf(ice.CLI_RUNTIME, "boot.hostname"), m.Option(ice.MSG_USERNAME)))
m.Richs(ice.WEB_FAVOR, nil, kit.Keys("river", m.Option(ice.MSG_USERROLE)), func(key string, value map[string]interface{}) {
m.Option("cache.limit", "100")
m.Grows(ice.WEB_FAVOR, kit.Keys("hash", key), "", "", func(index int, value map[string]interface{}) {
switch value["type"] {
case "storm":
storm = m.Option(ice.MSG_STORM, m.Cmdx("/steam", river, "spawn", value["name"]))
case "field":
m.Cmd("/storm", river, storm, "add", "", kit.Select("", value["text"]), value["name"], "")
}
})
})
})
}
}},
"/debug": {Name: "/debug", Help: "调试", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
"/carte": {Name: "/carte", Help: "菜单", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}}, "/carte": {Name: "/carte", Help: "菜单", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
"/debug": {Name: "/debug", Help: "调试", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
"/tutor": {Name: "/tutor", Help: "向导", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
"/favor": {Name: "/favor", Help: "收藏", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { "/favor": {Name: "/favor", Help: "收藏", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Hand = false m.Hand = false
if msg := m.Cmd(arg); !msg.Hand { if msg := m.Cmd(arg); !msg.Hand {
@ -158,8 +199,33 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心",
m.Push("nickname", value["nickname"]) m.Push("nickname", value["nickname"])
}) })
m.Echo(m.Option(ice.MSG_USERNAME)) m.Echo(m.Option(ice.MSG_USERNAME))
case "login": case "login":
m.Echo(m.Option(ice.MSG_SESSID)) m.Echo(m.Option(ice.MSG_SESSID))
case "share":
switch arg[1] {
case "river":
case "storm":
case "action":
if m.Option("index") != "" {
arg = append(arg, "tool.0.pod", m.Option("node"))
arg = append(arg, "tool.0.ctx", m.Option("group"))
arg = append(arg, "tool.0.cmd", m.Option("index"))
arg = append(arg, "tool.0.args", m.Option("args"))
arg = append(arg, "tool.0.single", "yes")
} else {
m.Cmd("/action", arg[5], arg[7]).Table(func(index int, value map[string]string, head []string) {
arg = append(arg, kit.Format("tool.%d.pod", index), value["node"])
arg = append(arg, kit.Format("tool.%d.ctx", index), value["group"])
arg = append(arg, kit.Format("tool.%d.cmd", index), value["index"])
arg = append(arg, kit.Format("tool.%d.args", index), value["args"])
})
}
default:
return
}
m.Cmdy(ice.WEB_SHARE, "add", arg[1], arg[2], arg[3], arg[4:])
} }
}}, }},
@ -180,7 +246,8 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心",
"user", kit.Data(kit.MDB_SHORT, "username"), "user", kit.Data(kit.MDB_SHORT, "username"),
"tool", kit.Data(), "tool", kit.Data(),
)) ))
m.Log("create", "river: %v name: %v", river, arg[1]) m.Log(ice.LOG_CREATE, "river: %v name: %v", river, arg[1])
// 添加用户
m.Cmd("/river", river, "add", arg[2:]) m.Cmd("/river", river, "add", arg[2:])
m.Echo(river) m.Echo(river)
} }
@ -200,14 +267,33 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心",
m.Push(key, value["meta"], []string{kit.MDB_KEY, kit.MDB_NAME}) m.Push(key, value["meta"], []string{kit.MDB_KEY, kit.MDB_NAME})
}) })
default: default:
if !m.Right(cmd, arg[1]) {
// 没有权限
m.Push("_output", "status")
m.Set("result").Echo("403")
break
}
switch arg[1] { switch arg[1] {
case "add": case "add":
m.Rich(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0], "user"), kit.Data("username", m.Conf(ice.CLI_RUNTIME, "boot.username"))) m.Rich(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0], "user"), kit.Data("username", m.Conf(ice.CLI_RUNTIME, "boot.username")))
// 添加用户 // 添加用户
for _, v := range arg[2:] { for _, v := range arg[2:] {
user := m.Rich(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0], "user"), kit.Data("username", v)) user := m.Rich(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0], "user"), kit.Data("username", v))
m.Log("insert", "river: %s user: %s name: %s", arg[0], user, v) m.Log(ice.LOG_INSERT, "river: %s user: %s name: %s", arg[0], user, v)
} }
case "rename":
// 重命名群组
old := m.Conf(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0], kit.MDB_META, kit.MDB_NAME))
m.Log(ice.LOG_MODIFY, "river: %s %s->%s", arg[0], old, arg[2])
m.Conf(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0], kit.MDB_META, kit.MDB_NAME), arg[2])
case "remove":
// 删除群组
m.Richs(ice.CHAT_RIVER, nil, arg[0], func(value map[string]interface{}) {
m.Log(ice.LOG_REMOVE, "river: %s value: %s", arg[0], kit.Format(value))
})
m.Conf(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0]), "")
} }
} }
}}, }},
@ -221,6 +307,20 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心",
m.Sort(kit.MDB_NAME) m.Sort(kit.MDB_NAME)
return return
} }
if len(arg) == 2 {
// 应用详情
m.Richs(ice.CHAT_RIVER, prefix, arg[1], func(key string, value map[string]interface{}) {
m.Push(key, value["meta"], []string{kit.MDB_KEY, kit.MDB_NAME})
})
return
}
if !m.Right(cmd, arg[2]) {
// 没有权限
m.Push("_output", "status")
m.Set("result").Echo("403")
return
}
switch arg[2] { switch arg[2] {
case "add": case "add":
@ -229,21 +329,19 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心",
id := m.Grow(ice.CHAT_RIVER, kit.Keys(prefix, kit.MDB_HASH, arg[1]), kit.Data( id := m.Grow(ice.CHAT_RIVER, kit.Keys(prefix, kit.MDB_HASH, arg[1]), kit.Data(
"pod", arg[i], "ctx", arg[i+1], "cmd", arg[i+2], "help", arg[i+3], "pod", arg[i], "ctx", arg[i+1], "cmd", arg[i+2], "help", arg[i+3],
)) ))
m.Log("insert", "storm: %s %d: %v", arg[1], id, arg[i:i+4]) m.Log(ice.LOG_INSERT, "storm: %s %d: %v", arg[1], id, arg[i:i+4])
} }
case "share":
m.Cmdy(ice.WEB_SHARE, "add", arg[3:])
case "rename": case "rename":
// 重命名应用 // 重命名应用
old := m.Conf(ice.CHAT_RIVER, kit.Keys(prefix, kit.MDB_HASH, arg[1], kit.MDB_META, kit.MDB_NAME)) old := m.Conf(ice.CHAT_RIVER, kit.Keys(prefix, kit.MDB_HASH, arg[1], kit.MDB_META, kit.MDB_NAME))
m.Info("rename storm: %s %s->%s", arg[1], old, arg[3]) m.Log(ice.LOG_MODIFY, "storm: %s %s->%s", arg[1], old, arg[3])
m.Conf(ice.CHAT_RIVER, kit.Keys(prefix, kit.MDB_HASH, arg[1], kit.MDB_META, kit.MDB_NAME), arg[3]) m.Conf(ice.CHAT_RIVER, kit.Keys(prefix, kit.MDB_HASH, arg[1], kit.MDB_META, kit.MDB_NAME), arg[3])
case "remove": case "remove":
// 删除应用 // 删除应用
m.Richs(ice.CHAT_RIVER, kit.Keys(prefix), arg[1], func(value map[string]interface{}) { m.Richs(ice.CHAT_RIVER, kit.Keys(prefix), arg[1], func(value map[string]interface{}) {
m.Log("remove", "storm: %s value: %s", arg[1], kit.Format(value)) m.Log(ice.LOG_REMOVE, "storm: %s value: %s", arg[1], kit.Format(value))
}) })
m.Conf(ice.CHAT_RIVER, kit.Keys(prefix, kit.MDB_HASH, arg[1]), "") m.Conf(ice.CHAT_RIVER, kit.Keys(prefix, kit.MDB_HASH, arg[1]), "")
} }
@ -251,6 +349,7 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心",
"/steam": {Name: "/steam", Help: "大气层", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { "/steam": {Name: "/steam", Help: "大气层", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) < 2 { if len(arg) < 2 {
if pod := m.Option("pod"); pod != "" { if pod := m.Option("pod"); pod != "" {
// 远程命令
m.Option("pod", "") m.Option("pod", "")
list := []string{} list := []string{}
m.Cmdy(ice.WEB_SPACE, pod, "web.chat./steam").Table(func(index int, value map[string]string, head []string) { m.Cmdy(ice.WEB_SPACE, pod, "web.chat./steam").Table(func(index int, value map[string]string, head []string) {
@ -259,6 +358,7 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心",
m.Append("name", list) m.Append("name", list)
return return
} }
// 设备列表 // 设备列表
m.Richs(ice.WEB_SPACE, nil, "*", func(key string, value map[string]interface{}) { m.Richs(ice.WEB_SPACE, nil, "*", func(key string, value map[string]interface{}) {
m.Push(key, value, []string{"type", "name", "user"}) m.Push(key, value, []string{"type", "name", "user"})
@ -272,11 +372,13 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心",
storm := m.Rich(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0], "tool"), kit.Dict( storm := m.Rich(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0], "tool"), kit.Dict(
kit.MDB_META, kit.Dict(kit.MDB_NAME, arg[2]), kit.MDB_META, kit.Dict(kit.MDB_NAME, arg[2]),
)) ))
m.Log("create", "storm: %s name: %v", storm, arg[2]) m.Log(ice.LOG_CREATE, "storm: %s name: %v", storm, arg[2])
// 添加工具
m.Cmd("/storm", arg[0], storm, "add", arg[3:]) m.Cmd("/storm", arg[0], storm, "add", arg[3:])
m.Echo(storm) m.Echo(storm)
case "append": case "append":
// 追加工具
m.Cmd("/storm", arg[0], arg[2], "add", arg[3:]) m.Cmd("/storm", arg[0], arg[2], "add", arg[3:])
default: default:
@ -285,7 +387,12 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心",
} }
}}, }},
"/action": {Name: "/action", Help: "小工具", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { "/header": {Name: "/header", Help: "菜单栏", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
"/footer": {Name: "/footer", Help: "状态栏", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
"/target": {Name: "/target", Help: "对话框", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
"/source": {Name: "/source", Help: "输入框", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
"/action": {Name: "/action", Help: "工作台", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
prefix := kit.Keys(kit.MDB_HASH, arg[0], "tool", kit.MDB_HASH, arg[1]) prefix := kit.Keys(kit.MDB_HASH, arg[0], "tool", kit.MDB_HASH, arg[1])
if len(arg) == 2 { if len(arg) == 2 {
// 命令列表 // 命令列表
@ -299,37 +406,28 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心",
m.Push("node", meta["pod"]) m.Push("node", meta["pod"])
m.Push("group", meta["ctx"]) m.Push("group", meta["ctx"])
m.Push("index", meta["cmd"]) m.Push("index", meta["cmd"])
m.Push("args", kit.Select("[]", kit.Format(meta["args"]))) m.Push("args", kit.Select("[]", kit.Format(meta["args"])))
msg := m.Cmd(m.Space(meta["pod"]), ice.CTX_COMMAND, meta["ctx"], meta["cmd"]) msg := m.Cmd(m.Space(meta["pod"]), ice.CTX_COMMAND, meta["ctx"], meta["cmd"])
m.Push("name", meta["cmd"]) m.Push("name", meta["cmd"])
m.Push("help", kit.Select(msg.Append("help"), kit.Format(meta["help"]))) m.Push("help", kit.Select(msg.Append("help"), kit.Format(meta["help"])))
m.Push("inputs", msg.Append("list"))
m.Push("feature", msg.Append("meta")) m.Push("feature", msg.Append("meta"))
m.Push("inputs", msg.Append("list"))
} }
}) })
return return
} }
switch arg[2] { switch arg[2] {
case "share":
list := []string{}
m.Grows(ice.CHAT_RIVER, prefix, "", "", func(index int, value map[string]interface{}) {
for k, v := range value["meta"].(map[string]interface{}) {
list = append(list, kit.Format("tool.%d.%v", index, k), kit.Format(v))
}
})
m.Cmdy(ice.WEB_SHARE, "add", "storm", arg[3], arg[4], list)
case "save": case "save":
// 保存应用
m.Conf(ice.CHAT_RIVER, kit.Keys(prefix, "list"), "") m.Conf(ice.CHAT_RIVER, kit.Keys(prefix, "list"), "")
for i := 3; i < len(arg)-4; i += 5 { for i := 3; i < len(arg)-4; i += 5 {
id := m.Grow(ice.CHAT_RIVER, kit.Keys(prefix), kit.Data( id := m.Grow(ice.CHAT_RIVER, kit.Keys(prefix), kit.Data(
"pod", arg[i], "ctx", arg[i+1], "cmd", arg[i+2], "pod", arg[i], "ctx", arg[i+1], "cmd", arg[i+2],
"help", arg[i+3], "args", arg[i+4], "help", arg[i+3], "args", arg[i+4],
)) ))
m.Log("insert", "storm: %s %d: %v", arg[1], id, arg[i:i+5]) m.Log(ice.LOG_INSERT, "storm: %s %d: %v", arg[1], id, arg[i:i+5])
} }
return return
} }
@ -338,8 +436,6 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心",
cmds := []string{} cmds := []string{}
m.Grows(ice.CHAT_RIVER, prefix, kit.MDB_ID, kit.Format(kit.Int(arg[2])+1), func(index int, value map[string]interface{}) { m.Grows(ice.CHAT_RIVER, prefix, kit.MDB_ID, kit.Format(kit.Int(arg[2])+1), func(index int, value map[string]interface{}) {
if meta, ok := kit.Value(value, "meta").(map[string]interface{}); ok { if meta, ok := kit.Value(value, "meta").(map[string]interface{}); ok {
cmds = kit.Simple(m.Space(meta["pod"]), kit.Keys(meta["ctx"], meta["cmd"]), arg[3:])
// 命令补全 // 命令补全
if len(arg) > 3 && arg[3] == "action" { if len(arg) > 3 && arg[3] == "action" {
switch arg[4] { switch arg[4] {
@ -347,6 +443,14 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心",
// 记录位置 // 记录位置
m.Cmdy("aaa.location", arg[5:]) m.Cmdy("aaa.location", arg[5:])
return return
case "share":
list := []string{}
for k, v := range meta {
list = append(list, k, kit.Format(v))
}
// 共享命令
m.Cmdy(ice.WEB_SHARE, "add", "action", arg[5], arg[6], list)
return
case "input": case "input":
switch arg[5] { switch arg[5] {
case "location": case "location":
@ -354,22 +458,27 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心",
m.Copy(m.Cmd("aaa.location"), "append", "name") m.Copy(m.Cmd("aaa.location"), "append", "name")
return return
} }
case "share":
list := []string{}
for k, v := range meta {
list = append(list, k, kit.Format(v))
}
m.Cmdy(ice.WEB_SHARE, "add", "action", arg[5], arg[6], list)
return
} }
} }
// 组装命令
cmds = kit.Simple(m.Space(meta["pod"]), kit.Keys(meta["ctx"], meta["cmd"]), arg[3:])
} }
}) })
// 执行命令 if len(cmds) == 0 {
if len(cmds) > 0 && m.Right(cmds) { return
m.Cmdy(cmds).Option("cmds", cmds)
} }
if !m.Right(cmd, arg[2]) {
// 没有权限
m.Push("_output", "status")
m.Set("result").Echo("403")
return
}
// 执行命令
m.Cmdy(cmds).Option("cmds", cmds)
}}, }},
}, },
} }

View File

@ -42,7 +42,8 @@ var Index = &ice.Context{Name: "code", Help: "编程中心",
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmd(ice.CTX_CONFIG, "load", "code.json") m.Load()
m.Watch(ice.SYSTEM_INIT, "compile", "linux") m.Watch(ice.SYSTEM_INIT, "compile", "linux")
m.Watch(ice.SYSTEM_INIT, "publish", "bin/ice.sh") m.Watch(ice.SYSTEM_INIT, "publish", "bin/ice.sh")
@ -55,7 +56,7 @@ var Index = &ice.Context{Name: "code", Help: "编程中心",
} }
}}, }},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmd(ice.CTX_CONFIG, "save", "code.json", "web.code.login") m.Save("login")
}}, }},
"compile": {Name: "compile", Help: "编译", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { "compile": {Name: "compile", Help: "编译", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {

View File

@ -28,7 +28,7 @@ var Index = &ice.Context{Name: "mall", Help: "贸易中心",
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmd(ice.CTX_CONFIG, "load", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json")) m.Load()
// m.Cmd(ice.CTX_CONFIG, "load", "mall.json") // m.Cmd(ice.CTX_CONFIG, "load", "mall.json")
// if m.Richs(ice.WEB_SPIDE, nil, "12306", nil) == nil { // if m.Richs(ice.WEB_SPIDE, nil, "12306", nil) == nil {
@ -36,7 +36,7 @@ var Index = &ice.Context{Name: "mall", Help: "贸易中心",
// } // }
}}, }},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmd(ice.CTX_CONFIG, "save", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json"), kit.Keys(m.Cap(ice.CTX_FOLLOW), "asset")) m.Save("asset")
// m.Cmd(ice.CTX_CONFIG, "save", "mall.json", "web.mall.railway") // m.Cmd(ice.CTX_CONFIG, "save", "mall.json", "web.mall.railway")
}}, }},

View File

@ -3,9 +3,13 @@ package shy
import ( import (
_ "github.com/shylinux/icebergs/base" _ "github.com/shylinux/icebergs/base"
_ "github.com/shylinux/icebergs/core/chat"
_ "github.com/shylinux/icebergs/core/code" _ "github.com/shylinux/icebergs/core/code"
_ "github.com/shylinux/icebergs/core/mall"
_ "github.com/shylinux/icebergs/core/team"
_ "github.com/shylinux/icebergs/core/wiki" _ "github.com/shylinux/icebergs/core/wiki"
_ "github.com/shylinux/icebergs/core/chat"
_ "github.com/shylinux/icebergs/core/team"
_ "github.com/shylinux/icebergs/core/mall"
) )

View File

@ -11,6 +11,20 @@ import (
"time" "time"
) )
func ShowDay(m *ice.Message, day time.Time) string {
if day.Day() == 1 {
if day.Month() == 1 {
return kit.Format(`<span data-year="%d" data-month="%d" data-day="%d">%d年</span>`,
day.Year(), day.Month(), day.Day(), day.Year())
} else {
return kit.Format(`<span data-year="%d" data-month="%d" data-day="%d">%d月</span>`,
day.Year(), day.Month(), day.Day(), day.Month())
}
}
return kit.Format(`<span data-year="%d" data-month="%d" data-day="%d">%d</span>`,
day.Year(), day.Month(), day.Day(), day.Day())
}
var Index = &ice.Context{Name: "team", Help: "团队中心", var Index = &ice.Context{Name: "team", Help: "团队中心",
Caches: map[string]*ice.Cache{}, Caches: map[string]*ice.Cache{},
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{
@ -20,55 +34,19 @@ var Index = &ice.Context{Name: "team", Help: "团队中心",
"template", kit.Dict( "template", kit.Dict(
"day", `<div class="task {{.status}}" data-zone="%s" data-id="{{.id}}" data-begin_time="{{.begin_time}}">{{.name}}: {{.text}}</div>`, "day", `<div class="task {{.status}}" data-zone="%s" data-id="{{.id}}" data-begin_time="{{.begin_time}}">{{.name}}: {{.text}}</div>`,
"week", `<div class="task {{.status}}" data-zone="%s" data-id="{{.id}}" data-begin_time="{{.begin_time}}" title="{{.text}}">{{.name}}</div>`, "week", `<div class="task {{.status}}" data-zone="%s" data-id="{{.id}}" data-begin_time="{{.begin_time}}" title="{{.text}}">{{.name}}</div>`,
"month", `<div class="task {{.status}}" data-zone="%s" data-id="{{.id}}" data-begin_time="{{.begin_time}}" title="{{.text}}">{{.name}}</div>`,
"year", `<div class="task {{.status}}" data-zone="%s" data-id="{{.id}}" data-begin_time="{{.begin_time}}">{{.name}}: {{.text}}</div>`, "year", `<div class="task {{.status}}" data-zone="%s" data-id="{{.id}}" data-begin_time="{{.begin_time}}">{{.name}}: {{.text}}</div>`,
), ),
)}, )},
"location": {Name: "location", Help: "位置", Value: kit.Data(kit.MDB_SHORT, "name")},
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmd(ice.CTX_CONFIG, "load", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json")) m.Load()
}}, }},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { 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"), m.Save("task")
kit.Keys(m.Cap(ice.CTX_FOLLOW), "task"))
}}, }},
"miss": {Name: "miss zone type name text", Help: "任务", List: kit.List(
kit.MDB_INPUT, "text", "name", "zone", "action", "auto", "figure", "key",
kit.MDB_INPUT, "text", "name", "type", "figure", "key",
kit.MDB_INPUT, "text", "name", "name", "figure", "key",
kit.MDB_INPUT, "button", "name", "添加",
kit.MDB_INPUT, "textarea", "name", "text",
kit.MDB_INPUT, "text", "name", "location", "figure", "key", "cb", "location",
), Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
if len(arg) > 0 && arg[0] == "action" {
switch arg[1] {
case "input":
switch arg[2] {
case "type", "name":
m.Confm("task", kit.Keys("meta.word", arg[2]), func(key string, value string) {
m.Push(arg[2], key)
m.Push("count", value)
})
m.Sort("count", "int_r")
case "zone":
m.Richs("task", nil, "*", func(key string, value map[string]interface{}) {
m.Push("zone", kit.Value(value, "meta.zone"))
m.Push("count", kit.Value(value, "meta.count"))
})
}
return
}
}
if len(arg) < 2 {
m.Cmdy("task", arg)
return
}
m.Cmdy("task", arg[0], "", arg[1:])
}},
"task": {Name: "task [zone [id [type [name [text args...]]]]]", Help: "任务", Meta: kit.Dict("remote", "you"), List: kit.List( "task": {Name: "task [zone [id [type [name [text args...]]]]]", Help: "任务", Meta: kit.Dict("remote", "you"), List: kit.List(
kit.MDB_INPUT, "text", "name", "zone", "action", "auto", kit.MDB_INPUT, "text", "name", "zone", "action", "auto",
kit.MDB_INPUT, "text", "name", "id", "action", "auto", kit.MDB_INPUT, "text", "name", "id", "action", "auto",
@ -79,7 +57,7 @@ var Index = &ice.Context{Name: "team", Help: "团队中心",
switch arg[1] { switch arg[1] {
case "export": case "export":
// 导出数据 // 导出数据
m.Option("cache.limit", "10000") m.Option("cache.limit", -2)
if f, p, e := kit.Create(arg[2]); m.Assert(e) { if f, p, e := kit.Create(arg[2]); m.Assert(e) {
defer f.Close() defer f.Close()
@ -106,7 +84,6 @@ var Index = &ice.Context{Name: "team", Help: "团队中心",
case "import": case "import":
// 导入数据 // 导入数据
m.Option("cache.limit", "10000")
m.CSV(m.Cmdx("nfs.cat", arg[2])).Table(func(index int, data map[string]string, head []string) { m.CSV(m.Cmdx("nfs.cat", arg[2])).Table(func(index int, data map[string]string, head []string) {
item := kit.Dict("time", data["time"], item := kit.Dict("time", data["time"],
"type", data["type"], "name", data["name"], "text", data["text"], "extra", kit.UnMarshal(data["extra"]), "type", data["type"], "name", data["name"], "text", data["text"], "extra", kit.UnMarshal(data["extra"]),
@ -129,7 +106,7 @@ var Index = &ice.Context{Name: "team", Help: "团队中心",
// 任务修改 // 任务修改
m.Richs(cmd, nil, kit.Select(m.Option("zone"), arg, 6), func(key string, account map[string]interface{}) { m.Richs(cmd, nil, kit.Select(m.Option("zone"), arg, 6), func(key string, account map[string]interface{}) {
m.Grows(cmd, kit.Keys("hash", key), "id", arg[5], func(index int, current map[string]interface{}) { m.Grows(cmd, kit.Keys("hash", key), "id", arg[5], func(index int, current map[string]interface{}) {
m.Log(ice.LOG_MODIFY, "%s: %s %s: %s->%s", key, index, kit.Value(current, arg[2]), arg[2], arg[3]) m.Log(ice.LOG_MODIFY, "%s: %d %s: %s->%s", key, index, kit.Value(current, arg[2]), arg[2], arg[3])
kit.Value(current, arg[2], arg[3]) kit.Value(current, arg[2], arg[3])
}) })
}) })
@ -169,7 +146,7 @@ var Index = &ice.Context{Name: "team", Help: "团队中心",
m.Log(ice.LOG_CREATE, "zone: %s", arg[0]) m.Log(ice.LOG_CREATE, "zone: %s", arg[0])
} }
field := []string{"begin_time", "close_time", "id", "status", "type", "name", "text"} field := []string{"begin_time", "id", "status", "type", "name", "text"}
m.Richs(cmd, nil, arg[0], func(key string, value map[string]interface{}) { m.Richs(cmd, nil, arg[0], func(key string, value map[string]interface{}) {
if len(arg) == 1 { if len(arg) == 1 {
// 任务列表 // 任务列表
@ -234,13 +211,13 @@ var Index = &ice.Context{Name: "team", Help: "团队中心",
m.Echo("%s: %d", kit.Value(value, "meta.zone"), n) m.Echo("%s: %d", kit.Value(value, "meta.zone"), n)
}) })
}}, }},
"plan": {Name: "plan day|week|month|year", Help: "计划", Meta: kit.Dict("display", "team/plan"), List: kit.List( "plan": {Name: "plan day|week|month|year", Help: "计划", Meta: kit.Dict("remote", "you", "display", "team/plan"), List: kit.List(
kit.MDB_INPUT, "select", "name", "scale", "value", "week", "values", []string{"day", "week", "month", "year", "long"}, "action", "auto", kit.MDB_INPUT, "select", "name", "scale", "value", "week", "values", []string{"day", "week", "month", "months", "year", "long"}, "action", "auto",
kit.MDB_INPUT, "text", "name", "begin_time", "figure", "date", "action", "auto", kit.MDB_INPUT, "text", "name", "begin_time", "figure", "date", "action", "auto",
kit.MDB_INPUT, "text", "name", "end_time", "figure", "date", "action", "auto", kit.MDB_INPUT, "text", "name", "end_time", "figure", "date", "action", "auto",
kit.MDB_INPUT, "button", "name", "查看", "action", "auto", kit.MDB_INPUT, "button", "name", "查看", "action", "auto",
), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Option("cache.limit", "10000") m.Option("cache.limit", -1)
// 起始日期 // 起始日期
first := time.Now() first := time.Now()
@ -326,17 +303,22 @@ var Index = &ice.Context{Name: "team", Help: "团队中心",
} }
case "month": case "month":
fallthrough
case "months":
// 月计划 // 月计划
one := first.AddDate(0, 0, -first.Day()+1) one := first.AddDate(0, 0, -first.Day()+1)
end := last.AddDate(0, 1, -last.Day()+1) end := last.AddDate(0, 1, -last.Day()+1)
template := m.Conf("plan", "meta.template.month")
// 查询任务 // 查询任务
name := map[string][]string{}
list := map[string][]map[string]interface{}{} list := map[string][]map[string]interface{}{}
m.Richs("task", nil, "*", func(key string, 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{}) { 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, e := time.ParseInLocation(ice.ICE_TIME, kit.Format(value["begin_time"]), time.Local); e == nil {
if index := t.Format("2006-01-02"); t.After(one) && t.Before(end) { if index := t.Format("2006-01-02"); t.After(one) && t.Before(end) {
list[index] = append(list[index], value) list[index] = append(list[index], value)
name[index] = append(name[index], key)
} }
} }
}) })
@ -345,18 +327,21 @@ var Index = &ice.Context{Name: "team", Help: "团队中心",
// 上月结尾 // 上月结尾
last := one.AddDate(0, 0, -int(one.Weekday())) last := one.AddDate(0, 0, -int(one.Weekday()))
for day := last; day.Before(one); day = day.AddDate(0, 0, 1) { for day := last; day.Before(one); day = day.AddDate(0, 0, 1) {
m.Push(head[int(day.Weekday())], day.Day()) m.Push(head[int(day.Weekday())], ShowDay(m, day))
} }
// 本月日期 // 本月日期
for day := one; day.Before(end); day = day.AddDate(0, 0, 1) { for day := one; day.Before(end); day = day.AddDate(0, 0, 1) {
note := []string{} note := []string{ShowDay(m, day)}
if day.Day() == 1 {
note = append(note, kit.Format("%d月", day.Month()))
} else {
note = append(note, kit.Format("%d", day.Day()))
}
index := day.Format("2006-01-02") index := day.Format("2006-01-02")
if arg[0] == "month" {
for i, v := range list[index] {
b, _ := kit.Render(kit.Format(template, name[index][i]), v)
note = append(note, string(b))
}
m.Push(head[int(day.Weekday())], strings.Join(note, ""))
continue
}
for _, v := range list[index] { for _, v := range list[index] {
note = append(note, kit.Format(`%s: %s`, v["name"], v["text"])) note = append(note, kit.Format(`%s: %s`, v["name"], v["text"]))
} }
@ -366,12 +351,11 @@ var Index = &ice.Context{Name: "team", Help: "团队中心",
note[0] = kit.Format(`%s<sup class="less">%s<sup>`, note[0], "") note[0] = kit.Format(`%s<sup class="less">%s<sup>`, note[0], "")
} }
m.Push(head[int(day.Weekday())], note[0]) m.Push(head[int(day.Weekday())], note[0])
} }
// 下月开头 // 下月开头
tail := end.AddDate(0, 0, 6-int(end.Weekday())+1) tail := end.AddDate(0, 0, 6-int(end.Weekday())+1)
for day := end; end.Weekday() != 0 && day.Before(tail); day = day.AddDate(0, 0, 1) { for day := end; end.Weekday() != 0 && day.Before(tail); day = day.AddDate(0, 0, 1) {
m.Push(head[int(day.Weekday())], day.Day()) m.Push(head[int(day.Weekday())], ShowDay(m, day))
} }
case "year": case "year":
@ -420,71 +404,92 @@ var Index = &ice.Context{Name: "team", Help: "团队中心",
m.Sort("year", "int") m.Sort("year", "int")
} }
}}, }},
"stat": {Name: "stat", Help: "统计", Meta: kit.Dict(), Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { "stat": {Name: "stat", Help: "统计", Meta: kit.Dict("remote", "you"), List: kit.List(
m.Option("cache.limit", "10000") kit.MDB_INPUT, "text", "name", "begin_time", "figure", "date", "action", "auto",
m.Richs("task", nil, kit.Select("*", arg, 0), func(key string, value map[string]interface{}) { kit.MDB_INPUT, "text", "name", "end_time", "figure", "date", "action", "auto",
kit.MDB_INPUT, "button", "name", "查看", "action", "auto",
), Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
begin_time := kit.Time(kit.Select("1990-07-30", arg, 0))
end_time := kit.Time(kit.Select("1990-07-30", arg, 1))
now_time := kit.Time(m.Time())
m.Option("cache.limit", -1)
m.Richs("task", nil, "*", func(key string, value map[string]interface{}) {
stat := map[string]int{} stat := map[string]int{}
m.Grows("task", 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 if len(arg) > 1 && kit.Time(kit.Format(value["begin_time"])) > end_time {
return
}
if len(arg) > 0 && kit.Time(kit.Format(value["begin_time"])) < begin_time {
return
}
if stat[kit.Format(value["status"])] += 1; value["status"] != "prepare" {
use := kit.Time(kit.Format(value["close_time"])) - kit.Time(kit.Format(value["begin_time"]))
if value["status"] == "process" {
use = now_time - kit.Time(kit.Format(value["begin_time"]))
}
stat["sum"] += use
if use > stat["max"] {
stat["max"] = use
}
if use < stat["min"] {
stat["min"] = use
}
}
stat["total"] += 1
}) })
m.Push("zone", kit.Value(value, "meta.zone")) m.Push("zone", kit.Value(value, "meta.zone"))
for _, k := range []string{"prepare", "process", "cancel", "finish"} { for _, k := range []string{"prepare", "process", "cancel", "finish", "total"} {
m.Push(k, stat[k]) m.Push(k, stat[k])
} }
m.Push("sum", kit.FmtTime(int64(stat["sum"])*int64(time.Second)))
if stat["finish"] == 0 {
stat["finish"] = 1
}
m.Push("avg", kit.FmtTime(int64(stat["sum"]/stat["finish"])*int64(time.Second)))
m.Push("min", kit.FmtTime(int64(stat["min"])*int64(time.Second)))
m.Push("max", kit.FmtTime(int64(stat["max"])*int64(time.Second)))
}) })
}}, }},
"miss": {Name: "miss zone type name text", Help: "任务", Meta: kit.Dict("remote", "you"), List: kit.List(
"progress": {Name: "progress", Help: "进度", Meta: kit.Dict( kit.MDB_INPUT, "text", "name", "zone", "figure", "key", "action", "auto",
"remote", "you", "display", "team/miss", kit.MDB_INPUT, "text", "name", "type", "figure", "key",
"detail", []string{"回退", "前进", "取消", "完成"}, kit.MDB_INPUT, "text", "name", "name", "figure", "key",
), List: kit.List( kit.MDB_INPUT, "button", "name", "添加",
kit.MDB_INPUT, "text", "value", "", kit.MDB_INPUT, "textarea", "name", "text",
kit.MDB_INPUT, "button", "value", "查看", "action", "auto", kit.MDB_INPUT, "text", "name", "location", "figure", "key", "cb", "location",
), Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { ), Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
hot := kit.Select(ice.FAVOR_MISS, m.Option("hot")) if len(arg) > 0 && arg[0] == "action" {
if len(arg) > 0 { switch arg[1] {
m.Richs(ice.WEB_FAVOR, nil, hot, func(key string, value map[string]interface{}) { case "input":
m.Grows(ice.WEB_FAVOR, kit.Keys("hash", key), "id", arg[0], func(index int, value map[string]interface{}) { // 输入补全
switch value = value["extra"].(map[string]interface{}); arg[1] { switch arg[2] {
case "前进": case "zone":
if value["status"] == "准备中" { m.Richs("task", nil, "*", func(key string, value map[string]interface{}) {
value["begin_time"] = m.Time() m.Push("zone", kit.Value(value, "meta.zone"))
value["close_time"] = m.Time("30m") m.Push("count", kit.Value(value, "meta.count"))
} })
if next := m.Conf(ice.APP_MISS, kit.Keys("meta.fsm", value["status"], "next")); next != "" { case "type", "name":
value["status"] = next m.Confm("task", kit.Keys("meta.word", arg[2]), func(key string, value string) {
kit.Value(value, "change.-2", kit.Dict("time", m.Time(), "status", next)) m.Push(arg[2], key)
} m.Push("count", value)
})
case "回退": }
if prev := m.Conf(ice.APP_MISS, kit.Keys("meta.fsm", value["status"], "prev")); prev != "" { m.Sort("count", "int_r")
value["status"] = prev return
kit.Value(value, "change.-2", kit.Dict("time", m.Time(), "status", prev)) }
}
case "取消":
value["status"] = "已取消"
value["close_time"] = m.Time()
case "完成":
value["status"] = "已完成"
value["close_time"] = m.Time()
}
})
})
} }
m.Confm(ice.APP_MISS, "meta.mis", func(index int, value string) { if len(arg) < 2 {
m.Push(value, "") // 查询任务
}) m.Cmdy("task", arg)
m.Richs(ice.WEB_FAVOR, nil, hot, func(key string, value map[string]interface{}) { return
m.Grows(ice.WEB_FAVOR, kit.Keys("hash", key), "", "", func(index int, value map[string]interface{}) { }
m.Push(kit.Format(kit.Value(value, "extra.status")), // 创建任务
kit.Format(`<span title="%v" data-id="%v">%v</span>`, m.Cmdy("task", arg[0], "", arg[1:])
kit.Format("%s-%s\n%s", kit.Value(value, "extra.begin_time"), kit.Value(value, "extra.close_time"), value["text"]),
value["id"], value["name"]))
})
})
}}, }},
}, },
} }

View File

@ -18,8 +18,7 @@ var Index = &ice.Context{Name: "wiki", Help: "文档中心",
Caches: map[string]*ice.Cache{}, Caches: map[string]*ice.Cache{},
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{
"note": {Name: "note", Help: "笔记", Value: kit.Data( "note": {Name: "note", Help: "笔记", Value: kit.Data(
"temp", "var/tmp/file", "path", "", "temp", "var/tmp/file",
"path", "",
"head", "time size line path", "head", "time size line path",
"alias", map[string]interface{}{ "alias", map[string]interface{}{
"label": []interface{}{"chart", "label"}, "label": []interface{}{"chart", "label"},
@ -52,11 +51,10 @@ var Index = &ice.Context{Name: "wiki", Help: "文档中心",
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmd(ice.CTX_CONFIG, "load", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json")) m.Load()
}}, }},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmd(ice.CTX_CONFIG, "save", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json"), kit.Keys(m.Cap(ice.CTX_FOLLOW), "feel")) m.Save("feel")
}}, }},
"note": {Name: "note file", Help: "笔记", Meta: kit.Dict("remote", "you", "display", "inner"), List: kit.List( "note": {Name: "note file", Help: "笔记", Meta: kit.Dict("remote", "you", "display", "inner"), List: kit.List(
@ -87,7 +85,7 @@ var Index = &ice.Context{Name: "wiki", Help: "文档中心",
m.Cmdy(kit.Select("_tree", "_text", len(arg) > 0 && strings.HasSuffix(arg[0], ".md")), arg) 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) { "_tree": {Name: "_tree path", Help: "文库", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Option("dir_deep", "true") // m.Option("dir_deep", "true")
m.Option("dir_reg", ".*\\.md") m.Option("dir_reg", ".*\\.md")
m.Cmdy("nfs.dir", kit.Select(m.Conf("note", "meta.path"), arg, 0), m.Conf("note", "meta.head")) m.Cmdy("nfs.dir", kit.Select(m.Conf("note", "meta.path"), arg, 0), m.Conf("note", "meta.head"))
}}, }},
@ -104,11 +102,11 @@ var Index = &ice.Context{Name: "wiki", Help: "文档中心",
// 生成文章 // 生成文章
buffer := bytes.NewBuffer([]byte{}) buffer := bytes.NewBuffer([]byte{})
f := m.Target().Server().(*web.Frame) f := m.Target().Server().(*web.Frame)
tmpl := f.HandleCGI(m, m.Confm("note", ice.Meta("alias")), arg[0]) tmpl := f.HandleCGI(m, m.Confm("note", "meta.alias"), arg[0])
m.Assert(tmpl.ExecuteTemplate(buffer, m.Option("filename", path.Base(arg[0])), m)) m.Assert(tmpl.ExecuteTemplate(buffer, m.Option("filename", path.Base(arg[0])), m))
// 缓存文章 // 缓存文章
if f, p, e := kit.Create(path.Join(m.Conf("note", ice.Meta("temp")), arg[0])); e == nil { if f, p, e := kit.Create(path.Join(m.Conf("note", "meta.temp"), arg[0])); e == nil {
defer f.Close() defer f.Close()
if n, e := f.Write(buffer.Bytes()); e == nil { if n, e := f.Write(buffer.Bytes()); e == nil {
m.Log("info", "save %d %v", n, p) m.Log("info", "save %d %v", n, p)
@ -303,9 +301,7 @@ var Index = &ice.Context{Name: "wiki", Help: "文档中心",
Stack(m, cmd, 0, kit.Parse(nil, "", chain.show(m, arg[1])...)) Stack(m, cmd, 0, kit.Parse(nil, "", chain.show(m, arg[1])...))
m.Echo("</div>") m.Echo("</div>")
}}, }},
"chart": {Name: "chart label|chain|table name text [fg bg fs ls p m]", Help: "绘图", Meta: map[string]interface{}{ "chart": {Name: "chart label|chain|table name text [fg bg fs ls p m]", Help: "绘图", Meta: map[string]interface{}{}, List: kit.List(
"display": "inner",
}, List: kit.List(
kit.MDB_INPUT, "select", "value", "chain", "values", "block chain table", kit.MDB_INPUT, "select", "value", "chain", "values", "block chain table",
kit.MDB_INPUT, "text", "value", "", kit.MDB_INPUT, "text", "value", "",
kit.MDB_INPUT, "button", "value", "生成", kit.MDB_INPUT, "button", "value", "生成",
@ -342,9 +338,9 @@ var Index = &ice.Context{Name: "wiki", Help: "文档中心",
m.Option("height", chart.GetHeight()) m.Option("height", chart.GetHeight())
// 生成网页 // 生成网页
m.Render(m.Conf("chart", ice.Meta("prefix"))) m.Render(m.Conf("chart", "meta.prefix"))
chart.Draw(m, 4, 4) chart.Draw(m, 4, 4)
m.Render(m.Conf("chart", ice.Meta("suffix"))) m.Render(m.Conf("chart", "meta.suffix"))
}}, }},
"draw": {Name: "draw", Help: "思维导图", Meta: kit.Dict("display", "wiki/draw"), List: kit.List( "draw": {Name: "draw", Help: "思维导图", Meta: kit.Dict("display", "wiki/draw"), List: kit.List(
@ -598,6 +594,19 @@ var Index = &ice.Context{Name: "wiki", Help: "文档中心",
m.Option("scan_mode", "scan") m.Option("scan_mode", "scan")
m.Cmdy("ssh.scan", "some", "some", path.Join(m.Conf("word", "meta.path"), arg[0])) m.Cmdy("ssh.scan", "some", "some", path.Join(m.Conf("word", "meta.path"), arg[0]))
}}, }},
"qrcode": {Name: "qrcode", Help: "扫码", Meta: kit.Dict("display", "wiki/image"), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
data := map[string]interface{}{}
for i := 0; i < len(arg)-1; i += 2 {
kit.Value(data, arg[i], arg[i+1])
}
m.Push("_output", "qrcode")
m.Echo(kit.Format(data))
}},
"qrcode2": {Name: "qrcode2", Help: "扫码", Meta: kit.Dict("display", "wiki/image"), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Push("_output", "qrcode")
m.Echo(kit.MergeURL(arg[0], arg[1:]))
}},
}, },
} }

View File

@ -20,10 +20,10 @@ var Index = &ice.Context{Name: "alpha", Help: "英汉词典",
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmd(ice.CTX_CONFIG, "load", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json")) m.Load()
}}, }},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmd(ice.CTX_CONFIG, "save", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json"), kit.Keys(m.Cap(ice.CTX_FOLLOW), "alpha")) m.Save("alpha")
}}, }},
"alpha": {Name: "alpha [load|list]", Help: "英汉词典", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { "alpha": {Name: "alpha [load|list]", Help: "英汉词典", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {

View File

@ -15,10 +15,10 @@ var Index = &ice.Context{Name: "chrome", Help: "chrome",
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmd(ice.CTX_CONFIG, "load", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json")) m.Load()
}}, }},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmd(ice.CTX_CONFIG, "save", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json"), kit.Keys(m.Cap(ice.CTX_FOLLOW), "history")) m.Save("history")
}}, }},
"/crx": {Name: "/crx", Help: "/crx", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { "/crx": {Name: "/crx", Help: "/crx", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {

View File

@ -23,7 +23,7 @@ var Index = &ice.Context{Name: "git", Help: "代码管理",
if s, e := os.Stat(".git"); e == nil && s.IsDir() { if s, e := os.Stat(".git"); e == nil && s.IsDir() {
m.Rich("repos", nil, kit.Data( m.Rich("repos", nil, kit.Data(
"name", path.Base(wd), "path", wd, "branch", "master", "name", path.Base(wd), "path", wd, "branch", "master",
"remote", strings.TrimSpace(m.Cmdx(ice.CLI_SYSTEM, "git", "remote", "get-url", "origin")), "remote", strings.TrimSpace(m.Cmdx(ice.CLI_SYSTEM, "git", "remote", "-v")),
)) ))
} }
@ -32,7 +32,7 @@ var Index = &ice.Context{Name: "git", Help: "代码管理",
if s, e := os.Stat(m.Option("cmd_dir", path.Join(value["path"], ".git"))); e == nil && s.IsDir() { if s, e := os.Stat(m.Option("cmd_dir", path.Join(value["path"], ".git"))); e == nil && s.IsDir() {
m.Rich("repos", nil, kit.Data( m.Rich("repos", nil, kit.Data(
"name", value["name"], "path", value["path"], "branch", "master", "name", value["name"], "path", value["path"], "branch", "master",
"remote", strings.TrimSpace(m.Cmdx(ice.CLI_SYSTEM, "git", "remote", "get-url", "origin")), "remote", strings.TrimSpace(m.Cmdx(ice.CLI_SYSTEM, "git", "remote", "-v")),
)) ))
} }
}) })
@ -42,11 +42,10 @@ var Index = &ice.Context{Name: "git", Help: "代码管理",
if s, e := os.Stat(m.Option("cmd_dir", path.Join(value["path"], ".git"))); e == nil && s.IsDir() { if s, e := os.Stat(m.Option("cmd_dir", path.Join(value["path"], ".git"))); e == nil && s.IsDir() {
m.Rich("repos", nil, kit.Data( m.Rich("repos", nil, kit.Data(
"name", value["name"], "path", value["path"], "branch", "master", "name", value["name"], "path", value["path"], "branch", "master",
"remote", strings.TrimSpace(m.Cmdx(ice.CLI_SYSTEM, "git", "remote", "get-url", "origin")), "remote", strings.TrimSpace(m.Cmdx(ice.CLI_SYSTEM, "git", "remote", "-v")),
)) ))
} }
}) })
m.Watch(ice.SYSTEM_INIT, "web.code.git.check", "volcanos")
}}, }},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}}, ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},

View File

@ -24,11 +24,11 @@ var Index = &ice.Context{Name: "input", Help: "输入法",
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmd(ice.CTX_CONFIG, "load", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json")) m.Load()
m.Cmd("web.code.git.repos", m.Conf("input", "meta.repos")) m.Cmd("web.code.git.repos", m.Conf("input", "meta.repos"))
}}, }},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmd(ice.CTX_CONFIG, "save", kit.Keys(m.Cap(ice.CTX_FOLLOW), "json"), kit.Keys(m.Cap(ice.CTX_FOLLOW), "input")) m.Save("input")
}}, }},
"load": {Name: "load file [name]", Help: "加载词库", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { "load": {Name: "load file [name]", Help: "加载词库", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {

View File

@ -56,15 +56,16 @@ var Index = &ice.Context{Name: "lark", Help: "lark",
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmd(ice.CTX_CONFIG, "load", "lark.json") m.Load()
m.Confm("app", "meta.userrole", func(key string, value string) { m.Confm("app", "meta.userrole", func(key string, value string) {
m.Cmd(ice.AAA_ROLE, value, key) m.Cmd(ice.AAA_ROLE, value, key)
}) })
m.Cmd(ice.WEB_SPIDE, "add", "lark", m.Conf("app", "meta.lark")) m.Cmd(ice.WEB_SPIDE, "add", "lark", m.Conf("app", "meta.lark"))
}}, }},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmd(ice.CTX_CONFIG, "save", "lark.json", "web.chat.lark.app") m.Save("app")
}}, }},
"app": {Name: "app login|token bot", Help: "应用", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { "app": {Name: "app login|token bot", Help: "应用", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
if len(arg) == 0 { if len(arg) == 0 {
m.Richs("app", nil, "*", func(key string, value map[string]interface{}) { m.Richs("app", nil, "*", func(key string, value map[string]interface{}) {

View File

@ -20,14 +20,14 @@ var Index = &ice.Context{Name: "mp", Help: "小程序",
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmd(ice.CTX_CONFIG, "load", "mp.json") m.Load()
m.Confm("login", "meta.userrole", func(key string, value string) { m.Confm("login", "meta.userrole", func(key string, value string) {
m.Cmd(ice.AAA_ROLE, value, key) m.Cmd(ice.AAA_ROLE, value, key)
}) })
m.Cmd(ice.WEB_SPIDE, "add", "weixin", m.Conf("login", "meta.weixin")) m.Cmd(ice.WEB_SPIDE, "add", "weixin", m.Conf("login", "meta.weixin"))
}}, }},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmd(ice.CTX_CONFIG, "save", "mp.json", "web.chat.mp.login") m.Save("login")
}}, }},
"/login/": {Name: "/login/", Help: "登录", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { "/login/": {Name: "/login/", Help: "登录", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
switch arg[0] { switch arg[0] {
@ -77,8 +77,6 @@ var Index = &ice.Context{Name: "mp", Help: "小程序",
m.Echo(m.Option("scan")).Push("_output", "qrcode") m.Echo(m.Option("scan")).Push("_output", "qrcode")
case "auth": case "auth":
m.Log("fuck", "what %v", m.Option(ice.MSG_USERNAME))
m.Log("fuck", "what %v", m.Option(ice.MSG_SESSID))
if !m.Options(ice.MSG_USERNAME) || !m.Options(ice.MSG_SESSID) { if !m.Options(ice.MSG_USERNAME) || !m.Options(ice.MSG_SESSID) {
m.Echo("401").Push("_output", "status") m.Echo("401").Push("_output", "status")
break break

View File

@ -14,9 +14,6 @@ var Index = &ice.Context{Name: "pi", Help: "pi",
"pi": {Name: "pi", Help: "pi", Value: kit.Data(kit.MDB_SHORT, "name")}, "pi": {Name: "pi", Help: "pi", Value: kit.Data(kit.MDB_SHORT, "name")},
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
"GPIO": {Name: "GPIO", Help: "GPIO", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { "GPIO": {Name: "GPIO", Help: "GPIO", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
p := kit.Format("/sys/class/gpio/gpio%s", arg[0]) p := kit.Format("/sys/class/gpio/gpio%s", arg[0])
if _, e := os.Stat(p); e != nil { if _, e := os.Stat(p); e != nil {

View File

@ -1,7 +1,9 @@
package misc package misc
import ( import (
_ "github.com/shylinux/icebergs/misc/chrome"
_ "github.com/shylinux/icebergs/misc/docker" _ "github.com/shylinux/icebergs/misc/docker"
_ "github.com/shylinux/icebergs/misc/git" _ "github.com/shylinux/icebergs/misc/git"
_ "github.com/shylinux/icebergs/misc/input"
_ "github.com/shylinux/icebergs/misc/tmux" _ "github.com/shylinux/icebergs/misc/tmux"
) )

View File

@ -1,56 +1,167 @@
package wx package wx
import ( import (
"crypto/sha1"
"encoding/hex"
"encoding/xml"
"github.com/shylinux/icebergs" "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/web"
"github.com/shylinux/icebergs/core/chat" "github.com/shylinux/icebergs/core/chat"
"github.com/shylinux/toolkits" "github.com/shylinux/toolkits"
"regexp" "sort"
"strings"
) )
var Index = &ice.Context{Name: "wx", Help: "wx", func reply(m *ice.Message) {
m.Push("_output", "result")
m.Render(m.Conf("login", "meta.template.text"))
}
func action(m *ice.Message) {
m.Push("_output", "result")
m.Echo(`<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[news]]></MsgType>
`, m.Option("FromUserName"), m.Option("ToUserName"), m.Option("CreateTime"))
count := 0
m.Table(func(index int, value map[string]string, head []string) {
count++
})
m.Echo(`<ArticleCount>%d</ArticleCount>
`, count)
m.Echo(`<Articles>
`)
m.Table(func(index int, value map[string]string, head []string) {
m.Echo(`<item>
<Title><![CDATA[%s]]></Title>
<Description><![CDATA[%s]]></Description>
<PicUrl><![CDATA[%s]]></PicUrl>
<Url><![CDATA[%s]]></Url>
</item>
`, value["name"], value["text"], value["view"], value["link"])
})
m.Echo(`</Articles>
`)
m.Echo(`</xml>
`)
m.Info("what %v", m.Result())
}
var Index = &ice.Context{Name: "wx", Help: "公众号",
Caches: map[string]*ice.Cache{}, Caches: map[string]*ice.Cache{},
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{
"login": {Name: "login", Help: "认证", Value: kit.Data("wechat", "https://login.weixin.qq.com")}, "login": {Name: "login", Help: "认证", Value: kit.Data(
"auth", "/sns/jscode2session?grant_type=authorization_code",
"weixin", "https://api.weixin.qq.com",
"appid", "", "appmm", "", "token", "",
"userrole", kit.Dict(),
"template", kit.Dict(
"text", `<xml>
<ToUserName><![CDATA[{{.Option "FromUserName"}}]]></ToUserName>
<FromUserName><![CDATA[{{.Option "ToUserName"}}]]></FromUserName>
<CreateTime>{{.Option "CreateTime"}}</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[{{.Append "reply"}}]]></Content>
</xml>`,
),
"menu", []interface{}{
kit.Dict("name", "home", "text", "主页", "view", "https://shylinux.com/static/volcanos/favicon.ico", "link", "https://shylinux.com"),
kit.Dict("name", "sub", "text", "工具", "view", "https://shylinux.com/static/volcanos/favicon.ico", "link", "https://shylinux.com"),
},
)},
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmd(ice.WEB_SPIDE, "add", "wechat", m.Conf("login", "meta.wechat")) m.Load()
m.Confm("login", "meta.userrole", func(key string, value string) {
m.Cmd(ice.AAA_ROLE, value, key)
})
}},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Save("login")
}}, }},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
"login": {Name: "login", Help: "认证", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { "/login/": {Name: "/login/", Help: "认证", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
what := m.Cmdx(ice.WEB_SPIDE, "wechat", "raw", "GET", "/jslogin", "appid", "wx782c26e4c19acffb", "fun", "new") check := []string{m.Conf("login", "meta.token"), m.Option("timestamp"), m.Option("nonce")}
// what := `window.QRLogin.code = 200; window.QRLogin.uuid = "gZUohppbCw==";` sort.Strings(check)
reg, _ := regexp.Compile(`window.QRLogin.code = (\d+); window.QRLogin.uuid = "(\S+?)";`) b := sha1.Sum([]byte(strings.Join(check, "")))
if list := reg.FindStringSubmatch(what); list[1] == "200" { if m.Warn(m.Option("signature") != hex.EncodeToString(b[:]), "error") {
m.Richs(ice.WEB_SPIDE, nil, "wechat", func(key string, value map[string]interface{}) { // 验证失败
if qrcode := kit.Format("%s/l/%s", kit.Value(value, "client.url"), list[2]); m.R == nil { return
m.Cmdy("cli.python", "qrcode", qrcode)
} else {
m.Push("_output", "qrcode").Echo(qrcode)
}
m.Gos(m, func(m *ice.Message) {
reg, _ := regexp.Compile(`window.code=(\d+)`)
for i := 0; i < 1000; i++ {
what := m.Cmdx(ice.WEB_SPIDE, "wechat", "raw", "GET", "/cgi-bin/mmwebwx-bin/login", "loginicon", "true", "uuid", list[2], "tip", "1", "r", kit.Int(m.Time("stamp"))/1579, "_", m.Time("stamp"))
// window.code=200; window.redirect_uri="https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket=A7_l6ng7wSjNbs7-qD3ArIRJ@qrticket_0&uuid=Ia1-kbZ0wA==&lang=zh_CN&scan=1579005657";
if list := reg.FindStringSubmatch(what); list[1] == "200" {
reg, _ := regexp.Compile(`window.redirect_uri="(\S+)";`)
if list := reg.FindStringSubmatch(what); len(list) > 1 {
what := m.Cmdx(ice.WEB_SPIDE, "wechat", "raw", "GET", list[1])
m.Info("what %s", what)
break
}
}
m.Info("wait scan %v", list)
m.Sleep("1s")
}
})
})
} }
if m.Option("echostr") != "" {
m.Push("_output", "result")
m.Echo(m.Option("echostr"))
// 绑定验证
return
}
// 解析数据
data := struct {
ToUserName string
FromUserName string
CreateTime int
MsgType string
Content string
MsgId int64
}{}
xml.NewDecoder(m.R.Body).Decode(&data)
m.Option("ToUserName", data.ToUserName)
m.Option("FromUserName", data.FromUserName)
m.Option("CreateTime", data.CreateTime)
m.Option(ice.MSG_USERNAME, data.FromUserName)
if m.Richs(ice.AAA_USER, nil, m.Option(ice.MSG_USERNAME), nil) == nil {
// 创建用户
m.Rich(ice.AAA_USER, nil, kit.Dict(
"username", m.Option(ice.MSG_USERNAME),
"usernode", m.Conf(ice.CLI_RUNTIME, "boot.hostname"),
))
m.Event(ice.USER_CREATE, m.Option(ice.MSG_USERNAME))
}
m.Option(ice.MSG_USERROLE, m.Cmdx(ice.AAA_ROLE, "check", data.FromUserName))
m.Info("%s: %s", m.Option(ice.MSG_USERROLE), m.Option(ice.MSG_USERNAME))
m.Option(ice.MSG_SESSID, m.Cmdx(ice.AAA_SESS, "create", m.Option(ice.MSG_USERNAME), m.Option(ice.MSG_USERROLE)))
m.Info("sessid: %s", m.Option(ice.MSG_SESSID))
switch m.Option("MsgType", data.MsgType) {
case "text":
if cmds := kit.Split(data.Content); !m.Right(cmds) {
action(m.Cmdy("menu"))
} else {
switch cmds[0] {
case "menu":
action(m.Cmdy("menu"))
default:
msg := m.Cmd(cmds)
if m.Hand = false; !msg.Hand {
msg = m.Cmd(ice.CLI_SYSTEM, cmds)
}
if msg.Result() == "" {
msg.Table()
}
reply(m.Push("reply", msg.Result()))
}
}
}
}},
"menu": {Name: "menu", Help: "菜单", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
kit.Fetch(m.Confv("login", "meta.menu"), func(index int, value map[string]interface{}) {
m.Push("", value, []string{"name", "text", "view"})
m.Push("link", kit.MergeURL(kit.Format(value["link"]), ice.MSG_SESSID, m.Option(ice.MSG_SESSID)))
})
}}, }},
}, },
} }
func init() { chat.Index.Register(Index, nil) } func init() { chat.Index.Register(Index, &web.Frame{}) }

339
type.go
View File

@ -34,8 +34,8 @@ type Config struct {
type Command struct { type Command struct {
Name string Name string
Help interface{} Help interface{}
Meta map[string]interface{}
List []interface{} List []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)
} }
type Context struct { type Context struct {
@ -74,9 +74,6 @@ func (c *Context) Cap(key string, arg ...interface{}) string {
} }
return c.Caches[key].Value return c.Caches[key].Value
} }
func (c *Context) Server() Server {
return c.server
}
func (c *Context) Run(m *Message, cmd *Command, key string, arg ...string) *Message { func (c *Context) Run(m *Message, cmd *Command, key string, arg ...string) *Message {
m.Hand = true 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)
@ -89,6 +86,9 @@ func (c *Context) Runs(m *Message, cmd string, key string, arg ...string) {
} }
return return
} }
func (c *Context) Server() Server {
return c.server
}
func (c *Context) Register(s *Context, x Server) *Context { func (c *Context) Register(s *Context, x Server) *Context {
Pulse.Log("register", "%s <- %s", c.Name, s.Name) Pulse.Log("register", "%s <- %s", c.Name, s.Name)
if c.contexts == nil { if c.contexts == nil {
@ -112,21 +112,24 @@ func (c *Context) Spawn(m *Message, name string, help string, arg ...string) *Co
return s return s
} }
func (c *Context) Begin(m *Message, arg ...string) *Context { func (c *Context) Begin(m *Message, arg ...string) *Context {
c.Caches[CTX_STATUS] = &Cache{Name: CTX_STATUS, Value: ""}
c.Caches[CTX_STREAM] = &Cache{Name: CTX_STREAM, Value: ""}
c.Caches[CTX_FOLLOW] = &Cache{Name: CTX_FOLLOW, Value: ""} c.Caches[CTX_FOLLOW] = &Cache{Name: CTX_FOLLOW, Value: ""}
c.Caches[CTX_STREAM] = &Cache{Name: CTX_STREAM, Value: ""}
c.Caches[CTX_STATUS] = &Cache{Name: CTX_STATUS, Value: ""}
m.Log(LOG_BEGIN, "%s", c.Name)
if c.begin = m; c.server != nil {
m.TryCatch(m, true, func(m *Message) {
c.server.Begin(m, arg...)
})
}
if c.context == Index { if c.context == Index {
c.Cap(CTX_FOLLOW, c.Name) c.Cap(CTX_FOLLOW, c.Name)
} else if c.context != nil { } else if c.context != nil {
c.Cap(CTX_FOLLOW, kit.Keys(c.context.Cap(CTX_FOLLOW), c.Name)) c.Cap(CTX_FOLLOW, kit.Keys(c.context.Cap(CTX_FOLLOW), c.Name))
} }
m.Log(LOG_BEGIN, "%s", c.Cap(CTX_FOLLOW))
c.Cap(CTX_STATUS, ICE_BEGIN)
if c.begin = m; c.server != nil {
m.TryCatch(m, true, func(m *Message) {
// 初始化模块
c.server.Begin(m, arg...)
})
}
return c return c
} }
func (c *Context) Start(m *Message, arg ...string) bool { func (c *Context) Start(m *Message, arg ...string) bool {
@ -135,12 +138,12 @@ func (c *Context) Start(m *Message, arg ...string) bool {
wait := make(chan bool) wait := make(chan bool)
m.Gos(m, func(m *Message) { m.Gos(m, func(m *Message) {
m.Log(LOG_START, "%s", c.Name) m.Log(LOG_START, "%s", c.Cap(CTX_FOLLOW))
c.Cap(CTX_STATUS, ICE_START)
c.Cap(CTX_STATUS, "start")
wait <- true wait <- true
// 启动模块
c.server.Start(m, arg...) c.server.Start(m, arg...)
c.Cap(CTX_STATUS, "close")
if m.Done(); m.wait != nil { if m.Done(); m.wait != nil {
m.wait <- true m.wait <- true
} }
@ -149,8 +152,11 @@ func (c *Context) Start(m *Message, arg ...string) bool {
return true return true
} }
func (c *Context) Close(m *Message, arg ...string) bool { func (c *Context) Close(m *Message, arg ...string) bool {
m.Log(LOG_CLOSE, "%s", c.Name) m.Log(LOG_CLOSE, "%s", c.Cap(CTX_FOLLOW))
c.Cap(CTX_STATUS, ICE_CLOSE)
if c.server != nil { if c.server != nil {
// 结束模块
return c.server.Close(m, arg...) return c.server.Close(m, arg...)
} }
return true return true
@ -178,11 +184,13 @@ type Message struct {
} }
func (m *Message) Time(args ...interface{}) string { func (m *Message) Time(args ...interface{}) string {
// [duration] [format [args...]]
t := m.time t := m.time
if len(args) > 0 { if len(args) > 0 {
switch arg := args[0].(type) { switch arg := args[0].(type) {
case string: case string:
if d, e := time.ParseDuration(arg); e == nil { if d, e := time.ParseDuration(arg); e == nil {
// 时间偏移
t, args = t.Add(d), args[1:] t, args = t.Add(d), args[1:]
} }
} }
@ -193,6 +201,7 @@ func (m *Message) Time(args ...interface{}) string {
case string: case string:
f = arg f = arg
if len(args) > 1 { if len(args) > 1 {
// 时间格式
f = fmt.Sprintf(f, args[1:]...) f = fmt.Sprintf(f, args[1:]...)
} }
} }
@ -219,13 +228,16 @@ func (m *Message) Format(key interface{}) string {
} else { } else {
return fmt.Sprintf("%dx%d %s", len(m.meta[m.meta["append"][0]]), len(m.meta["append"]), kit.Format(m.meta["append"])) return fmt.Sprintf("%dx%d %s", len(m.meta[m.meta["append"][0]]), len(m.meta["append"]), kit.Format(m.meta["append"]))
} }
case "time": case "time":
return m.Time() return m.Time()
case "ship": case "ship":
return fmt.Sprintf("%s->%s", m.source.Name, m.target.Name) return fmt.Sprintf("%s->%s", m.source.Name, m.target.Name)
case "prefix": case "prefix":
return fmt.Sprintf("%s %d %s->%s", m.Time(), m.code, m.source.Name, m.target.Name) return fmt.Sprintf("%s %d %s->%s", m.Time(), m.code, m.source.Name, m.target.Name)
case "chain": case "chain":
// 调用链
ms := []*Message{} ms := []*Message{}
for msg := m; msg != nil; msg = msg.message { for msg := m; msg != nil; msg = msg.message {
ms = append(ms, msg) ms = append(ms, msg)
@ -265,6 +277,7 @@ func (m *Message) Format(key interface{}) string {
} }
return strings.Join(meta, "") return strings.Join(meta, "")
case "stack": case "stack":
// 调用栈
pc := make([]uintptr, 100) pc := make([]uintptr, 100)
pc = pc[:runtime.Callers(5, pc)] pc = pc[:runtime.Callers(5, pc)]
frames := runtime.CallersFrames(pc) frames := runtime.CallersFrames(pc)
@ -290,10 +303,14 @@ func (m *Message) Formats(key string) string {
switch key { switch key {
case "meta": case "meta":
return kit.Formats(m.meta) return kit.Formats(m.meta)
default:
return m.Format(key)
} }
return m.time.Format(ICE_TIME) return m.Format(key)
}
func (m *Message) Spawns(arg ...interface{}) *Message {
msg := m.Spawn(arg...)
msg.code = m.target.root.ID()
m.messages = append(m.messages, msg)
return msg
} }
func (m *Message) Spawn(arg ...interface{}) *Message { func (m *Message) Spawn(arg ...interface{}) *Message {
msg := &Message{ msg := &Message{
@ -322,28 +339,7 @@ func (m *Message) Spawn(arg ...interface{}) *Message {
} }
return msg return msg
} }
func (m *Message) Spawns(arg ...interface{}) *Message {
msg := m.Spawn(arg...)
msg.code = m.target.root.ID()
m.messages = append(m.messages, msg)
return msg
}
func (m *Message) CSV(text string) *Message {
bio := bytes.NewBufferString(text)
r := csv.NewReader(bio)
heads, _ := r.Read()
for {
lines, e := r.Read()
if e != nil {
break
}
for i, k := range heads {
m.Push(k, kit.Select("", lines, i))
}
}
return m
}
func (m *Message) Add(key string, arg ...string) *Message { func (m *Message) Add(key string, arg ...string) *Message {
switch key { switch key {
case MSG_DETAIL, MSG_RESULT: case MSG_DETAIL, MSG_RESULT:
@ -378,41 +374,16 @@ func (m *Message) Set(key string, arg ...string) *Message {
} }
return m.Add(key, arg...) return m.Add(key, arg...)
} }
func (m *Message) Copy(msg *Message, arg ...string) *Message {
if msg == nil {
return m
}
if len(arg) > 0 {
for _, k := range arg[1:] {
if kit.IndexOf(m.meta[arg[0]], k) == -1 {
m.meta[arg[0]] = append(m.meta[arg[0]], k)
}
m.meta[k] = append(m.meta[k], msg.meta[k]...)
}
return m
}
for _, k := range msg.meta[MSG_OPTION] {
if kit.IndexOf(m.meta[MSG_OPTION], k) == -1 {
m.meta[MSG_OPTION] = append(m.meta[MSG_OPTION], k)
}
m.meta[k] = append(m.meta[k], msg.meta[k]...)
}
for _, k := range msg.meta[MSG_APPEND] {
if kit.IndexOf(m.meta[MSG_APPEND], k) == -1 {
m.meta[MSG_APPEND] = append(m.meta[MSG_APPEND], k)
}
m.meta[k] = append(m.meta[k], msg.meta[k]...)
}
m.meta[MSG_RESULT] = append(m.meta[MSG_RESULT], msg.meta[MSG_RESULT]...)
return m
}
func (m *Message) Push(key string, value interface{}, arg ...interface{}) *Message { func (m *Message) Push(key string, value interface{}, arg ...interface{}) *Message {
switch value := value.(type) { switch value := value.(type) {
case map[string]string: case map[string]string:
case map[string]interface{}: case map[string]interface{}:
if key == "detail" { if key == "detail" {
// 格式转换
value = kit.KeyValue(map[string]interface{}{}, "", value) value = kit.KeyValue(map[string]interface{}{}, "", value)
} }
// 键值排序
list := []string{} list := []string{}
if len(arg) > 0 { if len(arg) > 0 {
list = kit.Simple(arg[0]) list = kit.Simple(arg[0])
@ -423,6 +394,7 @@ func (m *Message) Push(key string, value interface{}, arg ...interface{}) *Messa
sort.Strings(list) sort.Strings(list)
} }
// 追加数据
for _, k := range list { for _, k := range list {
switch key { switch key {
case "detail": case "detail":
@ -438,6 +410,7 @@ func (m *Message) Push(key string, value interface{}, arg ...interface{}) *Messa
} }
return m return m
} }
for _, v := range kit.Simple(value) { for _, v := range kit.Simple(value) {
m.Add(MSG_APPEND, key, v) m.Add(MSG_APPEND, key, v)
} }
@ -450,7 +423,40 @@ func (m *Message) Echo(str string, arg ...interface{}) *Message {
m.meta[MSG_RESULT] = append(m.meta[MSG_RESULT], str) m.meta[MSG_RESULT] = append(m.meta[MSG_RESULT], str)
return m return m
} }
func (m *Message) Copy(msg *Message, arg ...string) *Message {
if len(arg) > 0 {
// 精确复制
for _, k := range arg[1:] {
if kit.IndexOf(m.meta[arg[0]], k) == -1 {
m.meta[arg[0]] = append(m.meta[arg[0]], k)
}
m.meta[k] = append(m.meta[k], msg.meta[k]...)
}
return m
}
// 复制选项
for _, k := range msg.meta[MSG_OPTION] {
if kit.IndexOf(m.meta[MSG_OPTION], k) == -1 {
m.meta[MSG_OPTION] = append(m.meta[MSG_OPTION], k)
}
m.meta[k] = append(m.meta[k], msg.meta[k]...)
}
// 复制数据
for _, k := range msg.meta[MSG_APPEND] {
if kit.IndexOf(m.meta[MSG_APPEND], k) == -1 {
m.meta[MSG_APPEND] = append(m.meta[MSG_APPEND], k)
}
m.meta[k] = append(m.meta[k], msg.meta[k]...)
}
// 复制文本
m.meta[MSG_RESULT] = append(m.meta[MSG_RESULT], msg.meta[MSG_RESULT]...)
return m
}
func (m *Message) Sort(key string, arg ...string) *Message { func (m *Message) Sort(key string, arg ...string) *Message {
// 排序方法
cmp := "str" cmp := "str"
if len(arg) > 0 && arg[0] != "" { if len(arg) > 0 && arg[0] != "" {
cmp = arg[0] cmp = arg[0]
@ -463,6 +469,7 @@ func (m *Message) Sort(key string, arg ...string) *Message {
} }
} }
// 排序因子
number := map[int]int{} number := map[int]int{}
table := []map[string]string{} table := []map[string]string{}
m.Table(func(index int, line map[string]string, head []string) { m.Table(func(index int, line map[string]string, head []string) {
@ -479,6 +486,7 @@ func (m *Message) Sort(key string, arg ...string) *Message {
} }
}) })
// 排序数据
for i := 0; i < len(table)-1; i++ { for i := 0; i < len(table)-1; i++ {
for j := i + 1; j < len(table); j++ { for j := i + 1; j < len(table); j++ {
result := false result := false
@ -504,10 +512,10 @@ func (m *Message) Sort(key string, arg ...string) *Message {
} }
} }
// 输出数据
for _, k := range m.meta[MSG_APPEND] { for _, k := range m.meta[MSG_APPEND] {
delete(m.meta, k) delete(m.meta, k)
} }
for _, v := range table { for _, v := range table {
for _, k := range m.meta[MSG_APPEND] { for _, k := range m.meta[MSG_APPEND] {
m.Add(MSG_APPEND, k, v[k]) m.Add(MSG_APPEND, k, v[k])
@ -525,11 +533,13 @@ func (m *Message) Table(cbs ...interface{}) *Message {
nrow = len(m.meta[k]) nrow = len(m.meta[k])
} }
} }
for i := 0; i < nrow; i++ { for i := 0; i < nrow; i++ {
line := map[string]string{} line := map[string]string{}
for _, k := range m.meta[MSG_APPEND] { for _, k := range m.meta[MSG_APPEND] {
line[k] = kit.Select("", m.meta[k], i) line[k] = kit.Select("", m.meta[k], i)
} }
// 依次回调
cb(i, line, m.meta[MSG_APPEND]) cb(i, line, m.meta[MSG_APPEND])
} }
} }
@ -554,7 +564,7 @@ func (m *Message) Table(cbs ...interface{}) *Message {
// 回调函数 // 回调函数
rows := kit.Select("\n", m.Option("table.row_sep")) rows := kit.Select("\n", m.Option("table.row_sep"))
cols := kit.Select(" ", m.Option("table.col_sep")) cols := kit.Select(" ", m.Option("table.col_sep"))
compact := kit.Select(m.Conf("table", "compact"), m.Option("table.compact")) == "true" compact := m.Option("table.compact") == "true"
cb := func(maps map[string]string, lists []string, line int) bool { cb := func(maps map[string]string, lists []string, line int) bool {
for i, v := range lists { for i, v := range lists {
if k := m.meta[MSG_APPEND][i]; compact { if k := m.meta[MSG_APPEND][i]; compact {
@ -591,6 +601,7 @@ func (m *Message) Table(cbs ...interface{}) *Message {
row[k], wor = data, append(wor, data+strings.Repeat(space, width[k]-kit.Width(data, len(space)))) row[k], wor = data, append(wor, data+strings.Repeat(space, width[k]-kit.Width(data, len(space))))
} }
// 依次回调
if !cb(row, wor, i) { if !cb(row, wor, i) {
break break
} }
@ -606,11 +617,15 @@ func (m *Message) Render(str string, arg ...interface{}) *Message {
} }
return m return m
} }
func (m *Message) Qrcode(str string, arg ...interface{}) *Message {
return m
}
func (m *Message) Split(str string, field string, space string, enter string) *Message { func (m *Message) Split(str string, field string, space string, enter string) *Message {
indexs := []int{} indexs := []int{}
fields := kit.Split(field, space) fields := kit.Split(field, space)
for i, l := range kit.Split(str, enter) { for i, l := range kit.Split(str, enter) {
if i == 0 && (field == "" || field == "index") { if i == 0 && (field == "" || field == "index") {
// 表头行
fields = kit.Split(l, space) fields = kit.Split(l, space)
if field == "index" { if field == "index" {
for _, v := range fields { for _, v := range fields {
@ -621,6 +636,7 @@ func (m *Message) Split(str string, field string, space string, enter string) *M
} }
if len(indexs) > 0 { if len(indexs) > 0 {
// 数据行
for i, v := range indexs { for i, v := range indexs {
if i == len(indexs)-1 { if i == len(indexs)-1 {
m.Push(kit.Select("some", fields, i), l[v:]) m.Push(kit.Select("some", fields, i), l[v:])
@ -637,6 +653,21 @@ func (m *Message) Split(str string, field string, space string, enter string) *M
} }
return m return m
} }
func (m *Message) CSV(text string) *Message {
bio := bytes.NewBufferString(text)
r := csv.NewReader(bio)
heads, _ := r.Read()
for {
lines, e := r.Read()
if e != nil {
break
}
for i, k := range heads {
m.Push(k, kit.Select("", lines, i))
}
}
return m
}
func (m *Message) Detail(arg ...interface{}) string { func (m *Message) Detail(arg ...interface{}) string {
return kit.Select("", m.meta[MSG_DETAIL], 0) return kit.Select("", m.meta[MSG_DETAIL], 0)
@ -646,6 +677,7 @@ func (m *Message) Detailv(arg ...interface{}) []string {
} }
func (m *Message) Optionv(key string, arg ...interface{}) interface{} { func (m *Message) Optionv(key string, arg ...interface{}) interface{} {
if len(arg) > 0 { if len(arg) > 0 {
// 写数据
if kit.IndexOf(m.meta[MSG_OPTION], key) == -1 { if kit.IndexOf(m.meta[MSG_OPTION], key) == -1 {
m.meta[MSG_OPTION] = append(m.meta[MSG_OPTION], key) m.meta[MSG_OPTION] = append(m.meta[MSG_OPTION], key)
} }
@ -662,9 +694,11 @@ func (m *Message) Optionv(key string, arg ...interface{}) interface{} {
for msg := m; msg != nil; msg = msg.message { for msg := m; msg != nil; msg = msg.message {
if list, ok := msg.data[key]; ok { if list, ok := msg.data[key]; ok {
// 读数据
return list return list
} }
if list, ok := msg.meta[key]; ok { if list, ok := msg.meta[key]; ok {
// 读选项
return list return list
} }
} }
@ -692,7 +726,7 @@ func (m *Message) Result(arg ...interface{}) string {
if len(arg) > 0 { if len(arg) > 0 {
switch v := arg[0].(type) { switch v := arg[0].(type) {
case int: case int:
return kit.Select("", m.Meta[MSG_RESULT], v) return kit.Select("", m.meta[MSG_RESULT], v)
} }
} }
return strings.Join(m.Resultv(), "") return strings.Join(m.Resultv(), "")
@ -700,9 +734,11 @@ func (m *Message) Result(arg ...interface{}) string {
func (m *Message) Log(level string, str string, arg ...interface{}) *Message { func (m *Message) Log(level string, str string, arg ...interface{}) *Message {
if str = strings.TrimSpace(fmt.Sprintf(str, arg...)); Log != nil { if str = strings.TrimSpace(fmt.Sprintf(str, arg...)); Log != nil {
// 日志模块
Log(m, level, str) Log(m, level, str)
} }
// 日志颜色
prefix, suffix := "", "" prefix, suffix := "", ""
switch level { switch level {
case LOG_ENABLE, LOG_IMPORT, LOG_CREATE, LOG_INSERT, LOG_EXPORT: case LOG_ENABLE, LOG_IMPORT, LOG_CREATE, LOG_INSERT, LOG_EXPORT:
@ -756,36 +792,6 @@ func (m *Message) Trace(key string, str string, arg ...interface{}) *Message {
return m return m
} }
func (m *Message) Space(arg interface{}) []string {
if arg == nil || kit.Format(arg) == m.Conf(CLI_RUNTIME, "node.name") {
return nil
}
return []string{WEB_SPACE, kit.Format(arg)}
}
func (m *Message) Right(arg ...interface{}) bool {
return m.Option(MSG_USERROLE) == ROLE_ROOT || !m.Warn(m.Cmdx(AAA_ROLE, "right", m.Option(MSG_USERROLE), kit.Keys(arg...)) != "ok", "no right")
}
func (m *Message) Event(key string, arg ...string) *Message {
m.Cmd(GDB_EVENT, "action", key, arg)
return m
}
func (m *Message) Watch(key string, arg ...string) *Message {
m.Cmd(GDB_EVENT, "listen", key, arg)
return m
}
func (m *Message) Assert(arg interface{}) bool {
switch arg := arg.(type) {
case nil:
return true
case bool:
if arg == true {
return true
}
}
panic(errors.New(fmt.Sprintf("error %v", arg)))
}
func (m *Message) TryCatch(msg *Message, safe bool, hand ...func(msg *Message)) *Message { func (m *Message) TryCatch(msg *Message, safe bool, hand ...func(msg *Message)) *Message {
defer func() { defer func() {
switch e := recover(); e { switch e := recover(); e {
@ -797,24 +803,36 @@ func (m *Message) TryCatch(msg *Message, safe bool, hand ...func(msg *Message))
m.Log(LOG_WARN, "catch: %s", e) m.Log(LOG_WARN, "catch: %s", e)
m.Log(LOG_INFO, "stack: %s", msg.Format("stack")) m.Log(LOG_INFO, "stack: %s", msg.Format("stack"))
if m.Log(LOG_WARN, "catch: %s", e); len(hand) > 1 { if m.Log(LOG_WARN, "catch: %s", e); len(hand) > 1 {
// 捕获异常
m.TryCatch(msg, safe, hand[1:]...) m.TryCatch(msg, safe, hand[1:]...)
} else if !safe { } else if !safe {
// 抛出异常
m.Assert(e) m.Assert(e)
} }
} }
}() }()
if len(hand) > 0 { if len(hand) > 0 {
// 运行函数
hand[0](msg) hand[0](msg)
} }
return m return m
} }
func (m *Message) Gos(msg *Message, cb func(*Message)) *Message { func (m *Message) Assert(arg interface{}) bool {
go func() { msg.TryCatch(msg, true, func(msg *Message) { cb(msg) }) }() switch arg := arg.(type) {
return m case nil:
return true
case bool:
if arg == true {
return true
}
}
// 抛出异常
panic(errors.New(fmt.Sprintf("error %v", arg)))
} }
func (m *Message) Run(arg ...string) *Message { func (m *Message) Sleep(arg string) *Message {
m.target.server.Start(m, arg...) time.Sleep(kit.Duration(arg))
return m return m
} }
func (m *Message) Hold(n int) *Message { func (m *Message) Hold(n int) *Message {
@ -839,21 +857,6 @@ func (m *Message) Done() bool {
ctx.wg.Done() ctx.wg.Done()
return true return true
} }
func (m *Message) Start(key string, arg ...string) *Message {
m.Travel(func(p *Context, s *Context) {
if s.Name == key {
s.Start(m.Spawns(s), arg...)
}
})
return m
}
func (m *Message) Starts(name string, help string, arg ...string) *Message {
m.wait = make(chan bool)
m.target.Spawn(m, name, help, arg...).Begin(m, arg...).Start(m, arg...)
<-m.wait
return m
}
func (m *Message) Call(sync bool, cb func(*Message) *Message) *Message { func (m *Message) Call(sync bool, cb func(*Message) *Message) *Message {
if sync { if sync {
wait := make(chan bool) wait := make(chan bool)
@ -871,8 +874,65 @@ func (m *Message) Back(sub *Message) *Message {
} }
return m return m
} }
func (m *Message) Sleep(arg string) *Message { func (m *Message) Gos(msg *Message, cb func(*Message)) *Message {
time.Sleep(kit.Duration(arg)) go func() { msg.TryCatch(msg, true, func(msg *Message) { cb(msg) }) }()
return m
}
func (m *Message) Run(arg ...string) *Message {
m.target.server.Start(m, arg...)
return m
}
func (m *Message) Start(key string, arg ...string) *Message {
m.Travel(func(p *Context, s *Context) {
if s.Name == key {
s.Start(m.Spawns(s), arg...)
}
})
return m
}
func (m *Message) Starts(name string, help string, arg ...string) *Message {
m.wait = make(chan bool)
m.target.Spawn(m, name, help, arg...).Begin(m, arg...).Start(m, arg...)
<-m.wait
return m
}
func (m *Message) Space(arg interface{}) []string {
if arg == nil || kit.Format(arg) == m.Conf(CLI_RUNTIME, "node.name") {
return nil
}
return []string{WEB_SPACE, kit.Format(arg)}
}
func (m *Message) Right(arg ...interface{}) bool {
return m.Option(MSG_USERROLE) == ROLE_ROOT || !m.Warn(m.Cmdx(AAA_ROLE, "right", m.Option(MSG_USERROLE), kit.Keys(arg...)) != "ok", "no right")
}
func (m *Message) Event(key string, arg ...string) *Message {
m.Cmd(GDB_EVENT, "action", key, arg)
return m
}
func (m *Message) Watch(key string, arg ...string) *Message {
m.Cmd(GDB_EVENT, "listen", key, arg)
return m
}
func (m *Message) Prefix(arg ...string) string {
return kit.Keys(m.Cap(CTX_FOLLOW), arg)
}
func (m *Message) Save(arg ...string) *Message {
list := []string{}
for _, k := range arg {
list = append(list, kit.Keys(m.Cap(CTX_FOLLOW), k))
}
m.Cmd(CTX_CONFIG, "save", kit.Keys(m.Cap(CTX_FOLLOW), "json"), list)
return m
}
func (m *Message) Load(arg ...string) *Message {
list := []string{}
for _, k := range arg {
list = append(list, kit.Keys(m.Cap(CTX_FOLLOW), k))
}
m.Cmd(CTX_CONFIG, "load", kit.Keys(m.Cap(CTX_FOLLOW), "json"), list)
return m return m
} }
@ -881,6 +941,7 @@ func (m *Message) Travel(cb interface{}) *Message {
for i := 0; i < len(list); i++ { for i := 0; i < len(list); i++ {
switch cb := cb.(type) { switch cb := cb.(type) {
case func(*Context, *Context): case func(*Context, *Context):
// 模块回调
cb(list[i].context, list[i]) cb(list[i].context, list[i])
case func(*Context, *Context, string, *Command): case func(*Context, *Context, string, *Command):
ls := []string{} ls := []string{}
@ -889,6 +950,7 @@ func (m *Message) Travel(cb interface{}) *Message {
} }
sort.Strings(ls) sort.Strings(ls)
for _, k := range ls { for _, k := range ls {
// 命令回调
cb(list[i].context, list[i], k, list[i].Commands[k]) cb(list[i].context, list[i], k, list[i].Commands[k])
} }
case func(*Context, *Context, string, *Config): case func(*Context, *Context, string, *Config):
@ -898,10 +960,12 @@ func (m *Message) Travel(cb interface{}) *Message {
} }
sort.Strings(ls) sort.Strings(ls)
for _, k := range ls { for _, k := range ls {
// 配置回调
cb(list[i].context, list[i], k, list[i].Configs[k]) cb(list[i].context, list[i], k, list[i].Configs[k])
} }
} }
// 下级模块
ls := []string{} ls := []string{}
for k := range list[i].contexts { for k := range list[i].contexts {
ls = append(ls, k) ls = append(ls, k)
@ -920,6 +984,7 @@ func (m *Message) Search(key interface{}, cb interface{}) *Message {
key = k key = k
} }
// 查找模块
p := m.target.root p := m.target.root
if strings.Contains(key, ":") { if strings.Contains(key, ":") {
@ -951,6 +1016,7 @@ func (m *Message) Search(key interface{}, cb interface{}) *Message {
p = m.target p = m.target
} }
// 遍历命令
switch cb := cb.(type) { switch cb := cb.(type) {
case func(p *Context, s *Context, key string, cmd *Command): case func(p *Context, s *Context, key string, cmd *Command):
if key == "" { if key == "" {
@ -984,9 +1050,6 @@ func (m *Message) Search(key interface{}, cb interface{}) *Message {
return m return m
} }
func Meta(arg ...interface{}) string {
return kit.MDB_META + "." + kit.Keys(arg...)
}
func (m *Message) Richs(key string, chain interface{}, raw interface{}, cb interface{}) (res map[string]interface{}) { func (m *Message) Richs(key string, chain interface{}, raw interface{}, cb interface{}) (res map[string]interface{}) {
// 数据结构 // 数据结构
cache := m.Confm(key, chain) cache := m.Confm(key, chain)
@ -1122,7 +1185,7 @@ func (m *Message) Grow(key string, chain interface{}, data interface{}) int {
least := kit.Int(kit.Select(m.Conf(WEB_CACHE, "meta.least"), kit.Select(kit.Format(meta["least"]), m.Option("cache.least")))) least := kit.Int(kit.Select(m.Conf(WEB_CACHE, "meta.least"), kit.Select(kit.Format(meta["least"]), m.Option("cache.least"))))
// 创建文件 // 创建文件
name := path.Join(kit.Select(m.Conf(WEB_CACHE, Meta("store")), kit.Select(kit.Format(meta["store"]), m.Option("cache.store"))), kit.Keys(key, chain, "csv")) name := path.Join(kit.Select(m.Conf(WEB_CACHE, "meta.store"), kit.Select(kit.Format(meta["store"]), m.Option("cache.store"))), kit.Keys(key, chain, "csv"))
if s, e := os.Stat(name); e == nil { if s, e := os.Stat(name); e == nil {
if s.Size() > kit.Int64(kit.Select(m.Conf(WEB_CACHE, "meta.fsize"), kit.Select(kit.Format(meta["fsize"]), m.Option("cache.fsize")))) { if s.Size() > kit.Int64(kit.Select(m.Conf(WEB_CACHE, "meta.fsize"), kit.Select(kit.Format(meta["fsize"]), m.Option("cache.fsize")))) {
name = strings.Replace(name, ".csv", fmt.Sprintf("_%d.csv", kit.Int(meta["offset"])), -1) name = strings.Replace(name, ".csv", fmt.Sprintf("_%d.csv", kit.Int(meta["offset"])), -1)
@ -1199,6 +1262,7 @@ func (m *Message) Grow(key string, chain interface{}, data interface{}) int {
return id return id
} }
func (m *Message) Grows(key string, chain interface{}, match string, value string, cb interface{}) map[string]interface{} { func (m *Message) Grows(key string, chain interface{}, match string, value string, cb interface{}) map[string]interface{} {
// 数据结构
cache := m.Confm(key, chain) cache := m.Confm(key, chain)
if cache == nil { if cache == nil {
return nil return nil
@ -1209,11 +1273,18 @@ func (m *Message) Grows(key string, chain interface{}, match string, value strin
return nil return nil
} }
// 数据范围
offend := kit.Int(kit.Select("0", m.Option("cache.offend"))) offend := kit.Int(kit.Select("0", m.Option("cache.offend")))
limit := kit.Int(kit.Select("10", m.Option("cache.limit"))) limit := kit.Int(kit.Select("10", m.Option("cache.limit")))
current := kit.Int(meta["offset"]) current := kit.Int(meta["offset"])
end := current + len(list) - offend end := current + len(list) - offend
begin := end - limit begin := end - limit
switch limit {
case -1:
begin = current
case -2:
begin = 0
}
if match == kit.MDB_ID { if match == kit.MDB_ID {
begin, end = kit.Int(value)-1, kit.Int(value) begin, end = kit.Int(value)-1, kit.Int(value)
@ -1222,9 +1293,11 @@ func (m *Message) Grows(key string, chain interface{}, match string, value strin
order := 0 order := 0
if begin < current { if begin < current {
// 读取磁盘
m.Log(LOG_INFO, "%s.%v read %v-%v from %v-%v", key, chain, begin, end, current, current+len(list)) m.Log(LOG_INFO, "%s.%v read %v-%v from %v-%v", key, chain, begin, end, current, current+len(list))
store, _ := meta["record"].([]interface{}) store, _ := meta["record"].([]interface{})
for s := len(store) - 1; s > -1; s-- { for s := len(store) - 1; s > -1; s-- {
// 查找索引
item, _ := store[s].(map[string]interface{}) item, _ := store[s].(map[string]interface{})
line := kit.Int(item["offset"]) line := kit.Int(item["offset"])
m.Log(LOG_INFO, "check history %v %v %v", s, line, item) m.Log(LOG_INFO, "check history %v %v %v", s, line, item)
@ -1237,6 +1310,7 @@ func (m *Message) Grows(key string, chain interface{}, match string, value strin
break break
} }
// 查找偏移
item, _ := store[s].(map[string]interface{}) item, _ := store[s].(map[string]interface{})
name := kit.Format(item["file"]) name := kit.Format(item["file"])
pos := kit.Int(item["position"]) pos := kit.Int(item["position"])
@ -1246,6 +1320,7 @@ func (m *Message) Grows(key string, chain interface{}, match string, value strin
continue continue
} }
// 打开文件
m.Log(LOG_IMPORT, "load history %v %v %v", s, offset, item) m.Log(LOG_IMPORT, "load history %v %v %v", s, offset, item)
if f, e := os.Open(name); m.Assert(e) { if f, e := os.Open(name); m.Assert(e) {
defer f.Close() defer f.Close()
@ -1336,8 +1411,10 @@ func (m *Message) Cmd(arg ...interface{}) *Message {
msg.meta[MSG_DETAIL] = list msg.meta[MSG_DETAIL] = list
m.Hand, msg.Hand, m = true, true, msg m.Hand, msg.Hand, m = true, true, msg
if you := m.Option(kit.Format(kit.Value(cmd.Meta, "remote"))); you != "" { if you := m.Option(kit.Format(kit.Value(cmd.Meta, "remote"))); you != "" {
// 远程命令
msg.Copy(msg.Spawns(c).Cmd(WEB_SPACE, you, list[0], list[1:])) msg.Copy(msg.Spawns(c).Cmd(WEB_SPACE, you, list[0], list[1:]))
} else { } else {
// 本地命令
p.Run(msg, cmd, key, list[1:]...) p.Run(msg, cmd, key, list[1:]...)
} }
m.Hand, msg.Hand = true, true m.Hand, msg.Hand = true, true
@ -1352,13 +1429,17 @@ func (m *Message) Confv(arg ...interface{}) (val interface{}) {
if len(arg) > 1 { if len(arg) > 1 {
if len(arg) > 2 { if len(arg) > 2 {
if arg[1] == nil { if arg[1] == nil {
// 写配置
conf.Value = arg[2] conf.Value = arg[2]
} else { } else {
// 写修改项
kit.Value(conf.Value, arg[1:]...) kit.Value(conf.Value, arg[1:]...)
} }
} }
// 读配置项
val = kit.Value(conf.Value, arg[1]) val = kit.Value(conf.Value, arg[1])
} else { } else {
// 读配置
val = conf.Value val = conf.Value
} }
}) })
@ -1392,8 +1473,10 @@ func (m *Message) Capv(arg ...interface{}) interface{} {
for c := s; c != nil; c = c.context { for c := s; c != nil; c = c.context {
if caps, ok := c.Caches[key]; ok { if caps, ok := c.Caches[key]; ok {
if len(arg) > 0 { if len(arg) > 0 {
// 写数据
caps.Value = kit.Format(arg[0]) caps.Value = kit.Format(arg[0])
} }
// 读数据
return caps.Value return caps.Value
} }
} }