diff --git a/base/ssh/ssh.go b/base/ssh/ssh.go index 9dfc2540..e26f5162 100644 --- a/base/ssh/ssh.go +++ b/base/ssh/ssh.go @@ -238,8 +238,25 @@ var Index = &ice.Context{Name: "ssh", Help: "终端模块", )}, "super": {Name: "super", Help: "super", Value: kit.Data()}, + + "demo": {Name: "demo", Help: "demo", Value: kit.Data( + "short", "name", + "limit", "5", "least", "2", + )}, }, Commands: map[string]*ice.Command{ + "demo": {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + data := m.Richs("demo", nil, arg[0], nil) + if data != nil { + m.Echo("%v", data) + return + } + + m.Rich("demo", nil, kit.Dict( + "name", arg[0], + )) + }}, + ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Load() }}, diff --git a/base/web/web.go b/base/web/web.go index 8d3cce8b..a95f3fb7 100644 --- a/base/web/web.go +++ b/base/web/web.go @@ -35,66 +35,73 @@ type Frame struct { send map[string]*ice.Message } -func Refresh(msg *ice.Message, n int) string { - return fmt.Sprintf(` -
- - - - - 请稍后,系统初始化中... - - `, n) -} - -func Redirect(msg *ice.Message, url string, arg ...interface{}) *ice.Message { - msg.Push("_output", "redirect") - msg.Echo(kit.MergeURL(url, arg...)) - return msg -} -func Cookie(msg *ice.Message, sessid string) string { - expire := time.Now().Add(kit.Duration(msg.Conf(ice.AAA_SESS, "meta.expire"))) - msg.Log("cookie", "expire:%v sessid:%s", kit.Format(expire), sessid) - http.SetCookie(msg.W, &http.Cookie{Name: ice.WEB_SESS, Value: sessid, Path: "/", Expires: expire}) - return sessid -} -func Upload(m *ice.Message, name string) string { - m.Cmdy(ice.WEB_STORY, "upload") - if s, e := os.Stat(name); e == nil && s.IsDir() { - name = path.Join(name, m.Append("name")) - } - m.Cmd(ice.WEB_STORY, ice.STORY_WATCH, m.Append("data"), name) - return name -} func Count(m *ice.Message, cmd, key, name string) int { count := kit.Int(m.Conf(cmd, kit.Keys(key, name))) m.Conf(cmd, kit.Keys(key, name), count+1) return count } +func Render(msg *ice.Message, cmd string, args ...interface{}) *ice.Message { + msg.Info("render %s: %v", cmd, args) + switch arg := kit.Simple(args...); cmd { + case "redirect": + http.Redirect(msg.W, msg.R, kit.MergeURL(arg[0], arg[1:]), 307) + + case "refresh": + arg = []string{"200", fmt.Sprintf(`%s`, + kit.Int(kit.Select("3", arg, 0)), kit.Select("请稍后,系统初始化中...", arg, 1), + )} + fallthrough + + case "status": + msg.W.WriteHeader(kit.Int(kit.Select("200", arg, 0))) + msg.W.Write([]byte(kit.Select("", arg, 1))) + + case "result": + msg.W.Write([]byte(kit.Format(arg[0], args[1:]...))) + + case "cookie": + expire := time.Now().Add(kit.Duration(msg.Conf(ice.AAA_SESS, "meta.expire"))) + http.SetCookie(msg.W, &http.Cookie{Value: arg[0], Name: kit.Select(ice.MSG_SESSID, arg, 1), Path: "/", Expires: expire}) + + case "qrcode": + if qr, e := qrcode.New(arg[0], qrcode.Medium); msg.Assert(e) { + msg.W.Header().Set("Content-Type", "image/png") + msg.Assert(qr.Write(256, msg.W)) + } + case "download": + msg.W.Header().Set("Content-Disposition", fmt.Sprintf("filename=%s", kit.Select(path.Base(arg[0]), arg, 2))) + msg.W.Header().Set("Content-Type", kit.Select("text/html", arg, 1)) + http.ServeFile(msg.W, msg.R, arg[0]) + default: + msg.W.Write([]byte(kit.Format(cmd, args...))) + } + msg.Append("_output", "render") + return msg +} func IsLocalIP(ip string) bool { return ip == "::1" || strings.HasPrefix(ip, "127.") } func (web *Frame) Login(msg *ice.Message, w http.ResponseWriter, r *http.Request) bool { + msg.Option(ice.MSG_USERNAME, "") + msg.Option(ice.MSG_USERROLE, "") + if msg.Options(ice.WEB_SESS) { // 会话认证 sub := msg.Cmd(ice.AAA_SESS, "check", msg.Option(ice.WEB_SESS)) - msg.Info("role: %s user: %s", msg.Option(ice.MSG_USERROLE, sub.Append("userrole")), + msg.Log(ice.LOG_LOGIN, "role: %s user: %s", msg.Option(ice.MSG_USERROLE, sub.Append("userrole")), msg.Option(ice.MSG_USERNAME, sub.Append("username"))) } - if strings.HasPrefix(msg.Option(ice.MSG_USERURL), "/space/") { - return true - } if (!msg.Options(ice.MSG_SESSID) || !msg.Options(ice.MSG_USERNAME)) && IsLocalIP(msg.Option(ice.MSG_USERIP)) { // 自动认证 msg.Option(ice.MSG_USERNAME, msg.Conf(ice.CLI_RUNTIME, "boot.username")) msg.Option(ice.MSG_USERROLE, msg.Cmdx(ice.AAA_ROLE, "check", msg.Option(ice.MSG_USERNAME))) - msg.Option(ice.MSG_SESSID, msg.Rich(ice.AAA_SESS, nil, kit.Dict( - "username", msg.Option(ice.MSG_USERNAME), "userrole", msg.Option(ice.MSG_USERROLE), - ))) - Cookie(msg, msg.Option(ice.MSG_SESSID)) - msg.Info("user: %s role: %s sess: %s", msg.Option(ice.MSG_USERNAME), msg.Option(ice.MSG_USERROLE), msg.Option(ice.MSG_SESSID)) + if strings.HasPrefix(msg.Option(ice.MSG_USERUA), "Mozilla/5.0") { + msg.Option(ice.MSG_SESSID, msg.Cmdx(ice.AAA_SESS, "create", msg.Option(ice.MSG_USERNAME), msg.Option(ice.MSG_USERROLE))) + Render(msg, "cookie", msg.Option(ice.MSG_SESSID)) + } + msg.Log(ice.LOG_LOGIN, "user: %s role: %s sess: %s", msg.Option(ice.MSG_USERNAME), msg.Option(ice.MSG_USERROLE), msg.Option(ice.MSG_SESSID)) } if s, ok := msg.Target().Commands[ice.WEB_LOGIN]; ok { @@ -213,7 +220,6 @@ func (web *Frame) HandleCmd(m *ice.Message, key string, cmd *ice.Command) { msg.Option(ice.MSG_USERUA, r.Header.Get("User-Agent")) msg.Option(ice.MSG_USERIP, r.Header.Get(ice.MSG_USERIP)) msg.Option(ice.MSG_USERURL, r.URL.Path) - msg.Option(ice.MSG_USERNAME, "") msg.Option(ice.WEB_SESS, "") msg.R, msg.W = r, w @@ -250,9 +256,8 @@ func (web *Frame) HandleCmd(m *ice.Message, key string, cmd *ice.Command) { // 请求参数 for k, v := range r.Form { - msg.Optionv(k, v) - if k == ice.MSG_SESSID { - Cookie(msg, v[0]) + if msg.Optionv(k, v); k == ice.MSG_SESSID { + Render(msg, "cookie", v[0]) } } @@ -262,42 +267,19 @@ func (web *Frame) HandleCmd(m *ice.Message, key string, cmd *ice.Command) { return } + // 解析命令 if msg.Optionv("cmds") == nil { msg.Optionv("cmds", strings.Split(msg.Option(ice.MSG_USERURL), "/")[2:]) } cmds := kit.Simple(msg.Optionv("cmds")) // 执行命令 - if msg.Option("proxy") != "" { - msg.Cmd(ice.WEB_PROXY, msg.Option("proxy"), msg.Option(ice.MSG_USERURL), cmds) - } else { - msg.Target().Run(msg, cmd, msg.Option(ice.MSG_USERURL), cmds...) - } + msg.Target().Run(msg, cmd, msg.Option(ice.MSG_USERURL), cmds...) // 输出响应 switch msg.Append("_output") { - case "void": - case "status": - msg.Info("status %s", msg.Result()) - w.WriteHeader(kit.Int(kit.Select("200", msg.Result(0)))) - - case "redirect": - http.Redirect(w, r, msg.Result(), 302) - - case "file": - msg.Info("_output: %s %s", msg.Append("_output"), msg.Append("file")) - w.Header().Set("Content-Disposition", fmt.Sprintf("filename=%s", kit.Select(msg.Append("name"), msg.Append("story")))) - w.Header().Set("Content-Type", kit.Select("text/html", msg.Append("type"))) - http.ServeFile(w, r, msg.Append("file")) - - case "qrcode": - if qr, e := qrcode.New(msg.Result(), qrcode.Medium); m.Assert(e) { - w.Header().Set("Content-Type", "image/png") - m.Assert(qr.Write(256, w)) - } - + case "render": case "result": - w.Header().Set("Content-Type", kit.Select("text/html", msg.Append("type"))) fmt.Fprint(w, msg.Result()) default: fmt.Fprint(w, msg.Formats("meta")) @@ -341,8 +323,10 @@ func (web *Frame) ServeHTTP(w http.ResponseWriter, r *http.Request) { // 初始化成功 m.Conf(ice.WEB_SERVE, "meta.init", "true") } - w.Write([]byte(Refresh(m, 5))) + m.W = w + Render(m, "refresh") m.Event(ice.SYSTEM_INIT) + m.W = nil } else { web.ServeMux.ServeHTTP(w, r) } @@ -483,16 +467,8 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", m.Conf(ice.WEB_FAVOR, "meta.template", favor_template) }}, ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - p := m.Conf(ice.WEB_CACHE, "meta.store") - m.Richs(ice.WEB_CACHE, nil, "*", func(key string, value map[string]interface{}) { - if f, _, e := kit.Create(path.Join(p, key[:2], key)); e == nil { - defer f.Close() - f.WriteString(kit.Formats(value)) - } - }) - // m.Conf(ice.WEB_CACHE, "hash", kit.Dict()) - m.Save(ice.WEB_FAVOR, ice.WEB_CACHE, ice.WEB_STORY, ice.WEB_SHARE, - ice.WEB_SPIDE, ice.WEB_SERVE) + m.Save(ice.WEB_SPIDE, ice.WEB_SERVE, + ice.WEB_FAVOR, ice.WEB_CACHE, ice.WEB_STORY, ice.WEB_SHARE) m.Done() m.Richs(ice.WEB_SPACE, nil, "*", func(key string, value map[string]interface{}) { @@ -971,10 +947,10 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", ), List: kit.List( kit.MDB_INPUT, "text", "name", "favor", "action", "auto", kit.MDB_INPUT, "text", "name", "id", "action", "auto", - kit.MDB_INPUT, "button", "value", "查看", "action", "auto", - kit.MDB_INPUT, "button", "value", "返回", "cb", "Last", - kit.MDB_INPUT, "button", "value", "渲染", - kit.MDB_INPUT, "button", "value", "回放", + kit.MDB_INPUT, "button", "name", "查看", "action", "auto", + kit.MDB_INPUT, "button", "name", "返回", "cb", "Last", + kit.MDB_INPUT, "button", "name", "渲染", + kit.MDB_INPUT, "button", "name", "回放", ), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { switch m.Option("_action") { case "渲染": @@ -1055,6 +1031,37 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", return } + switch arg[0] { + case "sync": + m.Richs(ice.WEB_FAVOR, nil, arg[1], func(key string, value map[string]interface{}) { + count := kit.Int(kit.Value(value, kit.Keys("meta.count"))) + + pull := kit.Int(kit.Value(value, kit.Keys("meta.remote", arg[2], "pull"))) + 1 + pull = 1 + m.Cmd(ice.WEB_SPIDE, arg[2], "msg", "/favor/pull", "favor", arg[3], "begin", pull).Table(func(index int, value map[string]string, head []string) { + kit.Value(value, kit.Keys("meta.remote", arg[2], arg[3], "pull"), value["id"]) + m.Log(ice.LOG_IMPORT, "%v", value) + m.Grow(ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, key), kit.Dict( + kit.MDB_TYPE, value["type"], kit.MDB_NAME, value["name"], kit.MDB_TEXT, value["text"], + "extra", kit.UnMarshal(value["extra"]), + )) + }) + + push := kit.Int(kit.Value(value, kit.Keys("meta.remote", arg[0], "push"))) + 1 + push = 1 + for i := push; i <= count; i++ { + m.Grows(ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, key), "id", kit.Format(i), func(index int, value map[string]interface{}) { + kit.Value(value, kit.Keys("meta.remote", arg[2], arg[3], "push"), value["id"]) + m.Cmd(ice.WEB_SPIDE, arg[2], "msg", "/favor/push", "favor", arg[3], + "type", value["type"], "name", value["name"], "text", value["text"], + "time", value["time"], "extra", kit.Format(value["extra"]), + ) + }) + } + return + }) + } + m.Option("favor", arg[0]) fields := []string{kit.MDB_TIME, kit.MDB_ID, kit.MDB_TYPE, kit.MDB_NAME, kit.MDB_TEXT} if len(arg) > 1 && arg[1] == "extra" { @@ -1671,42 +1678,36 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", switch kit.Select("", arg, 1) { case "download", "下载": - if m.Append("_output", "file"); strings.HasPrefix(kit.Format(value["text"]), m.Conf(ice.WEB_CACHE, "meta.path")) { - m.Append("type", value["type"]) - m.Append("name", value["name"]) - m.Append("file", value["text"]) + if strings.HasPrefix(kit.Format(value["text"]), m.Conf(ice.WEB_CACHE, "meta.path")) { + Render(m, "download", value["text"], value["type"], value["name"]) } else { - m.Append("_output", "result") - m.Echo("%s", value["text"]) + Render(m, "%s", value["text"]) } return case "detail", "详情": - m.Append("_output", "result") - m.Echo(kit.Formats(value)) + Render(m, kit.Formats(value)) return case "share", "共享码": - m.Append("_output", "qrcode") - m.Echo("%s/%s/", m.Conf(ice.WEB_SHARE, "meta.domain"), key) + Render(m, "qrcode", kit.Format("%s/%s/", m.Conf(ice.WEB_SHARE, "meta.domain"), key)) return case "value", "数据值": - m.Append("_output", "qrcode") - m.Echo("%s", value["text"]) + Render(m, "%s", value["text"]) return } switch value["type"] { case ice.TYPE_RIVER: // 共享群组 - Redirect(m, "/", "share", key, "river", value["text"]) + Render(m, "redirect", "/", "share", key, "river", kit.Format(value["text"])) case ice.TYPE_STORM: // 共享应用 - Redirect(m, "/", "share", key, "storm", value["text"], "river", kit.Value(value, "extra.river")) + Render(m, "redirect", "/", "share", key, "storm", kit.Format(value["text"]), "river", kit.Format(kit.Value(value, "extra.river"))) case ice.TYPE_ACTION: if len(arg) == 1 { // 跳转主页 - Redirect(m, "/share/"+arg[0]+"/", "title", value["name"]) + Render(m, "redirect", "/share/"+arg[0]+"/", "title", kit.Format(value["name"])) break } @@ -1757,8 +1758,7 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", case ice.TYPE_ACTIVE: // 扫码数据 - m.Append("_output", "qrcode") - m.Echo(kit.Format(value)) + Render(m, "qrcode", kit.Format(value)) default: // 查看数据 @@ -1829,7 +1829,28 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", case ice.STORY_DOWNLOAD: // 下载数据 m.Cmdy(ice.WEB_STORY, ice.STORY_INDEX, arg[1]) - m.Push("_output", kit.Select("file", "result", m.Append("file") == "")) + Render(m, kit.Select("download", "result", m.Append("file") == ""), m.Append("text")) + } + }}, + "/favor/": {Name: "/story/", Help: "故事会", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + switch arg[0] { + case "pull": + m.Richs(ice.WEB_FAVOR, nil, m.Option("favor"), func(key string, value map[string]interface{}) { + m.Option("cache.limit", kit.Int(kit.Value(value, "meta.count"))+1-kit.Int(m.Option("begin"))) + m.Grows(ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) { + m.Log(ice.LOG_EXPORT, "%v", value) + m.Push("", value, []string{"id", "type", "name", "text"}) + m.Push("extra", kit.Format(value["extra"])) + }) + }) + case "push": + m.Richs(ice.WEB_FAVOR, nil, m.Option("favor"), func(key string, value map[string]interface{}) { + m.Log(ice.LOG_IMPORT, "%v", value) + m.Grow(ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, key), kit.Dict( + kit.MDB_TYPE, m.Option("type"), kit.MDB_NAME, m.Option("name"), kit.MDB_TEXT, m.Option("text"), + "extra", kit.UnMarshal(m.Option("extra")), + )) + }) } }}, "/space/": {Name: "/space/", Help: "空间站", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { @@ -1837,7 +1858,7 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", switch list[2] { case "login": - m.Option(ice.MSG_SESSID, Cookie(m, m.Cmdx(ice.AAA_USER, "login", m.Option("username"), m.Option("password")))) + m.Option(ice.MSG_SESSID, Render(m, "cookie", m.Cmdx(ice.AAA_USER, "login", m.Option("username"), m.Option("password")))) return case "share": m.Cmdy(ice.WEB_SHARE, list[3:]) @@ -1889,8 +1910,7 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", path.Join("usr/volcanos", strings.Join(strings.Split(cmd, "/")[3:7], "/"))) } - m.Push("_output", "void") - http.ServeFile(m.W, m.R, path.Join("usr/volcanos", file)) + Render(m, "download", path.Join("usr/volcanos", file)) }}, "/plugin/github.com/": {Name: "/space/", Help: "空间站", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if _, e := os.Stat(path.Join("usr/volcanos", cmd)); e != nil { @@ -1898,8 +1918,7 @@ var Index = &ice.Context{Name: "web", Help: "网络模块", path.Join("usr/volcanos", strings.Join(strings.Split(cmd, "/")[1:5], "/"))) } - m.Push("_output", "void") - http.ServeFile(m.W, m.R, path.Join("usr/volcanos", cmd)) + Render(m, "download", path.Join("usr/volcanos", cmd)) }}, }, } diff --git a/conf.go b/conf.go index 680e822b..ae6c3dbc 100644 --- a/conf.go +++ b/conf.go @@ -86,19 +86,19 @@ const ( // LOG // 数据 LOG_ENABLE = "enable" LOG_IMPORT = "import" + LOG_EXPORT = "export" LOG_CREATE = "create" + LOG_REMOVE = "remove" LOG_INSERT = "insert" + LOG_DELETE = "delete" LOG_SELECT = "select" LOG_MODIFY = "modify" - LOG_DELETE = "delete" - LOG_REMOVE = "remove" - LOG_EXPORT = "export" // 事件 LOG_LISTEN = "listen" LOG_SIGNAL = "signal" - LOG_TIMERS = "timers" LOG_EVENTS = "events" + LOG_TIMERS = "timers" // 状态 LOG_BEGIN = "begin" @@ -165,6 +165,7 @@ const ( // ROLE ) const ( // CHAT CHAT_RIVER = "river" + CHAT_STORM = "storm" ) const ( // TYPE TYPE_SPIDE = "spide" diff --git a/core/chat/chat.go b/core/chat/chat.go index d6fbd4ce..170b3ff0 100644 --- a/core/chat/chat.go +++ b/core/chat/chat.go @@ -2,7 +2,6 @@ package chat import ( "github.com/shylinux/icebergs" - _ "github.com/shylinux/icebergs/base" "github.com/shylinux/icebergs/base/web" "github.com/shylinux/toolkits" ) @@ -55,6 +54,7 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心", []interface{}{"field", "note", "web.wiki"}, }), "black", kit.Dict("void", []interface{}{ + []interface{}{"/debug"}, []interface{}{"/river", "add"}, []interface{}{"/river", "share"}, []interface{}{"/river", "rename"}, @@ -65,6 +65,10 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心", []interface{}{"/storm", "add"}, }), "white", kit.Dict("void", []interface{}{ + []interface{}{"/toast"}, + []interface{}{"/carte"}, + []interface{}{"/tutor"}, + []interface{}{"/login"}, []interface{}{"/river"}, []interface{}{"/storm"}, []interface{}{"/action"}, @@ -75,9 +79,9 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心", }, Commands: map[string]*ice.Command{ ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Watch(ice.USER_CREATE, m.Prefix(ice.WEB_LOGIN), "init") - m.Watch(ice.SYSTEM_INIT, m.Prefix("init")) m.Load() + m.Watch(ice.SYSTEM_INIT, m.Prefix("init")) + m.Watch(ice.USER_CREATE, m.Prefix("auto")) }}, ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Save("river") @@ -103,8 +107,7 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心", m.Cmd(ice.AAA_ROLE, "white", ice.ROLE_VOID, "enable", value) }) } - - // 用户权限 + // 超级用户 m.Cmd(ice.AAA_USER, "first", m.Conf(ice.CLI_RUNTIME, "boot.username")) } @@ -113,50 +116,58 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心", m.Cap(ice.CTX_STREAM, m.Conf(ice.CHAT_RIVER, "meta.fe")) m.Cap(ice.CTX_STATUS, "start") }}, - ice.WEB_LOGIN: {Name: "_login", Help: "登录", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + "auto": {Name: "auto user", Help: "自动化", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Richs(ice.AAA_USER, nil, arg[0], func(key string, value map[string]interface{}) { + m.Option(ice.MSG_USERNAME, value["username"]) + m.Option(ice.MSG_USERROLE, m.Cmdx(ice.AAA_ROLE, "check", value["username"])) + + if len(arg[0]) > 8 { + arg[0] = arg[0][:8] + } + + // 创建群组 + name := kit.Select(arg[0], value["nickname"]) + "@" + m.Conf(ice.CLI_RUNTIME, "boot.hostname") + storm, river := "", m.Option(ice.MSG_RIVER, m.Cmdx("/ocean", "spawn", name, m.Option(ice.MSG_USERNAME))) + + // 创建应用 + m.Option("cache.limit", -2) + m.Richs(ice.WEB_FAVOR, nil, kit.Keys("river", m.Option(ice.MSG_USERROLE)), func(key string, value map[string]interface{}) { + m.Grows(ice.WEB_FAVOR, kit.Keys("hash", key), "", "", func(index int, value map[string]interface{}) { + switch value["type"] { + case "storm": + storm = m.Option(ice.MSG_STORM, m.Cmdx("/steam", river, "spawn", value["name"])) + case "field": + m.Cmd("/storm", river, storm, "add", "", kit.Select("", value["text"]), value["name"], "") + } + }) + }) + }) + }}, + + ice.WEB_LOGIN: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Option(ice.MSG_RIVER, "") + m.Option(ice.MSG_STORM, "") + if len(arg) > 0 { switch arg[0] { case "login": - // 用户登录 - m.Option(ice.MSG_SESSID, web.Cookie(m, m.Cmdx(ice.AAA_USER, "login", m.Option(ice.MSG_USERNAME, arg[1]), arg[2]))) - - case "init": - // 用户创建 - m.Richs(ice.AAA_USER, nil, arg[1], func(key string, value map[string]interface{}) { - m.Option(ice.MSG_USERNAME, value["username"]) - m.Option(ice.MSG_USERROLE, m.Cmdx(ice.AAA_ROLE, "check", value["username"])) - - name := kit.Select(arg[1], value["nickname"]) + "@" + m.Conf(ice.CLI_RUNTIME, "boot.hostname") - if len(arg[1]) > 8 { - name = kit.Select(arg[1][:8], value["nickname"]) + "@" + m.Conf(ice.CLI_RUNTIME, "boot.hostname") - } - - // 创建群组 - storm, river := "", m.Option(ice.MSG_RIVER, m.Cmdx("/ocean", "spawn", name, m.Option(ice.MSG_USERNAME))) - - // 创建应用 - m.Option("cache.limit", "100") - m.Richs(ice.WEB_FAVOR, nil, kit.Keys("river", m.Option(ice.MSG_USERROLE)), func(key string, value map[string]interface{}) { - m.Grows(ice.WEB_FAVOR, kit.Keys("hash", key), "", "", func(index int, value map[string]interface{}) { - switch value["type"] { - case "storm": - storm = m.Option(ice.MSG_STORM, m.Cmdx("/steam", river, "spawn", value["name"])) - case "field": - m.Cmd("/storm", river, storm, "add", "", kit.Select("", value["text"]), value["name"], "") - } - }) - }) - }) + // 密码登录 + if len(arg) > 2 { + m.Option(ice.MSG_SESSID, web.Render(m, "cookie", m.Cmdx(ice.AAA_USER, "login", m.Option(ice.MSG_USERNAME, arg[1]), arg[2]))) + } default: - // 用户群组 - m.Richs(ice.CHAT_RIVER, nil, arg[0], func(value map[string]interface{}) { - if m.Option(ice.MSG_RIVER, arg[0]); len(arg) > 1 { - m.Richs(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0], "tool"), arg[1], func(value map[string]interface{}) { - m.Option(ice.MSG_STORM, arg[1]) - }) - } - m.Info("river: %s storm: %s", m.Option(ice.MSG_RIVER), m.Option(ice.MSG_STORM)) + // 群组检查 + m.Richs(ice.CHAT_RIVER, nil, arg[0], func(key string, value map[string]interface{}) { + m.Richs(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0], "user"), m.Option(ice.MSG_USERNAME), func(key string, value map[string]interface{}) { + if m.Option(ice.MSG_RIVER, arg[0]); len(arg) > 1 { + // 应用检查 + m.Richs(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0], "tool"), arg[1], func(key string, value map[string]interface{}) { + m.Option(ice.MSG_STORM, arg[1]) + }) + } + m.Log(ice.LOG_LOGIN, "river: %s storm: %s", m.Option(ice.MSG_RIVER), m.Option(ice.MSG_STORM)) + }) }) } } @@ -166,33 +177,24 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心", // 登录检查 if m.Warn(!m.Options(ice.MSG_SESSID) || !m.Options(ice.MSG_USERNAME), "not login") { + web.Render(m, "status", 401, "not login") m.Option(ice.MSG_USERURL, "") - m.Push("_output", "status") - m.Set("result").Echo("401") return } // 权限检查 - if !m.Right(m.Option(ice.MSG_USERURL), m.Optionv("cmds")) { + if m.Warn(!m.Right(m.Option(ice.MSG_USERURL), m.Optionv("cmds")), "not auth") { + web.Render(m, "status", 403, "not auth") m.Option(ice.MSG_USERURL, "") - m.Push("_output", "status") - m.Set("result").Echo("403") return } }}, "/toast": {Name: "/toast", Help: "提示", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}}, "/carte": {Name: "/carte", Help: "菜单", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}}, - "/debug": {Name: "/debug", Help: "调试", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}}, "/tutor": {Name: "/tutor", Help: "向导", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}}, - "/favor": {Name: "/favor", Help: "收藏", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Hand = false - if msg := m.Cmd(arg); !msg.Hand { - m.Set("result").Cmdy(ice.CLI_SYSTEM, arg) - } else { - m.Copy(msg) - } - }}, + "/debug": {Name: "/debug", Help: "调试", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}}, + "/input": {Name: "/input", Help: "输入", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}}, "/login": {Name: "/login", Help: "登录", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { switch arg[0] { case "check": @@ -254,8 +256,7 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心", } }}, "/river": {Name: "/river", Help: "小河流", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - switch len(arg) { - case 0: + if len(arg) < 2 { // 群组列表 m.Richs(ice.CHAT_RIVER, nil, "*", func(key string, value map[string]interface{}) { m.Richs(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, key, "user"), m.Option(ice.MSG_USERNAME), func(k string, val map[string]interface{}) { @@ -263,45 +264,44 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心", }) }) m.Log(ice.LOG_SELECT, "%s", m.Format("append")) - case 1: - // 群组详情 - m.Richs(ice.CHAT_RIVER, nil, arg[0], func(key string, value map[string]interface{}) { - m.Push(key, value["meta"], []string{kit.MDB_KEY, kit.MDB_NAME}) + return + } + + if !m.Right(cmd, arg[1]) { + web.Render(m, "status", 403, "not auth") + return + } + + switch arg[1] { + case "add": + m.Rich(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0], "user"), kit.Data("username", m.Conf(ice.CLI_RUNTIME, "boot.username"))) + // 添加用户 + for _, v := range arg[2:] { + user := m.Rich(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0], "user"), kit.Data("username", v)) + m.Log(ice.LOG_INSERT, "river: %s user: %s name: %s", arg[0], user, v) + } + case "rename": + // 重命名群组 + old := m.Conf(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0], kit.MDB_META, kit.MDB_NAME)) + m.Log(ice.LOG_MODIFY, "river: %s %s->%s", arg[0], old, arg[2]) + m.Conf(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0], kit.MDB_META, kit.MDB_NAME), arg[2]) + + case "remove": + // 删除群组 + m.Richs(ice.CHAT_RIVER, nil, arg[0], func(value map[string]interface{}) { + m.Log(ice.LOG_REMOVE, "river: %s value: %s", arg[0], kit.Format(value)) }) - default: - if !m.Right(cmd, arg[1]) { - // 没有权限 - m.Push("_output", "status") - m.Set("result").Echo("403") - break - } - - switch arg[1] { - case "add": - m.Rich(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0], "user"), kit.Data("username", m.Conf(ice.CLI_RUNTIME, "boot.username"))) - // 添加用户 - for _, v := range arg[2:] { - user := m.Rich(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0], "user"), kit.Data("username", v)) - m.Log(ice.LOG_INSERT, "river: %s user: %s name: %s", arg[0], user, v) - } - case "rename": - // 重命名群组 - old := m.Conf(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0], kit.MDB_META, kit.MDB_NAME)) - m.Log(ice.LOG_MODIFY, "river: %s %s->%s", arg[0], old, arg[2]) - m.Conf(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0], kit.MDB_META, kit.MDB_NAME), arg[2]) - - case "remove": - // 删除群组 - m.Richs(ice.CHAT_RIVER, nil, arg[0], func(value map[string]interface{}) { - m.Log(ice.LOG_REMOVE, "river: %s value: %s", arg[0], kit.Format(value)) - }) - m.Conf(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0]), "") - } + m.Conf(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0]), "") } }}, "/storm": {Name: "/storm", Help: "暴风雨", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if m.Warn(m.Option(ice.MSG_RIVER) == "", "not join") { + web.Render(m, "status", 402, "not join") + return + } + prefix := kit.Keys(kit.MDB_HASH, arg[0], "tool") - if len(arg) < 2 { + if len(arg) < 3 { // 应用列表 m.Richs(ice.CHAT_RIVER, prefix, "*", func(key string, value map[string]interface{}) { m.Push(key, value["meta"], []string{kit.MDB_KEY, kit.MDB_NAME}) @@ -310,18 +310,9 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心", m.Sort(kit.MDB_NAME) return } - if len(arg) == 2 { - // 应用详情 - m.Richs(ice.CHAT_RIVER, prefix, arg[1], func(key string, value map[string]interface{}) { - m.Push(key, value["meta"], []string{kit.MDB_KEY, kit.MDB_NAME}) - }) - return - } if !m.Right(cmd, arg[2]) { - // 没有权限 - m.Push("_output", "status") - m.Set("result").Echo("403") + web.Render(m, "status", 403, "not auth") return } @@ -350,22 +341,29 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心", } }}, "/steam": {Name: "/steam", Help: "大气层", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if m.Warn(m.Option(ice.MSG_RIVER) == "", "not join") { + web.Render(m, "status", 402, "not join") + return + } + if len(arg) < 2 { - if pod := m.Option("pod"); pod != "" { - // 远程命令 - m.Option("pod", "") - list := []string{} - m.Cmdy(ice.WEB_SPACE, pod, "web.chat./steam").Table(func(index int, value map[string]string, head []string) { - list = append(list, pod+"."+value["name"]) + if list := []string{}; m.Option("pod") != "" { + // 远程空间 + m.Cmdy(ice.WEB_SPACE, m.Option("pod"), "web.chat./steam").Table(func(index int, value map[string]string, head []string) { + list = append(list, kit.Keys(m.Option("pod"), value["name"])) }) m.Append("name", list) - return + } else { + // 本地空间 + m.Richs(ice.WEB_SPACE, nil, "*", func(key string, value map[string]interface{}) { + m.Push(key, value, []string{"type", "name", "user"}) + }) } + return + } - // 设备列表 - m.Richs(ice.WEB_SPACE, nil, "*", func(key string, value map[string]interface{}) { - m.Push(key, value, []string{"type", "name", "user"}) - }) + if !m.Right(cmd, arg[1]) { + web.Render(m, "status", 403, "not auth") return } @@ -376,12 +374,12 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心", kit.MDB_META, kit.Dict(kit.MDB_NAME, arg[2]), )) m.Log(ice.LOG_CREATE, "storm: %s name: %v", storm, arg[2]) - // 添加工具 + // 添加命令 m.Cmd("/storm", arg[0], storm, "add", arg[3:]) m.Echo(storm) case "append": - // 追加工具 + // 追加命令 m.Cmd("/storm", arg[0], arg[2], "add", arg[3:]) default: @@ -396,6 +394,11 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心", "/target": {Name: "/target", Help: "对话框", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}}, "/source": {Name: "/source", Help: "输入框", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}}, "/action": {Name: "/action", Help: "工作台", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if m.Warn(m.Option(ice.MSG_RIVER) == "" || m.Option(ice.MSG_STORM) == "", "not join") { + web.Render(m, "status", 402, "not join") + return + } + prefix := kit.Keys(kit.MDB_HASH, arg[0], "tool", kit.MDB_HASH, arg[1]) if len(arg) == 2 { // 命令列表 @@ -439,8 +442,8 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心", cmds := []string{} m.Grows(ice.CHAT_RIVER, prefix, kit.MDB_ID, kit.Format(kit.Int(arg[2])+1), func(index int, value map[string]interface{}) { if meta, ok := kit.Value(value, "meta").(map[string]interface{}); ok { - // 命令补全 if len(arg) > 3 && arg[3] == "action" { + // 命令补全 switch arg[4] { case "input": switch arg[5] { @@ -453,21 +456,16 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心", case "favor": m.Cmdy(ice.WEB_FAVOR, arg[5:]) return + case "location": // 记录位置 m.Cmdy("aaa.location", arg[5:]) return + case "upload": m.Cmdy(ice.WEB_STORY, "upload") return - case "story": - // cmds := kit.Split(arg[7]) - // if m.Right(cmds, arg[8:]) { - // m.Cmdy(cmds, arg[8:]) - // } - // return - case "share": list := []string{} for k, v := range meta { @@ -485,16 +483,12 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心", }) if len(cmds) == 0 { - // 没有命令 - m.Push("_output", "status") - m.Set("result").Echo("404") + web.Render(m, "status", 404, "not found") return } if !m.Right(cmds) { - // 没有权限 - m.Push("_output", "status") - m.Set("result").Echo("403") + web.Render(m, "status", 403, "not auth") return } @@ -508,7 +502,6 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心", // 执行命令 m.Cmdy(proxy, cmds).Option("cmds", cmds) - // m.Cmd(ice.WEB_FAVOR, "cmd.history", "cmd", m.Option(ice.MSG_SESSID)[:6], strings.Join(cmds, " ")) }}, }, } diff --git a/go.sum b/go.sum index e8cc7540..2ab98fcf 100644 --- a/go.sum +++ b/go.sum @@ -4,6 +4,8 @@ github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvK github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/shylinux/toolkits v0.1.2 h1:yP24DXfcU5c7u3NVAxCGiMy5UMBRQH4gkKUZXOIN5fk= github.com/shylinux/toolkits v0.1.2/go.mod h1:Y68Ot6xOmo1bun67YvqC3chDGeU2gDxtsUnvVDGJm4g= +github.com/shylinux/toolkits v0.1.3 h1:bqxmbPFBKkOpv9uEb4bbeeovowsiBK7zDrPrQMUDlSc= +github.com/shylinux/toolkits v0.1.3/go.mod h1:Y68Ot6xOmo1bun67YvqC3chDGeU2gDxtsUnvVDGJm4g= github.com/skip2/go-qrcode v0.0.0-20191027152451-9434209cb086 h1:RYiqpb2ii2Z6J4x0wxK46kvPBbFuZcdhS+CIztmYgZs= github.com/skip2/go-qrcode v0.0.0-20191027152451-9434209cb086/go.mod h1:PLPIyL7ikehBD1OAjmKKiOEhbvWyHGaNDjquXMcYABo= golang.org/dl v0.0.0-20190829154251-82a15e2f2ead/go.mod h1:IUMfjQLJQd4UTqG1Z90tenwKoCX93Gn3MAQJMOSBsDQ= diff --git a/misc/lark/lark.go b/misc/lark/lark.go index dbbbc96d..baf62486 100644 --- a/misc/lark/lark.go +++ b/misc/lark/lark.go @@ -276,7 +276,7 @@ var Index = &ice.Context{Name: "lark", Help: "机器人", switch parse(m); m.Option("msg.type") { case "url_verification": // 绑定验证 - m.Push("_output", "result") + m.Append("_output", "result") m.Echo(kit.Format(map[string]interface{}{"challenge": m.Option("msg.challenge")})) case "event_callback": diff --git a/misc/mp/mp.go b/misc/mp/mp.go index 725ce12e..f911c8e6 100644 --- a/misc/mp/mp.go +++ b/misc/mp/mp.go @@ -55,11 +55,11 @@ var Index = &ice.Context{Name: "mp", Help: "小程序", }) case "scan": - m.Echo(m.Option("scan")).Push("_output", "qrcode") + web.Render(m, "qrcode", m.Option("scan")) case "auth": if !m.Options(ice.MSG_USERNAME) || !m.Options(ice.MSG_SESSID) { - m.Echo("401").Push("_output", "status") + web.Render(m, "status", 401, "not login") break } switch kit.Select("active", m.Option("type")) { diff --git a/misc/tmux/tmux.go b/misc/tmux/tmux.go index bb3163d5..adc00636 100644 --- a/misc/tmux/tmux.go +++ b/misc/tmux/tmux.go @@ -346,7 +346,7 @@ var Index = &ice.Context{Name: "tmux", Help: "工作台", switch arg = kit.Split(kit.Select("tmux.auto", arg, 0)); arg[0] { default: - m.Append("_output", "void") + m.Append("_output", "result") m.Cmd("auto", current, arg) } }}, diff --git a/misc/wx/wx.go b/misc/wx/wx.go index 66af56f0..b8c84bb4 100644 --- a/misc/wx/wx.go +++ b/misc/wx/wx.go @@ -32,11 +32,11 @@ func parse(m *ice.Message) { } func reply(m *ice.Message) { - m.Push("_output", "result") + m.Append("_output", "result") m.Render(m.Conf("login", "meta.template.text")) } func action(m *ice.Message) { - m.Push("_output", "result") + m.Append("_output", "result") m.Echo(`