1
0
mirror of https://shylinux.com/x/icebergs synced 2025-04-25 17:18:05 +08:00
This commit is contained in:
shaoying 2020-09-22 20:40:07 +08:00
parent 306e8d2f60
commit 40b4e1756a
11 changed files with 338 additions and 456 deletions

View File

@ -17,12 +17,14 @@ func _user_list(m *ice.Message) {
m.Sort(USERNAME)
}
func _user_login(m *ice.Message, name, word string) (ok bool) {
m.Debug("what %v %v", name, word)
if m.Richs(USER, nil, name, nil) == nil {
_user_create(m, name, "")
}
m.Richs(USER, nil, name, func(key string, value map[string]interface{}) {
if value[PASSWORD] == "" {
m.Debug("what %v %v", name, word)
if kit.Format(value[PASSWORD]) == "" {
ok, value[PASSWORD] = true, word
} else if value[PASSWORD] == word {
ok = true

View File

@ -1,7 +1,10 @@
package ctx
import (
"strings"
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/mdb"
kit "github.com/shylinux/toolkits"
)
@ -58,6 +61,33 @@ var Index = &ice.Context{Name: "ctx", Help: "配置模块",
})
}
}},
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmd(mdb.SEARCH, mdb.CREATE, COMMAND, m.AddCmd(&ice.Command{Hand: func(m *ice.Message, c *ice.Context, cc string, arg ...string) {
arg = arg[1:]
ice.Pulse.Travel(func(p *ice.Context, s *ice.Context, key string, cmd *ice.Command) {
if strings.HasPrefix(key, "_") || strings.HasPrefix(key, "/") {
return
}
if arg[1] != "" && arg[1] != key && arg[1] != s.Name {
return
}
if arg[2] != "" && !strings.Contains(kit.Format(cmd.Name), arg[2]) && !strings.Contains(kit.Format(cmd.Help), arg[2]) {
return
}
m.Push("pod", "")
m.Push("ctx", "web.chat")
m.Push("cmd", cc)
m.Push("time", m.Time())
m.Push("size", "")
m.Push("type", COMMAND)
m.Push("name", key)
m.Push("text", s.Cap(ice.CTX_FOLLOW))
})
}}))
}},
},
}

View File

@ -147,13 +147,17 @@ func _list_insert(m *ice.Message, prefix, key string, arg ...string) int {
func _list_delete(m *ice.Message, prefix, chain, field, value string) {
}
func _list_select(m *ice.Message, prefix, key, field, value string) {
fields := strings.Split(kit.Select("time,type,name,text", m.Option("fields")), ",")
fields := strings.Split(kit.Select("time,type,name,text", m.Option(FIELDS)), ",")
m.Grows(prefix, key, field, value, func(index int, val map[string]interface{}) {
if field == kit.MDB_ID && value != "" {
m.Push("detail", val)
return
if val[kit.MDB_META] != nil {
val = val[kit.MDB_META].(map[string]interface{})
}
if m.Option(FIELDS) == "detail" {
m.Push("detail", val)
} else {
m.Push(key, val, fields, val[kit.MDB_META])
}
m.Push("", val, fields, val[kit.MDB_META])
})
if m.Option(FIELDS) != "detail" {
m.Sort(kit.MDB_ID, "int_r")

View File

@ -4,7 +4,6 @@ import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa"
"github.com/shylinux/icebergs/base/cli"
"github.com/shylinux/icebergs/base/gdb"
"github.com/shylinux/icebergs/base/mdb"
"github.com/shylinux/icebergs/base/tcp"
kit "github.com/shylinux/toolkits"
@ -13,7 +12,6 @@ import (
"encoding/json"
"net/http"
"net/url"
"os"
"path"
"strings"
)
@ -193,16 +191,7 @@ func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool {
r.URL.Path = strings.Replace(r.URL.Path, "/debug", "/code", -1)
}
if r.URL.Path == "/" && m.Conf(SERVE, "meta.init") != "true" && len(ice.BinPack) == 0 {
if _, e := os.Stat(m.Conf(SERVE, "meta.volcanos.path")); e == nil {
// 初始化成功
m.Conf(SERVE, "meta.init", "true")
}
m.W = w
Render(m, "refresh", m.Conf(SERVE, "meta.volcanos.refresh"))
m.Event(gdb.SYSTEM_INIT)
m.W = nil
} else if r.URL.Path == "/" && m.Conf(SERVE, "meta.sso") != "" {
if r.URL.Path == "/" && m.Conf(SERVE, "meta.sso") != "" {
if r.ParseForm(); r.FormValue(ice.MSG_SESSID) != "" {
return true
}
@ -220,7 +209,7 @@ func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool {
}
return true
} else if r.URL.Path == "/share" && r.Method == "GET" {
http.ServeFile(w, r, m.Conf(SERVE, "meta.page.share"))
http.ServeFile(w, r, m.Conf(SERVE, "meta.volcanos.share"))
} else {
if b, ok := ice.BinPack[r.URL.Path]; ok {
log.Info("BinPack %v %v", r.URL.Path, len(b))
@ -241,9 +230,10 @@ func init() {
Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{
SERVE: {Name: "serve", Help: "服务器", Value: kit.Data(
"init", "false", "logheaders", "false",
"logheaders", "false",
"black", kit.Dict(),
"white", kit.Dict(
"header", true,
"login", true,
"share", true,
"space", true,
@ -254,19 +244,18 @@ func init() {
),
"intshell", kit.Dict(
"path", "usr/intshell", "index", "index.sh", "require", ".ish/pluged",
"index", "index.sh",
"path", "usr/intshell", "require", ".ish/pluged",
"repos", "https://github.com/shylinux/volcanos", "branch", "master",
),
"static", kit.Dict("/", "usr/volcanos/"),
"volcanos", kit.Dict("refresh", "5",
"share", "usr/volcanos/page/share.html",
"path", "usr/volcanos", "require", ".ish/pluged",
"repos", "https://github.com/shylinux/volcanos", "branch", "master",
), "page", kit.Dict(
"index", "usr/volcanos/page/index.html",
"share", "usr/volcanos/page/share.html",
), "publish", "usr/publish/",
"static", kit.Dict("/", "usr/volcanos/"),
"template", kit.Dict("path", "usr/template", "list", []interface{}{
`{{define "raw"}}{{.Result}}{{end}}`,
}),

View File

@ -67,6 +67,24 @@ func _action_order_list(m *ice.Message, river, storm string, arg ...string) {
}
}
func _action_list(m *ice.Message, river, storm string) {
m.Option(ice.MSG_RIVER, river)
m.Cmd(TOOL, storm).Table(func(index int, value map[string]string, head []string) {
m.Push(RIVER, river)
m.Push(STORM, storm)
m.Push(ACTION, value[kit.MDB_ID])
m.Push("node", value[POD])
m.Push("group", value[CTX])
m.Push("index", value[CMD])
msg := m.Cmd(m.Space(value[POD]), ctx.COMMAND, kit.Keys(value[CTX], value[CMD]))
ls := strings.Split(kit.Format(value[CMD]), ".")
m.Push("name", ls[len(ls)-1])
m.Push("help", kit.Select(msg.Append("help"), kit.Format(value["help"])))
m.Push("feature", msg.Append("meta"))
m.Push("inputs", msg.Append("list"))
})
return
if p := m.Option(POD); p != "" {
m.Option(POD, "")
// 代理列表
@ -98,9 +116,32 @@ func _action_list(m *ice.Message, river, storm string) {
}
})
}
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{}) {
if ok = m.Richs(RIVER, kit.Keys(kit.MDB_HASH, key, USER), m.Option(ice.MSG_USERNAME), nil) != nil; ok {
m.Log_AUTH(RIVER, river, STORM, storm)
}
})
}
return ok
}
func _action_show(m *ice.Message, river, storm, index string, arg ...string) {
cmds := []string{index}
prefix := kit.Keys(kit.MDB_HASH, river, TOOL, kit.MDB_HASH, storm)
cmds := []string{}
if m.Grows(RIVER, prefix, kit.MDB_ID, index, func(index int, value map[string]interface{}) {
if cmds = kit.Simple(kit.Keys(value[CTX], value[CMD])); value[POD] != "" {
m.Option(POD, value[POD])
}
}) == nil && m.Warn(!m.Right(cmds), ice.ErrNotAuth) {
m.Debug("what %v", prefix)
return
}
m.Cmdy(_action_proxy(m), cmds, arg)
return
if i, e := strconv.Atoi(index); e == nil {
m.Richs(web.SHARE, nil, m.Option("share"), func(key string, value map[string]interface{}) {
@ -162,8 +203,8 @@ func _action_show(m *ice.Message, river, storm, index string, arg ...string) {
m.Cmdy(_action_proxy(m), cmds)
}
func _action_proxy(m *ice.Message) (proxy []string) {
if m.Option(POD) != "" {
proxy = append(proxy, web.SPACE, m.Option(POD))
if p := m.Option(POD); p != "" {
proxy = append(proxy, web.SPACE, p)
m.Option(POD, "")
}
return proxy
@ -176,7 +217,19 @@ const ACTION = "action"
func init() {
Index.Merge(&ice.Context{Commands: map[string]*ice.Command{
"/" + ACTION: {Name: "/action", Help: "工作台", Action: map[string]*ice.Action{
ACTION: {Name: "action hash auto 添加", Help: "群组", Action: map[string]*ice.Action{
ctx.COMMAND: {Name: "command", Help: "命令", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(ctx.COMMAND, arg[0])
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 {
_action_list(m, m.Option(ice.MSG_RIVER), m.Option(ice.MSG_STORM))
return
}
_action_show(m, m.Option(ice.MSG_RIVER), m.Option(ice.MSG_STORM), arg[0], arg[1:]...)
}},
"/action": {Name: "/action", Help: "工作台", Action: map[string]*ice.Action{
web.SHARE: {Name: "share name text [pod ctx cmd arg]...", Help: "共享", Hand: func(m *ice.Message, arg ...string) {
_action_share_create(m, arg[0], arg[1], arg[2:]...)
}},
@ -191,21 +244,19 @@ func init() {
_action_order_list(m, m.Option(ice.MSG_RIVER), m.Option(ice.MSG_STORM), arg...)
}},
"command": {Name: "command", Help: "命令", Hand: func(m *ice.Message, arg ...string) {
if len(arg) == 1 {
m.Cmdy(ctx.COMMAND, arg[0])
return
}
m.Cmdy(arg[0], arg[1:])
ctx.COMMAND: {Name: "command", Help: "命令", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(ctx.COMMAND, arg[0])
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 {
// 命令列表
_action_list(m, m.Option(ice.MSG_RIVER), m.Option(ice.MSG_STORM))
if m.Warn(!_action_right(m, m.Option(ice.MSG_RIVER, arg[0]), m.Option(ice.MSG_STORM, arg[1])), ice.ErrNotAuth) {
return
}
// 执行命令
_action_show(m, m.Option(ice.MSG_RIVER), m.Option(ice.MSG_STORM), arg[0], arg[1:]...)
if len(arg) == 2 {
_action_list(m, arg[0], arg[1])
return
}
_action_show(m, arg[0], arg[1], arg[2], arg[3:]...)
}},
}}, nil)
}

View File

@ -2,275 +2,35 @@ package chat
import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa"
"github.com/shylinux/icebergs/base/ctx"
"github.com/shylinux/icebergs/base/gdb"
"github.com/shylinux/icebergs/base/mdb"
"github.com/shylinux/icebergs/base/web"
kit "github.com/shylinux/toolkits"
"strings"
)
var Index = &ice.Context{Name: "chat", Help: "聊天中心",
Configs: map[string]*ice.Config{},
const CHAT = "chat"
var Index = &ice.Context{Name: CHAT, Help: "聊天中心",
Commands: map[string]*ice.Command{
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Load()
m.Watch(gdb.SYSTEM_INIT, m.Prefix("init"))
m.Watch(gdb.USER_CREATE, m.Prefix("auto"))
m.Cmd(mdb.SEARCH, mdb.CREATE, ctx.COMMAND, m.AddCmd(&ice.Command{Hand: func(m *ice.Message, c *ice.Context, cc string, arg ...string) {
arg = arg[1:]
ice.Pulse.Travel(func(p *ice.Context, s *ice.Context, key string, cmd *ice.Command) {
if strings.HasPrefix(key, "_") || strings.HasPrefix(key, "/") {
return
}
if arg[1] != "" && arg[1] != key && arg[1] != s.Name {
return
}
if arg[2] != "" && !strings.Contains(kit.Format(cmd.Name), arg[2]) && !strings.Contains(kit.Format(cmd.Help), arg[2]) {
return
}
m.Push("pod", "")
m.Push("ctx", "web.chat")
m.Push("cmd", cc)
m.Push("time", m.Time())
m.Push("size", "")
m.Push("type", ctx.COMMAND)
m.Push("name", key)
m.Push("text", s.Cap(ice.CTX_FOLLOW))
})
}}))
m.Conf(RIVER, "meta.template", kit.Dict(
"base", kit.Dict(
"info", []interface{}{
"web.chat.info",
"web.chat.node",
"web.chat.tool",
"web.chat.user",
},
"miss", []interface{}{
"web.team.task",
"web.team.plan",
"web.wiki.word",
},
),
))
}},
ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Save(RIVER)
}},
"init": {Name: "init", Help: "初始化", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(m.Confm(RIVER, kit.MDB_HASH)) == 0 {
// 黑名单
kit.Fetch(m.Confv(RIVER, "meta.black.tech"), func(index int, value interface{}) {
m.Cmd(aaa.ROLE, aaa.Black, aaa.TECH, value)
})
// 白名单
kit.Fetch(m.Confv(RIVER, "meta.white.void"), func(index int, value interface{}) {
m.Cmd(aaa.ROLE, aaa.White, aaa.VOID, value)
})
}
m.Cap(ice.CTX_STATUS, "start")
}},
"auto": {Name: "auto user", Help: "自动化", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Richs(aaa.USER, nil, arg[0], func(key string, value map[string]interface{}) {
m.Option(ice.MSG_USERNICK, value[aaa.USERNAME])
m.Option(ice.MSG_USERNAME, value[aaa.USERNAME])
// 创建应用
storm, river := "", ""
m.Option("cache.limit", -2)
web.FavorList(m, kit.Keys(c.Cap(ice.CTX_FOLLOW), aaa.UserRole(m, value[aaa.USERNAME])), "").Table(func(index int, value map[string]string, head []string) {
switch value[kit.MDB_TYPE] {
case "river":
name, _ := kit.Render(kit.Format(value["name"]), m)
river = m.Option(ice.MSG_RIVER, m.Cmdx("/ocean", "spawn", string(name)))
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"], "")
}
})
})
}},
web.LOGIN: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Option(ice.MSG_RIVER, m.Option("river"))
m.Option(ice.MSG_STORM, m.Option("storm"))
if len(arg) > 0 {
switch arg[0] {
case "login":
// 密码登录
if len(arg) > 2 && aaa.UserLogin(m, arg[1], arg[2]) {
m.Option(ice.MSG_SESSID, aaa.SessCreate(m, m.Option(ice.MSG_USERNAME), m.Option(ice.MSG_USERROLE)))
web.Render(m, web.COOKIE, m.Option(ice.MSG_SESSID))
}
default:
switch m.Option(ice.MSG_USERURL) {
case "/river":
if len(arg) > 0 {
m.Option(ice.MSG_RIVER, arg[0])
arg = arg[1:]
}
if len(arg) > 1 && arg[1] == "storm" {
m.Option(ice.MSG_STORM, arg[0])
arg = arg[1:]
}
case "/storm":
if len(arg) > 0 {
m.Option(ice.MSG_RIVER, arg[0])
arg = arg[1:]
}
if len(arg) > 0 {
m.Option(ice.MSG_STORM, arg[0])
arg = arg[1:]
}
case "/action":
if len(arg) > 0 {
if arg[0] != "" {
m.Option(ice.MSG_RIVER, arg[0])
}
arg = arg[1:]
}
if len(arg) > 0 {
if arg[0] != "" {
m.Option(ice.MSG_STORM, arg[0])
}
arg = arg[1:]
}
}
// 群组检查
m.Richs(RIVER, nil, m.Option(ice.MSG_RIVER), func(key string, value map[string]interface{}) {
if kit.Value(value, "meta.type") == "private" {
m.Option(ice.MSG_DOMAIN, "U"+m.Option(ice.MSG_USERNAME))
} else if kit.Value(value, "meta.type") != "public" {
m.Option(ice.MSG_DOMAIN, "R"+m.Option(ice.MSG_RIVER))
}
if m.Richs(RIVER, kit.Keys(kit.MDB_HASH, m.Option(ice.MSG_RIVER), USER), m.Option(ice.MSG_USERNAME), func(key string, value map[string]interface{}) {
// 应用检查
m.Richs(RIVER, kit.Keys(kit.MDB_HASH, m.Option(ice.MSG_RIVER), TOOL), m.Option(ice.MSG_STORM), func(key string, value map[string]interface{}) {
})
}) == nil {
if m.Option("share") != "" {
m.Richs(web.SHARE, "", m.Option("share"), func(key string, value map[string]interface{}) {
if m.Option(ice.MSG_RIVER) == kit.Value(value, "extra.river") && m.Richs(RIVER, kit.Keys(kit.MDB_HASH, m.Option(ice.MSG_RIVER), USER), kit.Value(value, "extra.username"), nil) != nil {
return
}
// m.Option(ice.MSG_USERNAME, kit.Value(value, "extra.username"))
// m.Option(ice.MSG_USERROLE, kit.Value(value, "extra.userrole"))
// m.Log_AUTH(web.SHARE, key, "username", m.Option(ice.MSG_USERNAME))
m.Render(web.STATUS, 403, "not join")
m.Option(ice.MSG_USERURL, "")
return
})
return
}
m.Render(web.STATUS, 403, "not join")
m.Option(ice.MSG_USERURL, "")
return
}
})
m.Log_AUTH(RIVER, m.Option(ice.MSG_RIVER), STORM, m.Option(ice.MSG_STORM), "domain", m.Option(ice.MSG_DOMAIN))
m.Optionv(ice.MSG_CMDS, arg)
}
}
if m.Option(ice.MSG_USERURL) == "/header" {
// 免检
return
}
if m.Warn(!m.Right(m.Option(ice.MSG_USERURL), m.Optionv(ice.MSG_CMDS))) {
return
}
// 登录检查
if m.Warn(!m.Options(ice.MSG_USERNAME), "not login") {
if m.Option("share") == "" {
m.Render(web.STATUS, 401, "not login")
m.Option(ice.MSG_USERURL, "")
return
}
m.Option(ice.MSG_USERROLE, aaa.VOID)
}
// 权限检查
if m.Warn(!m.Right(m.Option(ice.MSG_USERURL), m.Optionv(ice.MSG_CMDS)), "not auth") {
m.Render(web.STATUS, 403, "not auth")
m.Option(ice.MSG_USERURL, "")
return
}
}},
"/ocean": {Name: "/ocean", Help: "大海洋", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 {
// 用户列表
m.Richs(aaa.USER, nil, "*", func(key string, value map[string]interface{}) {
m.Push(key, value, []string{"username", "usernode"})
})
return
}
switch arg[0] {
case "spawn":
// 创建群组
river := m.Rich(RIVER, nil, kit.Dict(
kit.MDB_META, kit.Dict(kit.MDB_NAME, arg[1]),
"user", kit.Data(kit.MDB_SHORT, "username"),
"tool", kit.Data(),
))
m.Log(ice.LOG_CREATE, "river: %v name: %v", river, arg[1])
// 添加用户
m.Cmd("/river", river, "add", m.Option(ice.MSG_USERNAME), arg[2:])
m.Echo(river)
}
}},
"/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") {
m.Render("status", 402, "not join")
return
}
if len(arg) < 2 {
if list := []string{}; m.Option("pod") != "" {
// 远程空间
m.Cmdy(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)
} else {
// 本地空间
m.Richs(web.SPACE, nil, "*", func(key string, value map[string]interface{}) {
switch value[kit.MDB_TYPE] {
case web.SERVER, web.WORKER:
m.Push(key, value, []string{"type", "name", "user"})
}
})
}
return
}
if m.Warn(!m.Right(cmd, arg[1])) {
m.Render("status", 403, "not auth")
return
}
switch arg[1] {
case "spawn":
// 创建应用
storm := m.Rich(RIVER, kit.Keys(kit.MDB_HASH, arg[0], "tool"), kit.Dict(
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:
// 命令列表
m.Cmdy(web.SPACE, arg[2], ctx.COMMAND)
}
}},
},
}

View File

@ -4,6 +4,7 @@ import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa"
"github.com/shylinux/icebergs/base/nfs"
"github.com/shylinux/icebergs/base/web"
kit "github.com/shylinux/toolkits"
"fmt"
@ -51,6 +52,10 @@ func init() {
m.Echo(m.Option(ice.MSG_USERNAME))
}},
LOGIN: {Name: "login", Help: "用户登录", Hand: func(m *ice.Message, arg ...string) {
if aaa.UserLogin(m, arg[0], arg[1]) {
m.Option(ice.MSG_SESSID, aaa.SessCreate(m, m.Option(ice.MSG_USERNAME), m.Option(ice.MSG_USERROLE)))
web.Render(m, web.COOKIE, m.Option(ice.MSG_SESSID))
}
m.Echo(m.Option(ice.MSG_USERNAME))
}},

View File

@ -3,10 +3,8 @@ package chat
import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa"
"github.com/shylinux/icebergs/base/cli"
"github.com/shylinux/icebergs/base/ctx"
"github.com/shylinux/icebergs/base/mdb"
"github.com/shylinux/icebergs/base/tcp"
"github.com/shylinux/icebergs/base/web"
kit "github.com/shylinux/toolkits"
)
@ -21,159 +19,40 @@ func _river_list(m *ice.Message) {
m.Cmdy(web.SPACE, p, "web.chat./river")
}
m.Richs(RIVER, nil, kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
if kit.Value(value, "meta.type") == "public" {
m.Push(key, value[kit.MDB_META], []string{kit.MDB_KEY, kit.MDB_NAME})
return
}
m.Richs(RIVER, kit.Keys(kit.MDB_HASH, key, USER), m.Option(ice.MSG_USERNAME), func(k string, val map[string]interface{}) {
m.Push(key, value[kit.MDB_META], []string{kit.MDB_KEY, kit.MDB_NAME}, val[kit.MDB_META])
})
})
}
func _river_share(m *ice.Message, river, name string, arg ...string) {
m.Cmdy(web.SHARE, RIVER, name, river, arg)
}
func _river_remove(m *ice.Message, river string) {
m.Richs(RIVER, nil, river, func(value map[string]interface{}) {
m.Log_REMOVE(RIVER, river, kit.MDB_VALUE, kit.Format(value))
})
m.Conf(RIVER, kit.Keys(kit.MDB_HASH, river), "")
}
func _river_rename(m *ice.Message, river string, name string) {
prefix := kit.Keys(kit.MDB_HASH, river, kit.MDB_META, kit.MDB_NAME)
old := m.Conf(RIVER, prefix)
m.Log_MODIFY(RIVER, river, kit.MDB_VALUE, name, "old", old)
m.Conf(RIVER, prefix, name)
}
func _river_create(m *ice.Message, kind, name, text string, arg ...string) {
h := m.Rich(RIVER, nil, kit.Dict(kit.MDB_META, kit.Dict(
kit.MDB_TYPE, kind, kit.MDB_NAME, name, kit.MDB_TEXT, text,
kit.MDB_EXTRA, kit.Dict(arg),
),
USER, kit.Data(kit.MDB_SHORT, aaa.USERNAME),
TOOL, kit.Data(),
))
m.Log_CREATE(kit.MDB_META, RIVER, kit.MDB_TYPE, kind, kit.MDB_NAME, name)
m.Option(ice.MSG_RIVER, h)
m.Cmdy(m.Prefix(USER), mdb.INSERT, aaa.USERNAME, cli.UserName)
m.Cmdy(m.Prefix(USER), mdb.INSERT, aaa.USERNAME, m.Option(ice.MSG_USERNAME))
kit.Fetch(m.Confv(RIVER, kit.Keys("meta.template", "base")), func(storm string, value interface{}) {
list := []string{}
kit.Fetch(value, func(index int, value string) {
m.Search(value, func(p *ice.Context, s *ice.Context, key string, cmd *ice.Command) {
list = append(list, "", s.Cap(ice.CTX_FOLLOW), key, kit.Simple(cmd.Help)[0])
})
})
storm = _storm_create(m, h, "", storm, "")
_storm_tool(m, h, storm, list...)
})
m.Set(ice.MSG_RESULT)
m.Echo(h)
}
const (
USER = "user"
INFO = "info"
NODE = "node"
TOOL = "tool"
USER = "user"
)
const RIVER = "river"
func init() {
Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{
RIVER: {Name: "river", Help: "群组", Value: kit.Data(
"template", kit.Dict(
"base", kit.Dict(
"info", []interface{}{
"web.chat.info",
"web.chat.tool",
"web.chat.node",
"web.chat.user",
},
"miss", []interface{}{
"web.team.task",
"web.team.plan",
"web.wiki.word",
},
),
),
aaa.Black, kit.Dict(aaa.TECH, []interface{}{
"/river.rename",
"/river.remove",
"/storm.remove",
"/storm.rename",
}),
aaa.White, kit.Dict(aaa.VOID, []interface{}{
"/header",
"/river",
"/storm",
"/action",
"/footer",
}),
)},
RIVER: {Name: RIVER, Help: "群组", Value: kit.Data()},
},
Commands: map[string]*ice.Command{
"info": {Name: "info auto 导出:button", Help: "信息", Action: map[string]*ice.Action{
INFO: {Name: "info auto", Help: "信息", Action: map[string]*ice.Action{
mdb.MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) {
arg[0] = kit.Keys(kit.MDB_META, arg[0])
m.Richs(RIVER, nil, m.Option(ice.MSG_RIVER), func(key string, value map[string]interface{}) {
m.Log_MODIFY(RIVER, m.Option(ice.MSG_RIVER), arg[0], arg[1], "old", kit.Format(kit.Value(value, arg[0])))
kit.Value(value, arg[0], arg[1])
})
}},
mdb.EXPORT: {Name: "export file", Help: "导出", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.EXPORT, m.Prefix(RIVER), "", mdb.HASH)
}},
mdb.IMPORT: {Name: "import file", Help: "导入", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.IMPORT, m.Prefix(RIVER), "", mdb.HASH)
m.Cmdy(mdb.EXPORT, RIVER, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH), arg)
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Richs(RIVER, nil, m.Option(ice.MSG_RIVER), func(key string, value map[string]interface{}) {
m.Push("detail", value[kit.MDB_META])
})
}},
TOOL: {Name: "tool hash=auto auto 添加 创建", Help: "工具", Action: map[string]*ice.Action{
mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) {
switch arg[0] {
case "storm":
_storm_list(m, m.Option(ice.MSG_RIVER))
case "ctx":
m.Cmdy(ctx.COMMAND)
case "cmd", "help":
m.Cmdy(ctx.COMMAND)
}
}},
mdb.CREATE: {Name: "create type=public,protected,private name=hi text=hello", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
_storm_create(m, m.Option(ice.MSG_RIVER), m.Option("type"), m.Option("name"), m.Option("text"))
}},
mdb.INSERT: {Name: "insert storm ctx cmd help", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.INSERT, RIVER, kit.Keys(kit.MDB_HASH, m.Option(ice.MSG_RIVER), TOOL, kit.MDB_HASH, m.Option(kit.MDB_HASH)), mdb.LIST, arg)
}},
mdb.MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) {
if m.Option(kit.MDB_ID) != "" {
m.Cmdy(mdb.MODIFY, RIVER, kit.Keys(kit.MDB_HASH, m.Option(ice.MSG_RIVER), TOOL, kit.MDB_HASH, m.Option(kit.MDB_HASH)), mdb.LIST, kit.MDB_ID, m.Option(kit.MDB_ID), arg)
} else {
m.Cmdy(mdb.MODIFY, RIVER, kit.Keys(kit.MDB_HASH, m.Option(ice.MSG_RIVER), TOOL), mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH), arg)
}
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 {
m.Option(mdb.FIELDS, "time,hash,name,count")
m.Cmdy(mdb.SELECT, RIVER, kit.Keys(kit.MDB_HASH, m.Option(ice.MSG_RIVER), TOOL), mdb.HASH)
} else {
m.Option(mdb.FIELDS, "time,id,ctx,cmd,help")
m.Cmdy(mdb.SELECT, RIVER, kit.Keys(kit.MDB_HASH, m.Option(ice.MSG_RIVER), TOOL, kit.MDB_HASH, arg[0]), mdb.LIST, kit.MDB_ID, arg[1:])
}
m.PushAction("删除")
m.Option(mdb.FIELDS, mdb.DETAIL)
m.Cmdy(mdb.SELECT, RIVER, "", mdb.HASH, kit.MDB_HASH, m.Option(ice.MSG_RIVER))
}},
NODE: {Name: "node hash=auto auto 添加 启动", Help: "设备", Action: map[string]*ice.Action{
"start": {Name: "start", Help: "启动", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy("web.code.install", "contexts", "base")
"invite": {Name: "invite", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy("web.code.publish", "contexts", "tool")
}},
mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(web.ROUTE)
"start": {Name: "start", Help: "启动", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy("web.code.publish", "contexts", "tool")
}},
mdb.INSERT: {Name: "insert route", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.INSERT, RIVER, kit.Keys(kit.MDB_HASH, m.Option(ice.MSG_RIVER), NODE), mdb.HASH, arg)
@ -181,6 +60,9 @@ func init() {
mdb.DELETE: {Name: "delete", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.DELETE, RIVER, kit.Keys(kit.MDB_HASH, m.Option(ice.MSG_RIVER), NODE), mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH))
}},
mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(web.ROUTE)
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Option(mdb.FIELDS, "time,hash,route")
m.Cmdy(mdb.SELECT, RIVER, kit.Keys(kit.MDB_HASH, m.Option(ice.MSG_RIVER), NODE), mdb.HASH)
@ -189,6 +71,48 @@ func init() {
})
m.PushAction("删除")
}},
TOOL: {Name: "tool key auto 添加 创建", Help: "工具", Action: map[string]*ice.Action{
mdb.CREATE: {Name: "create type=public,protected,private name=hi text=hello", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.INSERT, RIVER, kit.Keys(kit.MDB_HASH, m.Option(ice.MSG_RIVER), TOOL), mdb.HASH, arg)
}},
mdb.INSERT: {Name: "insert pod ctx cmd help", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.INSERT, RIVER, kit.Keys(kit.MDB_HASH, m.Option(ice.MSG_RIVER), TOOL, kit.MDB_HASH, m.Option(ice.MSG_STORM)), mdb.LIST, arg)
}},
mdb.MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) {
if m.Option(kit.MDB_ID) != "" {
m.Cmdy(mdb.MODIFY, RIVER, kit.Keys(kit.MDB_HASH, m.Option(ice.MSG_RIVER), TOOL, kit.MDB_HASH, m.Option(ice.MSG_STORM)), mdb.LIST, kit.MDB_ID, m.Option(kit.MDB_ID), arg)
} else {
m.Cmdy(mdb.MODIFY, RIVER, kit.Keys(kit.MDB_HASH, m.Option(ice.MSG_RIVER), TOOL), mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH), arg)
}
}},
mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) {
switch arg[0] {
case "pod":
_storm_list(m, m.Option(ice.MSG_RIVER))
case "ctx":
m.Cmdy(ctx.CONTEXT)
case "cmd", "help":
m.Cmdy(ctx.CONTEXT, m.Option("ctx"), ctx.COMMAND)
}
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 {
m.Option(mdb.FIELDS, "time,key,name,count")
m.Cmdy(mdb.SELECT, RIVER, kit.Keys(kit.MDB_HASH, m.Option(ice.MSG_RIVER), TOOL), mdb.HASH)
} else {
m.Option(mdb.FIELDS, "time,id,pod,ctx,cmd,help")
m.Cmdy(mdb.SELECT, RIVER, kit.Keys(kit.MDB_HASH, m.Option(ice.MSG_RIVER), TOOL, kit.MDB_HASH, arg[0]), mdb.LIST, kit.MDB_ID, arg[1:])
if len(m.Appendv(CMD)) == 0 {
m.Push("time", m.Time())
m.Push("id", "")
m.Push("pod", "")
m.Push("ctx", "")
m.Push("cmd", arg[1])
m.Push("help", "")
}
}
m.PushAction("删除")
}},
USER: {Name: "user hash=auto auto 添加 邀请", Help: "用户", Action: map[string]*ice.Action{
"invite": {Name: "invite", Help: "邀请", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy("web.wiki.spark", "inner", kit.MergeURL(m.Option(ice.MSG_USERWEB), "river", m.Option(ice.MSG_RIVER)))
@ -213,33 +137,56 @@ func init() {
})
m.PushAction("删除")
}},
RIVER: {Name: "river hash auto 添加", Help: "群组", Action: map[string]*ice.Action{
mdb.CREATE: {Name: "create type=public,protected,private name=hi text=hello", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
h := m.Cmdx(mdb.INSERT, RIVER, "", mdb.HASH, arg)
m.Option(ice.MSG_RIVER, h)
m.Echo(h)
"/river": {Name: "/river", Help: "小河流",
Action: map[string]*ice.Action{
mdb.CREATE: {Name: "create type name text arg...", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
_river_create(m, arg[0], arg[1], arg[2], arg[3:]...)
}},
mdb.RENAME: {Name: "rename name", Help: "更名", Hand: func(m *ice.Message, arg ...string) {
_river_rename(m, m.Option(ice.MSG_RIVER), arg[0])
}},
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
_river_remove(m, m.Option(ice.MSG_RIVER))
}},
web.SHARE: {Name: "share name", Help: "共享", Hand: func(m *ice.Message, arg ...string) {
_river_share(m, m.Option(ice.MSG_RIVER), arg[0])
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) > 0 && arg[0] == "storm" {
m.Cmdy("/storm", arg[1:])
return
}
if m.Option("_source") == "" && m.Option(ice.MSG_SESSID) == "" && !tcp.IPIsLocal(m, m.Option(ice.MSG_USERIP)) {
m.Render("status", "401")
return
}
m.Conf(RIVER, kit.Keys(kit.MDB_HASH, h, USER, kit.MDB_META, kit.MDB_SHORT), aaa.USERNAME)
m.Cmd(USER, mdb.INSERT, aaa.USERNAME, m.Option(ice.MSG_USERNAME))
kit.Fetch(m.Confv(RIVER, kit.Keys("meta.template", "base")), func(storm string, value interface{}) {
h := m.Cmdx(TOOL, mdb.CREATE, kit.MDB_TYPE, "public", kit.MDB_NAME, storm, kit.MDB_TEXT, storm)
m.Option(ice.MSG_STORM, h)
_river_list(m)
kit.Fetch(value, func(index int, value string) {
m.Search(value, func(p *ice.Context, s *ice.Context, key string, cmd *ice.Command) {
m.Cmd(TOOL, mdb.INSERT, "pod", "", "ctx", s.Cap(ice.CTX_FOLLOW), "cmd", key, "help", kit.Simple(cmd.Help)[0])
})
})
})
}},
mdb.MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.MODIFY, RIVER, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH), arg)
}},
mdb.REMOVE: {Name: "remove hash", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.DELETE, RIVER, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH))
}},
mdb.EXPORT: {Name: "export", Help: "导出", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.EXPORT, RIVER, "", mdb.HASH)
}},
mdb.IMPORT: {Name: "import", Help: "导入", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.IMPORT, RIVER, "", mdb.HASH)
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmdy(mdb.SELECT, RIVER, "", mdb.HASH, kit.MDB_HASH, arg)
m.PushAction("删除")
}},
"/river": {Name: "/river", Help: "小河流", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 {
_river_list(m)
return
}
if len(arg) == 1 {
m.Option(ice.MSG_RIVER, arg[0])
m.Cmdy(TOOL, arg[1:])
return
}
if !m.Warn(!m.Right(RIVER, arg), ice.ErrNotAuth) {
m.Cmdy(RIVER, arg)
}
}},
},
}, nil)
}

89
core/chat/trash.go Normal file
View File

@ -0,0 +1,89 @@
package chat
import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa"
"github.com/shylinux/icebergs/base/ctx"
"github.com/shylinux/icebergs/base/web"
kit "github.com/shylinux/toolkits"
)
func init() {
Index.Merge(&ice.Context{
Commands: map[string]*ice.Command{
"/ocean": {Name: "/ocean", Help: "大海洋", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 {
// 用户列表
m.Richs(aaa.USER, nil, "*", func(key string, value map[string]interface{}) {
m.Push(key, value, []string{"username", "usernode"})
})
return
}
switch arg[0] {
case "spawn":
// 创建群组
river := m.Rich(RIVER, nil, kit.Dict(
kit.MDB_META, kit.Dict(kit.MDB_NAME, arg[1]),
"user", kit.Data(kit.MDB_SHORT, "username"),
"tool", kit.Data(),
))
m.Log(ice.LOG_CREATE, "river: %v name: %v", river, arg[1])
// 添加用户
m.Cmd("/river", river, "add", m.Option(ice.MSG_USERNAME), arg[2:])
m.Echo(river)
}
}},
"/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") {
m.Render("status", 402, "not join")
return
}
if len(arg) < 2 {
if list := []string{}; m.Option("pod") != "" {
// 远程空间
m.Cmdy(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)
} else {
// 本地空间
m.Richs(web.SPACE, nil, "*", func(key string, value map[string]interface{}) {
switch value[kit.MDB_TYPE] {
case web.SERVER, web.WORKER:
m.Push(key, value, []string{"type", "name", "user"})
}
})
}
return
}
if m.Warn(!m.Right(cmd, arg[1])) {
m.Render("status", 403, "not auth")
return
}
switch arg[1] {
case "spawn":
// 创建应用
storm := m.Rich(RIVER, kit.Keys(kit.MDB_HASH, arg[0], "tool"), kit.Dict(
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:
// 命令列表
m.Cmdy(web.SPACE, arg[2], ctx.COMMAND)
}
}},
},
}, nil)
}

View File

@ -94,6 +94,11 @@ export ctx_dev={{.Option "httphost"}} ctx_temp=$(mktemp); curl -sL $ctx_dev >$ct
# 开发环境
mkdir contexts; cd contexts
export ctx_dev={{.Option "httphost"}} ctx_temp=$(mktemp); curl -sL $ctx_dev >$ctx_temp; source $ctx_temp dev
`,
"tool", `
# 生产环境
mkdir contexts; cd contexts
export ctx_dev={{.Option "httphost"}} ctx_share={{.Option "share"}} ctx_temp=$(mktemp); curl -sL $ctx_dev >$ctx_temp; source $ctx_temp dev
`,
)

View File

@ -587,7 +587,7 @@ func (m *Message) Search(key interface{}, cb interface{}) *Message {
break
}
for _, p = range []*Context{p, m.target, m.source} {
for _, p := range []*Context{m.target, p, m.source} {
for c := p; c != nil; c = c.context {
if cmd, ok := c.Commands[key]; ok {
cb(c, p, key, cmd)
@ -596,7 +596,7 @@ func (m *Message) Search(key interface{}, cb interface{}) *Message {
}
}
case func(p *Context, s *Context, key string, conf *Config):
for _, p = range []*Context{p, m.target, m.source} {
for _, p := range []*Context{m.target, p, m.source} {
for c := p; c != nil; c = c.context {
if cmd, ok := c.Configs[key]; ok {
cb(c.context, c, key, cmd)