forked from x/icebergs
add story.upload
This commit is contained in:
parent
b7a09f2733
commit
1e7aed134c
@ -18,7 +18,7 @@ var Index = &ice.Context{Name: "aaa", Help: "认证模块",
|
||||
ice.AAA_ROLE: {Name: "role", Help: "角色", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
switch arg[0] {
|
||||
case "check":
|
||||
m.Echo(kit.Select("void", "root", arg[1] == m.Conf("cli.runtime", "boot.username")))
|
||||
m.Echo(kit.Select("void", "root", arg[1] == m.Conf(ice.CLI_RUNTIME, "boot.username")))
|
||||
}
|
||||
}},
|
||||
ice.AAA_USER: {Name: "user", Help: "用户", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
@ -27,10 +27,10 @@ var Index = &ice.Context{Name: "aaa", Help: "认证模块",
|
||||
// 用户认证
|
||||
user := m.Richs(ice.AAA_USER, nil, arg[1], nil)
|
||||
if user == nil {
|
||||
m.Rich(ice.AAA_USER, nil, map[string]interface{}{
|
||||
"username": arg[1], "password": arg[2],
|
||||
"usernode": m.Conf("cli.runtime", "boot.hostname"),
|
||||
})
|
||||
m.Rich(ice.AAA_USER, nil, kit.Dict(
|
||||
"username", arg[1], "password", arg[2],
|
||||
"usernode", m.Conf(ice.CLI_RUNTIME, "boot.hostname"),
|
||||
))
|
||||
user = m.Richs(ice.AAA_USER, nil, arg[1], nil)
|
||||
m.Info("create user: %s %s", arg[1], kit.Format(user))
|
||||
} else if kit.Format(user["password"]) != arg[2] {
|
||||
@ -42,9 +42,9 @@ var Index = &ice.Context{Name: "aaa", Help: "认证模块",
|
||||
sessid := kit.Format(user[ice.WEB_SESS])
|
||||
if sessid == "" {
|
||||
role := m.Cmdx(ice.AAA_ROLE, "check", arg[1])
|
||||
sessid = m.Rich(ice.AAA_SESS, nil, map[string]interface{}{
|
||||
"username": arg[1], "userrole": role,
|
||||
})
|
||||
sessid = m.Rich(ice.AAA_SESS, nil, kit.Dict(
|
||||
"username", arg[1], "userrole", role,
|
||||
))
|
||||
m.Info("user: %s role: %s sess: %s", arg[1], role, sessid)
|
||||
}
|
||||
m.Echo(sessid)
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"github.com/shylinux/toolkits"
|
||||
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/user"
|
||||
@ -15,55 +16,58 @@ import (
|
||||
var Index = &ice.Context{Name: "cli", Help: "命令模块",
|
||||
Caches: map[string]*ice.Cache{},
|
||||
Configs: map[string]*ice.Config{
|
||||
"runtime": {Name: "runtime", Value: map[string]interface{}{
|
||||
"host": map[string]interface{}{},
|
||||
"boot": map[string]interface{}{},
|
||||
"node": map[string]interface{}{},
|
||||
"user": map[string]interface{}{},
|
||||
"work": map[string]interface{}{},
|
||||
}},
|
||||
ice.CLI_RUNTIME: {Name: "runtime", Help: "运行环境", Value: kit.Dict()},
|
||||
},
|
||||
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", "var/conf/cli.json")
|
||||
m.Cmd(ice.CTX_CONFIG, "load", "cli.json")
|
||||
|
||||
m.Conf("runtime", "host.GOARCH", runtime.GOARCH)
|
||||
m.Conf("runtime", "host.GOOS", runtime.GOOS)
|
||||
m.Conf("runtime", "host.pid", os.Getpid())
|
||||
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())
|
||||
|
||||
if name, e := os.Hostname(); e == nil {
|
||||
m.Conf("runtime", "boot.hostname", kit.Select(name, os.Getenv("HOSTNAME")))
|
||||
m.Conf(ice.CLI_RUNTIME, "boot.hostname", kit.Select(name, os.Getenv("HOSTNAME")))
|
||||
}
|
||||
if user, e := user.Current(); e == nil {
|
||||
m.Conf("runtime", "boot.username", path.Base(kit.Select(user.Name, os.Getenv("USER"))))
|
||||
m.Conf(ice.CLI_RUNTIME, "boot.username", path.Base(kit.Select(user.Name, os.Getenv("USER"))))
|
||||
}
|
||||
if name, e := os.Getwd(); e == nil {
|
||||
m.Conf("runtime", "boot.pathname", path.Base(kit.Select(name, os.Getenv("PWD"))))
|
||||
m.Conf(ice.CLI_RUNTIME, "boot.pathname", path.Base(kit.Select(name, os.Getenv("PWD"))))
|
||||
}
|
||||
|
||||
m.Conf("runtime", "node.type", "worker")
|
||||
m.Conf("runtime", "node.name", m.Conf("runtime", "boot.pathname"))
|
||||
m.Log("info", "runtime %v", kit.Formats(m.Confv("runtime")))
|
||||
m.Conf(ice.CLI_RUNTIME, "node.type", kit.MIME_WORKER)
|
||||
m.Conf(ice.CLI_RUNTIME, "node.name", m.Conf(ice.CLI_RUNTIME, "boot.pathname"))
|
||||
m.Log("info", "runtime %v", kit.Formats(m.Confv(ice.CLI_RUNTIME)))
|
||||
}},
|
||||
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Cmd(ice.CTX_CONFIG, "save", "var/conf/cli.json", "cli.runtime")
|
||||
m.Cmd(ice.CTX_CONFIG, "save", "cli.json", ice.CLI_RUNTIME)
|
||||
}},
|
||||
"runtime": {Name: "runtime", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
ice.CLI_RUNTIME: {Name: "runtime", Help: "运行环境", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
}},
|
||||
"system": {Name: "system", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
|
||||
ice.CLI_SYSTEM: {Name: "system", Help: "系统命令", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
|
||||
cmd := exec.Command(arg[0], arg[1:]...)
|
||||
|
||||
// 运行目录
|
||||
cmd.Dir = m.Option("cmd_dir")
|
||||
m.Log("info", "dir: %s", cmd.Dir)
|
||||
m.Info("dir: %s", cmd.Dir)
|
||||
|
||||
// 环境变量
|
||||
env := kit.Simple(m.Optionv("cmd_env"))
|
||||
for i := 0; i < len(env)-1; i += 2 {
|
||||
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", env[i], env[i+1]))
|
||||
}
|
||||
m.Info("env: %s", cmd.Env)
|
||||
|
||||
if m.Option("cmd_type") == "daemon" {
|
||||
// 守护进程
|
||||
m.Gos(m, func(m *ice.Message) {
|
||||
if e := cmd.Start(); e != nil {
|
||||
m.Log("warn", "%v start %s", arg, e)
|
||||
m.Warn(e != nil, "%v start: %s", arg, e)
|
||||
} else if e := cmd.Wait(); e != nil {
|
||||
m.Log("warn", "%v wait %s", arg, e)
|
||||
m.Warn(e != nil, "%v wait: %s", arg, e)
|
||||
} else {
|
||||
m.Log("info", "%v exit", arg)
|
||||
m.Info("%v exit", arg)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
@ -73,15 +77,13 @@ var Index = &ice.Context{Name: "cli", Help: "命令模块",
|
||||
cmd.Stdout = out
|
||||
cmd.Stderr = err
|
||||
if e := cmd.Run(); e != nil {
|
||||
m.Warn(e != nil, kit.Select(e.Error(), err.String()))
|
||||
m.Warn(e != nil, "%v run: %s", arg, kit.Select(e.Error(), err.String()))
|
||||
} else {
|
||||
m.Echo(out.String())
|
||||
}
|
||||
m.Push("code", int(cmd.ProcessState.ExitCode()))
|
||||
}
|
||||
}},
|
||||
"timer": {Name: "timer", Help: "hello", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -63,8 +63,8 @@ var Index = &ice.Context{Name: "ctx", Help: "元始模块",
|
||||
m.Push("meta", kit.Format(cmd.Meta))
|
||||
m.Push("list", kit.Format(cmd.List))
|
||||
} else {
|
||||
if cmd.Meta != nil && kit.Format(cmd.Meta["remote"]) == "true" && m.Option("you") != "" {
|
||||
m.Copy(m.Spawns(s).Cmd("web.space", m.Option("you"), "ctx.command", arg[0], arg[1], "run", arg[3:]))
|
||||
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:]))
|
||||
} else {
|
||||
m.Copy(s.Run(m.Spawns(s), cmd, key, arg[3:]...))
|
||||
}
|
||||
|
17
base/web/template.go
Normal file
17
base/web/template.go
Normal file
@ -0,0 +1,17 @@
|
||||
package web
|
||||
|
||||
var share_template = map[string]interface{}{
|
||||
"shy/story": `{{}}`,
|
||||
"shy/chain": `<!DOCTYPE html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" text="text/css" href="/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<fieldset>
|
||||
{{.Append "type"}}
|
||||
{{.Append "text"}}
|
||||
</fieldset>
|
||||
</body>
|
||||
`,
|
||||
}
|
503
base/web/web.go
503
base/web/web.go
@ -8,10 +8,12 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"text/template"
|
||||
@ -39,69 +41,66 @@ func Cookie(msg *ice.Message, sessid string) string {
|
||||
}
|
||||
func (web *Frame) Login(msg *ice.Message, w http.ResponseWriter, r *http.Request) bool {
|
||||
if msg.Options(ice.WEB_SESS) {
|
||||
sub := msg.Cmd("aaa.sess", "check", msg.Option(ice.WEB_SESS))
|
||||
msg.Log("info", "role: %s user: %s", msg.Option(ice.MSG_USERROLE, sub.Append("userrole")),
|
||||
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.Option(ice.MSG_USERNAME, sub.Append("username")))
|
||||
}
|
||||
|
||||
msg.Target().Runs(msg, msg.Option("url"), ice.WEB_LOGIN, kit.Simple(msg.Optionv("cmds"))...)
|
||||
return true
|
||||
if s, ok := msg.Target().Commands[ice.WEB_LOGIN]; ok {
|
||||
msg.Target().Run(msg, s, ice.WEB_LOGIN, kit.Simple(msg.Optionv("cmds"))...)
|
||||
}
|
||||
return msg.Option("url") != ""
|
||||
}
|
||||
func (web *Frame) HandleWSS(m *ice.Message, safe bool, c *websocket.Conn) bool {
|
||||
for {
|
||||
if t, b, e := c.ReadMessage(); e != nil {
|
||||
m.Log("warn", "space recv %d msg %v", t, e)
|
||||
if t, b, e := c.ReadMessage(); m.Warn(e != nil, "space recv %d msg %v", t, e) {
|
||||
break
|
||||
} else {
|
||||
switch t {
|
||||
case MSG_MAPS:
|
||||
// 接收报文
|
||||
socket, msg := c, m.Spawn(b)
|
||||
source := kit.Simple(msg.Optionv("_source"))
|
||||
target := kit.Simple(msg.Optionv("_target"))
|
||||
msg.Log("space", "recv %v %v->%v %v", t, source, target, msg.Formats("meta"))
|
||||
source := kit.Simple(msg.Optionv(ice.MSG_SOURCE))
|
||||
target := kit.Simple(msg.Optionv(ice.MSG_TARGET))
|
||||
msg.Info("recv %v %v->%v %v", t, source, target, msg.Format("meta"))
|
||||
|
||||
if len(target) > 0 {
|
||||
if s, ok := msg.Confv("web.space", "hash."+target[0]+".socket").(*websocket.Conn); ok {
|
||||
msg.Log("space", "route")
|
||||
// 转发报文
|
||||
socket, source, target = s, append(source, target[0]), target[1:]
|
||||
} else if call, ok := web.send[msg.Option("_target")]; len(target) == 1 && ok {
|
||||
msg.Log("space", "done")
|
||||
// 接收响应
|
||||
delete(web.send, msg.Option("_target"))
|
||||
call.Back(msg)
|
||||
break
|
||||
} else if msg.Option("_handle") == "true" {
|
||||
msg.Log("space", "miss")
|
||||
// 丢弃报文
|
||||
break
|
||||
} else {
|
||||
// 失败报文
|
||||
msg.Log("space", "error")
|
||||
msg.Echo("error")
|
||||
source, target = []string{source[len(source)-1]}, kit.Revert(source)[1:]
|
||||
}
|
||||
} else {
|
||||
msg.Log("space", "run")
|
||||
if len(target) == 0 {
|
||||
// 本地执行
|
||||
if safe {
|
||||
msg = msg.Cmd()
|
||||
if msg.Detail() == "exit" {
|
||||
if msg.Optionv(ice.MSG_HANDLE, "true"); !msg.Warn(!safe, "no right") {
|
||||
if msg = msg.Cmd(); msg.Detail() == "exit" {
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
msg.Echo("no right")
|
||||
}
|
||||
msg.Optionv("_handle", "true")
|
||||
kit.Revert(source)
|
||||
source, target = []string{source[0]}, source[1:]
|
||||
|
||||
} else if s, ok := msg.Confv(ice.WEB_SPACE, kit.Keys("hash", target[0], "socket")).(*websocket.Conn); ok {
|
||||
// 转发报文
|
||||
msg.Info("space route")
|
||||
socket, source, target = s, append(source, target[0]), target[1:]
|
||||
|
||||
} else if call, ok := web.send[msg.Option(ice.MSG_TARGET)]; len(target) == 1 && ok {
|
||||
// 接收响应
|
||||
msg.Info("space done")
|
||||
delete(web.send, msg.Option(ice.MSG_TARGET))
|
||||
call.Back(msg)
|
||||
break
|
||||
|
||||
} else if msg.Warn(msg.Option("_handle") == "true", "space miss") {
|
||||
// 丢弃报文
|
||||
break
|
||||
|
||||
} else {
|
||||
// 失败报文
|
||||
msg.Warn(true, "space error")
|
||||
source, target = []string{source[len(source)-1]}, kit.Revert(source)[1:]
|
||||
}
|
||||
|
||||
// 发送报文
|
||||
msg.Optionv("_source", source)
|
||||
msg.Optionv("_target", target)
|
||||
msg.Log("space", "send %v %v->%v %v", t, source, target, msg.Formats("meta"))
|
||||
msg.Optionv(ice.MSG_SOURCE, source)
|
||||
msg.Optionv(ice.MSG_TARGET, target)
|
||||
socket.WriteMessage(t, []byte(msg.Format("meta")))
|
||||
msg.Info("send %v %v->%v %v", t, source, target, msg.Format("meta"))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -151,10 +150,9 @@ func (web *Frame) HandleCGI(m *ice.Message, alias map[string]interface{}, which
|
||||
func (web *Frame) HandleCmd(m *ice.Message, key string, cmd *ice.Command) {
|
||||
web.HandleFunc(key, func(w http.ResponseWriter, r *http.Request) {
|
||||
m.TryCatch(m.Spawns(), true, func(msg *ice.Message) {
|
||||
defer func() {
|
||||
msg.Log("cost", msg.Format("cost"))
|
||||
}()
|
||||
defer func() { msg.Log("cost", msg.Format("cost")) }()
|
||||
|
||||
// 解析请求
|
||||
msg.Optionv("request", r)
|
||||
msg.Optionv("response", w)
|
||||
msg.Option("user.agent", r.Header.Get("User-Agent"))
|
||||
@ -176,40 +174,44 @@ func (web *Frame) HandleCmd(m *ice.Message, key string, cmd *ice.Command) {
|
||||
r.ParseMultipartForm(4096)
|
||||
if r.ParseForm(); len(r.PostForm) > 0 {
|
||||
for k, v := range r.PostForm {
|
||||
msg.Log("info", "%s: %v", k, v)
|
||||
msg.Info("%s: %v", k, v)
|
||||
}
|
||||
msg.Log("info", "")
|
||||
msg.Info("")
|
||||
}
|
||||
for k, v := range r.Form {
|
||||
for _, v := range v {
|
||||
msg.Add(ice.MSG_OPTION, k, v)
|
||||
}
|
||||
msg.Optionv(k, v)
|
||||
}
|
||||
|
||||
// 请求数据
|
||||
switch r.Header.Get("Content-Type") {
|
||||
case "application/json":
|
||||
var data interface{}
|
||||
if e := json.NewDecoder(r.Body).Decode(&data); e != nil {
|
||||
msg.Log("warn", "%v", e)
|
||||
}
|
||||
if e := json.NewDecoder(r.Body).Decode(&data); !msg.Warn(e != nil, "%s", e) {
|
||||
msg.Optionv("content_data", data)
|
||||
msg.Log("info", "%v", kit.Formats(data))
|
||||
msg.Info("%s", kit.Formats(data))
|
||||
}
|
||||
|
||||
switch d := data.(type) {
|
||||
case map[string]interface{}:
|
||||
for k, v := range d {
|
||||
for _, v := range kit.Simple(v) {
|
||||
msg.Add(ice.MSG_OPTION, k, v)
|
||||
}
|
||||
msg.Optionv(k, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 执行命令
|
||||
if web.Login(msg, w, r) && msg.Target().Run(msg, cmd, msg.Option("url"), kit.Simple(msg.Optionv("cmds"))...) != nil {
|
||||
switch msg.Append("content-type") {
|
||||
case "text/html":
|
||||
w.Header().Set("Content-Type", "text/html")
|
||||
// 输出响应
|
||||
switch msg.Append("_output") {
|
||||
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-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())
|
||||
default:
|
||||
fmt.Fprint(w, msg.Formats("meta"))
|
||||
@ -223,6 +225,7 @@ func (web *Frame) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
index := r.Header.Get("index.module") == ""
|
||||
if index {
|
||||
// 解析地址
|
||||
if ip := r.Header.Get("X-Forwarded-For"); ip != "" {
|
||||
r.Header.Set("user.ip", ip)
|
||||
} else if ip := r.Header.Get("X-Real-Ip"); ip != "" {
|
||||
@ -232,13 +235,29 @@ func (web *Frame) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
} else {
|
||||
r.Header.Set("user.ip", strings.Split(r.RemoteAddr, ":")[0])
|
||||
}
|
||||
m.Log("info", "").Log("info", "%v %s %s", r.Header.Get("user.ip"), r.Method, r.URL)
|
||||
m.Info("").Info("%s %s %s", r.Header.Get("user.ip"), r.Method, r.URL)
|
||||
|
||||
// 解析地址
|
||||
r.Header.Set("index.module", "some")
|
||||
r.Header.Set("index.url", r.URL.String())
|
||||
r.Header.Set("index.path", r.URL.Path)
|
||||
r.Header.Set("index.url", r.URL.String())
|
||||
}
|
||||
|
||||
if index && kit.Right(m.Conf(ice.WEB_SERVE, "meta.logheaders")) {
|
||||
for k, v := range r.Header {
|
||||
m.Info("%s: %v", k, kit.Format(v))
|
||||
}
|
||||
m.Info(" ")
|
||||
}
|
||||
|
||||
web.ServeMux.ServeHTTP(w, r)
|
||||
|
||||
if index && kit.Right(m.Conf(ice.WEB_SERVE, "meta.logheaders")) {
|
||||
for k, v := range w.Header() {
|
||||
m.Info("%s: %v", k, kit.Format(v))
|
||||
}
|
||||
m.Info(" ")
|
||||
}
|
||||
}
|
||||
|
||||
func (web *Frame) Spawn(m *ice.Message, c *ice.Context, arg ...string) ice.Server {
|
||||
@ -255,8 +274,9 @@ func (web *Frame) Start(m *ice.Message, arg ...string) bool {
|
||||
return
|
||||
}
|
||||
w.ServeMux = http.NewServeMux()
|
||||
msg := m.Spawns(s)
|
||||
|
||||
// 静态路由
|
||||
msg := m.Spawns(s)
|
||||
m.Confm(ice.WEB_SERVE, ice.Meta("static"), func(key string, value string) {
|
||||
m.Log("route", "%s <- %s <- %s", s.Name, key, value)
|
||||
w.Handle(key, http.StripPrefix(key, http.FileServer(http.Dir(value))))
|
||||
@ -279,8 +299,11 @@ func (web *Frame) Start(m *ice.Message, arg ...string) bool {
|
||||
}
|
||||
})
|
||||
|
||||
// 服务地址
|
||||
port := m.Cap(ice.CTX_STREAM, kit.Select(m.Conf(ice.WEB_SPIDE, ice.Meta("self", "port")), arg, 0))
|
||||
m.Log("serve", "listen %s %v", port, m.Conf("cli.runtime", "node"))
|
||||
m.Log("serve", "listen %s %v", port, m.Conf(ice.CLI_RUNTIME, "node"))
|
||||
|
||||
// 启动服务
|
||||
web.m, web.Server = m, &http.Server{Addr: port, Handler: web}
|
||||
m.Log("serve", "listen %s", web.Server.ListenAndServe())
|
||||
return true
|
||||
@ -300,9 +323,18 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
"template", map[string]interface{}{"path": "usr/template", "list": []interface{}{
|
||||
`{{define "raw"}}{{.Result}}{{end}}`,
|
||||
}},
|
||||
"logheaders", "false",
|
||||
)},
|
||||
ice.WEB_SPACE: {Name: "space", Help: "空间站", Value: kit.Data(
|
||||
"redial.a", 3000, "redial.b", 1000, "redial.c", 10,
|
||||
"buffer.r", 4096, "buffer.w", 4096,
|
||||
kit.MDB_SHORT, "name",
|
||||
)},
|
||||
ice.WEB_STORY: {Name: "story", Help: "故事会", Value: kit.Dict(
|
||||
kit.MDB_META, kit.Dict(kit.MDB_SHORT, "data",
|
||||
"download", `<a href="/code/zsh?cmd=download&arg=%s" target="_blank">%s</a>`),
|
||||
"head", kit.Data(kit.MDB_SHORT, "story"),
|
||||
)},
|
||||
ice.WEB_SPACE: {Name: "space", Help: "空间站", Value: kit.Data("buffer", 4096, "redial", 3000)},
|
||||
ice.WEB_STORY: {Name: "story", Help: "故事会", Value: kit.Data(kit.MDB_SHORT, "data")},
|
||||
ice.WEB_CACHE: {Name: "cache", Help: "缓存", Value: kit.Data(
|
||||
kit.MDB_SHORT, "text", "path", "var/file",
|
||||
"store", "var/data", "limit", "30", "least", "10",
|
||||
@ -310,7 +342,10 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
ice.WEB_ROUTE: {Name: "route", Help: "路由", Value: kit.Data()},
|
||||
ice.WEB_PROXY: {Name: "proxy", Help: "代理", Value: kit.Data()},
|
||||
ice.WEB_FAVOR: {Name: "favor", Help: "收藏", Value: kit.Data(kit.MDB_SHORT, kit.MDB_NAME)},
|
||||
ice.WEB_SHARE: {Name: "share", Help: "共享", Value: kit.Data()},
|
||||
ice.WEB_SHARE: {Name: "share", Help: "共享", Value: kit.Data(
|
||||
"href", `<a href="/share/%s" target="_blank">%s</a>`,
|
||||
"template", share_template,
|
||||
)},
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
|
||||
@ -318,24 +353,25 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
ice.WEB_SPIDE: {Name: "spide", Help: "客户端", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
}},
|
||||
ice.WEB_SERVE: {Name: "serve", Help: "服务器", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Conf("cli.runtime", "node.name", m.Conf("cli.runtime", "boot.hostname"))
|
||||
m.Conf("cli.runtime", "node.type", "server")
|
||||
m.Conf(ice.CLI_RUNTIME, "node.name", m.Conf(ice.CLI_RUNTIME, "boot.hostname"))
|
||||
m.Conf(ice.CLI_RUNTIME, "node.type", kit.MIME_SERVER)
|
||||
|
||||
m.Rich(ice.WEB_SPACE, nil, kit.Dict(
|
||||
"type", "myself",
|
||||
"node", m.Conf("cli.runtime", "boot.hostname"),
|
||||
"user", m.Conf("cli.runtime", "boot.username"),
|
||||
"type", kit.MIME_MYSELF,
|
||||
"name", m.Conf(ice.CLI_RUNTIME, "boot.hostname"),
|
||||
"user", m.Conf(ice.CLI_RUNTIME, "boot.username"),
|
||||
))
|
||||
m.Target().Start(m, arg...)
|
||||
}},
|
||||
ice.WEB_SPACE: {Name: "space", Help: "空间站", Meta: kit.Dict("exports", []string{"pod", "node"}), List: kit.List(
|
||||
kit.MDB_INPUT, "text", "name", "pod", "action", "auto",
|
||||
ice.WEB_SPACE: {Name: "space", Help: "空间站", Meta: kit.Dict("exports", []string{"pod", "name"}), List: kit.List(
|
||||
kit.MDB_INPUT, "text", "name", "node",
|
||||
kit.MDB_INPUT, "button", "value", "查看", "action", "auto",
|
||||
kit.MDB_INPUT, "button", "value", "返回", "cb", "Last",
|
||||
), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
if len(arg) == 0 {
|
||||
// 节点列表
|
||||
m.Richs(ice.WEB_SPACE, nil, "", func(key string, value map[string]interface{}) {
|
||||
m.Push(key, value)
|
||||
m.Push(key, value, []string{"time", "type", "name", "user"})
|
||||
})
|
||||
return
|
||||
}
|
||||
@ -343,98 +379,110 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
web := m.Target().Server().(*Frame)
|
||||
switch arg[0] {
|
||||
case "connect":
|
||||
node, name := m.Conf("cli.runtime", "node.type"), m.Conf("cli.runtime", "boot.hostname")
|
||||
if node == "worker" {
|
||||
name = m.Conf("cli.runtime", "boot.pathname")
|
||||
}
|
||||
host := kit.Select(m.Conf("web.spide", "self.port"), arg, 1)
|
||||
p := "ws://" + host + kit.Select("/space", arg, 2) + "?node=" + node + "&name=" + name
|
||||
// 基本信息
|
||||
node := m.Conf(ice.CLI_RUNTIME, "node.type")
|
||||
name := kit.Select(m.Conf(ice.CLI_RUNTIME, "boot.pathname"), m.Conf(ice.CLI_RUNTIME, "boot.hostname"), node == kit.MIME_SERVER)
|
||||
user := m.Conf(ice.CLI_RUNTIME, "boot.username")
|
||||
host := kit.Select(m.Conf(ice.WEB_SPIDE, "meta.self.port"), arg, 1)
|
||||
|
||||
if u, e := url.Parse(p); m.Assert(e) {
|
||||
m.TryCatch(m, true, func(m *ice.Message) {
|
||||
for {
|
||||
if s, e := net.Dial("tcp", host); e == nil {
|
||||
if s, _, e := websocket.NewClient(s, u, nil, m.Confi("web.space", "meta.buffer"), m.Confi("web.space", "meta.buffer")); e == nil {
|
||||
id := m.Option("_source", []string{kit.Format(c.ID()), "some"})
|
||||
web.send[id] = m
|
||||
s.WriteMessage(MSG_MAPS, []byte(m.Format("meta")))
|
||||
|
||||
if web.HandleWSS(m, true, s) {
|
||||
if u, e := url.Parse(kit.MergeURL("ws://"+host+kit.Select("/space", arg, 2), "node", node, "name", name, "user", user)); 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) {
|
||||
// 连接成功
|
||||
m.Info("conn %d success %s", i, u)
|
||||
if i = 0; web.HandleWSS(m, true, s) {
|
||||
break
|
||||
}
|
||||
} else {
|
||||
m.Log("warn", "wss %s", e)
|
||||
}
|
||||
} else {
|
||||
m.Log("warn", "dial %s", e)
|
||||
}
|
||||
time.Sleep(time.Duration(rand.Intn(m.Confi("web.space", "meta.redial"))) * time.Millisecond)
|
||||
m.Log("info", "reconnect %v", u)
|
||||
|
||||
// 断线重连
|
||||
sleep := time.Duration(rand.Intn(m.Confi(ice.WEB_SPACE, "meta.redial.a"))*i+i*m.Confi(ice.WEB_SPACE, "meta.redial.b")) * time.Millisecond
|
||||
m.Info("%d sleep: %s reconnect: %s", i, sleep, u)
|
||||
time.Sleep(sleep)
|
||||
}
|
||||
})
|
||||
}
|
||||
default:
|
||||
// 本地命令
|
||||
if arg[0] == "" || arg[0] == m.Conf("cli.runtime", "node.name") {
|
||||
if arg[0] == "" || arg[0] == m.Conf(ice.CLI_RUNTIME, "node.name") {
|
||||
m.Cmdy(arg[1:])
|
||||
break
|
||||
}
|
||||
|
||||
target := strings.Split(arg[0], ".")
|
||||
if socket, ok := m.Confv(ice.WEB_SPACE, "hash."+target[0]+".socket").(*websocket.Conn); !ok {
|
||||
m.Echo("error").Echo("not found")
|
||||
} else {
|
||||
m.Warn(m.Richs(ice.WEB_SPACE, nil, target[0], func(key string, value map[string]interface{}) {
|
||||
if socket, ok := value["socket"].(*websocket.Conn); ok {
|
||||
// 构造路由
|
||||
id := kit.Format(c.ID())
|
||||
m.Optionv("_source", []string{id, target[0]})
|
||||
m.Optionv("_target", target[1:])
|
||||
m.Optionv(ice.MSG_SOURCE, []string{id, target[0]})
|
||||
m.Optionv(ice.MSG_TARGET, target[1:])
|
||||
m.Set(ice.MSG_DETAIL, arg[1:]...)
|
||||
m.Info("send %s %s", id, m.Format("meta"))
|
||||
|
||||
web := m.Target().Server().(*Frame)
|
||||
web.send[id] = m
|
||||
|
||||
// 下发命令
|
||||
now := time.Now()
|
||||
m.Target().Server().(*Frame).send[id] = m
|
||||
socket.WriteMessage(MSG_MAPS, []byte(m.Format("meta")))
|
||||
m.Call(true, func(msg *ice.Message) *ice.Message {
|
||||
m.Copy(msg)
|
||||
m.Log("info", "cost %s", time.Now().Sub(now))
|
||||
// 返回结果
|
||||
m.Copy(msg).Log("cost", "cost: %s", kit.FmtTime(kit.Int64(time.Now().Sub(now))))
|
||||
return nil
|
||||
})
|
||||
}
|
||||
}) == nil, "not found %s", arg[0])
|
||||
}
|
||||
}},
|
||||
ice.WEB_STORY: {Name: "story", Help: "故事会", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
ice.WEB_STORY: {Name: "story", Help: "故事会", Meta: kit.Dict("exports", []string{"top", "story"}), List: kit.List(
|
||||
kit.MDB_INPUT, "text", "name", "top", "action", "auto",
|
||||
kit.MDB_INPUT, "button", "value", "查看", "action", "auto",
|
||||
kit.MDB_INPUT, "button", "value", "返回", "cb", "Last",
|
||||
), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
if len(arg) == 0 {
|
||||
m.Confm("story", ice.Meta("head"), func(key string, value map[string]interface{}) {
|
||||
m.Push(key, value, []string{"key", "type", "time", "story"})
|
||||
// 故事列表
|
||||
m.Richs(ice.WEB_STORY, "head", "", func(key string, value map[string]interface{}) {
|
||||
m.Push(key, value, []string{"time", "story", "scene"})
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// head list data time text file
|
||||
switch arg[0] {
|
||||
case "add":
|
||||
case "add", "upload":
|
||||
// 保存数据
|
||||
m.Cmdy(ice.WEB_CACHE, arg)
|
||||
arg = []string{arg[0], m.Append("type"), m.Append("name"), m.Append("data")}
|
||||
|
||||
// 查询索引
|
||||
head := kit.Hashs(arg[1], arg[2])
|
||||
prev := m.Conf("story", ice.Meta("head", head, "list"))
|
||||
head, prev := "", ""
|
||||
m.Richs(ice.WEB_STORY, "head", arg[2], func(key string, value map[string]interface{}) {
|
||||
head, prev = key, kit.Format(value["list"])
|
||||
m.Log("info", "head: %v prev: %v", head, prev)
|
||||
})
|
||||
|
||||
// 添加节点
|
||||
meta := map[string]interface{}{
|
||||
"time": m.Time(),
|
||||
"scene": arg[1],
|
||||
"story": arg[2],
|
||||
"data": m.Cmdx(ice.WEB_CACHE, "add", "text", arg[3]),
|
||||
"prev": prev,
|
||||
}
|
||||
list := m.Rich("story", nil, meta)
|
||||
m.Log("info", "list: %v meta: %v", list, kit.Format(meta))
|
||||
list := m.Rich(ice.WEB_STORY, nil, kit.Dict(
|
||||
"scene", arg[1], "story", arg[2], "data", arg[3], "prev", prev,
|
||||
))
|
||||
m.Info("%s: %s story: %s", arg[1], arg[2], list)
|
||||
m.Push("list", list)
|
||||
|
||||
// 添加索引
|
||||
m.Conf("story", ice.Meta("head", head), map[string]interface{}{
|
||||
"time": m.Time(), "scene": arg[1], "story": arg[2], "list": list,
|
||||
})
|
||||
m.Rich(ice.WEB_STORY, "head", kit.Dict(
|
||||
"scene", arg[1], "story", arg[2], "list", list,
|
||||
))
|
||||
|
||||
m.Echo(list)
|
||||
|
||||
case "download":
|
||||
// 下载文件
|
||||
if m.Cmdy(ice.WEB_STORY, "index", arg[1]); m.Append("file") != "" {
|
||||
m.Push("_output", "file")
|
||||
} else {
|
||||
m.Push("_output", "result")
|
||||
m.Echo(m.Append("text"))
|
||||
}
|
||||
|
||||
case "commit":
|
||||
// 查询索引
|
||||
head := kit.Hashs(arg[1])
|
||||
@ -472,55 +520,121 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
})
|
||||
m.Echo(list)
|
||||
|
||||
case "share":
|
||||
m.Cmdy(ice.WEB_SHARE, arg[1:])
|
||||
|
||||
case "history":
|
||||
list := kit.Select(arg[1], kit.Select(m.Conf(ice.WEB_STORY, ice.Meta("head", arg[1], "list")),
|
||||
m.Conf(ice.WEB_STORY, ice.Meta("head", kit.Hashs(arg[1]), "list"))))
|
||||
// 历史记录
|
||||
list := m.Cmd(ice.WEB_STORY, "index", arg[1]).Append("list")
|
||||
for i := 0; i < 10 && list != ""; i++ {
|
||||
m.Confm(ice.WEB_STORY, kit.Keys("hash", list), func(value map[string]interface{}) {
|
||||
m.Push(list, value, []string{"key", "time", "story", "scene"})
|
||||
m.Push("text", m.Conf(ice.WEB_CACHE, kit.Keys("hash", value["data"], "text")))
|
||||
m.Push(list, value, []string{"data"})
|
||||
// 直连节点
|
||||
m.Confm(ice.WEB_CACHE, kit.Keys("hash", value["data"]), func(val map[string]interface{}) {
|
||||
m.Push(list, value, []string{"key", "time", "scene", "story"})
|
||||
|
||||
m.Push("text", val["text"])
|
||||
m.Push("data", value["data"])
|
||||
})
|
||||
|
||||
// 复合节点
|
||||
kit.Fetch(value["list"], func(key string, val string) {
|
||||
m.Push(list, value, []string{"key", "time"})
|
||||
|
||||
node := m.Confm(ice.WEB_STORY, kit.Keys("hash", val))
|
||||
m.Push("scene", node["scene"])
|
||||
m.Push("story", kit.Keys(kit.Format(value["story"]), key))
|
||||
m.Push("scene", value["scene"])
|
||||
data := m.Conf(ice.WEB_STORY, kit.Keys("hash", val, "data"))
|
||||
m.Push("text", m.Conf(ice.WEB_CACHE, kit.Keys("hash", data, "text")))
|
||||
m.Push("data", data)
|
||||
|
||||
m.Push("text", m.Conf(ice.WEB_CACHE, kit.Keys("hash", node["data"], "text")))
|
||||
m.Push("data", node["data"])
|
||||
})
|
||||
|
||||
list = kit.Format(value["prev"])
|
||||
})
|
||||
}
|
||||
|
||||
case "share":
|
||||
m.Cmdy(ice.WEB_SHARE, arg[1:])
|
||||
|
||||
case "index":
|
||||
list := kit.Select(arg[1], kit.Select(m.Conf(ice.WEB_STORY, ice.Meta("head", arg[1], "list")),
|
||||
m.Conf(ice.WEB_STORY, ice.Meta("head", kit.Hashs(arg[1]), "list"))))
|
||||
data := kit.Select(list, m.Conf(ice.WEB_STORY, []string{"hash", list, "data"}))
|
||||
text := m.Conf(ice.WEB_CACHE, []string{"hash", data, "text"})
|
||||
m.Echo(text)
|
||||
// 查询索引
|
||||
if m.Richs(ice.WEB_STORY, "head", arg[1], func(key string, value map[string]interface{}) {
|
||||
arg[1] = kit.Format(value["list"])
|
||||
}) == 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])
|
||||
m.Push(arg[1], node, []string{"scene", "story"})
|
||||
arg[1] = kit.Format(node["data"])
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
if node := m.Confm(ice.WEB_CACHE, kit.Keys("hash", arg[1])); node != nil {
|
||||
m.Push("data", arg[1])
|
||||
m.Push(arg[1], node, []string{"text", "time", "size", "type", "name", "file"})
|
||||
m.Echo("%s", node["text"])
|
||||
}
|
||||
default:
|
||||
m.Cmd(ice.WEB_STORY, "history", arg).Table(func(index int, value map[string]string, head []string) {
|
||||
m.Push("time", value["time"])
|
||||
m.Push("story", value["story"])
|
||||
m.Push("text", value["text"])
|
||||
m.Push("list", kit.Format(m.Conf(ice.WEB_STORY, kit.Keys(kit.MDB_META, "download")), value["key"], value["key"]))
|
||||
})
|
||||
}
|
||||
}},
|
||||
ice.WEB_CACHE: {Name: "cache", Help: "缓存", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
if len(arg) == 0 {
|
||||
m.Confm("cache", "hash", func(key string, value map[string]interface{}) {
|
||||
m.Push(key, value, []string{"time", "text"})
|
||||
// 缓存列表
|
||||
m.Richs(ice.WEB_CACHE, nil, "", func(key string, value map[string]interface{}) {
|
||||
m.Push(key, value, []string{kit.MDB_TIME, kit.MDB_NAME, kit.MDB_SIZE, kit.MDB_TYPE, kit.MDB_TEXT})
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
switch arg[0] {
|
||||
case "upload":
|
||||
// 打开文件
|
||||
r := m.Optionv("request").(*http.Request)
|
||||
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()
|
||||
|
||||
// 保存文件
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
fallthrough
|
||||
case "add":
|
||||
// 添加数据
|
||||
data := m.Rich("cache", nil, map[string]interface{}{
|
||||
"time": m.Time(), "type": arg[1], arg[1]: arg[2],
|
||||
})
|
||||
m.Info("data: %v type: %v text: %v", data, arg[1], arg[2])
|
||||
m.Echo(data)
|
||||
m.Cmd("nfs.save", path.Join(m.Conf("cache", ice.Meta("path")), data[:2], data), arg[2])
|
||||
size := kit.Select(kit.Format(len(arg[3])), arg, 5)
|
||||
h := m.Rich(ice.WEB_CACHE, nil, 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],
|
||||
))
|
||||
m.Info("cache: %s type: %s name: %s", h, arg[1], arg[2])
|
||||
|
||||
// 返回结果
|
||||
m.Push("time", m.Time())
|
||||
m.Push("type", arg[1])
|
||||
m.Push("name", arg[2])
|
||||
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])
|
||||
}
|
||||
default:
|
||||
}
|
||||
}},
|
||||
ice.WEB_ROUTE: {Name: "route", Help: "路由", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
@ -536,9 +650,9 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
if len(arg) == 0 {
|
||||
// 收藏门类
|
||||
m.Richs(ice.WEB_FAVOR, nil, "", func(key string, value map[string]interface{}) {
|
||||
m.Push("time", kit.Value(value, "meta.time"))
|
||||
m.Push("favor", kit.Value(value, "meta.name"))
|
||||
m.Push("count", kit.Value(value, "meta.count"))
|
||||
m.Push("time", kit.Value(value, "meta.create_time"))
|
||||
})
|
||||
return
|
||||
}
|
||||
@ -569,7 +683,14 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
if len(arg) == 1 {
|
||||
// 收藏列表
|
||||
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{"create_time", "id", "type", "name", "text"})
|
||||
m.Push(kit.Format(index), value, []string{kit.MDB_TIME, kit.MDB_ID, kit.MDB_TYPE, kit.MDB_NAME})
|
||||
switch kit.Format(value[kit.MDB_TYPE]) {
|
||||
case kit.MIME_STORY:
|
||||
m.Push(kit.MDB_TEXT, kit.Format(m.Conf(ice.WEB_STORY, kit.Keys(kit.MDB_META, "download")),
|
||||
value[kit.MDB_TEXT], value[kit.MDB_TEXT]))
|
||||
default:
|
||||
m.Push(kit.MDB_TEXT, value[kit.MDB_TEXT])
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
@ -584,6 +705,9 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
})
|
||||
return
|
||||
}
|
||||
if arg[1] == "file" {
|
||||
arg[1] = kit.MIME_FILE
|
||||
}
|
||||
|
||||
// 添加收藏
|
||||
index := m.Grow(ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, favor), kit.Dict(
|
||||
@ -594,57 +718,58 @@ var Index = &ice.Context{Name: "web", Help: "网页模块",
|
||||
}},
|
||||
ice.WEB_SHARE: {Name: "share", Help: "共享", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
if len(arg) == 0 {
|
||||
m.Confm(ice.WEB_SHARE, "hash", func(key string, value map[string]interface{}) {
|
||||
m.Push(key, value)
|
||||
// 共享列表
|
||||
m.Richs(ice.WEB_SHARE, nil, "", func(key string, value map[string]interface{}) {
|
||||
m.Push(key, value, []string{kit.MDB_TIME, kit.MDB_TYPE, kit.MDB_NAME})
|
||||
m.Push("link", fmt.Sprintf(m.Conf(ice.WEB_SHARE, kit.Keys(kit.MDB_META, "href")), key, key))
|
||||
})
|
||||
return
|
||||
}
|
||||
m.Echo(m.Rich(ice.WEB_SHARE, nil, map[string]interface{}{
|
||||
"create_time": m.Time(), "type": arg[0], "name": arg[1], "text": kit.Select("", arg, 2),
|
||||
}))
|
||||
|
||||
// 创建共享
|
||||
h := m.Rich(ice.WEB_SHARE, nil, kit.Dict(
|
||||
kit.MDB_TYPE, arg[0], kit.MDB_NAME, arg[1], kit.MDB_TEXT, kit.Select("", arg, 2),
|
||||
))
|
||||
m.Info("share: %s", h)
|
||||
m.Echo(h)
|
||||
}},
|
||||
"/share/": &ice.Command{Name: "/share", Help: "共享", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
|
||||
"/share/": {Name: "/share", Help: "共享", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
key := kit.Select("", strings.Split(cmd, "/"), 2)
|
||||
m.Confm(ice.WEB_SHARE, kit.Keys("hash", key), func(value map[string]interface{}) {
|
||||
m.Push("content-type", "text/html")
|
||||
m.Echo(`<!DOCTYPE html>`)
|
||||
m.Echo(`<head>`)
|
||||
m.Echo(`<meta charset="utf-8">`)
|
||||
m.Echo(`<link rel="stylesheet" text="text/css" href="/style.css">`)
|
||||
m.Echo(`</head>`)
|
||||
m.Echo(`<body>`)
|
||||
m.Echo(`<fieldset>`)
|
||||
key := kit.Keys("web.wiki", value["type"])
|
||||
if key == "web.wiki.chain" {
|
||||
m.Cmdy("web.wiki.chart", "chain", value["name"], value["text"])
|
||||
} else {
|
||||
m.Cmdy(key, value["name"], "", value["text"])
|
||||
m.Info("share %s %v", key, kit.Format(value))
|
||||
switch value["type"] {
|
||||
case kit.MIME_STORY:
|
||||
m.Cmdy(ice.WEB_STORY, "index", value["text"]).Push("_output", "file")
|
||||
return
|
||||
default:
|
||||
m.Push("_output", "result").Push(key, value)
|
||||
m.Render(m.Conf(ice.WEB_SHARE, kit.Keys(kit.MDB_META, "template", value["type"])))
|
||||
m.Append("type", "text/html")
|
||||
}
|
||||
m.Echo(`</fieldset>`)
|
||||
m.Echo(`</body>`)
|
||||
|
||||
})
|
||||
}},
|
||||
|
||||
"/space": &ice.Command{Name: "/space", Help: "空间站", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
"/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)
|
||||
if s, e := websocket.Upgrade(w, r, nil, m.Confi("web.space", "meta.buffer"), m.Confi("web.space", "meta.buffer")); m.Assert(e) {
|
||||
h := m.Option("name")
|
||||
|
||||
meta := map[string]interface{}{
|
||||
"create_time": m.Time(),
|
||||
"socket": s,
|
||||
"type": m.Option("node"),
|
||||
"name": m.Option("name"),
|
||||
}
|
||||
m.Confv(ice.WEB_SPACE, []string{kit.MDB_HASH, h}, meta)
|
||||
m.Log("space", "conn %v %v", h, kit.Formats(m.Confv(ice.WEB_SPACE)))
|
||||
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) {
|
||||
// 添加节点
|
||||
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"),
|
||||
"socket", s,
|
||||
))
|
||||
m.Info("conn %s", m.Option(kit.MDB_NAME))
|
||||
|
||||
web := m.Target().Server().(*Frame)
|
||||
m.Gos(m, func(m *ice.Message) {
|
||||
// 监听消息
|
||||
web := m.Target().Server().(*Frame)
|
||||
web.HandleWSS(m, false, s)
|
||||
m.Log("space", "close %v %v", h, kit.Formats(m.Confv(ice.WEB_SPACE)))
|
||||
m.Confv(ice.WEB_SPACE, []string{kit.MDB_HASH, h}, "")
|
||||
m.Info("close %s %s", m.Option(kit.MDB_NAME), kit.Format(m.Confv(ice.WEB_SPACE, kit.Keys(kit.MDB_HASH, m.Option(kit.MDB_NAME)))))
|
||||
m.Confv(ice.WEB_SPACE, kit.Keys(kit.MDB_HASH, m.Option(kit.MDB_NAME)), "")
|
||||
})
|
||||
}
|
||||
}},
|
||||
|
11
conf.go
11
conf.go
@ -14,12 +14,20 @@ const (
|
||||
CTX_COMMAND = "command"
|
||||
CTX_CONTEXT = "context"
|
||||
)
|
||||
const (
|
||||
CLI_RUNTIME = "runtime"
|
||||
CLI_SYSTEM = "system"
|
||||
)
|
||||
const (
|
||||
MSG_DETAIL = "detail"
|
||||
MSG_OPTION = "option"
|
||||
MSG_APPEND = "append"
|
||||
MSG_RESULT = "result"
|
||||
|
||||
MSG_SOURCE = "_source"
|
||||
MSG_TARGET = "_target"
|
||||
MSG_HANDLE = "_handle"
|
||||
|
||||
MSG_SESSID = "sessid"
|
||||
MSG_USERNAME = "user.name"
|
||||
MSG_USERROLE = "user.role"
|
||||
@ -75,6 +83,9 @@ var Alias = map[string]string{
|
||||
CTX_COMMAND: "ctx.command",
|
||||
CTX_CONTEXT: "ctx.context",
|
||||
|
||||
CLI_RUNTIME: "cli.runtime",
|
||||
CLI_SYSTEM: "cli.system",
|
||||
|
||||
AAA_ROLE: "aaa.role",
|
||||
AAA_USER: "aaa.user",
|
||||
AAA_SESS: "aaa.sess",
|
||||
|
@ -49,7 +49,7 @@ var Index = &ice.Context{Name: "chat", Help: "聊天模块",
|
||||
|
||||
// 登录检查
|
||||
if m.Warn(!m.Options(ice.MSG_SESSID) || !m.Options(ice.MSG_USERNAME), "not login") {
|
||||
m.Option("path", "")
|
||||
m.Option("url", "")
|
||||
}
|
||||
}},
|
||||
|
||||
@ -145,7 +145,7 @@ var Index = &ice.Context{Name: "chat", Help: "聊天模块",
|
||||
if len(arg) < 2 {
|
||||
// 设备列表
|
||||
m.Richs(ice.WEB_SPACE, nil, "", func(key string, value map[string]interface{}) {
|
||||
m.Push(key, value, []string{"user", "node"})
|
||||
m.Push(key, value, []string{"type", "name", "user"})
|
||||
})
|
||||
return
|
||||
}
|
||||
|
@ -56,7 +56,26 @@ 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.GDB_EVENT, "listen", "miss.start", "web.code.docker", "image")
|
||||
}},
|
||||
"/zsh": {Name: "/zsh", Help: "终端", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Info("%s cmd: %s arg: %v sub: %v", cmd, m.Option("cmd"), m.Optionv("arg"), m.Optionv("sub"))
|
||||
|
||||
switch m.Option("cmd") {
|
||||
case "upload":
|
||||
// 上传文件
|
||||
msg := m.Cmd(ice.WEB_STORY, "upload")
|
||||
m.Push("_output", "result")
|
||||
m.Echo("list: %s\n", msg.Append("list"))
|
||||
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"))
|
||||
|
||||
case "download":
|
||||
// 下载文件
|
||||
m.Cmdy(ice.WEB_STORY, "download", m.Optionv("arg"))
|
||||
}
|
||||
}},
|
||||
"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"))
|
||||
|
@ -162,7 +162,7 @@ var Index = &ice.Context{Name: "wiki", Help: "文档模块",
|
||||
kit.Select("", arg, 0), m.Conf("note", ice.Meta("head")))
|
||||
}},
|
||||
"note": {Name: "note file", Help: "笔记", Meta: map[string]interface{}{
|
||||
"remote": "true", "display": "inner",
|
||||
"remote": "you", "display": "inner",
|
||||
"detail": []string{"add", "commit", "history", "share"},
|
||||
}, List: kit.List(
|
||||
kit.MDB_INPUT, "text", "value", "miss.md", "name", "path",
|
||||
|
@ -155,6 +155,7 @@ var Index = &ice.Context{Name: "tmux", Help: "终端模块",
|
||||
target := arg[0]
|
||||
if m.Cmd(prefix, "has-session", "-t", target).Append("code") != "0" {
|
||||
// 创建会话
|
||||
m.Option("cmd_env", "TMUX", "")
|
||||
m.Cmd(prefix, "new-session", "-ds", arg[0])
|
||||
}
|
||||
|
||||
|
36
type.go
36
type.go
@ -549,13 +549,13 @@ func (m *Message) Optionv(key string, arg ...interface{}) interface{} {
|
||||
m.meta[MSG_OPTION] = append(m.meta[MSG_OPTION], key)
|
||||
}
|
||||
|
||||
switch arg := arg[0].(type) {
|
||||
switch str := arg[0].(type) {
|
||||
case string:
|
||||
m.meta[key] = []string{arg}
|
||||
m.meta[key] = kit.Simple(arg)
|
||||
case []string:
|
||||
m.meta[key] = arg
|
||||
m.meta[key] = str
|
||||
default:
|
||||
m.data[key] = arg
|
||||
m.data[key] = str
|
||||
}
|
||||
}
|
||||
|
||||
@ -576,9 +576,12 @@ func (m *Message) Option(key string, arg ...interface{}) string {
|
||||
return kit.Select("", kit.Simple(m.Optionv(key, arg...)), 0)
|
||||
}
|
||||
func (m *Message) Append(key string, arg ...interface{}) string {
|
||||
return kit.Select("", m.meta[key], 0)
|
||||
return kit.Select("", m.Appendv(key, arg...), 0)
|
||||
}
|
||||
func (m *Message) Appendv(key string, arg ...interface{}) []string {
|
||||
if len(arg) > 0 {
|
||||
m.meta[key] = kit.Simple(arg...)
|
||||
}
|
||||
return m.meta[key]
|
||||
}
|
||||
func (m *Message) Resultv(arg ...interface{}) []string {
|
||||
@ -824,9 +827,11 @@ func (m *Message) Richs(key string, chain interface{}, raw interface{}, cb inter
|
||||
switch cb := cb.(type) {
|
||||
case func(string, map[string]interface{}):
|
||||
for k, v := range hash {
|
||||
cb(k, v.(map[string]interface{}))
|
||||
res = v.(map[string]interface{})
|
||||
cb(k, res)
|
||||
}
|
||||
}
|
||||
return res
|
||||
case "%":
|
||||
// 随机选取
|
||||
list := []string{}
|
||||
@ -875,11 +880,8 @@ func (m *Message) Rich(key string, chain interface{}, data interface{}) string {
|
||||
}
|
||||
|
||||
// 通用数据
|
||||
if kit.Value(data, "meta") != nil {
|
||||
kit.Value(data, "meta.create_time", m.Time())
|
||||
} else {
|
||||
kit.Value(data, "create_time", m.Time())
|
||||
}
|
||||
prefix := kit.Select("", "meta.", kit.Value(data, "meta") != nil)
|
||||
kit.Value(data, prefix+kit.MDB_TIME, m.Time())
|
||||
|
||||
// 生成键值
|
||||
h := ""
|
||||
@ -918,13 +920,9 @@ func (m *Message) Grow(key string, chain interface{}, data interface{}) int {
|
||||
|
||||
// 通用数据
|
||||
id := kit.Int(meta["count"]) + 1
|
||||
if kit.Value(data, "meta") != nil {
|
||||
kit.Value(data, "meta.id", id)
|
||||
kit.Value(data, "meta.create_time", m.Time())
|
||||
} else {
|
||||
kit.Value(data, "id", id)
|
||||
kit.Value(data, "create_time", m.Time())
|
||||
}
|
||||
prefix := kit.Select("", "meta.", kit.Value(data, "meta") != nil)
|
||||
kit.Value(data, prefix+kit.MDB_TIME, m.Time())
|
||||
kit.Value(data, prefix+kit.MDB_ID, id)
|
||||
|
||||
// 添加数据
|
||||
list = append(list, data)
|
||||
@ -1120,6 +1118,8 @@ func (m *Message) Cmd(arg ...interface{}) *Message {
|
||||
c.Run(msg, cmd, key, list[1:]...)
|
||||
})
|
||||
})
|
||||
|
||||
m.Warn(m.Hand == false, "not found %v", list)
|
||||
return m
|
||||
}
|
||||
func (m *Message) Confv(arg ...interface{}) (val interface{}) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user