forked from x/icebergs
opt spide
This commit is contained in:
parent
8cd59f9024
commit
13d8609a74
@ -4,7 +4,7 @@ icebergs是一个后端框架,通过模块化、集群化实现资源的无限
|
||||
|
||||
一键创建项目
|
||||
```
|
||||
mkdir miss; cd miss && curl -s https://raw.githubusercontent.com/shylinux/icebergs/master/demo/build.sh | sh
|
||||
mkdir miss; cd miss && curl -s https://shylinux.com/publish/build.sh | sh
|
||||
```
|
||||
|
||||
## 1 原型 type.go
|
||||
|
3
base.go
3
base.go
@ -28,11 +28,13 @@ func (f *Frame) Begin(m *Message, arg ...string) Server {
|
||||
}
|
||||
})
|
||||
m.target.wg = &sync.WaitGroup{}
|
||||
m.root.Cost("begin")
|
||||
return f
|
||||
}
|
||||
func (f *Frame) Start(m *Message, arg ...string) bool {
|
||||
m.Log(LOG_START, "ice")
|
||||
m.Cmd(ICE_INIT).Cmd("init", arg)
|
||||
m.root.Cost("start")
|
||||
return true
|
||||
}
|
||||
func (f *Frame) Close(m *Message, arg ...string) bool {
|
||||
@ -81,6 +83,7 @@ var Index = &Context{Name: "ice", Help: "冰山模块",
|
||||
})
|
||||
}},
|
||||
"init": {Name: "init", Help: "hello", Hand: func(m *Message, c *Context, cmd string, arg ...string) {
|
||||
m.root.Cost("_init")
|
||||
m.Start("log", arg...)
|
||||
m.Start("gdb", arg...)
|
||||
m.Start("ssh", arg...)
|
||||
|
@ -13,8 +13,12 @@ var Index = &ice.Context{Name: "aaa", Help: "认证模块",
|
||||
ice.AAA_SESS: {Name: "sess", Help: "会话", Value: kit.Data(kit.MDB_SHORT, "uniq", "expire", "720h")},
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
|
||||
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
|
||||
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Cmd(ice.CTX_CONFIG, "load", "aaa.json")
|
||||
}},
|
||||
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Cmd(ice.CTX_CONFIG, "save", "aaa.json", ice.AAA_ROLE, ice.AAA_USER, ice.AAA_SESS)
|
||||
}},
|
||||
ice.AAA_ROLE: {Name: "role", Help: "角色", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
switch arg[0] {
|
||||
case "check":
|
||||
|
@ -22,6 +22,8 @@ var Index = &ice.Context{Name: "cli", Help: "命令模块",
|
||||
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Cmd(ice.CTX_CONFIG, "load", "cli.json")
|
||||
|
||||
m.Conf(ice.CLI_RUNTIME, "host.ctx_self", os.Getenv("ctx_self"))
|
||||
m.Conf(ice.CLI_RUNTIME, "host.ctx_dev", os.Getenv("ctx_dev"))
|
||||
m.Conf(ice.CLI_RUNTIME, "host.GOARCH", runtime.GOARCH)
|
||||
m.Conf(ice.CLI_RUNTIME, "host.GOOS", runtime.GOOS)
|
||||
m.Conf(ice.CLI_RUNTIME, "host.pid", os.Getpid())
|
||||
|
@ -56,17 +56,23 @@ var Index = &ice.Context{Name: "ctx", Help: "元始模块",
|
||||
return
|
||||
}
|
||||
|
||||
m.Search(arg[0]+"."+arg[1], func(p *ice.Context, s *ice.Context, key string, cmd *ice.Command) {
|
||||
if len(arg) == 2 {
|
||||
chain := arg[0]
|
||||
if len(arg) > 1 {
|
||||
chain = arg[0] + "." + arg[1]
|
||||
arg = arg[1:]
|
||||
}
|
||||
arg = arg[1:]
|
||||
m.Search(chain, func(p *ice.Context, s *ice.Context, key string, cmd *ice.Command) {
|
||||
if len(arg) == 0 {
|
||||
m.Push("name", cmd.Name)
|
||||
m.Push("help", cmd.Help)
|
||||
m.Push("meta", kit.Format(cmd.Meta))
|
||||
m.Push("list", kit.Format(cmd.List))
|
||||
} else {
|
||||
if you := m.Option(kit.Format(kit.Value(cmd.Meta, "remote"))); you != "" {
|
||||
m.Copy(m.Spawns(s).Cmd("web.space", you, "ctx.command", arg[0], arg[1], "run", arg[3:]))
|
||||
m.Copy(m.Spawns(s).Cmd("web.space", you, "ctx.command", chain, "run", arg[1:]))
|
||||
} else {
|
||||
m.Copy(s.Run(m.Spawns(s), cmd, key, arg[3:]...))
|
||||
m.Copy(s.Run(m.Spawns(s), cmd, key, arg[1:]...))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -56,7 +56,7 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool {
|
||||
}
|
||||
m.Info("%s: %v", ice.GDB_EVENT, d)
|
||||
m.Grows(ice.GDB_EVENT, d[0], "", "", func(index int, value map[string]interface{}) {
|
||||
m.Cmd(value["cmd"], d[1:])
|
||||
m.Cmd(value["cmd"], d[1:]).Cost("event %v", d)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -35,11 +35,11 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool {
|
||||
fmt.Fprintf(f.out, m.Time(prompt, count, target.Name))
|
||||
for bio.Scan() {
|
||||
ls := kit.Split(bio.Text())
|
||||
m.Log("info", "input %v", ls)
|
||||
m.Log("info", "stdin input %v", ls)
|
||||
|
||||
msg := m.Spawn(target)
|
||||
msg := m.Spawns(target)
|
||||
if msg.Cmdy(ls); !msg.Hand {
|
||||
msg = msg.Cmdy("cli.system", ls)
|
||||
msg = msg.Set("result").Cmdy(ice.CLI_SYSTEM, ls)
|
||||
}
|
||||
res := msg.Result()
|
||||
if res == "" {
|
||||
@ -52,6 +52,7 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool {
|
||||
fmt.Fprint(f.out, "\n")
|
||||
}
|
||||
fmt.Fprintf(f.out, m.Time(prompt, count, target.Name))
|
||||
msg.Cost("stdin %v", ls)
|
||||
count++
|
||||
}
|
||||
return true
|
||||
|
342
base/web/web.go
342
base/web/web.go
@ -11,6 +11,7 @@ import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"mime/multipart"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@ -197,12 +198,11 @@ func (web *Frame) HandleCmd(m *ice.Message, key string, cmd *ice.Command) {
|
||||
}
|
||||
}
|
||||
default:
|
||||
r.ParseMultipartForm(4096)
|
||||
r.ParseMultipartForm(kit.Int64(kit.Select(r.Header.Get("Content-Length"), "4096")))
|
||||
if r.ParseForm(); len(r.PostForm) > 0 {
|
||||
for k, v := range r.PostForm {
|
||||
msg.Info("%s: %v", k, v)
|
||||
}
|
||||
msg.Info("")
|
||||
}
|
||||
}
|
||||
|
||||
@ -218,10 +218,9 @@ func (web *Frame) HandleCmd(m *ice.Message, key string, cmd *ice.Command) {
|
||||
case "void":
|
||||
case "file":
|
||||
msg.Info("_output: %s %s", msg.Append("_output"), msg.Append("file"))
|
||||
w.Header().Set("Content-Disposition", fmt.Sprintf("filename=%s", kit.Select("hi.txt", msg.Append("name"))))
|
||||
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 "result":
|
||||
w.Header().Set("Content-Type", kit.Select("text/html", msg.Append("type")))
|
||||
fmt.Fprint(w, msg.Result())
|
||||
@ -340,7 +339,7 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
"template", map[string]interface{}{"path": "usr/template", "list": []interface{}{
|
||||
`{{define "raw"}}{{.Result}}{{end}}`,
|
||||
}},
|
||||
"logheaders", "false",
|
||||
"logheaders", "true",
|
||||
)},
|
||||
ice.WEB_SPACE: {Name: "space", Help: "空间站", Value: kit.Data(kit.MDB_SHORT, "name",
|
||||
"redial.a", 3000, "redial.b", 1000, "redial.c", 10,
|
||||
@ -353,14 +352,21 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
ice.WEB_CACHE: {Name: "cache", Help: "缓存池", Value: kit.Data(kit.MDB_SHORT, "text", "path", "var/file", "store", "var/data", "limit", "30", "least", "10")},
|
||||
ice.WEB_STORY: {Name: "story", Help: "故事会", Value: kit.Dict(kit.MDB_META, kit.Dict(kit.MDB_SHORT, "data"), "head", kit.Data(kit.MDB_SHORT, "story"))},
|
||||
ice.WEB_SHARE: {Name: "share", Help: "共享链", Value: kit.Data("template", share_template)},
|
||||
ice.WEB_ROUTE: {Name: "route", Help: "路由表", Value: kit.Data()},
|
||||
ice.WEB_PROXY: {Name: "proxy", Help: "代理商", Value: kit.Data()},
|
||||
ice.WEB_ROUTE: {Name: "route", Help: "路由", Value: kit.Data()},
|
||||
ice.WEB_PROXY: {Name: "proxy", Help: "代理", Value: kit.Data()},
|
||||
ice.WEB_GROUP: {Name: "group", Help: "分组", Value: kit.Data()},
|
||||
ice.WEB_LABEL: {Name: "label", Help: "标签", Value: kit.Data()},
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Cmd(ice.CTX_CONFIG, "load", "web.json")
|
||||
m.Cmd(ice.WEB_SPIDE, "add", "self", "http://:9020")
|
||||
m.Cmd(ice.WEB_SPIDE, "add", "shy", "https://shylinux.com")
|
||||
}},
|
||||
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Done()
|
||||
m.Cmd(ice.CTX_CONFIG, "save", "web.json", ice.WEB_SPIDE, ice.WEB_FAVOR, ice.WEB_CACHE, ice.WEB_STORY, ice.WEB_SHARE)
|
||||
}},
|
||||
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Done() }},
|
||||
|
||||
ice.WEB_SPIDE: {Name: "spide", Help: "客户端", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
if len(arg) == 0 {
|
||||
@ -383,7 +389,7 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
"client", kit.Dict(
|
||||
"logheaders", false,
|
||||
"timeout", "100s",
|
||||
"method", "GET",
|
||||
"method", "POST",
|
||||
"protocol", uri.Scheme,
|
||||
"hostname", uri.Host,
|
||||
"path", dir,
|
||||
@ -396,20 +402,99 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
default:
|
||||
m.Richs(ice.WEB_SPIDE, nil, arg[0], func(key string, value map[string]interface{}) {
|
||||
client := value["client"].(map[string]interface{})
|
||||
method := kit.Select("GET", client["method"])
|
||||
uri := kit.MergeURL(kit.Format(client["url"]), arg[1:])
|
||||
|
||||
body, ok := m.Optionv("body").(io.Reader)
|
||||
if !ok && method == "POST" {
|
||||
if ls := strings.Split(uri, "?"); len(ls) > 0 {
|
||||
uri, body = ls[0], bytes.NewReader([]byte(ls[1]))
|
||||
}
|
||||
// 解析方法
|
||||
parse := ""
|
||||
switch arg[1] {
|
||||
case "parse":
|
||||
parse, arg = "parse", arg[1:]
|
||||
}
|
||||
|
||||
// 请求方法
|
||||
method := kit.Select("POST", client["method"])
|
||||
switch arg = arg[1:]; arg[0] {
|
||||
case "POST":
|
||||
method, arg = "POST", arg[1:]
|
||||
case "GET":
|
||||
method, arg = "GET", arg[1:]
|
||||
}
|
||||
|
||||
// 请求地址
|
||||
uri, arg := arg[0], arg[1:]
|
||||
|
||||
// 请求数据
|
||||
head := map[string]string{}
|
||||
body, ok := m.Optionv("body").(io.Reader)
|
||||
if !ok && len(arg) > 0 {
|
||||
switch arg[0] {
|
||||
case "file":
|
||||
if f, e := os.Open(arg[1]); m.Warn(e != nil, "%s", e) {
|
||||
return
|
||||
} else {
|
||||
defer f.Close()
|
||||
body, arg = f, arg[2:]
|
||||
}
|
||||
case "data":
|
||||
body, arg = bytes.NewBufferString(arg[1]), arg[2:]
|
||||
case "form":
|
||||
data := []string{}
|
||||
for i := 1; i < len(arg)-1; i += 2 {
|
||||
data = append(data, url.QueryEscape(arg[i])+"="+url.QueryEscape(arg[i+1]))
|
||||
}
|
||||
body = bytes.NewBufferString(strings.Join(data, "&"))
|
||||
head["Content-Type"] = "application/x-www-form-urlencoded"
|
||||
case "part":
|
||||
buf := &bytes.Buffer{}
|
||||
mp := multipart.NewWriter(buf)
|
||||
for i := 1; i < len(arg)-1; i += 2 {
|
||||
if strings.HasPrefix(arg[i+1], "@") {
|
||||
if f, e := os.Open(arg[i+1][1:]); m.Assert(e) {
|
||||
defer f.Close()
|
||||
if p, e := mp.CreateFormFile(arg[i], path.Base(arg[i+1][1:])); m.Assert(e) {
|
||||
io.Copy(p, f)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mp.WriteField(arg[i], arg[i+1])
|
||||
}
|
||||
}
|
||||
mp.Close()
|
||||
head["Content-Type"] = mp.FormDataContentType()
|
||||
body = buf
|
||||
default:
|
||||
data := map[string]interface{}{}
|
||||
for i := 0; i < len(arg)-1; i += 2 {
|
||||
kit.Value(data, arg[i], arg[i+1])
|
||||
}
|
||||
if b, e := json.Marshal(data); m.Assert(e) {
|
||||
head["Content-Type"] = "application/json"
|
||||
body = bytes.NewBuffer(b)
|
||||
}
|
||||
}
|
||||
arg = arg[:0]
|
||||
}
|
||||
|
||||
// 构造请求
|
||||
uri = kit.MergeURL2(kit.Format(client["url"]), uri, arg)
|
||||
req, e := http.NewRequest(method, uri, body)
|
||||
m.Log("info", "%s %s", req.Method, req.URL)
|
||||
m.Info("%s %s", req.Method, req.URL)
|
||||
m.Assert(e)
|
||||
|
||||
// 请求参数
|
||||
for k, v := range head {
|
||||
req.Header.Set(k, v)
|
||||
}
|
||||
kit.Fetch(client["header"], func(key string, value string) {
|
||||
req.Header.Set(key, value)
|
||||
})
|
||||
kit.Fetch(client["cookie"], func(key string, value string) {
|
||||
req.AddCookie(&http.Cookie{Name: key, Value: value})
|
||||
m.Info("%s: %s", key, value)
|
||||
})
|
||||
if method == "POST" {
|
||||
m.Info("%s: %s", req.Header.Get("Content-Length"), req.Header.Get("Content-Type"))
|
||||
}
|
||||
|
||||
// 请求代理
|
||||
web := m.Target().Server().(*Frame)
|
||||
if web.Client == nil {
|
||||
web.Client = &http.Client{Timeout: kit.Duration(kit.Format(client["timeout"]))}
|
||||
@ -417,16 +502,38 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
|
||||
// 发送请求
|
||||
res, e := web.Client.Do(req)
|
||||
|
||||
// 缓存参数
|
||||
for _, v := range res.Cookies() {
|
||||
kit.Value(client, "cookie."+v.Name, v.Value)
|
||||
m.Info("%s: %s", v.Name, v.Value)
|
||||
}
|
||||
|
||||
// 验证结果
|
||||
if m.Warn(e != nil, "%s", e) {
|
||||
return
|
||||
}
|
||||
|
||||
if m.Warn(res.StatusCode != http.StatusOK, "%s", res.Status) {
|
||||
} else if m.Warn(res.StatusCode != http.StatusOK, "%s", res.Status) {
|
||||
return
|
||||
}
|
||||
|
||||
if buf, e := ioutil.ReadAll(res.Body); m.Assert(e) {
|
||||
m.Echo(string(buf))
|
||||
switch parse {
|
||||
case "parse":
|
||||
data := map[string]interface{}{}
|
||||
m.Assert(json.NewDecoder(res.Body).Decode(&data))
|
||||
for k, v := range data {
|
||||
switch v := v.(type) {
|
||||
case []interface{}:
|
||||
m.Append(k, v)
|
||||
default:
|
||||
m.Append(k, kit.Format(v))
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
// 缓存结果
|
||||
m.Cost("%s %s: %s", res.Status, res.Header.Get("Content-Length"), res.Header.Get("Content-Type"))
|
||||
m.Optionv("response", res)
|
||||
m.Echo(m.Cmd(ice.WEB_CACHE, "download", res.Header.Get("Content-Type"), uri).Append("data"))
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -455,11 +562,34 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
m.Richs(ice.WEB_SPACE, nil, "", func(key string, value map[string]interface{}) {
|
||||
m.Push(key, value, []string{"time", "type", "name", "user"})
|
||||
})
|
||||
m.Sort("name")
|
||||
return
|
||||
}
|
||||
|
||||
web := m.Target().Server().(*Frame)
|
||||
switch arg[0] {
|
||||
case "share":
|
||||
switch arg[1] {
|
||||
case "add":
|
||||
m.Cmdy(ice.WEB_SPIDE, "self", "parse", path.Join("/space/share/add", path.Join(arg[2:]...)))
|
||||
default:
|
||||
m.Richs(ice.WEB_SPIDE, nil, "self", func(key string, value map[string]interface{}) {
|
||||
value["share"] = arg[1]
|
||||
})
|
||||
}
|
||||
|
||||
case "upload":
|
||||
for _, file := range arg[2:] {
|
||||
msg := m.Cmd(ice.WEB_STORY, "index", file)
|
||||
m.Cmdy(ice.WEB_SPIDE, arg[1], "POST", "/space/upload", "part",
|
||||
"type", msg.Append("type"), "name", msg.Append("name"),
|
||||
"text", msg.Append("text"), "upload", "@"+msg.Append("file"),
|
||||
)
|
||||
}
|
||||
case "download":
|
||||
m.Cmd(ice.WEB_STORY, "add", arg[1], arg[2],
|
||||
m.Cmdx(ice.WEB_SPIDE, arg[3], "/space/download/"+arg[4]))
|
||||
|
||||
case "connect":
|
||||
// 基本信息
|
||||
node := m.Conf(ice.CLI_RUNTIME, "node.type")
|
||||
@ -469,7 +599,7 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
m.Richs(ice.WEB_SPIDE, nil, kit.Select("self", arg, 1), func(key string, value map[string]interface{}) {
|
||||
host := kit.Format(kit.Value(value, "client.hostname"))
|
||||
|
||||
if u, e := url.Parse(kit.MergeURL("ws://"+host+"/space/", "node", node, "name", name, "user", user)); m.Assert(e) {
|
||||
if u, e := url.Parse(kit.MergeURL("ws://"+host+"/space/", "node", node, "name", name, "user", user, "share", value["share"])); m.Assert(e) {
|
||||
for i := 0; i < m.Confi(ice.WEB_SPACE, "meta.redial.c"); i++ {
|
||||
if s, e := net.Dial("tcp", host); !m.Warn(e != nil, "%s", e) {
|
||||
if s, _, e := websocket.NewClient(s, u, nil, m.Confi(ice.WEB_SPACE, "meta.buffer.r"), m.Confi(ice.WEB_SPACE, "meta.buffer.w")); !m.Warn(e != nil, "%s", e) {
|
||||
@ -504,6 +634,8 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
m.Optionv(ice.MSG_SOURCE, []string{id, target[0]})
|
||||
m.Optionv(ice.MSG_TARGET, target[1:])
|
||||
m.Set(ice.MSG_DETAIL, arg[1:]...)
|
||||
m.Option("hot", m.Option("hot"))
|
||||
m.Option("top", m.Option("top"))
|
||||
m.Info("send %s %s", id, m.Format("meta"))
|
||||
|
||||
// 下发命令
|
||||
@ -562,8 +694,16 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
// 任务列表
|
||||
m.Cmdy("nfs.dir", m.Conf(ice.WEB_DREAM, "meta.path"), "", "time name")
|
||||
m.Table(func(index int, value map[string]string, head []string) {
|
||||
m.Push("status", kit.Select("start", "stop", m.Richs(ice.WEB_SPACE, nil, value["name"], nil) == nil))
|
||||
if m.Richs(ice.WEB_SPACE, nil, value["name"], func(key string, value map[string]interface{}) {
|
||||
m.Push("type", value["type"])
|
||||
m.Push("status", "start")
|
||||
}) == nil {
|
||||
m.Push("type", "none")
|
||||
m.Push("status", "stop")
|
||||
}
|
||||
})
|
||||
m.Sort("name")
|
||||
m.Sort("status")
|
||||
}},
|
||||
ice.WEB_FAVOR: {Name: "favor", Help: "收藏夹", Meta: kit.Dict("remote", "you", "exports", []string{"hot", "favor"}, "detail", []string{"执行", "编辑", "收录", "下载"}), List: kit.List(
|
||||
kit.MDB_INPUT, "text", "name", "hot", "action", "auto",
|
||||
@ -586,7 +726,7 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
case "收录":
|
||||
m.Richs(ice.WEB_FAVOR, nil, m.Option("hot"), func(key string, value map[string]interface{}) {
|
||||
m.Grows(ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, key), "id", id, func(index int, value map[string]interface{}) {
|
||||
m.Cmd(ice.WEB_STORY, "add", value["type"], value["name"], value["text"])
|
||||
m.Cmd(ice.WEB_STORY, "add", value["type"], m.Option("top"), value["text"])
|
||||
})
|
||||
})
|
||||
arg = []string{m.Option("hot")}
|
||||
@ -638,7 +778,6 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
// 收藏列表
|
||||
m.Grows(ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, favor), "", "", func(index int, value map[string]interface{}) {
|
||||
m.Push(kit.Format(index), value, []string{kit.MDB_TIME, kit.MDB_ID, kit.MDB_TYPE, kit.MDB_NAME, kit.MDB_TEXT})
|
||||
m.Push("link", kit.Format(m.Conf(ice.WEB_SHARE, "meta.template.download"), value["data"], kit.Short(value["data"])))
|
||||
})
|
||||
return
|
||||
}
|
||||
@ -647,7 +786,13 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
// 收藏详情
|
||||
m.Grows(ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, favor), "id", arg[1], func(index int, value map[string]interface{}) {
|
||||
for k, v := range value {
|
||||
m.Push("key", k).Push("value", v)
|
||||
if k == "extra" {
|
||||
for k, v := range v.(map[string]interface{}) {
|
||||
m.Push("key", "extra."+k).Push("value", kit.Format(v))
|
||||
}
|
||||
} else {
|
||||
m.Push("key", k).Push("value", kit.Format(v))
|
||||
}
|
||||
}
|
||||
m.Sort("key")
|
||||
})
|
||||
@ -669,7 +814,7 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
m.Info("create favor: %s index: %d name: %s", favor, index, arg[2])
|
||||
m.Echo("%d", index)
|
||||
}},
|
||||
ice.WEB_CACHE: {Name: "cache", Help: "缓存池", Meta: kit.Dict("remote", "you"), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
ice.WEB_CACHE: {Name: "cache", Help: "缓存池", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
if len(arg) == 0 {
|
||||
// 记录列表
|
||||
m.Grows(ice.WEB_CACHE, nil, "", "", func(index int, value map[string]interface{}) {
|
||||
@ -681,22 +826,34 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
}
|
||||
|
||||
switch arg[0] {
|
||||
case "upload":
|
||||
case "upload", "download":
|
||||
// 打开文件
|
||||
r := m.Optionv("request").(*http.Request)
|
||||
if f, h, e := r.FormFile(kit.Select("upload", arg, 1)); m.Assert(e) {
|
||||
defer f.Close()
|
||||
if r, ok := m.Optionv("request").(*http.Request); ok {
|
||||
if f, h, e := r.FormFile(kit.Select("upload", arg, 1)); m.Assert(e) {
|
||||
defer f.Close()
|
||||
|
||||
// 创建文件
|
||||
file := kit.Hashs(f)
|
||||
if o, p, e := kit.Create(path.Join(m.Conf(ice.WEB_CACHE, ice.Meta("path")), file[:2], file)); m.Assert(e) {
|
||||
defer o.Close()
|
||||
// 创建文件
|
||||
file := kit.Hashs(f)
|
||||
if o, p, e := kit.Create(path.Join(m.Conf(ice.WEB_CACHE, ice.Meta("path")), file[:2], file)); m.Assert(e) {
|
||||
defer o.Close()
|
||||
|
||||
// 保存文件
|
||||
f.Seek(0, os.SEEK_SET)
|
||||
if n, e := io.Copy(o, f); m.Assert(e) {
|
||||
m.Info("upload: %s file: %s", kit.FmtSize(n), p)
|
||||
arg = kit.Simple(arg[0], h.Header.Get("Content-Type"), h.Filename, p, p, n)
|
||||
// 保存文件
|
||||
f.Seek(0, os.SEEK_SET)
|
||||
if n, e := io.Copy(o, f); m.Assert(e) {
|
||||
m.Info("upload: %s file: %s", kit.FmtSize(n), p)
|
||||
arg = kit.Simple(arg[0], h.Header.Get("Content-Type"), h.Filename, p, p, n)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if r, ok := m.Optionv("response").(*http.Response); ok {
|
||||
if buf, e := ioutil.ReadAll(r.Body); m.Assert(e) {
|
||||
file := kit.Hashs(string(buf))
|
||||
if o, p, e := kit.Create(path.Join(m.Conf(ice.WEB_CACHE, ice.Meta("path")), file[:2], file)); m.Assert(e) {
|
||||
defer o.Close()
|
||||
if n, e := o.Write(buf); m.Assert(e) {
|
||||
m.Info("download: %s file: %s", kit.FmtSize(int64(n)), p)
|
||||
arg = kit.Simple(arg[0], arg[1], arg[2], p, p, n)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -704,13 +861,21 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
case "add":
|
||||
// 添加数据
|
||||
size := kit.Select(kit.Format(len(arg[3])), arg, 5)
|
||||
h := m.Rich(ice.WEB_CACHE, nil, kit.Dict(
|
||||
data := kit.Dict(
|
||||
kit.MDB_TYPE, arg[1], kit.MDB_NAME, arg[2], kit.MDB_TEXT, arg[3],
|
||||
kit.MDB_FILE, kit.Select("", arg, 4),
|
||||
kit.MDB_SIZE, size, arg[1], arg[3],
|
||||
))
|
||||
kit.MDB_FILE, kit.Select("", arg, 4), kit.MDB_SIZE, size,
|
||||
)
|
||||
h := m.Rich(ice.WEB_CACHE, nil, data)
|
||||
m.Info("cache: %s type: %s name: %s", h, arg[1], arg[2])
|
||||
|
||||
// 保存数据
|
||||
if arg[0] == "add" && len(arg) == 4 {
|
||||
p := path.Join(m.Conf(ice.WEB_CACHE, ice.Meta("path")), h[:2], h)
|
||||
if m.Cmd("nfs.save", p, arg[3]); kit.Int(size) > 512 {
|
||||
data["text"], data["file"], arg[3] = p, p, p
|
||||
}
|
||||
}
|
||||
|
||||
// 添加记录
|
||||
m.Grow(ice.WEB_CACHE, nil, kit.Dict(
|
||||
kit.MDB_TYPE, arg[1], kit.MDB_NAME, arg[2], kit.MDB_TEXT, arg[3],
|
||||
@ -724,11 +889,6 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
m.Push("text", arg[3])
|
||||
m.Push("size", size)
|
||||
m.Push("data", h)
|
||||
|
||||
// 保存数据
|
||||
if arg[0] == "add" {
|
||||
m.Cmd("nfs.save", path.Join(m.Conf(ice.WEB_CACHE, ice.Meta("path")), h[:2], h), arg[3])
|
||||
}
|
||||
}
|
||||
}},
|
||||
ice.WEB_STORY: {Name: "story", Help: "故事会", Meta: kit.Dict("remote", "you", "exports", []string{"top", "story"}, "detail", []string{"归档", "共享", "下载"}), List: kit.List(
|
||||
@ -740,12 +900,15 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
switch arg[1] {
|
||||
case "共享":
|
||||
switch arg[2] {
|
||||
case "story":
|
||||
m.Cmd(ice.WEB_SHARE, "add", "story", arg[3], arg[3])
|
||||
arg = []string{}
|
||||
case "list":
|
||||
m.Cmd(ice.WEB_SHARE, "add", "story", m.Option("top"), arg[3])
|
||||
arg = []string{m.Option("top")}
|
||||
case "story", "list":
|
||||
pod := ""
|
||||
if list := kit.Simple(m.Optionv("_source")); len(list) > 0 {
|
||||
pod = strings.Join(list[1:], ".")
|
||||
}
|
||||
msg := m.Cmd(ice.WEB_STORY, "index", arg[3])
|
||||
m.Cmdy(ice.WEB_SPACE, "share", "add", ice.TYPE_STORY,
|
||||
msg.Append("story"), arg[3], "pod", pod, "data", arg[3])
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -755,6 +918,7 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
m.Richs(ice.WEB_STORY, "head", "", func(key string, value map[string]interface{}) {
|
||||
m.Push(key, value, []string{"time", "scene", "story", "count"})
|
||||
})
|
||||
m.Sort("time", "time_r")
|
||||
return
|
||||
}
|
||||
|
||||
@ -762,8 +926,10 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
switch arg[0] {
|
||||
case "add", "upload":
|
||||
// 保存数据
|
||||
m.Cmdy(ice.WEB_CACHE, arg)
|
||||
arg = []string{arg[0], m.Append("type"), m.Append("name"), m.Append("data")}
|
||||
if m.Richs(ice.WEB_CACHE, nil, arg[3], nil) == nil {
|
||||
m.Cmdy(ice.WEB_CACHE, arg)
|
||||
arg = []string{arg[0], m.Append("type"), m.Append("name"), m.Append("data")}
|
||||
}
|
||||
|
||||
// 查询索引
|
||||
head, prev, count := "", "", 0
|
||||
@ -867,7 +1033,6 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
}) == nil {
|
||||
arg[1] = kit.Select(arg[1], m.Conf(ice.WEB_STORY, kit.Keys("head.hash", arg[1], "list")))
|
||||
}
|
||||
|
||||
// 查询节点
|
||||
if node := m.Confm(ice.WEB_STORY, kit.Keys("hash", arg[1])); node != nil {
|
||||
m.Push("list", arg[1])
|
||||
@ -888,11 +1053,12 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
m.Push("scene", value["scene"])
|
||||
m.Push("story", value["story"])
|
||||
m.Push("drama", value["drama"])
|
||||
m.Push("link", kit.Format(m.Conf(ice.WEB_SHARE, "meta.template.download"), value["data"], kit.Short(value["data"])))
|
||||
m.Push("link", kit.Format(m.Conf(ice.WEB_SHARE, "meta.template.download"),
|
||||
kit.Format(value["data"])+"&pod="+m.Conf(ice.CLI_RUNTIME, "node.name"), kit.Short(value["data"])))
|
||||
})
|
||||
}
|
||||
}},
|
||||
ice.WEB_SHARE: {Name: "share", Help: "共享链", Meta: kit.Dict("remote", "you"), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
ice.WEB_SHARE: {Name: "share", Help: "共享链", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
if len(arg) == 0 {
|
||||
// 共享列表
|
||||
m.Grows(ice.WEB_SHARE, nil, "", "", func(key int, value map[string]interface{}) {
|
||||
@ -905,20 +1071,30 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
switch arg[0] {
|
||||
case "add":
|
||||
// 创建共享
|
||||
extra := kit.Dict()
|
||||
for i := 4; i < len(arg)-1; i += 2 {
|
||||
kit.Value(extra, arg[i], arg[i+1])
|
||||
}
|
||||
|
||||
h := m.Rich(ice.WEB_SHARE, nil, kit.Dict(
|
||||
kit.MDB_TYPE, arg[1], kit.MDB_NAME, arg[2], kit.MDB_TEXT, arg[3],
|
||||
"extra", extra,
|
||||
))
|
||||
m.Grow(ice.WEB_SHARE, nil, kit.Dict(
|
||||
kit.MDB_TYPE, arg[1], kit.MDB_NAME, arg[2], kit.MDB_TEXT, arg[3],
|
||||
"share", h,
|
||||
))
|
||||
m.Info("share: %s", h)
|
||||
m.Info("share: %s %s", h, extra)
|
||||
m.Echo(h)
|
||||
}
|
||||
}},
|
||||
ice.WEB_ROUTE: {Name: "route", Help: "路由表", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
ice.WEB_ROUTE: {Name: "route", Help: "路由", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
}},
|
||||
ice.WEB_PROXY: {Name: "proxy", Help: "代理商", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
ice.WEB_PROXY: {Name: "proxy", Help: "代理", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
}},
|
||||
ice.WEB_GROUP: {Name: "group", Help: "分组", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
}},
|
||||
ice.WEB_LABEL: {Name: "label", Help: "标签", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
}},
|
||||
|
||||
"/proxy/": {Name: "/proxy/", Help: "代理商", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
@ -928,12 +1104,12 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
m.Confm(ice.WEB_SHARE, kit.Keys("hash", key), func(value map[string]interface{}) {
|
||||
m.Info("share %s %v", key, kit.Format(value))
|
||||
switch value["type"] {
|
||||
case kit.MIME_STORY:
|
||||
if m.Cmdy(ice.WEB_STORY, "index", value["data"]); m.Append("file") != "" {
|
||||
m.Push("_output", "file")
|
||||
} else {
|
||||
m.Push("_output", "result")
|
||||
case ice.TYPE_STORY:
|
||||
if m.Cmdy(ice.WEB_STORY, "index", kit.Value(value, "extra.data")).Append("text") == "" {
|
||||
m.Cmdy(ice.WEB_SPACE, kit.Value(value, "extra.pod"), ice.WEB_STORY, "index", kit.Value(value, "extra.data"))
|
||||
}
|
||||
m.Push("_output", kit.Select("file", "result", m.Append("file") == ""))
|
||||
|
||||
default:
|
||||
if m.Cmdy(ice.WEB_STORY, "index", value["data"]); m.Append("file") != "" {
|
||||
m.Push("_output", "file")
|
||||
@ -947,15 +1123,34 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
"/space/": {Name: "/space/", Help: "空间站", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
r := m.Optionv("request").(*http.Request)
|
||||
w := m.Optionv("response").(http.ResponseWriter)
|
||||
list := strings.Split(cmd, "/")
|
||||
|
||||
switch list[2] {
|
||||
case "share":
|
||||
m.Cmdy(ice.WEB_SHARE, list[3:])
|
||||
return
|
||||
case "upload":
|
||||
m.Cmdy(ice.WEB_CACHE, "upload")
|
||||
return
|
||||
case "download":
|
||||
m.Cmdy(ice.WEB_STORY, "index", list[3])
|
||||
m.Push("_output", kit.Select("file", "result", m.Append("file") == ""))
|
||||
return
|
||||
}
|
||||
|
||||
if s, e := websocket.Upgrade(w, r, nil, m.Confi(ice.WEB_SPACE, "meta.buffer"), m.Confi(ice.WEB_SPACE, "meta.buffer")); m.Assert(e) {
|
||||
// 共享空间
|
||||
share := m.Option("share")
|
||||
if m.Richs(ice.WEB_SHARE, nil, share, nil) == nil {
|
||||
share = m.Cmdx(ice.WEB_SHARE, "add", m.Option("node"), m.Option("name"), m.Option("user"))
|
||||
}
|
||||
|
||||
// 添加节点
|
||||
h := m.Rich(ice.WEB_SPACE, nil, kit.Dict(
|
||||
kit.MDB_TYPE, m.Option("node"),
|
||||
kit.MDB_NAME, m.Option("name"),
|
||||
kit.MDB_USER, m.Option("user"),
|
||||
"share", m.Cmdx(ice.WEB_SHARE, "add", m.Option("node"), m.Option("name"), m.Option("user")),
|
||||
"share", share,
|
||||
"socket", s,
|
||||
))
|
||||
m.Info("space: %s", m.Option(kit.MDB_NAME))
|
||||
@ -967,6 +1162,11 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
m.Log("close", "%s: %s", m.Option(kit.MDB_NAME), kit.Format(m.Confv(ice.WEB_SPACE, kit.Keys(kit.MDB_HASH, h))))
|
||||
m.Confv(ice.WEB_SPACE, kit.Keys(kit.MDB_HASH, h), "")
|
||||
})
|
||||
|
||||
// 共享空间
|
||||
if share != m.Option("share") {
|
||||
m.Cmd(ice.WEB_SPACE, m.Option("name"), ice.WEB_SPACE, "share", share)
|
||||
}
|
||||
}
|
||||
}},
|
||||
"/static/volcanos/plugin/github.com/": {Name: "/space/", Help: "空间站", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
|
28
conf.go
28
conf.go
@ -46,6 +46,7 @@ const (
|
||||
WEB_TMPL = "render"
|
||||
|
||||
WEB_LOGIN = "_login"
|
||||
|
||||
WEB_SPIDE = "spide"
|
||||
WEB_SERVE = "serve"
|
||||
WEB_SPACE = "space"
|
||||
@ -56,9 +57,11 @@ const (
|
||||
WEB_SHARE = "share"
|
||||
WEB_ROUTE = "route"
|
||||
WEB_PROXY = "proxy"
|
||||
WEB_GROUP = "group"
|
||||
WEB_LABEL = "label"
|
||||
)
|
||||
const (
|
||||
LOG_CMD = "cmd"
|
||||
LOG_CMDS = "cmds"
|
||||
LOG_COST = "cost"
|
||||
LOG_INFO = "info"
|
||||
LOG_WARN = "warn"
|
||||
@ -95,7 +98,24 @@ const (
|
||||
)
|
||||
|
||||
const (
|
||||
CHAT_GROUP = "group"
|
||||
CHAT_RIVER = "river"
|
||||
)
|
||||
|
||||
const (
|
||||
TYPE_SPACE = "space"
|
||||
TYPE_RIVER = "river"
|
||||
TYPE_STORM = "storm"
|
||||
|
||||
TYPE_STORY = "story"
|
||||
TYPE_SHELL = "shell"
|
||||
TYPE_TABLE = "table"
|
||||
TYPE_INNER = "inner"
|
||||
TYPE_MEDIA = "media"
|
||||
)
|
||||
const (
|
||||
FAVOR_CHAT = "chat.init"
|
||||
FAVOR_TMUX = "tmux.init"
|
||||
FAVOR_RIVER = "river.init"
|
||||
)
|
||||
|
||||
var Alias = map[string]string{
|
||||
@ -120,6 +140,8 @@ var Alias = map[string]string{
|
||||
WEB_SHARE: "web.share",
|
||||
WEB_ROUTE: "web.route",
|
||||
WEB_PROXY: "web.proxy",
|
||||
WEB_GROUP: "web.group",
|
||||
WEB_LABEL: "web.label",
|
||||
|
||||
GDB_SIGNAL: "gdb.signal",
|
||||
GDB_TIMER: "gdb.timer",
|
||||
@ -137,7 +159,7 @@ var Alias = map[string]string{
|
||||
MDB_SELECT: "mdb.select",
|
||||
MDB_DELETE: "mdb.delete",
|
||||
|
||||
CHAT_GROUP: "web.chat.group",
|
||||
CHAT_RIVER: "web.chat.river",
|
||||
|
||||
"note": "web.wiki.note",
|
||||
}
|
||||
|
@ -10,18 +10,26 @@ import (
|
||||
var Index = &ice.Context{Name: "chat", Help: "聊天模块",
|
||||
Caches: map[string]*ice.Cache{},
|
||||
Configs: map[string]*ice.Config{
|
||||
ice.CHAT_GROUP: {Name: "group", Help: "群组", Value: kit.Data()},
|
||||
ice.CHAT_RIVER: {Name: "river", Help: "群组", Value: kit.Data()},
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Cmd(ice.CTX_CONFIG, "load", "aaa.json")
|
||||
m.Cmd(ice.CTX_CONFIG, "load", "web.json")
|
||||
m.Cmd(ice.CTX_CONFIG, "load", "chat.json")
|
||||
if m.Richs(ice.WEB_FAVOR, nil, ice.FAVOR_RIVER, nil) == nil {
|
||||
// 群组模板
|
||||
m.Cmd(ice.WEB_FAVOR, ice.FAVOR_RIVER, "river", "meet", "root")
|
||||
m.Cmd(ice.WEB_FAVOR, ice.FAVOR_RIVER, "user", m.Conf(ice.CLI_RUNTIME, "boot.username"), "root")
|
||||
m.Cmd(ice.WEB_FAVOR, ice.FAVOR_RIVER, "storm", "miss", "root")
|
||||
m.Cmd(ice.WEB_FAVOR, ice.FAVOR_RIVER, "action", "space", "root")
|
||||
m.Cmd(ice.WEB_FAVOR, ice.FAVOR_RIVER, "action", "dream", "root")
|
||||
m.Cmd(ice.WEB_FAVOR, ice.FAVOR_RIVER, "action", "favor", "root")
|
||||
m.Cmd(ice.WEB_FAVOR, ice.FAVOR_RIVER, "action", "cache", "root")
|
||||
m.Cmd(ice.WEB_FAVOR, ice.FAVOR_RIVER, "action", "story", "root")
|
||||
m.Cmd(ice.WEB_FAVOR, ice.FAVOR_RIVER, "action", "share", "root")
|
||||
}
|
||||
}},
|
||||
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Cmd(ice.CTX_CONFIG, "save", "chat.json", ice.CHAT_GROUP)
|
||||
m.Cmd(ice.CTX_CONFIG, "save", "web.json", ice.WEB_SPIDE, ice.WEB_FAVOR, ice.WEB_CACHE, ice.WEB_STORY, ice.WEB_SHARE)
|
||||
m.Cmd(ice.CTX_CONFIG, "save", "aaa.json", ice.AAA_ROLE, ice.AAA_USER, ice.AAA_SESS)
|
||||
m.Cmd(ice.CTX_CONFIG, "save", "chat.json", ice.CHAT_RIVER)
|
||||
}},
|
||||
|
||||
ice.WEB_LOGIN: {Name: "login", Help: "登录", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
@ -30,12 +38,29 @@ var Index = &ice.Context{Name: "chat", Help: "聊天模块",
|
||||
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]))))
|
||||
if m.Richs(ice.CHAT_RIVER, nil, "", nil) == nil {
|
||||
// 默认群组
|
||||
m.Richs(ice.WEB_FAVOR, nil, "river.init", func(key string, value map[string]interface{}) {
|
||||
m.Grows(ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) {
|
||||
switch kit.Format(value["type"]) {
|
||||
case "river":
|
||||
m.Option("river", m.Cmdx("/ocean", "spawn", value["name"]))
|
||||
case "user":
|
||||
m.Cmd("/river", m.Option("river"), "add", value["name"])
|
||||
case "storm":
|
||||
m.Option("storm", m.Cmdx("/steam", m.Option("river"), "spawn", value["name"]))
|
||||
case "action":
|
||||
m.Cmd("/storm", m.Option("river"), m.Option("storm"), "add", m.Conf(ice.CLI_RUNTIME, "node.name"), "", value["name"], value["text"])
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
default:
|
||||
// 用户群组
|
||||
m.Richs(ice.CHAT_GROUP, nil, arg[0], func(value map[string]interface{}) {
|
||||
m.Richs(ice.CHAT_RIVER, nil, arg[0], func(value map[string]interface{}) {
|
||||
m.Option(ice.MSG_RIVER, arg[0])
|
||||
if len(arg) > 1 {
|
||||
m.Richs(ice.CHAT_GROUP, kit.Keys(kit.MDB_HASH, arg[0], "tool"), arg[1], func(value map[string]interface{}) {
|
||||
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])
|
||||
})
|
||||
}
|
||||
@ -79,21 +104,22 @@ var Index = &ice.Context{Name: "chat", Help: "聊天模块",
|
||||
switch arg[0] {
|
||||
case "spawn":
|
||||
// 创建群组
|
||||
river := m.Rich(ice.CHAT_GROUP, nil, kit.Data(kit.MDB_NAME, arg[1]))
|
||||
river := m.Rich(ice.CHAT_RIVER, nil, kit.Data(kit.MDB_NAME, arg[1]))
|
||||
m.Info("create river: %v name: %v", river, arg[1])
|
||||
m.Cmd("/river", river, "add", arg[2:])
|
||||
m.Echo(river)
|
||||
}
|
||||
}},
|
||||
"/river": {Name: "/river", Help: "小河流", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
switch len(arg) {
|
||||
case 0:
|
||||
// 群组列表
|
||||
m.Richs(ice.CHAT_GROUP, nil, "", func(key string, value map[string]interface{}) {
|
||||
m.Richs(ice.CHAT_RIVER, nil, "", func(key string, value map[string]interface{}) {
|
||||
m.Push(key, value["meta"], []string{kit.MDB_KEY, kit.MDB_NAME})
|
||||
})
|
||||
case 1:
|
||||
// 群组详情
|
||||
m.Richs(ice.CHAT_GROUP, nil, arg[0], func(key string, value map[string]interface{}) {
|
||||
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})
|
||||
})
|
||||
default:
|
||||
@ -101,7 +127,7 @@ var Index = &ice.Context{Name: "chat", Help: "聊天模块",
|
||||
case "add":
|
||||
// 添加用户
|
||||
for _, v := range arg[2:] {
|
||||
user := m.Rich(ice.CHAT_GROUP, kit.Keys(kit.MDB_HASH, arg[0], "user"), kit.Data("username", v))
|
||||
user := m.Rich(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0], "user"), kit.Data("username", v))
|
||||
m.Info("add river: %s user: %s name: %s", arg[0], user, v)
|
||||
}
|
||||
}
|
||||
@ -111,7 +137,7 @@ var Index = &ice.Context{Name: "chat", Help: "聊天模块",
|
||||
prefix := kit.Keys(kit.MDB_HASH, arg[0], "tool")
|
||||
if len(arg) < 2 {
|
||||
// 应用列表
|
||||
m.Richs(ice.CHAT_GROUP, prefix, "", func(key string, value map[string]interface{}) {
|
||||
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})
|
||||
})
|
||||
m.Sort(kit.MDB_NAME)
|
||||
@ -122,23 +148,23 @@ var Index = &ice.Context{Name: "chat", Help: "聊天模块",
|
||||
case "add":
|
||||
// 添加命令
|
||||
for i := 3; i < len(arg)-3; i += 4 {
|
||||
id := m.Grow(ice.CHAT_GROUP, kit.Keys(prefix, kit.MDB_HASH, arg[1]), kit.Data(
|
||||
id := m.Grow(ice.CHAT_RIVER, kit.Keys(prefix, kit.MDB_HASH, arg[1]), kit.Data(
|
||||
"pod", arg[i], "ctx", arg[i+1], "cmd", arg[i+2], "key", arg[i+3],
|
||||
))
|
||||
m.Info("create tool %d %v", id, arg[i:i+4])
|
||||
}
|
||||
case "rename":
|
||||
// 重命名应用
|
||||
old := m.Conf(ice.CHAT_GROUP, kit.Keys(prefix, kit.MDB_HASH, arg[1], kit.MDB_META, kit.MDB_NAME))
|
||||
old := m.Conf(ice.CHAT_RIVER, kit.Keys(prefix, kit.MDB_HASH, arg[1], kit.MDB_META, kit.MDB_NAME))
|
||||
m.Info("rename storm: %s %s->%s", arg[1], old, arg[3])
|
||||
m.Conf(ice.CHAT_GROUP, kit.Keys(prefix, kit.MDB_HASH, arg[1], kit.MDB_META, kit.MDB_NAME), arg[3])
|
||||
m.Conf(ice.CHAT_RIVER, kit.Keys(prefix, kit.MDB_HASH, arg[1], kit.MDB_META, kit.MDB_NAME), arg[3])
|
||||
|
||||
case "remove":
|
||||
// 删除应用
|
||||
m.Richs(ice.CHAT_GROUP, kit.Keys(prefix), arg[1], func(value map[string]interface{}) {
|
||||
m.Richs(ice.CHAT_RIVER, kit.Keys(prefix), arg[1], func(value map[string]interface{}) {
|
||||
m.Info("remove storm: %s %s", arg[1], kit.Format(value))
|
||||
})
|
||||
m.Conf(ice.CHAT_GROUP, kit.Keys(prefix, kit.MDB_HASH, arg[1]), "")
|
||||
m.Conf(ice.CHAT_RIVER, kit.Keys(prefix, kit.MDB_HASH, arg[1]), "")
|
||||
}
|
||||
}},
|
||||
"/steam": {Name: "/steam", Help: "大气层", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
@ -153,9 +179,10 @@ var Index = &ice.Context{Name: "chat", Help: "聊天模块",
|
||||
switch arg[1] {
|
||||
case "spawn":
|
||||
// 创建应用
|
||||
storm := m.Rich(ice.CHAT_GROUP, kit.Keys(kit.MDB_HASH, arg[0], "tool"), kit.Data(kit.MDB_NAME, arg[2]))
|
||||
storm := m.Rich(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0], "tool"), kit.Data(kit.MDB_NAME, arg[2]))
|
||||
m.Info("create river: %s storm: %s name: %v", arg[0], storm, arg[2])
|
||||
m.Cmd("/storm", arg[0], storm, "add", arg[3:])
|
||||
m.Echo(storm)
|
||||
|
||||
default:
|
||||
// 命令列表
|
||||
@ -168,7 +195,7 @@ var Index = &ice.Context{Name: "chat", Help: "聊天模块",
|
||||
if len(arg) == 2 {
|
||||
// 命令列表
|
||||
m.Set(ice.MSG_OPTION)
|
||||
m.Grows(ice.CHAT_GROUP, prefix, "", "", func(index int, value map[string]interface{}) {
|
||||
m.Grows(ice.CHAT_RIVER, prefix, "", "", func(index int, value map[string]interface{}) {
|
||||
if meta, ok := kit.Value(value, "meta").(map[string]interface{}); ok {
|
||||
m.Push("river", arg[0])
|
||||
m.Push("storm", arg[1])
|
||||
@ -188,16 +215,20 @@ var Index = &ice.Context{Name: "chat", Help: "聊天模块",
|
||||
return
|
||||
}
|
||||
|
||||
// 执行命令
|
||||
m.Grows(ice.CHAT_GROUP, prefix, kit.MDB_ID, kit.Format(kit.Int(arg[2])+1), func(index int, value map[string]interface{}) {
|
||||
// 查询命令
|
||||
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 kit.Format(meta["pod"]) == m.Conf(ice.CLI_RUNTIME, "node.name") {
|
||||
m.Cmdy(kit.Keys(meta["ctx"], meta["cmd"]), arg[3:])
|
||||
cmds = kit.Simple(kit.Keys(meta["ctx"], meta["cmd"]), arg[3:])
|
||||
} else {
|
||||
m.Cmdy(ice.WEB_SPACE, meta["pod"], kit.Keys(meta["ctx"], meta["cmd"]), arg[3:])
|
||||
cmds = kit.Simple(ice.WEB_SPACE, meta["pod"], kit.Keys(meta["ctx"], meta["cmd"]), arg[3:])
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 执行命令
|
||||
m.Cmdy(cmds).Option("cmds", cmds)
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
@ -33,6 +33,10 @@ var Index = &ice.Context{Name: "code", Help: "编程模块",
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Cmd(ice.CTX_CONFIG, "load", "code.json")
|
||||
}},
|
||||
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Cmd(ice.CTX_CONFIG, "save", "code.json", "web.code.login")
|
||||
}},
|
||||
|
||||
"login": {Name: "login", Help: "登录", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
@ -47,18 +51,19 @@ var Index = &ice.Context{Name: "code", Help: "编程模块",
|
||||
}
|
||||
}
|
||||
|
||||
you := m.Conf(ice.WEB_SHARE, kit.Keys("hash", m.Option("share"), "name"))
|
||||
// 添加终端
|
||||
h := m.Rich("login", nil, kit.Dict(
|
||||
"status", "login",
|
||||
"type", kit.Select("zsh", arg, 1),
|
||||
"you", m.Conf(ice.WEB_SHARE, kit.Keys("hash", m.Option("share"), "name")),
|
||||
"you", you,
|
||||
"pwd", m.Option("pwd"),
|
||||
"pid", m.Option("pid"),
|
||||
"pane", m.Option("pane"),
|
||||
"hostname", m.Option("hostname"),
|
||||
"username", m.Option("username"),
|
||||
))
|
||||
m.Info("zsh %s", h)
|
||||
m.Info("%s: %s", you, h)
|
||||
m.Echo(h)
|
||||
|
||||
case "list":
|
||||
@ -78,28 +83,34 @@ var Index = &ice.Context{Name: "code", Help: "编程模块",
|
||||
case "login":
|
||||
m.Cmdy("login", "init", cmd).Push("_output", "result")
|
||||
case "upload":
|
||||
// 上传文件
|
||||
msg := m.Cmd(ice.WEB_STORY, "upload")
|
||||
m.Push("_output", "result")
|
||||
m.Echo("list: %s\n", msg.Append("list"))
|
||||
// 缓存文件
|
||||
msg := m.Cmd(ice.WEB_CACHE, "upload")
|
||||
m.Echo("data: %s\n", msg.Append("data"))
|
||||
m.Echo("time: %s\n", msg.Append("time"))
|
||||
m.Echo("type: %s\n", msg.Append("type"))
|
||||
m.Echo("name: %s\n", msg.Append("name"))
|
||||
m.Echo("size: %s\n", msg.Append("size"))
|
||||
m.Push("_output", "result")
|
||||
|
||||
// 下发文件
|
||||
m.Cmd(ice.WEB_SPACE, msg.Option("you"), ice.WEB_SPACE, "download", msg.Append("type"), msg.Append("name"), "self", msg.Append("data"))
|
||||
|
||||
case "download":
|
||||
// 下载文件
|
||||
m.Cmdy(ice.WEB_STORY, "download", m.Optionv("arg"))
|
||||
m.Option("you", "")
|
||||
if m.Cmdy(ice.WEB_STORY, "index", m.Option("arg")).Append("text") == "" {
|
||||
m.Cmdy(ice.WEB_SPACE, m.Option("pod"), ice.WEB_STORY, "index", m.Optionv("arg"))
|
||||
}
|
||||
m.Push("_output", kit.Select("file", "result", m.Append("file") == ""))
|
||||
|
||||
case "history":
|
||||
m.Option("you", "")
|
||||
vs := strings.SplitN(strings.TrimSpace(m.Option("arg")), " ", 2)
|
||||
m.Cmd(ice.WEB_SPACE, m.Option("you"), ice.WEB_FAVOR, "zsh.history", "shell", m.Option("sid"), kit.Select("", vs, 1),
|
||||
"sid", m.Option("sid"), "num", vs[0], "pwd", m.Option("pwd"))
|
||||
m.Push("_output", "void")
|
||||
}
|
||||
}},
|
||||
|
||||
"_tmux": {Name: "tmux [session [window [pane cmd]]]", Help: "窗口", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
prefix := kit.Simple(m.Confv("prefix", "tmux"))
|
||||
if len(arg) > 1 {
|
||||
|
@ -1,2 +1,2 @@
|
||||
all:
|
||||
go build -o bin/ice.bin main.go && chmod u+x bin/ice.bin && ./load.sh restart
|
||||
go build -o bin/ice.bin main.go && chmod u+x bin/ice.bin && ./ice.sh restart
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/icebergs/base/cli"
|
||||
"github.com/shylinux/toolkits"
|
||||
"path"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
@ -51,7 +52,14 @@ var Index = &ice.Context{Name: "tmux", Help: "终端模块",
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Cmd(ice.GDB_EVENT, "listen", ice.DREAM_START, "cli.tmux.session")
|
||||
m.Cmd(ice.GDB_EVENT, "listen", ice.DREAM_START, "cli.tmux.auto")
|
||||
if m.Richs(ice.WEB_STORY, "head", "auto.sh", nil) == nil {
|
||||
m.Cmd(ice.WEB_STORY, "add", "shell", "auto.sh", m.Cmdx(ice.WEB_SPIDE, "shy", "GET", "/publish/auto.sh"))
|
||||
}
|
||||
if m.Richs(ice.WEB_FAVOR, nil, ice.FAVOR_TMUX, nil) == nil {
|
||||
m.Cmd(ice.WEB_FAVOR, ice.FAVOR_TMUX, ice.TYPE_SHELL, "下载脚本", `curl -s "$ctx_dev/code/zsh?cmd=download&arg=auto.sh" > auto.sh`)
|
||||
m.Cmd(ice.WEB_FAVOR, ice.FAVOR_TMUX, ice.TYPE_SHELL, "加载脚本", `source auto.sh`)
|
||||
}
|
||||
}},
|
||||
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
}},
|
||||
@ -102,7 +110,7 @@ var Index = &ice.Context{Name: "tmux", Help: "终端模块",
|
||||
case "session":
|
||||
target = arg[3]
|
||||
}
|
||||
m.Cmd("run", target, m.Option("hot"))
|
||||
m.Cmd("auto", target, m.Option("hot"))
|
||||
arg = arg[:0]
|
||||
|
||||
case "select":
|
||||
@ -167,7 +175,7 @@ var Index = &ice.Context{Name: "tmux", Help: "终端模块",
|
||||
m.Option("cmd_env", "TMUX", "")
|
||||
m.Option("cmd_dir", m.Conf(ice.WEB_DREAM, "meta.path"))
|
||||
m.Cmd(prefix, "new-session", "-ds", arg[0])
|
||||
m.Cmd("run", arg[0], arg[1:])
|
||||
m.Cmd("auto", arg[0], arg[1:])
|
||||
arg = arg[:1]
|
||||
}
|
||||
|
||||
@ -209,15 +217,23 @@ var Index = &ice.Context{Name: "tmux", Help: "终端模块",
|
||||
"view": {Name: "view", Help: "终端", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Cmdy("cli.system", "tmux", "capture-pane", "-pt", kit.Select("", arg, 0)).Set("append")
|
||||
}},
|
||||
"run": {Name: "view", Help: "终端", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
"auto": {Name: "auto", Help: "终端", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
prefix := []string{"cli.system", "tmux"}
|
||||
|
||||
m.Option("cmd_env", "TMUX", "")
|
||||
m.Option("cmd_dir", path.Join(m.Conf(ice.WEB_DREAM, "meta.path"), arg[0]))
|
||||
|
||||
// 创建会话
|
||||
if m.Cmd(prefix, "has-session", "-t", arg[0]).Append("code") != "0" {
|
||||
m.Cmd(prefix, "new-session", "-ds", arg[0])
|
||||
}
|
||||
|
||||
m.Richs(ice.WEB_SPACE, nil, arg[0], func(key string, value map[string]interface{}) {
|
||||
m.Cmdy(prefix, "send-keys", "-t", arg[0], "export ctx_dev=", kit.Select(m.Conf(ice.CLI_RUNTIME, "host.ctx_dev"), m.Conf(ice.CLI_RUNTIME, "host.ctx_self")), "Enter")
|
||||
m.Cmdy(prefix, "send-keys", "-t", arg[0], "export ctx_share=", value["share"], "Enter")
|
||||
})
|
||||
|
||||
m.Option("cmd_env", "TMUX", "")
|
||||
m.Cmd(ice.WEB_FAVOR, kit.Select("some", arg, 1)).Table(func(index int, value map[string]string, head []string) {
|
||||
m.Cmd(ice.WEB_FAVOR, kit.Select("tmux.init", arg, 1)).Table(func(index int, value map[string]string, head []string) {
|
||||
switch value["type"] {
|
||||
case "shell":
|
||||
m.Cmdy(prefix, "send-keys", "-t", arg[0], value["text"], "Enter")
|
||||
|
23
type.go
23
type.go
@ -77,7 +77,7 @@ func (c *Context) Server() Server {
|
||||
}
|
||||
func (c *Context) Run(m *Message, cmd *Command, key string, arg ...string) *Message {
|
||||
m.Hand = true
|
||||
m.Log(LOG_CMD, "%s.%s %v", c.Name, key, arg)
|
||||
m.Log(LOG_CMDS, "%s.%s %v", c.Name, key, arg)
|
||||
cmd.Hand(m, c, key, arg...)
|
||||
return m
|
||||
}
|
||||
@ -599,21 +599,20 @@ func (m *Message) Log(level string, str string, arg ...interface{}) *Message {
|
||||
}
|
||||
prefix, suffix := "", ""
|
||||
switch level {
|
||||
case LOG_CMD, "start", "serve":
|
||||
case LOG_CMDS, "start", "serve":
|
||||
prefix, suffix = "\033[32m", "\033[0m"
|
||||
case LOG_COST:
|
||||
prefix, suffix = "\033[33m", "\033[0m"
|
||||
case LOG_WARN, LOG_ERROR, "close":
|
||||
prefix, suffix = "\033[31m", "\033[0m"
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "%s %d %s->%s %s%s %s%s\n",
|
||||
m.time.Format(ICE_TIME), m.code, m.source.Name, m.target.Name,
|
||||
fmt.Fprintf(os.Stderr, "%s %02d %9s %s%s %s%s\n",
|
||||
m.time.Format(ICE_TIME), m.code, fmt.Sprintf("%s->%s", m.source.Name, m.target.Name),
|
||||
prefix, level, str, suffix)
|
||||
return m
|
||||
}
|
||||
func (m *Message) Cost(str string, arg ...interface{}) *Message {
|
||||
m.Log(LOG_COST, "%s: %s", m.Format("cost"), kit.Format(str, arg...))
|
||||
return m.Log(LOG_INFO, str, arg...)
|
||||
return m.Log(LOG_COST, "%s: %s", m.Format("cost"), kit.Format(str, arg...))
|
||||
}
|
||||
func (m *Message) Info(str string, arg ...interface{}) *Message {
|
||||
return m.Log(LOG_INFO, str, arg...)
|
||||
@ -847,12 +846,14 @@ func (m *Message) Richs(key string, chain interface{}, raw interface{}, cb inter
|
||||
res, _ = hash[h].(map[string]interface{})
|
||||
default:
|
||||
// 单个查询
|
||||
switch kit.Format(kit.Value(meta, kit.MDB_SHORT)) {
|
||||
case "", "uniq":
|
||||
default:
|
||||
h = kit.Hashs(h)
|
||||
if res, ok = hash[h].(map[string]interface{}); !ok {
|
||||
switch kit.Format(kit.Value(meta, kit.MDB_SHORT)) {
|
||||
case "", "uniq":
|
||||
default:
|
||||
h = kit.Hashs(h)
|
||||
res, ok = hash[h].(map[string]interface{})
|
||||
}
|
||||
}
|
||||
res, _ = hash[h].(map[string]interface{})
|
||||
}
|
||||
|
||||
// 返回数据
|
||||
|
Loading…
x
Reference in New Issue
Block a user