mirror of
https://shylinux.com/x/icebergs
synced 2025-04-26 01:24:05 +08:00
opt icebergs
This commit is contained in:
parent
883441ab68
commit
74359c0048
@ -132,6 +132,11 @@ func init() {
|
||||
QRCODE: {Name: QRCODE, Help: "二维码", Value: kit.Data()},
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
ice.AddRender(ice.RENDER_QRCODE, func(m *ice.Message, cmd string, args ...interface{}) string {
|
||||
return m.Cmd(QRCODE, kit.Simple(args...)).Result()
|
||||
})
|
||||
}},
|
||||
QRCODE: {Name: "qrcode text fg bg size auto", Help: "二维码", Action: map[string]*ice.Action{}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Option(SIZE, kit.Select("240", arg, 3))
|
||||
m.Option(BG, kit.Select(WHITE, arg, 2))
|
||||
|
@ -12,9 +12,8 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
REFRESH = "refresh"
|
||||
STATUS = "status"
|
||||
COOKIE = "cookie"
|
||||
STATUS = "status"
|
||||
COOKIE = "cookie"
|
||||
)
|
||||
|
||||
func Render(msg *ice.Message, cmd string, args ...interface{}) {
|
||||
@ -23,21 +22,15 @@ func Render(msg *ice.Message, cmd string, args ...interface{}) {
|
||||
}
|
||||
|
||||
switch arg := kit.Simple(args...); cmd {
|
||||
case ice.RENDER_REDIRECT: // url [arg...]
|
||||
http.Redirect(msg.W, msg.R, kit.MergeURL(arg[0], arg[1:]), 307)
|
||||
|
||||
case REFRESH: // [delay [text]]
|
||||
arg = []string{"200", fmt.Sprintf(`<!DOCTYPE html><head><meta charset="utf-8"><meta http-equiv="Refresh" content="%d"></head><body>%s</body>`,
|
||||
kit.Int(kit.Select("3", arg, 0)), kit.Select("请稍后,系统初始化中...", arg, 1),
|
||||
)}
|
||||
fallthrough
|
||||
|
||||
case STATUS: // [code [text]]
|
||||
RenderStatus(msg, kit.Int(kit.Select("200", arg, 0)), kit.Select("", arg, 1))
|
||||
|
||||
case COOKIE: // value [name [path [expire]]]
|
||||
RenderCookie(msg, arg[0], arg[1:]...)
|
||||
|
||||
case ice.RENDER_REDIRECT: // url [arg...]
|
||||
http.Redirect(msg.W, msg.R, kit.MergeURL(arg[0], arg[1:]), 307)
|
||||
|
||||
case ice.RENDER_DOWNLOAD: // file [type [name]]
|
||||
msg.W.Header().Set("Content-Disposition", fmt.Sprintf("filename=%s", kit.Select(path.Base(kit.Select(arg[0], msg.Option("filename"))), arg, 2)))
|
||||
if RenderType(msg.W, arg[0], kit.Select("", arg, 1)); !ice.Dump(msg.W, arg[0], nil) {
|
||||
@ -71,7 +64,6 @@ func Render(msg *ice.Message, cmd string, args ...interface{}) {
|
||||
fmt.Fprint(msg.W, msg.Formats(kit.MDB_META))
|
||||
}
|
||||
}
|
||||
|
||||
func RenderStatus(msg *ice.Message, code int, text string) {
|
||||
msg.W.WriteHeader(code)
|
||||
msg.W.Write([]byte(text))
|
||||
|
@ -1,6 +1,7 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
@ -114,6 +115,27 @@ func init() {
|
||||
SHARE: {Name: SHARE, Help: "共享链", Value: kit.Data(kit.MDB_EXPIRE, "72h")},
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
ice.AddRender(ice.RENDER_DOWNLOAD, func(m *ice.Message, cmd string, args ...interface{}) string {
|
||||
arg := kit.Simple(args...)
|
||||
if arg[0] == "" {
|
||||
return ""
|
||||
}
|
||||
list := []string{}
|
||||
if m.Option(ice.MSG_USERPOD) != "" {
|
||||
list = append(list, "pod", m.Option(ice.MSG_USERPOD))
|
||||
}
|
||||
if len(arg) == 1 {
|
||||
arg[0] = kit.MergeURL2(m.Option(ice.MSG_USERWEB), path.Join(kit.Select("", "/share/local",
|
||||
!strings.HasPrefix(arg[0], "/")), arg[0]), list)
|
||||
} else {
|
||||
arg[1] = kit.MergeURL2(m.Option(ice.MSG_USERWEB), path.Join(kit.Select("", "/share/local",
|
||||
!strings.HasPrefix(arg[1], "/")), arg[1]), list, "filename", arg[0])
|
||||
}
|
||||
arg[0] = m.ReplaceLocalhost(arg[0])
|
||||
return fmt.Sprintf(`<a href="%s" download="%s">%s</a>`, m.ReplaceLocalhost(kit.Select(arg[0], arg, 1)), path.Base(arg[0]), arg[0])
|
||||
})
|
||||
}},
|
||||
SHARE: {Name: "share hash auto prunes", Help: "共享链", Action: map[string]*ice.Action{
|
||||
mdb.CREATE: {Name: "create type name text", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy(mdb.INSERT, SHARE, "", mdb.HASH, kit.MDB_TIME, m.Time(m.Conf(SHARE, kit.Keym(kit.MDB_EXPIRE))),
|
||||
|
@ -34,6 +34,27 @@ const SPARK = "spark"
|
||||
func init() {
|
||||
Index.Merge(&ice.Context{
|
||||
Commands: map[string]*ice.Command{
|
||||
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
ice.AddRender(ice.RENDER_SCRIPT, func(m *ice.Message, cmd string, args ...interface{}) string {
|
||||
arg := kit.Simple(args...)
|
||||
if len(arg) == 1 && arg[0] != kit.SSH_BREAK {
|
||||
arg = []string{kit.SSH_SHELL, arg[0]}
|
||||
}
|
||||
list := []string{kit.Format(`<div class="story" data-type="spark" data-name="%s">`, arg[0])}
|
||||
for _, l := range strings.Split(strings.Join(arg[1:], "\n"), "\n") {
|
||||
switch list = append(list, "<div>"); arg[0] {
|
||||
case kit.SSH_SHELL:
|
||||
list = append(list, "<label>", "$ ", "</label>")
|
||||
default:
|
||||
list = append(list, "<label>", "> ", "</label>")
|
||||
}
|
||||
list = append(list, "<span>", l, "</span>")
|
||||
list = append(list, "</div>")
|
||||
}
|
||||
list = append(list, "</div>")
|
||||
return strings.Join(list, "")
|
||||
})
|
||||
}},
|
||||
SPARK: {Name: "spark [name] text", Help: "段落", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
if len(arg) == 0 {
|
||||
m.Echo(`<br class="story" data-type="spark">`)
|
||||
|
28
data.go
28
data.go
@ -8,6 +8,34 @@ import (
|
||||
"github.com/shylinux/toolkits/miss"
|
||||
)
|
||||
|
||||
func (m *Message) Prefix(arg ...string) string {
|
||||
return kit.Keys(m.Cap(CTX_FOLLOW), arg)
|
||||
}
|
||||
func (m *Message) PrefixKey(arg ...string) string {
|
||||
return kit.Keys(m.Cap(CTX_FOLLOW), m._key, arg)
|
||||
}
|
||||
func (m *Message) Save(arg ...string) *Message {
|
||||
if len(arg) == 0 {
|
||||
for k := range m.target.Configs {
|
||||
arg = append(arg, k)
|
||||
}
|
||||
}
|
||||
list := []string{}
|
||||
for _, k := range arg {
|
||||
list = append(list, m.Prefix(k))
|
||||
}
|
||||
m.Cmd("ctx.config", "save", m.Prefix("json"), list)
|
||||
return m
|
||||
}
|
||||
func (m *Message) Load(arg ...string) *Message {
|
||||
list := []string{}
|
||||
for _, k := range arg {
|
||||
list = append(list, m.Prefix(k))
|
||||
}
|
||||
m.Cmd("ctx.config", "load", m.Prefix("json"), list)
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *Message) Richs(prefix string, chain interface{}, raw interface{}, cb interface{}) (res map[string]interface{}) {
|
||||
cache := m.Confm(prefix, chain)
|
||||
if cache == nil {
|
||||
|
33
exec.go
33
exec.go
@ -4,6 +4,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
kit "github.com/shylinux/toolkits"
|
||||
@ -76,6 +77,7 @@ func (m *Message) Done(b bool) bool {
|
||||
ctx.wg.Done()
|
||||
return true
|
||||
}
|
||||
|
||||
func (m *Message) Call(sync bool, cb func(*Message) *Message) *Message {
|
||||
wait := make(chan bool, 2)
|
||||
p := kit.Select("10s", m.Option("timeout"))
|
||||
@ -128,3 +130,34 @@ func (m *Message) Go(cb interface{}, args ...interface{}) *Message {
|
||||
}
|
||||
return m.Gos(m, cb, args...)
|
||||
}
|
||||
|
||||
func (m *Message) Watch(key string, arg ...string) *Message {
|
||||
if len(arg) == 0 {
|
||||
arg = append(arg, m.Prefix("auto"))
|
||||
}
|
||||
m.Cmd("gdb.event", "action", "listen", "event", key, "cmd", strings.Join(arg, " "))
|
||||
return m
|
||||
}
|
||||
func (m *Message) Event(key string, arg ...string) *Message {
|
||||
m.Cmd("gdb.event", "action", "action", "event", key, arg)
|
||||
return m
|
||||
}
|
||||
func (m *Message) Right(arg ...interface{}) bool {
|
||||
return m.Option(MSG_USERROLE) == "root" || !m.Warn(m.Cmdx("aaa.role", "right",
|
||||
m.Option(MSG_USERROLE), strings.ReplaceAll(kit.Keys(arg...), "/", ".")) != "ok",
|
||||
ErrNotRight, m.Option(MSG_USERROLE), " of ", strings.Join(kit.Simple(arg), "."), " at ", kit.FileLine(2, 3))
|
||||
}
|
||||
func (m *Message) Space(arg interface{}) []string {
|
||||
if arg == nil || arg == "" || kit.Format(arg) == m.Conf("cli.runtime", "node.name") {
|
||||
return nil
|
||||
}
|
||||
return []string{"web.space", kit.Format(arg)}
|
||||
}
|
||||
func (m *Message) PodCmd(arg ...interface{}) bool {
|
||||
if pod := m.Option("pod"); pod != "" {
|
||||
m.Option("pod", "")
|
||||
m.Cmd(append([]interface{}{"space", pod}, arg...))
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
11
meta.go
11
meta.go
@ -444,3 +444,14 @@ func (m *Message) Result(arg ...interface{}) string {
|
||||
}
|
||||
return strings.Join(m.Resultv(arg...), "")
|
||||
}
|
||||
|
||||
func (m *Message) SortInt(key string) { m.Sort(key, "int") }
|
||||
func (m *Message) SortIntR(key string) { m.Sort(key, "int_r") }
|
||||
func (m *Message) SortStr(key string) { m.Sort(key, "str") }
|
||||
func (m *Message) SortStrR(key string) { m.Sort(key, "str_r") }
|
||||
func (m *Message) SortTime(key string) { m.Sort(key, "time") }
|
||||
func (m *Message) SortTimeR(key string) { m.Sort(key, "time_r") }
|
||||
|
||||
func (m *Message) FormatMeta() string { return m.Format("meta") }
|
||||
func (m *Message) FormatSize() string { return m.Format("size") }
|
||||
func (m *Message) FormatCost() string { return m.Format("cost") }
|
||||
|
793
misc.go
793
misc.go
@ -5,440 +5,37 @@ import (
|
||||
"encoding/csv"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
kit "github.com/shylinux/toolkits"
|
||||
)
|
||||
|
||||
func (m *Message) Prefix(arg ...string) string {
|
||||
return kit.Keys(m.Cap(CTX_FOLLOW), arg)
|
||||
}
|
||||
func (m *Message) PrefixKey(arg ...string) string {
|
||||
return kit.Keys(m.Cap(CTX_FOLLOW), m._key, arg)
|
||||
}
|
||||
func (m *Message) Save(arg ...string) *Message {
|
||||
if len(arg) == 0 {
|
||||
for k := range m.target.Configs {
|
||||
arg = append(arg, k)
|
||||
}
|
||||
}
|
||||
list := []string{}
|
||||
for _, k := range arg {
|
||||
list = append(list, m.Prefix(k))
|
||||
}
|
||||
m.Cmd("ctx.config", "save", m.Prefix("json"), list)
|
||||
return m
|
||||
}
|
||||
func (m *Message) Load(arg ...string) *Message {
|
||||
list := []string{}
|
||||
for _, k := range arg {
|
||||
list = append(list, m.Prefix(k))
|
||||
}
|
||||
m.Cmd("ctx.config", "load", m.Prefix("json"), list)
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *Message) Watch(key string, arg ...string) *Message {
|
||||
if len(arg) == 0 {
|
||||
arg = append(arg, m.Prefix("auto"))
|
||||
}
|
||||
m.Cmd("gdb.event", "action", "listen", "event", key, "cmd", strings.Join(arg, " "))
|
||||
return m
|
||||
}
|
||||
func (m *Message) Event(key string, arg ...string) *Message {
|
||||
m.Cmd("gdb.event", "action", "action", "event", key, arg)
|
||||
return m
|
||||
}
|
||||
func (m *Message) Right(arg ...interface{}) bool {
|
||||
return m.Option(MSG_USERROLE) == "root" || !m.Warn(m.Cmdx("aaa.role", "right",
|
||||
m.Option(MSG_USERROLE), strings.ReplaceAll(kit.Keys(arg...), "/", ".")) != "ok",
|
||||
ErrNotRight, m.Option(MSG_USERROLE), " of ", strings.Join(kit.Simple(arg), "."), " at ", kit.FileLine(2, 3))
|
||||
}
|
||||
func (m *Message) Space(arg interface{}) []string {
|
||||
if arg == nil || arg == "" || kit.Format(arg) == m.Conf("cli.runtime", "node.name") {
|
||||
return nil
|
||||
}
|
||||
return []string{"web.space", kit.Format(arg)}
|
||||
}
|
||||
|
||||
func (m *Message) ShowPlugin(pod, ctx, cmd string, arg ...string) {
|
||||
m.Cmdy("web.space", pod, "context", ctx, "command", cmd)
|
||||
m.Option(MSG_PROCESS, PROCESS_FIELD)
|
||||
m.Option(FIELD_PREFIX, arg)
|
||||
}
|
||||
func (m *Message) PushPodCmd(cmd string, arg ...string) {
|
||||
m.Table(func(index int, value map[string]string, head []string) {
|
||||
m.Push("pod", m.Option(MSG_USERPOD))
|
||||
})
|
||||
|
||||
m.Cmd("web.space").Table(func(index int, value map[string]string, head []string) {
|
||||
switch value[kit.MDB_TYPE] {
|
||||
case "worker", "server":
|
||||
if value[kit.MDB_NAME] == Info.HostName {
|
||||
break
|
||||
}
|
||||
m.Cmd("web.space", value[kit.MDB_NAME], m.Prefix(cmd), arg).Table(func(index int, val map[string]string, head []string) {
|
||||
val["pod"] = kit.Keys(value[kit.MDB_NAME], val["pod"])
|
||||
m.Push("", val, head)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
func (m *Message) PushSearch(args ...interface{}) {
|
||||
data := kit.Dict(args...)
|
||||
for _, k := range kit.Split(m.Option(MSG_FIELDS)) {
|
||||
switch k {
|
||||
case "pod":
|
||||
// m.Push(k, kit.Select(m.Option(MSG_USERPOD), data[kit.SSH_POD]))
|
||||
case "ctx":
|
||||
m.Push(k, m.Prefix())
|
||||
case "cmd":
|
||||
m.Push(k, kit.Format(data["cmd"]))
|
||||
case kit.MDB_TIME:
|
||||
m.Push(k, kit.Select(m.Time(), data[k]))
|
||||
default:
|
||||
m.Push(k, kit.Format(kit.Select("", data[k])))
|
||||
}
|
||||
}
|
||||
}
|
||||
func (m *Message) PushSearchWeb(cmd string, name string) {
|
||||
msg := m.Spawn()
|
||||
msg.Option(MSG_FIELDS, "type,name,text")
|
||||
msg.Cmd("mdb.select", m.Prefix(cmd), "", kit.MDB_HASH).Table(func(index int, value map[string]string, head []string) {
|
||||
text := kit.MergeURL(value[kit.MDB_TEXT], value[kit.MDB_NAME], name)
|
||||
if value[kit.MDB_NAME] == "" {
|
||||
text = kit.MergeURL(value[kit.MDB_TEXT] + url.QueryEscape(name))
|
||||
}
|
||||
m.PushSearch("cmd", cmd, kit.MDB_TYPE, kit.Select("", value[kit.MDB_TYPE]), kit.MDB_NAME, name, kit.MDB_TEXT, text)
|
||||
})
|
||||
}
|
||||
|
||||
func Render(m *Message, cmd string, args ...interface{}) string {
|
||||
if m.IsCliUA() {
|
||||
switch arg := kit.Simple(args...); cmd {
|
||||
case RENDER_QRCODE: // text [size]
|
||||
msg := m.Cmd("cli.qrcode", arg[0])
|
||||
return msg.Result()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
switch arg := kit.Simple(args...); cmd {
|
||||
case RENDER_DOWNLOAD: // [name] file
|
||||
if arg[0] == "" {
|
||||
return ""
|
||||
}
|
||||
list := []string{}
|
||||
if m.Option(MSG_USERPOD) != "" {
|
||||
list = append(list, "pod", m.Option(MSG_USERPOD))
|
||||
}
|
||||
if len(arg) == 1 {
|
||||
arg[0] = kit.MergeURL2(m.Option(MSG_USERWEB), path.Join(kit.Select("", "/share/local",
|
||||
!strings.HasPrefix(arg[0], "/")), arg[0]), list)
|
||||
} else {
|
||||
arg[1] = kit.MergeURL2(m.Option(MSG_USERWEB), path.Join(kit.Select("", "/share/local",
|
||||
!strings.HasPrefix(arg[1], "/")), arg[1]), list, "filename", arg[0])
|
||||
}
|
||||
arg[0] = m.ReplaceLocalhost(arg[0])
|
||||
return fmt.Sprintf(`<a href="%s" download="%s">%s</a>`, m.ReplaceLocalhost(kit.Select(arg[0], arg, 1)), path.Base(arg[0]), arg[0])
|
||||
|
||||
case RENDER_ANCHOR: // [name] link
|
||||
return fmt.Sprintf(`<a href="%s" target="_blank">%s</a>`, kit.Select(arg[0], arg, 1), arg[0])
|
||||
|
||||
case RENDER_BUTTON: // name...
|
||||
if m._cmd == nil || m._cmd.Meta == nil {
|
||||
return ""
|
||||
}
|
||||
list := []string{}
|
||||
for _, k := range kit.Split(strings.Join(arg, ",")) {
|
||||
list = append(list, fmt.Sprintf(`<input type="button" name="%s" value="%s">`,
|
||||
k, kit.Select(k, kit.Value(m._cmd.Meta, kit.Keys("_trans", k)))))
|
||||
}
|
||||
return strings.Join(list, "")
|
||||
|
||||
case RENDER_IMAGES: // src [size]
|
||||
return fmt.Sprintf(`<img src="%s" height=%s>`, arg[0], kit.Select("120", arg, 1))
|
||||
|
||||
case RENDER_VIDEOS: // src [size]
|
||||
return fmt.Sprintf(`<video src="%s" height=%s controls>`, arg[0], kit.Select("120", arg, 1))
|
||||
|
||||
case RENDER_QRCODE: // text [size]
|
||||
return m.Cmdx("cli.qrcode", arg[0])
|
||||
|
||||
case RENDER_SCRIPT: // type text
|
||||
if len(arg) == 1 && arg[0] != kit.SSH_BREAK {
|
||||
arg = []string{kit.SSH_SHELL, arg[0]}
|
||||
}
|
||||
list := []string{kit.Format(`<div class="story" data-type="spark" data-name="%s">`, arg[0])}
|
||||
for _, l := range strings.Split(strings.Join(arg[1:], "\n"), "\n") {
|
||||
switch list = append(list, "<div>"); arg[0] {
|
||||
case kit.SSH_SHELL:
|
||||
list = append(list, "<label>", "$ ", "</label>")
|
||||
default:
|
||||
list = append(list, "<label>", "> ", "</label>")
|
||||
}
|
||||
list = append(list, "<span>", l, "</span>")
|
||||
list = append(list, "</div>")
|
||||
}
|
||||
list = append(list, "</div>")
|
||||
return strings.Join(list, "")
|
||||
default:
|
||||
return arg[0]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
func (m *Message) PushRender(key, view, name string, arg ...string) *Message {
|
||||
return m.Push(key, Render(m, view, name, arg))
|
||||
}
|
||||
func (m *Message) PushDownload(key string, arg ...interface{}) { // [name] file
|
||||
if !m.IsCliUA() {
|
||||
m.Push(key, Render(m, RENDER_DOWNLOAD, arg...))
|
||||
}
|
||||
}
|
||||
func (m *Message) PushAnchor(arg ...interface{}) { // [name] link
|
||||
if !m.IsCliUA() {
|
||||
m.Push(kit.MDB_LINK, Render(m, RENDER_ANCHOR, arg...))
|
||||
}
|
||||
}
|
||||
func (m *Message) PushButton(arg ...string) {
|
||||
if !m.IsCliUA() {
|
||||
m.Push("action", Render(m, RENDER_BUTTON, strings.Join(arg, ",")))
|
||||
}
|
||||
}
|
||||
func (m *Message) PushScript(arg ...string) *Message { // [type] text...
|
||||
return m.Push(kit.MDB_SCRIPT, Render(m, RENDER_SCRIPT, arg))
|
||||
}
|
||||
func (m *Message) PushImages(key, src string, arg ...string) { // key src [size]
|
||||
m.Push(key, Render(m, RENDER_IMAGES, src, arg))
|
||||
}
|
||||
func (m *Message) PushVideos(key, src string, arg ...string) { // key src [size]
|
||||
m.Push(key, Render(m, RENDER_VIDEOS, src, arg))
|
||||
}
|
||||
func (m *Message) PushQRCode(key string, text string, arg ...string) { // key text [size]
|
||||
m.Push(key, Render(m, RENDER_QRCODE, text, arg))
|
||||
}
|
||||
func (m *Message) PushAction(list ...interface{}) {
|
||||
m.Table(func(index int, value map[string]string, head []string) {
|
||||
m.PushButton(kit.Simple(list...)...)
|
||||
})
|
||||
}
|
||||
|
||||
func (m *Message) EchoAnchor(arg ...interface{}) *Message { // [name] link
|
||||
return m.Echo(Render(m, RENDER_ANCHOR, arg...))
|
||||
}
|
||||
func (m *Message) EchoButton(arg ...string) *Message {
|
||||
return m.Echo(Render(m, RENDER_BUTTON, strings.Join(arg, ",")))
|
||||
}
|
||||
func (m *Message) EchoScript(arg ...string) *Message {
|
||||
return m.Echo(Render(m, RENDER_SCRIPT, arg))
|
||||
}
|
||||
func (m *Message) EchoImages(src string, arg ...string) *Message {
|
||||
return m.Echo(Render(m, RENDER_IMAGES, src, arg))
|
||||
}
|
||||
func (m *Message) EchoQRCode(text string, arg ...string) *Message { // text [size]
|
||||
return m.Echo(Render(m, RENDER_QRCODE, text, arg))
|
||||
}
|
||||
func (m *Message) EchoDownload(arg ...interface{}) { // [name] file
|
||||
m.Echo(Render(m, RENDER_DOWNLOAD, arg...))
|
||||
}
|
||||
|
||||
func (m *Message) SortInt(key string) { m.Sort(key, "int") }
|
||||
func (m *Message) SortIntR(key string) { m.Sort(key, "int_r") }
|
||||
func (m *Message) SortStr(key string) { m.Sort(key, "str") }
|
||||
func (m *Message) SortStrR(key string) { m.Sort(key, "str_r") }
|
||||
func (m *Message) SortTime(key string) { m.Sort(key, "time") }
|
||||
func (m *Message) SortTimeR(key string) { m.Sort(key, "time_r") }
|
||||
|
||||
func (m *Message) FormatMeta() string { return m.Format("meta") }
|
||||
func (m *Message) FormatSize() string { return m.Format("size") }
|
||||
func (m *Message) FormatCost() string { return m.Format("cost") }
|
||||
|
||||
func (m *Message) Render(cmd string, args ...interface{}) *Message {
|
||||
m.Optionv(MSG_OUTPUT, cmd)
|
||||
m.Optionv(MSG_ARGS, args)
|
||||
|
||||
switch cmd {
|
||||
case RENDER_TEMPLATE: // text [data [type]]
|
||||
if len(args) == 1 {
|
||||
args = append(args, m)
|
||||
}
|
||||
if res, err := kit.Render(args[0].(string), args[1]); m.Assert(err) {
|
||||
m.Echo(string(res))
|
||||
}
|
||||
}
|
||||
return m
|
||||
}
|
||||
func (m *Message) RenderResult(args ...interface{}) *Message {
|
||||
return m.Render(RENDER_RESULT, args...)
|
||||
}
|
||||
func (m *Message) RenderTemplate(args ...interface{}) *Message {
|
||||
|
||||
return m.Render(RENDER_TEMPLATE, args...)
|
||||
}
|
||||
func (m *Message) RenderDownload(args ...interface{}) *Message {
|
||||
return m.Render(RENDER_DOWNLOAD, args...)
|
||||
}
|
||||
func (m *Message) RenderRedirect(args ...interface{}) *Message {
|
||||
return m.Render(RENDER_REDIRECT, args...)
|
||||
}
|
||||
func (m *Message) RenderIndex(serve, repos string) *Message {
|
||||
return m.RenderDownload(path.Join(m.Conf(serve, kit.Keym(repos, kit.SSH_PATH)), m.Conf(serve, kit.Keym(repos, kit.SSH_INDEX))))
|
||||
}
|
||||
|
||||
type Sort struct {
|
||||
Fields string
|
||||
Method string
|
||||
}
|
||||
type Option struct {
|
||||
Name string
|
||||
Value interface{}
|
||||
}
|
||||
|
||||
func (m *Message) OptionSimple(key ...string) (res []string) {
|
||||
for _, k := range strings.Split(strings.Join(key, ","), ",") {
|
||||
res = append(res, k, m.Option(k))
|
||||
}
|
||||
return
|
||||
}
|
||||
func OptionFields(str ...string) Option { return Option{MSG_FIELDS, strings.Join(str, ",")} }
|
||||
func OptionHash(str string) Option { return Option{kit.MDB_HASH, str} }
|
||||
func (m *Message) OptionFields(str ...string) { m.Option(MSG_FIELDS, strings.Join(str, ",")) }
|
||||
func (m *Message) OptionPage(arg ...string) {
|
||||
m.Option("cache.offend", kit.Select("0", arg, 1))
|
||||
m.Option("cache.limit", kit.Select("10", arg, 0))
|
||||
}
|
||||
func (m *Message) OptionLoad(file string) *Message {
|
||||
if f, e := os.Open(file); e == nil {
|
||||
defer f.Close()
|
||||
|
||||
var data interface{}
|
||||
json.NewDecoder(f).Decode(&data)
|
||||
|
||||
kit.Fetch(data, func(key string, value interface{}) { m.Option(key, kit.Simple(value)) })
|
||||
}
|
||||
return m
|
||||
}
|
||||
func (m *Message) Fields(length int, fields ...string) string {
|
||||
return m.Option(MSG_FIELDS, kit.Select(kit.Select("detail", fields, length), m.Option(MSG_FIELDS)))
|
||||
}
|
||||
func (m *Message) Upload(dir string) {
|
||||
up := kit.Simple(m.Optionv(MSG_UPLOAD))
|
||||
if p := path.Join(dir, up[1]); m.Option(MSG_USERPOD) == "" {
|
||||
// 本机文件
|
||||
m.Cmdy("web.cache", "watch", up[0], p)
|
||||
} else {
|
||||
// 下拉文件
|
||||
m.Cmdy("web.spide", "dev", "save", p, "GET",
|
||||
kit.MergeURL2(m.Option(MSG_USERWEB), path.Join("/share/cache", up[0])))
|
||||
}
|
||||
}
|
||||
func (m *Message) Action(arg ...string) {
|
||||
m.Option(MSG_ACTION, kit.Format(arg))
|
||||
}
|
||||
func (m *Message) Status(arg ...interface{}) {
|
||||
args := kit.Simple(arg)
|
||||
list := []map[string]interface{}{}
|
||||
for i := 0; i < len(args)-1; i += 2 {
|
||||
list = append(list, map[string]interface{}{
|
||||
kit.MDB_NAME: args[i], kit.MDB_VALUE: args[i+1],
|
||||
})
|
||||
}
|
||||
m.Option(MSG_STATUS, kit.Format(list))
|
||||
}
|
||||
func (m *Message) StatusTime(arg ...interface{}) {
|
||||
m.Status(kit.MDB_TIME, m.Time(), arg, "cost", m.FormatCost())
|
||||
}
|
||||
|
||||
func (m *Message) StatusTimeCount(arg ...interface{}) {
|
||||
m.Status(kit.MDB_TIME, m.Time(), kit.MDB_COUNT, m.FormatSize(), arg, "cost", m.FormatCost())
|
||||
}
|
||||
func (m *Message) StatusTimeCountTotal(arg ...interface{}) {
|
||||
m.Status(kit.MDB_TIME, m.Time(), kit.MDB_COUNT, m.FormatSize(), "total", arg, "cost", m.FormatCost())
|
||||
}
|
||||
|
||||
func (m *Message) Toast(content string, arg ...interface{}) {
|
||||
if len(arg) > 1 {
|
||||
switch val := arg[1].(type) {
|
||||
case string:
|
||||
if value, err := time.ParseDuration(val); err == nil {
|
||||
arg[1] = int(value / time.Millisecond)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if m.Option(MSG_USERPOD) == "" {
|
||||
m.Cmd("web.space", m.Option(MSG_DAEMON), "toast", "", content, arg)
|
||||
} else {
|
||||
m.Option(MSG_TOAST, kit.Simple(content, arg))
|
||||
}
|
||||
}
|
||||
func (m *Message) GoToast(title string, cb func(toast func(string, int, int))) {
|
||||
m.Go(func() {
|
||||
cb(func(name string, count, total int) {
|
||||
m.Toast(
|
||||
kit.Format("%s %s/%s", name, strings.TrimSuffix(kit.FmtSize(int64(count)), "B"), strings.TrimSuffix(kit.FmtSize(int64(total)), "B")),
|
||||
kit.Format("%s %d%%", title, count*100/total),
|
||||
kit.Select("1000", "10000", count < total),
|
||||
count*100/total,
|
||||
)
|
||||
})
|
||||
})
|
||||
}
|
||||
func (m *Message) Process(action string, arg ...interface{}) {
|
||||
m.Option(MSG_PROCESS, action)
|
||||
m.Option("_arg", arg...)
|
||||
}
|
||||
func (m *Message) ProcessRewrite(arg ...interface{}) {
|
||||
m.Process(PROCESS_REWRITE)
|
||||
m.Option("_arg", arg...)
|
||||
}
|
||||
func (m *Message) ProcessRefresh(delay string) {
|
||||
if d, e := time.ParseDuration(delay); e == nil {
|
||||
m.Option("_delay", int(d/time.Millisecond))
|
||||
}
|
||||
m.Process(PROCESS_REFRESH)
|
||||
}
|
||||
func (m *Message) ProcessRefresh30ms() { m.ProcessRefresh("30ms") }
|
||||
func (m *Message) ProcessRefresh300ms() { m.ProcessRefresh("300ms") }
|
||||
func (m *Message) ProcessRefresh3s() { m.ProcessRefresh("3s") }
|
||||
func (m *Message) ProcessCommand(cmd string, val []string, arg ...string) {
|
||||
if len(arg) > 0 && arg[0] == "run" {
|
||||
m.Cmdy(cmd, arg[1:])
|
||||
return
|
||||
}
|
||||
|
||||
m.Cmdy("command", cmd)
|
||||
m.ProcessField(cmd, "run")
|
||||
m.Push("arg", kit.Format(val))
|
||||
}
|
||||
func (m *Message) ProcessCommandOpt(arg ...string) {
|
||||
m.Push("opt", kit.Format(m.OptionSimple(arg...)))
|
||||
}
|
||||
func (m *Message) ProcessField(arg ...interface{}) {
|
||||
m.Process(PROCESS_FIELD)
|
||||
m.Option("_prefix", arg...)
|
||||
}
|
||||
func (m *Message) ProcessInner() { m.Process(PROCESS_INNER) }
|
||||
func (m *Message) ProcessHold() { m.Process(PROCESS_HOLD) }
|
||||
func (m *Message) ProcessBack() { m.Process(PROCESS_BACK) }
|
||||
|
||||
func (m *Message) Confi(key string, sub string) int {
|
||||
return kit.Int(m.Conf(key, sub))
|
||||
}
|
||||
func (m *Message) Capi(key string, val ...interface{}) int {
|
||||
if len(val) > 0 {
|
||||
m.Cap(key, kit.Int(m.Cap(key))+kit.Int(val[0]))
|
||||
}
|
||||
return kit.Int(m.Cap(key))
|
||||
}
|
||||
func (m *Message) Cut(fields ...string) *Message {
|
||||
m.meta[MSG_APPEND] = strings.Split(strings.Join(fields, ","), ",")
|
||||
return m
|
||||
}
|
||||
func (m *Message) CSV(text string, head ...string) *Message {
|
||||
bio := bytes.NewBufferString(text)
|
||||
r := csv.NewReader(bio)
|
||||
|
||||
if len(head) == 0 {
|
||||
head, _ = r.Read()
|
||||
}
|
||||
for {
|
||||
line, e := r.Read()
|
||||
if e != nil {
|
||||
break
|
||||
}
|
||||
for i, k := range head {
|
||||
m.Push(k, kit.Select("", line, i))
|
||||
}
|
||||
}
|
||||
return m
|
||||
}
|
||||
func (m *Message) Parse(meta string, key string, arg ...string) *Message {
|
||||
list := []string{}
|
||||
for _, line := range kit.Split(strings.Join(arg, " "), "\n") {
|
||||
@ -504,23 +101,103 @@ func (m *Message) Split(str string, field string, space string, enter string) *M
|
||||
}
|
||||
return m
|
||||
}
|
||||
func (m *Message) CSV(text string, head ...string) *Message {
|
||||
bio := bytes.NewBufferString(text)
|
||||
r := csv.NewReader(bio)
|
||||
func (m *Message) Format(key interface{}) string {
|
||||
switch key := key.(type) {
|
||||
case []byte:
|
||||
json.Unmarshal(key, &m.meta)
|
||||
case string:
|
||||
switch key {
|
||||
case "cost":
|
||||
return kit.FmtTime(kit.Int64(time.Since(m.time)))
|
||||
case "meta":
|
||||
return kit.Format(m.meta)
|
||||
case "size":
|
||||
if len(m.meta["append"]) == 0 {
|
||||
return fmt.Sprintf("%dx%d", 0, 0)
|
||||
} else {
|
||||
return fmt.Sprintf("%dx%d", len(m.meta[m.meta["append"][0]]), len(m.meta["append"]))
|
||||
}
|
||||
case "append":
|
||||
if len(m.meta["append"]) == 0 {
|
||||
return fmt.Sprintf("%dx%d %s", 0, 0, "[]")
|
||||
} else {
|
||||
return fmt.Sprintf("%dx%d %s", len(m.meta[m.meta["append"][0]]), len(m.meta["append"]), kit.Format(m.meta["append"]))
|
||||
}
|
||||
|
||||
if len(head) == 0 {
|
||||
head, _ = r.Read()
|
||||
}
|
||||
for {
|
||||
line, e := r.Read()
|
||||
if e != nil {
|
||||
break
|
||||
}
|
||||
for i, k := range head {
|
||||
m.Push(k, kit.Select("", line, i))
|
||||
case "time":
|
||||
return m.Time()
|
||||
case "ship":
|
||||
return fmt.Sprintf("%s->%s", m.source.Name, m.target.Name)
|
||||
case "prefix":
|
||||
return fmt.Sprintf("%s %d %s->%s", m.Time(), m.code, m.source.Name, m.target.Name)
|
||||
|
||||
case "chain":
|
||||
// 调用链
|
||||
ms := []*Message{}
|
||||
for msg := m; msg != nil; msg = msg.message {
|
||||
ms = append(ms, msg)
|
||||
}
|
||||
|
||||
meta := append([]string{}, "\n\n")
|
||||
for i := len(ms) - 1; i >= 0; i-- {
|
||||
msg := ms[i]
|
||||
|
||||
meta = append(meta, fmt.Sprintf("%s ", msg.Format("prefix")))
|
||||
if len(msg.meta[MSG_DETAIL]) > 0 {
|
||||
meta = append(meta, fmt.Sprintf("detail:%d %v", len(msg.meta[MSG_DETAIL]), msg.meta[MSG_DETAIL]))
|
||||
}
|
||||
|
||||
if len(msg.meta[MSG_OPTION]) > 0 {
|
||||
meta = append(meta, fmt.Sprintf("option:%d %v\n", len(msg.meta[MSG_OPTION]), msg.meta[MSG_OPTION]))
|
||||
for _, k := range msg.meta[MSG_OPTION] {
|
||||
if v, ok := msg.meta[k]; ok {
|
||||
meta = append(meta, fmt.Sprintf(" %s: %d %v\n", k, len(v), v))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
meta = append(meta, "\n")
|
||||
}
|
||||
|
||||
if len(msg.meta[MSG_APPEND]) > 0 {
|
||||
meta = append(meta, fmt.Sprintf(" append:%d %v\n", len(msg.meta[MSG_APPEND]), msg.meta[MSG_APPEND]))
|
||||
for _, k := range msg.meta[MSG_APPEND] {
|
||||
if v, ok := msg.meta[k]; ok {
|
||||
meta = append(meta, fmt.Sprintf(" %s: %d %v\n", k, len(v), v))
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(msg.meta[MSG_RESULT]) > 0 {
|
||||
meta = append(meta, fmt.Sprintf(" result:%d %v\n", len(msg.meta[MSG_RESULT]), msg.meta[MSG_RESULT]))
|
||||
}
|
||||
}
|
||||
return strings.Join(meta, "")
|
||||
case "stack":
|
||||
// 调用栈
|
||||
pc := make([]uintptr, 100)
|
||||
pc = pc[:runtime.Callers(5, pc)]
|
||||
frames := runtime.CallersFrames(pc)
|
||||
|
||||
meta := []string{}
|
||||
for {
|
||||
frame, more := frames.Next()
|
||||
file := strings.Split(frame.File, "/")
|
||||
name := strings.Split(frame.Function, "/")
|
||||
meta = append(meta, fmt.Sprintf("\n%s:%d\t%s", file[len(file)-1], frame.Line, name[len(name)-1]))
|
||||
if !more {
|
||||
break
|
||||
}
|
||||
}
|
||||
return strings.Join(meta, "")
|
||||
}
|
||||
}
|
||||
return m
|
||||
return m.time.Format(MOD_TIME)
|
||||
}
|
||||
func (m *Message) Formats(key string) string {
|
||||
switch key {
|
||||
case "meta":
|
||||
return kit.Formats(m.meta)
|
||||
}
|
||||
return m.Format(key)
|
||||
}
|
||||
func (m *Message) RenameAppend(from, to string) {
|
||||
for i, v := range m.meta[MSG_APPEND] {
|
||||
@ -531,17 +208,209 @@ func (m *Message) RenameAppend(from, to string) {
|
||||
}
|
||||
}
|
||||
}
|
||||
func (m *Message) IsCliUA() bool {
|
||||
if m.Option(MSG_USERUA) == "" || !strings.HasPrefix(m.Option(MSG_USERUA), "Mozilla/5.0") {
|
||||
return true
|
||||
|
||||
func (m *Message) cmd(arg ...interface{}) *Message {
|
||||
opts := map[string]interface{}{}
|
||||
args := []interface{}{}
|
||||
var cbs interface{}
|
||||
|
||||
// 解析参数
|
||||
for _, v := range arg {
|
||||
switch val := v.(type) {
|
||||
case func(int, map[string]string, []string):
|
||||
defer func() { m.Table(val) }()
|
||||
|
||||
case map[string]string:
|
||||
for k, v := range val {
|
||||
opts[k] = v
|
||||
}
|
||||
|
||||
case *Option:
|
||||
opts[val.Name] = val.Value
|
||||
case Option:
|
||||
opts[val.Name] = val.Value
|
||||
|
||||
case *Sort:
|
||||
defer func() { m.Sort(val.Fields, val.Method) }()
|
||||
case Sort:
|
||||
defer func() { m.Sort(val.Fields, val.Method) }()
|
||||
|
||||
default:
|
||||
if reflect.Func == reflect.TypeOf(val).Kind() {
|
||||
cbs = val
|
||||
} else {
|
||||
args = append(args, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
|
||||
// 解析命令
|
||||
list := kit.Simple(args...)
|
||||
if len(list) == 0 && !m.Hand {
|
||||
list = m.meta[MSG_DETAIL]
|
||||
}
|
||||
if len(list) == 0 {
|
||||
return m
|
||||
}
|
||||
|
||||
ok := false
|
||||
run := func(msg *Message, ctx *Context, cmd *Command, key string, arg ...string) {
|
||||
if ok = true; cbs != nil {
|
||||
msg.Option(list[0]+".cb", cbs)
|
||||
}
|
||||
for k, v := range opts {
|
||||
msg.Option(k, v)
|
||||
}
|
||||
|
||||
// 执行命令
|
||||
m.TryCatch(msg, true, func(msg *Message) {
|
||||
m = ctx.cmd(msg, cmd, key, arg...)
|
||||
})
|
||||
}
|
||||
|
||||
// 查找命令
|
||||
if cmd, ok := m.target.Commands[list[0]]; ok {
|
||||
run(m.Spawn(), m.target, cmd, list[0], list[1:]...)
|
||||
} else if cmd, ok := m.source.Commands[list[0]]; ok {
|
||||
run(m.Spawn(m.source), m.source, cmd, list[0], list[1:]...)
|
||||
} else {
|
||||
m.Search(list[0], func(p *Context, s *Context, key string, cmd *Command) {
|
||||
run(m.Spawn(s), s, cmd, key, list[1:]...)
|
||||
})
|
||||
}
|
||||
|
||||
// 系统命令
|
||||
if m.Warn(!ok, ErrNotFound, list) {
|
||||
return m.Set(MSG_RESULT).Cmdy("cli.system", list)
|
||||
}
|
||||
return m
|
||||
}
|
||||
func (m *Message) ReplaceLocalhost(url string) string {
|
||||
if strings.Contains(url, "://localhost") {
|
||||
return strings.Replace(url, "localhost", m.Cmd("tcp.host").Append("ip"), 1)
|
||||
func (c *Context) cmd(m *Message, cmd *Command, key string, arg ...string) *Message {
|
||||
if m._key, m._cmd = key, cmd; cmd == nil {
|
||||
return m
|
||||
}
|
||||
return url
|
||||
|
||||
m.meta[MSG_DETAIL] = kit.Simple(key, arg)
|
||||
if m.Hand = true; len(arg) > 1 && arg[0] == "action" && cmd.Action != nil {
|
||||
if h, ok := cmd.Action[arg[1]]; ok {
|
||||
return c._cmd(m, cmd, key, arg[1], h, arg[2:]...)
|
||||
}
|
||||
}
|
||||
if len(arg) > 0 && arg[0] != "command" && cmd.Action != nil {
|
||||
if h, ok := cmd.Action[arg[0]]; ok {
|
||||
return c._cmd(m, cmd, key, arg[0], h, arg[1:]...)
|
||||
}
|
||||
}
|
||||
|
||||
m.Log(LOG_CMDS, "%s.%s %d %v %s", c.Name, key, len(arg), arg,
|
||||
kit.Select(kit.FileLine(cmd.Hand, 3), kit.FileLine(9, 3), m.target.Name == "mdb"))
|
||||
cmd.Hand(m, c, key, arg...)
|
||||
return m
|
||||
}
|
||||
func (c *Context) _cmd(m *Message, cmd *Command, key string, k string, h *Action, arg ...string) *Message {
|
||||
if k == "run" && m.Warn(!m.Right(arg), ErrNotRight, arg) {
|
||||
return m
|
||||
}
|
||||
|
||||
m.Log(LOG_CMDS, "%s.%s %s %d %v %s", c.Name, key, k, len(arg), arg, kit.FileLine(h.Hand, 3))
|
||||
if len(h.List) > 0 && k != "search" {
|
||||
order := false
|
||||
for i, v := range h.List {
|
||||
name := kit.Format(kit.Value(v, "name"))
|
||||
value := kit.Format(kit.Value(v, "value"))
|
||||
|
||||
if i == 0 && len(arg) > 0 && arg[0] != name {
|
||||
order = true
|
||||
}
|
||||
if order {
|
||||
value = kit.Select(value, arg, i)
|
||||
}
|
||||
|
||||
m.Option(name, kit.Select(m.Option(name), value, !strings.HasPrefix(value, "@")))
|
||||
}
|
||||
if !order {
|
||||
for i := 0; i < len(arg)-1; i += 2 {
|
||||
m.Option(arg[i], arg[i+1])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if h.Hand == nil {
|
||||
m.Cmdy(kit.Split(h.Name), arg)
|
||||
} else {
|
||||
h.Hand(m, arg...)
|
||||
}
|
||||
return m
|
||||
}
|
||||
func (c *Context) split(key string, cmd *Command, name string) []interface{} {
|
||||
const (
|
||||
BUTTON = "button"
|
||||
SELECT = "select"
|
||||
TEXT = "text"
|
||||
TEXTAREA = "textarea"
|
||||
)
|
||||
|
||||
button, list := false, []interface{}{}
|
||||
for _, v := range kit.Split(kit.Select("key", name), " ", " ")[1:] {
|
||||
switch v {
|
||||
case "text":
|
||||
list = append(list, kit.List(kit.MDB_INPUT, TEXTAREA, kit.MDB_NAME, "text", kit.MDB_VALUE, "@key")...)
|
||||
continue
|
||||
case "page":
|
||||
list = append(list, kit.List(kit.MDB_INPUT, TEXT, kit.MDB_NAME, "limit")...)
|
||||
list = append(list, kit.List(kit.MDB_INPUT, TEXT, kit.MDB_NAME, "offend")...)
|
||||
list = append(list, kit.List(kit.MDB_INPUT, BUTTON, kit.MDB_NAME, "prev")...)
|
||||
list = append(list, kit.List(kit.MDB_INPUT, BUTTON, kit.MDB_NAME, "next")...)
|
||||
continue
|
||||
case "auto":
|
||||
list = append(list, kit.List(kit.MDB_INPUT, BUTTON, kit.MDB_NAME, "查看", kit.MDB_VALUE, "auto")...)
|
||||
list = append(list, kit.List(kit.MDB_INPUT, BUTTON, kit.MDB_NAME, "返回")...)
|
||||
button = true
|
||||
continue
|
||||
}
|
||||
|
||||
ls, value := kit.Split(v, " ", ":=@"), ""
|
||||
item := kit.Dict(kit.MDB_INPUT, kit.Select(TEXT, BUTTON, button))
|
||||
if kit.Value(item, kit.MDB_NAME, ls[0]); item[kit.MDB_INPUT] == TEXT {
|
||||
kit.Value(item, kit.MDB_VALUE, kit.Select("@key", "auto", strings.Contains(name, "auto")))
|
||||
}
|
||||
|
||||
for i := 1; i < len(ls); i += 2 {
|
||||
switch ls[i] {
|
||||
case ":":
|
||||
switch kit.Value(item, kit.MDB_INPUT, ls[i+1]); ls[i+1] {
|
||||
case TEXTAREA:
|
||||
kit.Value(item, "style.width", "360")
|
||||
kit.Value(item, "style.height", "60")
|
||||
case BUTTON:
|
||||
kit.Value(item, kit.MDB_VALUE, "")
|
||||
button = true
|
||||
}
|
||||
case "=":
|
||||
if value = kit.Select("", ls, i+1); len(ls) > i+1 && strings.Contains(ls[i+1], ",") {
|
||||
vs := strings.Split(ls[i+1], ",")
|
||||
kit.Value(item, "values", vs)
|
||||
kit.Value(item, kit.MDB_VALUE, vs[0])
|
||||
kit.Value(item, kit.MDB_INPUT, SELECT)
|
||||
if kit.Value(item, kit.MDB_NAME) == "scale" {
|
||||
kit.Value(item, kit.MDB_VALUE, "week")
|
||||
}
|
||||
} else {
|
||||
kit.Value(item, kit.MDB_VALUE, value)
|
||||
}
|
||||
case "@":
|
||||
if len(ls) > i+1 {
|
||||
if kit.Value(item, kit.MDB_INPUT) == BUTTON {
|
||||
kit.Value(item, "action", ls[i+1])
|
||||
} else {
|
||||
kit.Value(item, kit.MDB_VALUE, "@"+ls[i+1]+"="+value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
list = append(list, item)
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
func Display(file string, arg ...string) map[string]string {
|
||||
@ -553,40 +422,6 @@ func Display(file string, arg ...string) map[string]string {
|
||||
// return map[string]string{kit.MDB_DISPLAY: file, kit.MDB_STYLE: kit.Select("", arg, 0)}
|
||||
return map[string]string{"display": file, kit.MDB_STYLE: kit.Select("", arg, 0)}
|
||||
}
|
||||
func (m *Message) OptionSplit(fields ...string) (res []string) {
|
||||
for _, k := range strings.Split(strings.Join(fields, ","), ",") {
|
||||
res = append(res, m.Option(k))
|
||||
}
|
||||
return res
|
||||
}
|
||||
func (m *Message) OptionTemplate() string {
|
||||
res := []string{`class="story"`}
|
||||
for _, key := range kit.Split("style") {
|
||||
if m.Option(key) != "" {
|
||||
res = append(res, kit.Format(`s="%s"`, key, m.Option(key)))
|
||||
}
|
||||
}
|
||||
for _, key := range kit.Split("type,name,text") {
|
||||
if m.Option(key) != "" {
|
||||
res = append(res, kit.Format(`data-%s="%s"`, key, m.Option(key)))
|
||||
}
|
||||
}
|
||||
kit.Fetch(m.Optionv("extra"), func(key string, value string) {
|
||||
if value != "" {
|
||||
res = append(res, kit.Format(`data-%s="%s"`, key, value))
|
||||
}
|
||||
})
|
||||
return strings.Join(res, " ")
|
||||
}
|
||||
func (m *Message) PodCmd(arg ...interface{}) bool {
|
||||
if pod := m.Option("pod"); pod != "" {
|
||||
m.Option("pod", "")
|
||||
m.Cmd(append([]interface{}{"space", pod}, arg...))
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func MergeAction(list ...map[string]*Action) map[string]*Action {
|
||||
if len(list) == 0 {
|
||||
return nil
|
||||
|
310
type.go
310
type.go
@ -5,8 +5,6 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
@ -78,63 +76,6 @@ func (c *Context) Cap(key string, arg ...interface{}) string {
|
||||
}
|
||||
return c.Caches[key].Value
|
||||
}
|
||||
func (c *Context) _cmd(m *Message, cmd *Command, key string, k string, h *Action, arg ...string) *Message {
|
||||
if k == "run" && m.Warn(!m.Right(arg), ErrNotRight, arg) {
|
||||
return m
|
||||
}
|
||||
|
||||
m.Log(LOG_CMDS, "%s.%s %s %d %v %s", c.Name, key, k, len(arg), arg, kit.FileLine(h.Hand, 3))
|
||||
if len(h.List) > 0 && k != "search" {
|
||||
order := false
|
||||
for i, v := range h.List {
|
||||
name := kit.Format(kit.Value(v, "name"))
|
||||
value := kit.Format(kit.Value(v, "value"))
|
||||
|
||||
if i == 0 && len(arg) > 0 && arg[0] != name {
|
||||
order = true
|
||||
}
|
||||
if order {
|
||||
value = kit.Select(value, arg, i)
|
||||
}
|
||||
|
||||
m.Option(name, kit.Select(m.Option(name), value, !strings.HasPrefix(value, "@")))
|
||||
}
|
||||
if !order {
|
||||
for i := 0; i < len(arg)-1; i += 2 {
|
||||
m.Option(arg[i], arg[i+1])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if h.Hand == nil {
|
||||
m.Cmdy(kit.Split(h.Name), arg)
|
||||
} else {
|
||||
h.Hand(m, arg...)
|
||||
}
|
||||
return m
|
||||
}
|
||||
func (c *Context) cmd(m *Message, cmd *Command, key string, arg ...string) *Message {
|
||||
if m._key, m._cmd = key, cmd; cmd == nil {
|
||||
return m
|
||||
}
|
||||
|
||||
m.meta[MSG_DETAIL] = kit.Simple(key, arg)
|
||||
if m.Hand = true; len(arg) > 1 && arg[0] == "action" && cmd.Action != nil {
|
||||
if h, ok := cmd.Action[arg[1]]; ok {
|
||||
return c._cmd(m, cmd, key, arg[1], h, arg[2:]...)
|
||||
}
|
||||
}
|
||||
if len(arg) > 0 && arg[0] != "command" && cmd.Action != nil {
|
||||
if h, ok := cmd.Action[arg[0]]; ok {
|
||||
return c._cmd(m, cmd, key, arg[0], h, arg[1:]...)
|
||||
}
|
||||
}
|
||||
|
||||
m.Log(LOG_CMDS, "%s.%s %d %v %s", c.Name, key, len(arg), arg,
|
||||
kit.Select(kit.FileLine(cmd.Hand, 3), kit.FileLine(9, 3), m.target.Name == "mdb"))
|
||||
cmd.Hand(m, c, key, arg...)
|
||||
return m
|
||||
}
|
||||
func (c *Context) Cmd(m *Message, cmd string, key string, arg ...string) *Message {
|
||||
return c.cmd(m, m.Target().Commands[cmd], cmd, arg...)
|
||||
}
|
||||
@ -231,76 +172,6 @@ func (c *Context) Merge(s *Context) *Context {
|
||||
}
|
||||
return c
|
||||
}
|
||||
func (c *Context) split(key string, cmd *Command, name string) []interface{} {
|
||||
const (
|
||||
BUTTON = "button"
|
||||
SELECT = "select"
|
||||
TEXT = "text"
|
||||
TEXTAREA = "textarea"
|
||||
)
|
||||
|
||||
button, list := false, []interface{}{}
|
||||
for _, v := range kit.Split(kit.Select("key", name), " ", " ")[1:] {
|
||||
switch v {
|
||||
case "text":
|
||||
list = append(list, kit.List(kit.MDB_INPUT, TEXTAREA, kit.MDB_NAME, "text", kit.MDB_VALUE, "@key")...)
|
||||
continue
|
||||
case "page":
|
||||
list = append(list, kit.List(kit.MDB_INPUT, TEXT, kit.MDB_NAME, "limit")...)
|
||||
list = append(list, kit.List(kit.MDB_INPUT, TEXT, kit.MDB_NAME, "offend")...)
|
||||
list = append(list, kit.List(kit.MDB_INPUT, BUTTON, kit.MDB_NAME, "prev")...)
|
||||
list = append(list, kit.List(kit.MDB_INPUT, BUTTON, kit.MDB_NAME, "next")...)
|
||||
continue
|
||||
case "auto":
|
||||
list = append(list, kit.List(kit.MDB_INPUT, BUTTON, kit.MDB_NAME, "查看", kit.MDB_VALUE, "auto")...)
|
||||
list = append(list, kit.List(kit.MDB_INPUT, BUTTON, kit.MDB_NAME, "返回")...)
|
||||
button = true
|
||||
continue
|
||||
}
|
||||
|
||||
ls, value := kit.Split(v, " ", ":=@"), ""
|
||||
item := kit.Dict(kit.MDB_INPUT, kit.Select(TEXT, BUTTON, button))
|
||||
if kit.Value(item, kit.MDB_NAME, ls[0]); item[kit.MDB_INPUT] == TEXT {
|
||||
kit.Value(item, kit.MDB_VALUE, kit.Select("@key", "auto", strings.Contains(name, "auto")))
|
||||
}
|
||||
|
||||
for i := 1; i < len(ls); i += 2 {
|
||||
switch ls[i] {
|
||||
case ":":
|
||||
switch kit.Value(item, kit.MDB_INPUT, ls[i+1]); ls[i+1] {
|
||||
case TEXTAREA:
|
||||
kit.Value(item, "style.width", "360")
|
||||
kit.Value(item, "style.height", "60")
|
||||
case BUTTON:
|
||||
kit.Value(item, kit.MDB_VALUE, "")
|
||||
button = true
|
||||
}
|
||||
case "=":
|
||||
if value = kit.Select("", ls, i+1); len(ls) > i+1 && strings.Contains(ls[i+1], ",") {
|
||||
vs := strings.Split(ls[i+1], ",")
|
||||
kit.Value(item, "values", vs)
|
||||
kit.Value(item, kit.MDB_VALUE, vs[0])
|
||||
kit.Value(item, kit.MDB_INPUT, SELECT)
|
||||
if kit.Value(item, kit.MDB_NAME) == "scale" {
|
||||
kit.Value(item, kit.MDB_VALUE, "week")
|
||||
}
|
||||
} else {
|
||||
kit.Value(item, kit.MDB_VALUE, value)
|
||||
}
|
||||
case "@":
|
||||
if len(ls) > i+1 {
|
||||
if kit.Value(item, kit.MDB_INPUT) == BUTTON {
|
||||
kit.Value(item, "action", ls[i+1])
|
||||
} else {
|
||||
kit.Value(item, kit.MDB_VALUE, "@"+ls[i+1]+"="+value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
list = append(list, item)
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
func (c *Context) Spawn(m *Message, name string, help string, arg ...string) *Context {
|
||||
s := &Context{Name: name, Help: help, Caches: map[string]*Cache{}, Configs: map[string]*Config{}}
|
||||
@ -406,104 +277,6 @@ func (m *Message) Target() *Context {
|
||||
func (m *Message) Source() *Context {
|
||||
return m.source
|
||||
}
|
||||
func (m *Message) Format(key interface{}) string {
|
||||
switch key := key.(type) {
|
||||
case []byte:
|
||||
json.Unmarshal(key, &m.meta)
|
||||
case string:
|
||||
switch key {
|
||||
case "cost":
|
||||
return kit.FmtTime(kit.Int64(time.Since(m.time)))
|
||||
case "meta":
|
||||
return kit.Format(m.meta)
|
||||
case "size":
|
||||
if len(m.meta["append"]) == 0 {
|
||||
return fmt.Sprintf("%dx%d", 0, 0)
|
||||
} else {
|
||||
return fmt.Sprintf("%dx%d", len(m.meta[m.meta["append"][0]]), len(m.meta["append"]))
|
||||
}
|
||||
case "append":
|
||||
if len(m.meta["append"]) == 0 {
|
||||
return fmt.Sprintf("%dx%d %s", 0, 0, "[]")
|
||||
} else {
|
||||
return fmt.Sprintf("%dx%d %s", len(m.meta[m.meta["append"][0]]), len(m.meta["append"]), kit.Format(m.meta["append"]))
|
||||
}
|
||||
|
||||
case "time":
|
||||
return m.Time()
|
||||
case "ship":
|
||||
return fmt.Sprintf("%s->%s", m.source.Name, m.target.Name)
|
||||
case "prefix":
|
||||
return fmt.Sprintf("%s %d %s->%s", m.Time(), m.code, m.source.Name, m.target.Name)
|
||||
|
||||
case "chain":
|
||||
// 调用链
|
||||
ms := []*Message{}
|
||||
for msg := m; msg != nil; msg = msg.message {
|
||||
ms = append(ms, msg)
|
||||
}
|
||||
|
||||
meta := append([]string{}, "\n\n")
|
||||
for i := len(ms) - 1; i >= 0; i-- {
|
||||
msg := ms[i]
|
||||
|
||||
meta = append(meta, fmt.Sprintf("%s ", msg.Format("prefix")))
|
||||
if len(msg.meta[MSG_DETAIL]) > 0 {
|
||||
meta = append(meta, fmt.Sprintf("detail:%d %v", len(msg.meta[MSG_DETAIL]), msg.meta[MSG_DETAIL]))
|
||||
}
|
||||
|
||||
if len(msg.meta[MSG_OPTION]) > 0 {
|
||||
meta = append(meta, fmt.Sprintf("option:%d %v\n", len(msg.meta[MSG_OPTION]), msg.meta[MSG_OPTION]))
|
||||
for _, k := range msg.meta[MSG_OPTION] {
|
||||
if v, ok := msg.meta[k]; ok {
|
||||
meta = append(meta, fmt.Sprintf(" %s: %d %v\n", k, len(v), v))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
meta = append(meta, "\n")
|
||||
}
|
||||
|
||||
if len(msg.meta[MSG_APPEND]) > 0 {
|
||||
meta = append(meta, fmt.Sprintf(" append:%d %v\n", len(msg.meta[MSG_APPEND]), msg.meta[MSG_APPEND]))
|
||||
for _, k := range msg.meta[MSG_APPEND] {
|
||||
if v, ok := msg.meta[k]; ok {
|
||||
meta = append(meta, fmt.Sprintf(" %s: %d %v\n", k, len(v), v))
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(msg.meta[MSG_RESULT]) > 0 {
|
||||
meta = append(meta, fmt.Sprintf(" result:%d %v\n", len(msg.meta[MSG_RESULT]), msg.meta[MSG_RESULT]))
|
||||
}
|
||||
}
|
||||
return strings.Join(meta, "")
|
||||
case "stack":
|
||||
// 调用栈
|
||||
pc := make([]uintptr, 100)
|
||||
pc = pc[:runtime.Callers(5, pc)]
|
||||
frames := runtime.CallersFrames(pc)
|
||||
|
||||
meta := []string{}
|
||||
for {
|
||||
frame, more := frames.Next()
|
||||
file := strings.Split(frame.File, "/")
|
||||
name := strings.Split(frame.Function, "/")
|
||||
meta = append(meta, fmt.Sprintf("\n%s:%d\t%s", file[len(file)-1], frame.Line, name[len(name)-1]))
|
||||
if !more {
|
||||
break
|
||||
}
|
||||
}
|
||||
return strings.Join(meta, "")
|
||||
}
|
||||
}
|
||||
return m.time.Format(MOD_TIME)
|
||||
}
|
||||
func (m *Message) Formats(key string) string {
|
||||
switch key {
|
||||
case "meta":
|
||||
return kit.Formats(m.meta)
|
||||
}
|
||||
return m.Format(key)
|
||||
}
|
||||
func (m *Message) Spawn(arg ...interface{}) *Message {
|
||||
msg := &Message{
|
||||
time: time.Now(),
|
||||
@ -688,83 +461,10 @@ func (m *Message) Cmds(arg ...interface{}) *Message {
|
||||
func (m *Message) Cmd(arg ...interface{}) *Message {
|
||||
return m.cmd(arg...)
|
||||
}
|
||||
func (m *Message) cmd(arg ...interface{}) *Message {
|
||||
opts := map[string]interface{}{}
|
||||
args := []interface{}{}
|
||||
var cbs interface{}
|
||||
|
||||
// 解析参数
|
||||
for _, v := range arg {
|
||||
switch val := v.(type) {
|
||||
case func(int, map[string]string, []string):
|
||||
defer func() { m.Table(val) }()
|
||||
|
||||
case map[string]string:
|
||||
for k, v := range val {
|
||||
opts[k] = v
|
||||
}
|
||||
|
||||
case *Option:
|
||||
opts[val.Name] = val.Value
|
||||
case Option:
|
||||
opts[val.Name] = val.Value
|
||||
|
||||
case *Sort:
|
||||
defer func() { m.Sort(val.Fields, val.Method) }()
|
||||
case Sort:
|
||||
defer func() { m.Sort(val.Fields, val.Method) }()
|
||||
|
||||
default:
|
||||
if reflect.Func == reflect.TypeOf(val).Kind() {
|
||||
cbs = val
|
||||
} else {
|
||||
args = append(args, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 解析命令
|
||||
list := kit.Simple(args...)
|
||||
if len(list) == 0 && !m.Hand {
|
||||
list = m.meta[MSG_DETAIL]
|
||||
}
|
||||
if len(list) == 0 {
|
||||
return m
|
||||
}
|
||||
|
||||
ok := false
|
||||
run := func(msg *Message, ctx *Context, cmd *Command, key string, arg ...string) {
|
||||
if ok = true; cbs != nil {
|
||||
msg.Option(list[0]+".cb", cbs)
|
||||
}
|
||||
for k, v := range opts {
|
||||
msg.Option(k, v)
|
||||
}
|
||||
|
||||
// 执行命令
|
||||
m.TryCatch(msg, true, func(msg *Message) {
|
||||
m = ctx.cmd(msg, cmd, key, arg...)
|
||||
})
|
||||
}
|
||||
|
||||
// 查找命令
|
||||
if cmd, ok := m.target.Commands[list[0]]; ok {
|
||||
run(m.Spawn(), m.target, cmd, list[0], list[1:]...)
|
||||
} else if cmd, ok := m.source.Commands[list[0]]; ok {
|
||||
run(m.Spawn(m.source), m.source, cmd, list[0], list[1:]...)
|
||||
} else {
|
||||
m.Search(list[0], func(p *Context, s *Context, key string, cmd *Command) {
|
||||
run(m.Spawn(s), s, cmd, key, list[1:]...)
|
||||
})
|
||||
}
|
||||
|
||||
// 系统命令
|
||||
if m.Warn(!ok, ErrNotFound, list) {
|
||||
return m.Set(MSG_RESULT).Cmdy("cli.system", list)
|
||||
}
|
||||
return m
|
||||
func (m *Message) Confi(key string, sub string) int {
|
||||
return kit.Int(m.Conf(key, sub))
|
||||
}
|
||||
|
||||
func (m *Message) Confv(arg ...interface{}) (val interface{}) {
|
||||
m.Search(kit.Format(arg[0]), func(p *Context, s *Context, key string, conf *Config) {
|
||||
if len(arg) == 1 {
|
||||
@ -797,6 +497,12 @@ func (m *Message) Confm(key string, chain interface{}, cbs ...interface{}) map[s
|
||||
func (m *Message) Conf(arg ...interface{}) string {
|
||||
return kit.Format(m.Confv(arg...))
|
||||
}
|
||||
func (m *Message) Capi(key string, val ...interface{}) int {
|
||||
if len(val) > 0 {
|
||||
m.Cap(key, kit.Int(m.Cap(key))+kit.Int(val[0]))
|
||||
}
|
||||
return kit.Int(m.Cap(key))
|
||||
}
|
||||
func (m *Message) Capv(arg ...interface{}) interface{} {
|
||||
key := ""
|
||||
switch val := arg[0].(type) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user