From 98f4835f9d5456f8aaad7225c713f5e5a6aac373 Mon Sep 17 00:00:00 2001 From: harveyshao Date: Sun, 19 Jun 2022 08:18:50 +0800 Subject: [PATCH] add oauth --- base/aaa/role.go | 28 +++--- base/aaa/sess.go | 4 +- base/aaa/totp.go | 2 +- base/aaa/user.go | 18 ++-- base/cli/daemon.go | 3 + base/cli/forever.go | 24 +++-- base/cli/qrcode.go | 10 +-- base/cli/runtime.go | 2 +- base/ctx/config.go | 6 +- base/gdb/event.go | 4 +- base/gdb/gdb.go | 2 +- base/gdb/signal.go | 8 +- base/gdb/timer.go | 4 +- base/lex/matrix.go | 12 +-- base/lex/split.go | 12 +-- base/log/log.go | 4 +- base/mdb/engine.go | 2 +- base/mdb/hash.go | 45 +++++++--- base/mdb/list.go | 10 +-- base/mdb/plugin.go | 2 +- base/mdb/render.go | 2 +- base/mdb/search.go | 2 +- base/mdb/zone.go | 22 ++--- base/nfs/cat.go | 4 +- base/nfs/dir.go | 2 +- base/nfs/tail.go | 2 +- base/nfs/trash.go | 19 ++-- base/ssh/scripts.go | 10 +-- base/tcp/client.go | 2 +- base/tcp/port.go | 20 ++++- base/tcp/server.go | 2 +- base/web/broad.go | 2 +- base/web/cache.go | 4 +- base/web/dream.go | 2 +- base/web/render.go | 24 ++--- base/web/route.go | 2 +- base/web/serve.go | 10 +-- base/web/share.go | 4 +- base/web/space.go | 8 +- base/web/spide.go | 15 ++-- base/web/story.go | 48 +++++----- base/web/web.go | 2 + base/yac/matrix.go | 12 +-- base/yac/script.go | 2 +- conf.go | 18 +++- core/chat/action.go | 8 +- core/chat/div.go | 2 +- core/chat/header.go | 2 +- core/chat/oauth.go | 68 --------------- core/chat/oauth/oauth.go | 169 ++++++++++++++++++++++++++++++++++++ core/chat/oauth/oauth.shy | 18 ++++ core/chat/pod.go | 4 +- core/chat/river.go | 8 +- core/chat/search.go | 2 +- core/chat/storm.go | 2 +- core/chat/website.go | 12 +-- core/code/autogen.go | 4 +- core/code/inner.go | 2 +- core/code/install.go | 16 ++-- core/code/template.go | 8 +- core/code/upgrade.go | 2 +- core/core.go | 1 + core/mall/asset.go | 2 +- core/team/plan.go | 2 +- core/team/task.go | 2 +- core/wiki/chart.go | 14 +-- core/wiki/chart/block.go | 2 +- core/wiki/chart/chain.go | 14 +-- core/wiki/chart/label.go | 6 +- core/wiki/chart/sequence.go | 10 +-- core/wiki/field.go | 6 +- core/wiki/spark.go | 2 +- core/wiki/title.go | 6 +- data.go | 7 +- exec.go | 11 ++- go.mod | 1 + go.sum | 5 ++ info.go | 12 +-- init.go | 17 ++-- logs.go | 2 +- misc.go | 13 ++- misc/bash/input.go | 4 +- misc/bash/run.go | 2 +- misc/chrome/operate.go | 2 +- misc/coder/server.go | 2 +- misc/git/configs.go | 2 +- misc/git/total.go | 2 +- misc/input/input.go | 4 +- misc/lark/company.go | 4 +- misc/lark/employee.go | 2 +- misc/lark/form.go | 6 +- misc/lark/group.go | 4 +- misc/lark/msg.go | 8 +- misc/lark/send.go | 14 +-- misc/lark/talk.go | 2 +- misc/ssh/channel.go | 4 +- misc/ssh/connect.go | 4 +- misc/ssh/service.go | 4 +- misc/ssh/session.go | 4 +- misc/tmux/buffer.go | 2 +- misc/vim/tags.go | 2 +- misc/webview/webview.go | 4 +- option.go | 9 +- render.go | 23 +++++ type.go | 2 +- 105 files changed, 626 insertions(+), 394 deletions(-) delete mode 100644 core/chat/oauth.go create mode 100644 core/chat/oauth/oauth.go create mode 100644 core/chat/oauth/oauth.shy diff --git a/base/aaa/role.go b/base/aaa/role.go index 84db5da7..e9f6d83f 100644 --- a/base/aaa/role.go +++ b/base/aaa/role.go @@ -7,13 +7,13 @@ import ( ) func _role_list(m *ice.Message, userrole string) { - m.Richs(ROLE, nil, kit.Select(mdb.FOREACH, userrole), func(key string, value map[string]interface{}) { - kit.Fetch(value[BLACK], func(k string, v interface{}) { + m.Richs(ROLE, nil, kit.Select(mdb.FOREACH, userrole), func(key string, value ice.Map) { + kit.Fetch(value[BLACK], func(k string, v ice.Any) { m.Push(ROLE, kit.Value(value, mdb.NAME)) m.Push(mdb.ZONE, BLACK) m.Push(mdb.KEY, k) }) - kit.Fetch(value[WHITE], func(k string, v interface{}) { + kit.Fetch(value[WHITE], func(k string, v ice.Any) { m.Push(ROLE, kit.Value(value, mdb.NAME)) m.Push(mdb.ZONE, WHITE) m.Push(mdb.KEY, k) @@ -24,15 +24,15 @@ func _role_chain(arg ...string) string { return kit.ReplaceAll(kit.ReplaceAll(kit.Keys(arg), ice.PS, ice.PT), "..", ".") } func _role_black(m *ice.Message, userrole, chain string) { - m.Richs(ROLE, nil, userrole, func(key string, value map[string]interface{}) { - list := value[BLACK].(map[string]interface{}) + m.Richs(ROLE, nil, userrole, func(key string, value ice.Map) { + list := value[BLACK].(ice.Map) m.Log_INSERT(ROLE, userrole, BLACK, chain) list[chain] = true }) } func _role_white(m *ice.Message, userrole, chain string) { - m.Richs(ROLE, nil, userrole, func(key string, value map[string]interface{}) { - list := value[WHITE].(map[string]interface{}) + m.Richs(ROLE, nil, userrole, func(key string, value ice.Map) { + list := value[WHITE].(ice.Map) m.Log_INSERT(ROLE, userrole, WHITE, chain) list[chain] = true }) @@ -42,9 +42,9 @@ func _role_right(m *ice.Message, userrole string, keys ...string) (ok bool) { return true // 超级权限 } - m.Richs(ROLE, nil, kit.Select(VOID, userrole), func(key string, value map[string]interface{}) { + m.Richs(ROLE, nil, kit.Select(VOID, userrole), func(key string, value ice.Map) { ok = true - list := value[BLACK].(map[string]interface{}) + list := value[BLACK].(ice.Map) for i := 0; i < len(keys); i++ { if v, o := list[kit.Join(keys[:i+1], ice.PT)]; o && v == true { ok = false // 在黑名单 @@ -58,7 +58,7 @@ func _role_right(m *ice.Message, userrole string, keys ...string) (ok bool) { } ok = false - list = value[WHITE].(map[string]interface{}) + list = value[WHITE].(ice.Map) for i := 0; i < len(keys); i++ { if v, o := list[kit.Join(keys[:i+1], ice.PT)]; o && v == true { ok = true // 在白名单 @@ -105,16 +105,16 @@ func init() { m.Cmd(ROLE, WHITE, VOID, ice.USR_LOCAL_GO) }}, mdb.INSERT: {Name: "insert role=void,tech zone=white,black key=", Help: "添加", Hand: func(m *ice.Message, arg ...string) { - m.Richs(ROLE, nil, m.Option(ROLE), func(key string, value map[string]interface{}) { + m.Richs(ROLE, nil, m.Option(ROLE), func(key string, value ice.Map) { m.Log_INSERT(ROLE, m.Option(ROLE), m.Option(mdb.ZONE), m.Option(mdb.KEY)) - list := value[m.Option(mdb.ZONE)].(map[string]interface{}) + list := value[m.Option(mdb.ZONE)].(ice.Map) list[m.Option(mdb.KEY)] = true }) }}, mdb.DELETE: {Name: "delete", Help: "删除", Hand: func(m *ice.Message, arg ...string) { - m.Richs(ROLE, nil, m.Option(ROLE), func(key string, value map[string]interface{}) { + m.Richs(ROLE, nil, m.Option(ROLE), func(key string, value ice.Map) { m.Log_DELETE(ROLE, m.Option(ROLE), m.Option(mdb.ZONE), m.Option(mdb.KEY)) - list := value[m.Option(mdb.ZONE)].(map[string]interface{}) + list := value[m.Option(mdb.ZONE)].(ice.Map) delete(list, m.Option(mdb.KEY)) }) }}, diff --git a/base/aaa/sess.go b/base/aaa/sess.go index 1d6e0759..f1f755c9 100644 --- a/base/aaa/sess.go +++ b/base/aaa/sess.go @@ -14,11 +14,11 @@ func _sess_check(m *ice.Message, sessid string) bool { return false } - m.Richs(SESS, nil, sessid, func(value map[string]interface{}) { + m.Richs(SESS, nil, sessid, func(value ice.Map) { if value = kit.GetMeta(value); m.Warn(kit.Time(kit.Format(value[mdb.TIME])) < kit.Time(m.Time()), ice.ErrExpire) { return // 会话超时 } - if m.Richs(USER, nil, value[USERNAME], func(value map[string]interface{}) { + if m.Richs(USER, nil, value[USERNAME], func(value ice.Map) { m.Log_AUTH( USERROLE, m.Option(ice.MSG_USERROLE, value[USERROLE]), USERNAME, m.Option(ice.MSG_USERNAME, value[USERNAME]), diff --git a/base/aaa/totp.go b/base/aaa/totp.go index 27e4171c..197a91b0 100644 --- a/base/aaa/totp.go +++ b/base/aaa/totp.go @@ -59,7 +59,7 @@ func init() { )}, }, Commands: map[string]*ice.Command{ TOTP: {Name: "totp name auto create", Help: "令牌", Action: ice.MergeAction(map[string]*ice.Action{ - mdb.CREATE: {Name: "create name secret period=30 number=6", Help: "添加", Hand: func(m *ice.Message, arg ...string) { + mdb.CREATE: {Name: "create name=hi secret period=30 number=6", Help: "添加", Hand: func(m *ice.Message, arg ...string) { if m.Option(SECRET) == "" { // 创建密钥 m.Option(SECRET, _totp_gen(kit.Int64(m.Option(PERIOD)))) } diff --git a/base/aaa/user.go b/base/aaa/user.go index 9126bc90..5fae6c2b 100644 --- a/base/aaa/user.go +++ b/base/aaa/user.go @@ -14,7 +14,7 @@ func _user_login(m *ice.Message, name, word string) (ok bool) { _user_create(m, VOID, name, word) } - m.Richs(USER, nil, name, func(key string, value map[string]interface{}) { + m.Richs(USER, nil, name, func(key string, value ice.Map) { if ok = !m.Warn(word != "" && word != value[PASSWORD], ice.ErrNotRight); ok { m.Log_AUTH( USERROLE, m.Option(ice.MSG_USERROLE, value[USERROLE]), @@ -30,7 +30,7 @@ func _user_create(m *ice.Message, role, name, word string) { return } if word == "" { - if m.Richs(USER, nil, name, func(key string, value map[string]interface{}) { + if m.Richs(USER, nil, name, func(key string, value ice.Map) { word = kit.Format(value[PASSWORD]) }) == nil { word = kit.Hashs() @@ -40,7 +40,7 @@ func _user_create(m *ice.Message, role, name, word string) { m.Event(USER_CREATE, USER, name) } func _user_search(m *ice.Message, name, text string) { - m.Richs(USER, nil, mdb.FOREACH, func(key string, value map[string]interface{}) { + m.Richs(USER, nil, mdb.FOREACH, func(key string, value ice.Map) { if value = kit.GetMeta(value); name == "" || name == value[USERNAME] { m.PushSearch(kit.SimpleKV("", value[USERROLE], value[USERNAME], value[USERNICK]), value) } @@ -56,27 +56,27 @@ func UserRoot(m *ice.Message, arg ...string) *ice.Message { // password username } return m } -func UserRole(m *ice.Message, username interface{}) (role string) { +func UserRole(m *ice.Message, username ice.Any) (role string) { if role = VOID; username == ice.Info.UserName { return ROOT } - if m.Richs(USER, nil, kit.Format(username), func(key string, value map[string]interface{}) { + if m.Richs(USER, nil, kit.Format(username), func(key string, value ice.Map) { role = kit.Format(kit.GetMeta(value)[USERROLE]) }) == nil && kit.Format(username) == m.Option(ice.MSG_USERNAME) { return m.Option(ice.MSG_USERROLE) } return } -func UserNick(m *ice.Message, username interface{}) (nick string) { - if m.Richs(USER, nil, kit.Format(username), func(key string, value map[string]interface{}) { +func UserNick(m *ice.Message, username ice.Any) (nick string) { + if m.Richs(USER, nil, kit.Format(username), func(key string, value ice.Map) { nick = kit.Format(kit.GetMeta(value)[USERNICK]) }) == nil && kit.Format(username) == m.Option(ice.MSG_USERNAME) { return m.Option(ice.MSG_USERNICK) } return } -func UserZone(m *ice.Message, username interface{}) (zone string) { - m.Richs(USER, nil, kit.Format(username), func(key string, value map[string]interface{}) { +func UserZone(m *ice.Message, username ice.Any) (zone string) { + m.Richs(USER, nil, kit.Format(username), func(key string, value ice.Map) { zone = kit.Format(kit.GetMeta(value)[USERZONE]) }) return diff --git a/base/cli/daemon.go b/base/cli/daemon.go index 64cb0a3e..1b64f3c3 100644 --- a/base/cli/daemon.go +++ b/base/cli/daemon.go @@ -127,6 +127,9 @@ func init() { m.Cmd(mdb.MODIFY, DAEMON, "", mdb.HASH, m.OptionSimple(mdb.HASH), STATUS, STOP) m.Cmdy(SYSTEM, KILL, value[PID]) }) + if IsSuccess(m) { + m.SetAppend() + } }}, }, mdb.HashAction()), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { mdb.HashSelect(m, arg...).Set(ctx.ACTION).Table(func(index int, value map[string]string, head []string) { diff --git a/base/cli/forever.go b/base/cli/forever.go index ce73ae1e..89bdbaf6 100644 --- a/base/cli/forever.go +++ b/base/cli/forever.go @@ -9,6 +9,14 @@ import ( kit "shylinux.com/x/toolkits" ) +func _forever_kill(m *ice.Message, s string) { + if p := m.Cmdx(nfs.CAT, m.Conf("gdb.signal", kit.Keym(nfs.PATH))); p != "" { + if s != "" { + m.Cmd(SYSTEM, "kill", "-s", s, p) + } + m.Echo(p) + } +} func BinPath(arg ...string) string { return kit.Join(kit.Simple(arg, kit.Path(ice.BIN), kit.Path(ice.USR_LOCAL_BIN), kit.Path(ice.USR_LOCAL_GO_BIN), kit.Env(PATH)), ice.DF) } @@ -19,11 +27,9 @@ func init() { const SERVE = "serve" const RESTART = "restart" Index.Merge(&ice.Context{Commands: map[string]*ice.Command{ - FOREVER: {Name: "forever", Help: "启动", Action: map[string]*ice.Action{ + FOREVER: {Name: "forever auto", Help: "启动", Action: map[string]*ice.Action{ RESTART: {Name: "restart", Help: "重启", Hand: func(m *ice.Message, arg ...string) { - if p := m.Cmdx(nfs.CAT, m.Conf("gdb.signal", kit.Keym(nfs.PATH))); p != "" { - m.Cmd(SYSTEM, "kill", "-s", "INT", p) - } + _forever_kill(m, "INT") }}, SERVE: {Name: "serve", Help: "服务", Hand: func(m *ice.Message, arg ...string) { env := []string{PATH, BinPath(), HOME, kit.Select(kit.Path(""), os.Getenv(HOME))} @@ -46,12 +52,14 @@ func init() { SERVE, START, ice.DEV, "", aaa.USERNAME, aaa.ROOT, aaa.PASSWORD, aaa.ROOT, arg) }}, STOP: {Name: "stop", Help: "停止", Hand: func(m *ice.Message, arg ...string) { - if p := m.Cmdx(nfs.CAT, m.Conf("gdb.signal", kit.Keym(nfs.PATH))); p != "" { - m.Cmd(SYSTEM, "kill", "-s", "QUIT", p) - m.Echo(p) - } + _forever_kill(m, "QUIT") }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if len(arg) == 0 { + _forever_kill(m, "") + return + } + for { println(kit.Format("%s run %s", kit.Now(), kit.Join(arg, ice.SP))) if m.Sleep("1s"); IsSuccess(m.Cmd(SYSTEM, arg)) { diff --git a/base/cli/qrcode.go b/base/cli/qrcode.go index 056704af..2f3b71db 100644 --- a/base/cli/qrcode.go +++ b/base/cli/qrcode.go @@ -92,16 +92,16 @@ func _qrcode_web(m *ice.Message, text string) { } } -func Color(m *ice.Message, c string, str interface{}) string { +func Color(m *ice.Message, c string, str ice.Any) string { wrap, color := `%v`, c if m.IsCliUA() { wrap, color = "\033[3%sm%v\033[0m", _parse_cli_color(c) } return fmt.Sprintf(wrap, color, str) } -func ColorRed(m *ice.Message, str interface{}) string { return Color(m, RED, str) } -func ColorGreen(m *ice.Message, str interface{}) string { return Color(m, GREEN, str) } -func ColorYellow(m *ice.Message, str interface{}) string { return Color(m, YELLOW, str) } +func ColorRed(m *ice.Message, str ice.Any) string { return Color(m, RED, str) } +func ColorGreen(m *ice.Message, str ice.Any) string { return Color(m, GREEN, str) } +func ColorYellow(m *ice.Message, str ice.Any) string { return Color(m, YELLOW, str) } const ( FG = "fg" @@ -131,7 +131,7 @@ func init() { Index.Merge(&ice.Context{Commands: map[string]*ice.Command{ QRCODE: {Name: "qrcode text fg bg size auto", Help: "二维码", Action: map[string]*ice.Action{ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { - ice.AddRender(ice.RENDER_QRCODE, func(m *ice.Message, cmd string, args ...interface{}) string { + ice.AddRender(ice.RENDER_QRCODE, func(m *ice.Message, cmd string, args ...ice.Any) string { return m.Cmd(QRCODE, kit.Simple(args...)).Result() }) }}, diff --git a/base/cli/runtime.go b/base/cli/runtime.go index db8c95b2..1a47ce2f 100644 --- a/base/cli/runtime.go +++ b/base/cli/runtime.go @@ -16,7 +16,7 @@ import ( func _runtime_init(m *ice.Message) { // 版本信息 make - kit.Fetch(kit.UnMarshal(kit.Format(ice.Info.Make)), func(key string, value interface{}) { + kit.Fetch(kit.UnMarshal(kit.Format(ice.Info.Make)), func(key string, value ice.Any) { m.Conf(RUNTIME, kit.Keys(MAKE, strings.ToLower(key)), value) }) diff --git a/base/ctx/config.go b/base/ctx/config.go index d59b84ba..137f6f1f 100644 --- a/base/ctx/config.go +++ b/base/ctx/config.go @@ -30,7 +30,7 @@ func _config_save(m *ice.Message, name string, arg ...string) { defer f.Close() msg := m.Spawn(m.Source()) - data := map[string]interface{}{} + data := ice.Map{} for _, k := range arg { if v := msg.Confv(k); v != "" { data[k] = v @@ -52,7 +52,7 @@ func _config_load(m *ice.Message, name string, arg ...string) { defer f.Close() msg := m.Spawn(m.Source()) - data := map[string]interface{}{} + data := ice.Map{} json.NewDecoder(f).Decode(&data) // 加载配置 @@ -116,7 +116,7 @@ func init() { _config_grow(m, arg[0], arg[1], arg[2:]...) }}, "list": {Name: "list", Help: "列表", Hand: func(m *ice.Message, arg ...string) { - list := []interface{}{} + list := []ice.Any{} for _, v := range arg[2:] { list = append(list, v) } diff --git a/base/gdb/event.go b/base/gdb/event.go index d97f5042..97ade45c 100644 --- a/base/gdb/event.go +++ b/base/gdb/event.go @@ -26,12 +26,12 @@ func init() { LISTEN: {Name: "listen event cmd", Help: "监听", Hand: func(m *ice.Message, arg ...string) { _event_listen(m, m.Option(EVENT), m.Option(ice.CMD)) }}, - ACTION: {Name: "action event arg", Help: "触发", Hand: func(m *ice.Message, arg ...string) { + HAPPEN: {Name: "happen event arg", Help: "触发", Hand: func(m *ice.Message, arg ...string) { _event_action(m, m.Option(EVENT), arg[2:]...) }}, }, mdb.ZoneAction()), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if mdb.ZoneSelect(m, arg...); len(arg) == 0 { - m.PushAction(ACTION, mdb.REMOVE) + m.PushAction(HAPPEN, mdb.REMOVE) } }}, }}) diff --git a/base/gdb/gdb.go b/base/gdb/gdb.go index 70300919..565a5756 100644 --- a/base/gdb/gdb.go +++ b/base/gdb/gdb.go @@ -33,7 +33,7 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool { // // m.Cmd(TIMER, ACTION) case s := <-f.s: - m.Cmd(SIGNAL, ACTION, ACTION, SIGNAL, s) + m.Cmd(SIGNAL, HAPPEN, SIGNAL, s) } } return true diff --git a/base/gdb/signal.go b/base/gdb/signal.go index c5d71dc2..d178484c 100644 --- a/base/gdb/signal.go +++ b/base/gdb/signal.go @@ -39,8 +39,8 @@ func SignalNotify(m *ice.Message, sig int, cb func()) { } const ( - LISTEN = "listen" - ACTION = "action" + LISTEN = ice.LISTEN + HAPPEN = ice.HAPPEN ) const SIGNAL = "signal" @@ -64,12 +64,12 @@ func init() { LISTEN: {Name: "listen signal name cmd", Help: "监听", Hand: func(m *ice.Message, arg ...string) { _signal_listen(m, kit.Int(m.Option(SIGNAL)), arg...) }}, - ACTION: {Name: "action signal", Help: "触发", Hand: func(m *ice.Message, arg ...string) { + HAPPEN: {Name: "happen signal", Help: "触发", Hand: func(m *ice.Message, arg ...string) { _signal_action(m, m.Option(SIGNAL)) }}, }, mdb.HashAction()), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { mdb.HashSelect(m, arg...).Sort(SIGNAL) - m.PushAction(ACTION, mdb.REMOVE) + m.PushAction(HAPPEN, mdb.REMOVE) }}, }}) } diff --git a/base/gdb/timer.go b/base/gdb/timer.go index 292171b5..ffbf264d 100644 --- a/base/gdb/timer.go +++ b/base/gdb/timer.go @@ -13,7 +13,7 @@ func _timer_action(m *ice.Message, arg ...string) { now := time.Now().UnixNano() m.OptionFields(m.Config(mdb.FIELD)) - m.Richs(TIMER, "", mdb.FOREACH, func(key string, value map[string]interface{}) { + m.Richs(TIMER, "", mdb.FOREACH, func(key string, value ice.Map) { if value = kit.GetMeta(value); value[cli.STATUS] == cli.STOP { return } @@ -54,7 +54,7 @@ func init() { m.OptionFields(m.Config(mdb.FIELD)) m.Cmdy(mdb.PRUNES, TIMER, "", mdb.HASH, ORDER, 0) }}, - ACTION: {Name: "action", Help: "执行", Hand: func(m *ice.Message, arg ...string) { + HAPPEN: {Name: "happen", Help: "执行", Hand: func(m *ice.Message, arg ...string) { _timer_action(m, arg...) }}, }, mdb.ZoneAction()), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { diff --git a/base/lex/matrix.go b/base/lex/matrix.go index 5cd2f4ee..6218ad6e 100644 --- a/base/lex/matrix.go +++ b/base/lex/matrix.go @@ -359,11 +359,11 @@ func (mat *Matrix) show(m *ice.Message) { m.Status(NLANG, mat.nlang, NCELL, mat.ncell, NPAGE, len(mat.page), NHASH, len(mat.hash)) } func _lex_load(m *ice.Message) { - m.Richs(m.PrefixKey(), "", mdb.FOREACH, func(key string, value map[string]interface{}) { + m.Richs(m.PrefixKey(), "", mdb.FOREACH, func(key string, value ice.Map) { value = kit.GetMeta(value) mat := NewMatrix(m, kit.Int(kit.Select("32", value[NLANG])), kit.Int(kit.Select("256", value[NCELL]))) - m.Grows(m.PrefixKey(), kit.Keys(mdb.HASH, key), "", "", func(index int, value map[string]interface{}) { + m.Grows(m.PrefixKey(), kit.Keys(mdb.HASH, key), "", "", func(index int, value ice.Map) { mat.Train(m, kit.Format(value[NPAGE]), kit.Format(value[NHASH]), kit.Format(value[mdb.TEXT])) }) value[MATRIX] = mat @@ -402,7 +402,7 @@ func init() { m.Echo(h) }}, mdb.INSERT: {Name: "insert hash npage=num nhash=num text=123", Help: "添加", Hand: func(m *ice.Message, arg ...string) { - m.Richs(m.PrefixKey(), "", m.Option(mdb.HASH), func(key string, value map[string]interface{}) { + m.Richs(m.PrefixKey(), "", m.Option(mdb.HASH), func(key string, value ice.Map) { value = kit.GetMeta(value) mat, _ := value[MATRIX].(*Matrix) @@ -419,7 +419,7 @@ func init() { m.Cmdy(mdb.DELETE, m.PrefixKey(), "", mdb.HASH, mdb.HASH, m.Option(mdb.HASH)) }}, PARSE: {Name: "parse hash npage text=123", Help: "解析", Hand: func(m *ice.Message, arg ...string) { - m.Richs(m.PrefixKey(), "", m.Option(mdb.HASH), func(key string, value map[string]interface{}) { + m.Richs(m.PrefixKey(), "", m.Option(mdb.HASH), func(key string, value ice.Map) { value = kit.GetMeta(value) mat, _ := value[MATRIX].(*Matrix) @@ -432,7 +432,7 @@ func init() { m.ProcessInner() }}, "show": {Name: "show", Help: "矩阵", Hand: func(m *ice.Message, arg ...string) { - m.Richs(m.PrefixKey(), "", kit.Select(m.Option(mdb.HASH), arg, 0), func(key string, value map[string]interface{}) { + m.Richs(m.PrefixKey(), "", kit.Select(m.Option(mdb.HASH), arg, 0), func(key string, value ice.Map) { value = kit.GetMeta(value) value[MATRIX].(*Matrix).show(m) }) @@ -453,7 +453,7 @@ func init() { return } - m.Richs(m.PrefixKey(), "", arg[0], func(key string, value map[string]interface{}) { + m.Richs(m.PrefixKey(), "", arg[0], func(key string, value ice.Map) { value = kit.GetMeta(value) mat, _ := value[MATRIX].(*Matrix) diff --git a/base/lex/split.go b/base/lex/split.go index ceafc1f6..52617816 100644 --- a/base/lex/split.go +++ b/base/lex/split.go @@ -31,7 +31,7 @@ func _split_deep(stack []int, text string) ([]int, int) { stack = append(stack, tab) return stack, len(stack) } -func _split_list(m *ice.Message, file string, arg ...string) map[string]interface{} { +func _split_list(m *ice.Message, file string, arg ...string) ice.Map { const DEEP = "_deep" stack, deep := []int{}, 0 list := kit.List(kit.Data(DEEP, -1)) @@ -53,9 +53,9 @@ func _split_list(m *ice.Message, file string, arg ...string) map[string]interfac // 回调函数 ls := kit.Split(text, m.Option(SPLIT_SPACE), m.Option(SPLIT_BLOCK), m.Option(SPLIT_QUOTE), m.Option(SPLIT_TRANS)) switch cb := m.OptionCB(SPLIT).(type) { - case func(int, []string, map[string]interface{}) []string: + case func(int, []string, ice.Map) []string: ls = cb(deep, ls, data) - case func([]string, map[string]interface{}) []string: + case func([]string, ice.Map) []string: ls = cb(ls, data) case func([]string): cb(ls) @@ -84,10 +84,10 @@ func _split_list(m *ice.Message, file string, arg ...string) map[string]interfac } line = "" }) - return list[0].(map[string]interface{}) + return list[0].(ice.Map) } -func Split(m *ice.Message, arg ...string) map[string]interface{} { - return kit.Value(_split_list(m, arg[0], arg[1:]...), "list.0").(map[string]interface{}) +func Split(m *ice.Message, arg ...string) ice.Map { + return kit.Value(_split_list(m, arg[0], arg[1:]...), "list.0").(ice.Map) } const ( diff --git a/base/log/log.go b/base/log/log.go index 31ba3a41..a7c6cd16 100644 --- a/base/log/log.go +++ b/base/log/log.go @@ -126,12 +126,12 @@ var Index = &ice.Context{Name: "log", Help: "日志模块", Configs: map[string] if log.LogDisable { return // 禁用日志 } - m.Confm(VIEW, nil, func(key string, value map[string]interface{}) { + m.Confm(VIEW, nil, func(key string, value ice.Map) { kit.Fetch(value[mdb.LIST], func(index int, k string) { m.Conf(SHOW, kit.Keys(k, VIEW), key) }) }) - m.Confm(FILE, nil, func(key string, value map[string]interface{}) { + m.Confm(FILE, nil, func(key string, value ice.Map) { kit.Fetch(value[mdb.LIST], func(index int, k string) { m.Conf(SHOW, kit.Keys(k, FILE), key) }) diff --git a/base/mdb/engine.go b/base/mdb/engine.go index e41b2d41..459dab8b 100644 --- a/base/mdb/engine.go +++ b/base/mdb/engine.go @@ -19,7 +19,7 @@ func init() { }}, }, HashAction()), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if len(arg) > 1 { - m.Cmdy(SELECT, m.PrefixKey(), "", HASH, m.Config(SHORT), arg, func(value map[string]interface{}) { + m.Cmdy(SELECT, m.PrefixKey(), "", HASH, m.Config(SHORT), arg, func(value ice.Map) { m.Cmdy(kit.Keys(value[TEXT], value[NAME]), m.CommandKey(), arg[0], arg[1], kit.Select("", arg, 2), kit.Slice(arg, 3)) }) return diff --git a/base/mdb/hash.go b/base/mdb/hash.go index efce20f0..3d6d0f00 100644 --- a/base/mdb/hash.go +++ b/base/mdb/hash.go @@ -14,7 +14,7 @@ func _hash_fields(m *ice.Message) []string { } func _hash_inputs(m *ice.Message, prefix, chain string, field, value string) { list := map[string]int{} - m.Richs(prefix, chain, FOREACH, func(key string, val map[string]interface{}) { + m.Richs(prefix, chain, FOREACH, func(key string, val ice.Map) { if val = kit.GetMeta(val); kit.Format(val[COUNT]) != "" { list[kit.Format(val[field])] = kit.Int(val[COUNT]) } else { @@ -32,19 +32,23 @@ func _hash_insert(m *ice.Message, prefix, chain string, arg ...string) { m.Conf(prefix, kit.Keys(chain, kit.Keym(SHORT)), m.Conf(prefix, kit.Keym(SHORT))) } m.Log_INSERT(KEY, path.Join(prefix, chain), arg[0], arg[1]) + if expire := m.Conf(prefix, kit.Keys(chain, kit.Keym(EXPIRE))); expire != "" { + arg = kit.Simple(TIME, m.Time(expire), arg) + } + m.Echo(m.Rich(prefix, chain, kit.Data(arg))) } func _hash_delete(m *ice.Message, prefix, chain, field, value string) { if field != HASH { field, value = HASH, kit.Select(kit.Hashs(value), m.Option(HASH)) } - m.Richs(prefix, chain, value, func(key string, val map[string]interface{}) { + m.Richs(prefix, chain, value, func(key string, val ice.Map) { m.Log_DELETE(KEY, path.Join(prefix, chain), field, value, VALUE, kit.Format(val)) m.Conf(prefix, kit.Keys(chain, HASH, key), "") }) } func _hash_modify(m *ice.Message, prefix, chain string, field, value string, arg ...string) { - m.Richs(prefix, chain, value, func(key string, val map[string]interface{}) { + m.Richs(prefix, chain, value, func(key string, val ice.Map) { val = kit.GetMeta(val) m.Log_MODIFY(KEY, path.Join(prefix, chain), field, value, arg) for i := 0; i < len(arg); i += 2 { @@ -60,11 +64,11 @@ func _hash_select(m *ice.Message, prefix, chain, field, value string) { value = RANDOMS } fields := _hash_fields(m) - m.Richs(prefix, chain, value, func(key string, val map[string]interface{}) { + m.Richs(prefix, chain, value, func(key string, val ice.Map) { switch val = kit.GetMeta(val); cb := m.OptionCB(SELECT).(type) { - case func(fields []string, value map[string]interface{}): + case func(fields []string, value ice.Map): cb(fields, val) - case func(value map[string]interface{}): + case func(value ice.Map): cb(val) default: if m.OptionFields() == DETAIL { @@ -98,7 +102,7 @@ func _hash_import(m *ice.Message, prefix, chain, file string) { } defer f.Close() - list := map[string]interface{}{} + list := ice.Map{} m.Assert(json.NewDecoder(f).Decode(&list)) count := 0 @@ -119,9 +123,9 @@ func _hash_import(m *ice.Message, prefix, chain, file string) { } func _hash_prunes(m *ice.Message, prefix, chain string, arg ...string) { fields := _hash_fields(m) - m.Richs(prefix, chain, FOREACH, func(key string, val map[string]interface{}) { + m.Richs(prefix, chain, FOREACH, func(key string, val ice.Map) { switch val = kit.GetMeta(val); cb := m.OptionCB(PRUNES).(type) { - case func(string, map[string]interface{}) bool: + case func(string, ice.Map) bool: if !cb(key, val) { return } @@ -141,15 +145,28 @@ func _hash_prunes(m *ice.Message, prefix, chain string, arg ...string) { const HASH = "hash" -func AutoConfig(args ...interface{}) *ice.Action { +func AutoConfig(args ...ice.Any) *ice.Action { return &ice.Action{Hand: func(m *ice.Message, arg ...string) { if cs := m.Target().Configs; cs[m.CommandKey()] == nil { cs[m.CommandKey()] = &ice.Config{Value: kit.Data(args...)} m.Load(m.CommandKey()) } + if cs := m.Target().Commands; cs[m.CommandKey()].Meta[CREATE] != nil { + return + } + + inputs := []ice.Any{} + kit.Fetch(kit.Split(m.Config(FIELD)), func(i int, k string) { + switch k { + case TIME, HASH: + return + } + inputs = append(inputs, k) + }) + m.Design(CREATE, "创建", inputs...) }} } -func HashAction(args ...interface{}) map[string]*ice.Action { +func HashAction(args ...ice.Any) map[string]*ice.Action { _key := func(m *ice.Message) string { if m.Config(HASH) == UNIQ { return HASH @@ -163,7 +180,7 @@ func HashAction(args ...interface{}) map[string]*ice.Action { INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(INPUTS, m.PrefixKey(), "", HASH, arg) }}, - CREATE: {Name: "create type name text", Help: "创建", Hand: func(m *ice.Message, arg ...string) { + CREATE: {Name: "create", Help: "创建", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(INSERT, m.PrefixKey(), "", HASH, arg) }}, REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { @@ -189,7 +206,7 @@ func HashAction(args ...interface{}) map[string]*ice.Action { }}, }) } -func HashActionStatus(args ...interface{}) map[string]*ice.Action { +func HashActionStatus(args ...ice.Any) map[string]*ice.Action { list := HashAction(args...) list[PRUNES] = &ice.Action{Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) { m.OptionFields(m.Config(FIELD)) @@ -198,7 +215,7 @@ func HashActionStatus(args ...interface{}) map[string]*ice.Action { }} return list } -func HashCreate(m *ice.Message, arg ...interface{}) *ice.Message { +func HashCreate(m *ice.Message, arg ...ice.Any) *ice.Message { return m.Cmd(INSERT, m.PrefixKey(), "", HASH, kit.Simple(arg...)) } func HashSelect(m *ice.Message, arg ...string) *ice.Message { diff --git a/base/mdb/list.go b/base/mdb/list.go index 20dc0ca6..9beed6ff 100644 --- a/base/mdb/list.go +++ b/base/mdb/list.go @@ -14,7 +14,7 @@ func _list_fields(m *ice.Message) []string { } func _list_inputs(m *ice.Message, prefix, chain string, field, value string) { list := map[string]int{} - m.Grows(prefix, chain, "", "", func(index int, val map[string]interface{}) { + m.Grows(prefix, chain, "", "", func(index int, val ice.Map) { if val = kit.GetMeta(val); kit.Format(val[COUNT]) != "" { list[kit.Format(val[field])] = kit.Int(val[COUNT]) } else { @@ -34,7 +34,7 @@ func _list_insert(m *ice.Message, prefix, chain string, arg ...string) { func _list_delete(m *ice.Message, prefix, chain, field, value string) { } func _list_modify(m *ice.Message, prefix, chain string, field, value string, arg ...string) { - m.Grows(prefix, chain, field, value, func(index int, val map[string]interface{}) { + m.Grows(prefix, chain, field, value, func(index int, val ice.Map) { val = kit.GetMeta(val) m.Log_MODIFY(KEY, path.Join(prefix, chain), field, value, arg) for i := 0; i < len(arg); i += 2 { @@ -50,9 +50,9 @@ func _list_select(m *ice.Message, prefix, chain, field, value string) { field = "" } fields := _list_fields(m) - m.Grows(prefix, chain, kit.Select(m.Option(ice.CACHE_FIELD), field), kit.Select(m.Option(ice.CACHE_VALUE), value), func(index int, val map[string]interface{}) { + m.Grows(prefix, chain, kit.Select(m.Option(ice.CACHE_FIELD), field), kit.Select(m.Option(ice.CACHE_VALUE), value), func(index int, val ice.Map) { switch val = kit.GetMeta(val); cb := m.OptionCB(SELECT).(type) { - case func(fields []string, value map[string]interface{}): + case func(fields []string, value ice.Map): cb(fields, val) default: if m.OptionFields() == DETAIL { @@ -73,7 +73,7 @@ func _list_export(m *ice.Message, prefix, chain, file string) { count := 0 head := kit.Split(m.OptionFields()) - m.Grows(prefix, chain, "", "", func(index int, val map[string]interface{}) { + m.Grows(prefix, chain, "", "", func(index int, val ice.Map) { if val = kit.GetMeta(val); index == 0 { if len(head) == 0 || head[0] == ice.CACHE_DETAIL { // 默认表头 for k := range val { diff --git a/base/mdb/plugin.go b/base/mdb/plugin.go index a4130b4a..7180650e 100644 --- a/base/mdb/plugin.go +++ b/base/mdb/plugin.go @@ -19,7 +19,7 @@ func init() { }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if len(arg) > 1 { - m.Cmdy(SELECT, m.PrefixKey(), "", HASH, m.Config(SHORT), arg, func(value map[string]interface{}) { + m.Cmdy(SELECT, m.PrefixKey(), "", HASH, m.Config(SHORT), arg, func(value ice.Map) { m.Cmdy(kit.Keys(value[TEXT], value[NAME]), m.CommandKey(), arg[0], arg[1], kit.Select("", arg, 2), kit.Slice(arg, 3)) }) return diff --git a/base/mdb/render.go b/base/mdb/render.go index f9099f71..44274de0 100644 --- a/base/mdb/render.go +++ b/base/mdb/render.go @@ -19,7 +19,7 @@ func init() { }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if len(arg) > 1 { - m.Cmdy(SELECT, m.PrefixKey(), "", HASH, m.Config(SHORT), arg, func(value map[string]interface{}) { + m.Cmdy(SELECT, m.PrefixKey(), "", HASH, m.Config(SHORT), arg, func(value ice.Map) { m.Cmdy(kit.Keys(value[TEXT], value[NAME]), m.CommandKey(), arg[0], arg[1], kit.Select("", arg, 2), kit.Slice(arg, 3)) }) return diff --git a/base/mdb/search.go b/base/mdb/search.go index 6edf451e..e9ebfc22 100644 --- a/base/mdb/search.go +++ b/base/mdb/search.go @@ -19,7 +19,7 @@ func init() { }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if len(arg) > 1 { - m.Cmdy(SELECT, m.PrefixKey(), "", HASH, m.Config(SHORT), kit.Slice(arg, 0, 1), func(value map[string]interface{}) { + m.Cmdy(SELECT, m.PrefixKey(), "", HASH, m.Config(SHORT), kit.Slice(arg, 0, 1), func(value ice.Map) { m.OptionFields(kit.Select("ctx,cmd,type,name,text", kit.Select(m.OptionFields()))) m.Cmdy(kit.Keys(value[TEXT], value[NAME]), m.CommandKey(), arg[0], arg[1], kit.Select("", arg, 2), kit.Slice(arg, 3)) }) diff --git a/base/mdb/zone.go b/base/mdb/zone.go index 23ee439f..58edc5ee 100644 --- a/base/mdb/zone.go +++ b/base/mdb/zone.go @@ -21,7 +21,7 @@ func _zone_select(m *ice.Message, prefix, chain, zone string, id string) { fields := _zone_fields(m) cb := m.OptionCB(SELECT) - m.Richs(prefix, chain, kit.Select(FOREACH, zone), func(key string, val map[string]interface{}) { + m.Richs(prefix, chain, kit.Select(FOREACH, zone), func(key string, val ice.Map) { if val = kit.GetMeta(val); zone == "" { if m.OptionFields() == DETAIL { m.Push(DETAIL, val) @@ -31,15 +31,15 @@ func _zone_select(m *ice.Message, prefix, chain, zone string, id string) { return } - m.Grows(prefix, kit.Keys(chain, HASH, key), ID, id, func(index int, value map[string]interface{}) { + m.Grows(prefix, kit.Keys(chain, HASH, key), ID, id, func(index int, value ice.Map) { switch value = kit.GetMeta(value); cb := cb.(type) { - case func(string, []string, map[string]interface{}, map[string]interface{}): + case func(string, []string, ice.Map, ice.Map): cb(key, fields, value, val) - case func(string, map[string]interface{}, map[string]interface{}): + case func(string, ice.Map, ice.Map): cb(key, value, val) - case func(string, map[string]interface{}): + case func(string, ice.Map): cb(key, value) - case func(map[string]interface{}): + case func(ice.Map): cb(value) case func(map[string]string): res := map[string]string{} @@ -70,17 +70,17 @@ func _zone_export(m *ice.Message, prefix, chain, file string) { w.Write(fields) keys := []string{} - m.Richs(prefix, chain, FOREACH, func(key string, val map[string]interface{}) { + m.Richs(prefix, chain, FOREACH, func(key string, val ice.Map) { keys = append(keys, key) }) sort.Strings(keys) count := 0 for _, key := range keys { - m.Richs(prefix, chain, key, func(key string, val map[string]interface{}) { + m.Richs(prefix, chain, key, func(key string, val ice.Map) { val = kit.GetMeta(val) - m.Grows(prefix, kit.Keys(chain, HASH, key), "", "", func(index int, value map[string]interface{}) { + m.Grows(prefix, kit.Keys(chain, HASH, key), "", "", func(index int, value ice.Map) { value = kit.GetMeta(value) list := []string{} @@ -145,7 +145,7 @@ func _zone_import(m *ice.Message, prefix, chain, file string) { const ZONE = "zone" -func ZoneAction(args ...interface{}) map[string]*ice.Action { +func ZoneAction(args ...ice.Any) map[string]*ice.Action { _zone := func(m *ice.Message) string { return kit.Select(ZONE, m.Config(SHORT)) } return ice.SelectAction(map[string]*ice.Action{ice.CTX_INIT: AutoConfig(args...), @@ -229,7 +229,7 @@ func ZoneSelectAll(m *ice.Message, arg ...string) *ice.Message { m.Option(ice.CACHE_LIMIT, "-1") return ZoneSelect(m, arg...) } -func ZoneSelectCB(m *ice.Message, zone string, cb interface{}) *ice.Message { +func ZoneSelectCB(m *ice.Message, zone string, cb ice.Any) *ice.Message { m.OptionCB(SELECT, cb) m.Option(ice.CACHE_LIMIT, "-1") return ZoneSelect(m, zone) diff --git a/base/nfs/cat.go b/base/nfs/cat.go index 43a1b99d..4d1a06fe 100644 --- a/base/nfs/cat.go +++ b/base/nfs/cat.go @@ -31,9 +31,9 @@ func NewReadCloser(r io.Reader) *ReadCloser { return &ReadCloser{r: r} } -var rewriteList = []interface{}{} +var rewriteList = []ice.Any{} -func AddRewrite(cb interface{}) { rewriteList = append(rewriteList, cb) } +func AddRewrite(cb ice.Any) { rewriteList = append(rewriteList, cb) } func _cat_right(m *ice.Message, name string) bool { return aaa.RoleRight(m, m.Option(ice.MSG_USERROLE), strings.Split(name, ice.PS)...) diff --git a/base/nfs/dir.go b/base/nfs/dir.go index 383f7e3b..82d94901 100644 --- a/base/nfs/dir.go +++ b/base/nfs/dir.go @@ -168,7 +168,7 @@ func _dir_list(m *ice.Message, root string, name string, level int, deep bool, d if m.IsCliUA() || m.Option(ice.MSG_USERROLE) == aaa.VOID { break } - m.PushButton(kit.Select("", TRASH, !isDir)) + m.PushButton(TRASH) default: m.Push(field, "") } diff --git a/base/nfs/tail.go b/base/nfs/tail.go index 2c3ca545..6acf7fdb 100644 --- a/base/nfs/tail.go +++ b/base/nfs/tail.go @@ -43,7 +43,7 @@ func init() { }, Commands: map[string]*ice.Command{ TAIL: {Name: "tail name id auto page filter:text create", Help: "日志流", Action: ice.MergeAction(map[string]*ice.Action{ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { - m.Richs(TAIL, "", mdb.FOREACH, func(key string, value map[string]interface{}) { + m.Richs(TAIL, "", mdb.FOREACH, func(key string, value ice.Map) { value, _ = kit.GetMeta(value), m.Option(mdb.HASH, key) m.Cmd(TAIL, mdb.CREATE, kit.SimpleKV("file,name", value)) }) diff --git a/base/nfs/trash.go b/base/nfs/trash.go index 56f98536..5bc65ee9 100644 --- a/base/nfs/trash.go +++ b/base/nfs/trash.go @@ -11,18 +11,17 @@ import ( func _trash_create(m *ice.Message, name string) { if s, e := os.Stat(name); m.Assert(e) { - if s.IsDir() { - name = m.Cmdx(TAR, mdb.IMPORT, name) + p := path.Join(ice.VAR_TRASH, path.Base(name)) + if !s.IsDir() { + if f, e := os.Open(name); m.Assert(e) { + defer f.Close() + p = path.Join(ice.VAR_TRASH, kit.HashsPath(f)) + } } - if f, e := os.Open(name); m.Assert(e) { - defer f.Close() - - p := path.Join(m.Config(PATH), kit.HashsPath(f)) - MkdirAll(m, path.Dir(p)) - os.Remove(p) - os.Rename(name, p) - m.Cmdy(mdb.INSERT, TRASH, "", mdb.HASH, FILE, p, FROM, name) + MkdirAll(m, path.Dir(p)) + if os.RemoveAll(p); !m.Warn(os.Rename(name, p)) { + m.Cmd(mdb.INSERT, TRASH, "", mdb.HASH, FILE, p, FROM, name) } } } diff --git a/base/ssh/scripts.go b/base/ssh/scripts.go index 838c4f72..06f2d179 100644 --- a/base/ssh/scripts.go +++ b/base/ssh/scripts.go @@ -18,7 +18,7 @@ import ( kit "shylinux.com/x/toolkits" ) -func Render(msg *ice.Message, cmd string, args ...interface{}) (res string) { +func Render(msg *ice.Message, cmd string, args ...ice.Any) (res string) { switch arg := kit.Simple(args...); cmd { case ice.RENDER_VOID: return res @@ -77,7 +77,7 @@ func (f *Frame) prompt(m *ice.Message, list ...string) *Frame { } return f } -func (f *Frame) printf(m *ice.Message, str string, arg ...interface{}) *Frame { +func (f *Frame) printf(m *ice.Message, str string, arg ...ice.Any) *Frame { fmt.Fprint(f.stdout, kit.Format(str, arg...)) return f } @@ -123,7 +123,7 @@ func (f *Frame) parse(m *ice.Message, line string) string { msg.SetResult().Cmdy(cli.SYSTEM, ls) } - f.res = Render(msg, msg.Option(ice.MSG_OUTPUT), msg.Optionv(ice.MSG_ARGS).([]interface{})...) + f.res = Render(msg, msg.Option(ice.MSG_OUTPUT), msg.Optionv(ice.MSG_ARGS).([]ice.Any)...) } m.Sleep("10ms") return "" @@ -262,8 +262,8 @@ func init() { Index.Merge(&ice.Context{Configs: map[string]*ice.Config{ SOURCE: {Name: SOURCE, Help: "加载脚本", Value: kit.Data()}, PROMPT: {Name: PROMPT, Help: "命令提示", Value: kit.Data( - PS1, []interface{}{"\033[33;44m", mdb.COUNT, "[", mdb.TIME, "]", "\033[5m", TARGET, "\033[0m", "\033[44m", ">", "\033[0m ", "\033[?25h", "\033[32m"}, - PS2, []interface{}{mdb.COUNT, " ", TARGET, "> "}, + PS1, []ice.Any{"\033[33;44m", mdb.COUNT, "[", mdb.TIME, "]", "\033[5m", TARGET, "\033[0m", "\033[44m", ">", "\033[0m ", "\033[?25h", "\033[32m"}, + PS2, []ice.Any{mdb.COUNT, " ", TARGET, "> "}, )}, }, Commands: map[string]*ice.Command{ ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}}, diff --git a/base/tcp/client.go b/base/tcp/client.go index fde8cbc9..bf754d37 100644 --- a/base/tcp/client.go +++ b/base/tcp/client.go @@ -84,7 +84,7 @@ func init() { }, Commands: map[string]*ice.Command{ CLIENT: {Name: "client hash auto prunes", Help: "客户端", Action: ice.MergeAction(map[string]*ice.Action{ ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) { - m.Richs(CLIENT, "", mdb.FOREACH, func(key string, value map[string]interface{}) { + m.Richs(CLIENT, "", mdb.FOREACH, func(key string, value ice.Map) { kit.Value(value, kit.Keym(STATUS), CLOSE) }) m.Cmdy(SERVER, mdb.PRUNES) diff --git a/base/tcp/port.go b/base/tcp/port.go index 8fd9065b..f557fdbb 100644 --- a/base/tcp/port.go +++ b/base/tcp/port.go @@ -53,20 +53,34 @@ func init() { aaa.RIGHT: {Name: "right", Help: "分配", Hand: func(m *ice.Message, arg ...string) { m.Echo(_port_right(m, arg...)) }}, + nfs.TRASH: {Name: "trash", Help: "删除", Hand: func(m *ice.Message, arg ...string) { + if m.Option(PORT) != "" { + m.Cmd(nfs.TRASH, path.Join(ice.USR_LOCAL_DAEMON, m.Option(PORT))) + } + }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if len(arg) == 0 { - m.Option(nfs.DIR_ROOT, m.Conf(cli.DAEMON, kit.Keym(nfs.PATH))) - m.Cmd(nfs.DIR, nfs.PWD, nfs.DIR_CLI_FIELDS).Table(func(index int, value map[string]string, head []string) { + current := kit.Int(m.Config(BEGIN)) + m.Option(nfs.DIR_ROOT, ice.USR_LOCAL_DAEMON) + m.Cmd(nfs.DIR, nfs.PWD, nfs.DIR_CLI_FIELDS).Tables(func(value map[string]string) { bin := m.Cmd(nfs.DIR, path.Join(value[nfs.PATH], ice.BIN), nfs.DIR_CLI_FIELDS).Append(nfs.PATH) if bin == "" { bin = m.Cmd(nfs.DIR, path.Join(value[nfs.PATH], "sbin"), nfs.DIR_CLI_FIELDS).Append(nfs.PATH) } + port := kit.Int(path.Base(value[nfs.PATH])) + if port > current { + current = port + } + m.Push(mdb.TIME, value[mdb.TIME]) - m.Push(PORT, path.Base(value[nfs.PATH])) + m.Push(PORT, port) m.Push(nfs.SIZE, value[nfs.SIZE]) m.Push(ice.BIN, bin) }) m.SortInt(PORT) + m.PushAction(nfs.TRASH) + m.Config(CURRENT, current) + m.StatusTimeCount(m.ConfigSimple(BEGIN, CURRENT, END)) return } m.Option(nfs.DIR_ROOT, path.Join(m.Conf(cli.DAEMON, kit.Keym(nfs.PATH)), arg[0])) diff --git a/base/tcp/server.go b/base/tcp/server.go index a889585f..45c96401 100644 --- a/base/tcp/server.go +++ b/base/tcp/server.go @@ -92,7 +92,7 @@ func init() { }, Commands: map[string]*ice.Command{ SERVER: {Name: "server hash auto prunes", Help: "服务器", Action: ice.MergeAction(map[string]*ice.Action{ ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) { - m.Richs(SERVER, "", mdb.FOREACH, func(key string, value map[string]interface{}) { + m.Richs(SERVER, "", mdb.FOREACH, func(key string, value ice.Map) { kit.Value(value, kit.Keym(STATUS), CLOSE) }) m.Cmdy(SERVER, mdb.PRUNES) diff --git a/base/web/broad.go b/base/web/broad.go index c726a4b1..321fc5bb 100644 --- a/base/web/broad.go +++ b/base/web/broad.go @@ -58,7 +58,7 @@ func _serve_udp(m *ice.Message, host, port string) { } } func _broad_search(m *ice.Message, kind, name, text string, arg ...string) { - m.Richs(BROAD, nil, mdb.FOREACH, func(key string, value map[string]interface{}) { + m.Richs(BROAD, nil, mdb.FOREACH, func(key string, value ice.Map) { if value = kit.GetMeta(value); !strings.Contains(kit.Format(value[tcp.HOST]), name) { return } diff --git a/base/web/cache.go b/base/web/cache.go index ad72a745..7ed17217 100644 --- a/base/web/cache.go +++ b/base/web/cache.go @@ -96,7 +96,7 @@ func _cache_download(m *ice.Message, r *http.Response) (file, size string) { case func(int, int): cb(size, total) case []string: - m.Richs(cb[0], cb[1], cb[2], func(key string, value map[string]interface{}) { + m.Richs(cb[0], cb[1], cb[2], func(key string, value ice.Map) { value = kit.GetMeta(value) value[mdb.COUNT], value[mdb.TOTAL], value[mdb.VALUE] = size, total, kit.Format(s) }) @@ -143,7 +143,7 @@ func init() { )}, }, Commands: map[string]*ice.Command{ "/cache/": {Name: "/cache/", Help: "缓存池", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Richs(CACHE, nil, arg[0], func(key string, value map[string]interface{}) { + m.Richs(CACHE, nil, arg[0], func(key string, value ice.Map) { if kit.Format(value[nfs.FILE]) == "" { m.RenderResult(value[mdb.TEXT]) } else { diff --git a/base/web/dream.go b/base/web/dream.go index e86d3125..d8bc17e7 100644 --- a/base/web/dream.go +++ b/base/web/dream.go @@ -16,7 +16,7 @@ import ( func _dream_list(m *ice.Message) *ice.Message { return m.Cmdy(nfs.DIR, m.Config(nfs.PATH), "time,size,name").Table(func(index int, value map[string]string, head []string) { - if m.Richs(SPACE, nil, value[mdb.NAME], func(key string, val map[string]interface{}) { + if m.Richs(SPACE, nil, value[mdb.NAME], func(key string, val ice.Map) { m.Push(mdb.TYPE, val[mdb.TYPE]) m.Push(cli.STATUS, cli.START) m.PushButton("vimer", cli.OPEN, cli.STOP) diff --git a/base/web/render.go b/base/web/render.go index 562638a9..93d05409 100644 --- a/base/web/render.go +++ b/base/web/render.go @@ -18,21 +18,15 @@ const ( COOKIE = "cookie" ) -func Render(msg *ice.Message, cmd string, args ...interface{}) { +func Render(msg *ice.Message, cmd string, args ...ice.Any) { if cmd != "" { defer func() { msg.Log_EXPORT(cmd, args) }() } switch arg := kit.Simple(args...); cmd { - case STATUS: // [code [text]] - RenderStatus(msg, kit.Int(kit.Select("200", arg, 0)), kit.Select("", arg, 1)) - case COOKIE: // value [name [path [expire]]] RenderCookie(msg, arg[0], arg[1:]...) - case ice.RENDER_REDIRECT: // url [arg...] - RenderRedirect(msg, arg...) - case ice.RENDER_DOWNLOAD: // file [type [name]] if strings.HasPrefix(arg[0], "http") { http.Redirect(msg.W, msg.R, arg[0], http.StatusSeeOther) @@ -43,6 +37,9 @@ func Render(msg *ice.Message, cmd string, args ...interface{}) { http.ServeFile(msg.W, msg.R, kit.Path(arg[0])) } + case ice.RENDER_REDIRECT: // url [arg...] + RenderRedirect(msg, arg...) + case ice.RENDER_RESULT: if len(arg) > 0 { // [str [arg...]] msg.W.Write([]byte(kit.Format(arg[0], args[1:]...))) @@ -51,6 +48,13 @@ func Render(msg *ice.Message, cmd string, args ...interface{}) { msg.W.Write([]byte(msg.Result())) } + case STATUS, ice.RENDER_STATUS: // [code [text]] + RenderStatus(msg, kit.Int(kit.Select("200", arg, 0)), kit.Select("", arg, 1)) + + case ice.RENDER_JSON: + msg.W.Header().Set("Content-Type", "application/json") + msg.W.Write([]byte(arg[0])) + case ice.RENDER_VOID: // no output @@ -117,13 +121,13 @@ func RenderType(w http.ResponseWriter, name, mime string) { default: } } -func RenderResult(msg *ice.Message, arg ...interface{}) { +func RenderResult(msg *ice.Message, arg ...ice.Any) { Render(msg, ice.RENDER_RESULT, arg...) } -func RenderDownload(msg *ice.Message, arg ...interface{}) { +func RenderDownload(msg *ice.Message, arg ...ice.Any) { Render(msg, ice.RENDER_DOWNLOAD, arg...) } -func Format(tag string, arg ...interface{}) string { +func Format(tag string, arg ...ice.Any) string { return kit.Format("<%s>%s", tag, strings.Join(kit.Simple(arg), ""), tag) } diff --git a/base/web/route.go b/base/web/route.go index 63e31def..2c054208 100644 --- a/base/web/route.go +++ b/base/web/route.go @@ -12,7 +12,7 @@ import ( ) func _route_travel(m *ice.Message, route string) { - m.Richs(SPACE, nil, mdb.FOREACH, func(key string, val map[string]interface{}) { + m.Richs(SPACE, nil, mdb.FOREACH, func(key string, val ice.Map) { switch val[mdb.TYPE] { case SERVER: // 远程查询 if val[mdb.NAME] == ice.Info.NodeName { diff --git a/base/web/serve.go b/base/web/serve.go index 60d3f061..ac1e298d 100644 --- a/base/web/serve.go +++ b/base/web/serve.go @@ -17,9 +17,9 @@ import ( kit "shylinux.com/x/toolkits" ) -var rewriteList = []interface{}{} +var rewriteList = []ice.Any{} -func AddRewrite(cb interface{}) { rewriteList = append(rewriteList, cb) } +func AddRewrite(cb ice.Any) { rewriteList = append(rewriteList, cb) } func _serve_domain(m *ice.Message) string { if p := m.Config(DOMAIN); p != "" { @@ -131,12 +131,12 @@ func _serve_handle(key string, cmd *ice.Command, msg *ice.Message, w http.Respon switch r.Header.Get(ContentType) { case ContentJSON: defer r.Body.Close() - var data interface{} + var data ice.Any if e := json.NewDecoder(r.Body).Decode(&data); !msg.Warn(e, ice.ErrNotFound, data) { msg.Log_IMPORT(mdb.VALUE, kit.Format(data)) msg.Optionv(ice.MSG_USERDATA, data) } - kit.Fetch(data, func(key string, value interface{}) { msg.Optionv(key, value) }) + kit.Fetch(data, func(key string, value ice.Any) { msg.Optionv(key, value) }) default: r.ParseMultipartForm(kit.Int64(kit.Select("4096", r.Header.Get(ContentLength)))) @@ -205,7 +205,7 @@ func _serve_handle(key string, cmd *ice.Command, msg *ice.Message, w http.Respon // 输出响应 switch args := msg.Optionv(ice.MSG_ARGS).(type) { - case []interface{}: + case []ice.Any: Render(msg, msg.Option(ice.MSG_OUTPUT), args...) default: Render(msg, msg.Option(ice.MSG_OUTPUT), args) diff --git a/base/web/share.go b/base/web/share.go index 0741b4db..574e7ff2 100644 --- a/base/web/share.go +++ b/base/web/share.go @@ -18,7 +18,7 @@ import ( kit "shylinux.com/x/toolkits" ) -func _share_link(m *ice.Message, p string, arg ...interface{}) string { +func _share_link(m *ice.Message, p string, arg ...ice.Any) string { p = kit.Select("", "/share/local/", !strings.HasPrefix(p, ice.PS)) + p return tcp.ReplaceLocalhost(m, m.MergeURL2(p, arg...)) } @@ -129,7 +129,7 @@ func init() { }, Commands: map[string]*ice.Command{ SHARE: {Name: "share hash auto prunes", Help: "共享链", Action: ice.MergeAction(map[string]*ice.Action{ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { - ice.AddRender(ice.RENDER_DOWNLOAD, func(msg *ice.Message, cmd string, args ...interface{}) string { + ice.AddRender(ice.RENDER_DOWNLOAD, func(msg *ice.Message, cmd string, args ...ice.Any) string { list := []string{} if msg.Option(ice.MSG_USERPOD) != "" { list = append(list, ice.POD, msg.Option(ice.MSG_USERPOD)) diff --git a/base/web/space.go b/base/web/space.go index 0490817d..7d60b974 100644 --- a/base/web/space.go +++ b/base/web/space.go @@ -47,7 +47,7 @@ func _space_dial(m *ice.Message, dev, name string, arg ...string) { } value := m.Richs(SPIDE, nil, dev, nil) - client := kit.Value(value, tcp.CLIENT).(map[string]interface{}) + client := kit.Value(value, tcp.CLIENT).(ice.Map) host := kit.Format(client[tcp.HOSTNAME]) proto := strings.Replace(kit.Format(client[tcp.PROTOCOL]), "http", "ws", 1) @@ -109,7 +109,7 @@ func _space_handle(m *ice.Message, safe bool, send map[string]*ice.Message, c *w _space_echo(msg, []string{}, kit.Revert(source)[1:], c, name) } - } else if msg.Richs(SPACE, nil, target[0], func(key string, value map[string]interface{}) { + } else if msg.Richs(SPACE, nil, target[0], func(key string, value ice.Map) { if s, ok := value[SOCKET].(*websocket.Conn); ok { socket, source, target = s, source, target[1:] _space_echo(msg, source, target, socket, kit.Select("", target)) @@ -170,7 +170,7 @@ func _space_send(m *ice.Message, space string, arg ...string) { } target := kit.Split(space, ice.PT, ice.PT) - m.Warn(m.Richs(SPACE, nil, target[0], func(key string, value map[string]interface{}) { + m.Warn(m.Richs(SPACE, nil, target[0], func(key string, value ice.Map) { if socket, ok := value[SOCKET].(*websocket.Conn); !m.Warn(!ok, ice.ErrNotFound, SOCKET) { // 复制选项 @@ -203,7 +203,7 @@ func _space_send(m *ice.Message, space string, arg ...string) { }) == nil, ice.ErrNotFound, space) } func _space_search(m *ice.Message, kind, name, text string, arg ...string) { - m.Richs(SPACE, nil, mdb.FOREACH, func(key string, value map[string]interface{}) { + m.Richs(SPACE, nil, mdb.FOREACH, func(key string, value ice.Map) { if value = kit.GetMeta(value); !strings.Contains(kit.Format(value[mdb.NAME]), name) { return } diff --git a/base/web/spide.go b/base/web/spide.go index 4c8aa48b..fd3f1b20 100644 --- a/base/web/spide.go +++ b/base/web/spide.go @@ -24,7 +24,7 @@ import ( func _spide_create(m *ice.Message, name, address string) { if uri, e := url.Parse(address); e == nil && address != "" { - if m.Richs(SPIDE, nil, name, func(key string, value map[string]interface{}) { + if m.Richs(SPIDE, nil, name, func(key string, value ice.Map) { kit.Value(value, "client.hostname", uri.Host) kit.Value(value, "client.url", address) }) == nil { @@ -42,7 +42,7 @@ func _spide_create(m *ice.Message, name, address string) { } } func _spide_list(m *ice.Message, arg ...string) { - m.Richs(SPIDE, nil, arg[0], func(key string, value map[string]interface{}) { + m.Richs(SPIDE, nil, arg[0], func(key string, value ice.Map) { // 缓存方式 cache, save := "", "" switch arg[1] { @@ -60,7 +60,7 @@ func _spide_list(m *ice.Message, arg ...string) { } // 请求方法 - client := value[SPIDE_CLIENT].(map[string]interface{}) + client := value[SPIDE_CLIENT].(ice.Map) method := kit.Select(SPIDE_POST, client[SPIDE_METHOD]) switch arg = arg[1:]; arg[0] { case SPIDE_GET: @@ -163,7 +163,7 @@ func _spide_body(m *ice.Message, method string, arg ...string) (io.Reader, map[s arg = arg[1:] fallthrough default: - data := map[string]interface{}{} + data := ice.Map{} for i := 0; i < len(arg)-1; i += 2 { kit.Value(data, arg[i], arg[i+1]) } @@ -216,7 +216,7 @@ func _spide_part(m *ice.Message, arg ...string) (io.Reader, string) { } return buf, mp.FormDataContentType() } -func _spide_head(m *ice.Message, req *http.Request, head map[string]string, value map[string]interface{}) { +func _spide_head(m *ice.Message, req *http.Request, head map[string]string, value ice.Map) { m.Info("%s %s", req.Method, req.URL) kit.Fetch(value[SPIDE_HEADER], func(key string, value string) { req.Header.Set(key, value) @@ -289,14 +289,14 @@ func _spide_save(m *ice.Message, cache, save, uri string, res *http.Response) { default: b, _ := ioutil.ReadAll(res.Body) - var data interface{} + var data ice.Any if e := json.Unmarshal(b, &data); e != nil { m.Echo(string(b)) break } m.Optionv(SPIDE_RES, data) - data = kit.KeyValue(map[string]interface{}{}, "", data) + data = kit.KeyValue(ice.Map{}, "", data) m.Push("", data) } } @@ -321,6 +321,7 @@ const ( SPIDE_RES = "content_data" + Bearer = "Bearer" Authorization = "Authorization" ContentType = "Content-Type" ContentLength = "Content-Length" diff --git a/base/web/story.go b/base/web/story.go index 7fb8b436..a2568504 100644 --- a/base/web/story.go +++ b/base/web/story.go @@ -12,7 +12,7 @@ import ( func _story_list(m *ice.Message, name string, key string) { if name == "" { - m.Richs(STORY, HEAD, mdb.FOREACH, func(key string, value map[string]interface{}) { + m.Richs(STORY, HEAD, mdb.FOREACH, func(key string, value ice.Map) { m.Push(key, value, []string{mdb.TIME, mdb.COUNT, STORY}) }) m.SortTimeR(mdb.TIME) @@ -23,26 +23,26 @@ func _story_list(m *ice.Message, name string, key string) { return } - m.Richs(STORY, nil, key, func(key string, value map[string]interface{}) { + m.Richs(STORY, nil, key, func(key string, value ice.Map) { m.Push(mdb.DETAIL, value) }) } func _story_index(m *ice.Message, name string, withdata bool) { - m.Richs(STORY, HEAD, name, func(key string, value map[string]interface{}) { + m.Richs(STORY, HEAD, name, func(key string, value ice.Map) { // 查询索引 m.Push(HEAD, key) name = kit.Format(value[LIST]) }) - m.Richs(STORY, nil, name, func(key string, value map[string]interface{}) { + m.Richs(STORY, nil, name, func(key string, value ice.Map) { // 查询节点 m.Push(LIST, key) m.Push(key, value, []string{SCENE, STORY}) name = kit.Format(value[DATA]) }) - m.Richs(CACHE, nil, name, func(key string, value map[string]interface{}) { + m.Richs(CACHE, nil, name, func(key string, value ice.Map) { // 查询数据 m.Push(DATA, key) m.Push(key, value, []string{mdb.TEXT, nfs.FILE, nfs.SIZE, mdb.TIME, mdb.NAME, mdb.TYPE}) @@ -59,19 +59,19 @@ func _story_history(m *ice.Message, name string) { // 历史记录 list := m.Cmd(STORY, INDEX, name).Append(LIST) for i := 0; i < kit.Int(kit.Select("30", m.Option(ice.CACHE_LIMIT))) && list != ""; i++ { - m.Richs(STORY, nil, list, func(key string, value map[string]interface{}) { + m.Richs(STORY, nil, list, func(key string, value ice.Map) { // 直连节点 m.Push(key, value, []string{mdb.TIME, mdb.KEY, mdb.COUNT, SCENE, STORY}) - m.Richs(CACHE, nil, value[DATA], func(key string, value map[string]interface{}) { + m.Richs(CACHE, nil, value[DATA], func(key string, value ice.Map) { m.Push(DRAMA, value[mdb.TEXT]) m.Push(DATA, key) }) kit.Fetch(value[LIST], func(key string, val string) { - m.Richs(STORY, nil, val, func(key string, value map[string]interface{}) { + m.Richs(STORY, nil, val, func(key string, value ice.Map) { // 复合节点 m.Push(key, value, []string{mdb.TIME, mdb.KEY, mdb.COUNT, SCENE, STORY}) - m.Richs(CACHE, nil, value[DATA], func(key string, value map[string]interface{}) { + m.Richs(CACHE, nil, value[DATA], func(key string, value ice.Map) { m.Push(DRAMA, value[mdb.TEXT]) m.Push(DATA, key) }) @@ -84,7 +84,7 @@ func _story_history(m *ice.Message, name string) { } } func _story_write(m *ice.Message, scene, name, text string, arg ...string) { - if len(arg) < 1 || text == "" || m.Richs(CACHE, nil, text, func(key string, value map[string]interface{}) { text = key }) == nil { + if len(arg) < 1 || text == "" || m.Richs(CACHE, nil, text, func(key string, value ice.Map) { text = key }) == nil { // 添加缓存 m.Cmdy(CACHE, CATCH, scene, name, text, arg) scene, name, text = m.Append(mdb.TYPE), m.Append(mdb.NAME), m.Append(DATA) @@ -92,7 +92,7 @@ func _story_write(m *ice.Message, scene, name, text string, arg ...string) { // 查询索引 head, prev, value, count := "", "", kit.Dict(), 0 - m.Richs(STORY, HEAD, name, func(key string, val map[string]interface{}) { + m.Richs(STORY, HEAD, name, func(key string, val ice.Map) { head, prev, value, count = key, kit.Format(val[LIST]), val, kit.Int(val[mdb.COUNT]) m.Logs("info", HEAD, head, PREV, prev, mdb.COUNT, count) }) @@ -192,7 +192,7 @@ func init() { case PULL: list := m.Cmd(STORY, INDEX, m.Option("begin")).Append("list") for i := 0; i < 10 && list != "" && list != m.Option("end"); i++ { - if m.Richs(STORY, nil, list, func(key string, value map[string]interface{}) { + if m.Richs(STORY, nil, list, func(key string, value ice.Map) { // 节点信息 m.Push("list", key) m.Push("node", kit.Format(value)) @@ -212,7 +212,7 @@ func init() { m.Conf(CACHE, kit.Keys("hash", m.Option("data")), kit.UnMarshal(m.Option("save"))) } - node := kit.UnMarshal(m.Option("node")).(map[string]interface{}) + node := kit.UnMarshal(m.Option("node")).(ice.Map) if m.Richs(STORY, nil, m.Option("list"), nil) == nil { // 导入节点 m.Log(ice.LOG_IMPORT, "%v: %v", m.Option("list"), m.Option("node")) @@ -252,13 +252,13 @@ func _story_pull(m *ice.Message, arg ...string) { // 起止节点 prev, begin, end := "", arg[3], "" repos := kit.Keys("remote", arg[2], arg[3]) - m.Richs(STORY, "head", arg[1], func(key string, val map[string]interface{}) { + m.Richs(STORY, "head", arg[1], func(key string, val ice.Map) { end = kit.Format(kit.Value(val, kit.Keys(repos, "pull", "list"))) prev = kit.Format(val["list"]) }) pull := end - var first map[string]interface{} + var first ice.Map for begin != "" && begin != end { if m.Cmd(SPIDE, arg[2], "msg", "/story/pull", "begin", begin, "end", end).Table(func(index int, value map[string]string, head []string) { if m.Richs(CACHE, nil, value["data"], nil) == nil { @@ -272,7 +272,7 @@ func _story_pull(m *ice.Message, arg ...string) { } } - node := kit.UnMarshal(value["node"]).(map[string]interface{}) + node := kit.UnMarshal(value["node"]).(ice.Map) if m.Richs(STORY, nil, value["list"], nil) == nil { // 导入节点 m.Log(ice.LOG_IMPORT, "%v: %v", value["list"], value["node"]) @@ -290,7 +290,7 @@ func _story_pull(m *ice.Message, arg ...string) { } pull, first = kit.Format(value["list"]), node - m.Richs(STORY, "head", arg[1], func(key string, val map[string]interface{}) { + m.Richs(STORY, "head", arg[1], func(key string, val ice.Map) { prev = kit.Format(val["list"]) if kit.Int(node["count"]) > kit.Int(kit.Value(val, kit.Keys(repos, "pull", "count"))) { // 更新分支 @@ -305,7 +305,7 @@ func _story_pull(m *ice.Message, arg ...string) { if prev == kit.Format(node["prev"]) || prev == kit.Format(node["push"]) { // 快速合并 m.Log(ice.LOG_IMPORT, "%v: %v", pull, arg[2]) - m.Richs(STORY, "head", arg[1], func(key string, val map[string]interface{}) { + m.Richs(STORY, "head", arg[1], func(key string, val ice.Map) { val["count"] = first["count"] val["time"] = first["time"] val["list"] = pull @@ -327,7 +327,7 @@ func _story_push(m *ice.Message, arg ...string) { repos := kit.Keys("remote", arg[2], arg[3]) // 查询索引 prev, pull, some, list := "", "", "", "" - m.Richs(STORY, "head", arg[1], func(key string, val map[string]interface{}) { + m.Richs(STORY, "head", arg[1], func(key string, val ice.Map) { prev = kit.Format(val["list"]) pull = kit.Format(kit.Value(val, kit.Keys(repos, "pull", "list"))) for some = pull; prev != some && some != ""; { @@ -362,14 +362,14 @@ func _story_push(m *ice.Message, arg ...string) { // 查询节点 nodes := []string{} for list = prev; list != some; { - m.Richs(STORY, nil, list, func(key string, value map[string]interface{}) { + m.Richs(STORY, nil, list, func(key string, value ice.Map) { nodes, list = append(nodes, list), kit.Format(value["prev"]) }) } for _, v := range kit.Revert(nodes) { - m.Richs(STORY, nil, v, func(list string, node map[string]interface{}) { - m.Richs(CACHE, nil, node["data"], func(data string, save map[string]interface{}) { + m.Richs(STORY, nil, v, func(list string, node ice.Map) { + m.Richs(CACHE, nil, node["data"], func(data string, save ice.Map) { if kit.Format(save["file"]) != "" { // 推送缓存 m.Cmd(SPIDE, arg[2], "/story/upload", @@ -394,8 +394,8 @@ func _story_push(m *ice.Message, arg ...string) { } func _story_commit(m *ice.Message, arg ...string) { // 查询索引 - head, prev, value, count := "", "", map[string]interface{}{}, 0 - m.Richs(STORY, "head", arg[1], func(key string, val map[string]interface{}) { + head, prev, value, count := "", "", ice.Map{}, 0 + m.Richs(STORY, "head", arg[1], func(key string, val ice.Map) { head, prev, value, count = key, kit.Format(val["list"]), val, kit.Int(val["count"]) m.Log("info", "head: %v prev: %v count: %v", head, prev, count) }) diff --git a/base/web/web.go b/base/web/web.go index 1551b2c4..eaabd428 100644 --- a/base/web/web.go +++ b/base/web/web.go @@ -94,6 +94,8 @@ func (web *Frame) Close(m *ice.Message, arg ...string) bool { return m.Done(true) } +func P(arg ...string) string { return path.Join(ice.PS, path.Join(arg...)) } + const ( SERVE_START = "serve.start" SERVE_STOP = "serve.stop" diff --git a/base/yac/matrix.go b/base/yac/matrix.go index 4e00e926..6e5b7416 100644 --- a/base/yac/matrix.go +++ b/base/yac/matrix.go @@ -310,11 +310,11 @@ func (mat *Matrix) show(m *ice.Message) { } func _yac_load(m *ice.Message) { - m.Richs(m.PrefixKey(), "", mdb.FOREACH, func(key string, value map[string]interface{}) { + m.Richs(m.PrefixKey(), "", mdb.FOREACH, func(key string, value ice.Map) { value = kit.GetMeta(value) mat := NewMatrix(m, kit.Int(kit.Select("32", value[NLANG])), kit.Int(kit.Select("32", value[NCELL]))) - m.Grows(m.PrefixKey(), kit.Keys(mdb.HASH, key), "", "", func(index int, value map[string]interface{}) { + m.Grows(m.PrefixKey(), kit.Keys(mdb.HASH, key), "", "", func(index int, value ice.Map) { page := mat.index(m, NPAGE, kit.Format(value[NPAGE])) hash := mat.index(m, NHASH, kit.Format(value[NHASH])) if mat.mat[page] == nil { @@ -362,7 +362,7 @@ func init() { m.Echo(h) }}, mdb.INSERT: {Name: "insert name=shy npage=num nhash=num text=123", Help: "添加", Hand: func(m *ice.Message, arg ...string) { - m.Richs(m.PrefixKey(), "", m.Option(mdb.NAME), func(key string, value map[string]interface{}) { + m.Richs(m.PrefixKey(), "", m.Option(mdb.NAME), func(key string, value ice.Map) { value = kit.GetMeta(value) mat, _ := value[MATRIX].(*Matrix) @@ -388,7 +388,7 @@ func init() { m.Cmdy(mdb.DELETE, m.PrefixKey(), "", mdb.HASH, mdb.NAME, m.Option(mdb.NAME)) }}, PARSE: {Name: "parse name npage text=123", Help: "解析", Hand: func(m *ice.Message, arg ...string) { - m.Richs(m.PrefixKey(), "", m.Option(mdb.NAME), func(key string, value map[string]interface{}) { + m.Richs(m.PrefixKey(), "", m.Option(mdb.NAME), func(key string, value ice.Map) { value = kit.GetMeta(value) mat, _ := value[MATRIX].(*Matrix) @@ -409,7 +409,7 @@ func init() { m.ProcessInner() }}, "show": {Name: "show", Help: "矩阵", Hand: func(m *ice.Message, arg ...string) { - m.Richs(m.PrefixKey(), "", kit.Select(m.Option(mdb.NAME), arg, 0), func(key string, value map[string]interface{}) { + m.Richs(m.PrefixKey(), "", kit.Select(m.Option(mdb.NAME), arg, 0), func(key string, value ice.Map) { value = kit.GetMeta(value) value[MATRIX].(*Matrix).show(m) }) @@ -432,7 +432,7 @@ func init() { } // 词法矩阵 - m.Richs(m.PrefixKey(), "", arg[0], func(key string, value map[string]interface{}) { + m.Richs(m.PrefixKey(), "", arg[0], func(key string, value ice.Map) { value = kit.GetMeta(value) value[MATRIX].(*Matrix).show(m) }) diff --git a/base/yac/script.go b/base/yac/script.go index 56565427..a49e747a 100644 --- a/base/yac/script.go +++ b/base/yac/script.go @@ -64,7 +64,7 @@ func (s *stack) let(key, value string) string { } return "" } -func (s *stack) echo(arg ...interface{}) { +func (s *stack) echo(arg ...ice.Any) { s.res = append(s.res, kit.Simple(arg...)...) } diff --git a/conf.go b/conf.go index 955b2978..9dc70bff 100644 --- a/conf.go +++ b/conf.go @@ -132,7 +132,6 @@ const ( // DIR VAR_FILE = "var/file" VAR_PROXY = "var/proxy" VAR_TRASH = "var/trash" - BIN_ICE_SH = "bin/ice.sh" BIN_ICE_BIN = "bin/ice.bin" BIN_BOOT_LOG = "bin/boot.log" ETC_INIT_SHY = "etc/init.shy" @@ -207,6 +206,8 @@ const ( // MSG const ( // RENDER RENDER_RAW = "_raw" RENDER_VOID = "_void" + RENDER_JSON = "_json" + RENDER_STATUS = "_status" RENDER_RESULT = "_result" RENDER_ANCHOR = "_anchor" RENDER_BUTTON = "_button" @@ -348,3 +349,18 @@ const ( // mdb NAME = "name" TEXT = "text" ) +const ( // ssh + SOURCE = "source" +) +const ( // gdb + EVENT = "event" + LISTEN = "listen" + HAPPEN = "happen" + FILELINE = "fileline" +) +const ( // aaa + ROLE = "role" + RIGHT = "right" + USERROLE = "userrole" + ROOT = "root" +) diff --git a/core/chat/action.go b/core/chat/action.go index dd09bb6c..04046218 100644 --- a/core/chat/action.go +++ b/core/chat/action.go @@ -14,7 +14,7 @@ import ( func _action_right(m *ice.Message, river string, storm string) (ok bool) { if ok = true; m.Option(ice.MSG_USERROLE) == aaa.VOID { - m.Richs(RIVER, "", river, func(key string, value map[string]interface{}) { + m.Richs(RIVER, "", river, func(key string, value ice.Map) { if ok = m.Richs(RIVER, kit.Keys(mdb.HASH, key, OCEAN), m.Option(ice.MSG_USERNAME), nil) != nil; ok { m.Log_AUTH(RIVER, river, STORM, storm) } @@ -35,7 +35,7 @@ func _action_exec(m *ice.Message, river, storm, index string, arg ...string) { m.Option(ice.MSG_STORM, storm) cmds := []string{index} - if m.Grows(RIVER, _action_key(m, river, storm), mdb.ID, index, func(index int, value map[string]interface{}) { + if m.Grows(RIVER, _action_key(m, river, storm), mdb.ID, index, func(index int, value ice.Map) { if cmds = kit.Simple(kit.Keys(value[ice.CTX], value[ice.CMD])); kit.Format(value[ice.POD]) != "" { m.Option(ice.POD, value[ice.POD]) // 远程节点 } @@ -115,12 +115,12 @@ func _action_domain(m *ice.Message, cmd string, arg ...string) (domain string) { river := kit.Select(m.Option(ice.MSG_RIVER), arg, 0) storm := kit.Select(m.Option(ice.MSG_STORM), arg, 1) - m.Richs(RIVER, "", river, func(key string, value map[string]interface{}) { + m.Richs(RIVER, "", river, func(key string, value ice.Map) { switch kit.Value(kit.GetMeta(value), mdb.TYPE) { case PUBLIC: // 公有群 return case PROTECTED: // 共有群 - m.Richs(RIVER, kit.Keys(mdb.HASH, river, STORM), storm, func(key string, value map[string]interface{}) { + m.Richs(RIVER, kit.Keys(mdb.HASH, river, STORM), storm, func(key string, value ice.Map) { switch r := "R" + river; kit.Value(kit.GetMeta(value), mdb.TYPE) { case PUBLIC: // 公有组 domain = m.Option(ice.MSG_DOMAIN, kit.Keys(r)) diff --git a/core/chat/div.go b/core/chat/div.go index 4d73095a..93f59b0f 100644 --- a/core/chat/div.go +++ b/core/chat/div.go @@ -14,7 +14,7 @@ import ( func _div_parse(m *ice.Message, text string) string { m.Option(nfs.CAT_CONTENT, text) - return m.Cmdx(lex.SPLIT, "", "index", "args", func(ls []string, meta map[string]interface{}) []string { + return m.Cmdx(lex.SPLIT, "", "index", "args", func(ls []string, meta ice.Map) []string { if ls[0] == "div" { ls = append([]string{"", "", "style", kit.Select("div", ls, 1)}, kit.Slice(ls, 2)...) } diff --git a/core/chat/header.go b/core/chat/header.go index ad0a39d3..39ffe436 100644 --- a/core/chat/header.go +++ b/core/chat/header.go @@ -124,7 +124,7 @@ func init() { }}, ctx.CONFIG: {Name: "config scope", Help: "配置", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(web.SPACE, m.Option(ice.MSG_USERPOD), m.Prefix(OAUTH), CHECK, arg) + m.Cmdy(web.SPACE, m.Option(ice.MSG_USERPOD), m.Prefix("oauth.oauth"), CHECK, arg) }}, code.PUBLISH: {Name: "publish", Help: "发布", Hand: func(m *ice.Message, arg ...string) { if !m.PodCmd(code.PUBLISH, ice.CONTEXTS) { diff --git a/core/chat/oauth.go b/core/chat/oauth.go deleted file mode 100644 index 7ae12636..00000000 --- a/core/chat/oauth.go +++ /dev/null @@ -1,68 +0,0 @@ -package chat - -import ( - ice "shylinux.com/x/icebergs" - "shylinux.com/x/icebergs/base/aaa" - "shylinux.com/x/icebergs/base/cli" - "shylinux.com/x/icebergs/base/ctx" - "shylinux.com/x/icebergs/base/mdb" - "shylinux.com/x/icebergs/base/nfs" - "shylinux.com/x/icebergs/base/ssh" - "shylinux.com/x/icebergs/base/web" - kit "shylinux.com/x/toolkits" -) - -const OAUTH = "oauth" - -func init() { - const ( - CHECK = "check" - APPLY = "apply" - REPLY = "reply" - OFFER = "offer" - - OAUTH_APPLY = "/oauth/apply" - OAUTH_REPLY = "/oauth/reply" - OAUTH_OFFER = "/oauth/offer" - ) - const ( - SCOPE = "scope" - REDIRECT_URI = "redirect_uri" - ACCESS_TOKEN = "access_token" - EXPIRES = "expires" - ) - Index.Merge(&ice.Context{Commands: map[string]*ice.Command{ - OAUTH: {Name: "oauth hash auto prunes", Help: "授权", Action: ice.MergeAction(map[string]*ice.Action{ - ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { - m.Cmd(aaa.ROLE, aaa.WHITE, aaa.VOID, m.Prefix(OAUTH_APPLY)) - m.Cmd(aaa.ROLE, aaa.WHITE, aaa.VOID, m.Prefix(OAUTH_OFFER)) - }}, - CHECK: {Name: "check scope", Help: "检查", Hand: func(m *ice.Message, arg ...string) { - m.Echo(kit.MergeURL(m.Cmdx(cli.RUNTIME, cli.MAKE_DOMAIN)+OAUTH_APPLY, m.OptionSimple(SCOPE), REDIRECT_URI, - kit.Select(m.MergePodURL(OAUTH_REPLY), m.MergeLink("/chat/"+OAUTH_REPLY), m.Option(ice.MSG_USERPOD) == ""))) - }}, - APPLY: {Name: "apply redirect_uri", Help: "申请", Hand: func(m *ice.Message, arg ...string) { - if m.Right(m.Option(SCOPE)) { - token := mdb.HashCreate(m, mdb.TIME, m.Time(m.Config(EXPIRES)), aaa.USERNAME, m.Option(ice.MSG_USERNAME), m.OptionSimple(SCOPE, REDIRECT_URI)).Result() - m.ProcessReplace(kit.MergeURL(m.Option(REDIRECT_URI), OFFER, m.MergePodURL(OAUTH_OFFER, ACCESS_TOKEN, token))) - } - }}, - REPLY: {Name: "reply offer", Help: "通过", Hand: func(m *ice.Message, arg ...string) { - m.Option(web.SPIDE_HEADER, web.UserAgent, m.PrefixKey()) - m.Cmd(ssh.SOURCE, ice.ETC_LOCAL_SHY, kit.Dict(nfs.CAT_CONTENT, m.Cmdx(web.SPIDE, ice.DEV, web.SPIDE_GET, m.Option(OFFER)))) - m.ProcessHistory() - }}, - }, mdb.HashAction(mdb.SHORT, mdb.UNIQ, EXPIRES, "720h"), ctx.CmdAction())}, - OAUTH_APPLY: {Name: "/oauth/apply", Help: "授权申请", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.RenderCmd(m.Prefix(OAUTH), APPLY) - }}, - OAUTH_REPLY: {Name: "/oauth/reply", Help: "授权通过", Action: ctx.CmdAction(), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.RenderCmd(m.Prefix(OAUTH), REPLY) - }}, - OAUTH_OFFER: {Name: "/oauth/offer", Help: "授权资源", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - if msg := m.Cmd(OAUTH, m.Option(ACCESS_TOKEN), ice.OptionFields("time,scope")); kit.Time(msg.Time()) < kit.Time(msg.Append(mdb.TIME)) { - aaa.UserRoot(m).Cmdy(nfs.CAT, msg.Append(SCOPE)).RenderResult() - } - }}, - }}) -} diff --git a/core/chat/oauth/oauth.go b/core/chat/oauth/oauth.go new file mode 100644 index 00000000..c83a97e7 --- /dev/null +++ b/core/chat/oauth/oauth.go @@ -0,0 +1,169 @@ +package chat + +import ( + "strings" + "time" + + ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/aaa" + "shylinux.com/x/icebergs/base/ctx" + "shylinux.com/x/icebergs/base/mdb" + "shylinux.com/x/icebergs/base/nfs" + "shylinux.com/x/icebergs/base/ssh" + "shylinux.com/x/icebergs/base/web" + "shylinux.com/x/icebergs/core/chat" + kit "shylinux.com/x/toolkits" +) + +func _merge_url(m *ice.Message, domain, key string, arg ...ice.Any) string { + if domain == "" { + if m.Option(ice.MSG_USERPOD) == "" { + domain = m.MergeLink(ice.PS) + } else { + domain = m.MergeLink("/chat/pod/" + m.Option(ice.MSG_USERPOD)) + } + } + if domain = strings.TrimSuffix(domain, ice.PS); strings.Contains(domain, "/chat/pod/") { + domain += web.P(strings.TrimPrefix(m.Prefix(web.P(key)), "web.chat.")) + } else { + domain += m.RoutePath(key) + } + return kit.MergeURL(domain, arg...) +} + +const ( + CHECK = "check" + APPLY = "apply" + REPLY = "reply" + OFFER = "offer" +) +const ( + ACCESS_TOKEN = "access_token" + TOKEN_TYPE = "token_type" + EXPIRES_IN = "expires_in" + CODE = "code" + STATE = "state" + SCOPE = "scope" + CLIENT_ID = "client_id" + REDIRECT_URI = "redirect_uri" +) +const ( + AUTHORIZE = "authorize" + TOKEN = "token" + ACCESS = "access" + USERINFO = "userinfo" +) +const OAUTH = "oauth" + +var Index = &ice.Context{Name: OAUTH, Help: "认证授权", Commands: map[string]*ice.Command{ + OAUTH: {Name: "oauth hash auto prunes", Help: "权限", Action: ice.MergeAction(map[string]*ice.Action{ + CHECK: {Name: "check scope domain", Help: "检查", Hand: func(m *ice.Message, arg ...string) { + m.Echo(_merge_url(m, kit.Select(ice.Info.Make.Domain, m.Option(web.DOMAIN)), APPLY, m.OptionSimple(SCOPE), REDIRECT_URI, _merge_url(m, "", REPLY))) + }}, + APPLY: {Name: "apply scope redirect_uri", Help: "申请", Hand: func(m *ice.Message, arg ...string) { + if m.Right(m.Option(SCOPE)) { + token := m.Cmdx(OFFER, mdb.CREATE, aaa.USERNAME, m.Option(ice.MSG_USERNAME), m.OptionSimple(SCOPE, REDIRECT_URI)) + m.ProcessReplace(m.Option(REDIRECT_URI), m.OptionSimple(SCOPE), OFFER, _merge_url(m, "", OFFER, ACCESS_TOKEN, token)) + } else { + m.Cmdy(APPLY, mdb.CREATE, aaa.USERNAME, m.Option(ice.MSG_USERNAME), m.OptionSimple(SCOPE, REDIRECT_URI)) + } + }}, + REPLY: {Name: "reply scope offer", Help: "通过", Hand: func(m *ice.Message, arg ...string) { + m.Cmd(REPLY, mdb.CREATE, aaa.USERNAME, m.Option(ice.MSG_USERNAME), m.OptionSimple(SCOPE, OFFER)) + + m.Option(web.SPIDE_HEADER, web.UserAgent, m.PrefixKey()) + m.Cmd(ssh.SOURCE, m.Option(SCOPE), kit.Dict(nfs.CAT_CONTENT, m.Cmdx(web.SPIDE, ice.DEV, web.SPIDE_GET, m.Option(OFFER)))) + m.ProcessHistory() + }}, + })}, + + APPLY: {Name: "apply hash auto create prunes", Help: "申请", Action: mdb.HashAction(mdb.EXPIRE, "72h", mdb.FIELD, "time,hash,username,scope,redirect_uri")}, + REPLY: {Name: "reply hash auto create prunes", Help: "授权", Action: mdb.HashAction(mdb.EXPIRE, "720h", mdb.SHORT, mdb.UNIQ, mdb.FIELD, "time,hash,username,scope,offer")}, + OFFER: {Name: "offer hash auto create prunes", Help: "访问", Action: mdb.HashAction(mdb.EXPIRE, "720h", mdb.SHORT, mdb.UNIQ, mdb.FIELD, "time,hash,username,scope,redirect_uri")}, + + web.P(APPLY): {Name: "/apply scope redirect_uri", Help: "申请", Action: ctx.CmdAction(), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if m.Option(REDIRECT_URI) == "" { + m.RenderStatusBadRequest() // 参数错误 + + } else { // 申请 + m.RenderCmd(m.Prefix(OAUTH), APPLY) + } + }}, + web.P(REPLY): {Name: "/reply scope offer", Help: "授权", Action: ctx.CmdAction(), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if m.Option(OFFER) == "" { + m.RenderStatusBadRequest() // 参数错误 + + } else { // 授权 + m.RenderCmd(m.Prefix(OAUTH), REPLY) + } + }}, + web.P(OFFER): {Name: "/offer access_token", Help: "访问", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if m.Option(ACCESS_TOKEN) == "" { + m.RenderStatusBadRequest() // 参数错误 + + } else if msg := m.Cmd(OFFER, m.Option(ACCESS_TOKEN), ice.OptionFields("time,scope")); kit.Time(msg.Append(mdb.TIME)) < kit.Time(msg.Time()) { + m.RenderStatusUnauthorized() // 已过期 + + } else { // 访问 + aaa.UserRoot(m).Cmdy(nfs.CAT, msg.Append(SCOPE)).RenderResult() + } + }}, + + AUTHORIZE: {Name: "authorize hash auto create prunes", Help: "认证", Action: mdb.HashAction(mdb.SHORT, mdb.UNIQ, mdb.FIELD, "time,hash,redirect_uri")}, + TOKEN: {Name: "token hash auto create prunes", Help: "授权", Action: mdb.HashAction(mdb.EXPIRE, "72h", mdb.FIELD, "time,hash,used,state,scope,redirect_uri")}, + ACCESS: {Name: "access hash auto create prunes", Help: "访问", Action: mdb.HashAction(mdb.EXPIRE, "720h", mdb.SHORT, mdb.UNIQ, mdb.FIELD, "time,hash,username,scope,redirect_uri")}, + + web.P(AUTHORIZE): {Name: "/authorize state scope client_id redirect_uri", Help: "认证", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if m.Option(CLIENT_ID) == "" || m.Option(REDIRECT_URI) == "" { + m.RenderStatusBadRequest() // 参数错误 + + } else if uri := m.Cmd(AUTHORIZE, m.Option(CLIENT_ID)).Append(REDIRECT_URI); m.Warn(uri == "", ice.ErrNotFound, CLIENT_ID) { + m.RenderStatusNotFound() // 未找到 + + } else if m.Warn(!strings.HasPrefix(m.Option(REDIRECT_URI), uri), ice.ErrNotRight, REDIRECT_URI) { + m.RenderStatusForbidden() // 未匹配 + + } else { // 认证 + m.RenderRedirect(m.Option(REDIRECT_URI), CODE, m.Cmdx(TOKEN, mdb.CREATE, m.OptionSimple(STATE, SCOPE, REDIRECT_URI)), m.OptionSimple(STATE)) + } + }}, + web.P(TOKEN): {Name: "/token code redirect_uri", Help: "授权", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if m.Option(CODE) == "" || m.Option(REDIRECT_URI) == "" { + m.RenderStatusBadRequest() // 参数错误 + return + } + + const USED = "used" + msg := m.Cmd(TOKEN, m.Option(CODE)) + if uri := msg.Append(REDIRECT_URI); m.Warn(uri == "", ice.ErrNotFound, CODE) { + m.RenderStatusNotFound() // 未找到 + + } else if m.Warn(!strings.HasPrefix(m.Option(REDIRECT_URI), uri), ice.ErrNotRight, REDIRECT_URI) { + m.RenderStatusForbidden() // 未匹配 + + } else if m.Warn(msg.Append(USED) == ice.TRUE, ice.ErrNotRight, CODE) { + m.RenderStatusForbidden() // 已使用 + + } else if kit.Time(msg.Append(mdb.TIME)) < kit.Time(m.Time()) { + m.RenderStatusUnauthorized() // 已过期 + + } else { // 授权 + token := m.Cmdx(ACCESS, mdb.CREATE, aaa.USERNAME, m.Option(ice.MSG_USERNAME), msg.AppendSimple(SCOPE, REDIRECT_URI)) + m.RenderJson(ACCESS_TOKEN, token, TOKEN_TYPE, web.Bearer, EXPIRES_IN, kit.Duration(m.Conf(ACCESS, kit.Keym(mdb.EXPIRE)))/time.Second) + m.Cmdx(TOKEN, mdb.MODIFY, mdb.HASH, m.Option(CODE), USED, ice.TRUE) + } + }}, + web.P(USERINFO): {Name: "/userinfo Authorization", Help: "信息", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if ls := strings.SplitN(m.R.Header.Get(web.Authorization), ice.SP, 2); m.Warn(len(ls) != 2 || ls[1] == "", ice.ErrNotFound, web.Bearer) { + m.RenderStatusBadRequest() // 参数错误 + + } else if msg := m.Cmd(ACCESS, ls[1]); kit.Time(msg.Append(mdb.TIME)) < kit.Time(m.Time()) { + m.RenderStatusUnauthorized() // 已过期 + + } else { // 访问 + m.RenderJson(mdb.NAME, msg.Append(aaa.USERNAME), aaa.EMAIL, msg.Append(aaa.USERNAME)) + } + }}, +}} + +func init() { chat.Index.Register(Index, &web.Frame{}) } diff --git a/core/chat/oauth/oauth.shy b/core/chat/oauth/oauth.shy new file mode 100644 index 00000000..5e84cb19 --- /dev/null +++ b/core/chat/oauth/oauth.shy @@ -0,0 +1,18 @@ +section "oauth" +refer ` +官网 https://oauth.net/2/ +标准 http://www.rfcreader.com/#rfc6749 +博客 https://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html +服务 https://developers.google.com/identity/protocols/oauth2 +服务 https://docs.github.com/cn/developers/apps/building-oauth-apps/authorizing-oauth-apps +应用 https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-authentication/github/ +` + +field web.chat.oauth.apply +field web.chat.oauth.reply +field web.chat.oauth.offer + +field web.chat.oauth.authorize +field web.chat.oauth.token +field web.chat.oauth.access + diff --git a/core/chat/pod.go b/core/chat/pod.go index 1554dfbb..7857a4aa 100644 --- a/core/chat/pod.go +++ b/core/chat/pod.go @@ -49,7 +49,9 @@ func init() { } else if arg[1] == "cmd" { // 节点命令 m.Cmdy(web.SPACE, arg[0], m.Prefix(CMD), path.Join(arg[2:]...)) } else { - m.Cmdy(web.SPACE, m.Option(ice.MSG_USERPOD), "web.chat."+ice.PS+path.Join(arg[1:]...)) + m.Debug("what %v", path.Join(arg[1:]...)) + m.Cmdy(web.SPACE, m.Option(ice.MSG_USERPOD), "web.chat."+strings.TrimPrefix(path.Join(arg[1:]...), "chat/")) + // m.Cmdy(web.SPACE, m.Option(ice.MSG_USERPOD), "web.chat."+ice.PS+path.Join(arg[1:]...)) } }}, }}) diff --git a/core/chat/river.go b/core/chat/river.go index b5b52d9c..fb6a6051 100644 --- a/core/chat/river.go +++ b/core/chat/river.go @@ -12,7 +12,7 @@ import ( kit "shylinux.com/x/toolkits" ) -func _river_key(m *ice.Message, key ...interface{}) string { +func _river_key(m *ice.Message, key ...ice.Any) string { return kit.Keys(mdb.HASH, m.Option(ice.MSG_RIVER), kit.Simple(key)) } func _river_list(m *ice.Message) { @@ -43,8 +43,8 @@ func _river_list(m *ice.Message) { } } - m.Richs(RIVER, nil, mdb.FOREACH, func(key string, value map[string]interface{}) { - m.Richs(RIVER, kit.Keys(mdb.HASH, key, OCEAN), m.Option(ice.MSG_USERNAME), func(k string, val map[string]interface{}) { + m.Richs(RIVER, nil, mdb.FOREACH, func(key string, value ice.Map) { + m.Richs(RIVER, kit.Keys(mdb.HASH, key, OCEAN), m.Option(ice.MSG_USERNAME), func(k string, val ice.Map) { m.Push(key, kit.GetMeta(value), []string{mdb.HASH, mdb.NAME}, kit.GetMeta(val)) }) }) @@ -152,7 +152,7 @@ func init() { m.Conf(RIVER, kit.Keys(mdb.HASH, h, OCEAN, kit.Keym(mdb.SHORT)), aaa.USERNAME) m.Cmd(OCEAN, mdb.INSERT, aaa.USERNAME, m.Option(ice.MSG_USERNAME)) - kit.Fetch(m.Confv(RIVER, kit.Keym(nfs.TEMPLATE, kit.Select("base", m.Option(nfs.TEMPLATE)))), func(storm string, value interface{}) { + kit.Fetch(m.Confv(RIVER, kit.Keym(nfs.TEMPLATE, kit.Select("base", m.Option(nfs.TEMPLATE)))), func(storm string, value ice.Any) { h := m.Cmdx(STORM, mdb.CREATE, mdb.TYPE, PUBLIC, mdb.NAME, storm, mdb.TEXT, storm) kit.Fetch(value, func(index int, value string) { diff --git a/core/chat/search.go b/core/chat/search.go index 10f8199f..64e750f6 100644 --- a/core/chat/search.go +++ b/core/chat/search.go @@ -15,7 +15,7 @@ func init() { }, Commands: map[string]*ice.Command{ "/search": {Name: "/search", Help: "搜索引擎", Action: ice.MergeAction(map[string]*ice.Action{ mdb.SEARCH: {Name: "search type name text", Help: "搜索", Hand: func(m *ice.Message, arg ...string) { - m.Richs("/search", "", mdb.FOREACH, func(key string, value map[string]interface{}) { + m.Richs("/search", "", mdb.FOREACH, func(key string, value ice.Map) { if value = kit.GetMeta(value); arg[1] != "" && !kit.Contains(value[mdb.NAME], arg[1]) { return } diff --git a/core/chat/storm.go b/core/chat/storm.go index 26aa9460..cbc29283 100644 --- a/core/chat/storm.go +++ b/core/chat/storm.go @@ -7,7 +7,7 @@ import ( kit "shylinux.com/x/toolkits" ) -func _storm_key(m *ice.Message, key ...interface{}) string { +func _storm_key(m *ice.Message, key ...ice.Any) string { return _river_key(m, STORM, mdb.HASH, kit.Keys(key)) } diff --git a/core/chat/website.go b/core/chat/website.go index 398835f0..9d4303c5 100644 --- a/core/chat/website.go +++ b/core/chat/website.go @@ -22,7 +22,7 @@ func _website_url(m *ice.Message, file string) string { } return strings.Split(kit.MergeURL2(m.Option(ice.MSG_USERWEB), path.Join("/chat", p)), "?")[0] } -func _website_parse(m *ice.Message, text string, args ...string) (map[string]interface{}, bool) { +func _website_parse(m *ice.Message, text string, args ...string) (ice.Map, bool) { if text == "" { return nil, false } @@ -37,7 +37,7 @@ func _website_parse(m *ice.Message, text string, args ...string) (map[string]int nriver := 0 nstorm := 0 - m.Cmd(lex.SPLIT, "", mdb.KEY, mdb.NAME, func(deep int, ls []string, meta map[string]interface{}) []string { + m.Cmd(lex.SPLIT, "", mdb.KEY, mdb.NAME, func(deep int, ls []string, meta ice.Map) []string { if deep == 1 { switch ls[0] { case "header": @@ -71,7 +71,7 @@ func _website_parse(m *ice.Message, text string, args ...string) (map[string]int fallthrough case "-": for _, v := range ls[1:] { - last[mdb.LIST] = append(last[mdb.LIST].([]interface{}), kit.Dict(mdb.INDEX, kit.Keys(prefix, v), "order", len(last))) + last[mdb.LIST] = append(last[mdb.LIST].([]ice.Any), kit.Dict(mdb.INDEX, kit.Keys(prefix, v), "order", len(last))) } return ls } @@ -118,7 +118,7 @@ func _website_parse(m *ice.Message, text string, args ...string) (map[string]int storm[ls[0]] = last prefix = "" default: - last[mdb.LIST] = append(last[mdb.LIST].([]interface{}), + last[mdb.LIST] = append(last[mdb.LIST].([]ice.Any), kit.Dict(mdb.NAME, kit.Select(ls[0], data[mdb.NAME]), mdb.HELP, ls[1], mdb.INDEX, ls[0], "order", len(last), data)) } return ls @@ -152,7 +152,7 @@ func _website_render(m *ice.Message, w http.ResponseWriter, r *http.Request, kin default: msg.RenderDownload(text) } - web.Render(msg, msg.Option(ice.MSG_OUTPUT), msg.Optionv(ice.MSG_ARGS).([]interface{})...) + web.Render(msg, msg.Option(ice.MSG_OUTPUT), msg.Optionv(ice.MSG_ARGS).([]ice.Any)...) return true } func _website_search(m *ice.Message, kind, name, text string, arg ...string) { @@ -183,7 +183,7 @@ func init() { if r.Method != http.MethodGet { return false } - if ok := true; m.Richs(WEBSITE, nil, r.URL.Path, func(key string, value map[string]interface{}) { + if ok := true; m.Richs(WEBSITE, nil, r.URL.Path, func(key string, value ice.Map) { value = kit.GetMeta(value) ok = _website_render(m, w, r, kit.Format(value[mdb.TYPE]), kit.Format(value[mdb.TEXT])) }) != nil && ok { diff --git a/core/code/autogen.go b/core/code/autogen.go index c4ebebde..4e91d016 100644 --- a/core/code/autogen.go +++ b/core/code/autogen.go @@ -115,7 +115,7 @@ go 1.11 return } -func _autogen_git(m *ice.Message, arg ...string) map[string]interface{} { +func _autogen_git(m *ice.Message, arg ...string) ice.Map { return kit.Dict("Path", kit.Path(""), "Time", m.Time(), arg, "Hash", strings.TrimSpace(m.Cmdx(cli.SYSTEM, "git", "log", "-n1", `--pretty=%H`)), "Remote", strings.TrimSpace(m.Cmdx(cli.SYSTEM, "git", "config", "remote.origin.url")), @@ -126,7 +126,7 @@ func _autogen_git(m *ice.Message, arg ...string) map[string]interface{} { } func _autogen_gits(m *ice.Message, arg ...string) string { res := []string{} - kit.Fetch(_autogen_git(m, arg...), func(k string, v interface{}) { + kit.Fetch(_autogen_git(m, arg...), func(k string, v ice.Any) { res = append(res, kit.Format(` %s: "%s",`, k, v)) }) return kit.Join(res, ice.NL) diff --git a/core/code/inner.go b/core/code/inner.go index 2292ae4e..bb78a9cd 100644 --- a/core/code/inner.go +++ b/core/code/inner.go @@ -61,7 +61,7 @@ func _inner_make(m *ice.Message, msg *ice.Message) { func LoadPlug(m *ice.Message, language ...string) { for _, language := range language { m.Conf(nfs.CAT, kit.Keym(nfs.SOURCE, kit.Ext(language)), ice.TRUE) - m.Confm(language, kit.Keym(PLUG, PREPARE), func(key string, value interface{}) { + m.Confm(language, kit.Keym(PLUG, PREPARE), func(key string, value ice.Any) { for _, v := range kit.Simple(value) { m.Conf(language, kit.Keym(PLUG, KEYWORD, v), key) } diff --git a/core/code/install.go b/core/code/install.go index 7df4624d..27ca79ed 100644 --- a/core/code/install.go +++ b/core/code/install.go @@ -15,7 +15,11 @@ import ( ) func _install_path(m *ice.Message, link string) string { - return path.Join(ice.USR_INSTALL, kit.TrimExt(kit.Select(m.Option(mdb.LINK), link))) + link = kit.Select(m.Option(mdb.LINK), link) + if p := path.Join(ice.USR_INSTALL, kit.TrimExt(link)); kit.FileExists(p) { + return p + } + return path.Join(ice.USR_INSTALL, strings.Split(m.Cmdx(cli.SYSTEM, "sh", "-c", kit.Format("tar tf %s| head -n1", path.Join(ice.USR_INSTALL, path.Base(link)))), ice.PS)[0]) } func _install_download(m *ice.Message) { link := m.Option(mdb.LINK) @@ -34,7 +38,7 @@ func _install_download(m *ice.Message) { defer m.ToastSuccess() // 下载进度 - m.Richs(INSTALL, "", name, func(key string, value map[string]interface{}) { + m.Richs(INSTALL, "", name, func(key string, value ice.Map) { value = kit.GetMeta(value) m.OptionCB(web.SPIDE, func(count int, total int, step int) { value[mdb.COUNT], value[mdb.TOTAL], value[mdb.VALUE] = count, total, step @@ -112,6 +116,8 @@ func _install_start(m *ice.Message, arg ...string) { switch cb := m.Optionv(PREPARE).(type) { case func(string) []string: args = append(args, cb(p)...) + case func(string): + cb(p) } if m.Cmdy(cli.DAEMON, arg[1:], args); cli.IsSuccess(m) { @@ -196,7 +202,7 @@ func init() { }}) } -func InstallAction(args ...interface{}) map[string]*ice.Action { +func InstallAction(args ...ice.Any) map[string]*ice.Action { return ice.SelectAction(map[string]*ice.Action{ice.CTX_INIT: mdb.AutoConfig(args...), web.DOWNLOAD: {Name: "download", Help: "下载", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(INSTALL, web.DOWNLOAD, m.Config(nfs.SOURCE)) @@ -212,11 +218,11 @@ func InstallAction(args ...interface{}) map[string]*ice.Action { }}, }) } -func InstallSoftware(m *ice.Message, bin string, list interface{}) (ok bool) { +func InstallSoftware(m *ice.Message, bin string, list ice.Any) (ok bool) { if cli.SystemFind(m, bin) != "" { return true } - kit.Fetch(list, func(index int, value map[string]interface{}) { + kit.Fetch(list, func(index int, value ice.Map) { if strings.Contains(m.Cmdx(cli.RUNTIME, kit.Keys(tcp.HOST, cli.OSID)), kit.Format(value[cli.OSID])) { cli.PushStream(m) m.Cmd(cli.SYSTEM, value[ice.CMD]) diff --git a/core/code/template.go b/core/code/template.go index d14e5e26..ef6dd435 100644 --- a/core/code/template.go +++ b/core/code/template.go @@ -44,8 +44,8 @@ func init() { }) } -var _template_list = [][]interface{}{ - []interface{}{"", "txt", "网站索引", ` +var _template_list = [][]ice.Any{ + []ice.Any{"", "txt", "网站索引", ` hi hi cli.qrcode @@ -53,12 +53,12 @@ hi cli.runtime `}, - []interface{}{"", "js", "前端模块", `Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, cb, target) { + []ice.Any{"", "js", "前端模块", `Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, cb, target) { can.onmotion.clear(can) can.onappend.table(can, msg) can.onappend.board(can, msg) }})`}, - []interface{}{"", "go", "后端模块", `package {{.Option "zone"}} + []ice.Any{"", "go", "后端模块", `package {{.Option "zone"}} import ( "shylinux.com/x/ice" diff --git a/core/code/upgrade.go b/core/code/upgrade.go index ad84069c..21b2b5bb 100644 --- a/core/code/upgrade.go +++ b/core/code/upgrade.go @@ -28,7 +28,7 @@ func init() { m.Sleep("1s").Go(func() { m.Cmd(ice.EXIT, 1) }) }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Grows(cmd, kit.Keys(mdb.HASH, kit.Select(cli.SYSTEM, arg, 0)), "", "", func(index int, value map[string]interface{}) { + m.Grows(cmd, kit.Keys(mdb.HASH, kit.Select(cli.SYSTEM, arg, 0)), "", "", func(index int, value ice.Map) { if value[nfs.FILE] == ice.ICE_BIN { // 程序文件 value[nfs.FILE] = kit.Keys(ice.ICE, runtime.GOOS, runtime.GOARCH) defer m.Cmd(cli.SYSTEM, "mv", value[nfs.FILE], ice.BIN_ICE_BIN) diff --git a/core/core.go b/core/core.go index ceb9df2a..1e02af17 100644 --- a/core/core.go +++ b/core/core.go @@ -2,6 +2,7 @@ package shy import ( _ "shylinux.com/x/icebergs/core/chat" + _ "shylinux.com/x/icebergs/core/chat/oauth" _ "shylinux.com/x/icebergs/core/code" _ "shylinux.com/x/icebergs/core/mall" _ "shylinux.com/x/icebergs/core/team" diff --git a/core/mall/asset.go b/core/mall/asset.go index ebb4ce14..e2d3cce7 100644 --- a/core/mall/asset.go +++ b/core/mall/asset.go @@ -27,7 +27,7 @@ func _sub_amount(m *ice.Message, arg []string) { func _asset_check(m *ice.Message, account string) { amount := 0 - m.OptionCB(mdb.SELECT, func(key string, value map[string]interface{}) { + m.OptionCB(mdb.SELECT, func(key string, value ice.Map) { amount += kit.Int(kit.Value(value, AMOUNT)) }) m.Cmd(mdb.SELECT, m.PrefixKey(), "", mdb.ZONE, account, ice.OptionFields(m.Config(mdb.FIELD))) diff --git a/core/team/plan.go b/core/team/plan.go index 835b06e1..3a84468b 100644 --- a/core/team/plan.go +++ b/core/team/plan.go @@ -42,7 +42,7 @@ func _plan_scope(m *ice.Message, tz int, arg ...string) (time.Time, time.Time) { func _plan_list(m *ice.Message, begin_time, end_time time.Time) *ice.Message { m.Option(ice.CACHE_LIMIT, "100") m.Fields(0, "begin_time,close_time,zone,id,level,status,score,type,name,text,pod,extra") - m.OptionCB(mdb.SELECT, func(key string, fields []string, value, val map[string]interface{}) { + m.OptionCB(mdb.SELECT, func(key string, fields []string, value, val ice.Map) { begin, _ := time.ParseInLocation(ice.MOD_TIME, kit.Format(value[BEGIN_TIME]), time.Local) if begin_time.After(begin) || begin.After(end_time) { return diff --git a/core/team/task.go b/core/team/task.go index f0b2a6a0..327f944a 100644 --- a/core/team/task.go +++ b/core/team/task.go @@ -7,7 +7,7 @@ import ( kit "shylinux.com/x/toolkits" ) -func _task_action(m *ice.Message, status interface{}, action ...string) string { +func _task_action(m *ice.Message, status ice.Any, action ...string) string { switch status { case PREPARE: action = append(action, BEGIN) diff --git a/core/wiki/chart.go b/core/wiki/chart.go index 038dd365..be7e54a9 100644 --- a/core/wiki/chart.go +++ b/core/wiki/chart.go @@ -11,17 +11,17 @@ import ( type Item struct { list []string - args []interface{} + args []ice.Any } -func NewItem(list []string, args ...interface{}) *Item { +func NewItem(list []string, args ...ice.Any) *Item { return &Item{list, args} } -func (item *Item) Echo(str string, arg ...interface{}) *Item { +func (item *Item) Echo(str string, arg ...ice.Any) *Item { item.list = append(item.list, kit.Format(str, arg...)) return item } -func (item *Item) Push(str string, arg interface{}) *Item { +func (item *Item) Push(str string, arg ice.Any) *Item { switch arg := arg.(type) { case string: if arg == "" { @@ -57,7 +57,7 @@ func AddGroupOption(m *ice.Message, group string, arg ...string) { m.Option(kit.Keys(group, arg[i]), arg[i+1]) } } -func (g *Group) Option(group string, key string, arg ...interface{}) string { +func (g *Group) Option(group string, key string, arg ...ice.Any) string { return g.Get(group).Option(kit.Keys(group, key), arg...) } func (g *Group) Get(group string) *ice.Message { return g.list[group] } @@ -72,7 +72,7 @@ func (g *Group) Join(arg ...string) string { } return kit.Join(args, ice.SP) } -func (g *Group) Echo(group string, str string, arg ...interface{}) *ice.Message { +func (g *Group) Echo(group string, str string, arg ...ice.Any) *ice.Message { return g.Get(group).Echo(str, arg...) } func (g *Group) EchoRect(group string, height, width, x, y int, arg ...string) *ice.Message { // rx ry @@ -118,7 +118,7 @@ func (g *Group) Dump(m *ice.Message, group string, arg ...string) *Group { type Chart interface { Init(*ice.Message, ...string) Chart - Data(*ice.Message, interface{}) Chart + Data(*ice.Message, ice.Any) Chart Draw(*ice.Message, int, int) Chart GetHeight(...string) int diff --git a/core/wiki/chart/block.go b/core/wiki/chart/block.go index cf51eb44..199597d4 100644 --- a/core/wiki/chart/block.go +++ b/core/wiki/chart/block.go @@ -38,7 +38,7 @@ func (b *Block) Init(m *ice.Message, arg ...string) wiki.Chart { } return b } -func (b *Block) Data(m *ice.Message, meta interface{}) wiki.Chart { +func (b *Block) Data(m *ice.Message, meta ice.Any) wiki.Chart { b.Text = kit.Select(b.Text, kit.Value(meta, mdb.TEXT)) kit.Fetch(meta, func(key string, value string) { switch key { diff --git a/core/wiki/chart/chain.go b/core/wiki/chart/chain.go index 69a57f0b..78ba3b0a 100644 --- a/core/wiki/chart/chain.go +++ b/core/wiki/chart/chain.go @@ -11,7 +11,7 @@ import ( ) type Chain struct { - data map[string]interface{} + data ice.Map gs *wiki.Group Block } @@ -22,7 +22,7 @@ func (c *Chain) Init(m *ice.Message, arg ...string) wiki.Chart { m.Option(nfs.CAT_CONTENT, arg[0]) m.Option(lex.SPLIT_BLOCK, ice.SP) max, stack := 0, kit.List(kit.Dict("_deep", -1, "width", "0")) - m.OptionCB(lex.SPLIT, func(deep int, ls []string, data map[string]interface{}) []string { + m.OptionCB(lex.SPLIT, func(deep int, ls []string, data ice.Map) []string { for deep <= kit.Int(kit.Value(stack[len(stack)-1], "_deep")) { stack = stack[:len(stack)-1] } @@ -49,17 +49,17 @@ func (c *Chain) Draw(m *ice.Message, x, y int) wiki.Chart { return c } -func (c *Chain) size(m *ice.Message, root map[string]interface{}) (height int) { +func (c *Chain) size(m *ice.Message, root ice.Map) (height int) { meta := kit.GetMeta(root) - if list, ok := root[mdb.LIST].([]interface{}); ok && len(list) > 0 { - kit.Fetch(root[mdb.LIST], func(index int, value map[string]interface{}) { height += c.size(m, value) }) + if list, ok := root[mdb.LIST].([]ice.Any); ok && len(list) > 0 { + kit.Fetch(root[mdb.LIST], func(index int, value ice.Map) { height += c.size(m, value) }) } else { height = 1 } meta[wiki.HEIGHT] = height return height } -func (c *Chain) draw(m *ice.Message, root map[string]interface{}, x, y int, p *Block) int { +func (c *Chain) draw(m *ice.Message, root ice.Map, x, y int, p *Block) int { meta := kit.GetMeta(root) item := &Block{FontSize: p.FontSize, Padding: p.Padding, MarginX: p.MarginX, MarginY: p.MarginY} @@ -88,7 +88,7 @@ func (c *Chain) draw(m *ice.Message, root map[string]interface{}, x, y int, p *B // 递归 h, x := 0, x+item.GetWidths() - if kit.Fetch(root[mdb.LIST], func(index int, value map[string]interface{}) { + if kit.Fetch(root[mdb.LIST], func(index int, value ice.Map) { h += c.draw(m, value, x, y+h, item) }); h == 0 { return item.GetHeights() diff --git a/core/wiki/chart/label.go b/core/wiki/chart/label.go index 03ad993c..b33aed2e 100644 --- a/core/wiki/chart/label.go +++ b/core/wiki/chart/label.go @@ -21,12 +21,12 @@ func (l *Label) Init(m *ice.Message, arg ...string) wiki.Chart { // 解析数据 l.max = map[int]int{} m.Option(lex.SPLIT_BLOCK, ice.SP) - m.Cmd(lex.SPLIT, "", kit.Dict(nfs.CAT_CONTENT, arg[0]), func(ls []string, data map[string]interface{}) []string { + m.Cmd(lex.SPLIT, "", kit.Dict(nfs.CAT_CONTENT, arg[0]), func(ls []string, data ice.Map) []string { l.data = append(l.data, ls) for i, v := range ls { switch data := kit.Parse(nil, "", kit.Split(v)...).(type) { - case map[string]interface{}: + case ice.Map: v = kit.Select("", data[mdb.TEXT]) } if w := l.GetWidth(v); w > l.max[i] { @@ -57,7 +57,7 @@ func (l *Label) Draw(m *ice.Message, x, y int) wiki.Chart { // 数据 item = &Block{FontSize: l.FontSize, Padding: l.Padding, MarginX: l.MarginX, MarginY: l.MarginY} switch data := kit.Parse(nil, "", kit.Split(text)...).(type) { - case map[string]interface{}: + case ice.Map: item.Init(m, kit.Select(text, data[mdb.TEXT])).Data(m, data) default: item.Init(m, text) diff --git a/core/wiki/chart/sequence.go b/core/wiki/chart/sequence.go index 12562f06..fb9072fc 100644 --- a/core/wiki/chart/sequence.go +++ b/core/wiki/chart/sequence.go @@ -12,13 +12,13 @@ import ( type Sequence struct { head []string - list [][]map[string]interface{} + list [][]ice.Map pos []int max int Block } -func (s *Sequence) push(m *ice.Message, list string, arg ...interface{}) map[string]interface{} { +func (s *Sequence) push(m *ice.Message, list string, arg ...ice.Any) ice.Map { node, node_list := kit.Dict(arg...), kit.Int(list) s.list[node_list] = append(s.list[node_list], node) // _max := kit.Max(len(s.list[node_list])-1, s.pos[node_list]) @@ -31,17 +31,17 @@ func (s *Sequence) Init(m *ice.Message, arg ...string) wiki.Chart { // 解析数据 m.Option(lex.SPLIT_BLOCK, ice.SP) - m.Cmd(lex.SPLIT, "", kit.Dict(nfs.CAT_CONTENT, arg[0]), func(ls []string, data map[string]interface{}) []string { + m.Cmd(lex.SPLIT, "", kit.Dict(nfs.CAT_CONTENT, arg[0]), func(ls []string, data ice.Map) []string { if len(s.head) == 0 { // 添加标题 s.head, s.pos = ls, make([]int, len(ls)) for i := 0; i < len(ls); i++ { - s.list = append(s.list, []map[string]interface{}{}) + s.list = append(s.list, []ice.Map{}) } return ls } from_node := s.push(m, ls[0]) - list := map[string]map[string]interface{}{ls[0]: from_node} + list := map[string]ice.Map{ls[0]: from_node} for step, i := 0, 1; i < len(ls)-1; i += 2 { to_node := list[ls[i+1]] if to_node == nil { diff --git a/core/wiki/field.go b/core/wiki/field.go index d32d2497..c4dd59f5 100644 --- a/core/wiki/field.go +++ b/core/wiki/field.go @@ -11,7 +11,7 @@ import ( kit "shylinux.com/x/toolkits" ) -func Parse(m *ice.Message, meta string, key string, arg ...string) (data interface{}) { +func Parse(m *ice.Message, meta string, key string, arg ...string) (data ice.Any) { list := []string{} for _, line := range kit.Split(strings.Join(arg, ice.SP), ice.NL) { ls := kit.Split(line) @@ -92,14 +92,14 @@ func _field_show(m *ice.Message, name, text string, arg ...string) { args := kit.Simple(m.Optionv(arg[i])) count := 0 - kit.Fetch(meta[INPUTS], func(index int, value map[string]interface{}) { + kit.Fetch(meta[INPUTS], func(index int, value ice.Map) { if value[mdb.TYPE] != "button" { count++ } }) if len(args) > count { - list := meta[INPUTS].([]interface{}) + list := meta[INPUTS].([]ice.Any) for i := count; i < len(args); i++ { list = append(list, kit.Dict(mdb.TYPE, "text", mdb.NAME, ARGS, mdb.VALUE, args[i])) } diff --git a/core/wiki/spark.go b/core/wiki/spark.go index 85a750db..4931f7a2 100644 --- a/core/wiki/spark.go +++ b/core/wiki/spark.go @@ -46,7 +46,7 @@ func init() { Index.Merge(&ice.Context{Commands: map[string]*ice.Command{ SPARK: {Name: "spark [name] text auto field:text value:text", Help: "段落", Action: map[string]*ice.Action{ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { - ice.AddRender(ice.RENDER_SCRIPT, func(m *ice.Message, cmd string, args ...interface{}) string { + ice.AddRender(ice.RENDER_SCRIPT, func(m *ice.Message, cmd string, args ...ice.Any) string { arg := kit.Simple(args...) if m.IsCliUA() { if len(arg) > 1 { diff --git a/core/wiki/title.go b/core/wiki/title.go index 01461524..a950797d 100644 --- a/core/wiki/title.go +++ b/core/wiki/title.go @@ -11,7 +11,7 @@ import ( ) func _title_parse(m *ice.Message, dir string, text string) string { - return m.Cmdx(lex.SPLIT, "", "name,link", kit.Dict(nfs.CAT_CONTENT, text), func(ls []string, data map[string]interface{}) []string { + return m.Cmdx(lex.SPLIT, "", "name,link", kit.Dict(nfs.CAT_CONTENT, text), func(ls []string, data ice.Map) []string { if len(ls) > 1 { ls[1] = path.Join(dir, ls[1]) } @@ -57,8 +57,8 @@ func _title_show(m *ice.Message, kind, text string, arg ...string) { _wiki_template(m, TITLE, "", text, arg...) // 添加目录 - menu, _ := m.Optionv(MENU).(map[string]interface{}) - menu[mdb.LIST] = append(menu[mdb.LIST].([]interface{}), kit.Dict(m.OptionSimple("level,prefix,text"))) + menu, _ := m.Optionv(MENU).(ice.Map) + menu[mdb.LIST] = append(menu[mdb.LIST].([]ice.Any), kit.Dict(m.OptionSimple("level,prefix,text"))) } const ( diff --git a/data.go b/data.go index 8870f662..6f6ba489 100644 --- a/data.go +++ b/data.go @@ -14,11 +14,14 @@ func (m *Message) ActionKey() string { func (m *Message) CommandKey() string { return strings.TrimSuffix(strings.TrimPrefix(m._key, PS), PS) } +func (m *Message) RoutePath(arg ...string) string { + return m.Target().RoutePath(arg...) +} func (m *Message) PrefixKey(arg ...string) string { - return kit.Keys(m.Cap(CTX_FOLLOW), m.CommandKey(), arg) + return kit.Keys(m.Prefix(m.CommandKey()), arg) } func (m *Message) Prefix(arg ...string) string { - return kit.Keys(m.Cap(CTX_FOLLOW), arg) + return m.Target().PrefixKey(arg...) } func (m *Message) ConfigSet(keys string, arg ...string) { for i, k := range kit.Split(keys) { diff --git a/exec.go b/exec.go index d2efc27e..070ec08c 100644 --- a/exec.go +++ b/exec.go @@ -52,7 +52,6 @@ func (m *Message) Assert(expr Any) bool { panic(expr) } func (m *Message) Sleep(d string, arg ...Any) *Message { - // m.Debug("sleep %s %s", d, kit.FileLine(2, 3)) if time.Sleep(kit.Duration(d)); len(arg) > 0 { m.Cmdy(arg...) } @@ -137,20 +136,20 @@ func (m *Message) Watch(key string, arg ...string) *Message { if len(arg) == 0 { arg = append(arg, m.Prefix(AUTO)) } - m.Cmd("event", ACTION, "listen", "event", key, CMD, kit.Join(arg, SP)) + m.Cmd(EVENT, ACTION, LISTEN, EVENT, key, CMD, kit.Join(arg, SP)) return m } func (m *Message) Event(key string, arg ...string) *Message { - m.Cmd("event", ACTION, "action", "event", key, arg) + m.Cmd(EVENT, ACTION, HAPPEN, EVENT, key, arg) return m } func (m *Message) Right(arg ...Any) bool { key := strings.ReplaceAll(kit.Keys(arg...), PS, PT) - return m.Option(MSG_USERROLE) == "root" || !m.Warn(m.Cmdx("role", "right", m.Option(MSG_USERROLE), key) != OK, - ErrNotRight, kit.Join(kit.Simple(arg), PT), "userrole", m.Option(MSG_USERROLE), "fileline", kit.FileLine(2, 3)) + return m.Option(MSG_USERROLE) == ROOT || !m.Warn(m.Cmdx(ROLE, RIGHT, m.Option(MSG_USERROLE), key) != OK, + ErrNotRight, kit.Join(kit.Simple(arg), PT), USERROLE, m.Option(MSG_USERROLE), FILELINE, kit.FileLine(2, 3)) } func (m *Message) Space(arg Any) []string { - if arg == nil || arg == "" || kit.Format(arg) == m.Conf("runtime", "node.name") { + if arg == nil || arg == "" || kit.Format(arg) == Info.NodeName { return nil } return []string{SPACE, kit.Format(arg)} diff --git a/go.mod b/go.mod index f04f2c49..82617b1c 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.11 require ( shylinux.com/x/go-qrcode v0.0.1 + shylinux.com/x/ice v0.9.9 shylinux.com/x/toolkits v0.6.1 shylinux.com/x/websocket v0.0.1 ) diff --git a/go.sum b/go.sum index 2885b91a..9ebcac9a 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,9 @@ +shylinux.com/x/go-qrcode v0.0.1 h1:/eOGqMj1qtgs9Ymd12zTUa1gcJZs9S92kj2lb0QzKsE= shylinux.com/x/go-qrcode v0.0.1/go.mod h1:KAbtU+KwiiABMZ/CJ0zh9PI2AX82Uf9rRYcQ4ODm4po= +shylinux.com/x/ice v0.9.9 h1:gmAw2sz09Lll+2ppMK8I+XtGWLZ1XNyYVJCWFudF6xU= +shylinux.com/x/ice v0.9.9/go.mod h1:9zZRlYWlqsm2+VJlUqowLj1BaV/FmYHgcjS0NwZqXb4= +shylinux.com/x/icebergs v1.2.6/go.mod h1:zoEhlaCsUxAqKG4l+IPY35bbT1ACb8DFBb/xzjCDuvc= shylinux.com/x/toolkits v0.6.1 h1:ePUEz8v+vz6nhaF0SImQ+nk/4OMAc0FfDmUEyH3v3kA= shylinux.com/x/toolkits v0.6.1/go.mod h1:8LbYHe7oxBIqb6s4MSOD+4d28QvPdvkyCVtwB/JW7AA= +shylinux.com/x/websocket v0.0.1 h1:OBc21DxqsGlQ2+Pz76xqLyDNo1LV+PUUqfWi+1PZPDE= shylinux.com/x/websocket v0.0.1/go.mod h1:AaSpMToOxbMULKQytzczeHPuqb708vK1vrAzCxLo/XE= diff --git a/info.go b/info.go index 1438dfde..00d414cd 100644 --- a/info.go +++ b/info.go @@ -40,11 +40,11 @@ var Info = struct { Route map[string]string // 路由命令 File map[string]string // 文件命令 Pack map[string][]byte // 打包文件 - Dump func(w io.Writer, name string, cb func(string)) bool - Log func(m *Message, p, l, s string) + names Map render map[string]func(*Message, string, ...Any) string - names Map + Dump func(w io.Writer, name string, cb func(string)) bool + Log func(m *Message, p, l, s string) }{ Help: ` ^_^ 欢迎使用冰山框架 ^_^ @@ -57,11 +57,11 @@ source: https://shylinux.com/x/icebergs Route: map[string]string{}, File: map[string]string{}, Pack: map[string][]byte{}, - Dump: func(w io.Writer, name string, cb func(string)) bool { return false }, - Log: func(m *Message, p, l, s string) {}, + names: Map{}, render: map[string]func(*Message, string, ...Any) string{}, - names: Map{}, + Dump: func(w io.Writer, name string, cb func(string)) bool { return false }, + Log: func(m *Message, p, l, s string) {}, } func FileURI(dir string) string { diff --git a/init.go b/init.go index 24285b59..e05e72f5 100644 --- a/init.go +++ b/init.go @@ -53,8 +53,8 @@ func (f *Frame) Close(m *Message, arg ...string) bool { return true } -var Index = &Context{Name: "ice", Help: "冰山模块", Configs: map[string]*Config{ - HELP: {Value: kit.Data("index", Info.Help)}, +var Index = &Context{Name: ICE, Help: "冰山模块", Configs: map[string]*Config{ + HELP: {Value: kit.Data(INDEX, Info.Help)}, }, Commands: map[string]*Command{ CTX_INIT: {Hand: func(m *Message, c *Context, cmd string, arg ...string) { defer m.Cost(CTX_INIT) @@ -66,16 +66,16 @@ var Index = &Context{Name: "ice", Help: "冰山模块", Configs: map[string]*Con }}, INIT: {Name: "init", Help: "启动", Hand: func(m *Message, c *Context, cmd string, arg ...string) { m.root.Cmd(CTX_INIT) - m.Cmd("source", ETC_INIT_SHY) + m.Cmd(SOURCE, ETC_INIT_SHY) }}, HELP: {Name: "help", Help: "帮助", Hand: func(m *Message, c *Context, cmd string, arg ...string) { - m.Echo(m.Config("index")) + m.Echo(m.Config(INDEX)) }}, EXIT: {Name: "exit", Help: "结束", Hand: func(m *Message, c *Context, cmd string, arg ...string) { m.root.Option(EXIT, kit.Select("0", arg, 0)) defer c.Close(m.root.Spawn(), arg...) - m.Cmd("source", ETC_EXIT_SHY) + m.Cmd(SOURCE, ETC_EXIT_SHY) m.root.Cmd(CTX_EXIT) }}, CTX_EXIT: {Hand: func(m *Message, c *Context, cmd string, arg ...string) { @@ -91,11 +91,8 @@ var Index = &Context{Name: "ice", Help: "冰山模块", Configs: map[string]*Con }) }}, }, server: &Frame{}, wg: &sync.WaitGroup{}} -var Pulse = &Message{ - time: time.Now(), code: 0, - meta: map[string][]string{}, - data: Map{}, - +var Pulse = &Message{time: time.Now(), code: 0, + meta: map[string][]string{}, data: Map{}, source: Index, target: Index, Hand: true, } diff --git a/logs.go b/logs.go index ea05be71..aa68bea5 100644 --- a/logs.go +++ b/logs.go @@ -83,7 +83,7 @@ func (m *Message) Warn(err Any, arg ...Any) bool { if err == io.EOF { return false } - arg = append(arg, "err", err) + arg = append(arg, ERR, err) case bool: if !err { return false diff --git a/misc.go b/misc.go index fed9713b..2dca606a 100644 --- a/misc.go +++ b/misc.go @@ -3,6 +3,7 @@ package ice import ( "bytes" "encoding/csv" + "path" "reflect" "strings" @@ -40,8 +41,8 @@ func (m *Message) Split(str string, arg ...string) *Message { // field sp nl if strings.TrimSpace(l) == "" { continue } - if i == 0 && (field == "" || field == "index") { // 表头行 - if fields = kit.Split(l, sp, sp); field == "index" { + if i == 0 && (field == "" || field == INDEX) { // 表头行 + if fields = kit.Split(l, sp, sp); field == INDEX { for _, v := range fields { indexs = append(indexs, strings.Index(l, v)) } @@ -72,7 +73,7 @@ func (m *Message) Split(str string, arg ...string) *Message { // field sp nl return m } func (m *Message) SplitIndex(str string, arg ...string) *Message { - return m.Split(str, kit.Simple("index", arg)...) + return m.Split(str, kit.Simple(INDEX, arg)...) } func (m *Message) PushDetail(value Any, arg ...string) *Message { return m.Push(CACHE_DETAIL, value, kit.Split(kit.Join(arg))) @@ -221,6 +222,12 @@ func (m *Message) cmd(arg ...Any) *Message { m.Warn(!ok, ErrNotFound, kit.Format(list)) return m } +func (c *Context) PrefixKey(arg ...string) string { + return kit.Keys(c.Cap(CTX_FOLLOW), arg) +} +func (c *Context) RoutePath(arg ...string) string { + return path.Join(strings.TrimPrefix(strings.ReplaceAll(c.Cap(CTX_FOLLOW), PT, PS), "web"), path.Join(arg...)) +} func (c *Context) cmd(m *Message, cmd *Command, key string, arg ...string) *Message { if m._key, m._cmd = key, cmd; cmd == nil { return m diff --git a/misc/bash/input.go b/misc/bash/input.go index cf1cd639..95469ebe 100644 --- a/misc/bash/input.go +++ b/misc/bash/input.go @@ -35,7 +35,7 @@ func init() { line := []rune(m.Option("line")) if begin := kit.Int(m.Option("point")); begin < len(line) { - m.Richs("login", nil, m.Option("sid"), func(key string, value map[string]interface{}) { + m.Richs("login", nil, m.Option("sid"), func(key string, value ice.Map) { m.Echo(string(line[:begin])) for i := begin; i < len(line); i++ { if i-begin < 3 && i < len(line)-1 { @@ -60,7 +60,7 @@ func init() { } fallthrough case "end": - m.Richs("login", nil, m.Option("sid"), func(key string, value map[string]interface{}) { + m.Richs("login", nil, m.Option("sid"), func(key string, value ice.Map) { last_text := kit.Format(kit.Value(value, "last.text")) last_list := kit.Simple(kit.Value(value, "last.list")) last_index := kit.Int(kit.Value(value, "last.index")) diff --git a/misc/bash/run.go b/misc/bash/run.go index 91f2d05d..1110acff 100644 --- a/misc/bash/run.go +++ b/misc/bash/run.go @@ -21,7 +21,7 @@ func _run_action(m *ice.Message, cmd *ice.Command, code string, arg ...string) { kit.Fetch(cmd.Meta["_trans"], func(k string, v string) { list = append(list, k) args = append(args, kit.Format(` %s)`, k)) - kit.Fetch(cmd.Meta[k], func(index int, value map[string]interface{}) { + kit.Fetch(cmd.Meta[k], func(index int, value ice.Map) { args = append(args, kit.Format(` read -p "input %s: " v; url="$url/%s/$v" `, value[mdb.NAME], value[mdb.NAME])) }) args = append(args, kit.Format(` ;;`)) diff --git a/misc/chrome/operate.go b/misc/chrome/operate.go index 5339366d..5eb401fe 100644 --- a/misc/chrome/operate.go +++ b/misc/chrome/operate.go @@ -13,7 +13,7 @@ type operate struct { list string `name:"list wid tid url auto" help:"操作"` } -func (o operate) send(m *ice.Message, arg ...interface{}) *ice.Message { +func (o operate) send(m *ice.Message, arg ...ice.Any) *ice.Message { return m.Cmdy(web.SPACE, "chrome", "chrome", arg) } diff --git a/misc/coder/server.go b/misc/coder/server.go index b461f4b4..4d265bc7 100644 --- a/misc/coder/server.go +++ b/misc/coder/server.go @@ -42,7 +42,7 @@ password: %s } func (s server) List(m *ice.Message, arg ...string) *ice.Message { if s.Code.List(m, "", arg...); len(arg) == 0 { - s.PushLink(m).Tables(func(value map[string]string) { + m.Tables(func(value map[string]string) { switch value[cli.STATUS] { case cli.START: m.PushButton(s.Open, s.Stop) diff --git a/misc/git/configs.go b/misc/git/configs.go index e1ff8b07..73925dea 100644 --- a/misc/git/configs.go +++ b/misc/git/configs.go @@ -45,7 +45,7 @@ func init() { }, Commands: map[string]*ice.Command{ CONFIGS: {Name: "configs name auto create import", Help: "配置键", Action: map[string]*ice.Action{ mdb.IMPORT: {Name: "import", Help: "初始化", Hand: func(m *ice.Message, arg ...string) { - kit.Fetch(m.Configv(ice.INIT), func(conf string, value interface{}) { + kit.Fetch(m.Configv(ice.INIT), func(conf string, value ice.Any) { kit.Fetch(value, func(key string, value string) { _configs_set(m, kit.Keys(conf, key), value) }) }) }}, diff --git a/misc/git/total.go b/misc/git/total.go index 1a9f1653..14f5b0c1 100644 --- a/misc/git/total.go +++ b/misc/git/total.go @@ -51,7 +51,7 @@ func init() { // 提交统计 days, commit, adds, dels, rest := 0, 0, 0, 0, 0 - m.Richs(REPOS, nil, mdb.FOREACH, func(mu *sync.Mutex, key string, value map[string]interface{}) { + m.Richs(REPOS, nil, mdb.FOREACH, func(mu *sync.Mutex, key string, value ice.Map) { value = kit.GetMeta(value) if m.Config(kit.Keys("skip", value[mdb.NAME])) == ice.TRUE { return diff --git a/misc/input/input.go b/misc/input/input.go index 881b9f3d..d30979d3 100644 --- a/misc/input/input.go +++ b/misc/input/input.go @@ -73,8 +73,8 @@ func (i input) Save(m *ice.Message, arg ...string) { n := 0 m.Option(ice.CACHE_LIMIT, -2) for _, lib := range kit.Split(m.Option(mdb.ZONE)) { - m.Richs(m.PrefixKey(), "", lib, func(key string, value map[string]interface{}) { - m.Grows(m.PrefixKey(), kit.Keys(mdb.HASH, key), "", "", func(index int, value map[string]interface{}) { + m.Richs(m.PrefixKey(), "", lib, func(key string, value ice.Map) { + m.Grows(m.PrefixKey(), kit.Keys(mdb.HASH, key), "", "", func(index int, value ice.Map) { if value[CODE] != "z" { fmt.Fprintf(f, "%s %s %s\n", value[TEXT], value[CODE], value[WEIGHT]) n++ diff --git a/misc/lark/company.go b/misc/lark/company.go index 03001521..4a8f5366 100644 --- a/misc/lark/company.go +++ b/misc/lark/company.go @@ -12,7 +12,7 @@ func _company_list(m *ice.Message, appid string) { kit.Fetch(kit.Value(data, "data.authed_departments"), func(index int, ship_id string) { _, data := _lark_get(m, appid, "/open-apis/contact/v1/department/detail/batch_get", "department_ids", ship_id) - kit.Fetch(kit.Value(data, "data.department_infos"), func(index int, value map[string]interface{}) { + kit.Fetch(kit.Value(data, "data.department_infos"), func(index int, value ice.Map) { m.Push(SHIP_ID, ship_id) m.Push(mdb.NAME, value[mdb.NAME]) m.Push(mdb.COUNT, value["member_count"]) @@ -25,7 +25,7 @@ func _company_members(m *ice.Message, appid string, ship_id string) { _, data := _lark_get(m, appid, "/open-apis/contact/v1/department/user/list", "department_id", ship_id, "page_size", "100", "fetch_child", ice.TRUE) - kit.Fetch(kit.Value(data, "data.user_list"), func(index int, value map[string]interface{}) { + kit.Fetch(kit.Value(data, "data.user_list"), func(index int, value ice.Map) { msg := m.Cmd(EMPLOYEE, appid, value[OPEN_ID]) m.PushImages(aaa.AVATAR, msg.Append("avatar_72")) m.Push(aaa.GENDER, kit.Select("女", "男", msg.Append(aaa.GENDER) == "1")) diff --git a/misc/lark/employee.go b/misc/lark/employee.go index a3799e08..ec988821 100644 --- a/misc/lark/employee.go +++ b/misc/lark/employee.go @@ -11,7 +11,7 @@ import ( func _employee_info(m *ice.Message, appid string, arg ...string) { for _, id := range arg { _, data := _lark_get(m, appid, "/open-apis/contact/v1/user/batch_get", "open_ids", id) - kit.Fetch(kit.Value(data, "data.user_infos"), func(index int, value map[string]interface{}) { + kit.Fetch(kit.Value(data, "data.user_infos"), func(index int, value ice.Map) { m.Push(mdb.DETAIL, value) }) } diff --git a/misc/lark/form.go b/misc/lark/form.go index 122b4d5e..3d1d8f5e 100644 --- a/misc/lark/form.go +++ b/misc/lark/form.go @@ -20,14 +20,14 @@ func init() { form[CHAT_ID], arg = arg[0], arg[1:] } - elements := []interface{}{} + elements := []ice.Any{} elements = append(elements, kit.Dict( "tag", "div", "text", kit.Dict( "tag", "plain_text", CONTENT, kit.Select(" ", arg[1]), ), )) - actions := []interface{}{} + actions := []ice.Any{} for i := 2; i < len(arg); i++ { button := kit.Dict( "tag", "button", "type", "default", "text", kit.Dict( @@ -47,7 +47,7 @@ func init() { case "url": button[arg[i+1]], i = arg[i+2], i+2 default: - button["value"], i = map[string]interface{}{ + button["value"], i = ice.Map{ ice.MSG_RIVER: m.Option(ice.MSG_RIVER), ice.MSG_STORM: m.Option(ice.MSG_STORM), APP_ID: m.Option(APP_ID), diff --git a/misc/lark/group.go b/misc/lark/group.go index 2e6a70db..7703a408 100644 --- a/misc/lark/group.go +++ b/misc/lark/group.go @@ -9,7 +9,7 @@ import ( func _group_list(m *ice.Message, appid string) { _, data := _lark_get(m, appid, "/open-apis/chat/v4/list") - kit.Fetch(kit.Value(data, "data.groups"), func(index int, value map[string]interface{}) { + kit.Fetch(kit.Value(data, "data.groups"), func(index int, value ice.Map) { m.Push(CHAT_ID, value[CHAT_ID]) m.PushImages(aaa.AVATAR, kit.Format(value[aaa.AVATAR]), "72") m.Push(mdb.NAME, value[mdb.NAME]) @@ -20,7 +20,7 @@ func _group_list(m *ice.Message, appid string) { } func _group_members(m *ice.Message, appid string, chat_id string) { _, data := _lark_get(m, appid, "/open-apis/chat/v4/info", "chat_id", chat_id) - kit.Fetch(kit.Value(data, "data.members"), func(index int, value map[string]interface{}) { + kit.Fetch(kit.Value(data, "data.members"), func(index int, value ice.Map) { msg := m.Cmd(EMPLOYEE, appid, value[OPEN_ID]) m.PushImages(aaa.AVATAR, msg.Append("avatar_72")) m.Push(aaa.GENDER, kit.Select("女", "男", msg.Append(aaa.GENDER) == "1")) diff --git a/misc/lark/msg.go b/misc/lark/msg.go index 9c7ebe9f..2deaced5 100644 --- a/misc/lark/msg.go +++ b/misc/lark/msg.go @@ -12,12 +12,12 @@ import ( kit "shylinux.com/x/toolkits" ) -func _lark_get(m *ice.Message, appid string, arg ...interface{}) (*ice.Message, interface{}) { +func _lark_get(m *ice.Message, appid string, arg ...ice.Any) (*ice.Message, ice.Any) { m.Option(web.SPIDE_HEADER, "Authorization", "Bearer "+m.Cmdx(APP, TOKEN, appid), web.ContentType, web.ContentJSON) msg := m.Cmd(web.SPIDE, LARK, http.MethodGet, arg) return msg, msg.Optionv(web.SPIDE_RES) } -func _lark_post(m *ice.Message, appid string, arg ...interface{}) *ice.Message { +func _lark_post(m *ice.Message, appid string, arg ...ice.Any) *ice.Message { m.Option(web.SPIDE_HEADER, "Authorization", "Bearer "+m.Cmdx(APP, TOKEN, appid), web.ContentType, web.ContentJSON) return m.Cmd(web.SPIDE, LARK, arg) } @@ -28,10 +28,10 @@ func _lark_parse(m *ice.Message) { m.Optionv(ice.MSG_USERDATA, data) switch d := data.(type) { - case map[string]interface{}: + case ice.Map: for k, v := range d { switch d := v.(type) { - case map[string]interface{}: + case ice.Map: for k, v := range d { m.Add(ice.MSG_OPTION, k, kit.Format(v)) } diff --git a/misc/lark/send.go b/misc/lark/send.go index 35d72b0f..98cb3c05 100644 --- a/misc/lark/send.go +++ b/misc/lark/send.go @@ -10,7 +10,7 @@ import ( kit "shylinux.com/x/toolkits" ) -func _send_text(m *ice.Message, form map[string]interface{}, arg ...string) bool { +func _send_text(m *ice.Message, form ice.Map, arg ...string) bool { switch len(arg) { case 0: case 1: @@ -23,20 +23,20 @@ func _send_text(m *ice.Message, form map[string]interface{}, arg ...string) bool if len(arg) == 2 && strings.TrimSpace(arg[1]) == "" { return false } - content := []interface{}{} - line := []interface{}{} + content := []ice.Any{} + line := []ice.Any{} for _, v := range arg[1:] { if v == "\n" { - content, line = append(content, line), []interface{}{} + content, line = append(content, line), []ice.Any{} continue } - line = append(line, map[string]interface{}{"tag": "text", "text": v + " "}) + line = append(line, ice.Map{"tag": "text", "text": v + " "}) } content = append(content, line) kit.Value(form, "msg_type", "post") - kit.Value(form, "content.post", map[string]interface{}{ - "zh_cn": map[string]interface{}{"title": arg[0], CONTENT: content}, + kit.Value(form, "content.post", ice.Map{ + "zh_cn": ice.Map{"title": arg[0], CONTENT: content}, }) } return true diff --git a/misc/lark/talk.go b/misc/lark/talk.go index 20bf70b2..1399aca8 100644 --- a/misc/lark/talk.go +++ b/misc/lark/talk.go @@ -47,7 +47,7 @@ func init() { _lark_post(m, m.Option(APP_ID), "/open-apis/message/v4/send/", web.SPIDE_DATA, kit.Formats( kit.Dict("msg_type", "interactive", "chat_id", m.Option(OPEN_CHAT_ID), "card", kit.Dict( "header", kit.Dict("title", kit.Dict("tag", "lark_md", "content", strings.Join(cmds, " "))), - "elements", []interface{}{kit.Dict("tag", "div", "fields", []interface{}{ + "elements", []ice.Any{kit.Dict("tag", "div", "fields", []ice.Any{ kit.Dict("is_short", true, "text", kit.Dict( "tag", "lark_md", "content", strings.Join(val, "\n"), )), diff --git a/misc/ssh/channel.go b/misc/ssh/channel.go index 2b09f491..0c05a0a0 100644 --- a/misc/ssh/channel.go +++ b/misc/ssh/channel.go @@ -74,7 +74,7 @@ func init() { }, Commands: map[string]*ice.Command{ CHANNEL: {Name: "channel hash id auto", Help: "通道", Action: ice.MergeAction(map[string]*ice.Action{ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { - m.Richs(CHANNEL, "", mdb.FOREACH, func(key string, value map[string]interface{}) { + m.Richs(CHANNEL, "", mdb.FOREACH, func(key string, value ice.Map) { kit.Value(value, kit.Keym(mdb.STATUS), tcp.CLOSE) }) }}, @@ -89,7 +89,7 @@ func init() { ctx.COMMAND: {Name: "command cmd=pwd", Help: "命令", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(mdb.INSERT, CHANNEL, kit.Keys(mdb.HASH, m.Option(mdb.HASH)), mdb.LIST, mdb.TYPE, CMD, mdb.TEXT, m.Option(CMD)) - m.Richs(CHANNEL, "", m.Option(mdb.HASH), func(key string, value map[string]interface{}) { + m.Richs(CHANNEL, "", m.Option(mdb.HASH), func(key string, value ice.Map) { if w, ok := kit.Value(value, kit.Keym(INPUT)).(io.Writer); ok { w.Write([]byte(m.Option(CMD) + ice.NL)) } diff --git a/misc/ssh/connect.go b/misc/ssh/connect.go index 83972d8d..cd95db6d 100644 --- a/misc/ssh/connect.go +++ b/misc/ssh/connect.go @@ -180,7 +180,7 @@ func init() { }}, SESSION: {Name: "session name", Help: "会话", Hand: func(m *ice.Message, arg ...string) { var client *ssh.Client - m.Richs(CONNECT, "", m.Option(mdb.NAME), func(key string, value map[string]interface{}) { + m.Richs(CONNECT, "", m.Option(mdb.NAME), func(key string, value ice.Map) { client, _ = value[CONNECT].(*ssh.Client) }) @@ -192,7 +192,7 @@ func init() { m.Echo(h) }}, "command": {Name: "command cmd=pwd", Help: "命令", Hand: func(m *ice.Message, arg ...string) { - m.Richs(CONNECT, "", m.Option(mdb.NAME), func(key string, value map[string]interface{}) { + m.Richs(CONNECT, "", m.Option(mdb.NAME), func(key string, value ice.Map) { if client, ok := value[CONNECT].(*ssh.Client); ok { if session, e := client.NewSession(); m.Assert(e) { defer session.Close() diff --git a/misc/ssh/service.go b/misc/ssh/service.go index 4321bcf1..d882fe15 100644 --- a/misc/ssh/service.go +++ b/misc/ssh/service.go @@ -106,14 +106,14 @@ func init() { }, Commands: map[string]*ice.Command{ SERVICE: {Name: "service port id auto listen prunes", Help: "服务", Action: ice.MergeAction(map[string]*ice.Action{ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { - m.Richs(SERVICE, "", mdb.FOREACH, func(key string, value map[string]interface{}) { + m.Richs(SERVICE, "", mdb.FOREACH, func(key string, value ice.Map) { if value = kit.GetMeta(value); kit.Value(value, mdb.STATUS) == tcp.OPEN { m.Cmd(SERVICE, tcp.LISTEN, tcp.PORT, value[tcp.PORT], value) } }) }}, tcp.LISTEN: {Name: "listen port=9030 private=.ssh/id_rsa authkey=.ssh/authorized_keys", Help: "添加", Hand: func(m *ice.Message, arg ...string) { - if m.Richs(SERVICE, "", m.Option(tcp.PORT), func(key string, value map[string]interface{}) { + if m.Richs(SERVICE, "", m.Option(tcp.PORT), func(key string, value ice.Map) { kit.Value(value, kit.Keym(mdb.STATUS), tcp.OPEN) }) == nil { m.Cmd(mdb.INSERT, SERVICE, "", mdb.HASH, tcp.PORT, m.Option(tcp.PORT), diff --git a/misc/ssh/session.go b/misc/ssh/session.go index a6dd476a..500f7d81 100644 --- a/misc/ssh/session.go +++ b/misc/ssh/session.go @@ -36,7 +36,7 @@ func _ssh_session(m *ice.Message, h string, client *ssh.Client) (*ssh.Session, e } }) - m.Richs(SESSION, "", h, func(key string, value map[string]interface{}) { + m.Richs(SESSION, "", h, func(key string, value ice.Map) { kit.Value(value, kit.Keym(OUTPUT), out, kit.Keym(INPUT), in) }) @@ -66,7 +66,7 @@ func init() { m.Cmdy(SESSION, ctx.ACTION, ctx.COMMAND, CMD, m.Option(mdb.TEXT)) }}, ctx.COMMAND: {Name: "command cmd=pwd", Help: "命令", Hand: func(m *ice.Message, arg ...string) { - m.Richs(SESSION, "", m.Option(mdb.NAME), func(key string, value map[string]interface{}) { + m.Richs(SESSION, "", m.Option(mdb.NAME), func(key string, value ice.Map) { if w, ok := kit.Value(value, kit.Keym(INPUT)).(io.Writer); ok { m.Grow(SESSION, kit.Keys(mdb.HASH, key), kit.Dict(mdb.TYPE, CMD, mdb.TEXT, m.Option(CMD))) w.Write([]byte(m.Option(CMD) + ice.NL)) diff --git a/misc/tmux/buffer.go b/misc/tmux/buffer.go index 26bdf785..c7905c36 100644 --- a/misc/tmux/buffer.go +++ b/misc/tmux/buffer.go @@ -43,7 +43,7 @@ func init() { m.Option(ice.CACHE_LIMIT, "-1") m.Cmdy(mdb.IMPORT, m.PrefixKey(), "", mdb.LIST) - m.Grows(m.PrefixKey(), "", "", "", func(index int, value map[string]interface{}) { + m.Grows(m.PrefixKey(), "", "", "", func(index int, value ice.Map) { m.Cmd(cli.SYSTEM, TMUX, "set-buffer", "-b", value[mdb.NAME], value[mdb.TEXT]) }) }}, diff --git a/misc/vim/tags.go b/misc/vim/tags.go index 3324dce6..79f46985 100644 --- a/misc/vim/tags.go +++ b/misc/vim/tags.go @@ -50,7 +50,7 @@ func init() { }}, TAGS: {Name: "tags zone id auto", Help: "索引", Action: ice.MergeAction(map[string]*ice.Action{ "listTags": {Name: "listTags", Help: "索引", Hand: func(m *ice.Message, arg ...string) { - kit.Fetch(kit.UnMarshal(m.Option(mdb.TEXT)), func(index int, value map[string]interface{}) { + kit.Fetch(kit.UnMarshal(m.Option(mdb.TEXT)), func(index int, value ice.Map) { m.Cmd(TAGS, mdb.INSERT, mdb.ZONE, value[mdb.ZONE], kit.Simple(value)) }) m.ProcessRefresh300ms() diff --git a/misc/webview/webview.go b/misc/webview/webview.go index 45aafcca..318a2cbe 100644 --- a/misc/webview/webview.go +++ b/misc/webview/webview.go @@ -61,13 +61,13 @@ func (w WebView) navigate(url string) { w.WebView.Navigate(url) } -func Run(cb func(*WebView) interface{}) { +func Run(cb func(*WebView) ice.Any) { w := webview.New(true) defer w.Destroy() defer w.Run() view := &WebView{Source: "src/webview.txt", WebView: w} - kit.Reflect(cb(view), func(name string, value interface{}) { w.WebView.Bind(name, value) }) + kit.Reflect(cb(view), func(name string, value ice.Any) { w.WebView.Bind(name, value) }) if !view.Menu() { view.navigate("http://localhost:9020") diff --git a/option.go b/option.go index ecb35c63..98dff0b9 100644 --- a/option.go +++ b/option.go @@ -217,8 +217,8 @@ func (m *Message) Process(action string, arg ...Any) { func (m *Message) ProcessLocation(arg ...Any) { m.Process(PROCESS_LOCATION, arg...) } -func (m *Message) ProcessReplace(arg ...Any) { - m.Process(PROCESS_REPLACE, arg...) +func (m *Message) ProcessReplace(url string, arg ...Any) { + m.Process(PROCESS_REPLACE, kit.MergeURL(url, arg...)) } func (m *Message) ProcessHistory(arg ...Any) { m.Process(PROCESS_HISTORY, arg...) @@ -277,6 +277,11 @@ func (m *Message) MergeLink(url string, arg ...Any) string { return strings.Split(m.MergeURL2(url, arg...), "?")[0] } func (m *Message) MergePodURL(url string, arg ...Any) string { + if m.Option(MSG_USERPOD) == "" { + url = strings.TrimPrefix(url, "web.") + return kit.MergeURL(m.MergeLink(url), arg...) + } + url = strings.TrimPrefix(url, "web.chat.") return kit.MergeURL(m.MergeLink(path.Join("/chat/pod/", m.Option(MSG_USERPOD), url)), arg...) } func (m *Message) MergePod(pod string, arg ...Any) string { diff --git a/render.go b/render.go index ecb97aa2..23d3a561 100644 --- a/render.go +++ b/render.go @@ -1,6 +1,7 @@ package ice import ( + "net/http" "path" "strings" @@ -63,6 +64,28 @@ func (m *Message) Render(cmd string, args ...Any) *Message { } return m } +func (m *Message) RenderVoid(args ...Any) *Message { + return m.Render(RENDER_VOID, args...) +} +func (m *Message) RenderJson(args ...Any) *Message { + return m.Render(RENDER_JSON, kit.Format(kit.Dict(args...))) +} +func (m *Message) RenderStatus(status int) *Message { + return m.Render(RENDER_STATUS, status) +} +func (m *Message) RenderStatusBadRequest() *Message { + return m.Render(RENDER_STATUS, http.StatusBadRequest) +} +func (m *Message) RenderStatusUnauthorized() *Message { + return m.Render(RENDER_STATUS, http.StatusUnauthorized) +} +func (m *Message) RenderStatusNotFound() *Message { + return m.Render(RENDER_STATUS, http.StatusNotFound) +} +func (m *Message) RenderStatusForbidden() *Message { + return m.Render(RENDER_STATUS, http.StatusForbidden) +} + func (m *Message) RenderResult(args ...Any) *Message { return m.Render(RENDER_RESULT, args...) } diff --git a/type.go b/type.go index fe04a63e..7bdbcfe8 100644 --- a/type.go +++ b/type.go @@ -14,7 +14,7 @@ import ( ) type Any = interface{} -type Map = map[string]interface{} +type Map = map[string]Any type ActionHandler func(m *Message, arg ...string) type CommandHandler func(m *Message, c *Context, key string, arg ...string)