diff --git a/README.md b/README.md
index 8ce6cf27..2061e1e2 100644
--- a/README.md
+++ b/README.md
@@ -1,129 +1,3 @@
# 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/
+icebergs 是一个应用框架,通过模块化、集群化、自动化方式,在各种设备上,一键部署完整的个人云计算与云研发平台。
diff --git a/base/aaa/user.go b/base/aaa/user.go
index 8b205a63..bab220ad 100644
--- a/base/aaa/user.go
+++ b/base/aaa/user.go
@@ -83,11 +83,11 @@ func init() {
}
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))
- userrole := m.Option(ice.MSG_USERROLE, kit.Select(ROOT, arg, 2))
- m.Option(ice.MSG_USERNICK, UserNick(m, username))
+ usernick := m.Option(ice.MSG_USERNICK, kit.Select(UserNick(m, username), arg, 2))
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
}
return m
diff --git a/base/cli/runtime.go b/base/cli/runtime.go
index 0bc0f250..6d067bce 100644
--- a/base/cli/runtime.go
+++ b/base/cli/runtime.go
@@ -216,7 +216,7 @@ func init() {
}},
PROCKILL: {Name: "prockill", Help: "结束进程", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(gdb.SIGNAL, gdb.STOP, m.Option("PID"))
- m.ProcessRefresh30ms()
+ m.ProcessRefresh()
}},
DISKINFO: {Name: "diskinfo", Help: "磁盘信息", Hand: func(m *ice.Message, arg ...string) {
_runtime_diskinfo(m)
diff --git a/base/mdb/mdb.go b/base/mdb/mdb.go
index 2ba8b414..cb8649f0 100644
--- a/base/mdb/mdb.go
+++ b/base/mdb/mdb.go
@@ -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) {
- defer m.ProcessRefresh3ms()
+ defer m.ProcessRefresh()
switch arg[2] {
case ZONE: // insert key sub type zone arg...
_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) {
- defer m.ProcessRefresh3ms()
+ defer m.ProcessRefresh()
switch arg[2] {
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])
diff --git a/base/mdb/search.go b/base/mdb/search.go
index 87940690..f0b79d84 100644
--- a/base/mdb/search.go
+++ b/base/mdb/search.go
@@ -9,6 +9,13 @@ const SEARCH = "search"
func init() {
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 {
return ice.Actions{
diff --git a/base/ssh/script.go b/base/ssh/script.go
index 0895dca7..cd4f7b25 100644
--- a/base/ssh/script.go
+++ b/base/ssh/script.go
@@ -36,6 +36,9 @@ func (f *Frame) prompt(m *ice.Message, list ...string) *Frame {
if f.source != STDIO {
return f
}
+ if m.Target().Cap(ice.CTX_STATUS) == ice.CTX_CLOSE {
+ return f
+ }
if len(list) == 0 {
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() {
msg.SetResult().Cmdy(cli.SYSTEM, ls)
}
-
f.res = Render(msg, msg.Option(ice.MSG_OUTPUT), msg.Optionv(ice.MSG_ARGS).([]ice.Any)...)
return ""
}
diff --git a/base/web/dream.go b/base/web/dream.go
index 143d91df..95814f78 100644
--- a/base/web/dream.go
+++ b/base/web/dream.go
@@ -31,7 +31,7 @@ func _dream_list(m *ice.Message) *ice.Message {
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) {
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),
))
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))
defer ToastProcess(m)()
diff --git a/base/web/serve.go b/base/web/serve.go
index dc803362..6601c5ab 100644
--- a/base/web/serve.go
+++ b/base/web/serve.go
@@ -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))))
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)
@@ -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 {
m.Option(tcp.PORT, m.Cmdx(tcp.PORT, aaa.RIGHT))
}
-
- 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))
+ aaa.UserRoot(m, m.Option(aaa.PASSWORD), m.Option(aaa.USERNAME), m.Option(aaa.USERNICK))
m.Target().Start(m, m.OptionSimple(tcp.HOST, tcp.PORT)...)
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))
}
}},
- 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)
}},
}, mdb.HashAction())},
@@ -396,7 +392,7 @@ func init() {
}},
PP(ice.HELP): {Name: "/help/", Help: "帮助", Hand: func(m *ice.Message, arg ...string) {
if len(arg) == 0 {
- arg = append(arg, ice.TUTOR_SHY)
+ arg = append(arg, "tutor.shy")
}
if len(arg) > 0 && arg[0] != ctx.ACTION {
arg[0] = path.Join(ice.SRC_HELP, arg[0])
@@ -404,4 +400,13 @@ func init() {
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
+ })
}
diff --git a/conf.go b/conf.go
index edda3810..459a1c17 100644
--- a/conf.go
+++ b/conf.go
@@ -14,12 +14,12 @@ const (
OK = "ok"
TRUE = "true"
FALSE = "false"
- SUCCESS = "success"
- FAILURE = "failure"
PROCESS = "process"
+ FAILURE = "failure"
+ SUCCESS = "success"
- AUTO = "auto"
HTTP = "http"
+ AUTO = "auto"
LIST = "list"
BACK = "back"
@@ -28,6 +28,7 @@ const (
MISC = "misc"
SHY = "shy"
+ COM = "com"
DEV = "dev"
OPS = "ops"
ICE = "ice"
@@ -49,16 +50,16 @@ const ( // MOD
MOD_TIME = "2006-01-02 15:04:05"
)
const ( // REPOS
- VOLCANOS = "volcanos"
- LEARNING = "learning"
- ICEBERGS = "icebergs"
- TOOLKITS = "toolkits"
INTSHELL = "intshell"
CONTEXTS = "contexts"
+ ICEBERGS = "icebergs"
+ TOOLKITS = "toolkits"
+ VOLCANOS = "volcanos"
+ LEARNING = "learning"
INSTALL = "install"
- RELEASE = "release"
PUBLISH = "publish"
+ RELEASE = "release"
REQUIRE = "require"
DISPLAY = "display"
)
@@ -69,12 +70,12 @@ const ( // DIR
VAR = "var"
USR = "usr"
+ SVG = "svg"
HTML = "html"
CSS = "css"
JS = "js"
GO = "go"
SH = "sh"
- SVG = "svg"
CSV = "csv"
JSON = "json"
@@ -89,45 +90,41 @@ const ( // DIR
FRAME_JS = "frame.js"
INDEX_JS = "index.js"
INDEX_SH = "index.sh"
- INDEX_IML = "index.iml"
- TUTOR_SHY = "tutor.shy"
- PLUGIN_INPUT = "/plugin/input"
- PLUGIN_STORY = "/plugin/story"
- PLUGIN_LOCAL = "/plugin/local"
- NODE_MODULES = "node_modules"
- ISH_PLUGED = ".ish/pluged"
+ PLUGIN_INPUT = "/plugin/input/"
+ PLUGIN_STORY = "/plugin/story/"
+ PLUGIN_LOCAL = "/plugin/local/"
+ NODE_MODULES = "node_modules/"
+ ISH_PLUGED = ".ish/pluged/"
- USR_VOLCANOS = "usr/volcanos"
- USR_LEARNING = "usr/learning"
- USR_ICEBERGS = "usr/icebergs"
- USR_TOOLKITS = "usr/toolkits"
- USR_INTSHELL = "usr/intshell"
- USR_INSTALL = "usr/install"
- USR_RELEASE = "usr/release"
- USR_PUBLISH = "usr/publish"
+ USR_VOLCANOS = "usr/volcanos/"
+ USR_LEARNING = "usr/learning/"
+ USR_ICEBERGS = "usr/icebergs/"
+ USR_TOOLKITS = "usr/toolkits/"
+ USR_INTSHELL = "usr/intshell/"
+ USR_INSTALL = "usr/install/"
+ USR_PUBLISH = "usr/publish/"
+ USR_RELEASE = "usr/release/"
- USR_LOCAL = "usr/local"
- USR_LOCAL_GO = "usr/local/go"
- USR_LOCAL_GO_BIN = "usr/local/go/bin"
- USR_LOCAL_BIN = "usr/local/bin"
- USR_LOCAL_LIB = "usr/local/lib"
- USR_LOCAL_WORK = "usr/local/work"
- USR_LOCAL_IMAGE = "usr/local/image"
- USR_LOCAL_MEDIA = "usr/local/media"
- USR_LOCAL_RIVER = "usr/local/river"
- USR_LOCAL_DAEMON = "usr/local/daemon"
- USR_LOCAL_EXPORT = "usr/local/export"
- USR_LOCAL_REPOS = "usr/local/repos"
+ USR_LOCAL = "usr/local/"
+ USR_LOCAL_GO = "usr/local/go/"
+ USR_LOCAL_GO_BIN = "usr/local/go/bin/"
+ USR_LOCAL_BIN = "usr/local/bin/"
+ USR_LOCAL_LIB = "usr/local/lib/"
+ USR_LOCAL_WORK = "usr/local/work/"
+ USR_LOCAL_IMAGE = "usr/local/image/"
+ USR_LOCAL_DAEMON = "usr/local/daemon/"
+ USR_LOCAL_EXPORT = "usr/local/export/"
+ USR_LOCAL_REPOS = "usr/local/repos/"
- VAR_RUN = "var/run"
- VAR_TMP = "var/tmp"
- VAR_LOG = "var/log"
- VAR_CONF = "var/conf"
- VAR_DATA = "var/data"
- VAR_FILE = "var/file"
- VAR_PROXY = "var/proxy"
- VAR_TRASH = "var/trash"
+ VAR_RUN = "var/run/"
+ VAR_TMP = "var/tmp/"
+ VAR_LOG = "var/log/"
+ VAR_CONF = "var/conf/"
+ VAR_DATA = "var/data/"
+ VAR_FILE = "var/file/"
+ VAR_PROXY = "var/proxy/"
+ VAR_TRASH = "var/trash/"
BIN_ICE_BIN = "bin/ice.bin"
BIN_BOOT_LOG = "bin/boot.log"
ETC_INIT_SHY = "etc/init.shy"
@@ -136,13 +133,13 @@ const ( // DIR
ETC_MISS_SH = "etc/miss.sh"
ETC_PATH = "etc/path"
- SRC_HELP = "src/help"
- SRC_DEBUG = "src/debug"
- SRC_RELEASE = "src/release"
+ SRC_HELP = "src/help/"
+ SRC_DEBUG = "src/debug/"
+ SRC_RELEASE = "src/release/"
+ SRC_MAIN_SVG = "src/main.svg"
+ SRC_MAIN_SHY = "src/main.shy"
SRC_MAIN_JS = "src/main.js"
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_BINPACK_GO = "src/binpack.go"
SRC_RELAY_GO = "src/relay.go"
@@ -167,8 +164,8 @@ const ( // MSG
MSG_SOURCE = "_source"
MSG_TARGET = "_target"
MSG_HANDLE = "_handle"
- MSG_DAEMON = "_daemon"
MSG_UPLOAD = "_upload"
+ MSG_DAEMON = "_daemon"
MSG_ACTION = "_action"
MSG_STATUS = "_status"
@@ -193,24 +190,25 @@ const ( // MSG
MSG_USERZONE = "user.zone"
MSG_LANGUAGE = "user.lang"
- MSG_TITLE = "sess.title"
- MSG_TOPIC = "sess.topic"
- MSG_RIVER = "sess.river"
- MSG_STORM = "sess.storm"
- MSG_FILES = "file.system"
+ MSG_TITLE = "sess.title"
+ MSG_TOPIC = "sess.topic"
+ MSG_RIVER = "sess.river"
+ MSG_STORM = "sess.storm"
+ MSG_FILES = "file.system"
+ LOG_DISABLE = "log.disable"
FIELDS_DETAIL = "detail"
)
const ( // RENDER
- RENDER_TEMPLATE = "_template"
- RENDER_ANCHOR = "_anchor"
- RENDER_BUTTON = "_button"
- RENDER_IMAGES = "_images"
- RENDER_VIDEOS = "_videos"
- RENDER_IFRAME = "_iframe"
- RENDER_QRCODE = "_qrcode"
- RENDER_SCRIPT = "_script"
+ RENDER_BUTTON = "_button"
+ RENDER_ANCHOR = "_anchor"
+ RENDER_QRCODE = "_qrcode"
+ RENDER_IMAGES = "_images"
+ RENDER_VIDEOS = "_videos"
+ RENDER_IFRAME = "_iframe"
+ RENDER_SCRIPT = "_script"
+ RENDER_TEMPLATE = "_template"
RENDER_STATUS = "_status"
RENDER_REDIRECT = "_redirect"
RENDER_DOWNLOAD = "_download"
@@ -227,9 +225,9 @@ const ( // PROCESS
PROCESS_REFRESH = "_refresh"
PROCESS_REWRITE = "_rewrite"
PROCESS_DISPLAY = "_display"
- PROCESS_INNER = "_inner"
PROCESS_FIELD = "_field"
PROCESS_FLOAT = "_float"
+ PROCESS_INNER = "_inner"
PROCESS_AGAIN = "_again"
PROCESS_HOLD = "_hold"
@@ -242,6 +240,9 @@ const ( // PROCESS
FIELD_PREFIX = "_prefix"
)
const ( // CTX
+ CTX_ARG = "ctx_arg"
+ CTX_DAEMON = "ctx_daemon"
+
CTX_FOLLOW = "follow"
CTX_STATUS = "status"
CTX_STREAM = "stream"
@@ -253,50 +254,64 @@ const ( // CTX
CTX_INIT = "_init"
CTX_EXIT = "_exit"
-
- CTX_ARG = "ctx_arg"
- CTX_DAEMON = "ctx_daemon"
)
-
const ( // LOG
LOG_CMDS = "cmds"
LOG_AUTH = "auth"
LOG_COST = "cost"
LOG_INFO = "info"
LOG_WARN = "warn"
- LOG_DEBUG = "debug"
LOG_ERROR = "error"
+ LOG_DEBUG = "debug"
)
const ( // Err
ErrWarn = "warn: "
- ErrNotLogin = "not login: "
- ErrNotRight = "not right: "
- ErrNotFound = "not found: "
- ErrNotValid = "not valid: "
- ErrNotStart = "not start: "
+ ErrNotLogin = "not login: "
+ ErrNotRight = "not right: "
+ ErrNotFound = "not found: "
+ ErrNotValid = "not valid: "
+ ErrNotStart = "not start: "
+
ErrNotImplement = "not implement: "
)
-
const ( // ctx
COMMAND = "command"
ACTION = "action"
STYLE = "style"
INDEX = "index"
)
-const ( // mdb
- AAA = "aaa"
- MDB = "mdb"
- KEY = "key"
- VALUE = "value"
- FIELD = "field"
- EXTRA = "extra"
- SCRIPT = "script"
- META = "meta"
- HASH = "hash"
- TIME = "time"
- TYPE = "type"
- NAME = "name"
- TEXT = "text"
- LINK = "link"
+const ( // web
+ SERVE = "serve"
+ SPACE = "space"
+
+ TOPIC = "topic"
+ TITLE = "title"
+ WIDTH = "width"
+ HEIGHT = "height"
+)
+const ( // nfs
+ SOURCE = "source"
+ SCRIPT = "script"
+)
+const ( // mdb
+ SEARCH = "search"
+ SELECT = "select"
+
+ KEY = "key"
+ VALUE = "value"
+ EXTRA = "extra"
+ FIELD = "field"
+ META = "meta"
+ HASH = "hash"
+ TIME = "time"
+ TYPE = "type"
+ NAME = "name"
+ TEXT = "text"
+ LINK = "link"
+)
+const ( // ice
+ MDB = "mdb"
+ AAA = "aaa"
+ CLI = "cli"
)
diff --git a/core/chat/website.go b/core/chat/website.go
index 4f038a18..bb6fde15 100644
--- a/core/chat/website.go
+++ b/core/chat/website.go
@@ -89,7 +89,7 @@ func _website_parse(m *ice.Message, text string, args ...string) (ice.Map, bool)
case ctx.ARGS:
data[ls[i]] = kit.Split(ls[i+1])
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:
data[ls[i]] = kit.UnMarshal(ls[i+1])
default:
diff --git a/core/mall/asset.go b/core/mall/asset.go
index f1b03e78..5973a3c7 100644
--- a/core/mall/asset.go
+++ b/core/mall/asset.go
@@ -86,7 +86,7 @@ func init() {
m.Cmd(ASSET, func(value ice.Maps) {
_asset_check(m, value[ACCOUNT])
})
- m.ProcessRefresh30ms()
+ m.ProcessRefresh()
} else {
_asset_check(m, m.Option(ACCOUNT))
}
diff --git a/core/wiki/word.go b/core/wiki/word.go
index 32d0eac5..d9a4b8db 100644
--- a/core/wiki/word.go
+++ b/core/wiki/word.go
@@ -12,7 +12,7 @@ import (
)
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)))
}
diff --git a/data.go b/data.go
index 4cc89a45..a91c3248 100644
--- a/data.go
+++ b/data.go
@@ -7,13 +7,13 @@ import (
)
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 {
- 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 {
- 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 {
return m.Target().PrefixKey(arg...)
diff --git a/exec.go b/exec.go
index 797efb15..086edd76 100644
--- a/exec.go
+++ b/exec.go
@@ -7,23 +7,23 @@ import (
"time"
kit "shylinux.com/x/toolkits"
+ "shylinux.com/x/toolkits/logs"
"shylinux.com/x/toolkits/task"
)
func (m *Message) TryCatch(msg *Message, silent bool, hand ...func(msg *Message)) *Message {
defer func() {
switch e := recover(); e {
- case io.EOF:
- case nil:
+ case nil, io.EOF:
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("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 {
m.TryCatch(msg, silent, hand[1:]...)
} else if !silent {
- m.Assert(e) // 抛出异常
+ m.Assert(e)
}
}
}()
@@ -36,13 +36,13 @@ func (m *Message) Assert(expr Any) bool {
switch e := expr.(type) {
case nil:
return true
- case error:
case bool:
if e == true {
return true
}
+ case error:
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)
panic(expr)
diff --git a/info.go b/info.go
index 7027db34..a90ac1d4 100644
--- a/info.go
+++ b/info.go
@@ -1,13 +1,13 @@
package ice
type MakeInfo struct {
- Path string
Time string
+ Path string
Hash string
+ Domain string
Module string
Remote string
Branch string
- Domain string
Version string
HostName string
UserName string
@@ -21,19 +21,20 @@ var Info = struct {
UserName string
PassWord string
- Colors bool
Domain string
NodeType string
NodeName string
CtxShare string
CtxRiver string
PidPath string
+ Colors bool
Help string
- Route Maps // 路由命令
- File Maps // 文件命令
- names Map
+ File Maps
+ Route Maps
+ index Map
+ merges []MergeHandler
render map[string]func(*Message, string, ...Any) string
Save 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
source: https://shylinux.com/x/icebergs
`,
- Route: Maps{},
File: Maps{},
- names: Map{},
+ Route: Maps{},
+ index: Map{},
render: map[string]func(*Message, string, ...Any) string{},
Save: 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) {},
}
+
+type MergeHandler func(*Context, string, *Command, string, *Action) (Handler, Handler)
+
+func AddMerges(h ...MergeHandler) { Info.merges = append(Info.merges, h...) }
diff --git a/init.go b/init.go
index a061e805..a7ac0c69 100644
--- a/init.go
+++ b/init.go
@@ -12,10 +12,7 @@ import (
type Frame struct{}
-func (f *Frame) Spawn(m *Message, c *Context, arg ...string) Server {
- return &Frame{}
-}
-func (f *Frame) Begin(m *Message, arg ...string) Server {
+func (s *Frame) Begin(m *Message, arg ...string) Server {
list := map[*Context]*Message{m.target: m}
m.Travel(func(p *Context, s *Context) {
s.root = m.target
@@ -24,21 +21,20 @@ func (f *Frame) Begin(m *Message, arg ...string) Server {
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.Cmd(kit.Keys(MDB, CTX_INIT))
- m.Cmd("cli.runtime", CTX_INIT)
+ m.Cmd(kit.Keys(CLI, CTX_INIT))
m.Cmdy(INIT, arg)
-
for _, k := range kit.Split(kit.Select("ctx,log,gdb,ssh", os.Getenv(CTX_DAEMON))) {
m.Start(k)
}
- m.Cmd(arg)
+ m.Cmdy(arg)
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}
m.Travel(func(p *Context, s *Context) {
if msg, ok := list[p]; ok && msg != nil {
@@ -47,9 +43,10 @@ func (f *Frame) Close(m *Message, arg ...string) bool {
}
})
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
}
+func (s *Frame) Spawn(m *Message, c *Context, arg ...string) Server { return &Frame{} }
const (
INIT = "init"
@@ -58,9 +55,7 @@ const (
QUIT = "quit"
)
-var Index = &Context{Name: ICE, Help: "冰山模块", Configs: Configs{
- HELP: {Value: kit.Data(INDEX, Info.Help)},
-}, Commands: Commands{
+var Index = &Context{Name: ICE, Help: "冰山模块", Configs: Configs{HELP: {Value: kit.Data(INDEX, Info.Help)}}, Commands: Commands{
CTX_INIT: {Hand: func(m *Message, arg ...string) {
m.root.Travel(func(p *Context, c *Context) {
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.Cmd("source", ETC_INIT_SHY)
+ m.Cmd(SOURCE, ETC_INIT_SHY)
}},
- HELP: {Name: "help", Help: "帮助", Hand: func(m *Message, arg ...string) {
- m.Echo(m.Config(INDEX))
- }},
- 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...)
+ HELP: {Hand: func(m *Message, arg ...string) { m.Echo(m.Config(INDEX)) }},
+ QUIT: {Hand: func(m *Message, arg ...string) { os.Exit(0) }},
+ EXIT: {Hand: func(m *Message, arg ...string) {
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)
}},
CTX_EXIT: {Hand: func(m *Message, arg ...string) {
+ defer m.Target().Close(m.root.Spawn(), arg...)
m.root.Travel(func(p *Context, c *Context) {
if cmd, ok := c.Commands[CTX_EXIT]; ok && p != nil {
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 Run(arg ...string) string {
- if len(arg) == 0 { // 进程参数
- arg = kit.Simple(arg, os.Args[1:], kit.Split(os.Getenv(CTX_ARG)))
+ if len(arg) == 0 && len(os.Args) > 1 {
+ arg = kit.Simple(os.Args[1:], kit.Split(kit.Env(CTX_ARG)))
}
-
Pulse.meta[MSG_DETAIL] = arg
- switch Index.Merge(Index).Begin(Pulse.Spawn(), arg...); kit.Select("", arg, 0) {
- case "serve", "space": // 启动服务
+ switch Index.Merge(Index).Begin(Pulse, arg...); kit.Select("", arg, 0) {
+ case SERVE, SPACE:
if Index.Start(Pulse, arg...) {
conf.Wait()
- println()
os.Exit(kit.Int(Pulse.Option(EXIT)))
}
- default: // 执行命令
+ default:
if logs.Disable(true); len(arg) == 0 {
arg = append(arg, HELP)
}
- Pulse.Cmd(INIT)
- if Pulse.Cmdy(arg); strings.TrimSpace(Pulse.Result()) == "" {
+ if Pulse.Cmd(INIT).Cmdy(arg); strings.TrimSpace(Pulse.Result()) == "" {
Pulse.Table()
}
- }
-
- if !strings.HasSuffix(Pulse.Result(), NL) {
- Pulse.Echo(NL)
+ if !strings.HasSuffix(Pulse.Result(), NL) {
+ Pulse.Echo(NL)
+ }
}
return Pulse.Result()
}
diff --git a/logs.go b/logs.go
index bbb3cc31..11b327a2 100644
--- a/logs.go
+++ b/logs.go
@@ -29,27 +29,21 @@ func (m *Message) join(arg ...Any) (string, []Any) {
continue
}
switch v := arg[i+1].(type) {
- case logs.Meta:
- list = append(list, key)
- meta = append(meta, v)
- continue
case time.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
}
func (m *Message) log(level string, str string, arg ...Any) *Message {
_source := logs.FileLineMeta(logs.FileLine(3, 3))
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
}
-
- // 日志颜色
prefix, suffix := "", ""
if Info.Colors {
switch level {
@@ -57,20 +51,16 @@ func (m *Message) log(level string, str string, arg ...Any) *Message {
prefix, suffix = "\033[32m", "\033[0m"
case LOG_AUTH, LOG_COST:
prefix, suffix = "\033[33m", "\033[0m"
- case LOG_WARN:
+ case LOG_WARN, LOG_ERROR:
prefix, suffix = "\033[31m", "\033[0m"
}
}
-
- // 长度截断
switch level {
case LOG_INFO:
if len(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)...)
return m
}
@@ -116,32 +106,26 @@ func (m *Message) Warn(err Any, arg ...Any) bool {
if !m.IsErr() {
if m.error(arg...); len(arg) > 0 {
switch kit.Format(arg[0]) {
- case ErrNotValid:
- m.RenderStatusBadRequest(str)
case ErrNotLogin:
m.RenderStatusUnauthorized(str)
case ErrNotRight:
m.RenderStatusForbidden(str)
case ErrNotFound:
m.RenderStatusNotFound(str)
+ case ErrNotValid:
+ m.RenderStatusBadRequest(str)
}
}
}
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 {
if err {
- m.error(arg...)
- m.log(LOG_ERROR, m.FormatStack(1, 100))
str, meta := m.join(arg...)
- m.log(LOG_ERROR, str, meta)
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 false
@@ -156,12 +140,19 @@ func (m *Message) error(arg ...Any) {
arg = append(arg, "")
}
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 {
- 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 {
@@ -187,7 +178,6 @@ func (m *Message) FormatChain() string {
for msg := m; msg != nil; msg = msg.message {
ms = append(ms, msg)
}
-
meta := append([]string{}, NL)
for i := len(ms) - 1; i >= 0; i-- {
msg := ms[i]
@@ -213,20 +203,16 @@ func (m *Message) FormatChain() string {
func (m *Message) FormatStack(s, n int) string {
pc := make([]uintptr, n+10)
frames := runtime.CallersFrames(pc[:runtime.Callers(s+1, pc)])
-
list := []string{}
for {
frame, more := frames.Next()
file := kit.Slice(kit.Split(frame.File, 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) {
- // case "reflect", "runtime", "http", "task", "icebergs":
case "reflect", "runtime", "http":
default:
list = append(list, kit.Format("%s:%d\t%s", file, frame.Line, name))
}
-
if len(list) >= n {
break
}
diff --git a/meta.go b/meta.go
index 66b712cb..003cf587 100644
--- a/meta.go
+++ b/meta.go
@@ -7,6 +7,24 @@ import (
kit "shylinux.com/x/toolkits"
)
+func (m *Message) setDetail(key string, arg ...string) *Message {
+ for i := 0; i < len(m.meta[KEY]); i++ {
+ if m.meta[KEY][i] == key {
+ if len(arg) > 0 {
+ m.meta[VALUE][i] = arg[0]
+ 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
+}
func (m *Message) Set(key string, arg ...string) *Message {
switch key {
case MSG_DETAIL, MSG_RESULT:
@@ -14,61 +32,33 @@ func (m *Message) Set(key string, arg ...string) *Message {
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
+ m.setDetail(arg[0], arg[1:]...)
+ } else {
+ delete(m.meta, KEY)
+ delete(m.meta, VALUE)
+ delete(m.meta, MSG_APPEND)
}
- 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 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
}
+ return m
default:
+ if m.FieldsIsDetail() {
+ return m.setDetail(key, arg...)
+ }
for _, k := range kit.Split(key) {
delete(m.meta, k)
}
- if m.FieldsIsDetail() {
- for i := 0; i < len(m.meta[KEY]); i++ {
- if m.meta[KEY][i] == key {
- if len(arg) > 0 {
- m.meta[VALUE][i] = arg[0]
- 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
- }
+ }
+ if len(arg) == 0 {
+ return m
}
return m.Add(key, arg...)
}
@@ -76,21 +66,15 @@ func (m *Message) Add(key string, arg ...string) *Message {
switch key {
case MSG_DETAIL, MSG_RESULT:
m.meta[key] = append(m.meta[key], arg...)
-
case MSG_OPTION, MSG_APPEND:
if len(arg) == 0 {
break
}
- if key == MSG_APPEND {
- if i := kit.IndexOf(m.meta[MSG_OPTION], arg[0]); i > -1 {
- m.meta[MSG_OPTION][i] = ""
+ if index := 0; key == MSG_APPEND {
+ if m.meta[MSG_OPTION], index = kit.SliceRemove(m.meta[MSG_OPTION], arg[0]); index > -1 {
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 {
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() {
head = kit.Split(m.OptionFields())
}
-
switch value := value.(type) {
case Map:
- if len(head) == 0 { // 键值排序
- head = kit.SortedKey(kit.KeyValue(Map{}, "", value))
+ if len(head) == 0 {
+ head = kit.SortedKey(kit.KeyValue(nil, "", value))
}
-
var val Map
if len(arg) > 1 {
val, _ = arg[1].(Map)
}
-
for _, k := range head {
- // 查找数据
var v Any
switch k {
case KEY, HASH:
@@ -158,40 +138,33 @@ func (m *Message) Push(key string, value Any, arg ...Any) *Message {
break
}
}
-
- // 追加数据
switch v := kit.Format(v); key {
case FIELDS_DETAIL:
switch k {
case "_target":
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)
default:
m.Add(MSG_APPEND, k, v)
}
}
-
case Maps:
- if len(head) == 0 { // 键值排序
+ if len(head) == 0 {
head = kit.SortedKey(value)
}
-
for _, k := range head {
m.Push(k, value[k])
}
-
default:
for _, v := range kit.Simple(value, arg) {
if m.FieldsIsDetail() {
- if key != KEY || key != VALUE {
- m.Add(MSG_APPEND, KEY, key)
- m.Add(MSG_APPEND, VALUE, kit.Format(value))
- continue
- }
+ m.Add(MSG_APPEND, KEY, key)
+ m.Add(MSG_APPEND, VALUE, kit.Format(value))
+ } else {
+ m.Add(MSG_APPEND, key, v)
}
- m.Add(MSG_APPEND, key, v)
}
}
return m
@@ -200,8 +173,7 @@ func (m *Message) Echo(str string, arg ...Any) *Message {
if str == "" {
return m
}
- m.meta[MSG_RESULT] = append(m.meta[MSG_RESULT], kit.Format(str, arg...))
- return m
+ return m.Add(MSG_RESULT, kit.Format(str, arg...))
}
func (m *Message) Copy(msg *Message, arg ...string) *Message {
if m == nil || msg == nil || m == msg {
@@ -213,12 +185,9 @@ func (m *Message) Copy(msg *Message, arg ...string) *Message {
}
return m
}
-
for _, k := range msg.meta[MSG_OPTION] {
switch k {
- case MSG_CMDS:
- case MSG_FIELDS:
- case MSG_SESSID:
+ case MSG_CMDS, MSG_FIELDS, MSG_SESSID:
continue
}
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] {
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
+ return m.Add(MSG_RESULT, msg.meta[MSG_RESULT]...)
}
func (m *Message) Length() (max int) {
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 {
return m.Table(func(index int, value Maps, head []string) {
for _, cb := range cbs {
- if cb != nil {
- cb(value)
- }
+ cb(value)
}
})
}
func (m *Message) Table(cbs ...func(index int, value Maps, head []string)) *Message {
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])
+ n := m.Length()
+ if n == 0 {
return m
}
-
- n := m.Length()
- for i := 0; i < n; i++ {
- line := Maps{}
- 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
}
-
const (
TABLE_SPACE = "table.space"
TABLE_ROW_SEP = "table.row_sep"
TABLE_COL_SEP = "table.col_sep"
TABLE_COMPACT = "table.compact"
+ TABLE_ALIGN = "table.align"
)
- //计算列宽
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] {
- if len(m.meta[k]) > depth {
- depth = len(m.meta[k])
+ if len(m.meta[k]) > length {
+ length = len(m.meta[k])
}
width[k] = kit.Width(k, len(space))
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))
cols := kit.Select(SP, m.Option(TABLE_COL_SEP))
- compact := m.Option(TABLE_COMPACT) == TRUE
- cb := func(value Maps, field []string, index int) bool {
- for i, v := range field {
- if k := m.meta[MSG_APPEND][i]; compact {
- v = value[k]
- }
-
- if m.Echo(v); i < len(field)-1 {
+ show := func(value []string) {
+ for i, v := range value {
+ if m.Echo(v); i < len(value)-1 {
m.Echo(cols)
}
}
m.Echo(rows)
- return true
}
-
- // 输出表头
- row, wor := Maps{}, []string{}
- for _, k := range m.meta[MSG_APPEND] {
- row[k], wor = k, append(wor, k+strings.Repeat(space, width[k]-kit.Width(k, len(space))))
- }
- if !cb(row, wor, -1) {
- return m
- }
-
- // 输出数据
- 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))))
+ compact := m.Option(TABLE_COMPACT) == TRUE
+ _align := kit.Select("left", m.Option(TABLE_ALIGN))
+ align := func(value string, width int) string {
+ if compact {
+ return value + space
}
- if !cb(row, wor, i) {
- break
+ n := width - kit.Width(value, len(space))
+ 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
+ }
+ 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
}
+
+const (
+ INT = "int"
+ STR = "str"
+ // TIME = "time"
+
+ TIME_R = "time_r"
+ STR_R = "str_r"
+ INT_R = "int_r"
+)
+
func (m *Message) Sort(key string, arg ...string) *Message {
- ls := kit.Split(key)
- if key = ls[0]; m.FieldsIsDetail() && key != KEY {
+ if m.FieldsIsDetail() {
return m
}
- const (
- STR = "str"
- INT = "int"
- TIME = "time"
-
- TIME_R = "time_r"
- INT_R = "int_r"
- STR_R = "str_r"
-
- GT = ">"
- LT = "<"
- )
-
- // 排序方法
- cmp := STR
- if len(arg) > 0 && arg[0] != "" {
- cmp = arg[0]
- } else {
- cmp = INT
- for _, v := range m.meta[key] {
- if _, e := strconv.Atoi(v); e != nil {
- cmp = STR
+ keys, cmps := kit.Split(key), kit.Simple()
+ for i, k := range keys {
+ cmp := kit.Select("", arg, i)
+ if cmp == "" {
+ cmp = INT
+ for _, v := range m.meta[k] {
+ if _, e := strconv.Atoi(v); e != nil {
+ 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]))
- }
- })
- compare := func(i, j int, op string) bool {
- for k := range ls {
- if k == 0 {
+ list := []Maps{}
+ m.Tables(func(value Maps) { list = append(list, value) })
+ gt := func(i, j int) bool {
+ for s, k := range keys {
+ a, b := list[i][k], list[j][k]
+ if a == b {
continue
}
- if table[i][ls[k]] == table[j][ls[k]] {
- continue
+ switch cmp := cmps[s]; cmp {
+ 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
}
-
- // 排序数据
- for i := 0; i < len(table)-1; i++ {
- 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 swap {
- table[i], table[j] = table[j], table[i]
- number[i], number[j] = number[j], number[i]
+ for i := 0; i < len(list)-1; i++ {
+ min := i
+ for j := i + 1; j < len(list); j++ {
+ if gt(min, j) {
+ min = j
}
}
+ if min != i {
+ list[i], list[min] = list[min], list[i]
+ }
}
-
- // 输出数据
for _, k := range m.meta[MSG_APPEND] {
delete(m.meta, k)
}
- for _, v := range table {
+ for _, v := range list {
for _, k := range m.meta[MSG_APPEND] {
m.Add(MSG_APPEND, k, v[k])
}
}
return m
}
-func (m *Message) SortInt(key string) { m.Sort(key, "int") }
-func (m *Message) SortIntR(key string) { m.Sort(key, "int_r") }
-func (m *Message) SortStr(key string) { m.Sort(key, "str") }
-func (m *Message) SortStrR(key string) { m.Sort(key, "str_r") }
-func (m *Message) SortTime(key string) { m.Sort(key, "time") }
-func (m *Message) SortTimeR(key string) { m.Sort(key, "time_r") }
+func (m *Message) SortInt(key string) { m.Sort(key, INT) }
+func (m *Message) SortStr(key string) { m.Sort(key, STR) }
+func (m *Message) SortTime(key string) { m.Sort(key, TIME) }
+func (m *Message) SortTimeR(key string) { m.Sort(key, TIME_R) }
+func (m *Message) SortStrR(key string) { m.Sort(key, STR_R) }
+func (m *Message) SortIntR(key string) { m.Sort(key, INT_R) }
func (m *Message) Detail(arg ...Any) string {
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 {
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 {
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)
}
-
- switch delete(m.data, key); str := arg[0].(type) {
+ switch delete(m.data, key); v := arg[0].(type) {
case nil:
delete(m.meta, key)
case string:
m.meta[key] = kit.Simple(arg...)
case []string:
- m.meta[key] = str
+ m.meta[key] = v
default:
- m.data[key] = str
+ m.data[key] = v
}
}
-
for msg := m; msg != nil; msg = msg.message {
- if list, ok := msg.data[key]; ok {
- return list // 读数据
+ if v, ok := msg.data[key]; ok {
+ return v
}
- if list, ok := msg.meta[key]; ok {
- return list // 读选项
+ if v, ok := msg.meta[key]; ok {
+ return v
}
}
return nil
}
-func (m *Message) Message() *Message {
- return m.message
-}
func (m *Message) Option(key string, arg ...Any) string {
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)
}
func (m *Message) Appendv(key string, arg ...Any) []string {
- if key == MSG_APPEND {
- if len(arg) > 0 {
- m.meta[MSG_APPEND] = kit.Simple(arg)
- }
- return m.meta[key]
- }
-
- if m.FieldsIsDetail() && key != KEY {
+ if m.FieldsIsDetail() {
for i, k := range m.meta[KEY] {
if k == key || k == kit.Keys(EXTRA, key) {
if len(arg) > 0 {
@@ -526,7 +451,12 @@ func (m *Message) Appendv(key string, arg ...Any) []string {
}
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 {
m.meta[key] = kit.Simple(arg...)
}
diff --git a/misc.go b/misc.go
index 6a2ea404..a18b0e4b 100644
--- a/misc.go
+++ b/misc.go
@@ -8,7 +8,7 @@ import (
"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)
field := kit.Select("", arg, 0)
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) == "" {
continue
}
- if i == 0 && (field == "" || field == INDEX) { // 表头行
+ if i == 0 && (field == "" || field == INDEX) {
if fields = kit.Split(l, sp, sp); field == INDEX {
if strings.HasPrefix(l, SP) || strings.HasPrefix(l, TB) {
indexs = append(indexs, 0)
@@ -37,8 +37,7 @@ func (m *Message) Split(str string, arg ...string) *Message { // field sp nl
}
continue
}
-
- if len(indexs) > 0 { // 按位切分
+ if len(indexs) > 0 {
for i, v := range indexs {
if v >= len(l) {
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
}
-
ls := kit.Split(l, sp, sp)
for i, v := range ls {
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)))
}
-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 {
for _, k := range m.meta[MSG_APPEND] {
m.RenameAppend(k, strings.ToLower(k))
@@ -101,7 +87,7 @@ func (m *Message) RenameOption(from, to string) *Message {
m.Option(from, "")
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 {
if arg[i] == arg[i+1] {
continue
@@ -154,9 +140,6 @@ func (m *Message) SetResult(arg ...string) *Message {
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) {
list := kit.List()
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)
}
}
+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 {
- args, opts := []Any{}, Map{}
- var cbs Any
-
- // 解析参数
- _source := logs.FileLine(3, 3)
+ args, opts, cbs, _source := []Any{}, Map{}, kit.Value(nil), logs.FileLine(3, 3)
for _, v := range arg {
switch val := v.(type) {
case string:
@@ -203,12 +201,10 @@ func (m *Message) _command(arg ...Any) *Message {
opts[val.Name] = val.Value
case *Option:
opts[val.Name] = val.Value
-
case logs.Meta:
if val.Key == "fileline" {
_source = val.Value
}
-
case func(int, Maps, []string):
defer func() { m.Table(val) }()
case func(Maps):
@@ -221,8 +217,6 @@ func (m *Message) _command(arg ...Any) *Message {
}
}
}
-
- // 解析命令
list := kit.Simple(args...)
if len(list) == 0 && !m.Hand {
list = m.meta[MSG_DETAIL]
@@ -230,25 +224,20 @@ func (m *Message) _command(arg ...Any) *Message {
if len(list) == 0 {
return m
}
-
ok := false
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 {
- msg.OptionCB(kit.Slice(kit.Split(list[0], PT), -1)[0], cbs)
+ msg.OptionCB(key, cbs)
}
for k, v := range opts {
msg.Option(k, v)
}
-
- // 执行命令
msg._source = _source
m.TryCatch(msg, true, func(msg *Message) { m = ctx._command(msg, cmd, key, arg...) })
}
-
- // 查找命令
if list[0] == "" {
- list[0] = m._key
- run(m.Spawn(), m.target, m._cmd, list[0], list[1:]...)
+ run(m.Spawn(), m.target, m._cmd, m._key, list[1:]...)
} 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:]...)
} 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))
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 {
- 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
}
-
- if m.Hand, m.meta[MSG_DETAIL] = true, kit.Simple(key, arg); cmd.Actions != nil {
+ if m.Hand, m.meta[MSG_DETAIL] = true, kit.Simple(m.PrefixKey(), arg); cmd.Actions != nil {
if len(arg) > 1 && arg[0] == ACTION {
if h, ok := cmd.Actions[arg[1]]; ok {
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)
}
}
}
-
- 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
+ return m.CmdHand(cmd, key, arg...)
}
func (c *Context) _action(m *Message, cmd *Command, key string, sub string, h *Action, arg ...string) *Message {
if h.Hand == nil {
m.Cmdy(kit.Split(h.Name), arg)
return m
}
-
- if m._sub = sub; len(h.List) > 0 && sub != "search" {
+ if m._sub = sub; len(h.List) > 0 && sub != SEARCH {
order := false
for i, v := range h.List {
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 {
m.Option(name, kit.Select(value, arg, i))
- } else if m.Option(name) == "" && value != "" {
- m.Option(name, value)
+ } else {
+ m.OptionDefault(name, value)
}
}
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 {
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...)
return m
}
-func MergeActions(list ...Any) Actions {
- if len(list) == 0 {
+func MergeActions(arg ...Any) Actions {
+ if len(arg) == 0 {
return nil
}
- base := list[0].(Actions)
- for _, from := range list[1:] {
+ list := arg[0].(Actions)
+ for _, from := range arg[1:] {
switch from := from.(type) {
case Actions:
for k, v := range from {
- if h, ok := base[k]; !ok {
- base[k] = v
+ if h, ok := list[k]; !ok {
+ list[k] = v
} else if h.Hand == nil {
h.Hand = v.Hand
} else if k == CTX_INIT {
- last := base[k].Hand
- prev := v.Hand
- base[k].Hand = func(m *Message, arg ...string) {
- prev(m, arg...)
+ last := h.Hand
+ hand := v.Hand
+ h.Hand = func(m *Message, arg ...string) {
+ hand(m, arg...)
last(m, arg...)
}
}
}
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) {
for k, v := range cmd.Actions {
func(k string) {
- if h, ok := base[k]; !ok {
- base[k] = &Action{Name: v.Name, Help: v.Help, Hand: func(m *Message, arg ...string) {
- m.Cmdy(from, k, arg)
- }}
+ if h, ok := list[k]; !ok {
+ list[k] = &Action{Name: v.Name, Help: v.Help, Hand: func(m *Message, arg ...string) { m.Cmdy(from, k, arg) }}
} else if h.Hand == nil {
- h.Hand = func(m *Message, arg ...string) {
- m.Cmdy(from, k, arg)
- }
+ h.Hand = func(m *Message, arg ...string) { m.Cmdy(from, k, arg) }
}
}(k)
}
- m.target.Merge(m.target)
})
+ if h != nil {
+ h.Hand(m, arg...)
+ }
}}
default:
Pulse.ErrorNotImplement(from)
}
}
- return base
+ return list
}
func SplitCmd(name string, actions Actions) (list []Any) {
const (
@@ -414,7 +364,6 @@ func SplitCmd(name string, actions Actions) (list []Any) {
PAGE = "page"
ARGS = "args"
)
-
item, button := kit.Dict(), false
push := func(arg ...string) {
button = kit.Select("", arg, 0) == BUTTON
@@ -432,7 +381,7 @@ func SplitCmd(name string, actions Actions) (list []Any) {
push(BUTTON, ls[i], AUTO)
case AUTO:
push(BUTTON, LIST, AUTO)
- push(BUTTON, BACK, AUTO)
+ push(BUTTON, BACK)
case PAGE:
push(TEXT, "limit")
push(TEXT, "offend")
diff --git a/misc/git/status.go b/misc/git/status.go
index b056f2d7..b1e361c5 100644
--- a/misc/git/status.go
+++ b/misc/git/status.go
@@ -287,7 +287,7 @@ func init() {
}
_repos_cmd(m, m.Option(REPOS), TAG, m.Option(VERSION))
_repos_cmd(m, m.Option(REPOS), PUSH, "--tags")
- m.ProcessRefresh30ms()
+ m.ProcessRefresh()
}},
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) {
@@ -319,6 +319,9 @@ func init() {
m.Cmdy(code.VIMER, code.DEVPACK)
}},
web.DREAM_TABLES: {Hand: func(m *ice.Message, arg ...string) {
+ if m.Option(mdb.TYPE) != web.WORKER {
+ return
+ }
text := []string{}
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") {
diff --git a/misc/lark/group.go b/misc/lark/group.go
index 0f808baa..8c04bae2 100644
--- a/misc/lark/group.go
+++ b/misc/lark/group.go
@@ -11,7 +11,7 @@ func _group_list(m *ice.Message, appid string) {
_, data := _lark_get(m, appid, "/open-apis/chat/v4/list")
kit.Fetch(kit.Value(data, "data.groups"), func(index int, value ice.Map) {
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.TEXT, value["description"])
m.Push(OPEN_ID, value["owner_open_id"])
diff --git a/misc/vim/tags.go b/misc/vim/tags.go
index 58805d6a..717803d6 100644
--- a/misc/vim/tags.go
+++ b/misc/vim/tags.go
@@ -140,7 +140,7 @@ func init() {
}
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: "添加"},
code.INNER: {Name: "inner", Help: "源码", Hand: func(m *ice.Message, arg ...string) {
diff --git a/option.go b/option.go
index ea3acb96..4319541d 100644
--- a/option.go
+++ b/option.go
@@ -38,10 +38,10 @@ func (m *Message) OptionSimple(key ...string) (res []string) {
if len(key) == 0 {
for _, k := range kit.Split(m.Config(FIELD)) {
switch k {
- case "", TIME, HASH:
+ case TIME, HASH:
continue
}
- if m.Option(k) == "" {
+ if k == "" || m.Option(k) == "" {
continue
}
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))
return m
}
-func (m *Message) Status(arg ...Any) {
- list := kit.List()
- args := kit.Simple(arg)
+func (m *Message) Status(arg ...Any) *Message {
+ list, args := kit.List(), kit.Simple(arg)
for i := 0; i < len(args)-1; i += 2 {
list = append(list, kit.Dict(NAME, args[i], VALUE, args[i+1]))
}
m.Option(MSG_STATUS, kit.Format(list))
+ return m
}
func (m *Message) StatusTime(arg ...Any) *Message {
- m.Status(TIME, m.Time(), arg, kit.MDB_COST, m.FormatCost())
- return m
+ return m.Status(TIME, m.Time(), arg, kit.MDB_COST, m.FormatCost())
}
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
+ return m.Status(TIME, m.Time(), kit.MDB_COUNT, kit.Split(m.FormatSize())[0], arg, kit.MDB_COST, m.FormatCost())
}
-func (m *Message) StatusTimeCountTotal(arg ...Any) {
- 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) StatusTimeCountTotal(arg ...Any) *Message {
+ 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) {
- m.Option(MSG_PROCESS, action)
+func (m *Message) Process(cmd string, arg ...Any) {
+ m.Option(MSG_PROCESS, cmd)
m.Option(PROCESS_ARG, arg...)
}
func (m *Message) ProcessLocation(arg ...Any) {
@@ -128,16 +126,12 @@ func (m *Message) ProcessHistory(arg ...Any) {
func (m *Message) ProcessConfirm(arg ...Any) {
m.Process(PROCESS_CONFIRM, arg...)
}
-func (m *Message) ProcessRefresh(arg ...string) { // delay
- if d, e := time.ParseDuration(kit.Select("300ms", arg, 0)); e == nil {
- m.Option("_delay", int(d/time.Millisecond))
- }
+func (m *Message) ProcessRefresh(arg ...string) {
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) {
m.Process(PROCESS_REWRITE, arg...)
}
@@ -146,11 +140,11 @@ func (m *Message) ProcessDisplay(arg ...Any) {
m.Option(MSG_DISPLAY, arg...)
}
-func (m *Message) ProcessInner() { m.Process(PROCESS_INNER) }
func (m *Message) ProcessField(arg ...Any) {
m.Process(PROCESS_FIELD)
m.Option(FIELD_PREFIX, arg...)
}
+func (m *Message) ProcessInner() { m.Process(PROCESS_INNER) }
func (m *Message) ProcessAgain() { m.Process(PROCESS_AGAIN) }
func (m *Message) ProcessHold(text ...Any) { m.Process(PROCESS_HOLD, text...) }
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) 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...))
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 {
if file == "" {
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))
}
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 {
p := kit.Split(kit.FileLine(n, 100), DF)[0]
if strings.Contains(p, "go/pkg/mod") {
diff --git a/render.go b/render.go
index 128131c7..87ae7787 100644
--- a/render.go
+++ b/render.go
@@ -14,12 +14,7 @@ func Render(m *Message, cmd string, args ...Any) string {
if render, ok := Info.render[cmd]; ok {
return render(m, cmd, args...)
}
-
switch arg := kit.Simple(args...); cmd {
- case RENDER_ANCHOR: // [name] link
- p := kit.Select(arg[0], arg, 1)
- return kit.Format(`%s`, p, arg[0])
-
case RENDER_BUTTON:
list := []string{}
for _, k := range args {
@@ -44,47 +39,40 @@ func Render(m *Message, cmd string, args ...Any) string {
}
}
return strings.Join(list, "")
-
- case RENDER_IMAGES: // src [height]
- if m.Option("height") != "" && m.Option("width") != "" {
- return kit.Format(`
`, arg[0], m.Option("height"), m.Option("width"))
- }
- if strings.Contains(m.Option(MSG_USERUA), "Mobile") {
- return kit.Format(`
`, arg[0], kit.Int(kit.Select(kit.Select("120", m.Option("width")), arg, 1))-24)
- }
- return kit.Format(`
`, 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(`