1
0
mirror of https://shylinux.com/x/icebergs synced 2025-04-26 09:34:05 +08:00

opt icebergs

This commit is contained in:
shylinux 2021-07-29 08:40:12 +08:00
parent 883441ab68
commit 74359c0048
9 changed files with 447 additions and 794 deletions

View File

@ -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))

View File

@ -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))

View File

@ -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))),

View File

@ -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>", "&gt; ", "</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
View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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>", "&gt; ", "</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
View File

@ -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) {