mirror of
https://shylinux.com/x/icebergs
synced 2025-06-26 18:37:29 +08:00
opt chat
This commit is contained in:
parent
deca0a8e8d
commit
15c6d3f064
128
README.md
128
README.md
@ -1,129 +1,3 @@
|
|||||||
# icebergs
|
# icebergs
|
||||||
|
|
||||||
icebergs是一个应用框架,通过模块化、集群化、自动化,快速搭建起完整的个人云计算平台。
|
icebergs 是一个应用框架,通过模块化、集群化、自动化方式,在各种设备上,一键部署完整的个人云计算与云研发平台。
|
||||||
|
|
||||||
- 使用icebergs可以将各种模块或项目集成到一起,快速开发出集中式的服务器。
|
|
||||||
- 使用icebergs可以将各种设备自由的组合在一起,快速搭建起分布式的服务器。
|
|
||||||
|
|
||||||
## 0. 搭建服务
|
|
||||||
### 0.1 一键部署
|
|
||||||
```sh
|
|
||||||
mkdir miss; cd miss && curl -s https://shylinux.com/publish/ice.sh | sh
|
|
||||||
```
|
|
||||||
|
|
||||||
脚本会根据当前系统类型,自动下载程序文件ice.bin,并自动启动服务。
|
|
||||||
|
|
||||||
### 0.2 使用方式
|
|
||||||
**终端交互**
|
|
||||||
|
|
||||||
启动后的进程,像bash一样是一个可交互的shell,可以执行各种模块命令或系统命令。
|
|
||||||
|
|
||||||
**网页交互**
|
|
||||||
|
|
||||||
默认还会启动一个web服务,访问地址 http://localhost:9020 ,就可以通过网页进行操作。
|
|
||||||
|
|
||||||
**重启服务**
|
|
||||||
|
|
||||||
在终端按Ctrl+C,就可以重新启动服务。
|
|
||||||
|
|
||||||
**结束服务**
|
|
||||||
|
|
||||||
在终端按Ctrl+\,就可以停止服务。
|
|
||||||
|
|
||||||
### 0.3 使用示例
|
|
||||||
|
|
||||||
## 1. 项目开发
|
|
||||||
icebergs是一个应用框架,如果官方模块无法满足使用需求,还可以搜集第三方模块,自行编译程序。
|
|
||||||
|
|
||||||
如果第三方模块也无法满足使用需求,还可以自己开发模块,
|
|
||||||
icebergs提供了模板,可以一键创建新模块,快速添加自己的功能模块。
|
|
||||||
|
|
||||||
### 1.1 部署环境
|
|
||||||
*开发环境,需要提前安装好git和golang*
|
|
||||||
```sh
|
|
||||||
mkdir miss; cd miss && curl -s https://shylinux.com/publish/template.sh | sh
|
|
||||||
```
|
|
||||||
template.sh会自动创建出项目模板,并自动编译生成程序,然后启动服务。
|
|
||||||
|
|
||||||
为了方便以后创建项目与模块。
|
|
||||||
可以将辅助脚本template.sh下载,并添加到可执行目录中。
|
|
||||||
|
|
||||||
### 1.2 添加第三方模块
|
|
||||||
|
|
||||||
在src/main.go文件中,就可以import任意的第三方模块,
|
|
||||||
执行一下make命令,就会重新生成ice.bin。
|
|
||||||
重新启动服务,就可以使用第三方模块了。
|
|
||||||
|
|
||||||
### 1.3 开发模块
|
|
||||||
```sh
|
|
||||||
template.sh tutor hello
|
|
||||||
```
|
|
||||||
使用之前下载的template.sh,调用tutor命令,并指定模块名称hello,就可以一键创建模块了。
|
|
||||||
|
|
||||||
在src/main.go 中import新加的模块,
|
|
||||||
执行make命令,程序编译完成后,
|
|
||||||
重启服务,就可以使用新模块了。
|
|
||||||
|
|
||||||
### 1.4 开发框架
|
|
||||||
如果现有的框架,无法满足需求,还可以下载框架源码自行更改。
|
|
||||||
|
|
||||||
```sh
|
|
||||||
git clone https://shylinux.com/x/icebergs usr/icebergs
|
|
||||||
```
|
|
||||||
修改go.mod文件,引用本地框架。
|
|
||||||
```go
|
|
||||||
replace shylinux.com/x/icebergs => ./usr/icebergs
|
|
||||||
```
|
|
||||||
|
|
||||||
## 2 原型 type.go
|
|
||||||
### 2.1 msg.Detail
|
|
||||||
### 2.2 msg.Option
|
|
||||||
### 2.3 msg.Append
|
|
||||||
### 2.4 msg.Result
|
|
||||||
### 2.5 msg.Travel
|
|
||||||
### 2.6 msg.Search
|
|
||||||
### 2.7 msg.Conf
|
|
||||||
### 2.8 msg.Cmd
|
|
||||||
### 2.9 msg.Cap
|
|
||||||
|
|
||||||
## 3 框架 base.go
|
|
||||||
### 3.1 注册模块 Register
|
|
||||||
### 3.2 创建资源 Begin
|
|
||||||
### 3.3 加载配置 _init
|
|
||||||
### 3.4 启动服务 Start
|
|
||||||
### 3.5 保存配置 _exit
|
|
||||||
### 3.6 释放资源 Close
|
|
||||||
|
|
||||||
## 4 基础模块 base/
|
|
||||||
### 4.1 模块中心 base/ctx/
|
|
||||||
### 4.2 命令中心 base/cli/
|
|
||||||
### 4.3 认证中心 base/aaa/
|
|
||||||
### 4.4 网页中心 base/web/
|
|
||||||
|
|
||||||
### 4.5 词法中心 base/lex/
|
|
||||||
### 4.6 语法中心 base/yac/
|
|
||||||
### 4.7 事件中心 base/gdb/
|
|
||||||
### 4.8 日志中心 base/log/
|
|
||||||
|
|
||||||
### 4.9 网络中心 base/tcp/
|
|
||||||
### 4.10 文件中心 base/nfs/
|
|
||||||
### 4.11 终端中心 base/ssh/
|
|
||||||
### 4.12 数据中心 base/mdb/
|
|
||||||
|
|
||||||
## 5 核心模块 core/
|
|
||||||
### 5.1 编程中心 core/code/
|
|
||||||
### 5.2 文档中心 core/wiki/
|
|
||||||
### 5.3 聊天中心 core/chat/
|
|
||||||
### 5.4 团队中心 core/team/
|
|
||||||
### 5.5 贸易中心 core/mall/
|
|
||||||
|
|
||||||
## 6 其它模块 misc/
|
|
||||||
### 6.1 终端管理 misc/zsh/
|
|
||||||
### 6.1 终端管理 misc/tmux/
|
|
||||||
### 6.1 代码管理 misc/git/
|
|
||||||
### 6.1 代码管理 misc/vim/
|
|
||||||
### 6.1 公众号 misc/mp/
|
|
||||||
### 6.1 小程序 misc/wx/
|
|
||||||
### 6.1 浏览器 misc/chrome/
|
|
||||||
### 6.1 机器人 misc/lark/
|
|
||||||
### 6.1 开发板 misc/pi/
|
|
||||||
|
@ -83,11 +83,11 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func UserRoot(m *ice.Message, arg ...string) *ice.Message { // password username userrole
|
func UserRoot(m *ice.Message, arg ...string) *ice.Message { // password username userrole
|
||||||
|
userrole := m.Option(ice.MSG_USERROLE, ROOT)
|
||||||
username := m.Option(ice.MSG_USERNAME, kit.Select(ice.Info.UserName, arg, 1))
|
username := m.Option(ice.MSG_USERNAME, kit.Select(ice.Info.UserName, arg, 1))
|
||||||
userrole := m.Option(ice.MSG_USERROLE, kit.Select(ROOT, arg, 2))
|
usernick := m.Option(ice.MSG_USERNICK, kit.Select(UserNick(m, username), arg, 2))
|
||||||
m.Option(ice.MSG_USERNICK, UserNick(m, username))
|
|
||||||
if len(arg) > 0 {
|
if len(arg) > 0 {
|
||||||
m.Cmd(USER, mdb.CREATE, username, kit.Select("", arg, 0), userrole, kit.Select("", arg, 3))
|
m.Cmd(USER, mdb.CREATE, username, kit.Select("", arg, 0), userrole, usernick)
|
||||||
ice.Info.UserName = username
|
ice.Info.UserName = username
|
||||||
}
|
}
|
||||||
return m
|
return m
|
||||||
|
@ -216,7 +216,7 @@ func init() {
|
|||||||
}},
|
}},
|
||||||
PROCKILL: {Name: "prockill", Help: "结束进程", Hand: func(m *ice.Message, arg ...string) {
|
PROCKILL: {Name: "prockill", Help: "结束进程", Hand: func(m *ice.Message, arg ...string) {
|
||||||
m.Cmdy(gdb.SIGNAL, gdb.STOP, m.Option("PID"))
|
m.Cmdy(gdb.SIGNAL, gdb.STOP, m.Option("PID"))
|
||||||
m.ProcessRefresh30ms()
|
m.ProcessRefresh()
|
||||||
}},
|
}},
|
||||||
DISKINFO: {Name: "diskinfo", Help: "磁盘信息", Hand: func(m *ice.Message, arg ...string) {
|
DISKINFO: {Name: "diskinfo", Help: "磁盘信息", Hand: func(m *ice.Message, arg ...string) {
|
||||||
_runtime_diskinfo(m)
|
_runtime_diskinfo(m)
|
||||||
|
@ -191,7 +191,7 @@ var Index = &ice.Context{Name: MDB, Help: "数据模块", Commands: ice.Commands
|
|||||||
}
|
}
|
||||||
}},
|
}},
|
||||||
INSERT: {Name: "insert key sub type arg...", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
|
INSERT: {Name: "insert key sub type arg...", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
|
||||||
defer m.ProcessRefresh3ms()
|
defer m.ProcessRefresh()
|
||||||
switch arg[2] {
|
switch arg[2] {
|
||||||
case ZONE: // insert key sub type zone arg...
|
case ZONE: // insert key sub type zone arg...
|
||||||
_zone_insert(m, arg[0], arg[1], arg[3], arg[4:]...)
|
_zone_insert(m, arg[0], arg[1], arg[3], arg[4:]...)
|
||||||
@ -202,7 +202,7 @@ var Index = &ice.Context{Name: MDB, Help: "数据模块", Commands: ice.Commands
|
|||||||
}
|
}
|
||||||
}},
|
}},
|
||||||
DELETE: {Name: "delete key sub type field value", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
|
DELETE: {Name: "delete key sub type field value", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
|
||||||
defer m.ProcessRefresh3ms()
|
defer m.ProcessRefresh()
|
||||||
switch arg[2] {
|
switch arg[2] {
|
||||||
case ZONE: // delete key sub type zone field value
|
case ZONE: // delete key sub type zone field value
|
||||||
// _list_delete(m, arg[0], _domain_chain(m, kit.Keys(arg[1], kit.KeyHash(arg[3]))), arg[4], arg[5])
|
// _list_delete(m, arg[0], _domain_chain(m, kit.Keys(arg[1], kit.KeyHash(arg[3]))), arg[4], arg[5])
|
||||||
|
@ -9,6 +9,13 @@ const SEARCH = "search"
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
Index.MergeCommands(ice.Commands{SEARCH: {Name: "search type name text auto", Help: "搜索", Actions: RenderAction()}})
|
Index.MergeCommands(ice.Commands{SEARCH: {Name: "search type name text auto", Help: "搜索", Actions: RenderAction()}})
|
||||||
|
ice.AddMerges(func(c *ice.Context, key string, cmd *ice.Command, sub string, action *ice.Action) (ice.Handler, ice.Handler) {
|
||||||
|
switch sub {
|
||||||
|
case SEARCH:
|
||||||
|
return func(m *ice.Message, arg ...string) { m.Cmd(SEARCH, CREATE, m.CommandKey(), m.PrefixKey()) }, nil
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
})
|
||||||
}
|
}
|
||||||
func SearchAction() ice.Actions {
|
func SearchAction() ice.Actions {
|
||||||
return ice.Actions{
|
return ice.Actions{
|
||||||
|
@ -36,6 +36,9 @@ func (f *Frame) prompt(m *ice.Message, list ...string) *Frame {
|
|||||||
if f.source != STDIO {
|
if f.source != STDIO {
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
if m.Target().Cap(ice.CTX_STATUS) == ice.CTX_CLOSE {
|
||||||
|
return f
|
||||||
|
}
|
||||||
if len(list) == 0 {
|
if len(list) == 0 {
|
||||||
list = append(list, f.ps1...)
|
list = append(list, f.ps1...)
|
||||||
}
|
}
|
||||||
@ -106,7 +109,6 @@ func (f *Frame) parse(m *ice.Message, h, line string) string {
|
|||||||
if msg.Cmdy(ls); h == STDIO && msg.IsErrNotFound() {
|
if msg.Cmdy(ls); h == STDIO && msg.IsErrNotFound() {
|
||||||
msg.SetResult().Cmdy(cli.SYSTEM, ls)
|
msg.SetResult().Cmdy(cli.SYSTEM, ls)
|
||||||
}
|
}
|
||||||
|
|
||||||
f.res = Render(msg, msg.Option(ice.MSG_OUTPUT), msg.Optionv(ice.MSG_ARGS).([]ice.Any)...)
|
f.res = Render(msg, msg.Option(ice.MSG_OUTPUT), msg.Optionv(ice.MSG_ARGS).([]ice.Any)...)
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ func _dream_list(m *ice.Message) *ice.Message {
|
|||||||
m.PushButton(cli.START, nfs.TRASH)
|
m.PushButton(cli.START, nfs.TRASH)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return m.Sort("status,type,name").StatusTimeCount(cli.START, len(list))
|
return m.Sort("status,type,name", ice.STR, ice.STR, ice.STR_R).StatusTimeCount(cli.START, len(list))
|
||||||
}
|
}
|
||||||
func _dream_show(m *ice.Message, name string) {
|
func _dream_show(m *ice.Message, name string) {
|
||||||
if m.Warn(name == "", ice.ErrNotValid) {
|
if m.Warn(name == "", ice.ErrNotValid) {
|
||||||
@ -61,7 +61,7 @@ func _dream_show(m *ice.Message, name string) {
|
|||||||
kit.EnvSimple(cli.HOME, cli.TERM, cli.SHELL), m.Configv(cli.ENV),
|
kit.EnvSimple(cli.HOME, cli.TERM, cli.SHELL), m.Configv(cli.ENV),
|
||||||
))
|
))
|
||||||
m.Optionv(cli.CMD_OUTPUT, path.Join(p, ice.BIN_BOOT_LOG))
|
m.Optionv(cli.CMD_OUTPUT, path.Join(p, ice.BIN_BOOT_LOG))
|
||||||
defer m.OptionMulti(cli.CMD_DIR, "", cli.CMD_ENV, "", cli.CMD_OUTPUT, "")
|
defer m.Options(cli.CMD_DIR, "", cli.CMD_ENV, "", cli.CMD_OUTPUT, "")
|
||||||
gdb.Event(m, DREAM_CREATE, m.OptionSimple(mdb.NAME, mdb.TYPE))
|
gdb.Event(m, DREAM_CREATE, m.OptionSimple(mdb.NAME, mdb.TYPE))
|
||||||
|
|
||||||
defer ToastProcess(m)()
|
defer ToastProcess(m)()
|
||||||
|
@ -41,7 +41,7 @@ func _serve_rewrite(m *ice.Message) {
|
|||||||
return Render(msg, ice.RENDER_DOWNLOAD, path.Join(msg.Config(kit.Keys(repos, nfs.PATH)), msg.Config(kit.Keys(repos, INDEX))))
|
return Render(msg, ice.RENDER_DOWNLOAD, path.Join(msg.Config(kit.Keys(repos, nfs.PATH)), msg.Config(kit.Keys(repos, INDEX))))
|
||||||
|
|
||||||
case PP(ice.HELP):
|
case PP(ice.HELP):
|
||||||
r.URL.Path = P(ice.HELP, ice.TUTOR_SHY)
|
r.URL.Path = P(ice.HELP, "tutor.shy")
|
||||||
}
|
}
|
||||||
|
|
||||||
p := path.Join(ice.USR, repos, r.URL.Path)
|
p := path.Join(ice.USR, repos, r.URL.Path)
|
||||||
@ -89,11 +89,7 @@ func _serve_start(m *ice.Message) {
|
|||||||
if cli.NodeInfo(m, SERVER, kit.Select(ice.Info.HostName, m.Option("nodename"))); m.Option(tcp.PORT) == tcp.RANDOM {
|
if cli.NodeInfo(m, SERVER, kit.Select(ice.Info.HostName, m.Option("nodename"))); m.Option(tcp.PORT) == tcp.RANDOM {
|
||||||
m.Option(tcp.PORT, m.Cmdx(tcp.PORT, aaa.RIGHT))
|
m.Option(tcp.PORT, m.Cmdx(tcp.PORT, aaa.RIGHT))
|
||||||
}
|
}
|
||||||
|
aaa.UserRoot(m, m.Option(aaa.PASSWORD), m.Option(aaa.USERNAME), m.Option(aaa.USERNICK))
|
||||||
if m.Option("staffname") != "" {
|
|
||||||
m.Config("staffname", m.Option(aaa.USERNAME, m.Option("staffname")))
|
|
||||||
}
|
|
||||||
aaa.UserRoot(m, m.Option(aaa.PASSWORD), m.Option(aaa.USERNAME), m.Option(aaa.USERROLE), m.Option(aaa.USERNICK))
|
|
||||||
|
|
||||||
m.Target().Start(m, m.OptionSimple(tcp.HOST, tcp.PORT)...)
|
m.Target().Start(m, m.OptionSimple(tcp.HOST, tcp.PORT)...)
|
||||||
m.Go(func() { m.Cmd(BROAD, SERVE) })
|
m.Go(func() { m.Cmd(BROAD, SERVE) })
|
||||||
@ -364,7 +360,7 @@ func init() {
|
|||||||
ctx.DisplayStorySpide(m, lex.PREFIX, m.ActionKey(), nfs.ROOT, MergeLink(m, ice.PS))
|
ctx.DisplayStorySpide(m, lex.PREFIX, m.ActionKey(), nfs.ROOT, MergeLink(m, ice.PS))
|
||||||
}
|
}
|
||||||
}},
|
}},
|
||||||
cli.START: {Name: "start dev proto=http host port=9020 nodename password username userrole usernick staffname", Help: "启动", Hand: func(m *ice.Message, arg ...string) {
|
cli.START: {Name: "start dev proto=http host port=9020 nodename password username usernick", Help: "启动", Hand: func(m *ice.Message, arg ...string) {
|
||||||
_serve_start(m)
|
_serve_start(m)
|
||||||
}},
|
}},
|
||||||
}, mdb.HashAction())},
|
}, mdb.HashAction())},
|
||||||
@ -396,7 +392,7 @@ func init() {
|
|||||||
}},
|
}},
|
||||||
PP(ice.HELP): {Name: "/help/", Help: "帮助", Hand: func(m *ice.Message, arg ...string) {
|
PP(ice.HELP): {Name: "/help/", Help: "帮助", Hand: func(m *ice.Message, arg ...string) {
|
||||||
if len(arg) == 0 {
|
if len(arg) == 0 {
|
||||||
arg = append(arg, ice.TUTOR_SHY)
|
arg = append(arg, "tutor.shy")
|
||||||
}
|
}
|
||||||
if len(arg) > 0 && arg[0] != ctx.ACTION {
|
if len(arg) > 0 && arg[0] != ctx.ACTION {
|
||||||
arg[0] = path.Join(ice.SRC_HELP, arg[0])
|
arg[0] = path.Join(ice.SRC_HELP, arg[0])
|
||||||
@ -404,4 +400,13 @@ func init() {
|
|||||||
m.Cmdy("web.chat./cmd/", arg)
|
m.Cmdy("web.chat./cmd/", arg)
|
||||||
}},
|
}},
|
||||||
}})
|
}})
|
||||||
|
ice.AddMerges(func(c *ice.Context, key string, cmd *ice.Command, sub string, action *ice.Action) (ice.Handler, ice.Handler) {
|
||||||
|
if strings.HasPrefix(sub, ice.PS) {
|
||||||
|
if sub = kit.Select(sub, PP(key), sub == ice.PS); action.Hand == nil {
|
||||||
|
action.Hand = func(m *ice.Message, arg ...string) { m.Cmdy(key, arg) }
|
||||||
|
}
|
||||||
|
c.Commands[sub] = &ice.Command{Name: sub, Help: cmd.Help, Hand: action.Hand}
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
143
conf.go
143
conf.go
@ -14,12 +14,12 @@ const (
|
|||||||
OK = "ok"
|
OK = "ok"
|
||||||
TRUE = "true"
|
TRUE = "true"
|
||||||
FALSE = "false"
|
FALSE = "false"
|
||||||
SUCCESS = "success"
|
|
||||||
FAILURE = "failure"
|
|
||||||
PROCESS = "process"
|
PROCESS = "process"
|
||||||
|
FAILURE = "failure"
|
||||||
|
SUCCESS = "success"
|
||||||
|
|
||||||
AUTO = "auto"
|
|
||||||
HTTP = "http"
|
HTTP = "http"
|
||||||
|
AUTO = "auto"
|
||||||
LIST = "list"
|
LIST = "list"
|
||||||
BACK = "back"
|
BACK = "back"
|
||||||
|
|
||||||
@ -28,6 +28,7 @@ const (
|
|||||||
MISC = "misc"
|
MISC = "misc"
|
||||||
|
|
||||||
SHY = "shy"
|
SHY = "shy"
|
||||||
|
COM = "com"
|
||||||
DEV = "dev"
|
DEV = "dev"
|
||||||
OPS = "ops"
|
OPS = "ops"
|
||||||
ICE = "ice"
|
ICE = "ice"
|
||||||
@ -49,16 +50,16 @@ const ( // MOD
|
|||||||
MOD_TIME = "2006-01-02 15:04:05"
|
MOD_TIME = "2006-01-02 15:04:05"
|
||||||
)
|
)
|
||||||
const ( // REPOS
|
const ( // REPOS
|
||||||
VOLCANOS = "volcanos"
|
|
||||||
LEARNING = "learning"
|
|
||||||
ICEBERGS = "icebergs"
|
|
||||||
TOOLKITS = "toolkits"
|
|
||||||
INTSHELL = "intshell"
|
INTSHELL = "intshell"
|
||||||
CONTEXTS = "contexts"
|
CONTEXTS = "contexts"
|
||||||
|
ICEBERGS = "icebergs"
|
||||||
|
TOOLKITS = "toolkits"
|
||||||
|
VOLCANOS = "volcanos"
|
||||||
|
LEARNING = "learning"
|
||||||
|
|
||||||
INSTALL = "install"
|
INSTALL = "install"
|
||||||
RELEASE = "release"
|
|
||||||
PUBLISH = "publish"
|
PUBLISH = "publish"
|
||||||
|
RELEASE = "release"
|
||||||
REQUIRE = "require"
|
REQUIRE = "require"
|
||||||
DISPLAY = "display"
|
DISPLAY = "display"
|
||||||
)
|
)
|
||||||
@ -69,12 +70,12 @@ const ( // DIR
|
|||||||
VAR = "var"
|
VAR = "var"
|
||||||
USR = "usr"
|
USR = "usr"
|
||||||
|
|
||||||
|
SVG = "svg"
|
||||||
HTML = "html"
|
HTML = "html"
|
||||||
CSS = "css"
|
CSS = "css"
|
||||||
JS = "js"
|
JS = "js"
|
||||||
GO = "go"
|
GO = "go"
|
||||||
SH = "sh"
|
SH = "sh"
|
||||||
SVG = "svg"
|
|
||||||
CSV = "csv"
|
CSV = "csv"
|
||||||
JSON = "json"
|
JSON = "json"
|
||||||
|
|
||||||
@ -89,45 +90,41 @@ const ( // DIR
|
|||||||
FRAME_JS = "frame.js"
|
FRAME_JS = "frame.js"
|
||||||
INDEX_JS = "index.js"
|
INDEX_JS = "index.js"
|
||||||
INDEX_SH = "index.sh"
|
INDEX_SH = "index.sh"
|
||||||
INDEX_IML = "index.iml"
|
|
||||||
TUTOR_SHY = "tutor.shy"
|
|
||||||
|
|
||||||
PLUGIN_INPUT = "/plugin/input"
|
PLUGIN_INPUT = "/plugin/input/"
|
||||||
PLUGIN_STORY = "/plugin/story"
|
PLUGIN_STORY = "/plugin/story/"
|
||||||
PLUGIN_LOCAL = "/plugin/local"
|
PLUGIN_LOCAL = "/plugin/local/"
|
||||||
NODE_MODULES = "node_modules"
|
NODE_MODULES = "node_modules/"
|
||||||
ISH_PLUGED = ".ish/pluged"
|
ISH_PLUGED = ".ish/pluged/"
|
||||||
|
|
||||||
USR_VOLCANOS = "usr/volcanos"
|
USR_VOLCANOS = "usr/volcanos/"
|
||||||
USR_LEARNING = "usr/learning"
|
USR_LEARNING = "usr/learning/"
|
||||||
USR_ICEBERGS = "usr/icebergs"
|
USR_ICEBERGS = "usr/icebergs/"
|
||||||
USR_TOOLKITS = "usr/toolkits"
|
USR_TOOLKITS = "usr/toolkits/"
|
||||||
USR_INTSHELL = "usr/intshell"
|
USR_INTSHELL = "usr/intshell/"
|
||||||
USR_INSTALL = "usr/install"
|
USR_INSTALL = "usr/install/"
|
||||||
USR_RELEASE = "usr/release"
|
USR_PUBLISH = "usr/publish/"
|
||||||
USR_PUBLISH = "usr/publish"
|
USR_RELEASE = "usr/release/"
|
||||||
|
|
||||||
USR_LOCAL = "usr/local"
|
USR_LOCAL = "usr/local/"
|
||||||
USR_LOCAL_GO = "usr/local/go"
|
USR_LOCAL_GO = "usr/local/go/"
|
||||||
USR_LOCAL_GO_BIN = "usr/local/go/bin"
|
USR_LOCAL_GO_BIN = "usr/local/go/bin/"
|
||||||
USR_LOCAL_BIN = "usr/local/bin"
|
USR_LOCAL_BIN = "usr/local/bin/"
|
||||||
USR_LOCAL_LIB = "usr/local/lib"
|
USR_LOCAL_LIB = "usr/local/lib/"
|
||||||
USR_LOCAL_WORK = "usr/local/work"
|
USR_LOCAL_WORK = "usr/local/work/"
|
||||||
USR_LOCAL_IMAGE = "usr/local/image"
|
USR_LOCAL_IMAGE = "usr/local/image/"
|
||||||
USR_LOCAL_MEDIA = "usr/local/media"
|
USR_LOCAL_DAEMON = "usr/local/daemon/"
|
||||||
USR_LOCAL_RIVER = "usr/local/river"
|
USR_LOCAL_EXPORT = "usr/local/export/"
|
||||||
USR_LOCAL_DAEMON = "usr/local/daemon"
|
USR_LOCAL_REPOS = "usr/local/repos/"
|
||||||
USR_LOCAL_EXPORT = "usr/local/export"
|
|
||||||
USR_LOCAL_REPOS = "usr/local/repos"
|
|
||||||
|
|
||||||
VAR_RUN = "var/run"
|
VAR_RUN = "var/run/"
|
||||||
VAR_TMP = "var/tmp"
|
VAR_TMP = "var/tmp/"
|
||||||
VAR_LOG = "var/log"
|
VAR_LOG = "var/log/"
|
||||||
VAR_CONF = "var/conf"
|
VAR_CONF = "var/conf/"
|
||||||
VAR_DATA = "var/data"
|
VAR_DATA = "var/data/"
|
||||||
VAR_FILE = "var/file"
|
VAR_FILE = "var/file/"
|
||||||
VAR_PROXY = "var/proxy"
|
VAR_PROXY = "var/proxy/"
|
||||||
VAR_TRASH = "var/trash"
|
VAR_TRASH = "var/trash/"
|
||||||
BIN_ICE_BIN = "bin/ice.bin"
|
BIN_ICE_BIN = "bin/ice.bin"
|
||||||
BIN_BOOT_LOG = "bin/boot.log"
|
BIN_BOOT_LOG = "bin/boot.log"
|
||||||
ETC_INIT_SHY = "etc/init.shy"
|
ETC_INIT_SHY = "etc/init.shy"
|
||||||
@ -136,13 +133,13 @@ const ( // DIR
|
|||||||
ETC_MISS_SH = "etc/miss.sh"
|
ETC_MISS_SH = "etc/miss.sh"
|
||||||
ETC_PATH = "etc/path"
|
ETC_PATH = "etc/path"
|
||||||
|
|
||||||
SRC_HELP = "src/help"
|
SRC_HELP = "src/help/"
|
||||||
SRC_DEBUG = "src/debug"
|
SRC_DEBUG = "src/debug/"
|
||||||
SRC_RELEASE = "src/release"
|
SRC_RELEASE = "src/release/"
|
||||||
|
SRC_MAIN_SVG = "src/main.svg"
|
||||||
|
SRC_MAIN_SHY = "src/main.shy"
|
||||||
SRC_MAIN_JS = "src/main.js"
|
SRC_MAIN_JS = "src/main.js"
|
||||||
SRC_MAIN_GO = "src/main.go"
|
SRC_MAIN_GO = "src/main.go"
|
||||||
SRC_MAIN_SHY = "src/main.shy"
|
|
||||||
SRC_MAIN_SVG = "src/main.svg"
|
|
||||||
SRC_VERSION_GO = "src/version.go"
|
SRC_VERSION_GO = "src/version.go"
|
||||||
SRC_BINPACK_GO = "src/binpack.go"
|
SRC_BINPACK_GO = "src/binpack.go"
|
||||||
SRC_RELAY_GO = "src/relay.go"
|
SRC_RELAY_GO = "src/relay.go"
|
||||||
@ -167,8 +164,8 @@ const ( // MSG
|
|||||||
MSG_SOURCE = "_source"
|
MSG_SOURCE = "_source"
|
||||||
MSG_TARGET = "_target"
|
MSG_TARGET = "_target"
|
||||||
MSG_HANDLE = "_handle"
|
MSG_HANDLE = "_handle"
|
||||||
MSG_DAEMON = "_daemon"
|
|
||||||
MSG_UPLOAD = "_upload"
|
MSG_UPLOAD = "_upload"
|
||||||
|
MSG_DAEMON = "_daemon"
|
||||||
MSG_ACTION = "_action"
|
MSG_ACTION = "_action"
|
||||||
MSG_STATUS = "_status"
|
MSG_STATUS = "_status"
|
||||||
|
|
||||||
@ -198,19 +195,20 @@ const ( // MSG
|
|||||||
MSG_RIVER = "sess.river"
|
MSG_RIVER = "sess.river"
|
||||||
MSG_STORM = "sess.storm"
|
MSG_STORM = "sess.storm"
|
||||||
MSG_FILES = "file.system"
|
MSG_FILES = "file.system"
|
||||||
|
LOG_DISABLE = "log.disable"
|
||||||
|
|
||||||
FIELDS_DETAIL = "detail"
|
FIELDS_DETAIL = "detail"
|
||||||
)
|
)
|
||||||
const ( // RENDER
|
const ( // RENDER
|
||||||
RENDER_TEMPLATE = "_template"
|
|
||||||
RENDER_ANCHOR = "_anchor"
|
|
||||||
RENDER_BUTTON = "_button"
|
RENDER_BUTTON = "_button"
|
||||||
|
RENDER_ANCHOR = "_anchor"
|
||||||
|
RENDER_QRCODE = "_qrcode"
|
||||||
RENDER_IMAGES = "_images"
|
RENDER_IMAGES = "_images"
|
||||||
RENDER_VIDEOS = "_videos"
|
RENDER_VIDEOS = "_videos"
|
||||||
RENDER_IFRAME = "_iframe"
|
RENDER_IFRAME = "_iframe"
|
||||||
RENDER_QRCODE = "_qrcode"
|
|
||||||
RENDER_SCRIPT = "_script"
|
RENDER_SCRIPT = "_script"
|
||||||
|
|
||||||
|
RENDER_TEMPLATE = "_template"
|
||||||
RENDER_STATUS = "_status"
|
RENDER_STATUS = "_status"
|
||||||
RENDER_REDIRECT = "_redirect"
|
RENDER_REDIRECT = "_redirect"
|
||||||
RENDER_DOWNLOAD = "_download"
|
RENDER_DOWNLOAD = "_download"
|
||||||
@ -227,9 +225,9 @@ const ( // PROCESS
|
|||||||
PROCESS_REFRESH = "_refresh"
|
PROCESS_REFRESH = "_refresh"
|
||||||
PROCESS_REWRITE = "_rewrite"
|
PROCESS_REWRITE = "_rewrite"
|
||||||
PROCESS_DISPLAY = "_display"
|
PROCESS_DISPLAY = "_display"
|
||||||
PROCESS_INNER = "_inner"
|
|
||||||
PROCESS_FIELD = "_field"
|
PROCESS_FIELD = "_field"
|
||||||
PROCESS_FLOAT = "_float"
|
PROCESS_FLOAT = "_float"
|
||||||
|
PROCESS_INNER = "_inner"
|
||||||
PROCESS_AGAIN = "_again"
|
PROCESS_AGAIN = "_again"
|
||||||
|
|
||||||
PROCESS_HOLD = "_hold"
|
PROCESS_HOLD = "_hold"
|
||||||
@ -242,6 +240,9 @@ const ( // PROCESS
|
|||||||
FIELD_PREFIX = "_prefix"
|
FIELD_PREFIX = "_prefix"
|
||||||
)
|
)
|
||||||
const ( // CTX
|
const ( // CTX
|
||||||
|
CTX_ARG = "ctx_arg"
|
||||||
|
CTX_DAEMON = "ctx_daemon"
|
||||||
|
|
||||||
CTX_FOLLOW = "follow"
|
CTX_FOLLOW = "follow"
|
||||||
CTX_STATUS = "status"
|
CTX_STATUS = "status"
|
||||||
CTX_STREAM = "stream"
|
CTX_STREAM = "stream"
|
||||||
@ -253,19 +254,15 @@ const ( // CTX
|
|||||||
|
|
||||||
CTX_INIT = "_init"
|
CTX_INIT = "_init"
|
||||||
CTX_EXIT = "_exit"
|
CTX_EXIT = "_exit"
|
||||||
|
|
||||||
CTX_ARG = "ctx_arg"
|
|
||||||
CTX_DAEMON = "ctx_daemon"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const ( // LOG
|
const ( // LOG
|
||||||
LOG_CMDS = "cmds"
|
LOG_CMDS = "cmds"
|
||||||
LOG_AUTH = "auth"
|
LOG_AUTH = "auth"
|
||||||
LOG_COST = "cost"
|
LOG_COST = "cost"
|
||||||
LOG_INFO = "info"
|
LOG_INFO = "info"
|
||||||
LOG_WARN = "warn"
|
LOG_WARN = "warn"
|
||||||
LOG_DEBUG = "debug"
|
|
||||||
LOG_ERROR = "error"
|
LOG_ERROR = "error"
|
||||||
|
LOG_DEBUG = "debug"
|
||||||
)
|
)
|
||||||
const ( // Err
|
const ( // Err
|
||||||
ErrWarn = "warn: "
|
ErrWarn = "warn: "
|
||||||
@ -275,23 +272,36 @@ const ( // Err
|
|||||||
ErrNotFound = "not found: "
|
ErrNotFound = "not found: "
|
||||||
ErrNotValid = "not valid: "
|
ErrNotValid = "not valid: "
|
||||||
ErrNotStart = "not start: "
|
ErrNotStart = "not start: "
|
||||||
|
|
||||||
ErrNotImplement = "not implement: "
|
ErrNotImplement = "not implement: "
|
||||||
)
|
)
|
||||||
|
|
||||||
const ( // ctx
|
const ( // ctx
|
||||||
COMMAND = "command"
|
COMMAND = "command"
|
||||||
ACTION = "action"
|
ACTION = "action"
|
||||||
STYLE = "style"
|
STYLE = "style"
|
||||||
INDEX = "index"
|
INDEX = "index"
|
||||||
)
|
)
|
||||||
|
const ( // web
|
||||||
|
SERVE = "serve"
|
||||||
|
SPACE = "space"
|
||||||
|
|
||||||
|
TOPIC = "topic"
|
||||||
|
TITLE = "title"
|
||||||
|
WIDTH = "width"
|
||||||
|
HEIGHT = "height"
|
||||||
|
)
|
||||||
|
const ( // nfs
|
||||||
|
SOURCE = "source"
|
||||||
|
SCRIPT = "script"
|
||||||
|
)
|
||||||
const ( // mdb
|
const ( // mdb
|
||||||
AAA = "aaa"
|
SEARCH = "search"
|
||||||
MDB = "mdb"
|
SELECT = "select"
|
||||||
|
|
||||||
KEY = "key"
|
KEY = "key"
|
||||||
VALUE = "value"
|
VALUE = "value"
|
||||||
FIELD = "field"
|
|
||||||
EXTRA = "extra"
|
EXTRA = "extra"
|
||||||
SCRIPT = "script"
|
FIELD = "field"
|
||||||
META = "meta"
|
META = "meta"
|
||||||
HASH = "hash"
|
HASH = "hash"
|
||||||
TIME = "time"
|
TIME = "time"
|
||||||
@ -300,3 +310,8 @@ const ( // mdb
|
|||||||
TEXT = "text"
|
TEXT = "text"
|
||||||
LINK = "link"
|
LINK = "link"
|
||||||
)
|
)
|
||||||
|
const ( // ice
|
||||||
|
MDB = "mdb"
|
||||||
|
AAA = "aaa"
|
||||||
|
CLI = "cli"
|
||||||
|
)
|
||||||
|
@ -89,7 +89,7 @@ func _website_parse(m *ice.Message, text string, args ...string) (ice.Map, bool)
|
|||||||
case ctx.ARGS:
|
case ctx.ARGS:
|
||||||
data[ls[i]] = kit.Split(ls[i+1])
|
data[ls[i]] = kit.Split(ls[i+1])
|
||||||
case ctx.DISPLAY:
|
case ctx.DISPLAY:
|
||||||
data[ls[i]] = ice.Display(ls[i+1])[ctx.DISPLAY]
|
// data[ls[i]] = ice.Display(ls[i+1])[ctx.DISPLAY]
|
||||||
case ctx.STYLE, ctx.ACTION, TITLE, MENUS:
|
case ctx.STYLE, ctx.ACTION, TITLE, MENUS:
|
||||||
data[ls[i]] = kit.UnMarshal(ls[i+1])
|
data[ls[i]] = kit.UnMarshal(ls[i+1])
|
||||||
default:
|
default:
|
||||||
|
@ -86,7 +86,7 @@ func init() {
|
|||||||
m.Cmd(ASSET, func(value ice.Maps) {
|
m.Cmd(ASSET, func(value ice.Maps) {
|
||||||
_asset_check(m, value[ACCOUNT])
|
_asset_check(m, value[ACCOUNT])
|
||||||
})
|
})
|
||||||
m.ProcessRefresh30ms()
|
m.ProcessRefresh()
|
||||||
} else {
|
} else {
|
||||||
_asset_check(m, m.Option(ACCOUNT))
|
_asset_check(m, m.Option(ACCOUNT))
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func _word_show(m *ice.Message, name string, arg ...string) {
|
func _word_show(m *ice.Message, name string, arg ...string) {
|
||||||
m.OptionMulti(ice.MSG_ALIAS, m.Configv(mdb.ALIAS), TITLE, map[string]int{}, MENU, kit.Dict(mdb.LIST, kit.List()))
|
m.Options(ice.MSG_ALIAS, m.Configv(mdb.ALIAS), TITLE, map[string]int{}, MENU, kit.Dict(mdb.LIST, kit.List()))
|
||||||
m.Cmdy(ssh.SOURCE, name, kit.Dict(nfs.DIR_ROOT, _wiki_path(m)))
|
m.Cmdy(ssh.SOURCE, name, kit.Dict(nfs.DIR_ROOT, _wiki_path(m)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
6
data.go
6
data.go
@ -7,13 +7,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (m *Message) ActionKey() string {
|
func (m *Message) ActionKey() string {
|
||||||
return strings.TrimSuffix(strings.TrimPrefix(m._sub, PS), PS)
|
return strings.TrimPrefix(strings.TrimSuffix(m._sub, PS), PS)
|
||||||
}
|
}
|
||||||
func (m *Message) CommandKey() string {
|
func (m *Message) CommandKey() string {
|
||||||
return strings.TrimSuffix(strings.TrimPrefix(m._key, PS), PS)
|
return strings.TrimPrefix(strings.TrimSuffix(m._key, PS), PS)
|
||||||
}
|
}
|
||||||
func (m *Message) PrefixKey(arg ...Any) string {
|
func (m *Message) PrefixKey(arg ...Any) string {
|
||||||
return kit.Keys(m.Prefix(m.CommandKey()), kit.Keys(arg))
|
return kit.Keys(m.Prefix(m.CommandKey()), kit.Keys(arg...))
|
||||||
}
|
}
|
||||||
func (m *Message) Prefix(arg ...string) string {
|
func (m *Message) Prefix(arg ...string) string {
|
||||||
return m.Target().PrefixKey(arg...)
|
return m.Target().PrefixKey(arg...)
|
||||||
|
14
exec.go
14
exec.go
@ -7,23 +7,23 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
kit "shylinux.com/x/toolkits"
|
kit "shylinux.com/x/toolkits"
|
||||||
|
"shylinux.com/x/toolkits/logs"
|
||||||
"shylinux.com/x/toolkits/task"
|
"shylinux.com/x/toolkits/task"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (m *Message) TryCatch(msg *Message, silent bool, hand ...func(msg *Message)) *Message {
|
func (m *Message) TryCatch(msg *Message, silent bool, hand ...func(msg *Message)) *Message {
|
||||||
defer func() {
|
defer func() {
|
||||||
switch e := recover(); e {
|
switch e := recover(); e {
|
||||||
case io.EOF:
|
case nil, io.EOF:
|
||||||
case nil:
|
|
||||||
default:
|
default:
|
||||||
fileline := m.FormatStack(2, 1)
|
fileline := m.FormatStack(2, 100)
|
||||||
m.Log(LOG_WARN, "catch: %s %s", e, fileline).Log("chain", msg.FormatChain())
|
m.Log(LOG_WARN, "catch: %s %s", e, fileline).Log("chain", msg.FormatChain())
|
||||||
m.Log(LOG_WARN, "catch: %s %s", e, fileline).Log("stack", msg.FormatStack(2, 100))
|
m.Log(LOG_WARN, "catch: %s %s", e, fileline).Log("stack", msg.FormatStack(2, 100))
|
||||||
m.Log(LOG_WARN, "catch: %s %s", e, fileline).Result(ErrWarn, e, " ", fileline)
|
m.Log(LOG_WARN, "catch: %s %s", e, fileline).Result(ErrWarn, e, SP, fileline)
|
||||||
if len(hand) > 1 {
|
if len(hand) > 1 {
|
||||||
m.TryCatch(msg, silent, hand[1:]...)
|
m.TryCatch(msg, silent, hand[1:]...)
|
||||||
} else if !silent {
|
} else if !silent {
|
||||||
m.Assert(e) // 抛出异常
|
m.Assert(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@ -36,13 +36,13 @@ func (m *Message) Assert(expr Any) bool {
|
|||||||
switch e := expr.(type) {
|
switch e := expr.(type) {
|
||||||
case nil:
|
case nil:
|
||||||
return true
|
return true
|
||||||
case error:
|
|
||||||
case bool:
|
case bool:
|
||||||
if e == true {
|
if e == true {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
case error:
|
||||||
default:
|
default:
|
||||||
expr = errors.New(kit.Format("error: %v", e))
|
expr = errors.New(kit.Format("error: %v %s", e, logs.FileLine(2, 3)))
|
||||||
}
|
}
|
||||||
m.Result(ErrWarn, expr)
|
m.Result(ErrWarn, expr)
|
||||||
panic(expr)
|
panic(expr)
|
||||||
|
21
info.go
21
info.go
@ -1,13 +1,13 @@
|
|||||||
package ice
|
package ice
|
||||||
|
|
||||||
type MakeInfo struct {
|
type MakeInfo struct {
|
||||||
Path string
|
|
||||||
Time string
|
Time string
|
||||||
|
Path string
|
||||||
Hash string
|
Hash string
|
||||||
|
Domain string
|
||||||
Module string
|
Module string
|
||||||
Remote string
|
Remote string
|
||||||
Branch string
|
Branch string
|
||||||
Domain string
|
|
||||||
Version string
|
Version string
|
||||||
HostName string
|
HostName string
|
||||||
UserName string
|
UserName string
|
||||||
@ -21,19 +21,20 @@ var Info = struct {
|
|||||||
UserName string
|
UserName string
|
||||||
PassWord string
|
PassWord string
|
||||||
|
|
||||||
Colors bool
|
|
||||||
Domain string
|
Domain string
|
||||||
NodeType string
|
NodeType string
|
||||||
NodeName string
|
NodeName string
|
||||||
CtxShare string
|
CtxShare string
|
||||||
CtxRiver string
|
CtxRiver string
|
||||||
PidPath string
|
PidPath string
|
||||||
|
Colors bool
|
||||||
|
|
||||||
Help string
|
Help string
|
||||||
Route Maps // 路由命令
|
File Maps
|
||||||
File Maps // 文件命令
|
Route Maps
|
||||||
names Map
|
index Map
|
||||||
|
|
||||||
|
merges []MergeHandler
|
||||||
render map[string]func(*Message, string, ...Any) string
|
render map[string]func(*Message, string, ...Any) string
|
||||||
Save func(m *Message, key ...string) *Message
|
Save func(m *Message, key ...string) *Message
|
||||||
Load func(m *Message, key ...string) *Message
|
Load func(m *Message, key ...string) *Message
|
||||||
@ -47,12 +48,16 @@ report: shylinuxc@gmail.com
|
|||||||
server: https://shylinux.com
|
server: https://shylinux.com
|
||||||
source: https://shylinux.com/x/icebergs
|
source: https://shylinux.com/x/icebergs
|
||||||
`,
|
`,
|
||||||
Route: Maps{},
|
|
||||||
File: Maps{},
|
File: Maps{},
|
||||||
names: Map{},
|
Route: Maps{},
|
||||||
|
index: Map{},
|
||||||
|
|
||||||
render: map[string]func(*Message, string, ...Any) string{},
|
render: map[string]func(*Message, string, ...Any) string{},
|
||||||
Save: func(m *Message, key ...string) *Message { return m },
|
Save: func(m *Message, key ...string) *Message { return m },
|
||||||
Load: func(m *Message, key ...string) *Message { return m },
|
Load: func(m *Message, key ...string) *Message { return m },
|
||||||
Log: func(m *Message, p, l, s string) {},
|
Log: func(m *Message, p, l, s string) {},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MergeHandler func(*Context, string, *Command, string, *Action) (Handler, Handler)
|
||||||
|
|
||||||
|
func AddMerges(h ...MergeHandler) { Info.merges = append(Info.merges, h...) }
|
||||||
|
59
init.go
59
init.go
@ -12,10 +12,7 @@ import (
|
|||||||
|
|
||||||
type Frame struct{}
|
type Frame struct{}
|
||||||
|
|
||||||
func (f *Frame) Spawn(m *Message, c *Context, arg ...string) Server {
|
func (s *Frame) Begin(m *Message, arg ...string) Server {
|
||||||
return &Frame{}
|
|
||||||
}
|
|
||||||
func (f *Frame) Begin(m *Message, arg ...string) Server {
|
|
||||||
list := map[*Context]*Message{m.target: m}
|
list := map[*Context]*Message{m.target: m}
|
||||||
m.Travel(func(p *Context, s *Context) {
|
m.Travel(func(p *Context, s *Context) {
|
||||||
s.root = m.target
|
s.root = m.target
|
||||||
@ -24,21 +21,20 @@ func (f *Frame) Begin(m *Message, arg ...string) Server {
|
|||||||
s.Begin(list[s], arg...)
|
s.Begin(list[s], arg...)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return f
|
return s
|
||||||
}
|
}
|
||||||
func (f *Frame) Start(m *Message, arg ...string) bool {
|
func (s *Frame) Start(m *Message, arg ...string) bool {
|
||||||
m.Cap(CTX_STREAM, strings.Split(m.Time(), SP)[1])
|
m.Cap(CTX_STREAM, strings.Split(m.Time(), SP)[1])
|
||||||
m.Cmd(kit.Keys(MDB, CTX_INIT))
|
m.Cmd(kit.Keys(MDB, CTX_INIT))
|
||||||
m.Cmd("cli.runtime", CTX_INIT)
|
m.Cmd(kit.Keys(CLI, CTX_INIT))
|
||||||
m.Cmdy(INIT, arg)
|
m.Cmdy(INIT, arg)
|
||||||
|
|
||||||
for _, k := range kit.Split(kit.Select("ctx,log,gdb,ssh", os.Getenv(CTX_DAEMON))) {
|
for _, k := range kit.Split(kit.Select("ctx,log,gdb,ssh", os.Getenv(CTX_DAEMON))) {
|
||||||
m.Start(k)
|
m.Start(k)
|
||||||
}
|
}
|
||||||
m.Cmd(arg)
|
m.Cmdy(arg)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
func (f *Frame) Close(m *Message, arg ...string) bool {
|
func (s *Frame) Close(m *Message, arg ...string) bool {
|
||||||
list := map[*Context]*Message{m.target: m}
|
list := map[*Context]*Message{m.target: m}
|
||||||
m.Travel(func(p *Context, s *Context) {
|
m.Travel(func(p *Context, s *Context) {
|
||||||
if msg, ok := list[p]; ok && msg != nil {
|
if msg, ok := list[p]; ok && msg != nil {
|
||||||
@ -47,9 +43,10 @@ func (f *Frame) Close(m *Message, arg ...string) bool {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
conf.Close()
|
conf.Close()
|
||||||
go func() { m.Sleep("1s"); os.Exit(kit.Int(Pulse.Option(EXIT))) }()
|
go func() { m.Sleep3s(); os.Exit(kit.Int(Pulse.Option(EXIT))) }()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
func (s *Frame) Spawn(m *Message, c *Context, arg ...string) Server { return &Frame{} }
|
||||||
|
|
||||||
const (
|
const (
|
||||||
INIT = "init"
|
INIT = "init"
|
||||||
@ -58,9 +55,7 @@ const (
|
|||||||
QUIT = "quit"
|
QUIT = "quit"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Index = &Context{Name: ICE, Help: "冰山模块", Configs: Configs{
|
var Index = &Context{Name: ICE, Help: "冰山模块", Configs: Configs{HELP: {Value: kit.Data(INDEX, Info.Help)}}, Commands: Commands{
|
||||||
HELP: {Value: kit.Data(INDEX, Info.Help)},
|
|
||||||
}, Commands: Commands{
|
|
||||||
CTX_INIT: {Hand: func(m *Message, arg ...string) {
|
CTX_INIT: {Hand: func(m *Message, arg ...string) {
|
||||||
m.root.Travel(func(p *Context, c *Context) {
|
m.root.Travel(func(p *Context, c *Context) {
|
||||||
if cmd, ok := c.Commands[CTX_INIT]; ok && p != nil {
|
if cmd, ok := c.Commands[CTX_INIT]; ok && p != nil {
|
||||||
@ -68,23 +63,19 @@ var Index = &Context{Name: ICE, Help: "冰山模块", Configs: Configs{
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}},
|
}},
|
||||||
INIT: {Name: "init", Help: "启动", Hand: func(m *Message, arg ...string) {
|
INIT: {Hand: func(m *Message, arg ...string) {
|
||||||
m.root.Cmd(CTX_INIT)
|
m.root.Cmd(CTX_INIT)
|
||||||
m.Cmd("source", ETC_INIT_SHY)
|
m.Cmd(SOURCE, ETC_INIT_SHY)
|
||||||
}},
|
}},
|
||||||
HELP: {Name: "help", Help: "帮助", Hand: func(m *Message, arg ...string) {
|
HELP: {Hand: func(m *Message, arg ...string) { m.Echo(m.Config(INDEX)) }},
|
||||||
m.Echo(m.Config(INDEX))
|
QUIT: {Hand: func(m *Message, arg ...string) { os.Exit(0) }},
|
||||||
}},
|
EXIT: {Hand: func(m *Message, arg ...string) {
|
||||||
QUIT: {Name: "quit", Help: "结束", Hand: func(m *Message, arg ...string) {
|
|
||||||
os.Exit(0)
|
|
||||||
}},
|
|
||||||
EXIT: {Name: "exit", Help: "退出", Hand: func(m *Message, arg ...string) {
|
|
||||||
defer m.Target().Close(m.root.Spawn(), arg...)
|
|
||||||
m.root.Option(EXIT, kit.Select("0", arg, 0))
|
m.root.Option(EXIT, kit.Select("0", arg, 0))
|
||||||
m.Cmd("source", ETC_EXIT_SHY)
|
m.Cmd(SOURCE, ETC_EXIT_SHY)
|
||||||
m.root.Cmd(CTX_EXIT)
|
m.root.Cmd(CTX_EXIT)
|
||||||
}},
|
}},
|
||||||
CTX_EXIT: {Hand: func(m *Message, arg ...string) {
|
CTX_EXIT: {Hand: func(m *Message, arg ...string) {
|
||||||
|
defer m.Target().Close(m.root.Spawn(), arg...)
|
||||||
m.root.Travel(func(p *Context, c *Context) {
|
m.root.Travel(func(p *Context, c *Context) {
|
||||||
if cmd, ok := c.Commands[CTX_EXIT]; ok && p != nil {
|
if cmd, ok := c.Commands[CTX_EXIT]; ok && p != nil {
|
||||||
m.TryCatch(m.Spawn(c), true, func(msg *Message) {
|
m.TryCatch(m.Spawn(c), true, func(msg *Message) {
|
||||||
@ -102,30 +93,26 @@ var Pulse = &Message{time: time.Now(), code: 0,
|
|||||||
func init() { Index.root, Pulse.root = Index, Pulse }
|
func init() { Index.root, Pulse.root = Index, Pulse }
|
||||||
|
|
||||||
func Run(arg ...string) string {
|
func Run(arg ...string) string {
|
||||||
if len(arg) == 0 { // 进程参数
|
if len(arg) == 0 && len(os.Args) > 1 {
|
||||||
arg = kit.Simple(arg, os.Args[1:], kit.Split(os.Getenv(CTX_ARG)))
|
arg = kit.Simple(os.Args[1:], kit.Split(kit.Env(CTX_ARG)))
|
||||||
}
|
}
|
||||||
|
|
||||||
Pulse.meta[MSG_DETAIL] = arg
|
Pulse.meta[MSG_DETAIL] = arg
|
||||||
switch Index.Merge(Index).Begin(Pulse.Spawn(), arg...); kit.Select("", arg, 0) {
|
switch Index.Merge(Index).Begin(Pulse, arg...); kit.Select("", arg, 0) {
|
||||||
case "serve", "space": // 启动服务
|
case SERVE, SPACE:
|
||||||
if Index.Start(Pulse, arg...) {
|
if Index.Start(Pulse, arg...) {
|
||||||
conf.Wait()
|
conf.Wait()
|
||||||
println()
|
|
||||||
os.Exit(kit.Int(Pulse.Option(EXIT)))
|
os.Exit(kit.Int(Pulse.Option(EXIT)))
|
||||||
}
|
}
|
||||||
default: // 执行命令
|
default:
|
||||||
if logs.Disable(true); len(arg) == 0 {
|
if logs.Disable(true); len(arg) == 0 {
|
||||||
arg = append(arg, HELP)
|
arg = append(arg, HELP)
|
||||||
}
|
}
|
||||||
Pulse.Cmd(INIT)
|
if Pulse.Cmd(INIT).Cmdy(arg); strings.TrimSpace(Pulse.Result()) == "" {
|
||||||
if Pulse.Cmdy(arg); strings.TrimSpace(Pulse.Result()) == "" {
|
|
||||||
Pulse.Table()
|
Pulse.Table()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if !strings.HasSuffix(Pulse.Result(), NL) {
|
if !strings.HasSuffix(Pulse.Result(), NL) {
|
||||||
Pulse.Echo(NL)
|
Pulse.Echo(NL)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return Pulse.Result()
|
return Pulse.Result()
|
||||||
}
|
}
|
||||||
|
54
logs.go
54
logs.go
@ -29,27 +29,21 @@ func (m *Message) join(arg ...Any) (string, []Any) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
switch v := arg[i+1].(type) {
|
switch v := arg[i+1].(type) {
|
||||||
case logs.Meta:
|
|
||||||
list = append(list, key)
|
|
||||||
meta = append(meta, v)
|
|
||||||
continue
|
|
||||||
case time.Time:
|
case time.Time:
|
||||||
arg[i+1] = v.Format(MOD_TIME)
|
arg[i+1] = v.Format(MOD_TIME)
|
||||||
}
|
}
|
||||||
list = append(list, key+kit.Select("", DF, !strings.HasSuffix(key, DF)), kit.Format(kit.Select("", kit.Simple(arg[i+1]), 0)))
|
list = append(list, key+kit.Select("", DF, !strings.Contains(key, DF)), kit.Format(arg[i+1]))
|
||||||
}
|
}
|
||||||
return kit.Join(list, SP), meta
|
return kit.Join(list, SP), meta
|
||||||
}
|
}
|
||||||
func (m *Message) log(level string, str string, arg ...Any) *Message {
|
func (m *Message) log(level string, str string, arg ...Any) *Message {
|
||||||
_source := logs.FileLineMeta(logs.FileLine(3, 3))
|
_source := logs.FileLineMeta(logs.FileLine(3, 3))
|
||||||
if Info.Log != nil {
|
if Info.Log != nil {
|
||||||
Info.Log(m, m.FormatPrefix(), level, logs.Format(str, append(arg, _source)...)) // 日志回调
|
Info.Log(m, m.FormatPrefix(), level, logs.Format(str, append(arg, _source)...))
|
||||||
}
|
}
|
||||||
if m.Option("log.disable") == TRUE {
|
if m.Option(LOG_DISABLE) == TRUE {
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
// 日志颜色
|
|
||||||
prefix, suffix := "", ""
|
prefix, suffix := "", ""
|
||||||
if Info.Colors {
|
if Info.Colors {
|
||||||
switch level {
|
switch level {
|
||||||
@ -57,20 +51,16 @@ func (m *Message) log(level string, str string, arg ...Any) *Message {
|
|||||||
prefix, suffix = "\033[32m", "\033[0m"
|
prefix, suffix = "\033[32m", "\033[0m"
|
||||||
case LOG_AUTH, LOG_COST:
|
case LOG_AUTH, LOG_COST:
|
||||||
prefix, suffix = "\033[33m", "\033[0m"
|
prefix, suffix = "\033[33m", "\033[0m"
|
||||||
case LOG_WARN:
|
case LOG_WARN, LOG_ERROR:
|
||||||
prefix, suffix = "\033[31m", "\033[0m"
|
prefix, suffix = "\033[31m", "\033[0m"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 长度截断
|
|
||||||
switch level {
|
switch level {
|
||||||
case LOG_INFO:
|
case LOG_INFO:
|
||||||
if len(str) > 4096 {
|
if len(str) > 4096 {
|
||||||
str = str[:4096]
|
str = str[:4096]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 输出日志
|
|
||||||
logs.Infof(str, append(arg, logs.PrefixMeta(kit.Format("%02d %4s->%-4s %s%s ", m.code, m.source.Name, m.target.Name, prefix, level)), logs.SuffixMeta(suffix), _source)...)
|
logs.Infof(str, append(arg, logs.PrefixMeta(kit.Format("%02d %4s->%-4s %s%s ", m.code, m.source.Name, m.target.Name, prefix, level)), logs.SuffixMeta(suffix), _source)...)
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
@ -116,32 +106,26 @@ func (m *Message) Warn(err Any, arg ...Any) bool {
|
|||||||
if !m.IsErr() {
|
if !m.IsErr() {
|
||||||
if m.error(arg...); len(arg) > 0 {
|
if m.error(arg...); len(arg) > 0 {
|
||||||
switch kit.Format(arg[0]) {
|
switch kit.Format(arg[0]) {
|
||||||
case ErrNotValid:
|
|
||||||
m.RenderStatusBadRequest(str)
|
|
||||||
case ErrNotLogin:
|
case ErrNotLogin:
|
||||||
m.RenderStatusUnauthorized(str)
|
m.RenderStatusUnauthorized(str)
|
||||||
case ErrNotRight:
|
case ErrNotRight:
|
||||||
m.RenderStatusForbidden(str)
|
m.RenderStatusForbidden(str)
|
||||||
case ErrNotFound:
|
case ErrNotFound:
|
||||||
m.RenderStatusNotFound(str)
|
m.RenderStatusNotFound(str)
|
||||||
|
case ErrNotValid:
|
||||||
|
m.RenderStatusBadRequest(str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
func (m *Message) Debug(str string, arg ...Any) {
|
|
||||||
if str == "" {
|
|
||||||
str = m.FormatMeta()
|
|
||||||
}
|
|
||||||
m.log(LOG_DEBUG, str, arg...)
|
|
||||||
}
|
|
||||||
func (m *Message) Error(err bool, arg ...Any) bool {
|
func (m *Message) Error(err bool, arg ...Any) bool {
|
||||||
if err {
|
if err {
|
||||||
m.error(arg...)
|
|
||||||
m.log(LOG_ERROR, m.FormatStack(1, 100))
|
|
||||||
str, meta := m.join(arg...)
|
str, meta := m.join(arg...)
|
||||||
m.log(LOG_ERROR, str, meta)
|
|
||||||
m.log(LOG_ERROR, m.FormatChain())
|
m.log(LOG_ERROR, m.FormatChain())
|
||||||
|
m.log(LOG_ERROR, str, meta)
|
||||||
|
m.log(LOG_ERROR, m.FormatStack(1, 100))
|
||||||
|
m.error(arg...)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
@ -156,12 +140,19 @@ func (m *Message) error(arg ...Any) {
|
|||||||
arg = append(arg, "")
|
arg = append(arg, "")
|
||||||
}
|
}
|
||||||
str, meta := m.join(arg[2:]...)
|
str, meta := m.join(arg[2:]...)
|
||||||
m.meta[MSG_RESULT] = kit.Simple(ErrWarn, arg[0], arg[1], str, meta)
|
m.Resultv(ErrWarn, arg[0], arg[1], str, meta)
|
||||||
|
}
|
||||||
|
func (m *Message) IsErrNotFound() bool {
|
||||||
|
return m.IsErr(ErrNotFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Message) IsErrNotFound() bool { return m.IsErr(ErrNotFound) }
|
|
||||||
func (m *Message) IsErr(arg ...string) bool {
|
func (m *Message) IsErr(arg ...string) bool {
|
||||||
return len(arg) > 0 && m.Result(1) == arg[0] || len(arg) == 0 && m.Result(0) == ErrWarn
|
return len(arg) == 0 && m.Result(0) == ErrWarn || len(arg) > 0 && m.Result(1) == arg[0]
|
||||||
|
}
|
||||||
|
func (m *Message) Debug(str string, arg ...Any) {
|
||||||
|
if str == "" {
|
||||||
|
str = m.FormatMeta()
|
||||||
|
}
|
||||||
|
m.log(LOG_DEBUG, str, arg...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Message) FormatPrefix() string {
|
func (m *Message) FormatPrefix() string {
|
||||||
@ -187,7 +178,6 @@ func (m *Message) FormatChain() string {
|
|||||||
for msg := m; msg != nil; msg = msg.message {
|
for msg := m; msg != nil; msg = msg.message {
|
||||||
ms = append(ms, msg)
|
ms = append(ms, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
meta := append([]string{}, NL)
|
meta := append([]string{}, NL)
|
||||||
for i := len(ms) - 1; i >= 0; i-- {
|
for i := len(ms) - 1; i >= 0; i-- {
|
||||||
msg := ms[i]
|
msg := ms[i]
|
||||||
@ -213,20 +203,16 @@ func (m *Message) FormatChain() string {
|
|||||||
func (m *Message) FormatStack(s, n int) string {
|
func (m *Message) FormatStack(s, n int) string {
|
||||||
pc := make([]uintptr, n+10)
|
pc := make([]uintptr, n+10)
|
||||||
frames := runtime.CallersFrames(pc[:runtime.Callers(s+1, pc)])
|
frames := runtime.CallersFrames(pc[:runtime.Callers(s+1, pc)])
|
||||||
|
|
||||||
list := []string{}
|
list := []string{}
|
||||||
for {
|
for {
|
||||||
frame, more := frames.Next()
|
frame, more := frames.Next()
|
||||||
file := kit.Slice(kit.Split(frame.File, PS, PS), -1)[0]
|
file := kit.Slice(kit.Split(frame.File, PS, PS), -1)[0]
|
||||||
name := kit.Slice(kit.Split(frame.Function, PS, PS), -1)[0]
|
name := kit.Slice(kit.Split(frame.Function, PS, PS), -1)[0]
|
||||||
|
|
||||||
switch ls := kit.Split(name, PT, PT); kit.Select("", ls, 0) {
|
switch ls := kit.Split(name, PT, PT); kit.Select("", ls, 0) {
|
||||||
// case "reflect", "runtime", "http", "task", "icebergs":
|
|
||||||
case "reflect", "runtime", "http":
|
case "reflect", "runtime", "http":
|
||||||
default:
|
default:
|
||||||
list = append(list, kit.Format("%s:%d\t%s", file, frame.Line, name))
|
list = append(list, kit.Format("%s:%d\t%s", file, frame.Line, name))
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(list) >= n {
|
if len(list) >= n {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
406
meta.go
406
meta.go
@ -7,51 +7,7 @@ import (
|
|||||||
kit "shylinux.com/x/toolkits"
|
kit "shylinux.com/x/toolkits"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (m *Message) Set(key string, arg ...string) *Message {
|
func (m *Message) setDetail(key string, arg ...string) *Message {
|
||||||
switch key {
|
|
||||||
case MSG_DETAIL, MSG_RESULT:
|
|
||||||
delete(m.meta, key)
|
|
||||||
case MSG_OPTION, MSG_APPEND:
|
|
||||||
if m.FieldsIsDetail() {
|
|
||||||
if len(arg) > 0 {
|
|
||||||
for i := 0; i < len(m.meta[KEY]); i++ {
|
|
||||||
if m.meta[KEY][i] == arg[0] {
|
|
||||||
if len(arg) > 1 {
|
|
||||||
m.meta[VALUE][i] = arg[1]
|
|
||||||
break
|
|
||||||
}
|
|
||||||
for ; i < len(m.meta[KEY])-1; i++ {
|
|
||||||
m.meta[KEY][i] = m.meta[KEY][i+1]
|
|
||||||
m.meta[VALUE][i] = m.meta[VALUE][i+1]
|
|
||||||
}
|
|
||||||
m.meta[KEY] = kit.Slice(m.meta[KEY], 0, -1)
|
|
||||||
m.meta[VALUE] = kit.Slice(m.meta[VALUE], 0, -1)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
delete(m.meta, KEY)
|
|
||||||
delete(m.meta, VALUE)
|
|
||||||
delete(m.meta, MSG_APPEND)
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
if len(arg) > 0 {
|
|
||||||
if delete(m.meta, arg[0]); len(arg) == 1 {
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for _, k := range m.meta[key] {
|
|
||||||
delete(m.meta, k)
|
|
||||||
}
|
|
||||||
delete(m.meta, key)
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
for _, k := range kit.Split(key) {
|
|
||||||
delete(m.meta, k)
|
|
||||||
}
|
|
||||||
if m.FieldsIsDetail() {
|
|
||||||
for i := 0; i < len(m.meta[KEY]); i++ {
|
for i := 0; i < len(m.meta[KEY]); i++ {
|
||||||
if m.meta[KEY][i] == key {
|
if m.meta[KEY][i] == key {
|
||||||
if len(arg) > 0 {
|
if len(arg) > 0 {
|
||||||
@ -68,7 +24,41 @@ func (m *Message) Set(key string, arg ...string) *Message {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return m
|
return m
|
||||||
|
}
|
||||||
|
func (m *Message) Set(key string, arg ...string) *Message {
|
||||||
|
switch key {
|
||||||
|
case MSG_DETAIL, MSG_RESULT:
|
||||||
|
delete(m.meta, key)
|
||||||
|
case MSG_OPTION, MSG_APPEND:
|
||||||
|
if m.FieldsIsDetail() {
|
||||||
|
if len(arg) > 0 {
|
||||||
|
m.setDetail(arg[0], arg[1:]...)
|
||||||
|
} else {
|
||||||
|
delete(m.meta, KEY)
|
||||||
|
delete(m.meta, VALUE)
|
||||||
|
delete(m.meta, MSG_APPEND)
|
||||||
}
|
}
|
||||||
|
} else if len(arg) > 0 {
|
||||||
|
if delete(m.meta, arg[0]); len(arg) > 1 {
|
||||||
|
m.meta[arg[0]] = arg[1:]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for _, k := range m.meta[key] {
|
||||||
|
delete(m.meta, k)
|
||||||
|
}
|
||||||
|
delete(m.meta, key)
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
default:
|
||||||
|
if m.FieldsIsDetail() {
|
||||||
|
return m.setDetail(key, arg...)
|
||||||
|
}
|
||||||
|
for _, k := range kit.Split(key) {
|
||||||
|
delete(m.meta, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(arg) == 0 {
|
||||||
|
return m
|
||||||
}
|
}
|
||||||
return m.Add(key, arg...)
|
return m.Add(key, arg...)
|
||||||
}
|
}
|
||||||
@ -76,21 +66,15 @@ func (m *Message) Add(key string, arg ...string) *Message {
|
|||||||
switch key {
|
switch key {
|
||||||
case MSG_DETAIL, MSG_RESULT:
|
case MSG_DETAIL, MSG_RESULT:
|
||||||
m.meta[key] = append(m.meta[key], arg...)
|
m.meta[key] = append(m.meta[key], arg...)
|
||||||
|
|
||||||
case MSG_OPTION, MSG_APPEND:
|
case MSG_OPTION, MSG_APPEND:
|
||||||
if len(arg) == 0 {
|
if len(arg) == 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if key == MSG_APPEND {
|
if index := 0; key == MSG_APPEND {
|
||||||
if i := kit.IndexOf(m.meta[MSG_OPTION], arg[0]); i > -1 {
|
if m.meta[MSG_OPTION], index = kit.SliceRemove(m.meta[MSG_OPTION], arg[0]); index > -1 {
|
||||||
m.meta[MSG_OPTION][i] = ""
|
|
||||||
delete(m.meta, arg[0])
|
delete(m.meta, arg[0])
|
||||||
}
|
}
|
||||||
if kit.IndexOf(m.meta[key], arg[0]) == -1 {
|
|
||||||
m.meta[arg[0]] = []string{}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if kit.IndexOf(m.meta[key], arg[0]) == -1 {
|
if kit.IndexOf(m.meta[key], arg[0]) == -1 {
|
||||||
m.meta[key] = append(m.meta[key], arg[0])
|
m.meta[key] = append(m.meta[key], arg[0])
|
||||||
}
|
}
|
||||||
@ -116,20 +100,16 @@ func (m *Message) Push(key string, value Any, arg ...Any) *Message {
|
|||||||
if len(head) == 0 && !m.FieldsIsDetail() {
|
if len(head) == 0 && !m.FieldsIsDetail() {
|
||||||
head = kit.Split(m.OptionFields())
|
head = kit.Split(m.OptionFields())
|
||||||
}
|
}
|
||||||
|
|
||||||
switch value := value.(type) {
|
switch value := value.(type) {
|
||||||
case Map:
|
case Map:
|
||||||
if len(head) == 0 { // 键值排序
|
if len(head) == 0 {
|
||||||
head = kit.SortedKey(kit.KeyValue(Map{}, "", value))
|
head = kit.SortedKey(kit.KeyValue(nil, "", value))
|
||||||
}
|
}
|
||||||
|
|
||||||
var val Map
|
var val Map
|
||||||
if len(arg) > 1 {
|
if len(arg) > 1 {
|
||||||
val, _ = arg[1].(Map)
|
val, _ = arg[1].(Map)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, k := range head {
|
for _, k := range head {
|
||||||
// 查找数据
|
|
||||||
var v Any
|
var v Any
|
||||||
switch k {
|
switch k {
|
||||||
case KEY, HASH:
|
case KEY, HASH:
|
||||||
@ -158,50 +138,42 @@ func (m *Message) Push(key string, value Any, arg ...Any) *Message {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 追加数据
|
|
||||||
switch v := kit.Format(v); key {
|
switch v := kit.Format(v); key {
|
||||||
case FIELDS_DETAIL:
|
case FIELDS_DETAIL:
|
||||||
switch k {
|
switch k {
|
||||||
case "_target":
|
case "_target":
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
m.Add(MSG_APPEND, KEY, strings.TrimPrefix(k, "extra."))
|
m.Add(MSG_APPEND, KEY, strings.TrimPrefix(k, EXTRA+PT))
|
||||||
m.Add(MSG_APPEND, VALUE, v)
|
m.Add(MSG_APPEND, VALUE, v)
|
||||||
default:
|
default:
|
||||||
m.Add(MSG_APPEND, k, v)
|
m.Add(MSG_APPEND, k, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case Maps:
|
case Maps:
|
||||||
if len(head) == 0 { // 键值排序
|
if len(head) == 0 {
|
||||||
head = kit.SortedKey(value)
|
head = kit.SortedKey(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, k := range head {
|
for _, k := range head {
|
||||||
m.Push(k, value[k])
|
m.Push(k, value[k])
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
for _, v := range kit.Simple(value, arg) {
|
for _, v := range kit.Simple(value, arg) {
|
||||||
if m.FieldsIsDetail() {
|
if m.FieldsIsDetail() {
|
||||||
if key != KEY || key != VALUE {
|
|
||||||
m.Add(MSG_APPEND, KEY, key)
|
m.Add(MSG_APPEND, KEY, key)
|
||||||
m.Add(MSG_APPEND, VALUE, kit.Format(value))
|
m.Add(MSG_APPEND, VALUE, kit.Format(value))
|
||||||
continue
|
} else {
|
||||||
}
|
|
||||||
}
|
|
||||||
m.Add(MSG_APPEND, key, v)
|
m.Add(MSG_APPEND, key, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
func (m *Message) Echo(str string, arg ...Any) *Message {
|
func (m *Message) Echo(str string, arg ...Any) *Message {
|
||||||
if str == "" {
|
if str == "" {
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
m.meta[MSG_RESULT] = append(m.meta[MSG_RESULT], kit.Format(str, arg...))
|
return m.Add(MSG_RESULT, kit.Format(str, arg...))
|
||||||
return m
|
|
||||||
}
|
}
|
||||||
func (m *Message) Copy(msg *Message, arg ...string) *Message {
|
func (m *Message) Copy(msg *Message, arg ...string) *Message {
|
||||||
if m == nil || msg == nil || m == msg {
|
if m == nil || msg == nil || m == msg {
|
||||||
@ -213,12 +185,9 @@ func (m *Message) Copy(msg *Message, arg ...string) *Message {
|
|||||||
}
|
}
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, k := range msg.meta[MSG_OPTION] {
|
for _, k := range msg.meta[MSG_OPTION] {
|
||||||
switch k {
|
switch k {
|
||||||
case MSG_CMDS:
|
case MSG_CMDS, MSG_FIELDS, MSG_SESSID:
|
||||||
case MSG_FIELDS:
|
|
||||||
case MSG_SESSID:
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if v, ok := msg.data[k]; ok {
|
if v, ok := msg.data[k]; ok {
|
||||||
@ -231,8 +200,7 @@ func (m *Message) Copy(msg *Message, arg ...string) *Message {
|
|||||||
for _, k := range msg.meta[MSG_APPEND] {
|
for _, k := range msg.meta[MSG_APPEND] {
|
||||||
m.Add(MSG_APPEND, kit.Simple(k, msg.meta[k])...)
|
m.Add(MSG_APPEND, kit.Simple(k, msg.meta[k])...)
|
||||||
}
|
}
|
||||||
m.meta[MSG_RESULT] = append(m.meta[MSG_RESULT], msg.meta[MSG_RESULT]...)
|
return m.Add(MSG_RESULT, msg.meta[MSG_RESULT]...)
|
||||||
return m
|
|
||||||
}
|
}
|
||||||
func (m *Message) Length() (max int) {
|
func (m *Message) Length() (max int) {
|
||||||
for _, k := range m.meta[MSG_APPEND] {
|
for _, k := range m.meta[MSG_APPEND] {
|
||||||
@ -245,49 +213,49 @@ func (m *Message) Length() (max int) {
|
|||||||
func (m *Message) Tables(cbs ...func(value Maps)) *Message {
|
func (m *Message) Tables(cbs ...func(value Maps)) *Message {
|
||||||
return m.Table(func(index int, value Maps, head []string) {
|
return m.Table(func(index int, value Maps, head []string) {
|
||||||
for _, cb := range cbs {
|
for _, cb := range cbs {
|
||||||
if cb != nil {
|
|
||||||
cb(value)
|
cb(value)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
func (m *Message) Table(cbs ...func(index int, value Maps, head []string)) *Message {
|
func (m *Message) Table(cbs ...func(index int, value Maps, head []string)) *Message {
|
||||||
if len(cbs) > 0 && cbs[0] != nil {
|
if len(cbs) > 0 && cbs[0] != nil {
|
||||||
if m.FieldsIsDetail() {
|
|
||||||
if m.Length() == 0 {
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
line := Maps{}
|
|
||||||
for i, k := range m.meta[KEY] {
|
|
||||||
line[k] = kit.Select("", m.meta[VALUE], i)
|
|
||||||
}
|
|
||||||
cbs[0](0, line, m.meta[KEY])
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
|
|
||||||
n := m.Length()
|
n := m.Length()
|
||||||
for i := 0; i < n; i++ {
|
if n == 0 {
|
||||||
line := Maps{}
|
return m
|
||||||
for _, k := range m.meta[MSG_APPEND] {
|
}
|
||||||
line[k] = kit.Select("", m.meta[k], i)
|
if m.FieldsIsDetail() {
|
||||||
|
value := Maps{}
|
||||||
|
for i, k := range m.meta[KEY] {
|
||||||
|
value[k] = kit.Select("", m.meta[VALUE], i)
|
||||||
|
}
|
||||||
|
for _, cb := range cbs {
|
||||||
|
cb(0, value, m.meta[KEY])
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
value := Maps{}
|
||||||
|
for _, k := range m.meta[MSG_APPEND] {
|
||||||
|
value[k] = kit.Select("", m.meta[k], i)
|
||||||
|
}
|
||||||
|
for _, cb := range cbs {
|
||||||
|
cb(i, value, m.meta[MSG_APPEND])
|
||||||
}
|
}
|
||||||
cbs[0](i, line, m.meta[MSG_APPEND])
|
|
||||||
}
|
}
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
TABLE_SPACE = "table.space"
|
TABLE_SPACE = "table.space"
|
||||||
TABLE_ROW_SEP = "table.row_sep"
|
TABLE_ROW_SEP = "table.row_sep"
|
||||||
TABLE_COL_SEP = "table.col_sep"
|
TABLE_COL_SEP = "table.col_sep"
|
||||||
TABLE_COMPACT = "table.compact"
|
TABLE_COMPACT = "table.compact"
|
||||||
|
TABLE_ALIGN = "table.align"
|
||||||
)
|
)
|
||||||
//计算列宽
|
|
||||||
space := kit.Select(SP, m.Option(TABLE_SPACE))
|
space := kit.Select(SP, m.Option(TABLE_SPACE))
|
||||||
depth, width := 0, map[string]int{}
|
length, width := 0, map[string]int{}
|
||||||
for _, k := range m.meta[MSG_APPEND] {
|
for _, k := range m.meta[MSG_APPEND] {
|
||||||
if len(m.meta[k]) > depth {
|
if len(m.meta[k]) > length {
|
||||||
depth = len(m.meta[k])
|
length = len(m.meta[k])
|
||||||
}
|
}
|
||||||
width[k] = kit.Width(k, len(space))
|
width[k] = kit.Width(k, len(space))
|
||||||
for _, v := range m.meta[k] {
|
for _, v := range m.meta[k] {
|
||||||
@ -296,165 +264,128 @@ func (m *Message) Table(cbs ...func(index int, value Maps, head []string)) *Mess
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 回调函数
|
|
||||||
rows := kit.Select(NL, m.Option(TABLE_ROW_SEP))
|
rows := kit.Select(NL, m.Option(TABLE_ROW_SEP))
|
||||||
cols := kit.Select(SP, m.Option(TABLE_COL_SEP))
|
cols := kit.Select(SP, m.Option(TABLE_COL_SEP))
|
||||||
compact := m.Option(TABLE_COMPACT) == TRUE
|
show := func(value []string) {
|
||||||
cb := func(value Maps, field []string, index int) bool {
|
for i, v := range value {
|
||||||
for i, v := range field {
|
if m.Echo(v); i < len(value)-1 {
|
||||||
if k := m.meta[MSG_APPEND][i]; compact {
|
|
||||||
v = value[k]
|
|
||||||
}
|
|
||||||
|
|
||||||
if m.Echo(v); i < len(field)-1 {
|
|
||||||
m.Echo(cols)
|
m.Echo(cols)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m.Echo(rows)
|
m.Echo(rows)
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
compact := m.Option(TABLE_COMPACT) == TRUE
|
||||||
// 输出表头
|
_align := kit.Select("left", m.Option(TABLE_ALIGN))
|
||||||
row, wor := Maps{}, []string{}
|
align := func(value string, width int) string {
|
||||||
for _, k := range m.meta[MSG_APPEND] {
|
if compact {
|
||||||
row[k], wor = k, append(wor, k+strings.Repeat(space, width[k]-kit.Width(k, len(space))))
|
return value + space
|
||||||
}
|
}
|
||||||
if !cb(row, wor, -1) {
|
n := width - kit.Width(value, len(space))
|
||||||
return m
|
switch _align {
|
||||||
|
case "left":
|
||||||
|
return value + strings.Repeat(space, n)
|
||||||
|
case "right":
|
||||||
|
return strings.Repeat(space, n) + value
|
||||||
|
case "center":
|
||||||
|
return strings.Repeat(space, n/2) + value + strings.Repeat(space, n-n/2)
|
||||||
}
|
}
|
||||||
|
return value + space
|
||||||
// 输出数据
|
|
||||||
for i := 0; i < depth; i++ {
|
|
||||||
row, wor := Maps{}, []string{}
|
|
||||||
for _, k := range m.meta[MSG_APPEND] {
|
|
||||||
data := ""
|
|
||||||
if i < len(m.meta[k]) {
|
|
||||||
data = m.meta[k][i]
|
|
||||||
}
|
|
||||||
|
|
||||||
row[k], wor = data, append(wor, data+strings.Repeat(space, width[k]-kit.Width(data, len(space))))
|
|
||||||
}
|
|
||||||
if !cb(row, wor, i) {
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
|
show(kit.Simple(m.meta[MSG_APPEND], func(k string) string { return align(k, width[k]) }))
|
||||||
|
for i := 0; i < length; i++ {
|
||||||
|
show(kit.Simple(m.meta[MSG_APPEND], func(k string) string { return align(kit.Select("", m.meta[k], i), width[k]) }))
|
||||||
}
|
}
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
func (m *Message) Sort(key string, arg ...string) *Message {
|
|
||||||
ls := kit.Split(key)
|
const (
|
||||||
if key = ls[0]; m.FieldsIsDetail() && key != KEY {
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
const (
|
|
||||||
STR = "str"
|
|
||||||
INT = "int"
|
INT = "int"
|
||||||
TIME = "time"
|
STR = "str"
|
||||||
|
// TIME = "time"
|
||||||
|
|
||||||
TIME_R = "time_r"
|
TIME_R = "time_r"
|
||||||
INT_R = "int_r"
|
|
||||||
STR_R = "str_r"
|
STR_R = "str_r"
|
||||||
|
INT_R = "int_r"
|
||||||
|
)
|
||||||
|
|
||||||
GT = ">"
|
func (m *Message) Sort(key string, arg ...string) *Message {
|
||||||
LT = "<"
|
if m.FieldsIsDetail() {
|
||||||
)
|
return m
|
||||||
|
}
|
||||||
// 排序方法
|
keys, cmps := kit.Split(key), kit.Simple()
|
||||||
cmp := STR
|
for i, k := range keys {
|
||||||
if len(arg) > 0 && arg[0] != "" {
|
cmp := kit.Select("", arg, i)
|
||||||
cmp = arg[0]
|
if cmp == "" {
|
||||||
} else {
|
|
||||||
cmp = INT
|
cmp = INT
|
||||||
for _, v := range m.meta[key] {
|
for _, v := range m.meta[k] {
|
||||||
if _, e := strconv.Atoi(v); e != nil {
|
if _, e := strconv.Atoi(v); e != nil {
|
||||||
cmp = STR
|
cmp = STR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
cmps = append(cmps, cmp)
|
||||||
// 排序因子
|
|
||||||
number := map[int]int64{}
|
|
||||||
table := []Maps{}
|
|
||||||
m.Table(func(index int, value Maps, head []string) {
|
|
||||||
switch table = append(table, value); cmp {
|
|
||||||
case INT:
|
|
||||||
number[index] = kit.Int64(value[key])
|
|
||||||
case INT_R:
|
|
||||||
number[index] = -kit.Int64(value[key])
|
|
||||||
case TIME:
|
|
||||||
number[index] = int64(kit.Time(value[key]))
|
|
||||||
case TIME_R:
|
|
||||||
number[index] = -int64(kit.Time(value[key]))
|
|
||||||
}
|
}
|
||||||
})
|
list := []Maps{}
|
||||||
compare := func(i, j int, op string) bool {
|
m.Tables(func(value Maps) { list = append(list, value) })
|
||||||
for k := range ls {
|
gt := func(i, j int) bool {
|
||||||
if k == 0 {
|
for s, k := range keys {
|
||||||
|
a, b := list[i][k], list[j][k]
|
||||||
|
if a == b {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if table[i][ls[k]] == table[j][ls[k]] {
|
switch cmp := cmps[s]; cmp {
|
||||||
continue
|
case INT, INT_R:
|
||||||
|
if kit.Int(a) > kit.Int(b) {
|
||||||
|
return cmp == INT
|
||||||
|
}
|
||||||
|
if kit.Int(a) < kit.Int(b) {
|
||||||
|
return cmp == INT_R
|
||||||
|
}
|
||||||
|
case STR, STR_R:
|
||||||
|
if a > b {
|
||||||
|
return cmp == STR
|
||||||
|
}
|
||||||
|
if a < b {
|
||||||
|
return cmp == STR_R
|
||||||
|
}
|
||||||
|
case TIME, TIME_R:
|
||||||
|
if kit.Time(a) > kit.Time(b) {
|
||||||
|
return cmp == TIME
|
||||||
|
}
|
||||||
|
if kit.Time(a) < kit.Time(b) {
|
||||||
|
return cmp == TIME_R
|
||||||
}
|
}
|
||||||
if op == GT && table[i][ls[k]] > table[j][ls[k]] {
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
if op == LT && table[i][ls[k]] < table[j][ls[k]] {
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return false
|
for i := 0; i < len(list)-1; i++ {
|
||||||
}
|
min := i
|
||||||
|
for j := i + 1; j < len(list); j++ {
|
||||||
// 排序数据
|
if gt(min, j) {
|
||||||
for i := 0; i < len(table)-1; i++ {
|
min = j
|
||||||
for j := i + 1; j < len(table); j++ {
|
|
||||||
swap := false
|
|
||||||
switch cmp {
|
|
||||||
case "", STR:
|
|
||||||
if table[i][key] > table[j][key] {
|
|
||||||
swap = true
|
|
||||||
} else if table[i][key] == table[j][key] && compare(i, j, GT) {
|
|
||||||
swap = true
|
|
||||||
}
|
|
||||||
case STR_R:
|
|
||||||
if table[i][key] < table[j][key] {
|
|
||||||
swap = true
|
|
||||||
} else if table[i][key] == table[j][key] && compare(i, j, LT) {
|
|
||||||
swap = true
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
if number[i] > number[j] {
|
|
||||||
swap = true
|
|
||||||
} else if table[i][key] == table[j][key] && compare(i, j, GT) {
|
|
||||||
swap = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if min != i {
|
||||||
if swap {
|
list[i], list[min] = list[min], list[i]
|
||||||
table[i], table[j] = table[j], table[i]
|
|
||||||
number[i], number[j] = number[j], number[i]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// 输出数据
|
|
||||||
for _, k := range m.meta[MSG_APPEND] {
|
for _, k := range m.meta[MSG_APPEND] {
|
||||||
delete(m.meta, k)
|
delete(m.meta, k)
|
||||||
}
|
}
|
||||||
for _, v := range table {
|
for _, v := range list {
|
||||||
for _, k := range m.meta[MSG_APPEND] {
|
for _, k := range m.meta[MSG_APPEND] {
|
||||||
m.Add(MSG_APPEND, k, v[k])
|
m.Add(MSG_APPEND, k, v[k])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
func (m *Message) SortInt(key string) { m.Sort(key, "int") }
|
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) SortStr(key string) { m.Sort(key, "str") }
|
func (m *Message) SortTime(key string) { m.Sort(key, TIME) }
|
||||||
func (m *Message) SortStrR(key string) { m.Sort(key, "str_r") }
|
func (m *Message) SortTimeR(key string) { m.Sort(key, TIME_R) }
|
||||||
func (m *Message) SortTime(key string) { m.Sort(key, "time") }
|
func (m *Message) SortStrR(key string) { m.Sort(key, STR_R) }
|
||||||
func (m *Message) SortTimeR(key string) { m.Sort(key, "time_r") }
|
func (m *Message) SortIntR(key string) { m.Sort(key, INT_R) }
|
||||||
|
|
||||||
func (m *Message) Detail(arg ...Any) string {
|
func (m *Message) Detail(arg ...Any) string {
|
||||||
return kit.Select("", m.meta[MSG_DETAIL], 0)
|
return kit.Select("", m.meta[MSG_DETAIL], 0)
|
||||||
@ -462,37 +393,38 @@ func (m *Message) Detail(arg ...Any) string {
|
|||||||
func (m *Message) Detailv(arg ...Any) []string {
|
func (m *Message) Detailv(arg ...Any) []string {
|
||||||
return m.meta[MSG_DETAIL]
|
return m.meta[MSG_DETAIL]
|
||||||
}
|
}
|
||||||
|
func (m *Message) Options(arg ...Any) Any {
|
||||||
|
for i := 0; i < len(arg)-1; i += 2 {
|
||||||
|
m.Optionv(kit.Format(arg[i]), arg[i+1])
|
||||||
|
}
|
||||||
|
return m.Optionv(kit.Format(arg[0]))
|
||||||
|
}
|
||||||
func (m *Message) Optionv(key string, arg ...Any) Any {
|
func (m *Message) Optionv(key string, arg ...Any) Any {
|
||||||
if len(arg) > 0 {
|
if len(arg) > 0 {
|
||||||
if kit.IndexOf(m.meta[MSG_OPTION], key) == -1 { // 写数据
|
if kit.IndexOf(m.meta[MSG_OPTION], key) == -1 {
|
||||||
m.meta[MSG_OPTION] = append(m.meta[MSG_OPTION], key)
|
m.meta[MSG_OPTION] = append(m.meta[MSG_OPTION], key)
|
||||||
}
|
}
|
||||||
|
switch delete(m.data, key); v := arg[0].(type) {
|
||||||
switch delete(m.data, key); str := arg[0].(type) {
|
|
||||||
case nil:
|
case nil:
|
||||||
delete(m.meta, key)
|
delete(m.meta, key)
|
||||||
case string:
|
case string:
|
||||||
m.meta[key] = kit.Simple(arg...)
|
m.meta[key] = kit.Simple(arg...)
|
||||||
case []string:
|
case []string:
|
||||||
m.meta[key] = str
|
m.meta[key] = v
|
||||||
default:
|
default:
|
||||||
m.data[key] = str
|
m.data[key] = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for msg := m; msg != nil; msg = msg.message {
|
for msg := m; msg != nil; msg = msg.message {
|
||||||
if list, ok := msg.data[key]; ok {
|
if v, ok := msg.data[key]; ok {
|
||||||
return list // 读数据
|
return v
|
||||||
}
|
}
|
||||||
if list, ok := msg.meta[key]; ok {
|
if v, ok := msg.meta[key]; ok {
|
||||||
return list // 读选项
|
return v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func (m *Message) Message() *Message {
|
|
||||||
return m.message
|
|
||||||
}
|
|
||||||
func (m *Message) Option(key string, arg ...Any) string {
|
func (m *Message) Option(key string, arg ...Any) string {
|
||||||
return kit.Select("", kit.Simple(m.Optionv(key, arg...)), 0)
|
return kit.Select("", kit.Simple(m.Optionv(key, arg...)), 0)
|
||||||
}
|
}
|
||||||
@ -503,14 +435,7 @@ func (m *Message) Append(key string, arg ...Any) string {
|
|||||||
return kit.Select("", m.Appendv(key, arg...), 0)
|
return kit.Select("", m.Appendv(key, arg...), 0)
|
||||||
}
|
}
|
||||||
func (m *Message) Appendv(key string, arg ...Any) []string {
|
func (m *Message) Appendv(key string, arg ...Any) []string {
|
||||||
if key == MSG_APPEND {
|
if m.FieldsIsDetail() {
|
||||||
if len(arg) > 0 {
|
|
||||||
m.meta[MSG_APPEND] = kit.Simple(arg)
|
|
||||||
}
|
|
||||||
return m.meta[key]
|
|
||||||
}
|
|
||||||
|
|
||||||
if m.FieldsIsDetail() && key != KEY {
|
|
||||||
for i, k := range m.meta[KEY] {
|
for i, k := range m.meta[KEY] {
|
||||||
if k == key || k == kit.Keys(EXTRA, key) {
|
if k == key || k == kit.Keys(EXTRA, key) {
|
||||||
if len(arg) > 0 {
|
if len(arg) > 0 {
|
||||||
@ -526,7 +451,12 @@ func (m *Message) Appendv(key string, arg ...Any) []string {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
if key == MSG_APPEND {
|
||||||
|
if len(arg) > 0 {
|
||||||
|
m.meta[MSG_APPEND] = kit.Simple(arg)
|
||||||
|
}
|
||||||
|
return m.meta[key]
|
||||||
|
}
|
||||||
if len(arg) > 0 {
|
if len(arg) > 0 {
|
||||||
m.meta[key] = kit.Simple(arg...)
|
m.meta[key] = kit.Simple(arg...)
|
||||||
}
|
}
|
||||||
|
157
misc.go
157
misc.go
@ -8,7 +8,7 @@ import (
|
|||||||
"shylinux.com/x/toolkits/logs"
|
"shylinux.com/x/toolkits/logs"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (m *Message) Split(str string, arg ...string) *Message { // field sp nl
|
func (m *Message) Split(str string, arg ...string) *Message {
|
||||||
m.Set(MSG_APPEND).Set(MSG_RESULT)
|
m.Set(MSG_APPEND).Set(MSG_RESULT)
|
||||||
field := kit.Select("", arg, 0)
|
field := kit.Select("", arg, 0)
|
||||||
sp := kit.Select(SP, arg, 1)
|
sp := kit.Select(SP, arg, 1)
|
||||||
@ -21,7 +21,7 @@ func (m *Message) Split(str string, arg ...string) *Message { // field sp nl
|
|||||||
if strings.TrimSpace(l) == "" {
|
if strings.TrimSpace(l) == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if i == 0 && (field == "" || field == INDEX) { // 表头行
|
if i == 0 && (field == "" || field == INDEX) {
|
||||||
if fields = kit.Split(l, sp, sp); field == INDEX {
|
if fields = kit.Split(l, sp, sp); field == INDEX {
|
||||||
if strings.HasPrefix(l, SP) || strings.HasPrefix(l, TB) {
|
if strings.HasPrefix(l, SP) || strings.HasPrefix(l, TB) {
|
||||||
indexs = append(indexs, 0)
|
indexs = append(indexs, 0)
|
||||||
@ -37,8 +37,7 @@ func (m *Message) Split(str string, arg ...string) *Message { // field sp nl
|
|||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if len(indexs) > 0 {
|
||||||
if len(indexs) > 0 { // 按位切分
|
|
||||||
for i, v := range indexs {
|
for i, v := range indexs {
|
||||||
if v >= len(l) {
|
if v >= len(l) {
|
||||||
m.Push(strings.TrimSpace(kit.Select(SP, fields, i)), "")
|
m.Push(strings.TrimSpace(kit.Select(SP, fields, i)), "")
|
||||||
@ -52,7 +51,6 @@ func (m *Message) Split(str string, arg ...string) *Message { // field sp nl
|
|||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
ls := kit.Split(l, sp, sp)
|
ls := kit.Split(l, sp, sp)
|
||||||
for i, v := range ls {
|
for i, v := range ls {
|
||||||
if i == len(fields)-1 {
|
if i == len(fields)-1 {
|
||||||
@ -78,18 +76,6 @@ func (m *Message) PushDetail(value Any, arg ...string) *Message {
|
|||||||
return m.Push(FIELDS_DETAIL, value, kit.Split(kit.Join(arg)))
|
return m.Push(FIELDS_DETAIL, value, kit.Split(kit.Join(arg)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Message) Options(arg ...Any) *Message {
|
|
||||||
for i := 0; i < len(arg); i += 2 {
|
|
||||||
m.Option(kit.Format(arg[i]), arg[i+1])
|
|
||||||
}
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
func (m *Message) OptionMulti(arg ...Any) *Message {
|
|
||||||
for i := 0; i < len(arg); i += 2 {
|
|
||||||
m.Option(kit.Format(arg[i]), arg[i+1])
|
|
||||||
}
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
func (m *Message) ToLowerAppend(arg ...string) *Message {
|
func (m *Message) ToLowerAppend(arg ...string) *Message {
|
||||||
for _, k := range m.meta[MSG_APPEND] {
|
for _, k := range m.meta[MSG_APPEND] {
|
||||||
m.RenameAppend(k, strings.ToLower(k))
|
m.RenameAppend(k, strings.ToLower(k))
|
||||||
@ -101,7 +87,7 @@ func (m *Message) RenameOption(from, to string) *Message {
|
|||||||
m.Option(from, "")
|
m.Option(from, "")
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
func (m *Message) RenameAppend(arg ...string) *Message { // [from to]...
|
func (m *Message) RenameAppend(arg ...string) *Message {
|
||||||
for i := 0; i < len(arg)-1; i += 2 {
|
for i := 0; i < len(arg)-1; i += 2 {
|
||||||
if arg[i] == arg[i+1] {
|
if arg[i] == arg[i+1] {
|
||||||
continue
|
continue
|
||||||
@ -154,9 +140,6 @@ func (m *Message) SetResult(arg ...string) *Message {
|
|||||||
return m.Set(MSG_RESULT, arg...)
|
return m.Set(MSG_RESULT, arg...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Message) IsMobile() bool {
|
|
||||||
return strings.Contains(m.Option(MSG_USERUA), "Mobile")
|
|
||||||
}
|
|
||||||
func (m *Message) Design(action Any, help string, input ...Any) {
|
func (m *Message) Design(action Any, help string, input ...Any) {
|
||||||
list := kit.List()
|
list := kit.List()
|
||||||
for _, input := range input {
|
for _, input := range input {
|
||||||
@ -181,12 +164,27 @@ func (m *Message) Design(action Any, help string, input ...Any) {
|
|||||||
kit.Value(m._cmd.Meta, kit.Keys("_trans", k), help)
|
kit.Value(m._cmd.Meta, kit.Keys("_trans", k), help)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
func (m *Message) CmdHand(cmd *Command, key string, arg ...string) *Message {
|
||||||
|
if m._key, m._cmd = key, cmd; cmd == nil {
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
if m._target = kit.FileLine(cmd.Hand, 3); cmd.RawHand != nil {
|
||||||
|
m._target = kit.Format(cmd.RawHand)
|
||||||
|
}
|
||||||
|
if fileline := kit.Select(m._target, m._source, m.target.Name == MDB); key == SELECT {
|
||||||
|
m.Log(LOG_CMDS, "%s.%s %d %v %v", m.Target().Name, key, len(arg), arg, m.Optionv(MSG_FIELDS), logs.FileLineMeta(fileline))
|
||||||
|
} else {
|
||||||
|
m.Log(LOG_CMDS, "%s.%s %d %v", m.Target().Name, key, len(arg), arg, logs.FileLineMeta(fileline))
|
||||||
|
}
|
||||||
|
if cmd.Hand != nil {
|
||||||
|
cmd.Hand(m, arg...)
|
||||||
|
} else if cmd.Actions != nil && cmd.Actions[SELECT] != nil {
|
||||||
|
cmd.Actions[SELECT].Hand(m, arg...)
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
func (m *Message) _command(arg ...Any) *Message {
|
func (m *Message) _command(arg ...Any) *Message {
|
||||||
args, opts := []Any{}, Map{}
|
args, opts, cbs, _source := []Any{}, Map{}, kit.Value(nil), logs.FileLine(3, 3)
|
||||||
var cbs Any
|
|
||||||
|
|
||||||
// 解析参数
|
|
||||||
_source := logs.FileLine(3, 3)
|
|
||||||
for _, v := range arg {
|
for _, v := range arg {
|
||||||
switch val := v.(type) {
|
switch val := v.(type) {
|
||||||
case string:
|
case string:
|
||||||
@ -203,12 +201,10 @@ func (m *Message) _command(arg ...Any) *Message {
|
|||||||
opts[val.Name] = val.Value
|
opts[val.Name] = val.Value
|
||||||
case *Option:
|
case *Option:
|
||||||
opts[val.Name] = val.Value
|
opts[val.Name] = val.Value
|
||||||
|
|
||||||
case logs.Meta:
|
case logs.Meta:
|
||||||
if val.Key == "fileline" {
|
if val.Key == "fileline" {
|
||||||
_source = val.Value
|
_source = val.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
case func(int, Maps, []string):
|
case func(int, Maps, []string):
|
||||||
defer func() { m.Table(val) }()
|
defer func() { m.Table(val) }()
|
||||||
case func(Maps):
|
case func(Maps):
|
||||||
@ -221,8 +217,6 @@ func (m *Message) _command(arg ...Any) *Message {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析命令
|
|
||||||
list := kit.Simple(args...)
|
list := kit.Simple(args...)
|
||||||
if len(list) == 0 && !m.Hand {
|
if len(list) == 0 && !m.Hand {
|
||||||
list = m.meta[MSG_DETAIL]
|
list = m.meta[MSG_DETAIL]
|
||||||
@ -230,25 +224,20 @@ func (m *Message) _command(arg ...Any) *Message {
|
|||||||
if len(list) == 0 {
|
if len(list) == 0 {
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
ok := false
|
ok := false
|
||||||
run := func(msg *Message, ctx *Context, cmd *Command, key string, arg ...string) {
|
run := func(msg *Message, ctx *Context, cmd *Command, key string, arg ...string) {
|
||||||
|
key = kit.Slice(strings.Split(key, PT), -1)[0]
|
||||||
if ok = true; cbs != nil {
|
if ok = true; cbs != nil {
|
||||||
msg.OptionCB(kit.Slice(kit.Split(list[0], PT), -1)[0], cbs)
|
msg.OptionCB(key, cbs)
|
||||||
}
|
}
|
||||||
for k, v := range opts {
|
for k, v := range opts {
|
||||||
msg.Option(k, v)
|
msg.Option(k, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 执行命令
|
|
||||||
msg._source = _source
|
msg._source = _source
|
||||||
m.TryCatch(msg, true, func(msg *Message) { m = ctx._command(msg, cmd, key, arg...) })
|
m.TryCatch(msg, true, func(msg *Message) { m = ctx._command(msg, cmd, key, arg...) })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查找命令
|
|
||||||
if list[0] == "" {
|
if list[0] == "" {
|
||||||
list[0] = m._key
|
run(m.Spawn(), m.target, m._cmd, m._key, list[1:]...)
|
||||||
run(m.Spawn(), m.target, m._cmd, list[0], list[1:]...)
|
|
||||||
} else if cmd, ok := m.target.Commands[strings.TrimPrefix(list[0], m.target.Cap(CTX_FOLLOW)+PT)]; ok {
|
} else if cmd, ok := m.target.Commands[strings.TrimPrefix(list[0], m.target.Cap(CTX_FOLLOW)+PT)]; ok {
|
||||||
run(m.Spawn(), m.target, cmd, list[0], list[1:]...)
|
run(m.Spawn(), m.target, cmd, list[0], list[1:]...)
|
||||||
} else if cmd, ok := m.source.Commands[strings.TrimPrefix(list[0], m.source.Cap(CTX_FOLLOW)+PT)]; ok {
|
} else if cmd, ok := m.source.Commands[strings.TrimPrefix(list[0], m.source.Cap(CTX_FOLLOW)+PT)]; ok {
|
||||||
@ -261,32 +250,11 @@ func (m *Message) _command(arg ...Any) *Message {
|
|||||||
m.Warn(!ok, ErrNotFound, kit.Format(list))
|
m.Warn(!ok, ErrNotFound, kit.Format(list))
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
func (m *Message) CmdHand(cmd *Command, key string, arg ...string) *Message {
|
|
||||||
if m._key, m._cmd = key, cmd; cmd == nil {
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
if m._target = kit.FileLine(cmd.Hand, 3); cmd.RawHand != nil {
|
|
||||||
m._target = kit.Format(cmd.RawHand)
|
|
||||||
}
|
|
||||||
if fileline := kit.Select(m._target, m._source, m.target.Name == MDB); key == "select" {
|
|
||||||
m.Log(LOG_CMDS, "%s.%s %d %v %v", m.Target().Name, key, len(arg), arg, m.Optionv(MSG_FIELDS), logs.FileLineMeta(fileline))
|
|
||||||
} else {
|
|
||||||
m.Log(LOG_CMDS, "%s.%s %d %v", m.Target().Name, key, len(arg), arg, logs.FileLineMeta(fileline))
|
|
||||||
}
|
|
||||||
if cmd.Hand != nil {
|
|
||||||
cmd.Hand(m, arg...)
|
|
||||||
} else if cmd.Actions != nil && cmd.Actions["select"] != nil {
|
|
||||||
cmd.Actions["select"].Hand(m, arg...)
|
|
||||||
}
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
func (c *Context) _command(m *Message, cmd *Command, key string, arg ...string) *Message {
|
func (c *Context) _command(m *Message, cmd *Command, key string, arg ...string) *Message {
|
||||||
key = kit.Slice(strings.Split(key, PT), -1)[0]
|
if m._key, m._sub, m._cmd = key, SELECT, cmd; cmd == nil {
|
||||||
if m._key, m._sub, m._cmd = key, "select", cmd; cmd == nil {
|
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
if m.Hand, m.meta[MSG_DETAIL] = true, kit.Simple(m.PrefixKey(), arg); cmd.Actions != nil {
|
||||||
if m.Hand, m.meta[MSG_DETAIL] = true, kit.Simple(key, arg); cmd.Actions != nil {
|
|
||||||
if len(arg) > 1 && arg[0] == ACTION {
|
if len(arg) > 1 && arg[0] == ACTION {
|
||||||
if h, ok := cmd.Actions[arg[1]]; ok {
|
if h, ok := cmd.Actions[arg[1]]; ok {
|
||||||
return c._action(m, cmd, key, arg[1], h, arg[2:]...)
|
return c._action(m, cmd, key, arg[1], h, arg[2:]...)
|
||||||
@ -298,30 +266,14 @@ func (c *Context) _command(m *Message, cmd *Command, key string, arg ...string)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return m.CmdHand(cmd, key, arg...)
|
||||||
if m._target = kit.FileLine(cmd.Hand, 3); cmd.RawHand != nil {
|
|
||||||
m._target = kit.Format(cmd.RawHand)
|
|
||||||
}
|
|
||||||
if fileline := kit.Select(m._target, m._source, m.target.Name == MDB); key == "select" {
|
|
||||||
m.Log(LOG_CMDS, "%s.%s %d %v %v", c.Name, key, len(arg), arg, m.Optionv(MSG_FIELDS), logs.FileLineMeta(fileline))
|
|
||||||
} else {
|
|
||||||
m.Log(LOG_CMDS, "%s.%s %d %v", c.Name, key, len(arg), arg, logs.FileLineMeta(fileline))
|
|
||||||
}
|
|
||||||
|
|
||||||
if cmd.Hand != nil {
|
|
||||||
cmd.Hand(m, arg...)
|
|
||||||
} else if cmd.Actions != nil && cmd.Actions["select"] != nil {
|
|
||||||
cmd.Actions["select"].Hand(m, arg...)
|
|
||||||
}
|
|
||||||
return m
|
|
||||||
}
|
}
|
||||||
func (c *Context) _action(m *Message, cmd *Command, key string, sub string, h *Action, arg ...string) *Message {
|
func (c *Context) _action(m *Message, cmd *Command, key string, sub string, h *Action, arg ...string) *Message {
|
||||||
if h.Hand == nil {
|
if h.Hand == nil {
|
||||||
m.Cmdy(kit.Split(h.Name), arg)
|
m.Cmdy(kit.Split(h.Name), arg)
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
if m._sub = sub; len(h.List) > 0 && sub != SEARCH {
|
||||||
if m._sub = sub; len(h.List) > 0 && sub != "search" {
|
|
||||||
order := false
|
order := false
|
||||||
for i, v := range h.List {
|
for i, v := range h.List {
|
||||||
name := kit.Format(kit.Value(v, NAME))
|
name := kit.Format(kit.Value(v, NAME))
|
||||||
@ -331,8 +283,8 @@ func (c *Context) _action(m *Message, cmd *Command, key string, sub string, h *A
|
|||||||
}
|
}
|
||||||
if order {
|
if order {
|
||||||
m.Option(name, kit.Select(value, arg, i))
|
m.Option(name, kit.Select(value, arg, i))
|
||||||
} else if m.Option(name) == "" && value != "" {
|
} else {
|
||||||
m.Option(name, value)
|
m.OptionDefault(name, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !order {
|
if !order {
|
||||||
@ -341,7 +293,6 @@ func (c *Context) _action(m *Message, cmd *Command, key string, sub string, h *A
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if m._target = kit.FileLine(h.Hand, 3); cmd.RawHand != nil {
|
if m._target = kit.FileLine(h.Hand, 3); cmd.RawHand != nil {
|
||||||
m._target = kit.Format(cmd.RawHand)
|
m._target = kit.Format(cmd.RawHand)
|
||||||
}
|
}
|
||||||
@ -350,52 +301,51 @@ func (c *Context) _action(m *Message, cmd *Command, key string, sub string, h *A
|
|||||||
h.Hand(m, arg...)
|
h.Hand(m, arg...)
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
func MergeActions(list ...Any) Actions {
|
func MergeActions(arg ...Any) Actions {
|
||||||
if len(list) == 0 {
|
if len(arg) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
base := list[0].(Actions)
|
list := arg[0].(Actions)
|
||||||
for _, from := range list[1:] {
|
for _, from := range arg[1:] {
|
||||||
switch from := from.(type) {
|
switch from := from.(type) {
|
||||||
case Actions:
|
case Actions:
|
||||||
for k, v := range from {
|
for k, v := range from {
|
||||||
if h, ok := base[k]; !ok {
|
if h, ok := list[k]; !ok {
|
||||||
base[k] = v
|
list[k] = v
|
||||||
} else if h.Hand == nil {
|
} else if h.Hand == nil {
|
||||||
h.Hand = v.Hand
|
h.Hand = v.Hand
|
||||||
} else if k == CTX_INIT {
|
} else if k == CTX_INIT {
|
||||||
last := base[k].Hand
|
last := h.Hand
|
||||||
prev := v.Hand
|
hand := v.Hand
|
||||||
base[k].Hand = func(m *Message, arg ...string) {
|
h.Hand = func(m *Message, arg ...string) {
|
||||||
prev(m, arg...)
|
hand(m, arg...)
|
||||||
last(m, arg...)
|
last(m, arg...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case string:
|
case string:
|
||||||
base[CTX_INIT] = &Action{Hand: func(m *Message, arg ...string) {
|
h := list[CTX_INIT]
|
||||||
|
list[CTX_INIT] = &Action{Hand: func(m *Message, arg ...string) {
|
||||||
m.Search(from, func(p *Context, s *Context, key string, cmd *Command) {
|
m.Search(from, func(p *Context, s *Context, key string, cmd *Command) {
|
||||||
for k, v := range cmd.Actions {
|
for k, v := range cmd.Actions {
|
||||||
func(k string) {
|
func(k string) {
|
||||||
if h, ok := base[k]; !ok {
|
if h, ok := list[k]; !ok {
|
||||||
base[k] = &Action{Name: v.Name, Help: v.Help, Hand: func(m *Message, arg ...string) {
|
list[k] = &Action{Name: v.Name, Help: v.Help, Hand: func(m *Message, arg ...string) { m.Cmdy(from, k, arg) }}
|
||||||
m.Cmdy(from, k, arg)
|
|
||||||
}}
|
|
||||||
} else if h.Hand == nil {
|
} else if h.Hand == nil {
|
||||||
h.Hand = func(m *Message, arg ...string) {
|
h.Hand = func(m *Message, arg ...string) { m.Cmdy(from, k, arg) }
|
||||||
m.Cmdy(from, k, arg)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}(k)
|
}(k)
|
||||||
}
|
}
|
||||||
m.target.Merge(m.target)
|
|
||||||
})
|
})
|
||||||
|
if h != nil {
|
||||||
|
h.Hand(m, arg...)
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
default:
|
default:
|
||||||
Pulse.ErrorNotImplement(from)
|
Pulse.ErrorNotImplement(from)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return base
|
return list
|
||||||
}
|
}
|
||||||
func SplitCmd(name string, actions Actions) (list []Any) {
|
func SplitCmd(name string, actions Actions) (list []Any) {
|
||||||
const (
|
const (
|
||||||
@ -414,7 +364,6 @@ func SplitCmd(name string, actions Actions) (list []Any) {
|
|||||||
PAGE = "page"
|
PAGE = "page"
|
||||||
ARGS = "args"
|
ARGS = "args"
|
||||||
)
|
)
|
||||||
|
|
||||||
item, button := kit.Dict(), false
|
item, button := kit.Dict(), false
|
||||||
push := func(arg ...string) {
|
push := func(arg ...string) {
|
||||||
button = kit.Select("", arg, 0) == BUTTON
|
button = kit.Select("", arg, 0) == BUTTON
|
||||||
@ -432,7 +381,7 @@ func SplitCmd(name string, actions Actions) (list []Any) {
|
|||||||
push(BUTTON, ls[i], AUTO)
|
push(BUTTON, ls[i], AUTO)
|
||||||
case AUTO:
|
case AUTO:
|
||||||
push(BUTTON, LIST, AUTO)
|
push(BUTTON, LIST, AUTO)
|
||||||
push(BUTTON, BACK, AUTO)
|
push(BUTTON, BACK)
|
||||||
case PAGE:
|
case PAGE:
|
||||||
push(TEXT, "limit")
|
push(TEXT, "limit")
|
||||||
push(TEXT, "offend")
|
push(TEXT, "offend")
|
||||||
|
@ -287,7 +287,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
_repos_cmd(m, m.Option(REPOS), TAG, m.Option(VERSION))
|
_repos_cmd(m, m.Option(REPOS), TAG, m.Option(VERSION))
|
||||||
_repos_cmd(m, m.Option(REPOS), PUSH, "--tags")
|
_repos_cmd(m, m.Option(REPOS), PUSH, "--tags")
|
||||||
m.ProcessRefresh30ms()
|
m.ProcessRefresh()
|
||||||
}},
|
}},
|
||||||
BRANCH: {Name: "branch", Help: "分支", Hand: func(m *ice.Message, arg ...string) {
|
BRANCH: {Name: "branch", Help: "分支", Hand: func(m *ice.Message, arg ...string) {
|
||||||
for _, line := range kit.Split(_repos_cmd(m.Spawn(), arg[0], BRANCH).Result(), ice.NL, ice.NL) {
|
for _, line := range kit.Split(_repos_cmd(m.Spawn(), arg[0], BRANCH).Result(), ice.NL, ice.NL) {
|
||||||
@ -319,6 +319,9 @@ func init() {
|
|||||||
m.Cmdy(code.VIMER, code.DEVPACK)
|
m.Cmdy(code.VIMER, code.DEVPACK)
|
||||||
}},
|
}},
|
||||||
web.DREAM_TABLES: {Hand: func(m *ice.Message, arg ...string) {
|
web.DREAM_TABLES: {Hand: func(m *ice.Message, arg ...string) {
|
||||||
|
if m.Option(mdb.TYPE) != web.WORKER {
|
||||||
|
return
|
||||||
|
}
|
||||||
text := []string{}
|
text := []string{}
|
||||||
for _, line := range kit.Split(m.Cmdx(web.SPACE, m.Option(mdb.NAME), cli.SYSTEM, "git", "diff", "--shortstat"), ice.FS, ice.FS) {
|
for _, line := range kit.Split(m.Cmdx(web.SPACE, m.Option(mdb.NAME), cli.SYSTEM, "git", "diff", "--shortstat"), ice.FS, ice.FS) {
|
||||||
if list := kit.Split(line); strings.Contains(line, "file") {
|
if list := kit.Split(line); strings.Contains(line, "file") {
|
||||||
|
@ -11,7 +11,7 @@ func _group_list(m *ice.Message, appid string) {
|
|||||||
_, data := _lark_get(m, appid, "/open-apis/chat/v4/list")
|
_, data := _lark_get(m, appid, "/open-apis/chat/v4/list")
|
||||||
kit.Fetch(kit.Value(data, "data.groups"), func(index int, value ice.Map) {
|
kit.Fetch(kit.Value(data, "data.groups"), func(index int, value ice.Map) {
|
||||||
m.Push(CHAT_ID, value[CHAT_ID])
|
m.Push(CHAT_ID, value[CHAT_ID])
|
||||||
m.PushImages(aaa.AVATAR, kit.Format(value[aaa.AVATAR]), "72")
|
m.PushImages(aaa.AVATAR, kit.Format(value[aaa.AVATAR]))
|
||||||
m.Push(mdb.NAME, value[mdb.NAME])
|
m.Push(mdb.NAME, value[mdb.NAME])
|
||||||
m.Push(mdb.TEXT, value["description"])
|
m.Push(mdb.TEXT, value["description"])
|
||||||
m.Push(OPEN_ID, value["owner_open_id"])
|
m.Push(OPEN_ID, value["owner_open_id"])
|
||||||
|
@ -140,7 +140,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
m.Cmd(TAGS, mdb.INSERT, mdb.ZONE, value[mdb.ZONE], kit.Simple(value))
|
m.Cmd(TAGS, mdb.INSERT, mdb.ZONE, value[mdb.ZONE], kit.Simple(value))
|
||||||
})
|
})
|
||||||
m.ProcessRefresh300ms()
|
m.ProcessRefresh()
|
||||||
}},
|
}},
|
||||||
mdb.INSERT: {Name: "insert zone=core type name=hi text=hello path file line", Help: "添加"},
|
mdb.INSERT: {Name: "insert zone=core type name=hi text=hello path file line", Help: "添加"},
|
||||||
code.INNER: {Name: "inner", Help: "源码", Hand: func(m *ice.Message, arg ...string) {
|
code.INNER: {Name: "inner", Help: "源码", Hand: func(m *ice.Message, arg ...string) {
|
||||||
|
66
option.go
66
option.go
@ -38,10 +38,10 @@ func (m *Message) OptionSimple(key ...string) (res []string) {
|
|||||||
if len(key) == 0 {
|
if len(key) == 0 {
|
||||||
for _, k := range kit.Split(m.Config(FIELD)) {
|
for _, k := range kit.Split(m.Config(FIELD)) {
|
||||||
switch k {
|
switch k {
|
||||||
case "", TIME, HASH:
|
case TIME, HASH:
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if m.Option(k) == "" {
|
if k == "" || m.Option(k) == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
res = append(res, k, m.Option(k))
|
res = append(res, k, m.Option(k))
|
||||||
@ -92,28 +92,26 @@ func (m *Message) Action(arg ...Any) *Message {
|
|||||||
m.Option(MSG_ACTION, kit.Format(arg))
|
m.Option(MSG_ACTION, kit.Format(arg))
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
func (m *Message) Status(arg ...Any) {
|
func (m *Message) Status(arg ...Any) *Message {
|
||||||
list := kit.List()
|
list, args := kit.List(), kit.Simple(arg)
|
||||||
args := kit.Simple(arg)
|
|
||||||
for i := 0; i < len(args)-1; i += 2 {
|
for i := 0; i < len(args)-1; i += 2 {
|
||||||
list = append(list, kit.Dict(NAME, args[i], VALUE, args[i+1]))
|
list = append(list, kit.Dict(NAME, args[i], VALUE, args[i+1]))
|
||||||
}
|
}
|
||||||
m.Option(MSG_STATUS, kit.Format(list))
|
m.Option(MSG_STATUS, kit.Format(list))
|
||||||
|
return m
|
||||||
}
|
}
|
||||||
func (m *Message) StatusTime(arg ...Any) *Message {
|
func (m *Message) StatusTime(arg ...Any) *Message {
|
||||||
m.Status(TIME, m.Time(), arg, kit.MDB_COST, m.FormatCost())
|
return m.Status(TIME, m.Time(), arg, kit.MDB_COST, m.FormatCost())
|
||||||
return m
|
|
||||||
}
|
}
|
||||||
func (m *Message) StatusTimeCount(arg ...Any) *Message {
|
func (m *Message) StatusTimeCount(arg ...Any) *Message {
|
||||||
m.Status(TIME, m.Time(), kit.MDB_COUNT, kit.Split(m.FormatSize())[0], arg, kit.MDB_COST, m.FormatCost())
|
return m.Status(TIME, m.Time(), kit.MDB_COUNT, kit.Split(m.FormatSize())[0], arg, kit.MDB_COST, m.FormatCost())
|
||||||
return m
|
|
||||||
}
|
}
|
||||||
func (m *Message) StatusTimeCountTotal(arg ...Any) {
|
func (m *Message) StatusTimeCountTotal(arg ...Any) *Message {
|
||||||
m.Status(TIME, m.Time(), kit.MDB_COUNT, kit.Split(m.FormatSize())[0], kit.MDB_TOTAL, arg, kit.MDB_COST, m.FormatCost())
|
return m.Status(TIME, m.Time(), kit.MDB_COUNT, kit.Split(m.FormatSize())[0], kit.MDB_TOTAL, arg, kit.MDB_COST, m.FormatCost())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Message) Process(action string, arg ...Any) {
|
func (m *Message) Process(cmd string, arg ...Any) {
|
||||||
m.Option(MSG_PROCESS, action)
|
m.Option(MSG_PROCESS, cmd)
|
||||||
m.Option(PROCESS_ARG, arg...)
|
m.Option(PROCESS_ARG, arg...)
|
||||||
}
|
}
|
||||||
func (m *Message) ProcessLocation(arg ...Any) {
|
func (m *Message) ProcessLocation(arg ...Any) {
|
||||||
@ -128,16 +126,12 @@ func (m *Message) ProcessHistory(arg ...Any) {
|
|||||||
func (m *Message) ProcessConfirm(arg ...Any) {
|
func (m *Message) ProcessConfirm(arg ...Any) {
|
||||||
m.Process(PROCESS_CONFIRM, arg...)
|
m.Process(PROCESS_CONFIRM, arg...)
|
||||||
}
|
}
|
||||||
func (m *Message) ProcessRefresh(arg ...string) { // delay
|
func (m *Message) ProcessRefresh(arg ...string) {
|
||||||
if d, e := time.ParseDuration(kit.Select("300ms", arg, 0)); e == nil {
|
|
||||||
m.Option("_delay", int(d/time.Millisecond))
|
|
||||||
}
|
|
||||||
m.Process(PROCESS_REFRESH)
|
m.Process(PROCESS_REFRESH)
|
||||||
|
if d, e := time.ParseDuration(kit.Select("30ms", arg, 0)); e == nil {
|
||||||
|
m.Option(PROCESS_ARG, int(d/time.Millisecond))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
func (m *Message) ProcessRefresh3ms() { m.ProcessRefresh("3ms") }
|
|
||||||
func (m *Message) ProcessRefresh30ms() { m.ProcessRefresh("30ms") }
|
|
||||||
func (m *Message) ProcessRefresh300ms() { m.ProcessRefresh("300ms") }
|
|
||||||
func (m *Message) ProcessRefresh3s() { m.ProcessRefresh("3s") }
|
|
||||||
func (m *Message) ProcessRewrite(arg ...Any) {
|
func (m *Message) ProcessRewrite(arg ...Any) {
|
||||||
m.Process(PROCESS_REWRITE, arg...)
|
m.Process(PROCESS_REWRITE, arg...)
|
||||||
}
|
}
|
||||||
@ -146,11 +140,11 @@ func (m *Message) ProcessDisplay(arg ...Any) {
|
|||||||
m.Option(MSG_DISPLAY, arg...)
|
m.Option(MSG_DISPLAY, arg...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Message) ProcessInner() { m.Process(PROCESS_INNER) }
|
|
||||||
func (m *Message) ProcessField(arg ...Any) {
|
func (m *Message) ProcessField(arg ...Any) {
|
||||||
m.Process(PROCESS_FIELD)
|
m.Process(PROCESS_FIELD)
|
||||||
m.Option(FIELD_PREFIX, arg...)
|
m.Option(FIELD_PREFIX, arg...)
|
||||||
}
|
}
|
||||||
|
func (m *Message) ProcessInner() { m.Process(PROCESS_INNER) }
|
||||||
func (m *Message) ProcessAgain() { m.Process(PROCESS_AGAIN) }
|
func (m *Message) ProcessAgain() { m.Process(PROCESS_AGAIN) }
|
||||||
func (m *Message) ProcessHold(text ...Any) { m.Process(PROCESS_HOLD, text...) }
|
func (m *Message) ProcessHold(text ...Any) { m.Process(PROCESS_HOLD, text...) }
|
||||||
func (m *Message) ProcessBack() { m.Process(PROCESS_BACK) }
|
func (m *Message) ProcessBack() { m.Process(PROCESS_BACK) }
|
||||||
@ -158,40 +152,22 @@ func (m *Message) ProcessRich(arg ...Any) { m.Process(PROCESS_RICH, arg...) }
|
|||||||
func (m *Message) ProcessGrow(arg ...Any) { m.Process(PROCESS_GROW, arg...) }
|
func (m *Message) ProcessGrow(arg ...Any) { m.Process(PROCESS_GROW, arg...) }
|
||||||
func (m *Message) ProcessOpen(url string) { m.Process(PROCESS_OPEN, url) }
|
func (m *Message) ProcessOpen(url string) { m.Process(PROCESS_OPEN, url) }
|
||||||
|
|
||||||
func (m *Message) Display(file string, arg ...Any) *Message { // repos local file
|
func (m *Message) Display(file string, arg ...Any) *Message {
|
||||||
m.Option(MSG_DISPLAY, kit.MergeURL(displayRequire(2, file)[DISPLAY], arg...))
|
m.Option(MSG_DISPLAY, kit.MergeURL(displayRequire(2, file)[DISPLAY], arg...))
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
func DisplayLocal(file string, arg ...string) Maps { // /plugin/local/file
|
|
||||||
if file == "" {
|
|
||||||
file = path.Join(kit.PathName(2), kit.Keys(kit.FileName(2), JS))
|
|
||||||
}
|
|
||||||
if !strings.HasPrefix(file, HTTP) && !strings.HasPrefix(file, PS) {
|
|
||||||
file = path.Join(PLUGIN_LOCAL, file)
|
|
||||||
}
|
|
||||||
return DisplayBase(file, arg...)
|
|
||||||
}
|
|
||||||
func DisplayStory(file string, arg ...string) Maps { // /plugin/story/file
|
|
||||||
if !strings.HasPrefix(file, HTTP) && !strings.HasPrefix(file, PS) {
|
|
||||||
file = path.Join(PLUGIN_STORY, file)
|
|
||||||
}
|
|
||||||
return DisplayBase(file, arg...)
|
|
||||||
}
|
|
||||||
func DisplayBase(file string, arg ...string) Maps {
|
|
||||||
return Maps{DISPLAY: file, STYLE: kit.Join(arg, SP)}
|
|
||||||
}
|
|
||||||
func Display(file string, arg ...string) Maps { // repos local file
|
|
||||||
return displayRequire(2, file, arg...)
|
|
||||||
}
|
|
||||||
func displayRequire(n int, file string, arg ...string) Maps {
|
func displayRequire(n int, file string, arg ...string) Maps {
|
||||||
if file == "" {
|
if file == "" {
|
||||||
file = kit.Keys(kit.FileName(n+1), JS)
|
file = kit.Keys(kit.FileName(n+1), JS)
|
||||||
}
|
}
|
||||||
if !strings.HasPrefix(file, HTTP) && !strings.HasPrefix(file, PS) {
|
if !strings.HasPrefix(file, PS) && !strings.HasPrefix(file, HTTP) {
|
||||||
file = path.Join(PS, path.Join(path.Dir(FileRequire(n+2)), file))
|
file = path.Join(PS, path.Join(path.Dir(FileRequire(n+2)), file))
|
||||||
}
|
}
|
||||||
return DisplayBase(file, arg...)
|
return DisplayBase(file, arg...)
|
||||||
}
|
}
|
||||||
|
func DisplayBase(file string, arg ...string) Maps {
|
||||||
|
return Maps{DISPLAY: file, STYLE: kit.Join(arg, SP)}
|
||||||
|
}
|
||||||
func FileRequire(n int) string {
|
func FileRequire(n int) string {
|
||||||
p := kit.Split(kit.FileLine(n, 100), DF)[0]
|
p := kit.Split(kit.FileLine(n, 100), DF)[0]
|
||||||
if strings.Contains(p, "go/pkg/mod") {
|
if strings.Contains(p, "go/pkg/mod") {
|
||||||
|
161
render.go
161
render.go
@ -14,12 +14,7 @@ func Render(m *Message, cmd string, args ...Any) string {
|
|||||||
if render, ok := Info.render[cmd]; ok {
|
if render, ok := Info.render[cmd]; ok {
|
||||||
return render(m, cmd, args...)
|
return render(m, cmd, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch arg := kit.Simple(args...); cmd {
|
switch arg := kit.Simple(args...); cmd {
|
||||||
case RENDER_ANCHOR: // [name] link
|
|
||||||
p := kit.Select(arg[0], arg, 1)
|
|
||||||
return kit.Format(`<a href="%s" target="_blank">%s</a>`, p, arg[0])
|
|
||||||
|
|
||||||
case RENDER_BUTTON:
|
case RENDER_BUTTON:
|
||||||
list := []string{}
|
list := []string{}
|
||||||
for _, k := range args {
|
for _, k := range args {
|
||||||
@ -44,47 +39,40 @@ func Render(m *Message, cmd string, args ...Any) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return strings.Join(list, "")
|
return strings.Join(list, "")
|
||||||
|
case RENDER_ANCHOR:
|
||||||
case RENDER_IMAGES: // src [height]
|
return kit.Format(`<a href="%s" target="_blank">%s</a>`, kit.Select(arg[0], arg, 1), arg[0])
|
||||||
if m.Option("height") != "" && m.Option("width") != "" {
|
case RENDER_IMAGES:
|
||||||
return kit.Format(`<img src="%s" style="max-height:%spx; max-width:%spx">`, arg[0], m.Option("height"), m.Option("width"))
|
return kit.Format(`<img src="%s" style="max-height:%spx; max-width:%spx">`, arg[0], m.Option(HEIGHT), m.Option(WIDTH))
|
||||||
}
|
case RENDER_VIDEOS:
|
||||||
if strings.Contains(m.Option(MSG_USERUA), "Mobile") {
|
return kit.Format(`<video src="%s" style="max-height:%spx; max-width:%spx" controls>`, arg[0], m.Option(HEIGHT), m.Option(WIDTH))
|
||||||
return kit.Format(`<img src="%s" width=%d>`, arg[0], kit.Int(kit.Select(kit.Select("120", m.Option("width")), arg, 1))-24)
|
|
||||||
}
|
|
||||||
return kit.Format(`<img src="%s" height=%d>`, arg[0], kit.Int(kit.Select(kit.Select("240", m.Option("height")), arg, 1))/2-24)
|
|
||||||
|
|
||||||
case RENDER_VIDEOS: // src [height]
|
|
||||||
if m.Option("height") != "" && m.Option("width") != "" {
|
|
||||||
return kit.Format(`<video src="%s" controls style="max-height:%spx; max-width:%spx">`, arg[0], m.Option("height"), m.Option("width"))
|
|
||||||
}
|
|
||||||
return kit.Format(`<video src="%s" height=%s controls>`, arg[0], kit.Select("120", arg, 1))
|
|
||||||
|
|
||||||
case RENDER_IFRAME:
|
case RENDER_IFRAME:
|
||||||
return kit.Format(`<iframe src="%s"></iframe>`, arg[0])
|
return kit.Format(`<iframe src="%s"></iframe>`, arg[0])
|
||||||
|
case RENDER_SCRIPT:
|
||||||
|
return kit.Format(`<code>%s</code>`, arg[0])
|
||||||
default:
|
default:
|
||||||
return arg[0]
|
if len(arg) == 1 {
|
||||||
|
return kit.Format(`<%s>%s</%s>`, cmd, arg[0], cmd)
|
||||||
|
}
|
||||||
|
return kit.Format(`<%s style="%s">%s</%s>`, cmd, kit.JoinKV(":", ";", arg[1:]...), arg[0], cmd)
|
||||||
}
|
}
|
||||||
return ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Message) Render(cmd string, args ...Any) *Message {
|
func (m *Message) Render(cmd string, arg ...Any) *Message {
|
||||||
switch cmd {
|
switch cmd {
|
||||||
case RENDER_TEMPLATE: // text [data]
|
case RENDER_TEMPLATE:
|
||||||
if len(args) == 1 {
|
if len(arg) == 1 {
|
||||||
args = append(args, m)
|
arg = append(arg, m)
|
||||||
}
|
}
|
||||||
if res, err := kit.Render(args[0].(string), args[1]); m.Assert(err) {
|
if res, err := kit.Render(arg[0].(string), arg[1]); m.Assert(err) {
|
||||||
m.Echo(string(res))
|
m.Echo(string(res))
|
||||||
}
|
}
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
m.Optionv(MSG_OUTPUT, cmd)
|
m.Options(MSG_OUTPUT, cmd, MSG_ARGS, arg)
|
||||||
m.Optionv(MSG_ARGS, args)
|
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
func (m *Message) RenderTemplate(args ...Any) *Message {
|
func (m *Message) RenderTemplate(arg ...Any) *Message {
|
||||||
return m.Render(RENDER_TEMPLATE, args...)
|
return m.Render(RENDER_TEMPLATE, arg...)
|
||||||
}
|
}
|
||||||
func (m *Message) RenderStatus(status int, arg ...string) *Message {
|
func (m *Message) RenderStatus(status int, arg ...string) *Message {
|
||||||
return m.Render(RENDER_STATUS, status, arg)
|
return m.Render(RENDER_STATUS, status, arg)
|
||||||
@ -101,65 +89,61 @@ func (m *Message) RenderStatusForbidden(arg ...string) *Message {
|
|||||||
func (m *Message) RenderStatusNotFound(arg ...string) *Message {
|
func (m *Message) RenderStatusNotFound(arg ...string) *Message {
|
||||||
return m.Render(RENDER_STATUS, http.StatusNotFound, arg)
|
return m.Render(RENDER_STATUS, http.StatusNotFound, arg)
|
||||||
}
|
}
|
||||||
func (m *Message) RenderRedirect(args ...Any) *Message {
|
func (m *Message) RenderRedirect(arg ...Any) *Message {
|
||||||
return m.Render(RENDER_REDIRECT, args...)
|
return m.Render(RENDER_REDIRECT, arg...)
|
||||||
}
|
}
|
||||||
func (m *Message) RenderDownload(args ...Any) *Message {
|
func (m *Message) RenderDownload(arg ...Any) *Message {
|
||||||
return m.Render(RENDER_DOWNLOAD, args...)
|
return m.Render(RENDER_DOWNLOAD, arg...)
|
||||||
}
|
}
|
||||||
func (m *Message) RenderResult(args ...Any) *Message { // [fmt arg...]
|
func (m *Message) RenderResult(arg ...Any) *Message {
|
||||||
return m.Render(RENDER_RESULT, args...)
|
return m.Render(RENDER_RESULT, arg...)
|
||||||
}
|
}
|
||||||
func (m *Message) RenderJson(args ...Any) *Message { // [key value]...
|
func (m *Message) RenderJson(arg ...Any) *Message {
|
||||||
return m.Render(RENDER_JSON, kit.Format(kit.Dict(args...)))
|
return m.Render(RENDER_JSON, kit.Format(kit.Dict(arg...)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Message) IsMobileUA() bool {
|
|
||||||
return strings.Contains(m.Option(MSG_USERUA), "Mobile")
|
|
||||||
}
|
|
||||||
func (m *Message) IsCliUA() bool {
|
func (m *Message) IsCliUA() bool {
|
||||||
if m.Option(MSG_USERUA) == "" || !strings.HasPrefix(m.Option(MSG_USERUA), "Mozilla") {
|
if m.Option(MSG_USERUA) == "" || !strings.HasPrefix(m.Option(MSG_USERUA), "Mozilla") {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
func (m *Message) PushAction(list ...Any) *Message {
|
func (m *Message) IsMobileUA() bool {
|
||||||
if len(m.meta[MSG_APPEND]) == 0 {
|
return strings.Contains(m.Option(MSG_USERUA), "Mobile")
|
||||||
return m
|
|
||||||
}
|
|
||||||
return m.Set(MSG_APPEND, ACTION).Tables(func(value Maps) { m.PushButton(list...) })
|
|
||||||
}
|
}
|
||||||
func (m *Message) PushSearch(args ...Any) {
|
func (m *Message) PushSearch(arg ...Any) {
|
||||||
data := kit.Dict(args...)
|
data := kit.Dict(arg...)
|
||||||
for i := 0; i < len(args); i += 2 {
|
for i := 0; i < len(arg); i += 2 {
|
||||||
switch k := args[i].(type) {
|
switch k := arg[i].(type) {
|
||||||
case string:
|
case string:
|
||||||
if i+1 < len(args) {
|
if i+1 < len(arg) {
|
||||||
data[k] = args[i+1]
|
data[k] = arg[i+1]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, k := range kit.Split(m.OptionFields()) {
|
for _, k := range kit.Split(m.OptionFields()) {
|
||||||
switch k {
|
switch k {
|
||||||
|
case TIME:
|
||||||
|
m.Push(k, kit.Select(m.Time(), data[k]))
|
||||||
case POD:
|
case POD:
|
||||||
m.Push(k, kit.Select("", data[k]))
|
m.Push(k, kit.Select("", data[k]))
|
||||||
case CTX:
|
case CTX:
|
||||||
m.Push(k, kit.Select(m.Prefix(), data[k]))
|
m.Push(k, kit.Select(m.Prefix(), data[k]))
|
||||||
case CMD:
|
case CMD:
|
||||||
m.Push(k, kit.Select(m.CommandKey(), data[k]))
|
m.Push(k, kit.Select(m.CommandKey(), data[k]))
|
||||||
case TIME:
|
|
||||||
m.Push(k, kit.Select(m.Time(), data[k]))
|
|
||||||
default:
|
default:
|
||||||
m.Push(k, kit.Select("", data[k]))
|
m.Push(k, kit.Select("", data[k]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (m *Message) PushAnchor(arg ...Any) { // [name] link
|
func (m *Message) PushAction(arg ...Any) *Message {
|
||||||
if !m.IsCliUA() {
|
if len(m.meta[MSG_APPEND]) == 0 {
|
||||||
m.Push(LINK, Render(m, RENDER_ANCHOR, arg...))
|
return m
|
||||||
}
|
}
|
||||||
|
return m.Set(MSG_APPEND, ACTION).Tables(func(value Maps) { m.PushButton(arg...) })
|
||||||
}
|
}
|
||||||
func (m *Message) PushButton(arg ...Any) *Message { // name...
|
|
||||||
|
func (m *Message) PushButton(arg ...Any) *Message {
|
||||||
if !m.IsCliUA() {
|
if !m.IsCliUA() {
|
||||||
if m.FieldsIsDetail() {
|
if m.FieldsIsDetail() {
|
||||||
for i, k := range m.meta[KEY] {
|
for i, k := range m.meta[KEY] {
|
||||||
@ -175,58 +159,63 @@ func (m *Message) PushButton(arg ...Any) *Message { // name...
|
|||||||
}
|
}
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
func (m *Message) PushImages(key, src string, arg ...string) { // key src [height]
|
func (m *Message) PushAnchor(arg ...string) {
|
||||||
if !m.IsCliUA() {
|
if !m.IsCliUA() {
|
||||||
m.Push(key, Render(m, RENDER_IMAGES, src, arg))
|
m.Push(LINK, Render(m, RENDER_ANCHOR, arg))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (m *Message) PushVideos(key, src string, arg ...string) { // key src [height]
|
func (m *Message) PushQRCode(key, src string) {
|
||||||
if !m.IsCliUA() {
|
if !m.IsCliUA() {
|
||||||
m.Push(key, Render(m, RENDER_VIDEOS, src, arg))
|
m.Push(key, Render(m, RENDER_QRCODE, src))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (m *Message) PushIFrame(key, src string, arg ...string) { // key src
|
func (m *Message) PushImages(key, src string) {
|
||||||
if !m.IsCliUA() {
|
if !m.IsCliUA() {
|
||||||
m.Push(key, Render(m, RENDER_IFRAME, src, arg))
|
m.Push(key, Render(m, RENDER_IMAGES, src))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (m *Message) PushQRCode(key string, src string, arg ...string) { // key src [height]
|
func (m *Message) PushVideos(key, src string) {
|
||||||
if !m.IsCliUA() {
|
if !m.IsCliUA() {
|
||||||
m.Push(key, Render(m, RENDER_QRCODE, src, arg))
|
m.Push(key, Render(m, RENDER_VIDEOS, src))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (m *Message) PushScript(arg ...string) { // [type] text...
|
func (m *Message) PushIFrame(key, src string) {
|
||||||
|
if !m.IsCliUA() {
|
||||||
|
m.Push(key, Render(m, RENDER_IFRAME, src))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (m *Message) PushScript(arg ...string) {
|
||||||
if !m.IsCliUA() {
|
if !m.IsCliUA() {
|
||||||
m.Push(SCRIPT, Render(m, RENDER_SCRIPT, arg))
|
m.Push(SCRIPT, Render(m, RENDER_SCRIPT, arg))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (m *Message) PushDownload(key string, arg ...Any) { // [name] file
|
func (m *Message) PushDownload(key string, arg ...string) {
|
||||||
if !m.IsCliUA() {
|
if !m.IsCliUA() {
|
||||||
m.Push(key, Render(m, RENDER_DOWNLOAD, arg...))
|
m.Push(key, Render(m, RENDER_DOWNLOAD, arg))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Message) EchoAnchor(arg ...Any) *Message { // [name] link
|
func (m *Message) EchoButton(arg ...Any) *Message {
|
||||||
return m.Echo(Render(m, RENDER_ANCHOR, arg...))
|
|
||||||
}
|
|
||||||
func (m *Message) EchoButton(arg ...Any) *Message { // name...
|
|
||||||
return m.Echo(Render(m, RENDER_BUTTON, arg...))
|
return m.Echo(Render(m, RENDER_BUTTON, arg...))
|
||||||
}
|
}
|
||||||
func (m *Message) EchoImages(src string, arg ...string) *Message { // src [height]
|
func (m *Message) EchoAnchor(arg ...string) *Message {
|
||||||
return m.Echo(Render(m, RENDER_IMAGES, src, arg))
|
return m.Echo(Render(m, RENDER_ANCHOR, arg))
|
||||||
}
|
}
|
||||||
func (m *Message) EchoVideos(src string, arg ...string) *Message { // src [height]
|
func (m *Message) EchoQRCode(src string) *Message {
|
||||||
return m.Echo(Render(m, RENDER_VIDEOS, src, arg))
|
return m.Echo(Render(m, RENDER_QRCODE, src))
|
||||||
}
|
}
|
||||||
func (m *Message) EchoIFrame(src string, arg ...string) *Message { // src
|
func (m *Message) EchoImages(src string) *Message {
|
||||||
return m.Echo(Render(m, RENDER_IFRAME, src, arg))
|
return m.Echo(Render(m, RENDER_IMAGES, src))
|
||||||
}
|
}
|
||||||
func (m *Message) EchoQRCode(src string, arg ...string) *Message { // src [height]
|
func (m *Message) EchoVideos(src string) *Message {
|
||||||
return m.Echo(Render(m, RENDER_QRCODE, src, arg))
|
return m.Echo(Render(m, RENDER_VIDEOS, src))
|
||||||
}
|
}
|
||||||
func (m *Message) EchoScript(arg ...string) *Message { // [type] text...
|
func (m *Message) EchoIFrame(src string) *Message {
|
||||||
|
return m.Echo(Render(m, RENDER_IFRAME, src))
|
||||||
|
}
|
||||||
|
func (m *Message) EchoScript(arg ...string) *Message {
|
||||||
return m.Echo(Render(m, RENDER_SCRIPT, arg))
|
return m.Echo(Render(m, RENDER_SCRIPT, arg))
|
||||||
}
|
}
|
||||||
func (m *Message) EchoDownload(arg ...Any) *Message { // [name] file
|
func (m *Message) EchoDownload(arg ...string) *Message {
|
||||||
return m.Echo(Render(m, RENDER_DOWNLOAD, arg...))
|
return m.Echo(Render(m, RENDER_DOWNLOAD, arg))
|
||||||
}
|
}
|
||||||
|
288
type.go
288
type.go
@ -5,7 +5,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"path"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
@ -63,21 +62,33 @@ type Context struct {
|
|||||||
root *Context
|
root *Context
|
||||||
server Server
|
server Server
|
||||||
|
|
||||||
begin *Message
|
|
||||||
start *Message
|
|
||||||
|
|
||||||
id int32
|
id int32
|
||||||
}
|
}
|
||||||
type Server interface {
|
type Server interface {
|
||||||
Spawn(m *Message, c *Context, arg ...string) Server
|
|
||||||
Begin(m *Message, arg ...string) Server
|
Begin(m *Message, arg ...string) Server
|
||||||
Start(m *Message, arg ...string) bool
|
Start(m *Message, arg ...string) bool
|
||||||
Close(m *Message, arg ...string) bool
|
Close(m *Message, arg ...string) bool
|
||||||
|
Spawn(m *Message, c *Context, arg ...string) Server
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) ID() int32 {
|
func (c *Context) ID() int32 {
|
||||||
return atomic.AddInt32(&c.id, 1)
|
return atomic.AddInt32(&c.id, 1)
|
||||||
}
|
}
|
||||||
|
func (c *Context) Cap(key string, arg ...Any) string {
|
||||||
|
if len(arg) > 0 {
|
||||||
|
c.Caches[key].Value = kit.Format(arg[0])
|
||||||
|
}
|
||||||
|
return c.Caches[key].Value
|
||||||
|
}
|
||||||
|
func (c *Context) Cmd(m *Message, key string, arg ...string) *Message {
|
||||||
|
return c._command(m, c.Commands[key], key, arg...)
|
||||||
|
}
|
||||||
|
func (c *Context) Server() Server {
|
||||||
|
return c.server
|
||||||
|
}
|
||||||
|
func (c *Context) PrefixKey(arg ...string) string {
|
||||||
|
return kit.Keys(c.Cap(CTX_FOLLOW), arg)
|
||||||
|
}
|
||||||
func (c *Command) GetFileLine() string {
|
func (c *Command) GetFileLine() string {
|
||||||
if c.RawHand != nil {
|
if c.RawHand != nil {
|
||||||
switch h := c.RawHand.(type) {
|
switch h := c.RawHand.(type) {
|
||||||
@ -92,25 +103,10 @@ func (c *Command) GetFileLine() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (c *Context) Cap(key string, arg ...Any) string {
|
|
||||||
if len(arg) > 0 {
|
|
||||||
c.Caches[key].Value = kit.Format(arg[0])
|
|
||||||
}
|
|
||||||
return c.Caches[key].Value
|
|
||||||
}
|
|
||||||
func (c *Context) Cmd(m *Message, key string, arg ...string) *Message {
|
|
||||||
return c._command(m, c.Commands[key], key, arg...)
|
|
||||||
}
|
|
||||||
func (c *Context) Server() Server {
|
|
||||||
return c.server
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Context) PrefixKey(arg ...string) string {
|
|
||||||
return kit.Keys(c.Cap(CTX_FOLLOW), arg)
|
|
||||||
}
|
|
||||||
func (c *Context) Register(s *Context, x Server, n ...string) *Context {
|
func (c *Context) Register(s *Context, x Server, n ...string) *Context {
|
||||||
for _, n := range n {
|
for _, n := range n {
|
||||||
if s, ok := Info.names[n]; ok {
|
if s, ok := Info.index[n]; ok {
|
||||||
last := ""
|
last := ""
|
||||||
switch s := s.(type) {
|
switch s := s.(type) {
|
||||||
case *Context:
|
case *Context:
|
||||||
@ -118,10 +114,9 @@ func (c *Context) Register(s *Context, x Server, n ...string) *Context {
|
|||||||
}
|
}
|
||||||
panic(kit.Format("%s %s %v", ErrWarn, n, last))
|
panic(kit.Format("%s %s %v", ErrWarn, n, last))
|
||||||
}
|
}
|
||||||
Info.names[n] = s
|
Info.index[n] = s
|
||||||
}
|
}
|
||||||
|
if c.Contexts == nil {
|
||||||
if s.Merge(s); c.Contexts == nil {
|
|
||||||
c.Contexts = Contexts{}
|
c.Contexts = Contexts{}
|
||||||
}
|
}
|
||||||
c.Contexts[s.Name] = s
|
c.Contexts[s.Name] = s
|
||||||
@ -147,14 +142,12 @@ func (c *Context) Merge(s *Context) *Context {
|
|||||||
if c.Commands[CTX_EXIT] == nil {
|
if c.Commands[CTX_EXIT] == nil {
|
||||||
c.Commands[CTX_EXIT] = &Command{Hand: func(m *Message, arg ...string) { Info.Save(m) }}
|
c.Commands[CTX_EXIT] = &Command{Hand: func(m *Message, arg ...string) { Info.Save(m) }}
|
||||||
}
|
}
|
||||||
|
merge := func(pre *Command, init bool, key string, cmd *Command, cb ...Handler) {
|
||||||
merge := func(pre *Command, before bool, key string, cmd *Command, cb ...Handler) {
|
|
||||||
last := pre.Hand
|
last := pre.Hand
|
||||||
pre.Hand = func(m *Message, arg ...string) {
|
pre.Hand = func(m *Message, arg ...string) {
|
||||||
if before {
|
if init {
|
||||||
last(m, arg...)
|
last(m, arg...)
|
||||||
}
|
}
|
||||||
|
|
||||||
_key, _cmd := m._key, m._cmd
|
_key, _cmd := m._key, m._cmd
|
||||||
m._key, m._cmd = key, cmd
|
m._key, m._cmd = key, cmd
|
||||||
for _, cb := range cb {
|
for _, cb := range cb {
|
||||||
@ -163,76 +156,60 @@ func (c *Context) Merge(s *Context) *Context {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
m._key, m._cmd = _key, _cmd
|
m._key, m._cmd = _key, _cmd
|
||||||
if !before {
|
if !init {
|
||||||
last(m, arg...)
|
last(m, arg...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for key, cmd := range s.Commands {
|
for key, cmd := range s.Commands {
|
||||||
if p, ok := c.Commands[key]; ok && s != c {
|
if pre, ok := c.Commands[key]; ok && s != c {
|
||||||
switch hand := cmd.Hand; key {
|
switch hand := cmd.Hand; key {
|
||||||
case CTX_INIT:
|
case CTX_INIT:
|
||||||
merge(p, true, key, cmd, hand)
|
merge(pre, true, key, cmd, hand)
|
||||||
|
continue
|
||||||
case CTX_EXIT:
|
case CTX_EXIT:
|
||||||
merge(p, false, key, cmd, hand)
|
merge(pre, false, key, cmd, hand)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Commands[key] = cmd; cmd.List == nil {
|
if c.Commands[key] = cmd; cmd.List == nil {
|
||||||
cmd.List = SplitCmd(cmd.Name, cmd.Actions)
|
cmd.List = SplitCmd(cmd.Name, cmd.Actions)
|
||||||
}
|
}
|
||||||
if cmd.Meta == nil {
|
if cmd.Meta == nil {
|
||||||
cmd.Meta = kit.Dict()
|
cmd.Meta = kit.Dict()
|
||||||
}
|
}
|
||||||
|
for sub, action := range cmd.Actions {
|
||||||
for k, a := range cmd.Actions {
|
if pre, ok := c.Commands[sub]; ok && s == c {
|
||||||
if p, ok := c.Commands[k]; ok {
|
switch h := action.Hand; sub {
|
||||||
switch h := a.Hand; k {
|
|
||||||
case CTX_INIT:
|
case CTX_INIT:
|
||||||
merge(p, true, key, cmd, func(m *Message, arg ...string) { h(m, arg...) })
|
merge(pre, true, key, cmd, h)
|
||||||
case CTX_EXIT:
|
case CTX_EXIT:
|
||||||
merge(p, false, key, cmd, func(m *Message, arg ...string) { h(m, arg...) })
|
merge(pre, false, key, cmd, h)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(k, PS) {
|
if s == c {
|
||||||
k = kit.Select(k, path.Join(PS, key)+PS, k == PS)
|
for _, h := range Info.merges {
|
||||||
c.Commands[k] = &Command{Name: k, Help: cmd.Help, Hand: func(m *Message, arg ...string) { m.Cmdy(m.CommandKey(), arg) }}
|
init, exit := h(c, key, cmd, sub, action)
|
||||||
|
merge(c.Commands[CTX_INIT], true, key, cmd, init)
|
||||||
|
merge(c.Commands[CTX_EXIT], false, key, cmd, exit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if help := kit.Split(action.Help, " ::"); len(help) > 0 {
|
||||||
|
if kit.Value(cmd.Meta, kit.Keys("_trans", strings.TrimPrefix(sub, "_")), help[0]); len(help) > 1 {
|
||||||
|
kit.Value(cmd.Meta, kit.Keys("_title", sub), help[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if action.Hand == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if action.List == nil {
|
||||||
if s != c {
|
action.List = SplitCmd(action.Name, nil)
|
||||||
switch k {
|
|
||||||
case "search":
|
|
||||||
merge(c.Commands[CTX_INIT], true, key, cmd, func(m *Message, arg ...string) {
|
|
||||||
if m.CommandKey() != "search" {
|
|
||||||
m.Cmd("search", "create", m.CommandKey(), m.PrefixKey())
|
|
||||||
}
|
}
|
||||||
})
|
if len(action.List) > 0 {
|
||||||
|
cmd.Meta[sub] = action.List
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
help := strings.SplitN(a.Help, ":", 2)
|
|
||||||
if len(help) == 1 || help[1] == "" {
|
|
||||||
help = strings.SplitN(help[0], ":", 2)
|
|
||||||
}
|
}
|
||||||
if kit.Value(cmd.Meta, kit.Keys("_trans", strings.TrimPrefix(k, "_")), help[0]); len(help) > 1 {
|
|
||||||
kit.Value(cmd.Meta, kit.Keys("title", k), help[1])
|
|
||||||
}
|
|
||||||
if a.Hand == nil {
|
|
||||||
continue // alias cmd
|
|
||||||
}
|
|
||||||
if a.List == nil {
|
|
||||||
a.List = SplitCmd(a.Name, nil)
|
|
||||||
}
|
|
||||||
if len(a.List) > 0 {
|
|
||||||
cmd.Meta[k] = a.List
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete(cmd.Actions, CTX_INIT)
|
|
||||||
delete(cmd.Actions, CTX_EXIT)
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.Configs == nil {
|
if c.Configs == nil {
|
||||||
c.Configs = Configs{}
|
c.Configs = Configs{}
|
||||||
}
|
}
|
||||||
@ -247,6 +224,44 @@ func (c *Context) Merge(s *Context) *Context {
|
|||||||
}
|
}
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
func (c *Context) Begin(m *Message, arg ...string) *Context {
|
||||||
|
follow := c.Name
|
||||||
|
if c.context != nil && c.context != Index {
|
||||||
|
follow = kit.Keys(c.context.Cap(CTX_FOLLOW), c.Name)
|
||||||
|
}
|
||||||
|
if c.Caches == nil {
|
||||||
|
c.Caches = Caches{}
|
||||||
|
}
|
||||||
|
c.Caches[CTX_FOLLOW] = &Cache{Name: CTX_FOLLOW, Value: follow}
|
||||||
|
c.Caches[CTX_STATUS] = &Cache{Name: CTX_STATUS, Value: CTX_BEGIN}
|
||||||
|
c.Caches[CTX_STREAM] = &Cache{Name: CTX_STREAM, Value: ""}
|
||||||
|
if c.Merge(c); c.server != nil {
|
||||||
|
c.server.Begin(m, arg...)
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
func (c *Context) Start(m *Message, arg ...string) bool {
|
||||||
|
wait := make(chan bool, 1)
|
||||||
|
defer func() { <-wait }()
|
||||||
|
m.Go(func() {
|
||||||
|
wait <- true
|
||||||
|
|
||||||
|
m.Log(CTX_START, c.Cap(CTX_FOLLOW))
|
||||||
|
c.Cap(CTX_STATUS, CTX_START)
|
||||||
|
if c.server != nil {
|
||||||
|
c.server.Start(m, arg...)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
func (c *Context) Close(m *Message, arg ...string) bool {
|
||||||
|
m.Log(CTX_CLOSE, c.Cap(CTX_FOLLOW))
|
||||||
|
c.Cap(CTX_STATUS, CTX_CLOSE)
|
||||||
|
if c.server != nil {
|
||||||
|
return c.server.Close(m, arg...)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
func (c *Context) Spawn(m *Message, name string, help string, arg ...string) *Context {
|
func (c *Context) Spawn(m *Message, name string, help string, arg ...string) *Context {
|
||||||
s := &Context{Name: name, Help: help}
|
s := &Context{Name: name, Help: help}
|
||||||
if c.server != nil {
|
if c.server != nil {
|
||||||
@ -257,44 +272,6 @@ func (c *Context) Spawn(m *Message, name string, help string, arg ...string) *Co
|
|||||||
m.target = s
|
m.target = s
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
func (c *Context) Begin(m *Message, arg ...string) *Context {
|
|
||||||
follow := c.Name
|
|
||||||
if c.context != nil && c.context != Index {
|
|
||||||
follow = kit.Keys(c.context.Cap(CTX_FOLLOW), c.Name)
|
|
||||||
}
|
|
||||||
c.Caches[CTX_FOLLOW] = &Cache{Name: CTX_FOLLOW, Value: follow}
|
|
||||||
c.Caches[CTX_STATUS] = &Cache{Name: CTX_STATUS, Value: CTX_BEGIN}
|
|
||||||
c.Caches[CTX_STREAM] = &Cache{Name: CTX_STREAM, Value: ""}
|
|
||||||
|
|
||||||
if c.begin = m; c.server != nil {
|
|
||||||
c.server.Begin(m, arg...)
|
|
||||||
}
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
func (c *Context) Start(m *Message, arg ...string) bool {
|
|
||||||
wait := make(chan bool, 1)
|
|
||||||
defer func() { <-wait }()
|
|
||||||
|
|
||||||
m.Go(func() {
|
|
||||||
m.Log(CTX_START, c.Cap(CTX_FOLLOW))
|
|
||||||
c.Cap(CTX_STATUS, CTX_START)
|
|
||||||
wait <- true
|
|
||||||
|
|
||||||
if c.start = m; c.server != nil {
|
|
||||||
c.server.Start(m, arg...)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
func (c *Context) Close(m *Message, arg ...string) bool {
|
|
||||||
m.Log(CTX_CLOSE, c.Cap(CTX_FOLLOW))
|
|
||||||
c.Cap(CTX_STATUS, CTX_CLOSE)
|
|
||||||
|
|
||||||
if c.server != nil {
|
|
||||||
return c.server.Close(m, arg...)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
type Message struct {
|
type Message struct {
|
||||||
time time.Time
|
time time.Time
|
||||||
@ -321,28 +298,11 @@ type Message struct {
|
|||||||
I io.Reader
|
I io.Reader
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (m *Message) getMeta(key string) []string {
|
func (m *Message) Time(args ...Any) string {
|
||||||
// defer m.lock.RLock()()
|
|
||||||
// return m.meta[key]
|
|
||||||
// }
|
|
||||||
// func (m *Message) setMeta(key string, value []string) {
|
|
||||||
// defer m.lock.Lock()()
|
|
||||||
// if value == nil {
|
|
||||||
// delete(m.meta, key)
|
|
||||||
// } else {
|
|
||||||
// m.meta[key] = value
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// func (m *Message) getData(key string) Any {
|
|
||||||
// defer m.lock.RLock()()
|
|
||||||
// return m._data[key]
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
func (m *Message) Time(args ...Any) string { // [duration] [format [args...]]
|
|
||||||
t := m.time
|
t := m.time
|
||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
switch arg := args[0].(type) {
|
switch arg := args[0].(type) {
|
||||||
case string: // 时间偏移
|
case string:
|
||||||
if d, e := time.ParseDuration(arg); e == nil {
|
if d, e := time.ParseDuration(arg); e == nil {
|
||||||
t, args = t.Add(d), args[1:]
|
t, args = t.Add(d), args[1:]
|
||||||
}
|
}
|
||||||
@ -351,7 +311,7 @@ func (m *Message) Time(args ...Any) string { // [duration] [format [args...]]
|
|||||||
f := MOD_TIME
|
f := MOD_TIME
|
||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
switch arg := args[0].(type) {
|
switch arg := args[0].(type) {
|
||||||
case string: // 时间格式
|
case string:
|
||||||
if f = arg; len(args) > 1 {
|
if f = arg; len(args) > 1 {
|
||||||
f = fmt.Sprintf(f, args[1:]...)
|
f = fmt.Sprintf(f, args[1:]...)
|
||||||
}
|
}
|
||||||
@ -365,6 +325,9 @@ func (m *Message) Target() *Context {
|
|||||||
func (m *Message) Source() *Context {
|
func (m *Message) Source() *Context {
|
||||||
return m.source
|
return m.source
|
||||||
}
|
}
|
||||||
|
func (m *Message) Message() *Message {
|
||||||
|
return m.message
|
||||||
|
}
|
||||||
func (m *Message) Spawn(arg ...Any) *Message {
|
func (m *Message) Spawn(arg ...Any) *Message {
|
||||||
msg := &Message{
|
msg := &Message{
|
||||||
time: time.Now(), code: int(m.target.root.ID()),
|
time: time.Now(), code: int(m.target.root.ID()),
|
||||||
@ -373,7 +336,6 @@ func (m *Message) Spawn(arg ...Any) *Message {
|
|||||||
source: m.target, target: m.target, _cmd: m._cmd, _key: m._key, _sub: m._sub,
|
source: m.target, target: m.target, _cmd: m._cmd, _key: m._key, _sub: m._sub,
|
||||||
W: m.W, R: m.R, O: m.O, I: m.I,
|
W: m.W, R: m.R, O: m.O, I: m.I,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, val := range arg {
|
for _, val := range arg {
|
||||||
switch val := val.(type) {
|
switch val := val.(type) {
|
||||||
case []byte:
|
case []byte:
|
||||||
@ -401,27 +363,24 @@ func (m *Message) Spawn(arg ...Any) *Message {
|
|||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
func (m *Message) Start(key string, arg ...string) *Message {
|
func (m *Message) Start(key string, arg ...string) *Message {
|
||||||
m.Search(key+PT, func(p *Context, s *Context) { s.Start(m.Spawn(s), arg...) })
|
return m.Search(key+PT, func(p *Context, s *Context) { s.Start(m.Spawn(s), arg...) })
|
||||||
return m
|
|
||||||
}
|
}
|
||||||
func (m *Message) Travel(cb Any) *Message {
|
func (m *Message) Travel(cb Any) *Message {
|
||||||
list := []*Context{m.root.target}
|
list := []*Context{m.root.target}
|
||||||
for i := 0; i < len(list); i++ {
|
for i := 0; i < len(list); i++ {
|
||||||
switch cb := cb.(type) {
|
switch cb := cb.(type) {
|
||||||
case func(*Context, *Context): // 遍历模块
|
case func(*Context, *Context):
|
||||||
cb(list[i].context, list[i])
|
cb(list[i].context, list[i])
|
||||||
|
|
||||||
case func(*Context, *Context, string, *Command):
|
case func(*Context, *Context, string, *Command):
|
||||||
target := m.target
|
target := m.target
|
||||||
for _, k := range kit.SortedKey(list[i].Commands) { // 命令列表
|
for _, k := range kit.SortedKey(list[i].Commands) {
|
||||||
m.target = list[i]
|
m.target = list[i]
|
||||||
cb(list[i].context, list[i], k, list[i].Commands[k])
|
cb(list[i].context, list[i], k, list[i].Commands[k])
|
||||||
}
|
}
|
||||||
m.target = target
|
m.target = target
|
||||||
|
|
||||||
case func(*Context, *Context, string, *Config):
|
case func(*Context, *Context, string, *Config):
|
||||||
target := m.target
|
target := m.target
|
||||||
for _, k := range kit.SortedKey(list[i].Configs) { // 配置列表
|
for _, k := range kit.SortedKey(list[i].Configs) {
|
||||||
m.target = list[i]
|
m.target = list[i]
|
||||||
cb(list[i].context, list[i], k, list[i].Configs[k])
|
cb(list[i].context, list[i], k, list[i].Configs[k])
|
||||||
}
|
}
|
||||||
@ -429,8 +388,7 @@ func (m *Message) Travel(cb Any) *Message {
|
|||||||
default:
|
default:
|
||||||
m.ErrorNotImplement(cb)
|
m.ErrorNotImplement(cb)
|
||||||
}
|
}
|
||||||
|
for _, k := range kit.SortedKey(list[i].Contexts) {
|
||||||
for _, k := range kit.SortedKey(list[i].Contexts) { // 遍历递进
|
|
||||||
list = append(list, list[i].Contexts[k])
|
list = append(list, list[i].Contexts[k])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -440,14 +398,12 @@ func (m *Message) Search(key string, cb Any) *Message {
|
|||||||
if key == "" {
|
if key == "" {
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查找模块
|
|
||||||
p := m.target.root
|
p := m.target.root
|
||||||
if key = strings.TrimPrefix(key, "ice."); key == PT {
|
if key = strings.TrimPrefix(key, "ice."); key == PT {
|
||||||
p, key = m.target, ""
|
p, key = m.target, ""
|
||||||
} else if key == ".." {
|
} else if key == ".." {
|
||||||
p, key = m.target.context, ""
|
p, key = m.target.context, ""
|
||||||
} else if key == "ice." {
|
} else if key == "..." {
|
||||||
p, key = m.target.root, ""
|
p, key = m.target.root, ""
|
||||||
} else if strings.Contains(key, PT) {
|
} else if strings.Contains(key, PT) {
|
||||||
ls := strings.Split(key, PT)
|
ls := strings.Split(key, PT)
|
||||||
@ -468,37 +424,33 @@ func (m *Message) Search(key string, cb Any) *Message {
|
|||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
key = ls[len(ls)-1]
|
key = ls[len(ls)-1]
|
||||||
} else if ctx, ok := Info.names[key].(*Context); ok {
|
} else if ctx, ok := Info.index[key].(*Context); ok {
|
||||||
p = ctx
|
p = ctx
|
||||||
} else {
|
} else {
|
||||||
p = m.target
|
p = m.target
|
||||||
}
|
}
|
||||||
|
|
||||||
switch cb := cb.(type) {
|
switch cb := cb.(type) {
|
||||||
case func(key string, cmd *Command):
|
case func(key string, cmd *Command):
|
||||||
if key == "" {
|
if key == "" {
|
||||||
for k, v := range p.Commands {
|
for k, v := range p.Commands {
|
||||||
cb(k, v) // 遍历命令
|
cb(k, v)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if cmd, ok := p.Commands[key]; ok {
|
if cmd, ok := p.Commands[key]; ok {
|
||||||
cb(key, cmd) // 查找命令
|
cb(key, cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
case func(p *Context, s *Context, key string, cmd *Command):
|
case func(p *Context, s *Context, key string, cmd *Command):
|
||||||
if key == "" {
|
if key == "" {
|
||||||
for k, v := range p.Commands {
|
for k, v := range p.Commands {
|
||||||
cb(p.context, p, k, v) // 遍历命令
|
cb(p.context, p, k, v)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, p := range []*Context{p, m.target, m.source} {
|
for _, p := range []*Context{p, m.target, m.source} {
|
||||||
for s := p; s != nil; s = s.context {
|
for s := p; s != nil; s = s.context {
|
||||||
if cmd, ok := s.Commands[key]; ok {
|
if cmd, ok := s.Commands[key]; ok {
|
||||||
cb(s.context, s, key, cmd) // 查找命令
|
cb(s.context, s, key, cmd)
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -506,23 +458,22 @@ func (m *Message) Search(key string, cb Any) *Message {
|
|||||||
case func(p *Context, s *Context, key string, conf *Config):
|
case func(p *Context, s *Context, key string, conf *Config):
|
||||||
if key == "" {
|
if key == "" {
|
||||||
for k, v := range p.Configs {
|
for k, v := range p.Configs {
|
||||||
cb(p.context, p, k, v) // 遍历命令
|
cb(p.context, p, k, v)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, p := range []*Context{p, m.target, m.source} {
|
for _, p := range []*Context{p, m.target, m.source} {
|
||||||
for s := p; s != nil; s = s.context {
|
for s := p; s != nil; s = s.context {
|
||||||
if cmd, ok := s.Configs[key]; ok {
|
if cmd, ok := s.Configs[key]; ok {
|
||||||
cb(s.context, s, key, cmd) // 查找配置
|
cb(s.context, s, key, cmd)
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case func(p *Context, s *Context, key string):
|
case func(p *Context, s *Context, key string):
|
||||||
cb(p.context, p, key) // 查找模块
|
cb(p.context, p, key)
|
||||||
case func(p *Context, s *Context):
|
case func(p *Context, s *Context):
|
||||||
cb(p.context, p) // 查找模块
|
cb(p.context, p)
|
||||||
default:
|
default:
|
||||||
m.ErrorNotImplement(cb)
|
m.ErrorNotImplement(cb)
|
||||||
}
|
}
|
||||||
@ -542,9 +493,7 @@ func (m *Message) CmdAppend(arg ...Any) string {
|
|||||||
}
|
}
|
||||||
func (m *Message) CmdMap(arg ...string) map[string]map[string]string {
|
func (m *Message) CmdMap(arg ...string) map[string]map[string]string {
|
||||||
field, list := kit.Slice(arg, -1)[0], map[string]map[string]string{}
|
field, list := kit.Slice(arg, -1)[0], map[string]map[string]string{}
|
||||||
m._command(kit.Slice(arg, 0, -1)).Tables(func(value Maps) {
|
m._command(kit.Slice(arg, 0, -1)).Tables(func(value Maps) { list[value[field]] = value })
|
||||||
list[value[field]] = value
|
|
||||||
})
|
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
func (m *Message) Cmd(arg ...Any) *Message {
|
func (m *Message) Cmd(arg ...Any) *Message {
|
||||||
@ -563,23 +512,21 @@ func (m *Message) Cmdy(arg ...Any) *Message {
|
|||||||
func (m *Message) Confi(key string, sub string) int {
|
func (m *Message) Confi(key string, sub string) int {
|
||||||
return kit.Int(m.Conf(key, sub))
|
return kit.Int(m.Conf(key, sub))
|
||||||
}
|
}
|
||||||
func (m *Message) Confv(arg ...Any) (val Any) { // key sub val
|
func (m *Message) Confv(arg ...Any) (val Any) {
|
||||||
run := func(conf *Config) {
|
run := func(conf *Config) {
|
||||||
if len(arg) == 1 {
|
if len(arg) == 1 {
|
||||||
val = conf.Value
|
val = conf.Value
|
||||||
return // 读配置
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(arg) > 2 {
|
if len(arg) > 2 {
|
||||||
if arg[1] == nil || arg[1] == "" {
|
if arg[1] == nil || arg[1] == "" {
|
||||||
conf.Value = arg[2] // 写配置
|
conf.Value = arg[2]
|
||||||
} else {
|
} else {
|
||||||
kit.Value(conf.Value, arg[1:]...) // 写配置项
|
kit.Value(conf.Value, arg[1:]...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val = kit.Value(conf.Value, arg[1]) // 读配置项
|
val = kit.Value(conf.Value, arg[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
key := kit.Format(arg[0])
|
key := kit.Format(arg[0])
|
||||||
if key == "" {
|
if key == "" {
|
||||||
key = m._key
|
key = m._key
|
||||||
@ -601,7 +548,7 @@ func (m *Message) Confm(key string, sub Any, cbs ...Any) Map {
|
|||||||
value, _ := val.(Map)
|
value, _ := val.(Map)
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
func (m *Message) Conf(arg ...Any) string { // key sub val
|
func (m *Message) Conf(arg ...Any) string {
|
||||||
return kit.Format(m.Confv(arg...))
|
return kit.Format(m.Confv(arg...))
|
||||||
}
|
}
|
||||||
func (m *Message) Capi(key string, val ...Any) int {
|
func (m *Message) Capi(key string, val ...Any) int {
|
||||||
@ -616,14 +563,13 @@ func (m *Message) Capv(arg ...Any) Any {
|
|||||||
case string:
|
case string:
|
||||||
key, arg = val, arg[1:]
|
key, arg = val, arg[1:]
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, s := range []*Context{m.target} {
|
for _, s := range []*Context{m.target} {
|
||||||
for c := s; c != nil; c = c.context {
|
for c := s; c != nil; c = c.context {
|
||||||
if caps, ok := c.Caches[key]; ok {
|
if caps, ok := c.Caches[key]; ok {
|
||||||
if len(arg) > 0 { // 写数据
|
if len(arg) > 0 {
|
||||||
caps.Value = kit.Format(arg[0])
|
caps.Value = kit.Format(arg[0])
|
||||||
}
|
}
|
||||||
return caps.Value // 读数据
|
return caps.Value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user