1
0
mirror of https://shylinux.com/x/icebergs synced 2025-04-25 17:18:05 +08:00

opt input

This commit is contained in:
shylinux 2021-10-14 03:20:26 +08:00
parent b5c6ba7019
commit 431c4064a4
41 changed files with 667 additions and 843 deletions

View File

@ -18,7 +18,7 @@ func _cli_init(m *ice.Message) {
})
// 环境变量
for _, k := range []string{CTX_SELF, CTX_DEV, CTX_SHY, CTX_PID, CTX_USER, CTX_SHARE, CTX_RIVER} {
for _, k := range []string{CTX_SHY, CTX_DEV, CTX_WEB, CTX_PID, CTX_USER, CTX_SHARE, CTX_RIVER} {
m.Conf(RUNTIME, kit.Keys(CONF, k), os.Getenv(k))
}
@ -83,10 +83,11 @@ const (
USERNAME = "username"
)
const (
CTX_SELF = "ctx_self"
CTX_DEV = "ctx_dev"
CTX_SHY = "ctx_shy"
CTX_DEV = "ctx_dev"
CTX_WEB = "ctx_web"
CTX_PID = "ctx_pid"
CTX_LOG = "ctx_log"
CTX_USER = "ctx_user"
CTX_SHARE = "ctx_share"
CTX_RIVER = "ctx_river"

View File

@ -93,7 +93,7 @@ func init() {
SYSTEM: {Name: SYSTEM, Help: "系统命令", Value: kit.Data()},
},
Commands: map[string]*ice.Command{
SYSTEM: {Name: "system cmd= run:button", Help: "系统命令", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
SYSTEM: {Name: "system cmd run:button", Help: "系统命令", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
if len(arg) == 0 {
m.Fields(len(arg), "time,id,cmd")
m.Cmdy(mdb.SELECT, SYSTEM, "", mdb.LIST)

View File

@ -33,7 +33,7 @@ func _command_list(m *ice.Message, name string) {
})
}
func _command_search(m *ice.Message, kind, name, text string) {
ice.Pulse.Travel(func(p *ice.Context, s *ice.Context, key string, cmd *ice.Command) {
m.Travel(func(p *ice.Context, s *ice.Context, key string, cmd *ice.Command) {
if key[0] == '/' || key[0] == '_' {
return // 内部命令
}
@ -41,8 +41,9 @@ func _command_search(m *ice.Message, kind, name, text string) {
return
}
m.PushSearch("cmd", COMMAND, CONTEXT, s.Cap(ice.CTX_FOLLOW), COMMAND, key,
m.PushSearch("cmd", COMMAND,
kit.MDB_TYPE, kind, kit.MDB_NAME, key, kit.MDB_TEXT, s.Cap(ice.CTX_FOLLOW),
CONTEXT, s.Cap(ice.CTX_FOLLOW), COMMAND, key,
)
})
}

View File

@ -116,6 +116,13 @@ func init() {
m.Conf(arg[0], "", "")
m.Cmd("exit", 1)
}},
"list": {Name: "list", Help: "列表", Hand: func(m *ice.Message, arg ...string) {
list := []interface{}{}
for _, v := range arg[2:] {
list = append(list, v)
}
m.Confv(arg[0], arg[1], kit.List(list...))
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 {
_config_list(m)

View File

@ -152,10 +152,10 @@ func HashAction(fields ...string) map[string]*ice.Action {
m.Cmdy(INSERT, m.PrefixKey(), "", HASH, arg)
}},
REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(DELETE, m.PrefixKey(), "", HASH, m.OptionSimple(kit.MDB_HASH))
m.Cmdy(DELETE, m.PrefixKey(), "", HASH, m.OptionSimple(m.Config(kit.MDB_SHORT)))
}},
MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(MODIFY, m.PrefixKey(), "", HASH, m.OptionSimple(kit.MDB_HASH), arg)
m.Cmdy(MODIFY, m.PrefixKey(), "", HASH, m.OptionSimple(m.Config(kit.MDB_SHORT)), arg)
}},
EXPORT: {Name: "export", Help: "导出", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(EXPORT, m.PrefixKey(), "", HASH)
@ -177,3 +177,7 @@ func HashAction(fields ...string) map[string]*ice.Action {
}},
}, fields...)
}
func HashSelect(m *ice.Message, arg ...string) {
m.Fields(len(arg), m.Config(kit.MDB_FIELD))
m.Cmdy(SELECT, m.PrefixKey(), "", HASH, m.Config(kit.MDB_SHORT), arg)
}

View File

@ -136,7 +136,7 @@ func ZoneAction(fields ...string) map[string]*ice.Action {
CREATE: {Name: "create zone", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(INSERT, m.PrefixKey(), "", HASH, arg)
}},
INSERT: {Name: "insert zone= type=go name=hi text=hello", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
INSERT: {Name: "insert zone type=go name=hi text=hello", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(INSERT, m.PrefixKey(), "", HASH, _zone(m), arg[1])
m.Cmdy(INSERT, m.PrefixKey(), "", ZONE, m.Option(_zone(m)), arg[2:])
}},

View File

@ -31,7 +31,7 @@ func _cat_find(m *ice.Message, name string) io.ReadCloser {
return f
}
if b, ok := ice.Info.BinPack[name]; ok {
if b, ok := ice.Info.Pack[name]; ok {
m.Logs("binpack", len(b), name)
return kit.NewReadCloser(bytes.NewBuffer(b))
}

View File

@ -8,6 +8,8 @@ import (
"path"
"strings"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/terminal"
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/aaa"
"shylinux.com/x/icebergs/base/cli"
@ -16,8 +18,6 @@ import (
"shylinux.com/x/icebergs/base/nfs"
"shylinux.com/x/icebergs/base/tcp"
kit "shylinux.com/x/toolkits"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/terminal"
)
func _ssh_open(m *ice.Message, arg ...string) {
@ -166,7 +166,7 @@ func init() {
})
}},
CONNECT: {Name: "connect hash auto dial prunes", Help: "连接", Action: map[string]*ice.Action{
tcp.OPEN: {Name: "open authfile= username=shy password= verfiy= host=shylinux.com port=22 private=.ssh/id_rsa", Help: "终端", Hand: func(m *ice.Message, arg ...string) {
tcp.OPEN: {Name: "open authfile username=shy password verfiy host=shylinux.com port=22 private=.ssh/id_rsa", Help: "终端", Hand: func(m *ice.Message, arg ...string) {
_ssh_open(m.OptionLoad(m.Option("authfile")), arg...)
m.Echo("exit %v:%v\n", m.Option(tcp.HOST), m.Option(tcp.PORT))
}},

View File

@ -185,7 +185,7 @@ func (f *Frame) parse(m *ice.Message, line string) string {
}
if async {
msg.Gos(msg, func(msg *ice.Message) { msg.Cmd(ls[0], ls[1:]) })
msg.Go(func() { msg.Cmd(ls[0], ls[1:]) })
continue
} else {
msg.Cmdy(ls[0], ls[1:])

View File

@ -47,7 +47,7 @@ func _dream_show(m *ice.Message, name string) {
// 任务模板
if m.Option(kit.MDB_TEMPLATE) != "" {
for _, file := range []string{ice.ETC_MISS, ice.SRC_MAIN_SHY, ice.SRC_MAIN_GO, ice.GO_MOD, ice.MAKEFILE} {
for _, file := range []string{ice.ETC_MISS_SH, ice.SRC_MAIN_SHY, ice.SRC_MAIN_GO, ice.GO_MOD, ice.MAKEFILE} {
if _, e := os.Stat(path.Join(p, file)); os.IsNotExist(e) {
switch m.Cmdy(nfs.COPY, path.Join(p, file), path.Join(m.Option(kit.MDB_TEMPLATE), file)); file {
case ice.GO_MOD:
@ -60,7 +60,7 @@ func _dream_show(m *ice.Message, name string) {
}
// 任务脚本
miss := path.Join(p, ice.ETC_MISS)
miss := path.Join(p, ice.ETC_MISS_SH)
if _, e := os.Stat(miss); os.IsNotExist(e) {
m.Cmd(nfs.SAVE, miss, m.Conf(DREAM, kit.Keym("miss")))
}
@ -115,7 +115,7 @@ func init() {
m.ProcessInner()
}},
cli.START: {Name: "start name repos river", Help: "启动", Hand: func(m *ice.Message, arg ...string) {
if m.Option(kit.MDB_NAME) == SPIDE_SELF {
if m.Option(kit.MDB_NAME) == SPIDE_WEB {
m.Option(kit.MDB_NAME, "")
}
_dream_show(m, m.Option(kit.MDB_NAME, kit.Select(path.Base(m.Option(kit.SSH_REPOS)), m.Option(kit.MDB_NAME))))
@ -140,7 +140,7 @@ func init() {
Configs: map[string]*ice.Config{
DREAM: {Name: DREAM, Help: "梦想家", Value: kit.Data(kit.MDB_PATH, ice.USR_LOCAL_WORK,
cli.CMD, []interface{}{"ice.bin", SPACE, tcp.DIAL},
cli.ENV, kit.Dict(ice.CTX_LOG, ice.BIN_BOOTLOG),
cli.ENV, kit.Dict(cli.CTX_LOG, ice.BIN_BOOTLOG),
"miss", `#!/bin/bash
if [ "$ISH_CONF_PRE" = "" ]; then
[ -f $PWD/.ish/plug.sh ] || [ -f $HOME/.ish/plug.sh ] || git clone ${ISH_CONF_HUB_PROXY:="https://"}shylinux.com/x/intshell $PWD/.ish

View File

@ -174,7 +174,7 @@ func _serve_handle(key string, cmd *ice.Command, msg *ice.Message, w http.Respon
// 执行命令
if cmds, ok := _serve_login(msg, kit.Simple(msg.Optionv(ice.MSG_CMDS)), w, r); ok {
msg.Option(ice.MSG_OPTS, msg.Optionv(ice.MSG_OPTION))
msg.Target().Cmd(msg, key, r.URL.Path, cmds...)
msg.Target().Cmd(msg, key, cmds...)
msg.Cost(kit.Format("%s %v %v", r.URL.Path, cmds, msg.Format(ice.MSG_APPEND)))
}
@ -198,7 +198,7 @@ func _serve_login(msg *ice.Message, cmds []string, w http.ResponseWriter, r *htt
if _, ok := msg.Target().Commands[WEB_LOGIN]; ok {
// 权限检查
msg.Target().Cmd(msg, WEB_LOGIN, r.URL.Path, cmds...)
msg.Target().Cmd(msg, WEB_LOGIN, cmds...)
return cmds, msg.Result(0) != ice.ErrWarn && msg.Result() != ice.FALSE
}
@ -268,7 +268,7 @@ func init() {
m.Conf(SERVE, kit.Keys(kit.MDB_META, aaa.WHITE, k), true)
}
}},
cli.START: {Name: "start dev= name=self proto=http host= port=9020", Help: "启动", Hand: func(m *ice.Message, arg ...string) {
cli.START: {Name: "start dev name=web proto=http host port=9020", Help: "启动", Hand: func(m *ice.Message, arg ...string) {
if cli.NodeInfo(m, SERVER, ice.Info.HostName); m.Option(tcp.PORT) == tcp.RANDOM {
m.Option(tcp.PORT, m.Cmdx(tcp.PORT, aaa.RIGHT))
}

View File

@ -289,7 +289,7 @@ func _spide_save(m *ice.Message, cache, save, uri string, res *http.Response) {
const (
SPIDE_SHY = "shy"
SPIDE_DEV = "dev"
SPIDE_SELF = "self"
SPIDE_WEB = "web"
SPIDE_RAW = "raw"
SPIDE_MSG = "msg"

View File

@ -100,8 +100,8 @@ var Index = &ice.Context{Name: WEB, Help: "网络模块", Commands: map[string]*
m.Conf(SPACE, kit.MDB_HASH, "")
m.Cmd(mdb.SEARCH, mdb.CREATE, SPACE, m.Prefix(SPACE))
m.Cmd(SPIDE, mdb.CREATE, SPIDE_WEB, kit.Select("http://:9020", m.Conf(cli.RUNTIME, "conf.ctx_web")))
m.Cmd(SPIDE, mdb.CREATE, SPIDE_DEV, kit.Select("http://:9020", m.Conf(cli.RUNTIME, "conf.ctx_dev")))
m.Cmd(SPIDE, mdb.CREATE, SPIDE_SELF, kit.Select("http://:9020", m.Conf(cli.RUNTIME, "conf.ctx_self")))
m.Cmd(SPIDE, mdb.CREATE, SPIDE_SHY, kit.Select("https://shylinux.com:443", m.Conf(cli.RUNTIME, "conf.ctx_shy")))
}},
ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {

117
cmd.go
View File

@ -1,117 +0,0 @@
package ice
import (
"reflect"
"strings"
kit "shylinux.com/x/toolkits"
)
func ref(obj interface{}) (reflect.Type, reflect.Value) {
t := reflect.TypeOf(obj)
v := reflect.ValueOf(obj)
if t.Kind() == reflect.Ptr {
t, v = t.Elem(), v.Elem()
}
return t, v
}
func val(m *Message, arg ...string) []reflect.Value {
args := []reflect.Value{reflect.ValueOf(m)}
for _, v := range arg {
args = append(args, reflect.ValueOf(v))
}
return args
}
func transMethod(config *Config, command *Command, obj interface{}) {
t, v := ref(obj)
for i := 0; i < v.NumMethod(); i++ {
method := v.Method(i)
var h func(*Message, ...string)
switch method.Interface().(type) {
case func(*Message, ...string):
h = func(m *Message, arg ...string) { method.Call(val(m, arg...)) }
case func(*Message):
h = func(m *Message, arg ...string) { method.Call(val(m)) }
default:
continue
}
if key := strings.ToLower(t.Method(i).Name); key == "list" {
command.Hand = func(m *Message, c *Context, cmd string, arg ...string) { h(m, arg...) }
} else {
if action, ok := command.Action[key]; !ok {
command.Action[key] = &Action{Hand: h}
} else {
action.Hand = h
}
}
}
}
func transField(config *Config, command *Command, obj interface{}) {
t, v := ref(obj)
for i := 0; i < v.NumField(); i++ {
if t.Field(i).Type.Kind() == reflect.Struct {
if v.Field(i).CanInterface() {
transField(config, command, v.Field(i).Interface())
}
}
}
meta := kit.Value(config.Value, kit.MDB_META)
for i := 0; i < v.NumField(); i++ {
key, tag := t.Field(i).Name, t.Field(i).Tag
if data := tag.Get("data"); data != "" {
kit.Value(meta, key, data)
}
if name := tag.Get("name"); name != "" {
if help := tag.Get("help"); key == "list" {
command.Name, command.Help = name, help
config.Name, config.Help = name, help
} else if action, ok := command.Action[key]; ok {
action.Name, action.Help = name, help
}
}
}
}
func Cmd(key string, obj interface{}) {
if obj == nil {
return
}
command := &Command{Action: map[string]*Action{}}
config := &Config{Value: kit.Data()}
transMethod(config, command, obj)
transField(config, command, obj)
last := Index
list := strings.Split(key, ".")
for i := 1; i < len(list); i++ {
has := false
Pulse.Search(strings.Join(list[:i], ".")+".", func(p *Context, s *Context) {
has, last = true, s
})
if !has {
context := &Context{Name: list[i-1]}
last.Register(context, nil)
last = context
}
if i < len(list)-1 {
continue
}
last.Merge(&Context{Commands: map[string]*Command{
CTX_INIT: {Hand: func(m *Message, c *Context, cmd string, arg ...string) {
if action, ok := command.Action["init"]; ok {
action.Hand(m, arg...)
} else {
m.Load()
}
}},
CTX_EXIT: {Hand: func(m *Message, c *Context, cmd string, arg ...string) {
m.Save()
}},
list[i]: command,
}, Configs: map[string]*Config{list[i]: config}})
}
}

108
conf.go
View File

@ -3,6 +3,23 @@ package ice
const (
SP = " "
NL = "\n"
OK = "ok"
TRUE = "true"
FALSE = "false"
SUCCESS = "success"
FAILURE = "failure"
INIT = "init"
EXIT = "exit"
SAVE = "save"
LOAD = "load"
HELP = "help"
ICE = "ice"
SHY = "shy"
DEV = "dev"
WEB = "web"
)
const ( // MOD
MOD_DIR = 0750
@ -21,15 +38,9 @@ const ( // REPOS
INTSHELL = "intshell"
CONTEXTS = "contexts"
INSTALL = "install"
REQUIRE = "require"
INSTALL = "install"
PUBLISH = "publish"
SUCCESS = "success"
FAILURE = "failure"
FALSE = "false"
TRUE = "true"
OK = "ok"
)
const ( // DIR
USR_VOLCANOS = "usr/volcanos"
@ -41,10 +52,10 @@ const ( // DIR
USR_LOCAL = "usr/local"
USR_LOCAL_WORK = "usr/local/work"
USR_LOCAL_RIVER = "usr/local/river"
USR_LOCAL_IMAGE = "usr/local/image"
USR_LOCAL_EXPORT = "usr/local/export"
USR_LOCAL_RIVER = "usr/local/river"
USR_LOCAL_DAEMON = "usr/local/daemon"
USR_LOCAL_EXPORT = "usr/local/export"
FAVICON = "favicon.ico"
PROTO_JS = "proto.js"
@ -54,36 +65,29 @@ const ( // DIR
ORDER_SH = "order.sh"
INDEX_SH = "index.sh"
VAR_TMP = "var/tmp"
VAR_RUN = "var/run"
VAR_TMP = "var/tmp"
VAR_LOG = "var/log"
VAR_CONF = "var/conf"
VAR_DATA = "var/data"
VAR_FILE = "var/file"
VAR_PROXY = "var/proxy"
VAR_TRASH = "var/trash"
BIN_ICE = "bin/ice.sh"
BIN_ICE_SH = "bin/ice.sh"
BIN_ICE_BIN = "bin/ice.bin"
BIN_BOOTLOG = "bin/boot.log"
ETC_INIT = "etc/init.shy"
ETC_EXIT = "etc/exit.shy"
ETC_MISS = "etc/miss.sh"
ETC_INIT_SHY = "etc/init.shy"
ETC_EXIT_SHY = "etc/exit.shy"
ETC_MISS_SH = "etc/miss.sh"
SRC_HELP = "src/help"
SRC_MAIN_SHY = "src/main.shy"
SRC_MAIN_GO = "src/main.go"
SRC_VERSION = "src/version.go"
SRC_BINPACK = "src/binpack.go"
SRC_VERSION_GO = "src/version.go"
SRC_BINPACK_GO = "src/binpack.go"
MAKEFILE = "makefile"
GO_MOD = "go.mod"
GO_SUM = "go.sum"
CTX_DEBUG = "ctx_debug"
CTX_DEV = "ctx_dev"
CTX_PID = "ctx_pid"
CTX_LOG = "ctx_log"
)
const ( // MSG
MSG_DETAIL = "detail"
@ -124,12 +128,18 @@ const ( // MSG
MSG_USERNAME = "user.name"
MSG_USERZONE = "user.zone"
MSG_USERROLE = "user.role"
MSG_LANGUAGE = "user.lang"
MSG_TITLE = "sess.title"
MSG_RIVER = "sess.river"
MSG_STORM = "sess.storm"
MSG_LOCAL = "sess.local"
MSG_TOAST = "sess.toast"
CACHE_LIMIT = "cache.limit"
CACHE_BEGIN = "cache.begin"
CACHE_COUNT = "cache.count"
CACHE_OFFEND = "cache.offend"
)
const ( // RENDER
RENDER_RAW = "_raw"
@ -137,40 +147,51 @@ const ( // RENDER
RENDER_RESULT = "_result"
RENDER_ANCHOR = "_anchor"
RENDER_BUTTON = "_button"
RENDER_SCRIPT = "_script"
RENDER_QRCODE = "_qrcode"
RENDER_IMAGES = "_images"
RENDER_VIDEOS = "_videos"
RENDER_QRCODE = "_qrcode"
RENDER_SCRIPT = "_script"
RENDER_TEMPLATE = "_template"
RENDER_DOWNLOAD = "_download"
RENDER_REDIRECT = "_redirect"
)
const ( // PROCESS
PROCESS_LOCATION = "_location"
PROCESS_REFRESH = "_refresh"
PROCESS_REWRITE = "_rewrite"
PROCESS_REFRESH = "_refresh"
PROCESS_DISPLAY = "_display"
PROCESS_FIELD = "_field"
PROCESS_INNER = "_inner"
PROCESS_AGAIN = "_again"
PROCESS_OPEN = "_open"
PROCESS_HOLD = "_hold"
PROCESS_BACK = "_back"
PROCESS_GROW = "_grow"
PROCESS_OPEN = "_open"
FIELD_PREFIX = "_prefix"
)
const ( // Err
ErrWarn = "warn: "
ErrExpire = "expire: "
ErrExists = "exists: "
ErrNotLogin = "not login: "
ErrNotFound = "not found: "
ErrNotRight = "not right: "
)
const ( // LOG
// 数据
LOG_CREATE = "create"
LOG_REMOVE = "remove"
LOG_MODIFY = "modify"
LOG_INSERT = "insert"
LOG_DELETE = "delete"
LOG_SELECT = "select"
LOG_EXPORT = "export"
LOG_IMPORT = "import"
// 通用
LOG_INFO = "info"
LOG_COST = "cost"
LOG_WARN = "warn"
LOG_ERROR = "error"
LOG_DEBUG = "debug"
// 命令
LOG_AUTH = "auth"
LOG_CMDS = "cmds"
LOG_SEND = "send"
LOG_RECV = "recv"
// 状态
LOG_BEGIN = "begin"
@ -178,16 +199,15 @@ const ( // LOG
LOG_SERVE = "serve"
LOG_CLOSE = "close"
// 分类
LOG_CMDS = "cmds"
LOG_AUTH = "auth"
LOG_SEND = "send"
LOG_RECV = "recv"
LOG_COST = "cost"
LOG_INFO = "info"
LOG_WARN = "warn"
LOG_ERROR = "error"
LOG_DEBUG = "debug"
// 数据
LOG_CREATE = "create"
LOG_REMOVE = "remove"
LOG_INSERT = "insert"
LOG_DELETE = "delete"
LOG_MODIFY = "modify"
LOG_SELECT = "select"
LOG_EXPORT = "export"
LOG_IMPORT = "import"
)
const ( // CTX
CTX_FOLLOW = "follow"

View File

@ -1,6 +1,8 @@
package chat
import (
"strings"
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/aaa"
"shylinux.com/x/icebergs/base/ctx"
@ -27,6 +29,7 @@ func _header_check(m *ice.Message, arg ...string) {
if m.Option(ice.MSG_USERNAME) == "" { // 单点登录
m.Option(web.SSO, m.Conf(web.SERVE, kit.Keym(web.SSO)))
m.Option(web.LOGIN, m.Config(web.LOGIN))
}
}
func _header_share(m *ice.Message, arg ...string) {
@ -36,6 +39,8 @@ func _header_share(m *ice.Message, arg ...string) {
m.Option(kit.MDB_LINK, tcp.ReplaceLocalhost(m, m.Option(kit.MDB_LINK)))
}
m.Option(kit.MDB_LINK, strings.Split(m.Option(kit.MDB_LINK), "?")[0])
m.Set(kit.MDB_NAME, kit.MDB_TEXT)
m.Push(kit.MDB_NAME, m.Option(kit.MDB_LINK))
m.PushQRCode(kit.MDB_TEXT, m.Option(kit.MDB_LINK))
@ -63,6 +68,7 @@ const (
CHECK = "check"
SHARE = "share"
GRANT = "grant"
LOGIN = "login"
)
const HEADER = "header"
@ -70,6 +76,7 @@ func init() {
Index.Merge(&ice.Context{Configs: map[string]*ice.Config{
HEADER: {Name: HEADER, Help: "标题栏", Value: kit.Data(
TITLE, "shylinux.com/x/contexts", MENUS, `["header", ["setting", "black", "white", "print", "webpack", "unpack"]]`,
LOGIN, kit.List("登录", "扫码"),
)},
}, Commands: map[string]*ice.Command{
"/header": {Name: "/header", Help: "标题栏", Action: map[string]*ice.Action{

View File

@ -100,7 +100,7 @@ func _autogen_version(m *ice.Message) {
m.Cmdy(cli.SYSTEM, "go", "mod", "init", path.Base(kit.Path("")))
}
file := ice.SRC_VERSION
file := ice.SRC_VERSION_GO
m.Cmd(nfs.SAVE, file, kit.Format(`package main
import (
@ -127,14 +127,14 @@ func init() {
defer m.Cmdy(nfs.CAT, file)
m.Cmdy(nfs.DIR, file, "time,size,line,path")
m.Cmdy(nfs.DIR, ice.SRC_BINPACK, "time,size,line,path")
m.Cmdy(nfs.DIR, ice.SRC_BINPACK_GO, "time,size,line,path")
m.Cmdy(nfs.DIR, ice.SRC_MAIN_GO, "time,size,line,path")
}
func _autogen_miss(m *ice.Message) {
m.Cmd(nfs.DEFS, ice.ETC_MISS, m.Conf(web.DREAM, kit.Keym("miss")))
defer m.Cmdy(nfs.CAT, ice.ETC_MISS)
m.Cmd(nfs.DEFS, ice.ETC_MISS_SH, m.Conf(web.DREAM, kit.Keym("miss")))
defer m.Cmdy(nfs.CAT, ice.ETC_MISS_SH)
m.Cmdy(nfs.DIR, ice.ETC_MISS, "time,size,line,path")
m.Cmdy(nfs.DIR, ice.ETC_MISS_SH, "time,size,line,path")
m.Cmdy(nfs.DIR, ice.GO_MOD, "time,size,line,path")
m.Cmdy(nfs.DIR, ice.GO_SUM, "time,size,line,path")
}
@ -144,7 +144,7 @@ const AUTOGEN = "autogen"
func init() {
Index.Merge(&ice.Context{Commands: map[string]*ice.Command{
AUTOGEN: {Name: "autogen path auto create binpack script", Help: "生成", Action: map[string]*ice.Action{
mdb.CREATE: {Name: "create main=src/main.go@key key= zone= type=Zone,Hash,Data name=hi list= help=", Help: "模块", Hand: func(m *ice.Message, arg ...string) {
mdb.CREATE: {Name: "create main=src/main.go@key key zone type=Zone,Hash,Data name=hi list help", Help: "模块", Hand: func(m *ice.Message, arg ...string) {
_defs(m, "zone", m.Option("name"), "help", m.Option("name"))
_defs(m, "key", kit.Keys("web.code", m.Option("zone"), m.Option("name")))
switch m.Option("type") {

View File

@ -82,7 +82,7 @@ func init() {
Index.Merge(&ice.Context{Commands: map[string]*ice.Command{
BINPACK: {Name: "binpack path auto create remove export", Help: "打包", Action: map[string]*ice.Action{
mdb.CREATE: {Name: "create", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
if pack, p, e := kit.Create(ice.SRC_BINPACK); m.Assert(e) {
if pack, p, e := kit.Create(ice.SRC_BINPACK_GO); m.Assert(e) {
defer pack.Close()
_pack_write(pack, `package main`)
@ -93,7 +93,7 @@ func init() {
_pack_write(pack, "")
_pack_write(pack, `func init() {`)
_pack_write(pack, ` ice.Info.BinPack = map[string][]byte{`)
_pack_write(pack, ` ice.Info.Pack = map[string][]byte{`)
_pack_volcanos(m, pack, ice.USR_VOLCANOS)
_pack_dir(m, pack, ice.USR_LEARNING)
@ -108,10 +108,10 @@ func init() {
}
}},
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
ice.Info.BinPack = map[string][]byte{}
ice.Info.Pack = map[string][]byte{}
}},
mdb.EXPORT: {Name: "export", Help: "导出", Hand: func(m *ice.Message, arg ...string) {
for key, value := range ice.Info.BinPack {
for key, value := range ice.Info.Pack {
if strings.HasPrefix(key, "/") {
key = ice.USR_VOLCANOS + key
}
@ -120,7 +120,7 @@ func init() {
}
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
for k, v := range ice.Info.BinPack {
for k, v := range ice.Info.Pack {
m.Push(kit.MDB_NAME, k)
m.Push(kit.MDB_SIZE, len(v))
}

View File

@ -110,18 +110,7 @@ func init() {
}
for _, i := range []string{"1", "2", "3", "8"} {
if text := _c_help(m, i, kit.Select(kit.MDB_MAIN, arg, 1)); text != "" {
for _, k := range kit.Split(m.Option(mdb.FIELDS)) {
switch k {
case kit.MDB_FILE:
m.Push(k, kit.Keys(arg[1], MAN+i))
case kit.MDB_LINE:
m.Push(k, 1)
case kit.MDB_TEXT:
m.Push(k, text)
default:
m.Push(k, "")
}
}
m.PushSearch(cli.CMD, "c", kit.MDB_FILE, kit.Keys(arg[1], MAN+i), kit.MDB_LINE, 1, kit.MDB_TEXT, text)
}
}
}},

View File

@ -59,7 +59,7 @@ func init() {
// 编译参数
m.Optionv(cli.CMD_ENV, kit.Simple(m.Confv(COMPILE, kit.Keym(cli.ENV)), "GOARCH", arch, "GOOS", goos))
if msg := m.Cmd(cli.SYSTEM, m.Confv(COMPILE, kit.Keym(GO)),
"-o", file, main, ice.SRC_VERSION, ice.SRC_BINPACK); msg.Append(cli.CMD_CODE) != "0" {
"-o", file, main, ice.SRC_VERSION_GO, ice.SRC_BINPACK_GO); msg.Append(cli.CMD_CODE) != "0" {
m.Copy(msg)
return
}

View File

@ -56,7 +56,7 @@ func init() {
ice.VOLCANOS: {Name: "volcanos", Help: "火山架", Hand: func(m *ice.Message, arg ...string) {
defer func() { m.EchoQRCode(m.Option(ice.MSG_USERWEB)) }()
defer func() { m.Cmdy(PUBLISH, ice.CONTEXTS, "miss") }()
m.Cmd(PUBLISH, mdb.CREATE, kit.MDB_FILE, ice.ETC_MISS)
m.Cmd(PUBLISH, mdb.CREATE, kit.MDB_FILE, ice.ETC_MISS_SH)
m.Cmd(PUBLISH, mdb.CREATE, kit.MDB_FILE, ice.GO_MOD)
m.Cmd(nfs.DEFS, path.Join(m.Conf(PUBLISH, kit.META_PATH), ice.ORDER_JS), m.Conf(PUBLISH, kit.Keym(JS)))

View File

@ -16,7 +16,7 @@ func init() {
Configs: map[string]*ice.Config{
UPGRADE: {Name: UPGRADE, Help: "升级", Value: kit.Dict(kit.MDB_HASH, kit.Dict(
cli.SYSTEM, kit.Dict(kit.MDB_LIST, kit.List(
kit.MDB_INPUT, "bin", kit.MDB_FILE, "ice.sh", kit.MDB_PATH, ice.BIN_ICE,
kit.MDB_INPUT, "bin", kit.MDB_FILE, "ice.sh", kit.MDB_PATH, ice.BIN_ICE_SH,
kit.MDB_INPUT, "bin", kit.MDB_FILE, "ice.bin", kit.MDB_PATH, ice.BIN_ICE_BIN,
)),
cli.SOURCE, kit.Dict(kit.MDB_LIST, kit.List(

View File

@ -33,7 +33,7 @@ func init() {
nfs.SAVE: {Name: "save type file path", Help: "保存", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(nfs.SAVE, path.Join(m.Option(kit.MDB_PATH), m.Option(kit.MDB_FILE)))
}},
AUTOGEN: {Name: "create main=src/main.go@key key= zone= type=Zone,Hash,Data name=hi list= help=", Help: "模块", Hand: func(m *ice.Message, arg ...string) {
AUTOGEN: {Name: "create main=src/main.go@key key zone type=Zone,Hash,Data name=hi list help", Help: "模块", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(AUTOGEN, mdb.CREATE, arg)
}},
COMPILE: {Name: "compile", Help: "编译", Hand: func(m *ice.Message, arg ...string) {

View File

@ -35,7 +35,7 @@ const PLAN = "plan"
func init() {
Index.Merge(&ice.Context{
Commands: map[string]*ice.Command{
PLAN: {Name: "plan scale=day,week,month,year,long begin_time@date auto insert export import", Help: "计划", Meta: kit.Dict(
PLAN: {Name: "plan scale=week,day,week,month,year,long begin_time@date auto insert export import", Help: "计划", Meta: kit.Dict(
ice.Display("/plugin/local/team/plan.js", PLAN),
), Action: map[string]*ice.Action{
mdb.INSERT: {Name: "insert zone type=once,step,week name text begin_time@date close_time@date", Help: "添加", Hand: func(m *ice.Message, arg ...string) {

29
data.go
View File

@ -8,11 +8,17 @@ import (
"shylinux.com/x/toolkits/miss"
)
func (m *Message) PrefixKey(arg ...string) string {
return kit.Keys(m.Cap(CTX_FOLLOW), strings.TrimPrefix(m._key, "/"), arg)
}
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) Config(key string) string {
return m.Conf(m.PrefixKey(), kit.Keym(key))
}
func (m *Message) ConfigSimple(key string) []string {
return []string{key, m.Conf(m.PrefixKey(), kit.Keym(key))}
}
func (m *Message) Save(arg ...string) *Message {
if len(arg) == 0 {
@ -24,7 +30,7 @@ func (m *Message) Save(arg ...string) *Message {
for _, k := range arg {
list = append(list, m.Prefix(k))
}
m.Cmd("ctx.config", "save", m.Prefix("json"), list)
m.Cmd("ctx.config", SAVE, m.Prefix("json"), list)
return m
}
func (m *Message) Load(arg ...string) *Message {
@ -32,7 +38,7 @@ func (m *Message) Load(arg ...string) *Message {
for _, k := range arg {
list = append(list, m.Prefix(k))
}
m.Cmd("ctx.config", "load", m.Prefix("json"), list)
m.Cmd("ctx.config", LOAD, m.Prefix("json"), list)
return m
}
@ -48,6 +54,7 @@ func (m *Message) Richs(prefix string, chain interface{}, raw interface{}, cb in
wg := &sync.WaitGroup{}
defer wg.Wait()
res = miss.Richs(kit.Keys(prefix, chain), cache, raw, func(key string, value map[string]interface{}) {
wg.Add(1)
@ -84,18 +91,18 @@ func (m *Message) Grows(prefix string, chain interface{}, match string, value st
return nil
}
limit := kit.Int(m.Option("cache.limit"))
if begin := kit.Int(m.Option("cache.begin")); begin != 0 && limit > 0 {
count := kit.Int(m.Option("cache.count", kit.Int(kit.Value(cache, kit.Keym("count")))))
limit := kit.Int(m.Option(CACHE_LIMIT))
if begin := kit.Int(m.Option(CACHE_BEGIN)); begin != 0 && limit > 0 {
count := kit.Int(m.Option(CACHE_COUNT, kit.Int(kit.Value(cache, kit.Keym(kit.MDB_COUNT)))))
if begin > 0 {
m.Option("cache.offend", count-begin-limit)
m.Option(CACHE_OFFEND, count-begin-limit)
} else {
m.Option("cache.offend", -begin-limit)
m.Option(CACHE_OFFEND, -begin-limit)
}
}
return miss.Grows(kit.Keys(prefix, chain), cache,
kit.Int(kit.Select("0", strings.TrimPrefix(m.Option("cache.offend"), "-"))),
kit.Int(kit.Select("10", m.Option("cache.limit"))),
kit.Int(kit.Select("0", strings.TrimPrefix(m.Option(CACHE_OFFEND), "-"))),
kit.Int(kit.Select("10", m.Option(CACHE_LIMIT))),
match, value, cb)
}

37
exec.go
View File

@ -2,7 +2,6 @@ package ice
import (
"errors"
"fmt"
"io"
"strings"
"time"
@ -36,22 +35,22 @@ func (m *Message) TryCatch(msg *Message, silent bool, hand ...func(msg *Message)
}
return m
}
func (m *Message) Assert(arg interface{}) bool {
switch arg := arg.(type) {
func (m *Message) Assert(expr interface{}) bool {
switch expr := expr.(type) {
case nil:
return true
case error:
panic(expr)
case bool:
if arg == true {
if expr == true {
return true
}
case error:
panic(arg)
}
panic(errors.New(fmt.Sprintf("error: %v", arg)))
panic(errors.New(kit.Format("error: %v", expr)))
}
func (m *Message) Sleep(arg string) *Message {
m.Debug("sleep %s %s", arg, kit.FileLine(2, 3))
time.Sleep(kit.Duration(arg))
func (m *Message) Sleep(d string) *Message {
m.Debug("sleep %s %s", d, kit.FileLine(2, 3))
time.Sleep(kit.Duration(d))
return m
}
func (m *Message) Hold(n int) *Message {
@ -77,15 +76,16 @@ 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"))
t := time.AfterFunc(kit.Duration(p), func() {
m.Warn(true, "%s timeout %v", p, m.Detailv())
wait <- false
m.Back(nil)
})
m.cb = func(sub *Message) *Message {
if sync {
wait <- true
@ -109,26 +109,19 @@ func (m *Message) Back(res *Message) *Message {
}
return m
}
func (m *Message) Gos(msg *Message, cb interface{}, args ...interface{}) *Message {
func (m *Message) Go(cb interface{}, args ...interface{}) *Message {
task.Put(kit.FileLine(3, 3), func(task *task.Task) error {
msg.TryCatch(msg, true, func(msg *Message) {
m.TryCatch(m, true, func(m *Message) {
switch cb := cb.(type) {
case func(*Message):
cb(msg)
cb(m.Spawn())
case func():
cb()
}
})
return nil
})
return msg
}
func (m *Message) Go(cb interface{}, args ...interface{}) *Message {
switch cb := cb.(type) {
case func(*Message):
return m.Gos(m.Spawn(), cb, args...)
}
return m.Gos(m, cb, args...)
return m
}
func (m *Message) Watch(key string, arg ...string) *Message {

2
go.mod
View File

@ -7,5 +7,5 @@ require (
github.com/kr/pty v1.1.8
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
shylinux.com/x/toolkits v0.3.3
shylinux.com/x/toolkits v0.3.4
)

2
go.sum
View File

@ -15,7 +15,5 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
shylinux.com/x/toolkits v0.3.0 h1:rF9SIE02VCfgpuI2P/H7EoJaWpf+zomxAaRHiYD7yjE=
shylinux.com/x/toolkits v0.3.0/go.mod h1:8LbYHe7oxBIqb6s4MSOD+4d28QvPdvkyCVtwB/JW7AA=
shylinux.com/x/toolkits v0.3.3 h1:yNH54CANAv7cPT264tpnDt9G2BVfGwLC9y3rxtU6pkg=
shylinux.com/x/toolkits v0.3.3/go.mod h1:8LbYHe7oxBIqb6s4MSOD+4d28QvPdvkyCVtwB/JW7AA=

144
init.go
View File

@ -1,7 +1,6 @@
package ice
import (
"io"
"os"
"strings"
"sync"
@ -11,8 +10,7 @@ import (
)
type Frame struct {
code int
wait chan bool
wait chan int
}
func (f *Frame) Spawn(m *Message, c *Context, arg ...string) Server {
@ -36,10 +34,10 @@ func (f *Frame) Start(m *Message, arg ...string) bool {
m.Log(LOG_START, "ice")
defer m.Cost("start ice")
m.Cap(CTX_STATUS, "start")
m.Cap(CTX_STATUS, CTX_START)
m.Cap(CTX_STREAM, strings.Split(m.Time(), " ")[1])
m.Cmdy("init", arg)
m.Cmdy(INIT, arg)
return true
}
func (f *Frame) Close(m *Message, arg ...string) bool {
@ -60,52 +58,35 @@ func (f *Frame) Close(m *Message, arg ...string) bool {
return true
}
var Index = &Context{Name: "ice", Help: "冰山模块",
Caches: map[string]*Cache{
CTX_FOLLOW: {Value: "ice"},
CTX_STREAM: {Value: "shy"},
CTX_STATUS: {Value: "begin"},
},
Configs: map[string]*Config{
"help": {Value: map[string]interface{}{
"index": []interface{}{
"^_^ 欢迎使用冰山框架 ^_^",
"^_^ Welcome to Icebergs World ^_^",
"",
"report: shylinuxc@gmail.com",
"server: https://shylinux.com",
"source: https://shylinux.com/x/icebergs",
"",
},
}},
},
Commands: map[string]*Command{
var Index = &Context{Name: "ice", Help: "冰山模块", Caches: map[string]*Cache{
CTX_FOLLOW: {Value: "ice"}, CTX_STREAM: {Value: "shy"}, CTX_STATUS: {Value: CTX_BEGIN},
}, Configs: map[string]*Config{
HELP: {Value: kit.Data("index", _help)},
}, Commands: map[string]*Command{
CTX_INIT: {Hand: func(m *Message, c *Context, cmd string, arg ...string) {
defer m.Cost("_init ice")
m.Travel(func(p *Context, c *Context) {
defer m.Cost(CTX_INIT)
m.root.Travel(func(p *Context, c *Context) {
if cmd, ok := c.Commands[CTX_INIT]; ok && p != nil {
c.cmd(m.Spawn(c), cmd, CTX_INIT, arg...)
}
})
}},
"init": {Name: "init", Help: "启动", Hand: func(m *Message, c *Context, cmd string, arg ...string) {
if m.target != m.target.root {
return
}
m.root.Cmd(CTX_INIT)
m.target.root.wg = &sync.WaitGroup{}
for _, k := range kit.Split(kit.Select("gdb,log,ssh,mdb")) {
m.Start(k)
}
m.Cmd("ssh.source", ETC_INIT, "init.shy", "启动配置")
}},
INIT: {Name: "init", Help: "启动", Hand: func(m *Message, c *Context, cmd string, arg ...string) {
m.root.Cmd(CTX_INIT)
m.Cmd("ssh.source", ETC_INIT_SHY, "init.shy", "启动配置")
m.Cmdy(arg)
}},
"help": {Name: "help", Help: "帮助", Hand: func(m *Message, c *Context, cmd string, arg ...string) {
m.Echo(strings.Join(kit.Simple(m.Confv("help", "index")), "\n"))
HELP: {Name: "help", Help: "帮助", Hand: func(m *Message, c *Context, cmd string, arg ...string) {
m.Echo(m.Config("index"))
}},
"exit": {Name: "exit restart:button", Help: "结束", Hand: func(m *Message, c *Context, cmd string, arg ...string) {
m.root.target.server.(*Frame).code = kit.Int(kit.Select("0", arg, 0))
m.Cmd("ssh.source", ETC_EXIT, "exit.shy", "退出配置")
EXIT: {Name: "exit", Help: "结束", Hand: func(m *Message, c *Context, cmd string, arg ...string) {
m.root.Option(EXIT, kit.Select("0", arg, 0))
m.Cmd("ssh.source", ETC_EXIT_SHY, "exit.shy", "退出配置")
m.root.Cmd(CTX_EXIT)
}},
CTX_EXIT: {Hand: func(m *Message, c *Context, cmd string, arg ...string) {
@ -117,11 +98,10 @@ var Index = &Context{Name: "ice", Help: "冰山模块",
})
}
})
f := c.server.(*Frame)
f.wait <- true
c.server.(*Frame).wait <- kit.Int(m.root.Option(EXIT))
}},
},
}
}}
var Pulse = &Message{
time: time.Now(), code: 0,
meta: map[string][]string{},
@ -129,87 +109,30 @@ var Pulse = &Message{
source: Index, target: Index, Hand: true,
}
var Info = struct {
HostName string
PathName string
UserName string
PassWord string
NodeType string
NodeName string
CtxShare string
CtxRiver string
Make struct {
Time string
Hash string
Remote string
Branch string
Version string
HostName string
UserName string
}
BinPack map[string][]byte
names map[string]interface{}
}{
BinPack: map[string][]byte{},
names: map[string]interface{}{},
}
func Dump(w io.Writer, name string, cb func(string)) bool {
for _, key := range []string{name, strings.TrimPrefix(name, USR_VOLCANOS)} {
if b, ok := Info.BinPack[key]; ok {
if cb != nil {
cb(name)
}
w.Write(b)
return true
}
}
return false
}
func Name(name string, value interface{}) string {
if s, ok := Info.names[name]; ok {
last := ""
switch s := s.(type) {
case *Context:
last = s.Name
}
panic(kit.Format("%s %s %v", ErrExists, name, last))
}
Info.names[name] = value
return name
}
func Run(arg ...string) string {
if len(arg) == 0 {
arg = os.Args[1:]
}
if len(arg) == 0 {
arg = append(arg, "help")
arg = append(arg, HELP)
}
frame := &Frame{wait: make(chan bool, 1)}
Index.root = Index
Index.server = frame
frame := &Frame{wait: make(chan int, 1)}
Index.Merge(Index)
Index.server = frame
Index.root = Index
Pulse.root = Pulse
Pulse.Option("name", "")
Pulse.Option("cache.limit", "30")
Pulse.Option("begin_time", Pulse.Time())
switch kit.Select("", arg, 0) {
case "space", "serve":
if _log_disable = false; frame.Begin(Pulse.Spawn(), arg...).Start(Pulse, arg...) {
frame.Close(Pulse.Spawn(), arg...)
}
<-frame.wait
os.Exit(frame.code)
os.Exit(<-frame.wait)
default:
_log_disable = os.Getenv(CTX_DEBUG) != TRUE
if Pulse.Cmdy(arg); Pulse.Result() == "" {
Pulse.Table()
}
@ -221,3 +144,12 @@ func Run(arg ...string) string {
return Pulse.Result()
}
var _help = `
^_^ 欢迎使用冰山框架 ^_^
^_^ Welcome to Icebergs World ^_^
report: shylinuxc@gmail.com
server: https://shylinux.com
source: https://shylinux.com/x/icebergs
`

193
logs.go
View File

@ -1,22 +1,16 @@
package ice
import (
"encoding/json"
"fmt"
"runtime"
"strings"
"time"
kit "shylinux.com/x/toolkits"
log "shylinux.com/x/toolkits/logs"
)
const (
ErrWarn = "warn: "
ErrExists = "exists: "
ErrExpire = "expire: "
ErrNotLogin = "not login: "
ErrNotFound = "not found: "
ErrNotRight = "not right: "
)
var _log_disable = true
var Log func(m *Message, p, l, s string)
@ -27,16 +21,12 @@ func (m *Message) log(level string, str string, arg ...interface{}) *Message {
if str = strings.TrimSpace(kit.Format(str, arg...)); Log != nil {
Log(m, m.Format(kit.MDB_PREFIX), level, str) // 日志分流
}
if m.Option("_disable_log") == TRUE {
return m // 屏蔽日志
}
// 日志颜色
prefix, suffix := "", ""
switch level {
case LOG_IMPORT, LOG_CREATE, LOG_INSERT, LOG_MODIFY, LOG_EXPORT:
prefix, suffix = "\033[36;44m", "\033[0m"
case LOG_CMDS, LOG_START, LOG_SERVE:
prefix, suffix = "\033[32m", "\033[0m"
case LOG_WARN, LOG_CLOSE, LOG_ERROR:
@ -48,7 +38,7 @@ func (m *Message) log(level string, str string, arg ...interface{}) *Message {
// 文件行号
switch level {
case LOG_CMDS, LOG_INFO, "refer", "form":
case "begin":
case LOG_BEGIN:
default:
suffix += " " + kit.FileLine(3, 3)
}
@ -66,19 +56,6 @@ func (m *Message) log(level string, str string, arg ...interface{}) *Message {
fmt.Sprintf("%4s->%-4s", m.source.Name, m.target.Name), prefix, level, str, suffix))
return m
}
func (m *Message) Log(level string, str string, arg ...interface{}) *Message {
return m.log(level, str, arg...)
}
func (m *Message) Info(str string, arg ...interface{}) *Message {
if m == nil {
return m
}
return m.log(LOG_INFO, str, arg...)
}
func (m *Message) Cost(arg ...interface{}) *Message {
list := []string{m.Format("cost"), m.join(arg...)}
return m.log(LOG_COST, strings.Join(list, " "))
}
func (m *Message) join(arg ...interface{}) string {
list := []string{}
for i := 0; i < len(arg); i += 2 {
@ -90,6 +67,17 @@ func (m *Message) join(arg ...interface{}) string {
}
return strings.Join(list, " ")
}
func (m *Message) Log(level string, str string, arg ...interface{}) *Message {
return m.log(level, str, arg...)
}
func (m *Message) Info(str string, arg ...interface{}) *Message {
return m.log(LOG_INFO, str, arg...)
}
func (m *Message) Cost(arg ...interface{}) *Message {
list := []string{m.FormatCost(), m.join(arg...)}
return m.log(LOG_COST, strings.Join(list, " "))
}
func (m *Message) Warn(err bool, arg ...interface{}) bool {
if !err || len(m.meta[MSG_RESULT]) > 0 && m.meta[MSG_RESULT][0] == ErrWarn {
return err
@ -113,43 +101,152 @@ func (m *Message) Debug(str string, arg ...interface{}) {
m.log(LOG_DEBUG, str, arg...)
}
func log_fields(arg ...interface{}) string {
list := []string{}
for i := 0; i < len(arg)-1; i += 2 {
list = append(list, fmt.Sprintf("%v: %v", arg[i], arg[i+1]))
}
return strings.Join(list, " ")
}
func (m *Message) Logs(level string, arg ...interface{}) *Message {
return m.log(level, log_fields(arg...))
return m.log(level, m.join(arg...))
}
func (m *Message) Log_AUTH(arg ...interface{}) *Message {
return m.log(LOG_AUTH, log_fields(arg...))
return m.log(LOG_AUTH, m.join(arg...))
}
func (m *Message) Log_SEND(arg ...interface{}) *Message {
return m.log(LOG_AUTH, log_fields(arg...))
return m.log(LOG_AUTH, m.join(arg...))
}
func (m *Message) Log_CREATE(arg ...interface{}) *Message {
return m.log(LOG_CREATE, log_fields(arg...))
return m.log(LOG_CREATE, m.join(arg...))
}
func (m *Message) Log_REMOVE(arg ...interface{}) *Message {
return m.log(LOG_REMOVE, log_fields(arg...))
return m.log(LOG_REMOVE, m.join(arg...))
}
func (m *Message) Log_INSERT(arg ...interface{}) *Message {
return m.log(LOG_INSERT, log_fields(arg...))
return m.log(LOG_INSERT, m.join(arg...))
}
func (m *Message) Log_DELETE(arg ...interface{}) *Message {
return m.log(LOG_DELETE, log_fields(arg...))
}
func (m *Message) Log_SELECT(arg ...interface{}) *Message {
return m.log(LOG_SELECT, log_fields(arg...))
return m.log(LOG_DELETE, m.join(arg...))
}
func (m *Message) Log_MODIFY(arg ...interface{}) *Message {
return m.log(LOG_MODIFY, log_fields(arg...))
return m.log(LOG_MODIFY, m.join(arg...))
}
func (m *Message) Log_IMPORT(arg ...interface{}) *Message {
return m.log(LOG_IMPORT, log_fields(arg...))
func (m *Message) Log_SELECT(arg ...interface{}) *Message {
return m.log(LOG_SELECT, m.join(arg...))
}
func (m *Message) Log_EXPORT(arg ...interface{}) *Message {
return m.log(LOG_EXPORT, log_fields(arg...))
return m.log(LOG_EXPORT, m.join(arg...))
}
func (m *Message) Log_IMPORT(arg ...interface{}) *Message {
return m.log(LOG_IMPORT, m.join(arg...))
}
func (m *Message) FormatStack() string {
// 调用栈
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, "")
}
func (m *Message) FormatChain() string {
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, "")
}
func (m *Message) FormatTime() string {
return m.Format("time")
}
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) 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":
return m.FormatChain()
case "stack":
return m.FormatStack()
}
}
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)
}

48
meta.go
View File

@ -9,21 +9,6 @@ import (
kit "shylinux.com/x/toolkits"
)
func (m *Message) Add(key string, arg ...string) *Message {
switch key {
case MSG_DETAIL, MSG_RESULT:
m.meta[key] = append(m.meta[key], arg...)
case MSG_OPTION, MSG_APPEND:
if len(arg) > 0 {
if kit.IndexOf(m.meta[key], arg[0]) == -1 {
m.meta[key] = append(m.meta[key], arg[0])
}
m.meta[arg[0]] = append(m.meta[arg[0]], arg[1:]...)
}
}
return m
}
func (m *Message) SetResult(arg ...interface{}) *Message {
m.Set(MSG_RESULT)
if len(arg) > 0 {
@ -69,6 +54,25 @@ func (m *Message) Set(key string, arg ...string) *Message {
}
return m.Add(key, arg...)
}
func (m *Message) Add(key string, arg ...string) *Message {
switch key {
case MSG_DETAIL, MSG_RESULT:
m.meta[key] = append(m.meta[key], arg...)
case MSG_OPTION, MSG_APPEND:
if len(arg) > 0 {
if kit.IndexOf(m.meta[key], arg[0]) == -1 {
m.meta[key] = append(m.meta[key], arg[0])
}
m.meta[arg[0]] = append(m.meta[arg[0]], arg[1:]...)
}
}
return m
}
func (m *Message) Cut(fields ...string) *Message {
m.meta[MSG_APPEND] = kit.Split(kit.Join(fields))
return m
}
func (m *Message) Push(key string, value interface{}, arg ...interface{}) *Message {
switch value := value.(type) {
case map[string]string:
@ -87,14 +91,14 @@ func (m *Message) Push(key string, value interface{}, arg ...interface{}) *Messa
case map[string]interface{}:
// 键值排序
list := []string{}
head := kit.Simple()
if len(arg) > 0 {
list = kit.Simple(arg[0])
head = kit.Simple(arg[0])
} else {
for k := range kit.KeyValue(map[string]interface{}{}, "", value) {
list = append(list, k)
head = append(head, k)
}
sort.Strings(list)
sort.Strings(head)
}
var val map[string]interface{}
@ -102,7 +106,7 @@ func (m *Message) Push(key string, value interface{}, arg ...interface{}) *Messa
val, _ = arg[1].(map[string]interface{})
}
for _, k := range list {
for _, k := range head {
// 查找数据
var v interface{}
switch k {
@ -472,7 +476,3 @@ 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") }

258
misc.go
View File

@ -3,22 +3,14 @@ package ice
import (
"bytes"
"encoding/csv"
"encoding/json"
"fmt"
"net/url"
"path"
"reflect"
"runtime"
"strings"
"time"
kit "shylinux.com/x/toolkits"
)
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)
@ -102,111 +94,17 @@ func (m *Message) Split(str string, field string, space string, enter string) *M
}
return m
}
func (m *Message) FormatStack() string {
// 调用栈
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
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) OptionUserWeb() *url.URL {
return kit.ParseURL(m.Option(MSG_USERWEB))
}
return strings.Join(meta, "")
}
func (m *Message) FormatChain() string {
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, "")
}
func (m *Message) FormatTime() string {
return m.Format("time")
}
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":
return m.FormatChain()
case "stack":
return m.FormatStack()
}
}
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) SetAppend(key ...string) {
m.Set(MSG_APPEND, key...)
}
func (m *Message) RenameAppend(from, to string) {
for i, v := range m.meta[MSG_APPEND] {
@ -217,6 +115,22 @@ func (m *Message) RenameAppend(from, to string) {
}
}
}
func (m *Message) AppendSimple(key ...string) (res []string) {
if len(key) == 0 {
key = append(key, m.Appendv(MSG_APPEND)...)
}
for _, k := range key {
res = append(res, k, m.Append(k))
}
return
}
func (m *Message) AppendTrans(cb func(value string, key string, index int) string) {
for _, k := range m.meta[MSG_APPEND] {
for i, v := range m.meta[k] {
m.meta[k][i] = cb(v, k, i)
}
}
}
func (m *Message) cmd(arg ...interface{}) *Message {
opts := map[string]interface{}{}
@ -362,74 +276,58 @@ func (c *Context) _cmd(m *Message, cmd *Command, key string, k string, h *Action
}
return m
}
func (c *Context) split(key string, cmd *Command, name string) []interface{} {
func (c *Context) split(name string) (list []interface{}) {
const (
BUTTON = "button"
SELECT = "select"
TEXT = "text"
TEXTAREA = "textarea"
SELECT = "select"
BUTTON = "button"
)
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, "list", kit.MDB_VALUE, "auto")...)
list = append(list, kit.List(kit.MDB_INPUT, BUTTON, kit.MDB_NAME, "back")...)
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 {
item, button := kit.Dict(), false
ls := kit.Split(name, " ", ":=@")
for i := 1; i < len(ls); i++ {
switch ls[i] {
case "text":
list = append(list, kit.List(kit.MDB_TYPE, TEXTAREA, kit.MDB_NAME, "text")...)
case "auto":
list = append(list, kit.List(kit.MDB_TYPE, BUTTON, kit.MDB_NAME, "list", kit.MDB_VALUE, "auto")...)
list = append(list, kit.List(kit.MDB_TYPE, BUTTON, kit.MDB_NAME, "back")...)
button = true
case "page":
list = append(list, kit.List(kit.MDB_TYPE, TEXT, kit.MDB_NAME, "limit")...)
list = append(list, kit.List(kit.MDB_TYPE, TEXT, kit.MDB_NAME, "offend")...)
list = append(list, kit.List(kit.MDB_TYPE, BUTTON, kit.MDB_NAME, "prev")...)
list = append(list, kit.List(kit.MDB_TYPE, BUTTON, kit.MDB_NAME, "next")...)
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, "")
if item[kit.MDB_TYPE] = kit.Select("", ls, i+1); item[kit.MDB_TYPE] == BUTTON {
button = true
}
i++
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")
}
if value := kit.Select("", ls, i+1); strings.Contains(value, ",") {
vs := strings.Split(value, ",")
if strings.Count(value, vs[0]) > 1 {
item["values"] = vs[1:]
} else {
kit.Value(item, kit.MDB_VALUE, value)
item["values"] = vs
}
item[kit.MDB_VALUE] = vs[0]
item[kit.MDB_TYPE] = SELECT
} else {
item[kit.MDB_VALUE] = value
}
i++
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)
}
}
}
}
item["action"] = kit.Select("", ls, i+1)
i++
default:
item = kit.Dict(kit.MDB_TYPE, kit.Select(TEXT, BUTTON, button), kit.MDB_NAME, ls[i])
list = append(list, item)
}
}
return list
}
@ -456,36 +354,6 @@ func MergeAction(list ...map[string]*Action) map[string]*Action {
}
return list[0]
}
func (m *Message) AppendSimple(key ...string) (res []string) {
if len(key) == 0 {
key = append(key, m.Appendv(MSG_APPEND)...)
}
for _, k := range key {
res = append(res, k, m.Append(k))
}
return
}
func (m *Message) AppendTrans(cb func(value string, key string, index int) string) {
for _, k := range m.meta[MSG_APPEND] {
for i, v := range m.meta[k] {
m.meta[k][i] = cb(v, k, i)
}
}
}
func (m *Message) OptionUserWeb() *url.URL {
return kit.ParseURL(m.Option(MSG_USERWEB))
}
func (m *Message) Config(key string) string {
return m.Conf(m.PrefixKey(), kit.Keym(key))
}
func (m *Message) ConfigSimple(key string) []string {
return []string{key, m.Conf(m.PrefixKey(), kit.Keym(key))}
}
func SelectAction(list map[string]*Action, fields ...string) map[string]*Action {
if len(fields) == 0 {
return list
@ -497,7 +365,3 @@ func SelectAction(list map[string]*Action, fields ...string) map[string]*Action
}
return res
}
func (m *Message) SetAppend(key ...string) {
m.Set(MSG_APPEND, key...)
}

View File

@ -30,7 +30,7 @@ func init() {
}},
}},
TRASH: {Name: "TRASH hash path auto prunes", Help: "回收站", Action: map[string]*ice.Action{
mdb.INSERT: {Name: "insert from= to=", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
mdb.INSERT: {Name: "insert from to", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.INSERT, m.Prefix(TRASH), "", mdb.HASH, m.OptionSimple(aaa.USERNAME, tcp.HOSTNAME, kit.MDB_SIZE, FROM, TO))
}},
mdb.REVERT: {Name: "revert", Help: "恢复", Hand: func(m *ice.Message, arg ...string) {

View File

@ -21,7 +21,7 @@ func init() {
mdb.CREATE: {Name: "create zone", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.INSERT, m.Prefix(FAVOR), "", mdb.HASH, arg)
}},
mdb.INSERT: {Name: "insert zone=数据结构 type= name=hi text=hello", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
mdb.INSERT: {Name: "insert zone=数据结构 type name=hi text=hello", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.INSERT, m.Prefix(FAVOR), "", mdb.HASH, m.OptionSimple(kit.MDB_ZONE))
m.Cmdy(mdb.INSERT, m.Prefix(FAVOR), kit.KeyHash(m.Option(kit.MDB_ZONE)), mdb.LIST, arg)
}},

View File

@ -170,7 +170,7 @@ var Index = &ice.Context{Name: INPUT, Help: "输入法",
mdb.EXPORT: {Name: "export file=usr/wubi-dict/person zone=person", Help: "导出", Hand: func(m *ice.Message, arg ...string) {
// _input_save(m, kit.Select("usr/wubi-dict/person", m.Option("file")), m.Option("zone"))
}},
mdb.IMPORT: {Name: "import file=usr/wubi-dict/person zone=", Help: "导入", Hand: func(m *ice.Message, arg ...string) {
mdb.IMPORT: {Name: "import file=usr/wubi-dict/person zone", Help: "导入", Hand: func(m *ice.Message, arg ...string) {
_input_load(m, kit.Select("usr/wubi-dict/person", m.Option(FILE)), m.Option(ZONE))
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {

View File

@ -61,7 +61,7 @@ func init() {
m.Cmdy(cli.SYSTEM, TMUX, "split-window", "-t", kit.Keys(name, "2"), "-h")
m.Cmd(cli.SYSTEM, TMUX, "send-keys", "-t", kit.Keys(name, "3"), "ish_miss_log", "Enter")
m.Cmd(cli.SYSTEM, TMUX, "send-keys", "-t", kit.Keys(name, "2"), "ish_miss_space dev self")
m.Cmd(cli.SYSTEM, TMUX, "send-keys", "-t", kit.Keys(name, "2"), "ish_miss_space dev web")
m.Cmd(cli.SYSTEM, TMUX, "send-keys", "-t", kit.Keys(name, "1"), "vi etc/miss.sh", "Enter")
m.Cmdy(cli.SYSTEM, TMUX, "link-window", "-s", name, "-t", "miss:")

View File

@ -1,6 +1,14 @@
package wework
import (
"crypto/aes"
"crypto/cipher"
"crypto/sha1"
"encoding/base64"
"encoding/hex"
"sort"
"strings"
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/web"
@ -9,30 +17,44 @@ import (
const BOT = "bot"
type Bot struct {
short string `data:"name"`
field string `data:"time,name,token,ekey,hook"`
func init() {
Index.Merge(&ice.Context{Configs: map[string]*ice.Config{
BOT: {Name: "bot", Help: "机器人", Value: kit.Data(
kit.MDB_SHORT, "name", kit.MDB_FIELD, "time,name,token,ekey,hook",
)},
}, Commands: map[string]*ice.Command{
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Load() }},
ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Save() }},
web.WEB_LOGIN: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
"/bot/": {Name: "/bot", Help: "机器人", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
msg := m.Cmd(BOT, arg[0])
list := []string{msg.Append("token"), m.Option("nonce"), m.Option("timestamp"), m.Option("echostr")}
sort.Strings(list)
res := sha1.Sum([]byte(strings.Join(list, "")))
m.Debug(hex.EncodeToString(res[:]))
create string `name:"list name token ekey hook" help:"创建"`
list string `name:"list name chat text:textarea auto create" help:"机器人"`
}
aeskey, err := base64.StdEncoding.DecodeString(msg.Append("ekey"))
m.Assert(err)
en_msg, err := base64.StdEncoding.DecodeString(m.Option("echostr"))
m.Assert(err)
block, err := aes.NewCipher(aeskey)
m.Assert(err)
mode := cipher.NewCBCDecrypter(block, aeskey[:aes.BlockSize])
mode.CryptBlocks(en_msg, en_msg)
func (b Bot) Create(m *ice.Message, arg ...string) {
m.Cmdy(mdb.INSERT, m.PrefixKey(), "", mdb.HASH, arg)
}
func (b Bot) List(m *ice.Message, arg ...string) {
m.Fields(len(arg), m.Config(kit.MDB_FIELD))
m.Cmdy(mdb.SELECT, m.PrefixKey(), "", mdb.HASH, m.Config(kit.MDB_SHORT), arg)
if len(arg) > 2 {
m.Cmd(web.SPIDE, mdb.CREATE, arg[0], m.Append("hook"))
}},
BOT: {Name: "bot name chat text:textarea auto create", Help: "机器人", Action: ice.MergeAction(map[string]*ice.Action{
mdb.CREATE: {Name: "create name token ekey hook", Help: "创建"},
}, mdb.HashAction()), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if mdb.HashSelect(m, arg...); len(arg) > 2 {
m.SetAppend()
m.Cmd(web.SPIDE, mdb.CREATE, arg[0], m.Append("hook"))
m.Cmdy(web.SPIDE, arg[0], "", kit.Format(kit.Dict(
"chatid", arg[1],
"msgtype", "text", "text", kit.Dict(
"content", arg[2],
),
"chatid", arg[1], "msgtype", "text", "text.content", arg[2],
)))
} else {
m.PushAction(mdb.REMOVE)
}
}},
}})
}
func init() { ice.Cmd("web.chat.wework.bot", Bot{}) }

View File

@ -1 +1,11 @@
package wework
import (
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/web"
"shylinux.com/x/icebergs/core/chat"
)
var Index = &ice.Context{Name: "wework", Help: "企业微信"}
func init() { chat.Index.Register(Index, &web.Frame{}) }

104
option.go
View File

@ -2,7 +2,6 @@ package ice
import (
"encoding/json"
"net/url"
"os"
"path"
"strings"
@ -15,22 +14,24 @@ type Sort struct {
Fields string
Method string
}
type Option struct {
Name string
Value interface{}
}
func OptionHash(str string) Option { return Option{kit.MDB_HASH, str} }
func OptionFields(str ...string) Option { return Option{MSG_FIELDS, strings.Join(str, ",")} }
func (m *Message) OptionFields(str ...string) string {
if len(str) > 0 {
m.Option(MSG_FIELDS, strings.Join(str, ","))
func OptionHash(arg string) Option { return Option{kit.MDB_HASH, arg} }
func OptionFields(arg ...string) Option { return Option{MSG_FIELDS, kit.Join(arg)} }
func (m *Message) OptionFields(arg ...string) string {
if len(arg) > 0 {
m.Option(MSG_FIELDS, kit.Join(arg))
}
return m.Option(MSG_FIELDS)
}
func (m *Message) OptionPage(arg ...string) {
m.Option("cache.offend", kit.Select("0", arg, 1))
m.Option("cache.limit", kit.Select("10", arg, 0))
m.Option(CACHE_LIMIT, kit.Select("10", arg, 0))
m.Option(CACHE_OFFEND, kit.Select("0", arg, 1))
}
func (m *Message) OptionLoad(file string) *Message {
if f, e := os.Open(file); e == nil {
@ -43,14 +44,14 @@ func (m *Message) OptionLoad(file string) *Message {
}
return m
}
func (m *Message) OptionSplit(fields ...string) (res []string) {
for _, k := range strings.Split(strings.Join(fields, ","), ",") {
func (m *Message) OptionSplit(key ...string) (res []string) {
for _, k := range kit.Split(kit.Join(key)) {
res = append(res, m.Option(k))
}
return res
}
func (m *Message) OptionSimple(key ...string) (res []string) {
for _, k := range strings.Split(strings.Join(key, ","), ",") {
for _, k := range kit.Split(kit.Join(key)) {
if k == "" || m.Option(k) == "" {
continue
}
@ -96,26 +97,24 @@ func (m *Message) Action(arg ...string) {
m.Option(MSG_ACTION, kit.Format(arg))
}
func (m *Message) Status(arg ...interface{}) {
list := kit.List()
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],
})
list = append(list, kit.Dict(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())
m.Status(kit.MDB_TIME, m.Time(), arg, kit.MDB_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())
m.Status(kit.MDB_TIME, m.Time(), kit.MDB_COUNT, m.FormatSize(), arg, kit.MDB_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())
m.Status(kit.MDB_TIME, m.Time(), kit.MDB_COUNT, m.FormatSize(), kit.MDB_TOTAL, arg, kit.MDB_COST, m.FormatCost())
}
func (m *Message) Toast(content string, arg ...interface{}) {
func (m *Message) Toast(text string, arg ...interface{}) { // [title [duration]]
if len(arg) > 1 {
switch val := arg[1].(type) {
case string:
@ -126,9 +125,9 @@ func (m *Message) Toast(content string, arg ...interface{}) {
}
if m.Option(MSG_USERPOD) == "" {
m.Cmd("web.space", m.Option(MSG_DAEMON), "toast", "", content, arg)
m.Cmd("web.space", m.Option(MSG_DAEMON), "toast", "", text, arg)
} else {
m.Option(MSG_TOAST, kit.Simple(content, arg))
m.Option(MSG_TOAST, kit.Simple(text, arg))
}
}
func (m *Message) GoToast(title string, cb func(toast func(string, int, int))) {
@ -163,6 +162,11 @@ func (m *Message) ProcessRefresh(delay string) {
func (m *Message) ProcessRefresh30ms() { m.ProcessRefresh("30ms") }
func (m *Message) ProcessRefresh300ms() { m.ProcessRefresh("300ms") }
func (m *Message) ProcessRefresh3s() { m.ProcessRefresh("3s") }
func (m *Message) ProcessDisplay(arg ...interface{}) {
m.Process(PROCESS_DISPLAY)
m.Option("_display", arg...)
}
func (m *Message) ProcessCommand(cmd string, val []string, arg ...string) {
if len(arg) > 0 && arg[0] == "run" {
m.Cmdy(cmd, arg[1:])
@ -180,64 +184,8 @@ func (m *Message) ProcessField(arg ...interface{}) {
m.Process(PROCESS_FIELD)
m.Option("_prefix", arg...)
}
func (m *Message) ProcessDisplay(arg ...interface{}) {
m.Process(PROCESS_DISPLAY)
m.Option("_display", arg...)
}
func (m *Message) ProcessInner() { m.Process(PROCESS_INNER) }
func (m *Message) ProcessAgain() { m.Process(PROCESS_AGAIN) }
func (m *Message) ProcessOpen(url string) { m.Process(PROCESS_OPEN, url) }
func (m *Message) ProcessHold() { m.Process(PROCESS_HOLD) }
func (m *Message) ProcessBack() { m.Process(PROCESS_BACK) }
func (m *Message) ProcessOpen(url string) { m.Process(PROCESS_OPEN, url) }
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)
})
}

120
render.go
View File

@ -1,8 +1,8 @@
package ice
import (
"net/url"
"path"
"reflect"
"strings"
kit "shylinux.com/x/toolkits"
@ -28,9 +28,9 @@ func Render(m *Message, cmd string, args ...interface{}) string {
break
}
list := []string{}
for _, k := range kit.Split(kit.Join(arg)) {
for _, k := range kit.Split(strings.ToLower(kit.Join(arg))) {
list = append(list, kit.Format(`<input type="button" name="%s" value="%s">`,
k, kit.Select(k, kit.Value(m._cmd.Meta, kit.Keys("_trans", k)), m.Option("language") != "en")))
k, kit.Select(k, kit.Value(m._cmd.Meta, kit.Keys("_trans", k)), m.Option(MSG_LANGUAGE) != "en")))
}
return kit.Join(list, " ")
@ -45,8 +45,12 @@ func Render(m *Message, cmd string, args ...interface{}) string {
}
return ""
}
func (m *Message) PushRender(key, view, name string, arg ...string) *Message {
return m.Push(key, Render(m, view, name, arg))
func (m *Message) IsCliUA() bool {
if m.Option(MSG_USERUA) == "" || !strings.HasPrefix(m.Option(MSG_USERUA), "Mozilla/5.0") {
return true
}
return false
}
func (m *Message) PushDownload(key string, arg ...interface{}) { // [name] file
if !m.IsCliUA() {
@ -58,59 +62,107 @@ func (m *Message) PushAnchor(arg ...interface{}) { // [name] link
m.Push(kit.MDB_LINK, Render(m, RENDER_ANCHOR, arg...))
}
}
func (m *Message) PushButton(list ...interface{}) {
if m.IsCliUA() {
return
}
for i, item := range list {
if t := reflect.TypeOf(item); t.Kind() == reflect.Func {
list[i] = kit.FuncName(item)
func (m *Message) PushButton(arg ...interface{}) { // name...
if !m.IsCliUA() {
m.Push(kit.MDB_ACTION, Render(m, RENDER_BUTTON, arg...))
}
}
m.Push(kit.MDB_ACTION, Render(m, RENDER_BUTTON, strings.ToLower(kit.Join(kit.Simple(list)))))
func (m *Message) PushScript(arg ...string) { // [type] text...
if !m.IsCliUA() {
m.Push(kit.MDB_SCRIPT, Render(m, RENDER_SCRIPT, arg))
}
func (m *Message) PushScript(arg ...string) *Message { // [type] text...
return m.Push(kit.MDB_SCRIPT, Render(m, RENDER_SCRIPT, 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) PushQRCode(key string, src string, arg ...string) { // key src [size]
if !m.IsCliUA() {
m.Push(key, Render(m, RENDER_QRCODE, src, arg))
}
}
func (m *Message) PushImages(key, src string, arg ...string) { // key src [size]
if !m.IsCliUA() {
m.Push(key, Render(m, RENDER_IMAGES, src, arg))
}
}
func (m *Message) PushVideos(key, src string, arg ...string) { // key src [size]
if !m.IsCliUA() {
m.Push(key, Render(m, RENDER_VIDEOS, src, arg))
}
}
func (m *Message) PushAction(list ...interface{}) {
m.Table(func(index int, value map[string]string, head []string) {
m.PushButton(list...)
})
}
func (m *Message) PushPodCmd(cmd string, arg ...string) {
if strings.Contains(m.OptionFields(), "pod") {
m.Table(func(index int, value map[string]string, head []string) {
m.Push("pod", m.Option(MSG_USERPOD))
})
}
func (m *Message) EchoDownload(arg ...interface{}) { // [name] file
m.Echo(Render(m, RENDER_DOWNLOAD, arg...))
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.OptionFields()) {
switch k {
case "pod":
m.Push(k, "")
// 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 (m *Message) EchoDownload(arg ...interface{}) *Message { // [name] file
return m.Echo(Render(m, RENDER_DOWNLOAD, arg...))
}
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, kit.Join(arg)))
func (m *Message) EchoButton(arg ...interface{}) *Message { // name...
return m.Echo(Render(m, RENDER_BUTTON, arg...))
}
func (m *Message) EchoScript(arg ...string) *Message {
func (m *Message) EchoScript(arg ...string) *Message { // [type] text...
return m.Echo(Render(m, RENDER_SCRIPT, arg))
}
func (m *Message) EchoQRCode(text string, arg ...string) *Message { // text [size]
return m.Echo(Render(m, RENDER_QRCODE, text, arg))
func (m *Message) EchoQRCode(src string, arg ...string) *Message { // src [size]
return m.Echo(Render(m, RENDER_QRCODE, src, arg))
}
func (m *Message) EchoImages(src string, arg ...string) *Message {
func (m *Message) EchoImages(src string, arg ...string) *Message { // src [size]
return m.Echo(Render(m, RENDER_IMAGES, src, arg))
}
func (m *Message) IsCliUA() bool {
if m.Option(MSG_USERUA) == "" || !strings.HasPrefix(m.Option(MSG_USERUA), "Mozilla/5.0") {
return true
}
return false
func (m *Message) EchoVideos(src string, arg ...string) *Message { // src [size]
return m.Echo(Render(m, RENDER_VIDEOS, src, arg))
}
func (m *Message) Render(cmd string, args ...interface{}) *Message {
@ -134,12 +186,12 @@ func (m *Message) RenderResult(args ...interface{}) *Message {
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) RenderDownload(args ...interface{}) *Message {
return m.Render(RENDER_DOWNLOAD, args...)
}
func (m *Message) RenderIndex(serve, repos string, file ...string) *Message {
return m.RenderDownload(path.Join(m.Conf(serve, kit.Keym(repos, kit.SSH_PATH)), kit.Select(m.Conf(serve, kit.Keym(repos, kit.SSH_INDEX)), path.Join(file...))))
}

55
type.go
View File

@ -27,16 +27,22 @@ type Config struct {
type Action struct {
Name string
Help string
List []interface{}
Hand func(m *Message, arg ...string)
List []interface{}
}
type Command struct {
Name string
Help string
List []interface{}
Action map[string]*Action
Meta map[string]interface{}
Hand func(m *Message, c *Context, key string, arg ...string)
Action map[string]*Action
List []interface{}
}
type Server interface {
Spawn(m *Message, c *Context, arg ...string) Server
Begin(m *Message, arg ...string) Server
Start(m *Message, arg ...string) bool
Close(m *Message, arg ...string) bool
}
type Context struct {
Name string
@ -57,12 +63,6 @@ type Context struct {
wg *sync.WaitGroup
id int32
}
type Server interface {
Spawn(m *Message, c *Context, arg ...string) Server
Begin(m *Message, arg ...string) Server
Start(m *Message, arg ...string) bool
Close(m *Message, arg ...string) bool
}
func (c *Context) ID() int32 {
if c == nil {
@ -76,21 +76,21 @@ func (c *Context) Cap(key string, arg ...interface{}) string {
}
return c.Caches[key].Value
}
func (c *Context) Cmd(m *Message, cmd string, key string, arg ...string) *Message {
return c.cmd(m, m.Target().Commands[cmd], cmd, arg...)
func (c *Context) Cmd(m *Message, key string, arg ...string) *Message {
return c.cmd(m, m.target.Commands[key], key, arg...)
}
func (c *Context) Server() Server {
return c.server
}
func (c *Context) Register(s *Context, x Server, name ...string) *Context {
if s.Name == "" {
if s.Merge(s); s.Name == "" {
s.Name = kit.Split(kit.Split(kit.FileLine(2, 3), ":")[0], "/")[1]
}
for _, n := range name {
Name(n, s)
}
s.Merge(s)
if c.contexts == nil {
c.contexts = map[string]*Context{}
@ -123,18 +123,15 @@ func (c *Context) Merge(s *Context) *Context {
}()
}
c.Commands[k] = v
if v.List == nil {
v.List = c.split(k, v, v.Name)
}
if v.Meta == nil {
v.Meta = kit.Dict()
}
if p := kit.Format(v.Meta[kit.MDB_STYLE]); p == "" {
v.Meta[kit.MDB_STYLE] = k
}
if c.Commands[k] = v; v.List == nil {
v.List = c.split(v.Name)
}
for k, a := range v.Action {
help := strings.SplitN(a.Help, "", 2)
@ -149,7 +146,7 @@ func (c *Context) Merge(s *Context) *Context {
continue
}
if a.List == nil {
a.List = c.split(k, nil, a.Name)
a.List = c.split(a.Name)
}
if len(a.List) > 0 {
v.Meta[k] = a.List
@ -252,9 +249,8 @@ func (m *Message) Time(args ...interface{}) string { // [duration] [format [args
t := m.time
if len(args) > 0 {
switch arg := args[0].(type) {
case string:
case string: // 时间偏移
if d, e := time.ParseDuration(arg); e == nil {
// 时间偏移
t, args = t.Add(d), args[1:]
}
}
@ -262,9 +258,8 @@ func (m *Message) Time(args ...interface{}) string { // [duration] [format [args
f := MOD_TIME
if len(args) > 0 {
switch arg := args[0].(type) {
case string:
case string: // 时间格式
if f = arg; len(args) > 1 {
// 时间格式
f = fmt.Sprintf(f, args[1:]...)
}
}
@ -279,19 +274,13 @@ func (m *Message) Source() *Context {
}
func (m *Message) Spawn(arg ...interface{}) *Message {
msg := &Message{
time: time.Now(),
code: int(m.target.root.ID()),
time: time.Now(), code: int(m.target.root.ID()),
meta: map[string][]string{},
data: map[string]interface{}{},
message: m, root: m.root,
source: m.target,
target: m.target,
W: m.W, R: m.R,
O: m.O, I: m.I,
source: m.target, target: m.target,
W: m.W, R: m.R, O: m.O, I: m.I,
}
if len(arg) > 0 {